utilium 1.7.10 → 1.7.12

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.
@@ -27,4 +27,16 @@ type LoggableDecoratorContext = Exclude<DecoratorContext, ClassFieldDecoratorCon
27
27
  * Create a function that can be used to decorate classes and non-field members.
28
28
  */
29
29
  export declare function createLogDecorator(options: CreateLoggerOptions): <T extends (...args: any[]) => any>(value: T, context: LoggableDecoratorContext) => T;
30
+ /**
31
+ * @internal @hidden
32
+ */
33
+ export declare let U_DEBUG: boolean;
34
+ /**
35
+ * @internal @hidden
36
+ */
37
+ export declare function _setDebug(value: boolean): void;
38
+ /**
39
+ * @internal @hidden
40
+ */
41
+ export declare function _debugLog(...text: any[]): void;
30
42
  export {};
package/dist/debugging.js CHANGED
@@ -53,3 +53,20 @@ export function createLogDecorator(options) {
53
53
  };
54
54
  };
55
55
  }
56
+ /**
57
+ * @internal @hidden
58
+ */
59
+ export let U_DEBUG = 'process' in globalThis && 'env' in globalThis.process && globalThis.process.env.U_DEBUG == 'true';
60
+ /**
61
+ * @internal @hidden
62
+ */
63
+ export function _setDebug(value) {
64
+ U_DEBUG = value;
65
+ }
66
+ /**
67
+ * @internal @hidden
68
+ */
69
+ export function _debugLog(...text) {
70
+ if (U_DEBUG)
71
+ console.debug('[U]', ...text);
72
+ }
@@ -10,7 +10,7 @@ declare global {
10
10
  readonly deserialize: unique symbol;
11
11
  }
12
12
  }
13
- export type TypeLike = Custom | Like | primitive.Valid;
13
+ export type TypeLike = Custom | Like | primitive.Valid | undefined | null;
14
14
  export type Type = Custom | Static | primitive.Typename;
15
15
  /**
16
16
  * Member initialization data
@@ -30,22 +30,31 @@ export interface Options {
30
30
  isUnion: boolean;
31
31
  }
32
32
  export interface Member {
33
+ name: string;
33
34
  type: Type;
34
- offset: number;
35
+ staticOffset: number;
35
36
  length?: number | string;
37
+ /** A C-style type/name declaration string, used for diagnostics */
38
+ decl: string;
36
39
  }
37
40
  export interface Metadata {
38
41
  options: Partial<Options>;
39
42
  members: Map<string, Member>;
40
- init?: MemberInit[];
41
43
  staticSize: number;
44
+ isDynamic: boolean;
42
45
  }
43
46
  type _DecoratorMetadata<T extends Metadata = Metadata> = DecoratorMetadata & {
44
- struct?: Partial<T>;
47
+ struct?: T;
48
+ structInit?: MemberInit[];
45
49
  };
46
50
  export interface DecoratorContext<T extends Metadata = Metadata> {
47
51
  metadata: _DecoratorMetadata<T>;
48
52
  }
53
+ /**
54
+ * Initializes the struct metadata for a class
55
+ * This also handles copying metadata from parent classes
56
+ */
57
+ export declare function initMetadata(context: DecoratorContext): MemberInit[];
49
58
  export type MemberContext = ClassMemberDecoratorContext & DecoratorContext;
50
59
  export interface Static<T extends Metadata = Metadata> {
51
60
  [Symbol.metadata]: {
@@ -63,12 +72,9 @@ export declare function isValidMetadata<T extends Metadata = Metadata>(arg: unkn
63
72
  /**
64
73
  * Polyfill context.metadata
65
74
  * @see https://github.com/microsoft/TypeScript/issues/53461
75
+ * @internal @hidden
66
76
  */
67
- export declare function _polyfill_contextMetadata(target: object): void;
68
- /**
69
- * Gets a reference to Symbol.metadata, even on platforms that do not expose it globally (like Node)
70
- */
71
- export declare function symbol_metadata(arg: ClassLike): typeof Symbol.metadata;
77
+ export declare function _polyfill_metadata(target: object): void;
72
78
  export declare function isStatic<T extends Metadata = Metadata>(arg: unknown): arg is Static<T>;
73
79
  export interface Instance<T extends Metadata = Metadata> {
74
80
  constructor: Static<T>;
@@ -90,7 +96,7 @@ export interface Custom {
90
96
  }
91
97
  export declare function isCustom(arg: unknown): arg is Custom;
92
98
  export type Like<T extends Metadata = Metadata> = InstanceLike<T> | StaticLike<T>;
93
- export type Size<T extends TypeLike> = T extends {
94
- readonly [Symbol.size]: infer S;
99
+ export type Size<T extends TypeLike> = T extends undefined | null ? 0 : T extends {
100
+ readonly [Symbol.size]: infer S extends number;
95
101
  } ? S : T extends primitive.Valid ? primitive.Size<T> : number;
96
102
  export {};
@@ -1,22 +1,32 @@
1
+ /**
2
+ * Polyfill Symbol.metadata
3
+ * @see https://github.com/microsoft/TypeScript/issues/53461
4
+ */
5
+ Symbol.metadata ??= Symbol.for('Symbol.metadata');
1
6
  Object.assign(Symbol, {
2
7
  size: Symbol('uSize'),
3
8
  serialize: Symbol('uSerialize'),
4
9
  deserialize: Symbol('uDeserialize'),
5
10
  });
11
+ /**
12
+ * Initializes the struct metadata for a class
13
+ * This also handles copying metadata from parent classes
14
+ */
15
+ export function initMetadata(context) {
16
+ context.metadata ??= {};
17
+ context.metadata.structInit = [...(context.metadata.structInit ?? [])];
18
+ return context.metadata.structInit;
19
+ }
6
20
  export function isValidMetadata(arg) {
7
21
  return arg != null && typeof arg == 'object' && 'struct' in arg;
8
22
  }
9
- /**
10
- * Polyfill Symbol.metadata
11
- * @see https://github.com/microsoft/TypeScript/issues/53461
12
- */
13
- Symbol.metadata ??= Symbol.for('Symbol.metadata');
14
23
  /**
15
24
  * Polyfill context.metadata
16
25
  * @see https://github.com/microsoft/TypeScript/issues/53461
26
+ * @internal @hidden
17
27
  */
18
- export function _polyfill_contextMetadata(target) {
19
- if (!Symbol?.metadata || Symbol.metadata in target)
28
+ export function _polyfill_metadata(target) {
29
+ if (Symbol.metadata in target)
20
30
  return;
21
31
  Object.defineProperty(target, Symbol.metadata, {
22
32
  enumerable: true,
@@ -25,21 +35,8 @@ export function _polyfill_contextMetadata(target) {
25
35
  value: Object.create(null),
26
36
  });
27
37
  }
28
- /**
29
- * Gets a reference to Symbol.metadata, even on platforms that do not expose it globally (like Node)
30
- */
31
- export function symbol_metadata(arg) {
32
- const symbol_metadata = Symbol.metadata || Object.getOwnPropertySymbols(arg).find(s => s.description == 'Symbol.metadata');
33
- _polyfill_contextMetadata(arg);
34
- if (!symbol_metadata) {
35
- throw new ReferenceError('Could not get a reference to Symbol.metadata');
36
- }
37
- return symbol_metadata;
38
- }
39
38
  export function isStatic(arg) {
40
- return (typeof arg == 'function'
41
- && symbol_metadata(arg) in arg
42
- && isValidMetadata(arg[symbol_metadata(arg)]));
39
+ return typeof arg == 'function' && Symbol.metadata in arg && isValidMetadata(arg[Symbol.metadata]);
43
40
  }
44
41
  export function isInstance(arg) {
45
42
  return arg != null && typeof arg == 'object' && isStatic(arg.constructor);
package/dist/struct.d.ts CHANGED
@@ -5,7 +5,7 @@ export * as Struct from './internal/struct.js';
5
5
  /**
6
6
  * Gets the size in bytes of a type
7
7
  */
8
- export declare function sizeof<T extends TypeLike>(type: T): Size<T>;
8
+ export declare function sizeof<T extends TypeLike>(type: T | T[]): Size<T>;
9
9
  /**
10
10
  * Returns the offset (in bytes) of a member in a struct.
11
11
  */
package/dist/struct.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { toUint8Array } from './buffer.js';
2
+ import { _debugLog } from './debugging.js';
2
3
  import * as primitive from './internal/primitives.js';
3
- import { checkInstance, checkStruct, isCustom, isStatic, symbol_metadata } from './internal/struct.js';
4
+ import { _polyfill_metadata, checkInstance, checkStruct, initMetadata, isCustom, isInstance, isStatic, } from './internal/struct.js';
4
5
  import { _throw } from './misc.js';
5
6
  import { capitalize } from './string.js';
6
7
  export * as Struct from './internal/struct.js';
@@ -8,6 +9,15 @@ export * as Struct from './internal/struct.js';
8
9
  * Gets the size in bytes of a type
9
10
  */
10
11
  export function sizeof(type) {
12
+ if (type === undefined || type === null)
13
+ return 0;
14
+ if (Array.isArray(type)) {
15
+ let size = 0;
16
+ for (let i = 0; i < type.length; i++) {
17
+ size += sizeof(type[i]);
18
+ }
19
+ return size;
20
+ }
11
21
  // primitive
12
22
  if (typeof type == 'string') {
13
23
  primitive.checkValid(type);
@@ -16,20 +26,40 @@ export function sizeof(type) {
16
26
  if (isCustom(type))
17
27
  return type[Symbol.size];
18
28
  checkStruct(type);
19
- const struct = isStatic(type) ? type : type.constructor;
20
- return struct[symbol_metadata(struct)].struct.staticSize;
29
+ const constructor = isStatic(type) ? type : type.constructor;
30
+ _polyfill_metadata(constructor);
31
+ const { struct } = constructor[Symbol.metadata];
32
+ if (isStatic(type))
33
+ return struct.staticSize;
34
+ let size = struct.staticSize;
35
+ for (const member of struct.members.values()) {
36
+ if (typeof member.length != 'string')
37
+ continue;
38
+ for (let i = 0; i < type[member.length]; i++) {
39
+ size += sizeof(type[member.name][i]);
40
+ }
41
+ }
42
+ return size;
21
43
  }
22
44
  /**
23
45
  * Returns the offset (in bytes) of a member in a struct.
24
46
  */
25
47
  export function offsetof(type, memberName) {
26
48
  checkStruct(type);
27
- const struct = isStatic(type) ? type : type.constructor;
28
- const metadata = struct[symbol_metadata(struct)].struct;
29
- const member = metadata.members.get(memberName);
30
- if (!member)
31
- throw new Error('Struct does not have member: ' + memberName);
32
- return member.offset;
49
+ const constructor = isStatic(type) ? type : type.constructor;
50
+ _polyfill_metadata(constructor);
51
+ const { struct } = constructor[Symbol.metadata];
52
+ if (isStatic(type) || !struct.isDynamic) {
53
+ return (struct.members.get(memberName)?.staticOffset
54
+ ?? _throw(new Error('Struct does not have member: ' + memberName)));
55
+ }
56
+ let offset = 0;
57
+ for (const member of struct.members.values()) {
58
+ if (member.name == memberName)
59
+ return offset;
60
+ offset += sizeof(type[member.name]);
61
+ }
62
+ throw new Error('Struct does not have member: ' + memberName);
33
63
  }
34
64
  /**
35
65
  * Aligns a number
@@ -37,65 +67,40 @@ export function offsetof(type, memberName) {
37
67
  export function align(value, alignment) {
38
68
  return Math.ceil(value / alignment) * alignment;
39
69
  }
40
- /**
41
- * Gets the length of an array in a struct
42
- * @param length The numeric length or the name of the field which has the array length (like __counted_by)
43
- * @param name The name of the array field— only used for errors
44
- */
45
- function _memberLength(struct, length, name) {
46
- if (length === undefined)
47
- return -1;
48
- if (typeof length != 'string')
49
- return Number.isSafeInteger(length) && length >= 0
50
- ? length
51
- : _throw(new Error('Array lengths must be natural numbers'));
52
- if (!(length in struct))
53
- throw new Error(`Can not use non-existent member to count ${name}: ` + length);
54
- const n = struct[length];
55
- if (typeof n != 'number')
56
- throw new Error(`Can not use "${name}" to count ${length}`);
57
- return n;
58
- }
59
- /** Compute the size of a struct including dynamically sized members */
60
- function _structSize() {
61
- const { staticSize, members } = this.constructor[symbol_metadata(this.constructor)].struct;
62
- let size = staticSize;
63
- for (const [name, { type, length: key }] of members) {
64
- if (typeof key != 'string')
65
- continue;
66
- size += sizeof(type) * _memberLength(this, key, name);
67
- }
68
- return size;
69
- }
70
70
  /**
71
71
  * Decorates a class as a struct
72
72
  */
73
73
  export function struct(options = {}) {
74
74
  return function _decorateStruct(target, context) {
75
- context.metadata ??= {};
76
- context.metadata.struct ??= {};
77
- context.metadata.struct.init ??= [];
78
- let staticSize = 0;
79
75
  const members = new Map();
80
- for (const { name, type, length } of context.metadata.struct.init) {
76
+ let staticSize = 0, isDynamic = false;
77
+ for (const { name, type, length } of initMetadata(context)) {
81
78
  if (!primitive.isValid(type) && !isStatic(type))
82
79
  throw new TypeError('Not a valid type: ' + type);
80
+ if (typeof length == 'string') {
81
+ const countedBy = members.get(length);
82
+ if (!countedBy)
83
+ throw new Error(`"${length}" is undefined or declared after "${name}"`);
84
+ if (!primitive.isType(countedBy.type))
85
+ throw new Error(`"${length}" is not a number and cannot be used to count "${name}"`);
86
+ }
87
+ let decl = `${typeof type == 'string' ? type : type.name} ${name}`;
88
+ if (length !== undefined)
89
+ decl += `[${length}]`;
83
90
  members.set(name, {
84
- offset: options.isUnion ? 0 : staticSize,
91
+ name,
92
+ staticOffset: options.isUnion ? 0 : staticSize,
85
93
  type: primitive.isValid(type) ? primitive.normalize(type) : type,
86
94
  length,
95
+ decl,
87
96
  });
88
97
  const memberSize = typeof length == 'string' ? 0 : sizeof(type) * (length || 1);
98
+ isDynamic ||= typeof length == 'string';
89
99
  staticSize = options.isUnion ? Math.max(staticSize, memberSize) : staticSize + memberSize;
90
100
  staticSize = align(staticSize, options.align || 1);
101
+ _debugLog('define', target.name + '.' + name);
91
102
  }
92
- context.metadata.struct = { options, members, staticSize };
93
- context.addInitializer(function () {
94
- Object.defineProperty(this.prototype, Symbol.size, {
95
- get: _structSize.bind(this),
96
- enumerable: false,
97
- });
98
- });
103
+ context.metadata.struct = { options, members, staticSize, isDynamic };
99
104
  return target;
100
105
  };
101
106
  }
@@ -111,13 +116,20 @@ export function member(type, length) {
111
116
  }
112
117
  if (!name)
113
118
  throw new ReferenceError('Invalid name for struct member');
114
- context.metadata ??= {};
115
- context.metadata.struct ??= {};
116
- context.metadata.struct.init ??= [];
117
- context.metadata.struct.init.push({ name, type, length });
119
+ initMetadata(context).push({ name, type, length });
118
120
  return value;
119
121
  };
120
122
  }
123
+ /** Gets the length of a member */
124
+ function _memberLength(instance, member) {
125
+ if (member.length === undefined)
126
+ return -1;
127
+ if (typeof member.length == 'string')
128
+ return instance[member.length];
129
+ return Number.isSafeInteger(member.length) && member.length >= 0
130
+ ? member.length
131
+ : _throw(new Error('Array lengths must be natural numbers'));
132
+ }
121
133
  /**
122
134
  * Serializes a struct into a Uint8Array
123
135
  */
@@ -125,47 +137,53 @@ export function serialize(instance) {
125
137
  if (isCustom(instance) && typeof instance[Symbol.serialize] == 'function')
126
138
  return instance[Symbol.serialize]();
127
139
  checkInstance(instance);
128
- const { options, members } = instance.constructor[symbol_metadata(instance.constructor)].struct;
129
- const buffer = new Uint8Array(sizeof(instance));
140
+ _polyfill_metadata(instance.constructor);
141
+ const { options, members } = instance.constructor[Symbol.metadata].struct;
142
+ const size = sizeof(instance);
143
+ const buffer = new Uint8Array(size);
130
144
  const view = new DataView(buffer.buffer);
145
+ _debugLog('serialize', instance.constructor.name);
146
+ let offset = 0, nextOffset = 0;
131
147
  // for unions we should write members in ascending last modified order, but we don't have that info.
132
- for (const [name, { type, length: rawLength, offset }] of members) {
133
- const length = _memberLength(instance, rawLength, name);
148
+ for (const member of members.values()) {
149
+ const length = _memberLength(instance, member);
150
+ _debugLog('\t', member.decl);
134
151
  for (let i = 0; i < Math.abs(length); i++) {
135
- const iOff = offset + sizeof(type) * i;
136
- let value = length != -1 ? instance[name][i] : instance[name];
152
+ let value = length != -1 ? instance[member.name][i] : instance[member.name];
137
153
  if (typeof value == 'string') {
138
154
  value = value.charCodeAt(0);
139
155
  }
140
- if (!primitive.isType(type)) {
141
- buffer.set(value ? serialize(value) : new Uint8Array(sizeof(type)), iOff);
156
+ offset = nextOffset;
157
+ nextOffset += isInstance(value) ? sizeof(value) : sizeof(member.type);
158
+ if (!primitive.isType(member.type)) {
159
+ buffer.set(value ? serialize(value) : new Uint8Array(sizeof(member.type)), offset);
142
160
  continue;
143
161
  }
144
- const fn = `set${capitalize(type)}`;
162
+ const fn = `set${capitalize(member.type)}`;
145
163
  if (fn == 'setInt64') {
146
- view.setBigInt64(iOff, BigInt(value), !options.bigEndian);
164
+ view.setBigInt64(offset, BigInt(value), !options.bigEndian);
147
165
  continue;
148
166
  }
149
167
  if (fn == 'setUint64') {
150
- view.setBigUint64(iOff, BigInt(value), !options.bigEndian);
168
+ view.setBigUint64(offset, BigInt(value), !options.bigEndian);
151
169
  continue;
152
170
  }
153
171
  if (fn == 'setInt128') {
154
- view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
155
- view.setBigInt64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
172
+ view.setBigUint64(offset + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
173
+ view.setBigInt64(offset + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
156
174
  continue;
157
175
  }
158
176
  if (fn == 'setUint128') {
159
- view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
160
- view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
177
+ view.setBigUint64(offset + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
178
+ view.setBigUint64(offset + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
161
179
  continue;
162
180
  }
163
181
  if (fn == 'setFloat128') {
164
- view.setFloat64(iOff + (!options.bigEndian ? 0 : 8), Number(value), !options.bigEndian);
165
- view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), BigInt(0), !options.bigEndian);
182
+ view.setFloat64(offset + (!options.bigEndian ? 0 : 8), Number(value), !options.bigEndian);
183
+ view.setBigUint64(offset + (!options.bigEndian ? 8 : 0), BigInt(0), !options.bigEndian);
166
184
  continue;
167
185
  }
168
- view[fn](iOff, Number(value), !options.bigEndian);
186
+ view[fn](offset, Number(value), !options.bigEndian);
169
187
  }
170
188
  }
171
189
  return buffer;
@@ -178,53 +196,62 @@ export function deserialize(instance, _buffer) {
178
196
  if (isCustom(instance) && typeof instance[Symbol.deserialize] == 'function')
179
197
  return instance[Symbol.deserialize](buffer);
180
198
  checkInstance(instance);
181
- const { options, members } = instance.constructor[symbol_metadata(instance.constructor)].struct;
199
+ _polyfill_metadata(instance.constructor);
200
+ const { options, members } = instance.constructor[Symbol.metadata].struct;
182
201
  const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
183
- for (const [name, { type, offset, length: rawLength }] of members) {
184
- const length = _memberLength(instance, rawLength, name);
202
+ _debugLog('deserialize', instance.constructor.name);
203
+ let offset = 0, nextOffset = 0;
204
+ for (const member of members.values()) {
205
+ const length = _memberLength(instance, member);
206
+ _debugLog('\t', member.decl);
185
207
  for (let i = 0; i < Math.abs(length); i++) {
186
- let object = length != -1 ? instance[name] : instance;
187
- const key = length != -1 ? i : name, iOff = offset + sizeof(type) * i;
188
- if (typeof instance[name] == 'string') {
189
- instance[name] =
190
- instance[name].slice(0, i) + String.fromCharCode(view.getUint8(iOff)) + instance[name].slice(i + 1);
208
+ let object = length != -1 ? instance[member.name] : instance;
209
+ const key = length != -1 ? i : member.name;
210
+ offset = nextOffset;
211
+ if (!isInstance(object[key]))
212
+ nextOffset += sizeof(member.type);
213
+ if (typeof instance[member.name] == 'string') {
214
+ instance[member.name] =
215
+ instance[member.name].slice(0, i)
216
+ + String.fromCharCode(view.getUint8(offset))
217
+ + instance[member.name].slice(i + 1);
191
218
  continue;
192
219
  }
193
- if (!primitive.isType(type)) {
194
- if (object[key] === null || object[key] === undefined) {
220
+ if (!primitive.isType(member.type)) {
221
+ if (object[key] === null || object[key] === undefined)
195
222
  continue;
196
- }
197
- deserialize(object[key], new Uint8Array(buffer.subarray(iOff, iOff + sizeof(type))));
223
+ deserialize(object[key], new Uint8Array(buffer.subarray(offset)));
224
+ nextOffset += sizeof(object[key]);
198
225
  continue;
199
226
  }
200
227
  if (length && length != -1)
201
228
  object ||= [];
202
- const fn = `get${capitalize(type)}`;
229
+ const fn = `get${capitalize(member.type)}`;
203
230
  if (fn == 'getInt64') {
204
- object[key] = view.getBigInt64(iOff, !options.bigEndian);
231
+ object[key] = view.getBigInt64(offset, !options.bigEndian);
205
232
  continue;
206
233
  }
207
234
  if (fn == 'getUint64') {
208
- object[key] = view.getBigUint64(iOff, !options.bigEndian);
235
+ object[key] = view.getBigUint64(offset, !options.bigEndian);
209
236
  continue;
210
237
  }
211
238
  if (fn == 'getInt128') {
212
239
  object[key] =
213
- (view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
214
- | view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
240
+ (view.getBigInt64(offset + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
241
+ | view.getBigUint64(offset + (!options.bigEndian ? 0 : 8), !options.bigEndian);
215
242
  continue;
216
243
  }
217
244
  if (fn == 'getUint128') {
218
245
  object[key] =
219
- (view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
220
- | view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
246
+ (view.getBigUint64(offset + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
247
+ | view.getBigUint64(offset + (!options.bigEndian ? 0 : 8), !options.bigEndian);
221
248
  continue;
222
249
  }
223
250
  if (fn == 'getFloat128') {
224
- object[key] = view.getFloat64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
251
+ object[key] = view.getFloat64(offset + (!options.bigEndian ? 0 : 8), !options.bigEndian);
225
252
  continue;
226
253
  }
227
- object[key] = view[fn](iOff, !options.bigEndian);
254
+ object[key] = view[fn](offset, !options.bigEndian);
228
255
  }
229
256
  }
230
257
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "utilium",
3
- "version": "1.7.10",
3
+ "version": "1.7.12",
4
4
  "description": "Typescript utilities",
5
5
  "funding": {
6
6
  "type": "individual",
package/src/debugging.ts CHANGED
@@ -92,3 +92,22 @@ export function createLogDecorator(options: CreateLoggerOptions) {
92
92
  } as T;
93
93
  };
94
94
  }
95
+
96
+ /**
97
+ * @internal @hidden
98
+ */
99
+ export let U_DEBUG = 'process' in globalThis && 'env' in globalThis.process && globalThis.process.env.U_DEBUG == 'true';
100
+
101
+ /**
102
+ * @internal @hidden
103
+ */
104
+ export function _setDebug(value: boolean) {
105
+ U_DEBUG = value;
106
+ }
107
+
108
+ /**
109
+ * @internal @hidden
110
+ */
111
+ export function _debugLog(...text: any[]) {
112
+ if (U_DEBUG) console.debug('[U]', ...text);
113
+ }
@@ -14,13 +14,19 @@ declare global {
14
14
  }
15
15
  }
16
16
 
17
+ /**
18
+ * Polyfill Symbol.metadata
19
+ * @see https://github.com/microsoft/TypeScript/issues/53461
20
+ */
21
+ (Symbol as { metadata: symbol }).metadata ??= Symbol.for('Symbol.metadata');
22
+
17
23
  Object.assign(Symbol, {
18
24
  size: Symbol('uSize'),
19
25
  serialize: Symbol('uSerialize'),
20
26
  deserialize: Symbol('uDeserialize'),
21
27
  });
22
28
 
23
- export type TypeLike = Custom | Like | primitive.Valid;
29
+ export type TypeLike = Custom | Like | primitive.Valid | undefined | null;
24
30
 
25
31
  export type Type = Custom | Static | primitive.Typename;
26
32
 
@@ -44,26 +50,43 @@ export interface Options {
44
50
  }
45
51
 
46
52
  export interface Member {
53
+ name: string;
47
54
  type: Type;
48
- offset: number;
55
+ staticOffset: number;
49
56
  length?: number | string;
57
+
58
+ /** A C-style type/name declaration string, used for diagnostics */
59
+ decl: string;
50
60
  }
51
61
 
52
62
  export interface Metadata {
53
63
  options: Partial<Options>;
54
64
  members: Map<string, Member>;
55
- init?: MemberInit[];
56
65
  staticSize: number;
66
+ isDynamic: boolean;
57
67
  }
58
68
 
59
69
  type _DecoratorMetadata<T extends Metadata = Metadata> = DecoratorMetadata & {
60
- struct?: Partial<T>;
70
+ struct?: T;
71
+ structInit?: MemberInit[];
61
72
  };
62
73
 
63
74
  export interface DecoratorContext<T extends Metadata = Metadata> {
64
75
  metadata: _DecoratorMetadata<T>;
65
76
  }
66
77
 
78
+ /**
79
+ * Initializes the struct metadata for a class
80
+ * This also handles copying metadata from parent classes
81
+ */
82
+ export function initMetadata(context: DecoratorContext): MemberInit[] {
83
+ context.metadata ??= {};
84
+
85
+ context.metadata.structInit = [...(context.metadata.structInit ?? [])];
86
+
87
+ return context.metadata.structInit;
88
+ }
89
+
67
90
  export type MemberContext = ClassMemberDecoratorContext & DecoratorContext;
68
91
 
69
92
  export interface Static<T extends Metadata = Metadata> {
@@ -84,18 +107,13 @@ export function isValidMetadata<T extends Metadata = Metadata>(
84
107
  return arg != null && typeof arg == 'object' && 'struct' in arg;
85
108
  }
86
109
 
87
- /**
88
- * Polyfill Symbol.metadata
89
- * @see https://github.com/microsoft/TypeScript/issues/53461
90
- */
91
- (Symbol as { metadata: symbol }).metadata ??= Symbol.for('Symbol.metadata');
92
-
93
110
  /**
94
111
  * Polyfill context.metadata
95
112
  * @see https://github.com/microsoft/TypeScript/issues/53461
113
+ * @internal @hidden
96
114
  */
97
- export function _polyfill_contextMetadata(target: object): void {
98
- if (!Symbol?.metadata || Symbol.metadata in target) return;
115
+ export function _polyfill_metadata(target: object): void {
116
+ if (Symbol.metadata in target) return;
99
117
 
100
118
  Object.defineProperty(target, Symbol.metadata, {
101
119
  enumerable: true,
@@ -105,26 +123,8 @@ export function _polyfill_contextMetadata(target: object): void {
105
123
  });
106
124
  }
107
125
 
108
- /**
109
- * Gets a reference to Symbol.metadata, even on platforms that do not expose it globally (like Node)
110
- */
111
- export function symbol_metadata(arg: ClassLike): typeof Symbol.metadata {
112
- const symbol_metadata =
113
- Symbol.metadata || Object.getOwnPropertySymbols(arg).find(s => s.description == 'Symbol.metadata');
114
- _polyfill_contextMetadata(arg);
115
- if (!symbol_metadata) {
116
- throw new ReferenceError('Could not get a reference to Symbol.metadata');
117
- }
118
-
119
- return symbol_metadata as typeof Symbol.metadata;
120
- }
121
-
122
126
  export function isStatic<T extends Metadata = Metadata>(arg: unknown): arg is Static<T> {
123
- return (
124
- typeof arg == 'function'
125
- && symbol_metadata(arg as ClassLike) in arg
126
- && isValidMetadata(arg[symbol_metadata(arg as ClassLike)])
127
- );
127
+ return typeof arg == 'function' && Symbol.metadata in arg && isValidMetadata(arg[Symbol.metadata]);
128
128
  }
129
129
 
130
130
  export interface Instance<T extends Metadata = Metadata> {
@@ -176,8 +176,10 @@ export function isCustom(arg: unknown): arg is Custom {
176
176
 
177
177
  export type Like<T extends Metadata = Metadata> = InstanceLike<T> | StaticLike<T>;
178
178
 
179
- export type Size<T extends TypeLike> = T extends { readonly [Symbol.size]: infer S }
180
- ? S
181
- : T extends primitive.Valid
182
- ? primitive.Size<T>
183
- : number;
179
+ export type Size<T extends TypeLike> = T extends undefined | null
180
+ ? 0
181
+ : T extends { readonly [Symbol.size]: infer S extends number }
182
+ ? S
183
+ : T extends primitive.Valid
184
+ ? primitive.Size<T>
185
+ : number;
package/src/struct.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { toUint8Array } from './buffer.js';
2
+ import { _debugLog } from './debugging.js';
2
3
  import * as primitive from './internal/primitives.js';
3
4
  import type {
4
5
  DecoratorContext,
@@ -10,11 +11,18 @@ import type {
10
11
  Metadata,
11
12
  Options,
12
13
  Size,
13
- Static,
14
14
  StaticLike,
15
15
  TypeLike,
16
16
  } from './internal/struct.js';
17
- import { checkInstance, checkStruct, isCustom, isStatic, symbol_metadata } from './internal/struct.js';
17
+ import {
18
+ _polyfill_metadata,
19
+ checkInstance,
20
+ checkStruct,
21
+ initMetadata,
22
+ isCustom,
23
+ isInstance,
24
+ isStatic,
25
+ } from './internal/struct.js';
18
26
  import { _throw } from './misc.js';
19
27
  import { capitalize } from './string.js';
20
28
  import type { ClassLike } from './types.js';
@@ -23,7 +31,19 @@ export * as Struct from './internal/struct.js';
23
31
  /**
24
32
  * Gets the size in bytes of a type
25
33
  */
26
- export function sizeof<T extends TypeLike>(type: T): Size<T> {
34
+ export function sizeof<T extends TypeLike>(type: T | T[]): Size<T> {
35
+ if (type === undefined || type === null) return 0 as Size<T>;
36
+
37
+ if (Array.isArray(type)) {
38
+ let size = 0;
39
+
40
+ for (let i = 0; i < type.length; i++) {
41
+ size += sizeof(type[i]);
42
+ }
43
+
44
+ return size as Size<T>;
45
+ }
46
+
27
47
  // primitive
28
48
  if (typeof type == 'string') {
29
49
  primitive.checkValid(type);
@@ -35,9 +55,22 @@ export function sizeof<T extends TypeLike>(type: T): Size<T> {
35
55
 
36
56
  checkStruct(type);
37
57
 
38
- const struct = isStatic(type) ? type : type.constructor;
58
+ const constructor = isStatic(type) ? type : type.constructor;
59
+ _polyfill_metadata(constructor);
60
+ const { struct } = constructor[Symbol.metadata];
61
+
62
+ if (isStatic(type)) return struct.staticSize as Size<T>;
39
63
 
40
- return struct[symbol_metadata(struct)].struct.staticSize as Size<T>;
64
+ let size = struct.staticSize;
65
+
66
+ for (const member of struct.members.values()) {
67
+ if (typeof member.length != 'string') continue;
68
+ for (let i = 0; i < (type as any)[member.length]; i++) {
69
+ size += sizeof((type as any)[member.name][i]);
70
+ }
71
+ }
72
+
73
+ return size as Size<T>;
41
74
  }
42
75
 
43
76
  /**
@@ -46,12 +79,26 @@ export function sizeof<T extends TypeLike>(type: T): Size<T> {
46
79
  export function offsetof(type: StaticLike | InstanceLike, memberName: string): number {
47
80
  checkStruct(type);
48
81
 
49
- const struct = isStatic(type) ? type : type.constructor;
50
- const metadata = struct[symbol_metadata(struct)].struct;
82
+ const constructor = isStatic(type) ? type : type.constructor;
83
+
84
+ _polyfill_metadata(constructor);
85
+ const { struct } = constructor[Symbol.metadata];
86
+
87
+ if (isStatic(type) || !struct.isDynamic) {
88
+ return (
89
+ struct.members.get(memberName)?.staticOffset
90
+ ?? _throw(new Error('Struct does not have member: ' + memberName))
91
+ );
92
+ }
93
+
94
+ let offset = 0;
95
+
96
+ for (const member of struct.members.values()) {
97
+ if (member.name == memberName) return offset;
98
+ offset += sizeof((type as any)[member.name]);
99
+ }
51
100
 
52
- const member = metadata.members.get(memberName);
53
- if (!member) throw new Error('Struct does not have member: ' + memberName);
54
- return member.offset;
101
+ throw new Error('Struct does not have member: ' + memberName);
55
102
  }
56
103
 
57
104
  /**
@@ -61,45 +108,6 @@ export function align(value: number, alignment: number): number {
61
108
  return Math.ceil(value / alignment) * alignment;
62
109
  }
63
110
 
64
- /**
65
- * Gets the length of an array in a struct
66
- * @param length The numeric length or the name of the field which has the array length (like __counted_by)
67
- * @param name The name of the array field— only used for errors
68
- */
69
- function _memberLength<T extends Metadata>(
70
- struct: Instance<T>,
71
- length: string | number | undefined,
72
- name: string
73
- ): number {
74
- if (length === undefined) return -1;
75
- if (typeof length != 'string')
76
- return Number.isSafeInteger(length) && length >= 0
77
- ? length
78
- : _throw(new Error('Array lengths must be natural numbers'));
79
-
80
- if (!(length in struct)) throw new Error(`Can not use non-existent member to count ${name}: ` + length);
81
-
82
- const n = (struct as any)[length];
83
-
84
- if (typeof n != 'number') throw new Error(`Can not use "${name}" to count ${length}`);
85
-
86
- return n;
87
- }
88
-
89
- /** Compute the size of a struct including dynamically sized members */
90
- function _structSize<T extends Metadata>(this: Instance<T>) {
91
- const { staticSize, members } = this.constructor[symbol_metadata(this.constructor)].struct;
92
-
93
- let size = staticSize;
94
-
95
- for (const [name, { type, length: key }] of members) {
96
- if (typeof key != 'string') continue;
97
- size += sizeof(type) * _memberLength(this, key, name);
98
- }
99
-
100
- return size;
101
- }
102
-
103
111
  /**
104
112
  * Decorates a class as a struct
105
113
  */
@@ -108,33 +116,44 @@ export function struct(options: Partial<Options> = {}) {
108
116
  target: T,
109
117
  context: ClassDecoratorContext & DecoratorContext
110
118
  ): T {
111
- context.metadata ??= {};
112
- context.metadata.struct ??= {};
113
- context.metadata.struct.init ??= [];
114
-
115
- let staticSize = 0;
116
119
  const members = new Map<string, Member>();
117
- for (const { name, type, length } of context.metadata.struct.init) {
120
+
121
+ let staticSize = 0,
122
+ isDynamic = false;
123
+
124
+ for (const { name, type, length } of initMetadata(context)) {
118
125
  if (!primitive.isValid(type) && !isStatic(type)) throw new TypeError('Not a valid type: ' + type);
119
126
 
127
+ if (typeof length == 'string') {
128
+ const countedBy = members.get(length);
129
+
130
+ if (!countedBy) throw new Error(`"${length}" is undefined or declared after "${name}"`);
131
+
132
+ if (!primitive.isType(countedBy.type))
133
+ throw new Error(`"${length}" is not a number and cannot be used to count "${name}"`);
134
+ }
135
+
136
+ let decl = `${typeof type == 'string' ? type : type.name} ${name}`;
137
+
138
+ if (length !== undefined) decl += `[${length}]`;
139
+
120
140
  members.set(name, {
121
- offset: options.isUnion ? 0 : staticSize,
141
+ name,
142
+ staticOffset: options.isUnion ? 0 : staticSize,
122
143
  type: primitive.isValid(type) ? primitive.normalize(type) : type,
123
144
  length,
145
+ decl,
124
146
  });
147
+
125
148
  const memberSize = typeof length == 'string' ? 0 : sizeof(type) * (length || 1);
149
+ isDynamic ||= typeof length == 'string';
126
150
  staticSize = options.isUnion ? Math.max(staticSize, memberSize) : staticSize + memberSize;
127
151
  staticSize = align(staticSize, options.align || 1);
128
- }
129
152
 
130
- context.metadata.struct = { options, members, staticSize } satisfies Metadata;
153
+ _debugLog('define', target.name + '.' + name);
154
+ }
131
155
 
132
- context.addInitializer(function (this: any) {
133
- Object.defineProperty(this.prototype, Symbol.size, {
134
- get: _structSize.bind(this),
135
- enumerable: false,
136
- });
137
- });
156
+ context.metadata.struct = { options, members, staticSize, isDynamic } satisfies Metadata;
138
157
 
139
158
  return target;
140
159
  };
@@ -153,14 +172,20 @@ export function member(type: primitive.Valid | ClassLike, length?: number | stri
153
172
 
154
173
  if (!name) throw new ReferenceError('Invalid name for struct member');
155
174
 
156
- context.metadata ??= {};
157
- context.metadata.struct ??= {};
158
- context.metadata.struct.init ??= [];
159
- context.metadata.struct.init.push({ name, type, length } satisfies MemberInit);
175
+ initMetadata(context).push({ name, type, length } satisfies MemberInit);
160
176
  return value;
161
177
  };
162
178
  }
163
179
 
180
+ /** Gets the length of a member */
181
+ function _memberLength<T extends Metadata>(instance: Instance<T>, member: Member): number {
182
+ if (member.length === undefined) return -1;
183
+ if (typeof member.length == 'string') return (instance as any)[member.length];
184
+ return Number.isSafeInteger(member.length) && member.length >= 0
185
+ ? member.length
186
+ : _throw(new Error('Array lengths must be natural numbers'));
187
+ }
188
+
164
189
  /**
165
190
  * Serializes a struct into a Uint8Array
166
191
  */
@@ -168,58 +193,69 @@ export function serialize(instance: unknown): Uint8Array {
168
193
  if (isCustom(instance) && typeof instance[Symbol.serialize] == 'function') return instance[Symbol.serialize]!();
169
194
 
170
195
  checkInstance(instance);
171
- const { options, members } = instance.constructor[symbol_metadata(instance.constructor)].struct;
196
+ _polyfill_metadata(instance.constructor);
197
+ const { options, members } = instance.constructor[Symbol.metadata].struct;
172
198
 
173
- const buffer = new Uint8Array(sizeof(instance));
199
+ const size = sizeof(instance);
200
+ const buffer = new Uint8Array(size);
174
201
  const view = new DataView(buffer.buffer);
175
202
 
203
+ _debugLog('serialize', instance.constructor.name);
204
+
205
+ let offset = 0,
206
+ nextOffset = 0;
207
+
176
208
  // for unions we should write members in ascending last modified order, but we don't have that info.
177
- for (const [name, { type, length: rawLength, offset }] of members) {
178
- const length = _memberLength(instance, rawLength, name);
179
- for (let i = 0; i < Math.abs(length); i++) {
180
- const iOff = offset + sizeof(type) * i;
209
+ for (const member of members.values()) {
210
+ const length = _memberLength(instance, member);
211
+
212
+ _debugLog('\t', member.decl);
181
213
 
182
- let value = length != -1 ? instance[name][i] : instance[name];
214
+ for (let i = 0; i < Math.abs(length); i++) {
215
+ let value = length != -1 ? instance[member.name][i] : instance[member.name];
183
216
  if (typeof value == 'string') {
184
217
  value = value.charCodeAt(0);
185
218
  }
186
219
 
187
- if (!primitive.isType(type)) {
188
- buffer.set(value ? serialize(value) : new Uint8Array(sizeof(type)), iOff);
220
+ offset = nextOffset;
221
+ nextOffset += isInstance(value) ? sizeof(value) : sizeof(member.type);
222
+
223
+ if (!primitive.isType(member.type)) {
224
+ buffer.set(value ? serialize(value) : new Uint8Array(sizeof(member.type)), offset);
189
225
  continue;
190
226
  }
191
227
 
192
- const fn = `set${capitalize(type)}` as const;
228
+ const fn = `set${capitalize(member.type)}` as const;
193
229
 
194
230
  if (fn == 'setInt64') {
195
- view.setBigInt64(iOff, BigInt(value), !options.bigEndian);
231
+ view.setBigInt64(offset, BigInt(value), !options.bigEndian);
196
232
  continue;
197
233
  }
198
234
 
199
235
  if (fn == 'setUint64') {
200
- view.setBigUint64(iOff, BigInt(value), !options.bigEndian);
236
+ view.setBigUint64(offset, BigInt(value), !options.bigEndian);
201
237
  continue;
202
238
  }
203
239
 
204
240
  if (fn == 'setInt128') {
205
- view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
206
- view.setBigInt64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
241
+ view.setBigUint64(offset + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
242
+ view.setBigInt64(offset + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
207
243
  continue;
208
244
  }
209
245
 
210
246
  if (fn == 'setUint128') {
211
- view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
212
- view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
247
+ view.setBigUint64(offset + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
248
+ view.setBigUint64(offset + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
213
249
  continue;
214
250
  }
215
251
 
216
252
  if (fn == 'setFloat128') {
217
- view.setFloat64(iOff + (!options.bigEndian ? 0 : 8), Number(value), !options.bigEndian);
218
- view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), BigInt(0), !options.bigEndian);
253
+ view.setFloat64(offset + (!options.bigEndian ? 0 : 8), Number(value), !options.bigEndian);
254
+ view.setBigUint64(offset + (!options.bigEndian ? 8 : 0), BigInt(0), !options.bigEndian);
219
255
  continue;
220
256
  }
221
257
 
222
- view[fn](iOff, Number(value), !options.bigEndian);
258
+ view[fn](offset, Number(value), !options.bigEndian);
223
259
  }
224
260
  }
225
261
 
@@ -236,64 +272,77 @@ export function deserialize(instance: unknown, _buffer: ArrayBufferLike | ArrayB
236
272
  return instance[Symbol.deserialize]!(buffer);
237
273
 
238
274
  checkInstance(instance);
239
- const { options, members } = instance.constructor[symbol_metadata(instance.constructor)].struct;
275
+ _polyfill_metadata(instance.constructor);
276
+ const { options, members } = instance.constructor[Symbol.metadata].struct;
240
277
 
241
278
  const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
242
279
 
243
- for (const [name, { type, offset, length: rawLength }] of members) {
244
- const length = _memberLength(instance, rawLength, name);
280
+ _debugLog('deserialize', instance.constructor.name);
281
+
282
+ let offset = 0,
283
+ nextOffset = 0;
284
+
285
+ for (const member of members.values()) {
286
+ const length = _memberLength(instance, member);
287
+
288
+ _debugLog('\t', member.decl);
289
+
245
290
  for (let i = 0; i < Math.abs(length); i++) {
246
- let object = length != -1 ? instance[name] : instance;
247
- const key = length != -1 ? i : name,
248
- iOff = offset + sizeof(type) * i;
291
+ let object = length != -1 ? instance[member.name] : instance;
292
+ const key = length != -1 ? i : member.name;
293
+
294
+ offset = nextOffset;
295
+ if (!isInstance(object[key])) nextOffset += sizeof(member.type);
249
296
 
250
- if (typeof instance[name] == 'string') {
251
- instance[name] =
252
- instance[name].slice(0, i) + String.fromCharCode(view.getUint8(iOff)) + instance[name].slice(i + 1);
297
+ if (typeof instance[member.name] == 'string') {
298
+ instance[member.name] =
299
+ instance[member.name].slice(0, i)
300
+ + String.fromCharCode(view.getUint8(offset))
301
+ + instance[member.name].slice(i + 1);
253
302
  continue;
254
303
  }
255
304
 
256
- if (!primitive.isType(type)) {
257
- if (object[key] === null || object[key] === undefined) {
258
- continue;
259
- }
260
- deserialize(object[key], new Uint8Array(buffer.subarray(iOff, iOff + sizeof(type))));
305
+ if (!primitive.isType(member.type)) {
306
+ if (object[key] === null || object[key] === undefined) continue;
307
+
308
+ deserialize(object[key], new Uint8Array(buffer.subarray(offset)));
309
+ nextOffset += sizeof(object[key]);
261
310
  continue;
262
311
  }
263
312
 
264
313
  if (length && length != -1) object ||= [];
265
314
 
266
- const fn = `get${capitalize(type)}` as const;
315
+ const fn = `get${capitalize(member.type)}` as const;
267
316
  if (fn == 'getInt64') {
268
- object[key] = view.getBigInt64(iOff, !options.bigEndian);
317
+ object[key] = view.getBigInt64(offset, !options.bigEndian);
269
318
  continue;
270
319
  }
271
320
 
272
321
  if (fn == 'getUint64') {
273
- object[key] = view.getBigUint64(iOff, !options.bigEndian);
322
+ object[key] = view.getBigUint64(offset, !options.bigEndian);
274
323
  continue;
275
324
  }
276
325
 
277
326
  if (fn == 'getInt128') {
278
327
  object[key] =
279
- (view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
280
- | view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
328
+ (view.getBigInt64(offset + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
329
+ | view.getBigUint64(offset + (!options.bigEndian ? 0 : 8), !options.bigEndian);
281
330
  continue;
282
331
  }
283
332
 
284
333
  if (fn == 'getUint128') {
285
334
  object[key] =
286
- (view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
287
- | view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
335
+ (view.getBigUint64(offset + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
336
+ | view.getBigUint64(offset + (!options.bigEndian ? 0 : 8), !options.bigEndian);
288
337
  continue;
289
338
  }
290
339
 
291
340
  if (fn == 'getFloat128') {
292
- object[key] = view.getFloat64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
341
+ object[key] = view.getFloat64(offset + (!options.bigEndian ? 0 : 8), !options.bigEndian);
293
342
  continue;
294
343
  }
295
344
 
296
- object[key] = view[fn](iOff, !options.bigEndian);
345
+ object[key] = view[fn](offset, !options.bigEndian);
297
346
  }
298
347
  }
299
348
  }