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

    1280x

    1280x

    12048x
    12048x

    5153x
    5153x
    5153x
    5153x

    804x
    804x
    804x
    804x

    6x
    6x
    6x
    6x

    6085x
    6085x

    12048x
    12048x

    12048x

    66x
    66x
    66x
    11470x
    5982x

    5689x
    5689x

    66x

    1609x
    1144x
    1144x

    1609x

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