123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.BsonDecoder = void 0;
- const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
- const values_1 = require("./values");
- class BsonDecoder {
- constructor(reader = new Reader_1.Reader()) {
- this.reader = reader;
- }
- read(uint8) {
- this.reader.reset(uint8);
- return this.readDocument();
- }
- decode(uint8) {
- this.reader.reset(uint8);
- return this.readDocument();
- }
- readAny() {
- return this.readDocument();
- }
- readDocument() {
- const reader = this.reader;
- const documentSize = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- const startPos = reader.x;
- const endPos = startPos + documentSize - 4 - 1;
- const obj = {};
- while (reader.x < endPos) {
- const elementType = reader.u8();
- if (elementType === 0)
- break;
- const key = this.readCString();
- const value = this.readElementValue(elementType);
- obj[key] = value;
- }
- if (reader.x <= endPos) {
- reader.x = startPos + documentSize - 4;
- }
- return obj;
- }
- readCString() {
- const reader = this.reader;
- const uint8 = reader.uint8;
- const x = reader.x;
- let length = 0;
- while (uint8[x + length] !== 0) {
- length++;
- }
- if (length === 0) {
- reader.x++;
- return '';
- }
- const str = reader.utf8(length);
- reader.x++;
- return str;
- }
- readString() {
- const reader = this.reader;
- const length = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- if (length <= 0) {
- throw new Error('Invalid string length');
- }
- const str = reader.utf8(length - 1);
- reader.x++;
- return str;
- }
- readElementValue(type) {
- const reader = this.reader;
- switch (type) {
- case 0x01:
- const doubleVal = reader.view.getFloat64(reader.x, true);
- reader.x += 8;
- return doubleVal;
- case 0x02:
- return this.readString();
- case 0x03:
- return this.readDocument();
- case 0x04:
- return this.readArray();
- case 0x05:
- return this.readBinary();
- case 0x06:
- return undefined;
- case 0x07:
- return this.readObjectId();
- case 0x08:
- return reader.u8() === 1;
- case 0x09:
- const dateVal = reader.view.getBigInt64(reader.x, true);
- reader.x += 8;
- return new Date(Number(dateVal));
- case 0x0a:
- return null;
- case 0x0b:
- return this.readRegex();
- case 0x0c:
- return this.readDbPointer();
- case 0x0d:
- return new values_1.BsonJavascriptCode(this.readString());
- case 0x0e:
- return Symbol(this.readString());
- case 0x0f:
- return this.readCodeWithScope();
- case 0x10:
- const int32Val = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- return int32Val;
- case 0x11:
- return this.readTimestamp();
- case 0x12:
- const int64Val = reader.view.getBigInt64(reader.x, true);
- reader.x += 8;
- return Number(int64Val);
- case 0x13:
- return this.readDecimal128();
- case 0xff:
- return new values_1.BsonMinKey();
- case 0x7f:
- return new values_1.BsonMaxKey();
- default:
- throw new Error(`Unsupported BSON type: 0x${type.toString(16)}`);
- }
- }
- readArray() {
- const doc = this.readDocument();
- const keys = Object.keys(doc).sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
- return keys.map((key) => doc[key]);
- }
- readBinary() {
- const reader = this.reader;
- const length = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- const subtype = reader.u8();
- const data = reader.buf(length);
- if (subtype === 0) {
- return data;
- }
- return new values_1.BsonBinary(subtype, data);
- }
- readObjectId() {
- const reader = this.reader;
- const uint8 = reader.uint8;
- const x = reader.x;
- const timestamp = (uint8[x] << 24) | (uint8[x + 1] << 16) | (uint8[x + 2] << 8) | uint8[x + 3];
- const processLo = uint8[x + 4] | (uint8[x + 5] << 8) | (uint8[x + 6] << 16) | (uint8[x + 7] << 24);
- const processHi = uint8[x + 8];
- const processLoUnsigned = processLo >>> 0;
- const process = processLoUnsigned + processHi * 0x100000000;
- const counter = (uint8[x + 9] << 16) | (uint8[x + 10] << 8) | uint8[x + 11];
- reader.x += 12;
- return new values_1.BsonObjectId(timestamp, process, counter);
- }
- readRegex() {
- const pattern = this.readCString();
- const flags = this.readCString();
- return new RegExp(pattern, flags);
- }
- readDbPointer() {
- const name = this.readString();
- const id = this.readObjectId();
- return new values_1.BsonDbPointer(name, id);
- }
- readCodeWithScope() {
- const reader = this.reader;
- const totalLength = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- const code = this.readString();
- const scope = this.readDocument();
- return new values_1.BsonJavascriptCodeWithScope(code, scope);
- }
- readTimestamp() {
- const reader = this.reader;
- const increment = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- const timestamp = reader.view.getInt32(reader.x, true);
- reader.x += 4;
- return new values_1.BsonTimestamp(increment, timestamp);
- }
- readDecimal128() {
- const reader = this.reader;
- const data = reader.buf(16);
- return new values_1.BsonDecimal128(data);
- }
- }
- exports.BsonDecoder = BsonDecoder;
- //# sourceMappingURL=BsonDecoder.js.map
|