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,1352 @@
1
+ #include "Variable.h"
2
+ #include "Attribute.h"
3
+ #include "Dimension.h"
4
+ #include "nodenetcdfjs.h"
5
+
6
+ namespace nodenetcdfjs
7
+ {
8
+
9
+ // Static constexpr arrays are defined in the header file
10
+ constexpr std::array<unsigned char, 11> Variable::type_sizes;
11
+ constexpr std::array<const char *, 11> Variable::type_names;
12
+
13
+ v8::Persistent<v8::Function> Variable::constructor;
14
+
15
+ Variable::Variable(int id_, int parent_id_) noexcept
16
+ : id(id_)
17
+ , parent_id(parent_id_)
18
+ {
19
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
20
+ v8::Local<v8::Object> obj =
21
+ v8::Local<v8::Function>::New(isolate, constructor)->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
22
+ Wrap(obj);
23
+ const int retval = nc_inq_var(parent_id, id, nullptr, &type, &ndims, nullptr, nullptr);
24
+ if (retval != NC_NOERR)
25
+ {
26
+ throw_netcdf_error(isolate, retval);
27
+ }
28
+ }
29
+
30
+ void Variable::Init(v8::Local<v8::Object> exports)
31
+ {
32
+ v8::Isolate *isolate = exports->GetIsolate();
33
+
34
+ v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(isolate);
35
+ tpl->SetClassName(v8::String::NewFromUtf8(isolate, "Variable", v8::NewStringType::kNormal).ToLocalChecked());
36
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
37
+ NODE_SET_PROTOTYPE_METHOD(tpl, "read", Variable::Read);
38
+ NODE_SET_PROTOTYPE_METHOD(tpl, "readSlice", Variable::ReadSlice);
39
+ NODE_SET_PROTOTYPE_METHOD(tpl, "readStridedSlice", Variable::ReadStridedSlice);
40
+ NODE_SET_PROTOTYPE_METHOD(tpl, "write", Variable::Write);
41
+ NODE_SET_PROTOTYPE_METHOD(tpl, "writeSlice", Variable::WriteSlice);
42
+ NODE_SET_PROTOTYPE_METHOD(tpl, "writeStridedSlice", Variable::WriteStridedSlice);
43
+ NODE_SET_PROTOTYPE_METHOD(tpl, "addAttribute", Variable::AddAttribute);
44
+ NODE_SET_PROTOTYPE_METHOD(tpl, "inspect", Variable::Inspect);
45
+ tpl->InstanceTemplate()->SetAccessor(
46
+ v8::String::NewFromUtf8(isolate, "id", v8::NewStringType::kNormal).ToLocalChecked(), Variable::GetId);
47
+ tpl->InstanceTemplate()->SetAccessor(
48
+ v8::String::NewFromUtf8(isolate, "type", v8::NewStringType::kNormal).ToLocalChecked(), Variable::GetType);
49
+ tpl->InstanceTemplate()->SetAccessor(
50
+ v8::String::NewFromUtf8(isolate, "dimensions", v8::NewStringType::kNormal).ToLocalChecked(),
51
+ Variable::GetDimensions);
52
+ tpl->InstanceTemplate()->SetAccessor(
53
+ v8::String::NewFromUtf8(isolate, "attributes", v8::NewStringType::kNormal).ToLocalChecked(),
54
+ Variable::GetAttributes);
55
+ tpl->InstanceTemplate()->SetAccessor(
56
+ v8::String::NewFromUtf8(isolate, "name", v8::NewStringType::kNormal).ToLocalChecked(), Variable::GetName,
57
+ Variable::SetName);
58
+ tpl->InstanceTemplate()->SetAccessor(
59
+ v8::String::NewFromUtf8(isolate, "endianness", v8::NewStringType::kNormal).ToLocalChecked(),
60
+ Variable::GetEndianness, Variable::SetEndianness);
61
+ tpl->InstanceTemplate()->SetAccessor(
62
+ v8::String::NewFromUtf8(isolate, "checksummode", v8::NewStringType::kNormal).ToLocalChecked(),
63
+ Variable::GetChecksumMode, Variable::SetChecksumMode);
64
+ tpl->InstanceTemplate()->SetAccessor(
65
+ v8::String::NewFromUtf8(isolate, "chunkmode", v8::NewStringType::kNormal).ToLocalChecked(),
66
+ Variable::GetChunkMode, Variable::SetChunkMode);
67
+ tpl->InstanceTemplate()->SetAccessor(
68
+ v8::String::NewFromUtf8(isolate, "chunksizes", v8::NewStringType::kNormal).ToLocalChecked(),
69
+ Variable::GetChunkSizes, Variable::SetChunkSizes);
70
+ tpl->InstanceTemplate()->SetAccessor(
71
+ v8::String::NewFromUtf8(isolate, "fillmode", v8::NewStringType::kNormal).ToLocalChecked(),
72
+ Variable::GetFillMode, Variable::SetFillMode);
73
+ tpl->InstanceTemplate()->SetAccessor(
74
+ v8::String::NewFromUtf8(isolate, "fillvalue", v8::NewStringType::kNormal).ToLocalChecked(),
75
+ Variable::GetFillValue, Variable::SetFillValue);
76
+ tpl->InstanceTemplate()->SetAccessor(
77
+ v8::String::NewFromUtf8(isolate, "compressionshuffle", v8::NewStringType::kNormal).ToLocalChecked(),
78
+ Variable::GetCompressionShuffle, Variable::SetCompressionShuffle);
79
+ tpl->InstanceTemplate()->SetAccessor(
80
+ v8::String::NewFromUtf8(isolate, "compressiondeflate", v8::NewStringType::kNormal).ToLocalChecked(),
81
+ Variable::GetCompressionDeflate, Variable::SetCompressionDeflate);
82
+ tpl->InstanceTemplate()->SetAccessor(
83
+ v8::String::NewFromUtf8(isolate, "compressionlevel", v8::NewStringType::kNormal).ToLocalChecked(),
84
+ Variable::GetCompressionLevel, Variable::SetCompressionLevel);
85
+ constructor.Reset(isolate, tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
86
+ }
87
+
88
+ bool Variable::get_name(char *name) const noexcept
89
+ {
90
+ const int retval = nc_inq_varname(parent_id, id, name);
91
+ if (retval != NC_NOERR)
92
+ {
93
+ throw_netcdf_error(v8::Isolate::GetCurrent(), retval);
94
+ return false;
95
+ }
96
+ return true;
97
+ }
98
+
99
+ void Variable::Write(const v8::FunctionCallbackInfo<v8::Value> &args)
100
+ {
101
+ v8::Isolate *isolate = args.GetIsolate();
102
+ auto *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
103
+
104
+ if (args.Length() != obj->ndims + 1)
105
+ {
106
+ isolate->ThrowException(v8::Exception::TypeError(
107
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
108
+ .ToLocalChecked()));
109
+ return;
110
+ }
111
+
112
+ std::vector<size_t> pos(obj->ndims);
113
+ std::vector<size_t> size(obj->ndims, 1);
114
+
115
+ for (int i = 0; i < obj->ndims; i++)
116
+ {
117
+ pos[i] = static_cast<size_t>(args[i]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
118
+ }
119
+ int retval = NC_NOERR;
120
+ switch (obj->type)
121
+ {
122
+ case NC_BYTE:
123
+ case NC_CHAR: {
124
+ const int8_t v = args[obj->ndims]->Int32Value(isolate->GetCurrentContext()).ToChecked();
125
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
126
+ }
127
+ break;
128
+ case NC_SHORT: {
129
+ const int16_t v = args[obj->ndims]->Int32Value(isolate->GetCurrentContext()).ToChecked();
130
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
131
+ }
132
+ break;
133
+ case NC_INT: {
134
+ const int32_t v = args[obj->ndims]->Int32Value(isolate->GetCurrentContext()).ToChecked();
135
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
136
+ }
137
+ break;
138
+ case NC_FLOAT: {
139
+ const float v = static_cast<float>(args[obj->ndims]->NumberValue(isolate->GetCurrentContext()).ToChecked());
140
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
141
+ }
142
+ break;
143
+ case NC_DOUBLE: {
144
+ const double v = args[obj->ndims]->NumberValue(isolate->GetCurrentContext()).ToChecked();
145
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
146
+ }
147
+ break;
148
+ case NC_UBYTE: {
149
+ const uint8_t v = args[obj->ndims]->Uint32Value(isolate->GetCurrentContext()).ToChecked();
150
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
151
+ }
152
+ break;
153
+ case NC_USHORT: {
154
+ const uint16_t v = args[obj->ndims]->Uint32Value(isolate->GetCurrentContext()).ToChecked();
155
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
156
+ }
157
+ break;
158
+ case NC_UINT: {
159
+ const uint32_t v = args[obj->ndims]->Uint32Value(isolate->GetCurrentContext()).ToChecked();
160
+ retval = nc_put_vara(obj->parent_id, obj->id, pos.data(), size.data(), &v);
161
+ }
162
+ break;
163
+ default:
164
+ isolate->ThrowException(v8::Exception::TypeError(
165
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
166
+ .ToLocalChecked()));
167
+ return;
168
+ }
169
+
170
+ if (retval != NC_NOERR)
171
+ {
172
+ throw_netcdf_error(isolate, retval);
173
+ }
174
+ }
175
+
176
+ void Variable::WriteSlice(const v8::FunctionCallbackInfo<v8::Value> &args)
177
+ {
178
+ v8::Isolate *isolate = args.GetIsolate();
179
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
180
+ if (args.Length() != 2 * obj->ndims + 1)
181
+ {
182
+ isolate->ThrowException(v8::Exception::TypeError(
183
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
184
+ .ToLocalChecked()));
185
+ return;
186
+ }
187
+ if (!args[2 * obj->ndims]->IsTypedArray())
188
+ {
189
+ isolate->ThrowException(v8::Exception::TypeError(
190
+ v8::String::NewFromUtf8(isolate, "Expecting a typed array", v8::NewStringType::kNormal).ToLocalChecked()));
191
+ return;
192
+ }
193
+ size_t *pos = new size_t[obj->ndims];
194
+ size_t *size = new size_t[obj->ndims];
195
+ size_t total_size = 1;
196
+ for (int i = 0; i < obj->ndims; i++)
197
+ {
198
+ pos[i] = static_cast<size_t>(args[2 * i]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
199
+ size_t s = static_cast<size_t>(args[2 * i + 1]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
200
+ size[i] = s;
201
+ total_size *= s;
202
+ }
203
+ v8::Local<v8::TypedArray> val = v8::Local<v8::TypedArray>::Cast(args[2 * obj->ndims]);
204
+ if (val->Length() != total_size)
205
+ {
206
+ isolate->ThrowException(v8::Exception::TypeError(
207
+ v8::String::NewFromUtf8(isolate, "Wrong size of array", v8::NewStringType::kNormal).ToLocalChecked()));
208
+ delete[] pos;
209
+ delete[] size;
210
+ return;
211
+ }
212
+
213
+ bool correct_type;
214
+ switch (obj->type)
215
+ {
216
+ case NC_BYTE:
217
+ case NC_CHAR:
218
+ correct_type = val->IsInt8Array();
219
+ break;
220
+ case NC_SHORT:
221
+ correct_type = val->IsInt16Array();
222
+ break;
223
+ case NC_INT:
224
+ correct_type = val->IsInt32Array();
225
+ break;
226
+ case NC_FLOAT:
227
+ correct_type = val->IsFloat32Array();
228
+ break;
229
+ case NC_DOUBLE:
230
+ correct_type = val->IsFloat64Array();
231
+ break;
232
+ case NC_UBYTE:
233
+ correct_type = val->IsUint8Array();
234
+ break;
235
+ case NC_USHORT:
236
+ correct_type = val->IsUint16Array();
237
+ break;
238
+ case NC_UINT:
239
+ correct_type = val->IsUint32Array();
240
+ break;
241
+ default:
242
+ isolate->ThrowException(v8::Exception::TypeError(
243
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
244
+ .ToLocalChecked()));
245
+ delete[] pos;
246
+ delete[] size;
247
+ return;
248
+ }
249
+ if (!correct_type)
250
+ {
251
+ isolate->ThrowException(v8::Exception::TypeError(
252
+ v8::String::NewFromUtf8(isolate, "Wrong array type", v8::NewStringType::kNormal).ToLocalChecked()));
253
+ delete[] pos;
254
+ delete[] size;
255
+ return;
256
+ }
257
+ int retval = nc_put_vara(obj->parent_id, obj->id, pos, size, val->Buffer()->GetBackingStore()->Data());
258
+ if (retval != NC_NOERR)
259
+ {
260
+ throw_netcdf_error(isolate, retval);
261
+ }
262
+ delete[] pos;
263
+ delete[] size;
264
+ }
265
+
266
+ void Variable::WriteStridedSlice(const v8::FunctionCallbackInfo<v8::Value> &args)
267
+ {
268
+ v8::Isolate *isolate = args.GetIsolate();
269
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
270
+ if (args.Length() != 3 * obj->ndims + 1)
271
+ {
272
+ isolate->ThrowException(v8::Exception::TypeError(
273
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
274
+ .ToLocalChecked()));
275
+ return;
276
+ }
277
+ if (!args[3 * obj->ndims]->IsTypedArray())
278
+ {
279
+ isolate->ThrowException(v8::Exception::TypeError(
280
+ v8::String::NewFromUtf8(isolate, "Expecting a typed array", v8::NewStringType::kNormal).ToLocalChecked()));
281
+ return;
282
+ }
283
+ size_t *pos = new size_t[obj->ndims];
284
+ size_t *size = new size_t[obj->ndims];
285
+ ptrdiff_t *stride = new ptrdiff_t[obj->ndims];
286
+ size_t total_size = 1;
287
+ for (int i = 0; i < obj->ndims; i++)
288
+ {
289
+ pos[i] = static_cast<size_t>(args[3 * i]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
290
+ size_t s = static_cast<size_t>(args[3 * i + 1]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
291
+ size[i] = s;
292
+ total_size *= s;
293
+ stride[i] = static_cast<ptrdiff_t>(args[3 * i + 2]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
294
+ }
295
+ v8::Local<v8::TypedArray> val = v8::Local<v8::TypedArray>::Cast(args[3 * obj->ndims]);
296
+ if (val->Length() != total_size)
297
+ {
298
+ isolate->ThrowException(v8::Exception::TypeError(
299
+ v8::String::NewFromUtf8(isolate, "Wrong size of array", v8::NewStringType::kNormal).ToLocalChecked()));
300
+ delete[] pos;
301
+ delete[] size;
302
+ delete[] stride;
303
+ return;
304
+ }
305
+
306
+ bool correct_type;
307
+ switch (obj->type)
308
+ {
309
+ case NC_BYTE:
310
+ case NC_CHAR:
311
+ correct_type = val->IsInt8Array();
312
+ break;
313
+ case NC_SHORT:
314
+ correct_type = val->IsInt16Array();
315
+ break;
316
+ case NC_INT:
317
+ correct_type = val->IsInt32Array();
318
+ break;
319
+ case NC_FLOAT:
320
+ correct_type = val->IsFloat32Array();
321
+ break;
322
+ case NC_DOUBLE:
323
+ correct_type = val->IsFloat64Array();
324
+ break;
325
+ case NC_UBYTE:
326
+ correct_type = val->IsUint8Array();
327
+ break;
328
+ case NC_USHORT:
329
+ correct_type = val->IsUint16Array();
330
+ break;
331
+ case NC_UINT:
332
+ correct_type = val->IsUint32Array();
333
+ break;
334
+ default:
335
+ isolate->ThrowException(v8::Exception::TypeError(
336
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
337
+ .ToLocalChecked()));
338
+ delete[] pos;
339
+ delete[] size;
340
+ delete[] stride;
341
+ return;
342
+ }
343
+ if (!correct_type)
344
+ {
345
+ isolate->ThrowException(v8::Exception::TypeError(
346
+ v8::String::NewFromUtf8(isolate, "Wrong array type", v8::NewStringType::kNormal).ToLocalChecked()));
347
+ delete[] pos;
348
+ delete[] size;
349
+ delete[] stride;
350
+ return;
351
+ }
352
+ int retval = nc_put_vars(obj->parent_id, obj->id, pos, size, stride, val->Buffer()->GetBackingStore()->Data());
353
+ if (retval != NC_NOERR)
354
+ {
355
+ throw_netcdf_error(isolate, retval);
356
+ }
357
+ delete[] pos;
358
+ delete[] size;
359
+ delete[] stride;
360
+ }
361
+
362
+ void Variable::Read(const v8::FunctionCallbackInfo<v8::Value> &args)
363
+ {
364
+ v8::Isolate *isolate = args.GetIsolate();
365
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
366
+ if (args.Length() != obj->ndims)
367
+ {
368
+ isolate->ThrowException(v8::Exception::TypeError(
369
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
370
+ .ToLocalChecked()));
371
+ return;
372
+ }
373
+ if (obj->type < NC_BYTE || obj->type > NC_UINT)
374
+ {
375
+ isolate->ThrowException(v8::Exception::TypeError(
376
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
377
+ .ToLocalChecked()));
378
+ return;
379
+ }
380
+ size_t *pos = new size_t[obj->ndims];
381
+ size_t *size = new size_t[obj->ndims];
382
+ for (int i = 0; i < obj->ndims; i++)
383
+ {
384
+ pos[i] = static_cast<size_t>(args[i]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
385
+ size[i] = 1;
386
+ }
387
+ v8::Local<v8::Value> result;
388
+ int retval;
389
+ switch (obj->type)
390
+ {
391
+ case NC_BYTE: {
392
+ int8_t v;
393
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
394
+ result = v8::Integer::New(isolate, v);
395
+ }
396
+ break;
397
+ case NC_CHAR: {
398
+ char v[2];
399
+ v[1] = 0;
400
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
401
+ result = v8::String::NewFromUtf8(isolate, v, v8::NewStringType::kNormal).ToLocalChecked();
402
+ }
403
+ break;
404
+ case NC_SHORT: {
405
+ int16_t v;
406
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
407
+ result = v8::Integer::New(isolate, v);
408
+ }
409
+ break;
410
+ case NC_INT: {
411
+ int32_t v;
412
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
413
+ result = v8::Integer::New(isolate, v);
414
+ }
415
+ break;
416
+ case NC_FLOAT: {
417
+ float v;
418
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
419
+ result = v8::Number::New(isolate, v);
420
+ }
421
+ break;
422
+ case NC_DOUBLE: {
423
+ double v;
424
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
425
+ result = v8::Number::New(isolate, v);
426
+ }
427
+ break;
428
+ case NC_UBYTE: {
429
+ uint8_t v;
430
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
431
+ result = v8::Integer::New(isolate, v);
432
+ }
433
+ break;
434
+ case NC_USHORT: {
435
+ uint16_t v;
436
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
437
+ result = v8::Integer::New(isolate, v);
438
+ }
439
+ break;
440
+ case NC_UINT: {
441
+ uint32_t v;
442
+ retval = nc_get_vara(obj->parent_id, obj->id, pos, size, &v);
443
+ result = v8::Integer::New(isolate, v);
444
+ }
445
+ break;
446
+ }
447
+ if (retval != NC_NOERR)
448
+ {
449
+ throw_netcdf_error(isolate, retval);
450
+ }
451
+ else
452
+ {
453
+ args.GetReturnValue().Set(result);
454
+ }
455
+ delete[] pos;
456
+ delete[] size;
457
+ }
458
+
459
+ void Variable::ReadSlice(const v8::FunctionCallbackInfo<v8::Value> &args)
460
+ {
461
+ v8::Isolate *isolate = args.GetIsolate();
462
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
463
+ if (args.Length() != 2 * obj->ndims)
464
+ {
465
+ isolate->ThrowException(v8::Exception::TypeError(
466
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
467
+ .ToLocalChecked()));
468
+ return;
469
+ }
470
+ if (obj->type < NC_BYTE || obj->type > NC_UINT)
471
+ {
472
+ isolate->ThrowException(v8::Exception::TypeError(
473
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
474
+ .ToLocalChecked()));
475
+ return;
476
+ }
477
+
478
+ size_t *pos = new size_t[obj->ndims];
479
+ size_t *size = new size_t[obj->ndims];
480
+ size_t total_size = 1;
481
+ for (int i = 0; i < obj->ndims; i++)
482
+ {
483
+ pos[i] = static_cast<size_t>(args[2 * i]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
484
+ size_t s = static_cast<size_t>(args[2 * i + 1]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
485
+ size[i] = s;
486
+ total_size *= s;
487
+ }
488
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, total_size * type_sizes[obj->type]);
489
+ int retval = nc_get_vara(obj->parent_id, obj->id, pos, size, buffer->GetBackingStore()->Data());
490
+ if (retval != NC_NOERR)
491
+ {
492
+ throw_netcdf_error(isolate, retval);
493
+ delete[] pos;
494
+ delete[] size;
495
+ return;
496
+ }
497
+ v8::Local<v8::Object> result;
498
+
499
+ switch (obj->type)
500
+ {
501
+ case NC_BYTE:
502
+ case NC_CHAR:
503
+ result = v8::Int8Array::New(buffer, 0, total_size);
504
+ break;
505
+ case NC_SHORT:
506
+ result = v8::Int16Array::New(buffer, 0, total_size);
507
+ break;
508
+ case NC_INT:
509
+ result = v8::Int32Array::New(buffer, 0, total_size);
510
+ break;
511
+ case NC_FLOAT:
512
+ result = v8::Float32Array::New(buffer, 0, total_size);
513
+ break;
514
+ case NC_DOUBLE:
515
+ result = v8::Float64Array::New(buffer, 0, total_size);
516
+ break;
517
+ case NC_UBYTE:
518
+ result = v8::Uint8Array::New(buffer, 0, total_size);
519
+ break;
520
+ case NC_USHORT:
521
+ result = v8::Uint16Array::New(buffer, 0, total_size);
522
+ break;
523
+ case NC_UINT:
524
+ result = v8::Uint32Array::New(buffer, 0, total_size);
525
+ break;
526
+ default:
527
+ isolate->ThrowException(v8::Exception::TypeError(
528
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
529
+ .ToLocalChecked()));
530
+ delete[] pos;
531
+ delete[] size;
532
+ return;
533
+ }
534
+ args.GetReturnValue().Set(result);
535
+ delete[] pos;
536
+ delete[] size;
537
+ }
538
+
539
+ void Variable::ReadStridedSlice(const v8::FunctionCallbackInfo<v8::Value> &args)
540
+ {
541
+ v8::Isolate *isolate = args.GetIsolate();
542
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
543
+ if (args.Length() != 3 * obj->ndims)
544
+ {
545
+ isolate->ThrowException(v8::Exception::TypeError(
546
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
547
+ .ToLocalChecked()));
548
+ return;
549
+ }
550
+ if (obj->type < NC_BYTE || obj->type > NC_UINT)
551
+ {
552
+ isolate->ThrowException(v8::Exception::TypeError(
553
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
554
+ .ToLocalChecked()));
555
+ return;
556
+ }
557
+
558
+ size_t *pos = new size_t[obj->ndims];
559
+ size_t *size = new size_t[obj->ndims];
560
+ ptrdiff_t *stride = new ptrdiff_t[obj->ndims];
561
+ size_t total_size = 1;
562
+ for (int i = 0; i < obj->ndims; i++)
563
+ {
564
+ pos[i] = static_cast<size_t>(args[3 * i]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
565
+ size_t s = static_cast<size_t>(args[3 * i + 1]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
566
+ size[i] = s;
567
+ total_size *= s;
568
+ stride[i] = static_cast<ptrdiff_t>(args[3 * i + 2]->IntegerValue(isolate->GetCurrentContext()).ToChecked());
569
+ }
570
+ v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, total_size * type_sizes[obj->type]);
571
+ int retval = nc_get_vars(obj->parent_id, obj->id, pos, size, stride, buffer->GetBackingStore()->Data());
572
+ if (retval != NC_NOERR)
573
+ {
574
+ throw_netcdf_error(isolate, retval);
575
+ delete[] pos;
576
+ delete[] size;
577
+ delete[] stride;
578
+ return;
579
+ }
580
+ v8::Local<v8::Object> result;
581
+
582
+ switch (obj->type)
583
+ {
584
+ case NC_BYTE:
585
+ case NC_CHAR:
586
+ result = v8::Int8Array::New(buffer, 0, total_size);
587
+ break;
588
+ case NC_SHORT:
589
+ result = v8::Int16Array::New(buffer, 0, total_size);
590
+ break;
591
+ case NC_INT:
592
+ result = v8::Int32Array::New(buffer, 0, total_size);
593
+ break;
594
+ case NC_FLOAT:
595
+ result = v8::Float32Array::New(buffer, 0, total_size);
596
+ break;
597
+ case NC_DOUBLE:
598
+ result = v8::Float64Array::New(buffer, 0, total_size);
599
+ break;
600
+ case NC_UBYTE:
601
+ result = v8::Uint8Array::New(buffer, 0, total_size);
602
+ break;
603
+ case NC_USHORT:
604
+ result = v8::Uint16Array::New(buffer, 0, total_size);
605
+ break;
606
+ case NC_UINT:
607
+ result = v8::Uint32Array::New(buffer, 0, total_size);
608
+ break;
609
+ }
610
+ args.GetReturnValue().Set(result);
611
+ delete[] pos;
612
+ delete[] size;
613
+ delete[] stride;
614
+ }
615
+
616
+ void Variable::AddAttribute(const v8::FunctionCallbackInfo<v8::Value> &args)
617
+ {
618
+ v8::Isolate *isolate = args.GetIsolate();
619
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(args.Holder());
620
+ if (args.Length() < 3)
621
+ {
622
+ isolate->ThrowException(v8::Exception::TypeError(
623
+ v8::String::NewFromUtf8(isolate, "Wrong number of arguments", v8::NewStringType::kNormal)
624
+ .ToLocalChecked()));
625
+ return;
626
+ }
627
+ std::string type_str = *v8::String::Utf8Value(
628
+ #if NODE_MAJOR_VERSION >= 8
629
+ isolate,
630
+ #endif
631
+ args[1]);
632
+ int type = get_type(type_str);
633
+ if (type == NC2_ERR)
634
+ {
635
+ isolate->ThrowException(v8::Exception::TypeError(
636
+ v8::String::NewFromUtf8(isolate, "Unknown variable type", v8::NewStringType::kNormal).ToLocalChecked()));
637
+ return;
638
+ }
639
+ Attribute *res = new Attribute(*v8::String::Utf8Value(
640
+ #if NODE_MAJOR_VERSION >= 8
641
+ isolate,
642
+ #endif
643
+ args[0]),
644
+ obj->id, obj->parent_id, type);
645
+ res->set_value(args[2]);
646
+ args.GetReturnValue().Set(res->handle());
647
+ }
648
+
649
+ void Variable::GetId(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
650
+ {
651
+ v8::Isolate *isolate = info.GetIsolate();
652
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
653
+ info.GetReturnValue().Set(v8::Integer::New(isolate, obj->id));
654
+ }
655
+
656
+ void Variable::GetDimensions(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
657
+ {
658
+ v8::Isolate *isolate = info.GetIsolate();
659
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
660
+ int *dim_ids = new int[obj->ndims];
661
+ int retval = nc_inq_vardimid(obj->parent_id, obj->id, dim_ids);
662
+ if (retval != NC_NOERR)
663
+ {
664
+ throw_netcdf_error(isolate, retval);
665
+ delete[] dim_ids;
666
+ return;
667
+ }
668
+ v8::Local<v8::Array> result = v8::Array::New(isolate);
669
+ for (int i = 0; i < obj->ndims; i++)
670
+ {
671
+ Dimension *d = new Dimension(dim_ids[i], obj->parent_id);
672
+ result->Set(isolate->GetCurrentContext(), i, d->handle());
673
+ }
674
+ info.GetReturnValue().Set(result);
675
+ delete[] dim_ids;
676
+ }
677
+
678
+ void Variable::GetAttributes(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
679
+ {
680
+ v8::Isolate *isolate = info.GetIsolate();
681
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
682
+ int natts;
683
+ int retval = nc_inq_varnatts(obj->parent_id, obj->id, &natts);
684
+ if (retval != NC_NOERR)
685
+ {
686
+ throw_netcdf_error(isolate, retval);
687
+ return;
688
+ }
689
+ v8::Local<v8::Object> result = v8::Object::New(isolate);
690
+ char name[NC_MAX_NAME + 1];
691
+ for (int i = 0; i < natts; i++)
692
+ {
693
+ retval = nc_inq_attname(obj->parent_id, obj->id, i, name);
694
+ if (retval != NC_NOERR)
695
+ {
696
+ throw_netcdf_error(isolate, retval);
697
+ return;
698
+ }
699
+ Attribute *a = new Attribute(name, obj->id, obj->parent_id);
700
+ result->Set(isolate->GetCurrentContext(),
701
+ v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal).ToLocalChecked(), a->handle());
702
+ }
703
+ info.GetReturnValue().Set(result);
704
+ }
705
+
706
+ void Variable::GetType(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
707
+ {
708
+ v8::Isolate *isolate = info.GetIsolate();
709
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
710
+ const char *res;
711
+ if (obj->type < NC_BYTE || obj->type > NC_UINT)
712
+ {
713
+ res = "Variable type not supported yet";
714
+ }
715
+ else
716
+ {
717
+ res = type_names[obj->type];
718
+ }
719
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, res, v8::NewStringType::kNormal).ToLocalChecked());
720
+ }
721
+
722
+ void Variable::GetName(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
723
+ {
724
+ v8::Isolate *isolate = info.GetIsolate();
725
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
726
+ char name[NC_MAX_NAME + 1];
727
+ if (obj->get_name(name))
728
+ {
729
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal).ToLocalChecked());
730
+ }
731
+ }
732
+
733
+ void Variable::SetName(v8::Local<v8::String> property, v8::Local<v8::Value> val,
734
+ const v8::PropertyCallbackInfo<void> &info)
735
+ {
736
+ v8::Isolate *isolate = info.GetIsolate();
737
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
738
+ v8::String::Utf8Value new_name_(
739
+ #if NODE_MAJOR_VERSION >= 8
740
+ isolate,
741
+ #endif
742
+ val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
743
+ int retval = nc_rename_var(obj->parent_id, obj->id, *new_name_);
744
+ if (retval != NC_NOERR)
745
+ {
746
+ throw_netcdf_error(isolate, retval);
747
+ return;
748
+ }
749
+ }
750
+
751
+ void Variable::GetEndianness(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
752
+ {
753
+ v8::Isolate *isolate = info.GetIsolate();
754
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
755
+ int v;
756
+ int retval = nc_inq_var_endian(obj->parent_id, obj->id, &v);
757
+ if (retval != NC_NOERR)
758
+ {
759
+ throw_netcdf_error(isolate, retval);
760
+ return;
761
+ }
762
+ const char *res;
763
+ switch (v)
764
+ {
765
+ case NC_ENDIAN_LITTLE:
766
+ res = "litte";
767
+ break;
768
+ case NC_ENDIAN_BIG:
769
+ res = "big";
770
+ break;
771
+ case NC_ENDIAN_NATIVE:
772
+ res = "native";
773
+ break;
774
+ default:
775
+ res = "unknown";
776
+ break;
777
+ }
778
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, res, v8::NewStringType::kNormal).ToLocalChecked());
779
+ }
780
+
781
+ void Variable::SetEndianness(v8::Local<v8::String> property, v8::Local<v8::Value> val,
782
+ const v8::PropertyCallbackInfo<void> &info)
783
+ {
784
+ v8::Isolate *isolate = info.GetIsolate();
785
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
786
+ std::string arg = *v8::String::Utf8Value(
787
+ #if NODE_MAJOR_VERSION >= 8
788
+ isolate,
789
+ #endif
790
+ val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
791
+ int v;
792
+ if (arg == "little")
793
+ {
794
+ v = NC_ENDIAN_LITTLE;
795
+ }
796
+ else if (arg == "big")
797
+ {
798
+ v = NC_ENDIAN_BIG;
799
+ }
800
+ else if (arg == "native")
801
+ {
802
+ v = NC_ENDIAN_NATIVE;
803
+ }
804
+ else
805
+ {
806
+ isolate->ThrowException(v8::Exception::TypeError(
807
+ v8::String::NewFromUtf8(isolate, "Unknown value", v8::NewStringType::kNormal).ToLocalChecked()));
808
+ return;
809
+ }
810
+ int retval = nc_def_var_endian(obj->parent_id, obj->id, v);
811
+ if (retval != NC_NOERR)
812
+ {
813
+ throw_netcdf_error(isolate, retval);
814
+ return;
815
+ }
816
+ }
817
+
818
+ void Variable::GetChecksumMode(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
819
+ {
820
+ v8::Isolate *isolate = info.GetIsolate();
821
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
822
+ int v;
823
+ int retval = nc_inq_var_fletcher32(obj->parent_id, obj->id, &v);
824
+ if (retval != NC_NOERR)
825
+ {
826
+ throw_netcdf_error(isolate, retval);
827
+ return;
828
+ }
829
+ const char *res;
830
+ switch (v)
831
+ {
832
+ case NC_NOCHECKSUM:
833
+ res = "none";
834
+ break;
835
+ case NC_FLETCHER32:
836
+ res = "fletcher32";
837
+ break;
838
+ default:
839
+ res = "unknown";
840
+ break;
841
+ }
842
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, res, v8::NewStringType::kNormal).ToLocalChecked());
843
+ }
844
+
845
+ void Variable::SetChecksumMode(v8::Local<v8::String> property, v8::Local<v8::Value> val,
846
+ const v8::PropertyCallbackInfo<void> &info)
847
+ {
848
+ v8::Isolate *isolate = info.GetIsolate();
849
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
850
+ std::string arg = *v8::String::Utf8Value(
851
+ #if NODE_MAJOR_VERSION >= 8
852
+ isolate,
853
+ #endif
854
+ val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
855
+ int v;
856
+ if (arg == "none")
857
+ {
858
+ v = NC_NOCHECKSUM;
859
+ }
860
+ else if (arg == "fletcher32")
861
+ {
862
+ v = NC_FLETCHER32;
863
+ }
864
+ else
865
+ {
866
+ isolate->ThrowException(v8::Exception::TypeError(
867
+ v8::String::NewFromUtf8(isolate, "Unknown value", v8::NewStringType::kNormal).ToLocalChecked()));
868
+ return;
869
+ }
870
+ int retval = nc_def_var_fletcher32(obj->parent_id, obj->id, v);
871
+ if (retval != NC_NOERR)
872
+ {
873
+ throw_netcdf_error(isolate, retval);
874
+ return;
875
+ }
876
+ }
877
+
878
+ void Variable::GetChunkMode(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
879
+ {
880
+ v8::Isolate *isolate = info.GetIsolate();
881
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
882
+ int v;
883
+ int retval = nc_inq_var_chunking(obj->parent_id, obj->id, &v, NULL);
884
+ if (retval != NC_NOERR)
885
+ {
886
+ throw_netcdf_error(isolate, retval);
887
+ return;
888
+ }
889
+ const char *res;
890
+ switch (v)
891
+ {
892
+ case NC_CONTIGUOUS:
893
+ res = "contiguous";
894
+ break;
895
+ case NC_CHUNKED:
896
+ res = "chunked";
897
+ break;
898
+ default:
899
+ res = "unknown";
900
+ break;
901
+ }
902
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, res, v8::NewStringType::kNormal).ToLocalChecked());
903
+ }
904
+
905
+ void Variable::SetChunkMode(v8::Local<v8::String> property, v8::Local<v8::Value> val,
906
+ const v8::PropertyCallbackInfo<void> &info)
907
+ {
908
+ v8::Isolate *isolate = info.GetIsolate();
909
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
910
+ std::string arg = *v8::String::Utf8Value(
911
+ #if NODE_MAJOR_VERSION >= 8
912
+ isolate,
913
+ #endif
914
+ val->ToString(isolate->GetCurrentContext()).ToLocalChecked());
915
+ int v;
916
+ if (arg == "contiguous")
917
+ {
918
+ v = NC_CONTIGUOUS;
919
+ }
920
+ else if (arg == "chunked")
921
+ {
922
+ v = NC_CHUNKED;
923
+ }
924
+ else
925
+ {
926
+ isolate->ThrowException(v8::Exception::TypeError(
927
+ v8::String::NewFromUtf8(isolate, "Unknown value", v8::NewStringType::kNormal).ToLocalChecked()));
928
+ return;
929
+ }
930
+ int len;
931
+ int retval = nc_inq_varndims(obj->parent_id, obj->id, &len);
932
+ if (retval != NC_NOERR)
933
+ {
934
+ throw_netcdf_error(isolate, retval);
935
+ return;
936
+ }
937
+ size_t *sizes = new size_t[len];
938
+ retval = nc_inq_var_chunking(obj->parent_id, obj->id, NULL, sizes);
939
+ if (retval != NC_NOERR)
940
+ {
941
+ throw_netcdf_error(isolate, retval);
942
+ delete[] sizes;
943
+ return;
944
+ }
945
+ retval = nc_def_var_chunking(obj->parent_id, obj->id, v, sizes);
946
+ if (retval != NC_NOERR)
947
+ {
948
+ throw_netcdf_error(isolate, retval);
949
+ }
950
+ delete[] sizes;
951
+ }
952
+
953
+ void Variable::GetChunkSizes(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
954
+ {
955
+ v8::Isolate *isolate = info.GetIsolate();
956
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
957
+ size_t *sizes = new size_t[obj->ndims];
958
+ int retval = nc_inq_var_chunking(obj->parent_id, obj->id, NULL, sizes);
959
+ if (retval != NC_NOERR)
960
+ {
961
+ throw_netcdf_error(isolate, retval);
962
+ delete[] sizes;
963
+ return;
964
+ }
965
+ v8::Local<v8::Array> result = v8::Array::New(isolate);
966
+ for (int i = 0; i < obj->ndims; i++)
967
+ {
968
+ result->Set(isolate->GetCurrentContext(), i, v8::Integer::New(isolate, i));
969
+ }
970
+ info.GetReturnValue().Set(result);
971
+ delete[] sizes;
972
+ }
973
+
974
+ void Variable::SetChunkSizes(v8::Local<v8::String> property, v8::Local<v8::Value> val,
975
+ const v8::PropertyCallbackInfo<void> &info)
976
+ {
977
+ v8::Isolate *isolate = info.GetIsolate();
978
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
979
+ if (!val->IsArray())
980
+ {
981
+ isolate->ThrowException(v8::Exception::TypeError(
982
+ v8::String::NewFromUtf8(isolate, "Expecting an array", v8::NewStringType::kNormal).ToLocalChecked()));
983
+ return;
984
+ }
985
+ v8::Local<v8::Object> array = val->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
986
+ if (array
987
+ ->Get(isolate->GetCurrentContext(),
988
+ v8::String::NewFromUtf8(isolate, "length", v8::NewStringType::kNormal).ToLocalChecked())
989
+ .ToLocalChecked()
990
+ ->Int32Value(isolate->GetCurrentContext())
991
+ .ToChecked() != obj->ndims)
992
+ {
993
+ isolate->ThrowException(v8::Exception::TypeError(
994
+ v8::String::NewFromUtf8(isolate, "Wrong array size", v8::NewStringType::kNormal).ToLocalChecked()));
995
+ return;
996
+ }
997
+ int v;
998
+ int retval = nc_inq_var_chunking(obj->parent_id, obj->id, &v, NULL);
999
+ if (retval != NC_NOERR)
1000
+ {
1001
+ throw_netcdf_error(isolate, retval);
1002
+ return;
1003
+ }
1004
+ size_t *sizes = new size_t[obj->ndims];
1005
+ for (int i = 0; i < obj->ndims; i++)
1006
+ {
1007
+ sizes[i] = array->Get(isolate->GetCurrentContext(), i)
1008
+ .ToLocalChecked()
1009
+ ->Uint32Value(isolate->GetCurrentContext())
1010
+ .ToChecked();
1011
+ }
1012
+ retval = nc_def_var_chunking(obj->parent_id, obj->id, v, sizes);
1013
+ if (retval != NC_NOERR)
1014
+ {
1015
+ throw_netcdf_error(isolate, retval);
1016
+ }
1017
+ delete[] sizes;
1018
+ }
1019
+
1020
+ void Variable::GetFillMode(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
1021
+ {
1022
+ v8::Isolate *isolate = info.GetIsolate();
1023
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1024
+ int v;
1025
+ int retval = nc_inq_var_fill(obj->parent_id, obj->id, &v, NULL);
1026
+ if (retval != NC_NOERR)
1027
+ {
1028
+ throw_netcdf_error(isolate, retval);
1029
+ return;
1030
+ }
1031
+ info.GetReturnValue().Set(v8::Boolean::New(isolate, v == 1));
1032
+ }
1033
+
1034
+ void Variable::SetFillMode(v8::Local<v8::String> property, v8::Local<v8::Value> val,
1035
+ const v8::PropertyCallbackInfo<void> &info)
1036
+ {
1037
+ v8::Isolate *isolate = info.GetIsolate();
1038
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1039
+ if (!val->IsBoolean())
1040
+ {
1041
+ isolate->ThrowException(v8::Exception::TypeError(
1042
+ v8::String::NewFromUtf8(isolate, "Expecting a boolean", v8::NewStringType::kNormal).ToLocalChecked()));
1043
+ return;
1044
+ }
1045
+ #if NODE_MAJOR_VERSION > 11
1046
+ int v = val->BooleanValue(isolate) ? 1 : 0;
1047
+ #else
1048
+ int v = val->BooleanValue() ? 1 : 0;
1049
+ #endif
1050
+ if (obj->type < NC_BYTE || obj->type > NC_UINT)
1051
+ {
1052
+ isolate->ThrowException(v8::Exception::TypeError(
1053
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
1054
+ .ToLocalChecked()));
1055
+ return;
1056
+ }
1057
+ uint8_t *value = new uint8_t[type_sizes[obj->type]];
1058
+ int retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, value);
1059
+ if (retval != NC_NOERR)
1060
+ {
1061
+ throw_netcdf_error(isolate, retval);
1062
+ delete[] value;
1063
+ return;
1064
+ }
1065
+ retval = nc_def_var_fill(obj->parent_id, obj->id, v, value);
1066
+ if (retval != NC_NOERR)
1067
+ {
1068
+ throw_netcdf_error(isolate, retval);
1069
+ }
1070
+ delete[] value;
1071
+ }
1072
+
1073
+ void Variable::GetFillValue(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
1074
+ {
1075
+ v8::Isolate *isolate = info.GetIsolate();
1076
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1077
+ v8::Local<v8::Value> result;
1078
+ int retval;
1079
+ switch (obj->type)
1080
+ {
1081
+ case NC_BYTE: {
1082
+ int8_t v;
1083
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1084
+ result = v8::Integer::New(isolate, v);
1085
+ }
1086
+ break;
1087
+ case NC_CHAR: {
1088
+ char v[2];
1089
+ v[1] = 0;
1090
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1091
+ result = v8::String::NewFromUtf8(isolate, v, v8::NewStringType::kNormal).ToLocalChecked();
1092
+ }
1093
+ break;
1094
+ case NC_SHORT: {
1095
+ int16_t v;
1096
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1097
+ result = v8::Integer::New(isolate, v);
1098
+ }
1099
+ break;
1100
+ case NC_INT: {
1101
+ int32_t v;
1102
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1103
+ result = v8::Integer::New(isolate, v);
1104
+ }
1105
+ break;
1106
+ case NC_FLOAT: {
1107
+ float v;
1108
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1109
+ result = v8::Number::New(isolate, v);
1110
+ }
1111
+ break;
1112
+ case NC_DOUBLE: {
1113
+ double v;
1114
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1115
+ result = v8::Number::New(isolate, v);
1116
+ }
1117
+ break;
1118
+ case NC_UBYTE: {
1119
+ uint8_t v;
1120
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1121
+ result = v8::Integer::New(isolate, v);
1122
+ }
1123
+ break;
1124
+ case NC_USHORT: {
1125
+ uint16_t v;
1126
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1127
+ result = v8::Integer::New(isolate, v);
1128
+ }
1129
+ break;
1130
+ case NC_UINT: {
1131
+ uint32_t v;
1132
+ retval = nc_inq_var_fill(obj->parent_id, obj->id, NULL, &v);
1133
+ result = v8::Integer::New(isolate, v);
1134
+ }
1135
+ break;
1136
+ default:
1137
+ isolate->ThrowException(v8::Exception::TypeError(
1138
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
1139
+ .ToLocalChecked()));
1140
+ return;
1141
+ }
1142
+ if (retval != NC_NOERR)
1143
+ {
1144
+ throw_netcdf_error(isolate, retval);
1145
+ return;
1146
+ }
1147
+ info.GetReturnValue().Set(result);
1148
+ }
1149
+
1150
+ void Variable::SetFillValue(v8::Local<v8::String> property, v8::Local<v8::Value> val,
1151
+ const v8::PropertyCallbackInfo<void> &info)
1152
+ {
1153
+ v8::Isolate *isolate = info.GetIsolate();
1154
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1155
+ int mode;
1156
+ int retval = nc_inq_var_fill(obj->parent_id, obj->id, &mode, NULL);
1157
+ if (retval != NC_NOERR)
1158
+ {
1159
+ throw_netcdf_error(isolate, retval);
1160
+ return;
1161
+ }
1162
+ switch (obj->type)
1163
+ {
1164
+ case NC_BYTE:
1165
+ case NC_CHAR: {
1166
+ int8_t v = val->Int32Value(isolate->GetCurrentContext()).ToChecked();
1167
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1168
+ }
1169
+ break;
1170
+ case NC_SHORT: {
1171
+ int16_t v = val->Int32Value(isolate->GetCurrentContext()).ToChecked();
1172
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1173
+ }
1174
+ break;
1175
+ case NC_INT: {
1176
+ int32_t v = val->Int32Value(isolate->GetCurrentContext()).ToChecked();
1177
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1178
+ }
1179
+ break;
1180
+ case NC_FLOAT: {
1181
+ float v = static_cast<float>(val->NumberValue(isolate->GetCurrentContext()).ToChecked());
1182
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1183
+ }
1184
+ break;
1185
+ case NC_DOUBLE: {
1186
+ double v = val->NumberValue(isolate->GetCurrentContext()).ToChecked();
1187
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1188
+ }
1189
+ break;
1190
+ case NC_UBYTE: {
1191
+ uint8_t v = val->Uint32Value(isolate->GetCurrentContext()).ToChecked();
1192
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1193
+ }
1194
+ break;
1195
+ case NC_USHORT: {
1196
+ uint16_t v = val->Uint32Value(isolate->GetCurrentContext()).ToChecked();
1197
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1198
+ }
1199
+ break;
1200
+ case NC_UINT: {
1201
+ uint32_t v = val->Uint32Value(isolate->GetCurrentContext()).ToChecked();
1202
+ retval = nc_def_var_fill(obj->parent_id, obj->id, mode, &v);
1203
+ }
1204
+ break;
1205
+ default:
1206
+ isolate->ThrowException(v8::Exception::TypeError(
1207
+ v8::String::NewFromUtf8(isolate, "Variable type not supported yet", v8::NewStringType::kNormal)
1208
+ .ToLocalChecked()));
1209
+ return;
1210
+ }
1211
+ if (retval != NC_NOERR)
1212
+ {
1213
+ throw_netcdf_error(isolate, retval);
1214
+ }
1215
+ }
1216
+
1217
+ void Variable::GetCompressionShuffle(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
1218
+ {
1219
+ v8::Isolate *isolate = info.GetIsolate();
1220
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1221
+ int v;
1222
+ int retval = nc_inq_var_deflate(obj->parent_id, obj->id, &v, NULL, NULL);
1223
+ if (retval != NC_NOERR)
1224
+ {
1225
+ throw_netcdf_error(isolate, retval);
1226
+ return;
1227
+ }
1228
+ info.GetReturnValue().Set(v8::Boolean::New(isolate, v == 1));
1229
+ }
1230
+
1231
+ void Variable::SetCompressionShuffle(v8::Local<v8::String> property, v8::Local<v8::Value> val,
1232
+ const v8::PropertyCallbackInfo<void> &info)
1233
+ {
1234
+ v8::Isolate *isolate = info.GetIsolate();
1235
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1236
+ if (!val->IsBoolean())
1237
+ {
1238
+ isolate->ThrowException(v8::Exception::TypeError(
1239
+ v8::String::NewFromUtf8(isolate, "Expecting a boolean", v8::NewStringType::kNormal).ToLocalChecked()));
1240
+ return;
1241
+ }
1242
+ #if NODE_MAJOR_VERSION > 11
1243
+ int v = val->BooleanValue(isolate) ? 1 : 0;
1244
+ #else
1245
+ int v = val->BooleanValue() ? 1 : 0;
1246
+ #endif
1247
+ int v1, v2;
1248
+ int retval = nc_inq_var_deflate(obj->parent_id, obj->id, NULL, &v1, &v2);
1249
+ if (retval != NC_NOERR)
1250
+ {
1251
+ throw_netcdf_error(isolate, retval);
1252
+ return;
1253
+ }
1254
+ retval = nc_def_var_deflate(obj->parent_id, obj->id, v, v1, v2);
1255
+ if (retval != NC_NOERR)
1256
+ {
1257
+ throw_netcdf_error(isolate, retval);
1258
+ }
1259
+ }
1260
+
1261
+ void Variable::GetCompressionDeflate(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
1262
+ {
1263
+ v8::Isolate *isolate = info.GetIsolate();
1264
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1265
+ int v;
1266
+ int retval = nc_inq_var_deflate(obj->parent_id, obj->id, NULL, &v, NULL);
1267
+ if (retval != NC_NOERR)
1268
+ {
1269
+ throw_netcdf_error(isolate, retval);
1270
+ return;
1271
+ }
1272
+ info.GetReturnValue().Set(v8::Boolean::New(isolate, v == 1));
1273
+ }
1274
+
1275
+ void Variable::SetCompressionDeflate(v8::Local<v8::String> property, v8::Local<v8::Value> val,
1276
+ const v8::PropertyCallbackInfo<void> &info)
1277
+ {
1278
+ v8::Isolate *isolate = info.GetIsolate();
1279
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1280
+ if (!val->IsBoolean())
1281
+ {
1282
+ isolate->ThrowException(v8::Exception::TypeError(
1283
+ v8::String::NewFromUtf8(isolate, "Expecting a boolean", v8::NewStringType::kNormal).ToLocalChecked()));
1284
+ return;
1285
+ }
1286
+ #if NODE_MAJOR_VERSION > 11
1287
+ int v = val->BooleanValue(isolate) ? 1 : 0;
1288
+ #else
1289
+ int v = val->BooleanValue() ? 1 : 0;
1290
+ #endif
1291
+ int v1, v2;
1292
+ int retval = nc_inq_var_deflate(obj->parent_id, obj->id, &v1, NULL, &v2);
1293
+ if (retval != NC_NOERR)
1294
+ {
1295
+ throw_netcdf_error(isolate, retval);
1296
+ return;
1297
+ }
1298
+ retval = nc_def_var_deflate(obj->parent_id, obj->id, v1, v, v2);
1299
+ if (retval != NC_NOERR)
1300
+ {
1301
+ throw_netcdf_error(isolate, retval);
1302
+ }
1303
+ }
1304
+
1305
+ void Variable::GetCompressionLevel(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value> &info)
1306
+ {
1307
+ v8::Isolate *isolate = info.GetIsolate();
1308
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1309
+ int v;
1310
+ int retval = nc_inq_var_deflate(obj->parent_id, obj->id, NULL, NULL, &v);
1311
+ if (retval != NC_NOERR)
1312
+ {
1313
+ throw_netcdf_error(isolate, retval);
1314
+ return;
1315
+ }
1316
+ info.GetReturnValue().Set(v8::Integer::New(isolate, v));
1317
+ }
1318
+
1319
+ void Variable::SetCompressionLevel(v8::Local<v8::String> property, v8::Local<v8::Value> val,
1320
+ const v8::PropertyCallbackInfo<void> &info)
1321
+ {
1322
+ v8::Isolate *isolate = info.GetIsolate();
1323
+ Variable *obj = node::ObjectWrap::Unwrap<Variable>(info.Holder());
1324
+ if (!val->IsUint32())
1325
+ {
1326
+ isolate->ThrowException(v8::Exception::TypeError(
1327
+ v8::String::NewFromUtf8(isolate, "Expecting a non-negative integer", v8::NewStringType::kNormal)
1328
+ .ToLocalChecked()));
1329
+ return;
1330
+ }
1331
+ int v = static_cast<int>(val->IntegerValue(isolate->GetCurrentContext()).ToChecked());
1332
+ int v1, v2;
1333
+ int retval = nc_inq_var_deflate(obj->parent_id, obj->id, &v1, &v2, NULL);
1334
+ if (retval != NC_NOERR)
1335
+ {
1336
+ throw_netcdf_error(isolate, retval);
1337
+ return;
1338
+ }
1339
+ retval = nc_def_var_deflate(obj->parent_id, obj->id, v1, v2, v);
1340
+ if (retval != NC_NOERR)
1341
+ {
1342
+ throw_netcdf_error(isolate, retval);
1343
+ }
1344
+ }
1345
+
1346
+ void Variable::Inspect(const v8::FunctionCallbackInfo<v8::Value> &args)
1347
+ {
1348
+ v8::Isolate *isolate = args.GetIsolate();
1349
+ args.GetReturnValue().Set(
1350
+ v8::String::NewFromUtf8(isolate, "[object Variable]", v8::NewStringType::kNormal).ToLocalChecked());
1351
+ }
1352
+ } // namespace nodenetcdfjs