| 84 | * ``` |
| 85 | */ |
| 86 | export function decodeVarint(buf: Uint8Array, offset = 0): [bigint, number] { |
| 87 | // Clear the last result from the Two's complement view |
| 88 | U64_VIEW[0] = 0n; |
| 89 | |
| 90 | // Setup the initiat state of the function |
| 91 | let intermediate = 0; |
| 92 | let position = 0; |
| 93 | let i = offset; |
| 94 | |
| 95 | // If the buffer is empty Throw |
| 96 | if (buf.length === 0) throw new RangeError("Cannot read empty buffer"); |
| 97 | |
| 98 | let byte; |
| 99 | do { |
| 100 | // Get a single byte from the buffer |
| 101 | byte = buf[i]!; |
| 102 | |
| 103 | // 1. Take the lower 7 bits of the byte. |
| 104 | // 2. Shift the bits into the correct position. |
| 105 | // 3. Bitwise OR it with the intermediate value |
| 106 | // QUIRK: in the 5th (and 10th) iteration of this loop it will overflow on the shift. |
| 107 | // This causes only the lower 4 bits to be shifted into place and removing the upper 3 bits |
| 108 | intermediate |= (byte & 0b01111111) << position; |
| 109 | |
| 110 | // If position is 28 |
| 111 | // it means that this iteration needs to be written the the two's complement view |
| 112 | // This only happens once due to the `-4` in this branch |
| 113 | if (position === 28) { |
| 114 | // Write to the view |
| 115 | U32_VIEW[0] = intermediate; |
| 116 | // set `intermediate` to the remaining 3 bits |
| 117 | // We only want the remaining three bits because the other 4 have been "consumed" on line 21 |
| 118 | intermediate = (byte & 0b01110000) >>> 4; |
| 119 | // set `position` to -4 because later 7 will be added, making it 3 |
| 120 | position = -4; |
| 121 | } |
| 122 | |
| 123 | // Increment the shift position by 7 |
| 124 | position += 7; |
| 125 | // Increment the iterator by 1 |
| 126 | i++; |
| 127 | // Keep going while there is a continuation bit |
| 128 | } while ((byte & 0b10000000) === 0b10000000); |
| 129 | // subtract the initial offset from `i` to get the bytes read |
| 130 | const nRead = i - offset; |
| 131 | |
| 132 | // If 10 bytes have been read and intermediate has overflown |
| 133 | // it means that the varint is malformed |
| 134 | // If 11 bytes have been read it means that the varint is malformed |
| 135 | // If `i` is bigger than the buffer it means we overread the buffer and the varint is malformed |
| 136 | if ((nRead === 10 && intermediate > -1) || nRead === 11 || i > buf.length) { |
| 137 | throw new RangeError( |
| 138 | "Cannot decode the varint input: Malformed or overflow varint", |
| 139 | ); |
| 140 | } |
| 141 | |
| 142 | // Write the intermediate value to the "empty" slot |
| 143 | // if the first slot is taken. Take the second slot |