diff --git a/packages/typed-binary/src/describe/index.ts b/packages/typed-binary/src/describe/index.ts index afbd354..f134b7d 100644 --- a/packages/typed-binary/src/describe/index.ts +++ b/packages/typed-binary/src/describe/index.ts @@ -2,7 +2,6 @@ import { type AnyObjectSchema, ArraySchema, BoolSchema, - ByteSchema, CharsSchema, DynamicArraySchema, Float16Schema, @@ -18,6 +17,12 @@ import { TypedArraySchema, Uint32Schema, } from '../structure'; +import { + Int8Schema, + Int16Schema, + Uint8Schema, + Uint16Schema, +} from '../structure/baseTypes'; import type { AnySchema, AnySchemaWithProperties, @@ -31,16 +36,23 @@ export const bool = new BoolSchema(); export const string = new StringSchema(); -export const byte = new ByteSchema(); +export const i8 = new Int8Schema(); +export const u8 = new Uint8Schema(); -export const i32 = new Int32Schema(); +export const i16 = new Int16Schema(); +export const u16 = new Uint16Schema(); +export const i32 = new Int32Schema(); export const u32 = new Uint32Schema(); export const f16 = new Float16Schema(); - export const f32 = new Float32Schema(); +/** + * Alias for `bin.u8` + */ +export const byte = u8; + export const chars = (length: T) => new CharsSchema(length); export const object =

>(properties: P) => diff --git a/packages/typed-binary/src/io/bufferReader.ts b/packages/typed-binary/src/io/bufferReader.ts index 19e8c2f..870056d 100644 --- a/packages/typed-binary/src/io/bufferReader.ts +++ b/packages/typed-binary/src/io/bufferReader.ts @@ -21,15 +21,23 @@ export class BufferReader extends BufferIOBase implements ISerialInput { return this.dataView.getUint8(this.byteOffset++); } - readFloat16() { - const value = this.dataView.getUint16(this.byteOffset, this.littleEndian); + readInt8() { + return this.dataView.getInt8(this.byteOffset++); + } + + readUint8() { + return this.dataView.getUint8(this.byteOffset++); + } + + readInt16() { + const value = this.dataView.getInt16(this.byteOffset, this.littleEndian); this.byteOffset += 2; - return float16ToNumber(value); + return value; } - readFloat32() { - const value = this.dataView.getFloat32(this.byteOffset, this.littleEndian); - this.byteOffset += 4; + readUint16() { + const value = this.dataView.getUint16(this.byteOffset, this.littleEndian); + this.byteOffset += 2; return value; } @@ -45,6 +53,18 @@ export class BufferReader extends BufferIOBase implements ISerialInput { return value; } + readFloat16() { + const value = this.dataView.getUint16(this.byteOffset, this.littleEndian); + this.byteOffset += 2; + return float16ToNumber(value); + } + + readFloat32() { + const value = this.dataView.getFloat32(this.byteOffset, this.littleEndian); + this.byteOffset += 4; + return value; + } + readString() { // Looking for the 'NULL' byte. let strLength = 0; diff --git a/packages/typed-binary/src/io/bufferWriter.ts b/packages/typed-binary/src/io/bufferWriter.ts index a5d1d56..7ee19b3 100644 --- a/packages/typed-binary/src/io/bufferWriter.ts +++ b/packages/typed-binary/src/io/bufferWriter.ts @@ -21,12 +21,21 @@ export class BufferWriter extends BufferIOBase implements ISerialOutput { this.dataView.setUint8(this.byteOffset++, value); } - writeFloat16(value: number): void { - this.dataView.setUint16( - this.byteOffset, - numberToFloat16(value), - this.littleEndian, - ); + writeInt8(value: number) { + this.dataView.setInt8(this.byteOffset++, value); + } + + writeUint8(value: number) { + this.dataView.setUint8(this.byteOffset++, value); + } + + writeInt16(value: number) { + this.dataView.setInt16(this.byteOffset, value, this.littleEndian); + this.byteOffset += 2; + } + + writeUint16(value: number) { + this.dataView.setUint16(this.byteOffset, value, this.littleEndian); this.byteOffset += 2; } @@ -40,6 +49,15 @@ export class BufferWriter extends BufferIOBase implements ISerialOutput { this.byteOffset += 4; } + writeFloat16(value: number): void { + this.dataView.setUint16( + this.byteOffset, + numberToFloat16(value), + this.littleEndian, + ); + this.byteOffset += 2; + } + writeFloat32(value: number) { this.dataView.setFloat32(this.byteOffset, value, this.littleEndian); this.byteOffset += 4; diff --git a/packages/typed-binary/src/io/types.ts b/packages/typed-binary/src/io/types.ts index a375d4a..6ff77df 100644 --- a/packages/typed-binary/src/io/types.ts +++ b/packages/typed-binary/src/io/types.ts @@ -4,11 +4,18 @@ export type BufferView = ArrayLike & ArrayBufferView; export interface ISerialInput { readBool(): boolean; + /** + * @deprecated Use `readUint8` instead. + */ readByte(): number; + readInt8(): number; + readUint8(): number; + readInt16(): number; + readUint16(): number; readInt32(): number; readUint32(): number; - readFloat32(): number; readFloat16(): number; + readFloat32(): number; readString(): string; readSlice(bufferView: BufferView, offset: number, byteLength: number): void; seekTo(offset: number): void; @@ -19,11 +26,18 @@ export interface ISerialInput { export interface ISerialOutput { writeBool(value: boolean): void; + /** + * @deprecated Use `writeUint8` instead. + */ writeByte(value: number): void; + writeInt8(value: number): void; + writeUint8(value: number): void; + writeInt16(value: number): void; + writeUint16(value: number): void; writeInt32(value: number): void; writeUint32(value: number): void; - writeFloat32(value: number): void; writeFloat16(value: number): void; + writeFloat32(value: number): void; writeString(value: string): void; writeSlice(bufferView: BufferView): void; seekTo(offset: number): void; diff --git a/packages/typed-binary/src/structure/baseTypes.ts b/packages/typed-binary/src/structure/baseTypes.ts index 8b9dbaa..802785a 100644 --- a/packages/typed-binary/src/structure/baseTypes.ts +++ b/packages/typed-binary/src/structure/baseTypes.ts @@ -70,10 +70,10 @@ export class StringSchema extends Schema { } //// -// BYTE +// i8 //// -export class ByteSchema extends Schema { +export class Int8Schema extends Schema { /** * The maximum number of bytes this schema can take up. * @@ -82,11 +82,11 @@ export class ByteSchema extends Schema { readonly maxSize = 1; read(input: ISerialInput): number { - return input.readByte(); + return input.readInt8(); } write(output: ISerialOutput, value: number): void { - output.writeByte(value); + output.writeInt8(value); } measure( @@ -97,6 +97,90 @@ export class ByteSchema extends Schema { } } +//// +// u8 +//// + +export class Uint8Schema extends Schema { + /** + * The maximum number of bytes this schema can take up. + * + * Alias for `.measure(MaxValue).size` + */ + readonly maxSize = 1; + + read(input: ISerialInput): number { + return input.readUint8(); + } + + write(output: ISerialOutput, value: number): void { + output.writeUint8(value); + } + + measure( + _: number | MaxValue, + measurer: IMeasurer = new Measurer(), + ): IMeasurer { + return measurer.add(1); + } +} + +//// +// i16 +//// + +export class Int16Schema extends Schema { + /** + * The maximum number of bytes this schema can take up. + * + * Alias for `.measure(MaxValue).size` + */ + readonly maxSize = 2; + + read(input: ISerialInput): number { + return input.readInt16(); + } + + write(output: ISerialOutput, value: number): void { + output.writeInt16(value); + } + + measure( + _: number | MaxValue, + measurer: IMeasurer = new Measurer(), + ): IMeasurer { + return measurer.add(2); + } +} + +//// +// u16 +//// + +export class Uint16Schema extends Schema { + /** + * The maximum number of bytes this schema can take up. + * + * Alias for `.measure(MaxValue).size` + */ + readonly maxSize = 2; + + read(input: ISerialInput): number { + return input.readUint16(); + } + + write(output: ISerialOutput, value: number): void { + output.writeUint16(value); + } + + measure( + _: number | MaxValue, + measurer: IMeasurer = new Measurer(), + ): IMeasurer { + return measurer.add(2); + } +} + //// // i32 //// diff --git a/packages/typed-binary/src/structure/index.ts b/packages/typed-binary/src/structure/index.ts index 839f547..b9169b2 100644 --- a/packages/typed-binary/src/structure/index.ts +++ b/packages/typed-binary/src/structure/index.ts @@ -14,7 +14,10 @@ export { // Specific schemas BoolSchema, StringSchema, - ByteSchema, + Int8Schema, + Uint8Schema, + Int16Schema, + Uint16Schema, Int32Schema, Uint32Schema, Float16Schema, diff --git a/packages/typed-binary/src/test/byte.test.ts b/packages/typed-binary/src/test/byte.test.ts deleted file mode 100644 index 6c93aa1..0000000 --- a/packages/typed-binary/src/test/byte.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { byte } from '../describe'; -import { encodeAndDecode } from './helpers/mock'; -import { randIntBetween } from './random'; - -describe('ByteSchema', () => { - it('should encode and decode a byte value', () => { - const value = randIntBetween(0, 256); - const decoded = encodeAndDecode(byte, value); - - expect(decoded).to.equal(value); - }); -}); diff --git a/packages/typed-binary/src/test/int.test.ts b/packages/typed-binary/src/test/int.test.ts index 68aeb93..dff04b9 100644 --- a/packages/typed-binary/src/test/int.test.ts +++ b/packages/typed-binary/src/test/int.test.ts @@ -1,9 +1,65 @@ import { describe, expect, it } from 'vitest'; -import { i32, u32 } from '../describe'; +import { i8, i16, i32, u8, u16, u32 } from '../describe'; import { encodeAndDecode } from './helpers/mock'; import { randIntBetween } from './random'; +describe('Int8Schema', () => { + it('should encode and decode a signed int8 value', () => { + const value = randIntBetween(-128, 127); + const decoded = encodeAndDecode(i8, value); + + expect(decoded).to.equal(value); + }); +}); + +describe('Uint8Schema', () => { + it('should encode and decode a byte value', () => { + const value = randIntBetween(0, 256); + const decoded = encodeAndDecode(u8, value); + + expect(decoded).to.equal(value); + }); +}); + +describe('Int16Schema', () => { + it('should encode and decode an int value', () => { + const value = randIntBetween(-100, 100); + const decoded = encodeAndDecode(i16, value); + + expect(decoded).to.equal(value); + }); + + it('should encode and decode the max pos int value', () => { + const value = 2 ** 15 - 1; + const decoded = encodeAndDecode(i16, value); + + expect(decoded).to.equal(value); + }); +}); + +describe('Uint16Schema', () => { + it('should encode and decode an uint16 value', () => { + const value = randIntBetween(0, 100); + const decoded = encodeAndDecode(u16, value); + + expect(decoded).to.equal(value); + }); + + it('should encode and decode the max uint16 value', () => { + const value = 2 ** 16 - 1; + const decoded = encodeAndDecode(u16, value); + + expect(decoded).to.equal(value); + }); + + it('max + 1 should overflow into 0', () => { + const decoded = encodeAndDecode(u16, 2 ** 16); + + expect(decoded).to.equal(0); + }); +}); + describe('Int32Schema', () => { it('should encode and decode an int value', () => { const value = randIntBetween(-100, 100); @@ -14,7 +70,7 @@ describe('Int32Schema', () => { it('should encode and decode the max pos int value', () => { const value = 2 ** 31 - 1; - const decoded = encodeAndDecode(u32, value); + const decoded = encodeAndDecode(i32, value); expect(decoded).to.equal(value); });