ebml.js 4.0.1 → 4.1.0

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.
package/dist/ebml.node.js CHANGED
@@ -23,307 +23,353 @@ module.exports = { debugLog }
23
23
  /***/ 776
24
24
  (module, __unused_webpack_exports, __webpack_require__) {
25
25
 
26
- const { Transform } = __webpack_require__(203);
27
- const tools = __webpack_require__(327);
28
- const schema = __webpack_require__(261);
29
- const { debugLog } = __webpack_require__(224);
30
-
31
- const debug = debugLog('ebml:decoder');
32
-
33
- const STATE_TAG = 1;
34
- const STATE_SIZE = 2;
35
- const STATE_CONTENT = 3;
36
-
37
- class EbmlDecoder extends Transform {
38
- /**
39
- * @property
40
- * @private
41
- * @type {Buffer}
42
- */
43
- mBuffer = null;
44
-
45
- /**
46
- * @private
47
- * @property
48
- * @readonly
49
- */
50
- mTagStack = [];
51
-
52
- /**
53
- * @property
54
- * @private
55
- * @type {Number}
56
- */
57
- mState = STATE_TAG;
58
-
59
- /**
60
- * @property
61
- * @private
62
- * @type {Number}
63
- */
64
- mCursor = 0;
65
-
66
- /**
67
- * @property
68
- * @private
69
- * @type {Number}
70
- */
71
- mTotal = 0;
72
-
73
- /**
74
- * @constructor
75
- * @param {Object} options The options to be passed along to the super class
76
- */
77
- constructor(options = {}) {
78
- super({ ...options, readableObjectMode: true });
79
- }
80
-
81
- get buffer() {
82
- return this.mBuffer;
83
- }
84
-
85
- get cursor() {
86
- return this.mCursor;
87
- }
88
-
89
- get state() {
90
- return this.mState;
91
- }
92
-
93
- get tagStack() {
94
- return this.mTagStack;
95
- }
96
-
97
- get total() {
98
- return this.mTotal;
99
- }
100
-
101
- set buffer(buffer) {
102
- this.mBuffer = buffer;
103
- }
104
-
105
- /**
106
- * @param {number} cursor
107
- */
108
- set cursor(cursor) {
109
- this.mCursor = cursor;
110
- }
111
-
112
- set state(state) {
113
- this.mState = state;
114
- }
115
-
116
- set total(total) {
117
- this.mTotal = total;
118
- }
119
-
120
- _transform(chunk, enc, done) {
121
- if (!this.buffer) {
122
- this.buffer = Buffer.from(chunk);
123
- } else {
124
- this.buffer = tools.concatenate(this.buffer, Buffer.from(chunk));
125
- }
126
-
127
- while (this.cursor < this.buffer.length) {
128
- if (this.state === STATE_TAG && !this.readTag()) {
129
- break;
130
- }
131
- if (this.state === STATE_SIZE && !this.readSize()) {
132
- break;
133
- }
134
- if (this.state === STATE_CONTENT && !this.readContent()) {
135
- break;
136
- }
137
- }
138
-
139
- done();
140
- }
141
-
142
- static getSchemaInfo(tag) {
143
- if (Number.isInteger(tag) && schema.has(tag)) {
144
- return schema.get(tag);
145
- }
146
- const tagStr = `0x${tag.toString(16).toUpperCase()}`
147
- const unknown = {
148
- type: null,
149
- name: `unknown-${tagStr}`,
150
- description: `${tagStr}`,
151
- level: -1,
152
- minver: -1,
153
- multiple: false,
154
- webm: false,
155
- };
156
- schema.set(tag, unknown)
157
- console.warn('[SCHEMA]', 'unknown tag:', tagStr)
158
- return unknown
159
- }
160
-
161
- readTag() {
162
- /* istanbul ignore if */
163
- if (debug.enabled) {
164
- debug('parsing tag');
165
- }
166
-
167
- if (this.cursor >= this.buffer.length) {
168
- /* istanbul ignore if */
169
- if (debug.enabled) {
170
- debug('waiting for more data');
171
- }
172
- return false;
173
- }
174
-
175
- const start = this.total;
176
- const tag = tools.readVint(this.buffer, this.cursor);
177
-
178
- if (tag == null) {
179
- /* istanbul ignore if */
180
- if (debug.enabled) {
181
- debug('waiting for more data');
182
- }
183
-
184
- return false;
185
- }
186
-
187
- const tagStr = tools.readHexString(
188
- this.buffer,
189
- this.cursor,
190
- this.cursor + tag.length,
191
- );
192
- const tagNum = Number.parseInt(tagStr, 16);
193
- this.cursor += tag.length;
194
- this.total += tag.length;
195
- this.state = STATE_SIZE;
196
-
197
- const tagObj = {
198
- tag: tag.value,
199
- tagStr,
200
- type: EbmlDecoder.getSchemaInfo(tagNum).type,
201
- name: EbmlDecoder.getSchemaInfo(tagNum).name,
202
- start,
203
- end: start + tag.length,
204
- };
205
-
206
- this.tagStack.push(tagObj);
207
- /* istanbul ignore if */
208
- if (debug.enabled) {
209
- debug(`read tag: ${tagStr}`);
210
- }
211
-
212
- return true;
213
- }
214
-
215
- readSize() {
216
- const tagObj = this.tagStack[this.tagStack.length - 1];
217
-
218
- /* istanbul ignore if */
219
- if (debug.enabled) {
220
- debug(`parsing size for tag: ${tagObj.tagStr}`);
221
- }
222
-
223
- if (this.cursor >= this.buffer.length) {
224
- /* istanbul ignore if */
225
- if (debug.enabled) {
226
- debug('waiting for more data');
227
- }
228
-
229
- return false;
230
- }
231
-
232
- const size = tools.readVint(this.buffer, this.cursor);
233
-
234
- if (size == null) {
235
- /* istanbul ignore if */
236
- if (debug.enabled) {
237
- debug('waiting for more data');
238
- }
239
-
240
- return false;
241
- }
242
-
243
- this.cursor += size.length;
244
- this.total += size.length;
245
- this.state = STATE_CONTENT;
246
- tagObj.dataSize = size.value;
247
-
248
- // unknown size
249
- if (size.value === -1) {
250
- tagObj.end = -1;
251
- } else {
252
- tagObj.end += size.value + size.length;
253
- }
254
- /* istanbul ignore if */
255
- if (debug.enabled) {
256
- debug(`read size: ${size.value}`);
257
- }
258
-
259
- return true;
260
- }
261
-
262
- readContent() {
263
- const { tagStr, type, dataSize, ...rest } = this.tagStack[this.tagStack.length - 1];
264
-
265
- /* istanbul ignore if */
266
- if (debug.enabled) {
267
- debug(`parsing content for tag: ${tagStr}`);
268
- }
269
-
270
- if (type === 'm') {
271
- /* istanbul ignore if */
272
- if (debug.enabled) {
273
- debug('content should be tags');
274
- }
275
- this.push(['start', { tagStr, type, dataSize, ...rest }]);
276
- this.state = STATE_TAG;
277
-
278
- return true;
279
- }
280
-
281
- if (this.buffer.length < this.cursor + dataSize) {
282
- /* istanbul ignore if */
283
- if (debug.enabled) {
284
- debug(`got: ${this.buffer.length}`);
285
- debug(`need: ${this.cursor + dataSize}`);
286
- debug('waiting for more data');
287
- }
288
-
289
- return false;
290
- }
291
-
292
- const data = this.buffer.subarray(this.cursor, this.cursor + dataSize);
293
- this.total += dataSize;
294
- this.state = STATE_TAG;
295
- this.buffer = this.buffer.subarray(this.cursor + dataSize);
296
- this.cursor = 0;
297
-
298
- this.tagStack.pop(); // remove the object from the stack
299
-
300
- this.push([
301
- 'tag',
302
- tools.readDataFromTag(
303
- { tagStr, type, dataSize, ...rest },
304
- Buffer.from(data),
305
- ),
306
- ]);
307
-
308
- while (this.tagStack.length > 0) {
309
- const topEle = this.tagStack[this.tagStack.length - 1];
310
- if (this.total < topEle.end) {
311
- break;
312
- }
313
- this.push(['end', topEle]);
314
- this.tagStack.pop();
315
- }
316
-
317
- /* istanbul ignore if */
318
- if (debug.enabled) {
319
- debug(`read data: ${data.toString('hex')}`);
320
- }
321
-
322
- return true;
323
- }
324
- }
325
-
326
- module.exports = EbmlDecoder
26
+ const { Transform } = __webpack_require__(203);
27
+ const tools = __webpack_require__(327);
28
+ const schema = __webpack_require__(261);
29
+ const { debugLog } = __webpack_require__(224);
30
+
31
+ const debug = debugLog('ebml:decoder');
32
+
33
+ const STATE_TAG = 1;
34
+ const STATE_SIZE = 2;
35
+ const STATE_CONTENT = 3;
36
+
37
+ class EbmlDecoder extends Transform {
38
+ /**
39
+ * @property
40
+ * @private
41
+ * @type {Buffer}
42
+ */
43
+ mBuffer = null;
44
+
45
+ /**
46
+ * @private
47
+ * @property
48
+ * @readonly
49
+ */
50
+ mTagStack = [];
51
+
52
+ /**
53
+ * @property
54
+ * @private
55
+ * @type {Number}
56
+ */
57
+ mState = STATE_TAG;
58
+
59
+ /**
60
+ * @property
61
+ * @private
62
+ * @type {Number}
63
+ */
64
+ mCursor = 0;
65
+
66
+ /**
67
+ * @property
68
+ * @private
69
+ * @type {Number}
70
+ */
71
+ mTotal = 0;
72
+
73
+ /** @private */
74
+ mIsLive = false
75
+
76
+ /**
77
+ * @constructor
78
+ * @param {{ isLive?: boolean }} options The options to be passed along to the super class
79
+ */
80
+ constructor(options = {}) {
81
+ super({ ...options, readableObjectMode: true });
82
+ this.mIsLive = options ? options.isLive : false
83
+ }
84
+
85
+ get isLive() {
86
+ return this.mIsLive;
87
+ }
88
+
89
+ get buffer() {
90
+ return this.mBuffer;
91
+ }
92
+
93
+ get cursor() {
94
+ return this.mCursor;
95
+ }
96
+
97
+ get state() {
98
+ return this.mState;
99
+ }
100
+
101
+ get tagStack() {
102
+ return this.mTagStack;
103
+ }
104
+
105
+ get total() {
106
+ return this.mTotal;
107
+ }
108
+
109
+ set buffer(buffer) {
110
+ this.mBuffer = buffer;
111
+ }
112
+
113
+ /**
114
+ * @param {number} cursor
115
+ */
116
+ set cursor(cursor) {
117
+ this.mCursor = cursor;
118
+ }
119
+
120
+ set state(state) {
121
+ this.mState = state;
122
+ }
123
+
124
+ set total(total) {
125
+ this.mTotal = total;
126
+ }
127
+
128
+ _transform(chunk, enc, done) {
129
+ if (!this.buffer) {
130
+ this.buffer = Buffer.from(chunk);
131
+ } else {
132
+ this.buffer = tools.concatenate(this.buffer, Buffer.from(chunk));
133
+ }
134
+
135
+ while (this.cursor < this.buffer.length) {
136
+ if (this.state === STATE_TAG && !this.readTag()) {
137
+ break;
138
+ }
139
+ if (this.state === STATE_SIZE && !this.readSize()) {
140
+ break;
141
+ }
142
+ if (this.state === STATE_CONTENT && !this.readContent()) {
143
+ break;
144
+ }
145
+ }
146
+
147
+ done();
148
+ }
149
+
150
+ static getSchemaInfo(tag) {
151
+ if (Number.isInteger(tag) && schema.has(tag)) {
152
+ return schema.get(tag);
153
+ }
154
+ const tagStr = `0x${tag.toString(16).toUpperCase()}`
155
+ const unknown = {
156
+ type: null,
157
+ name: `unknown-${tagStr}`,
158
+ description: `${tagStr}`,
159
+ level: -1,
160
+ minver: -1,
161
+ multiple: false,
162
+ webm: false,
163
+ };
164
+ schema.set(tag, unknown)
165
+ console.warn('[SCHEMA]', 'unknown tag:', tagStr)
166
+ return unknown
167
+ }
168
+
169
+ readTag() {
170
+ /* istanbul ignore if */
171
+ if (debug.enabled) {
172
+ debug('parsing tag');
173
+ }
174
+
175
+ if (this.cursor >= this.buffer.length) {
176
+ /* istanbul ignore if */
177
+ if (debug.enabled) {
178
+ debug('waiting for more data');
179
+ }
180
+ return false;
181
+ }
182
+
183
+ if (this.isLive && !this.findTagStart()) {
184
+ return false
185
+ }
186
+
187
+ const start = this.total;
188
+ const tag = tools.readVint(this.buffer, this.cursor);
189
+
190
+ if (tag == null) {
191
+ /* istanbul ignore if */
192
+ if (debug.enabled) {
193
+ debug('waiting for more data');
194
+ }
195
+
196
+ return false;
197
+ }
198
+
199
+ const tagStr = tools.readHexString(
200
+ this.buffer,
201
+ this.cursor,
202
+ this.cursor + tag.length,
203
+ );
204
+ const tagNum = Number.parseInt(tagStr, 16);
205
+ this.cursor += tag.length;
206
+ this.total += tag.length;
207
+ this.state = STATE_SIZE;
208
+
209
+ const tagObj = {
210
+ tag: tag.value,
211
+ tagStr,
212
+ type: EbmlDecoder.getSchemaInfo(tagNum).type,
213
+ name: EbmlDecoder.getSchemaInfo(tagNum).name,
214
+ start,
215
+ end: start + tag.length,
216
+ };
217
+
218
+ this.tagStack.push(tagObj);
219
+ /* istanbul ignore if */
220
+ if (debug.enabled) {
221
+ debug(`read tag: ${tagStr}`);
222
+ }
223
+
224
+ return true;
225
+ }
226
+
227
+ /** @private */
228
+ findTagStart() {
229
+ while (this.cursor < this.buffer.length) {
230
+ try {
231
+ const tag = tools.readVint(this.buffer, this.cursor);
232
+ if (tag == null) {
233
+ return false
234
+ }
235
+ const tagStr = tools.readHexString(
236
+ this.buffer,
237
+ this.cursor,
238
+ this.cursor + tag.length,
239
+ );
240
+ const tagNum = Number.parseInt(tagStr, 16);
241
+ const tagName = EbmlDecoder.getSchemaInfo(tagNum).name
242
+ if (tagName && tagName.startsWith('unknown')) {
243
+ this.cursor += 1
244
+ continue
245
+ }
246
+ if (this.cursor > 0 && !this.total) {
247
+ this.buffer = this.buffer.subarray(this.cursor)
248
+ this.cursor = 0
249
+ }
250
+ return true
251
+ } catch (e) {
252
+ if (!e.message.startsWith('Unrepresentable length')) {
253
+ throw e
254
+ }
255
+ this.cursor += 1
256
+ }
257
+ }
258
+ return false
259
+ }
260
+
261
+ readSize() {
262
+ const tagObj = this.tagStack[this.tagStack.length - 1];
263
+
264
+ /* istanbul ignore if */
265
+ if (debug.enabled) {
266
+ debug(`parsing size for tag: ${tagObj.tagStr}`);
267
+ }
268
+
269
+ if (this.cursor >= this.buffer.length) {
270
+ /* istanbul ignore if */
271
+ if (debug.enabled) {
272
+ debug('waiting for more data');
273
+ }
274
+
275
+ return false;
276
+ }
277
+
278
+ const size = tools.readVint(this.buffer, this.cursor);
279
+
280
+ if (size == null) {
281
+ /* istanbul ignore if */
282
+ if (debug.enabled) {
283
+ debug('waiting for more data');
284
+ }
285
+
286
+ return false;
287
+ }
288
+
289
+ this.cursor += size.length;
290
+ this.total += size.length;
291
+ this.state = STATE_CONTENT;
292
+ tagObj.dataSize = size.value;
293
+
294
+ // unknown size
295
+ if (size.value === -1) {
296
+ tagObj.end = -1;
297
+ } else {
298
+ tagObj.end += size.value + size.length;
299
+ }
300
+ /* istanbul ignore if */
301
+ if (debug.enabled) {
302
+ debug(`read size: ${size.value}`);
303
+ }
304
+
305
+ return true;
306
+ }
307
+
308
+ readContent() {
309
+ const { tagStr, type, dataSize, ...rest } = this.tagStack[this.tagStack.length - 1];
310
+
311
+ /* istanbul ignore if */
312
+ if (debug.enabled) {
313
+ debug(`parsing content for tag: ${tagStr}`);
314
+ }
315
+
316
+ if (type === 'm') {
317
+ /* istanbul ignore if */
318
+ if (debug.enabled) {
319
+ debug('content should be tags');
320
+ }
321
+ this.push(['start', { tagStr, type, dataSize, ...rest }]);
322
+ this.state = STATE_TAG;
323
+
324
+ return true;
325
+ }
326
+
327
+ if (this.buffer.length < this.cursor + dataSize) {
328
+ /* istanbul ignore if */
329
+ if (debug.enabled) {
330
+ debug(`got: ${this.buffer.length}`);
331
+ debug(`need: ${this.cursor + dataSize}`);
332
+ debug('waiting for more data');
333
+ }
334
+
335
+ return false;
336
+ }
337
+
338
+ const data = this.buffer.subarray(this.cursor, this.cursor + dataSize);
339
+ this.total += dataSize;
340
+ this.state = STATE_TAG;
341
+ this.buffer = this.buffer.subarray(this.cursor + dataSize);
342
+ this.cursor = 0;
343
+
344
+ this.tagStack.pop(); // remove the object from the stack
345
+
346
+ this.push([
347
+ 'tag',
348
+ tools.readDataFromTag(
349
+ { tagStr, type, dataSize, ...rest },
350
+ Buffer.from(data),
351
+ ),
352
+ ]);
353
+
354
+ while (this.tagStack.length > 0) {
355
+ const topEle = this.tagStack[this.tagStack.length - 1];
356
+ if (this.total < topEle.end) {
357
+ break;
358
+ }
359
+ this.push(['end', topEle]);
360
+ this.tagStack.pop();
361
+ }
362
+
363
+ /* istanbul ignore if */
364
+ if (debug.enabled) {
365
+ debug(`read data: ${data.toString('hex')}`);
366
+ }
367
+
368
+ return true;
369
+ }
370
+ }
371
+
372
+ module.exports = EbmlDecoder
327
373
 
328
374
 
329
375
  /***/ },