123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.BsonEncoder = void 0;
- const values_1 = require("./values");
- class BsonEncoder {
- constructor(writer) {
- this.writer = writer;
- }
- encode(value) {
- const writer = this.writer;
- writer.reset();
- this.writeAny(value);
- return writer.flush();
- }
- writeAny(value) {
- switch (typeof value) {
- case 'object': {
- if (value === null)
- throw new Error('NOT_OBJ');
- return this.writeObj(value);
- }
- }
- throw new Error('NOT_OBJ');
- }
- writeNull() {
- throw new Error('Method not implemented.');
- }
- writeUndef() {
- throw new Error('Method not implemented.');
- }
- writeBoolean(bool) {
- throw new Error('Method not implemented.');
- }
- writeNumber(num) {
- throw new Error('Method not implemented.');
- }
- writeInteger(int) {
- throw new Error('Method not implemented.');
- }
- writeUInteger(uint) {
- throw new Error('Method not implemented.');
- }
- writeInt32(int) {
- const writer = this.writer;
- writer.ensureCapacity(4);
- writer.view.setInt32(writer.x, int, true);
- writer.x += 4;
- }
- writeInt64(int) {
- const writer = this.writer;
- writer.ensureCapacity(8);
- writer.view.setBigInt64(writer.x, BigInt(int), true);
- writer.x += 8;
- }
- writeFloat(float) {
- const writer = this.writer;
- writer.ensureCapacity(4);
- writer.view.setFloat64(writer.x, float, true);
- writer.x += 8;
- }
- writeBigInt(int) {
- throw new Error('Method not implemented.');
- }
- writeBin(buf) {
- const length = buf.length;
- this.writeInt32(length);
- const writer = this.writer;
- writer.u8(0);
- writer.buf(buf, length);
- }
- writeStr(str) {
- const writer = this.writer;
- const length = str.length;
- const maxSize = 4 + 1 + 4 * length;
- writer.ensureCapacity(maxSize);
- const x = writer.x;
- this.writeInt32(length + 1);
- const bytesWritten = writer.utf8(str);
- writer.u8(0);
- if (bytesWritten !== length) {
- writer.view.setInt32(x, bytesWritten + 1, true);
- }
- }
- writeAsciiStr(str) {
- throw new Error('Method not implemented.');
- }
- writeArr(arr) {
- this.writeObj(arr);
- }
- writeObj(obj) {
- const writer = this.writer;
- writer.ensureCapacity(8);
- const x0 = writer.x0;
- const dx = writer.x - x0;
- writer.x += 4;
- const keys = Object.keys(obj);
- const length = keys.length;
- for (let i = 0; i < length; i++) {
- const key = keys[i];
- const value = obj[key];
- this.writeKey(key, value);
- }
- writer.u8(0);
- const x = writer.x0 + dx;
- const size = writer.x - x;
- writer.view.setUint32(x, size, true);
- }
- writeCString(str) {
- const writer = this.writer;
- const length = str.length;
- writer.ensureCapacity(1 + 4 * length);
- const uint8 = writer.uint8;
- let x = writer.x;
- let pos = 0;
- while (pos < length) {
- let value = str.charCodeAt(pos++);
- if ((value & 0xffffff80) === 0) {
- if (!value)
- break;
- uint8[x++] = value;
- continue;
- }
- else if ((value & 0xfffff800) === 0) {
- const octet = ((value >> 6) & 0x1f) | 0xc0;
- if (!octet)
- break;
- uint8[x++] = octet;
- }
- else {
- if (value >= 0xd800 && value <= 0xdbff) {
- if (pos < length) {
- const extra = str.charCodeAt(pos);
- if ((extra & 0xfc00) === 0xdc00) {
- pos++;
- value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
- }
- }
- }
- if ((value & 0xffff0000) === 0) {
- const octet1 = ((value >> 12) & 0x0f) | 0xe0;
- const octet2 = ((value >> 6) & 0x3f) | 0x80;
- if (!octet1 || !octet2)
- throw new Error('INVALID_CSTRING');
- uint8[x++] = octet1;
- uint8[x++] = octet2;
- }
- else {
- const octet1 = ((value >> 18) & 0x07) | 0xf0;
- const octet2 = ((value >> 12) & 0x3f) | 0x80;
- const octet3 = ((value >> 6) & 0x3f) | 0x80;
- if (!octet1 || !octet2 || !octet3)
- throw new Error('INVALID_CSTRING');
- uint8[x++] = octet1;
- uint8[x++] = octet2;
- uint8[x++] = octet3;
- }
- }
- const octet = (value & 0x3f) | 0x80;
- if (!octet)
- break;
- uint8[x++] = octet;
- }
- uint8[x++] = 0;
- writer.x = x;
- }
- writeObjectId(id) {
- const writer = this.writer;
- writer.ensureCapacity(12);
- const uint8 = writer.uint8;
- const x = writer.x;
- const { timestamp, process, counter } = id;
- uint8[x + 0] = timestamp >>> 24;
- uint8[x + 1] = (timestamp >>> 16) & 0xff;
- uint8[x + 2] = (timestamp >>> 8) & 0xff;
- uint8[x + 3] = timestamp & 0xff;
- uint8[x + 4] = process & 0xff;
- uint8[x + 5] = (process >>> 8) & 0xff;
- uint8[x + 6] = (process >>> 16) & 0xff;
- uint8[x + 7] = (process >>> 24) & 0xff;
- let lo32 = process | 0;
- if (lo32 < 0)
- lo32 += 4294967296;
- const hi32 = (process - lo32) / 4294967296;
- uint8[x + 8] = hi32 & 0xff;
- uint8[x + 9] = counter >>> 16;
- uint8[x + 10] = (counter >>> 8) & 0xff;
- uint8[x + 11] = counter & 0xff;
- writer.x += 12;
- }
- writeKey(key, value) {
- const writer = this.writer;
- switch (typeof value) {
- case 'number': {
- const isFloat = Math.floor(value) !== value;
- if (isFloat) {
- writer.u8(0x01);
- this.writeCString(key);
- this.writeFloat(value);
- break;
- }
- if (value <= 2147483647 && value >= -2147483648) {
- writer.u8(0x10);
- this.writeCString(key);
- this.writeInt32(value);
- break;
- }
- writer.u8(0x12);
- this.writeCString(key);
- this.writeInt64(value);
- break;
- }
- case 'string': {
- writer.u8(0x02);
- this.writeCString(key);
- this.writeStr(value);
- break;
- }
- case 'object': {
- if (value === null) {
- writer.u8(0x0a);
- this.writeCString(key);
- break;
- }
- const constructor = value.constructor;
- switch (constructor) {
- case Object: {
- writer.u8(0x03);
- this.writeCString(key);
- this.writeObj(value);
- break;
- }
- case Array: {
- writer.u8(0x04);
- this.writeCString(key);
- this.writeObj(value);
- break;
- }
- case Uint8Array: {
- writer.u8(0x05);
- this.writeCString(key);
- this.writeBin(value);
- break;
- }
- case values_1.BsonObjectId: {
- writer.u8(0x07);
- this.writeCString(key);
- this.writeObjectId(value);
- break;
- }
- case Date: {
- writer.u8(0x09);
- this.writeCString(key);
- writer.ensureCapacity(8);
- writer.view.setBigUint64(writer.x, BigInt(value.getTime()), true);
- writer.x += 8;
- break;
- }
- case RegExp: {
- writer.u8(0x0b);
- this.writeCString(key);
- this.writeCString(value.source);
- this.writeCString(value.flags);
- break;
- }
- case values_1.BsonDbPointer: {
- writer.u8(0x0c);
- this.writeCString(key);
- const pointer = value;
- this.writeStr(pointer.name);
- this.writeObjectId(pointer.id);
- break;
- }
- case values_1.BsonJavascriptCode: {
- writer.u8(0x0d);
- this.writeCString(key);
- this.writeStr(value.code);
- break;
- }
- case values_1.BsonInt32: {
- writer.u8(0x10);
- this.writeCString(key);
- this.writeInt32(value.value);
- break;
- }
- case values_1.BsonInt64: {
- writer.u8(0x12);
- this.writeCString(key);
- this.writeInt64(value.value);
- break;
- }
- case values_1.BsonFloat: {
- writer.u8(0x01);
- this.writeCString(key);
- this.writeFloat(value.value);
- break;
- }
- case values_1.BsonTimestamp: {
- writer.u8(0x11);
- this.writeCString(key);
- const ts = value;
- this.writeInt32(ts.increment);
- this.writeInt32(ts.timestamp);
- break;
- }
- case values_1.BsonDecimal128: {
- writer.u8(0x13);
- this.writeCString(key);
- const dec = value;
- if (dec.data.length !== 16)
- throw new Error('INVALID_DECIMAL128');
- writer.buf(dec.data, 16);
- break;
- }
- case values_1.BsonMinKey: {
- writer.u8(0xff);
- this.writeCString(key);
- break;
- }
- case values_1.BsonMaxKey: {
- writer.u8(0x7f);
- this.writeCString(key);
- break;
- }
- case values_1.BsonBinary: {
- writer.u8(0x05);
- this.writeCString(key);
- const bin = value;
- const length = bin.data.length;
- this.writeInt32(length);
- writer.u8(bin.subtype);
- writer.buf(bin.data, length);
- break;
- }
- default: {
- writer.u8(0x03);
- this.writeCString(key);
- this.writeObj(value);
- break;
- }
- }
- break;
- }
- case 'boolean': {
- writer.u8(0x08);
- this.writeCString(key);
- writer.u8(+value);
- break;
- }
- case 'undefined': {
- writer.u8(0x06);
- this.writeCString(key);
- break;
- }
- case 'symbol': {
- writer.u8(0x0e);
- this.writeCString(key);
- this.writeStr(value.description || '');
- break;
- }
- }
- }
- }
- exports.BsonEncoder = BsonEncoder;
- //# sourceMappingURL=BsonEncoder.js.map
|