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.
- package/dist/checksum.d.ts +5 -0
- package/dist/checksum.js +20 -0
- package/dist/internal/primitives.d.ts +5 -3
- package/dist/internal/primitives.js +3 -2
- package/dist/struct.d.ts +4 -0
- package/dist/struct.js +45 -4
- package/package.json +1 -1
- package/src/checksum.ts +22 -0
- package/src/internal/primitives.ts +9 -4
- package/src/struct.ts +54 -4
package/dist/checksum.js
ADDED
@@ -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
|
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
|
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
|
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
|
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
package/src/checksum.ts
ADDED
@@ -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']
|
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
|
111
|
-
|
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
|
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
|
}
|