nodenetcdf 4.9.32 → 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 CHANGED
@@ -11,3 +11,22 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
11
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
12
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
13
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ Copyright (c) Luke Shore <luke.a.shore@oliva.energy>
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this
18
+ software and associated documentation files (the "Software"), to deal in the Software
19
+ without restriction, including without limitation the rights to use, copy, modify,
20
+ merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
21
+ permit persons to whom the Software is furnished to do so, subject to the following
22
+ conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in all copies
25
+ or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
28
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
30
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
32
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Node.js native addon for reading and writing NodeNetCDF files, providing a comprehensive interface to the NetCDF-4 C library.
4
4
 
5
- IMPORTANT NOTE: this project dose not follow conventional open source standards we will accept PR's but we will not be actively changeing code unless something breaks
5
+ IMPORTANT NOTE: this project does not follow conventional open source standards we will accept PR's but we will not be actively changeing code unless something breaks
6
6
 
7
7
  ## Overview
8
8
 
@@ -294,7 +294,7 @@ The build process uses:
294
294
 
295
295
  ## Original Project and License
296
296
 
297
- This is a fork and modernization of the original [nodenetcdf](https://github.com/parro-it/nodenetcdf) project.
297
+ This is a fork and modernization of the original [netcdf4](https://github.com/parro-it/netcdf4) project.
298
298
 
299
299
  ### Original Contributors
300
300
 
@@ -323,6 +323,27 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
323
323
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
324
324
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
325
325
 
326
+ MIT License
327
+
328
+ Copyright (c) Luke Shore <luke.a.shore@oliva.energy>
329
+
330
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this
331
+ software and associated documentation files (the "Software"), to deal in the Software
332
+ without restriction, including without limitation the rights to use, copy, modify,
333
+ merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
334
+ permit persons to whom the Software is furnished to do so, subject to the following
335
+ conditions:
336
+
337
+ The above copyright notice and this permission notice shall be included in all copies
338
+ or substantial portions of the Software.
339
+
340
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
341
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
342
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
343
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
344
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
345
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
346
+
326
347
  ## Links
327
348
 
328
349
  - [Original Project](https://github.com/parro-it/nodenetcdf)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodenetcdf",
3
- "version": "4.9.32",
3
+ "version": "4.9.34",
4
4
  "description": "Read and write NodeNetCDF files",
5
5
  "main": "./build/Release/nodenetcdf.node",
6
6
  "types": "./index.d.ts",
package/src/Attribute.cpp CHANGED
@@ -4,7 +4,6 @@
4
4
  #include <iostream>
5
5
  #include <netcdf.h>
6
6
 
7
-
8
7
  namespace nodenetcdfjs
9
8
  {
10
9
 
@@ -21,9 +20,7 @@ Attribute::Attribute(const char *name_, int var_id_, int parent_id_) noexcept
21
20
  Wrap(obj);
22
21
  const int retval = nc_inq_atttype(parent_id, var_id_, name_, &type);
23
22
  if (retval != NC_NOERR)
24
- {
25
23
  throw_netcdf_error(isolate, retval);
26
- }
27
24
  }
28
25
 
29
26
  Attribute::Attribute(const char *name_, int var_id_, int parent_id_, int type_) noexcept
@@ -108,9 +105,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
108
105
  std::vector<int8_t> v(len);
109
106
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
110
107
  if (len == 1)
111
- {
112
108
  info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
113
- }
114
109
  else
115
110
  {
116
111
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int8_t));
@@ -123,9 +118,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
123
118
  std::vector<int16_t> v(len);
124
119
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
125
120
  if (len == 1)
126
- {
127
121
  info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
128
- }
129
122
  else
130
123
  {
131
124
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int16_t));
@@ -138,9 +131,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
138
131
  std::vector<int32_t> v(len);
139
132
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
140
133
  if (len == 1)
141
- {
142
134
  info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
143
- }
144
135
  else
145
136
  {
146
137
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int32_t));
@@ -153,9 +144,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
153
144
  std::vector<float> v(len);
154
145
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
155
146
  if (len == 1)
156
- {
157
147
  info.GetReturnValue().Set(v8::Number::New(isolate, v[0]));
158
- }
159
148
  else
160
149
  {
161
150
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(float));
@@ -168,9 +157,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
168
157
  std::vector<double> v(len);
169
158
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
170
159
  if (len == 1)
171
- {
172
160
  info.GetReturnValue().Set(v8::Number::New(isolate, v[0]));
173
- }
174
161
  else
175
162
  {
176
163
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(double));
@@ -183,9 +170,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
183
170
  std::vector<uint8_t> v(len);
184
171
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
185
172
  if (len == 1)
186
- {
187
173
  info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
188
- }
189
174
  else
190
175
  {
191
176
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint8_t));
@@ -198,9 +183,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
198
183
  std::vector<uint16_t> v(len);
199
184
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
200
185
  if (len == 1)
201
- {
202
186
  info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
203
- }
204
187
  else
205
188
  {
206
189
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint16_t));
@@ -213,9 +196,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
213
196
  std::vector<uint32_t> v(len);
214
197
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
215
198
  if (len == 1)
216
- {
217
199
  info.GetReturnValue().Set(v8::Integer::NewFromUnsigned(isolate, v[0]));
218
- }
219
200
  else
220
201
  {
221
202
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint32_t));
@@ -228,9 +209,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
228
209
  std::vector<int64_t> v(len);
229
210
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
230
211
  if (len == 1)
231
- {
232
212
  info.GetReturnValue().Set(v8::Integer::New(isolate, static_cast<int32_t>(v[0])));
233
- }
234
213
  else
235
214
  {
236
215
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int64_t));
@@ -243,9 +222,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
243
222
  std::vector<uint64_t> v(len);
244
223
  retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
245
224
  if (len == 1)
246
- {
247
225
  info.GetReturnValue().Set(v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(v[0])));
248
- }
249
226
  else
250
227
  {
251
228
  v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint64_t));
@@ -264,9 +241,7 @@ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallb
264
241
  break;
265
242
  }
266
243
  if (retval != NC_NOERR)
267
- {
268
244
  throw_netcdf_error(isolate, retval);
269
- }
270
245
  }
271
246
 
272
247
  void Attribute::SetValue(v8::Local<v8::String> property, v8::Local<v8::Value> val,
@@ -311,9 +286,7 @@ void Attribute::set_value(const v8::Local<v8::Value> &val)
311
286
  }
312
287
 
313
288
  if (retval != NC_NOERR)
314
- {
315
289
  throw_netcdf_error(isolate, retval);
316
- }
317
290
  }
318
291
 
319
292
  void Attribute::Delete(const v8::FunctionCallbackInfo<v8::Value> &args)
@@ -321,9 +294,7 @@ void Attribute::Delete(const v8::FunctionCallbackInfo<v8::Value> &args)
321
294
  auto *obj = node::ObjectWrap::Unwrap<Attribute>(args.Holder());
322
295
  const int retval = nc_del_att(obj->parent_id, obj->var_id, obj->name.c_str());
323
296
  if (retval != NC_NOERR)
324
- {
325
297
  throw_netcdf_error(args.GetIsolate(), retval);
326
- }
327
298
  }
328
299
 
329
300
  void Attribute::Inspect(const v8::FunctionCallbackInfo<v8::Value> &args)
@@ -338,40 +309,32 @@ void Attribute::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
338
309
  v8::Isolate *isolate = args.GetIsolate();
339
310
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
340
311
  const auto *obj = node::ObjectWrap::Unwrap<Attribute>(args.Holder());
341
-
342
- // Use internalized strings for better performance
312
+
343
313
  v8::Local<v8::String> name_str = v8::String::NewFromUtf8Literal(isolate, "name");
344
314
  v8::Local<v8::String> value_str = v8::String::NewFromUtf8Literal(isolate, "value");
345
-
315
+
346
316
  v8::Local<v8::Object> json = v8::Object::New(isolate);
347
-
348
- // Add name
349
- (void)json->CreateDataProperty(context, name_str,
350
- v8::String::NewFromUtf8(isolate, obj->name.c_str(), v8::NewStringType::kInternalized).ToLocalChecked());
351
-
352
- // Add value - get from the object's value property
353
- // Use a TryCatch to handle errors when getting the value
317
+
318
+ (void)json->CreateDataProperty(
319
+ context, name_str,
320
+ v8::String::NewFromUtf8(isolate, obj->name.c_str(), v8::NewStringType::kInternalized).ToLocalChecked());
321
+
354
322
  v8::TryCatch try_catch(isolate);
355
323
  v8::MaybeLocal<v8::Value> maybeValue = args.Holder()->Get(context, value_str);
356
324
  v8::Local<v8::Value> value;
357
-
325
+
358
326
  if (!maybeValue.ToLocal(&value) || try_catch.HasCaught())
359
327
  {
360
- // If getting the value failed or threw an exception, clear the exception
361
- // and set value to null instead of crashing
362
328
  if (try_catch.HasCaught())
363
- {
364
329
  try_catch.Reset();
365
- }
366
330
  value = v8::Null(isolate);
367
331
  }
368
332
  else if (value->IsTypedArray())
369
333
  {
370
- // Convert TypedArray to regular array for JSON serialization
371
334
  v8::Local<v8::TypedArray> typedArray = v8::Local<v8::TypedArray>::Cast(value);
372
335
  uint32_t length = typedArray->Length();
373
336
  v8::Local<v8::Array> array = v8::Array::New(isolate, length);
374
-
337
+
375
338
  for (uint32_t i = 0; i < length; i++)
376
339
  {
377
340
  v8::Local<v8::Value> element = typedArray->Get(context, i).ToLocalChecked();
@@ -379,10 +342,9 @@ void Attribute::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
379
342
  }
380
343
  value = array;
381
344
  }
382
- // Don't wrap primitives - only convert TypedArrays to arrays
383
-
345
+
384
346
  (void)json->CreateDataProperty(context, value_str, value);
385
-
347
+
386
348
  args.GetReturnValue().Set(json);
387
349
  }
388
350
  } // namespace nodenetcdfjs
package/src/Attribute.h CHANGED
@@ -8,13 +8,56 @@
8
8
  namespace nodenetcdfjs
9
9
  {
10
10
 
11
+ /**
12
+ * @brief Represents a NetCDF attribute wrapper for Node.js
13
+ *
14
+ * This class provides a Node.js interface to NetCDF attributes, which are metadata
15
+ * associated with variables or groups. Attributes can store information such as
16
+ * units, descriptions, valid ranges, and other metadata about the data.
17
+ *
18
+ * The class extends node::ObjectWrap to provide JavaScript binding capabilities,
19
+ * allowing attributes to be manipulated from JavaScript code.
20
+ */
11
21
  class Attribute : public node::ObjectWrap
12
22
  {
13
23
  public:
24
+ /**
25
+ * @brief Initialize the Attribute class and register it with Node.js
26
+ * @param exports The exports object to attach the Attribute constructor to
27
+ *
28
+ * This static method sets up the Attribute class for use in Node.js,
29
+ * defining its constructor and prototype methods.
30
+ */
14
31
  static void Init(v8::Local<v8::Object> exports);
32
+
33
+ /**
34
+ * @brief Construct an Attribute object
35
+ * @param name_ The name of the attribute
36
+ * @param var_id_ The variable ID this attribute belongs to
37
+ * @param parent_id_ The parent group/file ID
38
+ *
39
+ * Creates a new attribute with the specified name and parent identifiers.
40
+ */
15
41
  Attribute(const char *name_, int var_id_, int parent_id_) noexcept;
42
+
43
+ /**
44
+ * @brief Construct an Attribute object with explicit type
45
+ * @param name_ The name of the attribute
46
+ * @param var_id_ The variable ID this attribute belongs to
47
+ * @param parent_id_ The parent group/file ID
48
+ * @param type_ The NetCDF data type of the attribute
49
+ *
50
+ * Creates a new attribute with the specified name, parent identifiers, and data type.
51
+ */
16
52
  Attribute(const char *name_, int var_id_, int parent_id_, int type_) noexcept;
17
53
 
54
+ /**
55
+ * @brief Set the value of the attribute
56
+ * @param val The value to set (as a V8 value from JavaScript)
57
+ *
58
+ * Sets the attribute's value from a JavaScript value, performing appropriate
59
+ * type conversions as needed.
60
+ */
18
61
  void set_value(const v8::Local<v8::Value> &val);
19
62
 
20
63
  private:
@@ -24,21 +67,69 @@ class Attribute : public node::ObjectWrap
24
67
  Attribute(Attribute &&) = delete;
25
68
  Attribute &operator=(Attribute &&) = delete;
26
69
 
70
+ /// Persistent reference to the JavaScript constructor function
27
71
  static v8::Persistent<v8::Function> constructor;
28
72
 
73
+ /**
74
+ * @brief Delete this attribute from the NetCDF file
75
+ * @param args JavaScript function arguments
76
+ */
29
77
  static void Delete(const v8::FunctionCallbackInfo<v8::Value> &args);
78
+
79
+ /**
80
+ * @brief Getter for the attribute name property
81
+ * @param property The property name being accessed
82
+ * @param info Callback info containing the return value
83
+ */
30
84
  static void GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
85
+
86
+ /**
87
+ * @brief Setter for the attribute name property
88
+ * @param property The property name being set
89
+ * @param val The new value to set
90
+ * @param info Callback info for the setter
91
+ */
31
92
  static void SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
32
93
  const v8::PropertyCallbackInfo<void> &info);
94
+
95
+ /**
96
+ * @brief Getter for the attribute value property
97
+ * @param property The property name being accessed
98
+ * @param info Callback info containing the return value
99
+ */
33
100
  static void GetValue(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
101
+
102
+ /**
103
+ * @brief Setter for the attribute value property
104
+ * @param property The property name being set
105
+ * @param val The new value to set
106
+ * @param info Callback info for the setter
107
+ */
34
108
  static void SetValue(v8::Local<v8::String> property, v8::Local<v8::Value> val,
35
109
  const v8::PropertyCallbackInfo<void> &info);
110
+
111
+ /**
112
+ * @brief Custom inspect method for Node.js console output
113
+ * @param args JavaScript function arguments
114
+ */
36
115
  static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
116
+
117
+ /**
118
+ * @brief Convert attribute to JSON representation
119
+ * @param args JavaScript function arguments
120
+ */
37
121
  static void ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args);
38
122
 
123
+ /// The name of the attribute
39
124
  std::string name{};
125
+
126
+ /// The variable ID this attribute belongs to (-1 for global attributes)
40
127
  int var_id{-1};
128
+
129
+ /// The parent group/file ID
41
130
  int parent_id{-1};
131
+
132
+ /// The NetCDF data type of the attribute
42
133
  int type{-1};
43
134
  };
44
135
 
package/src/Dimension.cpp CHANGED
@@ -2,7 +2,6 @@
2
2
  #include "nodenetcdfjs.h"
3
3
  #include <netcdf.h>
4
4
 
5
-
6
5
  namespace nodenetcdfjs
7
6
  {
8
7
 
@@ -92,9 +91,7 @@ void Dimension::SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val
92
91
  const int retval = nc_rename_dim(obj->parent_id, obj->id, *new_name_);
93
92
 
94
93
  if (retval != NC_NOERR)
95
- {
96
94
  throw_netcdf_error(isolate, retval);
97
- }
98
95
  }
99
96
 
100
97
  void Dimension::Inspect(const v8::FunctionCallbackInfo<v8::Value> &args)
@@ -109,33 +106,26 @@ void Dimension::ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args)
109
106
  v8::Isolate *isolate = args.GetIsolate();
110
107
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
111
108
  const auto *obj = node::ObjectWrap::Unwrap<Dimension>(args.Holder());
112
-
113
- // Use internalized strings for better performance
109
+
114
110
  v8::Local<v8::String> id_str = v8::String::NewFromUtf8Literal(isolate, "id");
115
111
  v8::Local<v8::String> name_str = v8::String::NewFromUtf8Literal(isolate, "name");
116
112
  v8::Local<v8::String> length_str = v8::String::NewFromUtf8Literal(isolate, "length");
117
-
113
+
118
114
  v8::Local<v8::Object> json = v8::Object::New(isolate);
119
-
120
- // Add id
115
+
121
116
  (void)json->CreateDataProperty(context, id_str, v8::Integer::New(isolate, obj->id));
122
-
123
- // Add name
117
+
124
118
  std::array<char, NC_MAX_NAME + 1> name{};
125
119
  if (obj->get_name(name.data()))
126
- {
127
- (void)json->CreateDataProperty(context, name_str,
128
- v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked());
129
- }
130
-
131
- // Add length
120
+ (void)json->CreateDataProperty(
121
+ context, name_str,
122
+ v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kInternalized).ToLocalChecked());
123
+
132
124
  size_t len = 0;
133
125
  const int retval = nc_inq_dimlen(obj->parent_id, obj->id, &len);
134
126
  if (retval == NC_NOERR)
135
- {
136
127
  (void)json->CreateDataProperty(context, length_str, v8::Integer::New(isolate, static_cast<int32_t>(len)));
137
- }
138
-
128
+
139
129
  args.GetReturnValue().Set(json);
140
130
  }
141
131
  } // namespace nodenetcdfjs
package/src/Dimension.h CHANGED
@@ -7,12 +7,45 @@
7
7
  namespace nodenetcdfjs
8
8
  {
9
9
 
10
+ /**
11
+ * @brief Represents a NetCDF dimension wrapper for Node.js
12
+ *
13
+ * This class provides a Node.js interface to NetCDF dimensions, which define
14
+ * the shape and size of variables in a NetCDF file. Dimensions can be either
15
+ * fixed-length or unlimited (allowing growth over time).
16
+ *
17
+ * The class extends node::ObjectWrap to provide JavaScript binding capabilities,
18
+ * allowing dimensions to be queried and manipulated from JavaScript code.
19
+ */
10
20
  class Dimension : public node::ObjectWrap
11
21
  {
12
22
  public:
23
+ /**
24
+ * @brief Initialize the Dimension class and register it with Node.js
25
+ * @param exports The exports object to attach the Dimension constructor to
26
+ *
27
+ * This static method sets up the Dimension class for use in Node.js,
28
+ * defining its constructor and prototype methods.
29
+ */
13
30
  static void Init(v8::Local<v8::Object> exports);
31
+
32
+ /**
33
+ * @brief Construct a Dimension object
34
+ * @param id_ The dimension ID in the NetCDF file
35
+ * @param parent_id_ The parent group/file ID
36
+ *
37
+ * Creates a new dimension wrapper for an existing NetCDF dimension.
38
+ */
14
39
  Dimension(int id_, int parent_id_) noexcept;
15
40
 
41
+ /**
42
+ * @brief Get the name of this dimension
43
+ * @param name Buffer to store the dimension name
44
+ * @return true if successful, false otherwise
45
+ *
46
+ * Retrieves the dimension name from the NetCDF file and stores it
47
+ * in the provided buffer.
48
+ */
16
49
  [[nodiscard]] bool get_name(char *name) const noexcept;
17
50
 
18
51
  private:
@@ -22,17 +55,55 @@ class Dimension : public node::ObjectWrap
22
55
  Dimension(Dimension &&) = delete;
23
56
  Dimension &operator=(Dimension &&) = delete;
24
57
 
58
+ /// Persistent reference to the JavaScript constructor function
25
59
  static v8::Persistent<v8::Function> constructor;
26
60
 
61
+ /**
62
+ * @brief Getter for the dimension ID property
63
+ * @param property The property name being accessed
64
+ * @param info Callback info containing the return value
65
+ */
27
66
  static void GetId(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
67
+
68
+ /**
69
+ * @brief Getter for the dimension length property
70
+ * @param property The property name being accessed
71
+ * @param info Callback info containing the return value
72
+ */
28
73
  static void GetLength(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
74
+
75
+ /**
76
+ * @brief Getter for the dimension name property
77
+ * @param property The property name being accessed
78
+ * @param info Callback info containing the return value
79
+ */
29
80
  static void GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
81
+
82
+ /**
83
+ * @brief Setter for the dimension name property
84
+ * @param property The property name being set
85
+ * @param val The new value to set
86
+ * @param info Callback info for the setter
87
+ */
30
88
  static void SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
31
89
  const v8::PropertyCallbackInfo<void> &info);
90
+
91
+ /**
92
+ * @brief Custom inspect method for Node.js console output
93
+ * @param args JavaScript function arguments
94
+ */
32
95
  static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
96
+
97
+ /**
98
+ * @brief Convert dimension to JSON representation
99
+ * @param args JavaScript function arguments
100
+ */
33
101
  static void ToJSON(const v8::FunctionCallbackInfo<v8::Value> &args);
34
102
 
103
+ /// The dimension ID in the NetCDF file
35
104
  int id{-1};
105
+
106
+ /// The parent group/file ID
36
107
  int parent_id{-1};
37
108
  };
38
109
 
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,12 +149,27 @@ 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
- // Get the root group and serialize it
178
- v8::Local<v8::String> rootProp = v8::String::NewFromUtf8(isolate, "root", v8::NewStringType::kNormal).ToLocalChecked();
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
- // The root group's toJSON will automatically serialize all children recursively
156
+
157
+ if (root->IsObject())
158
+ {
159
+ v8::Local<v8::Object> rootObj = root->ToObject(context).ToLocalChecked();
160
+ v8::Local<v8::String> toJSONProp =
161
+ v8::String::NewFromUtf8(isolate, "toJSON", v8::NewStringType::kNormal).ToLocalChecked();
162
+ v8::Local<v8::Value> toJSONMethod = rootObj->Get(context, toJSONProp).ToLocalChecked();
163
+
164
+ if (toJSONMethod->IsFunction())
165
+ {
166
+ v8::Local<v8::Function> toJSONFunc = v8::Local<v8::Function>::Cast(toJSONMethod);
167
+ v8::Local<v8::Value> result = toJSONFunc->Call(context, rootObj, 0, nullptr).ToLocalChecked();
168
+ args.GetReturnValue().Set(result);
169
+ return;
170
+ }
171
+ }
172
+
182
173
  args.GetReturnValue().Set(root);
183
174
  }
184
175
  } // namespace nodenetcdfjs