175 lines
3.9 KiB
JavaScript
175 lines
3.9 KiB
JavaScript
class ByteStream {
|
|
constructor(buffer = null) {
|
|
this.buffer = buffer || Buffer.alloc(0)
|
|
this.offset = 0
|
|
}
|
|
|
|
readUInt8() {
|
|
if (this.offset >= this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
const value = this.buffer.readUInt8(this.offset)
|
|
this.offset += 1
|
|
return value
|
|
}
|
|
|
|
readUInt16() {
|
|
if (this.offset + 2 > this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
const value = this.buffer.readUInt16BE(this.offset)
|
|
this.offset += 2
|
|
return value
|
|
}
|
|
|
|
readUInt24() {
|
|
if (this.offset + 3 > this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
const value =
|
|
(this.buffer.readUInt8(this.offset) << 16) |
|
|
(this.buffer.readUInt8(this.offset + 1) << 8) |
|
|
this.buffer.readUInt8(this.offset + 2)
|
|
this.offset += 3
|
|
return value
|
|
}
|
|
|
|
readUInt32() {
|
|
if (this.offset + 4 > this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
const value = this.buffer.readUInt32BE(this.offset)
|
|
this.offset += 4
|
|
return value
|
|
}
|
|
|
|
readInt32() {
|
|
if (this.offset + 4 > this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
const value = this.buffer.readInt32BE(this.offset)
|
|
this.offset += 4
|
|
return value
|
|
}
|
|
|
|
readString() {
|
|
const length = this.readUInt32()
|
|
if (length === 0) return ""
|
|
|
|
if (this.offset + length > this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
|
|
const value = this.buffer.toString("utf8", this.offset, this.offset + length)
|
|
this.offset += length
|
|
return value
|
|
}
|
|
|
|
readBytes(length) {
|
|
if (this.offset + length > this.buffer.length) {
|
|
throw new Error("ByteStream: Cannot read beyond buffer length")
|
|
}
|
|
const value = this.buffer.slice(this.offset, this.offset + length)
|
|
this.offset += length
|
|
return value
|
|
}
|
|
|
|
writeUInt8(value) {
|
|
const buf = Buffer.alloc(1)
|
|
buf.writeUInt8(value, 0)
|
|
this.buffer = Buffer.concat([this.buffer, buf])
|
|
return this
|
|
}
|
|
|
|
writeUInt16(value) {
|
|
const buf = Buffer.alloc(2)
|
|
buf.writeUInt16BE(value, 0)
|
|
this.buffer = Buffer.concat([this.buffer, buf])
|
|
return this
|
|
}
|
|
|
|
writeUInt24(value) {
|
|
const buf = Buffer.alloc(3)
|
|
buf.writeUInt8((value >> 16) & 0xff, 0)
|
|
buf.writeUInt8((value >> 8) & 0xff, 1)
|
|
buf.writeUInt8(value & 0xff, 2)
|
|
this.buffer = Buffer.concat([this.buffer, buf])
|
|
return this
|
|
}
|
|
|
|
writeUInt32(value) {
|
|
const buf = Buffer.alloc(4)
|
|
buf.writeUInt32BE(value, 0)
|
|
this.buffer = Buffer.concat([this.buffer, buf])
|
|
return this
|
|
}
|
|
|
|
writeInt32(value) {
|
|
const buf = Buffer.alloc(4)
|
|
buf.writeInt32BE(value, 0)
|
|
this.buffer = Buffer.concat([this.buffer, buf])
|
|
return this
|
|
}
|
|
|
|
writeString(value) {
|
|
this.writeUInt32(value.length)
|
|
if (value.length > 0) {
|
|
const buf = Buffer.from(value, "utf8")
|
|
this.buffer = Buffer.concat([this.buffer, buf])
|
|
}
|
|
return this
|
|
}
|
|
|
|
writeBytes(bytes) {
|
|
this.buffer = Buffer.concat([this.buffer, bytes])
|
|
return this
|
|
}
|
|
|
|
// Utility methods
|
|
getBuffer() {
|
|
return this.buffer
|
|
}
|
|
|
|
getLength() {
|
|
return this.buffer.length
|
|
}
|
|
|
|
getRemainingLength() {
|
|
return this.buffer.length - this.offset
|
|
}
|
|
|
|
getOffset() {
|
|
return this.offset
|
|
}
|
|
|
|
setOffset(offset) {
|
|
if (offset < 0 || offset > this.buffer.length) {
|
|
throw new Error("ByteStream: Invalid offset")
|
|
}
|
|
this.offset = offset
|
|
return this
|
|
}
|
|
|
|
reset() {
|
|
this.buffer = Buffer.alloc(0)
|
|
this.offset = 0
|
|
return this
|
|
}
|
|
|
|
clone() {
|
|
const cloned = new ByteStream(Buffer.from(this.buffer))
|
|
cloned.offset = this.offset
|
|
return cloned
|
|
}
|
|
|
|
toHex() {
|
|
return this.buffer.toString("hex")
|
|
}
|
|
|
|
static fromHex(hexString) {
|
|
return new ByteStream(Buffer.from(hexString, "hex"))
|
|
}
|
|
}
|
|
|
|
module.exports = ByteStream
|