module.exports = (function() { var __MODS__ = {}; var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; }; var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; }; var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } }; var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; }; __DEFINE__(1682324647504, function(require, module, exports) { exports.parser = require('./parser').parser exports.generate = require('./generate') exports.writeToStream = require('./writeToStream') }, function(modId) {var map = {"./parser":1682324647505,"./generate":1682324647508,"./writeToStream":1682324647509}; return __REQUIRE__(map[modId], modId); }) __DEFINE__(1682324647505, function(require, module, exports) { const bl = require('bl') const EventEmitter = require('events') const Packet = require('./packet') const constants = require('./constants') const debug = require('debug')('mqtt-packet:parser') class Parser extends EventEmitter { constructor () { super() this.parser = this.constructor.parser } static parser (opt) { if (!(this instanceof Parser)) return (new Parser()).parser(opt) this.settings = opt || {} this._states = [ '_parseHeader', '_parseLength', '_parsePayload', '_newPacket' ] this._resetState() return this } _resetState () { debug('_resetState: resetting packet, error, _list, and _stateCounter') this.packet = new Packet() this.error = null this._list = bl() this._stateCounter = 0 } parse (buf) { if (this.error) this._resetState() this._list.append(buf) debug('parse: current state: %s', this._states[this._stateCounter]) while ((this.packet.length !== -1 || this._list.length > 0) && this[this._states[this._stateCounter]]() && !this.error) { this._stateCounter++ debug('parse: state complete. _stateCounter is now: %d', this._stateCounter) debug('parse: packet.length: %d, buffer list length: %d', this.packet.length, this._list.length) if (this._stateCounter >= this._states.length) this._stateCounter = 0 } debug('parse: exited while loop. packet: %d, buffer list length: %d', this.packet.length, this._list.length) return this._list.length } _parseHeader () { // There is at least one byte in the buffer const zero = this._list.readUInt8(0) this.packet.cmd = constants.types[zero >> constants.CMD_SHIFT] this.packet.retain = (zero & constants.RETAIN_MASK) !== 0 this.packet.qos = (zero >> constants.QOS_SHIFT) & constants.QOS_MASK this.packet.dup = (zero & constants.DUP_MASK) !== 0 debug('_parseHeader: packet: %o', this.packet) this._list.consume(1) return true } _parseLength () { // There is at least one byte in the list const result = this._parseVarByteNum(true) if (result) { this.packet.length = result.value this._list.consume(result.bytes) } debug('_parseLength %d', result.value) return !!result } _parsePayload () { debug('_parsePayload: payload %O', this._list) let result = false // Do we have a payload? Do we have enough data to complete the payload? // PINGs have no payload if (this.packet.length === 0 || this._list.length >= this.packet.length) { this._pos = 0 switch (this.packet.cmd) { case 'connect': this._parseConnect() break case 'connack': this._parseConnack() break case 'publish': this._parsePublish() break case 'puback': case 'pubrec': case 'pubrel': case 'pubcomp': this._parseConfirmation() break case 'subscribe': this._parseSubscribe() break case 'suback': this._parseSuback() break case 'unsubscribe': this._parseUnsubscribe() break case 'unsuback': this._parseUnsuback() break case 'pingreq': case 'pingresp': // These are empty, nothing to do break case 'disconnect': this._parseDisconnect() break case 'auth': this._parseAuth() break default: this._emitError(new Error('Not supported')) } result = true } debug('_parsePayload complete result: %s', result) return result } _parseConnect () { debug('_parseConnect') let topic // Will topic let payload // Will payload let password // Password let username // Username const flags = {} const packet = this.packet // Parse protocolId const protocolId = this._parseString() if (protocolId === null) return this._emitError(new Error('Cannot parse protocolId')) if (protocolId !== 'MQTT' && protocolId !== 'MQIsdp') { return this._emitError(new Error('Invalid protocolId')) } packet.protocolId = protocolId // Parse constants version number if (this._pos >= this._list.length) return this._emitError(new Error('Packet too short')) packet.protocolVersion = this._list.readUInt8(this._pos) if (packet.protocolVersion >= 128) { packet.bridgeMode = true packet.protocolVersion = packet.protocolVersion - 128 } if (packet.protocolVersion !== 3 && packet.protocolVersion !== 4 && packet.protocolVersion !== 5) { return this._emitError(new Error('Invalid protocol version')) } this._pos++ if (this._pos >= this._list.length) { return this._emitError(new Error('Packet too short')) } // Parse connect flags flags.username = (this._list.readUInt8(this._pos) & constants.USERNAME_MASK) flags.password = (this._list.readUInt8(this._pos) & constants.PASSWORD_MASK) flags.will = (this._list.readUInt8(this._pos) & constants.WILL_FLAG_MASK) if (flags.will) { packet.will = {} packet.will.retain = (this._list.readUInt8(this._pos) & constants.WILL_RETAIN_MASK) !== 0 packet.will.qos = (this._list.readUInt8(this._pos) & constants.WILL_QOS_MASK) >> constants.WILL_QOS_SHIFT } packet.clean = (this._list.readUInt8(this._pos) & constants.CLEAN_SESSION_MASK) !== 0 this._pos++ // Parse keepalive packet.keepalive = this._parseNum() if (packet.keepalive === -1) return this._emitError(new Error('Packet too short')) // parse properties if (packet.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } // Parse clientId const clientId = this._parseString() if (clientId === null) return this._emitError(new Error('Packet too short')) packet.clientId = clientId debug('_parseConnect: packet.clientId: %s', packet.clientId) if (flags.will) { if (packet.protocolVersion === 5) { const willProperties = this._parseProperties() if (Object.getOwnPropertyNames(willProperties).length) { packet.will.properties = willProperties } } // Parse will topic topic = this._parseString() if (topic === null) return this._emitError(new Error('Cannot parse will topic')) packet.will.topic = topic debug('_parseConnect: packet.will.topic: %s', packet.will.topic) // Parse will payload payload = this._parseBuffer() if (payload === null) return this._emitError(new Error('Cannot parse will payload')) packet.will.payload = payload debug('_parseConnect: packet.will.paylaod: %s', packet.will.payload) } // Parse username if (flags.username) { username = this._parseString() if (username === null) return this._emitError(new Error('Cannot parse username')) packet.username = username debug('_parseConnect: packet.username: %s', packet.username) } // Parse password if (flags.password) { password = this._parseBuffer() if (password === null) return this._emitError(new Error('Cannot parse password')) packet.password = password } // need for right parse auth packet and self set up this.settings = packet debug('_parseConnect: complete') return packet } _parseConnack () { debug('_parseConnack') const packet = this.packet if (this._list.length < 1) return null packet.sessionPresent = !!(this._list.readUInt8(this._pos++) & constants.SESSIONPRESENT_MASK) if (this.settings.protocolVersion === 5) { if (this._list.length >= 2) { packet.reasonCode = this._list.readUInt8(this._pos++) } else { packet.reasonCode = 0 } } else { if (this._list.length < 2) return null packet.returnCode = this._list.readUInt8(this._pos++) } if (packet.returnCode === -1 || packet.reasonCode === -1) return this._emitError(new Error('Cannot parse return code')) // mqtt 5 properties if (this.settings.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } debug('_parseConnack: complete') } _parsePublish () { debug('_parsePublish') const packet = this.packet packet.topic = this._parseString() if (packet.topic === null) return this._emitError(new Error('Cannot parse topic')) // Parse messageId if (packet.qos > 0) if (!this._parseMessageId()) { return } // Properties mqtt 5 if (this.settings.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } packet.payload = this._list.slice(this._pos, packet.length) debug('_parsePublish: payload from buffer list: %o', packet.payload) } _parseSubscribe () { debug('_parseSubscribe') const packet = this.packet let topic let options let qos let rh let rap let nl let subscription if (packet.qos !== 1) { return this._emitError(new Error('Wrong subscribe header')) } packet.subscriptions = [] if (!this._parseMessageId()) { return } // Properties mqtt 5 if (this.settings.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } while (this._pos < packet.length) { // Parse topic topic = this._parseString() if (topic === null) return this._emitError(new Error('Cannot parse topic')) if (this._pos >= packet.length) return this._emitError(new Error('Malformed Subscribe Payload')) options = this._parseByte() qos = options & constants.SUBSCRIBE_OPTIONS_QOS_MASK nl = ((options >> constants.SUBSCRIBE_OPTIONS_NL_SHIFT) & constants.SUBSCRIBE_OPTIONS_NL_MASK) !== 0 rap = ((options >> constants.SUBSCRIBE_OPTIONS_RAP_SHIFT) & constants.SUBSCRIBE_OPTIONS_RAP_MASK) !== 0 rh = (options >> constants.SUBSCRIBE_OPTIONS_RH_SHIFT) & constants.SUBSCRIBE_OPTIONS_RH_MASK subscription = { topic, qos } // mqtt 5 options if (this.settings.protocolVersion === 5) { subscription.nl = nl subscription.rap = rap subscription.rh = rh } else if (this.settings.bridgeMode) { subscription.rh = 0 subscription.rap = true subscription.nl = true } // Push pair to subscriptions debug('_parseSubscribe: push subscription `%s` to subscription', subscription) packet.subscriptions.push(subscription) } } _parseSuback () { debug('_parseSuback') const packet = this.packet this.packet.granted = [] if (!this._parseMessageId()) { return } // Properties mqtt 5 if (this.settings.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } // Parse granted QoSes while (this._pos < this.packet.length) { this.packet.granted.push(this._list.readUInt8(this._pos++)) } } _parseUnsubscribe () { debug('_parseUnsubscribe') const packet = this.packet packet.unsubscriptions = [] // Parse messageId if (!this._parseMessageId()) { return } // Properties mqtt 5 if (this.settings.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } while (this._pos < packet.length) { // Parse topic const topic = this._parseString() if (topic === null) return this._emitError(new Error('Cannot parse topic')) // Push topic to unsubscriptions debug('_parseUnsubscribe: push topic `%s` to unsubscriptions', topic) packet.unsubscriptions.push(topic) } } _parseUnsuback () { debug('_parseUnsuback') const packet = this.packet if (!this._parseMessageId()) return this._emitError(new Error('Cannot parse messageId')) // Properties mqtt 5 if (this.settings.protocolVersion === 5) { const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } // Parse granted QoSes packet.granted = [] while (this._pos < this.packet.length) { this.packet.granted.push(this._list.readUInt8(this._pos++)) } } } // parse packets like puback, pubrec, pubrel, pubcomp _parseConfirmation () { debug('_parseConfirmation: packet.cmd: `%s`', this.packet.cmd) const packet = this.packet this._parseMessageId() if (this.settings.protocolVersion === 5) { if (packet.length > 2) { // response code packet.reasonCode = this._parseByte() debug('_parseConfirmation: packet.reasonCode `%d`', packet.reasonCode) } else { packet.reasonCode = 0 } if (packet.length > 3) { // properies mqtt 5 const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } } return true } // parse disconnect packet _parseDisconnect () { const packet = this.packet debug('_parseDisconnect') if (this.settings.protocolVersion === 5) { // response code if (this._list.length > 0) { packet.reasonCode = this._parseByte() } else { packet.reasonCode = 0 } // properies mqtt 5 const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } } debug('_parseDisconnect result: true') return true } // parse auth packet _parseAuth () { debug('_parseAuth') const packet = this.packet if (this.settings.protocolVersion !== 5) { return this._emitError(new Error('Not supported auth packet for this version MQTT')) } // response code packet.reasonCode = this._parseByte() // properies mqtt 5 const properties = this._parseProperties() if (Object.getOwnPropertyNames(properties).length) { packet.properties = properties } debug('_parseAuth: result: true') return true } _parseMessageId () { const packet = this.packet packet.messageId = this._parseNum() if (packet.messageId === null) { this._emitError(new Error('Cannot parse messageId')) return false } debug('_parseMessageId: packet.messageId %d', packet.messageId) return true } _parseString (maybeBuffer) { const length = this._parseNum() const end = length + this._pos if (length === -1 || end > this._list.length || end > this.packet.length) return null const result = this._list.toString('utf8', this._pos, end) this._pos += length debug('_parseString: result: %s', result) return result } _parseStringPair () { debug('_parseStringPair') return { name: this._parseString(), value: this._parseString() } } _parseBuffer () { const length = this._parseNum() const end = length + this._pos if (length === -1 || end > this._list.length || end > this.packet.length) return null const result = this._list.slice(this._pos, end) this._pos += length debug('_parseBuffer: result: %o', result) return result } _parseNum () { if (this._list.length - this._pos < 2) return -1 const result = this._list.readUInt16BE(this._pos) this._pos += 2 debug('_parseNum: result: %s', result) return result } _parse4ByteNum () { if (this._list.length - this._pos < 4) return -1 const result = this._list.readUInt32BE(this._pos) this._pos += 4 debug('_parse4ByteNum: result: %s', result) return result } _parseVarByteNum (fullInfoFlag) { debug('_parseVarByteNum') const maxBytes = 4 let bytes = 0 let mul = 1 let value = 0 let result = false let current const padding = this._pos ? this._pos : 0 while (bytes < maxBytes && (padding + bytes) < this._list.length) { current = this._list.readUInt8(padding + bytes++) value += mul * (current & constants.VARBYTEINT_MASK) mul *= 0x80 if ((current & constants.VARBYTEINT_FIN_MASK) === 0) { result = true break } if (this._list.length <= bytes) { break } } if (!result && bytes === maxBytes && this._list.length >= bytes) { this._emitError(new Error('Invalid variable byte integer')) } if (padding) { this._pos += bytes } result = result ? fullInfoFlag ? { bytes, value } : value : false debug('_parseVarByteNum: result: %o', result) return result } _parseByte () { let result if (this._pos < this._list.length) { result = this._list.readUInt8(this._pos) this._pos++ } debug('_parseByte: result: %o', result) return result } _parseByType (type) { debug('_parseByType: type: %s', type) switch (type) { case 'byte': { return this._parseByte() !== 0 } case 'int8': { return this._parseByte() } case 'int16': { return this._parseNum() } case 'int32': { return this._parse4ByteNum() } case 'var': { return this._parseVarByteNum() } case 'string': { return this._parseString() } case 'pair': { return this._parseStringPair() } case 'binary': { return this._parseBuffer() } } } _parseProperties () { debug('_parseProperties') const length = this._parseVarByteNum() const start = this._pos const end = start + length const result = {} while (this._pos < end) { const type = this._parseByte() if (!type) { this._emitError(new Error('Cannot parse property code type')) return false } const name = constants.propertiesCodes[type] if (!name) { this._emitError(new Error('Unknown property')) return false } // user properties process if (name === 'userProperties') { if (!result[name]) { result[name] = Object.create(null) } const currentUserProperty = this._parseByType(constants.propertiesTypes[name]) if (result[name][currentUserProperty.name]) { if (Array.isArray(result[name][currentUserProperty.name])) { result[name][currentUserProperty.name].push(currentUserProperty.value) } else { const currentValue = result[name][currentUserProperty.name] result[name][currentUserProperty.name] = [currentValue] result[name][currentUserProperty.name].push(currentUserProperty.value) } } else { result[name][currentUserProperty.name] = currentUserProperty.value } continue } if (result[name]) { if (Array.isArray(result[name])) { result[name].push(this._parseByType(constants.propertiesTypes[name])) } else { result[name] = [result[name]] result[name].push(this._parseByType(constants.propertiesTypes[name])) } } else { result[name] = this._parseByType(constants.propertiesTypes[name]) } } return result } _newPacket () { debug('_newPacket') if (this.packet) { this._list.consume(this.packet.length) debug('_newPacket: parser emit packet: packet.cmd: %s, packet.payload: %s, packet.length: %d', this.packet.cmd, this.packet.payload, this.packet.length) this.emit('packet', this.packet) } debug('_newPacket: new packet') this.packet = new Packet() this._pos = 0 return true } _emitError (err) { debug('_emitError') this.error = err this.emit('error', err) } } module.exports = Parser }, function(modId) { var map = {"./packet":1682324647506,"./constants":1682324647507}; return __REQUIRE__(map[modId], modId); }) __DEFINE__(1682324647506, function(require, module, exports) { class Packet { constructor () { this.cmd = null this.retain = false this.qos = 0 this.dup = false this.length = -1 this.topic = null this.payload = null } } module.exports = Packet }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); }) __DEFINE__(1682324647507, function(require, module, exports) { /* Protocol - protocol constants */ const protocol = module.exports /* Command code => mnemonic */ protocol.types = { 0: 'reserved', 1: 'connect', 2: 'connack', 3: 'publish', 4: 'puback', 5: 'pubrec', 6: 'pubrel', 7: 'pubcomp', 8: 'subscribe', 9: 'suback', 10: 'unsubscribe', 11: 'unsuback', 12: 'pingreq', 13: 'pingresp', 14: 'disconnect', 15: 'auth' } /* Mnemonic => Command code */ protocol.codes = {} for (const k in protocol.types) { const v = protocol.types[k] protocol.codes[v] = k } /* Header */ protocol.CMD_SHIFT = 4 protocol.CMD_MASK = 0xF0 protocol.DUP_MASK = 0x08 protocol.QOS_MASK = 0x03 protocol.QOS_SHIFT = 1 protocol.RETAIN_MASK = 0x01 /* Length */ protocol.VARBYTEINT_MASK = 0x7F protocol.VARBYTEINT_FIN_MASK = 0x80 protocol.VARBYTEINT_MAX = 268435455 /* Connack */ protocol.SESSIONPRESENT_MASK = 0x01 protocol.SESSIONPRESENT_HEADER = Buffer.from([protocol.SESSIONPRESENT_MASK]) protocol.CONNACK_HEADER = Buffer.from([protocol.codes.connack << protocol.CMD_SHIFT]) /* Connect */ protocol.USERNAME_MASK = 0x80 protocol.PASSWORD_MASK = 0x40 protocol.WILL_RETAIN_MASK = 0x20 protocol.WILL_QOS_MASK = 0x18 protocol.WILL_QOS_SHIFT = 3 protocol.WILL_FLAG_MASK = 0x04 protocol.CLEAN_SESSION_MASK = 0x02 protocol.CONNECT_HEADER = Buffer.from([protocol.codes.connect << protocol.CMD_SHIFT]) /* Properties */ protocol.properties = { sessionExpiryInterval: 17, willDelayInterval: 24, receiveMaximum: 33, maximumPacketSize: 39, topicAliasMaximum: 34, requestResponseInformation: 25, requestProblemInformation: 23, userProperties: 38, authenticationMethod: 21, authenticationData: 22, payloadFormatIndicator: 1, messageExpiryInterval: 2, contentType: 3, responseTopic: 8, correlationData: 9, maximumQoS: 36, retainAvailable: 37, assignedClientIdentifier: 18, reasonString: 31, wildcardSubscriptionAvailable: 40, subscriptionIdentifiersAvailable: 41, sharedSubscriptionAvailable: 42, serverKeepAlive: 19, responseInformation: 26, serverReference: 28, topicAlias: 35, subscriptionIdentifier: 11 } protocol.propertiesCodes = {} for (const prop in protocol.properties) { const id = protocol.properties[prop] protocol.propertiesCodes[id] = prop } protocol.propertiesTypes = { sessionExpiryInterval: 'int32', willDelayInterval: 'int32', receiveMaximum: 'int16', maximumPacketSize: 'int32', topicAliasMaximum: 'int16', requestResponseInformation: 'byte', requestProblemInformation: 'byte', userProperties: 'pair', authenticationMethod: 'string', authenticationData: 'binary', payloadFormatIndicator: 'byte', messageExpiryInterval: 'int32', contentType: 'string', responseTopic: 'string', correlationData: 'binary', maximumQoS: 'int8', retainAvailable: 'byte', assignedClientIdentifier: 'string', reasonString: 'string', wildcardSubscriptionAvailable: 'byte', subscriptionIdentifiersAvailable: 'byte', sharedSubscriptionAvailable: 'byte', serverKeepAlive: 'int16', responseInformation: 'string', serverReference: 'string', topicAlias: 'int16', subscriptionIdentifier: 'var' } function genHeader (type) { return [0, 1, 2].map(qos => { return [0, 1].map(dup => { return [0, 1].map(retain => { const buf = Buffer.alloc(1) buf.writeUInt8( protocol.codes[type] << protocol.CMD_SHIFT | (dup ? protocol.DUP_MASK : 0) | qos << protocol.QOS_SHIFT | retain, 0, true) return buf }) }) }) } /* Publish */ protocol.PUBLISH_HEADER = genHeader('publish') /* Subscribe */ protocol.SUBSCRIBE_HEADER = genHeader('subscribe') protocol.SUBSCRIBE_OPTIONS_QOS_MASK = 0x03 protocol.SUBSCRIBE_OPTIONS_NL_MASK = 0x01 protocol.SUBSCRIBE_OPTIONS_NL_SHIFT = 2 protocol.SUBSCRIBE_OPTIONS_RAP_MASK = 0x01 protocol.SUBSCRIBE_OPTIONS_RAP_SHIFT = 3 protocol.SUBSCRIBE_OPTIONS_RH_MASK = 0x03 protocol.SUBSCRIBE_OPTIONS_RH_SHIFT = 4 protocol.SUBSCRIBE_OPTIONS_RH = [0x00, 0x10, 0x20] protocol.SUBSCRIBE_OPTIONS_NL = 0x04 protocol.SUBSCRIBE_OPTIONS_RAP = 0x08 protocol.SUBSCRIBE_OPTIONS_QOS = [0x00, 0x01, 0x02] /* Unsubscribe */ protocol.UNSUBSCRIBE_HEADER = genHeader('unsubscribe') /* Confirmations */ protocol.ACKS = { unsuback: genHeader('unsuback'), puback: genHeader('puback'), pubcomp: genHeader('pubcomp'), pubrel: genHeader('pubrel'), pubrec: genHeader('pubrec') } protocol.SUBACK_HEADER = Buffer.from([protocol.codes.suback << protocol.CMD_SHIFT]) /* Protocol versions */ protocol.VERSION3 = Buffer.from([3]) protocol.VERSION4 = Buffer.from([4]) protocol.VERSION5 = Buffer.from([5]) protocol.VERSION131 = Buffer.from([131]) protocol.VERSION132 = Buffer.from([132]) /* QoS */ protocol.QOS = [0, 1, 2].map(qos => { return Buffer.from([qos]) }) /* Empty packets */ protocol.EMPTY = { pingreq: Buffer.from([protocol.codes.pingreq << 4, 0]), pingresp: Buffer.from([protocol.codes.pingresp << 4, 0]), disconnect: Buffer.from([protocol.codes.disconnect << 4, 0]) } }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); }) __DEFINE__(1682324647508, function(require, module, exports) { const writeToStream = require('./writeToStream') const EventEmitter = require('events') function generate (packet, opts) { const stream = new Accumulator() writeToStream(packet, stream, opts) return stream.concat() } class Accumulator extends EventEmitter { constructor () { super() this._array = new Array(20) this._i = 0 } write (chunk) { this._array[this._i++] = chunk return true } concat () { let length = 0 const lengths = new Array(this._array.length) const list = this._array let pos = 0 let i for (i = 0; i < list.length && list[i] !== undefined; i++) { if (typeof list[i] !== 'string') lengths[i] = list[i].length else lengths[i] = Buffer.byteLength(list[i]) length += lengths[i] } const result = Buffer.allocUnsafe(length) for (i = 0; i < list.length && list[i] !== undefined; i++) { if (typeof list[i] !== 'string') { list[i].copy(result, pos) pos += lengths[i] } else { result.write(list[i], pos) pos += lengths[i] } } return result } } module.exports = generate }, function(modId) { var map = {"./writeToStream":1682324647509}; return __REQUIRE__(map[modId], modId); }) __DEFINE__(1682324647509, function(require, module, exports) { const protocol = require('./constants') const empty = Buffer.allocUnsafe(0) const zeroBuf = Buffer.from([0]) const numbers = require('./numbers') const nextTick = require('process-nextick-args').nextTick const debug = require('debug')('mqtt-packet:writeToStream') const numCache = numbers.cache const generateNumber = numbers.generateNumber const generateCache = numbers.generateCache const genBufVariableByteInt = numbers.genBufVariableByteInt const generate4ByteBuffer = numbers.generate4ByteBuffer let writeNumber = writeNumberCached let toGenerate = true function generate (packet, stream, opts) { debug('generate called') if (stream.cork) { stream.cork() nextTick(uncork, stream) } if (toGenerate) { toGenerate = false generateCache() } debug('generate: packet.cmd: %s', packet.cmd) switch (packet.cmd) { case 'connect': return connect(packet, stream, opts) case 'connack': return connack(packet, stream, opts) case 'publish': return publish(packet, stream, opts) case 'puback': case 'pubrec': case 'pubrel': case 'pubcomp': return confirmation(packet, stream, opts) case 'subscribe': return subscribe(packet, stream, opts) case 'suback': return suback(packet, stream, opts) case 'unsubscribe': return unsubscribe(packet, stream, opts) case 'unsuback': return unsuback(packet, stream, opts) case 'pingreq': case 'pingresp': return emptyPacket(packet, stream, opts) case 'disconnect': return disconnect(packet, stream, opts) case 'auth': return auth(packet, stream, opts) default: stream.emit('error', new Error('Unknown command')) return false } } /** * Controls numbers cache. * Set to "false" to allocate buffers on-the-flight instead of pre-generated cache */ Object.defineProperty(generate, 'cacheNumbers', { get () { return writeNumber === writeNumberCached }, set (value) { if (value) { if (!numCache || Object.keys(numCache).length === 0) toGenerate = true writeNumber = writeNumberCached } else { toGenerate = false writeNumber = writeNumberGenerated } } }) function uncork (stream) { stream.uncork() } function connect (packet, stream, opts) { const settings = packet || {} const protocolId = settings.protocolId || 'MQTT' let protocolVersion = settings.protocolVersion || 4 const will = settings.will let clean = settings.clean const keepalive = settings.keepalive || 0 const clientId = settings.clientId || '' const username = settings.username const password = settings.password /* mqtt5 new oprions */ const properties = settings.properties if (clean === undefined) clean = true let length = 0 // Must be a string and non-falsy if (!protocolId || (typeof protocolId !== 'string' && !Buffer.isBuffer(protocolId))) { stream.emit('error', new Error('Invalid protocolId')) return false } else length += protocolId.length + 2 // Must be 3 or 4 or 5 if (protocolVersion !== 3 && protocolVersion !== 4 && protocolVersion !== 5) { stream.emit('error', new Error('Invalid protocol version')) return false } else length += 1 // ClientId might be omitted in 3.1.1 and 5, but only if cleanSession is set to 1 if ((typeof clientId === 'string' || Buffer.isBuffer(clientId)) && (clientId || protocolVersion >= 4) && (clientId || clean)) { length += Buffer.byteLength(clientId) + 2 } else { if (protocolVersion < 4) { stream.emit('error', new Error('clientId must be supplied before 3.1.1')) return false } if ((clean * 1) === 0) { stream.emit('error', new Error('clientId must be given if cleanSession set to 0')) return false } } // Must be a two byte number if (typeof keepalive !== 'number' || keepalive < 0 || keepalive > 65535 || keepalive % 1 !== 0) { stream.emit('error', new Error('Invalid keepalive')) return false } else length += 2 // Connect flags length += 1 // Properties if (protocolVersion === 5) { var propertiesData = getProperties(stream, properties) if (!propertiesData) { return false } length += propertiesData.length } // If will exists... if (will) { // It must be an object if (typeof will !== 'object') { stream.emit('error', new Error('Invalid will')) return false } // It must have topic typeof string if (!will.topic || typeof will.topic !== 'string') { stream.emit('error', new Error('Invalid will topic')) return false } else { length += Buffer.byteLength(will.topic) + 2 } // Payload length += 2 // payload length if (will.payload) { if (will.payload.length >= 0) { if (typeof will.payload === 'string') { length += Buffer.byteLength(will.payload) } else { length += will.payload.length } } else { stream.emit('error', new Error('Invalid will payload')) return false } } // will properties var willProperties = {} if (protocolVersion === 5) { willProperties = getProperties(stream, will.properties) if (!willProperties) { return false } length += willProperties.length } } // Username let providedUsername = false if (username != null) { if (isStringOrBuffer(username)) { providedUsername = true length += Buffer.byteLength(username) + 2 } else { stream.emit('error', new Error('Invalid username')) return false } } // Password if (password != null) { if (!providedUsername) { stream.emit('error', new Error('Username is required to use password')) return false } if (isStringOrBuffer(password)) { length += byteLength(password) + 2 } else { stream.emit('error', new Error('Invalid password')) return false } } // Generate header stream.write(protocol.CONNECT_HEADER) // Generate length writeVarByteInt(stream, length) // Generate protocol ID writeStringOrBuffer(stream, protocolId) if (settings.bridgeMode) { protocolVersion += 128 } stream.write( protocolVersion === 131 ? protocol.VERSION131 : protocolVersion === 132 ? protocol.VERSION132 : protocolVersion === 4 ? protocol.VERSION4 : protocolVersion === 5 ? protocol.VERSION5 : protocol.VERSION3 ) // Connect flags let flags = 0 flags |= (username != null) ? protocol.USERNAME_MASK : 0 flags |= (password != null) ? protocol.PASSWORD_MASK : 0 flags |= (will && will.retain) ? protocol.WILL_RETAIN_MASK : 0 flags |= (will && will.qos) ? will.qos << protocol.WILL_QOS_SHIFT : 0 flags |= will ? protocol.WILL_FLAG_MASK : 0 flags |= clean ? protocol.CLEAN_SESSION_MASK : 0 stream.write(Buffer.from([flags])) // Keepalive writeNumber(stream, keepalive) // Properties if (protocolVersion === 5) { propertiesData.write() } // Client ID writeStringOrBuffer(stream, clientId) // Will if (will) { if (protocolVersion === 5) { willProperties.write() } writeString(stream, will.topic) writeStringOrBuffer(stream, will.payload) } // Username and password if (username != null) { writeStringOrBuffer(stream, username) } if (password != null) { writeStringOrBuffer(stream, password) } // This is a small packet that happens only once on a stream // We assume the stream is always free to receive more data after this return true } function connack (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const rc = version === 5 ? settings.reasonCode : settings.returnCode const properties = settings.properties let length = 2 // length of rc and sessionHeader // Check return code if (typeof rc !== 'number') { stream.emit('error', new Error('Invalid return code')) return false } // mqtt5 properties let propertiesData = null if (version === 5) { propertiesData = getProperties(stream, properties) if (!propertiesData) { return false } length += propertiesData.length } stream.write(protocol.CONNACK_HEADER) // length writeVarByteInt(stream, length) stream.write(settings.sessionPresent ? protocol.SESSIONPRESENT_HEADER : zeroBuf) stream.write(Buffer.from([rc])) if (propertiesData != null) { propertiesData.write() } return true } function publish (packet, stream, opts) { debug('publish: packet: %o', packet) const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const qos = settings.qos || 0 const retain = settings.retain ? protocol.RETAIN_MASK : 0 const topic = settings.topic const payload = settings.payload || empty const id = settings.messageId const properties = settings.properties let length = 0 // Topic must be a non-empty string or Buffer if (typeof topic === 'string') length += Buffer.byteLength(topic) + 2 else if (Buffer.isBuffer(topic)) length += topic.length + 2 else { stream.emit('error', new Error('Invalid topic')) return false } // Get the payload length if (!Buffer.isBuffer(payload)) length += Buffer.byteLength(payload) else length += payload.length // Message ID must a number if qos > 0 if (qos && typeof id !== 'number') { stream.emit('error', new Error('Invalid messageId')) return false } else if (qos) length += 2 // mqtt5 properties let propertiesData = null if (version === 5) { propertiesData = getProperties(stream, properties) if (!propertiesData) { return false } length += propertiesData.length } // Header stream.write(protocol.PUBLISH_HEADER[qos][settings.dup ? 1 : 0][retain ? 1 : 0]) // Remaining length writeVarByteInt(stream, length) // Topic writeNumber(stream, byteLength(topic)) stream.write(topic) // Message ID if (qos > 0) writeNumber(stream, id) // Properties if (propertiesData != null) { propertiesData.write() } // Payload debug('publish: payload: %o', payload) return stream.write(payload) } /* Puback, pubrec, pubrel and pubcomp */ function confirmation (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const type = settings.cmd || 'puback' const id = settings.messageId const dup = (settings.dup && type === 'pubrel') ? protocol.DUP_MASK : 0 let qos = 0 const reasonCode = settings.reasonCode const properties = settings.properties let length = version === 5 ? 3 : 2 if (type === 'pubrel') qos = 1 // Check message ID if (typeof id !== 'number') { stream.emit('error', new Error('Invalid messageId')) return false } // properies mqtt 5 let propertiesData = null if (version === 5) { // Confirm should not add empty property length with no properties (rfc 3.4.2.2.1) if (typeof properties === 'object') { propertiesData = getPropertiesByMaximumPacketSize(stream, properties, opts, length) if (!propertiesData) { return false } length += propertiesData.length } } // Header stream.write(protocol.ACKS[type][qos][dup][0]) // Length writeVarByteInt(stream, length) // Message ID writeNumber(stream, id) // reason code in header if (version === 5) { stream.write(Buffer.from([reasonCode])) } // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } return true } function subscribe (packet, stream, opts) { debug('subscribe: packet: ') const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const dup = settings.dup ? protocol.DUP_MASK : 0 const id = settings.messageId const subs = settings.subscriptions const properties = settings.properties let length = 0 // Check message ID if (typeof id !== 'number') { stream.emit('error', new Error('Invalid messageId')) return false } else length += 2 // properies mqtt 5 let propertiesData = null if (version === 5) { propertiesData = getProperties(stream, properties) if (!propertiesData) { return false } length += propertiesData.length } // Check subscriptions if (typeof subs === 'object' && subs.length) { for (let i = 0; i < subs.length; i += 1) { const itopic = subs[i].topic const iqos = subs[i].qos if (typeof itopic !== 'string') { stream.emit('error', new Error('Invalid subscriptions - invalid topic')) return false } if (typeof iqos !== 'number') { stream.emit('error', new Error('Invalid subscriptions - invalid qos')) return false } if (version === 5) { const nl = subs[i].nl || false if (typeof nl !== 'boolean') { stream.emit('error', new Error('Invalid subscriptions - invalid No Local')) return false } const rap = subs[i].rap || false if (typeof rap !== 'boolean') { stream.emit('error', new Error('Invalid subscriptions - invalid Retain as Published')) return false } const rh = subs[i].rh || 0 if (typeof rh !== 'number' || rh > 2) { stream.emit('error', new Error('Invalid subscriptions - invalid Retain Handling')) return false } } length += Buffer.byteLength(itopic) + 2 + 1 } } else { stream.emit('error', new Error('Invalid subscriptions')) return false } // Generate header debug('subscribe: writing to stream: %o', protocol.SUBSCRIBE_HEADER) stream.write(protocol.SUBSCRIBE_HEADER[1][dup ? 1 : 0][0]) // Generate length writeVarByteInt(stream, length) // Generate message ID writeNumber(stream, id) // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } let result = true // Generate subs for (const sub of subs) { const jtopic = sub.topic const jqos = sub.qos const jnl = +sub.nl const jrap = +sub.rap const jrh = sub.rh let joptions // Write topic string writeString(stream, jtopic) // options process joptions = protocol.SUBSCRIBE_OPTIONS_QOS[jqos] if (version === 5) { joptions |= jnl ? protocol.SUBSCRIBE_OPTIONS_NL : 0 joptions |= jrap ? protocol.SUBSCRIBE_OPTIONS_RAP : 0 joptions |= jrh ? protocol.SUBSCRIBE_OPTIONS_RH[jrh] : 0 } // Write options result = stream.write(Buffer.from([joptions])) } return result } function suback (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const id = settings.messageId const granted = settings.granted const properties = settings.properties let length = 0 // Check message ID if (typeof id !== 'number') { stream.emit('error', new Error('Invalid messageId')) return false } else length += 2 // Check granted qos vector if (typeof granted === 'object' && granted.length) { for (let i = 0; i < granted.length; i += 1) { if (typeof granted[i] !== 'number') { stream.emit('error', new Error('Invalid qos vector')) return false } length += 1 } } else { stream.emit('error', new Error('Invalid qos vector')) return false } // properies mqtt 5 let propertiesData = null if (version === 5) { propertiesData = getPropertiesByMaximumPacketSize(stream, properties, opts, length) if (!propertiesData) { return false } length += propertiesData.length } // header stream.write(protocol.SUBACK_HEADER) // Length writeVarByteInt(stream, length) // Message ID writeNumber(stream, id) // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } return stream.write(Buffer.from(granted)) } function unsubscribe (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const id = settings.messageId const dup = settings.dup ? protocol.DUP_MASK : 0 const unsubs = settings.unsubscriptions const properties = settings.properties let length = 0 // Check message ID if (typeof id !== 'number') { stream.emit('error', new Error('Invalid messageId')) return false } else { length += 2 } // Check unsubs if (typeof unsubs === 'object' && unsubs.length) { for (let i = 0; i < unsubs.length; i += 1) { if (typeof unsubs[i] !== 'string') { stream.emit('error', new Error('Invalid unsubscriptions')) return false } length += Buffer.byteLength(unsubs[i]) + 2 } } else { stream.emit('error', new Error('Invalid unsubscriptions')) return false } // properies mqtt 5 let propertiesData = null if (version === 5) { propertiesData = getProperties(stream, properties) if (!propertiesData) { return false } length += propertiesData.length } // Header stream.write(protocol.UNSUBSCRIBE_HEADER[1][dup ? 1 : 0][0]) // Length writeVarByteInt(stream, length) // Message ID writeNumber(stream, id) // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } // Unsubs let result = true for (let j = 0; j < unsubs.length; j++) { result = writeString(stream, unsubs[j]) } return result } function unsuback (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const id = settings.messageId const dup = settings.dup ? protocol.DUP_MASK : 0 const granted = settings.granted const properties = settings.properties const type = settings.cmd const qos = 0 let length = 2 // Check message ID if (typeof id !== 'number') { stream.emit('error', new Error('Invalid messageId')) return false } // Check granted if (version === 5) { if (typeof granted === 'object' && granted.length) { for (let i = 0; i < granted.length; i += 1) { if (typeof granted[i] !== 'number') { stream.emit('error', new Error('Invalid qos vector')) return false } length += 1 } } else { stream.emit('error', new Error('Invalid qos vector')) return false } } // properies mqtt 5 let propertiesData = null if (version === 5) { propertiesData = getPropertiesByMaximumPacketSize(stream, properties, opts, length) if (!propertiesData) { return false } length += propertiesData.length } // Header stream.write(protocol.ACKS[type][qos][dup][0]) // Length writeVarByteInt(stream, length) // Message ID writeNumber(stream, id) // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } // payload if (version === 5) { stream.write(Buffer.from(granted)) } return true } function emptyPacket (packet, stream, opts) { return stream.write(protocol.EMPTY[packet.cmd]) } function disconnect (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const reasonCode = settings.reasonCode const properties = settings.properties let length = version === 5 ? 1 : 0 // properies mqtt 5 let propertiesData = null if (version === 5) { propertiesData = getPropertiesByMaximumPacketSize(stream, properties, opts, length) if (!propertiesData) { return false } length += propertiesData.length } // Header stream.write(Buffer.from([protocol.codes.disconnect << 4])) // Length writeVarByteInt(stream, length) // reason code in header if (version === 5) { stream.write(Buffer.from([reasonCode])) } // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } return true } function auth (packet, stream, opts) { const version = opts ? opts.protocolVersion : 4 const settings = packet || {} const reasonCode = settings.reasonCode const properties = settings.properties let length = version === 5 ? 1 : 0 if (version !== 5) stream.emit('error', new Error('Invalid mqtt version for auth packet')) // properies mqtt 5 const propertiesData = getPropertiesByMaximumPacketSize(stream, properties, opts, length) if (!propertiesData) { return false } length += propertiesData.length // Header stream.write(Buffer.from([protocol.codes.auth << 4])) // Length writeVarByteInt(stream, length) // reason code in header stream.write(Buffer.from([reasonCode])) // properies mqtt 5 if (propertiesData !== null) { propertiesData.write() } return true } /** * writeVarByteInt - write an MQTT style variable byte integer to the buffer * * @param buffer - destination * @param pos - offset * @param length - length (>0) * @returns number of bytes written * * @api private */ const varByteIntCache = {} function writeVarByteInt (stream, num) { if (num > protocol.VARBYTEINT_MAX) { stream.emit('error', new Error(`Invalid variable byte integer: ${num}`)) return false } let buffer = varByteIntCache[num] if (!buffer) { buffer = genBufVariableByteInt(num) if (num < 16384) varByteIntCache[num] = buffer } debug('writeVarByteInt: writing to stream: %o', buffer) return stream.write(buffer) } /** * writeString - write a utf8 string to the buffer * * @param buffer - destination * @param pos - offset * @param string - string to write * @return number of bytes written * * @api private */ function writeString (stream, string) { const strlen = Buffer.byteLength(string) writeNumber(stream, strlen) debug('writeString: %s', string) return stream.write(string, 'utf8') } /** * writeStringPair - write a utf8 string pairs to the buffer * * @param buffer - destination * @param name - string name to write * @param value - string value to write * @return number of bytes written * * @api private */ function writeStringPair (stream, name, value) { writeString(stream, name) writeString(stream, value) } /** * writeNumber - write a two byte number to the buffer * * @param buffer - destination * @param pos - offset * @param number - number to write * @return number of bytes written * * @api private */ function writeNumberCached (stream, number) { debug('writeNumberCached: number: %d', number) debug('writeNumberCached: %o', numCache[number]) return stream.write(numCache[number]) } function writeNumberGenerated (stream, number) { const generatedNumber = generateNumber(number) debug('writeNumberGenerated: %o', generatedNumber) return stream.write(generatedNumber) } function write4ByteNumber (stream, number) { const generated4ByteBuffer = generate4ByteBuffer(number) debug('write4ByteNumber: %o', generated4ByteBuffer) return stream.write(generated4ByteBuffer) } /** * writeStringOrBuffer - write a String or Buffer with the its length prefix * * @param buffer - destination * @param pos - offset * @param toWrite - String or Buffer * @return number of bytes written */ function writeStringOrBuffer (stream, toWrite) { if (typeof toWrite === 'string') { writeString(stream, toWrite) } else if (toWrite) { writeNumber(stream, toWrite.length) stream.write(toWrite) } else writeNumber(stream, 0) } function getProperties (stream, properties) { /* connect properties */ if (typeof properties !== 'object' || properties.length != null) { return { length: 1, write () { writeProperties(stream, {}, 0) } } } let propertiesLength = 0 function getLengthProperty (name, value) { const type = protocol.propertiesTypes[name] let length = 0 switch (type) { case 'byte': { if (typeof value !== 'boolean') { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + 1 break } case 'int8': { if (typeof value !== 'number' || value < 0 || value > 0xff) { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + 1 break } case 'binary': { if (value && value === null) { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + Buffer.byteLength(value) + 2 break } case 'int16': { if (typeof value !== 'number' || value < 0 || value > 0xffff) { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + 2 break } case 'int32': { if (typeof value !== 'number' || value < 0 || value > 0xffffffff) { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + 4 break } case 'var': { // var byte integer is max 24 bits packed in 32 bits if (typeof value !== 'number' || value < 0 || value > 0x0fffffff) { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + Buffer.byteLength(genBufVariableByteInt(value)) break } case 'string': { if (typeof value !== 'string') { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += 1 + 2 + Buffer.byteLength(value.toString()) break } case 'pair': { if (typeof value !== 'object') { stream.emit('error', new Error(`Invalid ${name}: ${value}`)) return false } length += Object.getOwnPropertyNames(value).reduce((result, name) => { const currentValue = value[name] if (Array.isArray(currentValue)) { result += currentValue.reduce((currentLength, value) => { currentLength += 1 + 2 + Buffer.byteLength(name.toString()) + 2 + Buffer.byteLength(value.toString()) return currentLength }, 0) } else { result += 1 + 2 + Buffer.byteLength(name.toString()) + 2 + Buffer.byteLength(value[name].toString()) } return result }, 0) break } default: { stream.emit('error', new Error(`Invalid property ${name}: ${value}`)) return false } } return length } if (properties) { for (const propName in properties) { let propLength = 0 let propValueLength = 0 const propValue = properties[propName] if (Array.isArray(propValue)) { for (let valueIndex = 0; valueIndex < propValue.length; valueIndex++) { propValueLength = getLengthProperty(propName, propValue[valueIndex]) if (!propValueLength) { return false } propLength += propValueLength } } else { propValueLength = getLengthProperty(propName, propValue) if (!propValueLength) { return false } propLength = propValueLength } if (!propLength) return false propertiesLength += propLength } } const propertiesLengthLength = Buffer.byteLength(genBufVariableByteInt(propertiesLength)) return { length: propertiesLengthLength + propertiesLength, write () { writeProperties(stream, properties, propertiesLength) } } } function getPropertiesByMaximumPacketSize (stream, properties, opts, length) { const mayEmptyProps = ['reasonString', 'userProperties'] const maximumPacketSize = opts && opts.properties && opts.properties.maximumPacketSize ? opts.properties.maximumPacketSize : 0 let propertiesData = getProperties(stream, properties) if (maximumPacketSize) { while (length + propertiesData.length > maximumPacketSize) { const currentMayEmptyProp = mayEmptyProps.shift() if (currentMayEmptyProp && properties[currentMayEmptyProp]) { delete properties[currentMayEmptyProp] propertiesData = getProperties(stream, properties) } else { return false } } } return propertiesData } function writeProperty (stream, propName, value) { const type = protocol.propertiesTypes[propName] switch (type) { case 'byte': { stream.write(Buffer.from([protocol.properties[propName]])) stream.write(Buffer.from([+value])) break } case 'int8': { stream.write(Buffer.from([protocol.properties[propName]])) stream.write(Buffer.from([value])) break } case 'binary': { stream.write(Buffer.from([protocol.properties[propName]])) writeStringOrBuffer(stream, value) break } case 'int16': { stream.write(Buffer.from([protocol.properties[propName]])) writeNumber(stream, value) break } case 'int32': { stream.write(Buffer.from([protocol.properties[propName]])) write4ByteNumber(stream, value) break } case 'var': { stream.write(Buffer.from([protocol.properties[propName]])) writeVarByteInt(stream, value) break } case 'string': { stream.write(Buffer.from([protocol.properties[propName]])) writeString(stream, value) break } case 'pair': { Object.getOwnPropertyNames(value).forEach(name => { const currentValue = value[name] if (Array.isArray(currentValue)) { currentValue.forEach(value => { stream.write(Buffer.from([protocol.properties[propName]])) writeStringPair(stream, name.toString(), value.toString()) }) } else { stream.write(Buffer.from([protocol.properties[propName]])) writeStringPair(stream, name.toString(), currentValue.toString()) } }) break } default: { stream.emit('error', new Error(`Invalid property ${propName} value: ${value}`)) return false } } } function writeProperties (stream, properties, propertiesLength) { /* write properties to stream */ writeVarByteInt(stream, propertiesLength) for (const propName in properties) { if (Object.prototype.hasOwnProperty.call(properties, propName) && properties[propName] !== null) { const value = properties[propName] if (Array.isArray(value)) { for (let valueIndex = 0; valueIndex < value.length; valueIndex++) { writeProperty(stream, propName, value[valueIndex]) } } else { writeProperty(stream, propName, value) } } } } function byteLength (bufOrString) { if (!bufOrString) return 0 else if (bufOrString instanceof Buffer) return bufOrString.length else return Buffer.byteLength(bufOrString) } function isStringOrBuffer (field) { return typeof field === 'string' || field instanceof Buffer } module.exports = generate }, function(modId) { var map = {"./constants":1682324647507,"./numbers":1682324647510}; return __REQUIRE__(map[modId], modId); }) __DEFINE__(1682324647510, function(require, module, exports) { const max = 65536 const cache = {} // in node 6 Buffer.subarray returns a Uint8Array instead of a Buffer // later versions return a Buffer // alternative is Buffer.slice but that creates a new buffer // creating new buffers takes time // SubOk is only false on node < 8 const SubOk = Buffer.isBuffer(Buffer.from([1, 2]).subarray(0, 1)) function generateBuffer (i) { const buffer = Buffer.allocUnsafe(2) buffer.writeUInt8(i >> 8, 0) buffer.writeUInt8(i & 0x00FF, 0 + 1) return buffer } function generateCache () { for (let i = 0; i < max; i++) { cache[i] = generateBuffer(i) } } function genBufVariableByteInt (num) { const maxLength = 4 // max 4 bytes let digit = 0 let pos = 0 const buffer = Buffer.allocUnsafe(maxLength) do { digit = num % 128 | 0 num = num / 128 | 0 if (num > 0) digit = digit | 0x80 buffer.writeUInt8(digit, pos++) } while (num > 0 && pos < maxLength) if (num > 0) { pos = 0 } return SubOk ? buffer.subarray(0, pos) : buffer.slice(0, pos) } function generate4ByteBuffer (num) { const buffer = Buffer.allocUnsafe(4) buffer.writeUInt32BE(num, 0) return buffer } module.exports = { cache, generateCache, generateNumber: generateBuffer, genBufVariableByteInt, generate4ByteBuffer } }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); }) return __REQUIRE__(1682324647504); })() //miniprogram-npm-outsideDeps=["bl","events","debug","process-nextick-args"] //# sourceMappingURL=index.js.map