# 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
    27x
    27x
    27x

    1403x

    1403x

    22954x
    22954x

    13454x
    13454x
    13454x
    13454x

    1113x
    1113x
    1113x
    1113x

    9x
    9x
    9x
    9x

    8378x
    8378x

    22954x
    22954x

    22954x

    72x
    72x
    72x
    22402x
    14610x

    8002x
    8002x

    72x

    1736x
    1257x
    1257x

    1736x

     // @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;
      }
    }