All files / tar/lib large-numbers.js

100% Statements 59/59
100% Branches 20/20
100% Functions 8/8
100% Lines 57/57
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 83 84 85 86 87 88 89 90 91 92 93            14x 17x 17x 6x   11x 17x     14x 11x 11x 86x 29x   57x 57x         14x 6x 6x 6x 6x   60x 42x   18x 18x   60x 48x 12x 6x   6x 6x         14x 35x 35x 35x       14x 6x 6x 6x 6x 60x   60x 48x 12x 6x   6x 6x   60x 12x   6x     14x 29x 29x 29x 194x 194x 121x   29x     96x   14x  
'use strict'
// Tar can encode large and negative numbers using a leading byte of
// 0xff for negative, and 0x80 for positive.  The trailing byte in the
// section will always be 0x20, or in some implementations 0x00.
// this module encodes and decodes these things.
 
const encode = exports.encode = (num, buf) => {
  buf[buf.length - 1] = 0x20
  if (num < 0)
    encodeNegative(num, buf)
  else
    encodePositive(num, buf)
  return buf
}
 
const encodePositive = (num, buf) => {
  buf[0] = 0x80
  for (var i = buf.length - 2; i > 0; i--) {
    if (num === 0)
      buf[i] = 0
    else {
      buf[i] = num % 0x100
      num = Math.floor(num / 0x100)
    }
  }
}
 
const encodeNegative = (num, buf) => {
  buf[0] = 0xff
  var flipped = false
  num = num * -1
  for (var i = buf.length - 2; i > 0; i--) {
    var byte
    if (num === 0)
      byte = 0
    else {
      byte = num % 0x100
      num = Math.floor(num / 0x100)
    }
    if (flipped)
      buf[i] = onesComp(byte)
    else if (byte === 0)
      buf[i] = 0
    else {
      flipped = true
      buf[i] = twosComp(byte)
    }
  }
}
 
const parse = exports.parse = (buf) => {
  var post = buf[buf.length - 1]
  var pre = buf[0]
  return pre === 0x80 ? pos(buf.slice(1, buf.length - 1))
   : twos(buf.slice(1, buf.length - 1))
}
 
const twos = (buf) => {
  var len = buf.length
  var sum = 0
  var flipped = false
  for (var i = len - 1; i > -1; i--) {
    var byte = buf[i]
    var f
    if (flipped)
      f = onesComp(byte)
    else if (byte === 0)
      f = byte
    else {
      flipped = true
      f = twosComp(byte)
    }
    if (f !== 0)
      sum += f * Math.pow(256, len - i - 1)
  }
  return sum * -1
}
 
const pos = (buf) => {
  var len = buf.length
  var sum = 0
  for (var i = len - 1; i > -1; i--) {
    var byte = buf[i]
    if (byte !== 0)
      sum += byte * Math.pow(256, len - i - 1)
  }
  return sum
}
 
const onesComp = byte => (0xff ^ byte) & 0xff
 
const twosComp = byte => ((0xff ^ byte) + 1) & 0xff