Skip to content

Commit

Permalink
refactor: rename try basic latin functions to be consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken committed Feb 9, 2024
1 parent 1214643 commit 3aca300
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 40 deletions.
8 changes: 6 additions & 2 deletions src/utils/latin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
* @param end - The index to stop searching the uint8array
* @returns string if all bytes are within the basic latin range, otherwise null
*/
export function tryLatin(uint8array: Uint8Array, start: number, end: number): string | null {
export function tryReadBasicLatin(
uint8array: Uint8Array,
start: number,
end: number
): string | null {
if (uint8array.length === 0) {
return '';
}
Expand Down Expand Up @@ -74,7 +78,7 @@ export function tryLatin(uint8array: Uint8Array, start: number, end: number): st
* @param offset - The position in the destination to begin writing bytes to
* @returns the number of bytes written to destination if all code units are below 128, otherwise null
*/
export function tryWriteLatin(
export function tryWriteBasicLatin(
destination: Uint8Array,
source: string,
offset: number
Expand Down
6 changes: 3 additions & 3 deletions src/utils/node_byte_utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BSONError } from '../error';
import { validateUtf8 } from '../validate_utf8';
import { tryLatin, tryWriteLatin } from './latin';
import { tryReadBasicLatin, tryWriteBasicLatin } from './latin';

type NodeJsEncoding = 'base64' | 'hex' | 'utf8' | 'binary';
type NodeJsBuffer = ArrayBufferView &
Expand Down Expand Up @@ -124,7 +124,7 @@ export const nodeJsByteUtils = {
},

toUTF8(buffer: Uint8Array, start: number, end: number, fatal: boolean): string {
const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
const basicLatin = end - start <= 20 ? tryReadBasicLatin(buffer, start, end) : null;
if (basicLatin != null) {
return basicLatin;
}
Expand All @@ -149,7 +149,7 @@ export const nodeJsByteUtils = {
},

encodeUTF8Into(buffer: Uint8Array, source: string, byteOffset: number): number {
const latinBytesWritten = tryWriteLatin(buffer, source, byteOffset);
const latinBytesWritten = tryWriteBasicLatin(buffer, source, byteOffset);
if (latinBytesWritten != null) {
return latinBytesWritten;
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/web_byte_utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BSONError } from '../error';
import { tryLatin } from './latin';
import { tryReadBasicLatin } from './latin';

type TextDecoder = {
readonly encoding: string;
Expand Down Expand Up @@ -170,7 +170,7 @@ export const webByteUtils = {
},

toUTF8(uint8array: Uint8Array, start: number, end: number, fatal: boolean): string {
const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
const basicLatin = end - start <= 20 ? tryReadBasicLatin(uint8array, start, end) : null;
if (basicLatin != null) {
return basicLatin;
}
Expand Down
67 changes: 34 additions & 33 deletions test/node/utils/latin.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { expect } from 'chai';
import { tryLatin, tryWriteLatin } from '../../../src/utils/latin';
import { tryReadBasicLatin, tryWriteBasicLatin } from '../../../src/utils/latin';
import * as sinon from 'sinon';

describe('tryLatin()', () => {
describe('tryReadBasicLatin()', () => {
context('when given a buffer of length 0', () => {
it('returns an empty string', () => {
expect(tryLatin(new Uint8Array(), 0, 10)).to.equal('');
expect(tryReadBasicLatin(new Uint8Array(), 0, 10)).to.equal('');
});
});

context('when the distance between end and start is 0', () => {
it('returns an empty string', () => {
expect(tryLatin(new Uint8Array([1, 2, 3]), 0, 0)).to.equal('');
expect(tryReadBasicLatin(new Uint8Array([1, 2, 3]), 0, 0)).to.equal('');
});
});

Expand All @@ -30,61 +30,61 @@ describe('tryLatin()', () => {
context('when there is 1 byte', () => {
context('that exceed 127', () => {
it('returns null', () => {
expect(tryLatin(new Uint8Array([128]), 0, 1)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128]), 0, 1)).be.null;
});
});

it('calls fromCharCode once', () => {
tryLatin(new Uint8Array([95]), 0, 1);
tryReadBasicLatin(new Uint8Array([95]), 0, 1);
expect(fromCharCodeSpy).to.have.been.calledOnce;
});

it('never calls array.push', () => {
tryLatin(new Uint8Array([95]), 0, 1);
tryReadBasicLatin(new Uint8Array([95]), 0, 1);
expect(pushSpy).to.have.not.been.called;
});
});

context('when there is 2 bytes', () => {
context('that exceed 127', () => {
it('returns null', () => {
expect(tryLatin(new Uint8Array([0, 128]), 0, 2)).be.null;
expect(tryLatin(new Uint8Array([128, 0]), 0, 2)).be.null;
expect(tryLatin(new Uint8Array([128, 128]), 0, 2)).be.null;
expect(tryReadBasicLatin(new Uint8Array([0, 128]), 0, 2)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128, 0]), 0, 2)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128, 128]), 0, 2)).be.null;
});
});

it('calls fromCharCode twice', () => {
tryLatin(new Uint8Array([95, 105]), 0, 2);
tryReadBasicLatin(new Uint8Array([95, 105]), 0, 2);
expect(fromCharCodeSpy).to.have.been.calledTwice;
});

it('never calls array.push', () => {
tryLatin(new Uint8Array([95, 105]), 0, 2);
tryReadBasicLatin(new Uint8Array([95, 105]), 0, 2);
expect(pushSpy).to.have.not.been.called;
});
});

context('when there is 3 bytes', () => {
context('that exceed 127', () => {
it('returns null', () => {
expect(tryLatin(new Uint8Array([0, 0, 128]), 0, 3)).be.null;
expect(tryLatin(new Uint8Array([0, 128, 0]), 0, 3)).be.null;
expect(tryLatin(new Uint8Array([128, 0, 0]), 0, 3)).be.null;
expect(tryLatin(new Uint8Array([128, 128, 128]), 0, 3)).be.null;
expect(tryLatin(new Uint8Array([128, 128, 0]), 0, 3)).be.null;
expect(tryLatin(new Uint8Array([128, 0, 128]), 0, 3)).be.null;
expect(tryLatin(new Uint8Array([0, 128, 128]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([0, 0, 128]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([0, 128, 0]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128, 0, 0]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128, 128, 128]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128, 128, 0]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([128, 0, 128]), 0, 3)).be.null;
expect(tryReadBasicLatin(new Uint8Array([0, 128, 128]), 0, 3)).be.null;
});
});

it('calls fromCharCode thrice', () => {
tryLatin(new Uint8Array([95, 105, 100]), 0, 3);
tryReadBasicLatin(new Uint8Array([95, 105, 100]), 0, 3);
expect(fromCharCodeSpy).to.have.been.calledThrice;
});

it('never calls array.push', () => {
tryLatin(new Uint8Array([95, 105, 100]), 0, 3);
tryReadBasicLatin(new Uint8Array([95, 105, 100]), 0, 3);
expect(pushSpy).to.have.not.been.called;
});
});
Expand All @@ -93,44 +93,45 @@ describe('tryLatin()', () => {
context(`when there is ${stringLength} bytes`, () => {
context('that exceed 127', () => {
it('returns null', () => {
expect(tryLatin(new Uint8Array(stringLength).fill(128), 0, stringLength)).be.null;
expect(tryReadBasicLatin(new Uint8Array(stringLength).fill(128), 0, stringLength)).be
.null;
});
});

it('calls fromCharCode once', () => {
tryLatin(new Uint8Array(stringLength).fill(95), 0, stringLength);
tryReadBasicLatin(new Uint8Array(stringLength).fill(95), 0, stringLength);
expect(fromCharCodeSpy).to.have.been.calledOnce;
});

it(`calls array.push ${stringLength}`, () => {
tryLatin(new Uint8Array(stringLength).fill(95), 0, stringLength);
tryReadBasicLatin(new Uint8Array(stringLength).fill(95), 0, stringLength);
expect(pushSpy).to.have.callCount(stringLength);
});
});
}

context('when there is >21 bytes', () => {
it('returns null', () => {
expect(tryLatin(new Uint8Array(21).fill(95), 0, 21)).be.null;
expect(tryLatin(new Uint8Array(201).fill(95), 0, 201)).be.null;
expect(tryReadBasicLatin(new Uint8Array(21).fill(95), 0, 21)).be.null;
expect(tryReadBasicLatin(new Uint8Array(201).fill(95), 0, 201)).be.null;
});
});
});

describe('tryWriteLatin()', () => {
describe('tryWriteBasicLatin()', () => {
context('when given a string of length 0', () => {
it('returns 0 and does not modify the destination', () => {
const input = Uint8Array.from({ length: 10 }, () => 1);
expect(tryWriteLatin(input, '', 2)).to.equal(0);
expect(tryWriteBasicLatin(input, '', 2)).to.equal(0);
expect(input).to.deep.equal(Uint8Array.from({ length: 10 }, () => 1));
});
});

context('when given a string with a length larger than the buffer', () => {
it('returns null', () => {
const input = Uint8Array.from({ length: 10 }, () => 1);
expect(tryWriteLatin(input, 'a'.repeat(11), 0)).to.be.null;
expect(tryWriteLatin(input, 'a'.repeat(13), 2)).to.be.null;
expect(tryWriteBasicLatin(input, 'a'.repeat(11), 0)).to.be.null;
expect(tryWriteBasicLatin(input, 'a'.repeat(13), 2)).to.be.null;
});
});

Expand All @@ -149,7 +150,7 @@ describe('tryWriteLatin()', () => {
context('that exceed 127', () => {
it('returns null', () => {
expect(
tryWriteLatin(
tryWriteBasicLatin(
new Uint8Array(stringLength * 3),
'a'.repeat(stringLength - 1) + '\x80',
0
Expand All @@ -159,7 +160,7 @@ describe('tryWriteLatin()', () => {
});

it(`calls charCodeAt ${stringLength}`, () => {
tryWriteLatin(
tryWriteBasicLatin(
new Uint8Array(stringLength * 3),
String.fromCharCode(127).repeat(stringLength),
stringLength
Expand All @@ -171,7 +172,7 @@ describe('tryWriteLatin()', () => {

context('when there is >25 characters', () => {
it('returns null', () => {
expect(tryWriteLatin(new Uint8Array(75), 'a'.repeat(26), 0)).be.null;
expect(tryWriteBasicLatin(new Uint8Array(75), 'a'.repeat(26), 0)).be.null;
});
});
});

0 comments on commit 3aca300

Please sign in to comment.