-
Notifications
You must be signed in to change notification settings - Fork 1
/
protobufStreamParser.js
49 lines (41 loc) · 1.56 KB
/
protobufStreamParser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const fs = require('fs');
const path = require('path');
const through2 = require('through2')
const Protobuf = require("node-protobuf")
const varint = require('varint');
const baseMessageTypes = require('./baseMessageTypes')
const keynoteMessageTypes = require('./keynoteMessageTypes')
module.exports = () => {
const pb = new Protobuf(fs.readFileSync(path.join(__dirname, 'types.desc')))
return through2.obj(function (chunk, enc, cb) {
let cursor = 0;
while(cursor < chunk.length) {
const archiveInfoLength = varint.decode(chunk.slice(cursor));
cursor += varint.decode.bytes; //consumed x for length
// Get Archive Info
const archiveInfoBlob = chunk.slice(cursor, archiveInfoLength + cursor)
cursor += archiveInfoLength; // consumed archiveInfo
const archiveInfo = pb.parse(archiveInfoBlob, "ArchiveInfo");
let messages = []
archiveInfo.message_infos.forEach(messageInfo => {
const payloadBlob = chunk.slice(cursor, messageInfo.length + cursor)
cursor += messageInfo.length; // consumed payload
const type = keynoteMessageTypes[messageInfo.type] || baseMessageTypes[messageInfo.type];
if(payloadBlob.length < messageInfo.length) {
cb(new Error('IWA file truncated before reading last protobuf MessageInfo payload'))
} else {
messages.push({
messageInfo,
type,
payload: type && pb.parse(payloadBlob, type)
})
}
})
this.push({
archiveInfo,
messages
});
}
cb()
})
}