CborEncoderFast.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.CborEncoderFast = void 0;
  4. const Writer_1 = require("@jsonjoy.com/util/lib/buffers/Writer");
  5. const isSafeInteger = Number.isSafeInteger;
  6. class CborEncoderFast {
  7. constructor(writer = new Writer_1.Writer()) {
  8. this.writer = writer;
  9. }
  10. encode(value) {
  11. this.writeAny(value);
  12. return this.writer.flush();
  13. }
  14. encodeToSlice(value) {
  15. this.writeAny(value);
  16. return this.writer.flushSlice();
  17. }
  18. writeAny(value) {
  19. switch (typeof value) {
  20. case 'number':
  21. return this.writeNumber(value);
  22. case 'string':
  23. return this.writeStr(value);
  24. case 'boolean':
  25. return this.writer.u8(0xf4 + +value);
  26. case 'object': {
  27. if (!value)
  28. return this.writer.u8(0xf6);
  29. const constructor = value.constructor;
  30. switch (constructor) {
  31. case Array:
  32. return this.writeArr(value);
  33. default:
  34. return this.writeObj(value);
  35. }
  36. }
  37. }
  38. }
  39. writeCbor() {
  40. this.writer.u8u16(0xd9, 0xd9f7);
  41. }
  42. writeEnd() {
  43. this.writer.u8(255);
  44. }
  45. writeNull() {
  46. this.writer.u8(0xf6);
  47. }
  48. writeBoolean(bool) {
  49. if (bool)
  50. this.writer.u8(0xf5);
  51. else
  52. this.writer.u8(0xf4);
  53. }
  54. writeNumber(num) {
  55. if (isSafeInteger(num))
  56. this.writeInteger(num);
  57. else if (typeof num === 'bigint')
  58. this.writeBigInt(num);
  59. else
  60. this.writeFloat(num);
  61. }
  62. writeBigInt(int) {
  63. if (int >= 0)
  64. this.writeBigUint(int);
  65. else
  66. this.writeBigSint(int);
  67. }
  68. writeBigUint(uint) {
  69. if (uint <= Number.MAX_SAFE_INTEGER)
  70. return this.writeUInteger(Number(uint));
  71. this.writer.u8u64(0x1b, uint);
  72. }
  73. writeBigSint(int) {
  74. if (int >= Number.MIN_SAFE_INTEGER)
  75. return this.encodeNint(Number(int));
  76. const uint = -BigInt(1) - int;
  77. this.writer.u8u64(0x3b, uint);
  78. }
  79. writeInteger(int) {
  80. if (int >= 0)
  81. this.writeUInteger(int);
  82. else
  83. this.encodeNint(int);
  84. }
  85. writeUInteger(uint) {
  86. const writer = this.writer;
  87. writer.ensureCapacity(9);
  88. const uint8 = writer.uint8;
  89. let x = writer.x;
  90. if (uint <= 23) {
  91. uint8[x++] = 0 + uint;
  92. }
  93. else if (uint <= 0xff) {
  94. uint8[x++] = 0x18;
  95. uint8[x++] = uint;
  96. }
  97. else if (uint <= 0xffff) {
  98. uint8[x++] = 0x19;
  99. writer.view.setUint16(x, uint);
  100. x += 2;
  101. }
  102. else if (uint <= 0xffffffff) {
  103. uint8[x++] = 0x1a;
  104. writer.view.setUint32(x, uint);
  105. x += 4;
  106. }
  107. else {
  108. uint8[x++] = 0x1b;
  109. writer.view.setBigUint64(x, BigInt(uint));
  110. x += 8;
  111. }
  112. writer.x = x;
  113. }
  114. encodeNumber(num) {
  115. this.writeNumber(num);
  116. }
  117. encodeInteger(int) {
  118. this.writeInteger(int);
  119. }
  120. encodeUint(uint) {
  121. this.writeUInteger(uint);
  122. }
  123. encodeNint(int) {
  124. const uint = -1 - int;
  125. const writer = this.writer;
  126. writer.ensureCapacity(9);
  127. const uint8 = writer.uint8;
  128. let x = writer.x;
  129. if (uint < 24) {
  130. uint8[x++] = 32 + uint;
  131. }
  132. else if (uint <= 0xff) {
  133. uint8[x++] = 0x38;
  134. uint8[x++] = uint;
  135. }
  136. else if (uint <= 0xffff) {
  137. uint8[x++] = 0x39;
  138. writer.view.setUint16(x, uint);
  139. x += 2;
  140. }
  141. else if (uint <= 0xffffffff) {
  142. uint8[x++] = 0x3a;
  143. writer.view.setUint32(x, uint);
  144. x += 4;
  145. }
  146. else {
  147. uint8[x++] = 0x3b;
  148. writer.view.setBigUint64(x, BigInt(uint));
  149. x += 8;
  150. }
  151. writer.x = x;
  152. }
  153. writeFloat(float) {
  154. this.writer.u8f64(0xfb, float);
  155. }
  156. writeBin(buf) {
  157. const length = buf.length;
  158. this.writeBinHdr(length);
  159. this.writer.buf(buf, length);
  160. }
  161. writeBinHdr(length) {
  162. const writer = this.writer;
  163. if (length <= 23)
  164. writer.u8(64 + length);
  165. else if (length <= 0xff)
  166. writer.u16((0x58 << 8) + length);
  167. else if (length <= 0xffff)
  168. writer.u8u16(0x59, length);
  169. else if (length <= 0xffffffff)
  170. writer.u8u32(0x5a, length);
  171. else
  172. writer.u8u64(0x5b, length);
  173. }
  174. writeStr(str) {
  175. const writer = this.writer;
  176. const length = str.length;
  177. const maxSize = length * 4;
  178. writer.ensureCapacity(5 + maxSize);
  179. const uint8 = writer.uint8;
  180. let lengthOffset = writer.x;
  181. if (maxSize <= 23)
  182. writer.x++;
  183. else if (maxSize <= 0xff) {
  184. uint8[writer.x++] = 0x78;
  185. lengthOffset = writer.x;
  186. writer.x++;
  187. }
  188. else if (maxSize <= 0xffff) {
  189. uint8[writer.x++] = 0x79;
  190. lengthOffset = writer.x;
  191. writer.x += 2;
  192. }
  193. else {
  194. uint8[writer.x++] = 0x7a;
  195. lengthOffset = writer.x;
  196. writer.x += 4;
  197. }
  198. const bytesWritten = writer.utf8(str);
  199. if (maxSize <= 23)
  200. uint8[lengthOffset] = 96 + bytesWritten;
  201. else if (maxSize <= 0xff)
  202. uint8[lengthOffset] = bytesWritten;
  203. else if (maxSize <= 0xffff)
  204. writer.view.setUint16(lengthOffset, bytesWritten);
  205. else
  206. writer.view.setUint32(lengthOffset, bytesWritten);
  207. }
  208. writeStrHdr(length) {
  209. const writer = this.writer;
  210. if (length <= 23)
  211. writer.u8(96 + length);
  212. else if (length <= 0xff)
  213. writer.u16((0x78 << 8) + length);
  214. else if (length <= 0xffff)
  215. writer.u8u16(0x79, length);
  216. else
  217. writer.u8u32(0x7a, length);
  218. }
  219. writeAsciiStr(str) {
  220. this.writeStrHdr(str.length);
  221. this.writer.ascii(str);
  222. }
  223. writeArr(arr) {
  224. const length = arr.length;
  225. this.writeArrHdr(length);
  226. for (let i = 0; i < length; i++)
  227. this.writeAny(arr[i]);
  228. }
  229. writeArrHdr(length) {
  230. const writer = this.writer;
  231. if (length <= 23)
  232. writer.u8(128 + length);
  233. else if (length <= 0xff)
  234. writer.u16((0x98 << 8) + length);
  235. else if (length <= 0xffff)
  236. writer.u8u16(0x99, length);
  237. else if (length <= 0xffffffff)
  238. writer.u8u32(0x9a, length);
  239. else
  240. writer.u8u64(0x9b, length);
  241. }
  242. writeObj(obj) {
  243. const keys = Object.keys(obj);
  244. const length = keys.length;
  245. this.writeObjHdr(length);
  246. for (let i = 0; i < length; i++) {
  247. const key = keys[i];
  248. this.writeStr(key);
  249. this.writeAny(obj[key]);
  250. }
  251. }
  252. writeObjHdr(length) {
  253. const writer = this.writer;
  254. if (length <= 23)
  255. writer.u8(160 + length);
  256. else if (length <= 0xff)
  257. writer.u16((0xb8 << 8) + length);
  258. else if (length <= 0xffff)
  259. writer.u8u16(0xb9, length);
  260. else if (length <= 0xffffffff)
  261. writer.u8u32(0xba, length);
  262. else
  263. writer.u8u64(0xbb, length);
  264. }
  265. writeMapHdr(length) {
  266. this.writeObjHdr(length);
  267. }
  268. writeStartMap() {
  269. this.writer.u8(0xbf);
  270. }
  271. writeTag(tag, value) {
  272. this.writeTagHdr(tag);
  273. this.writeAny(value);
  274. }
  275. writeTagHdr(tag) {
  276. const writer = this.writer;
  277. if (tag <= 23)
  278. writer.u8(192 + tag);
  279. else if (tag <= 0xff)
  280. writer.u16((0xd8 << 8) + tag);
  281. else if (tag <= 0xffff)
  282. writer.u8u16(0xd9, tag);
  283. else if (tag <= 0xffffffff)
  284. writer.u8u32(0xda, tag);
  285. else
  286. writer.u8u64(0xdb, tag);
  287. }
  288. writeTkn(value) {
  289. const writer = this.writer;
  290. if (value <= 23)
  291. writer.u8(224 + value);
  292. else if (value <= 0xff)
  293. writer.u16((0xf8 << 8) + value);
  294. }
  295. writeStartStr() {
  296. this.writer.u8(0x7f);
  297. }
  298. writeStrChunk(str) {
  299. throw new Error('Not implemented');
  300. }
  301. writeEndStr() {
  302. throw new Error('Not implemented');
  303. }
  304. writeStartBin() {
  305. this.writer.u8(0x5f);
  306. }
  307. writeBinChunk(buf) {
  308. throw new Error('Not implemented');
  309. }
  310. writeEndBin() {
  311. throw new Error('Not implemented');
  312. }
  313. writeStartArr() {
  314. this.writer.u8(0x9f);
  315. }
  316. writeArrChunk(item) {
  317. throw new Error('Not implemented');
  318. }
  319. writeEndArr() {
  320. this.writer.u8(255);
  321. }
  322. writeStartObj() {
  323. this.writer.u8(0xbf);
  324. }
  325. writeObjChunk(key, value) {
  326. throw new Error('Not implemented');
  327. }
  328. writeEndObj() {
  329. this.writer.u8(255);
  330. }
  331. }
  332. exports.CborEncoderFast = CborEncoderFast;
  333. //# sourceMappingURL=CborEncoderFast.js.map