Skip to content

Commit 29229d3

Browse files
Merge branch 'mrschmidt/numbersonly' into mrschmidt/utf8
2 parents ffa4e12 + 92a8b8e commit 29229d3

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

packages/firestore/src/index/ordered_code_writer.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17+
import { debugAssert } from '../util/assert';
1718

1819

1920
/** These constants are taken from the backend. */
@@ -37,13 +38,10 @@ const BYTE_SIZE = 8;
3738
*/
3839
const DEFAULT_BUFFER_SIZE = 1024;
3940

40-
/**
41-
* Converts a JavaScript number to a byte array (using little endian
42-
* encoding).
43-
*/
41+
/** Converts a JavaScript number to a byte array (using big endian encoding). */
4442
function doubleToLongBits(value: number): Uint8Array {
4543
const dv = new DataView(new ArrayBuffer(8));
46-
dv.setFloat64(0, value, false);
44+
dv.setFloat64(0, value, /* littleEndian= */ false);
4745
return new Uint8Array(dv.buffer);
4846
}
4947

@@ -53,6 +51,7 @@ function doubleToLongBits(value: number): Uint8Array {
5351
* Visible for testing.
5452
*/
5553
export function numberOfLeadingZerosInByte(x: number): number {
54+
debugAssert(x < 256, 'Provided value is not a byte: ' + x);
5655
if (x === 0) {
5756
return 8;
5857
}
@@ -77,8 +76,12 @@ export function numberOfLeadingZerosInByte(x: number): number {
7776

7877
/** Counts the number of leading zeros in the given byte array. */
7978
function numberOfLeadingZeros(bytes: Uint8Array): number {
79+
debugAssert(
80+
bytes.length == 8,
81+
'Can only count leading zeros in 64-bit numbers'
82+
);
8083
let leadingZeros = 0;
81-
for (let i = 0; i < bytes.length; ++i) {
84+
for (let i = 0; i < 8; ++i) {
8285
const zeros = numberOfLeadingZerosInByte(bytes[i] & 0xff);
8386
leadingZeros += zeros;
8487
if (zeros !== 8) {
@@ -157,6 +160,8 @@ export class OrderedCodeWriter {
157160
}
158161

159162
writeNumberAscending(val: number): void {
163+
// Values are encoded with a single byte length prefix, followed by the
164+
// actual value in big-endian format with leading 0 bytes dropped.
160165
const value = this.toOrderedBits(val);
161166
const len = unsignedNumLength(value);
162167
this.ensureAvailable(1 + len);
@@ -167,6 +172,8 @@ export class OrderedCodeWriter {
167172
}
168173

169174
writeNumberDescending(val: number): void {
175+
// Values are encoded with a single byte length prefix, followed by the
176+
// inverted value in big-endian format with leading 0 bytes dropped.
170177
const value = this.toOrderedBits(val);
171178
const len = unsignedNumLength(value);
172179
this.ensureAvailable(1 + len);
@@ -185,7 +192,11 @@ export class OrderedCodeWriter {
185192
*/
186193
private toOrderedBits(val: number): Uint8Array {
187194
const value = doubleToLongBits(val);
195+
// Check if the first bit is set. We use a bit mask since value[0] is
196+
// encoded as a number from 0 to 255.
188197
const isNegative = (value[0] & 0x80) !== 0;
198+
199+
// Revert the two complement to get natural ordering
189200
value[0] ^= isNegative ? 0xff : 0x80;
190201
for (let i = 1; i < value.length; ++i) {
191202
value[i] ^= isNegative ? 0xff : 0x00;

0 commit comments

Comments
 (0)