# All files / src/utils output-stream.js

100% Statements 38/38
100% Branches 11/11
100% Functions 6/6
100% Lines 37/37

    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
    23x
    23x
    23x

    1218x

    1218x

    12878x
    12878x

    6173x
    6173x
    6173x
    6173x

    743x
    743x
    743x
    743x

    9x
    9x
    9x
    9x

    5953x
    5953x

    12878x
    12878x

    12878x

    59x
    59x
    59x
    59x
    11151x
    5691x

    5648x
    5648x

    59x

    1450x
    1098x
    1098x

    1450x

     // @flow
    import invariant from "invariant";
    import { encodeSigned, encodeUnsigned } from "./leb128";
    import { sizeof, set, u8 } from "wasm-types";

    // Used to output raw binary, holds values and types in a large array 'stream'
    export default class OutputStream {
      data: Array<any>;
      size: number;

      constructor() {
        // Our data, expand it
        this.data = [];

        // start at the beginning
        this.size = 0;
      }

      push(type: string, value: any, debug: string) {
        let size = 0;
        switch (type) {
          case "varuint7":
          case "varuint32":
          case "varint7":
          case "varint1": {
            // Encode all of the LEB128 aka 'var*' types
            value = encodeUnsigned(value);
            size = value.length;
            invariant(size, `Cannot write a value of size ${size}`);
            break;
          }
          case "varint32": {
            value = encodeSigned(value);
            size = value.length;
            invariant(size, `Cannot write a value of size ${size}`);
            break;
          }
          case "varint64": {
            value = encodeSigned(value);
            size = value.length;
            invariant(size, `Cannot write a value of size ${size}`);
            break;
          }
          default: {
            size = sizeof[type];
            invariant(size, `Cannot write a value of size ${size}, type ${type}`);
          }
        }

        this.data.push({ type, value, debug });
        this.size += size;

        return this;
      }

      // Get the BUFFER, not data array. **Always creates new buffer**
      buffer() {
        const buffer = new ArrayBuffer(this.size);
        const view = new DataView(buffer);
        let pc = 0;
        this.data.forEach(({ type, value }) => {
          if (Array.isArray(value)) {
            value.forEach(v => set(u8, pc++, view, v));
          } else {
            set(type, pc, view, value);
            pc += sizeof[type];
          }
        });
        return buffer;
      }

      // Writes source OutputStream into the current buffer
      write(source: ?OutputStream) {
        if (source) {
          this.data = this.data.concat(source.data);
          this.size += source.size;
        }

        return this;
      }
    }