@codesandbox/sandpack-client
Version:
<img style="width:100%" src="https://user-images.githubusercontent.com/4838076/143581035-ebee5ba2-9cb1-4fe8-a05b-2f44bd69bb4b.gif" alt="Component toolkit for live running code editing experiences" />
1,331 lines • 47.7 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var api_error_1 = require("../core/api_error");
var node_fs_stats_1 = require("../core/node_fs_stats");
var file_system_1 = require("../core/file_system");
var file_flag_1 = require("../core/file_flag");
var preload_file_1 = require("../generic/preload_file");
var util_1 = require("../core/util");
var path = require("path");
/**
* @hidden
*/
var rockRidgeIdentifier = "IEEE_P1282";
/**
* @hidden
*/
function getASCIIString(data, startIndex, length) {
return data.toString('ascii', startIndex, startIndex + length).trim();
}
/**
* @hidden
*/
function getJolietString(data, startIndex, length) {
if (length === 1) {
// Special: Root, parent, current directory are still a single byte.
return String.fromCharCode(data[startIndex]);
}
// UTF16-BE, which isn't natively supported by NodeJS Buffers.
// Length should be even, but pessimistically floor just in case.
var pairs = Math.floor(length / 2);
var chars = new Array(pairs);
for (var i = 0; i < pairs; i++) {
var pos = startIndex + (i << 1);
chars[i] = String.fromCharCode(data[pos + 1] | (data[pos] << 8));
}
return chars.join('');
}
/**
* @hidden
*/
function getDate(data, startIndex) {
var year = parseInt(getASCIIString(data, startIndex, 4), 10);
var mon = parseInt(getASCIIString(data, startIndex + 4, 2), 10);
var day = parseInt(getASCIIString(data, startIndex + 6, 2), 10);
var hour = parseInt(getASCIIString(data, startIndex + 8, 2), 10);
var min = parseInt(getASCIIString(data, startIndex + 10, 2), 10);
var sec = parseInt(getASCIIString(data, startIndex + 12, 2), 10);
var hundrethsSec = parseInt(getASCIIString(data, startIndex + 14, 2), 10);
// Last is a time-zone offset, but JavaScript dates don't support time zones well.
return new Date(year, mon, day, hour, min, sec, hundrethsSec * 100);
}
/**
* @hidden
*/
function getShortFormDate(data, startIndex) {
var yearsSince1900 = data[startIndex];
var month = data[startIndex + 1];
var day = data[startIndex + 2];
var hour = data[startIndex + 3];
var minute = data[startIndex + 4];
var second = data[startIndex + 5];
// JavaScript's Date support isn't so great; ignore timezone.
// const offsetFromGMT = this._data[24];
return new Date(yearsSince1900, month - 1, day, hour, minute, second);
}
/**
* @hidden
*/
function constructSystemUseEntry(bigData, i) {
var data = bigData.slice(i);
var sue = new SystemUseEntry(data);
switch (sue.signatureWord()) {
case 17221 /* SystemUseEntrySignatures.CE */:
return new CEEntry(data);
case 20548 /* SystemUseEntrySignatures.PD */:
return new PDEntry(data);
case 21328 /* SystemUseEntrySignatures.SP */:
return new SPEntry(data);
case 21332 /* SystemUseEntrySignatures.ST */:
return new STEntry(data);
case 17746 /* SystemUseEntrySignatures.ER */:
return new EREntry(data);
case 17747 /* SystemUseEntrySignatures.ES */:
return new ESEntry(data);
case 20568 /* SystemUseEntrySignatures.PX */:
return new PXEntry(data);
case 20558 /* SystemUseEntrySignatures.PN */:
return new PNEntry(data);
case 21324 /* SystemUseEntrySignatures.SL */:
return new SLEntry(data);
case 20045 /* SystemUseEntrySignatures.NM */:
return new NMEntry(data);
case 17228 /* SystemUseEntrySignatures.CL */:
return new CLEntry(data);
case 20556 /* SystemUseEntrySignatures.PL */:
return new PLEntry(data);
case 21061 /* SystemUseEntrySignatures.RE */:
return new REEntry(data);
case 21574 /* SystemUseEntrySignatures.TF */:
return new TFEntry(data);
case 21318 /* SystemUseEntrySignatures.SF */:
return new SFEntry(data);
case 21074 /* SystemUseEntrySignatures.RR */:
return new RREntry(data);
default:
return sue;
}
}
/**
* @hidden
*/
function constructSystemUseEntries(data, i, len, isoData) {
// If the remaining allocated space following the last recorded System Use Entry in a System
// Use field or Continuation Area is less than four bytes long, it cannot contain a System
// Use Entry and shall be ignored
len = len - 4;
var entries = new Array();
while (i < len) {
var entry = constructSystemUseEntry(data, i);
var length_1 = entry.length();
if (length_1 === 0) {
// Invalid SU section; prevent infinite loop.
return entries;
}
i += length_1;
if (entry instanceof STEntry) {
// ST indicates the end of entries.
break;
}
if (entry instanceof CEEntry) {
entries = entries.concat(entry.getEntries(isoData));
}
else {
entries.push(entry);
}
}
return entries;
}
/**
* @hidden
*/
var VolumeDescriptor = /** @class */ (function () {
function VolumeDescriptor(data) {
this._data = data;
}
VolumeDescriptor.prototype.type = function () {
return this._data[0];
};
VolumeDescriptor.prototype.standardIdentifier = function () {
return getASCIIString(this._data, 1, 5);
};
VolumeDescriptor.prototype.version = function () {
return this._data[6];
};
VolumeDescriptor.prototype.data = function () {
return this._data.slice(7, 2048);
};
return VolumeDescriptor;
}());
/**
* @hidden
*/
var PrimaryOrSupplementaryVolumeDescriptor = /** @class */ (function (_super) {
__extends(PrimaryOrSupplementaryVolumeDescriptor, _super);
function PrimaryOrSupplementaryVolumeDescriptor(data) {
var _this = _super.call(this, data) || this;
_this._root = null;
return _this;
}
PrimaryOrSupplementaryVolumeDescriptor.prototype.systemIdentifier = function () {
return this._getString32(8);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeIdentifier = function () {
return this._getString32(40);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSpaceSize = function () {
return this._data.readUInt32LE(80);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSetSize = function () {
return this._data.readUInt16LE(120);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSequenceNumber = function () {
return this._data.readUInt16LE(124);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.logicalBlockSize = function () {
return this._data.readUInt16LE(128);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.pathTableSize = function () {
return this._data.readUInt32LE(132);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfTypeLPathTable = function () {
return this._data.readUInt32LE(140);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfOptionalTypeLPathTable = function () {
return this._data.readUInt32LE(144);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfTypeMPathTable = function () {
return this._data.readUInt32BE(148);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfOptionalTypeMPathTable = function () {
return this._data.readUInt32BE(152);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.rootDirectoryEntry = function (isoData) {
if (this._root === null) {
this._root = this._constructRootDirectoryRecord(this._data.slice(156));
this._root.rootCheckForRockRidge(isoData);
}
return this._root;
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSetIdentifier = function () {
return this._getString(190, 128);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.publisherIdentifier = function () {
return this._getString(318, 128);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.dataPreparerIdentifier = function () {
return this._getString(446, 128);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.applicationIdentifier = function () {
return this._getString(574, 128);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.copyrightFileIdentifier = function () {
return this._getString(702, 38);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.abstractFileIdentifier = function () {
return this._getString(740, 36);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.bibliographicFileIdentifier = function () {
return this._getString(776, 37);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeCreationDate = function () {
return getDate(this._data, 813);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeModificationDate = function () {
return getDate(this._data, 830);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeExpirationDate = function () {
return getDate(this._data, 847);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeEffectiveDate = function () {
return getDate(this._data, 864);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.fileStructureVersion = function () {
return this._data[881];
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.applicationUsed = function () {
return this._data.slice(883, 883 + 512);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype.reserved = function () {
return this._data.slice(1395, 1395 + 653);
};
PrimaryOrSupplementaryVolumeDescriptor.prototype._getString32 = function (idx) {
return this._getString(idx, 32);
};
return PrimaryOrSupplementaryVolumeDescriptor;
}(VolumeDescriptor));
/**
* @hidden
*/
var PrimaryVolumeDescriptor = /** @class */ (function (_super) {
__extends(PrimaryVolumeDescriptor, _super);
function PrimaryVolumeDescriptor(data) {
var _this = _super.call(this, data) || this;
if (_this.type() !== 1 /* VolumeDescriptorTypeCode.PrimaryVolumeDescriptor */) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Invalid primary volume descriptor.");
}
return _this;
}
PrimaryVolumeDescriptor.prototype.name = function () {
return "ISO9660";
};
PrimaryVolumeDescriptor.prototype._constructRootDirectoryRecord = function (data) {
return new ISODirectoryRecord(data, -1);
};
PrimaryVolumeDescriptor.prototype._getString = function (idx, len) {
return this._getString(idx, len);
};
return PrimaryVolumeDescriptor;
}(PrimaryOrSupplementaryVolumeDescriptor));
/**
* @hidden
*/
var SupplementaryVolumeDescriptor = /** @class */ (function (_super) {
__extends(SupplementaryVolumeDescriptor, _super);
function SupplementaryVolumeDescriptor(data) {
var _this = _super.call(this, data) || this;
if (_this.type() !== 2 /* VolumeDescriptorTypeCode.SupplementaryVolumeDescriptor */) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Invalid supplementary volume descriptor.");
}
var escapeSequence = _this.escapeSequence();
var third = escapeSequence[2];
// Third character identifies what 'level' of the UCS specification to follow.
// We ignore it.
if (escapeSequence[0] !== 0x25 || escapeSequence[1] !== 0x2F ||
(third !== 0x40 && third !== 0x43 && third !== 0x45)) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Unrecognized escape sequence for SupplementaryVolumeDescriptor: ".concat(escapeSequence.toString()));
}
return _this;
}
SupplementaryVolumeDescriptor.prototype.name = function () {
return "Joliet";
};
SupplementaryVolumeDescriptor.prototype.escapeSequence = function () {
return this._data.slice(88, 120);
};
SupplementaryVolumeDescriptor.prototype._constructRootDirectoryRecord = function (data) {
return new JolietDirectoryRecord(data, -1);
};
SupplementaryVolumeDescriptor.prototype._getString = function (idx, len) {
return getJolietString(this._data, idx, len);
};
return SupplementaryVolumeDescriptor;
}(PrimaryOrSupplementaryVolumeDescriptor));
/**
* @hidden
*/
var DirectoryRecord = /** @class */ (function () {
function DirectoryRecord(data, rockRidgeOffset) {
this._suEntries = null;
this._fileOrDir = null;
this._data = data;
this._rockRidgeOffset = rockRidgeOffset;
}
DirectoryRecord.prototype.hasRockRidge = function () {
return this._rockRidgeOffset > -1;
};
DirectoryRecord.prototype.getRockRidgeOffset = function () {
return this._rockRidgeOffset;
};
/**
* !!ONLY VALID ON ROOT NODE!!
* Checks if Rock Ridge is enabled, and sets the offset.
*/
DirectoryRecord.prototype.rootCheckForRockRidge = function (isoData) {
var dir = this.getDirectory(isoData);
this._rockRidgeOffset = dir.getDotEntry(isoData)._getRockRidgeOffset(isoData);
if (this._rockRidgeOffset > -1) {
// Wipe out directory. Start over with RR knowledge.
this._fileOrDir = null;
}
};
DirectoryRecord.prototype.length = function () {
return this._data[0];
};
DirectoryRecord.prototype.extendedAttributeRecordLength = function () {
return this._data[1];
};
DirectoryRecord.prototype.lba = function () {
return this._data.readUInt32LE(2) * 2048;
};
DirectoryRecord.prototype.dataLength = function () {
return this._data.readUInt32LE(10);
};
DirectoryRecord.prototype.recordingDate = function () {
return getShortFormDate(this._data, 18);
};
DirectoryRecord.prototype.fileFlags = function () {
return this._data[25];
};
DirectoryRecord.prototype.fileUnitSize = function () {
return this._data[26];
};
DirectoryRecord.prototype.interleaveGapSize = function () {
return this._data[27];
};
DirectoryRecord.prototype.volumeSequenceNumber = function () {
return this._data.readUInt16LE(28);
};
DirectoryRecord.prototype.identifier = function () {
return this._getString(33, this._data[32]);
};
DirectoryRecord.prototype.fileName = function (isoData) {
if (this.hasRockRidge()) {
var fn = this._rockRidgeFilename(isoData);
if (fn !== null) {
return fn;
}
}
var ident = this.identifier();
if (this.isDirectory(isoData)) {
return ident;
}
// Files:
// - MUST have 0x2E (.) separating the name from the extension
// - MUST have 0x3B (;) separating the file name and extension from the version
// Gets expanded to two-byte char in Unicode directory records.
var versionSeparator = ident.indexOf(';');
if (versionSeparator === -1) {
// Some Joliet filenames lack the version separator, despite the standard
// specifying that it should be there.
return ident;
}
else if (ident[versionSeparator - 1] === '.') {
// Empty extension. Do not include '.' in the filename.
return ident.slice(0, versionSeparator - 1);
}
else {
// Include up to version separator.
return ident.slice(0, versionSeparator);
}
};
DirectoryRecord.prototype.isDirectory = function (isoData) {
var rv = Boolean(this.fileFlags() && 2 /* FileFlags.Directory */);
// If it lacks the Directory flag, it may still be a directory if we've exceeded the directory
// depth limit. Rock Ridge marks these as files and adds a special attribute.
if (!rv && this.hasRockRidge()) {
rv = this.getSUEntries(isoData).filter(function (e) { return e instanceof CLEntry; }).length > 0;
}
return rv;
};
DirectoryRecord.prototype.isSymlink = function (isoData) {
return this.hasRockRidge() && this.getSUEntries(isoData).filter(function (e) { return e instanceof SLEntry; }).length > 0;
};
DirectoryRecord.prototype.getSymlinkPath = function (isoData) {
var p = "";
var entries = this.getSUEntries(isoData);
var getStr = this._getGetString();
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
var entry = entries_1[_i];
if (entry instanceof SLEntry) {
var components = entry.componentRecords();
for (var _a = 0, components_1 = components; _a < components_1.length; _a++) {
var component = components_1[_a];
var flags = component.flags();
if (flags & 2 /* SLComponentFlags.CURRENT */) {
p += "./";
}
else if (flags & 4 /* SLComponentFlags.PARENT */) {
p += "../";
}
else if (flags & 8 /* SLComponentFlags.ROOT */) {
p += "/";
}
else {
p += component.content(getStr);
if (!(flags & 1 /* SLComponentFlags.CONTINUE */)) {
p += '/';
}
}
}
if (!entry.continueFlag()) {
// We are done with this link.
break;
}
}
}
if (p.length > 1 && p[p.length - 1] === '/') {
// Trim trailing '/'.
return p.slice(0, p.length - 1);
}
else {
return p;
}
};
DirectoryRecord.prototype.getFile = function (isoData) {
if (this.isDirectory(isoData)) {
throw new Error("Tried to get a File from a directory.");
}
if (this._fileOrDir === null) {
this._fileOrDir = isoData.slice(this.lba(), this.lba() + this.dataLength());
}
return this._fileOrDir;
};
DirectoryRecord.prototype.getDirectory = function (isoData) {
if (!this.isDirectory(isoData)) {
throw new Error("Tried to get a Directory from a file.");
}
if (this._fileOrDir === null) {
this._fileOrDir = this._constructDirectory(isoData);
}
return this._fileOrDir;
};
DirectoryRecord.prototype.getSUEntries = function (isoData) {
if (!this._suEntries) {
this._constructSUEntries(isoData);
}
return this._suEntries;
};
DirectoryRecord.prototype._rockRidgeFilename = function (isoData) {
var nmEntries = this.getSUEntries(isoData).filter(function (e) { return e instanceof NMEntry; });
if (nmEntries.length === 0 || nmEntries[0].flags() & (2 /* NMFlags.CURRENT */ | 4 /* NMFlags.PARENT */)) {
return null;
}
var str = '';
var getString = this._getGetString();
for (var _i = 0, nmEntries_1 = nmEntries; _i < nmEntries_1.length; _i++) {
var e = nmEntries_1[_i];
str += e.name(getString);
if (!(e.flags() & 1 /* NMFlags.CONTINUE */)) {
break;
}
}
return str;
};
DirectoryRecord.prototype._constructSUEntries = function (isoData) {
var i = 33 + this._data[32];
if (i % 2 === 1) {
// Skip padding field.
i++;
}
i += this._rockRidgeOffset;
this._suEntries = constructSystemUseEntries(this._data, i, this.length(), isoData);
};
/**
* !!ONLY VALID ON FIRST ENTRY OF ROOT DIRECTORY!!
* Returns -1 if rock ridge is not enabled. Otherwise, returns the offset
* at which system use fields begin.
*/
DirectoryRecord.prototype._getRockRidgeOffset = function (isoData) {
// In the worst case, we get some garbage SU entries.
// Fudge offset to 0 before proceeding.
this._rockRidgeOffset = 0;
var suEntries = this.getSUEntries(isoData);
if (suEntries.length > 0) {
var spEntry = suEntries[0];
if (spEntry instanceof SPEntry && spEntry.checkBytesPass()) {
// SUSP is in use.
for (var i = 1; i < suEntries.length; i++) {
var entry = suEntries[i];
if (entry instanceof RREntry || (entry instanceof EREntry && entry.extensionIdentifier() === rockRidgeIdentifier)) {
// Rock Ridge is in use!
return spEntry.bytesSkipped();
}
}
}
}
// Failed.
this._rockRidgeOffset = -1;
return -1;
};
return DirectoryRecord;
}());
/**
* @hidden
*/
var ISODirectoryRecord = /** @class */ (function (_super) {
__extends(ISODirectoryRecord, _super);
function ISODirectoryRecord(data, rockRidgeOffset) {
return _super.call(this, data, rockRidgeOffset) || this;
}
ISODirectoryRecord.prototype._getString = function (i, len) {
return getASCIIString(this._data, i, len);
};
ISODirectoryRecord.prototype._constructDirectory = function (isoData) {
return new ISODirectory(this, isoData);
};
ISODirectoryRecord.prototype._getGetString = function () {
return getASCIIString;
};
return ISODirectoryRecord;
}(DirectoryRecord));
/**
* @hidden
*/
var JolietDirectoryRecord = /** @class */ (function (_super) {
__extends(JolietDirectoryRecord, _super);
function JolietDirectoryRecord(data, rockRidgeOffset) {
return _super.call(this, data, rockRidgeOffset) || this;
}
JolietDirectoryRecord.prototype._getString = function (i, len) {
return getJolietString(this._data, i, len);
};
JolietDirectoryRecord.prototype._constructDirectory = function (isoData) {
return new JolietDirectory(this, isoData);
};
JolietDirectoryRecord.prototype._getGetString = function () {
return getJolietString;
};
return JolietDirectoryRecord;
}(DirectoryRecord));
/**
* @hidden
*/
var SystemUseEntry = /** @class */ (function () {
function SystemUseEntry(data) {
this._data = data;
}
SystemUseEntry.prototype.signatureWord = function () {
return this._data.readUInt16BE(0);
};
SystemUseEntry.prototype.signatureWordString = function () {
return getASCIIString(this._data, 0, 2);
};
SystemUseEntry.prototype.length = function () {
return this._data[2];
};
SystemUseEntry.prototype.suVersion = function () {
return this._data[3];
};
return SystemUseEntry;
}());
/**
* Continuation entry.
* @hidden
*/
var CEEntry = /** @class */ (function (_super) {
__extends(CEEntry, _super);
function CEEntry(data) {
var _this = _super.call(this, data) || this;
_this._entries = null;
return _this;
}
/**
* Logical block address of the continuation area.
*/
CEEntry.prototype.continuationLba = function () {
return this._data.readUInt32LE(4);
};
/**
* Offset into the logical block.
*/
CEEntry.prototype.continuationLbaOffset = function () {
return this._data.readUInt32LE(12);
};
/**
* Length of the continuation area.
*/
CEEntry.prototype.continuationLength = function () {
return this._data.readUInt32LE(20);
};
CEEntry.prototype.getEntries = function (isoData) {
if (!this._entries) {
var start = this.continuationLba() * 2048 + this.continuationLbaOffset();
this._entries = constructSystemUseEntries(isoData, start, this.continuationLength(), isoData);
}
return this._entries;
};
return CEEntry;
}(SystemUseEntry));
/**
* Padding entry.
* @hidden
*/
var PDEntry = /** @class */ (function (_super) {
__extends(PDEntry, _super);
function PDEntry(data) {
return _super.call(this, data) || this;
}
return PDEntry;
}(SystemUseEntry));
/**
* Identifies that SUSP is in-use.
* @hidden
*/
var SPEntry = /** @class */ (function (_super) {
__extends(SPEntry, _super);
function SPEntry(data) {
return _super.call(this, data) || this;
}
SPEntry.prototype.checkBytesPass = function () {
return this._data[4] === 0xBE && this._data[5] === 0xEF;
};
SPEntry.prototype.bytesSkipped = function () {
return this._data[6];
};
return SPEntry;
}(SystemUseEntry));
/**
* Identifies the end of the SUSP entries.
* @hidden
*/
var STEntry = /** @class */ (function (_super) {
__extends(STEntry, _super);
function STEntry(data) {
return _super.call(this, data) || this;
}
return STEntry;
}(SystemUseEntry));
/**
* Specifies system-specific extensions to SUSP.
* @hidden
*/
var EREntry = /** @class */ (function (_super) {
__extends(EREntry, _super);
function EREntry(data) {
return _super.call(this, data) || this;
}
EREntry.prototype.identifierLength = function () {
return this._data[4];
};
EREntry.prototype.descriptorLength = function () {
return this._data[5];
};
EREntry.prototype.sourceLength = function () {
return this._data[6];
};
EREntry.prototype.extensionVersion = function () {
return this._data[7];
};
EREntry.prototype.extensionIdentifier = function () {
return getASCIIString(this._data, 8, this.identifierLength());
};
EREntry.prototype.extensionDescriptor = function () {
return getASCIIString(this._data, 8 + this.identifierLength(), this.descriptorLength());
};
EREntry.prototype.extensionSource = function () {
return getASCIIString(this._data, 8 + this.identifierLength() + this.descriptorLength(), this.sourceLength());
};
return EREntry;
}(SystemUseEntry));
/**
* @hidden
*/
var ESEntry = /** @class */ (function (_super) {
__extends(ESEntry, _super);
function ESEntry(data) {
return _super.call(this, data) || this;
}
ESEntry.prototype.extensionSequence = function () {
return this._data[4];
};
return ESEntry;
}(SystemUseEntry));
/**
* RockRidge: Marks that RockRidge is in use [deprecated]
* @hidden
*/
var RREntry = /** @class */ (function (_super) {
__extends(RREntry, _super);
function RREntry(data) {
return _super.call(this, data) || this;
}
return RREntry;
}(SystemUseEntry));
/**
* RockRidge: Records POSIX file attributes.
* @hidden
*/
var PXEntry = /** @class */ (function (_super) {
__extends(PXEntry, _super);
function PXEntry(data) {
return _super.call(this, data) || this;
}
PXEntry.prototype.mode = function () {
return this._data.readUInt32LE(4);
};
PXEntry.prototype.fileLinks = function () {
return this._data.readUInt32LE(12);
};
PXEntry.prototype.uid = function () {
return this._data.readUInt32LE(20);
};
PXEntry.prototype.gid = function () {
return this._data.readUInt32LE(28);
};
PXEntry.prototype.inode = function () {
return this._data.readUInt32LE(36);
};
return PXEntry;
}(SystemUseEntry));
/**
* RockRidge: Records POSIX device number.
* @hidden
*/
var PNEntry = /** @class */ (function (_super) {
__extends(PNEntry, _super);
function PNEntry(data) {
return _super.call(this, data) || this;
}
PNEntry.prototype.devTHigh = function () {
return this._data.readUInt32LE(4);
};
PNEntry.prototype.devTLow = function () {
return this._data.readUInt32LE(12);
};
return PNEntry;
}(SystemUseEntry));
/**
* RockRidge: Records symbolic link
* @hidden
*/
var SLEntry = /** @class */ (function (_super) {
__extends(SLEntry, _super);
function SLEntry(data) {
return _super.call(this, data) || this;
}
SLEntry.prototype.flags = function () {
return this._data[4];
};
SLEntry.prototype.continueFlag = function () {
return this.flags() & 0x1;
};
SLEntry.prototype.componentRecords = function () {
var records = new Array();
var i = 5;
while (i < this.length()) {
var record = new SLComponentRecord(this._data.slice(i));
records.push(record);
i += record.length();
}
return records;
};
return SLEntry;
}(SystemUseEntry));
/**
* @hidden
*/
var SLComponentRecord = /** @class */ (function () {
function SLComponentRecord(data) {
this._data = data;
}
SLComponentRecord.prototype.flags = function () {
return this._data[0];
};
SLComponentRecord.prototype.length = function () {
return 2 + this.componentLength();
};
SLComponentRecord.prototype.componentLength = function () {
return this._data[1];
};
SLComponentRecord.prototype.content = function (getString) {
return getString(this._data, 2, this.componentLength());
};
return SLComponentRecord;
}());
/**
* RockRidge: Records alternate file name
* @hidden
*/
var NMEntry = /** @class */ (function (_super) {
__extends(NMEntry, _super);
function NMEntry(data) {
return _super.call(this, data) || this;
}
NMEntry.prototype.flags = function () {
return this._data[4];
};
NMEntry.prototype.name = function (getString) {
return getString(this._data, 5, this.length() - 5);
};
return NMEntry;
}(SystemUseEntry));
/**
* RockRidge: Records child link
* @hidden
*/
var CLEntry = /** @class */ (function (_super) {
__extends(CLEntry, _super);
function CLEntry(data) {
return _super.call(this, data) || this;
}
CLEntry.prototype.childDirectoryLba = function () {
return this._data.readUInt32LE(4);
};
return CLEntry;
}(SystemUseEntry));
/**
* RockRidge: Records parent link.
* @hidden
*/
var PLEntry = /** @class */ (function (_super) {
__extends(PLEntry, _super);
function PLEntry(data) {
return _super.call(this, data) || this;
}
PLEntry.prototype.parentDirectoryLba = function () {
return this._data.readUInt32LE(4);
};
return PLEntry;
}(SystemUseEntry));
/**
* RockRidge: Records relocated directory.
* @hidden
*/
var REEntry = /** @class */ (function (_super) {
__extends(REEntry, _super);
function REEntry(data) {
return _super.call(this, data) || this;
}
return REEntry;
}(SystemUseEntry));
/**
* RockRidge: Records file timestamps
* @hidden
*/
var TFEntry = /** @class */ (function (_super) {
__extends(TFEntry, _super);
function TFEntry(data) {
return _super.call(this, data) || this;
}
TFEntry.prototype.flags = function () {
return this._data[4];
};
TFEntry.prototype.creation = function () {
if (this.flags() & 1 /* TFFlags.CREATION */) {
if (this._longFormDates()) {
return getDate(this._data, 5);
}
else {
return getShortFormDate(this._data, 5);
}
}
else {
return null;
}
};
TFEntry.prototype.modify = function () {
if (this.flags() & 2 /* TFFlags.MODIFY */) {
var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0;
if (this._longFormDates()) {
return getDate(this._data, 5 + (previousDates * 17));
}
else {
return getShortFormDate(this._data, 5 + (previousDates * 7));
}
}
else {
return null;
}
};
TFEntry.prototype.access = function () {
if (this.flags() & 4 /* TFFlags.ACCESS */) {
var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0;
previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0;
if (this._longFormDates()) {
return getDate(this._data, 5 + (previousDates * 17));
}
else {
return getShortFormDate(this._data, 5 + (previousDates * 7));
}
}
else {
return null;
}
};
TFEntry.prototype.backup = function () {
if (this.flags() & 16 /* TFFlags.BACKUP */) {
var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0;
previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0;
previousDates += (this.flags() & 4 /* TFFlags.ACCESS */) ? 1 : 0;
if (this._longFormDates()) {
return getDate(this._data, 5 + (previousDates * 17));
}
else {
return getShortFormDate(this._data, 5 + (previousDates * 7));
}
}
else {
return null;
}
};
TFEntry.prototype.expiration = function () {
if (this.flags() & 32 /* TFFlags.EXPIRATION */) {
var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0;
previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0;
previousDates += (this.flags() & 4 /* TFFlags.ACCESS */) ? 1 : 0;
previousDates += (this.flags() & 16 /* TFFlags.BACKUP */) ? 1 : 0;
if (this._longFormDates()) {
return getDate(this._data, 5 + (previousDates * 17));
}
else {
return getShortFormDate(this._data, 5 + (previousDates * 7));
}
}
else {
return null;
}
};
TFEntry.prototype.effective = function () {
if (this.flags() & 64 /* TFFlags.EFFECTIVE */) {
var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0;
previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0;
previousDates += (this.flags() & 4 /* TFFlags.ACCESS */) ? 1 : 0;
previousDates += (this.flags() & 16 /* TFFlags.BACKUP */) ? 1 : 0;
previousDates += (this.flags() & 32 /* TFFlags.EXPIRATION */) ? 1 : 0;
if (this._longFormDates()) {
return getDate(this._data, 5 + (previousDates * 17));
}
else {
return getShortFormDate(this._data, 5 + (previousDates * 7));
}
}
else {
return null;
}
};
TFEntry.prototype._longFormDates = function () {
return Boolean(this.flags() && 128 /* TFFlags.LONG_FORM */);
};
return TFEntry;
}(SystemUseEntry));
/**
* RockRidge: File data in sparse format.
* @hidden
*/
var SFEntry = /** @class */ (function (_super) {
__extends(SFEntry, _super);
function SFEntry(data) {
return _super.call(this, data) || this;
}
SFEntry.prototype.virtualSizeHigh = function () {
return this._data.readUInt32LE(4);
};
SFEntry.prototype.virtualSizeLow = function () {
return this._data.readUInt32LE(12);
};
SFEntry.prototype.tableDepth = function () {
return this._data[20];
};
return SFEntry;
}(SystemUseEntry));
/**
* @hidden
*/
var Directory = /** @class */ (function () {
function Directory(record, isoData) {
this._fileList = [];
this._fileMap = {};
this._record = record;
var i = record.lba();
var iLimit = i + record.dataLength();
if (!(record.fileFlags() & 2 /* FileFlags.Directory */)) {
// Must have a CL entry.
var cl = record.getSUEntries(isoData).filter(function (e) { return e instanceof CLEntry; })[0];
i = cl.childDirectoryLba() * 2048;
iLimit = Infinity;
}
while (i < iLimit) {
var len = isoData[i];
// Zero-padding between sectors.
// TODO: Could optimize this to seek to nearest-sector upon
// seeing a 0.
if (len === 0) {
i++;
continue;
}
var r = this._constructDirectoryRecord(isoData.slice(i));
var fname = r.fileName(isoData);
// Skip '.' and '..' entries.
if (fname !== '\u0000' && fname !== '\u0001') {
// Skip relocated entries.
if (!r.hasRockRidge() || r.getSUEntries(isoData).filter(function (e) { return e instanceof REEntry; }).length === 0) {
this._fileMap[fname] = r;
this._fileList.push(fname);
}
}
else if (iLimit === Infinity) {
// First entry contains needed data.
iLimit = i + r.dataLength();
}
i += r.length();
}
}
/**
* Get the record with the given name.
* Returns undefined if not present.
*/
Directory.prototype.getRecord = function (name) {
return this._fileMap[name];
};
Directory.prototype.getFileList = function () {
return this._fileList;
};
Directory.prototype.getDotEntry = function (isoData) {
return this._constructDirectoryRecord(isoData.slice(this._record.lba()));
};
return Directory;
}());
/**
* @hidden
*/
var ISODirectory = /** @class */ (function (_super) {
__extends(ISODirectory, _super);
function ISODirectory(record, isoData) {
return _super.call(this, record, isoData) || this;
}
ISODirectory.prototype._constructDirectoryRecord = function (data) {
return new ISODirectoryRecord(data, this._record.getRockRidgeOffset());
};
return ISODirectory;
}(Directory));
/**
* @hidden
*/
var JolietDirectory = /** @class */ (function (_super) {
__extends(JolietDirectory, _super);
function JolietDirectory(record, isoData) {
return _super.call(this, record, isoData) || this;
}
JolietDirectory.prototype._constructDirectoryRecord = function (data) {
return new JolietDirectoryRecord(data, this._record.getRockRidgeOffset());
};
return JolietDirectory;
}(Directory));
/**
* Mounts an ISO file as a read-only file system.
*
* Supports:
* * Vanilla ISO9660 ISOs
* * Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard
*/
var IsoFS = /** @class */ (function (_super) {
__extends(IsoFS, _super);
/**
* **Deprecated. Please use IsoFS.Create() method instead.**
*
* Constructs a read-only file system from the given ISO.
* @param data The ISO file in a buffer.
* @param name The name of the ISO (optional; used for debug messages / identification via getName()).
*/
function IsoFS(data, name) {
if (name === void 0) { name = ""; }
var _this = _super.call(this) || this;
_this._data = data;
// Skip first 16 sectors.
var vdTerminatorFound = false;
var i = 16 * 2048;
var candidateVDs = new Array();
while (!vdTerminatorFound) {
var slice = data.slice(i);
var vd = new VolumeDescriptor(slice);
switch (vd.type()) {
case 1 /* VolumeDescriptorTypeCode.PrimaryVolumeDescriptor */:
candidateVDs.push(new PrimaryVolumeDescriptor(slice));
break;
case 2 /* VolumeDescriptorTypeCode.SupplementaryVolumeDescriptor */:
candidateVDs.push(new SupplementaryVolumeDescriptor(slice));
break;
case 255 /* VolumeDescriptorTypeCode.VolumeDescriptorSetTerminator */:
vdTerminatorFound = true;
break;
}
i += 2048;
}
if (candidateVDs.length === 0) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Unable to find a suitable volume descriptor.");
}
candidateVDs.forEach(function (v) {
// Take an SVD over a PVD.
if (!_this._pvd || _this._pvd.type() !== 2 /* VolumeDescriptorTypeCode.SupplementaryVolumeDescriptor */) {
_this._pvd = v;
}
});
_this._root = _this._pvd.rootDirectoryEntry(data);
_this._name = name;
return _this;
}
/**
* Creates an IsoFS instance with the given options.
*/
IsoFS.Create = function (opts, cb) {
try {
cb(null, new IsoFS(opts.data, opts.name));
}
catch (e) {
cb(e);
}
};
IsoFS.isAvailable = function () {
return true;
};
IsoFS.prototype.getName = function () {
var name = "IsoFS".concat(this._name).concat(this._pvd ? "-".concat(this._pvd.name()) : '');
if (this._root && this._root.hasRockRidge()) {
name += "-RockRidge";
}
return name;
};
IsoFS.prototype.diskSpace = function (path, cb) {
// Read-only file system.
cb(this._data.length, 0);
};
IsoFS.prototype.isReadOnly = function () {
return true;
};
IsoFS.prototype.supportsLinks = function () {
return false;
};
IsoFS.prototype.supportsProps = function () {
return false;
};
IsoFS.prototype.supportsSynch = function () {
return true;
};
IsoFS.prototype.statSync = function (p, isLstat) {
var record = this._getDirectoryRecord(p);
if (record === null) {
throw api_error_1.ApiError.ENOENT(p);
}
return this._getStats(p, record);
};
IsoFS.prototype.openSync = function (p, flags, mode) {
// INVARIANT: Cannot write to RO file systems.
if (flags.isWriteable()) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.EPERM, p);
}
// Check if the path exists, and is a file.
var record = this._getDirectoryRecord(p);
if (!record) {
throw api_error_1.ApiError.ENOENT(p);
}
else if (record.isSymlink(this._data)) {
return this.openSync(path.resolve(p, record.getSymlinkPath(this._data)), flags, mode);
}
else if (!record.isDirectory(this._data)) {
var data = record.getFile(this._data);
var stats = this._getStats(p, record);
switch (flags.pathExistsAction()) {
case file_flag_1.ActionType.THROW_EXCEPTION:
case file_flag_1.ActionType.TRUNCATE_FILE:
throw api_error_1.ApiError.EEXIST(p);
case file_flag_1.ActionType.NOP:
return new preload_file_1.NoSyncFile(this, p, flags, stats, data);
default:
throw new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, 'Invalid FileMode object.');
}
}
else {
throw api_error_1.ApiError.EISDIR(p);
}
};
IsoFS.prototype.readdirSync = function (path) {
// Check if it exists.
var record = this._getDirectoryRecord(path);
if (!record) {
throw api_error_1.ApiError.ENOENT(path);
}
else if (record.isDirectory(this._data)) {
return record.getDirectory(this._data).getFileList().slice(0);
}
else {
throw api_error_1.ApiError.ENOTDIR(path);
}
};
/**
* Specially-optimized readfile.
*/
IsoFS.prototype.readFileSync = function (fname, encoding, flag) {
// Get file.
var fd = this.openSync(fname, flag, 0x1a4);
try {
var fdCast = fd;
var fdBuff = fdCast.getBuffer();
if (encoding === null) {
return (0, util_1.copyingSlice)(fdBuff);
}
return fdBuff.toString(encoding);
}
finally {
fd.closeSync();
}
};
IsoFS.prototype._getDirectoryRecord = function (path) {
// Special case.
if (path === '/') {
return this._root;
}
var components = path.split('/').slice(1);
var dir = this._root;
for (var _i = 0, components_2 = components; _i < components_2.length; _i++) {
var component = components_2[_i];
if (dir.isDirectory(this._data)) {
dir = dir.getDirectory(this._data).getRecord(component);
if (!dir) {
return null;
}
}
else {
return null;
}
}
return dir;
};
IsoFS.prototype._getStats = function (p, record) {
if (record.isSymlink(this._data)) {
var newP = path.resolve(p, record.getSymlinkPath(this._data));
var dirRec = this._getDirectoryRecord(newP);
if (!dirRec) {
return null;
}
return this._getStats(newP, dirRec);
}
else {
var len = record.dataLength();
var mode = 0x16D;
var date = record.recordingDate().getTime();
var atime = date;
var mtime = date;
var ctime = date;
if (record.hasRockRidge()) {
var entries = record.getSUEntries(this._data);
for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) {
var entry = entries_2[_i];
if (entry instanceof PXEntry) {
mode = entry.mode();
}
else if (entry instanceof TFEntry) {
var flags = entry.flags();
if (flags & 4 /* TFFlags.ACCESS */) {
atime = entry.access().getTime();
}
if (flags & 2 /* TFFlags.MODIFY */) {
mtime = entry.modify().getTime();
}
if (flags & 1 /* TFFlags.CREATION */) {
ctime = entry.creation().getTime();
}
}
}
}
// Mask out writeable flags. This is a RO file system.
mode = mode & 0x16D;
return new node_fs_stats_1.default(record.isDirectory(this._data) ? node_fs_stats_1.FileType.DIRECTORY : node_fs_stats_1.FileType.FILE, len, mode, atime, mtime, ctime);
}
};
IsoFS.Name = "IsoFS";
IsoFS.Options = {
data: {
type: "object",
description: "The ISO file in a buffer",
validator: util_1.bufferValidator
}
};
return IsoFS;
}(file_system_1.SynchronousFileSystem));
exports.default = IsoFS;