@uk/tool
Version:
Uk tools module
120 lines (112 loc) • 4.83 kB
text/typescript
export interface BinBuffer {
index: number;
packedBitCount: number;
source: Buffer;
packetReadNext: boolean;
readUInt8(offset?: number, noAssert?: boolean): number;
readUInt16LE(offset?: number, noAssert?: boolean): number;
readUInt16BE(offset?: number, noAssert?: boolean): number;
readUInt32LE(offset?: number, noAssert?: boolean): number;
readUInt32BE(offset?: number, noAssert?: boolean): number;
readInt8(offset?: number, noAssert?: boolean): number;
readInt16LE(offset?: number, noAssert?: boolean): number;
readInt16BE(offset?: number, noAssert?: boolean): number;
readInt32LE(offset?: number, noAssert?: boolean): number;
readInt32BE(offset?: number, noAssert?: boolean): number;
readPackedInt(offset?: number, noAssert?: boolean): number;
writeUInt8(value: number, offset?: number, noAssert?: boolean): number;
writeUInt16LE(value: number, offset?: number, noAssert?: boolean): number;
writeUInt16BE(value: number, offset?: number, noAssert?: boolean): number;
writeUInt32LE(value: number, offset?: number, noAssert?: boolean): number;
writeUInt32BE(value: number, offset?: number, noAssert?: boolean): number;
writeInt8(value: number, offset?: number, noAssert?: boolean): number;
writeInt16LE(value: number, offset?: number, noAssert?: boolean): number;
writeInt16BE(value: number, offset?: number, noAssert?: boolean): number;
writeInt32LE(value: number, offset?: number, noAssert?: boolean): number;
writeInt32BE(value: number, offset?: number, noAssert?: boolean): number;
writeFloatLE(value: number, offset?: number, noAssert?: boolean): number;
writeFloatBE(value: number, offset?: number, noAssert?: boolean): number;
writeDoubleLE(value: number, offset?: number, noAssert?: boolean): number;
writeDoubleBE(value: number, offset?: number, noAssert?: boolean): number;
}
function createReader(func: Function, byteCount: number) {
return function(this: BinBuffer, idx?: number, noassert?: boolean): number {
const noidx = idx === undefined;
const rv = func.call(this.source, noidx ? this.index : idx, noassert);
if (noidx) this.index += byteCount;
return rv;
}
}
function createWriter(func: Function, byteCount: number) {
return function(this: BinBuffer, value?: any, idx?: number, noassert?: boolean): number {
const noidx = idx === undefined;
const rv = func.call(this.source, value, noidx ? this.index : idx, noassert);
if (noidx) this.index += byteCount;
return rv;
}
}
export const BinBuffer: { new(buffer: Buffer, index?: number): BinBuffer } = function BinBuffer(this: BinBuffer, buffer: Buffer, index?: number) {
this.source = buffer;
this.index = index || 0;
} as any;
for (const n in Buffer.prototype) {
const member = Buffer.prototype[n] as any;
if (member instanceof Function) {
let func;
switch (n) {
case 'readUInt8':
case 'readInt8':
func = createReader(member, 1);
break;
case 'readUInt16LE':
case 'readUInt16BE':
case 'readInt16LE':
case 'readInt16BE':
func = createReader(member, 2);
break;
case 'readUInt32LE':
case 'readUInt32BE':
case 'readInt32LE':
case 'readInt32BE':
func = createReader(member, 4);
break;
case 'writeUInt8':
case 'writeInt8':
func = createWriter(member, 1);
break;
case 'writeUInt16LE':
case 'writeUInt16BE':
case 'writeInt16LE':
case 'writeInt16BE':
func = createWriter(member, 2);
break;
case 'writeUInt32LE':
case 'writeUInt32BE':
case 'writeInt32LE':
case 'writeInt32BE':
func = createWriter(member, 4);
break;
default:
func = function(this: BinBuffer) {
member.apply(this.source, arguments);
}
break;
}
BinBuffer.prototype[n] = func;
} else {
BinBuffer.prototype[n] = member;
}
}
BinBuffer.prototype.readPackedInt = function(this: BinBuffer, offset?: number, noAssert?: boolean): number {
if (offset !== undefined && offset >= 0) this.index = +offset;
let rv = 0, byte = 0, idx = 0;
this.packetReadNext = false;
this.packedBitCount = 0;
do {
byte = this.source.readUInt8(this.index++);
rv = rv << 7 | byte & 0x7F;
this.packedBitCount += 7;
} while (byte & 0x80 && idx++ < 4);
this.packetReadNext = (byte & 0x80) !== 0;
return rv;
}