@futpib/parser 1.0.0 → 1.0.1

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 (171) hide show
  1. package/build/apk.d.ts +29 -3
  2. package/build/apkParser.d.ts +15 -2
  3. package/build/apkParser.js +70 -41
  4. package/build/apkParser.test.js +2 -2
  5. package/build/apkUnparser.d.ts +4 -0
  6. package/build/apkUnparser.js +90 -0
  7. package/build/apkUnparser.test.d.ts +1 -0
  8. package/build/apkUnparser.test.js +26 -0
  9. package/build/arbitraryFileSystemEntry.js +1 -1
  10. package/build/arbitraryZip.d.ts +1 -1
  11. package/build/arbitraryZip.js +13 -19
  12. package/build/arbitraryZipPermissions.d.ts +1 -8
  13. package/build/arbitraryZipPermissions.js +1 -16
  14. package/build/arbitraryZipStream.d.ts +1 -1
  15. package/build/arbitraryZipStream.js +3 -3
  16. package/build/arrayParser.d.ts +1 -1
  17. package/build/arrayParser.js +2 -2
  18. package/build/arrayParser.test.js +2 -2
  19. package/build/arrayUnparser.d.ts +2 -0
  20. package/build/arrayUnparser.js +8 -0
  21. package/build/bsonParser.test.js +2 -2
  22. package/build/customInvariant.d.ts +4 -0
  23. package/build/customInvariant.js +11 -0
  24. package/build/debugLogParser.d.ts +1 -1
  25. package/build/debugLogParser.js +1 -1
  26. package/build/elementParser.d.ts +2 -2
  27. package/build/elementParser.js +1 -1
  28. package/build/endOfInputParser.d.ts +2 -2
  29. package/build/exactElementParser.d.ts +1 -1
  30. package/build/exactSequenceParser.js +1 -1
  31. package/build/index.d.ts +5 -2
  32. package/build/index.js +3 -0
  33. package/build/inputReader.d.ts +3 -3
  34. package/build/inputReader.js +6 -6
  35. package/build/inputReader.test.js +7 -7
  36. package/build/javaKeyStore.d.ts +1 -0
  37. package/build/javaKeyStore.js +1 -0
  38. package/build/javaKeyStoreParser.d.ts +2 -0
  39. package/build/javaKeyStoreParser.js +67 -0
  40. package/build/javaKeyStoreParser.test.d.ts +1 -0
  41. package/build/javaKeyStoreParser.test.js +16 -0
  42. package/build/javaKeystoreParser.d.ts +2 -0
  43. package/build/javaKeystoreParser.js +7 -0
  44. package/build/jsonParser.js +3 -2
  45. package/build/jsonParser.test.js +2 -2
  46. package/build/listParser.d.ts +1 -1
  47. package/build/listParser.js +5 -5
  48. package/build/negativeLookahead.d.ts +1 -1
  49. package/build/negativeLookahead.js +16 -18
  50. package/build/negativeLookaheadParser.d.ts +2 -0
  51. package/build/negativeLookaheadParser.js +18 -0
  52. package/build/optionalParser.d.ts +1 -1
  53. package/build/optionalParser.js +2 -2
  54. package/build/parser.d.ts +3 -3
  55. package/build/parser.js +3 -3
  56. package/build/parser.test.js +16 -16
  57. package/build/parserAccessorParser.d.ts +1 -1
  58. package/build/parserConsumedSequenceParser.d.ts +2 -0
  59. package/build/parserConsumedSequenceParser.js +17 -0
  60. package/build/parserContext.d.ts +6 -6
  61. package/build/parserContext.js +15 -14
  62. package/build/parserContext.test.js +7 -7
  63. package/build/parserCreatorCompose.d.ts +3 -3
  64. package/build/parserCreatorCompose.js +2 -2
  65. package/build/parserImplementationInvariant.d.ts +1 -1
  66. package/build/parserImplementationInvariant.js +2 -2
  67. package/build/parserInputCompanion.d.ts +20 -0
  68. package/build/parserInputCompanion.js +30 -0
  69. package/build/parserInvariant.d.ts +1 -1
  70. package/build/parserInvariant.js +1 -1
  71. package/build/quantifierParser.d.ts +2 -0
  72. package/build/quantifierParser.js +17 -0
  73. package/build/sequenceBuffer.d.ts +3 -3
  74. package/build/sequenceBuffer.js +6 -6
  75. package/build/sequenceBuffer.test.js +2 -2
  76. package/build/sequenceUnparser.d.ts +2 -0
  77. package/build/sequenceUnparser.js +6 -0
  78. package/build/sliceBoundedParser.d.ts +1 -1
  79. package/build/sliceBoundedParser.js +1 -1
  80. package/build/sliceBoundedParser.test.js +2 -2
  81. package/build/terminatedArrayParser.d.ts +1 -1
  82. package/build/terminatedArrayParser.js +3 -3
  83. package/build/uint8Array.d.ts +1 -0
  84. package/build/uint8Array.js +7 -0
  85. package/build/unparser.d.ts +8 -0
  86. package/build/unparser.js +104 -0
  87. package/build/unparser.test.d.ts +1 -0
  88. package/build/unparser.test.js +150 -0
  89. package/build/unparserContext.d.ts +31 -0
  90. package/build/unparserContext.js +74 -0
  91. package/build/unparserError.d.ts +9 -0
  92. package/build/unparserError.js +9 -0
  93. package/build/unparserImplementationInvariant.d.ts +2 -0
  94. package/build/unparserImplementationInvariant.js +5 -0
  95. package/build/unparserInputCompanion.d.ts +15 -0
  96. package/build/unparserInputCompanion.js +13 -0
  97. package/build/unparserOutputCompanion.d.ts +15 -0
  98. package/build/unparserOutputCompanion.js +13 -0
  99. package/build/zip.d.ts +9 -17
  100. package/build/zipParser.d.ts +13 -10
  101. package/build/zipParser.js +48 -60
  102. package/build/zipParser.test.js +2 -7
  103. package/build/zipUnparser.d.ts +5 -0
  104. package/build/zipUnparser.js +171 -0
  105. package/build/zipUnparser.test.d.ts +1 -0
  106. package/build/zipUnparser.test.js +80 -0
  107. package/package.json +4 -2
  108. package/src/apk.ts +35 -3
  109. package/src/apkParser.test.ts +2 -2
  110. package/src/apkParser.test.ts.md +114 -111
  111. package/src/apkParser.test.ts.snap +0 -0
  112. package/src/apkParser.ts +150 -85
  113. package/src/apkUnparser.test.ts +37 -0
  114. package/src/apkUnparser.ts +120 -0
  115. package/src/arbitraryFileSystemEntry.ts +2 -4
  116. package/src/arbitraryZip.ts +20 -27
  117. package/src/arbitraryZipPermissions.ts +0 -25
  118. package/src/arbitraryZipStream.ts +4 -4
  119. package/src/arrayParser.test.ts +3 -3
  120. package/src/arrayParser.ts +3 -2
  121. package/src/arrayUnparser.ts +13 -0
  122. package/src/bsonParser.test.ts +2 -2
  123. package/src/bsonParser.ts +3 -3
  124. package/src/{parserInvariant.ts → customInvariant.ts} +1 -1
  125. package/src/debugLogParser.ts +1 -1
  126. package/src/elementParser.ts +3 -3
  127. package/src/endOfInputParser.ts +4 -4
  128. package/src/exactElementParser.ts +1 -1
  129. package/src/exactSequenceParser.ts +2 -2
  130. package/src/index.ts +15 -2
  131. package/src/inputReader.test.ts +7 -7
  132. package/src/inputReader.ts +5 -5
  133. package/src/javaKeyStore.ts +0 -0
  134. package/src/javaKeyStoreParser.test.ts +23 -0
  135. package/src/javaKeyStoreParser.test.ts.md +103 -0
  136. package/src/javaKeyStoreParser.test.ts.snap +0 -0
  137. package/src/javaKeyStoreParser.ts +136 -0
  138. package/src/jsonParser.test.ts +2 -2
  139. package/src/jsonParser.ts +13 -12
  140. package/src/listParser.ts +6 -6
  141. package/src/negativeLookaheadParser.ts +24 -0
  142. package/src/optionalParser.ts +3 -3
  143. package/src/parser.test.ts +19 -17
  144. package/src/parser.ts +7 -7
  145. package/src/parserAccessorParser.ts +1 -1
  146. package/src/parserConsumedSequenceParser.ts +20 -0
  147. package/src/parserContext.test.ts +7 -7
  148. package/src/parserContext.ts +18 -14
  149. package/src/parserCreatorCompose.ts +6 -6
  150. package/src/parserImplementationInvariant.ts +2 -2
  151. package/src/{inputCompanion.ts → parserInputCompanion.ts} +10 -6
  152. package/src/quantifierParser.ts +25 -0
  153. package/src/sequenceBuffer.test.ts +2 -2
  154. package/src/sequenceBuffer.ts +5 -5
  155. package/src/sequenceUnparser.ts +9 -0
  156. package/src/sliceBoundedParser.test.ts +2 -2
  157. package/src/sliceBoundedParser.ts +2 -2
  158. package/src/terminatedArrayParser.ts +3 -3
  159. package/src/uint8Array.ts +10 -0
  160. package/src/unparser.test.ts +221 -0
  161. package/src/unparser.ts +209 -0
  162. package/src/unparserContext.ts +127 -0
  163. package/src/unparserError.ts +12 -0
  164. package/src/unparserImplementationInvariant.ts +6 -0
  165. package/src/unparserOutputCompanion.ts +24 -0
  166. package/src/zip.ts +10 -22
  167. package/src/zipParser.test.ts +2 -8
  168. package/src/zipParser.ts +147 -129
  169. package/src/zipUnparser.test.ts +119 -0
  170. package/src/zipUnparser.ts +239 -0
  171. package/src/negativeLookahead.ts +0 -26
@@ -0,0 +1,239 @@
1
+ import zlib from 'node:zlib';
2
+ import { Unparser } from "./unparser.js";
3
+ import { Zip, ZipEntry, ZipFileEntry } from "./zip.js";
4
+ import { Readable } from 'node:stream';
5
+ import { pipeline } from 'node:stream/promises';
6
+ import { ZipEndOfCentralDirectoryRecord } from './zipParser.js';
7
+ import { uint8ArrayAsyncIterableToUint8Array } from './uint8Array.js';
8
+
9
+ const uint16LEUnparser: Unparser<number, Uint8Array> = async function * (uint16LE) {
10
+ const buffer = Buffer.alloc(2);
11
+ buffer.writeUInt16LE(uint16LE);
12
+ yield buffer;
13
+ }
14
+
15
+ const uint32LEUnparser: Unparser<number, Uint8Array> = async function * (uint32LE) {
16
+ const buffer = Buffer.alloc(4);
17
+ buffer.writeUInt32LE(uint32LE);
18
+ yield buffer;
19
+ }
20
+
21
+ const uint16LEPrefixedUint8ArrayUnparser: Unparser<Uint8Array, Uint8Array> = async function * (uint8Array, unparserContext) {
22
+ yield * uint16LEUnparser(uint8Array.length, unparserContext);
23
+ yield uint8Array;
24
+ }
25
+
26
+ const uint16LEPrefixedStringUnparser: Unparser<string, Uint8Array> = async function * (string, unparserContext) {
27
+ yield * uint16LEPrefixedUint8ArrayUnparser(Buffer.from(string, 'utf8'), unparserContext);
28
+ }
29
+
30
+ const dosDateTimeUnparser: Unparser<Date, Uint8Array> = async function * (date, unparserContext) {
31
+ yield * uint16LEUnparser(
32
+ (
33
+ date.getUTCSeconds() / 2
34
+ | date.getUTCMinutes() << 5
35
+ | date.getUTCHours() << 11
36
+ ),
37
+ unparserContext,
38
+ );
39
+ yield * uint16LEUnparser(
40
+ (
41
+ date.getUTCDate()
42
+ | (date.getUTCMonth() + 1) << 5
43
+ | (date.getUTCFullYear() - 1980) << 9
44
+ ),
45
+ unparserContext,
46
+ );
47
+ }
48
+
49
+ const zipCompressionMethodUnparser: Unparser<'store' | 'deflate', Uint8Array> = async function * (compressionMethod, unparserContext) {
50
+ if (compressionMethod === 'store') {
51
+ yield * uint16LEUnparser(0, unparserContext);
52
+ } else {
53
+ yield * uint16LEUnparser(8, unparserContext);
54
+ }
55
+ }
56
+
57
+ export const zipEndOfCentralDirectoryRecordUnparser: Unparser<ZipEndOfCentralDirectoryRecord, Uint8Array> = async function * (zipEndOfCentralDirectoryRecord, unparserContext) {
58
+ yield Buffer.from('504b0506', 'hex');
59
+ yield * uint16LEUnparser(zipEndOfCentralDirectoryRecord.numberOfThisDisk, unparserContext);
60
+ yield * uint16LEUnparser(zipEndOfCentralDirectoryRecord.numberOfTheDiskWithTheStartOfTheCentralDirectory, unparserContext);
61
+ yield * uint16LEUnparser(zipEndOfCentralDirectoryRecord.totalNumberOfEntriesInTheCentralDirectoryOnThisDisk, unparserContext);
62
+ yield * uint16LEUnparser(zipEndOfCentralDirectoryRecord.totalNumberOfEntriesInTheCentralDirectory, unparserContext);
63
+ yield * uint32LEUnparser(zipEndOfCentralDirectoryRecord.sizeOfTheCentralDirectory, unparserContext);
64
+ yield * uint32LEUnparser(zipEndOfCentralDirectoryRecord.offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber, unparserContext);
65
+
66
+ yield * uint16LEPrefixedStringUnparser(zipEndOfCentralDirectoryRecord.zipFileComment, unparserContext);
67
+ }
68
+
69
+ export const zipUnparser: Unparser<Zip, Uint8Array> = async function * (zip, unparserContext) {
70
+ const compressedContentByZipFileEntry = new Map<ZipFileEntry, undefined | Promise<Uint8Array>>(
71
+ zip.entries.flatMap(zipEntry => {
72
+ if (zipEntry.type !== 'file') {
73
+ return [];
74
+ }
75
+
76
+ if (zipEntry.compression === 'store') {
77
+ return [[zipEntry, Promise.resolve(zipEntry.content)]];
78
+ }
79
+
80
+ const uncompressedContent = zipEntry.content;
81
+
82
+ const deflate = zlib.createDeflateRaw();
83
+ const input = Readable.from(Buffer.from(uncompressedContent));
84
+
85
+ const promise = Promise.all([
86
+ pipeline(input, deflate),
87
+ uint8ArrayAsyncIterableToUint8Array(deflate),
88
+ ]);
89
+
90
+ return [[zipEntry, promise.then(([, compressedContent]) => compressedContent)]];
91
+ }),
92
+ );
93
+
94
+ const filePathByZipEntry = new Map<ZipEntry, string>(
95
+ zip.entries.map(zipEntry => [zipEntry, zipEntry.type === 'file' ? zipEntry.path : zipEntry.path + '/']),
96
+ );
97
+
98
+ const localHeaderPositionByZipEntry = new Map<ZipEntry, number>();
99
+
100
+ for (const zipEntry of zip.entries) {
101
+ localHeaderPositionByZipEntry.set(zipEntry, unparserContext.position);
102
+
103
+ yield Buffer.from('504b0304', 'hex');
104
+
105
+ yield * uint16LEUnparser(10, unparserContext); // version needed to extract
106
+ yield * uint16LEUnparser(0, unparserContext); // general purpose bit flag
107
+
108
+ if (zipEntry.type === 'file') {
109
+ yield * zipCompressionMethodUnparser(zipEntry.compression, unparserContext);
110
+ } else {
111
+ yield * uint16LEUnparser(0, unparserContext);
112
+ }
113
+
114
+ yield * dosDateTimeUnparser(zipEntry.date, unparserContext);
115
+
116
+ if (zipEntry.type === 'file') {
117
+ const compressedContent = await compressedContentByZipFileEntry.get(zipEntry)!;
118
+
119
+ yield * uint32LEUnparser(0, unparserContext); // crc32 // TODO
120
+ yield * uint32LEUnparser(compressedContent.length, unparserContext);
121
+ yield * uint32LEUnparser(zipEntry.content.length, unparserContext);
122
+ } else {
123
+ yield * uint32LEUnparser(0, unparserContext);
124
+ yield * uint32LEUnparser(0, unparserContext);
125
+ yield * uint32LEUnparser(0, unparserContext);
126
+ }
127
+
128
+ const filePath = filePathByZipEntry.get(zipEntry)!;
129
+
130
+ const filePathBuffer = Buffer.from(filePath, 'utf8');
131
+ const extraFieldBuffer = Buffer.alloc(0);
132
+ yield * uint16LEUnparser(filePathBuffer.length, unparserContext);
133
+ yield * uint16LEUnparser(extraFieldBuffer.length, unparserContext);
134
+ yield filePathBuffer;
135
+ yield extraFieldBuffer;
136
+
137
+ if (zipEntry.type === 'file') {
138
+ const compressedContent = await compressedContentByZipFileEntry.get(zipEntry)!;
139
+
140
+ yield compressedContent;
141
+ }
142
+ }
143
+
144
+ const startOfCentralDirectoryPosition = unparserContext.position;
145
+
146
+ for (const zipEntry of zip.entries) {
147
+ yield Buffer.from('504b0102', 'hex');
148
+
149
+ if (zipEntry.hostSystem === 'unix') {
150
+ yield 0; // zip specification version
151
+ yield 3; // host system
152
+ } else {
153
+ yield 0;
154
+ yield 0;
155
+ }
156
+
157
+ yield * uint16LEUnparser(0, unparserContext); // version needed to extract
158
+ yield * uint16LEUnparser(0, unparserContext); // general purpose bit flag
159
+
160
+ if (zipEntry.type === 'file') {
161
+ yield * zipCompressionMethodUnparser(zipEntry.compression, unparserContext);
162
+ } else {
163
+ yield * uint16LEUnparser(0, unparserContext);
164
+ }
165
+
166
+ yield * dosDateTimeUnparser(zipEntry.date, unparserContext);
167
+
168
+ if (zipEntry.type === 'file') {
169
+ const compressedContent = await compressedContentByZipFileEntry.get(zipEntry)!;
170
+
171
+ yield * uint32LEUnparser(0, unparserContext); // crc32 // TODO
172
+ yield * uint32LEUnparser(compressedContent.length, unparserContext);
173
+ yield * uint32LEUnparser(zipEntry.content.length, unparserContext);
174
+ } else {
175
+ yield * uint32LEUnparser(0, unparserContext);
176
+ yield * uint32LEUnparser(0, unparserContext);
177
+ yield * uint32LEUnparser(0, unparserContext);
178
+ }
179
+
180
+ const filePath = filePathByZipEntry.get(zipEntry)!;
181
+
182
+ const filePathBuffer = Buffer.from(filePath, 'utf8');
183
+ yield * uint16LEUnparser(filePathBuffer.length, unparserContext);
184
+ const extraFieldBuffer = Buffer.alloc(0);
185
+ yield * uint16LEUnparser(extraFieldBuffer.length, unparserContext);
186
+ const fileCommentBuffer = Buffer.from(zipEntry.comment, 'utf8');
187
+ yield * uint16LEUnparser(fileCommentBuffer.length, unparserContext);
188
+
189
+ yield * uint16LEUnparser(0, unparserContext); // disk number start
190
+ yield * uint16LEUnparser(0, unparserContext); // internal file attributes
191
+
192
+ if (zipEntry.hostSystem === 'unix') {
193
+ yield * uint32LEUnparser(
194
+ (
195
+ 0
196
+ | (
197
+ zipEntry.type === 'directory'
198
+ ? (0b0100_0000_0000_0000 << 16)
199
+ : (0b1000_0000_0000_0000 << 16)
200
+ )
201
+ ) >>> 0,
202
+ unparserContext,
203
+ );
204
+ } else {
205
+ yield * uint32LEUnparser(
206
+ (
207
+ 0
208
+ | (
209
+ zipEntry.type === 'directory'
210
+ ? 0b0001_0000
211
+ : 0
212
+ )
213
+ ),
214
+ unparserContext,
215
+ );
216
+ }
217
+
218
+ const localHeaderPosition = localHeaderPositionByZipEntry.get(zipEntry)!;
219
+
220
+ yield * uint32LEUnparser(localHeaderPosition, unparserContext);
221
+
222
+ yield filePathBuffer;
223
+ yield extraFieldBuffer;
224
+ yield fileCommentBuffer;
225
+ }
226
+
227
+ const endOfCentralDirectoryPosition = unparserContext.position;
228
+ const sizeOfTheCentralDirectory = endOfCentralDirectoryPosition - startOfCentralDirectoryPosition;
229
+
230
+ yield * zipEndOfCentralDirectoryRecordUnparser({
231
+ numberOfThisDisk: 0,
232
+ numberOfTheDiskWithTheStartOfTheCentralDirectory: 0,
233
+ totalNumberOfEntriesInTheCentralDirectoryOnThisDisk: zip.entries.length,
234
+ totalNumberOfEntriesInTheCentralDirectory: zip.entries.length,
235
+ sizeOfTheCentralDirectory,
236
+ offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber: startOfCentralDirectoryPosition,
237
+ zipFileComment: zip.comment,
238
+ }, unparserContext);
239
+ }
@@ -1,26 +0,0 @@
1
- import { getParserName, Parser } from "./parser.js";
2
- import { ParserParsingFailedError } from "./parserError.js";
3
-
4
- export const createNegativeLookaheadParser = <Sequence>(
5
- childParser: Parser<unknown, Sequence>,
6
- ): Parser<void, Sequence> => {
7
- return async parserContext => {
8
- const childParserContext = parserContext.lookahead();
9
- try {
10
- await childParser(childParserContext);
11
- parserContext.invariant(
12
- false,
13
- 'Negative lookahead assertion failed for child parser %s.',
14
- getParserName(childParser),
15
- );
16
- } catch (error) {
17
- if (error instanceof ParserParsingFailedError) {
18
- return;
19
- }
20
-
21
- throw error;
22
- } finally {
23
- childParserContext.dispose();
24
- }
25
- };
26
- };