@futpib/parser 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/build/allSettledStream.js +32 -14
  2. package/build/allSettledStream.test.js +32 -0
  3. package/build/androidPackage.d.ts +39 -0
  4. package/build/androidPackageParser.d.ts +17 -0
  5. package/build/androidPackageParser.js +183 -0
  6. package/build/{apkParser.test.js → androidPackageParser.test.js} +7 -7
  7. package/build/androidPackageUnparser.d.ts +4 -0
  8. package/build/androidPackageUnparser.js +90 -0
  9. package/build/androidPackageUnparser.test.js +26 -0
  10. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  11. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  12. package/build/arbitraryFileSystemEntry.js +1 -1
  13. package/build/arbitraryZip.d.ts +1 -1
  14. package/build/arbitraryZip.js +13 -19
  15. package/build/arbitraryZipPermissions.d.ts +1 -8
  16. package/build/arbitraryZipPermissions.js +1 -16
  17. package/build/arbitraryZipStream.d.ts +1 -1
  18. package/build/arbitraryZipStream.js +3 -3
  19. package/build/arrayParser.d.ts +1 -1
  20. package/build/arrayParser.js +2 -2
  21. package/build/arrayParser.test.js +4 -4
  22. package/build/arrayUnparser.d.ts +2 -0
  23. package/build/arrayUnparser.js +8 -0
  24. package/build/backsmali.d.ts +1 -0
  25. package/build/backsmali.js +22 -0
  26. package/build/bsonParser.js +6 -2
  27. package/build/bsonParser.test.js +2 -2
  28. package/build/{parserInvariant.d.ts → customInvariant.d.ts} +1 -1
  29. package/build/{parserInvariant.js → customInvariant.js} +1 -1
  30. package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
  31. package/build/dalvikBytecodeParser/formatParsers.js +169 -0
  32. package/build/dalvikBytecodeParser.d.ts +107 -0
  33. package/build/dalvikBytecodeParser.js +836 -0
  34. package/build/dalvikExecutable.d.ts +158 -0
  35. package/build/dalvikExecutable.js +20 -0
  36. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  37. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  38. package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
  39. package/build/dalvikExecutableParser/typeParsers.js +34 -0
  40. package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
  41. package/build/dalvikExecutableParser/typedNumbers.js +19 -0
  42. package/build/dalvikExecutableParser.d.ts +5 -0
  43. package/build/dalvikExecutableParser.js +1439 -0
  44. package/build/dalvikExecutableParser.test.js +70 -0
  45. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
  46. package/build/debugLogInputParser.d.ts +4 -0
  47. package/build/debugLogInputParser.js +16 -0
  48. package/build/debugLogParser.d.ts +1 -1
  49. package/build/debugLogParser.js +15 -4
  50. package/build/disjunctionParser.d.ts +2 -1
  51. package/build/disjunctionParser.js +4 -2
  52. package/build/elementParser.d.ts +2 -2
  53. package/build/elementParser.js +1 -1
  54. package/build/elementTerminatedArrayParser.d.ts +3 -0
  55. package/build/elementTerminatedArrayParser.js +18 -0
  56. package/build/elementTerminatedArrayParser.test.js +52 -0
  57. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  58. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  59. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  60. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  61. package/build/elementTerminatedSequenceParser.js +27 -0
  62. package/build/elementTerminatedSequenceParser.test.js +34 -0
  63. package/build/endOfInputParser.d.ts +2 -2
  64. package/build/exactElementParser.d.ts +1 -1
  65. package/build/exactElementParser.js +10 -5
  66. package/build/exactSequenceParser.d.ts +2 -1
  67. package/build/exactSequenceParser.js +12 -2
  68. package/build/fetchCid.d.ts +1 -0
  69. package/build/fetchCid.js +107 -0
  70. package/build/fixedLengthSequenceParser.d.ts +1 -0
  71. package/build/fixedLengthSequenceParser.js +18 -1
  72. package/build/fixedLengthSequenceParser.test.js +41 -0
  73. package/build/hasExecutable.d.ts +1 -0
  74. package/build/hasExecutable.js +8 -0
  75. package/build/highResolutionTimer.d.ts +16 -0
  76. package/build/highResolutionTimer.js +42 -0
  77. package/build/index.d.ts +5 -2
  78. package/build/index.js +3 -0
  79. package/build/inputReader.d.ts +14 -3
  80. package/build/inputReader.js +43 -6
  81. package/build/inputReader.test.js +172 -7
  82. package/build/inputReaderState.d.ts +10 -0
  83. package/build/inputReaderState.js +16 -0
  84. package/build/inspect.d.ts +1 -0
  85. package/build/inspect.js +7 -0
  86. package/build/javaKeyStoreParser.d.ts +2 -0
  87. package/build/javaKeyStoreParser.js +67 -0
  88. package/build/javaKeyStoreParser.test.d.ts +1 -0
  89. package/build/javaKeyStoreParser.test.js +16 -0
  90. package/build/jsonParser.d.ts +2 -0
  91. package/build/jsonParser.js +13 -15
  92. package/build/jsonParser.test.js +2 -2
  93. package/build/leb128Parser.d.ts +7 -0
  94. package/build/leb128Parser.js +82 -0
  95. package/build/leb128Parser.test.d.ts +1 -0
  96. package/build/leb128Parser.test.js +107 -0
  97. package/build/listParser.d.ts +1 -1
  98. package/build/listParser.js +5 -5
  99. package/build/lookaheadParser.d.ts +2 -0
  100. package/build/lookaheadParser.js +14 -0
  101. package/build/{negativeLookahead.d.ts → negativeLookaheadParser.d.ts} +1 -1
  102. package/build/negativeLookaheadParser.js +24 -0
  103. package/build/negativeLookaheadParser.test.d.ts +1 -0
  104. package/build/negativeLookaheadParser.test.js +30 -0
  105. package/build/nonEmptyArrayParser.d.ts +2 -0
  106. package/build/nonEmptyArrayParser.js +32 -0
  107. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  108. package/build/nonEmptyArrayParser.test.js +16 -0
  109. package/build/optionalParser.d.ts +1 -1
  110. package/build/optionalParser.js +2 -2
  111. package/build/parser.d.ts +13 -4
  112. package/build/parser.js +67 -32
  113. package/build/parser.test.js +94 -27
  114. package/build/parserAccessorParser.d.ts +1 -1
  115. package/build/parserAccessorParser.js +9 -1
  116. package/build/parserConsumedSequenceParser.d.ts +2 -0
  117. package/build/parserConsumedSequenceParser.js +22 -0
  118. package/build/parserContext.d.ts +20 -6
  119. package/build/parserContext.js +70 -40
  120. package/build/parserContext.test.js +34 -7
  121. package/build/parserCreatorCompose.d.ts +4 -3
  122. package/build/parserCreatorCompose.js +9 -3
  123. package/build/parserError.d.ts +6 -0
  124. package/build/parserError.js +6 -6
  125. package/build/parserImplementationInvariant.d.ts +1 -1
  126. package/build/parserImplementationInvariant.js +2 -2
  127. package/build/parserInputCompanion.d.ts +35 -0
  128. package/build/parserInputCompanion.js +68 -0
  129. package/build/promiseCompose.d.ts +1 -1
  130. package/build/promiseCompose.js +12 -1
  131. package/build/promiseSettled.d.ts +1 -0
  132. package/build/promiseSettled.js +4 -0
  133. package/build/quantifierParser.d.ts +2 -0
  134. package/build/quantifierParser.js +17 -0
  135. package/build/separatedArrayParser.d.ts +2 -0
  136. package/build/separatedArrayParser.js +39 -0
  137. package/build/separatedArrayParser.test.d.ts +1 -0
  138. package/build/separatedArrayParser.test.js +21 -0
  139. package/build/sequenceBuffer.d.ts +13 -3
  140. package/build/sequenceBuffer.js +60 -8
  141. package/build/sequenceBuffer.test.js +59 -2
  142. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  143. package/build/sequenceTerminatedSequenceParser.js +32 -0
  144. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  145. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  146. package/build/sequenceUnparser.d.ts +2 -0
  147. package/build/sequenceUnparser.js +6 -0
  148. package/build/skipParser.d.ts +1 -1
  149. package/build/skipParser.js +4 -2
  150. package/build/skipToParser.d.ts +2 -0
  151. package/build/skipToParser.js +11 -0
  152. package/build/sliceBoundedParser.d.ts +2 -2
  153. package/build/sliceBoundedParser.js +8 -3
  154. package/build/sliceBoundedParser.test.js +37 -3
  155. package/build/smali.d.ts +1 -0
  156. package/build/smali.js +17 -0
  157. package/build/smaliParser.d.ts +12 -0
  158. package/build/smaliParser.js +656 -0
  159. package/build/smaliParser.test.d.ts +1 -0
  160. package/build/smaliParser.test.js +115 -0
  161. package/build/terminatedArrayParser.d.ts +4 -2
  162. package/build/terminatedArrayParser.js +82 -5
  163. package/build/terminatedArrayParser.test.d.ts +1 -0
  164. package/build/terminatedArrayParser.test.js +131 -0
  165. package/build/toAsyncIterable.d.ts +1 -0
  166. package/build/toAsyncIterable.js +7 -0
  167. package/build/toAsyncIterator.d.ts +1 -0
  168. package/build/toAsyncIterator.js +33 -0
  169. package/build/tupleParser.d.ts +4 -0
  170. package/build/tupleParser.js +1 -5
  171. package/build/uint8Array.d.ts +1 -0
  172. package/build/uint8Array.js +7 -0
  173. package/build/unionParser.d.ts +2 -1
  174. package/build/unionParser.js +27 -12
  175. package/build/unionParser.test.d.ts +1 -0
  176. package/build/unionParser.test.js +60 -0
  177. package/build/unparser.d.ts +8 -0
  178. package/build/unparser.js +104 -0
  179. package/build/unparser.test.d.ts +1 -0
  180. package/build/unparser.test.js +150 -0
  181. package/build/unparserContext.d.ts +31 -0
  182. package/build/unparserContext.js +74 -0
  183. package/build/unparserError.d.ts +9 -0
  184. package/build/unparserError.js +9 -0
  185. package/build/unparserImplementationInvariant.d.ts +2 -0
  186. package/build/unparserImplementationInvariant.js +5 -0
  187. package/build/unparserOutputCompanion.d.ts +15 -0
  188. package/build/unparserOutputCompanion.js +13 -0
  189. package/build/zip.d.ts +9 -17
  190. package/build/zipParser.d.ts +20 -12
  191. package/build/zipParser.js +83 -71
  192. package/build/zipParser.test.js +2 -7
  193. package/build/zipUnparser.d.ts +8 -0
  194. package/build/zipUnparser.js +200 -0
  195. package/build/zipUnparser.test.d.ts +1 -0
  196. package/build/zipUnparser.test.js +80 -0
  197. package/package.json +26 -8
  198. package/src/allSettledStream.test.ts +40 -0
  199. package/src/allSettledStream.ts +47 -15
  200. package/src/androidPackage.ts +48 -0
  201. package/src/{apkParser.test.ts → androidPackageParser.test.ts} +7 -8
  202. package/src/androidPackageParser.test.ts.md +271 -0
  203. package/src/androidPackageParser.test.ts.snap +0 -0
  204. package/src/androidPackageParser.ts +440 -0
  205. package/src/androidPackageUnparser.test.ts +36 -0
  206. package/src/androidPackageUnparser.ts +120 -0
  207. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  208. package/src/arbitraryFileSystemEntry.ts +2 -4
  209. package/src/arbitraryZip.ts +20 -27
  210. package/src/arbitraryZipPermissions.ts +0 -25
  211. package/src/arbitraryZipStream.ts +4 -4
  212. package/src/arrayParser.test.ts +4 -4
  213. package/src/arrayParser.ts +3 -2
  214. package/src/arrayUnparser.ts +13 -0
  215. package/src/backsmali.ts +30 -0
  216. package/src/bsonParser.test.ts +2 -2
  217. package/src/bsonParser.ts +16 -5
  218. package/src/{parserInvariant.ts → customInvariant.ts} +2 -2
  219. package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
  220. package/src/dalvikBytecodeParser.ts +2074 -0
  221. package/src/dalvikExecutable.ts +220 -0
  222. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  223. package/src/dalvikExecutableParser/typeParsers.ts +65 -0
  224. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  225. package/src/dalvikExecutableParser.test.ts +89 -0
  226. package/src/dalvikExecutableParser.test.ts.md +634 -0
  227. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  228. package/src/dalvikExecutableParser.ts +2768 -0
  229. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
  230. package/src/debugLogInputParser.ts +28 -0
  231. package/src/debugLogParser.ts +20 -4
  232. package/src/disjunctionParser.ts +10 -5
  233. package/src/elementParser.ts +3 -3
  234. package/src/elementTerminatedArrayParser.test.ts +99 -0
  235. package/src/elementTerminatedArrayParser.ts +31 -0
  236. package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
  237. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  238. package/src/elementTerminatedSequenceParser.test.ts +54 -0
  239. package/src/elementTerminatedSequenceParser.ts +43 -0
  240. package/src/endOfInputParser.ts +4 -4
  241. package/src/exactElementParser.ts +18 -12
  242. package/src/exactSequenceParser.ts +24 -3
  243. package/src/fetchCid.ts +125 -0
  244. package/src/fixedLengthSequenceParser.test.ts +77 -0
  245. package/src/fixedLengthSequenceParser.ts +28 -1
  246. package/src/hasExecutable.ts +11 -0
  247. package/src/highResolutionTimer.ts +49 -0
  248. package/src/index.ts +15 -2
  249. package/src/inputReader.test.ts +216 -7
  250. package/src/inputReader.ts +80 -5
  251. package/src/inputReaderState.ts +33 -0
  252. package/src/inspect.ts +9 -0
  253. package/src/javaKeyStore.ts +0 -0
  254. package/src/javaKeyStoreParser.test.ts +22 -0
  255. package/src/javaKeyStoreParser.test.ts.md +103 -0
  256. package/src/javaKeyStoreParser.test.ts.snap +0 -0
  257. package/src/javaKeyStoreParser.ts +136 -0
  258. package/src/jsonParser.test.ts +2 -2
  259. package/src/jsonParser.ts +23 -34
  260. package/src/leb128Parser.test.ts +171 -0
  261. package/src/leb128Parser.ts +125 -0
  262. package/src/listParser.ts +6 -6
  263. package/src/lookaheadParser.ts +19 -0
  264. package/src/negativeLookaheadParser.test.ts +53 -0
  265. package/src/negativeLookaheadParser.ts +36 -0
  266. package/src/nonEmptyArrayParser.test.ts +20 -0
  267. package/src/nonEmptyArrayParser.ts +44 -0
  268. package/src/optionalParser.ts +4 -3
  269. package/src/parser.test.ts +148 -27
  270. package/src/parser.test.ts.md +21 -21
  271. package/src/parser.test.ts.snap +0 -0
  272. package/src/parser.ts +153 -49
  273. package/src/parserAccessorParser.ts +12 -2
  274. package/src/parserConsumedSequenceParser.ts +29 -0
  275. package/src/parserContext.test.ts +38 -7
  276. package/src/parserContext.ts +127 -51
  277. package/src/parserCreatorCompose.ts +25 -7
  278. package/src/parserError.ts +9 -6
  279. package/src/parserImplementationInvariant.ts +2 -2
  280. package/src/parserInputCompanion.ts +102 -0
  281. package/src/promiseCompose.ts +17 -3
  282. package/src/promiseSettled.ts +6 -0
  283. package/src/quantifierParser.ts +25 -0
  284. package/src/separatedArrayParser.test.ts +34 -0
  285. package/src/separatedArrayParser.ts +55 -0
  286. package/src/sequenceBuffer.test.ts +72 -2
  287. package/src/sequenceBuffer.ts +93 -7
  288. package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
  289. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  290. package/src/sequenceUnparser.ts +9 -0
  291. package/src/skipParser.ts +7 -5
  292. package/src/skipToParser.ts +16 -0
  293. package/src/sliceBoundedParser.test.ts +45 -3
  294. package/src/sliceBoundedParser.ts +21 -3
  295. package/src/smali.ts +24 -0
  296. package/src/smaliParser.test.ts +132 -0
  297. package/src/smaliParser.test.ts.md +2320 -0
  298. package/src/smaliParser.test.ts.snap +0 -0
  299. package/src/smaliParser.ts +1166 -0
  300. package/src/terminatedArrayParser.test.ts +258 -0
  301. package/src/terminatedArrayParser.ts +111 -6
  302. package/src/toAsyncIterable.ts +7 -0
  303. package/src/toAsyncIterator.ts +48 -0
  304. package/src/tupleParser.ts +8 -5
  305. package/src/uint8Array.ts +10 -0
  306. package/src/unionParser.test.ts +79 -0
  307. package/src/unionParser.ts +44 -16
  308. package/src/unparser.test.ts +221 -0
  309. package/src/unparser.ts +209 -0
  310. package/src/unparserContext.ts +127 -0
  311. package/src/unparserError.ts +12 -0
  312. package/src/unparserImplementationInvariant.ts +6 -0
  313. package/src/unparserOutputCompanion.ts +24 -0
  314. package/src/zip.ts +10 -22
  315. package/src/zipParser.test.ts +2 -8
  316. package/src/zipParser.ts +223 -146
  317. package/src/zipUnparser.test.ts +119 -0
  318. package/src/zipUnparser.ts +300 -0
  319. package/build/apk.d.ts +0 -13
  320. package/build/apkParser.d.ts +0 -3
  321. package/build/apkParser.js +0 -135
  322. package/build/arbitraryDosDate.d.ts +0 -2
  323. package/build/arbitraryDosDate.js +0 -8
  324. package/build/arbitraryZipEntry.d.ts +0 -3
  325. package/build/arbitraryZipEntry.js +0 -26
  326. package/build/createDisjunctionParser.d.ts +0 -2
  327. package/build/createDisjunctionParser.js +0 -47
  328. package/build/createExactParser.d.ts +0 -2
  329. package/build/createExactParser.js +0 -12
  330. package/build/createSequentialUnionParser.d.ts +0 -2
  331. package/build/createSequentialUnionParser.js +0 -69
  332. package/build/fixedLengthChunkParser.d.ts +0 -2
  333. package/build/fixedLengthChunkParser.js +0 -12
  334. package/build/fixedLengthParser.d.ts +0 -2
  335. package/build/fixedLengthParser.js +0 -12
  336. package/build/inputChunkBuffer.d.ts +0 -15
  337. package/build/inputChunkBuffer.js +0 -40
  338. package/build/inputChunkBuffer.test.js +0 -34
  339. package/build/inputCompanion.d.ts +0 -18
  340. package/build/inputCompanion.js +0 -28
  341. package/build/invariantDefined.d.ts +0 -1
  342. package/build/invariantDefined.js +0 -5
  343. package/build/invariantIdentity.d.ts +0 -3
  344. package/build/invariantIdentity.js +0 -5
  345. package/build/jsonParser2.d.ts +0 -3
  346. package/build/jsonParser2.js +0 -52
  347. package/build/jsonParser2.test.js +0 -22
  348. package/build/negativeLookahead.js +0 -20
  349. package/build/parserCompose.d.ts +0 -3
  350. package/build/parserCompose.js +0 -7
  351. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  352. package/build/parserImplementationInvariantInvariant.js +0 -15
  353. package/build/promiseFish.d.ts +0 -1
  354. package/build/promiseFish.js +0 -3
  355. package/build/sequenceParser.d.ts +0 -3
  356. package/build/sequenceParser.js +0 -10
  357. package/build/terminatedSequenceParser.d.ts +0 -2
  358. package/build/terminatedSequenceParser.js +0 -24
  359. package/build/zipEntry.d.ts +0 -28
  360. package/build/zipFile.d.ts +0 -32
  361. package/build/zipFileEntry.d.ts +0 -6
  362. package/src/apk.ts +0 -16
  363. package/src/apkParser.test.ts.md +0 -268
  364. package/src/apkParser.test.ts.snap +0 -0
  365. package/src/apkParser.ts +0 -327
  366. package/src/inputCompanion.ts +0 -43
  367. package/src/invariantDefined.ts +0 -6
  368. package/src/invariantIdentity.ts +0 -8
  369. package/src/negativeLookahead.ts +0 -26
  370. /package/build/{apk.js → androidPackage.js} +0 -0
  371. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  372. /package/build/{arbitraryDosPermissions.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  373. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  374. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  375. /package/build/{jsonParser2.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  376. /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  377. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  378. /package/build/{zipEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
  379. /package/build/{zipFile.js → javaKeyStore.d.ts} +0 -0
  380. /package/build/{zipFileEntry.js → javaKeyStore.js} +0 -0
@@ -1,9 +1,10 @@
1
1
  import test from 'ava';
2
2
  import { InputReaderImplementation } from './inputReader.js';
3
- import { stringInputCompanion } from './inputCompanion.js';
3
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
4
4
  import { ParserImplementationError } from './parserError.js';
5
+ import { toAsyncIterable } from './toAsyncIterable.js';
5
6
  test('inputReader', async (t) => {
6
- const inputReader = new InputReaderImplementation(stringInputCompanion, (async function* () {
7
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
7
8
  yield '';
8
9
  yield 'abc';
9
10
  yield 'def';
@@ -31,8 +32,41 @@ test('inputReader', async (t) => {
31
32
  inputReader.skip(1);
32
33
  t.is(await inputReader.peek(0), undefined);
33
34
  });
35
+ test('inputReader peekSequence', async (t) => {
36
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
37
+ yield '';
38
+ yield 'abc';
39
+ yield 'def';
40
+ yield '';
41
+ yield 'gh';
42
+ })());
43
+ t.is(await inputReader.peekSequence(0, 0), '');
44
+ t.is(await inputReader.peekSequence(0, 1), 'a');
45
+ inputReader.skip(0);
46
+ t.is(await inputReader.peekSequence(1, 2), 'b');
47
+ inputReader.skip(1);
48
+ t.is(await inputReader.peekSequence(1, 7), 'bcdefgh'.slice(1, 7));
49
+ t.is(await inputReader.peekSequence(1, 8), undefined);
50
+ inputReader.skip(6);
51
+ t.is(await inputReader.peekSequence(0, 0), '');
52
+ t.is(await inputReader.peekSequence(0, 1), 'h');
53
+ t.is(await inputReader.peekSequence(1, 2), undefined);
54
+ t.is(await inputReader.peekSequence(2, 2), undefined);
55
+ inputReader.skip(1);
56
+ t.is(await inputReader.peekSequence(0, 0), '');
57
+ t.is(await inputReader.peekSequence(0, 1), undefined);
58
+ t.is(await inputReader.peekSequence(1, 1), undefined);
59
+ inputReader.skip(0);
60
+ t.is(await inputReader.peekSequence(0, 0), '');
61
+ t.is(await inputReader.peekSequence(0, 1), undefined);
62
+ t.is(await inputReader.peekSequence(1, 1), undefined);
63
+ inputReader.skip(1);
64
+ t.is(await inputReader.peekSequence(0, 0), undefined);
65
+ t.is(await inputReader.peekSequence(0, 1), undefined);
66
+ t.is(await inputReader.peekSequence(1, 1), undefined);
67
+ });
34
68
  test('inputReader.peek concurrent', async (t) => {
35
- const inputReader = new InputReaderImplementation(stringInputCompanion, (async function* () {
69
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
36
70
  yield* 'abcdefgh';
37
71
  })());
38
72
  const peeks = await Promise.all([
@@ -50,18 +84,88 @@ test('inputReader.peek concurrent', async (t) => {
50
84
  ]);
51
85
  t.deepEqual(peeks, ['a', 'a', 'a', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
52
86
  });
87
+ test('inputReader.peekSequence concurrent', async (t) => {
88
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
89
+ yield* 'abcdefgh';
90
+ })());
91
+ const peeks = await Promise.all([1, 2, 3].flatMap(length => [
92
+ inputReader.peekSequence(0, 0 + length),
93
+ inputReader.peekSequence(0, 0 + length),
94
+ inputReader.peekSequence(0, 0 + length),
95
+ inputReader.peekSequence(0, 0 + length),
96
+ inputReader.peekSequence(1, 1 + length),
97
+ inputReader.peekSequence(2, 2 + length),
98
+ inputReader.peekSequence(3, 3 + length),
99
+ inputReader.peekSequence(4, 4 + length),
100
+ inputReader.peekSequence(5, 5 + length),
101
+ inputReader.peekSequence(6, 6 + length),
102
+ inputReader.peekSequence(7, 7 + length),
103
+ ]));
104
+ t.deepEqual(peeks, [
105
+ 'a',
106
+ 'a',
107
+ 'a',
108
+ 'a',
109
+ 'b',
110
+ 'c',
111
+ 'd',
112
+ 'e',
113
+ 'f',
114
+ 'g',
115
+ 'h',
116
+ 'ab',
117
+ 'ab',
118
+ 'ab',
119
+ 'ab',
120
+ 'bc',
121
+ 'cd',
122
+ 'de',
123
+ 'ef',
124
+ 'fg',
125
+ 'gh',
126
+ undefined,
127
+ 'abc',
128
+ 'abc',
129
+ 'abc',
130
+ 'abc',
131
+ 'bcd',
132
+ 'cde',
133
+ 'def',
134
+ 'efg',
135
+ 'fgh',
136
+ undefined,
137
+ undefined,
138
+ ]);
139
+ });
53
140
  test('inputReader skip while peeking', async (t) => {
54
- const inputReader = new InputReaderImplementation(stringInputCompanion, (async function* () {
141
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
55
142
  yield* 'abcdefgh';
56
143
  })());
57
144
  const peekPromise = inputReader.peek(0);
58
145
  inputReader.skip(1);
146
+ const peekAfterSkipPromise = inputReader.peek(0);
147
+ const peekSequenceAfterSkipPromise = inputReader.peekSequence(0, 5);
59
148
  t.is(await peekPromise, 'a');
60
149
  t.is(await inputReader.peek(0), 'b');
150
+ t.is(await peekAfterSkipPromise, 'b');
151
+ t.is(await peekSequenceAfterSkipPromise, 'bcdef');
152
+ });
153
+ test('inputReader skip while peeking sequence', async (t) => {
154
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
155
+ yield* 'abcdefgh';
156
+ })());
157
+ const peekPromise = inputReader.peekSequence(1, 5);
158
+ inputReader.skip(1);
159
+ const peekAfterSkipPromise = inputReader.peek(0);
160
+ const peekSequenceAfterSkipPromise = inputReader.peekSequence(0, 4);
161
+ t.is(await peekPromise, 'bcde', 'peekPromise');
162
+ t.is(await inputReader.peekSequence(0, 4), 'bcde', 'inputReader.peekSequence(0, 4)');
163
+ t.is(await peekAfterSkipPromise, 'b', 'peekAfterSkipPromise');
164
+ t.is(await peekSequenceAfterSkipPromise, 'bcde', 'peekSequenceAfterSkipPromise');
61
165
  });
62
166
  test('inputReader.lookahead', async (t) => {
63
167
  let read = 0;
64
- const inputReader = new InputReaderImplementation(stringInputCompanion, (async function* () {
168
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
65
169
  for (const character of 'abcdefgh') {
66
170
  read++;
67
171
  yield character;
@@ -129,7 +233,7 @@ test('inputReader.lookahead', async (t) => {
129
233
  });
130
234
  test('inputReader.lookahead concurrent', async (t) => {
131
235
  let read = 0;
132
- const inputReader = new InputReaderImplementation(stringInputCompanion, (async function* () {
236
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
133
237
  for (const character of 'abcdefgh') {
134
238
  read++;
135
239
  yield character;
@@ -154,7 +258,7 @@ test('inputReader.lookahead concurrent', async (t) => {
154
258
  });
155
259
  test('inputReader.lookahead skip position', async (t) => {
156
260
  let read = 0;
157
- const inputReader = new InputReaderImplementation(stringInputCompanion, (async function* () {
261
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
158
262
  for (const character of 'abcdefgh') {
159
263
  read++;
160
264
  yield character;
@@ -172,3 +276,64 @@ test('inputReader.lookahead skip position', async (t) => {
172
276
  t.is(await lookahead.peek(0), 'c');
173
277
  t.is(await lookahead1.peek(0), 'd');
174
278
  });
279
+ const END_OF_CONSUMED_SEQUENCES = Symbol('END_OF_CONSUMED_SEQUENCES');
280
+ const END_OF_BUFFERED_SEQUENCES = Symbol('END_OF_BUFFERED_SEQUENCES');
281
+ async function inputReaderStateToArray({ unconsumedBufferedSequences, consumedBufferedSequences, unbufferedSequences, }) {
282
+ const unconsumedBufferedSequencesArray = unconsumedBufferedSequences.slice();
283
+ const consumedBufferedSequencesArray = consumedBufferedSequences.slice();
284
+ const unbufferedSequencesArray = [];
285
+ if (unbufferedSequences) {
286
+ for await (const sequence of toAsyncIterable(unbufferedSequences)) {
287
+ unbufferedSequencesArray.push(sequence);
288
+ }
289
+ }
290
+ return [
291
+ ...consumedBufferedSequencesArray,
292
+ END_OF_CONSUMED_SEQUENCES,
293
+ ...unconsumedBufferedSequencesArray,
294
+ END_OF_BUFFERED_SEQUENCES,
295
+ ...unbufferedSequencesArray,
296
+ ];
297
+ }
298
+ for (const [input, position, expected,] of [
299
+ [
300
+ ['', 'abc', 'def', '', 'gh'],
301
+ 0,
302
+ [END_OF_CONSUMED_SEQUENCES, 'abc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh'],
303
+ ],
304
+ [
305
+ ['', 'abc', 'def', '', 'gh'],
306
+ 1,
307
+ ['a', END_OF_CONSUMED_SEQUENCES, 'bc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh'],
308
+ ],
309
+ [
310
+ ['', 'abc', 'def', '', 'gh'],
311
+ 2,
312
+ ['ab', END_OF_CONSUMED_SEQUENCES, 'c', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh'],
313
+ ],
314
+ [
315
+ ['', 'abc', 'def', '', 'gh'],
316
+ 3,
317
+ [END_OF_CONSUMED_SEQUENCES, 'def', END_OF_BUFFERED_SEQUENCES, '', 'gh'],
318
+ ],
319
+ [
320
+ ['', 'abc', 'def', '', 'gh'],
321
+ 4,
322
+ ['d', END_OF_CONSUMED_SEQUENCES, 'ef', END_OF_BUFFERED_SEQUENCES, '', 'gh'],
323
+ ],
324
+ [
325
+ ['', 'abc', 'def', '', 'gh'],
326
+ 8,
327
+ [END_OF_CONSUMED_SEQUENCES, END_OF_BUFFERED_SEQUENCES],
328
+ ],
329
+ ]) {
330
+ test('inputReader.toInputReaderState ' + JSON.stringify({ input, position }), async (t) => {
331
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function* () {
332
+ yield* input;
333
+ })());
334
+ inputReader.skip(position);
335
+ await inputReader.peek(0);
336
+ const actual = await inputReaderStateToArray(inputReader.toInputReaderState());
337
+ t.deepEqual(actual, expected);
338
+ });
339
+ }
@@ -0,0 +1,10 @@
1
+ export type InputReaderState<Sequence> = {
2
+ position: number;
3
+ consumedBufferedSequences: Sequence[];
4
+ unconsumedBufferedSequences: Sequence[];
5
+ unbufferedSequences: undefined | AsyncIterator<Sequence>;
6
+ };
7
+ export declare const inputReaderStateCompanion: {
8
+ isDone<Sequence>({ unconsumedBufferedSequences, unbufferedSequences, }: InputReaderState<Sequence>): boolean;
9
+ toRemainingInputAsyncIterator<Sequence>({ unconsumedBufferedSequences, unbufferedSequences, }: InputReaderState<Sequence>): AsyncIterable<Sequence>;
10
+ };
@@ -0,0 +1,16 @@
1
+ export const inputReaderStateCompanion = {
2
+ isDone({ unconsumedBufferedSequences, unbufferedSequences, }) {
3
+ return (unconsumedBufferedSequences.length === 0
4
+ && unbufferedSequences === undefined);
5
+ },
6
+ async *toRemainingInputAsyncIterator({ unconsumedBufferedSequences, unbufferedSequences, }) {
7
+ yield* unconsumedBufferedSequences;
8
+ if (unbufferedSequences !== undefined) {
9
+ yield* {
10
+ [Symbol.asyncIterator]() {
11
+ return unbufferedSequences;
12
+ },
13
+ };
14
+ }
15
+ },
16
+ };
@@ -0,0 +1 @@
1
+ export declare const inspect: (value: unknown) => string;
@@ -0,0 +1,7 @@
1
+ import { inspect as nodeInspect } from 'node:util';
2
+ export const inspect = (value) => {
3
+ if (value instanceof Uint8Array) {
4
+ value = Buffer.from(value);
5
+ }
6
+ return nodeInspect(value);
7
+ };
@@ -0,0 +1,2 @@
1
+ import { type Parser } from './parser.js';
2
+ export declare const javaKeyStoreParser: Parser<unknown, Uint8Array>;
@@ -0,0 +1,67 @@
1
+ import { createExactSequenceParser } from './exactSequenceParser.js';
2
+ import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
3
+ import { setParserName } from './parser.js';
4
+ import { parserCreatorCompose } from './parserCreatorCompose.js';
5
+ import { promiseCompose } from './promiseCompose.js';
6
+ import { createQuantifierParser } from './quantifierParser.js';
7
+ import { createTupleParser } from './tupleParser.js';
8
+ import { createUnionParser } from './unionParser.js';
9
+ // https://github.com/openjdk/jdk/blob/c517ffba7d9388e75b5d7bba77e565e71c0a7d76/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java#L512-L553
10
+ const uint64BEParser = promiseCompose(createFixedLengthSequenceParser(8), array => Buffer.from(array).readBigUInt64BE());
11
+ setParserName(uint64BEParser, 'uint64BEParser');
12
+ const uint32BEParser = promiseCompose(createFixedLengthSequenceParser(4), array => Buffer.from(array).readUInt32BE());
13
+ setParserName(uint32BEParser, 'uint32BEParser');
14
+ const uint16BEParser = promiseCompose(createFixedLengthSequenceParser(2), array => Buffer.from(array).readUInt16BE());
15
+ setParserName(uint16BEParser, 'uint16BEParser');
16
+ const createUint32BECountPrefixedParser = (elementParser) => parserCreatorCompose(() => uint32BEParser, count => createQuantifierParser(elementParser, count))();
17
+ const javaModifiedUTF8StringParser = promiseCompose(parserCreatorCompose(() => uint16BEParser, length => createFixedLengthSequenceParser(length))(), uint8Array => Buffer.from(uint8Array).toString('utf8'));
18
+ const uint32LengthPrefixedUint8ArrayParser = parserCreatorCompose(() => uint32BEParser, length => createFixedLengthSequenceParser(length))();
19
+ const javaKeyStoreImplementationParser = promiseCompose(createUnionParser([
20
+ createExactSequenceParser(Buffer.from('feedfeed', 'hex')),
21
+ createExactSequenceParser(Buffer.from('cececece', 'hex')),
22
+ ]), uint8Array => uint8Array[0] === 0xFE ? 'JKS' : 'JCEKS');
23
+ const javaKeyStorePrivateKeyEntryPrivateKeyParser = uint32LengthPrefixedUint8ArrayParser;
24
+ const javaKeyStorePrivateKeyEntryCertificateParser = promiseCompose(createTupleParser([
25
+ javaModifiedUTF8StringParser,
26
+ uint32LengthPrefixedUint8ArrayParser,
27
+ ]), ([type, certificate]) => ({ type, certificate }));
28
+ const javaKeyStorePrivateKeyEntryCertificateChainParser = createUint32BECountPrefixedParser(javaKeyStorePrivateKeyEntryCertificateParser);
29
+ const javaKeyStorePrivateKeyEntryParser = promiseCompose(createTupleParser([
30
+ createExactSequenceParser(Buffer.from('00000001', 'hex')),
31
+ javaModifiedUTF8StringParser,
32
+ uint64BEParser,
33
+ javaKeyStorePrivateKeyEntryPrivateKeyParser,
34
+ javaKeyStorePrivateKeyEntryCertificateChainParser,
35
+ ]), ([_tag, alias, creationDate, privateKey, certificateChain,]) => ({
36
+ type: 'privateKey',
37
+ alias,
38
+ creationDate: new Date(Number(creationDate)),
39
+ privateKey,
40
+ certificateChain,
41
+ }));
42
+ const javaKeyStoreTrustedCertEntryParser = createTupleParser([
43
+ createExactSequenceParser(Buffer.from('00000002', 'hex')),
44
+ async (parserContext) => parserContext.invariant(false, 'Not implemented'),
45
+ ]);
46
+ const javaKeyStoreSecretKeyEntryParser = createTupleParser([
47
+ createExactSequenceParser(Buffer.from('00000003', 'hex')),
48
+ async (parserContext) => parserContext.invariant(false, 'Not implemented'),
49
+ ]);
50
+ const javaKeyStoreEntryParser = createUnionParser([
51
+ javaKeyStorePrivateKeyEntryParser,
52
+ javaKeyStoreTrustedCertEntryParser,
53
+ javaKeyStoreSecretKeyEntryParser,
54
+ ]);
55
+ const javaKeyStoreEntriesParser = createUint32BECountPrefixedParser(javaKeyStoreEntryParser);
56
+ const javaKeyStoreParser_ = createTupleParser([
57
+ javaKeyStoreImplementationParser,
58
+ uint32BEParser,
59
+ javaKeyStoreEntriesParser,
60
+ createFixedLengthSequenceParser(20),
61
+ ]);
62
+ export const javaKeyStoreParser = promiseCompose(javaKeyStoreParser_, ([implementation, version, entries, hash,]) => ({
63
+ implementation,
64
+ version,
65
+ entries,
66
+ hash,
67
+ }));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import test from 'ava';
2
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
3
+ import { runParser } from './parser.js';
4
+ import { javaKeyStoreParser } from './javaKeyStoreParser.js';
5
+ import { fetchCid } from './fetchCid.js';
6
+ for (const javaKeyStoreCid of [
7
+ 'bafkreig6k53b6p7bdvfjxc5mcb4qv3mffqls5ymqerxkqd6ih2xy5cs3n4',
8
+ ]) {
9
+ test('javaKeyStore ' + javaKeyStoreCid, async (t) => {
10
+ const javaKeyStoreStream = await fetchCid(javaKeyStoreCid);
11
+ const actual = await runParser(javaKeyStoreParser, javaKeyStoreStream, uint8ArrayParserInputCompanion, {
12
+ errorJoinMode: 'all',
13
+ });
14
+ t.snapshot(actual);
15
+ });
16
+ }
@@ -1,3 +1,5 @@
1
1
  import { type JsonValue } from 'type-fest';
2
2
  import { type Parser } from './parser.js';
3
+ export declare const jsonStringParser: Parser<string, string>;
4
+ export declare const jsonNumberParser: Parser<number, string>;
3
5
  export declare const jsonValueParser: Parser<JsonValue, string>;
@@ -10,6 +10,7 @@ import { createArrayParser } from './arrayParser.js';
10
10
  import { createParserAccessorParser } from './parserAccessorParser.js';
11
11
  import { createElementParser } from './elementParser.js';
12
12
  import { parserCreatorCompose } from './parserCreatorCompose.js';
13
+ import { createSeparatedArrayParser } from './separatedArrayParser.js';
13
14
  const whitespaceParser = createArrayParser(createUnionParser([
14
15
  createExactSequenceParser(' '),
15
16
  createExactSequenceParser('\t'),
@@ -47,11 +48,11 @@ const jsonStringCharacterParser = createDisjunctionParser([
47
48
  return character;
48
49
  })(),
49
50
  ]);
50
- const jsonStringParser = promiseCompose(createTupleParser([
51
+ export const jsonStringParser = promiseCompose(createTupleParser([
51
52
  createExactSequenceParser('"'),
52
53
  promiseCompose(createTerminatedArrayParser(jsonStringCharacterParser, createExactSequenceParser('"')), ([characters]) => characters.join('')),
53
54
  ]), ([, string]) => string);
54
- const jsonNumberParser = parserCreatorCompose(() => createArrayParser(parserCreatorCompose(() => elementParser, (character) => async (parserContext) => {
55
+ export const jsonNumberParser = parserCreatorCompose(() => createArrayParser(parserCreatorCompose(() => elementParser, character => async (parserContext) => {
55
56
  parserContext.invariant((character === '-'
56
57
  || (character >= '0' && character <= '9')
57
58
  || character === '.'
@@ -59,7 +60,7 @@ const jsonNumberParser = parserCreatorCompose(() => createArrayParser(parserCrea
59
60
  || character === 'E'
60
61
  || character === '+'), 'Expected "-", "0" to "9", ".", "e", "E", "+", got "%s"', character);
61
62
  return character;
62
- })()), (characters) => async (parserContext) => {
63
+ })()), characters => async (parserContext) => {
63
64
  parserContext.invariant(characters.length > 0, 'Expected at least one character');
64
65
  return Number(characters.join(''));
65
66
  })();
@@ -67,6 +68,7 @@ const jsonTrueParser = promiseCompose(createExactSequenceParser('true'), () => t
67
68
  setParserName(jsonTrueParser, 'jsonTrueParser');
68
69
  const jsonFalseParser = promiseCompose(createExactSequenceParser('false'), () => false);
69
70
  setParserName(jsonFalseParser, 'jsonFalseParser');
71
+ // eslint-disable-next-line @typescript-eslint/ban-types
70
72
  const jsonNullParser = promiseCompose(createExactSequenceParser('null'), () => null);
71
73
  setParserName(jsonNullParser, 'jsonNullParser');
72
74
  const jsonPrimitiveParser = createUnionParser([
@@ -112,18 +114,14 @@ const jsonObjectParser = promiseCompose(createTupleParser([
112
114
  const jsonArrayParser = promiseCompose(createTupleParser([
113
115
  createExactSequenceParser('['),
114
116
  whitespaceParser,
115
- promiseCompose(createTerminatedArrayParser(createDisjunctionParser([
116
- promiseCompose(createTupleParser([
117
- createParserAccessorParser(() => jsonValueParser),
118
- whitespaceParser,
119
- createExactSequenceParser(','),
120
- whitespaceParser,
121
- ]), ([value]) => value),
122
- promiseCompose(createTupleParser([
123
- createParserAccessorParser(() => jsonValueParser),
124
- whitespaceParser,
125
- ]), ([value]) => value),
126
- ]), createExactSequenceParser(']')), ([values]) => values),
117
+ createSeparatedArrayParser(createParserAccessorParser(() => jsonValueParser), createTupleParser([
118
+ whitespaceParser,
119
+ createExactSequenceParser(','),
120
+ whitespaceParser,
121
+ ])),
122
+ whitespaceParser,
123
+ createExactSequenceParser(']'),
124
+ whitespaceParser,
127
125
  ]), ([_bracket, _whitespace, values]) => values);
128
126
  export const jsonValueParser = createUnionParser([
129
127
  jsonObjectParser,
@@ -2,12 +2,12 @@ import { testProp, fc } from '@fast-check/ava';
2
2
  import { jsonValueParser } from './jsonParser.js';
3
3
  import { runParser } from './parser.js';
4
4
  import { arbitrarilySlicedAsyncIterator } from './arbitrarilySlicedAsyncInterator.js';
5
- import { stringInputCompanion } from './inputCompanion.js';
5
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
6
6
  testProp('json', [
7
7
  arbitrarilySlicedAsyncIterator(fc.tuple(fc.json(), fc.nat())
8
8
  .map(([jsonString, indent]) => JSON.stringify(JSON.parse(jsonString), null, indent))),
9
9
  ], async (t, [jsonString, jsonStringChunkIterator]) => {
10
- const actual = await runParser(jsonValueParser, jsonStringChunkIterator, stringInputCompanion, {
10
+ const actual = await runParser(jsonValueParser, jsonStringChunkIterator, stringParserInputCompanion, {
11
11
  errorJoinMode: 'none',
12
12
  });
13
13
  const expected = JSON.parse(jsonString);
@@ -0,0 +1,7 @@
1
+ import { Parser } from "./parser.js";
2
+ export declare const uleb128Parser: Parser<bigint, Uint8Array>;
3
+ export declare const sleb128Parser: Parser<bigint, Uint8Array>;
4
+ export declare const uleb128NumberParser: Parser<number, Uint8Array>;
5
+ export declare const sleb128NumberParser: Parser<number, Uint8Array>;
6
+ export declare const uleb128UnsafeNumberParser: Parser<number, Uint8Array>;
7
+ export declare const sleb128UnsafeNumberParser: Parser<number, Uint8Array>;
@@ -0,0 +1,82 @@
1
+ export const uleb128Parser = async (parserContext) => {
2
+ let leastSignificantValueBitIndex = 0n;
3
+ let value = 0n;
4
+ while (true) {
5
+ const byte = await parserContext.read(0);
6
+ const byteValue = BigInt(byte & 0b01111111);
7
+ const byteNotLast = BigInt(byte & 0b10000000);
8
+ value |= byteValue << leastSignificantValueBitIndex;
9
+ if (byteNotLast) {
10
+ leastSignificantValueBitIndex += 7n;
11
+ continue;
12
+ }
13
+ break;
14
+ }
15
+ return value;
16
+ };
17
+ export const sleb128Parser = async (parserContext) => {
18
+ let value = 0n;
19
+ let leastSignificantValueBitIndex = 0n;
20
+ while (true) {
21
+ const byte = await parserContext.read(0);
22
+ const byteValue = BigInt(byte & 0b01111111);
23
+ const byteNotLast = BigInt(byte & 0b10000000);
24
+ value |= byteValue << leastSignificantValueBitIndex;
25
+ leastSignificantValueBitIndex += 7n;
26
+ if (byteNotLast) {
27
+ continue;
28
+ }
29
+ const mostSignificantInputBit = byte & 0b01000000;
30
+ if (mostSignificantInputBit) {
31
+ value |= (~0n << leastSignificantValueBitIndex);
32
+ }
33
+ break;
34
+ }
35
+ return value;
36
+ };
37
+ export const uleb128NumberParser = async (parserContext) => {
38
+ const value = await uleb128Parser(parserContext);
39
+ parserContext.invariant(Number(value) <= Number.MAX_SAFE_INTEGER, 'Value is too large to be represented as a number: %s', value);
40
+ return Number(value);
41
+ };
42
+ export const sleb128NumberParser = async (parserContext) => {
43
+ const value = await sleb128Parser(parserContext);
44
+ parserContext.invariant(Number(value) >= Number.MIN_SAFE_INTEGER && Number(value) <= Number.MAX_SAFE_INTEGER, 'Value is too large to be represented as a number: %s', value);
45
+ return Number(value);
46
+ };
47
+ export const uleb128UnsafeNumberParser = async (parserContext) => {
48
+ let leastSignificantValueBitIndex = 0;
49
+ let value = 0;
50
+ while (true) {
51
+ const byte = await parserContext.read(0);
52
+ const byteValue = byte & 0b01111111;
53
+ const byteNotLast = byte & 0b10000000;
54
+ value |= byteValue << leastSignificantValueBitIndex;
55
+ if (byteNotLast) {
56
+ leastSignificantValueBitIndex += 7;
57
+ continue;
58
+ }
59
+ break;
60
+ }
61
+ return value;
62
+ };
63
+ export const sleb128UnsafeNumberParser = async (parserContext) => {
64
+ let value = 0;
65
+ let leastSignificantValueBitIndex = 0;
66
+ while (true) {
67
+ const byte = await parserContext.read(0);
68
+ const byteValue = byte & 0b01111111;
69
+ const byteNotLast = byte & 0b10000000;
70
+ value |= byteValue << leastSignificantValueBitIndex;
71
+ leastSignificantValueBitIndex += 7;
72
+ if (byteNotLast) {
73
+ continue;
74
+ }
75
+ const mostSignificantInputBit = byte & 0b01000000;
76
+ if (leastSignificantValueBitIndex < 32 && mostSignificantInputBit) {
77
+ value |= (~0 << leastSignificantValueBitIndex);
78
+ }
79
+ break;
80
+ }
81
+ return value;
82
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,107 @@
1
+ import { testProp, fc } from '@fast-check/ava';
2
+ import test from 'ava';
3
+ // @ts-expect-error
4
+ import leb128 from 'leb128';
5
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
6
+ import { runParser } from './parser.js';
7
+ import { uleb128Parser, sleb128Parser, uleb128NumberParser, sleb128NumberParser } from './leb128Parser.js';
8
+ test('sleb128, uleb128, uleb128p1', async (t) => {
9
+ for (const [input, expectedSleb128, expectedUleb128,] of [
10
+ [Buffer.from('00', 'hex'), 0n, 0n],
11
+ [Buffer.from('01', 'hex'), 1n, 1n],
12
+ [Buffer.from('7f', 'hex'), -1n, 127n],
13
+ [Buffer.from('807f', 'hex'), -128n, 16256n],
14
+ ]) {
15
+ const actualSleb128 = await runParser(sleb128Parser, input, uint8ArrayParserInputCompanion);
16
+ const actualUleb128 = await runParser(uleb128Parser, input, uint8ArrayParserInputCompanion);
17
+ t.is(actualSleb128, expectedSleb128, 'sleb128');
18
+ t.is(actualUleb128, expectedUleb128, 'uleb128');
19
+ }
20
+ for (const [input, expectedUleb128,] of [
21
+ [new Uint8Array([2]), 2n],
22
+ [new Uint8Array([127]), 127n],
23
+ [new Uint8Array([0 + 0x80, 1]), 128n],
24
+ [new Uint8Array([1 + 0x80, 1]), 129n],
25
+ [new Uint8Array([57 + 0x80, 100]), 12857n],
26
+ ]) {
27
+ const actualUleb128 = await runParser(uleb128Parser, input, uint8ArrayParserInputCompanion);
28
+ t.is(actualUleb128, expectedUleb128, 'uleb128');
29
+ }
30
+ for (const [input, expectedSleb128,] of [
31
+ [new Uint8Array([2]), 2n],
32
+ [new Uint8Array([0x7e]), -2n],
33
+ [new Uint8Array([127 + 0x80, 0]), 127n],
34
+ [new Uint8Array([1 + 0x80, 0x7f]), -127n],
35
+ [new Uint8Array([0 + 0x80, 1]), 128n],
36
+ [new Uint8Array([0 + 0x80, 0x7f]), -128n],
37
+ [new Uint8Array([1 + 0x80, 1]), 129n],
38
+ [new Uint8Array([0x7f + 0x80, 0x7e]), -129n],
39
+ ]) {
40
+ const actualSleb128 = await runParser(sleb128Parser, input, uint8ArrayParserInputCompanion);
41
+ t.is(actualSleb128, expectedSleb128, 'sleb128');
42
+ }
43
+ });
44
+ testProp('uleb128NumberParser on small number', [
45
+ fc.nat(),
46
+ ], async (t, natural) => {
47
+ const uleb128 = leb128.unsigned.encode(natural);
48
+ const actualUleb128 = await runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion);
49
+ t.is(actualUleb128, natural, 'uleb128');
50
+ }, {
51
+ verbose: true,
52
+ });
53
+ testProp('sleb128NumberParser on small number', [
54
+ fc.integer(),
55
+ ], async (t, integer) => {
56
+ const sleb128 = leb128.signed.encode(integer);
57
+ const actualSleb128 = await runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion);
58
+ t.is(actualSleb128, integer, 'sleb128');
59
+ }, {
60
+ verbose: true,
61
+ });
62
+ // TODO?
63
+ testProp.skip('uleb128NumberParser on large number', [
64
+ fc.maxSafeNat(),
65
+ ], async (t, natural) => {
66
+ const uleb128 = leb128.unsigned.encode(natural);
67
+ if (natural > (2 ** 32) - 1) {
68
+ await t.throwsAsync(() => runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion));
69
+ return;
70
+ }
71
+ const actualUleb128 = await runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion);
72
+ t.is(actualUleb128, natural, 'uleb128');
73
+ }, {
74
+ verbose: true,
75
+ });
76
+ // TODO?
77
+ testProp.skip('sleb128NumberParser on large number', [
78
+ fc.maxSafeInteger(),
79
+ ], async (t, integer) => {
80
+ const sleb128 = leb128.signed.encode(integer);
81
+ if (integer > (2 ** 32) - 1 || integer < -(2 ** 32)) {
82
+ await t.throwsAsync(() => runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion));
83
+ return;
84
+ }
85
+ const actualSleb128 = await runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion);
86
+ t.is(actualSleb128, integer, 'sleb128');
87
+ }, {
88
+ verbose: true,
89
+ });
90
+ testProp('uleb128Parser on bigint', [
91
+ fc.bigInt({ min: 0n }),
92
+ ], async (t, bigInt) => {
93
+ const uleb128 = leb128.unsigned.encode(bigInt);
94
+ const actualUleb128 = await runParser(uleb128Parser, uleb128, uint8ArrayParserInputCompanion);
95
+ t.is(actualUleb128, bigInt, 'uleb128');
96
+ }, {
97
+ verbose: true,
98
+ });
99
+ testProp('sleb128Parser on bigint', [
100
+ fc.bigInt(),
101
+ ], async (t, bigInt) => {
102
+ const sleb128 = leb128.signed.encode(bigInt);
103
+ const actualSleb128 = await runParser(sleb128Parser, sleb128, uint8ArrayParserInputCompanion);
104
+ t.is(actualSleb128, bigInt, 'sleb128');
105
+ }, {
106
+ verbose: true,
107
+ });
@@ -1,2 +1,2 @@
1
- import { Parser } from "./parser.js";
1
+ import { type Parser } from './parser.js';
2
2
  export declare const createListParser: <ElementOutput, Sequence>(elementParser: Parser<ElementOutput, Sequence>) => Parser<ElementOutput[], Sequence>;