ensureCapacity(len: number) { let minCapacity = this.count + len; if (minCapacity > this.buf.length) { this.grow(minCapacity); // double grow } }
constructor(buffer: Buffer) { this.buf = buffer; this.pos = 0; this.count = buffer.length; }
add(socket: net.Socket, data: Buffer) { if (this.state !== ST_STARTED) { return; } this.httpServer.emit('connection', socket); if (typeof (socket as any).ondata === 'function') { // compatible with stream2 (socket as any).ondata(data, 0, data.length); } else { // compatible with old stream socket.emit('data', data); } }
decode(route: string, buf: Buffer) { let protos = this.protos[route]; this.buffer = buf; this.offset = 0; if (!!protos) { let ret = this.decodeMsg({}, protos, this.buffer.length); if (this.decodeCheckMsg && !checkMsgValid(ret, protos, this.protos)) { console.error('decode check msg failed:', route, buf.length, buf); return null; } return ret; } return null; }
encode2Bytes(key: string, msg: object) { let buffer = this.encode(key, msg); if (!buffer || !buffer.length) { console.warn('encode msg failed! key : %j, msg : %j', key, msg); return null; } let bytes = new Uint8Array(buffer.length); for (let offset = 0; offset < buffer.length; offset++) { bytes[offset] = buffer.readUInt8(offset); } return bytes; }
describe('msgEncoderTest', function () { let protos = Protobuf.parse(require('./example.json')); // console.log(protos); let protobuf = new Protobuf({encoderProtos: protos, decoderProtos: protos}); it('encodeTest', function () { // console.log('%j', tc); for (let route in tc) { let msg = tc[route]; console.log('===================='); console.log(route); let buffer = protobuf.encode(route, msg); console.log(msg); console.log(buffer.length); // console.log(buffer); let decodeMsg = protobuf.decode(route, buffer); console.log(decodeMsg); console.log('===================='); util.equal(msg, decodeMsg).should.equal(true); } }); });
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; }
/** * Read body segment from data buffer to socket.packageBuffer; * * @param {Object} socket Socket instance * @param {Object} data Buffer instance * @param {Number} offset offset read star from data * @return {Number} new offset of data after read */ readBody(data: Buffer, offset: number) { let blen = this.packageSize - this.packageOffset; let dlen = data.length - offset; let len = Math.min(blen, dlen); let dend = offset + len; data.copy(this.packageBuffer, this.packageOffset, offset, dend); this.packageOffset += len; if (this.packageOffset === this.packageSize) { // if all the package finished let buffer = this.packageBuffer; this.emit('message', buffer); this.reset(); } return dend; }
ondata(chunk: Buffer) { if (this.state === ST_CLOSED) { throw new Error('socket has closed'); } if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk)) { throw new Error('invalid data'); } if (typeof chunk === 'string') { chunk = Buffer.from(chunk, 'utf8'); } let offset = 0, end = chunk.length; while (offset < end && this.state !== ST_CLOSED) { if (this.state === ST_HEAD) { offset = this.readHead(chunk, offset); } if (this.state === ST_BODY) { offset = this.readBody(chunk, offset); } } return true; }
let encodeMsgRoute = function (compressRoute: boolean, _route: number | string | Buffer, buffer: Buffer, offset: number) { if (compressRoute) { let route = _route as number; if (route > MSG_ROUTE_CODE_MAX) { throw new Error('route number is overflow'); } buffer[offset++] = (route >> 8) & 0xff; buffer[offset++] = route & 0xff; } else { let route = _route as Buffer; if (route) { buffer[offset++] = route.length & 0xff; copyArray(buffer, offset, route as Buffer, 0, route.length); offset += route.length; } else { buffer[offset++] = 0; } } return offset; }
/** * Feed data into composer. It would emit the package by an event when the package finished. * * @param {Buffer} data next chunk of data read from stream. * @param {Number} offset (Optional) offset index of the data Buffer. 0 by default. * @param {Number} end (Optional) end index (not includ) of the data Buffer. data.lenght by default. * @return {void} */ feed(data: Buffer, offset?: number, end?: number) { if (!data) { return; } if (this.state === ST_ERROR) { throw new Error('compose in error state, reset it first'); } offset = offset || 0; end = end || data.length; while (offset < end) { if (this.state === ST_LENGTH) { offset = this._readLength(data, offset, end); } if (this.state === ST_DATA) { offset = this._readData(data, offset, end); } if (this.state === ST_ERROR) { break; } } }
constructor(buffer: Buffer) { this.buf = buffer; this.pos = 0; this.count = buffer.length; }
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; }