int-cli
Version:
INT is the new generation of bottom-up created system of IoT and blockchain
131 lines (130 loc) • 4.75 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const package_1 = require("./package");
const events_1 = require("events");
const msgpack = require('msgpack-lite');
const assert = require('assert');
var WRITER_EVENT;
(function (WRITER_EVENT) {
WRITER_EVENT["error"] = "error";
WRITER_EVENT["finish"] = "finish";
})(WRITER_EVENT = exports.WRITER_EVENT || (exports.WRITER_EVENT = {}));
class PackageStreamWriter extends events_1.EventEmitter {
constructor() {
super();
this.m_pending = [];
this.m_toSendLength = 0;
this.m_writtenLength = 0;
this.m_sentLength = 0;
}
static fromPackage(cmdType, body, dataLength = 0) {
let writer = new PackageStreamWriter();
let writeHeader = {
version: 0,
magic: package_1.Package.magic,
flags: 0,
bodyLength: 0,
totalLength: 0,
cmdType,
};
let bodyBuffer = null;
writeHeader.bodyLength = 0;
if (body) {
bodyBuffer = msgpack.encode(body);
writeHeader.bodyLength = bodyBuffer.length;
}
writeHeader.totalLength = package_1.Package.headerLength + writeHeader.bodyLength + dataLength;
let headerBuffer = Buffer.alloc(package_1.Package.headerLength);
let offset = 0;
offset = headerBuffer.writeUInt16BE(writeHeader.magic, offset);
offset = headerBuffer.writeUInt16BE(writeHeader.version, offset);
offset = headerBuffer.writeUInt16BE(writeHeader.flags, offset);
offset = headerBuffer.writeUInt16BE(writeHeader.cmdType, offset);
offset = headerBuffer.writeUInt32BE(writeHeader.totalLength, offset);
offset = headerBuffer.writeUInt32BE(writeHeader.bodyLength, offset);
writer.m_toSendLength = writeHeader.totalLength;
writer.m_writtenLength = package_1.Package.headerLength + writeHeader.bodyLength;
writer.m_pending.push(headerBuffer);
if (bodyBuffer) {
writer.m_pending.push(bodyBuffer);
}
return writer;
}
bind(connection) {
assert(!this.m_connection);
if (this.m_connection) {
return this;
}
this.m_connection = connection;
this._doSend();
return this;
}
clone() {
let writer = new PackageStreamWriter();
for (let buf of this.m_pending) {
let _buf = buf;
writer.m_pending.push(Buffer.from(_buf.buffer, _buf.offset, _buf.length));
}
writer.m_toSendLength = this.m_toSendLength;
writer.m_writtenLength = 0;
writer.m_sentLength = 0;
writer.m_drainListener = undefined;
return writer;
}
writeData(buffer) {
if (!buffer.length) {
return this;
}
if (this.m_writtenLength + buffer.length > this.m_toSendLength) {
return this;
}
this.m_writtenLength += buffer.length;
this.m_pending.push(buffer);
this._doSend();
return this;
}
async _doSend() {
if (!this.m_connection) {
return;
}
if (this.m_drainListener) {
return;
}
let spliceTo = 0;
for (; spliceTo < this.m_pending.length; ++spliceTo) {
let buffer = this.m_pending[spliceTo];
let sent = this.m_connection.send(buffer);
if (sent < 0) {
setImmediate(() => { this.emit(WRITER_EVENT.error); });
return;
}
this.m_sentLength += sent;
if (sent < buffer.length) {
assert(!this.m_drainListener);
this.m_drainListener = () => {
this.m_drainListener = undefined;
this._doSend();
};
this.m_pending[spliceTo] = Buffer.from(buffer.buffer, buffer.offset + sent, buffer.length - sent);
this.m_connection.once('drain', this.m_drainListener);
break;
}
}
this.m_pending.splice(0, spliceTo);
assert(this.m_sentLength <= this.m_toSendLength);
if (this.m_sentLength === this.m_toSendLength) {
setImmediate(() => { this.emit(WRITER_EVENT.finish); });
}
}
close() {
if (this.m_connection && this.m_drainListener) {
this.m_connection.removeListener('drain', this.m_drainListener);
}
this.removeAllListeners(WRITER_EVENT.finish);
this.removeAllListeners(WRITER_EVENT.error);
this.m_connection = undefined;
this.m_drainListener = undefined;
return;
}
}
exports.PackageStreamWriter = PackageStreamWriter;