123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- import { Binary, UUID } from './binary';
- import { Code } from './code';
- import { DBRef } from './db_ref';
- import { Decimal128 } from './decimal128';
- import { Double } from './double';
- import { Int32 } from './int_32';
- import { Long } from './long';
- import { MaxKey } from './max_key';
- import { MinKey } from './min_key';
- import { ObjectId } from './objectid';
- import { internalCalculateObjectSize } from './parser/calculate_size';
- // Parts of the parser
- import { internalDeserialize, type DeserializeOptions } from './parser/deserializer';
- import { serializeInto, type SerializeOptions } from './parser/serializer';
- import { BSONRegExp } from './regexp';
- import { BSONSymbol } from './symbol';
- import { Timestamp } from './timestamp';
- import { ByteUtils } from './utils/byte_utils';
- export type { UUIDExtended, BinaryExtended, BinaryExtendedLegacy, BinarySequence } from './binary';
- export type { CodeExtended } from './code';
- export type { DBRefLike } from './db_ref';
- export type { Decimal128Extended } from './decimal128';
- export type { DoubleExtended } from './double';
- export type { EJSONOptions } from './extended_json';
- export type { Int32Extended } from './int_32';
- export type { LongExtended } from './long';
- export type { MaxKeyExtended } from './max_key';
- export type { MinKeyExtended } from './min_key';
- export type { ObjectIdExtended, ObjectIdLike } from './objectid';
- export type { BSONRegExpExtended, BSONRegExpExtendedLegacy } from './regexp';
- export type { BSONSymbolExtended } from './symbol';
- export type { LongWithoutOverrides, TimestampExtended, TimestampOverrides } from './timestamp';
- export type { LongWithoutOverridesClass } from './timestamp';
- export type { SerializeOptions, DeserializeOptions };
- export {
- Code,
- BSONSymbol,
- DBRef,
- Binary,
- ObjectId,
- UUID,
- Long,
- Timestamp,
- Double,
- Int32,
- MinKey,
- MaxKey,
- BSONRegExp,
- Decimal128
- };
- export { BSONValue } from './bson_value';
- export { BSONError, BSONVersionError, BSONRuntimeError } from './error';
- export { BSONType } from './constants';
- export { EJSON } from './extended_json';
- /** @public */
- export interface Document {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [key: string]: any;
- }
- /** @internal */
- // Default Max Size
- const MAXSIZE = 1024 * 1024 * 17;
- // Current Internal Temporary Serialization Buffer
- let buffer = ByteUtils.allocate(MAXSIZE);
- /**
- * Sets the size of the internal serialization buffer.
- *
- * @param size - The desired size for the internal serialization buffer in bytes
- * @public
- */
- export function setInternalBufferSize(size: number): void {
- // Resize the internal serialization buffer if needed
- if (buffer.length < size) {
- buffer = ByteUtils.allocate(size);
- }
- }
- /**
- * Serialize a Javascript object.
- *
- * @param object - the Javascript object to serialize.
- * @returns Buffer object containing the serialized object.
- * @public
- */
- export function serialize(object: Document, options: SerializeOptions = {}): Uint8Array {
- // Unpack the options
- const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false;
- const serializeFunctions =
- typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
- const ignoreUndefined =
- typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
- const minInternalBufferSize =
- typeof options.minInternalBufferSize === 'number' ? options.minInternalBufferSize : MAXSIZE;
- // Resize the internal serialization buffer if needed
- if (buffer.length < minInternalBufferSize) {
- buffer = ByteUtils.allocate(minInternalBufferSize);
- }
- // Attempt to serialize
- const serializationIndex = serializeInto(
- buffer,
- object,
- checkKeys,
- 0,
- 0,
- serializeFunctions,
- ignoreUndefined,
- null
- );
- // Create the final buffer
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
- // Copy into the finished buffer
- finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
- // Return the buffer
- return finishedBuffer;
- }
- /**
- * Serialize a Javascript object using a predefined Buffer and index into the buffer,
- * useful when pre-allocating the space for serialization.
- *
- * @param object - the Javascript object to serialize.
- * @param finalBuffer - the Buffer you pre-allocated to store the serialized BSON object.
- * @returns the index pointing to the last written byte in the buffer.
- * @public
- */
- export function serializeWithBufferAndIndex(
- object: Document,
- finalBuffer: Uint8Array,
- options: SerializeOptions = {}
- ): number {
- // Unpack the options
- const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false;
- const serializeFunctions =
- typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
- const ignoreUndefined =
- typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
- const startIndex = typeof options.index === 'number' ? options.index : 0;
- // Attempt to serialize
- const serializationIndex = serializeInto(
- buffer,
- object,
- checkKeys,
- 0,
- 0,
- serializeFunctions,
- ignoreUndefined,
- null
- );
- finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex);
- // Return the index
- return startIndex + serializationIndex - 1;
- }
- /**
- * Deserialize data as BSON.
- *
- * @param buffer - the buffer containing the serialized set of BSON documents.
- * @returns returns the deserialized Javascript Object.
- * @public
- */
- export function deserialize(buffer: Uint8Array, options: DeserializeOptions = {}): Document {
- return internalDeserialize(ByteUtils.toLocalBufferType(buffer), options);
- }
- /** @public */
- export type CalculateObjectSizeOptions = Pick<
- SerializeOptions,
- 'serializeFunctions' | 'ignoreUndefined'
- >;
- /**
- * Calculate the bson size for a passed in Javascript object.
- *
- * @param object - the Javascript object to calculate the BSON byte size for
- * @returns size of BSON object in bytes
- * @public
- */
- export function calculateObjectSize(
- object: Document,
- options: CalculateObjectSizeOptions = {}
- ): number {
- options = options || {};
- const serializeFunctions =
- typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
- const ignoreUndefined =
- typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
- return internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined);
- }
- /**
- * Deserialize stream data as BSON documents.
- *
- * @param data - the buffer containing the serialized set of BSON documents.
- * @param startIndex - the start index in the data Buffer where the deserialization is to start.
- * @param numberOfDocuments - number of documents to deserialize.
- * @param documents - an array where to store the deserialized documents.
- * @param docStartIndex - the index in the documents array from where to start inserting documents.
- * @param options - additional options used for the deserialization.
- * @returns next index in the buffer after deserialization **x** numbers of documents.
- * @public
- */
- export function deserializeStream(
- data: Uint8Array | ArrayBuffer,
- startIndex: number,
- numberOfDocuments: number,
- documents: Document[],
- docStartIndex: number,
- options: DeserializeOptions
- ): number {
- const internalOptions = Object.assign(
- { allowObjectSmallerThanBufferSize: true, index: 0 },
- options
- );
- const bufferData = ByteUtils.toLocalBufferType(data);
- let index = startIndex;
- // Loop over all documents
- for (let i = 0; i < numberOfDocuments; i++) {
- // Find size of the document
- const size =
- bufferData[index] |
- (bufferData[index + 1] << 8) |
- (bufferData[index + 2] << 16) |
- (bufferData[index + 3] << 24);
- // Update options with index
- internalOptions.index = index;
- // Parse the document at this point
- documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
- // Adjust index by the document size
- index = index + size;
- }
- // Return object containing end index of parsing and list of documents
- return index;
- }
|