nodenetcdf 4.9.33 → 4.9.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.md +23 -2
- package/package.json +1 -1
- package/src/Attribute.cpp +11 -49
- package/src/Attribute.h +91 -0
- package/src/Dimension.cpp +9 -19
- package/src/Dimension.h +71 -0
- package/src/File.cpp +9 -34
- package/src/File.h +71 -0
- package/src/Group.cpp +45 -64
- package/src/Group.h +131 -0
- package/src/Variable.cpp +152 -67
- package/src/Variable.h +282 -1
- package/src/nodenetcdfjs.h +41 -0
package/src/File.cpp
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
#include <netcdf.h>
|
|
6
6
|
#include <string>
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
namespace nodenetcdfjs
|
|
10
9
|
{
|
|
11
10
|
|
|
@@ -21,11 +20,8 @@ File::~File()
|
|
|
21
20
|
{
|
|
22
21
|
if (!closed)
|
|
23
22
|
{
|
|
24
|
-
int retval = nc_close(id);
|
|
25
|
-
if (retval != NC_NOERR)
|
|
26
|
-
{
|
|
23
|
+
if (const int retval = nc_close(id); retval != NC_NOERR)
|
|
27
24
|
throw_netcdf_error(v8::Isolate::GetCurrent(), retval);
|
|
28
|
-
}
|
|
29
25
|
}
|
|
30
26
|
}
|
|
31
27
|
|
|
@@ -73,21 +69,13 @@ void File::New(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
73
69
|
*v8::String::Utf8Value(isolate, args[2]->ToString(isolate->GetCurrentContext()).ToLocalChecked());
|
|
74
70
|
|
|
75
71
|
if (format_arg == "classic")
|
|
76
|
-
{
|
|
77
72
|
format = 0;
|
|
78
|
-
}
|
|
79
73
|
else if (format_arg == "classic64")
|
|
80
|
-
{
|
|
81
74
|
format = NC_64BIT_OFFSET;
|
|
82
|
-
}
|
|
83
75
|
else if (format_arg == "nodenetcdf")
|
|
84
|
-
{
|
|
85
76
|
format = NC_NETCDF4;
|
|
86
|
-
}
|
|
87
77
|
else if (format_arg == "nodenetcdfclassic")
|
|
88
|
-
{
|
|
89
78
|
format = NC_NETCDF4 | NC_CLASSIC_MODEL;
|
|
90
|
-
}
|
|
91
79
|
else
|
|
92
80
|
{
|
|
93
81
|
isolate->ThrowException(v8::Exception::TypeError(
|
|
@@ -99,21 +87,13 @@ void File::New(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
99
87
|
|
|
100
88
|
int retval = NC_NOERR;
|
|
101
89
|
if (mode_arg == "r")
|
|
102
|
-
{
|
|
103
90
|
retval = nc_open(filename.c_str(), NC_NOWRITE, &id);
|
|
104
|
-
}
|
|
105
91
|
else if (mode_arg == "w")
|
|
106
|
-
{
|
|
107
92
|
retval = nc_open(filename.c_str(), NC_WRITE, &id);
|
|
108
|
-
}
|
|
109
93
|
else if (mode_arg == "c")
|
|
110
|
-
{
|
|
111
94
|
retval = nc_create(filename.c_str(), format | NC_NOCLOBBER, &id);
|
|
112
|
-
}
|
|
113
95
|
else if (mode_arg == "c!")
|
|
114
|
-
{
|
|
115
96
|
retval = nc_create(filename.c_str(), format | NC_CLOBBER, &id);
|
|
116
|
-
}
|
|
117
97
|
else
|
|
118
98
|
{
|
|
119
99
|
isolate->ThrowException(v8::Exception::TypeError(
|
|
@@ -146,9 +126,7 @@ void File::Sync(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
146
126
|
File *obj = node::ObjectWrap::Unwrap<File>(args.Holder());
|
|
147
127
|
int retval = nc_sync(obj->id);
|
|
148
128
|
if (retval != NC_NOERR)
|
|
149
|
-
{
|
|
150
129
|
throw_netcdf_error(args.GetIsolate(), retval);
|
|
151
|
-
}
|
|
152
130
|
}
|
|
153
131
|
|
|
154
132
|
void File::Close(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
@@ -156,9 +134,7 @@ void File::Close(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
156
134
|
File *obj = node::ObjectWrap::Unwrap<File>(args.Holder());
|
|
157
135
|
int retval = nc_close(obj->id);
|
|
158
136
|
if (retval != NC_NOERR)
|
|
159
|
-
{
|
|
160
137
|
throw_netcdf_error(args.GetIsolate(), retval);
|
|
161
|
-
}
|
|
162
138
|
obj->closed = true;
|
|
163
139
|
}
|
|
164
140
|
|
|
@@ -173,18 +149,18 @@ void File::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
173
149
|
{
|
|
174
150
|
v8::Isolate *isolate = args.GetIsolate();
|
|
175
151
|
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
152
|
+
|
|
153
|
+
v8::Local<v8::String> rootProp =
|
|
154
|
+
v8::String::NewFromUtf8(isolate, "root", v8::NewStringType::kNormal).ToLocalChecked();
|
|
179
155
|
v8::Local<v8::Value> root = args.Holder()->Get(context, rootProp).ToLocalChecked();
|
|
180
|
-
|
|
181
|
-
// Call toJSON on the root group to get proper array conversion
|
|
156
|
+
|
|
182
157
|
if (root->IsObject())
|
|
183
158
|
{
|
|
184
159
|
v8::Local<v8::Object> rootObj = root->ToObject(context).ToLocalChecked();
|
|
185
|
-
v8::Local<v8::String> toJSONProp =
|
|
160
|
+
v8::Local<v8::String> toJSONProp =
|
|
161
|
+
v8::String::NewFromUtf8(isolate, "toJSON", v8::NewStringType::kNormal).ToLocalChecked();
|
|
186
162
|
v8::Local<v8::Value> toJSONMethod = rootObj->Get(context, toJSONProp).ToLocalChecked();
|
|
187
|
-
|
|
163
|
+
|
|
188
164
|
if (toJSONMethod->IsFunction())
|
|
189
165
|
{
|
|
190
166
|
v8::Local<v8::Function> toJSONFunc = v8::Local<v8::Function>::Cast(toJSONMethod);
|
|
@@ -193,8 +169,7 @@ void File::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
193
169
|
return;
|
|
194
170
|
}
|
|
195
171
|
}
|
|
196
|
-
|
|
197
|
-
// Fallback: return root as-is
|
|
172
|
+
|
|
198
173
|
args.GetReturnValue().Set(root);
|
|
199
174
|
}
|
|
200
175
|
} // namespace nodenetcdfjs
|
package/src/File.h
CHANGED
|
@@ -9,13 +9,43 @@ namespace nodenetcdfjs
|
|
|
9
9
|
|
|
10
10
|
class Group;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @brief Represents a NetCDF file wrapper for Node.js
|
|
14
|
+
*
|
|
15
|
+
* This class provides a Node.js interface to NetCDF files, which are used for
|
|
16
|
+
* storing array-oriented scientific data. The File class handles opening, closing,
|
|
17
|
+
* and synchronizing NetCDF files, and serves as the entry point for accessing
|
|
18
|
+
* groups, variables, dimensions, and attributes within the file.
|
|
19
|
+
*
|
|
20
|
+
* The class extends node::ObjectWrap to provide JavaScript binding capabilities,
|
|
21
|
+
* allowing NetCDF files to be manipulated from JavaScript code.
|
|
22
|
+
*/
|
|
12
23
|
class File : public node::ObjectWrap
|
|
13
24
|
{
|
|
14
25
|
public:
|
|
26
|
+
/**
|
|
27
|
+
* @brief Initialize the File class and register it with Node.js
|
|
28
|
+
* @param exports The exports object to attach the File constructor to
|
|
29
|
+
*
|
|
30
|
+
* This static method sets up the File class for use in Node.js,
|
|
31
|
+
* defining its constructor and prototype methods.
|
|
32
|
+
*/
|
|
15
33
|
static void Init(v8::Local<v8::Object> exports);
|
|
16
34
|
|
|
17
35
|
private:
|
|
36
|
+
/**
|
|
37
|
+
* @brief Construct a File object
|
|
38
|
+
* @param id_ The file ID from the NetCDF library
|
|
39
|
+
*
|
|
40
|
+
* Creates a new file wrapper for an opened NetCDF file.
|
|
41
|
+
*/
|
|
18
42
|
explicit File(int id_) noexcept;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @brief Destructor for File object
|
|
46
|
+
*
|
|
47
|
+
* Ensures the NetCDF file is properly closed when the object is destroyed.
|
|
48
|
+
*/
|
|
19
49
|
~File() override;
|
|
20
50
|
|
|
21
51
|
// Delete copy and move operations for safety
|
|
@@ -24,17 +54,58 @@ class File : public node::ObjectWrap
|
|
|
24
54
|
File(File &&) = delete;
|
|
25
55
|
File &operator=(File &&) = delete;
|
|
26
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @brief Open a NetCDF file
|
|
59
|
+
* @param filename Path to the NetCDF file to open
|
|
60
|
+
* @param mode Access mode (read-only, read-write, create, etc.)
|
|
61
|
+
* @param format NetCDF format (classic, 64-bit offset, NetCDF-4, etc.)
|
|
62
|
+
* @return true if successful, false otherwise
|
|
63
|
+
*
|
|
64
|
+
* Opens a NetCDF file with the specified mode and format.
|
|
65
|
+
*/
|
|
27
66
|
[[nodiscard]] bool open(const char *filename, int mode, int format) noexcept;
|
|
28
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @brief JavaScript constructor for creating new File objects
|
|
70
|
+
* @param args JavaScript function arguments containing filename, mode, and format
|
|
71
|
+
*/
|
|
29
72
|
static void New(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @brief Close the NetCDF file
|
|
76
|
+
* @param args JavaScript function arguments
|
|
77
|
+
*
|
|
78
|
+
* Closes the file and releases associated resources.
|
|
79
|
+
*/
|
|
30
80
|
static void Close(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @brief Synchronize file to disk
|
|
84
|
+
* @param args JavaScript function arguments
|
|
85
|
+
*
|
|
86
|
+
* Flushes any buffered data to disk, ensuring data persistence.
|
|
87
|
+
*/
|
|
31
88
|
static void Sync(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @brief Custom inspect method for Node.js console output
|
|
92
|
+
* @param args JavaScript function arguments
|
|
93
|
+
*/
|
|
32
94
|
static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @brief Convert file to JSON representation
|
|
98
|
+
* @param args JavaScript function arguments
|
|
99
|
+
*/
|
|
33
100
|
static void ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
34
101
|
|
|
102
|
+
/// Persistent reference to the JavaScript constructor function
|
|
35
103
|
static v8::Persistent<v8::Function> constructor;
|
|
36
104
|
|
|
105
|
+
/// The file ID from the NetCDF library
|
|
37
106
|
int id{-1};
|
|
107
|
+
|
|
108
|
+
/// Flag indicating whether the file has been closed
|
|
38
109
|
bool closed{false};
|
|
39
110
|
};
|
|
40
111
|
|
package/src/Group.cpp
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
#include "nodenetcdfjs.h"
|
|
6
6
|
#include <netcdf.h>
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
namespace nodenetcdfjs
|
|
10
9
|
{
|
|
11
10
|
|
|
@@ -136,9 +135,7 @@ void Group::AddDimension(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
136
135
|
|
|
137
136
|
int len;
|
|
138
137
|
if (const std::string len_str = *v8::String::Utf8Value(isolate, args[1]); len_str == "unlimited")
|
|
139
|
-
{
|
|
140
138
|
len = NC_UNLIMITED;
|
|
141
|
-
}
|
|
142
139
|
else
|
|
143
140
|
{
|
|
144
141
|
if (!args[1]->IsUint32())
|
|
@@ -152,9 +149,8 @@ void Group::AddDimension(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
152
149
|
}
|
|
153
150
|
|
|
154
151
|
int new_id = -1;
|
|
155
|
-
const int retval = nc_def_dim(obj->id, *v8::String::Utf8Value(isolate, args[0]), len, &new_id);
|
|
156
|
-
|
|
157
|
-
if (retval != NC_NOERR)
|
|
152
|
+
if (const int retval = nc_def_dim(obj->id, *v8::String::Utf8Value(isolate, args[0]), len, &new_id);
|
|
153
|
+
retval != NC_NOERR)
|
|
158
154
|
{
|
|
159
155
|
throw_netcdf_error(isolate, retval);
|
|
160
156
|
return;
|
|
@@ -271,15 +267,12 @@ void Group::GetVariables(v8::Local<v8::String> property, const v8::PropertyCallb
|
|
|
271
267
|
{
|
|
272
268
|
auto *v = new Variable(var_ids[i], obj->id);
|
|
273
269
|
if (v->get_name(name.data()))
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
270
|
+
(void)result->CreateDataProperty(
|
|
271
|
+
context,
|
|
272
|
+
v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked(),
|
|
273
|
+
v->handle());
|
|
279
274
|
else
|
|
280
|
-
{
|
|
281
275
|
return;
|
|
282
|
-
}
|
|
283
276
|
}
|
|
284
277
|
info.GetReturnValue().Set(result);
|
|
285
278
|
}
|
|
@@ -314,7 +307,8 @@ void Group::GetDimensions(v8::Local<v8::String> property, const v8::PropertyCall
|
|
|
314
307
|
auto *d = new Dimension(dim_ids[i], obj->id);
|
|
315
308
|
if (d->get_name(name.data()))
|
|
316
309
|
{
|
|
317
|
-
(void)result->CreateDataProperty(
|
|
310
|
+
(void)result->CreateDataProperty(
|
|
311
|
+
context,
|
|
318
312
|
v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked(),
|
|
319
313
|
d->handle());
|
|
320
314
|
}
|
|
@@ -354,11 +348,13 @@ void Group::GetUnlimited(v8::Local<v8::String> property, const v8::PropertyCallb
|
|
|
354
348
|
auto *d = new Dimension(dim_ids[i], obj->id);
|
|
355
349
|
if (d->get_name(name.data()))
|
|
356
350
|
{
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
351
|
+
(void)result->CreateDataProperty(
|
|
352
|
+
context,
|
|
353
|
+
v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked(),
|
|
354
|
+
d->handle());
|
|
360
355
|
}
|
|
361
|
-
else
|
|
356
|
+
else
|
|
357
|
+
return;
|
|
362
358
|
}
|
|
363
359
|
info.GetReturnValue().Set(result);
|
|
364
360
|
}
|
|
@@ -389,9 +385,9 @@ void Group::GetAttributes(v8::Local<v8::String> property, const v8::PropertyCall
|
|
|
389
385
|
return;
|
|
390
386
|
}
|
|
391
387
|
auto *a = new Attribute(name.data(), NC_GLOBAL, obj->id);
|
|
392
|
-
(void)result->CreateDataProperty(
|
|
393
|
-
|
|
394
|
-
|
|
388
|
+
(void)result->CreateDataProperty(
|
|
389
|
+
context, v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked(),
|
|
390
|
+
a->handle());
|
|
395
391
|
}
|
|
396
392
|
info.GetReturnValue().Set(result);
|
|
397
393
|
}
|
|
@@ -426,14 +422,13 @@ void Group::GetSubgroups(v8::Local<v8::String> property, const v8::PropertyCallb
|
|
|
426
422
|
auto *g = new Group(grp_ids[i]);
|
|
427
423
|
if (g->get_name(name.data()))
|
|
428
424
|
{
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
425
|
+
(void)result->CreateDataProperty(
|
|
426
|
+
context,
|
|
427
|
+
v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked(),
|
|
428
|
+
g->handle());
|
|
432
429
|
}
|
|
433
430
|
else
|
|
434
|
-
{
|
|
435
431
|
return;
|
|
436
|
-
}
|
|
437
432
|
}
|
|
438
433
|
info.GetReturnValue().Set(result);
|
|
439
434
|
}
|
|
@@ -488,8 +483,7 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
488
483
|
v8::Isolate *isolate = args.GetIsolate();
|
|
489
484
|
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
|
490
485
|
const auto *obj = node::ObjectWrap::Unwrap<Group>(args.Holder());
|
|
491
|
-
|
|
492
|
-
// Use internalized strings for better performance
|
|
486
|
+
|
|
493
487
|
v8::Local<v8::String> id_str = v8::String::NewFromUtf8Literal(isolate, "id");
|
|
494
488
|
v8::Local<v8::String> name_str = v8::String::NewFromUtf8Literal(isolate, "name");
|
|
495
489
|
v8::Local<v8::String> fullname_str = v8::String::NewFromUtf8Literal(isolate, "fullname");
|
|
@@ -497,21 +491,17 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
497
491
|
v8::Local<v8::String> variables_str = v8::String::NewFromUtf8Literal(isolate, "variables");
|
|
498
492
|
v8::Local<v8::String> attributes_str = v8::String::NewFromUtf8Literal(isolate, "attributes");
|
|
499
493
|
v8::Local<v8::String> subgroups_str = v8::String::NewFromUtf8Literal(isolate, "subgroups");
|
|
500
|
-
|
|
494
|
+
|
|
501
495
|
v8::Local<v8::Object> json = v8::Object::New(isolate);
|
|
502
|
-
|
|
503
|
-
// Add id
|
|
496
|
+
|
|
504
497
|
(void)json->CreateDataProperty(context, id_str, v8::Integer::New(isolate, obj->id));
|
|
505
|
-
|
|
506
|
-
// Add name
|
|
498
|
+
|
|
507
499
|
std::array<char, NC_MAX_NAME + 1> name{};
|
|
508
500
|
if (obj->get_name(name.data()))
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
// Add fullname
|
|
501
|
+
(void)json->CreateDataProperty(
|
|
502
|
+
context, name_str,
|
|
503
|
+
v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked());
|
|
504
|
+
|
|
515
505
|
size_t len = 0;
|
|
516
506
|
int retval = nc_inq_grpname_len(obj->id, &len);
|
|
517
507
|
if (retval == NC_NOERR)
|
|
@@ -519,13 +509,11 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
519
509
|
std::vector<char> fullname(len + 1, '\0');
|
|
520
510
|
retval = nc_inq_grpname_full(obj->id, nullptr, fullname.data());
|
|
521
511
|
if (retval == NC_NOERR)
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
}
|
|
512
|
+
(void)json->CreateDataProperty(
|
|
513
|
+
context, fullname_str,
|
|
514
|
+
v8::String::NewFromUtf8(isolate, fullname.data(), v8::NewStringType::kInternalized).ToLocalChecked());
|
|
526
515
|
}
|
|
527
|
-
|
|
528
|
-
// Convert dimensions object to array, calling toJSON on each item
|
|
516
|
+
|
|
529
517
|
v8::Local<v8::Value> dimensions = args.Holder()->Get(context, dimensions_str).ToLocalChecked();
|
|
530
518
|
if (dimensions->IsObject() && !dimensions->IsNull())
|
|
531
519
|
{
|
|
@@ -533,13 +521,12 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
533
521
|
v8::Local<v8::Array> propNames = dimsObj->GetOwnPropertyNames(context).ToLocalChecked();
|
|
534
522
|
v8::Local<v8::Array> dimsArray = v8::Array::New(isolate, propNames->Length());
|
|
535
523
|
v8::Local<v8::String> toJSONStr = v8::String::NewFromUtf8Literal(isolate, "toJSON");
|
|
536
|
-
|
|
524
|
+
|
|
537
525
|
for (uint32_t i = 0; i < propNames->Length(); i++)
|
|
538
526
|
{
|
|
539
527
|
v8::Local<v8::Value> key = propNames->Get(context, i).ToLocalChecked();
|
|
540
528
|
v8::Local<v8::Value> value = dimsObj->Get(context, key).ToLocalChecked();
|
|
541
|
-
|
|
542
|
-
// Call toJSON if available to ensure proper serialization
|
|
529
|
+
|
|
543
530
|
if (value->IsObject())
|
|
544
531
|
{
|
|
545
532
|
v8::Local<v8::Object> valueObj = value->ToObject(context).ToLocalChecked();
|
|
@@ -554,8 +541,7 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
554
541
|
}
|
|
555
542
|
(void)json->CreateDataProperty(context, dimensions_str, dimsArray);
|
|
556
543
|
}
|
|
557
|
-
|
|
558
|
-
// Convert variables object to array, calling toJSON on each item
|
|
544
|
+
|
|
559
545
|
v8::Local<v8::Value> variables = args.Holder()->Get(context, variables_str).ToLocalChecked();
|
|
560
546
|
if (variables->IsObject() && !variables->IsNull())
|
|
561
547
|
{
|
|
@@ -563,13 +549,12 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
563
549
|
v8::Local<v8::Array> propNames = varsObj->GetOwnPropertyNames(context).ToLocalChecked();
|
|
564
550
|
v8::Local<v8::Array> varsArray = v8::Array::New(isolate, propNames->Length());
|
|
565
551
|
v8::Local<v8::String> toJSONStr = v8::String::NewFromUtf8Literal(isolate, "toJSON");
|
|
566
|
-
|
|
552
|
+
|
|
567
553
|
for (uint32_t i = 0; i < propNames->Length(); i++)
|
|
568
554
|
{
|
|
569
555
|
v8::Local<v8::Value> key = propNames->Get(context, i).ToLocalChecked();
|
|
570
556
|
v8::Local<v8::Value> value = varsObj->Get(context, key).ToLocalChecked();
|
|
571
|
-
|
|
572
|
-
// Call toJSON if available to ensure proper serialization
|
|
557
|
+
|
|
573
558
|
if (value->IsObject())
|
|
574
559
|
{
|
|
575
560
|
v8::Local<v8::Object> valueObj = value->ToObject(context).ToLocalChecked();
|
|
@@ -584,8 +569,7 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
584
569
|
}
|
|
585
570
|
(void)json->CreateDataProperty(context, variables_str, varsArray);
|
|
586
571
|
}
|
|
587
|
-
|
|
588
|
-
// Convert attributes object to array, calling toJSON on each item
|
|
572
|
+
|
|
589
573
|
v8::Local<v8::Value> attributes = args.Holder()->Get(context, attributes_str).ToLocalChecked();
|
|
590
574
|
if (attributes->IsObject() && !attributes->IsNull())
|
|
591
575
|
{
|
|
@@ -593,13 +577,12 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
593
577
|
v8::Local<v8::Array> propNames = attrsObj->GetOwnPropertyNames(context).ToLocalChecked();
|
|
594
578
|
v8::Local<v8::Array> attrsArray = v8::Array::New(isolate, propNames->Length());
|
|
595
579
|
v8::Local<v8::String> toJSONStr = v8::String::NewFromUtf8Literal(isolate, "toJSON");
|
|
596
|
-
|
|
580
|
+
|
|
597
581
|
for (uint32_t i = 0; i < propNames->Length(); i++)
|
|
598
582
|
{
|
|
599
583
|
v8::Local<v8::Value> key = propNames->Get(context, i).ToLocalChecked();
|
|
600
584
|
v8::Local<v8::Value> value = attrsObj->Get(context, key).ToLocalChecked();
|
|
601
|
-
|
|
602
|
-
// Call toJSON if available to ensure proper serialization
|
|
585
|
+
|
|
603
586
|
if (value->IsObject())
|
|
604
587
|
{
|
|
605
588
|
v8::Local<v8::Object> valueObj = value->ToObject(context).ToLocalChecked();
|
|
@@ -614,8 +597,7 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
614
597
|
}
|
|
615
598
|
(void)json->CreateDataProperty(context, attributes_str, attrsArray);
|
|
616
599
|
}
|
|
617
|
-
|
|
618
|
-
// Convert subgroups object to array, calling toJSON on each item
|
|
600
|
+
|
|
619
601
|
v8::Local<v8::Value> subgroups = args.Holder()->Get(context, subgroups_str).ToLocalChecked();
|
|
620
602
|
if (subgroups->IsObject() && !subgroups->IsNull())
|
|
621
603
|
{
|
|
@@ -623,13 +605,12 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
623
605
|
v8::Local<v8::Array> propNames = subgrpsObj->GetOwnPropertyNames(context).ToLocalChecked();
|
|
624
606
|
v8::Local<v8::Array> subgrpsArray = v8::Array::New(isolate, propNames->Length());
|
|
625
607
|
v8::Local<v8::String> toJSONStr = v8::String::NewFromUtf8Literal(isolate, "toJSON");
|
|
626
|
-
|
|
608
|
+
|
|
627
609
|
for (uint32_t i = 0; i < propNames->Length(); i++)
|
|
628
610
|
{
|
|
629
611
|
v8::Local<v8::Value> key = propNames->Get(context, i).ToLocalChecked();
|
|
630
612
|
v8::Local<v8::Value> value = subgrpsObj->Get(context, key).ToLocalChecked();
|
|
631
|
-
|
|
632
|
-
// Call toJSON if available to ensure proper serialization
|
|
613
|
+
|
|
633
614
|
if (value->IsObject())
|
|
634
615
|
{
|
|
635
616
|
v8::Local<v8::Object> valueObj = value->ToObject(context).ToLocalChecked();
|
|
@@ -644,7 +625,7 @@ void Group::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
|
|
|
644
625
|
}
|
|
645
626
|
(void)json->CreateDataProperty(context, subgroups_str, subgrpsArray);
|
|
646
627
|
}
|
|
647
|
-
|
|
628
|
+
|
|
648
629
|
args.GetReturnValue().Set(json);
|
|
649
630
|
}
|
|
650
631
|
} // namespace nodenetcdfjs
|
package/src/Group.h
CHANGED
|
@@ -9,12 +9,44 @@ namespace nodenetcdfjs
|
|
|
9
9
|
|
|
10
10
|
class Variable;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @brief Represents a NetCDF group wrapper for Node.js
|
|
14
|
+
*
|
|
15
|
+
* This class provides a Node.js interface to NetCDF groups, which are hierarchical
|
|
16
|
+
* containers for organizing variables, dimensions, attributes, and subgroups within
|
|
17
|
+
* a NetCDF file. Groups enable logical organization of related data items.
|
|
18
|
+
*
|
|
19
|
+
* The class extends node::ObjectWrap to provide JavaScript binding capabilities,
|
|
20
|
+
* allowing groups to be navigated and manipulated from JavaScript code.
|
|
21
|
+
*/
|
|
12
22
|
class Group : public node::ObjectWrap
|
|
13
23
|
{
|
|
14
24
|
public:
|
|
25
|
+
/**
|
|
26
|
+
* @brief Construct a Group object
|
|
27
|
+
* @param id The group ID in the NetCDF file
|
|
28
|
+
*
|
|
29
|
+
* Creates a new group wrapper for an existing NetCDF group.
|
|
30
|
+
*/
|
|
15
31
|
explicit Group(int id) noexcept;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @brief Initialize the Group class and register it with Node.js
|
|
35
|
+
* @param exports The exports object to attach the Group constructor to
|
|
36
|
+
*
|
|
37
|
+
* This static method sets up the Group class for use in Node.js,
|
|
38
|
+
* defining its constructor and prototype methods.
|
|
39
|
+
*/
|
|
16
40
|
static void Init(v8::Local<v8::Object> exports);
|
|
17
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @brief Get the name of this group
|
|
44
|
+
* @param name Buffer to store the group name
|
|
45
|
+
* @return true if successful, false otherwise
|
|
46
|
+
*
|
|
47
|
+
* Retrieves the group name from the NetCDF file and stores it
|
|
48
|
+
* in the provided buffer.
|
|
49
|
+
*/
|
|
18
50
|
[[nodiscard]] bool get_name(char *name) const noexcept;
|
|
19
51
|
|
|
20
52
|
private:
|
|
@@ -24,24 +56,123 @@ class Group : public node::ObjectWrap
|
|
|
24
56
|
Group(Group &&) = delete;
|
|
25
57
|
Group &operator=(Group &&) = delete;
|
|
26
58
|
|
|
59
|
+
/// Persistent reference to the JavaScript constructor function
|
|
27
60
|
static v8::Persistent<v8::Function> constructor;
|
|
28
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @brief Getter for the group ID property
|
|
64
|
+
* @param property The property name being accessed
|
|
65
|
+
* @param info Callback info containing the return value
|
|
66
|
+
*/
|
|
29
67
|
static void GetId(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @brief Getter for the variables property
|
|
71
|
+
* @param property The property name being accessed
|
|
72
|
+
* @param info Callback info containing the return value
|
|
73
|
+
*
|
|
74
|
+
* Returns an object containing all variables in this group.
|
|
75
|
+
*/
|
|
30
76
|
static void GetVariables(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @brief Getter for the dimensions property
|
|
80
|
+
* @param property The property name being accessed
|
|
81
|
+
* @param info Callback info containing the return value
|
|
82
|
+
*
|
|
83
|
+
* Returns an object containing all dimensions in this group.
|
|
84
|
+
*/
|
|
31
85
|
static void GetDimensions(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @brief Getter for the unlimited dimensions property
|
|
89
|
+
* @param property The property name being accessed
|
|
90
|
+
* @param info Callback info containing the return value
|
|
91
|
+
*
|
|
92
|
+
* Returns an array of unlimited dimension IDs in this group.
|
|
93
|
+
*/
|
|
32
94
|
static void GetUnlimited(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @brief Getter for the attributes property
|
|
98
|
+
* @param property The property name being accessed
|
|
99
|
+
* @param info Callback info containing the return value
|
|
100
|
+
*
|
|
101
|
+
* Returns an object containing all attributes in this group.
|
|
102
|
+
*/
|
|
33
103
|
static void GetAttributes(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @brief Getter for the subgroups property
|
|
107
|
+
* @param property The property name being accessed
|
|
108
|
+
* @param info Callback info containing the return value
|
|
109
|
+
*
|
|
110
|
+
* Returns an object containing all subgroups in this group.
|
|
111
|
+
*/
|
|
34
112
|
static void GetSubgroups(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @brief Getter for the group name property
|
|
116
|
+
* @param property The property name being accessed
|
|
117
|
+
* @param info Callback info containing the return value
|
|
118
|
+
*/
|
|
35
119
|
static void GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @brief Getter for the full group name property
|
|
123
|
+
* @param property The property name being accessed
|
|
124
|
+
* @param info Callback info containing the return value
|
|
125
|
+
*
|
|
126
|
+
* Returns the full path to this group from the root.
|
|
127
|
+
*/
|
|
36
128
|
static void GetFullname(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
|
|
37
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @brief Add a new attribute to this group
|
|
132
|
+
* @param args JavaScript function arguments (name, type, value)
|
|
133
|
+
*
|
|
134
|
+
* Creates a new attribute with the specified name, type, and value.
|
|
135
|
+
*/
|
|
38
136
|
static void AddAttribute(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @brief Add a new dimension to this group
|
|
140
|
+
* @param args JavaScript function arguments (name, length)
|
|
141
|
+
*
|
|
142
|
+
* Creates a new dimension with the specified name and length.
|
|
143
|
+
* Use 0 or NC_UNLIMITED for an unlimited dimension.
|
|
144
|
+
*/
|
|
39
145
|
static void AddDimension(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @brief Add a new subgroup to this group
|
|
149
|
+
* @param args JavaScript function arguments (name)
|
|
150
|
+
*
|
|
151
|
+
* Creates a new subgroup with the specified name.
|
|
152
|
+
*/
|
|
40
153
|
static void AddSubgroup(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @brief Add a new variable to this group
|
|
157
|
+
* @param args JavaScript function arguments (name, type, dimensions)
|
|
158
|
+
*
|
|
159
|
+
* Creates a new variable with the specified name, data type, and dimensions.
|
|
160
|
+
*/
|
|
41
161
|
static void AddVariable(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @brief Custom inspect method for Node.js console output
|
|
165
|
+
* @param args JavaScript function arguments
|
|
166
|
+
*/
|
|
42
167
|
static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @brief Convert group to JSON representation
|
|
171
|
+
* @param args JavaScript function arguments
|
|
172
|
+
*/
|
|
43
173
|
static void ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args);
|
|
44
174
|
|
|
175
|
+
/// The group ID in the NetCDF file
|
|
45
176
|
int id{-1};
|
|
46
177
|
};
|
|
47
178
|
|