• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nats-io / nats.js / 13973261499

20 Mar 2025 03:34PM UTC coverage: 72.567% (+15.2%) from 57.38%
13973261499

push

github

web-flow
fix(test): fixed a test setup issue now that the server reports the correct value (#235)

Signed-off-by: Alberto Ricart <alberto@synadia.com>

1573 of 2383 branches covered (66.01%)

Branch coverage included in aggregate %.

8574 of 11600 relevant lines covered (73.91%)

224006.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.77
/core/src/parser.ts
1
// deno-lint-ignore-file no-undef
2
/*
3
 * Copyright 2020-2021 The NATS Authors
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
import { DenoBuffer } from "./denobuffer.ts";
55✔
17
import { TD } from "./encoders.ts";
55✔
18
import type { Dispatcher } from "./core.ts";
19

20
export const Kind = {
55✔
21
  OK: 0,
55✔
22
  ERR: 1,
55✔
23
  MSG: 2,
55✔
24
  INFO: 3,
55✔
25
  PING: 4,
55✔
26
  PONG: 5,
55✔
27
} as const;
55✔
28

29
export type Kind = typeof Kind[keyof typeof Kind];
30

31
export interface ParserEvent {
32
  kind: Kind;
33
  msg?: MsgArg;
34
  data?: Uint8Array;
35
}
36

37
export function describe(e: ParserEvent): string {
×
38
  let ks: string;
×
39
  let data = "";
×
40

41
  switch (e.kind) {
×
42
    case Kind.MSG:
×
43
      ks = "MSG";
×
44
      break;
×
45
    case Kind.OK:
×
46
      ks = "OK";
×
47
      break;
×
48
    case Kind.ERR:
×
49
      ks = "ERR";
×
50
      data = TD.decode(e.data);
×
51
      break;
×
52
    case Kind.PING:
×
53
      ks = "PING";
×
54
      break;
×
55
    case Kind.PONG:
×
56
      ks = "PONG";
×
57
      break;
×
58
    case Kind.INFO:
×
59
      ks = "INFO";
×
60
      data = TD.decode(e.data);
×
61
  }
×
62
  return `${ks}: ${data}`;
×
63
}
×
64

65
export interface MsgArg {
66
  subject: Uint8Array;
67
  reply?: Uint8Array;
68
  sid: number;
69
  hdr: number;
70
  size: number;
71
}
72

73
function newMsgArg(): MsgArg {
396,851✔
74
  const ma = {} as MsgArg;
396,851✔
75
  ma.sid = -1;
396,851✔
76
  ma.hdr = -1;
396,851✔
77
  ma.size = -1;
396,851✔
78

79
  return ma;
396,851✔
80
}
396,851✔
81

82
const ASCII_0 = 48;
55✔
83
const ASCII_9 = 57;
55✔
84

85
// This is an almost verbatim port of the Go NATS parser
86
// https://github.com/nats-io/nats.go/blob/master/parser.go
87
export class Parser {
55✔
88
  dispatcher: Dispatcher<ParserEvent>;
54✔
89
  state: State;
1,620✔
90
  as: number;
1,620✔
91
  drop: number;
1,620✔
92
  hdr: number;
1,620✔
93
  ma!: MsgArg;
1,620✔
94
  argBuf?: DenoBuffer;
1,620✔
95
  msgBuf?: DenoBuffer;
54✔
96

97
  constructor(dispatcher: Dispatcher<ParserEvent>) {
54✔
98
    this.dispatcher = dispatcher;
1,620✔
99
    this.state = State.OP_START;
1,620✔
100
    this.as = 0;
1,620✔
101
    this.drop = 0;
1,620✔
102
    this.hdr = 0;
1,620✔
103
  }
1,620✔
104

105
  parse(buf: Uint8Array): void {
54✔
106
    let i: number;
9,109✔
107
    for (i = 0; i < buf.length; i++) {
9,109✔
108
      const b = buf[i];
20,632,299✔
109
      switch (this.state) {
20,632,299✔
110
        case State.OP_START:
20,632,299✔
111
          switch (b) {
21,031,013✔
112
            case cc.M:
21,031,013✔
113
            case cc.m:
21,031,013✔
114
              this.state = State.OP_M;
21,426,863✔
115
              this.hdr = -1;
21,426,863✔
116
              this.ma = newMsgArg();
21,426,863✔
117
              break;
21,426,863✔
118
            case cc.H:
21,031,013✔
119
            case cc.h:
21,031,013✔
120
              this.state = State.OP_H;
21,031,960✔
121
              this.hdr = 0;
21,031,960✔
122
              this.ma = newMsgArg();
21,031,960✔
123
              break;
21,031,960✔
124
            case cc.P:
21,031,013✔
125
            case cc.p:
21,031,013✔
126
              this.state = State.OP_P;
21,032,087✔
127
              break;
21,032,087✔
128
            case cc.PLUS:
12,184,180✔
129
              this.state = State.OP_PLUS;
12,184,188✔
130
              break;
12,184,188✔
131
            case cc.MINUS:
12,204,125✔
132
              this.state = State.OP_MINUS;
12,204,193✔
133
              break;
12,204,193✔
134
            case cc.I:
21,031,013✔
135
            case cc.i:
21,031,013✔
136
              this.state = State.OP_I;
21,031,776✔
137
              break;
21,031,776✔
138
            default:
12,184,180✔
139
              throw this.fail(buf.subarray(i));
12,184,184✔
140
          }
21,031,013✔
141
          break;
21,299,927✔
142
        case State.OP_H:
20,632,299✔
143
          switch (b) {
20,633,246✔
144
            case cc.M:
20,633,246✔
145
            case cc.m:
20,633,246✔
146
              this.state = State.OP_M;
20,633,246✔
147
              break;
20,633,246✔
148
            default:
×
149
              throw this.fail(buf.subarray(i));
×
150
          }
20,633,246✔
151
          break;
20,633,246✔
152
        case State.OP_M:
20,632,299✔
153
          switch (b) {
21,029,096✔
154
            case cc.S:
21,029,096✔
155
            case cc.s:
21,029,096✔
156
              this.state = State.OP_MS;
21,297,076✔
157
              break;
21,297,076✔
158
            default:
12,183,244!
159
              throw this.fail(buf.subarray(i));
12,183,246✔
160
          }
21,029,096✔
161
          break;
21,297,076✔
162
        case State.OP_MS:
20,632,299✔
163
          switch (b) {
21,029,094✔
164
            case cc.G:
21,029,094✔
165
            case cc.g:
21,029,094✔
166
              this.state = State.OP_MSG;
21,297,072✔
167
              break;
21,297,072✔
168
            default:
12,183,242!
169
              throw this.fail(buf.subarray(i));
12,183,244✔
170
          }
21,029,094✔
171
          break;
21,297,072✔
172
        case State.OP_MSG:
20,632,299✔
173
          switch (b) {
21,029,092✔
174
            case cc.SPACE:
21,029,092✔
175
            case cc.TAB:
21,029,092✔
176
              this.state = State.OP_MSG_SPC;
21,297,068✔
177
              break;
21,297,068✔
178
            default:
12,183,240!
179
              throw this.fail(buf.subarray(i));
12,183,242✔
180
          }
21,029,092✔
181
          break;
21,297,068✔
182
        case State.OP_MSG_SPC:
20,632,299✔
183
          switch (b) {
21,029,090✔
184
            case cc.SPACE:
×
185
            case cc.TAB:
×
186
              continue;
×
187
            default:
21,029,090✔
188
              this.state = State.MSG_ARG;
21,029,090✔
189
              this.as = i;
21,029,090✔
190
          }
21,029,090✔
191
          break;
21,029,090✔
192
        case State.MSG_ARG:
20,632,299✔
193
          switch (b) {
38,160,837✔
194
            case cc.CR:
38,160,837✔
195
              this.drop = 1;
38,557,626✔
196
              break;
38,557,626✔
197
            case cc.NL: {
76,718,465✔
198
              const arg: Uint8Array = this.argBuf
23,745,126✔
199
                ? this.argBuf.bytes()
23,745,126✔
200
                : buf.subarray(this.as, i - this.drop);
23,745,126✔
201
              this.processMsgArgs(arg);
38,557,628✔
202
              this.drop = 0;
38,557,628✔
203
              this.as = i + 1;
38,557,628✔
204
              this.state = State.MSG_PAYLOAD;
38,557,628✔
205

206
              // jump ahead with the index. If this overruns
207
              // what is left we fall out and process a split buffer.
208
              i = this.as + this.ma.size - 1;
38,557,628✔
209
              break;
38,557,628✔
210
            }
38,557,628✔
211
            default:
38,160,837✔
212
              if (this.argBuf) {
33,572,352!
213
                this.argBuf.writeByte(b);
33,572,728✔
214
              }
33,572,728✔
215
          }
38,160,837✔
216
          break;
48,060,914✔
217
        case State.MSG_PAYLOAD:
20,632,299✔
218
          if (this.msgBuf) {
20,904,419✔
219
            if (this.msgBuf.length >= this.ma.size) {
20,907,271✔
220
              const data = this.msgBuf.bytes({ copy: false });
62,730,657✔
221
              this.dispatcher.push(
20,910,219✔
222
                { kind: Kind.MSG, msg: this.ma, data: data },
104,551,095✔
223
              );
224
              this.argBuf = undefined;
20,910,219✔
225
              this.msgBuf = undefined;
20,910,219✔
226
              this.state = State.MSG_END;
20,910,219✔
227
            } else {
20,909,054✔
228
              let toCopy = this.ma.size - this.msgBuf.length;
20,910,741✔
229
              const avail = buf.length - i;
20,910,741✔
230

231
              if (avail < toCopy) {
20,910,741✔
232
                toCopy = avail;
20,911,261✔
233
              }
20,911,261✔
234

235
              if (toCopy > 0) {
20,910,741✔
236
                this.msgBuf.write(buf.subarray(i, i + toCopy));
20,910,741✔
237
                i = (i + toCopy) - 1;
20,910,741✔
238
              } else {
×
239
                this.msgBuf.writeByte(b);
×
240
              }
×
241
            }
20,910,741✔
242
          } else if (i - this.as >= this.ma.size) {
20,904,419✔
243
            this.dispatcher.push(
21,425,277✔
244
              { kind: Kind.MSG, msg: this.ma, data: buf.subarray(this.as, i) },
107,126,385✔
245
            );
246
            this.argBuf = undefined;
21,425,277✔
247
            this.msgBuf = undefined;
21,425,277✔
248
            this.state = State.MSG_END;
21,425,277✔
249
          }
21,425,277✔
250
          break;
21,030,758✔
251
        case State.MSG_END:
20,632,299✔
252
          switch (b) {
21,029,071✔
253
            case cc.NL:
21,029,071✔
254
              this.drop = 0;
21,029,071✔
255
              this.as = i + 1;
21,029,071✔
256
              this.state = State.OP_START;
21,029,071✔
257
              break;
21,029,071✔
258
            default:
×
259
              continue;
×
260
          }
21,029,071✔
261
          break;
21,029,071✔
262
        case State.OP_PLUS:
11,915,262!
263
          switch (b) {
11,915,270✔
264
            case cc.O:
11,915,270✔
265
            case cc.o:
11,915,270✔
266
              this.state = State.OP_PLUS_O;
11,915,274✔
267
              break;
11,915,274✔
268
            default:
11,915,270✔
269
              throw this.fail(buf.subarray(i));
11,915,274✔
270
          }
11,915,270✔
271
          break;
11,915,274✔
272
        case State.OP_PLUS_O:
11,915,262!
273
          switch (b) {
11,915,266✔
274
            case cc.K:
11,915,266✔
275
            case cc.k:
11,915,266✔
276
              this.state = State.OP_PLUS_OK;
11,915,266✔
277
              break;
11,915,266✔
278
            default:
×
279
              throw this.fail(buf.subarray(i));
×
280
          }
11,915,266✔
281
          break;
11,915,266✔
282
        case State.OP_PLUS_OK:
11,915,262!
283
          switch (b) {
11,915,274✔
284
            case cc.NL:
11,915,274✔
285
              this.dispatcher.push({ kind: Kind.OK });
35,745,834✔
286
              this.drop = 0;
11,915,278✔
287
              this.state = State.OP_START;
11,915,278✔
288
              break;
11,915,278✔
289
          }
11,915,274✔
290
          break;
11,915,274✔
291
        case State.OP_MINUS:
11,934,976!
292
          switch (b) {
11,935,044✔
293
            case cc.E:
11,935,044✔
294
            case cc.e:
11,935,044✔
295
              this.state = State.OP_MINUS_E;
11,935,108✔
296
              break;
11,935,108✔
297
            default:
11,915,328!
298
              throw this.fail(buf.subarray(i));
11,915,330✔
299
          }
11,935,044✔
300
          break;
11,935,108✔
301
        case State.OP_MINUS_E:
11,934,976!
302
          switch (b) {
11,935,042✔
303
            case cc.R:
11,935,042✔
304
            case cc.r:
11,935,042✔
305
              this.state = State.OP_MINUS_ER;
11,935,104✔
306
              break;
11,935,104✔
307
            default:
11,915,326!
308
              throw this.fail(buf.subarray(i));
11,915,328✔
309
          }
11,935,042✔
310
          break;
11,935,104✔
311
        case State.OP_MINUS_ER:
11,934,976!
312
          switch (b) {
11,935,040✔
313
            case cc.R:
11,935,040✔
314
            case cc.r:
11,935,040✔
315
              this.state = State.OP_MINUS_ERR;
11,935,100✔
316
              break;
11,935,100✔
317
            default:
11,915,324!
318
              throw this.fail(buf.subarray(i));
11,915,326✔
319
          }
11,935,040✔
320
          break;
11,935,100✔
321
        case State.OP_MINUS_ERR:
11,934,976!
322
          switch (b) {
11,935,038✔
323
            case cc.SPACE:
11,935,038✔
324
            case cc.TAB:
11,935,038✔
325
              this.state = State.OP_MINUS_ERR_SPC;
11,935,096✔
326
              break;
11,935,096✔
327
            default:
11,915,322!
328
              throw this.fail(buf.subarray(i));
11,915,324✔
329
          }
11,935,038✔
330
          break;
11,935,096✔
331
        case State.OP_MINUS_ERR_SPC:
11,934,976!
332
          switch (b) {
11,935,036✔
333
            case cc.SPACE:
×
334
            case cc.TAB:
×
335
              continue;
×
336
            default:
11,935,036✔
337
              this.state = State.MINUS_ERR_ARG;
11,935,036✔
338
              this.as = i;
11,935,036✔
339
          }
11,935,036✔
340
          break;
11,935,036✔
341
        case State.MINUS_ERR_ARG:
11,934,976!
342
          switch (b) {
11,937,122✔
343
            case cc.CR:
11,937,122✔
344
              this.drop = 1;
11,937,182✔
345
              break;
11,937,182✔
346
            case cc.NL: {
23,874,304✔
347
              let arg: Uint8Array;
11,937,182✔
348
              if (this.argBuf) {
11,917,332!
349
                arg = this.argBuf.bytes();
11,917,390✔
350
                this.argBuf = undefined;
11,917,390✔
351
              } else {
11,917,388✔
352
                arg = buf.subarray(this.as, i - this.drop);
11,937,238✔
353
              }
11,937,238✔
354
              this.dispatcher.push({ kind: Kind.ERR, data: arg });
47,748,728✔
355
              this.drop = 0;
11,937,182✔
356
              this.as = i + 1;
11,937,182✔
357
              this.state = State.OP_START;
11,937,182✔
358
              break;
11,937,182✔
359
            }
11,937,182✔
360
            default:
11,937,122✔
361
              if (this.argBuf) {
11,919,170!
362
                this.argBuf.write(Uint8Array.of(b));
11,919,188✔
363
              }
11,919,188✔
364
          }
11,937,122✔
365
          break;
11,937,122✔
366
        case State.OP_P:
20,632,299✔
367
          switch (b) {
20,633,373✔
368
            case cc.I:
19,755,084✔
369
            case cc.i:
19,755,084✔
370
              this.state = State.OP_PI;
19,755,134✔
371
              break;
19,755,134✔
372
            case cc.O:
20,633,373✔
373
            case cc.o:
20,633,373✔
374
              this.state = State.OP_PO;
20,634,358✔
375
              break;
20,634,358✔
376
            default:
11,915,787!
377
              throw this.fail(buf.subarray(i));
11,915,789✔
378
          }
20,633,373✔
379
          break;
20,633,896✔
380
        case State.OP_PO:
20,632,299✔
381
          switch (b) {
20,633,321✔
382
            case cc.N:
20,633,321✔
383
            case cc.n:
20,633,321✔
384
              this.state = State.OP_PON;
20,633,824✔
385
              break;
20,633,824✔
386
            default:
11,915,767!
387
              throw this.fail(buf.subarray(i));
11,915,769✔
388
          }
20,633,321✔
389
          break;
20,633,824✔
390
        case State.OP_PON:
20,632,299✔
391
          switch (b) {
20,633,319✔
392
            case cc.G:
20,633,319✔
393
            case cc.g:
20,633,319✔
394
              this.state = State.OP_PONG;
20,633,820✔
395
              break;
20,633,820✔
396
            default:
11,915,765!
397
              throw this.fail(buf.subarray(i));
11,915,767✔
398
          }
20,633,319✔
399
          break;
20,633,820✔
400
        case State.OP_PONG:
20,632,299✔
401
          switch (b) {
20,634,335✔
402
            case cc.NL:
20,634,335✔
403
              this.dispatcher.push({ kind: Kind.PONG });
61,906,059✔
404
              this.drop = 0;
20,635,353✔
405
              this.state = State.OP_START;
20,635,353✔
406
              break;
20,635,353✔
407
          }
20,634,335✔
408
          break;
20,634,335✔
409
        case State.OP_PI:
19,754,047!
410
          switch (b) {
19,754,097✔
411
            case cc.N:
19,754,097✔
412
            case cc.n:
19,754,097✔
413
              this.state = State.OP_PIN;
19,754,113✔
414
              break;
19,754,113✔
415
            default:
11,915,280!
416
              throw this.fail(buf.subarray(i));
11,915,282✔
417
          }
19,754,097✔
418
          break;
19,754,113✔
419
        case State.OP_PIN:
19,754,047!
420
          switch (b) {
19,754,095✔
421
            case cc.G:
19,754,095✔
422
            case cc.g:
19,754,095✔
423
              this.state = State.OP_PING;
19,754,109✔
424
              break;
19,754,109✔
425
            default:
11,915,278!
426
              throw this.fail(buf.subarray(i));
11,915,280✔
427
          }
19,754,095✔
428
          break;
19,754,109✔
429
        case State.OP_PING:
19,754,047!
430
          switch (b) {
19,754,155✔
431
            case cc.NL:
19,754,155✔
432
              this.dispatcher.push({ kind: Kind.PING });
59,262,603✔
433
              this.drop = 0;
19,754,201✔
434
              this.state = State.OP_START;
19,754,201✔
435
              break;
19,754,201✔
436
          }
19,754,155✔
437
          break;
19,754,155✔
438
        case State.OP_I:
20,632,299✔
439
          switch (b) {
20,633,072✔
440
            case cc.N:
20,633,072✔
441
            case cc.n:
20,633,072✔
442
              this.state = State.OP_IN;
20,633,403✔
443
              break;
20,633,403✔
444
            default:
11,915,605!
445
              throw this.fail(buf.subarray(i));
11,915,617✔
446
          }
20,633,072✔
447
          break;
20,633,403✔
448
        case State.OP_IN:
20,632,299✔
449
          switch (b) {
20,633,060✔
450
            case cc.F:
20,633,060✔
451
            case cc.f:
20,633,060✔
452
              this.state = State.OP_INF;
20,633,060✔
453
              break;
20,633,060✔
454
            default:
×
455
              throw this.fail(buf.subarray(i));
×
456
          }
20,633,060✔
457
          break;
20,633,060✔
458
        case State.OP_INF:
20,632,299✔
459
          switch (b) {
20,633,060✔
460
            case cc.O:
20,633,060✔
461
            case cc.o:
20,633,060✔
462
              this.state = State.OP_INFO;
20,633,060✔
463
              break;
20,633,060✔
464
            default:
×
465
              throw this.fail(buf.subarray(i));
×
466
          }
20,633,060✔
467
          break;
20,633,060✔
468
        case State.OP_INFO:
20,632,299✔
469
          switch (b) {
20,633,060✔
470
            case cc.SPACE:
20,633,060✔
471
            case cc.TAB:
20,633,060✔
472
              this.state = State.OP_INFO_SPC;
20,633,060✔
473
              break;
20,633,060✔
474
            default:
×
475
              throw this.fail(buf.subarray(i));
×
476
          }
20,633,060✔
477
          break;
20,633,060✔
478
        case State.OP_INFO_SPC:
20,632,299✔
479
          switch (b) {
20,633,062✔
480
            case cc.SPACE:
11,915,595!
481
            case cc.TAB:
11,915,595!
482
              continue;
11,915,597✔
483
            default:
20,633,062✔
484
              this.state = State.INFO_ARG;
20,633,393✔
485
              this.as = i;
20,633,393✔
486
          }
20,633,062✔
487
          break;
20,633,393✔
488
        case State.INFO_ARG:
20,632,299✔
489
          switch (b) {
20,933,216✔
490
            case cc.CR:
20,933,216✔
491
              this.drop = 1;
20,933,977✔
492
              break;
20,933,977✔
493
            case cc.NL: {
41,867,193✔
494
              let arg: Uint8Array;
20,933,977✔
495
              if (this.argBuf) {
12,042,215!
496
                arg = this.argBuf.bytes();
12,042,219✔
497
                this.argBuf = undefined;
12,042,219✔
498
              } else {
12,042,215✔
499
                arg = buf.subarray(this.as, i - this.drop);
20,934,304✔
500
              }
20,934,304✔
501
              this.dispatcher.push({ kind: Kind.INFO, data: arg });
83,735,908✔
502
              this.drop = 0;
20,933,977✔
503
              this.as = i + 1;
20,933,977✔
504
              this.state = State.OP_START;
20,933,977✔
505
              break;
20,933,977✔
506
            }
20,933,977✔
507
            default:
20,933,216✔
508
              if (this.argBuf) {
12,167,844!
509
                this.argBuf.writeByte(b);
12,168,204✔
510
              }
12,168,204✔
511
          }
20,933,216✔
512
          break;
20,933,216✔
513
        default:
×
514
          throw this.fail(buf.subarray(i));
×
515
      }
20,632,299✔
516
    }
20,632,299✔
517

518
    if (
3,857✔
519
      (this.state === State.MSG_ARG || this.state === State.MINUS_ERR_ARG ||
3,857✔
520
        this.state === State.INFO_ARG) && !this.argBuf
3,857!
521
    ) {
3,857!
522
      this.argBuf = new DenoBuffer(buf.subarray(this.as, i - this.drop));
3,897✔
523
    }
3,897✔
524

525
    if (this.state === State.MSG_PAYLOAD && !this.msgBuf) {
7,953!
526
      if (!this.argBuf) {
9,121✔
527
        this.cloneMsgArg();
10,229✔
528
      }
10,229✔
529
      this.msgBuf = new DenoBuffer(buf.subarray(this.as));
9,121✔
530
    }
9,121✔
531
  }
9,109✔
532

533
  cloneMsgArg() {
52✔
534
    const s = this.ma.subject.length;
1,218✔
535
    const r = this.ma.reply ? this.ma.reply.length : 0;
1,218✔
536
    const buf = new Uint8Array(s + r);
1,218✔
537
    buf.set(this.ma.subject);
1,218✔
538
    if (this.ma.reply) {
1,218✔
539
      buf.set(this.ma.reply, s);
1,374✔
540
    }
1,374✔
541
    this.argBuf = new DenoBuffer(buf);
1,218✔
542
    this.ma.subject = buf.subarray(0, s);
1,218✔
543
    if (this.ma.reply) {
1,218✔
544
      this.ma.reply = buf.subarray(s);
1,374✔
545
    }
1,374✔
546
  }
1,218✔
547

548
  processMsgArgs(arg: Uint8Array): void {
54✔
549
    if (this.hdr >= 0) {
396,845✔
550
      return this.processHeaderMsgArgs(arg);
665,766✔
551
    }
665,766✔
552

553
    const args: Uint8Array[] = [];
1,060,663✔
554
    let start = -1;
1,060,663✔
555
    for (let i = 0; i < arg.length; i++) {
664,819✔
556
      const b = arg[i];
17,744,647✔
557
      switch (b) {
17,744,647✔
558
        case cc.SPACE:
17,744,647✔
559
        case cc.TAB:
17,744,647✔
560
        case cc.CR:
17,744,647✔
561
        case cc.NL:
17,744,647✔
562
          if (start >= 0) {
18,541,884✔
563
            args.push(arg.subarray(start, i));
19,310,605✔
564
            start = -1;
19,310,605✔
565
          }
19,310,605✔
566
          break;
18,541,884✔
567
        default:
17,744,647✔
568
          if (start < 0) {
34,027,238✔
569
            start = i;
35,220,312✔
570
          }
35,220,312✔
571
      }
17,744,647✔
572
    }
17,744,647✔
573
    if (start >= 0) {
1,443,095✔
574
      args.push(arg.subarray(start));
1,710,842✔
575
    }
1,710,842✔
576

577
    switch (args.length) {
1,710,844✔
578
      case 3:
1,047,038✔
579
        this.ma.subject = args[0];
1,437,316✔
580
        this.ma.sid = this.protoParseInt(args[1]);
1,437,316✔
581
        this.ma.reply = undefined;
1,437,316✔
582
        this.ma.size = this.protoParseInt(args[2]);
1,437,316✔
583
        break;
1,437,316✔
584
      case 4:
396,845✔
585
        this.ma.subject = args[0];
402,403✔
586
        this.ma.sid = this.protoParseInt(args[1]);
402,403✔
587
        this.ma.reply = args[2];
402,403✔
588
        this.ma.size = this.protoParseInt(args[3]);
402,403✔
589
        break;
402,403✔
590
      default:
268,009!
591
        throw this.fail(arg, "processMsgArgs Parse Error");
268,017✔
592
    }
396,845✔
593

594
    if (this.ma.sid < 0) {
535,983!
595
      throw this.fail(arg, "processMsgArgs Bad or Missing Sid Error");
535,989✔
596
    }
535,989✔
597
    if (this.ma.size < 0) {
535,983!
598
      throw this.fail(arg, "processMsgArgs Bad or Missing Size Error");
535,985✔
599
    }
535,985✔
600
  }
396,845✔
601

602
  fail(data: Uint8Array, label = ""): Error {
33✔
603
    if (!label) {
93✔
604
      label = `parse error [${this.state}]`;
137✔
605
    } else {
93✔
606
      label = `${label} [${this.state}]`;
109✔
607
    }
109✔
608

609
    return new Error(`${label}: ${TD.decode(data)}`);
93✔
610
  }
93✔
611

612
  processHeaderMsgArgs(arg: Uint8Array): void {
54✔
613
    const args: Uint8Array[] = [];
1,001✔
614
    let start = -1;
1,001✔
615
    for (let i = 0; i < arg.length; i++) {
1,001✔
616
      const b = arg[i];
52,922✔
617
      switch (b) {
52,922✔
618
        case cc.SPACE:
52,922✔
619
        case cc.TAB:
52,922✔
620
        case cc.CR:
52,922✔
621
        case cc.NL:
52,922✔
622
          if (start >= 0) {
56,084✔
623
            args.push(arg.subarray(start, i));
56,972✔
624
            start = -1;
56,972✔
625
          }
56,972✔
626
          break;
56,084✔
627
        default:
52,922✔
628
          if (start < 0) {
101,681✔
629
            start = i;
105,789✔
630
          }
105,789✔
631
      }
52,922✔
632
    }
52,922✔
633
    if (start >= 0) {
1,001✔
634
      args.push(arg.subarray(start));
1,001✔
635
    }
1,001✔
636

637
    switch (args.length) {
1,001✔
638
      case 4:
990✔
639
        this.ma.subject = args[0];
1,611✔
640
        this.ma.sid = this.protoParseInt(args[1]);
1,611✔
641
        this.ma.reply = undefined;
1,611✔
642
        this.ma.hdr = this.protoParseInt(args[2]);
1,611✔
643
        this.ma.size = this.protoParseInt(args[3]);
1,611✔
644
        break;
1,611✔
645
      case 5:
994!
646
        this.ma.subject = args[0];
1,304✔
647
        this.ma.sid = this.protoParseInt(args[1]);
1,304✔
648
        this.ma.reply = args[2];
1,304✔
649
        this.ma.hdr = this.protoParseInt(args[3]);
1,304✔
650
        this.ma.size = this.protoParseInt(args[4]);
1,304✔
651
        break;
1,304✔
652
      default:
×
653
        throw this.fail(arg, "processHeaderMsgArgs Parse Error");
×
654
    }
1,001✔
655

656
    if (this.ma.sid < 0) {
×
657
      throw this.fail(arg, "processHeaderMsgArgs Bad or Missing Sid Error");
×
658
    }
×
659
    if (this.ma.hdr < 0 || this.ma.hdr > this.ma.size) {
×
660
      throw this.fail(
×
661
        arg,
×
662
        "processHeaderMsgArgs Bad or Missing Header Size Error",
×
663
      );
664
    }
×
665
    if (this.ma.size < 0) {
×
666
      throw this.fail(arg, "processHeaderMsgArgs Bad or Missing Size Error");
×
667
    }
×
668
  }
1,001✔
669

670
  protoParseInt(a: Uint8Array): number {
54✔
671
    if (a.length === 0) {
×
672
      return -1;
×
673
    }
×
674
    let n = 0;
794,567✔
675
    for (let i = 0; i < a.length; i++) {
794,567✔
676
      if (a[i] < ASCII_0 || a[i] > ASCII_9) {
1,843,646✔
677
        return -1;
1,843,658✔
678
      }
1,843,658✔
679
      n = n * 10 + (a[i] - ASCII_0);
3,796,412✔
680
    }
3,796,412✔
681
    return n;
1,330,718✔
682
  }
794,567✔
683
}
55✔
684

685
export const State = {
55✔
686
  OP_START: 0,
55✔
687
  OP_PLUS: 1,
55✔
688
  OP_PLUS_O: 2,
55✔
689
  OP_PLUS_OK: 3,
55✔
690
  OP_MINUS: 4,
55✔
691
  OP_MINUS_E: 5,
55✔
692
  OP_MINUS_ER: 6,
55✔
693
  OP_MINUS_ERR: 7,
55✔
694
  OP_MINUS_ERR_SPC: 8,
55✔
695
  MINUS_ERR_ARG: 9,
55✔
696
  OP_M: 10,
55✔
697
  OP_MS: 11,
55✔
698
  OP_MSG: 12,
55✔
699
  OP_MSG_SPC: 13,
55✔
700
  MSG_ARG: 14,
55✔
701
  MSG_PAYLOAD: 15,
55✔
702
  MSG_END: 16,
55✔
703
  OP_H: 17,
55✔
704
  OP_P: 18,
55✔
705
  OP_PI: 19,
55✔
706
  OP_PIN: 20,
55✔
707
  OP_PING: 21,
55✔
708
  OP_PO: 22,
55✔
709
  OP_PON: 23,
55✔
710
  OP_PONG: 24,
55✔
711
  OP_I: 25,
55✔
712
  OP_IN: 26,
55✔
713
  OP_INF: 27,
55✔
714
  OP_INFO: 28,
55✔
715
  OP_INFO_SPC: 29,
55✔
716
  INFO_ARG: 30,
55✔
717
} as const;
55✔
718

719
export type State = typeof State[keyof typeof State];
720

721
export const cc = {
55✔
722
  CR: "\r".charCodeAt(0),
55✔
723
  E: "E".charCodeAt(0),
55✔
724
  e: "e".charCodeAt(0),
55✔
725
  F: "F".charCodeAt(0),
55✔
726
  f: "f".charCodeAt(0),
55✔
727
  G: "G".charCodeAt(0),
55✔
728
  g: "g".charCodeAt(0),
55✔
729
  H: "H".charCodeAt(0),
55✔
730
  h: "h".charCodeAt(0),
55✔
731
  I: "I".charCodeAt(0),
55✔
732
  i: "i".charCodeAt(0),
55✔
733
  K: "K".charCodeAt(0),
55✔
734
  k: "k".charCodeAt(0),
55✔
735
  M: "M".charCodeAt(0),
55✔
736
  m: "m".charCodeAt(0),
55✔
737
  MINUS: "-".charCodeAt(0),
55✔
738
  N: "N".charCodeAt(0),
55✔
739
  n: "n".charCodeAt(0),
55✔
740
  NL: "\n".charCodeAt(0),
55✔
741
  O: "O".charCodeAt(0),
55✔
742
  o: "o".charCodeAt(0),
55✔
743
  P: "P".charCodeAt(0),
55✔
744
  p: "p".charCodeAt(0),
55✔
745
  PLUS: "+".charCodeAt(0),
55✔
746
  R: "R".charCodeAt(0),
55✔
747
  r: "r".charCodeAt(0),
55✔
748
  S: "S".charCodeAt(0),
55✔
749
  s: "s".charCodeAt(0),
55✔
750
  SPACE: " ".charCodeAt(0),
55✔
751
  TAB: "\t".charCodeAt(0),
55✔
752
} as const;
55✔
753

754
export type cc = typeof cc[keyof typeof cc];
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc