All files / json-pack/src/cbor CborEncoder.ts

89.74% Statements 35/39
88% Branches 22/25
83.33% Functions 5/6
94.11% Lines 32/34

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 7712x 12x 12x 12x     12x                     352721x   279366x   57861x   2278x   12259x 11278x 11278x     6574x   4648x   42x   3x   5x   1x 1x     5x 4x 4x 4x       4x   953x             4324x 4305x       3x 3x 5x 5x         3x      
import {isFloat32} from '@jsonjoy.com/buffers/lib/isFloat32';
import {JsonPackExtension} from '../JsonPackExtension';
import {CborEncoderFast} from './CborEncoderFast';
import {JsonPackValue} from '../JsonPackValue';
import type {IWriter, IWriterGrowable} from '@jsonjoy.com/buffers/lib';
 
export class CborEncoder<W extends IWriter & IWriterGrowable = IWriter & IWriterGrowable> extends CborEncoderFast<W> {
  /**
   * Called when the encoder encounters a value that it does not know how to encode.
   *
   * @param value Some JavaScript value.
   */
  public writeUnknown(value: unknown): void {
    this.writeNull();
  }
 
  public writeAny(value: unknown): void {
    switch (typeof value) {
      case 'number':
        return this.writeNumber(value as number);
      case 'string':
        return this.writeStr(value);
      case 'boolean':
        return this.writer.u8(0xf4 + +value);
      case 'object': {
        if (!value) return this.writer.u8(0xf6);
        const constr = value.constructor;
        switch (constr) {
          case Object:
          case undefined:
            return this.writeObj(value as Record<string, unknown>);
          case Array:
            return this.writeArr(value as unknown[]);
          case Uint8Array:
            return this.writeBin(value as Uint8Array);
          case Map:
            return this.writeMap(value as Map<unknown, unknown>);
          case JsonPackExtension:
            return this.writeTag((<JsonPackExtension>value).tag, (<JsonPackExtension>value).val);
          case JsonPackValue: {
            const buf = (value as JsonPackValue).val;
            return this.writer.buf(buf, buf.length);
          }
          default:
            if (value instanceof Uint8Array) return this.writeBin(value);
            Iif (Array.isArray(value)) return this.writeArr(value);
            Iif (value instanceof Map) return this.writeMap(value);
            return this.writeUnknown(value);
        }
      }
      case 'undefined':
        return this.writeUndef();
      case 'bigint':
        return this.writeBigInt(value as bigint);
      default:
        return this.writeUnknown(value);
    }
  }
 
  public writeFloat(float: number): void {
    if (isFloat32(float)) this.writer.u8f32(0xfa, float);
    else this.writer.u8f64(0xfb, float);
  }
 
  public writeMap(map: Map<unknown, unknown>): void {
    this.writeMapHdr(map.size);
    map.forEach((value, key) => {
      this.writeAny(key);
      this.writeAny(value);
    });
  }
 
  public writeUndef(): void {
    this.writer.u8(0xf7);
  }
}