base.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. var base = base || {};
  2. base.Int64 = class Int64 {
  3. constructor(low, high) {
  4. this.low = low | 0;
  5. this.high = high | 0;
  6. }
  7. static create(value) {
  8. if (isNaN(value)) {
  9. return base.Int64.zero;
  10. }
  11. if (value <= -9223372036854776000) {
  12. return base.Int64.min;
  13. }
  14. if (value + 1 >= 9223372036854776000) {
  15. return base.Int64.max;
  16. }
  17. if (value < 0) {
  18. return base.Int64.create(-value).negate();
  19. }
  20. return new base.Int64((value % 4294967296) | 0, (value / 4294967296));
  21. }
  22. get isZero() {
  23. return this.low === 0 && this.high === 0;
  24. }
  25. get isNegative() {
  26. return this.high < 0;
  27. }
  28. negate() {
  29. if (this.equals(base.Int64.min)) {
  30. return base.Int64.min;
  31. }
  32. return this.not().add(base.Int64.one);
  33. }
  34. not() {
  35. return new Int64(~this.low, ~this.high);
  36. }
  37. equals(other) {
  38. if (!(other instanceof base.Int64) && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) {
  39. return false;
  40. }
  41. return this.high === other.high && this.low === other.low;
  42. }
  43. compare(other) {
  44. if (this.equals(other)) {
  45. return 0;
  46. }
  47. const thisNeg = this.isNegative;
  48. const otherNeg = other.isNegative;
  49. if (thisNeg && !otherNeg) {
  50. return -1;
  51. }
  52. if (!thisNeg && otherNeg) {
  53. return 1;
  54. }
  55. return this.subtract(other).isNegative ? -1 : 1;
  56. }
  57. add(other) {
  58. return base.Utility.add(this, other, false);
  59. }
  60. subtract(other) {
  61. return base.Utility.subtract(this, other, false);
  62. }
  63. multiply(other) {
  64. return base.Utility.multiply(this, other, false);
  65. }
  66. divide(other) {
  67. return base.Utility.divide(this, other, false);
  68. }
  69. toInteger() {
  70. return this.low;
  71. }
  72. toNumber() {
  73. if (this.high === 0) {
  74. return this.low >>> 0;
  75. }
  76. if (this.high === -1) {
  77. return this.low;
  78. }
  79. return (this.high * 4294967296) + (this.low >>> 0);
  80. }
  81. toString(radix) {
  82. const r = radix || 10;
  83. if (r < 2 || r > 16) {
  84. throw new RangeError('radix');
  85. }
  86. if (this.isZero) {
  87. return '0';
  88. }
  89. if (this.high < 0) {
  90. if (this.equals(base.Int64.min)) {
  91. const r = new Int64(radix, 0);
  92. const div = this.divide(r);
  93. const remainder = div.multiply(r).subtract(this);
  94. return div.toString(r) + (remainder.low >>> 0).toString(r);
  95. }
  96. return '-' + this.negate().toString(r);
  97. }
  98. if (this.high === 0) {
  99. return this.low.toString(radix);
  100. }
  101. return base.Utility.text(this, false, r);
  102. }
  103. };
  104. base.Int64.min = new base.Int64(0, -2147483648);
  105. base.Int64.zero = new base.Int64(0, 0);
  106. base.Int64.one = new base.Int64(1, 0);
  107. base.Int64.power24 = new base.Int64(1 << 24, 0);
  108. base.Int64.max = new base.Int64(0, 2147483647);
  109. base.Uint64 = class Uint64 {
  110. constructor(low, high) {
  111. this.low = low | 0;
  112. this.high = high | 0;
  113. }
  114. static create(value) {
  115. if (isNaN(value)) {
  116. return base.Uint64.zero;
  117. }
  118. if (value < 0) {
  119. return base.Uint64.zero;
  120. }
  121. if (value >= 18446744073709552000) {
  122. return base.Uint64.max;
  123. }
  124. if (value < 0) {
  125. return base.Uint64.create(-value).negate();
  126. }
  127. return new base.Uint64((value % 4294967296) | 0, (value / 4294967296));
  128. }
  129. get isZero() {
  130. return this.low === 0 && this.high === 0;
  131. }
  132. get isNegative() {
  133. return false;
  134. }
  135. negate() {
  136. return this.not().add(base.Int64.one);
  137. }
  138. not() {
  139. return new base.Uint64(~this.low, ~this.high);
  140. }
  141. equals(other) {
  142. if (!(other instanceof base.Uint64) && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) {
  143. return false;
  144. }
  145. return this.high === other.high && this.low === other.low;
  146. }
  147. compare(other) {
  148. if (this.equals(other)) {
  149. return 0;
  150. }
  151. const thisNeg = this.isNegative;
  152. const otherNeg = other.isNegative;
  153. if (thisNeg && !otherNeg) {
  154. return -1;
  155. }
  156. if (!thisNeg && otherNeg) {
  157. return 1;
  158. }
  159. return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
  160. }
  161. add(other) {
  162. return base.Utility.add(this, other, true);
  163. }
  164. subtract(other) {
  165. return base.Utility.subtract(this, other, true);
  166. }
  167. multiply(other) {
  168. return base.Utility.multiply(this, other, true);
  169. }
  170. divide(other) {
  171. return base.Utility.divide(this, other, true);
  172. }
  173. toInteger() {
  174. return this.low >>> 0;
  175. }
  176. toNumber() {
  177. if (this.high === 0) {
  178. return this.low >>> 0;
  179. }
  180. return ((this.high >>> 0) * 4294967296) + (this.low >>> 0);
  181. }
  182. toString(radix) {
  183. const r = radix || 10;
  184. if (r < 2 || 36 < r) {
  185. throw new RangeError('radix');
  186. }
  187. if (this.isZero) {
  188. return '0';
  189. }
  190. if (this.high === 0) {
  191. return this.low.toString(radix);
  192. }
  193. return base.Utility.text(this, true, r);
  194. }
  195. };
  196. base.Utility = class {
  197. static add(a, b, unsigned) {
  198. const a48 = a.high >>> 16;
  199. const a32 = a.high & 0xFFFF;
  200. const a16 = a.low >>> 16;
  201. const a00 = a.low & 0xFFFF;
  202. const b48 = b.high >>> 16;
  203. const b32 = b.high & 0xFFFF;
  204. const b16 = b.low >>> 16;
  205. const b00 = b.low & 0xFFFF;
  206. let c48 = 0;
  207. let c32 = 0;
  208. let c16 = 0;
  209. let c00 = 0;
  210. c00 += a00 + b00;
  211. c16 += c00 >>> 16;
  212. c00 &= 0xFFFF;
  213. c16 += a16 + b16;
  214. c32 += c16 >>> 16;
  215. c16 &= 0xFFFF;
  216. c32 += a32 + b32;
  217. c48 += c32 >>> 16;
  218. c32 &= 0xFFFF;
  219. c48 += a48 + b48;
  220. c48 &= 0xFFFF;
  221. return base.Utility._create((c16 << 16) | c00, (c48 << 16) | c32, unsigned);
  222. }
  223. static subtract(a, b, unsigned) {
  224. return base.Utility.add(a, b.negate(), unsigned);
  225. }
  226. static multiply(a, b, unsigned) {
  227. if (a.isZero) {
  228. return base.Int64.zero;
  229. }
  230. if (b.isZero) {
  231. return base.Int64.zero;
  232. }
  233. if (a.equals(base.Int64.min)) {
  234. return b.isOdd() ? base.Int64.min : base.Int64.zero;
  235. }
  236. if (b.equals(base.Int64.min)) {
  237. return b.isOdd() ? base.Int64.min : base.Int64.zero;
  238. }
  239. if (a.isNegative) {
  240. if (b.isNegative) {
  241. return this.negate().multiply(b.negate());
  242. }
  243. return this.negate().multiply(b).negate();
  244. }
  245. else if (b.isNegative) {
  246. return this.multiply(b.negate()).negate();
  247. }
  248. if (a.compare(base.Int64.power24) < 0 && b.compare(base.Int64.power24) < 0) {
  249. return unsigned ? base.Uint64.create(a.toNumber() * b.toNumber()) : base.Int64.create(a.toNumber() * b.toNumber());
  250. }
  251. const a48 = a.high >>> 16;
  252. const a32 = a.high & 0xFFFF;
  253. const a16 = a.low >>> 16;
  254. const a00 = a.low & 0xFFFF;
  255. const b48 = b.high >>> 16;
  256. const b32 = b.high & 0xFFFF;
  257. const b16 = b.low >>> 16;
  258. const b00 = b.low & 0xFFFF;
  259. let c48 = 0;
  260. let c32 = 0;
  261. let c16 = 0;
  262. let c00 = 0;
  263. c00 += a00 * b00;
  264. c16 += c00 >>> 16;
  265. c00 &= 0xFFFF;
  266. c16 += a16 * b00;
  267. c32 += c16 >>> 16;
  268. c16 &= 0xFFFF;
  269. c16 += a00 * b16;
  270. c32 += c16 >>> 16;
  271. c16 &= 0xFFFF;
  272. c32 += a32 * b00;
  273. c48 += c32 >>> 16;
  274. c32 &= 0xFFFF;
  275. c32 += a16 * b16;
  276. c48 += c32 >>> 16;
  277. c32 &= 0xFFFF;
  278. c32 += a00 * b32;
  279. c48 += c32 >>> 16;
  280. c32 &= 0xFFFF;
  281. c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
  282. c48 &= 0xFFFF;
  283. return base.Utility._create((c16 << 16) | c00, (c48 << 16) | c32, unsigned);
  284. }
  285. static divide(a, b, unsigned) {
  286. if (b.isZero) {
  287. throw new Error('Division by zero.');
  288. }
  289. if (a.isZero) {
  290. return unsigned ? base.Uint64.zero : base.Int64.zero;
  291. }
  292. let approx;
  293. let remainder;
  294. let result;
  295. if (!unsigned) {
  296. if (a.equals(base.Int64.min)) {
  297. if (b.equals(base.Int64.one) || b.equals(base.Int64.negativeOne)) {
  298. return base.Int64.min;
  299. }
  300. else if (b.equals(base.Int64.min)) {
  301. return base.Int64.one;
  302. }
  303. const half = base.Utility._shiftRight(a, unsigned, 1);
  304. const halfDivide = half.divide(b);
  305. approx = base.Utility._shiftLeft(halfDivide, halfDivide instanceof base.Uint64, 1);
  306. if (approx.eq(base.Int64.zero)) {
  307. return b.isNegative ? base.Int64.one : base.Int64.negativeOne;
  308. }
  309. remainder = a.subtract(b.multiply(approx));
  310. result = approx.add(remainder.divide(b));
  311. return result;
  312. }
  313. else if (b.equals(base.Int64.min)) {
  314. return unsigned ? base.Uint64.zero : base.Int64.zero;
  315. }
  316. if (a.isNegative) {
  317. if (b.isNegative) {
  318. return this.negate().divide(b.negate());
  319. }
  320. return a.negate().divide(b).negate();
  321. }
  322. else if (b.isNegative) {
  323. return a.divide(b.negate()).negate();
  324. }
  325. result = base.Int64.zero;
  326. }
  327. else {
  328. if (!(b instanceof base.Uint64)) {
  329. b = new base.Uint64(b.low, b.high);
  330. }
  331. if (b.compare(a) > 0) {
  332. return base.Int64.zero;
  333. }
  334. if (b.compare(base.Utility._shiftRight(a, unsigned, 1)) > 0) {
  335. return base.Uint64.one;
  336. }
  337. result = base.Uint64.zero;
  338. }
  339. remainder = a;
  340. while (remainder.compare(b) >= 0) {
  341. let approx = Math.max(1, Math.floor(remainder.toNumber() / b.toNumber()));
  342. const log2 = Math.ceil(Math.log(approx) / Math.LN2);
  343. const delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
  344. let approxResult = base.Int64.create(approx);
  345. let approxRemainder = approxResult.multiply(b);
  346. while (approxRemainder.isNegative || approxRemainder.compare(remainder) > 0) {
  347. approx -= delta;
  348. approxResult = unsigned ? base.Uint64.create(approx) : base.Int64.create(approx);
  349. approxRemainder = approxResult.multiply(b);
  350. }
  351. if (approxResult.isZero) {
  352. approxResult = base.Int64.one;
  353. }
  354. result = result.add(approxResult);
  355. remainder = remainder.subtract(approxRemainder);
  356. }
  357. return result;
  358. }
  359. static text(value, unsigned, radix) {
  360. const power = unsigned ? base.Uint64.create(Math.pow(radix, 6)) : base.Int64.create(Math.pow(radix, 6));
  361. let remainder = value;
  362. let result = '';
  363. for (;;) {
  364. const remainderDiv = remainder.divide(power);
  365. const intval = remainder.subtract(remainderDiv.multiply(power)).toInteger() >>> 0;
  366. let digits = intval.toString(radix);
  367. remainder = remainderDiv;
  368. if (remainder.low === 0 && remainder.high === 0) {
  369. return digits + result;
  370. }
  371. while (digits.length < 6) {
  372. digits = '0' + digits;
  373. }
  374. result = '' + digits + result;
  375. }
  376. }
  377. static _shiftLeft(value, unsigned, shift) {
  378. return base.Utility._create(value.low << shift, (value.high << shift) | (value.low >>> (32 - shift)), unsigned);
  379. }
  380. static _shiftRight(value, unsigned, shift) {
  381. return base.Utility._create((value.low >>> shift) | (value.high << (32 - shift)), value.high >> shift, unsigned);
  382. }
  383. static _create(low, high, unsigned) {
  384. return unsigned ? new base.Uint64(low, high) : new base.Int64(low, high);
  385. }
  386. };
  387. base.Uint64.zero = new base.Uint64(0, 0);
  388. base.Uint64.one = new base.Uint64(1, 0);
  389. base.Uint64.max = new base.Uint64(-1, -1);
  390. base.Complex = class Complex {
  391. constructor(real, imaginary) {
  392. this.real = real;
  393. this.imaginary = imaginary;
  394. }
  395. static create(real, imaginary) {
  396. return new base.Complex(real, imaginary);
  397. }
  398. toString(/* radix */) {
  399. return this.real + ' + ' + this.imaginary + 'i';
  400. }
  401. };
  402. if (!DataView.prototype.getFloat16) {
  403. DataView.prototype.getFloat16 = function(byteOffset, littleEndian) {
  404. const value = this.getUint16(byteOffset, littleEndian);
  405. const e = (value & 0x7C00) >> 10;
  406. let f = value & 0x03FF;
  407. if (e == 0) {
  408. f = 0.00006103515625 * (f / 1024);
  409. }
  410. else if (e == 0x1F) {
  411. f = f ? NaN : Infinity;
  412. }
  413. else {
  414. f = DataView.__float16_pow[e] * (1 + (f / 1024));
  415. }
  416. return value & 0x8000 ? -f : f;
  417. };
  418. DataView.__float16_pow = {
  419. 1: 1/16384, 2: 1/8192, 3: 1/4096, 4: 1/2048, 5: 1/1024, 6: 1/512, 7: 1/256, 8: 1/128,
  420. 9: 1/64, 10: 1/32, 11: 1/16, 12: 1/8, 13: 1/4, 14: 1/2, 15: 1, 16: 2,
  421. 17: 4, 18: 8, 19: 16, 20: 32, 21: 64, 22: 128, 23: 256, 24: 512,
  422. 25: 1024, 26: 2048, 27: 4096, 28: 8192, 29: 16384, 30: 32768, 31: 65536
  423. };
  424. }
  425. if (!DataView.prototype.setFloat16) {
  426. DataView.prototype.setFloat16 = function(byteOffset, value, littleEndian) {
  427. DataView.__float16_float[0] = value;
  428. value = DataView.__float16_int[0];
  429. const s = (value >>> 16) & 0x8000;
  430. const e = (value >>> 23) & 0xff;
  431. const f = value & 0x7fffff;
  432. const v = s | DataView.__float16_base[e] | (f >> DataView.__float16_shift[e]);
  433. this.setUint16(byteOffset, v, littleEndian);
  434. };
  435. DataView.__float16_float = new Float32Array(1);
  436. DataView.__float16_int = new Uint32Array(DataView.__float16_float.buffer, 0, DataView.__float16_float.length);
  437. DataView.__float16_base = new Uint32Array(256);
  438. DataView.__float16_shift = new Uint32Array(256);
  439. for (let i = 0; i < 256; ++i) {
  440. const e = i - 127;
  441. if (e < -27) {
  442. DataView.__float16_base[i] = 0x0000;
  443. DataView.__float16_shift[i] = 24;
  444. }
  445. else if (e < -14) {
  446. DataView.__float16_base[i] = 0x0400 >> -e - 14;
  447. DataView.__float16_shift[i] = -e - 1;
  448. }
  449. else if (e <= 15) {
  450. DataView.__float16_base[i] = e + 15 << 10;
  451. DataView.__float16_shift[i] = 13;
  452. }
  453. else if (e < 128) {
  454. DataView.__float16_base[i] = 0x7c00;
  455. DataView.__float16_shift[i] = 24;
  456. }
  457. else {
  458. DataView.__float16_base[i] = 0x7c00;
  459. DataView.__float16_shift[i] = 13;
  460. }
  461. }
  462. }
  463. if (!DataView.prototype.getBfloat16) {
  464. DataView.prototype.getBfloat16 = function(byteOffset, littleEndian) {
  465. if (littleEndian) {
  466. DataView.__bfloat16_get_uint16_le[1] = this.getUint16(byteOffset, littleEndian);
  467. return DataView.__bfloat16_get_float32_le[0];
  468. }
  469. DataView.__bfloat16_uint16_be[0] = this.getUint16(byteOffset, littleEndian);
  470. return DataView.__bfloat16_get_float32_be[0];
  471. };
  472. DataView.__bfloat16_get_float32_le = new Float32Array(1);
  473. DataView.__bfloat16_get_float32_be = new Float32Array(1);
  474. DataView.__bfloat16_get_uint16_le = new Uint16Array(DataView.__bfloat16_get_float32_le.buffer, DataView.__bfloat16_get_float32_le.byteOffset, 2);
  475. DataView.__bfloat16_get_uint16_be = new Uint16Array(DataView.__bfloat16_get_float32_be.buffer, DataView.__bfloat16_get_float32_be.byteOffset, 2);
  476. }
  477. DataView.prototype.getInt64 = DataView.prototype.getInt64 || function(byteOffset, littleEndian) {
  478. return littleEndian ?
  479. new base.Int64(this.getUint32(byteOffset, true), this.getUint32(byteOffset + 4, true)) :
  480. new base.Int64(this.getUint32(byteOffset + 4, true), this.getUint32(byteOffset, true));
  481. };
  482. DataView.prototype.setInt64 = DataView.prototype.setInt64 || function(byteOffset, value, littleEndian) {
  483. if (littleEndian) {
  484. this.setUint32(byteOffset, value.low, true);
  485. this.setUint32(byteOffset + 4, value.high, true);
  486. }
  487. else {
  488. this.setUint32(byteOffset + 4, value.low, false);
  489. this.setUint32(byteOffset, value.high, false);
  490. }
  491. };
  492. DataView.prototype.getUint64 = DataView.prototype.getUint64 || function(byteOffset, littleEndian) {
  493. return littleEndian ?
  494. new base.Uint64(this.getUint32(byteOffset, true), this.getUint32(byteOffset + 4, true)) :
  495. new base.Uint64(this.getUint32(byteOffset + 4, true), this.getUint32(byteOffset, true));
  496. };
  497. DataView.prototype.setUint64 = DataView.prototype.setUint64 || function(byteOffset, value, littleEndian) {
  498. if (littleEndian) {
  499. this.setUint32(byteOffset, value.low, true);
  500. this.setUint32(byteOffset + 4, value.high, true);
  501. }
  502. else {
  503. this.setUint32(byteOffset + 4, value.low, false);
  504. this.setUint32(byteOffset, value.high, false);
  505. }
  506. };
  507. DataView.prototype.getComplex64 = DataView.prototype.getComplex64 || function(byteOffset, littleEndian) {
  508. const real = littleEndian ? this.getFloat32(byteOffset, littleEndian) : this.getFloat32(byteOffset + 4, littleEndian);
  509. const imaginary = littleEndian ? this.getFloat32(byteOffset + 4, littleEndian) : this.getFloat32(byteOffset, littleEndian);
  510. return base.Complex.create(real, imaginary);
  511. };
  512. DataView.prototype.setComplex64 = DataView.prototype.setComplex64 || function(byteOffset, value, littleEndian) {
  513. if (littleEndian) {
  514. this.setFloat32(byteOffset, value.real, littleEndian);
  515. this.setFloat32(byteOffset + 4, value.imaginary, littleEndian);
  516. }
  517. else {
  518. this.setFloat32(byteOffset + 4, value.real, littleEndian);
  519. this.setFloat32(byteOffset, value.imaginary, littleEndian);
  520. }
  521. };
  522. DataView.prototype.getComplex128 = DataView.prototype.getComplex128 || function(byteOffset, littleEndian) {
  523. const real = littleEndian ? this.getFloat64(byteOffset, littleEndian) : this.getFloat64(byteOffset + 8, littleEndian);
  524. const imaginary = littleEndian ? this.getFloat64(byteOffset + 8, littleEndian) : this.getFloat64(byteOffset, littleEndian);
  525. return base.Complex.create(real, imaginary);
  526. };
  527. DataView.prototype.setComplex128 = DataView.prototype.setComplex128 || function(byteOffset, value, littleEndian) {
  528. if (littleEndian) {
  529. this.setFloat64(byteOffset, value.real, littleEndian);
  530. this.setFloat64(byteOffset + 8, value.imaginary, littleEndian);
  531. }
  532. else {
  533. this.setFloat64(byteOffset + 8, value.real, littleEndian);
  534. this.setFloat64(byteOffset, value.imaginary, littleEndian);
  535. }
  536. };
  537. DataView.prototype.getBits = DataView.prototype.getBits || function(offset, bits /*, signed */) {
  538. offset = offset * bits;
  539. const available = (this.byteLength << 3) - offset;
  540. if (bits > available) {
  541. throw new RangeError();
  542. }
  543. let value = 0;
  544. let index = 0;
  545. while (index < bits) {
  546. const remainder = offset & 7;
  547. const size = Math.min(bits - index, 8 - remainder);
  548. value <<= size;
  549. value |= (this.getUint8(offset >> 3) >> (8 - size - remainder)) & ~(0xff << size);
  550. offset += size;
  551. index += size;
  552. }
  553. return value;
  554. };
  555. base.BinaryReader = class {
  556. constructor(data) {
  557. this._buffer = data instanceof Uint8Array ? data : data.peek();
  558. this._position = 0;
  559. this._length = this._buffer.length;
  560. this._view = new DataView(this._buffer.buffer, this._buffer.byteOffset, this._buffer.byteLength);
  561. }
  562. get length() {
  563. return this._length;
  564. }
  565. get position() {
  566. return this._position;
  567. }
  568. seek(position) {
  569. this._position = position >= 0 ? position : this._length + position;
  570. if (this._position > this._length || this._position < 0) {
  571. throw new Error('Expected ' + (this._position - this._length) + ' more bytes. The file might be corrupted. Unexpected end of file.');
  572. }
  573. }
  574. skip(offset) {
  575. this._position += offset;
  576. if (this._position > this._length) {
  577. throw new Error('Expected ' + (this._position - this._length) + ' more bytes. The file might be corrupted. Unexpected end of file.');
  578. }
  579. }
  580. align(mod) {
  581. if (this._position % mod != 0) {
  582. this.skip(mod - (this._position % mod));
  583. }
  584. }
  585. peek(length) {
  586. if (this._position === 0 && length === undefined) {
  587. return this._buffer;
  588. }
  589. const position = this._position;
  590. this.skip(length !== undefined ? length : this._length - this._position);
  591. const end = this._position;
  592. this._position = position;
  593. return this._buffer.slice(position, end);
  594. }
  595. read(length) {
  596. if (this._position === 0 && length === undefined) {
  597. this._position = this._length;
  598. return this._buffer;
  599. }
  600. const position = this._position;
  601. this.skip(length !== undefined ? length : this._length - this._position);
  602. return this._buffer.slice(position, this._position);
  603. }
  604. byte() {
  605. const position = this._position;
  606. this.skip(1);
  607. return this._buffer[position];
  608. }
  609. int8() {
  610. const position = this._position;
  611. this.skip(1);
  612. return this._view.getInt8(position, true);
  613. }
  614. int16() {
  615. const position = this._position;
  616. this.skip(2);
  617. return this._view.getInt16(position, true);
  618. }
  619. int32() {
  620. const position = this._position;
  621. this.skip(4);
  622. return this._view.getInt32(position, true);
  623. }
  624. int64() {
  625. const position = this._position;
  626. this.skip(8);
  627. return this._view.getInt64(position, true).toNumber();
  628. }
  629. uint16() {
  630. const position = this._position;
  631. this.skip(2);
  632. return this._view.getUint16(position, true);
  633. }
  634. uint32() {
  635. const position = this._position;
  636. this.skip(4);
  637. return this._view.getUint32(position, true);
  638. }
  639. uint64() {
  640. const position = this._position;
  641. this.skip(8);
  642. const low = this._view.getUint32(position, true);
  643. const high = this._view.getUint32(position + 4, true);
  644. if (high === 0) {
  645. return low;
  646. }
  647. const value = (high * 4294967296) + low;
  648. if (Number.isSafeInteger(value)) {
  649. return value;
  650. }
  651. throw new Error("Unsigned 64-bit value exceeds safe integer.");
  652. }
  653. float32() {
  654. const position = this._position;
  655. this.skip(4);
  656. return this._view.getFloat32(position, true);
  657. }
  658. float64() {
  659. const position = this._position;
  660. this.skip(8);
  661. return this._view.getFloat64(position, true);
  662. }
  663. string() {
  664. const length = this.uint32();
  665. const position = this._position;
  666. this.skip(length);
  667. const data = this._buffer.subarray(position, this._position);
  668. this._decoder = this._decoder || new TextDecoder('utf-8');
  669. return this._decoder.decode(data);
  670. }
  671. boolean() {
  672. return this.byte() !== 0 ? true : false;
  673. }
  674. };
  675. base.Metadata = class {
  676. static open(context, name) {
  677. base.Metadata._metadata = base.Metadata._metadata || new Map();
  678. if (base.Metadata._metadata.has(name)) {
  679. return Promise.resolve(base.Metadata._metadata.get(name));
  680. }
  681. return context.request(name, 'utf-8', null).then((data) => {
  682. const library = new base.Metadata(data);
  683. base.Metadata._metadata.set(name, library);
  684. return library;
  685. }).catch(() => {
  686. const library = new base.Metadata(null);
  687. base.Metadata._metadata.set(name, library);
  688. return library;
  689. });
  690. }
  691. constructor(data) {
  692. this._types = new Map();
  693. this._attributes = new Map();
  694. if (data) {
  695. const metadata = JSON.parse(data);
  696. for (const entry of metadata) {
  697. this._types.set(entry.name, entry);
  698. if (entry.identifier !== undefined) {
  699. this._types.set(entry.identifier, entry);
  700. }
  701. }
  702. }
  703. }
  704. type(name) {
  705. if (!this._types.has(name)) {
  706. this._types.set(name, { name: name.toString() });
  707. }
  708. return this._types.get(name);
  709. }
  710. attribute(type, name) {
  711. const key = type + ':' + name;
  712. if (!this._attributes.has(key)) {
  713. this._attributes.set(key, null);
  714. const metadata = this.type(type);
  715. if (metadata && Array.isArray(metadata.attributes)) {
  716. for (const attribute of metadata.attributes) {
  717. this._attributes.set(type + ':' + attribute.name, attribute);
  718. }
  719. }
  720. }
  721. return this._attributes.get(key);
  722. }
  723. };
  724. if (typeof window !== 'undefined' && typeof window.Long != 'undefined') {
  725. window.long = { Long: window.Long };
  726. window.Int64 = base.Int64;
  727. window.Uint64 = base.Uint64;
  728. }
  729. if (typeof module !== 'undefined' && typeof module.exports === 'object') {
  730. module.exports.Int64 = base.Int64;
  731. module.exports.Uint64 = base.Uint64;
  732. module.exports.BinaryReader = base.BinaryReader;
  733. module.exports.Metadata = base.Metadata;
  734. }