# All files Stack.ts

3.23% Statements 1/31
0% Branches 0/14
0% Functions 0/2
3.33% Lines 1/30

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
    77
    78
    79
    80
    81
    821x

     export class Stack {
      /**
       * Decodes a number from the stack format (signed magnitude
       * representation).
       * @param buf
       */
      public static decodeNum(buf: Buffer): bigint {
        let result = BigInt(0);
        if (buf.length === 0) {
          return result;
        }

        // convert little-endian number to big-endian which swaps around the bytes
        // that occurred during encoding making the negative flag be in the first
        // byte
        const be = Buffer.from(buf).reverse();

        // check if the number is negative, which occurs when the 0x80 bit is set
        // on the first number
        let neg = false;
        if (be[0] & 0x80) {
          neg = true;
          be[0] = be[0] & 0x7f; // remove the 0x80 bit
        }

        // set result to MSB
        result = BigInt(be[0]);

        // read each byte off the buffer
        for (let i = 1; i < be.length; i++) {
          result <<= BigInt(8); // shift right 1-byte
          result += BigInt(be[i]);
        }

        if (neg) {
          return -result;
        } else {
          return result;
        }
      }

      /**
       * Encodes a number into a stack compatible byte-array. The number
       * is encoded using little-endian signed-magnitude representation.
       * @param num
       */
      public static encodeNum(input: number | bigint): Buffer {
        const num = BigInt(input);

        const bytes = [];
        const neg = num < 0;
        let abs = num > 0 ? num : -num;

        // push each byte starting with the smallest
        while (abs > 0) {
          bytes.push(Number(abs & BigInt(0xff))); // push on smallest byte
          abs >>= BigInt(8); // shift off smallest byte
        }

        // check if the last byte has the 0x80 bit set if so, then we either push
        // a 0 or 0x80 if it is postive or negative
        if (bytes[bytes.length - 1] & 0x80) {
          if (neg) {
            bytes.push(0x80);
          } else {
            bytes.push(0x00);
          }
        }

        // if the number is negative we set the 0x80 bit for the number to indicate
        // it is negative
        else {
          if (neg) {
            bytes[bytes.length - 1] |= 0x80;
          }
        }

        // return a buffer of the number
        return Buffer.from(bytes);
      }
    }