All files / json-pack/src/rm RmRecordDecoder.ts

89.18% Statements 33/37
75% Branches 9/12
100% Functions 3/3
90.9% Lines 30/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 475x 5x 5x   5x 15x 15x     60x       94x 94x 94x 75x 75x 75x 75x 75x 75x 75x 75x 60x 60x 60x 54x 2x 2x 2x 2x   6x 6x               15x 15x      
import {StreamingReader} from '@jsonjoy.com/buffers/lib/StreamingReader';
import {Reader} from '@jsonjoy.com/buffers/lib/Reader';
import {concatList} from '@jsonjoy.com/buffers/lib/concat';
 
export class RmRecordDecoder {
  public readonly reader = new StreamingReader();
  protected fragments: Uint8Array[] = [];
 
  public push(uint8: Uint8Array): void {
    this.reader.push(uint8);
  }
 
  public readRecord(): Reader | undefined {
    const reader = this.reader;
    let size = reader.size();
    if (size < 4) return undefined;
    const x = reader.x;
    READ_FRAGMENT: {
      try {
        const header = reader.u32();
        size -= 4;
        const fin = !!(header & 0b10000000_00000000_00000000_00000000);
        const len = header & 0b01111111_11111111_11111111_11111111;
        if (size < len) break READ_FRAGMENT;
        reader.consume();
        const fragments = this.fragments;
        if (fin) {
          if (!fragments.length) return reader.cut(len);
          fragments.push(reader.buf(len));
          const record = concatList(fragments);
          this.fragments = [];
          return record.length ? new Reader(record) : undefined;
        } else {
          fragments.push(reader.buf(len));
          return undefined;
        }
      } catch (err) {
        reader.x = x;
        if (err instanceof RangeError) return undefined;
        else throw err;
      }
    }
    reader.x = x;
    return undefined;
  }
}