You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							105 lines
						
					
					
						
							2.2 KiB
						
					
					
				
			
		
		
	
	
							105 lines
						
					
					
						
							2.2 KiB
						
					
					
				'use strict'
 | 
						|
// Tar can encode large and negative numbers using a leading byte of
 | 
						|
// 0xff for negative, and 0x80 for positive.
 | 
						|
 | 
						|
const encode = (num, buf) => {
 | 
						|
  if (!Number.isSafeInteger(num)) {
 | 
						|
  // The number is so large that javascript cannot represent it with integer
 | 
						|
  // precision.
 | 
						|
    throw Error('cannot encode number outside of javascript safe integer range')
 | 
						|
  } else if (num < 0) {
 | 
						|
    encodeNegative(num, buf)
 | 
						|
  } else {
 | 
						|
    encodePositive(num, buf)
 | 
						|
  }
 | 
						|
  return buf
 | 
						|
}
 | 
						|
 | 
						|
const encodePositive = (num, buf) => {
 | 
						|
  buf[0] = 0x80
 | 
						|
 | 
						|
  for (var i = buf.length; i > 1; i--) {
 | 
						|
    buf[i - 1] = num & 0xff
 | 
						|
    num = Math.floor(num / 0x100)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const encodeNegative = (num, buf) => {
 | 
						|
  buf[0] = 0xff
 | 
						|
  var flipped = false
 | 
						|
  num = num * -1
 | 
						|
  for (var i = buf.length; i > 1; i--) {
 | 
						|
    var byte = num & 0xff
 | 
						|
    num = Math.floor(num / 0x100)
 | 
						|
    if (flipped) {
 | 
						|
      buf[i - 1] = onesComp(byte)
 | 
						|
    } else if (byte === 0) {
 | 
						|
      buf[i - 1] = 0
 | 
						|
    } else {
 | 
						|
      flipped = true
 | 
						|
      buf[i - 1] = twosComp(byte)
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const parse = (buf) => {
 | 
						|
  const pre = buf[0]
 | 
						|
  const value = pre === 0x80 ? pos(buf.slice(1, buf.length))
 | 
						|
    : pre === 0xff ? twos(buf)
 | 
						|
    : null
 | 
						|
  if (value === null) {
 | 
						|
    throw Error('invalid base256 encoding')
 | 
						|
  }
 | 
						|
 | 
						|
  if (!Number.isSafeInteger(value)) {
 | 
						|
  // The number is so large that javascript cannot represent it with integer
 | 
						|
  // precision.
 | 
						|
    throw Error('parsed number outside of javascript safe integer range')
 | 
						|
  }
 | 
						|
 | 
						|
  return value
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  encode,
 | 
						|
  parse,
 | 
						|
}
 |