You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
3.4 KiB
JavaScript

'use strict';
const Promise = require("bluebird");
const memoizee = require("memoizee");
const debug = require("debug")("iso9660:object:directory");
const parseDirectoryRecord = require("../parse/directory-record");
module.exports = function(image) {
const createFile = require("./file")(image);
return function createDirectory(directoryRecord, parent) {
debug(`Creating new directory object for ${directoryRecord.identifier.filename}`);
return {
type: "directory",
filename: directoryRecord.identifier.filename,
version: directoryRecord.identifier.version,
parent: parent,
recordingDate: directoryRecord.recordingDate,
getChildren: memoizee(function getChildren() {
return Promise.try(() => {
function getDirectoryContents() {
return Promise.try(() => {
return image.getSectorOffset(directoryRecord.extentLocation);
}).then((sectorOffset) => {
return image.readRange(sectorOffset, sectorOffset + directoryRecord.extentSize - 1);
});
}
return Promise.all([
image.getPrimaryVolumeDescriptor(),
getDirectoryContents()
]);
}).spread((primaryVolumeDescriptor, directoryContents) => {
const roundToNextSector = require("../round-to-next-sector")(primaryVolumeDescriptor.data.sectorSize);
let pos = 0;
let records = [];
while (pos < directoryContents.length) {
let recordLength = directoryContents.readUInt8(pos);
if (recordLength === 0) {
/* We ran out of records for this sector, skip to the next. */
pos = roundToNextSector(pos);
} else {
let directoryRecord = parseDirectoryRecord(directoryContents.slice(pos, pos + recordLength));
records.push(directoryRecord);
pos += recordLength;
}
}
return records.slice(2).map((record) => {
if (record.fileFlags.directory) {
debug(`Found directory: ${record.identifier.filename}`);
return createDirectory(record, this);
} else {
debug(`Found file: ${record.identifier.filename}`);
return createFile(record, this);
}
});
});
}),
getTree: function getTree() {
return Promise.try(() => {
return this.getChildren();
}).map((child) => {
if (child.type === "directory") {
return Promise.try(() => {
return child.getTree();
}).then((tree) => {
return Object.assign({
children: tree
}, child);
});
} else {
return child;
}
});
}
}
}
}