node-ctypes 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -23,12 +23,7 @@ const getNativeModulePath = (moduleName, nativeFile, config = "Release") => {
23
23
  if (process.versions?.electron) {
24
24
  const electronProcess = process;
25
25
  if (electronProcess.resourcesPath) {
26
- const unpackedPath = path.join(
27
- electronProcess.resourcesPath,
28
- "app.asar.unpacked",
29
- "node_modules",
30
- moduleName,
31
- );
26
+ const unpackedPath = path.join(electronProcess.resourcesPath, "app.asar.unpacked", "node_modules", moduleName);
32
27
  if (existsSync(buildPath(unpackedPath))) {
33
28
  return buildPath(unpackedPath);
34
29
  }
@@ -36,9 +31,7 @@ const getNativeModulePath = (moduleName, nativeFile, config = "Release") => {
36
31
  }
37
32
 
38
33
  // Check in current working directory's node_modules
39
- const cwdPath = buildPath(
40
- path.join(process.cwd(), "node_modules", moduleName),
41
- );
34
+ const cwdPath = buildPath(path.join(process.cwd(), "node_modules", moduleName));
42
35
  if (existsSync(cwdPath)) {
43
36
  return cwdPath;
44
37
  }
@@ -58,10 +51,7 @@ const getNativeModulePath = (moduleName, nativeFile, config = "Release") => {
58
51
  }
59
52
  }
60
53
 
61
- throw new Error(
62
- `Native module "${nativeFile}" not found for "${moduleName}". ` +
63
- `Searched in Electron resources, node_modules, and local build.`,
64
- );
54
+ throw new Error(`Native module "${nativeFile}" not found for "${moduleName}". ` + `Searched in Electron resources, node_modules, and local build.`);
65
55
  };
66
56
 
67
57
  // Load the native module
@@ -71,25 +61,13 @@ try {
71
61
  } catch (e) {
72
62
  const platform = process.platform;
73
63
  const arch = process.arch;
74
- nativeModulePath = getNativeModulePath(
75
- "node-ctypes",
76
- `ctypes-${platform}-${arch}.node`,
77
- );
64
+ nativeModulePath = getNativeModulePath("node-ctypes", `ctypes-${platform}-${arch}.node`);
78
65
  }
79
66
  const require = createRequire(path.join(process.cwd(), "index.js"));
80
67
  const native = require(nativeModulePath);
81
68
 
82
69
  // Re-esporta le classi native
83
- const {
84
- Version,
85
- Library,
86
- FFIFunction,
87
- Callback,
88
- ThreadSafeCallback,
89
- CType,
90
- StructType,
91
- ArrayType,
92
- } = native;
70
+ const { Version, Library, FFIFunction, Callback, ThreadSafeCallback, CType, StructType, ArrayType } = native;
93
71
 
94
72
  // Tipi predefiniti
95
73
  const types = native.types;
@@ -112,10 +90,7 @@ function _toNativeType(type) {
112
90
  return type._type;
113
91
  }
114
92
  // Struct/Union classes pass through
115
- if (
116
- typeof type === "function" &&
117
- (type.prototype instanceof Structure || type.prototype instanceof Union)
118
- ) {
93
+ if (typeof type === "function" && (type.prototype instanceof Structure || type.prototype instanceof Union)) {
119
94
  return type;
120
95
  }
121
96
  // Native CType objects pass through
@@ -132,18 +107,6 @@ function _toNativeTypes(types) {
132
107
  return types.map(_toNativeType);
133
108
  }
134
109
 
135
- // ============================================================================
136
- // Type Lookup Tables
137
- // Centralizes type information to avoid duplicated switch statements
138
- // ============================================================================
139
-
140
- // TYPE_READERS removed - using SimpleCData._reader directly
141
-
142
- // TYPE_WRITERS removed - using SimpleCData._writer directly
143
-
144
- /** @type {Map<string, number>} */
145
- // TYPE_SIZES removed - using SimpleCData._size directly
146
-
147
110
  /**
148
111
  * Carica una libreria dinamica
149
112
  * @param {string|null} libPath - Percorso della libreria o null per l'eseguibile corrente
@@ -153,6 +116,62 @@ function load(libPath) {
153
116
  return new Library(libPath);
154
117
  }
155
118
 
119
+ /**
120
+ * Wrapper per funzioni con sintassi Python-like ctypes (argtypes/restype)
121
+ */
122
+ class FunctionWrapper {
123
+ constructor(cdll, name) {
124
+ const argtypes = [];
125
+ let restype = undefined;
126
+ let cachedFunc = null;
127
+
128
+ // Create a function and proxy it to make it callable
129
+ const func = (...args) => {
130
+ if (restype === undefined) {
131
+ throw new Error(`Function ${name}: restype not set`);
132
+ }
133
+ if (!cachedFunc) {
134
+ cachedFunc = cdll.func(name, restype, argtypes);
135
+ }
136
+ return cachedFunc(...args);
137
+ };
138
+
139
+ // Proxy the function to intercept property access
140
+ return new Proxy(func, {
141
+ get(target, prop) {
142
+ if (prop === "argtypes") return argtypes;
143
+ if (prop === "restype") return restype;
144
+ if (prop === "errcheck") return cachedFunc ? cachedFunc.errcheck : undefined;
145
+ return target[prop];
146
+ },
147
+ set(target, prop, value) {
148
+ if (prop === "argtypes") {
149
+ argtypes.splice(0, argtypes.length, ...value);
150
+ cachedFunc = null; // Invalidate cache
151
+ return true;
152
+ }
153
+ if (prop === "restype") {
154
+ restype = value;
155
+ cachedFunc = null; // Invalidate cache
156
+ return true;
157
+ }
158
+ if (prop === "errcheck") {
159
+ if (!cachedFunc) {
160
+ if (restype === undefined) {
161
+ throw new Error(`Function ${name}: restype not set`);
162
+ }
163
+ cachedFunc = cdll.func(name, restype, argtypes);
164
+ }
165
+ cachedFunc.errcheck = value;
166
+ return true;
167
+ }
168
+ target[prop] = value;
169
+ return true;
170
+ },
171
+ });
172
+ }
173
+ }
174
+
156
175
  /**
157
176
  * Wrapper conveniente per CDLL (come in Python ctypes)
158
177
  */
@@ -160,6 +179,18 @@ class CDLL {
160
179
  constructor(libPath) {
161
180
  this._lib = new Library(libPath);
162
181
  this._cache = new Map();
182
+
183
+ // Return a proxy to enable Python-like syntax: libc.abs.argtypes = [...]; libc.abs.restype = ...; libc.abs(...)
184
+ return new Proxy(this, {
185
+ get(target, prop, receiver) {
186
+ // Allow access to existing properties/methods
187
+ if (prop in target || typeof prop !== "string") {
188
+ return Reflect.get(target, prop, receiver);
189
+ }
190
+ // Assume it's a function name from the library
191
+ return new FunctionWrapper(target, prop);
192
+ },
193
+ });
163
194
  }
164
195
 
165
196
  /**
@@ -177,44 +208,99 @@ class CDLL {
177
208
  return this._cache.get(cacheKey);
178
209
  }
179
210
 
180
- const ffiFunc = this._lib.func(
181
- name,
182
- _toNativeType(returnType),
183
- _toNativeTypes(argTypes),
184
- options,
185
- );
186
-
187
- // Crea wrapper minimo ottimizzato
188
- // Estrae ._buffer solo da argomenti che sono oggetti NON-Buffer
189
- const callMethod = function (...args) {
190
- // Process args: extract _buffer from struct proxies
191
- const processedArgs = [];
192
-
193
- for (let i = 0; i < args.length; i++) {
194
- const arg = args[i];
195
- // Check for _buffer FIRST (handles Proxy-wrapped structs)
196
- // This avoids calling Buffer.isBuffer() on Proxy which can cause issues
197
- if (arg && typeof arg === "object") {
198
- // Check for struct proxy FIRST - accessing _buffer on Proxy is safe
199
- // but Buffer.isBuffer(proxy) can cause hangs
200
- if (arg._buffer !== undefined && Buffer.isBuffer(arg._buffer)) {
201
- // Struct proxy or object with _buffer
202
- processedArgs.push(arg._buffer);
203
- } else if (Buffer.isBuffer(arg)) {
204
- // Already a buffer, use directly
205
- processedArgs.push(arg);
211
+ const ffiFunc = this._lib.func(name, _toNativeType(returnType), _toNativeTypes(argTypes), options);
212
+
213
+ // =========================================================================
214
+ // OPTIMIZATION: Create specialized wrapper based on argument types
215
+ // For primitive-only args, bypass the processing loop entirely
216
+ // =========================================================================
217
+
218
+ const argCount = argTypes.length;
219
+
220
+ // Check if all args are primitive types (no structs/buffers that need _buffer extraction)
221
+ const allPrimitive = argTypes.every((t) => {
222
+ if (typeof t === "function" && t._isSimpleCData) {
223
+ // SimpleCData types that are NOT pointers are primitive
224
+ const typeName = t._type;
225
+ return typeName !== "pointer" && typeName !== "char_p" && typeName !== "wchar_p";
226
+ }
227
+ if (typeof t === "string") {
228
+ return t !== "pointer" && t !== "char_p" && t !== "wchar_p" && t !== "void_p";
229
+ }
230
+ // CType objects from native - check if it's a pointer type
231
+ if (t && typeof t === "object" && t.name) {
232
+ return !t.name.includes("pointer") && !t.name.includes("char_p");
233
+ }
234
+ return false;
235
+ });
236
+
237
+ let callMethod;
238
+
239
+ if (argCount === 0) {
240
+ // FAST PATH: No arguments - direct call
241
+ callMethod = function () {
242
+ return ffiFunc.call();
243
+ };
244
+ } else if (allPrimitive) {
245
+ // FAST PATH: All primitive args - direct call without processing
246
+ switch (argCount) {
247
+ case 1:
248
+ callMethod = function (a0) {
249
+ return ffiFunc.call(a0);
250
+ };
251
+ break;
252
+ case 2:
253
+ callMethod = function (a0, a1) {
254
+ return ffiFunc.call(a0, a1);
255
+ };
256
+ break;
257
+ case 3:
258
+ callMethod = function (a0, a1, a2) {
259
+ return ffiFunc.call(a0, a1, a2);
260
+ };
261
+ break;
262
+ case 4:
263
+ callMethod = function (a0, a1, a2, a3) {
264
+ return ffiFunc.call(a0, a1, a2, a3);
265
+ };
266
+ break;
267
+ default:
268
+ // Fallback for many args
269
+ callMethod = function (...args) {
270
+ return ffiFunc.call(...args);
271
+ };
272
+ }
273
+ } else {
274
+ // SLOW PATH: Has buffer/struct args - need to extract _buffer
275
+ callMethod = function (...args) {
276
+ const processedArgs = [];
277
+
278
+ for (let i = 0; i < args.length; i++) {
279
+ const arg = args[i];
280
+ // Check for _buffer FIRST (handles Proxy-wrapped structs)
281
+ // This avoids calling Buffer.isBuffer() on Proxy which can cause issues
282
+ if (arg && typeof arg === "object") {
283
+ // Check for struct proxy FIRST - accessing _buffer on Proxy is safe
284
+ // but Buffer.isBuffer(proxy) can cause hangs
285
+ if (arg._buffer !== undefined && Buffer.isBuffer(arg._buffer)) {
286
+ // Struct proxy or object with _buffer
287
+ processedArgs.push(arg._buffer);
288
+ } else if (Buffer.isBuffer(arg)) {
289
+ // Already a buffer, use directly
290
+ processedArgs.push(arg);
291
+ } else {
292
+ // Other object, pass as-is
293
+ processedArgs.push(arg);
294
+ }
206
295
  } else {
207
- // Other object, pass as-is
296
+ // Primitive value (number, string, bigint, null, undefined)
208
297
  processedArgs.push(arg);
209
298
  }
210
- } else {
211
- // Primitive value (number, string, bigint, null, undefined)
212
- processedArgs.push(arg);
213
299
  }
214
- }
215
300
 
216
- return ffiFunc.call(...processedArgs);
217
- };
301
+ return ffiFunc.call(...processedArgs);
302
+ };
303
+ }
218
304
 
219
305
  // Aggiungi metadata come proprietà non-enumerable per non interferire
220
306
  Object.defineProperties(callMethod, {
@@ -256,11 +342,7 @@ class CDLL {
256
342
  * @returns {Object} Oggetto callback con proprietà pointer e metodi
257
343
  */
258
344
  callback(fn, returnType, argTypes = []) {
259
- return this._lib.callback(
260
- _toNativeType(returnType),
261
- _toNativeTypes(argTypes),
262
- fn,
263
- );
345
+ return this._lib.callback(_toNativeType(returnType), _toNativeTypes(argTypes), fn);
264
346
  }
265
347
 
266
348
  /**
@@ -306,11 +388,7 @@ class WinDLL extends CDLL {
306
388
  * @returns {Object} Oggetto con .pointer (BigInt), .release()
307
389
  */
308
390
  function callback(fn, returnType, argTypes = []) {
309
- const cb = new Callback(
310
- fn,
311
- _toNativeType(returnType),
312
- _toNativeTypes(argTypes),
313
- );
391
+ const cb = new Callback(fn, _toNativeType(returnType), _toNativeTypes(argTypes));
314
392
 
315
393
  return {
316
394
  get pointer() {
@@ -338,11 +416,7 @@ function callback(fn, returnType, argTypes = []) {
338
416
  * @returns {Object} Oggetto con .pointer (BigInt), .release()
339
417
  */
340
418
  function threadSafeCallback(fn, returnType, argTypes = []) {
341
- const cb = new ThreadSafeCallback(
342
- fn,
343
- _toNativeType(returnType),
344
- _toNativeTypes(argTypes),
345
- );
419
+ const cb = new ThreadSafeCallback(fn, _toNativeType(returnType), _toNativeTypes(argTypes));
346
420
 
347
421
  return {
348
422
  get pointer() {
@@ -547,12 +621,7 @@ function sizeof(type) {
547
621
  }
548
622
 
549
623
  // SimpleCData instance (e.g., sizeof(new c_uint64()))
550
- if (
551
- type &&
552
- type._buffer &&
553
- type.constructor &&
554
- type.constructor._isSimpleCData
555
- ) {
624
+ if (type && type._buffer && type.constructor && type.constructor._isSimpleCData) {
556
625
  return type.constructor._size;
557
626
  }
558
627
 
@@ -569,26 +638,16 @@ function sizeof(type) {
569
638
  }
570
639
 
571
640
  // Struct type
572
- if (
573
- typeof type === "object" &&
574
- type !== null &&
575
- typeof type.size === "number"
576
- ) {
641
+ if (typeof type === "object" && type !== null && typeof type.size === "number") {
577
642
  return type.size;
578
643
  }
579
644
 
580
645
  // Array type
581
- if (
582
- typeof type === "object" &&
583
- type !== null &&
584
- typeof type.getSize === "function"
585
- ) {
646
+ if (typeof type === "object" && type !== null && typeof type.getSize === "function") {
586
647
  return type.getSize();
587
648
  }
588
649
 
589
- throw new TypeError(
590
- `sizeof: unsupported type. Use SimpleCData classes like c_int32, c_uint64, etc.`,
591
- );
650
+ throw new TypeError(`sizeof: unsupported type. Use SimpleCData classes like c_int32, c_uint64, etc.`);
592
651
  }
593
652
 
594
653
  /**
@@ -690,8 +749,7 @@ function ptrToBuffer(address, size) {
690
749
  * @returns {Object} Tipo puntatore
691
750
  */
692
751
  function POINTER(baseType) {
693
- const baseSize =
694
- typeof baseType === "object" ? baseType.size : sizeof(baseType);
752
+ const baseSize = typeof baseType === "object" ? baseType.size : sizeof(baseType);
695
753
  const typeName = typeof baseType === "object" ? "struct" : baseType;
696
754
 
697
755
  return {
@@ -794,9 +852,7 @@ function union(fields) {
794
852
  else {
795
853
  // Validate type is a SimpleCData class
796
854
  if (!(typeof type === "function" && type._isSimpleCData)) {
797
- throw new TypeError(
798
- `union field "${name}": type must be a SimpleCData class, struct, union, or array`,
799
- );
855
+ throw new TypeError(`union field "${name}": type must be a SimpleCData class, struct, union, or array`);
800
856
  }
801
857
  size = type._size;
802
858
  alignment = Math.min(size, native.POINTER_SIZE);
@@ -854,13 +910,7 @@ function union(fields) {
854
910
  if (prop === Symbol.iterator) return undefined;
855
911
 
856
912
  // Handle Buffer/TypedArray properties FIRST before field checks
857
- if (
858
- prop === "length" ||
859
- prop === "byteLength" ||
860
- prop === "byteOffset" ||
861
- prop === "buffer" ||
862
- prop === "BYTES_PER_ELEMENT"
863
- ) {
913
+ if (prop === "length" || prop === "byteLength" || prop === "byteOffset" || prop === "buffer" || prop === "BYTES_PER_ELEMENT") {
864
914
  return target[prop];
865
915
  }
866
916
 
@@ -895,10 +945,7 @@ function union(fields) {
895
945
  return fieldDefs.map((f) => f.name);
896
946
  },
897
947
  getOwnPropertyDescriptor(target, prop) {
898
- if (
899
- typeof prop === "string" &&
900
- (fieldMap.has(prop) || prop === "_buffer" || prop === "toObject")
901
- ) {
948
+ if (typeof prop === "string" && (fieldMap.has(prop) || prop === "_buffer" || prop === "toObject")) {
902
949
  return {
903
950
  enumerable: prop !== "_buffer" && prop !== "toObject",
904
951
  configurable: true,
@@ -928,13 +975,7 @@ function union(fields) {
928
975
 
929
976
  // Bit field
930
977
  if (field.isBitField) {
931
- return _readBitField(
932
- buf,
933
- field.offset,
934
- field.type,
935
- field.bitOffset,
936
- field.bitSize,
937
- );
978
+ return _readBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize);
938
979
  }
939
980
 
940
981
  // Nested struct
@@ -948,19 +989,11 @@ function union(fields) {
948
989
  if (prop === Symbol.toStringTag) return "NestedUnionInstance";
949
990
  if (prop === Symbol.iterator) return undefined;
950
991
  // Handle Buffer/TypedArray properties
951
- if (
952
- prop === "length" ||
953
- prop === "byteLength" ||
954
- prop === "byteOffset" ||
955
- prop === "buffer" ||
956
- prop === "BYTES_PER_ELEMENT"
957
- ) {
992
+ if (prop === "length" || prop === "byteLength" || prop === "byteOffset" || prop === "buffer" || prop === "BYTES_PER_ELEMENT") {
958
993
  return target[prop];
959
994
  }
960
995
  if (typeof prop === "string" && field.type.fields) {
961
- if (
962
- field.type.fields.some((f) => f.name === prop && !f.isAnonymous)
963
- ) {
996
+ if (field.type.fields.some((f) => f.name === prop && !f.isAnonymous)) {
964
997
  return field.type.get(target, prop);
965
998
  }
966
999
  }
@@ -970,9 +1003,7 @@ function union(fields) {
970
1003
  },
971
1004
  set(target, prop, value, receiver) {
972
1005
  if (typeof prop === "string" && field.type.fields) {
973
- if (
974
- field.type.fields.some((f) => f.name === prop && !f.isAnonymous)
975
- ) {
1006
+ if (field.type.fields.some((f) => f.name === prop && !f.isAnonymous)) {
976
1007
  field.type.set(target, prop, value);
977
1008
  return true;
978
1009
  }
@@ -987,16 +1018,10 @@ function union(fields) {
987
1018
  return Reflect.has(target, prop);
988
1019
  },
989
1020
  ownKeys(target) {
990
- return (field.type.fields || [])
991
- .filter((f) => !f.isAnonymous)
992
- .map((f) => f.name);
1021
+ return (field.type.fields || []).filter((f) => !f.isAnonymous).map((f) => f.name);
993
1022
  },
994
1023
  getOwnPropertyDescriptor(target, prop) {
995
- if (
996
- typeof prop === "string" &&
997
- field.type.fields &&
998
- field.type.fields.some((f) => f.name === prop)
999
- ) {
1024
+ if (typeof prop === "string" && field.type.fields && field.type.fields.some((f) => f.name === prop)) {
1000
1025
  return {
1001
1026
  enumerable: true,
1002
1027
  configurable: true,
@@ -1010,9 +1035,7 @@ function union(fields) {
1010
1035
 
1011
1036
  // Array
1012
1037
  if (field.isArray) {
1013
- return field.type.wrap(
1014
- buf.subarray(field.offset, field.offset + field.size),
1015
- );
1038
+ return field.type.wrap(buf.subarray(field.offset, field.offset + field.size));
1016
1039
  }
1017
1040
 
1018
1041
  // Tipo base
@@ -1038,14 +1061,7 @@ function union(fields) {
1038
1061
 
1039
1062
  // Bit field
1040
1063
  if (field.isBitField) {
1041
- _writeBitField(
1042
- buf,
1043
- field.offset,
1044
- field.type,
1045
- field.bitOffset,
1046
- field.bitSize,
1047
- value,
1048
- );
1064
+ _writeBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize, value);
1049
1065
  return;
1050
1066
  }
1051
1067
 
@@ -1054,10 +1070,7 @@ function union(fields) {
1054
1070
  if (Buffer.isBuffer(value)) {
1055
1071
  value.copy(buf, field.offset, 0, field.size);
1056
1072
  } else if (typeof value === "object") {
1057
- const nestedBuf = buf.subarray(
1058
- field.offset,
1059
- field.offset + field.size,
1060
- );
1073
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
1061
1074
  for (const [k, v] of Object.entries(value)) {
1062
1075
  field.type.set(nestedBuf, k, v);
1063
1076
  }
@@ -1070,9 +1083,7 @@ function union(fields) {
1070
1083
  if (Buffer.isBuffer(value)) {
1071
1084
  value.copy(buf, field.offset, 0, field.size);
1072
1085
  } else if (Array.isArray(value)) {
1073
- const wrapped = field.type.wrap(
1074
- buf.subarray(field.offset, field.offset + field.size),
1075
- );
1086
+ const wrapped = field.type.wrap(buf.subarray(field.offset, field.offset + field.size));
1076
1087
  for (let i = 0; i < Math.min(value.length, field.type.length); i++) {
1077
1088
  wrapped[i] = value[i];
1078
1089
  }
@@ -1090,11 +1101,7 @@ function union(fields) {
1090
1101
  toObject(bufOrObj) {
1091
1102
  // Se è già un object (non buffer), ritorna così com'è
1092
1103
  if (!Buffer.isBuffer(bufOrObj)) {
1093
- if (
1094
- bufOrObj &&
1095
- bufOrObj._buffer &&
1096
- bufOrObj._buffer.length === maxSize
1097
- ) {
1104
+ if (bufOrObj && bufOrObj._buffer && bufOrObj._buffer.length === maxSize) {
1098
1105
  return bufOrObj; // Già convertito
1099
1106
  }
1100
1107
  // Se è un plain object, convertilo in union
@@ -1128,13 +1135,7 @@ function union(fields) {
1128
1135
  Object.defineProperty(obj, field.name, {
1129
1136
  get() {
1130
1137
  if (field.isBitField) {
1131
- return _readBitField(
1132
- buf,
1133
- 0,
1134
- field.type,
1135
- field.bitOffset,
1136
- field.bitSize,
1137
- );
1138
+ return _readBitField(buf, 0, field.type, field.bitOffset, field.bitSize);
1138
1139
  } else if (field.isNested) {
1139
1140
  // Cache nested objects per evitare di ricrearli ogni volta
1140
1141
  if (!nestedCache.has(field.name)) {
@@ -1152,14 +1153,7 @@ function union(fields) {
1152
1153
  },
1153
1154
  set(value) {
1154
1155
  if (field.isBitField) {
1155
- _writeBitField(
1156
- buf,
1157
- 0,
1158
- field.type,
1159
- field.bitOffset,
1160
- field.bitSize,
1161
- value,
1162
- );
1156
+ _writeBitField(buf, 0, field.type, field.bitOffset, field.bitSize, value);
1163
1157
  } else {
1164
1158
  writeValue(buf, field.type, value, 0);
1165
1159
  }
@@ -1229,12 +1223,7 @@ class Structure {
1229
1223
  buf.fill(0);
1230
1224
 
1231
1225
  // Support positional args: new Point(10,20)
1232
- if (
1233
- args.length === 1 &&
1234
- typeof args[0] === "object" &&
1235
- !Array.isArray(args[0]) &&
1236
- !Buffer.isBuffer(args[0])
1237
- ) {
1226
+ if (args.length === 1 && typeof args[0] === "object" && !Array.isArray(args[0]) && !Buffer.isBuffer(args[0])) {
1238
1227
  const initial = args[0];
1239
1228
  for (const [k, v] of Object.entries(initial)) {
1240
1229
  def.set(buf, k, v);
@@ -1312,8 +1301,7 @@ class Structure {
1312
1301
  return Reflect.set(target, prop, value, receiver);
1313
1302
  },
1314
1303
  has(target, prop) {
1315
- if (prop === "_buffer" || prop === "_structDef" || prop === "toObject")
1316
- return true;
1304
+ if (prop === "_buffer" || prop === "_structDef" || prop === "toObject") return true;
1317
1305
  if (typeof prop === "string" && fieldMap.has(prop)) return true;
1318
1306
  if (typeof prop === "string" && anonFieldNames.has(prop)) return true;
1319
1307
  return Reflect.has(target, prop);
@@ -1332,10 +1320,7 @@ class Structure {
1332
1320
  return keys;
1333
1321
  },
1334
1322
  getOwnPropertyDescriptor(target, prop) {
1335
- if (
1336
- typeof prop === "string" &&
1337
- (fieldMap.has(prop) || anonFieldNames.has(prop))
1338
- ) {
1323
+ if (typeof prop === "string" && (fieldMap.has(prop) || anonFieldNames.has(prop))) {
1339
1324
  return {
1340
1325
  enumerable: true,
1341
1326
  configurable: true,
@@ -1465,19 +1450,11 @@ class Structure {
1465
1450
 
1466
1451
  // Direct typed array access for numeric fields (maximum performance)
1467
1452
  getInt32Array(offset = 0, length) {
1468
- return new Int32Array(
1469
- this.__buffer.buffer,
1470
- this.__buffer.byteOffset + offset,
1471
- length,
1472
- );
1453
+ return new Int32Array(this.__buffer.buffer, this.__buffer.byteOffset + offset, length);
1473
1454
  }
1474
1455
 
1475
1456
  getFloat64Array(offset = 0, length) {
1476
- return new Float64Array(
1477
- this.__buffer.buffer,
1478
- this.__buffer.byteOffset + offset,
1479
- length,
1480
- );
1457
+ return new Float64Array(this.__buffer.buffer, this.__buffer.byteOffset + offset, length);
1481
1458
  }
1482
1459
 
1483
1460
  // Get raw buffer slice for external operations
@@ -1545,9 +1522,7 @@ class Union extends Structure {
1545
1522
  function array(elementType, count) {
1546
1523
  // Validate elementType is a SimpleCData class
1547
1524
  if (!(typeof elementType === "function" && elementType._isSimpleCData)) {
1548
- throw new TypeError(
1549
- "array elementType must be a SimpleCData class (e.g., c_int32, c_uint8)",
1550
- );
1525
+ throw new TypeError("array elementType must be a SimpleCData class (e.g., c_int32, c_uint8)");
1551
1526
  }
1552
1527
 
1553
1528
  const elementSize = elementType._size;
@@ -1666,12 +1641,7 @@ function array(elementType, count) {
1666
1641
  }
1667
1642
  } else if (typeof values === "string") {
1668
1643
  for (let i = 0; i < Math.min(values.length, count); i++) {
1669
- writeValue(
1670
- buffer,
1671
- elementType,
1672
- values.charCodeAt(i),
1673
- i * sizeof(elementType),
1674
- );
1644
+ writeValue(buffer, elementType, values.charCodeAt(i), i * sizeof(elementType));
1675
1645
  }
1676
1646
  }
1677
1647
  return wrap(buffer);
@@ -1786,15 +1756,7 @@ function _initWinError() {
1786
1756
  _win_error_funcs = {
1787
1757
  GetLastError: kernel32.func("GetLastError", c_uint32, []),
1788
1758
  SetLastError: kernel32.func("SetLastError", c_void, [c_uint32]),
1789
- FormatMessageW: kernel32.func("FormatMessageW", c_uint32, [
1790
- c_uint32,
1791
- c_void_p,
1792
- c_uint32,
1793
- c_uint32,
1794
- c_void_p,
1795
- c_uint32,
1796
- c_void_p,
1797
- ]),
1759
+ FormatMessageW: kernel32.func("FormatMessageW", c_uint32, [c_uint32, c_void_p, c_uint32, c_uint32, c_void_p, c_uint32, c_void_p]),
1798
1760
  _lib: kernel32,
1799
1761
  };
1800
1762
  } catch (e) {
@@ -1893,9 +1855,7 @@ function bitfield(baseType, bits) {
1893
1855
  const maxBits = baseSize * 8;
1894
1856
 
1895
1857
  if (bits < 1 || bits > maxBits) {
1896
- throw new Error(
1897
- `Bit field size must be between 1 and ${maxBits} for ${baseType}`,
1898
- );
1858
+ throw new Error(`Bit field size must be between 1 and ${maxBits} for ${baseType}`);
1899
1859
  }
1900
1860
 
1901
1861
  return {
@@ -1910,22 +1870,14 @@ function bitfield(baseType, bits) {
1910
1870
  * Helper per verificare se un tipo è una struct
1911
1871
  */
1912
1872
  function _isStruct(type) {
1913
- return (
1914
- typeof type === "object" &&
1915
- type !== null &&
1916
- typeof type.size === "number" &&
1917
- Array.isArray(type.fields) &&
1918
- typeof type.create === "function"
1919
- );
1873
+ return typeof type === "object" && type !== null && typeof type.size === "number" && Array.isArray(type.fields) && typeof type.create === "function";
1920
1874
  }
1921
1875
 
1922
1876
  /**
1923
1877
  * Helper per verificare se un tipo è un array type
1924
1878
  */
1925
1879
  function _isArrayType(type) {
1926
- return (
1927
- typeof type === "object" && type !== null && type._isArrayType === true
1928
- );
1880
+ return typeof type === "object" && type !== null && type._isArrayType === true;
1929
1881
  }
1930
1882
 
1931
1883
  /**
@@ -2007,8 +1959,7 @@ function _writeBitField(buf, offset, baseType, bitOffset, bitSize, newValue) {
2007
1959
  if (baseSize === 8) {
2008
1960
  const mask = (1n << BigInt(bitSize)) - 1n;
2009
1961
  const clearMask = ~(mask << BigInt(bitOffset));
2010
- value =
2011
- (value & clearMask) | ((BigInt(newValue) & mask) << BigInt(bitOffset));
1962
+ value = (value & clearMask) | ((BigInt(newValue) & mask) << BigInt(bitOffset));
2012
1963
  } else {
2013
1964
  const mask = (1 << bitSize) - 1;
2014
1965
  const clearMask = ~(mask << bitOffset);
@@ -2046,12 +1997,7 @@ function struct(fields, options = {}) {
2046
1997
  let fieldDef;
2047
1998
 
2048
1999
  // Caso 0: Anonymous field - { type: SomeStruct, anonymous: true }
2049
- if (
2050
- typeof type === "object" &&
2051
- type !== null &&
2052
- type.anonymous === true &&
2053
- type.type
2054
- ) {
2000
+ if (typeof type === "object" && type !== null && type.anonymous === true && type.type) {
2055
2001
  // Reset bit field state
2056
2002
  currentBitFieldBase = null;
2057
2003
  currentBitOffset = 0;
@@ -2087,9 +2033,7 @@ function struct(fields, options = {}) {
2087
2033
  const alignment = packed ? 1 : Math.min(baseSize, native.POINTER_SIZE);
2088
2034
 
2089
2035
  // Verifica se possiamo continuare nel bit field corrente
2090
- const canContinue =
2091
- currentBitFieldBase === baseType &&
2092
- currentBitOffset + bits <= baseSize * 8;
2036
+ const canContinue = currentBitFieldBase === baseType && currentBitOffset + bits <= baseSize * 8;
2093
2037
 
2094
2038
  if (!canContinue) {
2095
2039
  // Inizia un nuovo bit field
@@ -2190,9 +2134,7 @@ function struct(fields, options = {}) {
2190
2134
 
2191
2135
  // Validate type is a SimpleCData class
2192
2136
  if (!(typeof type === "function" && type._isSimpleCData)) {
2193
- throw new TypeError(
2194
- `struct field "${name}": type must be a SimpleCData class, struct, union, or array`,
2195
- );
2137
+ throw new TypeError(`struct field "${name}": type must be a SimpleCData class, struct, union, or array`);
2196
2138
  }
2197
2139
 
2198
2140
  const size = type._size;
@@ -2252,9 +2194,7 @@ function struct(fields, options = {}) {
2252
2194
  if (fieldType && fieldType._isSimpleCData) {
2253
2195
  const fieldOffset = offset; // Capture offset for closure
2254
2196
  fieldReaders.set(name, (buf) => fieldType._reader(buf, fieldOffset));
2255
- fieldWriters.set(name, (buf, val) =>
2256
- fieldType._writer(buf, fieldOffset, val),
2257
- );
2197
+ fieldWriters.set(name, (buf, val) => fieldType._writer(buf, fieldOffset, val));
2258
2198
  }
2259
2199
  }
2260
2200
 
@@ -2303,13 +2243,7 @@ function struct(fields, options = {}) {
2303
2243
 
2304
2244
  // Handle Buffer/TypedArray properties FIRST before field checks
2305
2245
  // TypedArray methods need direct access to avoid Proxy interference
2306
- if (
2307
- prop === "length" ||
2308
- prop === "byteLength" ||
2309
- prop === "byteOffset" ||
2310
- prop === "buffer" ||
2311
- prop === "BYTES_PER_ELEMENT"
2312
- ) {
2246
+ if (prop === "length" || prop === "byteLength" || prop === "byteOffset" || prop === "buffer" || prop === "BYTES_PER_ELEMENT") {
2313
2247
  return target[prop];
2314
2248
  }
2315
2249
 
@@ -2394,10 +2328,7 @@ function struct(fields, options = {}) {
2394
2328
  return keys;
2395
2329
  },
2396
2330
  getOwnPropertyDescriptor(target, prop) {
2397
- if (
2398
- typeof prop === "string" &&
2399
- (fieldMap.has(prop) || prop === "_buffer" || prop === "toObject")
2400
- ) {
2331
+ if (typeof prop === "string" && (fieldMap.has(prop) || prop === "_buffer" || prop === "toObject")) {
2401
2332
  return {
2402
2333
  enumerable: prop !== "_buffer" && prop !== "toObject",
2403
2334
  configurable: true,
@@ -2469,47 +2400,28 @@ function struct(fields, options = {}) {
2469
2400
  if (field) {
2470
2401
  // Bit field
2471
2402
  if (field.isBitField) {
2472
- return _readBitField(
2473
- buf,
2474
- field.offset,
2475
- field.type,
2476
- field.bitOffset,
2477
- field.bitSize,
2478
- );
2403
+ return _readBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize);
2479
2404
  }
2480
2405
 
2481
2406
  // Nested struct (senza dot = ritorna intero oggetto)
2482
2407
  if (field.isNested) {
2483
- const nestedBuf = buf.subarray(
2484
- field.offset,
2485
- field.offset + field.size,
2486
- );
2408
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
2487
2409
  // Proxy-based nested instance
2488
2410
  return field.type.create
2489
2411
  ? // Se ha create(), usa quello per creare il proxy
2490
2412
  new Proxy(nestedBuf, {
2491
2413
  get(target, prop, receiver) {
2492
2414
  if (prop === "_buffer") return target;
2493
- if (prop === "toObject")
2494
- return () => field.type.toObject(target);
2495
- if (prop === Symbol.toStringTag)
2496
- return "NestedStructInstance";
2415
+ if (prop === "toObject") return () => field.type.toObject(target);
2416
+ if (prop === Symbol.toStringTag) return "NestedStructInstance";
2497
2417
  if (prop === Symbol.iterator) return undefined;
2498
2418
  // Handle Buffer/TypedArray properties
2499
- if (
2500
- prop === "length" ||
2501
- prop === "byteLength" ||
2502
- prop === "byteOffset" ||
2503
- prop === "buffer" ||
2504
- prop === "BYTES_PER_ELEMENT"
2505
- ) {
2419
+ if (prop === "length" || prop === "byteLength" || prop === "byteOffset" || prop === "buffer" || prop === "BYTES_PER_ELEMENT") {
2506
2420
  return target[prop];
2507
2421
  }
2508
2422
  if (typeof prop === "string") {
2509
2423
  // Check direct fields
2510
- const nestedFieldMap = field.type.fields
2511
- ? new Map(field.type.fields.map((f) => [f.name, f]))
2512
- : new Map();
2424
+ const nestedFieldMap = field.type.fields ? new Map(field.type.fields.map((f) => [f.name, f])) : new Map();
2513
2425
  if (nestedFieldMap.has(prop)) {
2514
2426
  return field.type.get(target, prop);
2515
2427
  }
@@ -2528,9 +2440,7 @@ function struct(fields, options = {}) {
2528
2440
  },
2529
2441
  set(target, prop, value, receiver) {
2530
2442
  if (typeof prop === "string") {
2531
- const nestedFieldMap = field.type.fields
2532
- ? new Map(field.type.fields.map((f) => [f.name, f]))
2533
- : new Map();
2443
+ const nestedFieldMap = field.type.fields ? new Map(field.type.fields.map((f) => [f.name, f])) : new Map();
2534
2444
  if (nestedFieldMap.has(prop)) {
2535
2445
  field.type.set(target, prop, value);
2536
2446
  return true;
@@ -2550,8 +2460,7 @@ function struct(fields, options = {}) {
2550
2460
  has(target, prop) {
2551
2461
  if (prop === "_buffer" || prop === "toObject") return true;
2552
2462
  if (typeof prop === "string" && field.type.fields) {
2553
- if (field.type.fields.some((f) => f.name === prop))
2554
- return true;
2463
+ if (field.type.fields.some((f) => f.name === prop)) return true;
2555
2464
  }
2556
2465
  return Reflect.has(target, prop);
2557
2466
  },
@@ -2559,11 +2468,7 @@ function struct(fields, options = {}) {
2559
2468
  return (field.type.fields || []).map((f) => f.name);
2560
2469
  },
2561
2470
  getOwnPropertyDescriptor(target, prop) {
2562
- if (
2563
- typeof prop === "string" &&
2564
- field.type.fields &&
2565
- field.type.fields.some((f) => f.name === prop)
2566
- ) {
2471
+ if (typeof prop === "string" && field.type.fields && field.type.fields.some((f) => f.name === prop)) {
2567
2472
  return {
2568
2473
  enumerable: true,
2569
2474
  configurable: true,
@@ -2578,10 +2483,7 @@ function struct(fields, options = {}) {
2578
2483
 
2579
2484
  // Array field
2580
2485
  if (field.isArray) {
2581
- const arrayBuf = buf.subarray(
2582
- field.offset,
2583
- field.offset + field.size,
2584
- );
2486
+ const arrayBuf = buf.subarray(field.offset, field.offset + field.size);
2585
2487
  return field.type.wrap(arrayBuf);
2586
2488
  }
2587
2489
 
@@ -2599,9 +2501,7 @@ function struct(fields, options = {}) {
2599
2501
  if (!field) {
2600
2502
  for (const f of fieldDefs) {
2601
2503
  if (f.isAnonymous && f.type && f.type.fields) {
2602
- const hasField = f.type.fields.some(
2603
- (subField) => subField.name === firstPart,
2604
- );
2504
+ const hasField = f.type.fields.some((subField) => subField.name === firstPart);
2605
2505
  if (hasField) {
2606
2506
  const nestedBuf = buf.subarray(f.offset, f.offset + f.size);
2607
2507
  return f.type.get(nestedBuf, fieldName);
@@ -2650,14 +2550,7 @@ function struct(fields, options = {}) {
2650
2550
  if (field) {
2651
2551
  // Bit field
2652
2552
  if (field.isBitField) {
2653
- _writeBitField(
2654
- buf,
2655
- field.offset,
2656
- field.type,
2657
- field.bitOffset,
2658
- field.bitSize,
2659
- value,
2660
- );
2553
+ _writeBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize, value);
2661
2554
  return;
2662
2555
  }
2663
2556
 
@@ -2666,10 +2559,7 @@ function struct(fields, options = {}) {
2666
2559
  if (Buffer.isBuffer(value)) {
2667
2560
  value.copy(buf, field.offset, 0, field.size);
2668
2561
  } else if (typeof value === "object") {
2669
- const nestedBuf = buf.subarray(
2670
- field.offset,
2671
- field.offset + field.size,
2672
- );
2562
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
2673
2563
  for (const [k, v] of Object.entries(value)) {
2674
2564
  field.type.set(nestedBuf, k, v);
2675
2565
  }
@@ -2682,16 +2572,9 @@ function struct(fields, options = {}) {
2682
2572
  if (Buffer.isBuffer(value)) {
2683
2573
  value.copy(buf, field.offset, 0, field.size);
2684
2574
  } else if (Array.isArray(value)) {
2685
- const arrayBuf = buf.subarray(
2686
- field.offset,
2687
- field.offset + field.size,
2688
- );
2575
+ const arrayBuf = buf.subarray(field.offset, field.offset + field.size);
2689
2576
  const wrapped = field.type.wrap(arrayBuf);
2690
- for (
2691
- let i = 0;
2692
- i < Math.min(value.length, field.type.length);
2693
- i++
2694
- ) {
2577
+ for (let i = 0; i < Math.min(value.length, field.type.length); i++) {
2695
2578
  wrapped[i] = value[i];
2696
2579
  }
2697
2580
  }
@@ -2714,9 +2597,7 @@ function struct(fields, options = {}) {
2714
2597
  for (const f of fieldDefs) {
2715
2598
  if (f.isAnonymous && f.type && f.type.fields) {
2716
2599
  // Verifica se il campo esiste nel tipo anonimo
2717
- const hasField = f.type.fields.some(
2718
- (subField) => subField.name === firstPart,
2719
- );
2600
+ const hasField = f.type.fields.some((subField) => subField.name === firstPart);
2720
2601
  if (hasField) {
2721
2602
  // Scrive nel campo dell'anonymous field
2722
2603
  const nestedBuf = buf.subarray(f.offset, f.offset + f.size);
@@ -2730,14 +2611,7 @@ function struct(fields, options = {}) {
2730
2611
 
2731
2612
  // Bit field
2732
2613
  if (field.isBitField) {
2733
- _writeBitField(
2734
- buf,
2735
- field.offset,
2736
- field.type,
2737
- field.bitOffset,
2738
- field.bitSize,
2739
- value,
2740
- );
2614
+ _writeBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize, value);
2741
2615
  return;
2742
2616
  }
2743
2617
 
@@ -2745,20 +2619,14 @@ function struct(fields, options = {}) {
2745
2619
  if (field.isNested) {
2746
2620
  if (parts.length > 1) {
2747
2621
  // Accesso a campo annidato singolo
2748
- const nestedBuf = buf.subarray(
2749
- field.offset,
2750
- field.offset + field.size,
2751
- );
2622
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
2752
2623
  field.type.set(nestedBuf, parts.slice(1).join("."), value);
2753
2624
  } else if (Buffer.isBuffer(value)) {
2754
2625
  // Copia buffer
2755
2626
  value.copy(buf, field.offset, 0, field.size);
2756
2627
  } else if (typeof value === "object") {
2757
2628
  // Imposta campi da oggetto
2758
- const nestedBuf = buf.subarray(
2759
- field.offset,
2760
- field.offset + field.size,
2761
- );
2629
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
2762
2630
  for (const [k, v] of Object.entries(value)) {
2763
2631
  field.type.set(nestedBuf, k, v);
2764
2632
  }
@@ -2773,10 +2641,7 @@ function struct(fields, options = {}) {
2773
2641
  value.copy(buf, field.offset, 0, field.size);
2774
2642
  } else if (Array.isArray(value)) {
2775
2643
  // Inizializza da array JavaScript
2776
- const arrayBuf = buf.subarray(
2777
- field.offset,
2778
- field.offset + field.size,
2779
- );
2644
+ const arrayBuf = buf.subarray(field.offset, field.offset + field.size);
2780
2645
  const wrapped = field.type.wrap(arrayBuf);
2781
2646
  for (let i = 0; i < Math.min(value.length, field.type.length); i++) {
2782
2647
  wrapped[i] = value[i];
@@ -2819,18 +2684,9 @@ function struct(fields, options = {}) {
2819
2684
  // Leggi tutti i campi in una volta (eager approach)
2820
2685
  for (const field of fieldDefs) {
2821
2686
  if (field.isBitField) {
2822
- result[field.name] = _readBitField(
2823
- buf,
2824
- field.offset,
2825
- field.type,
2826
- field.bitOffset,
2827
- field.bitSize,
2828
- );
2687
+ result[field.name] = _readBitField(buf, field.offset, field.type, field.bitOffset, field.bitSize);
2829
2688
  } else if (field.isNested) {
2830
- const nestedBuf = buf.subarray(
2831
- field.offset,
2832
- field.offset + field.size,
2833
- );
2689
+ const nestedBuf = buf.subarray(field.offset, field.offset + field.size);
2834
2690
  const nestedObj = field.type.toObject(nestedBuf);
2835
2691
  if (field.isAnonymous) {
2836
2692
  // Anonymous fields: promote their fields to parent level
@@ -2839,10 +2695,7 @@ function struct(fields, options = {}) {
2839
2695
  result[field.name] = nestedObj;
2840
2696
  }
2841
2697
  } else if (field.isArray) {
2842
- const arrayBuf = buf.subarray(
2843
- field.offset,
2844
- field.offset + field.size,
2845
- );
2698
+ const arrayBuf = buf.subarray(field.offset, field.offset + field.size);
2846
2699
  result[field.name] = field.type.wrap(arrayBuf);
2847
2700
  } else {
2848
2701
  // Tipo base - lettura diretta
@@ -2863,8 +2716,7 @@ function struct(fields, options = {}) {
2863
2716
  // O(1) lookup con Map
2864
2717
  const field = fieldMap.get(fieldName);
2865
2718
  if (!field) throw new Error(`Unknown field: ${fieldName}`);
2866
- if (!field.isNested)
2867
- throw new Error(`Field ${fieldName} is not a nested struct`);
2719
+ if (!field.isNested) throw new Error(`Field ${fieldName} is not a nested struct`);
2868
2720
  return buf.subarray(field.offset, field.offset + field.size);
2869
2721
  },
2870
2722
  };
@@ -2876,10 +2728,7 @@ function struct(fields, options = {}) {
2876
2728
  structDef._cppStructType = cppStructType;
2877
2729
  } catch (e) {
2878
2730
  // Se fallisce, continua senza C++ (fallback a JS)
2879
- console.warn(
2880
- "Failed to create C++ StructType, using JavaScript fallback:",
2881
- e.message,
2882
- );
2731
+ console.warn("Failed to create C++ StructType, using JavaScript fallback:", e.message);
2883
2732
  }
2884
2733
 
2885
2734
  // fromObject: write plain object values into buffer
@@ -3140,10 +2989,7 @@ class c_wchar extends SimpleCData {
3140
2989
  class c_void_p extends SimpleCData {
3141
2990
  static _size = native.POINTER_SIZE;
3142
2991
  static _type = "pointer";
3143
- static _reader = (buf, off) =>
3144
- native.POINTER_SIZE === 8
3145
- ? buf.readBigUInt64LE(off)
3146
- : BigInt(buf.readUInt32LE(off));
2992
+ static _reader = (buf, off) => (native.POINTER_SIZE === 8 ? buf.readBigUInt64LE(off) : BigInt(buf.readUInt32LE(off)));
3147
2993
  static _writer = (buf, off, val) => {
3148
2994
  // Accept Buffers (pointer to memory) and struct proxies with _buffer
3149
2995
  if (Buffer.isBuffer(val)) {
@@ -3153,12 +2999,7 @@ class c_void_p extends SimpleCData {
3153
2999
  else buf.writeUInt32LE(Number(v), off);
3154
3000
  return;
3155
3001
  }
3156
- if (
3157
- val &&
3158
- typeof val === "object" &&
3159
- val._buffer &&
3160
- Buffer.isBuffer(val._buffer)
3161
- ) {
3002
+ if (val && typeof val === "object" && val._buffer && Buffer.isBuffer(val._buffer)) {
3162
3003
  const addr = addressOf(val._buffer);
3163
3004
  const v = typeof addr === "bigint" ? addr : BigInt(addr || 0);
3164
3005
  if (native.POINTER_SIZE === 8) buf.writeBigUInt64LE(v, off);
@@ -3179,10 +3020,7 @@ class c_void_p extends SimpleCData {
3179
3020
  class c_size_t extends SimpleCData {
3180
3021
  static _size = native.POINTER_SIZE;
3181
3022
  static _type = "size_t";
3182
- static _reader = (buf, off) =>
3183
- native.POINTER_SIZE === 8
3184
- ? buf.readBigUInt64LE(off)
3185
- : BigInt(buf.readUInt32LE(off));
3023
+ static _reader = (buf, off) => (native.POINTER_SIZE === 8 ? buf.readBigUInt64LE(off) : BigInt(buf.readUInt32LE(off)));
3186
3024
  static _writer = (buf, off, val) => {
3187
3025
  const v = typeof val === "bigint" ? val : BigInt(val || 0);
3188
3026
  if (native.POINTER_SIZE === 8) {
@@ -3202,27 +3040,15 @@ const _longSize = native.sizeof ? native.sizeof("long") : 4;
3202
3040
  class c_long extends SimpleCData {
3203
3041
  static _size = _longSize;
3204
3042
  static _type = "long";
3205
- static _reader =
3206
- _longSize === 8
3207
- ? (buf, off) => buf.readBigInt64LE(off)
3208
- : (buf, off) => buf.readInt32LE(off);
3209
- static _writer =
3210
- _longSize === 8
3211
- ? (buf, off, val) => buf.writeBigInt64LE(BigInt(val), off)
3212
- : (buf, off, val) => buf.writeInt32LE(val, off);
3043
+ static _reader = _longSize === 8 ? (buf, off) => buf.readBigInt64LE(off) : (buf, off) => buf.readInt32LE(off);
3044
+ static _writer = _longSize === 8 ? (buf, off, val) => buf.writeBigInt64LE(BigInt(val), off) : (buf, off, val) => buf.writeInt32LE(val, off);
3213
3045
  }
3214
3046
 
3215
3047
  class c_ulong extends SimpleCData {
3216
3048
  static _size = _longSize;
3217
3049
  static _type = "ulong";
3218
- static _reader =
3219
- _longSize === 8
3220
- ? (buf, off) => buf.readBigUInt64LE(off)
3221
- : (buf, off) => buf.readUInt32LE(off);
3222
- static _writer =
3223
- _longSize === 8
3224
- ? (buf, off, val) => buf.writeBigUInt64LE(BigInt(val), off)
3225
- : (buf, off, val) => buf.writeUInt32LE(val, off);
3050
+ static _reader = _longSize === 8 ? (buf, off) => buf.readBigUInt64LE(off) : (buf, off) => buf.readUInt32LE(off);
3051
+ static _writer = _longSize === 8 ? (buf, off, val) => buf.writeBigUInt64LE(BigInt(val), off) : (buf, off, val) => buf.writeUInt32LE(val, off);
3226
3052
  }
3227
3053
 
3228
3054
  // ============================================================================
@@ -3232,10 +3058,7 @@ class c_ulong extends SimpleCData {
3232
3058
  class c_char_p extends SimpleCData {
3233
3059
  static _size = native.POINTER_SIZE;
3234
3060
  static _type = "char_p";
3235
- static _reader = (buf, off) =>
3236
- native.POINTER_SIZE === 8
3237
- ? buf.readBigUInt64LE(off)
3238
- : BigInt(buf.readUInt32LE(off));
3061
+ static _reader = (buf, off) => (native.POINTER_SIZE === 8 ? buf.readBigUInt64LE(off) : BigInt(buf.readUInt32LE(off)));
3239
3062
  static _writer = (buf, off, val) => {
3240
3063
  if (Buffer.isBuffer(val)) {
3241
3064
  const addr = addressOf(val);
@@ -3259,10 +3082,7 @@ class c_char_p extends SimpleCData {
3259
3082
  class c_wchar_p extends SimpleCData {
3260
3083
  static _size = native.POINTER_SIZE;
3261
3084
  static _type = "wchar_p";
3262
- static _reader = (buf, off) =>
3263
- native.POINTER_SIZE === 8
3264
- ? buf.readBigUInt64LE(off)
3265
- : BigInt(buf.readUInt32LE(off));
3085
+ static _reader = (buf, off) => (native.POINTER_SIZE === 8 ? buf.readBigUInt64LE(off) : BigInt(buf.readUInt32LE(off)));
3266
3086
  static _writer = (buf, off, val) => {
3267
3087
  if (Buffer.isBuffer(val)) {
3268
3088
  const addr = addressOf(val);
@@ -3319,9 +3139,7 @@ function create_string_buffer(init) {
3319
3139
  buf[init.length] = 0; // null terminator
3320
3140
  return buf;
3321
3141
  }
3322
- throw new TypeError(
3323
- "create_string_buffer requires number, string, or Buffer",
3324
- );
3142
+ throw new TypeError("create_string_buffer requires number, string, or Buffer");
3325
3143
  }
3326
3144
 
3327
3145
  /**