diff options
author | John Allwine <jallwine86@gmail.com> | 2013-05-03 12:44:09 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-05-09 11:57:17 -0700 |
commit | 88afab276ec671e688898baec4b47deac868f10f (patch) | |
tree | 8467e99764e1e0f09f7f3e164bfa03201b8da93b /src | |
parent | 15d5d02a28b4d6bd66a8f621297965a36c16d879 (diff) |
changed createLazyFile to only issue xhr requests when the file is accessed (fixes issue #1127)
Diffstat (limited to 'src')
-rw-r--r-- | src/library.js | 125 |
1 files changed, 74 insertions, 51 deletions
diff --git a/src/library.js b/src/library.js index 41796551..f22eaecf 100644 --- a/src/library.js +++ b/src/library.js @@ -296,74 +296,97 @@ LibraryManager.library = { if (typeof XMLHttpRequest !== 'undefined') { if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse. - var LazyUint8Array = function(chunkSize, length) { - this.length = length; - this.chunkSize = chunkSize; + var LazyUint8Array = function() { + this.lengthKnown = false; this.chunks = []; // Loaded chunks. Index is the chunk number } LazyUint8Array.prototype.get = function(idx) { if (idx > this.length-1 || idx < 0) { return undefined; } - var chunkOffset = idx % chunkSize; - var chunkNum = Math.floor(idx / chunkSize); + var chunkOffset = idx % this.chunkSize; + var chunkNum = Math.floor(idx / this.chunkSize); return this.getter(chunkNum)[chunkOffset]; } LazyUint8Array.prototype.setDataGetter = function(getter) { this.getter = getter; } - - // Find length - var xhr = new XMLHttpRequest(); - xhr.open('HEAD', url, false); - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - var datalength = Number(xhr.getResponseHeader("Content-length")); - var header; - var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; + + LazyUint8Array.prototype.getLength = function() { + // Find length + var xhr = new XMLHttpRequest(); + xhr.open('HEAD', url, false); + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); + var datalength = Number(xhr.getResponseHeader("Content-length")); + var header; + var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; #if SMALL_XHR_CHUNKS - var chunkSize = 1024; // Chunk size in bytes + var chunkSize = 1024; // Chunk size in bytes #else - var chunkSize = 1024*1024; // Chunk size in bytes + var chunkSize = 1024*1024; // Chunk size in bytes #endif - if (!hasByteServing) chunkSize = datalength; - - // Function to get a range from the remote URL. - var doXHR = (function(from, to) { - if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); - if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!"); - - // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); - - // Some hints to the browser that we want binary data. - if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; - if (xhr.overrideMimeType) { - xhr.overrideMimeType('text/plain; charset=x-user-defined'); - } + if (!hasByteServing) chunkSize = datalength; + + // Function to get a range from the remote URL. + var doXHR = (function(from, to) { + if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); + if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!"); + + // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); + + // Some hints to the browser that we want binary data. + if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; + if (xhr.overrideMimeType) { + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + } + + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); + if (xhr.response !== undefined) { + return new Uint8Array(xhr.response || []); + } else { + return intArrayFromString(xhr.responseText || '', true); + } + }); + var lazyArray = this; + lazyArray.setDataGetter(function(chunkNum) { + var start = chunkNum * chunkSize; + var end = (chunkNum+1) * chunkSize - 1; // including this byte + end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block + if (typeof(lazyArray.chunks[chunkNum]) === "undefined") { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!"); + return lazyArray.chunks[chunkNum]; + }); + + this._length = datalength; + this._chunkSize = chunkSize; + this.lengthKnown = true; + } - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - if (xhr.response !== undefined) { - return new Uint8Array(xhr.response || []); - } else { - return intArrayFromString(xhr.responseText || '', true); - } + var lazyArray = new LazyUint8Array(); + Object.defineProperty(lazyArray, "length", { + get: function() { + if(!this.lengthKnown) { + this.getLength(); + } + return this._length; + } }); - - var lazyArray = new LazyUint8Array(chunkSize, datalength); - lazyArray.setDataGetter(function(chunkNum) { - var start = chunkNum * lazyArray.chunkSize; - var end = (chunkNum+1) * lazyArray.chunkSize - 1; // including this byte - end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block - if (typeof(lazyArray.chunks[chunkNum]) === "undefined") { - lazyArray.chunks[chunkNum] = doXHR(start, end); - } - if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!"); - return lazyArray.chunks[chunkNum]; + Object.defineProperty(lazyArray, "chunkSize", { + get: function() { + if(!this.lengthKnown) { + this.getLength(); + } + return this._chunkSize; + } }); + var properties = { isDevice: false, contents: lazyArray }; } else { var properties = { isDevice: false, url: url }; |