EjsonEncoder.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.EjsonEncoder = void 0;
  4. const values_1 = require("../bson/values");
  5. const toBase64Bin_1 = require("@jsonjoy.com/base64/lib/toBase64Bin");
  6. const JsonEncoder_1 = require("../json/JsonEncoder");
  7. class EjsonEncoder extends JsonEncoder_1.JsonEncoder {
  8. constructor(writer, options = {}) {
  9. super(writer);
  10. this.options = options;
  11. }
  12. encodeToString(value) {
  13. const bytes = this.encode(value);
  14. return new TextDecoder().decode(bytes);
  15. }
  16. writeUnknown(value) {
  17. this.writeNull();
  18. }
  19. writeAny(value) {
  20. if (value === null || value === undefined) {
  21. if (value === undefined) {
  22. return this.writeUndefinedWrapper();
  23. }
  24. return this.writeNull();
  25. }
  26. if (typeof value === 'boolean') {
  27. return this.writeBoolean(value);
  28. }
  29. if (typeof value === 'string') {
  30. return this.writeStr(value);
  31. }
  32. if (typeof value === 'number') {
  33. return this.writeNumberAsEjson(value);
  34. }
  35. if (Array.isArray(value)) {
  36. return this.writeArr(value);
  37. }
  38. if (value instanceof Date) {
  39. return this.writeDateAsEjson(value);
  40. }
  41. if (value instanceof RegExp) {
  42. return this.writeRegExpAsEjson(value);
  43. }
  44. if (value instanceof values_1.BsonObjectId) {
  45. return this.writeObjectIdAsEjson(value);
  46. }
  47. if (value instanceof values_1.BsonInt32) {
  48. return this.writeBsonInt32AsEjson(value);
  49. }
  50. if (value instanceof values_1.BsonInt64) {
  51. return this.writeBsonInt64AsEjson(value);
  52. }
  53. if (value instanceof values_1.BsonFloat) {
  54. return this.writeBsonFloatAsEjson(value);
  55. }
  56. if (value instanceof values_1.BsonDecimal128) {
  57. return this.writeBsonDecimal128AsEjson(value);
  58. }
  59. if (value instanceof values_1.BsonBinary) {
  60. return this.writeBsonBinaryAsEjson(value);
  61. }
  62. if (value instanceof values_1.BsonJavascriptCode) {
  63. return this.writeBsonCodeAsEjson(value);
  64. }
  65. if (value instanceof values_1.BsonJavascriptCodeWithScope) {
  66. return this.writeBsonCodeWScopeAsEjson(value);
  67. }
  68. if (value instanceof values_1.BsonSymbol) {
  69. return this.writeBsonSymbolAsEjson(value);
  70. }
  71. if (value instanceof values_1.BsonTimestamp) {
  72. return this.writeBsonTimestampAsEjson(value);
  73. }
  74. if (value instanceof values_1.BsonDbPointer) {
  75. return this.writeBsonDbPointerAsEjson(value);
  76. }
  77. if (value instanceof values_1.BsonMinKey) {
  78. return this.writeBsonMinKeyAsEjson();
  79. }
  80. if (value instanceof values_1.BsonMaxKey) {
  81. return this.writeBsonMaxKeyAsEjson();
  82. }
  83. if (typeof value === 'object' && value !== null) {
  84. return this.writeObj(value);
  85. }
  86. return this.writeUnknown(value);
  87. }
  88. writeBin(buf) {
  89. const writer = this.writer;
  90. const length = buf.length;
  91. writer.ensureCapacity(38 + 3 + (length << 1));
  92. const view = writer.view;
  93. let x = writer.x;
  94. view.setUint32(x, 577003892);
  95. x += 4;
  96. view.setUint32(x, 1631215984);
  97. x += 4;
  98. view.setUint32(x, 1886153059);
  99. x += 4;
  100. view.setUint32(x, 1635019119);
  101. x += 4;
  102. view.setUint32(x, 1848602467);
  103. x += 4;
  104. view.setUint32(x, 1952805933);
  105. x += 4;
  106. view.setUint32(x, 1937011301);
  107. x += 4;
  108. view.setUint32(x, 1634548578);
  109. x += 4;
  110. view.setUint32(x, 1634952502);
  111. x += 4;
  112. view.setUint16(x, 13356);
  113. x += 2;
  114. x = (0, toBase64Bin_1.toBase64Bin)(buf, 0, length, view, x);
  115. writer.uint8[x++] = 0x22;
  116. writer.x = x;
  117. }
  118. writeStr(str) {
  119. const writer = this.writer;
  120. const length = str.length;
  121. writer.ensureCapacity(length * 4 + 2);
  122. if (length < 256) {
  123. let x = writer.x;
  124. const uint8 = writer.uint8;
  125. uint8[x++] = 0x22;
  126. for (let i = 0; i < length; i++) {
  127. const code = str.charCodeAt(i);
  128. switch (code) {
  129. case 34:
  130. case 92:
  131. uint8[x++] = 0x5c;
  132. break;
  133. }
  134. if (code < 32 || code > 126) {
  135. writer.utf8(JSON.stringify(str));
  136. return;
  137. }
  138. else
  139. uint8[x++] = code;
  140. }
  141. uint8[x++] = 0x22;
  142. writer.x = x;
  143. return;
  144. }
  145. writer.utf8(JSON.stringify(str));
  146. }
  147. writeAsciiStr(str) {
  148. const length = str.length;
  149. const writer = this.writer;
  150. writer.ensureCapacity(length * 2 + 2);
  151. const uint8 = writer.uint8;
  152. let x = writer.x;
  153. uint8[x++] = 0x22;
  154. for (let i = 0; i < length; i++) {
  155. const code = str.charCodeAt(i);
  156. switch (code) {
  157. case 34:
  158. case 92:
  159. uint8[x++] = 0x5c;
  160. break;
  161. }
  162. uint8[x++] = code;
  163. }
  164. uint8[x++] = 0x22;
  165. writer.x = x;
  166. }
  167. writeArr(arr) {
  168. const writer = this.writer;
  169. writer.u8(0x5b);
  170. const length = arr.length;
  171. const last = length - 1;
  172. for (let i = 0; i < last; i++) {
  173. this.writeAny(arr[i]);
  174. writer.u8(0x2c);
  175. }
  176. if (last >= 0)
  177. this.writeAny(arr[last]);
  178. writer.u8(0x5d);
  179. }
  180. writeObj(obj) {
  181. const writer = this.writer;
  182. const keys = Object.keys(obj);
  183. const length = keys.length;
  184. if (!length)
  185. return writer.u16(0x7b7d);
  186. writer.u8(0x7b);
  187. for (let i = 0; i < length; i++) {
  188. const key = keys[i];
  189. const value = obj[key];
  190. this.writeStr(key);
  191. writer.u8(0x3a);
  192. this.writeAny(value);
  193. writer.u8(0x2c);
  194. }
  195. writer.uint8[writer.x - 1] = 0x7d;
  196. }
  197. writeUndefinedWrapper() {
  198. const writer = this.writer;
  199. writer.ensureCapacity(18);
  200. writer.u8(0x7b);
  201. writer.u32(0x2224756e);
  202. writer.u32(0x64656669);
  203. writer.u32(0x6e656422);
  204. writer.u8(0x3a);
  205. writer.u32(0x74727565);
  206. writer.u8(0x7d);
  207. }
  208. writeNumberAsEjson(value) {
  209. if (this.options.canonical) {
  210. if (Number.isInteger(value)) {
  211. if (value >= -2147483648 && value <= 2147483647) {
  212. this.writeNumberIntWrapper(value);
  213. }
  214. else {
  215. this.writeNumberLongWrapper(value);
  216. }
  217. }
  218. else {
  219. this.writeNumberDoubleWrapper(value);
  220. }
  221. }
  222. else {
  223. if (!isFinite(value)) {
  224. this.writeNumberDoubleWrapper(value);
  225. }
  226. else {
  227. this.writeNumber(value);
  228. }
  229. }
  230. }
  231. writeNumberIntWrapper(value) {
  232. const writer = this.writer;
  233. writer.u8(0x7b);
  234. writer.u32(0x22246e75);
  235. writer.u32(0x6d626572);
  236. writer.u32(0x496e7422);
  237. writer.u8(0x3a);
  238. this.writeStr(value + '');
  239. writer.u8(0x7d);
  240. }
  241. writeNumberLongWrapper(value) {
  242. const writer = this.writer;
  243. writer.u8(0x7b);
  244. writer.u32(0x22246e75);
  245. writer.u32(0x6d626572);
  246. writer.u32(0x4c6f6e67);
  247. writer.u16(0x223a);
  248. this.writeStr(value + '');
  249. writer.u8(0x7d);
  250. }
  251. writeNumberDoubleWrapper(value) {
  252. const writer = this.writer;
  253. writer.u8(0x7b);
  254. writer.u32(0x22246e75);
  255. writer.u32(0x6d626572);
  256. writer.u32(0x446f7562);
  257. writer.u16(0x6c65);
  258. writer.u16(0x223a);
  259. if (!isFinite(value)) {
  260. this.writeStr(this.formatNonFinite(value));
  261. }
  262. else {
  263. this.writeStr(value + '');
  264. }
  265. writer.u8(0x7d);
  266. }
  267. writeDateAsEjson(value) {
  268. const timestamp = value.getTime();
  269. if (isNaN(timestamp)) {
  270. throw new Error('Invalid Date');
  271. }
  272. const writer = this.writer;
  273. writer.u8(0x7b);
  274. writer.u32(0x22246461);
  275. writer.u16(0x7465);
  276. writer.u16(0x223a);
  277. if (this.options.canonical) {
  278. writer.u8(0x7b);
  279. writer.u32(0x22246e75);
  280. writer.u32(0x6d626572);
  281. writer.u32(0x4c6f6e67);
  282. writer.u16(0x223a);
  283. this.writeStr(timestamp + '');
  284. writer.u8(0x7d);
  285. }
  286. else {
  287. const year = value.getFullYear();
  288. if (year >= 1970 && year <= 9999) {
  289. this.writeStr(value.toISOString());
  290. }
  291. else {
  292. writer.u8(0x7b);
  293. writer.u32(0x22246e75);
  294. writer.u32(0x6d626572);
  295. writer.u32(0x4c6f6e67);
  296. writer.u16(0x223a);
  297. this.writeStr(timestamp + '');
  298. writer.u8(0x7d);
  299. }
  300. }
  301. writer.u8(0x7d);
  302. }
  303. writeRegExpAsEjson(value) {
  304. const writer = this.writer;
  305. writer.u8(0x7b);
  306. writer.u32(0x22247265);
  307. writer.u32(0x67756c61);
  308. writer.u32(0x72457870);
  309. writer.u32(0x72657373);
  310. writer.u32(0x696f6e22);
  311. writer.u16(0x3a7b);
  312. writer.u32(0x22706174);
  313. writer.u32(0x7465726e);
  314. writer.u16(0x223a);
  315. this.writeStr(value.source);
  316. writer.u8(0x2c);
  317. writer.u32(0x226f7074);
  318. writer.u32(0x696f6e73);
  319. writer.u16(0x223a);
  320. this.writeStr(value.flags);
  321. writer.u16(0x7d7d);
  322. }
  323. writeObjectIdAsEjson(value) {
  324. const writer = this.writer;
  325. writer.u8(0x7b);
  326. writer.u32(0x22246f69);
  327. writer.u16(0x6422);
  328. writer.u8(0x3a);
  329. this.writeStr(this.objectIdToHex(value));
  330. writer.u8(0x7d);
  331. }
  332. writeBsonInt32AsEjson(value) {
  333. if (this.options.canonical) {
  334. this.writeNumberIntWrapper(value.value);
  335. }
  336. else {
  337. this.writeNumber(value.value);
  338. }
  339. }
  340. writeBsonInt64AsEjson(value) {
  341. if (this.options.canonical) {
  342. this.writeNumberLongWrapper(value.value);
  343. }
  344. else {
  345. this.writeNumber(value.value);
  346. }
  347. }
  348. writeBsonFloatAsEjson(value) {
  349. if (this.options.canonical) {
  350. this.writeNumberDoubleWrapper(value.value);
  351. }
  352. else {
  353. if (!isFinite(value.value)) {
  354. this.writeNumberDoubleWrapper(value.value);
  355. }
  356. else {
  357. this.writeNumber(value.value);
  358. }
  359. }
  360. }
  361. writeBsonDecimal128AsEjson(value) {
  362. const writer = this.writer;
  363. writer.u8(0x7b);
  364. writer.u32(0x22246e75);
  365. writer.u32(0x6d626572);
  366. writer.u32(0x44656369);
  367. writer.u32(0x6d616c22);
  368. writer.u8(0x3a);
  369. this.writeStr(this.decimal128ToString(value.data));
  370. writer.u8(0x7d);
  371. }
  372. writeBsonBinaryAsEjson(value) {
  373. const writer = this.writer;
  374. writer.u8(0x7b);
  375. writer.u32(0x22246269);
  376. writer.u32(0x6e617279);
  377. writer.u16(0x223a);
  378. writer.u8(0x7b);
  379. writer.u32(0x22626173);
  380. writer.u32(0x65363422);
  381. writer.u8(0x3a);
  382. this.writeStr(this.uint8ArrayToBase64(value.data));
  383. writer.u8(0x2c);
  384. writer.u32(0x22737562);
  385. writer.u32(0x54797065);
  386. writer.u16(0x223a);
  387. this.writeStr(value.subtype.toString(16).padStart(2, '0'));
  388. writer.u16(0x7d7d);
  389. }
  390. writeBsonCodeAsEjson(value) {
  391. const writer = this.writer;
  392. writer.u8(0x7b);
  393. writer.u32(0x2224636f);
  394. writer.u16(0x6465);
  395. writer.u16(0x223a);
  396. this.writeStr(value.code);
  397. writer.u8(0x7d);
  398. }
  399. writeBsonCodeWScopeAsEjson(value) {
  400. const writer = this.writer;
  401. writer.u8(0x7b);
  402. writer.u32(0x2224636f);
  403. writer.u16(0x6465);
  404. writer.u16(0x223a);
  405. this.writeStr(value.code);
  406. writer.u8(0x2c);
  407. writer.u32(0x22247363);
  408. writer.u32(0x6f706522);
  409. writer.u8(0x3a);
  410. this.writeAny(value.scope);
  411. writer.u8(0x7d);
  412. }
  413. writeBsonSymbolAsEjson(value) {
  414. const writer = this.writer;
  415. writer.u8(0x7b);
  416. writer.u32(0x22247379);
  417. writer.u32(0x6d626f6c);
  418. writer.u16(0x223a);
  419. this.writeStr(value.symbol);
  420. writer.u8(0x7d);
  421. }
  422. writeBsonTimestampAsEjson(value) {
  423. const writer = this.writer;
  424. writer.u8(0x7b);
  425. writer.u32(0x22247469);
  426. writer.u32(0x6d657374);
  427. writer.u32(0x616d7022);
  428. writer.u16(0x3a7b);
  429. writer.u16(0x2274);
  430. writer.u16(0x223a);
  431. this.writeNumber(value.timestamp);
  432. writer.u8(0x2c);
  433. writer.u16(0x2269);
  434. writer.u16(0x223a);
  435. this.writeNumber(value.increment);
  436. writer.u16(0x7d7d);
  437. }
  438. writeBsonDbPointerAsEjson(value) {
  439. const writer = this.writer;
  440. writer.u8(0x7b);
  441. writer.u32(0x22246462);
  442. writer.u32(0x506f696e);
  443. writer.u32(0x74657222);
  444. writer.u16(0x3a7b);
  445. writer.u32(0x22247265);
  446. writer.u16(0x6622);
  447. writer.u8(0x3a);
  448. this.writeStr(value.name);
  449. writer.u8(0x2c);
  450. writer.u32(0x22246964);
  451. writer.u16(0x223a);
  452. this.writeAny(value.id);
  453. writer.u16(0x7d7d);
  454. }
  455. writeBsonMinKeyAsEjson() {
  456. const writer = this.writer;
  457. writer.u8(0x7b);
  458. writer.u32(0x22246d69);
  459. writer.u32(0x6e4b6579);
  460. writer.u16(0x223a);
  461. this.writeNumber(1);
  462. writer.u8(0x7d);
  463. }
  464. writeBsonMaxKeyAsEjson() {
  465. const writer = this.writer;
  466. writer.u8(0x7b);
  467. writer.u32(0x22246d61);
  468. writer.u32(0x784b6579);
  469. writer.u16(0x223a);
  470. this.writeNumber(1);
  471. writer.u8(0x7d);
  472. }
  473. formatNonFinite(value) {
  474. if (value === Infinity)
  475. return 'Infinity';
  476. if (value === -Infinity)
  477. return '-Infinity';
  478. return 'NaN';
  479. }
  480. objectIdToHex(objectId) {
  481. const timestamp = objectId.timestamp.toString(16).padStart(8, '0');
  482. const process = objectId.process.toString(16).padStart(10, '0');
  483. const counter = objectId.counter.toString(16).padStart(6, '0');
  484. return timestamp + process + counter;
  485. }
  486. uint8ArrayToBase64(data) {
  487. let binary = '';
  488. for (let i = 0; i < data.length; i++) {
  489. binary += String.fromCharCode(data[i]);
  490. }
  491. return btoa(binary);
  492. }
  493. decimal128ToString(data) {
  494. return '0';
  495. }
  496. }
  497. exports.EjsonEncoder = EjsonEncoder;
  498. //# sourceMappingURL=EjsonEncoder.js.map