'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; } }); } } } }