split-frames 2.4.5 → 2.5.1

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) 2024, 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,263 @@
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
+ [![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)
@@ -0,0 +1,52 @@
1
+ import { Transform } from "node:stream";
2
+ export type tTagObject = Record<string, tTag>;
3
+ export type tControlBits = "none" | "end+1" | "end+2";
4
+ export type tTag = number | Buffer | number[] | Buffer[];
5
+ export interface iSearchedBits {
6
+ "start": number;
7
+ "end": number;
8
+ }
9
+ export interface iOptions {
10
+ "startWith"?: tTag;
11
+ "startTimeout"?: number;
12
+ "endWith"?: tTag;
13
+ "escapeWith"?: tTag;
14
+ "escaped"?: number[];
15
+ "specifics"?: tTagObject;
16
+ "controlBits"?: tControlBits;
17
+ }
18
+ export interface iConf extends iOptions {
19
+ "escaped": number[];
20
+ "specifics": tTagObject;
21
+ "controlBits": tControlBits;
22
+ }
23
+ export default class SplitFrames extends Transform {
24
+ protected _frame: Buffer;
25
+ protected _digesting: boolean;
26
+ protected _timeoutDigest: NodeJS.Timeout | null;
27
+ protected _startWith: iConf["startWith"];
28
+ protected _startTimeout: iConf["startTimeout"];
29
+ protected _endWith: iConf["endWith"];
30
+ protected _escapeWith: iConf["escapeWith"];
31
+ protected _escaped: iConf["escaped"];
32
+ protected _specifics: iConf["specifics"];
33
+ protected _controlBits: iConf["controlBits"];
34
+ protected _digester: (enc?: BufferEncoding) => void;
35
+ constructor(options?: iOptions);
36
+ _transform(chunk: Buffer, enc: BufferEncoding, cb: (err?: Error | null, data?: any) => void): void;
37
+ protected _chooseDigester(): (enc?: BufferEncoding) => void;
38
+ protected _digest(enc?: BufferEncoding): void;
39
+ private _digestNoStartNoEnd;
40
+ private _digestStartOnly;
41
+ private _digestEndOnly;
42
+ private _extractSpecifics;
43
+ private _digestStartAndEnd;
44
+ private _searchFirstTag;
45
+ private _searchFirstNumberTag;
46
+ private _searchFirstBufferOrArrayTag;
47
+ private _searchFirstStart;
48
+ private _searchFirstEnd;
49
+ private _searchTags;
50
+ private _searchNumberTags;
51
+ private _searchBufferOrArrayTags;
52
+ }