1023e9be53e4196b4f6dca426701bf6ec73857a6934f76d830747d126c166bdfc9fd58e1e54d4389d0df75d046cabecae61f70917a9619fc56317ea7194c03 2.5 KB

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