Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Last active May 29, 2022 13:08
Show Gist options
  • Save burdiuz/6617d06d44fcf0361ada4b38373f20ac to your computer and use it in GitHub Desktop.
Save burdiuz/6617d06d44fcf0361ada4b38373f20ac to your computer and use it in GitHub Desktop.
Simple wrapper over Uint8Array with a playhead
class ByteArray {
constructor(buffer, initPosition = 0) {
this.buffer = typeof buffer === "number" ? new Uint8Array(buffer) : buffer;
this.position = initPosition;
}
get bytesAvailable() {
return this.buffer.length - this.position;
}
get length() {
return this.buffer.length;
}
toString(charset = "utf-8") {
const decoder = new TextDecoder(charset);
return decoder.decode(this.buffer);
}
readUnsignedByte() {
return this.buffer[this.position++];
}
readUnsignedShort() {
return (this.readUnsignedByte() << 8) | this.readUnsignedByte();
}
readUnsignedInt() {
const value = (this.readUnsignedShort() << 16) | this.readUnsignedShort();
return value >>> 0;
}
/**
*
* @param {*} bytes Target byte array where to write bytes
* @param {*} offset Position defines where to start writing bytes into target
* @param {*} length Abmount of bytes to read
* @returns Target byte array
*/
readBytes(bytes, offset = 0, length = 0) {
if (!length) {
length = this.bytesAvailable;
}
if (!bytes) {
bytes = new ByteArray(offset + length);
}
let amountToRead = Math.min(this.bytesAvailable, length);
bytes.position = offset;
while (amountToRead > 0) {
bytes.writeUnsignedByte(this.readUnsignedByte());
amountToRead--;
}
return bytes;
}
readMultiByte(length, charSet = "utf-8") {
const part = this.readBytes(null, 0, length);
return part.toString(charSet);
}
writeUnsignedByte(value) {
this.buffer[this.position++] = (value >>> 0) & 0xff;
}
writeUnsignedShort(value) {
this.writeUnsignedByte(value >>> 8);
this.writeUnsignedByte(value);
}
writeUnsignedInt(value) {
this.writeUnsignedShort(value >>> 16);
this.writeUnsignedShort(value);
}
/**
*
* @param {*} bytes Byte array, ource of the data
* @param {*} offset Position from where to start reading
* @param {*} length Length of data to read
*/
writeBytes(bytes, offset = 0, length = 0) {
const pos = bytes.position;
bytes.position = offset;
if (!length) {
length = bytes.bytesAvailable;
}
while (length > 0) {
this.writeUnsignedByte(bytes.readUnsignedByte());
length--;
}
bytes.position = pos;
}
// charset not available for TextEncoder
// it is utf-8 by default
writeMultiByte(str) {
this.writeBytes(ByteArray.fromString(str));
}
/**
*
* @param {*} string Only utf-8 strings servisable
* @returns ByteArray
*/
static fromString(string) {
const decoder = new TextEncoder();
const buffer = decoder.encode(string);
return new ByteArray(buffer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment