mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
498 lines
15 KiB
498 lines
15 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.EjsonEncoder = void 0;
|
|
const values_1 = require("../bson/values");
|
|
const toBase64Bin_1 = require("@jsonjoy.com/base64/lib/toBase64Bin");
|
|
const JsonEncoder_1 = require("../json/JsonEncoder");
|
|
class EjsonEncoder extends JsonEncoder_1.JsonEncoder {
|
|
constructor(writer, options = {}) {
|
|
super(writer);
|
|
this.options = options;
|
|
}
|
|
encodeToString(value) {
|
|
const bytes = this.encode(value);
|
|
return new TextDecoder().decode(bytes);
|
|
}
|
|
writeUnknown(value) {
|
|
this.writeNull();
|
|
}
|
|
writeAny(value) {
|
|
if (value === null || value === undefined) {
|
|
if (value === undefined) {
|
|
return this.writeUndefinedWrapper();
|
|
}
|
|
return this.writeNull();
|
|
}
|
|
if (typeof value === 'boolean') {
|
|
return this.writeBoolean(value);
|
|
}
|
|
if (typeof value === 'string') {
|
|
return this.writeStr(value);
|
|
}
|
|
if (typeof value === 'number') {
|
|
return this.writeNumberAsEjson(value);
|
|
}
|
|
if (Array.isArray(value)) {
|
|
return this.writeArr(value);
|
|
}
|
|
if (value instanceof Date) {
|
|
return this.writeDateAsEjson(value);
|
|
}
|
|
if (value instanceof RegExp) {
|
|
return this.writeRegExpAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonObjectId) {
|
|
return this.writeObjectIdAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonInt32) {
|
|
return this.writeBsonInt32AsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonInt64) {
|
|
return this.writeBsonInt64AsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonFloat) {
|
|
return this.writeBsonFloatAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonDecimal128) {
|
|
return this.writeBsonDecimal128AsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonBinary) {
|
|
return this.writeBsonBinaryAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonJavascriptCode) {
|
|
return this.writeBsonCodeAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonJavascriptCodeWithScope) {
|
|
return this.writeBsonCodeWScopeAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonSymbol) {
|
|
return this.writeBsonSymbolAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonTimestamp) {
|
|
return this.writeBsonTimestampAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonDbPointer) {
|
|
return this.writeBsonDbPointerAsEjson(value);
|
|
}
|
|
if (value instanceof values_1.BsonMinKey) {
|
|
return this.writeBsonMinKeyAsEjson();
|
|
}
|
|
if (value instanceof values_1.BsonMaxKey) {
|
|
return this.writeBsonMaxKeyAsEjson();
|
|
}
|
|
if (typeof value === 'object' && value !== null) {
|
|
return this.writeObj(value);
|
|
}
|
|
return this.writeUnknown(value);
|
|
}
|
|
writeBin(buf) {
|
|
const writer = this.writer;
|
|
const length = buf.length;
|
|
writer.ensureCapacity(38 + 3 + (length << 1));
|
|
const view = writer.view;
|
|
let x = writer.x;
|
|
view.setUint32(x, 577003892);
|
|
x += 4;
|
|
view.setUint32(x, 1631215984);
|
|
x += 4;
|
|
view.setUint32(x, 1886153059);
|
|
x += 4;
|
|
view.setUint32(x, 1635019119);
|
|
x += 4;
|
|
view.setUint32(x, 1848602467);
|
|
x += 4;
|
|
view.setUint32(x, 1952805933);
|
|
x += 4;
|
|
view.setUint32(x, 1937011301);
|
|
x += 4;
|
|
view.setUint32(x, 1634548578);
|
|
x += 4;
|
|
view.setUint32(x, 1634952502);
|
|
x += 4;
|
|
view.setUint16(x, 13356);
|
|
x += 2;
|
|
x = (0, toBase64Bin_1.toBase64Bin)(buf, 0, length, view, x);
|
|
writer.uint8[x++] = 0x22;
|
|
writer.x = x;
|
|
}
|
|
writeStr(str) {
|
|
const writer = this.writer;
|
|
const length = str.length;
|
|
writer.ensureCapacity(length * 4 + 2);
|
|
if (length < 256) {
|
|
let x = writer.x;
|
|
const uint8 = writer.uint8;
|
|
uint8[x++] = 0x22;
|
|
for (let i = 0; i < length; i++) {
|
|
const code = str.charCodeAt(i);
|
|
switch (code) {
|
|
case 34:
|
|
case 92:
|
|
uint8[x++] = 0x5c;
|
|
break;
|
|
}
|
|
if (code < 32 || code > 126) {
|
|
writer.utf8(JSON.stringify(str));
|
|
return;
|
|
}
|
|
else
|
|
uint8[x++] = code;
|
|
}
|
|
uint8[x++] = 0x22;
|
|
writer.x = x;
|
|
return;
|
|
}
|
|
writer.utf8(JSON.stringify(str));
|
|
}
|
|
writeAsciiStr(str) {
|
|
const length = str.length;
|
|
const writer = this.writer;
|
|
writer.ensureCapacity(length * 2 + 2);
|
|
const uint8 = writer.uint8;
|
|
let x = writer.x;
|
|
uint8[x++] = 0x22;
|
|
for (let i = 0; i < length; i++) {
|
|
const code = str.charCodeAt(i);
|
|
switch (code) {
|
|
case 34:
|
|
case 92:
|
|
uint8[x++] = 0x5c;
|
|
break;
|
|
}
|
|
uint8[x++] = code;
|
|
}
|
|
uint8[x++] = 0x22;
|
|
writer.x = x;
|
|
}
|
|
writeArr(arr) {
|
|
const writer = this.writer;
|
|
writer.u8(0x5b);
|
|
const length = arr.length;
|
|
const last = length - 1;
|
|
for (let i = 0; i < last; i++) {
|
|
this.writeAny(arr[i]);
|
|
writer.u8(0x2c);
|
|
}
|
|
if (last >= 0)
|
|
this.writeAny(arr[last]);
|
|
writer.u8(0x5d);
|
|
}
|
|
writeObj(obj) {
|
|
const writer = this.writer;
|
|
const keys = Object.keys(obj);
|
|
const length = keys.length;
|
|
if (!length)
|
|
return writer.u16(0x7b7d);
|
|
writer.u8(0x7b);
|
|
for (let i = 0; i < length; i++) {
|
|
const key = keys[i];
|
|
const value = obj[key];
|
|
this.writeStr(key);
|
|
writer.u8(0x3a);
|
|
this.writeAny(value);
|
|
writer.u8(0x2c);
|
|
}
|
|
writer.uint8[writer.x - 1] = 0x7d;
|
|
}
|
|
writeUndefinedWrapper() {
|
|
const writer = this.writer;
|
|
writer.ensureCapacity(18);
|
|
writer.u8(0x7b);
|
|
writer.u32(0x2224756e);
|
|
writer.u32(0x64656669);
|
|
writer.u32(0x6e656422);
|
|
writer.u8(0x3a);
|
|
writer.u32(0x74727565);
|
|
writer.u8(0x7d);
|
|
}
|
|
writeNumberAsEjson(value) {
|
|
if (this.options.canonical) {
|
|
if (Number.isInteger(value)) {
|
|
if (value >= -2147483648 && value <= 2147483647) {
|
|
this.writeNumberIntWrapper(value);
|
|
}
|
|
else {
|
|
this.writeNumberLongWrapper(value);
|
|
}
|
|
}
|
|
else {
|
|
this.writeNumberDoubleWrapper(value);
|
|
}
|
|
}
|
|
else {
|
|
if (!isFinite(value)) {
|
|
this.writeNumberDoubleWrapper(value);
|
|
}
|
|
else {
|
|
this.writeNumber(value);
|
|
}
|
|
}
|
|
}
|
|
writeNumberIntWrapper(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246e75);
|
|
writer.u32(0x6d626572);
|
|
writer.u32(0x496e7422);
|
|
writer.u8(0x3a);
|
|
this.writeStr(value + '');
|
|
writer.u8(0x7d);
|
|
}
|
|
writeNumberLongWrapper(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246e75);
|
|
writer.u32(0x6d626572);
|
|
writer.u32(0x4c6f6e67);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value + '');
|
|
writer.u8(0x7d);
|
|
}
|
|
writeNumberDoubleWrapper(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246e75);
|
|
writer.u32(0x6d626572);
|
|
writer.u32(0x446f7562);
|
|
writer.u16(0x6c65);
|
|
writer.u16(0x223a);
|
|
if (!isFinite(value)) {
|
|
this.writeStr(this.formatNonFinite(value));
|
|
}
|
|
else {
|
|
this.writeStr(value + '');
|
|
}
|
|
writer.u8(0x7d);
|
|
}
|
|
writeDateAsEjson(value) {
|
|
const timestamp = value.getTime();
|
|
if (isNaN(timestamp)) {
|
|
throw new Error('Invalid Date');
|
|
}
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246461);
|
|
writer.u16(0x7465);
|
|
writer.u16(0x223a);
|
|
if (this.options.canonical) {
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246e75);
|
|
writer.u32(0x6d626572);
|
|
writer.u32(0x4c6f6e67);
|
|
writer.u16(0x223a);
|
|
this.writeStr(timestamp + '');
|
|
writer.u8(0x7d);
|
|
}
|
|
else {
|
|
const year = value.getFullYear();
|
|
if (year >= 1970 && year <= 9999) {
|
|
this.writeStr(value.toISOString());
|
|
}
|
|
else {
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246e75);
|
|
writer.u32(0x6d626572);
|
|
writer.u32(0x4c6f6e67);
|
|
writer.u16(0x223a);
|
|
this.writeStr(timestamp + '');
|
|
writer.u8(0x7d);
|
|
}
|
|
}
|
|
writer.u8(0x7d);
|
|
}
|
|
writeRegExpAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22247265);
|
|
writer.u32(0x67756c61);
|
|
writer.u32(0x72457870);
|
|
writer.u32(0x72657373);
|
|
writer.u32(0x696f6e22);
|
|
writer.u16(0x3a7b);
|
|
writer.u32(0x22706174);
|
|
writer.u32(0x7465726e);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value.source);
|
|
writer.u8(0x2c);
|
|
writer.u32(0x226f7074);
|
|
writer.u32(0x696f6e73);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value.flags);
|
|
writer.u16(0x7d7d);
|
|
}
|
|
writeObjectIdAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246f69);
|
|
writer.u16(0x6422);
|
|
writer.u8(0x3a);
|
|
this.writeStr(this.objectIdToHex(value));
|
|
writer.u8(0x7d);
|
|
}
|
|
writeBsonInt32AsEjson(value) {
|
|
if (this.options.canonical) {
|
|
this.writeNumberIntWrapper(value.value);
|
|
}
|
|
else {
|
|
this.writeNumber(value.value);
|
|
}
|
|
}
|
|
writeBsonInt64AsEjson(value) {
|
|
if (this.options.canonical) {
|
|
this.writeNumberLongWrapper(value.value);
|
|
}
|
|
else {
|
|
this.writeNumber(value.value);
|
|
}
|
|
}
|
|
writeBsonFloatAsEjson(value) {
|
|
if (this.options.canonical) {
|
|
this.writeNumberDoubleWrapper(value.value);
|
|
}
|
|
else {
|
|
if (!isFinite(value.value)) {
|
|
this.writeNumberDoubleWrapper(value.value);
|
|
}
|
|
else {
|
|
this.writeNumber(value.value);
|
|
}
|
|
}
|
|
}
|
|
writeBsonDecimal128AsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246e75);
|
|
writer.u32(0x6d626572);
|
|
writer.u32(0x44656369);
|
|
writer.u32(0x6d616c22);
|
|
writer.u8(0x3a);
|
|
this.writeStr(this.decimal128ToString(value.data));
|
|
writer.u8(0x7d);
|
|
}
|
|
writeBsonBinaryAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246269);
|
|
writer.u32(0x6e617279);
|
|
writer.u16(0x223a);
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22626173);
|
|
writer.u32(0x65363422);
|
|
writer.u8(0x3a);
|
|
this.writeStr(this.uint8ArrayToBase64(value.data));
|
|
writer.u8(0x2c);
|
|
writer.u32(0x22737562);
|
|
writer.u32(0x54797065);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value.subtype.toString(16).padStart(2, '0'));
|
|
writer.u16(0x7d7d);
|
|
}
|
|
writeBsonCodeAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x2224636f);
|
|
writer.u16(0x6465);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value.code);
|
|
writer.u8(0x7d);
|
|
}
|
|
writeBsonCodeWScopeAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x2224636f);
|
|
writer.u16(0x6465);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value.code);
|
|
writer.u8(0x2c);
|
|
writer.u32(0x22247363);
|
|
writer.u32(0x6f706522);
|
|
writer.u8(0x3a);
|
|
this.writeAny(value.scope);
|
|
writer.u8(0x7d);
|
|
}
|
|
writeBsonSymbolAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22247379);
|
|
writer.u32(0x6d626f6c);
|
|
writer.u16(0x223a);
|
|
this.writeStr(value.symbol);
|
|
writer.u8(0x7d);
|
|
}
|
|
writeBsonTimestampAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22247469);
|
|
writer.u32(0x6d657374);
|
|
writer.u32(0x616d7022);
|
|
writer.u16(0x3a7b);
|
|
writer.u16(0x2274);
|
|
writer.u16(0x223a);
|
|
this.writeNumber(value.timestamp);
|
|
writer.u8(0x2c);
|
|
writer.u16(0x2269);
|
|
writer.u16(0x223a);
|
|
this.writeNumber(value.increment);
|
|
writer.u16(0x7d7d);
|
|
}
|
|
writeBsonDbPointerAsEjson(value) {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246462);
|
|
writer.u32(0x506f696e);
|
|
writer.u32(0x74657222);
|
|
writer.u16(0x3a7b);
|
|
writer.u32(0x22247265);
|
|
writer.u16(0x6622);
|
|
writer.u8(0x3a);
|
|
this.writeStr(value.name);
|
|
writer.u8(0x2c);
|
|
writer.u32(0x22246964);
|
|
writer.u16(0x223a);
|
|
this.writeAny(value.id);
|
|
writer.u16(0x7d7d);
|
|
}
|
|
writeBsonMinKeyAsEjson() {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246d69);
|
|
writer.u32(0x6e4b6579);
|
|
writer.u16(0x223a);
|
|
this.writeNumber(1);
|
|
writer.u8(0x7d);
|
|
}
|
|
writeBsonMaxKeyAsEjson() {
|
|
const writer = this.writer;
|
|
writer.u8(0x7b);
|
|
writer.u32(0x22246d61);
|
|
writer.u32(0x784b6579);
|
|
writer.u16(0x223a);
|
|
this.writeNumber(1);
|
|
writer.u8(0x7d);
|
|
}
|
|
formatNonFinite(value) {
|
|
if (value === Infinity)
|
|
return 'Infinity';
|
|
if (value === -Infinity)
|
|
return '-Infinity';
|
|
return 'NaN';
|
|
}
|
|
objectIdToHex(objectId) {
|
|
const timestamp = objectId.timestamp.toString(16).padStart(8, '0');
|
|
const process = objectId.process.toString(16).padStart(10, '0');
|
|
const counter = objectId.counter.toString(16).padStart(6, '0');
|
|
return timestamp + process + counter;
|
|
}
|
|
uint8ArrayToBase64(data) {
|
|
let binary = '';
|
|
for (let i = 0; i < data.length; i++) {
|
|
binary += String.fromCharCode(data[i]);
|
|
}
|
|
return btoa(binary);
|
|
}
|
|
decimal128ToString(data) {
|
|
return '0';
|
|
}
|
|
}
|
|
exports.EjsonEncoder = EjsonEncoder;
|
|
//# sourceMappingURL=EjsonEncoder.js.map
|