| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /*
- Copyright (c) 2013 Gildas Lormeau. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- (function() {
- "use strict";
- var ERR_HTTP_RANGE = "HTTP Range not supported.";
- var Reader = zip.Reader;
- var Writer = zip.Writer;
-
- var ZipDirectoryEntry;
- var appendABViewSupported;
- try {
- appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0;
- } catch (e) {
- }
- function isHttpFamily(url) {
- var a = document.createElement("a");
- a.href = url;
- return a.protocol === "http:" || a.protocol === "https:";
- }
- function HttpReader(url) {
- var that = this;
- function getData(callback, onerror) {
- var request;
- if (!that.data) {
- request = new XMLHttpRequest();
- request.addEventListener("load", function() {
- if (!that.size)
- that.size = Number(request.getResponseHeader("Content-Length")) || Number(request.response.byteLength);
- that.data = new Uint8Array(request.response);
- callback();
- }, false);
- request.addEventListener("error", onerror, false);
- request.open("GET", url);
- request.responseType = "arraybuffer";
- request.send();
- } else
- callback();
- }
- function init(callback, onerror) {
- if (!isHttpFamily(url)) {
- // For schemas other than http(s), HTTP HEAD may be unavailable,
- // so use HTTP GET instead.
- getData(callback, onerror);
- return;
- }
- var request = new XMLHttpRequest();
- request.addEventListener("load", function() {
- that.size = Number(request.getResponseHeader("Content-Length"));
- // If response header doesn't return size then prefetch the content.
- if (!that.size) {
- getData(callback, onerror);
- } else {
- callback();
- }
- }, false);
- request.addEventListener("error", onerror, false);
- request.open("HEAD", url);
- request.send();
- }
- function readUint8Array(index, length, callback, onerror) {
- getData(function() {
- callback(new Uint8Array(that.data.subarray(index, index + length)));
- }, onerror);
- }
- that.size = 0;
- that.init = init;
- that.readUint8Array = readUint8Array;
- }
- HttpReader.prototype = new Reader();
- HttpReader.prototype.constructor = HttpReader;
- function HttpRangeReader(url) {
- var that = this;
- function init(callback, onerror) {
- var request = new XMLHttpRequest();
- request.addEventListener("load", function() {
- that.size = Number(request.getResponseHeader("Content-Length"));
- if (request.getResponseHeader("Accept-Ranges") == "bytes")
- callback();
- else
- onerror(ERR_HTTP_RANGE);
- }, false);
- request.addEventListener("error", onerror, false);
- request.open("HEAD", url);
- request.send();
- }
- function readArrayBuffer(index, length, callback, onerror) {
- var request = new XMLHttpRequest();
- request.open("GET", url);
- request.responseType = "arraybuffer";
- request.setRequestHeader("Range", "bytes=" + index + "-" + (index + length - 1));
- request.addEventListener("load", function() {
- callback(request.response);
- }, false);
- request.addEventListener("error", onerror, false);
- request.send();
- }
- function readUint8Array(index, length, callback, onerror) {
- readArrayBuffer(index, length, function(arraybuffer) {
- callback(new Uint8Array(arraybuffer));
- }, onerror);
- }
- that.size = 0;
- that.init = init;
- that.readUint8Array = readUint8Array;
- }
- HttpRangeReader.prototype = new Reader();
- HttpRangeReader.prototype.constructor = HttpRangeReader;
- function ArrayBufferReader(arrayBuffer) {
- var that = this;
- function init(callback, onerror) {
- that.size = arrayBuffer.byteLength;
- callback();
- }
- function readUint8Array(index, length, callback, onerror) {
- callback(new Uint8Array(arrayBuffer.slice(index, index + length)));
- }
- that.size = 0;
- that.init = init;
- that.readUint8Array = readUint8Array;
- }
- ArrayBufferReader.prototype = new Reader();
- ArrayBufferReader.prototype.constructor = ArrayBufferReader;
- function ArrayBufferWriter() {
- var array, that = this;
- function init(callback, onerror) {
- array = new Uint8Array();
- callback();
- }
- function writeUint8Array(arr, callback, onerror) {
- var tmpArray = new Uint8Array(array.length + arr.length);
- tmpArray.set(array);
- tmpArray.set(arr, array.length);
- array = tmpArray;
- callback();
- }
- function getData(callback) {
- callback(array.buffer);
- }
- that.init = init;
- that.writeUint8Array = writeUint8Array;
- that.getData = getData;
- }
- ArrayBufferWriter.prototype = new Writer();
- ArrayBufferWriter.prototype.constructor = ArrayBufferWriter;
- function FileWriter(fileEntry, contentType) {
- var writer, that = this;
- function init(callback, onerror) {
- fileEntry.createWriter(function(fileWriter) {
- writer = fileWriter;
- callback();
- }, onerror);
- }
- function writeUint8Array(array, callback, onerror) {
- var blob = new Blob([ appendABViewSupported ? array : array.buffer ], {
- type : contentType
- });
- writer.onwrite = function() {
- writer.onwrite = null;
- callback();
- };
- writer.onerror = onerror;
- writer.write(blob);
- }
- function getData(callback) {
- fileEntry.file(callback);
- }
- that.init = init;
- that.writeUint8Array = writeUint8Array;
- that.getData = getData;
- }
- FileWriter.prototype = new Writer();
- FileWriter.prototype.constructor = FileWriter;
- zip.FileWriter = FileWriter;
- zip.HttpReader = HttpReader;
- zip.HttpRangeReader = HttpRangeReader;
- zip.ArrayBufferReader = ArrayBufferReader;
- zip.ArrayBufferWriter = ArrayBufferWriter;
- if (zip.fs) {
- ZipDirectoryEntry = zip.fs.ZipDirectoryEntry;
- ZipDirectoryEntry.prototype.addHttpContent = function(name, URL, useRangeHeader) {
- function addChild(parent, name, params, directory) {
- if (parent.directory)
- return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new zip.fs.ZipFileEntry(parent.fs, name, params, parent);
- else
- throw "Parent entry is not a directory.";
- }
- return addChild(this, name, {
- data : URL,
- Reader : useRangeHeader ? HttpRangeReader : HttpReader
- });
- };
- ZipDirectoryEntry.prototype.importHttpContent = function(URL, useRangeHeader, onend, onerror) {
- this.importZip(useRangeHeader ? new HttpRangeReader(URL) : new HttpReader(URL), onend, onerror);
- };
- zip.fs.FS.prototype.importHttpContent = function(URL, useRangeHeader, onend, onerror) {
- this.entries = [];
- this.root = new ZipDirectoryEntry(this);
- this.root.importHttpContent(URL, useRangeHeader, onend, onerror);
- };
- }
- })();
|