UNPKG

occaecatidicta

Version:
193 lines (159 loc) 4.77 kB
import { getLogger } from 'omelox-logger'; let logger = getLogger('omelox-rpc', 'OutputBuffer'); import * as Utils from '../utils'; let BUFFER_SIZE_DEFAULT = 32; export class OutputBuffer { count = 0; size: number; offset: number = 0; buf: Buffer; constructor(size?: number) { this.size = size || BUFFER_SIZE_DEFAULT; this.buf = Buffer.alloc(this.size); } getData() { return this.buf; } getLength() { return this.count; } write(data: string, offset: number, len: number) { this.ensureCapacity(len); this.buf.write(data, offset, len); this.count += len; } writeBoolean(v: boolean) { this.writeByte(v ? 1 : 0); } writeByte(v: number) { this.ensureCapacity(1); this.buf.writeUInt8(v, this.count++); } writeBytes(bytes: Array<number>) { let len = bytes.length; this.ensureCapacity(len + 4); this.writeInt(len); for (let i = 0; i < len; i++) { this.buf.writeUInt8(bytes[i], this.count++); } } writeChar(v: number) { this.writeByte(v); } writeChars(bytes: Array<number>) { this.writeBytes(bytes); } writeDouble(v: number) { this.ensureCapacity(8); this.buf.writeDoubleLE(v, this.count); this.count += 8; } writeFloat(v: number) { this.ensureCapacity(4); this.buf.writeFloatLE(v, this.count); this.count += 4; } writeInt(v: number) { this.ensureCapacity(4); this.buf.writeInt32LE(v, this.count); this.count += 4; } writeShort(v: number) { this.ensureCapacity(2); this.buf.writeInt16LE(v, this.count); this.count += 2; } writeUInt(v: number) { this.ensureCapacity(4); this.buf.writeUInt32LE(v, this.count); this.count += 4; } writeUShort(v: number) { this.ensureCapacity(2); this.buf.writeUInt16LE(v, this.count); this.count += 2; } writeString(str: string) { let len = Buffer.byteLength(str); this.ensureCapacity(len + 4); this.writeInt(len); this.buf.write(str, this.count, len); this.count += len; } writeObject(object: any) { let type = Utils.getType(object); // console.log('writeObject type %s', type); // console.log(object) if (!type) { logger.error('invalid writeObject ' + object); return; } this.writeShort(type); let typeMap = Utils.typeMap; if (typeMap['null'] === type) { return; } if (typeMap['buffer'] === type) { this.writeBytes(object); return; } if (typeMap['array'] === type) { let len = object.length; this.writeInt(len); for (let i = 0; i < len; i++) { this.writeObject(object[i]); } return; } if (typeMap['string'] === type) { this.writeString(object); return; } if (typeMap['object'] === type) { this.writeString(JSON.stringify(object)); // logger.error('invalid writeObject object must be bearcat beans and should implement writeFields and readFields interfaces'); return; } if (typeMap['bean'] === type) { this.writeString(object['$id']); object.writeFields(this); return; } if (typeMap['boolean'] === type) { this.writeBoolean(object); return; } if (typeMap['float'] === type) { this.writeFloat(object); return; } if (typeMap['number'] === type) { this.writeInt(object); return; } } ensureCapacity(len: number) { let minCapacity = this.count + len; if (minCapacity > this.buf.length) { this.grow(minCapacity); // double grow } } grow(minCapacity: number) { let oldCapacity = this.buf.length; let newCapacity = oldCapacity << 1; if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } if (newCapacity < 0 && minCapacity < 0) { throw new Error('OutOfMemoryError'); // newCapacity = 0x7fffffff; // Integer.MAX_VALUE } // console.log('grow minCapacity %d newCapacity %d', minCapacity, newCapacity); let newBuf = Buffer.alloc(newCapacity); this.buf.copy(newBuf); this.buf = newBuf; } getBuffer() { return this.buf.slice(0, this.offset); } }