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