'use strict'; const Promise = require("bluebird"); const streamToPromise = require("stream-to-promise"); const memoizee = require("memoizee"); const promiseWhile = require("promise-while-loop"); const parsePathTable = require("./parse/path-table"); const deeplyUnique = require("../deeply-unique"); const readVolumeDescriptors = require("./read/volume-descriptors"); const readPathTable = require("./read/path-table"); let imageOffset = 32 * 1024; // first 32KB are system area, ref http://wiki.osdev.org/ISO_9660#System_Area module.exports = function createImage(seekable) { let image = { createReadStream: function createReadStream(start, end) { return Promise.try(() => { return seekable.createReadStream(start, end); }); }, readRange: function readRange(start, end) { return Promise.try(() => { return this.createReadStream(start, end); }).then((stream) => { return streamToPromise(stream); }); }, readSectors: function readSectors(firstSector, sectorCount) { return Promise.try(() => { return this.getSectorSize(); }).then((sectorSize) => { return this.readRange(firstSector * sectorSize, (firstSector + sectorCount) * sectorSize - 1); }); }, getVolumeDescriptors: memoizee(function getVolumeDescriptors() { return readVolumeDescriptors(this); }), getUniqueVolumeDescriptors: function getUniqueVolumeDescriptors() { return Promise.try(() => { return this.getVolumeDescriptors(); }).then((descriptors) => { return deeplyUnique(descriptors); }); }, getPrimaryVolumeDescriptor: function getPrimaryVolumeDescriptor() { return Promise.try(() => { return this.getVolumeDescriptors(); }).then((descriptors) => { let primaryVolumeDescriptor = descriptors.find((descriptor) => descriptor.type === "primary"); if (primaryVolumeDescriptor != null) { return primaryVolumeDescriptor; } else { throw new Error("No primary volume descriptor could be found"); } }) }, getSectorSize: function getSectorSize() { return Promise.try(() => { return this.getPrimaryVolumeDescriptor(); }).then((primaryVolumeDescriptor) => { return primaryVolumeDescriptor.data.sectorSize; }); }, getSectorOffset: function getSectorOffset(sector) { // FIXME: Remove? return Promise.try(() => { return this.getSectorSize(); }).then((sectorSize) => { return sectorSize * sector; }); }, getPathTable: function getPathTable() { return readPathTable(this); }, getRootDirectory: memoizee(function getRootDirectory(volumeIndex) { return Promise.try(() => { if (volumeIndex == null) { return this.getPrimaryVolumeDescriptor(); } else { return Promise.try(() => { return this.getVolumeDescriptors(); }).then((descriptors) => { if (descriptors[volumeIndex] == null) { throw new Error("No volume descriptor with that ID exists"); } else { return descriptors[volumeIndex]; } }); } }).then((volumeDescriptor) => { return createDirectory(volumeDescriptor.data.rootDirectory); }); }) } const createDirectory = require("./object/directory")(image); return image; }