split-frames 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,13 +1,13 @@
1
- Copyright (c) 2023, Sébastien Vidal
2
-
3
- Permission to use, copy, modify, and/or distribute this software for any
4
- purpose with or without fee is hereby granted, provided that the above
5
- copyright notice and this permission notice appear in all copies.
6
-
7
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1
+ Copyright (c) 2026, Sébastien Vidal
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,263 +1,268 @@
1
- # split-frames
2
- Split Buffer frames from streams
3
-
4
- [![Build Status](https://api.travis-ci.org/Psychopoulet/split-frames.svg?branch=master)](https://travis-ci.org/Psychopoulet/split-frames)
5
- [![Coverage Status](https://coveralls.io/repos/github/Psychopoulet/split-frames/badge.svg?branch=master)](https://coveralls.io/github/Psychopoulet/split-frames)
6
- [![Dependency Status](https://david-dm.org/Psychopoulet/split-frames/status.svg)](https://david-dm.org/Psychopoulet/split-frames)
7
- [![Dev dependency Status](https://david-dm.org/Psychopoulet/split-frames/dev-status.svg)](https://david-dm.org/Psychopoulet/split-frames?type=dev)
8
- [![Issues](https://img.shields.io/github/issues/Psychopoulet/split-frames.svg)](https://github.com/Psychopoulet/split-frames/issues)
9
- [![Pull requests](https://img.shields.io/github/issues-pr/Psychopoulet/split-frames.svg)](https://github.com/Psychopoulet/split-frames/pulls)
10
-
11
- ## Installation
12
-
13
- ```bash
14
- $ npm install split-frames
15
- ```
16
-
17
- ## Doc
18
-
19
- > Works very well with, for example, [serialport](https://www.npmjs.com/package/serialport) for industrial protocols like Concert
20
-
21
- > /!\ this version only split frames properly, and does not remove start & end tags or escape bits anymore.
22
-
23
- ### Methods
24
-
25
- * inherited from [stream.Transform](https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams)
26
- * constructor ([ options: object ]): split-frames instance
27
-
28
- ### Options
29
-
30
- > All these options are optionnal
31
-
32
- ```typescript
33
- type ControlBits = "none" | "end+1" | "end+2";
34
- type Tag: number | Buffer | Array< number | Buffer >
35
- ```
36
-
37
- * ```javascript "startWith": Tag ```
38
- * ```javascript "startTimeout": integer ``` (default: 200)
39
- * ```javascript "endWith": Tag ```
40
- * ```javascript "escapeWith": number ```
41
- * ```javascript "escaped": Array<number> ```
42
- * ```javascript "specifics": object ```
43
- * ```javascript "controlBits": ControlBits ``` (default: "none")
44
-
45
- > "startTimeout" is a timeout (in milliseconds) which end frame in "start only" mode, if no second "start" bit is encountered after the first one
46
-
47
- > "specifics" is a [ key: string => value: Tag ] object which fire a "key" event when a "value" tag is found out of the message and not escaped
48
- > ex : { "specifics": { "nak": 0x25 } } will fire an "nak" event when 0x25 bit is encountered
49
-
50
- ## Examples
51
-
52
- In the following exemples, "Splitter" and "Readable" classes are defined like that :
53
-
54
- ```typescript
55
- // typescript
56
- import Splitter = require("split-frames");
57
- import { Readable } from "stream";
58
- ```
59
-
60
- ```javascript
61
- // javascript
62
- const Splitter = require("split-frames");
63
- const { Readable } = require("stream");
64
- ```
65
-
66
- The "createReadStream" function is defined like that :
67
-
68
- ```javascript
69
- function createReadStream () {
70
- return new Readable({
71
- read () { }
72
- });
73
- }
74
- ```
75
-
76
- And the "STX", "DLE" and "ETX" constants are defined like that :
77
-
78
- ```javascript
79
- const STX = 0x02, ETX = 0x03, DLE = 0x10, ACK = 0x06, NAK = 0x15, WAK = 0x13;
80
- ```
81
-
82
- ### want to split frames content on a start bit ?
83
-
84
- ```javascript
85
- const stream = createReadStream();
86
-
87
- stream.pipe(new Splitter({
88
- "startWith": STX
89
- })).on("data", (chunk) => {
90
- // Buffer([ STX, 0x24, 0x25, 0x26 ])
91
- // Buffer([ STX, 0x24, 0x25 ])
92
- });
93
-
94
- stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, STX, 0x24 ]));
95
- stream.push(Buffer.from([ 0x25, STX ]));
96
- ```
97
-
98
- ### prefere an end bit ?
99
-
100
- ```javascript
101
- const stream = createReadStream();
102
-
103
- stream.pipe(new Splitter({
104
- "endWith": ETX
105
- })).on("data", (chunk) => {
106
- // Buffer([ 0x24, 0x25, 0x26, ETX ])
107
- // Buffer([ 0x24, 0x25, ETX ])
108
- });
109
-
110
- stream.push(Buffer.from([ 0x24, 0x25, 0x26, ETX, 0x24, 0x25 ]));
111
- stream.push(Buffer.from([ ETX ]));
112
- ```
113
-
114
- ### want both ?
115
-
116
- ```javascript
117
- const stream = createReadStream();
118
-
119
- stream.pipe(new Splitter({
120
- "startWith": STX, "endWith": ETX
121
- })).on("data", (chunk) => {
122
- // Buffer([ STX, 0x24, 0x25, 0x26, ETX ])
123
- // Buffer([ STX, 0x24, 0x25, ETX ])
124
- });
125
-
126
- stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, ETX, 0x24, 0x25, STX ]));
127
- stream.push(Buffer.from([ 0x24, 0x25, ETX ]));
128
- ```
129
-
130
- ### what about two end bits (works with start one as well) ?
131
-
132
- ```javascript
133
- const stream = createReadStream();
134
-
135
- stream.pipe(new Splitter({
136
- "startWith": STX, "endWith": Buffer.from([ DLE, ETX ])
137
- })).on("data", (chunk) => {
138
- // Buffer([ STX, 0x24, 0x25, 0x26, DLE, ETX ])
139
- });
140
-
141
- stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, DLE, ETX, STX, 0x24, 0x25 ]));
142
- ```
143
-
144
- ### Do you need to parse escaped bits ?
145
-
146
- ```javascript
147
- const stream = createReadStream();
148
-
149
- stream.pipe(new Splitter({
150
- "startWith": STX, "endWith": ETX,
151
- "escapeWith": DLE, "escaped": [ DLE, STX, ETX ]
152
- })).on("data", (chunk) => {
153
- // Buffer([ STX, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
154
- });
155
-
156
- stream.push(Buffer.from([ 0x20, STX, 0x24, DLE, STX, 0x25, 0x26 ]));
157
- stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, STX, 0x24, 0x25 ]));
158
- ```
159
-
160
- ### And what do you think about multiple start (or end !) bits possibilities ?
161
-
162
- For even parity in seriaport, for example
163
-
164
- ```javascript
165
- const STX2 = 0x82;
166
- const stream = createReadStream();
167
-
168
- stream.pipe(new Splitter({
169
- "startWith": [ STX, STX2 ], "endWith": ETX,
170
- "escapeWith": DLE, "escaped": [ DLE, STX, ETX ]
171
- })).on("data", (chunk) => {
172
- // Buffer([ STX, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
173
- // Buffer([ STX2, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
174
- });
175
-
176
- stream.push(Buffer.from([ 0x24, STX, 0x24, DLE, STX, 0x25, ACK ]));
177
- stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, ACK, 0x24, 0x25 ]));
178
- stream.push(Buffer.from([ STX2, 0x24, DLE, STX, 0x25, ACK ]));
179
- stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, ACK, 0x24, 0x25 ]));
180
- ```
181
-
182
- ### Want to extract specific tags ?
183
-
184
- > positive acknowledgement, negative acknowledgement, waiting for acknowledgement, whatever...
185
- > only with no tags || start AND end tags || end tags (for firsts bits)
186
-
187
- ```javascript
188
- const stream = createReadStream();
189
-
190
- stream.pipe(new Splitter({
191
- "startWith": STX, "endWith": ETX,
192
- "specifics": {
193
- "ack": ACK, "nak": NAK, "wak": WAK, "whatever": 0x51
194
- },
195
- "escapeWith": DLE, "escaped": [ DLE, ACK, NAK, WAK ]
196
- })).on("ack", () => {
197
- console.log("ack received"); // (only 1x) -> good, escaped, in data
198
- }).on("nak", () => {
199
- console.log("nak received"); // (only 1x) -> in data, good, escaped
200
- }).on("wak", () => {
201
- console.log("wak received"); // (only 1x) -> in data, good, escaped
202
- }).on("whatever", () => {
203
- console.log("whatever received"); // (only 1x)
204
- }).on("data", (chunk) => {
205
- // Buffer([ STX, 0x20, 0x21, 0x22, ACK, NAK, WAK, 0x23, ETX ]) (x1)
206
- });
207
-
208
- stream.push(Buffer.from([ 0x51, 0x24, ACK, DLE, ACK, STX, 0x20, 0x21, 0x22, ACK, NAK, WAK ]));
209
- stream.push(Buffer.from([ 0x23, ETX, NAK, DLE, NAK, WAK, DLE, WAK, 0x20, 0x21 ]));
210
- ```
211
-
212
- ### Want to use control bits ?
213
-
214
- > used to compute LRC, MSB, LSB, etc...
215
- > this example is for a structure like STX <data> ETX LRC, where LRC compute all <data> bits
216
-
217
- ```javascript
218
-
219
- function _computeLRC (frame) {
220
-
221
- let lrc = 0x00;
222
-
223
- for (let i = 0; i < frame.length; ++i) {
224
- lrc ^= frame[i];
225
- }
226
-
227
- return lrc;
228
-
229
- }
230
-
231
- const stream = createReadStream();
232
-
233
- stream.pipe(new Splitter({
234
- "startWith": STX, "endWith": ETX,
235
- "controlBits": "end+1"
236
- })).on("data", (chunk) => {
237
-
238
- // Buffer([ STX, 0x20, 0x21, 0x22, 0x24, ETX, 0x07 ]) (x1)
239
-
240
- const data = chunk.slice(1, chunk.length - 2); // Buffer([ 0x20, 0x21, 0x22, 0x24 ])
241
- const LRC = chunk[chunk.length - 1];
242
-
243
- if (_computeLRC(data) === LRC) {
244
- console.log("OK");
245
- }
246
- else {
247
- console.error(new Error("not well-computed data :" + data.toString("hex") + "|" + Buffer.from([ LRC ]).toString("hex")));
248
- }
249
-
250
- });
251
-
252
- stream.push(Buffer.from([ 0x51, 0x24, STX, 0x20, 0x21, 0x22, 0x24, ETX, 0x07, 0x24 ]));
253
- ```
254
-
255
- ## Tests
256
-
257
- ```bash
258
- $ npm run-script tests
259
- ```
260
-
261
- ## License
262
-
263
- [ISC](LICENSE)
1
+ # split-frames
2
+ Split Buffer frames from streams
3
+
4
+ [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=Psychopoulet_split-frames&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=Psychopoulet_split-frames)
5
+ [![Issues](https://img.shields.io/github/issues/Psychopoulet/split-frames.svg)](https://github.com/Psychopoulet/split-frames/issues)
6
+ [![Pull requests](https://img.shields.io/github/issues-pr/Psychopoulet/split-frames.svg)](https://github.com/Psychopoulet/split-frames/pulls)
7
+
8
+ [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=Psychopoulet_split-frames&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=Psychopoulet_split-frames)
9
+ [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=Psychopoulet_split-frames&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=Psychopoulet_split-frames)
10
+ [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=Psychopoulet_split-frames&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=Psychopoulet_split-frames)
11
+ [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=Psychopoulet_split-frames&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=Psychopoulet_split-frames)
12
+ [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=Psychopoulet_split-frames&metric=bugs)](https://sonarcloud.io/summary/new_code?id=Psychopoulet_split-frames)
13
+
14
+ [![Known Vulnerabilities](https://snyk.io/test/github/Psychopoulet/split-frames/badge.svg)](https://snyk.io/test/github/Psychopoulet/split-frames)
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ $ npm install split-frames
20
+ ```
21
+
22
+ ## Doc
23
+
24
+ > Works very well with, for example, [serialport](https://www.npmjs.com/package/serialport) for industrial protocols like Concert
25
+
26
+ > /!\ this version only split frames properly, and does not remove start & end tags or escape bits anymore.
27
+
28
+ ### Methods
29
+
30
+ * inherited from [stream.Transform](https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams)
31
+ * constructor ([ options: object ]): split-frames instance
32
+
33
+ ### Options
34
+
35
+ > All these options are optionnal
36
+
37
+ ```typescript
38
+ type ControlBits = "none" | "end+1" | "end+2";
39
+ type Tag: number | Buffer | Array< number | Buffer >
40
+ ```
41
+
42
+ * ```javascript "startWith": Tag ```
43
+ * ```javascript "startTimeout": integer ``` (default: 200)
44
+ * ```javascript "endWith": Tag ```
45
+ * ```javascript "escapeWith": number ```
46
+ * ```javascript "escaped": Array<number> ```
47
+ * ```javascript "specifics": object ```
48
+ * ```javascript "controlBits": ControlBits ``` (default: "none")
49
+
50
+ > "startTimeout" is a timeout (in milliseconds) which end frame in "start only" mode, if no second "start" bit is encountered after the first one
51
+
52
+ > "specifics" is a [ key: string => value: Tag ] object which fire a "key" event when a "value" tag is found out of the message and not escaped
53
+ > ex : { "specifics": { "nak": 0x25 } } will fire an "nak" event when 0x25 bit is encountered
54
+
55
+ ## Examples
56
+
57
+ In the following exemples, "Splitter" and "Readable" classes are defined like that :
58
+
59
+ ```typescript
60
+ // typescript
61
+ import Splitter = require("split-frames");
62
+ import { Readable } from "stream";
63
+ ```
64
+
65
+ ```javascript
66
+ // javascript
67
+ const Splitter = require("split-frames");
68
+ const { Readable } = require("stream");
69
+ ```
70
+
71
+ The "createReadStream" function is defined like that :
72
+
73
+ ```javascript
74
+ function createReadStream () {
75
+ return new Readable({
76
+ read () { }
77
+ });
78
+ }
79
+ ```
80
+
81
+ And the "STX", "DLE" and "ETX" constants are defined like that :
82
+
83
+ ```javascript
84
+ const STX = 0x02, ETX = 0x03, DLE = 0x10, ACK = 0x06, NAK = 0x15, WAK = 0x13;
85
+ ```
86
+
87
+ ### want to split frames content on a start bit ?
88
+
89
+ ```javascript
90
+ const stream = createReadStream();
91
+
92
+ stream.pipe(new Splitter({
93
+ "startWith": STX
94
+ })).on("data", (chunk) => {
95
+ // Buffer([ STX, 0x24, 0x25, 0x26 ])
96
+ // Buffer([ STX, 0x24, 0x25 ])
97
+ });
98
+
99
+ stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, STX, 0x24 ]));
100
+ stream.push(Buffer.from([ 0x25, STX ]));
101
+ ```
102
+
103
+ ### prefere an end bit ?
104
+
105
+ ```javascript
106
+ const stream = createReadStream();
107
+
108
+ stream.pipe(new Splitter({
109
+ "endWith": ETX
110
+ })).on("data", (chunk) => {
111
+ // Buffer([ 0x24, 0x25, 0x26, ETX ])
112
+ // Buffer([ 0x24, 0x25, ETX ])
113
+ });
114
+
115
+ stream.push(Buffer.from([ 0x24, 0x25, 0x26, ETX, 0x24, 0x25 ]));
116
+ stream.push(Buffer.from([ ETX ]));
117
+ ```
118
+
119
+ ### want both ?
120
+
121
+ ```javascript
122
+ const stream = createReadStream();
123
+
124
+ stream.pipe(new Splitter({
125
+ "startWith": STX, "endWith": ETX
126
+ })).on("data", (chunk) => {
127
+ // Buffer([ STX, 0x24, 0x25, 0x26, ETX ])
128
+ // Buffer([ STX, 0x24, 0x25, ETX ])
129
+ });
130
+
131
+ stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, ETX, 0x24, 0x25, STX ]));
132
+ stream.push(Buffer.from([ 0x24, 0x25, ETX ]));
133
+ ```
134
+
135
+ ### what about two end bits (works with start one as well) ?
136
+
137
+ ```javascript
138
+ const stream = createReadStream();
139
+
140
+ stream.pipe(new Splitter({
141
+ "startWith": STX, "endWith": Buffer.from([ DLE, ETX ])
142
+ })).on("data", (chunk) => {
143
+ // Buffer([ STX, 0x24, 0x25, 0x26, DLE, ETX ])
144
+ });
145
+
146
+ stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, DLE, ETX, STX, 0x24, 0x25 ]));
147
+ ```
148
+
149
+ ### Do you need to parse escaped bits ?
150
+
151
+ ```javascript
152
+ const stream = createReadStream();
153
+
154
+ stream.pipe(new Splitter({
155
+ "startWith": STX, "endWith": ETX,
156
+ "escapeWith": DLE, "escaped": [ DLE, STX, ETX ]
157
+ })).on("data", (chunk) => {
158
+ // Buffer([ STX, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
159
+ });
160
+
161
+ stream.push(Buffer.from([ 0x20, STX, 0x24, DLE, STX, 0x25, 0x26 ]));
162
+ stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, STX, 0x24, 0x25 ]));
163
+ ```
164
+
165
+ ### And what do you think about multiple start (or end !) bits possibilities ?
166
+
167
+ For even parity in seriaport, for example
168
+
169
+ ```javascript
170
+ const STX2 = 0x82;
171
+ const stream = createReadStream();
172
+
173
+ stream.pipe(new Splitter({
174
+ "startWith": [ STX, STX2 ], "endWith": ETX,
175
+ "escapeWith": DLE, "escaped": [ DLE, STX, ETX ]
176
+ })).on("data", (chunk) => {
177
+ // Buffer([ STX, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
178
+ // Buffer([ STX2, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
179
+ });
180
+
181
+ stream.push(Buffer.from([ 0x24, STX, 0x24, DLE, STX, 0x25, ACK ]));
182
+ stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, ACK, 0x24, 0x25 ]));
183
+ stream.push(Buffer.from([ STX2, 0x24, DLE, STX, 0x25, ACK ]));
184
+ stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, ACK, 0x24, 0x25 ]));
185
+ ```
186
+
187
+ ### Want to extract specific tags ?
188
+
189
+ > positive acknowledgement, negative acknowledgement, waiting for acknowledgement, whatever...
190
+ > only with no tags || start AND end tags || end tags (for firsts bits)
191
+
192
+ ```javascript
193
+ const stream = createReadStream();
194
+
195
+ stream.pipe(new Splitter({
196
+ "startWith": STX, "endWith": ETX,
197
+ "specifics": {
198
+ "ack": ACK, "nak": NAK, "wak": WAK, "whatever": 0x51
199
+ },
200
+ "escapeWith": DLE, "escaped": [ DLE, ACK, NAK, WAK ]
201
+ })).on("ack", () => {
202
+ console.log("ack received"); // (only 1x) -> good, escaped, in data
203
+ }).on("nak", () => {
204
+ console.log("nak received"); // (only 1x) -> in data, good, escaped
205
+ }).on("wak", () => {
206
+ console.log("wak received"); // (only 1x) -> in data, good, escaped
207
+ }).on("whatever", () => {
208
+ console.log("whatever received"); // (only 1x)
209
+ }).on("data", (chunk) => {
210
+ // Buffer([ STX, 0x20, 0x21, 0x22, ACK, NAK, WAK, 0x23, ETX ]) (x1)
211
+ });
212
+
213
+ stream.push(Buffer.from([ 0x51, 0x24, ACK, DLE, ACK, STX, 0x20, 0x21, 0x22, ACK, NAK, WAK ]));
214
+ stream.push(Buffer.from([ 0x23, ETX, NAK, DLE, NAK, WAK, DLE, WAK, 0x20, 0x21 ]));
215
+ ```
216
+
217
+ ### Want to use control bits ?
218
+
219
+ > used to compute LRC, MSB, LSB, etc...
220
+ > this example is for a structure like STX <data> ETX LRC, where LRC compute all <data> bits
221
+
222
+ ```javascript
223
+
224
+ function _computeLRC (frame) {
225
+
226
+ let lrc = 0x00;
227
+
228
+ for (let i = 0; i < frame.length; ++i) {
229
+ lrc ^= frame[i];
230
+ }
231
+
232
+ return lrc;
233
+
234
+ }
235
+
236
+ const stream = createReadStream();
237
+
238
+ stream.pipe(new Splitter({
239
+ "startWith": STX, "endWith": ETX,
240
+ "controlBits": "end+1"
241
+ })).on("data", (chunk) => {
242
+
243
+ // Buffer([ STX, 0x20, 0x21, 0x22, 0x24, ETX, 0x07 ]) (x1)
244
+
245
+ const data = chunk.slice(1, chunk.length - 2); // Buffer([ 0x20, 0x21, 0x22, 0x24 ])
246
+ const LRC = chunk[chunk.length - 1];
247
+
248
+ if (_computeLRC(data) === LRC) {
249
+ console.log("OK");
250
+ }
251
+ else {
252
+ console.error(new Error("not well-computed data :" + data.toString("hex") + "|" + Buffer.from([ LRC ]).toString("hex")));
253
+ }
254
+
255
+ });
256
+
257
+ stream.push(Buffer.from([ 0x51, 0x24, STX, 0x20, 0x21, 0x22, 0x24, ETX, 0x07, 0x24 ]));
258
+ ```
259
+
260
+ ## Tests
261
+
262
+ ```bash
263
+ $ npm run-script tests
264
+ ```
265
+
266
+ ## License
267
+
268
+ [ISC](LICENSE)