"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const events_1 = require("events"); // import * as streampkg from 'stream-pkg'; // import * as profiler from 'v8-profiler'; // import * as fs from 'fs'; const ST_LENGTH = 1; // state that we should read length const ST_DATA = 2; // state that we should read data const ST_ERROR = 3; // state that something wrong has happened class Composer extends events_1.EventEmitter { constructor() { super(); this.headbuf = new Buffer(2); this.headoffset = 0; this.state = ST_LENGTH; this.dataoffset = 0; this.buffoffset = 0; this.end = 0; this.length = 0; this.left = 0; this.hugePackMode = 0; this.hugePackModeFinished = 0; this.hugeBuf = Buffer.alloc(0); } feed(data) { if (!data) { return; } if (this.state === ST_ERROR) { throw new Error('compose in error state, reset it first'); } this.dataoffset = 0; this.end = data.length; this.length = this.length || 0; // data.copy(this._buf, this.offset); // this._buf.write(data); // Buffer.concat([this._buf, data]); while (this.dataoffset < this.end) { if (this.state === ST_LENGTH) { if (this.headoffset && (this.end - this.dataoffset + this.headoffset) >= 2) { data.copy(this.headbuf, this.headoffset, this.dataoffset, this.dataoffset + 2 - this.headoffset); this.dataoffset += 2 - this.headoffset; this.headoffset = 0; this.left = this.headbuf.readUInt16LE(0); if (this.hugePackMode && this.left < 32701) { this.hugePackModeFinished = 1; this.hugePackMode = 0; } if (this.left > 32700) { this.left = 32700; this.hugePackMode = 1; this.hugePackModeFinished = 0; if (!this.hugeBuf) { this.hugeBuf = Buffer.alloc(0); } } this.state = ST_DATA; this.buf = new Buffer(this.left); } else { if (this.end - this.dataoffset >= 2) { this.left = data.readUInt16LE(this.dataoffset); if (this.hugePackMode && this.left < 32701) { this.hugePackModeFinished = 1; this.hugePackMode = 0; } if (this.left > 32700) { this.left = 32700; this.hugePackMode = 1; this.hugePackModeFinished = 0; if (!this.hugeBuf) { this.hugeBuf = Buffer.alloc(0); } } this.state = ST_DATA; this.dataoffset = this.dataoffset + 2; this.buf = new Buffer(this.left); } else { data.copy(this.headbuf, 0, this.dataoffset, this.end); this.headoffset = this.end - this.dataoffset; this.dataoffset += this.headoffset; } } } if (this.state === ST_DATA) { let length = Math.min(this.left, data.length - this.dataoffset); data.copy(this.buf, this.buf.length - this.left, this.dataoffset, this.dataoffset + length); this.left -= length; this.dataoffset += length; if ((this.hugePackMode || this.hugePackModeFinished) && this.left === 0) { if (this.hugePackModeFinished === 0) { this.hugeBuf = Buffer.concat([this.hugeBuf, this.buf]); this.left = 0; this.state = ST_LENGTH; delete this.buf; } if (this.hugePackModeFinished === 1) { this.hugeBuf = Buffer.concat([this.hugeBuf, this.buf]); this.emit('data', this.hugeBuf); this.hugePackModeFinished = 0; this.hugePackMode = 0; this.left = 0; this.state = ST_LENGTH; delete this.buf; delete this.hugeBuf; } } else { if (this.left === 0) { this.emit('data', this.buf); this.left = 0; this.state = ST_LENGTH; delete this.buf; } } // return; } if (this.state === ST_ERROR) { break; } } } compose(data) { if (data.length === 0) { throw new Error('data should not be empty.'); } let d = Buffer.from(data); let totalLength = d.length; let offset = 0; let buf = new Buffer(d.length + 2 * (Math.floor(totalLength / 32700) + 1)); let loop = 0; while (totalLength !== 0) { let writelength = totalLength; let currentLength = totalLength; if (writelength > 32700) { writelength = 32701; currentLength = 32700; } buf.writeUInt16LE(writelength, offset + 2 * (loop)); d.copy(buf, 2 * (loop + 1) + offset, offset, offset + currentLength); offset = offset + currentLength; totalLength = totalLength - currentLength; loop = loop + 1; } return buf; } } exports.Composer = Composer; // profiler.startProfiling(); // let comp = new Compose(); // let buf = comp.compose(JSON.stringify({ // 'id': 10, // 'msg': { // 'namespace': 'user', 'serverType': 'test', 'service': 'service', 'method': 'echo', // 'args': [{ 'index': 9, 'time': 1498919947021 }], // }, // })); // console.time('1'); // for (let i = 0; i < 1; i++) { // comp.compose('你好世界'); // } // console.timeEnd('1'); // comp.on('data', (d: Buffer) => { // let s = JSON.parse(d.toString()); // console.log(s); // }); // console.time('1'); // for (let i = 0; i < 100; i++) { // buf = comp.compose(JSON.stringify({ // 'id': 10, // 'msg': { // 'namespace': 'user', 'serverType': 'test', 'service': 'service', 'method': 'echo', // 'args': [{ 'index': 9, 'time': 1498919947021 }], // }, // })); // comp.feed(buf); // comp.feed(buf.slice(0, 5)); // comp.feed(buf.slice(5, buf.length)); // } // console.timeEnd('1'); // let sp = new streampkg(); // buf = sp.compose('你好世界'); // console.time('1'); // for (let i = 0; i < 1000000; i++) { // sp.compose('你好世界'); // } // console.timeEnd('1'); // sp.on('data', (d) => { // // let s = d.toString(); // //console.log(s); // }); // console.time('1'); // for (let i = 0; i < 1000000; i++) { // sp.feed(buf); // sp.feed(buf.slice(0, 5)); // sp.feed(buf.slice(5, buf.length)); // } // console.timeEnd('1'); // profiler.stopProfiling().export((error, result) => { // fs.writeFileSync('client.cpuprofile', result); // console.log('clientside profile saved'); // });