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
			| 
								 
											3 years ago
										 
									 | 
							
								'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,
							 | 
						||
| 
								 | 
							
								}
							 |