mqtt stuff added
This commit is contained in:
10
node_modules/mqtt-packet/.travis.yml
generated
vendored
Normal file
10
node_modules/mqtt-packet/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- 9
|
||||
- 8
|
||||
- 7
|
||||
- 6
|
||||
- 4
|
||||
script:
|
||||
npm run ci
|
27
node_modules/mqtt-packet/CONTRIBUTING.md
generated
vendored
Normal file
27
node_modules/mqtt-packet/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# mqtt-packet is an OPEN Open Source Project
|
||||
|
||||
-----------------------------------------
|
||||
|
||||
## What?
|
||||
|
||||
Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
|
||||
|
||||
## Rules
|
||||
|
||||
There are a few basic ground-rules for contributors:
|
||||
|
||||
1. **No `--force` pushes** or modifying the Git history in any way.
|
||||
1. **Non-master branches** ought to be used for ongoing work.
|
||||
1. **External API changes and significant modifications** ought to be subject to an **internal pull-request** to solicit feedback from other contributors.
|
||||
1. Internal pull-requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor.
|
||||
1. Contributors should attempt to adhere to the prevailing code-style.
|
||||
|
||||
## Releases
|
||||
|
||||
Declaring formal releases remains the prerogative of the project maintainer.
|
||||
|
||||
## Changes to this arrangement
|
||||
|
||||
This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
|
||||
|
||||
-----------------------------------------
|
13
node_modules/mqtt-packet/LICENSE.md
generated
vendored
Normal file
13
node_modules/mqtt-packet/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Copyright (c) 2014-2017 mqtt-packet contributors
|
||||
---------------------------------------
|
||||
|
||||
*mqtt-packet contributors listed at <https://github.com/mqttjs/mqtt-packet#contributors>*
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
350
node_modules/mqtt-packet/README.md
generated
vendored
Normal file
350
node_modules/mqtt-packet/README.md
generated
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
mqtt-packet [](https://travis-ci.org/mqttjs/mqtt-packet)
|
||||
===========
|
||||
|
||||
Encode and Decode MQTT 3.1.1 packets the node way.
|
||||
|
||||
[](https://github.com/feross/standard)
|
||||
|
||||
* <a href="#installation">Installation</a>
|
||||
* <a href="#examples">Examples</a>
|
||||
* <a href="#packets">Packets</a>
|
||||
* <a href="#api">API</a>
|
||||
* <a href="#contributing">Contributing</a>
|
||||
* <a href="#license">License & copyright</a>
|
||||
|
||||
This library is tested with node v4, v6 and v7. The last version to support
|
||||
older versions of node was mqtt-packet@4.1.2.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```bash
|
||||
npm install mqtt-packet --save
|
||||
```
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
### Generating
|
||||
|
||||
```js
|
||||
var mqtt = require('mqtt-packet')
|
||||
var object = {
|
||||
cmd: 'publish',
|
||||
retain: false,
|
||||
qos: 0,
|
||||
dup: false,
|
||||
length: 10,
|
||||
topic: 'test',
|
||||
payload: 'test' // Can also be a Buffer
|
||||
}
|
||||
|
||||
console.log(mqtt.generate(object))
|
||||
// Prints:
|
||||
//
|
||||
// <Buffer 30 0a 00 04 74 65 73 74 74 65 73 74>
|
||||
//
|
||||
// Which is the same as:
|
||||
//
|
||||
// new Buffer([
|
||||
// 48, 10, // Header (publish)
|
||||
// 0, 4, // Topic length
|
||||
// 116, 101, 115, 116, // Topic (test)
|
||||
// 116, 101, 115, 116 // Payload (test)
|
||||
// ])
|
||||
```
|
||||
|
||||
### Parsing
|
||||
|
||||
```js
|
||||
var mqtt = require('mqtt-packet')
|
||||
var parser = mqtt.parser()
|
||||
|
||||
// Synchronously emits all the parsed packets
|
||||
parser.on('packet', function(packet) {
|
||||
console.log(packet)
|
||||
// Prints:
|
||||
//
|
||||
// {
|
||||
// cmd: 'publish',
|
||||
// retain: false,
|
||||
// qos: 0,
|
||||
// dup: false,
|
||||
// length: 10,
|
||||
// topic: 'test',
|
||||
// payload: <Buffer 74 65 73 74>
|
||||
// }
|
||||
})
|
||||
|
||||
parser.parse(new Buffer([
|
||||
48, 10, // Header (publish)
|
||||
0, 4, // Topic length
|
||||
116, 101, 115, 116, // Topic (test)
|
||||
116, 101, 115, 116 // Payload (test)
|
||||
])
|
||||
// Returns the number of bytes left in the parser
|
||||
```
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* <a href="#generate"><code>mqtt#<b>generate()</b></code></a>
|
||||
* <a href="#writeToStream"><code>mqtt#<b>writeToStream()</b></code></a>
|
||||
* <a href="#parser"><code>mqtt#<b>parser()</b></code></a>
|
||||
|
||||
<a name="generate">
|
||||
|
||||
### mqtt.generate(object)
|
||||
|
||||
Generates a `Buffer` containing an MQTT packet.
|
||||
The object must be one of the ones specified by the [packets](#packets)
|
||||
section. Throws an `Error` if a packet cannot be generated.
|
||||
|
||||
<a name="writeToStream">
|
||||
|
||||
### mqtt.writeToStream(object, stream)
|
||||
|
||||
Writes the mqtt packet defined by `object` to the given stream.
|
||||
The object must be one of the ones specified by the [packets](#packets)
|
||||
section. Emits an `Error` on the stream if a packet cannot be generated.
|
||||
On node >= 0.12, this function automatically calls `cork()` on your stream,
|
||||
and then it calls `uncork()` on the next tick.
|
||||
By default cache for number buffers is enabled.
|
||||
It creates a list of buffers for faster write. To disable cache set `mqtt.writeToStream.cacheNumbers = false`.
|
||||
Should be set before any `writeToStream` calls.
|
||||
|
||||
<a name="parser">
|
||||
|
||||
### mqtt.parser()
|
||||
|
||||
Returns a new `Parser` object. `Parser` inherits from `EventEmitter` and
|
||||
will emit:
|
||||
|
||||
* `packet`, when a new packet is parsed, according to
|
||||
[packets](#packets)
|
||||
* `error`, if an error happens
|
||||
|
||||
<a name="parse">
|
||||
|
||||
#### Parser.parse(buffer)
|
||||
|
||||
Parses a given `Buffer` and emits synchronously all the MQTT packets that
|
||||
are included. Returns the number of bytes left to parse.
|
||||
|
||||
If an error happens, an `error` event will be emitted, but no `packet` events
|
||||
will be emitted after that. Calling `parse()` again clears the error and
|
||||
previous buffer, as if you created a new `Parser`.
|
||||
|
||||
Packets
|
||||
-------
|
||||
|
||||
This section describes the format of all packets emitted by the `Parser`
|
||||
and that you can input to `generate`.
|
||||
|
||||
### Connect
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'connect',
|
||||
protocolId: 'MQTT', // Or 'MQIsdp' in MQTT 3.1
|
||||
protocolVersion: 4, // Or 3 in MQTT 3.1
|
||||
clean: true, // Can also be false
|
||||
clientId: 'my-device',
|
||||
keepalive: 0, // Seconds which can be any positive number, with 0 as the default setting
|
||||
username: 'matteo',
|
||||
password: new Buffer('collina'), // Passwords are buffers
|
||||
will: {
|
||||
topic: 'mydevice/status',
|
||||
payload: new Buffer('dead') // Payloads are buffers
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If `protocolVersion` is 3, `clientId` is mandatory and `generate` will throw if
|
||||
missing.
|
||||
|
||||
If `password` or `will.payload` are passed as strings, they will
|
||||
automatically be converted into a `Buffer`.
|
||||
|
||||
### Connack
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'connack',
|
||||
returnCode: 0, // Or whatever else you see fit
|
||||
sessionPresent: false // Can also be true.
|
||||
}
|
||||
```
|
||||
|
||||
The only mandatory argument is `returnCode`, as `generate` will throw if
|
||||
missing.
|
||||
|
||||
### Subscribe
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'subscribe',
|
||||
messageId: 42,
|
||||
subscriptions: [{
|
||||
topic: 'test',
|
||||
qos: 0
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
All properties are mandatory.
|
||||
|
||||
### Suback
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'suback',
|
||||
messageId: 42,
|
||||
granted: [0, 1, 2, 128]
|
||||
}
|
||||
```
|
||||
|
||||
All the granted qos __must__ be < 256, as they are encoded as UInt8.
|
||||
All properties are mandatory.
|
||||
|
||||
### Unsubscribe
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'unsubscribe',
|
||||
messageId: 42,
|
||||
unsubscriptions: [
|
||||
'test',
|
||||
'a/topic'
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
All properties are mandatory.
|
||||
|
||||
### Unsuback
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'unsuback',
|
||||
messageId: 42
|
||||
}
|
||||
```
|
||||
|
||||
All properties are mandatory.
|
||||
|
||||
### Publish
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'publish',
|
||||
messageId: 42,
|
||||
qos: 2,
|
||||
dup: false,
|
||||
topic: 'test',
|
||||
payload: new Buffer('test'),
|
||||
retain: false
|
||||
}
|
||||
```
|
||||
|
||||
Only the `topic` property is mandatory.
|
||||
Both `topic` and `payload` can be `Buffer` objects instead of strings.
|
||||
`messageId` is mandatory for `qos > 0`.
|
||||
|
||||
### Puback
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'puback',
|
||||
messageId: 42
|
||||
}
|
||||
```
|
||||
|
||||
The only mandatory property is `messageId`, as `generate` will throw if
|
||||
missing.
|
||||
|
||||
### Pubrec
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'pubcomp',
|
||||
messageId: 42
|
||||
}
|
||||
```
|
||||
|
||||
The only mandatory property is `messageId`, as `generate` will throw if
|
||||
missing.
|
||||
|
||||
### Pubrel
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'pubrel',
|
||||
messageId: 42
|
||||
}
|
||||
```
|
||||
|
||||
The only mandatory property is `messageId`, as `generate` will throw if
|
||||
missing.
|
||||
|
||||
### Pubcomp
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'pubcomp',
|
||||
messageId: 42
|
||||
}
|
||||
```
|
||||
|
||||
The only mandatory property is `messageId`, as `generate` will throw if
|
||||
missing.
|
||||
|
||||
### Pingreq
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'pingreq'
|
||||
}
|
||||
```
|
||||
|
||||
### Pingresp
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'pingresp'
|
||||
}
|
||||
```
|
||||
|
||||
### Disconnect
|
||||
|
||||
```js
|
||||
{
|
||||
cmd: 'disconnect'
|
||||
}
|
||||
```
|
||||
|
||||
<a name="contributing"></a>
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
mqtt-packet is an **OPEN Open Source Project**. This means that:
|
||||
|
||||
> Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
|
||||
|
||||
See the [CONTRIBUTING.md](https://github.com/mqttjs/mqtt-packet/blob/master/CONTRIBUTING.md) file for more details.
|
||||
|
||||
### Contributors
|
||||
|
||||
mqtt-packet is only possible due to the excellent work of the following contributors:
|
||||
|
||||
<table><tbody>
|
||||
<tr><th align="left">Matteo Collina</th><td><a href="https://github.com/mcollina">GitHub/mcollina</a></td><td><a href="http://twitter.com/matteocollina">Twitter/@matteocollina</a></td></tr>
|
||||
<tr><th align="left">Adam Rudd</th><td><a href="https://github.com/adamvr">GitHub/adamvr</a></td><td><a href="http://twitter.com/adam_vr">Twitter/@adam_vr</a></td></tr>
|
||||
<tr><th align="left">Peter Sorowka</th><td><a href="https://github.com/psorowka">GitHub/psorowka</a></td><td><a href="http://twitter.com/psorowka">Twitter/@psorowka</a></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
29
node_modules/mqtt-packet/benchmarks/generate.js
generated
vendored
Normal file
29
node_modules/mqtt-packet/benchmarks/generate.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
|
||||
var mqtt = require('../')
|
||||
var max = 100000
|
||||
var i
|
||||
var buf = Buffer.from('test')
|
||||
|
||||
// initialize it
|
||||
mqtt.generate({
|
||||
cmd: 'publish',
|
||||
topic: 'test',
|
||||
payload: buf
|
||||
})
|
||||
|
||||
var start = Date.now()
|
||||
var time
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
mqtt.generate({
|
||||
cmd: 'publish',
|
||||
topic: 'test',
|
||||
payload: buf
|
||||
})
|
||||
}
|
||||
|
||||
time = Date.now() - start
|
||||
console.log('Total time', time)
|
||||
console.log('Total packets', max)
|
||||
console.log('Packet/s', max / time * 1000)
|
51
node_modules/mqtt-packet/benchmarks/generateNet.js
generated
vendored
Normal file
51
node_modules/mqtt-packet/benchmarks/generateNet.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
var mqtt = require('../')
|
||||
var max = 1000000
|
||||
var i = 0
|
||||
var start = Date.now()
|
||||
var time
|
||||
var buf = Buffer.allocUnsafe(10)
|
||||
var net = require('net')
|
||||
var server = net.createServer(handle)
|
||||
var dest
|
||||
|
||||
buf.fill('test')
|
||||
|
||||
function handle (sock) {
|
||||
sock.resume()
|
||||
}
|
||||
|
||||
server.listen(0, function () {
|
||||
dest = net.connect(server.address())
|
||||
|
||||
dest.on('connect', tickWait)
|
||||
dest.on('drain', tickWait)
|
||||
dest.on('finish', function () {
|
||||
time = Date.now() - start
|
||||
console.log('Total time', time)
|
||||
console.log('Total packets', max)
|
||||
console.log('Packet/s', max / time * 1000)
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
|
||||
function tickWait () {
|
||||
// console.log('tickWait', i)
|
||||
var res = true
|
||||
// var toSend = new Buffer(5 + buf.length)
|
||||
|
||||
for (; i < max && res; i++) {
|
||||
res = dest.write(mqtt.generate({
|
||||
cmd: 'publish',
|
||||
topic: 'test',
|
||||
payload: buf
|
||||
}))
|
||||
// buf.copy(toSend, 5)
|
||||
// res = dest.write(toSend, 'buffer')
|
||||
// console.log(res)
|
||||
}
|
||||
|
||||
if (i >= max) {
|
||||
dest.end()
|
||||
}
|
||||
}
|
21
node_modules/mqtt-packet/benchmarks/parse.js
generated
vendored
Normal file
21
node_modules/mqtt-packet/benchmarks/parse.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
var mqtt = require('../')
|
||||
var parser = mqtt.parser()
|
||||
var max = 10000000
|
||||
var i
|
||||
var start = Date.now() / 1000
|
||||
var time
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
parser.parse(Buffer.from([
|
||||
48, 10, // Header (publish)
|
||||
0, 4, // Topic length
|
||||
116, 101, 115, 116, // Topic (test)
|
||||
116, 101, 115, 116 // Payload (test)
|
||||
]))
|
||||
}
|
||||
|
||||
time = Date.now() / 1000 - start
|
||||
console.log('Total packets', max)
|
||||
console.log('Total time', Math.round(time * 100) / 100)
|
||||
console.log('Packet/s', max / time)
|
49
node_modules/mqtt-packet/benchmarks/writeToStream.js
generated
vendored
Normal file
49
node_modules/mqtt-packet/benchmarks/writeToStream.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
var mqtt = require('../')
|
||||
var max = 1000000
|
||||
var i = 0
|
||||
var start = Date.now()
|
||||
var time
|
||||
var buf = Buffer.allocUnsafe(10)
|
||||
var net = require('net')
|
||||
var server = net.createServer(handle)
|
||||
var dest
|
||||
|
||||
function handle (sock) {
|
||||
sock.resume()
|
||||
}
|
||||
|
||||
buf.fill('test')
|
||||
|
||||
server.listen(0, function () {
|
||||
dest = net.connect(server.address())
|
||||
|
||||
dest.on('connect', tickWait)
|
||||
dest.on('drain', tickWait)
|
||||
dest.on('finish', function () {
|
||||
time = Date.now() - start
|
||||
console.log('Total time', time)
|
||||
console.log('Total packets', max)
|
||||
console.log('Packet/s', max / time * 1000)
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
|
||||
function tickWait () {
|
||||
var res = true
|
||||
// var toSend = new Buffer(5)
|
||||
|
||||
for (; i < max && res; i++) {
|
||||
res = mqtt.writeToStream({
|
||||
cmd: 'publish',
|
||||
topic: 'test',
|
||||
payload: buf
|
||||
}, dest)
|
||||
// dest.write(toSend, 'buffer')
|
||||
// res = dest.write(buf, 'buffer')
|
||||
}
|
||||
|
||||
if (i >= max) {
|
||||
dest.end()
|
||||
}
|
||||
}
|
111
node_modules/mqtt-packet/constants.js
generated
vendored
Normal file
111
node_modules/mqtt-packet/constants.js
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
'use strict'
|
||||
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
|
||||
/* Protocol - protocol constants */
|
||||
var 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: 'reserved'
|
||||
}
|
||||
|
||||
/* Mnemonic => Command code */
|
||||
protocol.codes = {}
|
||||
for (var k in protocol.types) {
|
||||
var 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.LENGTH_MASK = 0x7F
|
||||
protocol.LENGTH_FIN_MASK = 0x80
|
||||
|
||||
/* 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])
|
||||
|
||||
function genHeader (type) {
|
||||
return [0, 1, 2].map(function (qos) {
|
||||
return [0, 1].map(function (dup) {
|
||||
return [0, 1].map(function (retain) {
|
||||
var buf = new Buffer(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')
|
||||
|
||||
/* 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])
|
||||
|
||||
/* QoS */
|
||||
protocol.QOS = [0, 1, 2].map(function (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])
|
||||
}
|
56
node_modules/mqtt-packet/generate.js
generated
vendored
Normal file
56
node_modules/mqtt-packet/generate.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
'use strict'
|
||||
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
var writeToStream = require('./writeToStream')
|
||||
var EE = require('events').EventEmitter
|
||||
var inherits = require('inherits')
|
||||
|
||||
function generate (packet) {
|
||||
var stream = new Accumulator()
|
||||
writeToStream(packet, stream)
|
||||
return stream.concat()
|
||||
}
|
||||
|
||||
function Accumulator () {
|
||||
this._array = new Array(20)
|
||||
this._i = 0
|
||||
}
|
||||
|
||||
inherits(Accumulator, EE)
|
||||
|
||||
Accumulator.prototype.write = function (chunk) {
|
||||
this._array[this._i++] = chunk
|
||||
return true
|
||||
}
|
||||
|
||||
Accumulator.prototype.concat = function () {
|
||||
var length = 0
|
||||
var lengths = new Array(this._array.length)
|
||||
var list = this._array
|
||||
var pos = 0
|
||||
var i
|
||||
var result
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
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
|
5
node_modules/mqtt-packet/mqtt.js
generated
vendored
Normal file
5
node_modules/mqtt-packet/mqtt.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
exports.parser = require('./parser')
|
||||
exports.generate = require('./generate')
|
||||
exports.writeToStream = require('./writeToStream')
|
25
node_modules/mqtt-packet/numbers.js
generated
vendored
Normal file
25
node_modules/mqtt-packet/numbers.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
'use strict'
|
||||
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
var max = 65536
|
||||
var cache = {}
|
||||
|
||||
function generateBuffer (i) {
|
||||
var buffer = Buffer.allocUnsafe(2)
|
||||
buffer.writeUInt8(i >> 8, 0)
|
||||
buffer.writeUInt8(i & 0x00FF, 0 + 1)
|
||||
|
||||
return buffer
|
||||
}
|
||||
|
||||
function generateCache () {
|
||||
for (var i = 0; i < max; i++) {
|
||||
cache[i] = generateBuffer(i)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
cache: cache,
|
||||
generateCache: generateCache,
|
||||
generateNumber: generateBuffer
|
||||
}
|
88
node_modules/mqtt-packet/package.json
generated
vendored
Normal file
88
node_modules/mqtt-packet/package.json
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
{
|
||||
"_from": "mqtt-packet@^5.6.0",
|
||||
"_id": "mqtt-packet@5.6.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-QECe2ivqcR1LRsPobRsjenEKAC3i1a5gmm+jNKJLrsiq9PaSQ18LlKFuxvhGxWkvGEPadWv6rKd31O4ICqS1Xw==",
|
||||
"_location": "/mqtt-packet",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "mqtt-packet@^5.6.0",
|
||||
"name": "mqtt-packet",
|
||||
"escapedName": "mqtt-packet",
|
||||
"rawSpec": "^5.6.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.6.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/mqtt"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.0.tgz",
|
||||
"_shasum": "923fb704d0ce0bd6ac81c7e1cc09469b1512d2fd",
|
||||
"_spec": "mqtt-packet@^5.6.0",
|
||||
"_where": "/home/wn/workspace-node/PiAlive/node_modules/mqtt",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mqttjs/mqtt-packet/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Matteo Collina",
|
||||
"email": "matteo.collina@gmail.com",
|
||||
"url": "https://github.com/mcollina"
|
||||
},
|
||||
{
|
||||
"name": "Adam Rudd",
|
||||
"email": "damvrr@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Peter Sorowka",
|
||||
"url": "https://github.com/psorowka"
|
||||
},
|
||||
{
|
||||
"name": "Wouter Klijn",
|
||||
"email": "contact@wuhkuh.com",
|
||||
"url": "https://github.com/wuhkuh"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"bl": "^1.2.1",
|
||||
"inherits": "^2.0.3",
|
||||
"process-nextick-args": "^2.0.0",
|
||||
"safe-buffer": "^5.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Parse and generate MQTT packets like a breeze",
|
||||
"devDependencies": {
|
||||
"dev-null": "^0.1.1",
|
||||
"pre-commit": "^1.2.2",
|
||||
"readable-stream": "^2.3.0",
|
||||
"standard": "^10.0.2",
|
||||
"tap-spec": "^4.1.1",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"homepage": "https://github.com/mqttjs/mqtt-packet",
|
||||
"keywords": [
|
||||
"MQTT",
|
||||
"packet",
|
||||
"parse",
|
||||
"publish",
|
||||
"subscribe",
|
||||
"pubsub"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "mqtt.js",
|
||||
"name": "mqtt-packet",
|
||||
"pre-commit": "test",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mqttjs/mqtt-packet.git"
|
||||
},
|
||||
"scripts": {
|
||||
"ci": "tape test.js && node testRandom && standard",
|
||||
"test": "tape test.js | tap-spec && standard"
|
||||
},
|
||||
"types": "types/index.d.ts",
|
||||
"version": "5.6.0"
|
||||
}
|
12
node_modules/mqtt-packet/packet.js
generated
vendored
Normal file
12
node_modules/mqtt-packet/packet.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
function Packet () {
|
||||
this.cmd = null
|
||||
this.retain = false
|
||||
this.qos = 0
|
||||
this.dup = false
|
||||
this.length = -1
|
||||
this.topic = null
|
||||
this.payload = null
|
||||
}
|
||||
|
||||
module.exports = Packet
|
375
node_modules/mqtt-packet/parser.js
generated
vendored
Normal file
375
node_modules/mqtt-packet/parser.js
generated
vendored
Normal file
@ -0,0 +1,375 @@
|
||||
'use strict'
|
||||
|
||||
var bl = require('bl')
|
||||
var inherits = require('inherits')
|
||||
var EE = require('events').EventEmitter
|
||||
var Packet = require('./packet')
|
||||
var constants = require('./constants')
|
||||
|
||||
function Parser () {
|
||||
if (!(this instanceof Parser)) return new Parser()
|
||||
|
||||
this._states = [
|
||||
'_parseHeader',
|
||||
'_parseLength',
|
||||
'_parsePayload',
|
||||
'_newPacket'
|
||||
]
|
||||
|
||||
this._resetState()
|
||||
}
|
||||
|
||||
inherits(Parser, EE)
|
||||
|
||||
Parser.prototype._resetState = function () {
|
||||
this.packet = new Packet()
|
||||
this.error = null
|
||||
this._list = bl()
|
||||
this._stateCounter = 0
|
||||
}
|
||||
|
||||
Parser.prototype.parse = function (buf) {
|
||||
if (this.error) this._resetState()
|
||||
|
||||
this._list.append(buf)
|
||||
|
||||
while ((this.packet.length !== -1 || this._list.length > 0) &&
|
||||
this[this._states[this._stateCounter]]() &&
|
||||
!this.error) {
|
||||
this._stateCounter++
|
||||
|
||||
if (this._stateCounter >= this._states.length) this._stateCounter = 0
|
||||
}
|
||||
|
||||
return this._list.length
|
||||
}
|
||||
|
||||
Parser.prototype._parseHeader = function () {
|
||||
// There is at least one byte in the buffer
|
||||
var 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
|
||||
|
||||
this._list.consume(1)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
Parser.prototype._parseLength = function () {
|
||||
// There is at least one byte in the list
|
||||
var bytes = 0
|
||||
var mul = 1
|
||||
var length = 0
|
||||
var result = true
|
||||
var current
|
||||
|
||||
while (bytes < 5) {
|
||||
current = this._list.readUInt8(bytes++)
|
||||
length += mul * (current & constants.LENGTH_MASK)
|
||||
mul *= 0x80
|
||||
|
||||
if ((current & constants.LENGTH_FIN_MASK) === 0) break
|
||||
if (this._list.length <= bytes) {
|
||||
result = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
this.packet.length = length
|
||||
this._list.consume(bytes)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Parser.prototype._parsePayload = function () {
|
||||
var 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._parseMessageId()
|
||||
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':
|
||||
case 'disconnect':
|
||||
// These are empty, nothing to do
|
||||
break
|
||||
default:
|
||||
this._emitError(new Error('Not supported'))
|
||||
}
|
||||
|
||||
result = true
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Parser.prototype._parseConnect = function () {
|
||||
var protocolId // Protocol ID
|
||||
var clientId // Client ID
|
||||
var topic // Will topic
|
||||
var payload // Will payload
|
||||
var password // Password
|
||||
var username // Username
|
||||
var flags = {}
|
||||
var packet = this.packet
|
||||
|
||||
// Parse protocolId
|
||||
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 !== 3 && packet.protocolVersion !== 4) {
|
||||
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 clientId
|
||||
clientId = this._parseString()
|
||||
if (clientId === null) return this._emitError(new Error('Packet too short'))
|
||||
packet.clientId = clientId
|
||||
|
||||
if (flags.will) {
|
||||
// Parse will topic
|
||||
topic = this._parseString()
|
||||
if (topic === null) return this._emitError(new Error('Cannot parse will topic'))
|
||||
packet.will.topic = topic
|
||||
|
||||
// Parse will payload
|
||||
payload = this._parseBuffer()
|
||||
if (payload === null) return this._emitError(new Error('Cannot parse will payload'))
|
||||
packet.will.payload = payload
|
||||
}
|
||||
|
||||
// Parse username
|
||||
if (flags.username) {
|
||||
username = this._parseString()
|
||||
if (username === null) return this._emitError(new Error('Cannot parse username'))
|
||||
packet.username = username
|
||||
}
|
||||
|
||||
// Parse password
|
||||
if (flags.password) {
|
||||
password = this._parseBuffer()
|
||||
if (password === null) return this._emitError(new Error('Cannot parse password'))
|
||||
packet.password = password
|
||||
}
|
||||
|
||||
return packet
|
||||
}
|
||||
|
||||
Parser.prototype._parseConnack = function () {
|
||||
var packet = this.packet
|
||||
|
||||
if (this._list.length < 2) return null
|
||||
|
||||
packet.sessionPresent = !!(this._list.readUInt8(this._pos++) & constants.SESSIONPRESENT_MASK)
|
||||
packet.returnCode = this._list.readUInt8(this._pos)
|
||||
|
||||
if (packet.returnCode === -1) return this._emitError(new Error('Cannot parse return code'))
|
||||
}
|
||||
|
||||
Parser.prototype._parsePublish = function () {
|
||||
var 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 }
|
||||
|
||||
packet.payload = this._list.slice(this._pos, packet.length)
|
||||
}
|
||||
|
||||
Parser.prototype._parseSubscribe = function () {
|
||||
var packet = this.packet
|
||||
var topic
|
||||
var qos
|
||||
|
||||
if (packet.qos !== 1) {
|
||||
return this._emitError(new Error('Wrong subscribe header'))
|
||||
}
|
||||
|
||||
packet.subscriptions = []
|
||||
|
||||
if (!this._parseMessageId()) { return }
|
||||
|
||||
while (this._pos < packet.length) {
|
||||
// Parse topic
|
||||
topic = this._parseString()
|
||||
if (topic === null) return this._emitError(new Error('Cannot parse topic'))
|
||||
|
||||
qos = this._list.readUInt8(this._pos++)
|
||||
|
||||
// Push pair to subscriptions
|
||||
packet.subscriptions.push({ topic: topic, qos: qos })
|
||||
}
|
||||
}
|
||||
|
||||
Parser.prototype._parseSuback = function () {
|
||||
this.packet.granted = []
|
||||
|
||||
if (!this._parseMessageId()) { return }
|
||||
|
||||
// Parse granted QoSes
|
||||
while (this._pos < this.packet.length) {
|
||||
this.packet.granted.push(this._list.readUInt8(this._pos++))
|
||||
}
|
||||
}
|
||||
|
||||
Parser.prototype._parseUnsubscribe = function () {
|
||||
var packet = this.packet
|
||||
|
||||
packet.unsubscriptions = []
|
||||
|
||||
// Parse messageId
|
||||
if (!this._parseMessageId()) { return }
|
||||
|
||||
while (this._pos < packet.length) {
|
||||
var topic
|
||||
|
||||
// Parse topic
|
||||
topic = this._parseString()
|
||||
if (topic === null) return this._emitError(new Error('Cannot parse topic'))
|
||||
|
||||
// Push topic to unsubscriptions
|
||||
packet.unsubscriptions.push(topic)
|
||||
}
|
||||
}
|
||||
|
||||
Parser.prototype._parseUnsuback = function () {
|
||||
if (!this._parseMessageId()) return this._emitError(new Error('Cannot parse messageId'))
|
||||
}
|
||||
|
||||
Parser.prototype._parseMessageId = function () {
|
||||
var packet = this.packet
|
||||
|
||||
packet.messageId = this._parseNum()
|
||||
|
||||
if (packet.messageId === null) {
|
||||
this._emitError(new Error('Cannot parse messageId'))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
Parser.prototype._parseString = function (maybeBuffer) {
|
||||
var length = this._parseNum()
|
||||
var result
|
||||
var end = length + this._pos
|
||||
|
||||
if (length === -1 || end > this._list.length || end > this.packet.length) return null
|
||||
|
||||
result = this._list.toString('utf8', this._pos, end)
|
||||
this._pos += length
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Parser.prototype._parseBuffer = function () {
|
||||
var length = this._parseNum()
|
||||
var result
|
||||
var end = length + this._pos
|
||||
|
||||
if (length === -1 || end > this._list.length || end > this.packet.length) return null
|
||||
|
||||
result = this._list.slice(this._pos, end)
|
||||
|
||||
this._pos += length
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Parser.prototype._parseNum = function () {
|
||||
if (this._list.length - this._pos < 2) return -1
|
||||
|
||||
var result = this._list.readUInt16BE(this._pos)
|
||||
this._pos += 2
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Parser.prototype._newPacket = function () {
|
||||
if (this.packet) {
|
||||
this._list.consume(this.packet.length)
|
||||
this.emit('packet', this.packet)
|
||||
}
|
||||
|
||||
this.packet = new Packet()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
Parser.prototype._emitError = function (err) {
|
||||
this.error = err
|
||||
this.emit('error', err)
|
||||
}
|
||||
|
||||
module.exports = Parser
|
1257
node_modules/mqtt-packet/test.js
generated
vendored
Normal file
1257
node_modules/mqtt-packet/test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
90
node_modules/mqtt-packet/testRandom.js
generated
vendored
Normal file
90
node_modules/mqtt-packet/testRandom.js
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
'use strict'
|
||||
|
||||
var mqtt = require('./')
|
||||
var crypto = require('crypto')
|
||||
var max = 1E5
|
||||
var i
|
||||
var start = Date.now() / 1000
|
||||
var time
|
||||
var errors = 0
|
||||
var packets = 0
|
||||
var randomPacket
|
||||
var firstBytes = [
|
||||
16 * 1, // CONNECT
|
||||
16 * 2, // CONNACK
|
||||
16 * 3, // PUBLISH, QoS: 0, No Retain, No Dup
|
||||
16 * 3 + 1, // PUBLISH, QoS: 0, Retain, No Dup
|
||||
16 * 3 + 8, // PUBLISH, QoS: 0, No Retain, Dup
|
||||
16 * 3 + 1 + 8, // PUBLISH, QoS: 0, Retain, Dup
|
||||
16 * 3 + 2, // PUBLISH, QoS: 1, No Retain, No Dup
|
||||
16 * 3 + 2 + 1, // PUBLISH, QoS: 1, Retain, No Dup
|
||||
16 * 3 + 2 + 8, // PUBLISH, QoS: 1, No Retain, Dup
|
||||
16 * 3 + 2 + 1 + 8, // PUBLISH, QoS: 1, Retain, Dup
|
||||
16 * 3 + 4, // PUBLISH, QoS: 2, No Retain, No Dup
|
||||
16 * 3 + 4 + 1, // PUBLISH, QoS: 2, Retain, No Dup
|
||||
16 * 3 + 4 + 8, // PUBLISH, QoS: 2, No Retain, Dup
|
||||
16 * 3 + 4 + 1 + 8, // PUBLISH, QoS: 2, Retain, Dup
|
||||
16 * 4, // PUBACK
|
||||
16 * 5, // PUBREC
|
||||
16 * 6, // PUBREL
|
||||
16 * 7, // PUBCOMP
|
||||
16 * 8, // SUBSCRIBE
|
||||
16 * 9, // SUBACK
|
||||
16 * 10, // UNSUBSCRIBE
|
||||
16 * 11, // UNSUBACK
|
||||
16 * 12, // PINGREQ
|
||||
16 * 13, // PINGRESP
|
||||
16 * 14, // DISCONNECT
|
||||
16 * 15 // RESERVED
|
||||
]
|
||||
|
||||
function doParse () {
|
||||
var parser = mqtt.parser()
|
||||
|
||||
parser.on('error', onError)
|
||||
parser.on('packet', onPacket)
|
||||
randomPacket = crypto.randomBytes(Math.floor(Math.random() * 512))
|
||||
|
||||
// Increase probability to have a valid first byte in order to at least
|
||||
// enter the parser
|
||||
if (Math.random() > 0.2 && randomPacket.length > 0) randomPacket.writeUInt8(firstBytes[Math.floor(Math.random() * firstBytes.length)], 0)
|
||||
parser.parse(randomPacket)
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Starting benchmark')
|
||||
for (i = 0; i < max; i++) {
|
||||
doParse()
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Exception occurred at packet')
|
||||
console.log(randomPacket)
|
||||
console.log(e.message)
|
||||
console.log(e.stack)
|
||||
}
|
||||
|
||||
function onError () {
|
||||
errors++
|
||||
}
|
||||
|
||||
function onPacket () {
|
||||
packets++
|
||||
}
|
||||
|
||||
var delta = Math.abs(max - packets - errors)
|
||||
time = Date.now() / 1000 - start
|
||||
console.log('Benchmark complete')
|
||||
console.log('==========================')
|
||||
console.log('Sent packets:', max)
|
||||
console.log('Total time:', Math.round(time * 100) / 100, 'seconds', '\r\n')
|
||||
|
||||
console.log('Valid packets:', packets)
|
||||
console.log('Erroneous packets:', errors)
|
||||
|
||||
if ((max - packets - errors) < 0) console.log('Excess packets:', delta, '\r\n')
|
||||
else console.log('Missing packets:', delta, '\r\n')
|
||||
|
||||
console.log('Total packets:', packets + errors)
|
||||
console.log('Total errors:', errors + delta)
|
||||
console.log('Error rate:', ((errors + delta) / max * 100).toFixed(2) + '%')
|
||||
console.log('==========================')
|
142
node_modules/mqtt-packet/types/index.d.ts
generated
vendored
Normal file
142
node_modules/mqtt-packet/types/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
import EventEmitter = NodeJS.EventEmitter
|
||||
import WritableStream = NodeJS.WritableStream
|
||||
|
||||
export declare type QoS = 0 | 1 | 2
|
||||
|
||||
export declare type PacketCmd = 'connack' |
|
||||
'connect' |
|
||||
'disconnect' |
|
||||
'pingreq' |
|
||||
'pingresp' |
|
||||
'puback' |
|
||||
'pubcomp' |
|
||||
'publish' |
|
||||
'pubrel' |
|
||||
'pubrec' |
|
||||
'suback' |
|
||||
'subscribe' |
|
||||
'unsuback' |
|
||||
'unsubscribe'
|
||||
|
||||
export interface IPacket {
|
||||
cmd: PacketCmd
|
||||
messageId?: number
|
||||
length?: number
|
||||
}
|
||||
|
||||
export interface IConnectPacket extends IPacket {
|
||||
cmd: 'connect'
|
||||
clientId: string
|
||||
protocolVersion?: 4 | 3
|
||||
protocolId?: 'MQTT' | 'MQIsdp'
|
||||
clean?: boolean
|
||||
keepalive?: number
|
||||
username?: string
|
||||
password?: Buffer
|
||||
will?: {
|
||||
topic: string
|
||||
payload: Buffer
|
||||
qos?: QoS
|
||||
retain?: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export interface IPublishPacket extends IPacket {
|
||||
cmd: 'publish'
|
||||
qos: QoS
|
||||
dup: boolean
|
||||
retain: boolean
|
||||
topic: string
|
||||
payload: string | Buffer
|
||||
}
|
||||
|
||||
export interface IConnackPacket extends IPacket {
|
||||
cmd: 'connack'
|
||||
returnCode: number
|
||||
sessionPresent: boolean
|
||||
}
|
||||
|
||||
export interface ISubscription {
|
||||
topic: string
|
||||
qos: QoS
|
||||
}
|
||||
|
||||
export interface ISubscribePacket extends IPacket {
|
||||
cmd: 'subscribe'
|
||||
subscriptions: ISubscription[]
|
||||
}
|
||||
|
||||
export interface ISubackPacket extends IPacket {
|
||||
cmd: 'suback'
|
||||
granted: number[]
|
||||
}
|
||||
|
||||
export interface IUnsubscribePacket extends IPacket {
|
||||
cmd: 'unsubscribe'
|
||||
unsubscriptions: string[]
|
||||
}
|
||||
|
||||
export interface IUnsubackPacket extends IPacket {
|
||||
cmd: 'unsuback'
|
||||
}
|
||||
|
||||
export interface IPubackPacket extends IPacket {
|
||||
cmd: 'puback'
|
||||
}
|
||||
|
||||
export interface IPubcompPacket extends IPacket {
|
||||
cmd: 'pubcomp'
|
||||
}
|
||||
|
||||
export interface IPubrelPacket extends IPacket {
|
||||
cmd: 'pubrel'
|
||||
}
|
||||
|
||||
export interface IPubrecPacket extends IPacket {
|
||||
cmd: 'pubrec'
|
||||
}
|
||||
|
||||
export interface IPingreqPacket extends IPacket {
|
||||
cmd: 'pingreq'
|
||||
}
|
||||
|
||||
export interface IPingrespPacket extends IPacket {
|
||||
cmd: 'pingresp'
|
||||
}
|
||||
|
||||
export interface IDisconnectPacket extends IPacket {
|
||||
cmd: 'disconnect'
|
||||
}
|
||||
|
||||
export declare type Packet = IConnectPacket |
|
||||
IPublishPacket |
|
||||
IConnackPacket |
|
||||
ISubscribePacket |
|
||||
ISubackPacket |
|
||||
IUnsubscribePacket |
|
||||
IUnsubackPacket |
|
||||
IPubackPacket |
|
||||
IPubcompPacket |
|
||||
IPubrelPacket |
|
||||
IPingreqPacket |
|
||||
IPingrespPacket |
|
||||
IDisconnectPacket |
|
||||
IPubrecPacket
|
||||
|
||||
export interface Parser extends EventEmitter {
|
||||
on(event: 'packet', callback: (packet: Packet) => void): this
|
||||
|
||||
on(event: 'error', callback: (error: any) => void): this
|
||||
|
||||
parse(buffer: Buffer): number
|
||||
}
|
||||
|
||||
export declare function parser(): Parser
|
||||
|
||||
export declare function generate(packet: Packet): Buffer
|
||||
|
||||
export declare function writeToStream(object: Packet, stream: WritableStream): void
|
||||
|
||||
export declare namespace writeToStream {
|
||||
let cacheNumbers: boolean
|
||||
}
|
595
node_modules/mqtt-packet/writeToStream.js
generated
vendored
Normal file
595
node_modules/mqtt-packet/writeToStream.js
generated
vendored
Normal file
@ -0,0 +1,595 @@
|
||||
'use strict'
|
||||
|
||||
var protocol = require('./constants')
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
var empty = Buffer.allocUnsafe(0)
|
||||
var zeroBuf = Buffer.from([0])
|
||||
var numbers = require('./numbers')
|
||||
var nextTick = require('process-nextick-args').nextTick
|
||||
|
||||
var numCache = numbers.cache
|
||||
var generateNumber = numbers.generateNumber
|
||||
var generateCache = numbers.generateCache
|
||||
var writeNumber = writeNumberCached
|
||||
var toGenerate = true
|
||||
|
||||
function generate (packet, stream) {
|
||||
if (stream.cork) {
|
||||
stream.cork()
|
||||
nextTick(uncork, stream)
|
||||
}
|
||||
|
||||
if (toGenerate) {
|
||||
toGenerate = false
|
||||
generateCache()
|
||||
}
|
||||
|
||||
switch (packet.cmd) {
|
||||
case 'connect':
|
||||
return connect(packet, stream)
|
||||
case 'connack':
|
||||
return connack(packet, stream)
|
||||
case 'publish':
|
||||
return publish(packet, stream)
|
||||
case 'puback':
|
||||
case 'pubrec':
|
||||
case 'pubrel':
|
||||
case 'pubcomp':
|
||||
case 'unsuback':
|
||||
return confirmation(packet, stream)
|
||||
case 'subscribe':
|
||||
return subscribe(packet, stream)
|
||||
case 'suback':
|
||||
return suback(packet, stream)
|
||||
case 'unsubscribe':
|
||||
return unsubscribe(packet, stream)
|
||||
case 'pingreq':
|
||||
case 'pingresp':
|
||||
case 'disconnect':
|
||||
return emptyPacket(packet, stream)
|
||||
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: function () {
|
||||
return writeNumber === writeNumberCached
|
||||
},
|
||||
set: function (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 (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var protocolId = settings.protocolId || 'MQTT'
|
||||
var protocolVersion = settings.protocolVersion || 4
|
||||
var will = settings.will
|
||||
var clean = settings.clean
|
||||
var keepalive = settings.keepalive || 0
|
||||
var clientId = settings.clientId || ''
|
||||
var username = settings.username
|
||||
var password = settings.password
|
||||
|
||||
if (clean === undefined) clean = true
|
||||
|
||||
var 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
|
||||
if (protocolVersion !== 3 && protocolVersion !== 4) {
|
||||
stream.emit('error', new Error('Invalid protocol version'))
|
||||
return false
|
||||
} else length += 1
|
||||
|
||||
// ClientId might be omitted in 3.1.1, but only if cleanSession is set to 1
|
||||
if ((typeof clientId === 'string' || Buffer.isBuffer(clientId)) &&
|
||||
(clientId || protocolVersion === 4) && (clientId || clean)) {
|
||||
length += clientId.length + 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
|
||||
|
||||
// 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
|
||||
if (will.payload && will.payload) {
|
||||
if (will.payload.length >= 0) {
|
||||
if (typeof will.payload === 'string') {
|
||||
length += Buffer.byteLength(will.payload) + 2
|
||||
} else {
|
||||
length += will.payload.length + 2
|
||||
}
|
||||
} else {
|
||||
stream.emit('error', new Error('Invalid will payload'))
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
length += 2
|
||||
}
|
||||
}
|
||||
|
||||
// Username
|
||||
var 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
|
||||
writeLength(stream, length)
|
||||
|
||||
// Generate protocol ID
|
||||
writeStringOrBuffer(stream, protocolId)
|
||||
stream.write(
|
||||
protocolVersion === 4 ? protocol.VERSION4 : protocol.VERSION3
|
||||
)
|
||||
|
||||
// Connect flags
|
||||
var 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)
|
||||
|
||||
// Client ID
|
||||
writeStringOrBuffer(stream, clientId)
|
||||
|
||||
// Will
|
||||
if (will) {
|
||||
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 (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var rc = settings.returnCode
|
||||
|
||||
// Check return code
|
||||
if (typeof rc !== 'number') {
|
||||
stream.emit('error', new Error('Invalid return code'))
|
||||
return false
|
||||
}
|
||||
|
||||
stream.write(protocol.CONNACK_HEADER)
|
||||
writeLength(stream, 2)
|
||||
stream.write(opts.sessionPresent ? protocol.SESSIONPRESENT_HEADER : zeroBuf)
|
||||
|
||||
return stream.write(Buffer.from([rc]))
|
||||
}
|
||||
|
||||
function publish (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var qos = settings.qos || 0
|
||||
var retain = settings.retain ? protocol.RETAIN_MASK : 0
|
||||
var topic = settings.topic
|
||||
var payload = settings.payload || empty
|
||||
var id = settings.messageId
|
||||
|
||||
var 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
|
||||
|
||||
// Header
|
||||
stream.write(protocol.PUBLISH_HEADER[qos][opts.dup ? 1 : 0][retain ? 1 : 0])
|
||||
|
||||
// Remaining length
|
||||
writeLength(stream, length)
|
||||
|
||||
// Topic
|
||||
writeNumber(stream, byteLength(topic))
|
||||
stream.write(topic)
|
||||
|
||||
// Message ID
|
||||
if (qos > 0) writeNumber(stream, id)
|
||||
|
||||
// Payload
|
||||
return stream.write(payload)
|
||||
}
|
||||
|
||||
/* Puback, pubrec, pubrel and pubcomp */
|
||||
function confirmation (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var type = settings.cmd || 'puback'
|
||||
var id = settings.messageId
|
||||
var dup = (settings.dup && type === 'pubrel') ? protocol.DUP_MASK : 0
|
||||
var qos = 0
|
||||
|
||||
if (type === 'pubrel') qos = 1
|
||||
|
||||
// Check message ID
|
||||
if (typeof id !== 'number') {
|
||||
stream.emit('error', new Error('Invalid messageId'))
|
||||
return false
|
||||
}
|
||||
|
||||
// Header
|
||||
stream.write(protocol.ACKS[type][qos][dup][0])
|
||||
|
||||
// Length
|
||||
writeLength(stream, 2)
|
||||
|
||||
// Message ID
|
||||
return writeNumber(stream, id)
|
||||
}
|
||||
|
||||
function subscribe (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var dup = settings.dup ? protocol.DUP_MASK : 0
|
||||
var id = settings.messageId
|
||||
var subs = settings.subscriptions
|
||||
|
||||
var length = 0
|
||||
|
||||
// Check message ID
|
||||
if (typeof id !== 'number') {
|
||||
stream.emit('error', new Error('Invalid messageId'))
|
||||
return false
|
||||
} else length += 2
|
||||
|
||||
// Check subscriptions
|
||||
if (typeof subs === 'object' && subs.length) {
|
||||
for (var i = 0; i < subs.length; i += 1) {
|
||||
var itopic = subs[i].topic
|
||||
var 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
|
||||
}
|
||||
|
||||
length += Buffer.byteLength(itopic) + 2 + 1
|
||||
}
|
||||
} else {
|
||||
stream.emit('error', new Error('Invalid subscriptions'))
|
||||
return false
|
||||
}
|
||||
|
||||
// Generate header
|
||||
stream.write(protocol.SUBSCRIBE_HEADER[1][dup ? 1 : 0][0])
|
||||
|
||||
// Generate length
|
||||
writeLength(stream, length)
|
||||
|
||||
// Generate message ID
|
||||
writeNumber(stream, id)
|
||||
|
||||
var result = true
|
||||
|
||||
// Generate subs
|
||||
for (var j = 0; j < subs.length; j++) {
|
||||
var sub = subs[j]
|
||||
var jtopic = sub.topic
|
||||
var jqos = sub.qos
|
||||
|
||||
// Write topic string
|
||||
writeString(stream, jtopic)
|
||||
|
||||
// Write qos
|
||||
result = stream.write(protocol.QOS[jqos])
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function suback (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var id = settings.messageId
|
||||
var granted = settings.granted
|
||||
|
||||
var 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 (var 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
|
||||
}
|
||||
|
||||
// header
|
||||
stream.write(protocol.SUBACK_HEADER)
|
||||
|
||||
// Length
|
||||
writeLength(stream, length)
|
||||
|
||||
// Message ID
|
||||
writeNumber(stream, id)
|
||||
|
||||
return stream.write(Buffer.from(granted))
|
||||
}
|
||||
|
||||
function unsubscribe (opts, stream) {
|
||||
var settings = opts || {}
|
||||
var id = settings.messageId
|
||||
var dup = settings.dup ? protocol.DUP_MASK : 0
|
||||
var unsubs = settings.unsubscriptions
|
||||
|
||||
var 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 (var 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
|
||||
}
|
||||
|
||||
// Header
|
||||
stream.write(protocol.UNSUBSCRIBE_HEADER[1][dup ? 1 : 0][0])
|
||||
|
||||
// Length
|
||||
writeLength(stream, length)
|
||||
|
||||
// Message ID
|
||||
writeNumber(stream, id)
|
||||
|
||||
// Unsubs
|
||||
var result = true
|
||||
for (var j = 0; j < unsubs.length; j++) {
|
||||
result = writeString(stream, unsubs[j])
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function emptyPacket (opts, stream) {
|
||||
return stream.write(protocol.EMPTY[opts.cmd])
|
||||
}
|
||||
|
||||
/**
|
||||
* calcLengthLength - calculate the length of the remaining
|
||||
* length field
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
function calcLengthLength (length) {
|
||||
if (length >= 0 && length < 128) return 1
|
||||
else if (length >= 128 && length < 16384) return 2
|
||||
else if (length >= 16384 && length < 2097152) return 3
|
||||
else if (length >= 2097152 && length < 268435456) return 4
|
||||
else return 0
|
||||
}
|
||||
|
||||
function genBufLength (length) {
|
||||
var digit = 0
|
||||
var pos = 0
|
||||
var buffer = Buffer.allocUnsafe(calcLengthLength(length))
|
||||
|
||||
do {
|
||||
digit = length % 128 | 0
|
||||
length = length / 128 | 0
|
||||
if (length > 0) digit = digit | 0x80
|
||||
|
||||
buffer.writeUInt8(digit, pos++)
|
||||
} while (length > 0)
|
||||
|
||||
return buffer
|
||||
}
|
||||
|
||||
/**
|
||||
* writeLength - write an MQTT style length field to the buffer
|
||||
*
|
||||
* @param <Buffer> buffer - destination
|
||||
* @param <Number> pos - offset
|
||||
* @param <Number> length - length (>0)
|
||||
* @returns <Number> number of bytes written
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var lengthCache = {}
|
||||
function writeLength (stream, length) {
|
||||
var buffer = lengthCache[length]
|
||||
|
||||
if (!buffer) {
|
||||
buffer = genBufLength(length)
|
||||
if (length < 16384) lengthCache[length] = buffer
|
||||
}
|
||||
|
||||
stream.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* writeString - write a utf8 string to the buffer
|
||||
*
|
||||
* @param <Buffer> buffer - destination
|
||||
* @param <Number> pos - offset
|
||||
* @param <String> string - string to write
|
||||
* @return <Number> number of bytes written
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function writeString (stream, string) {
|
||||
var strlen = Buffer.byteLength(string)
|
||||
writeNumber(stream, strlen)
|
||||
|
||||
stream.write(string, 'utf8')
|
||||
}
|
||||
|
||||
/**
|
||||
* writeNumber - write a two byte number to the buffer
|
||||
*
|
||||
* @param <Buffer> buffer - destination
|
||||
* @param <Number> pos - offset
|
||||
* @param <String> number - number to write
|
||||
* @return <Number> number of bytes written
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
function writeNumberCached (stream, number) {
|
||||
return stream.write(numCache[number])
|
||||
}
|
||||
function writeNumberGenerated (stream, number) {
|
||||
return stream.write(generateNumber(number))
|
||||
}
|
||||
|
||||
/**
|
||||
* writeStringOrBuffer - write a String or Buffer with the its length prefix
|
||||
*
|
||||
* @param <Buffer> buffer - destination
|
||||
* @param <Number> pos - offset
|
||||
* @param <String> toWrite - String or Buffer
|
||||
* @return <Number> 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 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
|
Reference in New Issue
Block a user