Created
June 23, 2024 12:33
-
-
Save iamtekeste/6f188896569a875135554755ba1be368 to your computer and use it in GitHub Desktop.
BinaryWriter to be used with Rive projects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum Endian { | |
Little = "little", | |
Big = "big", | |
} | |
class BinaryWriter { | |
variableEncodeList = new Uint8Array(8); | |
writeIndex = 0; | |
alignment: number; // Add this line | |
endian: Endian; // Add this line | |
buffer: Uint8Array; // Add this line | |
constructor(alignment = 1024, endian = Endian.Little) { | |
this.alignment = Math.max(1, alignment); | |
this.endian = endian; | |
this.buffer = new Uint8Array(this.alignment); | |
} | |
get size() { | |
return this.writeIndex; | |
} | |
nextAlignment(length: number) { | |
return Math.ceil(length / this.alignment) * this.alignment; | |
} | |
ensureAvailable(byteLength: number) { | |
if (this.writeIndex + byteLength > this.buffer.length) { | |
let newLength = this.buffer.length + this.nextAlignment(byteLength); | |
const newBuffer = new Uint8Array(newLength); | |
newBuffer.set(this.buffer); | |
this.buffer = newBuffer; | |
} | |
} | |
get uint8Buffer() { | |
return new Uint8Array( | |
this.buffer.buffer, | |
this.buffer.byteOffset, | |
this.size | |
); | |
} | |
getBuffer() { | |
return this.buffer; | |
} | |
writeFloat32(value: number) { | |
this.ensureAvailable(4); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setFloat32(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 4; | |
} | |
writeFloat64(value: number) { | |
this.ensureAvailable(8); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setFloat64(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 8; | |
} | |
writeInt8(value: number) { | |
this.ensureAvailable(1); | |
this.buffer[this.writeIndex] = value; | |
this.writeIndex += 1; | |
} | |
writeUint8(value: number) { | |
this.ensureAvailable(1); | |
this.buffer[this.writeIndex] = value; | |
this.writeIndex += 1; | |
} | |
writeInt16(value: number) { | |
this.ensureAvailable(2); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setInt16(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 2; | |
} | |
writeUint16(value: number) { | |
this.ensureAvailable(2); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setUint16(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 2; | |
} | |
writeInt32(value) { | |
this.ensureAvailable(4); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setInt32(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 4; | |
} | |
writeUint32(value: number) { | |
this.ensureAvailable(4); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setUint32(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 4; | |
} | |
writeInt64(value: bigint) { | |
this.ensureAvailable(8); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setBigInt64(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 8; | |
} | |
writeUint64(value: bigint) { | |
this.ensureAvailable(8); | |
const view = new DataView(this.buffer.buffer, this.buffer.byteOffset); | |
view.setBigUint64(this.writeIndex, value, this.endian === Endian.Little); | |
this.writeIndex += 8; | |
} | |
write(bytes: Uint8Array, length?: number) { | |
length = length ? length : bytes.length; | |
this.ensureAvailable(length); | |
this.buffer.set(bytes, this.writeIndex); | |
this.writeIndex += length; | |
} | |
writeVarUint(value: number) { | |
let size = Math.ceil(value.toString(2).length / 7); | |
let index = 0; | |
let i = 0; | |
while (i < size) { | |
let part = value & 0x7f; | |
value >>= 7; | |
this.variableEncodeList[index++] = part; | |
i += 1; | |
} | |
for (let i = 0; i < index - 1; i++) { | |
this.variableEncodeList[i] |= 0x80; | |
} | |
this.write(this.variableEncodeList.subarray(0, index)); | |
} | |
writeString(value: string, explicitLength: boolean = true) { | |
const encoder = new TextEncoder(); | |
const bytes = encoder.encode(value); | |
if (explicitLength) { | |
this.writeVarUint(bytes.length); | |
} | |
this.write(bytes); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment