seq_stream.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.SeqStream = void 0;
  4. const byte_stream_1 = require("./byte_stream");
  5. const pow2_24 = 16777216;
  6. class SeqStream {
  7. constructor(parameters = {}) {
  8. this._stream = new byte_stream_1.ByteStream();
  9. this._length = 0;
  10. this._start = 0;
  11. this.backward = false;
  12. this.appendBlock = 0;
  13. this.prevLength = 0;
  14. this.prevStart = 0;
  15. if ("view" in parameters) {
  16. this.stream = new byte_stream_1.ByteStream({ view: parameters.view });
  17. }
  18. else if ("buffer" in parameters) {
  19. this.stream = new byte_stream_1.ByteStream({ buffer: parameters.buffer });
  20. }
  21. else if ("string" in parameters) {
  22. this.stream = new byte_stream_1.ByteStream({ string: parameters.string });
  23. }
  24. else if ("hexstring" in parameters) {
  25. this.stream = new byte_stream_1.ByteStream({ hexstring: parameters.hexstring });
  26. }
  27. else if ("stream" in parameters) {
  28. this.stream = parameters.stream.slice();
  29. }
  30. else {
  31. this.stream = new byte_stream_1.ByteStream();
  32. }
  33. if ("backward" in parameters && parameters.backward) {
  34. this.backward = parameters.backward;
  35. this._start = this.stream.length;
  36. }
  37. if ("length" in parameters && parameters.length > 0) {
  38. this._length = parameters.length;
  39. }
  40. if ("start" in parameters && parameters.start && parameters.start > 0) {
  41. this._start = parameters.start;
  42. }
  43. if ("appendBlock" in parameters && parameters.appendBlock && parameters.appendBlock > 0) {
  44. this.appendBlock = parameters.appendBlock;
  45. }
  46. }
  47. set stream(value) {
  48. this._stream = value;
  49. this.prevLength = this._length;
  50. this._length = value.length;
  51. this.prevStart = this._start;
  52. this._start = 0;
  53. }
  54. get stream() {
  55. return this._stream;
  56. }
  57. set length(value) {
  58. this.prevLength = this._length;
  59. this._length = value;
  60. }
  61. get length() {
  62. if (this.appendBlock) {
  63. return this.start;
  64. }
  65. return this._length;
  66. }
  67. set start(value) {
  68. if (value > this.stream.length)
  69. return;
  70. this.prevStart = this._start;
  71. this.prevLength = this._length;
  72. this._length -= (this.backward) ? (this._start - value) : (value - this._start);
  73. this._start = value;
  74. }
  75. get start() {
  76. return this._start;
  77. }
  78. get buffer() {
  79. return this._stream.buffer.slice(0, this._length);
  80. }
  81. resetPosition() {
  82. this._start = this.prevStart;
  83. this._length = this.prevLength;
  84. }
  85. findPattern(pattern, gap = null) {
  86. if ((gap == null) || (gap > this.length)) {
  87. gap = this.length;
  88. }
  89. const result = this.stream.findPattern(pattern, this.start, this.length, this.backward);
  90. if (result == (-1))
  91. return result;
  92. if (this.backward) {
  93. if (result < (this.start - pattern.length - gap)) {
  94. return (-1);
  95. }
  96. }
  97. else {
  98. if (result > (this.start + pattern.length + gap)) {
  99. return (-1);
  100. }
  101. }
  102. this.start = result;
  103. return result;
  104. }
  105. findFirstIn(patterns, gap = null) {
  106. if ((gap == null) || (gap > this.length)) {
  107. gap = this.length;
  108. }
  109. const result = this.stream.findFirstIn(patterns, this.start, this.length, this.backward);
  110. if (result.id == (-1))
  111. return result;
  112. if (this.backward) {
  113. if (result.position < (this.start - patterns[result.id].length - gap)) {
  114. return {
  115. id: (-1),
  116. position: (this.backward) ? 0 : (this.start + this.length)
  117. };
  118. }
  119. }
  120. else {
  121. if (result.position > (this.start + patterns[result.id].length + gap)) {
  122. return {
  123. id: (-1),
  124. position: (this.backward) ? 0 : (this.start + this.length)
  125. };
  126. }
  127. }
  128. this.start = result.position;
  129. return result;
  130. }
  131. findAllIn(patterns) {
  132. const start = (this.backward) ? (this.start - this.length) : this.start;
  133. return this.stream.findAllIn(patterns, start, this.length);
  134. }
  135. findFirstNotIn(patterns, gap = null) {
  136. if ((gap == null) || (gap > this._length)) {
  137. gap = this._length;
  138. }
  139. const result = this._stream.findFirstNotIn(patterns, this._start, this._length, this.backward);
  140. if ((result.left.id == (-1)) && (result.right.id == (-1))) {
  141. return result;
  142. }
  143. if (this.backward) {
  144. if (result.right.id != (-1)) {
  145. if (result.right.position < (this._start - patterns[result.right.id].length - gap)) {
  146. return {
  147. left: {
  148. id: (-1),
  149. position: this._start
  150. },
  151. right: {
  152. id: (-1),
  153. position: 0
  154. },
  155. value: new byte_stream_1.ByteStream()
  156. };
  157. }
  158. }
  159. }
  160. else {
  161. if (result.left.id != (-1)) {
  162. if (result.left.position > (this._start + patterns[result.left.id].length + gap)) {
  163. return {
  164. left: {
  165. id: (-1),
  166. position: this._start
  167. },
  168. right: {
  169. id: (-1),
  170. position: 0
  171. },
  172. value: new byte_stream_1.ByteStream()
  173. };
  174. }
  175. }
  176. }
  177. if (this.backward) {
  178. if (result.left.id == (-1)) {
  179. this.start = 0;
  180. }
  181. else {
  182. this.start = result.left.position;
  183. }
  184. }
  185. else {
  186. if (result.right.id == (-1)) {
  187. this.start = (this._start + this._length);
  188. }
  189. else {
  190. this.start = result.right.position;
  191. }
  192. }
  193. return result;
  194. }
  195. findAllNotIn(patterns) {
  196. const start = (this.backward) ? (this._start - this._length) : this._start;
  197. return this._stream.findAllNotIn(patterns, start, this._length);
  198. }
  199. findFirstSequence(patterns, length = null, gap = null) {
  200. if ((length == null) || (length > this._length)) {
  201. length = this._length;
  202. }
  203. if ((gap == null) || (gap > length)) {
  204. gap = length;
  205. }
  206. const result = this._stream.findFirstSequence(patterns, this._start, length, this.backward);
  207. if (result.value.length == 0) {
  208. return result;
  209. }
  210. if (this.backward) {
  211. if (result.position < (this._start - result.value.length - gap)) {
  212. return {
  213. position: (-1),
  214. value: new byte_stream_1.ByteStream()
  215. };
  216. }
  217. }
  218. else {
  219. if (result.position > (this._start + result.value.length + gap)) {
  220. return {
  221. position: (-1),
  222. value: new byte_stream_1.ByteStream()
  223. };
  224. }
  225. }
  226. this.start = result.position;
  227. return result;
  228. }
  229. findAllSequences(patterns) {
  230. const start = (this.backward) ? (this.start - this.length) : this.start;
  231. return this.stream.findAllSequences(patterns, start, this.length);
  232. }
  233. findPairedPatterns(leftPattern, rightPattern, gap = null) {
  234. if ((gap == null) || (gap > this.length)) {
  235. gap = this.length;
  236. }
  237. const start = (this.backward) ? (this.start - this.length) : this.start;
  238. const result = this.stream.findPairedPatterns(leftPattern, rightPattern, start, this.length);
  239. if (result.length) {
  240. if (this.backward) {
  241. if (result[0].right < (this.start - rightPattern.length - gap)) {
  242. return [];
  243. }
  244. }
  245. else {
  246. if (result[0].left > (this.start + leftPattern.length + gap)) {
  247. return [];
  248. }
  249. }
  250. }
  251. return result;
  252. }
  253. findPairedArrays(leftPatterns, rightPatterns, gap = null) {
  254. if ((gap == null) || (gap > this.length)) {
  255. gap = this.length;
  256. }
  257. const start = (this.backward) ? (this.start - this.length) : this.start;
  258. const result = this.stream.findPairedArrays(leftPatterns, rightPatterns, start, this.length);
  259. if (result.length) {
  260. if (this.backward) {
  261. if (result[0].right.position < (this.start - rightPatterns[result[0].right.id].length - gap)) {
  262. return [];
  263. }
  264. }
  265. else {
  266. if (result[0].left.position > (this.start + leftPatterns[result[0].left.id].length + gap)) {
  267. return [];
  268. }
  269. }
  270. }
  271. return result;
  272. }
  273. replacePattern(searchPattern, replacePattern) {
  274. const start = (this.backward) ? (this.start - this.length) : this.start;
  275. return this.stream.replacePattern(searchPattern, replacePattern, start, this.length);
  276. }
  277. skipPatterns(patterns) {
  278. const result = this.stream.skipPatterns(patterns, this.start, this.length, this.backward);
  279. this.start = result;
  280. return result;
  281. }
  282. skipNotPatterns(patterns) {
  283. const result = this.stream.skipNotPatterns(patterns, this.start, this.length, this.backward);
  284. if (result == (-1))
  285. return (-1);
  286. this.start = result;
  287. return result;
  288. }
  289. append(stream) {
  290. this.beforeAppend(stream.length);
  291. this._stream.view.set(stream.view, this._start);
  292. this._length += (stream.length * 2);
  293. this.start = (this._start + stream.length);
  294. this.prevLength -= (stream.length * 2);
  295. }
  296. appendView(view) {
  297. this.beforeAppend(view.length);
  298. this._stream.view.set(view, this._start);
  299. this._length += (view.length * 2);
  300. this.start = (this._start + view.length);
  301. this.prevLength -= (view.length * 2);
  302. }
  303. appendChar(char) {
  304. this.beforeAppend(1);
  305. this._stream.view[this._start] = char;
  306. this._length += 2;
  307. this.start = (this._start + 1);
  308. this.prevLength -= 2;
  309. }
  310. appendUint16(number) {
  311. this.beforeAppend(2);
  312. const value = new Uint16Array([number]);
  313. const view = new Uint8Array(value.buffer);
  314. this.stream.view[this._start] = view[1];
  315. this._stream.view[this._start + 1] = view[0];
  316. this._length += 4;
  317. this.start = this._start + 2;
  318. this.prevLength -= 4;
  319. }
  320. appendUint24(number) {
  321. this.beforeAppend(3);
  322. const value = new Uint32Array([number]);
  323. const view = new Uint8Array(value.buffer);
  324. this._stream.view[this._start] = view[2];
  325. this._stream.view[this._start + 1] = view[1];
  326. this._stream.view[this._start + 2] = view[0];
  327. this._length += 6;
  328. this.start = (this._start + 3);
  329. this.prevLength -= 6;
  330. }
  331. appendUint32(number) {
  332. this.beforeAppend(4);
  333. const value = new Uint32Array([number]);
  334. const view = new Uint8Array(value.buffer);
  335. this._stream.view[this._start] = view[3];
  336. this._stream.view[this._start + 1] = view[2];
  337. this._stream.view[this._start + 2] = view[1];
  338. this._stream.view[this._start + 3] = view[0];
  339. this._length += 8;
  340. this.start = (this._start + 4);
  341. this.prevLength -= 8;
  342. }
  343. appendInt16(number) {
  344. this.beforeAppend(2);
  345. const value = new Int16Array([number]);
  346. const view = new Uint8Array(value.buffer);
  347. this._stream.view[this._start] = view[1];
  348. this._stream.view[this._start + 1] = view[0];
  349. this._length += 4;
  350. this.start = (this._start + 2);
  351. this.prevLength -= 4;
  352. }
  353. appendInt32(number) {
  354. this.beforeAppend(4);
  355. const value = new Int32Array([number]);
  356. const view = new Uint8Array(value.buffer);
  357. this._stream.view[this._start] = view[3];
  358. this._stream.view[this._start + 1] = view[2];
  359. this._stream.view[this._start + 2] = view[1];
  360. this._stream.view[this._start + 3] = view[0];
  361. this._length += 8;
  362. this.start = (this._start + 4);
  363. this.prevLength -= 8;
  364. }
  365. getBlock(size, changeLength = true) {
  366. if (this._length <= 0) {
  367. return new Uint8Array(0);
  368. }
  369. if (this._length < size) {
  370. size = this._length;
  371. }
  372. let result;
  373. if (this.backward) {
  374. const view = this._stream.view.subarray(this._length - size, this._length);
  375. result = new Uint8Array(size);
  376. for (let i = 0; i < size; i++) {
  377. result[size - 1 - i] = view[i];
  378. }
  379. }
  380. else {
  381. result = this._stream.view.subarray(this._start, this._start + size);
  382. }
  383. if (changeLength) {
  384. this.start += ((this.backward) ? ((-1) * size) : size);
  385. }
  386. return result;
  387. }
  388. getUint16(changeLength = true) {
  389. const block = this.getBlock(2, changeLength);
  390. if (block.length < 2)
  391. return 0;
  392. return (block[0] << 8) | block[1];
  393. }
  394. getInt16(changeLength = true) {
  395. const num = this.getUint16(changeLength);
  396. const negative = 0x8000;
  397. if (num & negative) {
  398. return -(negative - (num ^ negative));
  399. }
  400. return num;
  401. }
  402. getUint24(changeLength = true) {
  403. const block = this.getBlock(4, changeLength);
  404. if (block.length < 3)
  405. return 0;
  406. return (block[0] << 16) |
  407. (block[1] << 8) |
  408. block[2];
  409. }
  410. getUint32(changeLength = true) {
  411. const block = this.getBlock(4, changeLength);
  412. if (block.length < 4)
  413. return 0;
  414. return (block[0] * pow2_24) +
  415. (block[1] << 16) +
  416. (block[2] << 8) +
  417. block[3];
  418. }
  419. getInt32(changeLength = true) {
  420. const num = this.getUint32(changeLength);
  421. const negative = 0x80000000;
  422. if (num & negative) {
  423. return -(negative - (num ^ negative));
  424. }
  425. return num;
  426. }
  427. beforeAppend(size) {
  428. if ((this._start + size) > this._stream.length) {
  429. if (size > this.appendBlock) {
  430. this.appendBlock = size + SeqStream.APPEND_BLOCK;
  431. }
  432. this._stream.realloc(this._stream.length + this.appendBlock);
  433. }
  434. }
  435. }
  436. exports.SeqStream = SeqStream;
  437. SeqStream.APPEND_BLOCK = 1000;