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

nats-io / nats.js / 13041776921

29 Jan 2025 10:36PM UTC coverage: 82.727% (+0.02%) from 82.71%
13041776921

push

github

web-flow
fix: typo in the documentation of the list() method of the Objm class (#198)

2271 of 3098 branches covered (73.31%)

Branch coverage included in aggregate %.

9631 of 11289 relevant lines covered (85.31%)

787245.13 hits per line

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

82.15
/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 enum Kind {
110✔
21
  OK,
22
  ERR,
23
  MSG,
24
  INFO,
25
  PING,
26
  PONG,
27
}
28

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

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

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

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

71
function newMsgArg(): MsgArg {
395,875✔
72
  const ma = {} as MsgArg;
395,875✔
73
  ma.sid = -1;
395,875✔
74
  ma.hdr = -1;
395,875✔
75
  ma.size = -1;
395,875✔
76

77
  return ma;
395,875✔
78
}
395,875✔
79

80
const ASCII_0 = 48;
55✔
81
const ASCII_9 = 57;
55✔
82

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

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

103
  parse(buf: Uint8Array): void {
54✔
104
    let i: number;
8,840✔
105
    for (i = 0; i < buf.length; i++) {
8,840✔
106
      const b = buf[i];
20,570,522✔
107
      switch (this.state) {
20,570,522✔
108
        case State.OP_START:
20,570,522✔
109
          switch (b) {
20,968,237✔
110
            case cc.M:
20,968,237✔
111
            case cc.m:
20,968,237✔
112
              this.state = State.OP_M;
21,363,475✔
113
              this.hdr = -1;
21,363,475✔
114
              this.ma = newMsgArg();
21,363,475✔
115
              break;
21,363,475✔
116
            case cc.H:
20,968,237✔
117
            case cc.h:
20,968,237✔
118
              this.state = State.OP_H;
20,968,820✔
119
              this.hdr = 0;
20,968,820✔
120
              this.ma = newMsgArg();
20,968,820✔
121
              break;
20,968,820✔
122
            case cc.P:
20,968,237✔
123
            case cc.p:
20,968,237✔
124
              this.state = State.OP_P;
20,969,298✔
125
              break;
20,969,298✔
126
            case cc.PLUS:
12,184,473✔
127
              this.state = State.OP_PLUS;
12,184,481✔
128
              break;
12,184,481✔
129
            case cc.MINUS:
12,204,447✔
130
              this.state = State.OP_MINUS;
12,204,515✔
131
              break;
12,204,515✔
132
            case cc.I:
20,968,237✔
133
            case cc.i:
20,968,237✔
134
              this.state = State.OP_I;
20,968,990✔
135
              break;
20,968,990✔
136
            default:
12,184,473✔
137
              throw this.fail(buf.subarray(i));
12,184,477✔
138
          }
20,968,237✔
139
          break;
21,237,150✔
140
        case State.OP_H:
20,570,522✔
141
          switch (b) {
20,571,105✔
142
            case cc.M:
20,571,105✔
143
            case cc.m:
20,571,105✔
144
              this.state = State.OP_M;
20,571,105✔
145
              break;
20,571,105✔
146
            default:
×
147
              throw this.fail(buf.subarray(i));
×
148
          }
20,571,105✔
149
          break;
20,571,105✔
150
        case State.OP_M:
20,570,522✔
151
          switch (b) {
20,966,343✔
152
            case cc.S:
20,966,343✔
153
            case cc.s:
20,966,343✔
154
              this.state = State.OP_MS;
21,234,323✔
155
              break;
21,234,323✔
156
            default:
12,183,538!
157
              throw this.fail(buf.subarray(i));
12,183,540✔
158
          }
20,966,343✔
159
          break;
21,234,323✔
160
        case State.OP_MS:
20,570,522✔
161
          switch (b) {
20,966,341✔
162
            case cc.G:
20,966,341✔
163
            case cc.g:
20,966,341✔
164
              this.state = State.OP_MSG;
21,234,319✔
165
              break;
21,234,319✔
166
            default:
12,183,536!
167
              throw this.fail(buf.subarray(i));
12,183,538✔
168
          }
20,966,341✔
169
          break;
21,234,319✔
170
        case State.OP_MSG:
20,570,522✔
171
          switch (b) {
20,966,339✔
172
            case cc.SPACE:
20,966,339✔
173
            case cc.TAB:
20,966,339✔
174
              this.state = State.OP_MSG_SPC;
21,234,315✔
175
              break;
21,234,315✔
176
            default:
12,183,534!
177
              throw this.fail(buf.subarray(i));
12,183,536✔
178
          }
20,966,339✔
179
          break;
21,234,315✔
180
        case State.OP_MSG_SPC:
20,570,522✔
181
          switch (b) {
20,966,337✔
182
            case cc.SPACE:
×
183
            case cc.TAB:
×
184
              continue;
×
185
            default:
20,966,337✔
186
              this.state = State.MSG_ARG;
20,966,337✔
187
              this.as = i;
20,966,337✔
188
          }
20,966,337✔
189
          break;
20,966,337✔
190
        case State.MSG_ARG:
20,570,522✔
191
          switch (b) {
38,048,227✔
192
            case cc.CR:
38,048,227✔
193
              this.drop = 1;
38,444,040✔
194
              break;
38,444,040✔
195
            case cc.NL: {
76,492,269✔
196
              const arg: Uint8Array = this.argBuf
23,745,439✔
197
                ? this.argBuf.bytes()
23,745,439✔
198
                : buf.subarray(this.as, i - this.drop);
23,745,439✔
199
              this.processMsgArgs(arg);
38,444,042✔
200
              this.drop = 0;
38,444,042✔
201
              this.as = i + 1;
38,444,042✔
202
              this.state = State.MSG_PAYLOAD;
38,444,042✔
203

204
              // jump ahead with the index. If this overruns
205
              // what is left we fall out and process a split buffer.
206
              i = this.as + this.ma.size - 1;
38,444,042✔
207
              break;
38,444,042✔
208
            }
38,444,042✔
209
            default:
38,048,227✔
210
              if (this.argBuf) {
33,572,657!
211
                this.argBuf.writeByte(b);
33,573,075✔
212
              }
33,573,075✔
213
          }
38,048,227✔
214
          break;
47,948,304✔
215
        case State.MSG_PAYLOAD:
20,570,522✔
216
          if (this.msgBuf) {
20,841,576✔
217
            if (this.msgBuf.length >= this.ma.size) {
20,844,427✔
218
              const data = this.msgBuf.bytes({ copy: false });
62,542,134✔
219
              this.dispatcher.push(
20,847,378✔
220
                { kind: Kind.MSG, msg: this.ma, data: data },
104,236,890✔
221
              );
222
              this.argBuf = undefined;
20,847,378✔
223
              this.msgBuf = undefined;
20,847,378✔
224
              this.state = State.MSG_END;
20,847,378✔
225
            } else {
20,846,213✔
226
              let toCopy = this.ma.size - this.msgBuf.length;
20,847,899✔
227
              const avail = buf.length - i;
20,847,899✔
228

229
              if (avail < toCopy) {
20,847,899✔
230
                toCopy = avail;
20,848,418✔
231
              }
20,848,418✔
232

233
              if (toCopy > 0) {
20,847,899✔
234
                this.msgBuf.write(buf.subarray(i, i + toCopy));
20,847,899✔
235
                i = (i + toCopy) - 1;
20,847,899✔
236
              } else {
×
237
                this.msgBuf.writeByte(b);
×
238
              }
×
239
            }
20,847,899✔
240
          } else if (i - this.as >= this.ma.size) {
20,841,576✔
241
            this.dispatcher.push(
21,361,547✔
242
              { kind: Kind.MSG, msg: this.ma, data: buf.subarray(this.as, i) },
106,807,735✔
243
            );
244
            this.argBuf = undefined;
21,361,547✔
245
            this.msgBuf = undefined;
21,361,547✔
246
            this.state = State.MSG_END;
21,361,547✔
247
          }
21,361,547✔
248
          break;
20,968,004✔
249
        case State.MSG_END:
20,570,522✔
250
          switch (b) {
20,966,318✔
251
            case cc.NL:
20,966,318✔
252
              this.drop = 0;
20,966,318✔
253
              this.as = i + 1;
20,966,318✔
254
              this.state = State.OP_START;
20,966,318✔
255
              break;
20,966,318✔
256
            default:
×
257
              continue;
×
258
          }
20,966,318✔
259
          break;
20,966,318✔
260
        case State.OP_PLUS:
11,915,556!
261
          switch (b) {
11,915,564✔
262
            case cc.O:
11,915,564✔
263
            case cc.o:
11,915,564✔
264
              this.state = State.OP_PLUS_O;
11,915,568✔
265
              break;
11,915,568✔
266
            default:
11,915,564✔
267
              throw this.fail(buf.subarray(i));
11,915,568✔
268
          }
11,915,564✔
269
          break;
11,915,568✔
270
        case State.OP_PLUS_O:
11,915,556!
271
          switch (b) {
11,915,560✔
272
            case cc.K:
11,915,560✔
273
            case cc.k:
11,915,560✔
274
              this.state = State.OP_PLUS_OK;
11,915,560✔
275
              break;
11,915,560✔
276
            default:
×
277
              throw this.fail(buf.subarray(i));
×
278
          }
11,915,560✔
279
          break;
11,915,560✔
280
        case State.OP_PLUS_OK:
11,915,556!
281
          switch (b) {
11,915,568✔
282
            case cc.NL:
11,915,568✔
283
              this.dispatcher.push({ kind: Kind.OK });
35,746,716✔
284
              this.drop = 0;
11,915,572✔
285
              this.state = State.OP_START;
11,915,572✔
286
              break;
11,915,572✔
287
          }
11,915,568✔
288
          break;
11,915,568✔
289
        case State.OP_MINUS:
11,935,299!
290
          switch (b) {
11,935,367✔
291
            case cc.E:
11,935,367✔
292
            case cc.e:
11,935,367✔
293
              this.state = State.OP_MINUS_E;
11,935,431✔
294
              break;
11,935,431✔
295
            default:
11,915,622!
296
              throw this.fail(buf.subarray(i));
11,915,624✔
297
          }
11,935,367✔
298
          break;
11,935,431✔
299
        case State.OP_MINUS_E:
11,935,299!
300
          switch (b) {
11,935,365✔
301
            case cc.R:
11,935,365✔
302
            case cc.r:
11,935,365✔
303
              this.state = State.OP_MINUS_ER;
11,935,427✔
304
              break;
11,935,427✔
305
            default:
11,915,620!
306
              throw this.fail(buf.subarray(i));
11,915,622✔
307
          }
11,935,365✔
308
          break;
11,935,427✔
309
        case State.OP_MINUS_ER:
11,935,299!
310
          switch (b) {
11,935,363✔
311
            case cc.R:
11,935,363✔
312
            case cc.r:
11,935,363✔
313
              this.state = State.OP_MINUS_ERR;
11,935,423✔
314
              break;
11,935,423✔
315
            default:
11,915,618!
316
              throw this.fail(buf.subarray(i));
11,915,620✔
317
          }
11,935,363✔
318
          break;
11,935,423✔
319
        case State.OP_MINUS_ERR:
11,935,299!
320
          switch (b) {
11,935,361✔
321
            case cc.SPACE:
11,935,361✔
322
            case cc.TAB:
11,935,361✔
323
              this.state = State.OP_MINUS_ERR_SPC;
11,935,419✔
324
              break;
11,935,419✔
325
            default:
11,915,616!
326
              throw this.fail(buf.subarray(i));
11,915,618✔
327
          }
11,935,361✔
328
          break;
11,935,419✔
329
        case State.OP_MINUS_ERR_SPC:
11,935,299!
330
          switch (b) {
11,935,359✔
331
            case cc.SPACE:
×
332
            case cc.TAB:
×
333
              continue;
×
334
            default:
11,935,359✔
335
              this.state = State.MINUS_ERR_ARG;
11,935,359✔
336
              this.as = i;
11,935,359✔
337
          }
11,935,359✔
338
          break;
11,935,359✔
339
        case State.MINUS_ERR_ARG:
11,935,299!
340
          switch (b) {
11,937,445✔
341
            case cc.CR:
11,937,445✔
342
              this.drop = 1;
11,937,505✔
343
              break;
11,937,505✔
344
            case cc.NL: {
23,874,950✔
345
              let arg: Uint8Array;
11,937,505✔
346
              if (this.argBuf) {
11,917,626!
347
                arg = this.argBuf.bytes();
11,917,684✔
348
                this.argBuf = undefined;
11,917,684✔
349
              } else {
11,917,682✔
350
                arg = buf.subarray(this.as, i - this.drop);
11,937,561✔
351
              }
11,937,561✔
352
              this.dispatcher.push({ kind: Kind.ERR, data: arg });
47,750,020✔
353
              this.drop = 0;
11,937,505✔
354
              this.as = i + 1;
11,937,505✔
355
              this.state = State.OP_START;
11,937,505✔
356
              break;
11,937,505✔
357
            }
11,937,505✔
358
            default:
11,937,445✔
359
              if (this.argBuf) {
11,919,464!
360
                this.argBuf.write(Uint8Array.of(b));
11,919,482✔
361
              }
11,919,482✔
362
          }
11,937,445✔
363
          break;
11,937,445✔
364
        case State.OP_P:
20,570,522✔
365
          switch (b) {
20,571,583✔
366
            case cc.I:
19,693,267✔
367
            case cc.i:
19,693,267✔
368
              this.state = State.OP_PI;
19,693,314✔
369
              break;
19,693,314✔
370
            case cc.O:
20,571,583✔
371
            case cc.o:
20,571,583✔
372
              this.state = State.OP_PO;
20,572,558✔
373
              break;
20,572,558✔
374
            default:
11,916,080!
375
              throw this.fail(buf.subarray(i));
11,916,082✔
376
          }
20,571,583✔
377
          break;
20,572,105✔
378
        case State.OP_PO:
20,570,522✔
379
          switch (b) {
20,571,534✔
380
            case cc.N:
20,571,534✔
381
            case cc.n:
20,571,534✔
382
              this.state = State.OP_PON;
20,572,037✔
383
              break;
20,572,037✔
384
            default:
11,916,061!
385
              throw this.fail(buf.subarray(i));
11,916,063✔
386
          }
20,571,534✔
387
          break;
20,572,037✔
388
        case State.OP_PON:
20,570,522✔
389
          switch (b) {
20,571,532✔
390
            case cc.G:
20,571,532✔
391
            case cc.g:
20,571,532✔
392
              this.state = State.OP_PONG;
20,572,033✔
393
              break;
20,572,033✔
394
            default:
11,916,059!
395
              throw this.fail(buf.subarray(i));
11,916,061✔
396
          }
20,571,532✔
397
          break;
20,572,033✔
398
        case State.OP_PONG:
20,570,522✔
399
          switch (b) {
20,572,538✔
400
            case cc.NL:
20,572,538✔
401
              this.dispatcher.push({ kind: Kind.PONG });
61,720,638✔
402
              this.drop = 0;
20,573,546✔
403
              this.state = State.OP_START;
20,573,546✔
404
              break;
20,573,546✔
405
          }
20,572,538✔
406
          break;
20,572,538✔
407
        case State.OP_PI:
19,692,243!
408
          switch (b) {
19,692,290✔
409
            case cc.N:
19,692,290✔
410
            case cc.n:
19,692,290✔
411
              this.state = State.OP_PIN;
19,692,305✔
412
              break;
19,692,305✔
413
            default:
11,915,573!
414
              throw this.fail(buf.subarray(i));
11,915,575✔
415
          }
19,692,290✔
416
          break;
19,692,305✔
417
        case State.OP_PIN:
19,692,243!
418
          switch (b) {
19,692,288✔
419
            case cc.G:
19,692,288✔
420
            case cc.g:
19,692,288✔
421
              this.state = State.OP_PING;
19,692,301✔
422
              break;
19,692,301✔
423
            default:
11,915,571!
424
              throw this.fail(buf.subarray(i));
11,915,573✔
425
          }
19,692,288✔
426
          break;
19,692,301✔
427
        case State.OP_PING:
19,692,243!
428
          switch (b) {
19,692,345✔
429
            case cc.NL:
19,692,345✔
430
              this.dispatcher.push({ kind: Kind.PING });
59,077,164✔
431
              this.drop = 0;
19,692,388✔
432
              this.state = State.OP_START;
19,692,388✔
433
              break;
19,692,388✔
434
          }
19,692,345✔
435
          break;
19,692,345✔
436
        case State.OP_I:
20,570,522✔
437
          switch (b) {
20,571,285✔
438
            case cc.N:
20,571,285✔
439
            case cc.n:
20,571,285✔
440
              this.state = State.OP_IN;
20,571,616✔
441
              break;
20,571,616✔
442
            default:
11,915,899!
443
              throw this.fail(buf.subarray(i));
11,915,911✔
444
          }
20,571,285✔
445
          break;
20,571,616✔
446
        case State.OP_IN:
20,570,522✔
447
          switch (b) {
20,571,273✔
448
            case cc.F:
20,571,273✔
449
            case cc.f:
20,571,273✔
450
              this.state = State.OP_INF;
20,571,273✔
451
              break;
20,571,273✔
452
            default:
×
453
              throw this.fail(buf.subarray(i));
×
454
          }
20,571,273✔
455
          break;
20,571,273✔
456
        case State.OP_INF:
20,570,522✔
457
          switch (b) {
20,571,273✔
458
            case cc.O:
20,571,273✔
459
            case cc.o:
20,571,273✔
460
              this.state = State.OP_INFO;
20,571,273✔
461
              break;
20,571,273✔
462
            default:
×
463
              throw this.fail(buf.subarray(i));
×
464
          }
20,571,273✔
465
          break;
20,571,273✔
466
        case State.OP_INFO:
20,570,522✔
467
          switch (b) {
20,571,273✔
468
            case cc.SPACE:
20,571,273✔
469
            case cc.TAB:
20,571,273✔
470
              this.state = State.OP_INFO_SPC;
20,571,273✔
471
              break;
20,571,273✔
472
            default:
×
473
              throw this.fail(buf.subarray(i));
×
474
          }
20,571,273✔
475
          break;
20,571,273✔
476
        case State.OP_INFO_SPC:
20,570,522✔
477
          switch (b) {
20,571,275✔
478
            case cc.SPACE:
11,915,889!
479
            case cc.TAB:
11,915,889!
480
              continue;
11,915,891✔
481
            default:
20,571,275✔
482
              this.state = State.INFO_ARG;
20,571,606✔
483
              this.as = i;
20,571,606✔
484
          }
20,571,275✔
485
          break;
20,571,606✔
486
        case State.INFO_ARG:
20,570,522✔
487
          switch (b) {
20,868,099✔
488
            case cc.CR:
20,868,099✔
489
              this.drop = 1;
20,868,850✔
490
              break;
20,868,850✔
491
            case cc.NL: {
41,736,949✔
492
              let arg: Uint8Array;
20,868,850✔
493
              if (this.argBuf) {
12,042,800!
494
                arg = this.argBuf.bytes();
12,042,804✔
495
                this.argBuf = undefined;
12,042,804✔
496
              } else {
12,042,800✔
497
                arg = buf.subarray(this.as, i - this.drop);
20,869,177✔
498
              }
20,869,177✔
499
              this.dispatcher.push({ kind: Kind.INFO, data: arg });
83,475,400✔
500
              this.drop = 0;
20,868,850✔
501
              this.as = i + 1;
20,868,850✔
502
              this.state = State.OP_START;
20,868,850✔
503
              break;
20,868,850✔
504
            }
20,868,850✔
505
            default:
20,868,099✔
506
              if (this.argBuf) {
12,168,720!
507
                this.argBuf.writeByte(b);
12,169,080✔
508
              }
12,169,080✔
509
          }
20,868,099✔
510
          break;
20,868,099✔
511
        default:
×
512
          throw this.fail(buf.subarray(i));
×
513
      }
20,570,522✔
514
    }
20,570,522✔
515

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

523
    if (this.state === State.MSG_PAYLOAD && !this.msgBuf) {
7,690!
524
      if (!this.argBuf) {
8,858✔
525
        this.cloneMsgArg();
9,971✔
526
      }
9,971✔
527
      this.msgBuf = new DenoBuffer(buf.subarray(this.as));
8,858✔
528
    }
8,858✔
529
  }
8,840✔
530

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

546
  processMsgArgs(arg: Uint8Array): void {
54✔
547
    if (this.hdr >= 0) {
395,869✔
548
      return this.processHeaderMsgArgs(arg);
664,426✔
549
    }
664,426✔
550

551
    const args: Uint8Array[] = [];
1,059,075✔
552
    let start = -1;
1,059,075✔
553
    for (let i = 0; i < arg.length; i++) {
663,843✔
554
      const b = arg[i];
17,708,229✔
555
      switch (b) {
17,708,229✔
556
        case cc.SPACE:
17,708,229✔
557
        case cc.TAB:
17,708,229✔
558
        case cc.CR:
17,708,229✔
559
        case cc.NL:
17,708,229✔
560
          if (start >= 0) {
18,504,175✔
561
            args.push(arg.subarray(start, i));
19,271,606✔
562
            start = -1;
19,271,606✔
563
          }
19,271,606✔
564
          break;
18,504,175✔
565
        default:
17,708,229✔
566
          if (start < 0) {
33,956,669✔
567
            start = i;
35,147,841✔
568
          }
35,147,841✔
569
      }
17,708,229✔
570
    }
17,708,229✔
571
    if (start >= 0) {
1,440,869✔
572
      args.push(arg.subarray(start));
1,708,616✔
573
    }
1,708,616✔
574

575
    switch (args.length) {
1,708,618✔
576
      case 3:
1,045,424✔
577
        this.ma.subject = args[0];
1,435,156✔
578
        this.ma.sid = this.protoParseInt(args[1]);
1,435,156✔
579
        this.ma.reply = undefined;
1,435,156✔
580
        this.ma.size = this.protoParseInt(args[2]);
1,435,156✔
581
        break;
1,435,156✔
582
      case 4:
395,869✔
583
        this.ma.subject = args[0];
401,361✔
584
        this.ma.sid = this.protoParseInt(args[1]);
401,361✔
585
        this.ma.reply = args[2];
401,361✔
586
        this.ma.size = this.protoParseInt(args[3]);
401,361✔
587
        break;
401,361✔
588
      default:
268,009!
589
        throw this.fail(arg, "processMsgArgs Parse Error");
268,017✔
590
    }
395,869✔
591

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

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

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

610
  processHeaderMsgArgs(arg: Uint8Array): void {
54✔
611
    const args: Uint8Array[] = [];
637✔
612
    let start = -1;
637✔
613
    for (let i = 0; i < arg.length; i++) {
637✔
614
      const b = arg[i];
38,143✔
615
      switch (b) {
38,143✔
616
        case cc.SPACE:
38,143✔
617
        case cc.TAB:
38,143✔
618
        case cc.CR:
38,143✔
619
        case cc.NL:
38,143✔
620
          if (start >= 0) {
40,213✔
621
            args.push(arg.subarray(start, i));
41,101✔
622
            start = -1;
41,101✔
623
          }
41,101✔
624
          break;
40,213✔
625
        default:
38,143✔
626
          if (start < 0) {
73,579✔
627
            start = i;
76,231✔
628
          }
76,231✔
629
      }
38,143✔
630
    }
38,143✔
631
    if (start >= 0) {
637✔
632
      args.push(arg.subarray(start));
637✔
633
    }
637✔
634

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

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

668
  protoParseInt(a: Uint8Array): number {
54✔
669
    if (a.length === 0) {
×
670
      return -1;
×
671
    }
×
672
    let n = 0;
792,251✔
673
    for (let i = 0; i < a.length; i++) {
792,251✔
674
      if (a[i] < ASCII_0 || a[i] > ASCII_9) {
1,843,646✔
675
        return -1;
1,843,658✔
676
      }
1,843,658✔
677
      n = n * 10 + (a[i] - ASCII_0);
3,789,598✔
678
    }
3,789,598✔
679
    return n;
1,328,402✔
680
  }
792,251✔
681
}
55✔
682

683
export enum State {
110✔
684
  OP_START = 0,
685
  OP_PLUS,
686
  OP_PLUS_O,
687
  OP_PLUS_OK,
688
  OP_MINUS,
689
  OP_MINUS_E,
690
  OP_MINUS_ER,
691
  OP_MINUS_ERR,
692
  OP_MINUS_ERR_SPC,
693
  MINUS_ERR_ARG,
694
  OP_M,
695
  OP_MS,
696
  OP_MSG,
697
  OP_MSG_SPC,
698
  MSG_ARG,
699
  MSG_PAYLOAD,
700
  MSG_END,
701
  OP_H,
702
  OP_P,
703
  OP_PI,
704
  OP_PIN,
705
  OP_PING,
706
  OP_PO,
707
  OP_PON,
708
  OP_PONG,
709
  OP_I,
710
  OP_IN,
711
  OP_INF,
712
  OP_INFO,
713
  OP_INFO_SPC,
714
  INFO_ARG,
715
}
716

717
enum cc {
110✔
718
  CR = "\r".charCodeAt(0),
110✔
719
  E = "E".charCodeAt(0),
110✔
720
  e = "e".charCodeAt(0),
110✔
721
  F = "F".charCodeAt(0),
110✔
722
  f = "f".charCodeAt(0),
110✔
723
  G = "G".charCodeAt(0),
110✔
724
  g = "g".charCodeAt(0),
110✔
725
  H = "H".charCodeAt(0),
110✔
726
  h = "h".charCodeAt(0),
110✔
727
  I = "I".charCodeAt(0),
110✔
728
  i = "i".charCodeAt(0),
110✔
729
  K = "K".charCodeAt(0),
110✔
730
  k = "k".charCodeAt(0),
110✔
731
  M = "M".charCodeAt(0),
110✔
732
  m = "m".charCodeAt(0),
110✔
733
  MINUS = "-".charCodeAt(0),
110✔
734
  N = "N".charCodeAt(0),
110✔
735
  n = "n".charCodeAt(0),
110✔
736
  NL = "\n".charCodeAt(0),
110✔
737
  O = "O".charCodeAt(0),
110✔
738
  o = "o".charCodeAt(0),
110✔
739
  P = "P".charCodeAt(0),
110✔
740
  p = "p".charCodeAt(0),
110✔
741
  PLUS = "+".charCodeAt(0),
110✔
742
  R = "R".charCodeAt(0),
110✔
743
  r = "r".charCodeAt(0),
110✔
744
  S = "S".charCodeAt(0),
110✔
745
  s = "s".charCodeAt(0),
110✔
746
  SPACE = " ".charCodeAt(0),
110✔
747
  TAB = "\t".charCodeAt(0),
110✔
748
}
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