Skip to content

Commit

Permalink
feat: Added missing numeric schemas.
Browse files Browse the repository at this point in the history
  • Loading branch information
iwoplaza committed Dec 17, 2024
1 parent c2e353e commit 7184d2f
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 38 deletions.
20 changes: 16 additions & 4 deletions packages/typed-binary/src/describe/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
type AnyObjectSchema,
ArraySchema,
BoolSchema,
ByteSchema,
CharsSchema,
DynamicArraySchema,
Float16Schema,
Expand All @@ -18,6 +17,12 @@ import {
TypedArraySchema,
Uint32Schema,
} from '../structure';
import {
Int16Schema,
Int8Schema,
Uint16Schema,
Uint8Schema,
} from '../structure/baseTypes';
import type {
AnySchema,
AnySchemaWithProperties,
Expand All @@ -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 = <T extends number>(length: T) => new CharsSchema(length);

export const object = <P extends Record<string, AnySchema>>(properties: P) =>
Expand Down
32 changes: 26 additions & 6 deletions packages/typed-binary/src/io/bufferReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
30 changes: 24 additions & 6 deletions packages/typed-binary/src/io/bufferWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
18 changes: 16 additions & 2 deletions packages/typed-binary/src/io/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ export type BufferView = ArrayLike<number> & 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;
Expand All @@ -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;
Expand Down
92 changes: 88 additions & 4 deletions packages/typed-binary/src/structure/baseTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ export class StringSchema extends Schema<string> {
}

////
// BYTE
// i8
////

export class ByteSchema extends Schema<number> {
export class Int8Schema extends Schema<number> {
/**
* The maximum number of bytes this schema can take up.
*
Expand All @@ -82,11 +82,11 @@ export class ByteSchema extends Schema<number> {
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(
Expand All @@ -97,6 +97,90 @@ export class ByteSchema extends Schema<number> {
}
}

////
// u8
////

export class Uint8Schema extends Schema<number> {
/**
* 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<number> {
/**
* 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<number> {
/**
* 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
////
Expand Down
14 changes: 0 additions & 14 deletions packages/typed-binary/src/test/byte.test.ts

This file was deleted.

60 changes: 58 additions & 2 deletions packages/typed-binary/src/test/int.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
import { describe, expect, it } from 'vitest';

import { i32, u32 } from '../describe';
import { i8, u8, i16, u16, i32, 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);
Expand All @@ -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);
});
Expand Down

0 comments on commit 7184d2f

Please sign in to comment.