mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-05 19:42:15 +02:00
refactor(struct): remove all DataView usage
This commit is contained in:
parent
1d319929ed
commit
75ff6d0ed6
15 changed files with 62 additions and 115 deletions
|
@ -30,7 +30,7 @@ This package is part of [Tango ADB](https://github.com/yume-chan/ya-webadb). Gen
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Check the latest documentation at https://tango-adb.github.io/docs/
|
Check the latest documentation at https://docs.tangoapp.dev/
|
||||||
|
|
||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { getUint16 } from "@yume-chan/no-data-view";
|
import { getUint16, setUint16 } from "@yume-chan/no-data-view";
|
||||||
import type { NumberFieldVariant } from "@yume-chan/struct";
|
import type { NumberFieldVariant } from "@yume-chan/struct";
|
||||||
import { NumberFieldDefinition } from "@yume-chan/struct";
|
import { NumberFieldDefinition } from "@yume-chan/struct";
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@ export const ScrcpyUnsignedFloatNumberVariant: NumberFieldVariant = {
|
||||||
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/server/src/main/java/com/genymobile/scrcpy/Binary.java#L22
|
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/server/src/main/java/com/genymobile/scrcpy/Binary.java#L22
|
||||||
return value === 0xffff ? 1 : value / 0x10000;
|
return value === 0xffff ? 1 : value / 0x10000;
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value, littleEndian) {
|
serialize(array, offset, value, littleEndian) {
|
||||||
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/app/src/util/binary.h#L51
|
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/app/src/util/binary.h#L51
|
||||||
value = clamp(value, -1, 1);
|
value = clamp(value, -1, 1);
|
||||||
value = value === 1 ? 0xffff : value * 0x10000;
|
value = value === 1 ? 0xffff : value * 0x10000;
|
||||||
dataView.setUint16(offset, value, littleEndian);
|
setUint16(array, offset, value, littleEndian);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,24 +9,24 @@ import {
|
||||||
|
|
||||||
describe("ScrcpyFloatToInt16NumberType", () => {
|
describe("ScrcpyFloatToInt16NumberType", () => {
|
||||||
it("should serialize", () => {
|
it("should serialize", () => {
|
||||||
const dataView = new DataView(new ArrayBuffer(2));
|
const array = new Uint8Array(2);
|
||||||
ScrcpySignedFloatNumberVariant.serialize(dataView, 0, -1, true);
|
ScrcpySignedFloatNumberVariant.serialize(array, 0, -1, true);
|
||||||
expect(dataView.getInt16(0, true)).toBe(-0x8000);
|
expect(new DataView(array.buffer).getInt16(0, true)).toBe(-0x8000);
|
||||||
|
|
||||||
ScrcpySignedFloatNumberVariant.serialize(dataView, 0, 0, true);
|
ScrcpySignedFloatNumberVariant.serialize(array, 0, 0, true);
|
||||||
expect(dataView.getInt16(0, true)).toBe(0);
|
expect(new DataView(array.buffer).getInt16(0, true)).toBe(0);
|
||||||
|
|
||||||
ScrcpySignedFloatNumberVariant.serialize(dataView, 0, 1, true);
|
ScrcpySignedFloatNumberVariant.serialize(array, 0, 1, true);
|
||||||
expect(dataView.getInt16(0, true)).toBe(0x7fff);
|
expect(new DataView(array.buffer).getInt16(0, true)).toBe(0x7fff);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should clamp input values", () => {
|
it("should clamp input values", () => {
|
||||||
const dataView = new DataView(new ArrayBuffer(2));
|
const array = new Uint8Array(2);
|
||||||
ScrcpySignedFloatNumberVariant.serialize(dataView, 0, -2, true);
|
ScrcpySignedFloatNumberVariant.serialize(array, 0, -2, true);
|
||||||
expect(dataView.getInt16(0, true)).toBe(-0x8000);
|
expect(new DataView(array.buffer).getInt16(0, true)).toBe(-0x8000);
|
||||||
|
|
||||||
ScrcpySignedFloatNumberVariant.serialize(dataView, 0, 2, true);
|
ScrcpySignedFloatNumberVariant.serialize(array, 0, 2, true);
|
||||||
expect(dataView.getInt16(0, true)).toBe(0x7fff);
|
expect(new DataView(array.buffer).getInt16(0, true)).toBe(0x7fff);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should deserialize", () => {
|
it("should deserialize", () => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { getInt16 } from "@yume-chan/no-data-view";
|
import { getInt16, setInt16 } from "@yume-chan/no-data-view";
|
||||||
import type { NumberFieldVariant } from "@yume-chan/struct";
|
import type { NumberFieldVariant } from "@yume-chan/struct";
|
||||||
import Struct, { NumberFieldDefinition } from "@yume-chan/struct";
|
import Struct, { NumberFieldDefinition } from "@yume-chan/struct";
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@ export const ScrcpySignedFloatNumberVariant: NumberFieldVariant = {
|
||||||
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/server/src/main/java/com/genymobile/scrcpy/Binary.java#L34
|
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/server/src/main/java/com/genymobile/scrcpy/Binary.java#L34
|
||||||
return value === 0x7fff ? 1 : value / 0x8000;
|
return value === 0x7fff ? 1 : value / 0x8000;
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value, littleEndian) {
|
serialize(array, offset, value, littleEndian) {
|
||||||
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/app/src/util/binary.h#L65
|
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/app/src/util/binary.h#L65
|
||||||
value = clamp(value, -1, 1);
|
value = clamp(value, -1, 1);
|
||||||
value = value === 1 ? 0x7fff : value * 0x8000;
|
value = value === 1 ? 0x7fff : value * 0x8000;
|
||||||
dataView.setInt16(offset, value, littleEndian);
|
setInt16(array, offset, value, littleEndian);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@ Some features can be polyfilled to support older runtimes, but this library does
|
||||||
| [`Promise`][mdn_promise] | 32 | 12 | 29 | No | 8 | 0.12 |
|
| [`Promise`][mdn_promise] | 32 | 12 | 29 | No | 8 | 0.12 |
|
||||||
| [`ArrayBuffer`][mdn_arraybuffer] | 7 | 12 | 4 | 10 | 5.1 | 0.10 |
|
| [`ArrayBuffer`][mdn_arraybuffer] | 7 | 12 | 4 | 10 | 5.1 | 0.10 |
|
||||||
| [`Uint8Array`][mdn_uint8array] | 7 | 12 | 4 | 10 | 5.1 | 0.10 |
|
| [`Uint8Array`][mdn_uint8array] | 7 | 12 | 4 | 10 | 5.1 | 0.10 |
|
||||||
| [`DataView`][mdn_dataview] | 9 | 12 | 15 | 10 | 5.1 | 0.10 |
|
|
||||||
| _Overall_ | 32 | 12 | 29 | No | 8 | 0.12 |
|
| _Overall_ | 32 | 12 | 29 | No | 8 | 0.12 |
|
||||||
|
|
||||||
### [`int64`/`uint64`](#int64uint64-1)
|
### [`int64`/`uint64`](#int64uint64-1)
|
||||||
|
@ -115,9 +114,7 @@ Some features can be polyfilled to support older runtimes, but this library does
|
||||||
[mdn_promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
[mdn_promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
||||||
[mdn_arraybuffer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
|
[mdn_arraybuffer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
|
||||||
[mdn_uint8array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
|
[mdn_uint8array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
|
||||||
[mdn_dataview]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
|
|
||||||
[mdn_bigint]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
|
[mdn_bigint]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
|
||||||
[mdn_dataview]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
|
|
||||||
[mdn_textencoder]: https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder
|
[mdn_textencoder]: https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
@ -169,7 +166,7 @@ class Struct<
|
||||||
TFields extends object = {},
|
TFields extends object = {},
|
||||||
TOmitInitKey extends string | number | symbol = never,
|
TOmitInitKey extends string | number | symbol = never,
|
||||||
TExtra extends object = {},
|
TExtra extends object = {},
|
||||||
TPostDeserialized = undefined
|
TPostDeserialized = undefined,
|
||||||
> {
|
> {
|
||||||
public constructor(options: Partial<StructOptions> = StructDefaultOptions);
|
public constructor(options: Partial<StructOptions> = StructDefaultOptions);
|
||||||
}
|
}
|
||||||
|
@ -640,7 +637,7 @@ struct.field("foo", new NumberFieldDefinition(NumberFieldType.Int8));
|
||||||
abstract class StructFieldDefinition<
|
abstract class StructFieldDefinition<
|
||||||
TOptions = void,
|
TOptions = void,
|
||||||
TValue = unknown,
|
TValue = unknown,
|
||||||
TOmitInitKey extends PropertyKey = never
|
TOmitInitKey extends PropertyKey = never,
|
||||||
> {
|
> {
|
||||||
public readonly options: TOptions;
|
public readonly options: TOptions;
|
||||||
|
|
||||||
|
@ -742,9 +739,9 @@ If one needs to manipulate other states when getting/setting values, they can ov
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
abstract serialize(
|
abstract serialize(
|
||||||
dataView: DataView,
|
array: Uint8Array,
|
||||||
offset: number
|
offset: number
|
||||||
): void;
|
): void;
|
||||||
```
|
```
|
||||||
|
|
||||||
Derived classes must implement this method to serialize current value into `dataView`, from `offset`. It must not write more bytes than what its `getSize` returned.
|
Derived classes must implement this method to serialize current value into `array`, from `offset`. It must not write more bytes than what its `getSize` returned.
|
||||||
|
|
|
@ -13,12 +13,7 @@ describe("StructFieldValue", () => {
|
||||||
describe(".constructor", () => {
|
describe(".constructor", () => {
|
||||||
it("should save parameters", () => {
|
it("should save parameters", () => {
|
||||||
class MockStructFieldValue extends StructFieldValue<never> {
|
class MockStructFieldValue extends StructFieldValue<never> {
|
||||||
override serialize(
|
override serialize(array: Uint8Array, offset: number): void {
|
||||||
dataView: DataView,
|
|
||||||
array: Uint8Array,
|
|
||||||
offset: number,
|
|
||||||
): void {
|
|
||||||
void dataView;
|
|
||||||
void array;
|
void array;
|
||||||
void offset;
|
void offset;
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
|
@ -83,12 +78,7 @@ describe("StructFieldValue", () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockStructFieldValue extends StructFieldValue<any> {
|
class MockStructFieldValue extends StructFieldValue<any> {
|
||||||
override serialize(
|
override serialize(array: Uint8Array, offset: number): void {
|
||||||
dataView: DataView,
|
|
||||||
array: Uint8Array,
|
|
||||||
offset: number,
|
|
||||||
): void {
|
|
||||||
void dataView;
|
|
||||||
void array;
|
void array;
|
||||||
void offset;
|
void offset;
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
|
@ -109,12 +99,7 @@ describe("StructFieldValue", () => {
|
||||||
describe("#set", () => {
|
describe("#set", () => {
|
||||||
it("should update its internal value", () => {
|
it("should update its internal value", () => {
|
||||||
class MockStructFieldValue extends StructFieldValue<any> {
|
class MockStructFieldValue extends StructFieldValue<any> {
|
||||||
override serialize(
|
override serialize(array: Uint8Array, offset: number): void {
|
||||||
dataView: DataView,
|
|
||||||
array: Uint8Array,
|
|
||||||
offset: number,
|
|
||||||
): void {
|
|
||||||
void dataView;
|
|
||||||
void array;
|
void array;
|
||||||
void offset;
|
void offset;
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
|
|
|
@ -65,11 +65,7 @@ export abstract class StructFieldValue<
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When implemented in derived classes, serializes this field into `dataView` at `offset`
|
* When implemented in derived classes, serializes this field into `array` at `offset`
|
||||||
*/
|
*/
|
||||||
abstract serialize(
|
abstract serialize(array: Uint8Array, offset: number): void;
|
||||||
dataView: DataView,
|
|
||||||
array: Uint8Array,
|
|
||||||
offset: number,
|
|
||||||
): void;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -690,14 +690,9 @@ export class Struct<
|
||||||
throw new TypeError("Output buffer is too small");
|
throw new TypeError("Output buffer is too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataView = new DataView(
|
|
||||||
output.buffer,
|
|
||||||
output.byteOffset,
|
|
||||||
output.byteLength,
|
|
||||||
);
|
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
for (const { fieldValue, size } of fieldsInfo) {
|
for (const { fieldValue, size } of fieldsInfo) {
|
||||||
fieldValue.serialize(dataView, output, offset);
|
fieldValue.serialize(output, offset);
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ export class BigIntFieldDefinition<
|
||||||
export class BigIntFieldValue<
|
export class BigIntFieldValue<
|
||||||
TDefinition extends BigIntFieldDefinition<BigIntFieldVariant, unknown>,
|
TDefinition extends BigIntFieldDefinition<BigIntFieldVariant, unknown>,
|
||||||
> extends StructFieldValue<TDefinition> {
|
> extends StructFieldValue<TDefinition> {
|
||||||
override serialize(_: DataView, array: Uint8Array, offset: number): void {
|
override serialize(array: Uint8Array, offset: number): void {
|
||||||
this.definition.variant.serialize(
|
this.definition.variant.serialize(
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
|
|
|
@ -190,8 +190,7 @@ describe("Types", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const targetArray = new Uint8Array(size);
|
const targetArray = new Uint8Array(size);
|
||||||
const targetView = new DataView(targetArray.buffer);
|
fieldValue.serialize(targetArray, 0);
|
||||||
fieldValue.serialize(targetView, targetArray, 0);
|
|
||||||
|
|
||||||
expect(targetArray).toEqual(sourceArray);
|
expect(targetArray).toEqual(sourceArray);
|
||||||
});
|
});
|
||||||
|
@ -220,8 +219,7 @@ describe("Types", () => {
|
||||||
fieldValue.set(sourceArray);
|
fieldValue.set(sourceArray);
|
||||||
|
|
||||||
const targetArray = new Uint8Array(size);
|
const targetArray = new Uint8Array(size);
|
||||||
const targetView = new DataView(targetArray.buffer);
|
fieldValue.serialize(targetArray, 0);
|
||||||
fieldValue.serialize(targetView, targetArray, 0);
|
|
||||||
|
|
||||||
expect(targetArray).toEqual(sourceArray);
|
expect(targetArray).toEqual(sourceArray);
|
||||||
});
|
});
|
||||||
|
|
|
@ -188,7 +188,7 @@ export class BufferLikeFieldValue<
|
||||||
this.array = undefined;
|
this.array = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
override serialize(_: DataView, array: Uint8Array, offset: number): void {
|
override serialize(array: Uint8Array, offset: number): void {
|
||||||
this.array ??= this.definition.converter.toBuffer(this.value);
|
this.array ??= this.definition.converter.toBuffer(this.value);
|
||||||
array.set(this.array, offset);
|
array.set(this.array, offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,10 @@ class MockLengthFieldValue extends StructFieldValue<any> {
|
||||||
void value;
|
void value;
|
||||||
});
|
});
|
||||||
|
|
||||||
serialize = jest.fn(
|
serialize = jest.fn((array: Uint8Array, offset: number): void => {
|
||||||
(dataView: DataView, _: Uint8Array, offset: number): void => {
|
void array;
|
||||||
void dataView;
|
void offset;
|
||||||
void offset;
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("Types", () => {
|
describe("Types", () => {
|
||||||
|
@ -64,12 +62,7 @@ describe("Types", () => {
|
||||||
|
|
||||||
override getSize = jest.fn(() => this.size);
|
override getSize = jest.fn(() => this.size);
|
||||||
|
|
||||||
override serialize(
|
override serialize(array: Uint8Array, offset: number): void {
|
||||||
dataView: DataView,
|
|
||||||
array: Uint8Array,
|
|
||||||
offset: number,
|
|
||||||
): void {
|
|
||||||
void dataView;
|
|
||||||
void array;
|
void array;
|
||||||
void offset;
|
void offset;
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
|
@ -174,13 +167,12 @@ describe("Types", () => {
|
||||||
mockBufferFieldValue,
|
mockBufferFieldValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
const dataView = {} as any;
|
|
||||||
const array = {} as any;
|
const array = {} as any;
|
||||||
const offset = {} as any;
|
const offset = {} as any;
|
||||||
|
|
||||||
mockOriginalFieldValue.value = 10;
|
mockOriginalFieldValue.value = 10;
|
||||||
mockBufferFieldValue.size = 0;
|
mockBufferFieldValue.size = 0;
|
||||||
lengthFieldValue.serialize(dataView, array, offset);
|
lengthFieldValue.serialize(array, offset);
|
||||||
expect(mockOriginalFieldValue.get).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.get).toHaveBeenCalledTimes(1);
|
||||||
expect(mockOriginalFieldValue.get).toHaveReturnedWith(10);
|
expect(mockOriginalFieldValue.get).toHaveReturnedWith(10);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
||||||
|
@ -189,7 +181,6 @@ describe("Types", () => {
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
||||||
dataView,
|
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
);
|
);
|
||||||
|
@ -197,14 +188,13 @@ describe("Types", () => {
|
||||||
mockOriginalFieldValue.set.mockClear();
|
mockOriginalFieldValue.set.mockClear();
|
||||||
mockOriginalFieldValue.serialize.mockClear();
|
mockOriginalFieldValue.serialize.mockClear();
|
||||||
mockBufferFieldValue.size = 100;
|
mockBufferFieldValue.size = 100;
|
||||||
lengthFieldValue.serialize(dataView, array, offset);
|
lengthFieldValue.serialize(array, offset);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledWith(100);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledWith(100);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledTimes(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledTimes(
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
||||||
dataView,
|
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
);
|
);
|
||||||
|
@ -219,13 +209,12 @@ describe("Types", () => {
|
||||||
mockBufferFieldValue,
|
mockBufferFieldValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
const dataView = {} as any;
|
|
||||||
const array = {} as any;
|
const array = {} as any;
|
||||||
const offset = {} as any;
|
const offset = {} as any;
|
||||||
|
|
||||||
mockOriginalFieldValue.value = "10";
|
mockOriginalFieldValue.value = "10";
|
||||||
mockBufferFieldValue.size = 0;
|
mockBufferFieldValue.size = 0;
|
||||||
lengthFieldValue.serialize(dataView, array, offset);
|
lengthFieldValue.serialize(array, offset);
|
||||||
expect(mockOriginalFieldValue.get).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.get).toHaveBeenCalledTimes(1);
|
||||||
expect(mockOriginalFieldValue.get).toHaveReturnedWith("10");
|
expect(mockOriginalFieldValue.get).toHaveReturnedWith("10");
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
||||||
|
@ -234,7 +223,6 @@ describe("Types", () => {
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
||||||
dataView,
|
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
);
|
);
|
||||||
|
@ -242,14 +230,13 @@ describe("Types", () => {
|
||||||
mockOriginalFieldValue.set.mockClear();
|
mockOriginalFieldValue.set.mockClear();
|
||||||
mockOriginalFieldValue.serialize.mockClear();
|
mockOriginalFieldValue.serialize.mockClear();
|
||||||
mockBufferFieldValue.size = 100;
|
mockBufferFieldValue.size = 100;
|
||||||
lengthFieldValue.serialize(dataView, array, offset);
|
lengthFieldValue.serialize(array, offset);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledWith("100");
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledWith("100");
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledTimes(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledTimes(
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
||||||
dataView,
|
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
);
|
);
|
||||||
|
@ -268,13 +255,12 @@ describe("Types", () => {
|
||||||
mockBufferFieldValue.definition.options.lengthFieldRadix =
|
mockBufferFieldValue.definition.options.lengthFieldRadix =
|
||||||
radix;
|
radix;
|
||||||
|
|
||||||
const dataView = {} as any;
|
|
||||||
const array = {} as any;
|
const array = {} as any;
|
||||||
const offset = {} as any;
|
const offset = {} as any;
|
||||||
|
|
||||||
mockOriginalFieldValue.value = "10";
|
mockOriginalFieldValue.value = "10";
|
||||||
mockBufferFieldValue.size = 0;
|
mockBufferFieldValue.size = 0;
|
||||||
lengthFieldValue.serialize(dataView, array, offset);
|
lengthFieldValue.serialize(array, offset);
|
||||||
expect(mockOriginalFieldValue.get).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.get).toHaveBeenCalledTimes(1);
|
||||||
expect(mockOriginalFieldValue.get).toHaveReturnedWith("10");
|
expect(mockOriginalFieldValue.get).toHaveReturnedWith("10");
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
||||||
|
@ -283,7 +269,6 @@ describe("Types", () => {
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
||||||
dataView,
|
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
);
|
);
|
||||||
|
@ -291,7 +276,7 @@ describe("Types", () => {
|
||||||
mockOriginalFieldValue.set.mockClear();
|
mockOriginalFieldValue.set.mockClear();
|
||||||
mockOriginalFieldValue.serialize.mockClear();
|
mockOriginalFieldValue.serialize.mockClear();
|
||||||
mockBufferFieldValue.size = 100;
|
mockBufferFieldValue.size = 100;
|
||||||
lengthFieldValue.serialize(dataView, array, offset);
|
lengthFieldValue.serialize(array, offset);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledTimes(1);
|
||||||
expect(mockOriginalFieldValue.set).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.set).toHaveBeenCalledWith(
|
||||||
(100).toString(radix),
|
(100).toString(radix),
|
||||||
|
@ -300,7 +285,6 @@ describe("Types", () => {
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
expect(mockOriginalFieldValue.serialize).toHaveBeenCalledWith(
|
||||||
dataView,
|
|
||||||
array,
|
array,
|
||||||
offset,
|
offset,
|
||||||
);
|
);
|
||||||
|
|
|
@ -192,8 +192,8 @@ export class VariableLengthBufferLikeFieldLengthValue extends StructFieldValue<
|
||||||
// It will always be in sync with the buffer size
|
// It will always be in sync with the buffer size
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(dataView: DataView, array: Uint8Array, offset: number) {
|
serialize(array: Uint8Array, offset: number) {
|
||||||
this.originalValue.set(this.get());
|
this.originalValue.set(this.get());
|
||||||
this.originalValue.serialize(dataView, array, offset);
|
this.originalValue.serialize(array, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,8 +315,7 @@ describe("Types", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const array = new Uint8Array(10);
|
const array = new Uint8Array(10);
|
||||||
const dataView = new DataView(array.buffer);
|
value.serialize(array, 2);
|
||||||
value.serialize(dataView, array, 2);
|
|
||||||
|
|
||||||
expect(Array.from(array)).toEqual([
|
expect(Array.from(array)).toEqual([
|
||||||
0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
|
@ -4,6 +4,10 @@ import {
|
||||||
getInt8,
|
getInt8,
|
||||||
getUint16,
|
getUint16,
|
||||||
getUint32,
|
getUint32,
|
||||||
|
setInt16,
|
||||||
|
setInt32,
|
||||||
|
setUint16,
|
||||||
|
setUint32,
|
||||||
} from "@yume-chan/no-data-view";
|
} from "@yume-chan/no-data-view";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
@ -21,7 +25,7 @@ export interface NumberFieldVariant {
|
||||||
size: number;
|
size: number;
|
||||||
deserialize(array: Uint8Array, littleEndian: boolean): number;
|
deserialize(array: Uint8Array, littleEndian: boolean): number;
|
||||||
serialize(
|
serialize(
|
||||||
dataView: DataView,
|
array: Uint8Array,
|
||||||
offset: number,
|
offset: number,
|
||||||
value: number,
|
value: number,
|
||||||
littleEndian: boolean,
|
littleEndian: boolean,
|
||||||
|
@ -35,8 +39,8 @@ export namespace NumberFieldVariant {
|
||||||
deserialize(array) {
|
deserialize(array) {
|
||||||
return array[0]!;
|
return array[0]!;
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value) {
|
serialize(array, offset, value) {
|
||||||
dataView.setUint8(offset, value);
|
array[offset] = value;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,8 +50,8 @@ export namespace NumberFieldVariant {
|
||||||
deserialize(array) {
|
deserialize(array) {
|
||||||
return getInt8(array, 0);
|
return getInt8(array, 0);
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value) {
|
serialize(array, offset, value) {
|
||||||
dataView.setInt8(offset, value);
|
array[offset] = value;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,14 +59,9 @@ export namespace NumberFieldVariant {
|
||||||
signed: false,
|
signed: false,
|
||||||
size: 2,
|
size: 2,
|
||||||
deserialize(array, littleEndian) {
|
deserialize(array, littleEndian) {
|
||||||
// PERF: Creating many `DataView`s over small buffers is 90% slower
|
|
||||||
// than this. Even if the `DataView` is cached, `DataView#getUint16`
|
|
||||||
// is still 1% slower than this.
|
|
||||||
return getUint16(array, 0, littleEndian);
|
return getUint16(array, 0, littleEndian);
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value, littleEndian) {
|
serialize: setUint16,
|
||||||
dataView.setUint16(offset, value, littleEndian);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Int16: NumberFieldVariant = {
|
export const Int16: NumberFieldVariant = {
|
||||||
|
@ -71,9 +70,7 @@ export namespace NumberFieldVariant {
|
||||||
deserialize(array, littleEndian) {
|
deserialize(array, littleEndian) {
|
||||||
return getInt16(array, 0, littleEndian);
|
return getInt16(array, 0, littleEndian);
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value, littleEndian) {
|
serialize: setInt16,
|
||||||
dataView.setInt16(offset, value, littleEndian);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Uint32: NumberFieldVariant = {
|
export const Uint32: NumberFieldVariant = {
|
||||||
|
@ -82,9 +79,7 @@ export namespace NumberFieldVariant {
|
||||||
deserialize(array, littleEndian) {
|
deserialize(array, littleEndian) {
|
||||||
return getUint32(array, 0, littleEndian);
|
return getUint32(array, 0, littleEndian);
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value, littleEndian) {
|
serialize: setUint32,
|
||||||
dataView.setUint32(offset, value, littleEndian);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Int32: NumberFieldVariant = {
|
export const Int32: NumberFieldVariant = {
|
||||||
|
@ -93,9 +88,7 @@ export namespace NumberFieldVariant {
|
||||||
deserialize(array, littleEndian) {
|
deserialize(array, littleEndian) {
|
||||||
return getInt32(array, 0, littleEndian);
|
return getInt32(array, 0, littleEndian);
|
||||||
},
|
},
|
||||||
serialize(dataView, offset, value, littleEndian) {
|
serialize: setInt32,
|
||||||
dataView.setInt32(offset, value, littleEndian);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,9 +148,9 @@ export class NumberFieldDefinition<
|
||||||
export class NumberFieldValue<
|
export class NumberFieldValue<
|
||||||
TDefinition extends NumberFieldDefinition<NumberFieldVariant, unknown>,
|
TDefinition extends NumberFieldDefinition<NumberFieldVariant, unknown>,
|
||||||
> extends StructFieldValue<TDefinition> {
|
> extends StructFieldValue<TDefinition> {
|
||||||
serialize(dataView: DataView, _: Uint8Array, offset: number): void {
|
serialize(array: Uint8Array, offset: number): void {
|
||||||
this.definition.variant.serialize(
|
this.definition.variant.serialize(
|
||||||
dataView,
|
array,
|
||||||
offset,
|
offset,
|
||||||
this.value as never,
|
this.value as never,
|
||||||
this.options.littleEndian,
|
this.options.littleEndian,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue