All files / rpc-codec-binary/src BinaryMessageWriter.ts

93.67% Statements 74/79
79.41% Branches 27/34
100% Functions 5/5
94.52% Lines 69/73

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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 1083x         3x 324x                 1560x 1458x 1458x 1458x 102x 102x 102x 102x 102x                   540x 540x 540x 540x 540x 540x 540x 540x 540x 360x 360x 360x 327x 180x   540x 540x 540x 540x 540x       285x 285x 285x 285x 285x 285x 216x 144x 144x 144x 144x 72x   285x 285x 285x 285x 285x                   1275x 1275x 1275x 1275x 1275x 1275x 1275x 1275x 1275x 1275x 771x 514x 514x 514x 482x 257x   1275x 1275x 1275x 1275x 1275x      
import {Value} from '@jsonjoy.com/json-type';
import type {getEncoder} from '@jsonjoy.com/json-type/lib/codegen/binary/shared';
import type {BinaryJsonEncoder} from '@jsonjoy.com/json-pack';
import type {JsonValueCodec} from '@jsonjoy.com/json-pack/lib/codecs/types';
 
export class BinaryMessageWriter {
  constructor(public getTypeEncoder?: typeof getEncoder) {}
 
  writeHeader(
    writer: BinaryJsonEncoder['writer'],
    typeU16: number,
    id: number,
    payloadSize: number,
    start: number,
  ): void {
    if (payloadSize <= 0b1111_11111111) {
      const w1 = typeU16 | payloadSize;
      const w2 = id;
      writer.view.setUint32(start, (w1 << 16) | w2);
    } else if (payloadSize <= 0b1111_11111111_1111111) {
      writer.u8(id & 0xff);
      const w1 = typeU16 | 0b000_1_0000_00000000 | (payloadSize >> 7);
      const w2 = ((payloadSize & 0b0111_1111) << 8) | (id >> 8);
      writer.view.setUint32(start, (w1 << 16) | w2);
    } else E{
      writer.u16(id);
      const w1 = typeU16 | 0b000_1_0000_00000000 | (payloadSize >> 15);
      const w2 = 0b1000_0000_00000000 | (payloadSize & 0b0111_1111_11111111);
      writer.view.setUint32(start, (w1 << 16) | w2);
    }
  }
 
  writeType2(codec: JsonValueCodec, name: string, value: unknown | Value<any> | undefined): void {
    const encoder = codec.encoder;
    const writer = encoder.writer;
    const nameLength = name.length;
    writer.move(4);
    writer.ascii(name);
    const x0 = writer.x0;
    const x = writer.x;
    Eif (value !== void 0) {
      if (value instanceof Value) {
        const type = value.type;
        const data = value.data;
        if (type && this.getTypeEncoder) this.getTypeEncoder(codec, type)(data, encoder);
        else Eif (data !== void 0) encoder.writeAny(data);
      } else encoder.writeAny(value);
    }
    const shift = writer.x0 - x0;
    const payloadStart = x + shift;
    const start = payloadStart - 4 - nameLength;
    const payloadSize = writer.x - payloadStart;
    writer.view.setUint32(start, (payloadSize << 8) + nameLength);
  }
 
  writeType3(codec: JsonValueCodec, typeU16: number, id: number, value: unknown | Value<any> | undefined): void {
    const encoder = codec.encoder;
    const writer = encoder.writer;
    writer.move(4);
    const x0 = writer.x0;
    const x = writer.x;
    if (value !== void 0) {
      if (value instanceof Value) {
        const type = value.type;
        const data = value.data;
        Iif (type && this.getTypeEncoder) this.getTypeEncoder(codec, type)(data, encoder);
        else Eif (data !== void 0) encoder.writeAny(data);
      } else encoder.writeAny(value);
    }
    const shift = writer.x0 - x0;
    const payloadStart = x + shift;
    const start = payloadStart - 4;
    const payloadSize = writer.x - payloadStart;
    this.writeHeader(writer, typeU16, id, payloadSize, start);
  }
 
  writeType4(
    codec: JsonValueCodec,
    typeU16: number,
    id: number,
    name: string,
    value: unknown | Value<any> | undefined,
  ): void {
    const encoder = codec.encoder;
    const writer = encoder.writer;
    const nameLength = name.length;
    writer.ensureCapacity(5 + nameLength);
    writer.uint8[writer.x + 4] = nameLength;
    writer.x += 5;
    writer.ascii(name);
    const x0 = writer.x0;
    const x = writer.x;
    if (value !== void 0) {
      if (value instanceof Value) {
        const type = value.type;
        const data = value.data;
        if (type && this.getTypeEncoder) this.getTypeEncoder(codec, type)(data, encoder);
        else Eif (data !== void 0) encoder.writeAny(data);
      } else encoder.writeAny(value);
    }
    const shift = writer.x0 - x0;
    const payloadStart = x + shift;
    const start = payloadStart - 5 - nameLength;
    const payloadSize = writer.x - payloadStart;
    this.writeHeader(writer, typeU16, id, payloadSize, start);
  }
}