11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci// Tar can encode large and negative numbers using a leading byte of
31cb0ef41Sopenharmony_ci// 0xff for negative, and 0x80 for positive.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst encode = (num, buf) => {
61cb0ef41Sopenharmony_ci  if (!Number.isSafeInteger(num)) {
71cb0ef41Sopenharmony_ci  // The number is so large that javascript cannot represent it with integer
81cb0ef41Sopenharmony_ci  // precision.
91cb0ef41Sopenharmony_ci    throw Error('cannot encode number outside of javascript safe integer range')
101cb0ef41Sopenharmony_ci  } else if (num < 0) {
111cb0ef41Sopenharmony_ci    encodeNegative(num, buf)
121cb0ef41Sopenharmony_ci  } else {
131cb0ef41Sopenharmony_ci    encodePositive(num, buf)
141cb0ef41Sopenharmony_ci  }
151cb0ef41Sopenharmony_ci  return buf
161cb0ef41Sopenharmony_ci}
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciconst encodePositive = (num, buf) => {
191cb0ef41Sopenharmony_ci  buf[0] = 0x80
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci  for (var i = buf.length; i > 1; i--) {
221cb0ef41Sopenharmony_ci    buf[i - 1] = num & 0xff
231cb0ef41Sopenharmony_ci    num = Math.floor(num / 0x100)
241cb0ef41Sopenharmony_ci  }
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciconst encodeNegative = (num, buf) => {
281cb0ef41Sopenharmony_ci  buf[0] = 0xff
291cb0ef41Sopenharmony_ci  var flipped = false
301cb0ef41Sopenharmony_ci  num = num * -1
311cb0ef41Sopenharmony_ci  for (var i = buf.length; i > 1; i--) {
321cb0ef41Sopenharmony_ci    var byte = num & 0xff
331cb0ef41Sopenharmony_ci    num = Math.floor(num / 0x100)
341cb0ef41Sopenharmony_ci    if (flipped) {
351cb0ef41Sopenharmony_ci      buf[i - 1] = onesComp(byte)
361cb0ef41Sopenharmony_ci    } else if (byte === 0) {
371cb0ef41Sopenharmony_ci      buf[i - 1] = 0
381cb0ef41Sopenharmony_ci    } else {
391cb0ef41Sopenharmony_ci      flipped = true
401cb0ef41Sopenharmony_ci      buf[i - 1] = twosComp(byte)
411cb0ef41Sopenharmony_ci    }
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciconst parse = (buf) => {
461cb0ef41Sopenharmony_ci  const pre = buf[0]
471cb0ef41Sopenharmony_ci  const value = pre === 0x80 ? pos(buf.slice(1, buf.length))
481cb0ef41Sopenharmony_ci    : pre === 0xff ? twos(buf)
491cb0ef41Sopenharmony_ci    : null
501cb0ef41Sopenharmony_ci  if (value === null) {
511cb0ef41Sopenharmony_ci    throw Error('invalid base256 encoding')
521cb0ef41Sopenharmony_ci  }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  if (!Number.isSafeInteger(value)) {
551cb0ef41Sopenharmony_ci  // The number is so large that javascript cannot represent it with integer
561cb0ef41Sopenharmony_ci  // precision.
571cb0ef41Sopenharmony_ci    throw Error('parsed number outside of javascript safe integer range')
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  return value
611cb0ef41Sopenharmony_ci}
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ciconst twos = (buf) => {
641cb0ef41Sopenharmony_ci  var len = buf.length
651cb0ef41Sopenharmony_ci  var sum = 0
661cb0ef41Sopenharmony_ci  var flipped = false
671cb0ef41Sopenharmony_ci  for (var i = len - 1; i > -1; i--) {
681cb0ef41Sopenharmony_ci    var byte = buf[i]
691cb0ef41Sopenharmony_ci    var f
701cb0ef41Sopenharmony_ci    if (flipped) {
711cb0ef41Sopenharmony_ci      f = onesComp(byte)
721cb0ef41Sopenharmony_ci    } else if (byte === 0) {
731cb0ef41Sopenharmony_ci      f = byte
741cb0ef41Sopenharmony_ci    } else {
751cb0ef41Sopenharmony_ci      flipped = true
761cb0ef41Sopenharmony_ci      f = twosComp(byte)
771cb0ef41Sopenharmony_ci    }
781cb0ef41Sopenharmony_ci    if (f !== 0) {
791cb0ef41Sopenharmony_ci      sum -= f * Math.pow(256, len - i - 1)
801cb0ef41Sopenharmony_ci    }
811cb0ef41Sopenharmony_ci  }
821cb0ef41Sopenharmony_ci  return sum
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ciconst pos = (buf) => {
861cb0ef41Sopenharmony_ci  var len = buf.length
871cb0ef41Sopenharmony_ci  var sum = 0
881cb0ef41Sopenharmony_ci  for (var i = len - 1; i > -1; i--) {
891cb0ef41Sopenharmony_ci    var byte = buf[i]
901cb0ef41Sopenharmony_ci    if (byte !== 0) {
911cb0ef41Sopenharmony_ci      sum += byte * Math.pow(256, len - i - 1)
921cb0ef41Sopenharmony_ci    }
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci  return sum
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ciconst onesComp = byte => (0xff ^ byte) & 0xff
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciconst twosComp = byte => ((0xff ^ byte) + 1) & 0xff
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_cimodule.exports = {
1021cb0ef41Sopenharmony_ci  encode,
1031cb0ef41Sopenharmony_ci  parse,
1041cb0ef41Sopenharmony_ci}
105