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

100% Statements 37/37
100% Branches 12/12
100% Functions 6/6
100% Lines 36/36

    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

    1220x

    1220x

    11589x
    11589x

    4978x
    4978x
    4978x
    4978x

    773x
    773x
    773x
    773x

    9x
    9x
    9x
    9x

    5829x
    5829x

    11589x
    11589x

    11589x

    63x
    63x
    63x
    11044x
    5769x

    5460x
    5460x

    63x

    1530x
    1090x
    1090x

    1530x

     // @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.
      // Returns a new buffer unless one is passed in to be written to.
      buffer(buffer: ArrayBuffer = 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;
      }
    }