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.
@@ -1,384 +1,400 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- // deps
7
- // natives
8
- const node_stream_1 = require("node:stream");
9
- // locals
10
- const initData_1 = __importDefault(require("./checkers/initData"));
11
- ;
12
- ;
13
- ;
14
- // module
15
- class SplitFrames extends node_stream_1.Transform {
16
- // constructor
17
- constructor(options) {
18
- super();
19
- this._frame = Buffer.from([]);
20
- this._digesting = false;
21
- this._timeoutDigest = null;
22
- // from params
23
- const validatedOptions = (0, initData_1.default)(options);
24
- this._startWith = validatedOptions.startWith;
25
- this._startTimeout = validatedOptions.startTimeout;
26
- this._endWith = validatedOptions.endWith;
27
- this._escapeWith = validatedOptions.escapeWith;
28
- this._escaped = validatedOptions.escaped;
29
- this._specifics = validatedOptions.specifics;
30
- this._controlBits = validatedOptions.controlBits;
31
- // dynamic digester
32
- this._digester = this._chooseDigester();
33
- }
34
- // methods
35
- // public
36
- _transform(chunk, enc, cb) {
37
- if (chunk.length) {
38
- this._frame = Buffer.concat([this._frame, chunk]);
39
- if (!this._digesting) {
40
- this._digest(enc);
41
- }
42
- }
43
- return cb();
44
- }
45
- // protected
46
- _chooseDigester() {
47
- let digester = undefined;
48
- if (undefined === this._startWith && undefined === this._endWith) {
49
- digester = this._digestNoStartNoEnd;
50
- }
51
- else if (undefined !== this._startWith && undefined === this._endWith) {
52
- digester = this._digestStartOnly;
53
- }
54
- else if (undefined === this._startWith && undefined !== this._endWith) {
55
- digester = this._digestEndOnly;
56
- }
57
- else {
58
- digester = this._digestStartAndEnd;
59
- }
60
- return digester;
61
- }
62
- _digest(enc) {
63
- if (!this._frame.length) {
64
- this._digesting = false;
65
- }
66
- else {
67
- this._digesting = true;
68
- try {
69
- this._digester(enc);
70
- }
71
- catch (e) {
72
- this.emit("error", e);
73
- }
74
- }
75
- }
76
- // private
77
- // digesters
78
- _digestNoStartNoEnd() {
79
- const KEYS = Object.keys(this._specifics);
80
- if (KEYS.length) {
81
- KEYS.forEach((key) => {
82
- const size = "object" === typeof this._specifics[key] && this._specifics[key] instanceof Buffer ? this._specifics[key].length : 1;
83
- for (let foundAt = this._searchTags(this._specifics[key]); -1 < foundAt; foundAt = this._searchTags(this._specifics[key])) {
84
- this.emit(key);
85
- this._frame = Buffer.from(Buffer.concat([
86
- this._frame.slice(0, foundAt),
87
- this._frame.slice(foundAt + size, this._frame.length)
88
- ]));
89
- }
90
- });
91
- }
92
- this.push(Buffer.from(this._frame));
93
- this._frame = Buffer.from([]);
94
- this._digesting = false;
95
- }
96
- _digestStartOnly(enc) {
97
- if (this._timeoutDigest) {
98
- clearTimeout(this._timeoutDigest);
99
- this._timeoutDigest = null;
100
- }
101
- const firstStart = this._searchFirstStart();
102
- // no start tag detected
103
- if (!firstStart) {
104
- this._frame = Buffer.from([]);
105
- this._digesting = false;
106
- }
107
- // first start tag detected
108
- else {
109
- const nextStartAt = this._searchTags(this._startWith, firstStart.end);
110
- // second start tag not detected
111
- if (-1 >= nextStartAt) {
112
- // remove useless bits
113
- this._frame = 0 < firstStart.start ? Buffer.from(this._frame.slice(firstStart.start, this._frame.length)) : this._frame;
114
- this._digesting = false;
115
- this._timeoutDigest = setTimeout(() => {
116
- clearTimeout(this._timeoutDigest);
117
- this._timeoutDigest = null;
118
- this.push(Buffer.from(this._frame.slice(firstStart.start, this._frame.length)));
119
- this._frame = Buffer.from([]);
120
- this._digesting = false;
121
- }, this._startTimeout);
122
- }
123
- // second start tag detected
124
- else {
125
- // extract first frame
126
- this.push(Buffer.from(this._frame.slice(firstStart.start, nextStartAt)));
127
- // remove extracted frame from main one
128
- this._frame = Buffer.from(this._frame.slice(nextStartAt, this._frame.length));
129
- // second full frame detected (force minimal data length)
130
- if (-1 < this._searchTags(this._startWith, 1)) {
131
- this._digest(enc);
132
- }
133
- else {
134
- this._digesting = false;
135
- }
136
- }
137
- }
138
- }
139
- _digestEndOnly(enc) {
140
- this._extractSpecifics();
141
- const firstEnd = this._searchFirstEnd();
142
- // no end tag detected
143
- if (!firstEnd) {
144
- this._digesting = false;
145
- }
146
- // first end tag detected
147
- else {
148
- // extract first frame
149
- this.push(Buffer.from(this._frame.slice(0, firstEnd.end)));
150
- // remove extracted frame from main one
151
- this._frame = Buffer.from(this._frame.slice(firstEnd.end, this._frame.length));
152
- // second full frame detected
153
- if (-1 < this._searchTags(this._endWith)) {
154
- this._digest(enc);
155
- }
156
- else {
157
- this._digesting = false;
158
- }
159
- }
160
- }
161
- _extractSpecifics() {
162
- let found = false;
163
- Object.keys(this._specifics).forEach((key) => {
164
- if (0 === this._frame.indexOf(this._specifics[key])) {
165
- found = true;
166
- const size = "object" === typeof this._specifics[key] && this._specifics[key] instanceof Buffer ?
167
- this._specifics[key].length : 1;
168
- this.emit(key);
169
- this._frame = Buffer.from(this._frame.slice(size, this._frame.length));
170
- }
171
- });
172
- if (found) {
173
- this._extractSpecifics();
174
- }
175
- }
176
- _digestStartAndEnd(enc) {
177
- const KEYS = Object.keys(this._specifics);
178
- if (KEYS.length) {
179
- KEYS.forEach((key) => {
180
- const firstStart = this._searchFirstStart();
181
- const size = "object" === typeof this._specifics[key] && this._specifics[key] instanceof Buffer ? this._specifics[key].length : 1;
182
- for (let foundAt = this._searchTags(this._specifics[key]), i = 0; -1 < foundAt && (!firstStart || foundAt < firstStart.start - i); foundAt = this._searchTags(this._specifics[key]), i += size) {
183
- this.emit(key);
184
- this._frame = Buffer.from(Buffer.concat([
185
- this._frame.slice(0, foundAt),
186
- this._frame.slice(foundAt + size, this._frame.length)
187
- ]));
188
- }
189
- });
190
- }
191
- const firstStart = this._searchFirstStart();
192
- // no start tag detected
193
- if (!firstStart) {
194
- this._frame = Buffer.from([]);
195
- this._digesting = false;
196
- }
197
- // start tag detected
198
- else {
199
- const firstEnd = this._searchFirstEnd();
200
- // end tag not detected
201
- if (!firstEnd) {
202
- // remove useless bits
203
- this._frame = 0 < firstStart.start ? Buffer.from(this._frame.slice(firstStart.start, this._frame.length)) : this._frame;
204
- this._digesting = false;
205
- }
206
- // end tag detected
207
- else {
208
- this.push(Buffer.from(this._frame.slice(firstStart.start, firstEnd.end)));
209
- // remove extracted frame from main one
210
- this._frame = Buffer.from(this._frame.slice(firstEnd.end, this._frame.length));
211
- // search specifics
212
- let foundSpecific = false;
213
- for (let i = 0; i < KEYS.length && !foundSpecific; ++i) {
214
- if (-1 < this._searchTags(this._specifics[KEYS[i]])) {
215
- foundSpecific = true;
216
- break;
217
- }
218
- }
219
- // specific detected or second start detected (force minimal data length)
220
- if (foundSpecific || -1 < this._searchTags(this._startWith, 1)) {
221
- this._digest(enc);
222
- }
223
- else {
224
- this._digesting = false;
225
- }
226
- }
227
- }
228
- }
229
- // search tag
230
- _searchFirstTag(tag, beginAt = 0) {
231
- let startAt = -1;
232
- let endAt = -1;
233
- // number
234
- if ("number" === typeof tag) {
235
- const find = this._searchFirstNumberTag(tag, beginAt);
236
- startAt = find.start;
237
- endAt = find.end;
238
- }
239
- // Buffer | Array
240
- else if ("object" === typeof tag) {
241
- const find = this._searchFirstBufferOrArrayTag(tag, beginAt);
242
- startAt = find.start;
243
- endAt = find.end;
244
- }
245
- // not found
246
- if (-1 >= startAt || -1 >= endAt) {
247
- return undefined;
248
- }
249
- // escaped
250
- else if (0 < startAt &&
251
- // must be a number to be escaped
252
- 1 === endAt - startAt &&
253
- this._escaped.includes(this._frame[startAt]) && this._frame[startAt - 1] === this._escapeWith) {
254
- // escaper not escaped
255
- if (!this._escaped.includes(this._escapeWith) || 1 >= startAt || this._frame[startAt - 2] !== this._escapeWith) {
256
- return this._searchFirstTag(tag, endAt + 1);
257
- }
258
- else {
259
- return {
260
- "start": startAt,
261
- "end": endAt
262
- };
263
- }
264
- }
265
- // not escaped
266
- else {
267
- return {
268
- "start": startAt,
269
- "end": endAt
270
- };
271
- }
272
- }
273
- _searchFirstNumberTag(tag, beginAt) {
274
- const startAt = this._frame.indexOf(tag, beginAt);
275
- return {
276
- "start": startAt,
277
- "end": startAt + 1
278
- };
279
- }
280
- _searchFirstBufferOrArrayTag(tag, beginAt) {
281
- let startAt = -1;
282
- let endAt = -1;
283
- // Buffer
284
- if (tag instanceof Buffer) {
285
- startAt = this._frame.indexOf(tag, beginAt);
286
- endAt = startAt + tag.length;
287
- }
288
- // Array
289
- else if (tag instanceof Array) {
290
- for (let i = 0; i < tag.length; ++i) {
291
- // number | Buffer
292
- if ("number" === typeof tag[i] ||
293
- ("object" === typeof tag[i] && tag[i] instanceof Buffer)) {
294
- const _startAt = this._frame.indexOf(tag[i], beginAt);
295
- if (-1 < _startAt && (-1 >= startAt || _startAt < startAt)) {
296
- startAt = _startAt;
297
- endAt = startAt + ("number" === typeof tag[i] ? 1 : tag[i].length);
298
- }
299
- }
300
- }
301
- }
302
- return {
303
- "start": startAt,
304
- "end": endAt
305
- };
306
- }
307
- _searchFirstStart() {
308
- return this._searchFirstTag(this._startWith);
309
- }
310
- _searchFirstEnd() {
311
- const firstTag = this._searchFirstTag(this._endWith);
312
- if (firstTag) {
313
- if ("end+1" === this._controlBits) {
314
- firstTag.end += 1;
315
- }
316
- else if ("end+2" === this._controlBits) {
317
- firstTag.end += 2;
318
- }
319
- // end tag detected but without valid control bits length
320
- if (firstTag.end > this._frame.length) {
321
- return undefined;
322
- }
323
- }
324
- return firstTag;
325
- }
326
- _searchTags(tags, beginAt = 0) {
327
- // number
328
- if ("number" === typeof tags) {
329
- return this._searchNumberTags(tags, beginAt);
330
- }
331
- // Buffer | Array
332
- else if ("object" === typeof tags) {
333
- return this._searchBufferOrArrayTags(tags, beginAt);
334
- }
335
- return -1;
336
- }
337
- _searchNumberTags(tags, beginAt) {
338
- const foundAt = this._frame.indexOf(tags, beginAt);
339
- // escaped
340
- if (0 < foundAt &&
341
- this._escaped.includes(this._frame[foundAt]) &&
342
- this._frame[foundAt - 1] === this._escapeWith) {
343
- // escaper not escaped
344
- if (!this._escaped.includes(this._escapeWith) || 1 >= foundAt || this._frame[foundAt - 2] !== this._escapeWith) {
345
- return this._searchTags(tags, foundAt + 1);
346
- }
347
- }
348
- return foundAt;
349
- }
350
- _searchBufferOrArrayTags(tags, beginAt) {
351
- // Buffer
352
- if (tags instanceof Buffer) {
353
- return this._frame.indexOf(tags, beginAt);
354
- }
355
- // Array
356
- else if (tags instanceof Array) {
357
- let foundAt = -1;
358
- let type = "undefined";
359
- for (let i = 0; i < tags.length; ++i) {
360
- // number | Buffer
361
- if ("number" === typeof tags[i] || ("object" === typeof tags[i] && tags[i] instanceof Buffer)) {
362
- const _foundAt = this._frame.indexOf(tags[i], beginAt);
363
- if (-1 < _foundAt && (-1 >= foundAt || _foundAt < foundAt)) {
364
- foundAt = _foundAt;
365
- type = typeof tags[i];
366
- }
367
- }
368
- }
369
- // escaped
370
- if ("number" === type && 0 < foundAt &&
371
- this._escaped.includes(this._frame[foundAt]) &&
372
- this._frame[foundAt - 1] === this._escapeWith) {
373
- // escaper not escaped
374
- if (!this._escaped.includes(this._escapeWith) || 1 >= foundAt || this._frame[foundAt - 2] !== this._escapeWith) {
375
- foundAt = this._searchTags(tags, foundAt + 1);
376
- }
377
- }
378
- return foundAt;
379
- }
380
- return -1;
381
- }
382
- }
383
- exports.default = SplitFrames;
384
- ;
1
+ "use strict";
2
+ /*
3
+ eslint-disable no-unmodified-loop-condition
4
+ */
5
+ // => no-unmodified-loop-condition is disabled to allow data generation in a loop (_digestStartAndEnd)
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ // deps
11
+ // natives
12
+ const node_stream_1 = require("node:stream");
13
+ // locals
14
+ const initData_1 = __importDefault(require("./checkers/initData"));
15
+ // module
16
+ class SplitFrames extends node_stream_1.Transform {
17
+ // attributes
18
+ // protected
19
+ _frame;
20
+ _digesting;
21
+ _timeoutDigest;
22
+ // from params
23
+ _startWith;
24
+ _startTimeout;
25
+ _endWith;
26
+ _escapeWith;
27
+ _escaped;
28
+ _specifics;
29
+ _controlBits;
30
+ // dynamic digester
31
+ _digester;
32
+ // constructor
33
+ constructor(options) {
34
+ super();
35
+ this._frame = Buffer.from([]);
36
+ this._digesting = false;
37
+ this._timeoutDigest = null;
38
+ // from params
39
+ const validatedOptions = (0, initData_1.default)(options);
40
+ this._startWith = validatedOptions.startWith;
41
+ this._startTimeout = validatedOptions.startTimeout;
42
+ this._endWith = validatedOptions.endWith;
43
+ this._escapeWith = validatedOptions.escapeWith;
44
+ this._escaped = validatedOptions.escaped;
45
+ this._specifics = validatedOptions.specifics;
46
+ this._controlBits = validatedOptions.controlBits;
47
+ // dynamic digester
48
+ this._digester = this._chooseDigester();
49
+ }
50
+ // methods
51
+ // public
52
+ _transform(chunk, enc, cb) {
53
+ if (chunk.length) {
54
+ this._frame = Buffer.concat([this._frame, chunk]);
55
+ if (!this._digesting) {
56
+ this._digest(enc);
57
+ }
58
+ }
59
+ return cb();
60
+ }
61
+ // protected
62
+ _chooseDigester() {
63
+ if (undefined === this._startWith && undefined === this._endWith) {
64
+ return this._digestNoStartNoEnd.bind(this);
65
+ }
66
+ else if (undefined !== this._startWith && undefined === this._endWith) {
67
+ return this._digestStartOnly.bind(this);
68
+ }
69
+ else if (undefined === this._startWith && undefined !== this._endWith) {
70
+ return this._digestEndOnly.bind(this);
71
+ }
72
+ return this._digestStartAndEnd.bind(this);
73
+ }
74
+ _digest(enc) {
75
+ if (!this._frame.length) {
76
+ this._digesting = false;
77
+ }
78
+ else {
79
+ this._digesting = true;
80
+ try {
81
+ this._digester(enc);
82
+ }
83
+ catch (e) {
84
+ this.emit("error", e);
85
+ }
86
+ }
87
+ }
88
+ // private
89
+ // digesters
90
+ _digestNoStartNoEnd() {
91
+ const KEYS = Object.keys(this._specifics);
92
+ if (KEYS.length) {
93
+ KEYS.forEach((key) => {
94
+ const size = "object" === typeof this._specifics[key] && this._specifics[key] instanceof Buffer ? this._specifics[key].length : 1;
95
+ for (let foundAt = this._searchTags(this._specifics[key]); -1 < foundAt; foundAt = this._searchTags(this._specifics[key])) {
96
+ this.emit(key);
97
+ this._frame = Buffer.from(Buffer.concat([
98
+ this._frame.slice(0, foundAt),
99
+ this._frame.slice(foundAt + size, this._frame.length)
100
+ ]));
101
+ }
102
+ });
103
+ }
104
+ this.push(Buffer.from(this._frame));
105
+ this._frame = Buffer.from([]);
106
+ this._digesting = false;
107
+ }
108
+ _digestStartOnly(enc) {
109
+ if (this._timeoutDigest) {
110
+ clearTimeout(this._timeoutDigest);
111
+ this._timeoutDigest = null;
112
+ }
113
+ const firstStart = this._searchFirstStart();
114
+ // no start tag detected
115
+ if (!firstStart) {
116
+ this._digesting = false;
117
+ }
118
+ // first start tag detected
119
+ else {
120
+ const nextStartAt = this._searchTags(this._startWith, firstStart.end);
121
+ // second start tag not detected
122
+ if (-1 >= nextStartAt) {
123
+ // remove useless bits
124
+ this._frame = 0 < firstStart.start ? Buffer.from(this._frame.slice(firstStart.start, this._frame.length)) : this._frame;
125
+ this._digesting = false;
126
+ this._timeoutDigest = setTimeout(() => {
127
+ clearTimeout(this._timeoutDigest);
128
+ this._timeoutDigest = null;
129
+ this.push(Buffer.from(this._frame.slice(firstStart.start, this._frame.length)));
130
+ this._frame = Buffer.from([]);
131
+ this._digesting = false;
132
+ }, this._startTimeout);
133
+ }
134
+ // second start tag detected
135
+ else {
136
+ // extract first frame
137
+ this.push(Buffer.from(this._frame.slice(firstStart.start, nextStartAt)));
138
+ // remove extracted frame from main one
139
+ this._frame = Buffer.from(this._frame.slice(nextStartAt, this._frame.length));
140
+ // second full frame detected (force minimal data length)
141
+ if (-1 < this._searchTags(this._startWith, 1)) {
142
+ this._digest(enc);
143
+ }
144
+ else {
145
+ this._digesting = false;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ _digestEndOnly(enc) {
151
+ this._extractSpecifics();
152
+ const firstEnd = this._searchFirstEnd(0);
153
+ // no end tag detected
154
+ if (!firstEnd) {
155
+ this._digesting = false;
156
+ }
157
+ // first end tag detected
158
+ else {
159
+ // extract first frame
160
+ this.push(Buffer.from(this._frame.slice(0, firstEnd.end)));
161
+ // remove extracted frame from main one
162
+ this._frame = Buffer.from(this._frame.slice(firstEnd.end, this._frame.length));
163
+ // second full frame detected
164
+ if (-1 < this._searchTags(this._endWith)) {
165
+ this._digest(enc);
166
+ }
167
+ else {
168
+ this._digesting = false;
169
+ }
170
+ }
171
+ }
172
+ _extractSpecifics() {
173
+ let found = false;
174
+ Object.keys(this._specifics).forEach((key) => {
175
+ if (0 === this._frame.indexOf(this._specifics[key])) {
176
+ found = true;
177
+ const size = "object" === typeof this._specifics[key] && this._specifics[key] instanceof Buffer
178
+ ? this._specifics[key].length
179
+ : 1;
180
+ this.emit(key);
181
+ this._frame = Buffer.from(this._frame.slice(size, this._frame.length));
182
+ }
183
+ });
184
+ // disabled due to malfunction
185
+ if (found) { // eslint-disable-line @typescript-eslint/no-unnecessary-condition
186
+ this._extractSpecifics();
187
+ }
188
+ }
189
+ _digestStartAndEnd(enc) {
190
+ const KEYS = Object.keys(this._specifics);
191
+ if (KEYS.length) {
192
+ KEYS.forEach((key) => {
193
+ const firstStart = this._searchFirstStart();
194
+ const size = "object" === typeof this._specifics[key] && this._specifics[key] instanceof Buffer ? this._specifics[key].length : 1;
195
+ for (let foundAt = this._searchTags(this._specifics[key]), i = 0; -1 < foundAt && (!firstStart || foundAt < firstStart.start - i); foundAt = this._searchTags(this._specifics[key]), i += size) {
196
+ this.emit(key);
197
+ this._frame = Buffer.from(Buffer.concat([
198
+ this._frame.slice(0, foundAt),
199
+ this._frame.slice(foundAt + size, this._frame.length)
200
+ ]));
201
+ }
202
+ });
203
+ }
204
+ const firstStart = this._searchFirstStart();
205
+ // no start tag detected
206
+ if (!firstStart) {
207
+ this._digesting = false;
208
+ }
209
+ // start tag detected
210
+ else {
211
+ const firstEnd = this._searchFirstEnd(firstStart.end);
212
+ // end tag not detected
213
+ if (!firstEnd) {
214
+ // remove useless bits
215
+ this._frame = 0 < firstStart.start ? Buffer.from(this._frame.slice(firstStart.start, this._frame.length)) : this._frame;
216
+ this._digesting = false;
217
+ }
218
+ // end tag detected
219
+ else {
220
+ this.push(Buffer.from(this._frame.slice(firstStart.start, firstEnd.end)));
221
+ // remove extracted frame from main one
222
+ this._frame = Buffer.from(this._frame.slice(firstEnd.end, this._frame.length));
223
+ // search specifics
224
+ let foundSpecific = false;
225
+ for (let i = 0; i < KEYS.length; ++i) {
226
+ if (-1 < this._searchTags(this._specifics[KEYS[i]])) {
227
+ foundSpecific = true;
228
+ break;
229
+ }
230
+ }
231
+ // specific detected or second start detected (force minimal data length)
232
+ if (foundSpecific || -1 < this._searchTags(this._startWith, 1)) {
233
+ this._digest(enc);
234
+ }
235
+ else {
236
+ this._digesting = false;
237
+ }
238
+ }
239
+ }
240
+ }
241
+ // search tag
242
+ _searchFirstTag(tag, beginAt = 0) {
243
+ let startAt = -1;
244
+ let endAt = -1;
245
+ // number
246
+ if ("number" === typeof tag) {
247
+ const find = this._searchFirstNumberTag(tag, beginAt);
248
+ startAt = find.start;
249
+ endAt = find.end;
250
+ }
251
+ // Buffer | Array
252
+ else if ("object" === typeof tag) {
253
+ const find = this._searchFirstBufferOrArrayTag(tag, beginAt);
254
+ startAt = find.start;
255
+ endAt = find.end;
256
+ }
257
+ // not found
258
+ if (-1 >= startAt || -1 >= endAt) {
259
+ return undefined;
260
+ }
261
+ // escaped
262
+ else if (0 < startAt
263
+ && 1 === endAt - startAt // must be a number to be escaped
264
+ && this._escaped.includes(this._frame[startAt])
265
+ && this._frame[startAt - 1] === this._escapeWith) {
266
+ // escaper not escaped
267
+ if (!this._escaped.includes(this._escapeWith) || 1 >= startAt || this._frame[startAt - 2] !== this._escapeWith) {
268
+ return this._searchFirstTag(tag, endAt + 1);
269
+ }
270
+ else {
271
+ return {
272
+ "start": startAt,
273
+ "end": endAt
274
+ };
275
+ }
276
+ }
277
+ // not escaped
278
+ else {
279
+ return {
280
+ "start": startAt,
281
+ "end": endAt
282
+ };
283
+ }
284
+ }
285
+ _searchFirstNumberTag(tag, beginAt) {
286
+ const startAt = this._frame.indexOf(tag, beginAt);
287
+ return {
288
+ "start": startAt,
289
+ "end": startAt + 1
290
+ };
291
+ }
292
+ _searchFirstBufferOrArrayTag(tag, beginAt) {
293
+ let startAt = -1;
294
+ let endAt = -1;
295
+ // Buffer
296
+ if (tag instanceof Buffer) {
297
+ startAt = this._frame.indexOf(tag, beginAt);
298
+ if (-1 < startAt) {
299
+ endAt = startAt + tag.length;
300
+ }
301
+ }
302
+ // Array
303
+ else if (tag instanceof Array) {
304
+ for (let i = 0; i < tag.length; ++i) {
305
+ // number | Buffer
306
+ if ("number" === typeof tag[i]
307
+ || ("object" === typeof tag[i] && tag[i] instanceof Buffer)) {
308
+ const _startAt = this._frame.indexOf(tag[i], beginAt);
309
+ if (-1 < _startAt && (-1 >= startAt || _startAt < startAt)) {
310
+ startAt = _startAt;
311
+ if (-1 < startAt) {
312
+ endAt = startAt + ("number" === typeof tag[i] ? 1 : tag[i].length);
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ return {
319
+ "start": startAt,
320
+ "end": endAt
321
+ };
322
+ }
323
+ _searchFirstStart() {
324
+ return this._searchFirstTag(this._startWith);
325
+ }
326
+ _searchFirstEnd(startEndAt) {
327
+ const firstTag = this._searchFirstTag(this._endWith, startEndAt);
328
+ if (firstTag) {
329
+ if ("end+1" === this._controlBits) {
330
+ firstTag.end += 1;
331
+ }
332
+ else if ("end+2" === this._controlBits) {
333
+ firstTag.end += 2;
334
+ }
335
+ // end tag detected but without valid control bits length
336
+ if (firstTag.end > this._frame.length) {
337
+ return undefined;
338
+ }
339
+ }
340
+ return firstTag;
341
+ }
342
+ _searchTags(tags, beginAt = 0) {
343
+ // number
344
+ if ("number" === typeof tags) {
345
+ return this._searchNumberTags(tags, beginAt);
346
+ }
347
+ // Buffer | Array
348
+ else if ("object" === typeof tags) {
349
+ return this._searchBufferOrArrayTags(tags, beginAt);
350
+ }
351
+ return -1;
352
+ }
353
+ _searchNumberTags(tags, beginAt) {
354
+ const foundAt = this._frame.indexOf(tags, beginAt);
355
+ // escaped
356
+ if (0 < foundAt
357
+ && this._escaped.includes(this._frame[foundAt])
358
+ && this._frame[foundAt - 1] === this._escapeWith) {
359
+ // escaper not escaped
360
+ if (!this._escaped.includes(this._escapeWith) || 1 >= foundAt || this._frame[foundAt - 2] !== this._escapeWith) {
361
+ return this._searchTags(tags, foundAt + 1);
362
+ }
363
+ }
364
+ return foundAt;
365
+ }
366
+ _searchBufferOrArrayTags(tags, beginAt) {
367
+ // Buffer
368
+ if (tags instanceof Buffer) {
369
+ return this._frame.indexOf(tags, beginAt);
370
+ }
371
+ // Array
372
+ else if (tags instanceof Array) {
373
+ let foundAt = -1;
374
+ let type = "undefined";
375
+ for (let i = 0; i < tags.length; ++i) {
376
+ // number | Buffer
377
+ if ("number" === typeof tags[i]
378
+ || ("object" === typeof tags[i] && tags[i] instanceof Buffer)) {
379
+ const _foundAt = this._frame.indexOf(tags[i], beginAt);
380
+ if (-1 < _foundAt && (-1 >= foundAt || _foundAt < foundAt)) {
381
+ foundAt = _foundAt;
382
+ type = typeof tags[i];
383
+ }
384
+ }
385
+ }
386
+ // escaped
387
+ if ("number" === type && 0 < foundAt
388
+ && this._escaped.includes(this._frame[foundAt])
389
+ && this._frame[foundAt - 1] === this._escapeWith) {
390
+ // escaper not escaped
391
+ if (!this._escaped.includes(this._escapeWith) || 1 >= foundAt || this._frame[foundAt - 2] !== this._escapeWith) {
392
+ foundAt = this._searchTags(tags, foundAt + 1);
393
+ }
394
+ }
395
+ return foundAt;
396
+ }
397
+ return -1;
398
+ }
399
+ }
400
+ exports.default = SplitFrames;