diff --git a/.vscode/settings.json b/.vscode/settings.json index d9cacd40f..ecbf47ef4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -127,6 +127,7 @@ "webp", "winrate", "wotblitz", + "xffn", "xkdkw", "XMLDVPL", "YAMLDVPL", diff --git a/docs/guide/bkon.md b/docs/guide/bkon.md index a6a2f2ca5..66ae5e772 100644 --- a/docs/guide/bkon.md +++ b/docs/guide/bkon.md @@ -1,6 +1,6 @@ # Blitzkrieg Object Notation -A compact binary representation of JSON objects. This documentation uses a frankenstein version of C++ structs that I came up with. Deal with it. +A compact binary representation similar to JSON objects. This documentation uses some funky (yet concise) syntax I developed (don't worry, my C++ isn't that bad!). ## Primitives @@ -70,10 +70,7 @@ enum ValueType { Object, } -struct Value { - uint8 type; - // what comes next depends on type -} +struct Value = `Value${ValueType}` struct ValueNull { ValueType.Null type; diff --git a/src/core/streams/buffer.ts b/src/core/streams/buffer.ts index beba425b5..19457a0a3 100644 --- a/src/core/streams/buffer.ts +++ b/src/core/streams/buffer.ts @@ -71,3 +71,76 @@ export class ReadStream { return this.buffer.readUInt8(this.increment(1)) === 1; } } + +export class WriteStream { + private array: number[] = []; + + get buffer() { + return Buffer.from(this.array); + } + + constructor(buffer?: Buffer) { + if (buffer) this.array = Array.from(buffer); + } + + byte(value: Uint8Array) { + this.array.push(...value); + return this; + } + + ascii(value: string) { + for (let index = 0; index < value.length; index++) { + this.array.push(value.charCodeAt(index)); + } + return this; + } + + private uintN(bytes: number, value: number) { + for (let index = 0; index < bytes; index++) { + this.array.push((value >>> (8 * index)) & 0xff); + } + return this; + } + uint8(value: number) { + this.uintN(1, value); + return this; + } + uint16(value: number) { + this.uintN(2, value); + return this; + } + uint32(value: number) { + this.uintN(4, value); + return this; + } + uint64(value: bigint) { + for (let index = 0n; index < 8n; index++) { + this.uint8(Number((value >> (8n * index)) & 0xffn)); + } + return this; + } + private intN(bytes: number, value: number) { + for (let index = 0; index < bytes; index++) { + this.array.push((value >> (8 * index)) & 0xff); + } + return this; + } + int8(value: number) { + this.intN(1, value); + return this; + } + int16(value: number) { + this.intN(2, value); + return this; + } + int32(value: number) { + this.intN(4, value); + return this; + } + int64(value: bigint) { + for (let index = 0n; index < 8n; index++) { + this.int8(Number((value >> (8n * index)) & 0xffn)); + } + return this; + } +}