value-parser.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _metadataParser = require("./metadata-parser");
  7. var _dataType = require("./data-type");
  8. var _iconvLite = _interopRequireDefault(require("iconv-lite"));
  9. var _sprintfJs = require("sprintf-js");
  10. var _guidParser = require("./guid-parser");
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. const NULL = (1 << 16) - 1;
  13. const MAX = (1 << 16) - 1;
  14. const THREE_AND_A_THIRD = 3 + 1 / 3;
  15. const MONEY_DIVISOR = 10000;
  16. const PLP_NULL = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
  17. const UNKNOWN_PLP_LEN = Buffer.from([0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
  18. const DEFAULT_ENCODING = 'utf8';
  19. function readTinyInt(parser, callback) {
  20. parser.readUInt8(callback);
  21. }
  22. function readSmallInt(parser, callback) {
  23. parser.readInt16LE(callback);
  24. }
  25. function readInt(parser, callback) {
  26. parser.readInt32LE(callback);
  27. }
  28. function readBigInt(parser, callback) {
  29. parser.readBigInt64LE(value => {
  30. callback(value.toString());
  31. });
  32. }
  33. function readReal(parser, callback) {
  34. parser.readFloatLE(callback);
  35. }
  36. function readFloat(parser, callback) {
  37. parser.readDoubleLE(callback);
  38. }
  39. function readSmallMoney(parser, callback) {
  40. parser.readInt32LE(value => {
  41. callback(value / MONEY_DIVISOR);
  42. });
  43. }
  44. function readMoney(parser, callback) {
  45. parser.readInt32LE(high => {
  46. parser.readUInt32LE(low => {
  47. callback((low + 0x100000000 * high) / MONEY_DIVISOR);
  48. });
  49. });
  50. }
  51. function readBit(parser, callback) {
  52. parser.readUInt8(value => {
  53. callback(!!value);
  54. });
  55. }
  56. function valueParse(parser, metadata, options, callback) {
  57. const type = metadata.type;
  58. switch (type.name) {
  59. case 'Null':
  60. return callback(null);
  61. case 'TinyInt':
  62. return readTinyInt(parser, callback);
  63. case 'SmallInt':
  64. return readSmallInt(parser, callback);
  65. case 'Int':
  66. return readInt(parser, callback);
  67. case 'BigInt':
  68. return readBigInt(parser, callback);
  69. case 'IntN':
  70. return parser.readUInt8(dataLength => {
  71. switch (dataLength) {
  72. case 0:
  73. return callback(null);
  74. case 1:
  75. return readTinyInt(parser, callback);
  76. case 2:
  77. return readSmallInt(parser, callback);
  78. case 4:
  79. return readInt(parser, callback);
  80. case 8:
  81. return readBigInt(parser, callback);
  82. default:
  83. return parser.emit('error', new Error('Unsupported dataLength ' + dataLength + ' for IntN'));
  84. }
  85. });
  86. case 'Real':
  87. return readReal(parser, callback);
  88. case 'Float':
  89. return readFloat(parser, callback);
  90. case 'FloatN':
  91. return parser.readUInt8(dataLength => {
  92. switch (dataLength) {
  93. case 0:
  94. return callback(null);
  95. case 4:
  96. return readReal(parser, callback);
  97. case 8:
  98. return readFloat(parser, callback);
  99. default:
  100. return parser.emit('error', new Error('Unsupported dataLength ' + dataLength + ' for FloatN'));
  101. }
  102. });
  103. case 'SmallMoney':
  104. return readSmallMoney(parser, callback);
  105. case 'Money':
  106. return readMoney(parser, callback);
  107. case 'MoneyN':
  108. return parser.readUInt8(dataLength => {
  109. switch (dataLength) {
  110. case 0:
  111. return callback(null);
  112. case 4:
  113. return readSmallMoney(parser, callback);
  114. case 8:
  115. return readMoney(parser, callback);
  116. default:
  117. return parser.emit('error', new Error('Unsupported dataLength ' + dataLength + ' for MoneyN'));
  118. }
  119. });
  120. case 'Bit':
  121. return readBit(parser, callback);
  122. case 'BitN':
  123. return parser.readUInt8(dataLength => {
  124. switch (dataLength) {
  125. case 0:
  126. return callback(null);
  127. case 1:
  128. return readBit(parser, callback);
  129. default:
  130. return parser.emit('error', new Error('Unsupported dataLength ' + dataLength + ' for BitN'));
  131. }
  132. });
  133. case 'VarChar':
  134. case 'Char':
  135. const codepage = metadata.collation.codepage;
  136. if (metadata.dataLength === MAX) {
  137. return readMaxChars(parser, codepage, callback);
  138. } else {
  139. return parser.readUInt16LE(dataLength => {
  140. if (dataLength === NULL) {
  141. return callback(null);
  142. }
  143. readChars(parser, dataLength, codepage, callback);
  144. });
  145. }
  146. case 'NVarChar':
  147. case 'NChar':
  148. if (metadata.dataLength === MAX) {
  149. return readMaxNChars(parser, callback);
  150. } else {
  151. return parser.readUInt16LE(dataLength => {
  152. if (dataLength === NULL) {
  153. return callback(null);
  154. }
  155. readNChars(parser, dataLength, callback);
  156. });
  157. }
  158. case 'VarBinary':
  159. case 'Binary':
  160. if (metadata.dataLength === MAX) {
  161. return readMaxBinary(parser, callback);
  162. } else {
  163. return parser.readUInt16LE(dataLength => {
  164. if (dataLength === NULL) {
  165. return callback(null);
  166. }
  167. readBinary(parser, dataLength, callback);
  168. });
  169. }
  170. case 'Text':
  171. return parser.readUInt8(textPointerLength => {
  172. if (textPointerLength === 0) {
  173. return callback(null);
  174. }
  175. parser.readBuffer(textPointerLength, _textPointer => {
  176. parser.readBuffer(8, _timestamp => {
  177. parser.readUInt32LE(dataLength => {
  178. readChars(parser, dataLength, metadata.collation.codepage, callback);
  179. });
  180. });
  181. });
  182. });
  183. case 'NText':
  184. return parser.readUInt8(textPointerLength => {
  185. if (textPointerLength === 0) {
  186. return callback(null);
  187. }
  188. parser.readBuffer(textPointerLength, _textPointer => {
  189. parser.readBuffer(8, _timestamp => {
  190. parser.readUInt32LE(dataLength => {
  191. readNChars(parser, dataLength, callback);
  192. });
  193. });
  194. });
  195. });
  196. case 'Image':
  197. return parser.readUInt8(textPointerLength => {
  198. if (textPointerLength === 0) {
  199. return callback(null);
  200. }
  201. parser.readBuffer(textPointerLength, _textPointer => {
  202. parser.readBuffer(8, _timestamp => {
  203. parser.readUInt32LE(dataLength => {
  204. readBinary(parser, dataLength, callback);
  205. });
  206. });
  207. });
  208. });
  209. case 'Xml':
  210. return readMaxNChars(parser, callback);
  211. case 'SmallDateTime':
  212. return readSmallDateTime(parser, options.useUTC, callback);
  213. case 'DateTime':
  214. return readDateTime(parser, options.useUTC, callback);
  215. case 'DateTimeN':
  216. return parser.readUInt8(dataLength => {
  217. switch (dataLength) {
  218. case 0:
  219. return callback(null);
  220. case 4:
  221. return readSmallDateTime(parser, options.useUTC, callback);
  222. case 8:
  223. return readDateTime(parser, options.useUTC, callback);
  224. default:
  225. return parser.emit('error', new Error('Unsupported dataLength ' + dataLength + ' for DateTimeN'));
  226. }
  227. });
  228. case 'Time':
  229. return parser.readUInt8(dataLength => {
  230. if (dataLength === 0) {
  231. return callback(null);
  232. } else {
  233. return readTime(parser, dataLength, metadata.scale, options.useUTC, callback);
  234. }
  235. });
  236. case 'Date':
  237. return parser.readUInt8(dataLength => {
  238. if (dataLength === 0) {
  239. return callback(null);
  240. } else {
  241. return readDate(parser, options.useUTC, callback);
  242. }
  243. });
  244. case 'DateTime2':
  245. return parser.readUInt8(dataLength => {
  246. if (dataLength === 0) {
  247. return callback(null);
  248. } else {
  249. return readDateTime2(parser, dataLength, metadata.scale, options.useUTC, callback);
  250. }
  251. });
  252. case 'DateTimeOffset':
  253. return parser.readUInt8(dataLength => {
  254. if (dataLength === 0) {
  255. return callback(null);
  256. } else {
  257. return readDateTimeOffset(parser, dataLength, metadata.scale, callback);
  258. }
  259. });
  260. case 'NumericN':
  261. case 'DecimalN':
  262. return parser.readUInt8(dataLength => {
  263. if (dataLength === 0) {
  264. return callback(null);
  265. } else {
  266. return readNumeric(parser, dataLength, metadata.precision, metadata.scale, callback);
  267. }
  268. });
  269. case 'UniqueIdentifier':
  270. return parser.readUInt8(dataLength => {
  271. switch (dataLength) {
  272. case 0:
  273. return callback(null);
  274. case 0x10:
  275. return readUniqueIdentifier(parser, options, callback);
  276. default:
  277. return parser.emit('error', new Error((0, _sprintfJs.sprintf)('Unsupported guid size %d', dataLength - 1)));
  278. }
  279. });
  280. case 'UDT':
  281. return readMaxBinary(parser, callback);
  282. case 'Variant':
  283. return parser.readUInt32LE(dataLength => {
  284. if (dataLength === 0) {
  285. return callback(null);
  286. }
  287. readVariant(parser, options, dataLength, callback);
  288. });
  289. default:
  290. parser.emit('error', new Error((0, _sprintfJs.sprintf)('Unrecognised type %s', type.name)));
  291. }
  292. }
  293. function readUniqueIdentifier(parser, options, callback) {
  294. parser.readBuffer(0x10, data => {
  295. callback(options.lowerCaseGuids ? (0, _guidParser.bufferToLowerCaseGuid)(data) : (0, _guidParser.bufferToUpperCaseGuid)(data));
  296. });
  297. }
  298. function readNumeric(parser, dataLength, _precision, scale, callback) {
  299. parser.readUInt8(sign => {
  300. sign = sign === 1 ? 1 : -1;
  301. let readValue;
  302. if (dataLength === 5) {
  303. readValue = parser.readUInt32LE;
  304. } else if (dataLength === 9) {
  305. readValue = parser.readUNumeric64LE;
  306. } else if (dataLength === 13) {
  307. readValue = parser.readUNumeric96LE;
  308. } else if (dataLength === 17) {
  309. readValue = parser.readUNumeric128LE;
  310. } else {
  311. return parser.emit('error', new Error((0, _sprintfJs.sprintf)('Unsupported numeric dataLength %d', dataLength)));
  312. }
  313. readValue.call(parser, value => {
  314. callback(value * sign / Math.pow(10, scale));
  315. });
  316. });
  317. }
  318. function readVariant(parser, options, dataLength, callback) {
  319. return parser.readUInt8(baseType => {
  320. const type = _dataType.TYPE[baseType];
  321. return parser.readUInt8(propBytes => {
  322. dataLength = dataLength - propBytes - 2;
  323. switch (type.name) {
  324. case 'UniqueIdentifier':
  325. return readUniqueIdentifier(parser, options, callback);
  326. case 'Bit':
  327. return readBit(parser, callback);
  328. case 'TinyInt':
  329. return readTinyInt(parser, callback);
  330. case 'SmallInt':
  331. return readSmallInt(parser, callback);
  332. case 'Int':
  333. return readInt(parser, callback);
  334. case 'BigInt':
  335. return readBigInt(parser, callback);
  336. case 'SmallDateTime':
  337. return readSmallDateTime(parser, options.useUTC, callback);
  338. case 'DateTime':
  339. return readDateTime(parser, options.useUTC, callback);
  340. case 'Real':
  341. return readReal(parser, callback);
  342. case 'Float':
  343. return readFloat(parser, callback);
  344. case 'SmallMoney':
  345. return readSmallMoney(parser, callback);
  346. case 'Money':
  347. return readMoney(parser, callback);
  348. case 'Date':
  349. return readDate(parser, options.useUTC, callback);
  350. case 'Time':
  351. return parser.readUInt8(scale => {
  352. return readTime(parser, dataLength, scale, options.useUTC, callback);
  353. });
  354. case 'DateTime2':
  355. return parser.readUInt8(scale => {
  356. return readDateTime2(parser, dataLength, scale, options.useUTC, callback);
  357. });
  358. case 'DateTimeOffset':
  359. return parser.readUInt8(scale => {
  360. return readDateTimeOffset(parser, dataLength, scale, callback);
  361. });
  362. case 'VarBinary':
  363. case 'Binary':
  364. return parser.readUInt16LE(_maxLength => {
  365. readBinary(parser, dataLength, callback);
  366. });
  367. case 'NumericN':
  368. case 'DecimalN':
  369. return parser.readUInt8(precision => {
  370. parser.readUInt8(scale => {
  371. readNumeric(parser, dataLength, precision, scale, callback);
  372. });
  373. });
  374. case 'VarChar':
  375. case 'Char':
  376. return parser.readUInt16LE(_maxLength => {
  377. (0, _metadataParser.readCollation)(parser, collation => {
  378. readChars(parser, dataLength, collation.codepage, callback);
  379. });
  380. });
  381. case 'NVarChar':
  382. case 'NChar':
  383. return parser.readUInt16LE(_maxLength => {
  384. (0, _metadataParser.readCollation)(parser, _collation => {
  385. readNChars(parser, dataLength, callback);
  386. });
  387. });
  388. default:
  389. throw new Error('Invalid type!');
  390. }
  391. });
  392. });
  393. }
  394. function readBinary(parser, dataLength, callback) {
  395. return parser.readBuffer(dataLength, callback);
  396. }
  397. function readChars(parser, dataLength, codepage, callback) {
  398. if (codepage == null) {
  399. codepage = DEFAULT_ENCODING;
  400. }
  401. return parser.readBuffer(dataLength, data => {
  402. callback(_iconvLite.default.decode(data, codepage));
  403. });
  404. }
  405. function readNChars(parser, dataLength, callback) {
  406. parser.readBuffer(dataLength, data => {
  407. callback(data.toString('ucs2'));
  408. });
  409. }
  410. function readMaxBinary(parser, callback) {
  411. return readMax(parser, callback);
  412. }
  413. function readMaxChars(parser, codepage, callback) {
  414. if (codepage == null) {
  415. codepage = DEFAULT_ENCODING;
  416. }
  417. readMax(parser, data => {
  418. if (data) {
  419. callback(_iconvLite.default.decode(data, codepage));
  420. } else {
  421. callback(null);
  422. }
  423. });
  424. }
  425. function readMaxNChars(parser, callback) {
  426. readMax(parser, data => {
  427. if (data) {
  428. callback(data.toString('ucs2'));
  429. } else {
  430. callback(null);
  431. }
  432. });
  433. }
  434. function readMax(parser, callback) {
  435. parser.readBuffer(8, type => {
  436. if (type.equals(PLP_NULL)) {
  437. return callback(null);
  438. } else if (type.equals(UNKNOWN_PLP_LEN)) {
  439. return readMaxUnknownLength(parser, callback);
  440. } else {
  441. const low = type.readUInt32LE(0);
  442. const high = type.readUInt32LE(4);
  443. if (high >= 2 << 53 - 32) {
  444. console.warn('Read UInt64LE > 53 bits : high=' + high + ', low=' + low);
  445. }
  446. const expectedLength = low + 0x100000000 * high;
  447. return readMaxKnownLength(parser, expectedLength, callback);
  448. }
  449. });
  450. }
  451. function readMaxKnownLength(parser, totalLength, callback) {
  452. const data = Buffer.alloc(totalLength, 0);
  453. let offset = 0;
  454. function next(done) {
  455. parser.readUInt32LE(chunkLength => {
  456. if (!chunkLength) {
  457. return done();
  458. }
  459. parser.readBuffer(chunkLength, chunk => {
  460. chunk.copy(data, offset);
  461. offset += chunkLength;
  462. next(done);
  463. });
  464. });
  465. }
  466. next(() => {
  467. if (offset !== totalLength) {
  468. parser.emit('error', new Error('Partially Length-prefixed Bytes unmatched lengths : expected ' + totalLength + ', but got ' + offset + ' bytes'));
  469. }
  470. callback(data);
  471. });
  472. }
  473. function readMaxUnknownLength(parser, callback) {
  474. const chunks = [];
  475. let length = 0;
  476. function next(done) {
  477. parser.readUInt32LE(chunkLength => {
  478. if (!chunkLength) {
  479. return done();
  480. }
  481. parser.readBuffer(chunkLength, chunk => {
  482. chunks.push(chunk);
  483. length += chunkLength;
  484. next(done);
  485. });
  486. });
  487. }
  488. next(() => {
  489. callback(Buffer.concat(chunks, length));
  490. });
  491. }
  492. function readSmallDateTime(parser, useUTC, callback) {
  493. parser.readUInt16LE(days => {
  494. parser.readUInt16LE(minutes => {
  495. let value;
  496. if (useUTC) {
  497. value = new Date(Date.UTC(1900, 0, 1 + days, 0, minutes));
  498. } else {
  499. value = new Date(1900, 0, 1 + days, 0, minutes);
  500. }
  501. callback(value);
  502. });
  503. });
  504. }
  505. function readDateTime(parser, useUTC, callback) {
  506. parser.readInt32LE(days => {
  507. parser.readUInt32LE(threeHundredthsOfSecond => {
  508. const milliseconds = Math.round(threeHundredthsOfSecond * THREE_AND_A_THIRD);
  509. let value;
  510. if (useUTC) {
  511. value = new Date(Date.UTC(1900, 0, 1 + days, 0, 0, 0, milliseconds));
  512. } else {
  513. value = new Date(1900, 0, 1 + days, 0, 0, 0, milliseconds);
  514. }
  515. callback(value);
  516. });
  517. });
  518. }
  519. function readTime(parser, dataLength, scale, useUTC, callback) {
  520. let readValue;
  521. switch (dataLength) {
  522. case 3:
  523. readValue = parser.readUInt24LE;
  524. break;
  525. case 4:
  526. readValue = parser.readUInt32LE;
  527. break;
  528. case 5:
  529. readValue = parser.readUInt40LE;
  530. }
  531. readValue.call(parser, value => {
  532. if (scale < 7) {
  533. for (let i = scale; i < 7; i++) {
  534. value *= 10;
  535. }
  536. }
  537. let date;
  538. if (useUTC) {
  539. date = new Date(Date.UTC(1970, 0, 1, 0, 0, 0, value / 10000));
  540. } else {
  541. date = new Date(1970, 0, 1, 0, 0, 0, value / 10000);
  542. }
  543. Object.defineProperty(date, 'nanosecondsDelta', {
  544. enumerable: false,
  545. value: value % 10000 / Math.pow(10, 7)
  546. });
  547. callback(date);
  548. });
  549. }
  550. function readDate(parser, useUTC, callback) {
  551. parser.readUInt24LE(days => {
  552. if (useUTC) {
  553. callback(new Date(Date.UTC(2000, 0, days - 730118)));
  554. } else {
  555. callback(new Date(2000, 0, days - 730118));
  556. }
  557. });
  558. }
  559. function readDateTime2(parser, dataLength, scale, useUTC, callback) {
  560. readTime(parser, dataLength - 3, scale, useUTC, time => {
  561. // TODO: 'input' is 'time', but TypeScript cannot find "time.nanosecondsDelta";
  562. parser.readUInt24LE(days => {
  563. let date;
  564. if (useUTC) {
  565. date = new Date(Date.UTC(2000, 0, days - 730118, 0, 0, 0, +time));
  566. } else {
  567. date = new Date(2000, 0, days - 730118, time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds());
  568. }
  569. Object.defineProperty(date, 'nanosecondsDelta', {
  570. enumerable: false,
  571. value: time.nanosecondsDelta
  572. });
  573. callback(date);
  574. });
  575. });
  576. }
  577. function readDateTimeOffset(parser, dataLength, scale, callback) {
  578. readTime(parser, dataLength - 5, scale, true, time => {
  579. parser.readUInt24LE(days => {
  580. // offset
  581. parser.readInt16LE(() => {
  582. const date = new Date(Date.UTC(2000, 0, days - 730118, 0, 0, 0, +time));
  583. Object.defineProperty(date, 'nanosecondsDelta', {
  584. enumerable: false,
  585. value: time.nanosecondsDelta
  586. });
  587. callback(date);
  588. });
  589. });
  590. });
  591. }
  592. var _default = valueParse;
  593. exports.default = _default;
  594. module.exports = valueParse;