node-ctypes 0.1.7 → 1.0.0

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.

Potentially problematic release.


This version of node-ctypes might be problematic. Click here for more details.

@@ -0,0 +1,465 @@
1
+ /**
2
+ * @file union.js
3
+ * @module structures/union
4
+ * @description Union type definition implementation for C-style unions.
5
+ *
6
+ * This module provides Python ctypes-compatible union types where all fields
7
+ * share the same memory location (offset 0). The union size is the maximum
8
+ * size of all fields, with proper alignment.
9
+ *
10
+ * **Python ctypes Compatibility**:
11
+ * Similar to Python's `ctypes.Union` class with `_fields_` definition.
12
+ *
13
+ * @example Basic union
14
+ * ```javascript
15
+ * import { union, c_int32, c_float } from 'node-ctypes';
16
+ *
17
+ * const Value = union({
18
+ * asInt: c_int32,
19
+ * asFloat: c_float
20
+ * });
21
+ *
22
+ * const val = Value.create();
23
+ * val.asInt = 0x3F800000;
24
+ * console.log(val.asFloat); // 1.0 (same memory, different interpretation)
25
+ * ```
26
+ *
27
+ * @example Union with nested types
28
+ * ```javascript
29
+ * const Data = union({
30
+ * bytes: array(c_uint8, 8),
31
+ * int64: c_int64,
32
+ * floats: array(c_float, 2)
33
+ * });
34
+ * ```
35
+ */
36
+
37
+ import { _readBitField, _writeBitField } from "./bitfield.js";
38
+
39
+ /**
40
+ * Creates a union type definition where all fields share offset 0.
41
+ *
42
+ * Returns a union definition object with methods to create instances,
43
+ * read/write fields, and convert to/from JavaScript objects. All fields
44
+ * in a union share the same memory location.
45
+ *
46
+ * **Python ctypes Compatibility**:
47
+ * Similar to Python's `Union` class with `_fields_` attribute.
48
+ *
49
+ * @param {Object} fields - Field definitions { name: type, ... }
50
+ * @param {Function} sizeof - sizeof function reference
51
+ * @param {Function} alloc - alloc function reference
52
+ * @param {Function} readValue - readValue function reference
53
+ * @param {Function} writeValue - writeValue function reference
54
+ * @param {Function} _isStruct - _isStruct function reference
55
+ * @param {Function} _isArrayType - _isArrayType function reference
56
+ * @param {Function} _isBitField - _isBitField function reference
57
+ * @param {Function} Structure - Structure class reference
58
+ * @param {Function} Union - Union class reference
59
+ * @param {Object} native - Native module reference
60
+ * @returns {Object} Union definition with create, get, set, toObject methods
61
+ * @throws {TypeError} If field types are invalid
62
+ *
63
+ * @example Create union with different interpretations
64
+ * ```javascript
65
+ * const Value = union({
66
+ * asInt: c_int32,
67
+ * asFloat: c_float,
68
+ * bytes: array(c_uint8, 4)
69
+ * });
70
+ *
71
+ * const val = Value.create({ asInt: 1065353216 });
72
+ * console.log(val.asFloat); // 1.0
73
+ * console.log([...val.bytes]); // [0, 0, 128, 63]
74
+ * ```
75
+ *
76
+ * @example Union with structs
77
+ * ```javascript
78
+ * class Point extends Structure {
79
+ * static _fields_ = [['x', c_int32], ['y', c_int32]];
80
+ * }
81
+ *
82
+ * const Variant = union({
83
+ * point: Point,
84
+ * int64: c_int64
85
+ * });
86
+ * ```
87
+ */
88
+ export function union(fields, sizeof, alloc, readValue, writeValue, _isStruct, _isArrayType, _isBitField, Structure, Union, native) {
89
+ let maxSize = 0;
90
+ let maxAlignment = 1;
91
+ const fieldDefs = [];
92
+
93
+ for (const [name, type] of Object.entries(fields)) {
94
+ let size, alignment;
95
+ let fieldDef = { name, type, offset: 0 };
96
+
97
+ // Nested struct (object form)
98
+ if (_isStruct(type)) {
99
+ size = type.size;
100
+ alignment = type.alignment;
101
+ fieldDef.isNested = true;
102
+ }
103
+ // Struct class (declarata come `class X extends Structure`)
104
+ else if (typeof type === "function" && type.prototype instanceof Structure) {
105
+ const nested = type._structDef || type._buildStruct();
106
+ size = nested.size;
107
+ alignment = nested.alignment;
108
+ fieldDef.type = nested;
109
+ fieldDef.isNested = true;
110
+ }
111
+ // Union class (declarata come `class X extends Union`)
112
+ else if (typeof type === "function" && type.prototype instanceof Union) {
113
+ const nested = type._unionDef || type._buildUnion();
114
+ size = nested.size;
115
+ alignment = nested.alignment;
116
+ fieldDef.type = nested;
117
+ fieldDef.isNested = true;
118
+ }
119
+ // Array type
120
+ else if (_isArrayType(type)) {
121
+ size = type.getSize();
122
+ const elemSize = sizeof(type.elementType);
123
+ alignment = Math.min(elemSize, native.POINTER_SIZE);
124
+ fieldDef.isArray = true;
125
+ }
126
+ // Bit field - in union ogni bitfield occupa l'intero baseType
127
+ else if (_isBitField(type)) {
128
+ size = type.baseSize;
129
+ alignment = Math.min(size, native.POINTER_SIZE);
130
+ fieldDef.isBitField = true;
131
+ fieldDef.bitOffset = 0;
132
+ fieldDef.bitSize = type.bits;
133
+ fieldDef.baseSize = type.baseSize;
134
+ fieldDef.type = type.baseType; // Usa il tipo base per lettura/scrittura
135
+ }
136
+ // Tipo base (SimpleCData)
137
+ else {
138
+ // Validate type is a SimpleCData class
139
+ if (!(typeof type === "function" && type._isSimpleCData)) {
140
+ throw new TypeError(`union field "${name}": type must be a SimpleCData class, struct, union, or array`);
141
+ }
142
+ size = type._size;
143
+ alignment = Math.min(size, native.POINTER_SIZE);
144
+ fieldDef.type = type;
145
+ }
146
+
147
+ fieldDef.size = size;
148
+ fieldDef.alignment = alignment;
149
+ fieldDefs.push(fieldDef);
150
+
151
+ if (size > maxSize) {
152
+ maxSize = size;
153
+ }
154
+ if (alignment > maxAlignment) {
155
+ maxAlignment = alignment;
156
+ }
157
+ }
158
+
159
+ // Padding finale per allineamento
160
+ if (maxSize % maxAlignment !== 0) {
161
+ maxSize += maxAlignment - (maxSize % maxAlignment);
162
+ }
163
+
164
+ // Crea Map per lookup O(1)
165
+ const fieldMap = new Map();
166
+ for (const field of fieldDefs) {
167
+ fieldMap.set(field.name, field);
168
+ }
169
+
170
+ const unionDef = {
171
+ size: maxSize,
172
+ alignment: maxAlignment,
173
+ fields: fieldDefs,
174
+ isUnion: true,
175
+ _isStructType: true, // Per compatibilità con _isStruct()
176
+
177
+ create(values = {}) {
178
+ const buf = alloc(maxSize);
179
+ buf.fill(0);
180
+
181
+ // Prima imposta i campi diretti
182
+ for (const field of fieldDefs) {
183
+ if (values[field.name] !== undefined) {
184
+ unionDef.set(buf, field.name, values[field.name]);
185
+ }
186
+ }
187
+
188
+ // Proxy-based instance (single Proxy instead of N defineProperty calls)
189
+ return new Proxy(buf, {
190
+ get(target, prop, receiver) {
191
+ // Special properties
192
+ if (prop === "_buffer") return target;
193
+ if (prop === "toObject") return () => unionDef.toObject(target);
194
+ if (prop === Symbol.toStringTag) return "UnionInstance";
195
+ if (prop === Symbol.iterator) return undefined;
196
+
197
+ // Handle Buffer/TypedArray properties FIRST before field checks
198
+ if (prop === "length" || prop === "byteLength" || prop === "byteOffset" || prop === "buffer" || prop === "BYTES_PER_ELEMENT") {
199
+ return target[prop];
200
+ }
201
+
202
+ // Check if it's a known field
203
+ if (typeof prop === "string" && fieldMap.has(prop)) {
204
+ return unionDef.get(target, prop);
205
+ }
206
+
207
+ // Fallback to buffer properties and methods
208
+ const value = target[prop];
209
+ if (typeof value === "function") {
210
+ return value.bind(target);
211
+ }
212
+ return value;
213
+ },
214
+ set(target, prop, value, receiver) {
215
+ // Check if it's a known field
216
+ if (typeof prop === "string" && fieldMap.has(prop)) {
217
+ unionDef.set(target, prop, value);
218
+ return true;
219
+ }
220
+
221
+ // Fallback
222
+ return Reflect.set(target, prop, value, receiver);
223
+ },
224
+ has(target, prop) {
225
+ if (prop === "_buffer" || prop === "toObject") return true;
226
+ if (typeof prop === "string" && fieldMap.has(prop)) return true;
227
+ return Reflect.has(target, prop);
228
+ },
229
+ ownKeys(target) {
230
+ return fieldDefs.map((f) => f.name);
231
+ },
232
+ getOwnPropertyDescriptor(target, prop) {
233
+ if (typeof prop === "string" && (fieldMap.has(prop) || prop === "_buffer" || prop === "toObject")) {
234
+ return {
235
+ enumerable: prop !== "_buffer" && prop !== "toObject",
236
+ configurable: true,
237
+ writable: true,
238
+ };
239
+ }
240
+ return Reflect.getOwnPropertyDescriptor(target, prop);
241
+ },
242
+ });
243
+ },
244
+
245
+ get(bufOrObj, fieldName) {
246
+ // NUOVO: supporta sia buffer che object wrapper
247
+ let buf;
248
+ if (Buffer.isBuffer(bufOrObj)) {
249
+ buf = bufOrObj;
250
+ } else if (bufOrObj && bufOrObj._buffer) {
251
+ // Object wrapper - accesso diretto tramite property
252
+ return bufOrObj[fieldName];
253
+ } else {
254
+ throw new TypeError("Expected Buffer or union instance");
255
+ }
256
+
257
+ // O(1) lookup con Map
258
+ const field = fieldMap.get(fieldName);
259
+ if (!field) throw new Error(`Unknown field: ${fieldName}`);
260
+
261
+ // Bit field
262
+ if (field.isBitField) {
263
+ return _readBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize, sizeof);
264
+ }
265
+
266
+ // Nested struct
267
+ if (field.isNested) {
268
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
269
+ // Proxy-based nested instance
270
+ return new Proxy(nestedBuf, {
271
+ get(target, prop, receiver) {
272
+ if (prop === "_buffer") return target;
273
+ if (prop === "toObject") return () => field.type.toObject(target);
274
+ if (prop === Symbol.toStringTag) return "NestedUnionInstance";
275
+ if (prop === Symbol.iterator) return undefined;
276
+ // Handle Buffer/TypedArray properties
277
+ if (prop === "length" || prop === "byteLength" || prop === "byteOffset" || prop === "buffer" || prop === "BYTES_PER_ELEMENT") {
278
+ return target[prop];
279
+ }
280
+ if (typeof prop === "string" && field.type.fields) {
281
+ if (field.type.fields.some((f) => f.name === prop && !f.isAnonymous)) {
282
+ return field.type.get(target, prop);
283
+ }
284
+ }
285
+ const value = target[prop];
286
+ if (typeof value === "function") return value.bind(target);
287
+ return value;
288
+ },
289
+ set(target, prop, value, receiver) {
290
+ if (typeof prop === "string" && field.type.fields) {
291
+ if (field.type.fields.some((f) => f.name === prop && !f.isAnonymous)) {
292
+ field.type.set(target, prop, value);
293
+ return true;
294
+ }
295
+ }
296
+ return Reflect.set(target, prop, value, receiver);
297
+ },
298
+ has(target, prop) {
299
+ if (prop === "_buffer" || prop === "toObject") return true;
300
+ if (typeof prop === "string" && field.type.fields) {
301
+ if (field.type.fields.some((f) => f.name === prop)) return true;
302
+ }
303
+ return Reflect.has(target, prop);
304
+ },
305
+ ownKeys(target) {
306
+ return (field.type.fields || []).filter((f) => !f.isAnonymous).map((f) => f.name);
307
+ },
308
+ getOwnPropertyDescriptor(target, prop) {
309
+ if (typeof prop === "string" && field.type.fields && field.type.fields.some((f) => f.name === prop)) {
310
+ return {
311
+ enumerable: true,
312
+ configurable: true,
313
+ writable: true,
314
+ };
315
+ }
316
+ return Reflect.getOwnPropertyDescriptor(target, prop);
317
+ },
318
+ });
319
+ }
320
+
321
+ // Array
322
+ if (field.isArray) {
323
+ return field.type.wrap(buf.subarray(field.offset, field.offset + field.size));
324
+ }
325
+
326
+ // Tipo base
327
+ return readValue(buf, field.type, field.offset);
328
+ },
329
+
330
+ set(bufOrObj, fieldName, value) {
331
+ // NUOVO: supporta sia buffer che object wrapper
332
+ let buf;
333
+ if (Buffer.isBuffer(bufOrObj)) {
334
+ buf = bufOrObj;
335
+ } else if (bufOrObj && bufOrObj._buffer) {
336
+ // Object wrapper - accesso diretto tramite property
337
+ bufOrObj[fieldName] = value;
338
+ return;
339
+ } else {
340
+ throw new TypeError("Expected Buffer or union instance");
341
+ }
342
+
343
+ // Lookup with Map
344
+ const field = fieldMap.get(fieldName);
345
+ if (!field) throw new Error(`Unknown field: ${fieldName}`);
346
+
347
+ // Bit field
348
+ if (field.isBitField) {
349
+ _writeBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize, value, sizeof);
350
+ return;
351
+ }
352
+
353
+ // Nested struct
354
+ if (field.isNested) {
355
+ if (Buffer.isBuffer(value)) {
356
+ value.copy(buf, field.offset, 0, field.size);
357
+ } else if (typeof value === "object") {
358
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
359
+ for (const [k, v] of Object.entries(value)) {
360
+ field.type.set(nestedBuf, k, v);
361
+ }
362
+ }
363
+ return;
364
+ }
365
+
366
+ // Array
367
+ if (field.isArray) {
368
+ if (Buffer.isBuffer(value)) {
369
+ value.copy(buf, field.offset, 0, field.size);
370
+ } else if (Array.isArray(value)) {
371
+ const wrapped = field.type.wrap(buf.subarray(field.offset, field.offset + field.size));
372
+ for (let i = 0; i < Math.min(value.length, field.type.length); i++) {
373
+ wrapped[i] = value[i];
374
+ }
375
+ } else if (value && value._buffer && Buffer.isBuffer(value._buffer)) {
376
+ // Handle array proxy instances
377
+ value._buffer.copy(buf, field.offset, 0, field.size);
378
+ }
379
+ return;
380
+ }
381
+
382
+ // Tipo base
383
+ writeValue(buf, field.type, value, field.offset);
384
+ },
385
+
386
+ toObject(bufOrObj) {
387
+ // Se è già un object (non buffer), ritorna così com'è
388
+ if (!Buffer.isBuffer(bufOrObj)) {
389
+ if (bufOrObj && bufOrObj._buffer && bufOrObj._buffer.length === maxSize) {
390
+ return bufOrObj; // Già convertito
391
+ }
392
+ // Se è un plain object, convertilo in union
393
+ if (typeof bufOrObj === "object") {
394
+ const buf = alloc(maxSize);
395
+ buf.fill(0);
396
+ for (const [name, value] of Object.entries(bufOrObj)) {
397
+ unionDef.set(buf, name, value);
398
+ }
399
+ return unionDef.toObject(buf);
400
+ }
401
+ throw new TypeError("Expected Buffer or union instance");
402
+ }
403
+
404
+ const buf = bufOrObj;
405
+ const obj = {};
406
+
407
+ // Cache per oggetti nested (struct/union) per evitare di ricrearli ogni volta
408
+ const nestedCache = new Map();
409
+
410
+ // Aggiungi _buffer come property nascosta
411
+ Object.defineProperty(obj, "_buffer", {
412
+ value: buf,
413
+ writable: false,
414
+ enumerable: false,
415
+ configurable: false,
416
+ });
417
+
418
+ // Per union, tutte le properties leggono/scrivono all'offset 0
419
+ for (const field of fieldDefs) {
420
+ Object.defineProperty(obj, field.name, {
421
+ get() {
422
+ if (field.isBitField) {
423
+ return _readBitField(buf, 0, field.type, field.bitOffset, field.bitSize, sizeof);
424
+ } else if (field.isNested) {
425
+ // Cache nested objects per evitare di ricrearli ogni volta
426
+ if (!nestedCache.has(field.name)) {
427
+ const nestedBuf = buf.subarray(0, field.size);
428
+ const nestedObj = field.type.toObject(nestedBuf);
429
+ nestedCache.set(field.name, nestedObj);
430
+ }
431
+ return nestedCache.get(field.name);
432
+ } else if (field.isArray) {
433
+ const wrapped = field.type.wrap(buf.subarray(0, field.size));
434
+ return [...wrapped];
435
+ } else {
436
+ return readValue(buf, field.type, 0);
437
+ }
438
+ },
439
+ set(value) {
440
+ if (field.isBitField) {
441
+ _writeBitField(buf, 0, field.type, field.bitOffset, field.bitSize, value, sizeof);
442
+ } else {
443
+ writeValue(buf, field.type, value, 0);
444
+ }
445
+ },
446
+ enumerable: true,
447
+ configurable: false,
448
+ });
449
+ }
450
+
451
+ return obj;
452
+ },
453
+
454
+ // fromObject: write plain object values into buffer
455
+ fromObject: function (buf, obj) {
456
+ for (const [key, value] of Object.entries(obj)) {
457
+ if (this.fields.some((f) => f.name === key)) {
458
+ this.set(buf, key, value);
459
+ }
460
+ }
461
+ },
462
+ };
463
+
464
+ return unionDef;
465
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @file SimpleCData.js
3
+ * @module types/SimpleCData
4
+ * @description SimpleCData base class for primitive C types.
5
+ *
6
+ * This module provides the `SimpleCData` base class that serves as the foundation
7
+ * for all primitive C types (integers, floats, chars, pointers). It handles
8
+ * memory allocation, value reading/writing, and provides Python ctypes-compatible
9
+ * methods.
10
+ *
11
+ * **Python ctypes Compatibility**:
12
+ * Direct equivalent to Python's `ctypes._SimpleCData` base class.
13
+ *
14
+ * @example Creating custom type
15
+ * ```javascript
16
+ * import { SimpleCData } from 'node-ctypes';
17
+ *
18
+ * class c_int32 extends SimpleCData {
19
+ * static _size = 4;
20
+ * static _type = 'int32';
21
+ * static _reader = (buf, off) => buf.readInt32LE(off);
22
+ * static _writer = (buf, off, val) => buf.writeInt32LE(val, off);
23
+ * }
24
+ *
25
+ * const x = new c_int32(42);
26
+ * console.log(x.value); // 42
27
+ * x.value = 100;
28
+ * console.log(x.value); // 100
29
+ * ```
30
+ *
31
+ * @example Using from_buffer (zero-copy)
32
+ * ```javascript
33
+ * const buffer = Buffer.from([0x2A, 0x00, 0x00, 0x00]); // 42 in LE
34
+ * const x = c_int32.from_buffer(buffer, 0);
35
+ * console.log(x.value); // 42
36
+ * x.value = 100; // Modifies original buffer!
37
+ * console.log(buffer); // [0x64, 0x00, 0x00, 0x00]
38
+ * ```
39
+ *
40
+ * @example Using from_buffer_copy
41
+ * ```javascript
42
+ * const buffer = Buffer.from([0x2A, 0x00, 0x00, 0x00]);
43
+ * const x = c_int32.from_buffer_copy(buffer, 0);
44
+ * x.value = 100; // Does NOT modify original buffer
45
+ * console.log(buffer); // Still [0x2A, 0x00, 0x00, 0x00]
46
+ * ```
47
+ */
48
+
49
+ /**
50
+ * Creates the SimpleCData base class with required dependencies injected.
51
+ *
52
+ * @param {Function} alloc - Memory allocation function
53
+ * @returns {Class} SimpleCData base class
54
+ * @private
55
+ */
56
+ export function createSimpleCDataClass(alloc) {
57
+ /**
58
+ * SimpleCData base class for primitive C types.
59
+ *
60
+ * Subclasses must define:
61
+ * - `static _size`: Size in bytes
62
+ * - `static _type`: Type name string
63
+ * - `static _reader(buffer, offset)`: Function to read value from buffer
64
+ * - `static _writer(buffer, offset, value)`: Function to write value to buffer
65
+ *
66
+ * **Python ctypes Compatibility**:
67
+ * Similar to Python's `ctypes._SimpleCData` with:
68
+ * - `.value` property for get/set
69
+ * - `.size` property
70
+ * - `from_buffer()` for zero-copy wrapping
71
+ * - `from_buffer_copy()` for copied data
72
+ *
73
+ * @class SimpleCData
74
+ *
75
+ * @example Integer type
76
+ * ```javascript
77
+ * class c_uint8 extends SimpleCData {
78
+ * static _size = 1;
79
+ * static _type = 'uint8';
80
+ * static _reader = (buf, off) => buf.readUInt8(off);
81
+ * static _writer = (buf, off, val) => buf.writeUInt8(val, off);
82
+ * }
83
+ *
84
+ * const byte = new c_uint8(255);
85
+ * console.log(byte.value); // 255
86
+ * console.log(byte.size); // 1
87
+ * console.log(byte.toString()); // "c_uint8(255)"
88
+ * ```
89
+ *
90
+ * @example Float type
91
+ * ```javascript
92
+ * class c_float extends SimpleCData {
93
+ * static _size = 4;
94
+ * static _type = 'float';
95
+ * static _reader = (buf, off) => buf.readFloatLE(off);
96
+ * static _writer = (buf, off, val) => buf.writeFloatLE(val, off);
97
+ * }
98
+ *
99
+ * const pi = new c_float(3.14159);
100
+ * console.log(pi.value); // 3.1415898799896240
101
+ * ```
102
+ */
103
+ class SimpleCData {
104
+ /**
105
+ * @param {number|bigint} [value] - Initial value (default: 0)
106
+ */
107
+ constructor(value) {
108
+ const Ctor = this.constructor;
109
+ this._buffer = alloc(Ctor._size);
110
+ if (value !== undefined && value !== null) {
111
+ this.value = value;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Get the current value
117
+ */
118
+ get value() {
119
+ const Ctor = this.constructor;
120
+ return Ctor._reader(this._buffer, 0);
121
+ }
122
+
123
+ /**
124
+ * Set the value
125
+ */
126
+ set value(v) {
127
+ const Ctor = this.constructor;
128
+ Ctor._writer(this._buffer, 0, v);
129
+ }
130
+
131
+ /**
132
+ * Size of the type in bytes (instance property)
133
+ */
134
+ get size() {
135
+ return this.constructor._size;
136
+ }
137
+
138
+ /**
139
+ * Create instance from existing buffer (Python ctypes compatible)
140
+ * WARNING: Returns a VIEW into the buffer, not a copy!
141
+ * @param {Buffer} buffer - Source buffer
142
+ * @param {number} [offset=0] - Offset in buffer
143
+ * @returns {SimpleCData} New instance wrapping the buffer slice
144
+ */
145
+ static from_buffer(buffer, offset = 0) {
146
+ if (!Buffer.isBuffer(buffer)) {
147
+ throw new TypeError("from_buffer requires a Buffer");
148
+ }
149
+ const inst = Object.create(this.prototype);
150
+ inst._buffer = buffer.subarray(offset, offset + this._size);
151
+ return inst;
152
+ }
153
+
154
+ /**
155
+ * Create instance from a COPY of buffer data (Python ctypes compatible)
156
+ * @param {Buffer} buffer - Source buffer
157
+ * @param {number} [offset=0] - Offset in buffer
158
+ * @returns {SimpleCData} New instance with copied data
159
+ */
160
+ static from_buffer_copy(buffer, offset = 0) {
161
+ if (!Buffer.isBuffer(buffer)) {
162
+ throw new TypeError("from_buffer_copy requires a Buffer");
163
+ }
164
+ const inst = new this();
165
+ buffer.copy(inst._buffer, 0, offset, offset + this._size);
166
+ return inst;
167
+ }
168
+
169
+ /**
170
+ * Size of the type in bytes (static property)
171
+ */
172
+ static get size() {
173
+ return this._size;
174
+ }
175
+
176
+ toString() {
177
+ return `${this.constructor.name}(${this.value})`;
178
+ }
179
+
180
+ toJSON() {
181
+ const v = this.value;
182
+ return typeof v === "bigint" ? v.toString() : v;
183
+ }
184
+
185
+ valueOf() {
186
+ return this.value;
187
+ }
188
+ }
189
+
190
+ SimpleCData._isSimpleCData = true;
191
+
192
+ return SimpleCData;
193
+ }