Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple delimiters in PacketLengthParser, as well as delimiters of sizes > 1 byte #2709

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [12.0.1](https://github.com/serialport/node-serialport/compare/v12.0.0...v12.0.1) (2023-09-26)

**Note:** Version bump only for package serialport-monorepo

# [12.0.0](https://github.com/serialport/node-serialport/compare/v11.0.1...v12.0.0) (2023-08-29)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"conventionalCommits": true
}
},
"version": "12.0.0",
"version": "12.0.1",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/parser-packet-length/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [12.0.1](https://github.com/serialport/node-serialport/compare/v12.0.0...v12.0.1) (2023-09-26)

**Note:** Version bump only for package @serialport/parser-packet-length

# [12.0.0](https://github.com/serialport/node-serialport/compare/v11.0.1...v12.0.0) (2023-08-29)

**Note:** Version bump only for package @serialport/parser-packet-length
Expand Down
41 changes: 41 additions & 0 deletions packages/parser-packet-length/lib/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,45 @@ describe('DelimiterParser', () => {
assert.deepEqual(spy.getCall(1).args[0], Buffer.concat([Buffer.from([0xaa, 0x02, 0x13, 0x00]), Buffer.from('Each and Every One\n')]))
assert(spy.calledTwice)
})

it('works with multiple delimiters', () => {
const spy = sinon.spy()
const parser = new PacketLengthParser({ delimiter: [0xaa, 0xbb], lengthOffset: 2, packetOverhead: 4, lengthBytes: 2 })
parser.on('data', spy)
parser.write(Buffer.from('\xbb\x01\x0d'))
parser.write(Buffer.from('\x00I love hobits\xaa\x02\x13\x00Each '))
parser.write(Buffer.from('and Every One\n'))

assert.deepEqual(spy.getCall(0).args[0], Buffer.concat([Buffer.from([0xbb, 0x01, 0x0d, 0x00]), Buffer.from('I love hobits')]))
assert.deepEqual(spy.getCall(1).args[0], Buffer.concat([Buffer.from([0xaa, 0x02, 0x13, 0x00]), Buffer.from('Each and Every One\n')]))
assert(spy.calledTwice)
})

it('works with multibyte delimiters', () => {
const spy = sinon.spy()
const parser = new PacketLengthParser({ delimiter: [0xababba], delimiterBytes: 3, lengthOffset: 3, packetOverhead: 4, lengthBytes: 1 })
parser.on('data', spy)
parser.write(Buffer.from([0xab, 0xab, 0xba, 0x0d]))
parser.write(Buffer.from('I love hobits'))
parser.write(Buffer.from([0xab, 0xab, 0xba, 0x13]))
parser.write(Buffer.from('Each and Every One\n'))

assert.deepEqual(spy.getCall(0).args[0], Buffer.concat([Buffer.from([0xab, 0xab, 0xba, 0x0d]), Buffer.from('I love hobits')]))
assert.deepEqual(spy.getCall(1).args[0], Buffer.concat([Buffer.from([0xab, 0xab, 0xba, 0x13]), Buffer.from('Each and Every One\n')]))
assert(spy.calledTwice)
})

it('works with multiple multibyte delimiters', () => {
const spy = sinon.spy()
const parser = new PacketLengthParser({ delimiter: [0xababba, 0xbaddad], delimiterBytes: 3, lengthOffset: 3, packetOverhead: 4, lengthBytes: 1 })
parser.on('data', spy)
parser.write(Buffer.from([0xab, 0xab, 0xba, 0x0d]))
parser.write(Buffer.from('I love hobits'))
parser.write(Buffer.from([0xba, 0xdd, 0xad, 0x13]))
parser.write(Buffer.from('Each and Every One\n'))

assert.deepEqual(spy.getCall(0).args[0], Buffer.concat([Buffer.from([0xab, 0xab, 0xba, 0x0d]), Buffer.from('I love hobits')]))
assert.deepEqual(spy.getCall(1).args[0], Buffer.concat([Buffer.from([0xba, 0xdd, 0xad, 0x13]), Buffer.from('Each and Every One\n')]))
assert(spy.calledTwice)
})
})
29 changes: 19 additions & 10 deletions packages/parser-packet-length/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Transform, TransformCallback, TransformOptions } from 'stream'

export interface PacketLengthOptions extends TransformOptions {
/** delimiter to use defaults to 0xaa */
delimiter?: number
/** delimiter(s) to use defaults to 0xaa */
delimiter?: number | number[]
/** delimiter length in bytes defaults to 1 */
delimiterBytes?: number
/** overhead of packet (including length, delimiter and any checksum / packet footer) defaults to 2 */
packetOverhead?: number
/** number of bytes containing length defaults to 1 */
Expand All @@ -29,14 +31,15 @@ export interface PacketLengthOptions extends TransformOptions {
export class PacketLengthParser extends Transform {
buffer: Buffer
start: boolean
opts: { delimiter: number; packetOverhead: number; lengthBytes: number; lengthOffset: number; maxLen: number }
opts: { delimiter: number[]; delimiterBytes: number; packetOverhead: number; lengthBytes: number; lengthOffset: number; maxLen: number }
constructor(options: PacketLengthOptions = {}) {
super(options)

const { delimiter = 0xaa, packetOverhead = 2, lengthBytes = 1, lengthOffset = 1, maxLen = 0xff } = options
const { delimiter = [0xaa], delimiterBytes = 1, packetOverhead = 2, lengthBytes = 1, lengthOffset = 1, maxLen = 0xff } = options

this.opts = {
delimiter,
delimiter: ([] as number[]).concat(delimiter),
delimiterBytes,
packetOverhead,
lengthBytes,
lengthOffset,
Expand All @@ -51,13 +54,8 @@ export class PacketLengthParser extends Transform {
for (let ndx = 0; ndx < chunk.length; ndx++) {
const byte = chunk[ndx]

if (byte === this.opts.delimiter) {
this.start = true
}

if (true === this.start) {
this.buffer = Buffer.concat([this.buffer, Buffer.from([byte])])

if (this.buffer.length >= this.opts.lengthOffset + this.opts.lengthBytes) {
const len = this.buffer.readUIntLE(this.opts.lengthOffset, this.opts.lengthBytes)

Expand All @@ -67,6 +65,17 @@ export class PacketLengthParser extends Transform {
this.start = false
}
}
} else {
this.buffer = Buffer.concat([Buffer.from([byte]), this.buffer])
if (this.buffer.length === this.opts.delimiterBytes) {
const delimiter = this.buffer.readUIntLE(0, this.opts.delimiterBytes)
if (this.opts.delimiter.includes(delimiter)) {
this.start = true
this.buffer = Buffer.from([...this.buffer].reverse())
} else {
this.buffer = Buffer.from(this.buffer.subarray(1, this.buffer.length))
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/parser-packet-length/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"build": "tsc --build tsconfig-build.json"
},
"version": "12.0.0",
"version": "12.0.1",
"engines": {
"node": ">=8.6.0"
},
Expand Down
4 changes: 4 additions & 0 deletions packages/repl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [12.0.1](https://github.com/serialport/node-serialport/compare/v12.0.0...v12.0.1) (2023-09-26)

**Note:** Version bump only for package @serialport/repl

# [12.0.0](https://github.com/serialport/node-serialport/compare/v11.0.1...v12.0.0) (2023-08-29)

**Note:** Version bump only for package @serialport/repl
Expand Down
4 changes: 2 additions & 2 deletions packages/repl/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@serialport/repl",
"version": "12.0.0",
"version": "12.0.1",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
Expand All @@ -11,7 +11,7 @@
},
"dependencies": {
"promirepl": "^2.0.1",
"serialport": "12.0.0"
"serialport": "12.0.1"
},
"engines": {
"node": ">=12.0.0"
Expand Down
4 changes: 4 additions & 0 deletions packages/serialport/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [12.0.1](https://github.com/serialport/node-serialport/compare/v12.0.0...v12.0.1) (2023-09-26)

**Note:** Version bump only for package serialport

# [12.0.0](https://github.com/serialport/node-serialport/compare/v11.0.1...v12.0.0) (2023-08-29)

### Bug Fixes
Expand Down
4 changes: 2 additions & 2 deletions packages/serialport/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "serialport",
"version": "12.0.0",
"version": "12.0.1",
"description": "Node.js package to access serial ports. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them!",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -56,7 +56,7 @@
"@serialport/parser-cctalk": "12.0.0",
"@serialport/parser-delimiter": "12.0.0",
"@serialport/parser-inter-byte-timeout": "12.0.0",
"@serialport/parser-packet-length": "12.0.0",
"@serialport/parser-packet-length": "12.0.1",
"@serialport/parser-readline": "12.0.0",
"@serialport/parser-ready": "12.0.0",
"@serialport/parser-regex": "12.0.0",
Expand Down