nodenetcdf 4.9.3

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.
@@ -0,0 +1,93 @@
1
+ const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ // Allow users to skip vcpkg setup if they prefer system libraries
7
+ if (process.env.SKIP_VCPKG_SETUP === '1') {
8
+ console.log('SKIP_VCPKG_SETUP is set, skipping vcpkg setup');
9
+ console.log('Make sure NetCDF libraries are installed on your system');
10
+ process.exit(0);
11
+ }
12
+
13
+ const platform = os.platform();
14
+
15
+ console.log('Setting up vcpkg and NetCDF dependencies...');
16
+
17
+ // Determine vcpkg triplet based on platform
18
+ let triplet;
19
+ if (platform === 'win32') {
20
+ triplet = 'x64-windows';
21
+ } else if (platform === 'linux') {
22
+ triplet = 'x64-linux';
23
+ } else if (platform === 'darwin') {
24
+ triplet = 'arm64-osx';
25
+ } else {
26
+ console.error(`Unsupported platform: ${platform}`);
27
+ process.exit(1);
28
+ }
29
+
30
+ function runCommand(cmd, options = {}) {
31
+ console.log(`Running: ${cmd}`);
32
+ try {
33
+ execSync(cmd, {
34
+ stdio: 'inherit',
35
+ ...options
36
+ });
37
+ } catch (error) {
38
+ console.error(`Failed to run command: ${cmd}`);
39
+ throw error;
40
+ }
41
+ }
42
+
43
+ // Check if vcpkg directory exists
44
+ if (!fs.existsSync('vcpkg')) {
45
+ console.log('vcpkg not found, cloning repository...');
46
+ runCommand('git clone https://github.com/microsoft/vcpkg.git');
47
+ } else {
48
+ console.log('vcpkg directory already exists');
49
+ }
50
+
51
+ // Bootstrap vcpkg
52
+ const vcpkgExecutable = platform === 'win32' ? 'vcpkg.exe' : 'vcpkg';
53
+ const vcpkgPath = path.join('vcpkg', vcpkgExecutable);
54
+
55
+ if (!fs.existsSync(vcpkgPath)) {
56
+ console.log('Bootstrapping vcpkg...');
57
+ if (platform === 'win32') {
58
+ runCommand('.\\vcpkg\\bootstrap-vcpkg.bat', { shell: true });
59
+ } else {
60
+ runCommand('./vcpkg/bootstrap-vcpkg.sh', { shell: true });
61
+ }
62
+ } else {
63
+ console.log('vcpkg already bootstrapped');
64
+ }
65
+
66
+ // Install nodenetcdf using vcpkg
67
+ console.log(`Installing netcdf-c for ${triplet}...`);
68
+ try {
69
+ runCommand(`${vcpkgPath} install netcdf-c:${triplet}`);
70
+ console.log('NetCDF dependencies installed successfully!');
71
+ } catch (error) {
72
+ console.error('Failed to install netcdf-c');
73
+ console.error('You may need to install build tools for your platform:');
74
+ console.error('- Windows: Visual Studio Build Tools');
75
+ console.error('- Linux: build-essential, cmake');
76
+ console.error('- macOS: Xcode Command Line Tools');
77
+ process.exit(1);
78
+ }
79
+
80
+ console.log('vcpkg setup complete!');
81
+
82
+ // Verify that netcdf.h is actually available
83
+ const vcpkgInstalledDir = path.join('vcpkg', 'installed', triplet);
84
+ const includeDir = path.join(vcpkgInstalledDir, 'include');
85
+ const netcdfHeader = path.join(includeDir, 'netcdf.h');
86
+
87
+ if (fs.existsSync(netcdfHeader)) {
88
+ console.log(`✓ Verified netcdf.h exists at: ${netcdfHeader}`);
89
+ } else {
90
+ console.error(`✗ ERROR: netcdf.h not found at: ${netcdfHeader}`);
91
+ console.error('vcpkg installation may have failed or be incomplete');
92
+ process.exit(1);
93
+ }
@@ -0,0 +1,61 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ // Determine the platform-specific vcpkg directory
6
+ const platform = os.platform();
7
+ let triplet;
8
+
9
+ if (platform === 'win32') {
10
+ triplet = 'x64-windows';
11
+ } else if (platform === 'linux') {
12
+ triplet = 'x64-linux';
13
+ } else if (platform === 'darwin') {
14
+ triplet = 'arm64-osx';
15
+ } else {
16
+ console.error(`Unsupported platform: ${platform}`);
17
+ process.exit(1);
18
+ }
19
+
20
+ console.log('Verifying build dependencies...');
21
+
22
+ // Check if vcpkg installed directory exists
23
+ const vcpkgInstalledDir = path.join('vcpkg', 'installed', triplet);
24
+ if (!fs.existsSync(vcpkgInstalledDir)) {
25
+ console.error(`✗ ERROR: vcpkg installation directory not found: ${vcpkgInstalledDir}`);
26
+ console.error('Please run: npm run preinstall');
27
+ process.exit(1);
28
+ }
29
+
30
+ // Verify netcdf.h exists
31
+ const includeDir = path.join(vcpkgInstalledDir, 'include');
32
+ const netcdfHeader = path.join(includeDir, 'netcdf.h');
33
+
34
+ if (!fs.existsSync(netcdfHeader)) {
35
+ console.error(`✗ ERROR: netcdf.h not found at: ${netcdfHeader}`);
36
+ console.error('vcpkg installation may be incomplete');
37
+ console.error('Please run: npm run preinstall');
38
+ process.exit(1);
39
+ }
40
+
41
+ console.log(`✓ Found netcdf.h at: ${netcdfHeader}`);
42
+
43
+ // Verify library files exist
44
+ const libDir = path.join(vcpkgInstalledDir, 'lib');
45
+ let requiredLib;
46
+
47
+ if (platform === 'win32') {
48
+ requiredLib = path.join(libDir, 'netcdf.lib');
49
+ } else {
50
+ requiredLib = path.join(libDir, 'libnetcdf.a');
51
+ }
52
+
53
+ if (!fs.existsSync(requiredLib)) {
54
+ console.error(`✗ ERROR: NetCDF library not found at: ${requiredLib}`);
55
+ console.error('vcpkg installation may be incomplete');
56
+ console.error('Please run: npm run preinstall');
57
+ process.exit(1);
58
+ }
59
+
60
+ console.log(`✓ Found NetCDF library at: ${requiredLib}`);
61
+ console.log(`✓ Build dependencies verified for ${triplet}`);
@@ -0,0 +1,334 @@
1
+ #include "Attribute.h"
2
+ #include "nodenetcdfjs.h"
3
+ #include <inttypes.h>
4
+ #include <iostream>
5
+ #include <netcdf.h>
6
+
7
+
8
+ namespace nodenetcdfjs
9
+ {
10
+
11
+ v8::Persistent<v8::Function> Attribute::constructor;
12
+
13
+ Attribute::Attribute(const char *name_, int var_id_, int parent_id_) noexcept
14
+ : name(name_)
15
+ , var_id(var_id_)
16
+ , parent_id(parent_id_)
17
+ {
18
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
19
+ v8::Local<v8::Object> obj =
20
+ v8::Local<v8::Function>::New(isolate, constructor)->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
21
+ Wrap(obj);
22
+ const int retval = nc_inq_atttype(parent_id, var_id_, name_, &type);
23
+ if (retval != NC_NOERR)
24
+ {
25
+ throw_netcdf_error(isolate, retval);
26
+ }
27
+ }
28
+
29
+ Attribute::Attribute(const char *name_, int var_id_, int parent_id_, int type_) noexcept
30
+ : name(name_)
31
+ , var_id(var_id_)
32
+ , parent_id(parent_id_)
33
+ , type(type_)
34
+ {
35
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
36
+ v8::Local<v8::Object> obj =
37
+ v8::Local<v8::Function>::New(isolate, constructor)->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
38
+ Wrap(obj);
39
+ }
40
+
41
+ void Attribute::Init(v8::Local<v8::Object> exports)
42
+ {
43
+ v8::Isolate *isolate = exports->GetIsolate();
44
+ v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(isolate);
45
+ tpl->SetClassName(v8::String::NewFromUtf8(isolate, "Attribute", v8::NewStringType::kNormal).ToLocalChecked());
46
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
47
+ NODE_SET_PROTOTYPE_METHOD(tpl, "delete", Attribute::Delete);
48
+ NODE_SET_PROTOTYPE_METHOD(tpl, "inspect", Attribute::Inspect);
49
+ tpl->InstanceTemplate()->SetAccessor(
50
+ v8::String::NewFromUtf8(isolate, "name", v8::NewStringType::kNormal).ToLocalChecked(), Attribute::GetName,
51
+ Attribute::SetName);
52
+ tpl->InstanceTemplate()->SetAccessor(
53
+ v8::String::NewFromUtf8(isolate, "value", v8::NewStringType::kNormal).ToLocalChecked(), Attribute::GetValue,
54
+ Attribute::SetValue);
55
+ constructor.Reset(isolate, tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
56
+ }
57
+
58
+ void Attribute::GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
59
+ {
60
+ v8::Isolate *isolate = info.GetIsolate();
61
+ const auto *obj = node::ObjectWrap::Unwrap<Attribute>(info.Holder());
62
+ info.GetReturnValue().Set(
63
+ v8::String::NewFromUtf8(isolate, obj->name.c_str(), v8::NewStringType::kNormal).ToLocalChecked());
64
+ }
65
+
66
+ void Attribute::SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
67
+ const v8::PropertyCallbackInfo<void> &info)
68
+ {
69
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
70
+ auto *obj = node::ObjectWrap::Unwrap<Attribute>(info.Holder());
71
+
72
+ const v8::String::Utf8Value new_name_(isolate, val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
73
+ const int retval = nc_rename_att(obj->parent_id, obj->var_id, obj->name.c_str(), *new_name_);
74
+
75
+ if (retval != NC_NOERR)
76
+ {
77
+ throw_netcdf_error(isolate, retval);
78
+ return;
79
+ }
80
+ obj->name = *new_name_;
81
+ }
82
+
83
+ void Attribute::GetValue(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
84
+ {
85
+ v8::Isolate *isolate = info.GetIsolate();
86
+ const auto *obj = node::ObjectWrap::Unwrap<Attribute>(info.Holder());
87
+
88
+ if ((obj->type < NC_BYTE || obj->type > NC_UINT64) && obj->type != NC_STRING)
89
+ {
90
+ isolate->ThrowException(v8::Exception::TypeError(
91
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
92
+ .ToLocalChecked()));
93
+ return;
94
+ }
95
+
96
+ size_t len = 0;
97
+ int retval = nc_inq_attlen(obj->parent_id, obj->var_id, obj->name.c_str(), &len);
98
+ if (retval != NC_NOERR)
99
+ {
100
+ throw_netcdf_error(isolate, retval);
101
+ return;
102
+ }
103
+
104
+ switch (obj->type)
105
+ {
106
+ case NC_BYTE: {
107
+ std::vector<int8_t> v(len);
108
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
109
+ if (len == 1)
110
+ {
111
+ info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
112
+ }
113
+ else
114
+ {
115
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int8_t));
116
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(int8_t));
117
+ info.GetReturnValue().Set(v8::Int8Array::New(buffer, 0, len));
118
+ }
119
+ }
120
+ break;
121
+ case NC_SHORT: {
122
+ std::vector<int16_t> v(len);
123
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
124
+ if (len == 1)
125
+ {
126
+ info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
127
+ }
128
+ else
129
+ {
130
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int16_t));
131
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(int16_t));
132
+ info.GetReturnValue().Set(v8::Int16Array::New(buffer, 0, len));
133
+ }
134
+ }
135
+ break;
136
+ case NC_INT: {
137
+ std::vector<int32_t> v(len);
138
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
139
+ if (len == 1)
140
+ {
141
+ info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
142
+ }
143
+ else
144
+ {
145
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int32_t));
146
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(int32_t));
147
+ info.GetReturnValue().Set(v8::Int32Array::New(buffer, 0, len));
148
+ }
149
+ }
150
+ break;
151
+ case NC_FLOAT: {
152
+ std::vector<float> v(len);
153
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
154
+ if (len == 1)
155
+ {
156
+ info.GetReturnValue().Set(v8::Number::New(isolate, v[0]));
157
+ }
158
+ else
159
+ {
160
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(float));
161
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(float));
162
+ info.GetReturnValue().Set(v8::Float32Array::New(buffer, 0, len));
163
+ }
164
+ }
165
+ break;
166
+ case NC_DOUBLE: {
167
+ std::vector<double> v(len);
168
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
169
+ if (len == 1)
170
+ {
171
+ info.GetReturnValue().Set(v8::Number::New(isolate, v[0]));
172
+ }
173
+ else
174
+ {
175
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(double));
176
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(double));
177
+ info.GetReturnValue().Set(v8::Float64Array::New(buffer, 0, len));
178
+ }
179
+ }
180
+ break;
181
+ case NC_UBYTE: {
182
+ std::vector<uint8_t> v(len);
183
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
184
+ if (len == 1)
185
+ {
186
+ info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
187
+ }
188
+ else
189
+ {
190
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint8_t));
191
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(uint8_t));
192
+ info.GetReturnValue().Set(v8::Uint8Array::New(buffer, 0, len));
193
+ }
194
+ }
195
+ break;
196
+ case NC_USHORT: {
197
+ std::vector<uint16_t> v(len);
198
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
199
+ if (len == 1)
200
+ {
201
+ info.GetReturnValue().Set(v8::Integer::New(isolate, v[0]));
202
+ }
203
+ else
204
+ {
205
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint16_t));
206
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(uint16_t));
207
+ info.GetReturnValue().Set(v8::Uint16Array::New(buffer, 0, len));
208
+ }
209
+ }
210
+ break;
211
+ case NC_UINT: {
212
+ std::vector<uint32_t> v(len);
213
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
214
+ if (len == 1)
215
+ {
216
+ info.GetReturnValue().Set(v8::Integer::NewFromUnsigned(isolate, v[0]));
217
+ }
218
+ else
219
+ {
220
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint32_t));
221
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(uint32_t));
222
+ info.GetReturnValue().Set(v8::Uint32Array::New(buffer, 0, len));
223
+ }
224
+ }
225
+ break;
226
+ case NC_INT64: {
227
+ std::vector<int64_t> v(len);
228
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
229
+ if (len == 1)
230
+ {
231
+ info.GetReturnValue().Set(v8::Integer::New(isolate, static_cast<int32_t>(v[0])));
232
+ }
233
+ else
234
+ {
235
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(int64_t));
236
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(int64_t));
237
+ info.GetReturnValue().Set(v8::Int32Array::New(buffer, 0, len));
238
+ }
239
+ }
240
+ break;
241
+ case NC_UINT64: {
242
+ std::vector<uint64_t> v(len);
243
+ retval = nc_get_att(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
244
+ if (len == 1)
245
+ {
246
+ info.GetReturnValue().Set(v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(v[0])));
247
+ }
248
+ else
249
+ {
250
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, len * sizeof(uint64_t));
251
+ memcpy(buffer->GetBackingStore()->Data(), v.data(), len * sizeof(uint64_t));
252
+ info.GetReturnValue().Set(v8::Uint32Array::New(buffer, 0, len));
253
+ }
254
+ }
255
+ break;
256
+ case NC_CHAR:
257
+ case NC_STRING: {
258
+ std::vector<char> v(len + 1, '\0');
259
+ retval = nc_get_att_text(obj->parent_id, obj->var_id, obj->name.c_str(), v.data());
260
+ info.GetReturnValue().Set(
261
+ v8::String::NewFromUtf8(isolate, v.data(), v8::NewStringType::kNormal).ToLocalChecked());
262
+ }
263
+ break;
264
+ }
265
+ if (retval != NC_NOERR)
266
+ {
267
+ throw_netcdf_error(isolate, retval);
268
+ }
269
+ }
270
+
271
+ void Attribute::SetValue(v8::Local<v8::String> property, v8::Local<v8::Value> val,
272
+ const v8::PropertyCallbackInfo<void> &info)
273
+ {
274
+ auto *obj = node::ObjectWrap::Unwrap<Attribute>(info.Holder());
275
+ obj->set_value(val);
276
+ }
277
+
278
+ void Attribute::set_value(const v8::Local<v8::Value> &val)
279
+ {
280
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
281
+ if ((type < NC_BYTE || type > NC_UINT) && type != NC_STRING)
282
+ {
283
+ isolate->ThrowException(v8::Exception::TypeError(
284
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
285
+ .ToLocalChecked()));
286
+ return;
287
+ }
288
+
289
+ int retval = NC_NOERR;
290
+ if (val->IsUint32())
291
+ {
292
+ const uint32_t v = val->Uint32Value(isolate->GetCurrentContext()).ToChecked();
293
+ retval = nc_put_att(parent_id, var_id, name.c_str(), NC_UINT, 1, &v);
294
+ }
295
+ else if (val->IsInt32())
296
+ {
297
+ const int32_t v = val->Int32Value(isolate->GetCurrentContext()).ToChecked();
298
+ retval = nc_put_att(parent_id, var_id, name.c_str(), NC_INT, 1, &v);
299
+ }
300
+ else if (val->IsNumber())
301
+ {
302
+ const double v = val->NumberValue(isolate->GetCurrentContext()).ToChecked();
303
+ retval = nc_put_att(parent_id, var_id, name.c_str(), NC_DOUBLE, 1, &v);
304
+ }
305
+ else
306
+ {
307
+ const std::string v =
308
+ *v8::String::Utf8Value(isolate, val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
309
+ retval = nc_put_att_text(parent_id, var_id, name.c_str(), v.length(), v.c_str());
310
+ }
311
+
312
+ if (retval != NC_NOERR)
313
+ {
314
+ throw_netcdf_error(isolate, retval);
315
+ }
316
+ }
317
+
318
+ void Attribute::Delete(const v8::FunctionCallbackInfo<v8::Value> &args)
319
+ {
320
+ auto *obj = node::ObjectWrap::Unwrap<Attribute>(args.Holder());
321
+ const int retval = nc_del_att(obj->parent_id, obj->var_id, obj->name.c_str());
322
+ if (retval != NC_NOERR)
323
+ {
324
+ throw_netcdf_error(args.GetIsolate(), retval);
325
+ }
326
+ }
327
+
328
+ void Attribute::Inspect(const v8::FunctionCallbackInfo<v8::Value> &args)
329
+ {
330
+ v8::Isolate *isolate = args.GetIsolate();
331
+ args.GetReturnValue().Set(
332
+ v8::String::NewFromUtf8(isolate, "[object Attribute]", v8::NewStringType::kNormal).ToLocalChecked());
333
+ }
334
+ } // namespace nodenetcdfjs
@@ -0,0 +1,46 @@
1
+ #ifndef NODENETCDFJS_ATTRIBUTE_H
2
+ #define NODENETCDFJS_ATTRIBUTE_H
3
+
4
+ #include <node.h>
5
+ #include <node_object_wrap.h>
6
+ #include <string>
7
+
8
+ namespace nodenetcdfjs
9
+ {
10
+
11
+ class Attribute : public node::ObjectWrap
12
+ {
13
+ public:
14
+ static void Init(v8::Local<v8::Object> exports);
15
+ Attribute(const char *name_, int var_id_, int parent_id_) noexcept;
16
+ Attribute(const char *name_, int var_id_, int parent_id_, int type_) noexcept;
17
+
18
+ void set_value(const v8::Local<v8::Value> &val);
19
+
20
+ private:
21
+ // Delete copy and move operations for safety
22
+ Attribute(const Attribute &) = delete;
23
+ Attribute &operator=(const Attribute &) = delete;
24
+ Attribute(Attribute &&) = delete;
25
+ Attribute &operator=(Attribute &&) = delete;
26
+
27
+ static v8::Persistent<v8::Function> constructor;
28
+
29
+ static void Delete(const v8::FunctionCallbackInfo<v8::Value> &args);
30
+ static void GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
31
+ static void SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
32
+ const v8::PropertyCallbackInfo<void> &info);
33
+ static void GetValue(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
34
+ static void SetValue(v8::Local<v8::String> property, v8::Local<v8::Value> val,
35
+ const v8::PropertyCallbackInfo<void> &info);
36
+ static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
37
+
38
+ std::string name{};
39
+ int var_id{-1};
40
+ int parent_id{-1};
41
+ int type{-1};
42
+ };
43
+
44
+ } // namespace nodenetcdfjs
45
+
46
+ #endif
@@ -0,0 +1,105 @@
1
+ #include "Dimension.h"
2
+ #include "nodenetcdfjs.h"
3
+ #include <netcdf.h>
4
+
5
+
6
+ namespace nodenetcdfjs
7
+ {
8
+
9
+ v8::Persistent<v8::Function> Dimension::constructor;
10
+
11
+ Dimension::Dimension(int id_, int parent_id_) noexcept
12
+ : id(id_)
13
+ , parent_id(parent_id_)
14
+ {
15
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
16
+ v8::Local<v8::Object> obj =
17
+ v8::Local<v8::Function>::New(isolate, constructor)->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
18
+ Wrap(obj);
19
+ }
20
+
21
+ void Dimension::Init(v8::Local<v8::Object> exports)
22
+ {
23
+ v8::Isolate *isolate = exports->GetIsolate();
24
+ v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(isolate);
25
+ tpl->SetClassName(v8::String::NewFromUtf8(isolate, "Dimension", v8::NewStringType::kNormal).ToLocalChecked());
26
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
27
+ NODE_SET_PROTOTYPE_METHOD(tpl, "inspect", Dimension::Inspect);
28
+ tpl->InstanceTemplate()->SetAccessor(
29
+ v8::String::NewFromUtf8(isolate, "id", v8::NewStringType::kNormal).ToLocalChecked(), Dimension::GetId);
30
+ tpl->InstanceTemplate()->SetAccessor(
31
+ v8::String::NewFromUtf8(isolate, "length", v8::NewStringType::kNormal).ToLocalChecked(), Dimension::GetLength);
32
+ tpl->InstanceTemplate()->SetAccessor(
33
+ v8::String::NewFromUtf8(isolate, "name", v8::NewStringType::kNormal).ToLocalChecked(), Dimension::GetName,
34
+ Dimension::SetName);
35
+ constructor.Reset(isolate, tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
36
+ }
37
+
38
+ bool Dimension::get_name(char *name) const noexcept
39
+ {
40
+ const int retval = nc_inq_dimname(parent_id, id, name);
41
+ if (retval != NC_NOERR)
42
+ {
43
+ throw_netcdf_error(v8::Isolate::GetCurrent(), retval);
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+
49
+ void Dimension::GetId(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
50
+ {
51
+ v8::Isolate *isolate = info.GetIsolate();
52
+ const auto *obj = node::ObjectWrap::Unwrap<Dimension>(info.Holder());
53
+ info.GetReturnValue().Set(v8::Integer::New(isolate, obj->id));
54
+ }
55
+
56
+ void Dimension::GetLength(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
57
+ {
58
+ v8::Isolate *isolate = info.GetIsolate();
59
+ const auto *obj = node::ObjectWrap::Unwrap<Dimension>(info.Holder());
60
+
61
+ size_t len = 0;
62
+ const int retval = nc_inq_dimlen(obj->parent_id, obj->id, &len);
63
+ if (retval != NC_NOERR)
64
+ {
65
+ throw_netcdf_error(isolate, retval);
66
+ return;
67
+ }
68
+ info.GetReturnValue().Set(v8::Integer::New(isolate, static_cast<int32_t>(len)));
69
+ }
70
+
71
+ void Dimension::GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
72
+ {
73
+ v8::Isolate *isolate = info.GetIsolate();
74
+ const auto *obj = node::ObjectWrap::Unwrap<Dimension>(info.Holder());
75
+
76
+ std::array<char, NC_MAX_NAME + 1> name{};
77
+ if (obj->get_name(name.data()))
78
+ {
79
+ info.GetReturnValue().Set(
80
+ v8::String::NewFromUtf8(isolate, name.data(), v8::NewStringType::kNormal).ToLocalChecked());
81
+ }
82
+ }
83
+
84
+ void Dimension::SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
85
+ const v8::PropertyCallbackInfo<void> &info)
86
+ {
87
+ v8::Isolate *isolate = info.GetIsolate();
88
+ auto *obj = node::ObjectWrap::Unwrap<Dimension>(info.Holder());
89
+
90
+ const v8::String::Utf8Value new_name_(isolate, val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
91
+ const int retval = nc_rename_dim(obj->parent_id, obj->id, *new_name_);
92
+
93
+ if (retval != NC_NOERR)
94
+ {
95
+ throw_netcdf_error(isolate, retval);
96
+ }
97
+ }
98
+
99
+ void Dimension::Inspect(const v8::FunctionCallbackInfo<v8::Value> &args)
100
+ {
101
+ v8::Isolate *isolate = args.GetIsolate();
102
+ args.GetReturnValue().Set(
103
+ v8::String::NewFromUtf8(isolate, "[object Dimension]", v8::NewStringType::kNormal).ToLocalChecked());
104
+ }
105
+ } // namespace nodenetcdfjs
@@ -0,0 +1,40 @@
1
+ #ifndef NODENETCDFJS_DIMENSION_H
2
+ #define NODENETCDFJS_DIMENSION_H
3
+
4
+ #include <node.h>
5
+ #include <node_object_wrap.h>
6
+
7
+ namespace nodenetcdfjs
8
+ {
9
+
10
+ class Dimension : public node::ObjectWrap
11
+ {
12
+ public:
13
+ static void Init(v8::Local<v8::Object> exports);
14
+ Dimension(int id_, int parent_id_) noexcept;
15
+
16
+ [[nodiscard]] bool get_name(char *name) const noexcept;
17
+
18
+ private:
19
+ // Delete copy and move operations for safety
20
+ Dimension(const Dimension &) = delete;
21
+ Dimension &operator=(const Dimension &) = delete;
22
+ Dimension(Dimension &&) = delete;
23
+ Dimension &operator=(Dimension &&) = delete;
24
+
25
+ static v8::Persistent<v8::Function> constructor;
26
+
27
+ static void GetId(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
28
+ static void GetLength(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
29
+ static void GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info);
30
+ static void SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
31
+ const v8::PropertyCallbackInfo<void> &info);
32
+ static void Inspect(const v8::FunctionCallbackInfo<v8::Value> &args);
33
+
34
+ int id{-1};
35
+ int parent_id{-1};
36
+ };
37
+
38
+ } // namespace nodenetcdfjs
39
+
40
+ #endif