基本schema测试
This commit is contained in:
218
node_modules/bson/src/parser/calculate_size.ts
generated
vendored
Normal file
218
node_modules/bson/src/parser/calculate_size.ts
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
import { Binary } from '../binary';
|
||||
import type { Document } from '../bson';
|
||||
import { BSONError, BSONVersionError } from '../error';
|
||||
import * as constants from '../constants';
|
||||
import { ByteUtils } from '../utils/byte_utils';
|
||||
import { isAnyArrayBuffer, isDate, isRegExp } from './utils';
|
||||
|
||||
export function internalCalculateObjectSize(
|
||||
object: Document,
|
||||
serializeFunctions?: boolean,
|
||||
ignoreUndefined?: boolean
|
||||
): number {
|
||||
let totalLength = 4 + 1;
|
||||
|
||||
if (Array.isArray(object)) {
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
totalLength += calculateElement(
|
||||
i.toString(),
|
||||
object[i],
|
||||
serializeFunctions,
|
||||
true,
|
||||
ignoreUndefined
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// If we have toBSON defined, override the current object
|
||||
|
||||
if (typeof object?.toBSON === 'function') {
|
||||
object = object.toBSON();
|
||||
}
|
||||
|
||||
// Calculate size
|
||||
for (const key of Object.keys(object)) {
|
||||
totalLength += calculateElement(key, object[key], serializeFunctions, false, ignoreUndefined);
|
||||
}
|
||||
}
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function calculateElement(
|
||||
name: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value: any,
|
||||
serializeFunctions = false,
|
||||
isArray = false,
|
||||
ignoreUndefined = false
|
||||
) {
|
||||
// If we have toBSON defined, override the current object
|
||||
if (typeof value?.toBSON === 'function') {
|
||||
value = value.toBSON();
|
||||
}
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return 1 + ByteUtils.utf8ByteLength(name) + 1 + 4 + ByteUtils.utf8ByteLength(value) + 1;
|
||||
case 'number':
|
||||
if (
|
||||
Math.floor(value) === value &&
|
||||
value >= constants.JS_INT_MIN &&
|
||||
value <= constants.JS_INT_MAX
|
||||
) {
|
||||
if (value >= constants.BSON_INT32_MIN && value <= constants.BSON_INT32_MAX) {
|
||||
// 32 bit
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (4 + 1);
|
||||
} else {
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
|
||||
}
|
||||
} else {
|
||||
// 64 bit
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
|
||||
}
|
||||
case 'undefined':
|
||||
if (isArray || !ignoreUndefined)
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1;
|
||||
return 0;
|
||||
case 'boolean':
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1);
|
||||
case 'object':
|
||||
if (
|
||||
value != null &&
|
||||
typeof value._bsontype === 'string' &&
|
||||
value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION
|
||||
) {
|
||||
throw new BSONVersionError();
|
||||
} else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1;
|
||||
} else if (value._bsontype === 'ObjectId') {
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1);
|
||||
} else if (value instanceof Date || isDate(value)) {
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
|
||||
} else if (
|
||||
ArrayBuffer.isView(value) ||
|
||||
value instanceof ArrayBuffer ||
|
||||
isAnyArrayBuffer(value)
|
||||
) {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 4 + 1) + value.byteLength
|
||||
);
|
||||
} else if (
|
||||
value._bsontype === 'Long' ||
|
||||
value._bsontype === 'Double' ||
|
||||
value._bsontype === 'Timestamp'
|
||||
) {
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
|
||||
} else if (value._bsontype === 'Decimal128') {
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (16 + 1);
|
||||
} else if (value._bsontype === 'Code') {
|
||||
// Calculate size depending on the availability of a scope
|
||||
if (value.scope != null && Object.keys(value.scope).length > 0) {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
1 +
|
||||
4 +
|
||||
4 +
|
||||
ByteUtils.utf8ByteLength(value.code.toString()) +
|
||||
1 +
|
||||
internalCalculateObjectSize(value.scope, serializeFunctions, ignoreUndefined)
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
1 +
|
||||
4 +
|
||||
ByteUtils.utf8ByteLength(value.code.toString()) +
|
||||
1
|
||||
);
|
||||
}
|
||||
} else if (value._bsontype === 'Binary') {
|
||||
const binary: Binary = value;
|
||||
// Check what kind of subtype we have
|
||||
if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
(binary.position + 1 + 4 + 1 + 4)
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1)
|
||||
);
|
||||
}
|
||||
} else if (value._bsontype === 'Symbol') {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
ByteUtils.utf8ByteLength(value.value) +
|
||||
4 +
|
||||
1 +
|
||||
1
|
||||
);
|
||||
} else if (value._bsontype === 'DBRef') {
|
||||
// Set up correct object for serialization
|
||||
const ordered_values = Object.assign(
|
||||
{
|
||||
$ref: value.collection,
|
||||
$id: value.oid
|
||||
},
|
||||
value.fields
|
||||
);
|
||||
|
||||
// Add db reference if it exists
|
||||
if (value.db != null) {
|
||||
ordered_values['$db'] = value.db;
|
||||
}
|
||||
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
1 +
|
||||
internalCalculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined)
|
||||
);
|
||||
} else if (value instanceof RegExp || isRegExp(value)) {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
1 +
|
||||
ByteUtils.utf8ByteLength(value.source) +
|
||||
1 +
|
||||
(value.global ? 1 : 0) +
|
||||
(value.ignoreCase ? 1 : 0) +
|
||||
(value.multiline ? 1 : 0) +
|
||||
1
|
||||
);
|
||||
} else if (value._bsontype === 'BSONRegExp') {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
1 +
|
||||
ByteUtils.utf8ByteLength(value.pattern) +
|
||||
1 +
|
||||
ByteUtils.utf8ByteLength(value.options) +
|
||||
1
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
internalCalculateObjectSize(value, serializeFunctions, ignoreUndefined) +
|
||||
1
|
||||
);
|
||||
}
|
||||
case 'function':
|
||||
if (serializeFunctions) {
|
||||
return (
|
||||
(name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) +
|
||||
1 +
|
||||
4 +
|
||||
ByteUtils.utf8ByteLength(value.toString()) +
|
||||
1
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
case 'bigint':
|
||||
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
|
||||
case 'symbol':
|
||||
return 0;
|
||||
default:
|
||||
throw new BSONError(`Unrecognized JS type: ${typeof value}`);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user