ZigZagEncoding.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const { pow, floor } = Math;
  4. const TWO_POW_7 = pow(2, 7);
  5. const TWO_POW_14 = pow(2, 14);
  6. const TWO_POW_21 = pow(2, 21);
  7. const TWO_POW_28 = pow(2, 28);
  8. const TWO_POW_35 = pow(2, 35);
  9. const TWO_POW_42 = pow(2, 42);
  10. const TWO_POW_49 = pow(2, 49);
  11. const TWO_POW_56 = pow(2, 56);
  12. /**
  13. * This class provides encoding and decoding methods for writing and reading
  14. * ZigZag-encoded LEB128-64b9B-variant (Little Endian Base 128) values to/from a
  15. * {@link ByteBuffer}. LEB128's variable length encoding provides for using a
  16. * smaller nuber of bytes for smaller values, and the use of ZigZag encoding
  17. * allows small (closer to zero) negative values to use fewer bytes. Details
  18. * on both LEB128 and ZigZag can be readily found elsewhere.
  19. *
  20. * The LEB128-64b9B-variant encoding used here diverges from the "original"
  21. * LEB128 as it extends to 64 bit values: In the original LEB128, a 64 bit
  22. * value can take up to 10 bytes in the stream, where this variant's encoding
  23. * of a 64 bit values will max out at 9 bytes.
  24. *
  25. * As such, this encoder/decoder should NOT be used for encoding or decoding
  26. * "standard" LEB128 formats (e.g. Google Protocol Buffers).
  27. */
  28. class ZigZagEncoding {
  29. /**
  30. * Writes a long value to the given buffer in LEB128 ZigZag encoded format
  31. * (negative numbers not supported)
  32. * @param buffer the buffer to write to
  33. * @param value the value to write to the buffer
  34. */
  35. static encode(buffer, value) {
  36. if (value >= 0) {
  37. value = value * 2;
  38. }
  39. else {
  40. value = -value * 2 - 1;
  41. }
  42. if (value < TWO_POW_7) {
  43. buffer.put(value);
  44. }
  45. else {
  46. buffer.put(value | 0x80);
  47. if (value < TWO_POW_14) {
  48. buffer.put(floor(value / TWO_POW_7));
  49. }
  50. else {
  51. buffer.put(floor(value / TWO_POW_7) | 0x80);
  52. if (value < TWO_POW_21) {
  53. buffer.put(floor(value / TWO_POW_14));
  54. }
  55. else {
  56. buffer.put(floor(value / TWO_POW_14) | 0x80);
  57. if (value < TWO_POW_28) {
  58. buffer.put(floor(value / TWO_POW_21));
  59. }
  60. else {
  61. buffer.put(floor(value / TWO_POW_21) | 0x80);
  62. if (value < TWO_POW_35) {
  63. buffer.put(floor(value / TWO_POW_28));
  64. }
  65. else {
  66. buffer.put(floor(value / TWO_POW_28) | 0x80);
  67. if (value < TWO_POW_42) {
  68. buffer.put(floor(value / TWO_POW_35));
  69. }
  70. else {
  71. buffer.put(floor(value / TWO_POW_35) | 0x80);
  72. if (value < TWO_POW_49) {
  73. buffer.put(floor(value / TWO_POW_42));
  74. }
  75. else {
  76. buffer.put(floor(value / TWO_POW_42) | 0x80);
  77. if (value < TWO_POW_56) {
  78. buffer.put(floor(value / TWO_POW_49));
  79. }
  80. else {
  81. // should not happen
  82. buffer.put(floor(value / TWO_POW_49) + 0x80);
  83. buffer.put(floor(value / TWO_POW_56));
  84. }
  85. }
  86. }
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93. /**
  94. * Read an LEB128-64b9B ZigZag encoded long value from the given buffer
  95. * (negative numbers not supported)
  96. * @param buffer the buffer to read from
  97. * @return the value read from the buffer
  98. */
  99. static decode(buffer) {
  100. let v = buffer.get();
  101. let value = v & 0x7f;
  102. if ((v & 0x80) != 0) {
  103. v = buffer.get();
  104. value += (v & 0x7f) * TWO_POW_7;
  105. if ((v & 0x80) != 0) {
  106. v = buffer.get();
  107. value += (v & 0x7f) * TWO_POW_14;
  108. if ((v & 0x80) != 0) {
  109. v = buffer.get();
  110. value += (v & 0x7f) * TWO_POW_21;
  111. if ((v & 0x80) != 0) {
  112. v = buffer.get();
  113. value += (v & 0x7f) * TWO_POW_28;
  114. if ((v & 0x80) != 0) {
  115. v = buffer.get();
  116. value += (v & 0x7f) * TWO_POW_35;
  117. if ((v & 0x80) != 0) {
  118. v = buffer.get();
  119. value += (v & 0x7f) * TWO_POW_42;
  120. if ((v & 0x80) != 0) {
  121. v = buffer.get();
  122. value += (v & 0x7f) * TWO_POW_49;
  123. if ((v & 0x80) != 0) {
  124. v = buffer.get();
  125. value += (v & 0x7f) * TWO_POW_56;
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. }
  133. }
  134. if (value % 2 === 0) {
  135. value = value / 2;
  136. }
  137. else {
  138. value = -(value + 1) / 2;
  139. }
  140. return value;
  141. }
  142. }
  143. exports.default = ZigZagEncoding;
  144. //# sourceMappingURL=ZigZagEncoding.js.map