Fixed disk size calculation, ensuring that the disk size we select for a collection of files will actually work (including cluster overhead)
This commit is contained in:
parent
187e09dd48
commit
fb57561660
2 changed files with 35 additions and 21 deletions
|
|
@ -22,7 +22,7 @@ indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.{php,xml,xsl}]
|
[*.{php,xml,xsl,sh}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
|
||||||
|
|
@ -74,10 +74,10 @@ var logFile = null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fNormalize attempts to enforce consistency across multiple dump requests, including the order of files within every
|
* fNormalize attempts to enforce consistency across multiple dump requests, including the order of files within every
|
||||||
* directory, the use of hard-coded volume label timestamps, etc. And since I assume that normalization is a wonderful
|
* directory, the use of hard-coded volume label timestamps, replacement of line-endings in text files, etc. And since
|
||||||
* thing, I don't provide any UI for turning it off.
|
* I assume that normalization is a wonderful thing, I don't provide any UI for turning it off.
|
||||||
*/
|
*/
|
||||||
var fNormalize = true;
|
var fNormalize = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BufferPF(init, start, end)
|
* BufferPF(init, start, end)
|
||||||
|
|
@ -1577,8 +1577,10 @@ DiskDump.prototype.addManifestInfo = function(fileInfo)
|
||||||
*/
|
*/
|
||||||
DiskDump.prototype.isTextFile = function(sFileName)
|
DiskDump.prototype.isTextFile = function(sFileName)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < DiskDump.asTextFileExts.length; i++) {
|
if (fNormalize) {
|
||||||
if (str.endsWith(sFileName, DiskDump.asTextFileExts[i])) return true;
|
for (var i = 0; i < DiskDump.asTextFileExts.length; i++) {
|
||||||
|
if (str.endsWith(sFileName, DiskDump.asTextFileExts[i])) return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -1633,7 +1635,7 @@ DiskDump.prototype.readDir = function(sDir, fRoot, done)
|
||||||
* file name order that I was originally seeing may have simply been due to out-of-order fs.stat()
|
* file name order that I was originally seeing may have simply been due to out-of-order fs.stat()
|
||||||
* calls, because I used to call addManifestInfo() in the callback.
|
* calls, because I used to call addManifestInfo() in the callback.
|
||||||
*/
|
*/
|
||||||
// if (fNormalize) asFiles.sort();
|
if (fNormalize) asFiles.sort();
|
||||||
|
|
||||||
for (iFile = 0; iFile < asFiles.length; iFile++) {
|
for (iFile = 0; iFile < asFiles.length; iFile++) {
|
||||||
var sFileName = asFiles[iFile];
|
var sFileName = asFiles[iFile];
|
||||||
|
|
@ -1927,7 +1929,7 @@ DiskDump.prototype.buildVolLabel = function(sDir)
|
||||||
*
|
*
|
||||||
* UPDATE: I'm not sure I care about that anymore. Time-stamping the created disk image seems more useful.
|
* UPDATE: I'm not sure I care about that anymore. Time-stamping the created disk image seems more useful.
|
||||||
*/
|
*/
|
||||||
fileInfo.FILE_TIME = /* fNormalize? new Date(1981, 7, 12, 12) : */ new Date();
|
fileInfo.FILE_TIME = fNormalize? new Date(1981, 7, 12, 12) : new Date();
|
||||||
this.validateTime(fileInfo.FILE_TIME);
|
this.validateTime(fileInfo.FILE_TIME);
|
||||||
fileInfo.FILE_SIZE = 0;
|
fileInfo.FILE_SIZE = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2247,31 +2249,27 @@ DiskDump.prototype.buildImage = function(fDir, done)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calcFileSizes(aFiles)
|
* calcFileSizes(aFiles, cSectorsPerCluster)
|
||||||
*
|
|
||||||
* WARNING: Our "total data" calculation should be rounding up to the next cluster,
|
|
||||||
* not the next sector, because data on the disk is cluster-granular, not sector-granular.
|
|
||||||
* But we have a chicken-and-egg problem: we won't know the cluster size until we've
|
|
||||||
* calculated total data and found a BPB we think will accommodate it. So, the code below
|
|
||||||
* will still have to be prepared for running out of disk space. This is just a good estimate.
|
|
||||||
*
|
*
|
||||||
* @this {DiskDump}
|
* @this {DiskDump}
|
||||||
* @param {Array} aFiles
|
* @param {Array} aFiles
|
||||||
|
* @param {number} [cSectorsPerCluster] (default is 1)
|
||||||
* @return {number} of bytes required for all files, including all subdirectories
|
* @return {number} of bytes required for all files, including all subdirectories
|
||||||
*/
|
*/
|
||||||
DiskDump.prototype.calcFileSizes = function(aFiles)
|
DiskDump.prototype.calcFileSizes = function(aFiles, cSectorsPerCluster)
|
||||||
{
|
{
|
||||||
var cbTotal = 0;
|
var cbTotal = 0;
|
||||||
|
var cbCluster = (cSectorsPerCluster || 1) * 512;
|
||||||
for (var iFile = 0; iFile < aFiles.length; iFile++) {
|
for (var iFile = 0; iFile < aFiles.length; iFile++) {
|
||||||
var cb = aFiles[iFile].FILE_SIZE;
|
var cb = aFiles[iFile].FILE_SIZE;
|
||||||
var cbSubTotal = 0;
|
var cbSubTotal = 0;
|
||||||
if (cb < 0) {
|
if (cb < 0) {
|
||||||
cb = (aFiles[iFile].FILE_DATA.length + 2) * 32;
|
cb = (aFiles[iFile].FILE_DATA.length + 2) * 32;
|
||||||
cbSubTotal = this.calcFileSizes(aFiles[iFile].FILE_DATA);
|
cbSubTotal = this.calcFileSizes(aFiles[iFile].FILE_DATA, cSectorsPerCluster);
|
||||||
}
|
}
|
||||||
cbTotal += cb;
|
cbTotal += cb;
|
||||||
if ((cb %= 512)) {
|
if ((cb %= cbCluster)) {
|
||||||
cbTotal += 512 - cb; // WARNING: rounding to next sector may not be enough (see above)
|
cbTotal += cbCluster - cb;
|
||||||
}
|
}
|
||||||
cbTotal += cbSubTotal;
|
cbTotal += cbSubTotal;
|
||||||
}
|
}
|
||||||
|
|
@ -2370,6 +2368,12 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
*/
|
*/
|
||||||
var cbMax = (this.kbTarget || 1440) * 1024;
|
var cbMax = (this.kbTarget || 1440) * 1024;
|
||||||
var nTargetSectors = (this.kbTarget? this.kbTarget * 2 : 0);
|
var nTargetSectors = (this.kbTarget? this.kbTarget * 2 : 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This initializes cbTotal assuming a "best case scenario" (ie, one sector per cluster); as soon as
|
||||||
|
* we find a BPB that will support that size, we recalculate cbTotal using that BPB's cluster size, and
|
||||||
|
* then we re-verify that that BPB will work. If not, then we keep looking.
|
||||||
|
*/
|
||||||
var cbTotal = this.calcFileSizes(aFiles);
|
var cbTotal = this.calcFileSizes(aFiles);
|
||||||
|
|
||||||
if (fDebug) DiskDump.logConsole("total calculated size for " + aFiles.length + " files/folders: " + cbTotal + " bytes (" + str.toHex(cbTotal, 0, true) + ")");
|
if (fDebug) DiskDump.logConsole("total calculated size for " + aFiles.length + " files/folders: " + cbTotal + " bytes (" + str.toHex(cbTotal, 0, true) + ")");
|
||||||
|
|
@ -2397,7 +2401,7 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
*
|
*
|
||||||
* UPDATE: I've undone the above change, because when creating a disk image for an old application like:
|
* UPDATE: I've undone the above change, because when creating a disk image for an old application like:
|
||||||
*
|
*
|
||||||
* /apps/pcx86/1983/adventmath ["Adventures in Math" (1983)]
|
* /apps/pcx86/1983/adventmath ["Adventures in Math (1983)"]
|
||||||
*
|
*
|
||||||
* it's important to create a disk image that will work with PC-DOS 1.0, which didn't understand 180Kb and 360Kb
|
* it's important to create a disk image that will work with PC-DOS 1.0, which didn't understand 180Kb and 360Kb
|
||||||
* disk images.
|
* disk images.
|
||||||
|
|
@ -2423,7 +2427,17 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
cHeads = abBoot[0x1A] | (abBoot[0x1B] << 8);
|
cHeads = abBoot[0x1A] | (abBoot[0x1B] << 8);
|
||||||
cDataSectors = cTotalSectors - cRootSectors - cFATs * cFATSectors + 1;
|
cDataSectors = cTotalSectors - cRootSectors - cFATs * cFATSectors + 1;
|
||||||
cbAvail = cDataSectors * cbSector;
|
cbAvail = cDataSectors * cbSector;
|
||||||
if (nTargetSectors && cTotalSectors == nTargetSectors || !nTargetSectors && cbTotal <= cbAvail) break;
|
if (!nTargetSectors) {
|
||||||
|
if (cbTotal <= cbAvail) {
|
||||||
|
var cb = this.calcFileSizes(aFiles, cSectorsPerCluster);
|
||||||
|
if (cb <= cbAvail) {
|
||||||
|
cbTotal = cb;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (cTotalSectors == nTargetSectors) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iBPB == DiskDump.aDefaultBPBs.length) {
|
if (iBPB == DiskDump.aDefaultBPBs.length) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue