1'use strict' 2// Tar can encode large and negative numbers using a leading byte of 3// 0xff for negative, and 0x80 for positive. 4 5const encode = exports.encode = (num, buf) => { 6 if (!Number.isSafeInteger(num)) 7 // The number is so large that javascript cannot represent it with integer 8 // precision. 9 throw TypeError('cannot encode number outside of javascript safe integer range') 10 else if (num < 0) 11 encodeNegative(num, buf) 12 else 13 encodePositive(num, buf) 14 return buf 15} 16 17const encodePositive = (num, buf) => { 18 buf[0] = 0x80 19 20 for (var i = buf.length; i > 1; i--) { 21 buf[i-1] = num & 0xff 22 num = Math.floor(num / 0x100) 23 } 24} 25 26const encodeNegative = (num, buf) => { 27 buf[0] = 0xff 28 var flipped = false 29 num = num * -1 30 for (var i = buf.length; i > 1; i--) { 31 var byte = num & 0xff 32 num = Math.floor(num / 0x100) 33 if (flipped) 34 buf[i-1] = onesComp(byte) 35 else if (byte === 0) 36 buf[i-1] = 0 37 else { 38 flipped = true 39 buf[i-1] = twosComp(byte) 40 } 41 } 42} 43 44const parse = exports.parse = (buf) => { 45 var post = buf[buf.length - 1] 46 var pre = buf[0] 47 var value; 48 if (pre === 0x80) 49 value = pos(buf.slice(1, buf.length)) 50 else if (pre === 0xff) 51 value = twos(buf) 52 else 53 throw TypeError('invalid base256 encoding') 54 55 if (!Number.isSafeInteger(value)) 56 // The number is so large that javascript cannot represent it with integer 57 // precision. 58 throw TypeError('parsed number outside of javascript safe integer range') 59 60 return value 61} 62 63const twos = (buf) => { 64 var len = buf.length 65 var sum = 0 66 var flipped = false 67 for (var i = len - 1; i > -1; i--) { 68 var byte = buf[i] 69 var f 70 if (flipped) 71 f = onesComp(byte) 72 else if (byte === 0) 73 f = byte 74 else { 75 flipped = true 76 f = twosComp(byte) 77 } 78 if (f !== 0) 79 sum -= f * Math.pow(256, len - i - 1) 80 } 81 return sum 82} 83 84const pos = (buf) => { 85 var len = buf.length 86 var sum = 0 87 for (var i = len - 1; i > -1; i--) { 88 var byte = buf[i] 89 if (byte !== 0) 90 sum += byte * Math.pow(256, len - i - 1) 91 } 92 return sum 93} 94 95const onesComp = byte => (0xff ^ byte) & 0xff 96 97const twosComp = byte => ((0xff ^ byte) + 1) & 0xff 98