utilium 1.2.10 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ /** Utilities for computing checksums */
2
+ /**
3
+ * Computes the CRC32C checksum of a Uint8Array.
4
+ */
5
+ export declare function crc32c(data: Uint8Array): number;
@@ -0,0 +1,20 @@
1
+ /** Utilities for computing checksums */
2
+ // Precompute CRC32C table
3
+ const crc32cTable = new Uint32Array(256);
4
+ for (let i = 0; i < 256; i++) {
5
+ let value = i;
6
+ for (let j = 0; j < 8; j++) {
7
+ value = value & 1 ? 0x82f63b78 ^ (value >>> 1) : value >>> 1;
8
+ }
9
+ crc32cTable[i] = value;
10
+ }
11
+ /**
12
+ * Computes the CRC32C checksum of a Uint8Array.
13
+ */
14
+ export function crc32c(data) {
15
+ let crc = 0xffffffff;
16
+ for (let i = 0; i < data.length; i++) {
17
+ crc = (crc >>> 8) ^ crc32cTable[(crc ^ data[i]) & 0xff];
18
+ }
19
+ return (crc ^ 0xffffffff) >>> 0;
20
+ }
@@ -3,12 +3,13 @@ type BitsToBytes = {
3
3
  '16': 2;
4
4
  '32': 4;
5
5
  '64': 8;
6
+ '128': 16;
6
7
  };
7
8
  export type Size<T extends string> = T extends `${'int' | 'uint' | 'float'}${infer bits}` ? (bits extends keyof BitsToBytes ? BitsToBytes[bits] : never) : never;
8
- export type Type = `${'int' | 'uint'}${8 | 16 | 32 | 64}` | `float${32 | 64}`;
9
+ export declare const types: readonly ["int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "int128", "uint128", "float32", "float64", "float128"];
10
+ export type Type = (typeof types)[number];
9
11
  export type Valid = Type | Capitalize<Type> | 'char';
10
- export declare const types: ("int8" | "int16" | "int32" | "int64" | "uint8" | "uint16" | "uint32" | "uint64" | "float32" | "float64")[];
11
- export declare const valids: ("int8" | "int16" | "int32" | "int64" | "uint8" | "uint16" | "uint32" | "uint64" | "float32" | "float64" | "Int8" | "Int16" | "Int32" | "Int64" | "Uint8" | "Uint16" | "Uint32" | "Uint64" | "Float32" | "Float64" | "char")[];
12
+ export declare const valids: ("int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "int128" | "uint128" | "float32" | "float64" | "float128" | "Int8" | "Uint8" | "Int16" | "Uint16" | "Int32" | "Uint32" | "Int64" | "Uint64" | "Int128" | "Uint128" | "Float32" | "Float64" | "Float128" | "char")[];
12
13
  export declare const regex: RegExp;
13
14
  export type Normalize<T extends Valid> = T extends 'char' ? 'uint8' : Uncapitalize<T>;
14
15
  export declare function normalize<T extends Valid>(type: T): Normalize<T>;
@@ -21,4 +22,5 @@ export declare function isValid(type: {
21
22
  export declare function checkValid(type: {
22
23
  toString(): string;
23
24
  }): asserts type is Valid;
25
+ export declare const mask64: bigint;
24
26
  export {};
@@ -1,7 +1,7 @@
1
1
  import { capitalize } from '../string.js';
2
- export const types = ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'float32', 'float64'];
2
+ export const types = ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'int128', 'uint128', 'float32', 'float64', 'float128'];
3
3
  export const valids = [...types, ...types.map(t => capitalize(t)), 'char'];
4
- export const regex = /^(u?int|float)(8|16|32|64)$/i;
4
+ export const regex = /^(u?int|float)(8|16|32|64|128)$/i;
5
5
  export function normalize(type) {
6
6
  return (type == 'char' ? 'uint8' : type.toLowerCase());
7
7
  }
@@ -16,3 +16,4 @@ export function checkValid(type) {
16
16
  throw new TypeError('Not a valid primitive type: ' + type);
17
17
  }
18
18
  }
19
+ export const mask64 = BigInt('0xffffffffffffffff');
package/dist/struct.d.ts CHANGED
@@ -7,6 +7,10 @@ export * as Struct from './internal/struct.js';
7
7
  * Gets the size in bytes of a type
8
8
  */
9
9
  export declare function sizeof<T extends primitive.Valid | StaticLike | InstanceLike>(type: T): Size<T>;
10
+ /**
11
+ * Returns the offset (in bytes) of a member in a struct.
12
+ */
13
+ export declare function offsetof(type: StaticLike | InstanceLike, memberName: string): number;
10
14
  /**
11
15
  * Aligns a number
12
16
  */
package/dist/struct.js CHANGED
@@ -15,6 +15,18 @@ export function sizeof(type) {
15
15
  const struct = isStatic(type) ? type : type.constructor;
16
16
  return struct[symbol_metadata(struct)][Symbol.struct_metadata].size;
17
17
  }
18
+ /**
19
+ * Returns the offset (in bytes) of a member in a struct.
20
+ */
21
+ export function offsetof(type, memberName) {
22
+ checkStruct(type);
23
+ const struct = isStatic(type) ? type : type.constructor;
24
+ const metadata = struct[symbol_metadata(struct)][Symbol.struct_metadata];
25
+ const member = metadata.members.get(memberName);
26
+ if (!member)
27
+ throw new Error('Struct does not have member: ' + memberName);
28
+ return member.offset;
29
+ }
18
30
  /**
19
31
  * Aligns a number
20
32
  */
@@ -88,8 +100,7 @@ export function serialize(instance) {
88
100
  buffer.set(value ? serialize(value) : new Uint8Array(sizeof(type)), iOff);
89
101
  continue;
90
102
  }
91
- const Type = capitalize(type);
92
- const fn = ('set' + Type);
103
+ const fn = `set${capitalize(type)}`;
93
104
  if (fn == 'setInt64') {
94
105
  view.setBigInt64(iOff, BigInt(value), !options.bigEndian);
95
106
  continue;
@@ -98,6 +109,21 @@ export function serialize(instance) {
98
109
  view.setBigUint64(iOff, BigInt(value), !options.bigEndian);
99
110
  continue;
100
111
  }
112
+ if (fn == 'setInt128') {
113
+ view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
114
+ view.setBigInt64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
115
+ continue;
116
+ }
117
+ if (fn == 'setUint128') {
118
+ view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
119
+ view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
120
+ continue;
121
+ }
122
+ if (fn == 'setFloat128') {
123
+ view.setFloat64(iOff + (!options.bigEndian ? 0 : 8), Number(value), !options.bigEndian);
124
+ view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), BigInt(0), !options.bigEndian);
125
+ continue;
126
+ }
101
127
  view[fn](iOff, Number(value), !options.bigEndian);
102
128
  }
103
129
  }
@@ -132,8 +158,7 @@ export function deserialize(instance, _buffer) {
132
158
  if (length > 0) {
133
159
  object ||= [];
134
160
  }
135
- const Type = capitalize(type);
136
- const fn = ('get' + Type);
161
+ const fn = `get${capitalize(type)}`;
137
162
  if (fn == 'getInt64') {
138
163
  object[key] = view.getBigInt64(iOff, !options.bigEndian);
139
164
  continue;
@@ -142,6 +167,22 @@ export function deserialize(instance, _buffer) {
142
167
  object[key] = view.getBigUint64(iOff, !options.bigEndian);
143
168
  continue;
144
169
  }
170
+ if (fn == 'getInt128') {
171
+ object[key] =
172
+ (view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64)) |
173
+ view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
174
+ continue;
175
+ }
176
+ if (fn == 'getUint128') {
177
+ object[key] =
178
+ (view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64)) |
179
+ view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
180
+ continue;
181
+ }
182
+ if (fn == 'getFloat128') {
183
+ object[key] = view.getFloat64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
184
+ continue;
185
+ }
145
186
  object[key] = view[fn](iOff, !options.bigEndian);
146
187
  }
147
188
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "utilium",
3
- "version": "1.2.10",
3
+ "version": "1.3.1",
4
4
  "description": "Typescript utilities",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -0,0 +1,22 @@
1
+ /** Utilities for computing checksums */
2
+
3
+ // Precompute CRC32C table
4
+ const crc32cTable = new Uint32Array(256);
5
+ for (let i = 0; i < 256; i++) {
6
+ let value = i;
7
+ for (let j = 0; j < 8; j++) {
8
+ value = value & 1 ? 0x82f63b78 ^ (value >>> 1) : value >>> 1;
9
+ }
10
+ crc32cTable[i] = value;
11
+ }
12
+
13
+ /**
14
+ * Computes the CRC32C checksum of a Uint8Array.
15
+ */
16
+ export function crc32c(data: Uint8Array): number {
17
+ let crc = 0xffffffff;
18
+ for (let i = 0; i < data.length; i++) {
19
+ crc = (crc >>> 8) ^ crc32cTable[(crc ^ data[i]) & 0xff];
20
+ }
21
+ return (crc ^ 0xffffffff) >>> 0;
22
+ }
@@ -5,17 +5,20 @@ type BitsToBytes = {
5
5
  '16': 2;
6
6
  '32': 4;
7
7
  '64': 8;
8
+ '128': 16;
8
9
  };
9
10
 
10
11
  export type Size<T extends string> = T extends `${'int' | 'uint' | 'float'}${infer bits}` ? (bits extends keyof BitsToBytes ? BitsToBytes[bits] : never) : never;
11
- export type Type = `${'int' | 'uint'}${8 | 16 | 32 | 64}` | `float${32 | 64}`;
12
- export type Valid = Type | Capitalize<Type> | 'char';
13
12
 
14
- export const types = ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'float32', 'float64'] satisfies Type[];
13
+ export const types = ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'int128', 'uint128', 'float32', 'float64', 'float128'] as const;
14
+
15
+ export type Type = (typeof types)[number];
16
+
17
+ export type Valid = Type | Capitalize<Type> | 'char';
15
18
 
16
19
  export const valids = [...types, ...types.map(t => capitalize(t)), 'char'] satisfies Valid[];
17
20
 
18
- export const regex = /^(u?int|float)(8|16|32|64)$/i;
21
+ export const regex = /^(u?int|float)(8|16|32|64|128)$/i;
19
22
 
20
23
  export type Normalize<T extends Valid> = T extends 'char' ? 'uint8' : Uncapitalize<T>;
21
24
 
@@ -36,3 +39,5 @@ export function checkValid(type: { toString(): string }): asserts type is Valid
36
39
  throw new TypeError('Not a valid primitive type: ' + type);
37
40
  }
38
41
  }
42
+
43
+ export const mask64 = BigInt('0xffffffffffffffff');
package/src/struct.ts CHANGED
@@ -23,6 +23,20 @@ export function sizeof<T extends primitive.Valid | StaticLike | InstanceLike>(ty
23
23
  return struct[symbol_metadata(struct)][Symbol.struct_metadata].size as Size<T>;
24
24
  }
25
25
 
26
+ /**
27
+ * Returns the offset (in bytes) of a member in a struct.
28
+ */
29
+ export function offsetof(type: StaticLike | InstanceLike, memberName: string): number {
30
+ checkStruct(type);
31
+
32
+ const struct = isStatic(type) ? type : type.constructor;
33
+ const metadata = struct[symbol_metadata(struct)][Symbol.struct_metadata];
34
+
35
+ const member = metadata.members.get(memberName);
36
+ if (!member) throw new Error('Struct does not have member: ' + memberName);
37
+ return member.offset;
38
+ }
39
+
26
40
  /**
27
41
  * Aligns a number
28
42
  */
@@ -107,8 +121,8 @@ export function serialize(instance: unknown): Uint8Array {
107
121
  continue;
108
122
  }
109
123
 
110
- const Type = capitalize(type);
111
- const fn = ('set' + Type) as `set${typeof Type}`;
124
+ const fn = `set${capitalize(type)}` as const;
125
+
112
126
  if (fn == 'setInt64') {
113
127
  view.setBigInt64(iOff, BigInt(value), !options.bigEndian);
114
128
  continue;
@@ -119,6 +133,24 @@ export function serialize(instance: unknown): Uint8Array {
119
133
  continue;
120
134
  }
121
135
 
136
+ if (fn == 'setInt128') {
137
+ view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
138
+ view.setBigInt64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
139
+ continue;
140
+ }
141
+
142
+ if (fn == 'setUint128') {
143
+ view.setBigUint64(iOff + (!options.bigEndian ? 0 : 8), value & primitive.mask64, !options.bigEndian);
144
+ view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), value >> BigInt(64), !options.bigEndian);
145
+ continue;
146
+ }
147
+
148
+ if (fn == 'setFloat128') {
149
+ view.setFloat64(iOff + (!options.bigEndian ? 0 : 8), Number(value), !options.bigEndian);
150
+ view.setBigUint64(iOff + (!options.bigEndian ? 8 : 0), BigInt(0), !options.bigEndian);
151
+ continue;
152
+ }
153
+
122
154
  view[fn](iOff, Number(value), !options.bigEndian);
123
155
  }
124
156
  }
@@ -163,8 +195,7 @@ export function deserialize(instance: unknown, _buffer: ArrayBufferLike | ArrayB
163
195
  object ||= [];
164
196
  }
165
197
 
166
- const Type = capitalize(type);
167
- const fn = ('get' + Type) as `get${typeof Type}`;
198
+ const fn = `get${capitalize(type)}` as const;
168
199
  if (fn == 'getInt64') {
169
200
  object[key] = view.getBigInt64(iOff, !options.bigEndian);
170
201
  continue;
@@ -175,6 +206,25 @@ export function deserialize(instance: unknown, _buffer: ArrayBufferLike | ArrayB
175
206
  continue;
176
207
  }
177
208
 
209
+ if (fn == 'getInt128') {
210
+ object[key] =
211
+ (view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64)) |
212
+ view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
213
+ continue;
214
+ }
215
+
216
+ if (fn == 'getUint128') {
217
+ object[key] =
218
+ (view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64)) |
219
+ view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
220
+ continue;
221
+ }
222
+
223
+ if (fn == 'getFloat128') {
224
+ object[key] = view.getFloat64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
225
+ continue;
226
+ }
227
+
178
228
  object[key] = view[fn](iOff, !options.bigEndian);
179
229
  }
180
230
  }