occaecatidicta
Version:
193 lines (159 loc) • 4.77 kB
text/typescript
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);
}
}