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 |
---|