UNPKG

@creditkarma/thrift-server-core

Version:
304 lines 9.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BinaryProtocol = void 0; const binary = require("../binary"); const errors_1 = require("../errors"); const types_1 = require("../types"); const logger_1 = require("../logger"); const TProtocol_1 = require("./TProtocol"); const VERSION_MASK = -65536; const VERSION_1 = -2147418112; const TYPE_MASK = 0x000000ff; class BinaryProtocol extends TProtocol_1.TProtocol { constructor(trans, logger = logger_1.defaultLogger) { super(trans, logger); } writeMessageBegin(name, type, requestId) { this.writeI32(VERSION_1 | type); this.writeString(name); this.writeI32(requestId); if (this.requestId) { this.logger(['warn', 'BinaryProtocol'], `requestId already set: ${name}`); } else { this.requestId = requestId; } } writeMessageEnd() { if (this.requestId !== null) { this.requestId = null; } else { this.logger(['warn', 'BinaryProtocol'], 'No requestId to unset'); } } writeStructBegin(name) { } writeStructEnd() { } writeFieldBegin(name, type, id) { this.writeByte(type); this.writeI16(id); } writeFieldEnd() { } writeFieldStop() { this.writeByte(types_1.TType.STOP); } writeMapBegin(keyType, valueType, size) { this.writeByte(keyType); this.writeByte(valueType); this.writeI32(size); } writeMapEnd() { } writeListBegin(elementType, size) { this.writeByte(elementType); this.writeI32(size); } writeListEnd() { } writeSetBegin(elementType, size) { this.writeByte(elementType); this.writeI32(size); } writeSetEnd() { } writeBool(bool) { if (bool) { this.writeByte(1); } else { this.writeByte(0); } } writeByte(byte) { const value = Number(byte); if (!isNaN(value)) { this.transport.write(Buffer.from([value])); } else { throw new TypeError(`Expected number but found type ${typeof byte}`); } } writeI16(i16) { const value = Number(i16); if (!isNaN(value)) { this.transport.write(binary.writeI16(Buffer.alloc(2), value)); } else { throw new TypeError(`Expected number but found type ${typeof i16}`); } } writeI32(i32) { const value = Number(i32); if (!isNaN(value)) { this.transport.write(binary.writeI32(Buffer.alloc(4), value)); } else { throw new TypeError(`Expected number but found type ${typeof i32}`); } } writeI64(i64) { if (typeof i64 === 'number') { i64 = new types_1.Int64(i64); } else if (typeof i64 === 'string') { i64 = types_1.Int64.fromDecimalString(i64); } if ((0, types_1.isInt64)(i64)) { this.transport.write(i64.buffer); } else { throw new TypeError(`Expected Int64, number, or decimal string but found type ${typeof i64}`); } } writeDouble(dub) { const value = Number(dub); if (!isNaN(value)) { this.transport.write(binary.writeDouble(Buffer.alloc(8), value)); } else { throw new TypeError(`Expected number but found type ${typeof dub}`); } } writeStringOrBinary(name, encoding, data) { if (typeof data === 'string') { this.writeI32(Buffer.byteLength(data, encoding)); this.transport.write(Buffer.from(data, encoding)); } else if (data instanceof Buffer) { this.writeI32(data.length); this.transport.write(data); } else { throw new TypeError(`Argument of type ${typeof data} should be buffer or string`); } } writeString(data) { this.writeStringOrBinary('writeString', 'utf8', data); } writeBinary(data) { this.writeStringOrBinary('writeBinary', 'binary', data); } readMessageBegin() { const size = this.readI32(); if (size < 0) { const version = size & VERSION_MASK; if (version !== VERSION_1) { throw new errors_1.TProtocolException(errors_1.TProtocolExceptionType.BAD_VERSION, `Bad version in readMessageBegin: ${size}`); } return { fieldName: this.readString(), messageType: size & TYPE_MASK, requestId: this.readI32(), }; } else { return { fieldName: this.transport.readString(size), messageType: this.readByte(), requestId: this.readI32(), }; } } readMessageEnd() { } readStructBegin() { return { fieldName: '' }; } readStructEnd() { } readFieldBegin() { const type = this.readByte(); if (type === types_1.TType.STOP) { return { fieldName: '', fieldType: type, fieldId: 0 }; } else { const id = this.readI16(); return { fieldName: '', fieldType: type, fieldId: id }; } } readFieldEnd() { } readMapBegin() { const keyType = this.readByte(); const valueType = this.readByte(); const size = this.readI32(); return { keyType, valueType, size }; } readMapEnd() { } readListBegin() { const elementType = this.readByte(); const size = this.readI32(); return { elementType, size }; } readListEnd() { } readSetBegin() { const elementType = this.readByte(); const size = this.readI32(); return { elementType, size }; } readSetEnd() { } readBool() { const byte = this.readByte(); return byte !== 0; } readByte() { return this.transport.readByte(); } readI16() { return this.transport.readI16(); } readI32() { return this.transport.readI32(); } readI64() { const buff = this.transport.read(8); return new types_1.Int64(buff); } readDouble() { return this.transport.readDouble(); } readBinary() { const len = this.readI32(); if (len === 0) { return Buffer.alloc(0); } else if (len < 0) { throw new errors_1.TProtocolException(errors_1.TProtocolExceptionType.NEGATIVE_SIZE, 'Negative binary size'); } else { return this.transport.read(len); } } readString() { const len = this.readI32(); if (len === 0) { return ''; } if (len < 0) { throw new errors_1.TProtocolException(errors_1.TProtocolExceptionType.NEGATIVE_SIZE, 'Negative string size'); } return this.transport.readString(len); } getTransport() { return this.transport; } skip(type) { switch (type) { case types_1.TType.STOP: return; case types_1.TType.BOOL: this.readBool(); break; case types_1.TType.BYTE: this.readByte(); break; case types_1.TType.I16: this.readI16(); break; case types_1.TType.I32: this.readI32(); break; case types_1.TType.I64: this.readI64(); break; case types_1.TType.DOUBLE: this.readDouble(); break; case types_1.TType.STRING: this.readString(); break; case types_1.TType.STRUCT: this.readStructBegin(); while (true) { const fieldBegin = this.readFieldBegin(); if (fieldBegin.fieldType === types_1.TType.STOP) { break; } this.skip(fieldBegin.fieldType); this.readFieldEnd(); } this.readStructEnd(); break; case types_1.TType.MAP: const mapBegin = this.readMapBegin(); for (let i = 0; i < mapBegin.size; ++i) { this.skip(mapBegin.keyType); this.skip(mapBegin.valueType); } this.readMapEnd(); break; case types_1.TType.SET: const setBegin = this.readSetBegin(); for (let i2 = 0; i2 < setBegin.size; ++i2) { this.skip(setBegin.elementType); } this.readSetEnd(); break; case types_1.TType.LIST: const listBegin = this.readListBegin(); for (let i3 = 0; i3 < listBegin.size; ++i3) { this.skip(listBegin.elementType); } this.readListEnd(); break; default: throw new Error('Invalid type: ' + type); } } } exports.BinaryProtocol = BinaryProtocol; //# sourceMappingURL=BinaryProtocol.js.map