From 231bc201e74c9954f6f2198addc8c639548cfcd1 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Sun, 8 Nov 2015 10:30:47 -0800 Subject: [PATCH] Allow gzipped disk images --- .../compaq/deskpro386/vga/4096kb/machine.xml | 2 +- modules/pcjs/lib/computer.js | 10 +++---- modules/pcjs/lib/disk.js | 27 +++++++++---------- modules/pcjs/lib/rom.js | 18 ++++++------- modules/pcjs/lib/video.js | 12 ++++----- modules/shared/lib/dumpapi.js | 5 ++-- modules/shared/lib/weblib.js | 9 +++---- 7 files changed, 41 insertions(+), 42 deletions(-) diff --git a/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml b/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml index 32b894e51..aa24b8002 100644 --- a/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml +++ b/devices/pc/machine/compaq/deskpro386/vga/4096kb/machine.xml @@ -13,7 +13,7 @@ - + diff --git a/modules/pcjs/lib/computer.js b/modules/pcjs/lib/computer.js index 9782782c1..df714412e 100644 --- a/modules/pcjs/lib/computer.js +++ b/modules/pcjs/lib/computer.js @@ -252,7 +252,7 @@ function Computer(parmsComputer, parmsMachine, fSuspended) { if (!sStatePath) { this.setReady(); } else { - web.loadResource(sStatePath, true, null, this, this.onLoadSetReady); + web.loadResource(sStatePath, true, null, this, this.doneLoad); } if (!fSuspended) { @@ -321,20 +321,20 @@ Computer.prototype.getUserID = function() }; /** - * onLoadSetReady(sStateFile, sStateData, nErrorCode) + * doneLoad(sURL, sStateData, nErrorCode) * * @this {Computer} - * @param {string} sStateFile + * @param {string} sURL * @param {string} sStateData * @param {number} nErrorCode */ -Computer.prototype.onLoadSetReady = function(sStateFile, sStateData, nErrorCode) +Computer.prototype.doneLoad = function(sURL, sStateData, nErrorCode) { if (!nErrorCode) { this.sStateData = sStateData; this.fStateData = true; if (DEBUG && this.messageEnabled()) { - this.printMessage("loaded state file " + sStateFile.replace(this.sUserID || "xxx", "xxx")); + this.printMessage("loaded state file " + sURL.replace(this.sUserID || "xxx", "xxx")); } } else { this.sResumePath = null; diff --git a/modules/pcjs/lib/disk.js b/modules/pcjs/lib/disk.js index b78c76b64..5e848caa9 100644 --- a/modules/pcjs/lib/disk.js +++ b/modules/pcjs/lib/disk.js @@ -1012,6 +1012,8 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller) this.sDiskName = sDiskName; this.sDiskPath = sDiskPath; + this.sDiskFile = str.getBaseName(sDiskPath); + this.fnNotify = fnNotify; this.controllerNotify = controller || this.controller; @@ -1036,7 +1038,7 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller) * converter to return the corresponding JSON-encoded data. */ var sDiskExt = str.getExtension(sDiskPath); - if (sDiskExt == DumpAPI.FORMAT.JSON) { + if (sDiskExt == DumpAPI.FORMAT.JSON || sDiskExt == DumpAPI.FORMAT.JSON_GZ) { sDiskURL = encodeURI(sDiskPath); } else { if (this.mode == DiskAPI.MODE.DEMANDRW || this.mode == DiskAPI.MODE.DEMANDRO) { @@ -1076,7 +1078,7 @@ Disk.prototype.load = function(sDiskName, sDiskPath, file, fnNotify, controller) } } } - web.loadResource(sDiskURL, true, null, this, this.doneLoad, sDiskPath); + web.loadResource(sDiskURL, true, null, this, this.doneLoad); }; /** @@ -1135,35 +1137,32 @@ Disk.prototype.build = function(buffer, fModified) }; /** - * doneLoad(sDiskFile, sDiskData, nErrorCode, sDiskPath) + * doneLoad(sURL, sDiskData, nErrorCode) * * This function was originally called mount(). If the mount is successful, we pass the Disk object to the * caller's fnNotify handler; otherwise, we pass null. * * @this {Disk} - * @param {string} sDiskFile + * @param {string} sURL * @param {string} sDiskData * @param {number} nErrorCode (response from server if anything other than 200) - * @param {string} sDiskPath (passed through from load() to loadResource()) */ -Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath) +Disk.prototype.doneLoad = function(sURL, sDiskData, nErrorCode) { var disk = null; this.fWriteProtected = false; var fPrintOnly = (nErrorCode < 0 && this.cmp && !this.cmp.aFlags.fPowered); - this.sDiskFile = sDiskFile; - if (this.fOnDemand) { if (!nErrorCode) { if (DEBUG && this.messageEnabled()) { - this.printMessage('doneLoad("' + sDiskFile + '","' + sDiskPath + '")'); + this.printMessage('doneLoad("' + this.sDiskPath + '")'); } this.fRemote = true; if (BACKTRACK || SYMBOLS) this.buildFileTable(); disk = this; } else { - this.controller.notice('Unable to connect to disk "' + sDiskPath + '" (error ' + nErrorCode + ': ' + sDiskData + ')', fPrintOnly); + this.controller.notice('Unable to connect to disk "' + this.sDiskPath + '" (error ' + nErrorCode + ': ' + sDiskData + ')', fPrintOnly); } } else if (nErrorCode) { @@ -1174,10 +1173,10 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath) * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the * notify() alert if there's no specific error AND the computer is not powered up yet. */ - this.controller.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ")", fPrintOnly); + this.controller.notice("Unable to load disk \"" + this.sDiskName + "\" (error " + nErrorCode + ": " + sURL + ")", fPrintOnly); } else { if (DEBUG && this.messageEnabled()) { - this.printMessage('doneLoad("' + sDiskFile + '","' + sDiskPath + '")'); + this.printMessage('doneLoad("' + this.sDiskPath + '")'); } try { /* @@ -1189,7 +1188,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath) * TODO: Provide some UI for turning write-protection on/off for disks at will, and provide * an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well. */ - var sBaseName = str.getBaseName(sDiskFile, true).toLowerCase(); + var sBaseName = str.getBaseName(this.sDiskFile, true).toLowerCase(); if (sBaseName.indexOf("-readonly") > 0) { this.fWriteProtected = true; } else { @@ -1354,7 +1353,7 @@ Disk.prototype.doneLoad = function(sDiskFile, sDiskData, nErrorCode, sDiskPath) disk = this; } } catch (e) { - Component.error("Disk image error: " + e.message); + Component.error("Disk image error (" + sURL + "): " + e.message); } } diff --git a/modules/pcjs/lib/rom.js b/modules/pcjs/lib/rom.js index ab1a700eb..4963a443f 100644 --- a/modules/pcjs/lib/rom.js +++ b/modules/pcjs/lib/rom.js @@ -52,7 +52,7 @@ if (NODE) { * notify: ID of a component to notify once the ROM is in place (optional) * * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the - * ROM data file has finished loading (see onLoadROM()). + * ROM data file has finished loading (see doneLoad()). * * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received * is the ROM you expected. @@ -117,7 +117,7 @@ function ROM(parmsROM) if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) { sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true'; } - web.loadResource(sFileURL, true, null, this, ROM.prototype.onLoadROM); + web.loadResource(sFileURL, true, null, this, this.doneLoad); } } @@ -212,17 +212,17 @@ ROM.prototype.powerDown = function(fSave, fShutdown) }; /** - * onLoadROM(sROMFile, sROMData, nErrorCode) + * doneLoad(sURL, sROMData, nErrorCode) * * @this {ROM} - * @param {string} sROMFile + * @param {string} sURL * @param {string} sROMData * @param {number} nErrorCode (response from server if anything other than 200) */ -ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode) +ROM.prototype.doneLoad = function(sURL, sROMData, nErrorCode) { if (nErrorCode) { - this.notice("Unable to load system ROM (error " + nErrorCode + ")"); + this.notice("Unable to load system ROM (error " + nErrorCode + ": " + sURL + ")"); return; } if (sROMData.charAt(0) == "[" || sROMData.charAt(0) == "{") { @@ -256,7 +256,7 @@ ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode) this.aSymbols = rom['symbols']; if (!this.abROM.length) { - Component.error("Empty ROM: " + sROMFile); + Component.error("Empty ROM: " + sURL); return; } else if (this.abROM.length == 1) { @@ -286,8 +286,8 @@ ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode) /** * copyROM() * - * This function is called by both initBus() and onLoadROM(), but it cannot copy the the ROM data into place - * until after initBus() has received the Bus component AND onloadROM() has received the abROM data. When both + * This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place + * until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both * those criteria are satisfied, the component becomes "ready". * * @this {ROM} diff --git a/modules/pcjs/lib/video.js b/modules/pcjs/lib/video.js index 18418fb04..d8df27ab2 100644 --- a/modules/pcjs/lib/video.js +++ b/modules/pcjs/lib/video.js @@ -288,7 +288,7 @@ function Video(parmsVideo, canvas, context, textarea, container) if (sFileExt != "json") { sFileURL = web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + sFileURL + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES; } - web.loadResource(sFileURL, true, null, this, this.onLoadSetFonts); + web.loadResource(sFileURL, true, null, this, this.doneLoad); } } @@ -3710,17 +3710,17 @@ Video.prototype.restore = function(data) }; /** - * onLoadSetFonts(sFontFile, sFontData, nErrorCode) + * doneLoad(sURL, sFontData, nErrorCode) * * @this {Video} - * @param {string} sFontFile + * @param {string} sURL * @param {string} sFontData * @param {number} nErrorCode (response from server if anything other than 200) */ -Video.prototype.onLoadSetFonts = function(sFontFile, sFontData, nErrorCode) +Video.prototype.doneLoad = function(sURL, sFontData, nErrorCode) { if (nErrorCode) { - this.notice("Unable to load font ROM image (error " + nErrorCode + ")"); + this.notice("Unable to load font ROM (error " + nErrorCode + ": " + sURL + ")"); return; } try { @@ -3730,7 +3730,7 @@ Video.prototype.onLoadSetFonts = function(sFontFile, sFontData, nErrorCode) var abFontData = eval("(" + sFontData + ")"); if (!abFontData.length) { - Component.error("Empty font ROM image: " + sFontFile); + Component.error("Empty font ROM: " + sURL); return; } else if (abFontData.length == 1) { diff --git a/modules/shared/lib/dumpapi.js b/modules/shared/lib/dumpapi.js index 15f8ac7bc..327f3b819 100644 --- a/modules/shared/lib/dumpapi.js +++ b/modules/shared/lib/dumpapi.js @@ -67,6 +67,7 @@ var DumpAPI = { }, FORMAT: { JSON: "json", // default + JSON_GZ: "gz", // gzip is currently used ONLY for compressed JSON DATA: "data", // same as "json", but built without JSON.stringify() (DiskDump only) HEX: "hex", // deprecated BYTES: "bytes", // displays data as hex bytes; normally used only when comments are enabled @@ -77,9 +78,9 @@ var DumpAPI = { /* * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must - * also provide a list of commands which, when combined with the endpoint, define a unique request. + * also provide a list of commands which, when combined with the endpoint, define a unique request. */ DumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH]; DumpAPI.asFileCommands = [DumpAPI.QUERY.FILE]; -if (NODE) module.exports = DumpAPI; \ No newline at end of file +if (NODE) module.exports = DumpAPI; diff --git a/modules/shared/lib/weblib.js b/modules/shared/lib/weblib.js index f5c3e1011..e0c5d2fc7 100644 --- a/modules/shared/lib/weblib.js +++ b/modules/shared/lib/weblib.js @@ -203,7 +203,6 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti } var nErrorCode = 0; var sURLData = null; - var sURLName = str.getBaseName(sURL); var xmlHTTP = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP")); if (fAsync) { xmlHTTP.onreadystatechange = function() { @@ -231,9 +230,9 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti } if (fnNotify) { if (!componentNotify) { - fnNotify(sURLName, sURLData, nErrorCode, pNotify); + fnNotify(sURL, sURLData, nErrorCode, pNotify); } else { - fnNotify.call(componentNotify, sURLName, sURLData, nErrorCode, pNotify); + fnNotify.call(componentNotify, sURL, sURLData, nErrorCode, pNotify); } } } @@ -267,9 +266,9 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti } if (fnNotify) { if (!componentNotify) { - fnNotify(sURLName, sURLData, nErrorCode, pNotify); + fnNotify(sURL, sURLData, nErrorCode, pNotify); } else { - fnNotify.call(componentNotify, sURLName, sURLData, nErrorCode, pNotify); + fnNotify.call(componentNotify, sURL, sURLData, nErrorCode, pNotify); } } response = [nErrorCode, sURLData];