UNPKG

1.8 kBJavaScriptView Raw
1'use strict';
2
3
4var once = require('./lib/common').once;
5var error = require('./lib/common').error;
6var parsers = require('./lib/parsers_stream');
7
8
9function unrecognizedFormat() {
10 return error('unrecognized file format', 'ECONTENT');
11}
12
13
14module.exports = function probeStream(stream, _callback) {
15 var callback = once(function () {
16 // We should postpone callback to allow all piped parsers accept .write().
17 // In other case, if stream is closed from callback that can cause
18 // exceptions like "write after end".
19 var args = Array.prototype.slice.call(arguments);
20
21 process.nextTick(function () {
22 _callback.apply(null, args);
23 });
24 });
25
26 var pStreams = [];
27
28 // prevent "possible EventEmitter memory leak" warnings
29 stream.setMaxListeners(0);
30
31 function cleanup(strm) {
32 var i;
33
34 if (strm) {
35 stream.unpipe(strm);
36 strm.end();
37 i = pStreams.indexOf(strm);
38 if (i >= 0) pStreams.splice(i, 1);
39 return;
40 }
41
42 for (i = 0; i < pStreams.length; i++) {
43 stream.unpipe(pStreams[i]);
44 pStreams[i].end();
45 }
46 pStreams.length = 0;
47 }
48
49 stream.on('error', function (err) { cleanup(); callback(err); });
50
51 Object.keys(parsers).forEach(function (type) {
52 var pStream = parsers[type]();
53
54 pStream.on('data', function (result) {
55 callback(null, result);
56 cleanup();
57 });
58
59 pStream.on('error', function () {
60 // silently ignore errors because user does not need to know
61 // that something wrong is happening here
62 });
63
64 pStream.on('end', function () {
65 cleanup(pStream);
66
67 if (pStreams.length === 0) {
68 cleanup();
69 callback(unrecognizedFormat());
70 }
71 });
72
73 stream.pipe(pStream);
74
75 pStreams.push(pStream);
76 });
77};
78
79
80module.exports.parsers = parsers;