bson 4.1.0 → 4.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +48 -1
- package/README.md +7 -9
- package/bower.json +1 -1
- package/bson.d.ts +986 -0
- package/dist/bson.browser.esm.js +7811 -5011
- package/dist/bson.browser.esm.js.map +1 -0
- package/dist/bson.browser.umd.js +7862 -5099
- package/dist/bson.browser.umd.js.map +1 -0
- package/dist/bson.bundle.js +8723 -9228
- package/dist/bson.bundle.js.map +1 -0
- package/dist/bson.esm.js +5728 -4951
- package/dist/bson.esm.js.map +1 -0
- package/etc/prepare.js +19 -0
- package/lib/binary.js +218 -398
- package/lib/binary.js.map +1 -0
- package/lib/bson.js +201 -240
- package/lib/bson.js.map +1 -0
- package/lib/code.js +41 -41
- package/lib/code.js.map +1 -0
- package/lib/constants.js +78 -203
- package/lib/constants.js.map +1 -0
- package/lib/db_ref.js +88 -81
- package/lib/db_ref.js.map +1 -0
- package/lib/decimal128.js +667 -777
- package/lib/decimal128.js.map +1 -0
- package/lib/double.js +68 -70
- package/lib/double.js.map +1 -0
- package/lib/ensure_buffer.js +22 -18
- package/lib/ensure_buffer.js.map +1 -0
- package/lib/extended_json.js +310 -321
- package/lib/extended_json.js.map +1 -0
- package/lib/float_parser.js +98 -104
- package/lib/float_parser.js.map +1 -0
- package/lib/int_32.js +50 -49
- package/lib/int_32.js.map +1 -0
- package/lib/long.js +881 -16
- package/lib/long.js.map +1 -0
- package/lib/map.js +130 -122
- package/lib/map.js.map +1 -0
- package/lib/max_key.js +28 -25
- package/lib/max_key.js.map +1 -0
- package/lib/min_key.js +28 -25
- package/lib/min_key.js.map +1 -0
- package/lib/objectid.js +300 -410
- package/lib/objectid.js.map +1 -0
- package/lib/parser/calculate_size.js +188 -224
- package/lib/parser/calculate_size.js.map +1 -0
- package/lib/parser/deserializer.js +545 -621
- package/lib/parser/deserializer.js.map +1 -0
- package/lib/parser/serializer.js +798 -923
- package/lib/parser/serializer.js.map +1 -0
- package/lib/parser/utils.js +92 -30
- package/lib/parser/utils.js.map +1 -0
- package/lib/regexp.js +61 -74
- package/lib/regexp.js.map +1 -0
- package/lib/symbol.js +45 -58
- package/lib/symbol.js.map +1 -0
- package/lib/timestamp.js +91 -95
- package/lib/timestamp.js.map +1 -0
- package/lib/uuid.js +48 -0
- package/lib/uuid.js.map +1 -0
- package/lib/validate_utf8.js +41 -42
- package/lib/validate_utf8.js.map +1 -0
- package/package.json +53 -31
- package/src/binary.ts +272 -0
- package/src/bson.ts +326 -0
- package/src/code.ts +61 -0
- package/src/constants.ts +104 -0
- package/src/db_ref.ts +119 -0
- package/src/decimal128.ts +803 -0
- package/src/double.ts +87 -0
- package/src/ensure_buffer.ts +26 -0
- package/src/extended_json.ts +395 -0
- package/src/float_parser.ts +152 -0
- package/src/int_32.ts +66 -0
- package/src/long.ts +1002 -0
- package/src/map.ts +139 -0
- package/src/max_key.ts +37 -0
- package/src/min_key.ts +37 -0
- package/src/objectid.ts +379 -0
- package/src/parser/calculate_size.ts +230 -0
- package/src/parser/deserializer.ts +655 -0
- package/src/parser/serializer.ts +1069 -0
- package/src/parser/utils.ts +93 -0
- package/src/regexp.ts +94 -0
- package/src/symbol.ts +59 -0
- package/src/timestamp.ts +108 -0
- package/src/uuid.ts +57 -0
- package/src/validate_utf8.ts +47 -0
- package/lib/fnv1a.js +0 -48
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes our expected stringified form of a function across versions of node
|
|
5
|
+
* @param fn - The function to stringify
|
|
6
|
+
*/
|
|
7
|
+
export function normalizedFunctionString(fn: Function): string {
|
|
8
|
+
return fn.toString().replace('function(', 'function (');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function insecureRandomBytes(size: number): Uint8Array {
|
|
12
|
+
const result = Buffer.alloc(size);
|
|
13
|
+
for (let i = 0; i < size; ++i) result[i] = Math.floor(Math.random() * 256);
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* We do not want to have to include DOM types just for this check */
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
declare let window: any;
|
|
20
|
+
declare let require: Function;
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
declare let global: any;
|
|
23
|
+
declare const self: unknown;
|
|
24
|
+
|
|
25
|
+
export let randomBytes = insecureRandomBytes;
|
|
26
|
+
if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {
|
|
27
|
+
randomBytes = size => window.crypto.getRandomValues(Buffer.alloc(size));
|
|
28
|
+
} else {
|
|
29
|
+
try {
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
31
|
+
randomBytes = require('crypto').randomBytes;
|
|
32
|
+
} catch (e) {
|
|
33
|
+
// keep the fallback
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// NOTE: in transpiled cases the above require might return null/undefined
|
|
37
|
+
if (randomBytes == null) {
|
|
38
|
+
randomBytes = insecureRandomBytes;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isUint8Array(value: unknown): value is Uint8Array {
|
|
43
|
+
return Object.prototype.toString.call(value) === '[object Uint8Array]';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function isBigInt64Array(value: unknown): value is BigInt64Array {
|
|
47
|
+
return Object.prototype.toString.call(value) === '[object BigInt64Array]';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function isBigUInt64Array(value: unknown): value is BigUint64Array {
|
|
51
|
+
return Object.prototype.toString.call(value) === '[object BigUint64Array]';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Call to check if your environment has `Buffer` */
|
|
55
|
+
export function haveBuffer(): boolean {
|
|
56
|
+
return typeof global !== 'undefined' && typeof global.Buffer !== 'undefined';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Callable in any environment to check if value is a Buffer */
|
|
60
|
+
export function isBuffer(value: unknown): value is Buffer {
|
|
61
|
+
return typeof value === 'object' && value?.constructor?.name === 'Buffer';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// To ensure that 0.4 of node works correctly
|
|
65
|
+
export function isDate(d: unknown): d is Date {
|
|
66
|
+
return isObjectLike(d) && Object.prototype.toString.call(d) === '[object Date]';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @internal
|
|
71
|
+
* this is to solve the `'someKey' in x` problem where x is unknown.
|
|
72
|
+
* https://github.com/typescript-eslint/typescript-eslint/issues/1071#issuecomment-541955753
|
|
73
|
+
*/
|
|
74
|
+
export function isObjectLike(candidate: unknown): candidate is Record<string, unknown> {
|
|
75
|
+
return typeof candidate === 'object' && candidate !== null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare let console: { warn(...message: unknown[]): void };
|
|
79
|
+
export function deprecate<T extends Function>(fn: T, message: string): T {
|
|
80
|
+
if (typeof window === 'undefined' && typeof self === 'undefined') {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
82
|
+
return require('util').deprecate(fn, message);
|
|
83
|
+
}
|
|
84
|
+
let warned = false;
|
|
85
|
+
function deprecated(this: unknown, ...args: unknown[]) {
|
|
86
|
+
if (!warned) {
|
|
87
|
+
console.warn(message);
|
|
88
|
+
warned = true;
|
|
89
|
+
}
|
|
90
|
+
return fn.apply(this, ...args);
|
|
91
|
+
}
|
|
92
|
+
return (deprecated as unknown) as T;
|
|
93
|
+
}
|
package/src/regexp.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { EJSONOptions } from './extended_json';
|
|
2
|
+
|
|
3
|
+
function alphabetize(str: string): string {
|
|
4
|
+
return str.split('').sort().join('');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** @public */
|
|
8
|
+
export interface BSONRegExpExtendedLegacy {
|
|
9
|
+
$regex: string | BSONRegExp;
|
|
10
|
+
$options: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @public */
|
|
14
|
+
export interface BSONRegExpExtended {
|
|
15
|
+
$regularExpression: {
|
|
16
|
+
pattern: string;
|
|
17
|
+
options: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A class representation of the BSON RegExp type.
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export class BSONRegExp {
|
|
26
|
+
_bsontype!: 'BSONRegExp';
|
|
27
|
+
|
|
28
|
+
pattern!: string;
|
|
29
|
+
options!: string;
|
|
30
|
+
/**
|
|
31
|
+
* @param pattern - The regular expression pattern to match
|
|
32
|
+
* @param options - The regular expression options
|
|
33
|
+
*/
|
|
34
|
+
constructor(pattern: string, options?: string) {
|
|
35
|
+
if (!(this instanceof BSONRegExp)) return new BSONRegExp(pattern, options);
|
|
36
|
+
|
|
37
|
+
this.pattern = pattern;
|
|
38
|
+
this.options = options ?? '';
|
|
39
|
+
// Execute
|
|
40
|
+
alphabetize(this.options);
|
|
41
|
+
|
|
42
|
+
// Validate options
|
|
43
|
+
for (let i = 0; i < this.options.length; i++) {
|
|
44
|
+
if (
|
|
45
|
+
!(
|
|
46
|
+
this.options[i] === 'i' ||
|
|
47
|
+
this.options[i] === 'm' ||
|
|
48
|
+
this.options[i] === 'x' ||
|
|
49
|
+
this.options[i] === 'l' ||
|
|
50
|
+
this.options[i] === 's' ||
|
|
51
|
+
this.options[i] === 'u'
|
|
52
|
+
)
|
|
53
|
+
) {
|
|
54
|
+
throw new Error(`The regular expression option [${this.options[i]}] is not supported`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static parseOptions(options?: string): string {
|
|
60
|
+
return options ? options.split('').sort().join('') : '';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @internal */
|
|
64
|
+
toExtendedJSON(options?: EJSONOptions): BSONRegExpExtendedLegacy | BSONRegExpExtended {
|
|
65
|
+
options = options || {};
|
|
66
|
+
if (options.legacy) {
|
|
67
|
+
return { $regex: this.pattern, $options: this.options };
|
|
68
|
+
}
|
|
69
|
+
return { $regularExpression: { pattern: this.pattern, options: this.options } };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @internal */
|
|
73
|
+
static fromExtendedJSON(doc: BSONRegExpExtendedLegacy | BSONRegExpExtended): BSONRegExp {
|
|
74
|
+
if ('$regex' in doc) {
|
|
75
|
+
if (typeof doc.$regex !== 'string') {
|
|
76
|
+
// This is for $regex query operators that have extended json values.
|
|
77
|
+
if (doc.$regex._bsontype === 'BSONRegExp') {
|
|
78
|
+
return (doc as unknown) as BSONRegExp;
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
return new BSONRegExp(doc.$regex, BSONRegExp.parseOptions(doc.$options));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if ('$regularExpression' in doc) {
|
|
85
|
+
return new BSONRegExp(
|
|
86
|
+
doc.$regularExpression.pattern,
|
|
87
|
+
BSONRegExp.parseOptions(doc.$regularExpression.options)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
throw new TypeError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Object.defineProperty(BSONRegExp.prototype, '_bsontype', { value: 'BSONRegExp' });
|
package/src/symbol.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** @public */
|
|
2
|
+
export interface BSONSymbolExtended {
|
|
3
|
+
$symbol: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A class representation of the BSON Symbol type.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export class BSONSymbol {
|
|
11
|
+
_bsontype!: 'Symbol';
|
|
12
|
+
|
|
13
|
+
value!: string;
|
|
14
|
+
/**
|
|
15
|
+
* @param value - the string representing the symbol.
|
|
16
|
+
*/
|
|
17
|
+
constructor(value: string) {
|
|
18
|
+
if (!(this instanceof BSONSymbol)) return new BSONSymbol(value);
|
|
19
|
+
|
|
20
|
+
this.value = value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Access the wrapped string value. */
|
|
24
|
+
valueOf(): string {
|
|
25
|
+
return this.value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @internal */
|
|
29
|
+
toString(): string {
|
|
30
|
+
return this.value;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** @internal */
|
|
34
|
+
inspect(): string {
|
|
35
|
+
return `new BSONSymbol("${this.value}")`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** @internal */
|
|
39
|
+
toJSON(): string {
|
|
40
|
+
return this.value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** @internal */
|
|
44
|
+
toExtendedJSON(): BSONSymbolExtended {
|
|
45
|
+
return { $symbol: this.value };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** @internal */
|
|
49
|
+
static fromExtendedJSON(doc: BSONSymbolExtended): BSONSymbol {
|
|
50
|
+
return new BSONSymbol(doc.$symbol);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** @internal */
|
|
54
|
+
[Symbol.for('nodejs.util.inspect.custom')](): string {
|
|
55
|
+
return this.inspect();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Object.defineProperty(BSONSymbol.prototype, '_bsontype', { value: 'Symbol' });
|
package/src/timestamp.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Long } from './long';
|
|
2
|
+
|
|
3
|
+
/** @public */
|
|
4
|
+
export type TimestampOverrides = '_bsontype' | 'toExtendedJSON' | 'fromExtendedJSON' | 'inspect';
|
|
5
|
+
/** @public */
|
|
6
|
+
export type LongWithoutOverrides = new (low: number | Long, high?: number, unsigned?: boolean) => {
|
|
7
|
+
[P in Exclude<keyof Long, TimestampOverrides>]: Long[P];
|
|
8
|
+
};
|
|
9
|
+
/** @public */
|
|
10
|
+
export const LongWithoutOverridesClass: LongWithoutOverrides = (Long as unknown) as LongWithoutOverrides;
|
|
11
|
+
|
|
12
|
+
/** @public */
|
|
13
|
+
export interface TimestampExtended {
|
|
14
|
+
$timestamp: {
|
|
15
|
+
t: number;
|
|
16
|
+
i: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** @public */
|
|
21
|
+
export class Timestamp extends LongWithoutOverridesClass {
|
|
22
|
+
_bsontype!: 'Timestamp';
|
|
23
|
+
|
|
24
|
+
static readonly MAX_VALUE = Long.MAX_UNSIGNED_VALUE;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param low - A 64-bit Long representing the Timestamp.
|
|
28
|
+
*/
|
|
29
|
+
constructor(low: Long);
|
|
30
|
+
/**
|
|
31
|
+
* @param low - the low (signed) 32 bits of the Timestamp.
|
|
32
|
+
* @param high - the high (signed) 32 bits of the Timestamp.
|
|
33
|
+
*/
|
|
34
|
+
constructor(low: Long);
|
|
35
|
+
constructor(low: number, high: number);
|
|
36
|
+
constructor(low: number | Long, high?: number) {
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
38
|
+
///@ts-expect-error
|
|
39
|
+
if (!(this instanceof Timestamp)) return new Timestamp(low, high);
|
|
40
|
+
|
|
41
|
+
if (Long.isLong(low)) {
|
|
42
|
+
super(low.low, low.high, true);
|
|
43
|
+
} else {
|
|
44
|
+
super(low, high, true);
|
|
45
|
+
}
|
|
46
|
+
Object.defineProperty(this, '_bsontype', {
|
|
47
|
+
value: 'Timestamp',
|
|
48
|
+
writable: false,
|
|
49
|
+
configurable: false,
|
|
50
|
+
enumerable: false
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
toJSON(): { $timestamp: string } {
|
|
55
|
+
return {
|
|
56
|
+
$timestamp: this.toString()
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Returns a Timestamp represented by the given (32-bit) integer value. */
|
|
61
|
+
static fromInt(value: number): Timestamp {
|
|
62
|
+
return new Timestamp(Long.fromInt(value, true));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Returns a Timestamp representing the given number value, provided that it is a finite number. Otherwise, zero is returned. */
|
|
66
|
+
static fromNumber(value: number): Timestamp {
|
|
67
|
+
return new Timestamp(Long.fromNumber(value, true));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Returns a Timestamp for the given high and low bits. Each is assumed to use 32 bits.
|
|
72
|
+
*
|
|
73
|
+
* @param lowBits - the low 32-bits.
|
|
74
|
+
* @param highBits - the high 32-bits.
|
|
75
|
+
*/
|
|
76
|
+
static fromBits(lowBits: number, highBits: number): Timestamp {
|
|
77
|
+
return new Timestamp(lowBits, highBits);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Returns a Timestamp from the given string, optionally using the given radix.
|
|
82
|
+
*
|
|
83
|
+
* @param str - the textual representation of the Timestamp.
|
|
84
|
+
* @param optRadix - the radix in which the text is written.
|
|
85
|
+
*/
|
|
86
|
+
static fromString(str: string, optRadix: number): Timestamp {
|
|
87
|
+
return new Timestamp(Long.fromString(str, true, optRadix));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** @internal */
|
|
91
|
+
toExtendedJSON(): TimestampExtended {
|
|
92
|
+
return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** @internal */
|
|
96
|
+
static fromExtendedJSON(doc: TimestampExtended): Timestamp {
|
|
97
|
+
return new Timestamp(doc.$timestamp.i, doc.$timestamp.t);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** @internal */
|
|
101
|
+
[Symbol.for('nodejs.util.inspect.custom')](): string {
|
|
102
|
+
return this.inspect();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
inspect(): string {
|
|
106
|
+
return `new Timestamp(${this.getLowBits().toString()}, ${this.getHighBits().toString()})`;
|
|
107
|
+
}
|
|
108
|
+
}
|
package/src/uuid.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UUID regular expression pattern copied from `uuid` npm module.
|
|
3
|
+
* @see https://github.com/uuidjs/uuid/blob/master/src/regex.js
|
|
4
|
+
*/
|
|
5
|
+
const UUID_RX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
|
6
|
+
|
|
7
|
+
/** @public */
|
|
8
|
+
export interface UUIDExtended {
|
|
9
|
+
$uuid: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Parser function copied from `uuid` npm module.
|
|
14
|
+
* @see https://github.com/uuidjs/uuid/blob/master/src/parse.js
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export function parseUUID(uuid: string): Uint8Array {
|
|
18
|
+
if (typeof uuid !== 'string') {
|
|
19
|
+
throw new TypeError('Invalid type for UUID, expected string but got ' + typeof uuid);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!UUID_RX.test(uuid)) {
|
|
23
|
+
throw new TypeError('Invalid format for UUID: ' + uuid);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let v;
|
|
27
|
+
const arr = new Uint8Array(16);
|
|
28
|
+
|
|
29
|
+
// Parse ########-....-....-....-............
|
|
30
|
+
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
|
|
31
|
+
arr[1] = (v >>> 16) & 0xff;
|
|
32
|
+
arr[2] = (v >>> 8) & 0xff;
|
|
33
|
+
arr[3] = v & 0xff;
|
|
34
|
+
|
|
35
|
+
// Parse ........-####-....-....-............
|
|
36
|
+
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
|
|
37
|
+
arr[5] = v & 0xff;
|
|
38
|
+
|
|
39
|
+
// Parse ........-....-####-....-............
|
|
40
|
+
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
|
|
41
|
+
arr[7] = v & 0xff;
|
|
42
|
+
|
|
43
|
+
// Parse ........-....-....-####-............
|
|
44
|
+
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
|
|
45
|
+
arr[9] = v & 0xff;
|
|
46
|
+
|
|
47
|
+
// Parse ........-....-....-....-############
|
|
48
|
+
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
|
|
49
|
+
arr[10] = ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff;
|
|
50
|
+
arr[11] = (v / 0x100000000) & 0xff;
|
|
51
|
+
arr[12] = (v >>> 24) & 0xff;
|
|
52
|
+
arr[13] = (v >>> 16) & 0xff;
|
|
53
|
+
arr[14] = (v >>> 8) & 0xff;
|
|
54
|
+
arr[15] = v & 0xff;
|
|
55
|
+
|
|
56
|
+
return arr;
|
|
57
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const FIRST_BIT = 0x80;
|
|
2
|
+
const FIRST_TWO_BITS = 0xc0;
|
|
3
|
+
const FIRST_THREE_BITS = 0xe0;
|
|
4
|
+
const FIRST_FOUR_BITS = 0xf0;
|
|
5
|
+
const FIRST_FIVE_BITS = 0xf8;
|
|
6
|
+
|
|
7
|
+
const TWO_BIT_CHAR = 0xc0;
|
|
8
|
+
const THREE_BIT_CHAR = 0xe0;
|
|
9
|
+
const FOUR_BIT_CHAR = 0xf0;
|
|
10
|
+
const CONTINUING_CHAR = 0x80;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Determines if the passed in bytes are valid utf8
|
|
14
|
+
* @param bytes - An array of 8-bit bytes. Must be indexable and have length property
|
|
15
|
+
* @param start - The index to start validating
|
|
16
|
+
* @param end - The index to end validating
|
|
17
|
+
*/
|
|
18
|
+
export function validateUtf8(
|
|
19
|
+
bytes: { [index: number]: number },
|
|
20
|
+
start: number,
|
|
21
|
+
end: number
|
|
22
|
+
): boolean {
|
|
23
|
+
let continuation = 0;
|
|
24
|
+
|
|
25
|
+
for (let i = start; i < end; i += 1) {
|
|
26
|
+
const byte = bytes[i];
|
|
27
|
+
|
|
28
|
+
if (continuation) {
|
|
29
|
+
if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
continuation -= 1;
|
|
33
|
+
} else if (byte & FIRST_BIT) {
|
|
34
|
+
if ((byte & FIRST_THREE_BITS) === TWO_BIT_CHAR) {
|
|
35
|
+
continuation = 1;
|
|
36
|
+
} else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) {
|
|
37
|
+
continuation = 2;
|
|
38
|
+
} else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) {
|
|
39
|
+
continuation = 3;
|
|
40
|
+
} else {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return !continuation;
|
|
47
|
+
}
|
package/lib/fnv1a.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Buffer = require('buffer').Buffer;
|
|
4
|
-
const Long = require('./long');
|
|
5
|
-
|
|
6
|
-
const MASK_8 = 0xff;
|
|
7
|
-
const MASK_24 = 0xffffff;
|
|
8
|
-
const MASK_32 = 0xffffffff;
|
|
9
|
-
|
|
10
|
-
// See http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param for the definition of these parameters;
|
|
11
|
-
const FNV_PRIME = new Long(16777619, 0);
|
|
12
|
-
const OFFSET_BASIS = new Long(2166136261, 0);
|
|
13
|
-
const FNV_MASK = new Long(MASK_32, 0);
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Implementation of the FNV-1a hash for a 32-bit hash value
|
|
17
|
-
* Algorithm can be found here: http://www.isthe.com/chongo/tech/comp/fnv/#FNV-1a
|
|
18
|
-
* @ignore
|
|
19
|
-
*/
|
|
20
|
-
function fnv1a32(input, encoding) {
|
|
21
|
-
encoding = encoding || 'utf8';
|
|
22
|
-
const octets = Buffer.from(input, encoding);
|
|
23
|
-
|
|
24
|
-
let hash = OFFSET_BASIS;
|
|
25
|
-
for (let i = 0; i < octets.length; i += 1) {
|
|
26
|
-
hash = hash.xor(new Long(octets[i], 0));
|
|
27
|
-
hash = hash.multiply(FNV_PRIME);
|
|
28
|
-
hash = hash.and(FNV_MASK);
|
|
29
|
-
}
|
|
30
|
-
return hash.getLowBitsUnsigned();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Implements FNV-1a to generate 32-bit hash, then uses xor-folding
|
|
35
|
-
* to convert to a 24-bit hash. See here for more info:
|
|
36
|
-
* http://www.isthe.com/chongo/tech/comp/fnv/#xor-fold
|
|
37
|
-
* @ignore
|
|
38
|
-
*/
|
|
39
|
-
function fnv1a24(input, encoding) {
|
|
40
|
-
const _32bit = fnv1a32(input, encoding);
|
|
41
|
-
const base = _32bit & MASK_24;
|
|
42
|
-
const top = (_32bit >>> 24) & MASK_8;
|
|
43
|
-
const final = (base ^ top) & MASK_24;
|
|
44
|
-
|
|
45
|
-
return final;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
module.exports = { fnv1a24, fnv1a32 };
|