unzipper
Version:
Unzip cross-platform streaming API
83 lines (75 loc) • 2.65 kB
JavaScript
var binary = require('binary');
var PullStream = require('../PullStream');
var unzip = require('./unzip');
var Promise = require('bluebird');
var BufferStream = require('../BufferStream');
var signature = Buffer(4);
signature.writeUInt32LE(0x06054b50,0);
module.exports = function centralDirectory(source) {
var endDir = PullStream(),
records = PullStream(),
self = this,
vars;
return source.size()
.then(function(size) {
source.stream(size-40).pipe(endDir);
return endDir.pull(signature);
})
.then(function() {
return endDir.pull(22);
})
.then(function(data) {
vars = binary.parse(data)
.word32lu('signature')
.word16lu('diskNumber')
.word16lu('diskStart')
.word16lu('numberOfRecordsOnDisk')
.word16lu('numberOfRecords')
.word32lu('sizeOfCentralDirectory')
.word32lu('offsetToStartOfCentralDirectory')
.word16lu('commentLength')
.vars;
source.stream(vars.offsetToStartOfCentralDirectory).pipe(records);
vars.files = Promise.mapSeries(Array(vars.numberOfRecords),function() {
return records.pull(46).then(function(data) {
var vars = binary.parse(data)
.word32lu('signature')
.word16lu('versionMadeBy')
.word16lu('versionsNeededToExtract')
.word16lu('flags')
.word16lu('compressionMethod')
.word16lu('lastModifiedTime')
.word16lu('lastModifiedDate')
.word32lu('crc32')
.word32lu('compressedSize')
.word32lu('uncompressedSize')
.word16lu('fileNameLength')
.word16lu('extraFieldLength')
.word16lu('fileCommentLength')
.word16lu('diskNumber')
.word16lu('internalFileAttributes')
.word32lu('externalFileAttributes')
.word32lu('offsetToLocalFileHeader')
.vars;
return records.pull(vars.fileNameLength).then(function(fileName) {
vars.path = fileName.toString('utf8');
return records.pull(vars.extraFieldLength);
})
.then(function(extraField) {
return records.pull(vars.fileCommentLength);
})
.then(function(comment) {
vars.comment = comment;
vars.stream = function(_password) {
return unzip(source, vars.offsetToLocalFileHeader,_password);
};
vars.buffer = function(_password) {
return BufferStream(vars.stream(_password));
};
return vars;
});
});
});
return Promise.props(vars);
});
};