mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-30 23:03:02 +00:00 
			
		
		
		
	Code Csmetics kthoom integration
This commit is contained in:
		| @@ -13,341 +13,342 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|  |  | ||||||
| (function() { | (function() { | ||||||
|  |  | ||||||
| // =========================================================================== |     // =========================================================================== | ||||||
| // Stolen from Closure because it's the best way to do Java-like inheritance. |     // Stolen from Closure because it's the best way to do Java-like inheritance. | ||||||
| bitjs.base = function(me, opt_methodName, var_args) { |     bitjs.base = function(me, opt_methodName, var_args) { | ||||||
|   var caller = arguments.callee.caller; |         var caller = arguments.callee.caller; | ||||||
|   if (caller.superClass_) { |         if (caller.superClass_) { | ||||||
|     // This is a constructor. Call the superclass constructor. |             // This is a constructor. Call the superclass constructor. | ||||||
|     return caller.superClass_.constructor.apply( |             return caller.superClass_.constructor.apply( | ||||||
|         me, Array.prototype.slice.call(arguments, 1)); |                 me, Array.prototype.slice.call(arguments, 1)); | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var args = Array.prototype.slice.call(arguments, 2); |         var args = Array.prototype.slice.call(arguments, 2); | ||||||
|   var foundCaller = false; |         var foundCaller = false; | ||||||
|   for (var ctor = me.constructor; |         for (var ctor = me.constructor; | ||||||
|        ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) { |             ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) { | ||||||
|     if (ctor.prototype[opt_methodName] === caller) { |             if (ctor.prototype[opt_methodName] === caller) { | ||||||
|       foundCaller = true; |                 foundCaller = true; | ||||||
|     } else if (foundCaller) { |             } else if (foundCaller) { | ||||||
|       return ctor.prototype[opt_methodName].apply(me, args); |                 return ctor.prototype[opt_methodName].apply(me, args); | ||||||
|     } |             } | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   // If we did not find the caller in the prototype chain, |         // If we did not find the caller in the prototype chain, | ||||||
|   // then one of two things happened: |         // then one of two things happened: | ||||||
|   // 1) The caller is an instance method. |         // 1) The caller is an instance method. | ||||||
|   // 2) This method was not called by the right caller. |         // 2) This method was not called by the right caller. | ||||||
|   if (me[opt_methodName] === caller) { |         if (me[opt_methodName] === caller) { | ||||||
|     return me.constructor.prototype[opt_methodName].apply(me, args); |             return me.constructor.prototype[opt_methodName].apply(me, args); | ||||||
|   } else { |         } else { | ||||||
|     throw Error( |             throw Error( | ||||||
|         'goog.base called from a method of one name ' + |                 'goog.base called from a method of one name ' + | ||||||
|         'to a method of a different name'); |                 'to a method of a different name'); | ||||||
|   } |         } | ||||||
| }; |     }; | ||||||
| bitjs.inherits = function(childCtor, parentCtor) { |     bitjs.inherits = function(childCtor, parentCtor) { | ||||||
|   /** @constructor */ |         /** @constructor */ | ||||||
|   function tempCtor() {}; |         function tempCtor() {}; | ||||||
|   tempCtor.prototype = parentCtor.prototype; |         tempCtor.prototype = parentCtor.prototype; | ||||||
|   childCtor.superClass_ = parentCtor.prototype; |         childCtor.superClass_ = parentCtor.prototype; | ||||||
|   childCtor.prototype = new tempCtor(); |         childCtor.prototype = new tempCtor(); | ||||||
|   childCtor.prototype.constructor = childCtor; |         childCtor.prototype.constructor = childCtor; | ||||||
| }; |     }; | ||||||
| // =========================================================================== |     // =========================================================================== | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * An unarchive event. |      * An unarchive event. | ||||||
|  * |      * | ||||||
|  * @param {string} type The event type. |      * @param {string} type The event type. | ||||||
|  * @constructor |      * @constructor | ||||||
|  */ |      */ | ||||||
| bitjs.archive.UnarchiveEvent = function(type) { |     bitjs.archive.UnarchiveEvent = function(type) { | ||||||
|   /** |         /** | ||||||
|    * The event type. |         * The event type. | ||||||
|    * |         * | ||||||
|    * @type {string} |         * @type {string} | ||||||
|    */ |         */ | ||||||
|   this.type = type; |         this.type = type; | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The UnarchiveEvent types. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveEvent.Type = { |  | ||||||
|   START: 'start', |  | ||||||
|   PROGRESS: 'progress', |  | ||||||
|   EXTRACT: 'extract', |  | ||||||
|   FINISH: 'finish', |  | ||||||
|   INFO: 'info', |  | ||||||
|   ERROR: 'error' |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Useful for passing info up to the client (for debugging). |  | ||||||
|  * |  | ||||||
|  * @param {string} msg The info message. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveInfoEvent = function(msg) { |  | ||||||
|   bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.INFO); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * The information message. |  | ||||||
|    * |  | ||||||
|    * @type {string} |  | ||||||
|    */ |  | ||||||
|   this.msg = msg; |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.UnarchiveInfoEvent, bitjs.archive.UnarchiveEvent); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * An unrecoverable error has occured. |  | ||||||
|  * |  | ||||||
|  * @param {string} msg The error message. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveErrorEvent = function(msg) { |  | ||||||
|   bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.ERROR); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * The information message. |  | ||||||
|    * |  | ||||||
|    * @type {string} |  | ||||||
|    */ |  | ||||||
|   this.msg = msg; |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.UnarchiveErrorEvent, bitjs.archive.UnarchiveEvent); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Start event. |  | ||||||
|  * |  | ||||||
|  * @param {string} msg The info message. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveStartEvent = function() { |  | ||||||
|   bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.START); |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.UnarchiveStartEvent, bitjs.archive.UnarchiveEvent); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Finish event. |  | ||||||
|  * |  | ||||||
|  * @param {string} msg The info message. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveFinishEvent = function() { |  | ||||||
|   bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.FINISH); |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.UnarchiveFinishEvent, bitjs.archive.UnarchiveEvent); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Progress event. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveProgressEvent = function( |  | ||||||
|     currentFilename, |  | ||||||
|     currentFileNumber, |  | ||||||
|     currentBytesUnarchivedInFile, |  | ||||||
|     currentBytesUnarchived, |  | ||||||
|     totalUncompressedBytesInArchive, |  | ||||||
|     totalFilesInArchive) { |  | ||||||
|   bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.PROGRESS); |  | ||||||
|  |  | ||||||
|   this.currentFilename = currentFilename; |  | ||||||
|   this.currentFileNumber = currentFileNumber; |  | ||||||
|   this.currentBytesUnarchivedInFile = currentBytesUnarchivedInFile; |  | ||||||
|   this.totalFilesInArchive = totalFilesInArchive; |  | ||||||
|   this.currentBytesUnarchived = currentBytesUnarchived; |  | ||||||
|   this.totalUncompressedBytesInArchive = totalUncompressedBytesInArchive; |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.UnarchiveProgressEvent, bitjs.archive.UnarchiveEvent); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * All extracted files returned by an Unarchiver will implement |  | ||||||
|  * the following interface: |  | ||||||
|  * |  | ||||||
|  * interface UnarchivedFile { |  | ||||||
|  *   string filename |  | ||||||
|  *   TypedArray fileData   |  | ||||||
|  * } |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Extract event. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.UnarchiveExtractEvent = function(unarchivedFile) { |  | ||||||
|   bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.EXTRACT); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * @type {UnarchivedFile} |  | ||||||
|    */ |  | ||||||
|   this.unarchivedFile = unarchivedFile; |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.UnarchiveExtractEvent, bitjs.archive.UnarchiveEvent); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Base class for all Unarchivers. |  | ||||||
|  * |  | ||||||
|  * @param {ArrayBuffer} arrayBuffer The Array Buffer. |  | ||||||
|  * @param {string} opt_pathToBitJS Optional string for where the BitJS files are located. |  | ||||||
|  * @constructor |  | ||||||
|  */ |  | ||||||
| bitjs.archive.Unarchiver = function(arrayBuffer, opt_pathToBitJS) { |  | ||||||
|   /** |  | ||||||
|    * The ArrayBuffer object. |  | ||||||
|    * @type {ArrayBuffer} |  | ||||||
|    * @protected |  | ||||||
|    */ |  | ||||||
|   this.ab = arrayBuffer; |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * The path to the BitJS files. |  | ||||||
|    * @type {string} |  | ||||||
|    * @private |  | ||||||
|    */ |  | ||||||
|   this.pathToBitJS_ = opt_pathToBitJS || ''; |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * A map from event type to an array of listeners. |  | ||||||
|    * @type {Map.<string, Array>} |  | ||||||
|    */ |  | ||||||
|   this.listeners_ = {}; |  | ||||||
|   for (var type in bitjs.archive.UnarchiveEvent.Type) { |  | ||||||
|     this.listeners_[bitjs.archive.UnarchiveEvent.Type[type]] = []; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Private web worker initialized during start(). |  | ||||||
|  * @type {Worker} |  | ||||||
|  * @private |  | ||||||
|  */ |  | ||||||
| bitjs.archive.Unarchiver.prototype.worker_ = null; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * This method must be overridden by the subclass to return the script filename. |  | ||||||
|  * @return {string} The script filename. |  | ||||||
|  * @protected. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.Unarchiver.prototype.getScriptFileName = function() { |  | ||||||
|   throw 'Subclasses of AbstractUnarchiver must overload getScriptFileName()'; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Adds an event listener for UnarchiveEvents. |  | ||||||
|  * |  | ||||||
|  * @param {string} Event type. |  | ||||||
|  * @param {function} An event handler function. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.Unarchiver.prototype.addEventListener = function(type, listener) { |  | ||||||
|   if (type in this.listeners_) { |  | ||||||
|     if (this.listeners_[type].indexOf(listener) == -1) { |  | ||||||
|       this.listeners_[type].push(listener); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Removes an event listener. |  | ||||||
|  * |  | ||||||
|  * @param {string} Event type. |  | ||||||
|  * @param {EventListener|function} An event listener or handler function. |  | ||||||
|  */ |  | ||||||
| bitjs.archive.Unarchiver.prototype.removeEventListener = function(type, listener) { |  | ||||||
|   if (type in this.listeners_) { |  | ||||||
|     var index = this.listeners_[type].indexOf(listener); |  | ||||||
|     if (index != -1) { |  | ||||||
|       this.listeners_[type].splice(index, 1); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Receive an event and pass it to the listener functions. |  | ||||||
|  * |  | ||||||
|  * @param {bitjs.archive.UnarchiveEvent} e |  | ||||||
|  * @private |  | ||||||
|  */ |  | ||||||
| bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { |  | ||||||
|   if ((e instanceof bitjs.archive.UnarchiveEvent || e.type) &&  |  | ||||||
|       this.listeners_[e.type] instanceof Array) { |  | ||||||
|     this.listeners_[e.type].forEach(function (listener) { listener(e) }); |  | ||||||
|     if (e.type == bitjs.archive.UnarchiveEvent.Type.FINISH) { |  | ||||||
|         this.worker_.terminate(); |  | ||||||
|     } |  | ||||||
|   } else { |  | ||||||
|     console.log(e); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Starts the unarchive in a separate Web Worker thread and returns immediately. |  | ||||||
|  */ |  | ||||||
|  bitjs.archive.Unarchiver.prototype.start = function() { |  | ||||||
|   var me = this; |  | ||||||
|   var scriptFileName = this.pathToBitJS_ + this.getScriptFileName(); |  | ||||||
|   if (scriptFileName) { |  | ||||||
|     this.worker_ = new Worker(scriptFileName); |  | ||||||
|  |  | ||||||
|     this.worker_.onerror = function(e) { |  | ||||||
|       console.log('Worker error: message = ' + e.message); |  | ||||||
|       throw e; |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     this.worker_.onmessage = function(e) { |     /** | ||||||
|       if (typeof e.data == 'string') { |      * The UnarchiveEvent types. | ||||||
|         // Just log any strings the workers pump our way. |      */ | ||||||
|         console.log(e.data); |     bitjs.archive.UnarchiveEvent.Type = { | ||||||
|       } else { |         START: 'start', | ||||||
|         // Assume that it is an UnarchiveEvent.  Some browsers preserve the 'type' |         PROGRESS: 'progress', | ||||||
|         // so that instanceof UnarchiveEvent returns true, but others do not. |         EXTRACT: 'extract', | ||||||
|         me.handleWorkerEvent_(e.data); |         FINISH: 'finish', | ||||||
|       }  |         INFO: 'info', | ||||||
|  |         ERROR: 'error' | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     this.worker_.postMessage({file: this.ab}); |     /** | ||||||
|   } |      * Useful for passing info up to the client (for debugging). | ||||||
| }; |      * | ||||||
|  |      * @param {string} msg The info message. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.UnarchiveInfoEvent = function(msg) { | ||||||
|  |         bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.INFO); | ||||||
|  |  | ||||||
| /** |         /** | ||||||
|  * Terminates the Web Worker for this Unarchiver and returns immediately. |         * The information message. | ||||||
|  */ |         * | ||||||
| bitjs.archive.Unarchiver.prototype.stop = function() { |         * @type {string} | ||||||
|   if (this.worker_) { |         */ | ||||||
|     this.worker_.terminate(); |         this.msg = msg; | ||||||
|   } |     }; | ||||||
| }; |     bitjs.inherits(bitjs.archive.UnarchiveInfoEvent, bitjs.archive.UnarchiveEvent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * An unrecoverable error has occured. | ||||||
|  |      * | ||||||
|  |      * @param {string} msg The error message. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.UnarchiveErrorEvent = function(msg) { | ||||||
|  |         bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.ERROR); | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |         * The information message. | ||||||
|  |         * | ||||||
|  |         * @type {string} | ||||||
|  |         */ | ||||||
|  |         this.msg = msg; | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.UnarchiveErrorEvent, bitjs.archive.UnarchiveEvent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Start event. | ||||||
|  |      * | ||||||
|  |      * @param {string} msg The info message. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.UnarchiveStartEvent = function() { | ||||||
|  |         bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.START); | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.UnarchiveStartEvent, bitjs.archive.UnarchiveEvent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Finish event. | ||||||
|  |      * | ||||||
|  |      * @param {string} msg The info message. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.UnarchiveFinishEvent = function() { | ||||||
|  |         bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.FINISH); | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.UnarchiveFinishEvent, bitjs.archive.UnarchiveEvent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Progress event. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.UnarchiveProgressEvent = function( | ||||||
|  |             currentFilename, | ||||||
|  |             currentFileNumber, | ||||||
|  |             currentBytesUnarchivedInFile, | ||||||
|  |             currentBytesUnarchived, | ||||||
|  |             totalUncompressedBytesInArchive, | ||||||
|  |             totalFilesInArchive) | ||||||
|  |     { | ||||||
|  |         bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.PROGRESS); | ||||||
|  |  | ||||||
|  |         this.currentFilename = currentFilename; | ||||||
|  |         this.currentFileNumber = currentFileNumber; | ||||||
|  |         this.currentBytesUnarchivedInFile = currentBytesUnarchivedInFile; | ||||||
|  |         this.totalFilesInArchive = totalFilesInArchive; | ||||||
|  |         this.currentBytesUnarchived = currentBytesUnarchived; | ||||||
|  |         this.totalUncompressedBytesInArchive = totalUncompressedBytesInArchive; | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.UnarchiveProgressEvent, bitjs.archive.UnarchiveEvent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * All extracted files returned by an Unarchiver will implement | ||||||
|  |      * the following interface: | ||||||
|  |      * | ||||||
|  |      * interface UnarchivedFile { | ||||||
|  |      *   string filename | ||||||
|  |      *   TypedArray fileData | ||||||
|  |      * } | ||||||
|  |      * | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Extract event. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.UnarchiveExtractEvent = function(unarchivedFile) { | ||||||
|  |         bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.EXTRACT); | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |         * @type {UnarchivedFile} | ||||||
|  |         */ | ||||||
|  |         this.unarchivedFile = unarchivedFile; | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.UnarchiveExtractEvent, bitjs.archive.UnarchiveEvent); | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Unzipper |      * Base class for all Unarchivers. | ||||||
|  * @extends {bitjs.archive.Unarchiver} |      * | ||||||
|  * @constructor |      * @param {ArrayBuffer} arrayBuffer The Array Buffer. | ||||||
|  */ |      * @param {string} opt_pathToBitJS Optional string for where the BitJS files are located. | ||||||
| bitjs.archive.Unzipper = function(arrayBuffer, opt_pathToBitJS) { |      * @constructor | ||||||
|   bitjs.base(this, arrayBuffer, opt_pathToBitJS); |      */ | ||||||
| }; |     bitjs.archive.Unarchiver = function(arrayBuffer, opt_pathToBitJS) { | ||||||
| bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver); |         /** | ||||||
| bitjs.archive.Unzipper.prototype.getScriptFileName = function() { return 'unzip.js' }; |         * The ArrayBuffer object. | ||||||
|  |         * @type {ArrayBuffer} | ||||||
|  |         * @protected | ||||||
|  |         */ | ||||||
|  |         this.ab = arrayBuffer; | ||||||
|  |  | ||||||
| /** |         /** | ||||||
|  * Unrarrer |         * The path to the BitJS files. | ||||||
|  * @extends {bitjs.archive.Unarchiver} |         * @type {string} | ||||||
|  * @constructor |         * @private | ||||||
|  */ |         */ | ||||||
| bitjs.archive.Unrarrer = function(arrayBuffer, opt_pathToBitJS) { |         this.pathToBitJS_ = opt_pathToBitJS || ''; | ||||||
|   bitjs.base(this, arrayBuffer, opt_pathToBitJS); |  | ||||||
| }; |  | ||||||
| bitjs.inherits(bitjs.archive.Unrarrer, bitjs.archive.Unarchiver); |  | ||||||
| bitjs.archive.Unrarrer.prototype.getScriptFileName = function() { return 'unrar.js' }; |  | ||||||
|  |  | ||||||
| /** |         /** | ||||||
|  * Untarrer |         * A map from event type to an array of listeners. | ||||||
|  * @extends {bitjs.archive.Unarchiver} |         * @type {Map.<string, Array>} | ||||||
|  * @constructor |         */ | ||||||
|  */ |         this.listeners_ = {}; | ||||||
| bitjs.archive.Untarrer = function(arrayBuffer, opt_pathToBitJS) { |         for (var type in bitjs.archive.UnarchiveEvent.Type) { | ||||||
|   bitjs.base(this, arrayBuffer, opt_pathToBitJS); |             this.listeners_[bitjs.archive.UnarchiveEvent.Type[type]] = []; | ||||||
| }; |         } | ||||||
| bitjs.inherits(bitjs.archive.Untarrer, bitjs.archive.Unarchiver); |     }; | ||||||
| bitjs.archive.Untarrer.prototype.getScriptFileName = function() { return 'untar.js' }; |  | ||||||
|  |     /** | ||||||
|  |      * Private web worker initialized during start(). | ||||||
|  |      * @type {Worker} | ||||||
|  |      * @private | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unarchiver.prototype.worker_ = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * This method must be overridden by the subclass to return the script filename. | ||||||
|  |      * @return {string} The script filename. | ||||||
|  |      * @protected. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unarchiver.prototype.getScriptFileName = function() { | ||||||
|  |         throw 'Subclasses of AbstractUnarchiver must overload getScriptFileName()'; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Adds an event listener for UnarchiveEvents. | ||||||
|  |      * | ||||||
|  |      * @param {string} Event type. | ||||||
|  |      * @param {function} An event handler function. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unarchiver.prototype.addEventListener = function(type, listener) { | ||||||
|  |         if (type in this.listeners_) { | ||||||
|  |             if (this.listeners_[type].indexOf(listener) == -1) { | ||||||
|  |                 this.listeners_[type].push(listener); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Removes an event listener. | ||||||
|  |      * | ||||||
|  |      * @param {string} Event type. | ||||||
|  |      * @param {EventListener|function} An event listener or handler function. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unarchiver.prototype.removeEventListener = function(type, listener) { | ||||||
|  |         if (type in this.listeners_) { | ||||||
|  |             var index = this.listeners_[type].indexOf(listener); | ||||||
|  |             if (index != -1) { | ||||||
|  |                 this.listeners_[type].splice(index, 1); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Receive an event and pass it to the listener functions. | ||||||
|  |      * | ||||||
|  |      * @param {bitjs.archive.UnarchiveEvent} e | ||||||
|  |      * @private | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { | ||||||
|  |         if ((e instanceof bitjs.archive.UnarchiveEvent || e.type) && | ||||||
|  |             this.listeners_[e.type] instanceof Array) { | ||||||
|  |             this.listeners_[e.type].forEach(function (listener) { listener(e) }); | ||||||
|  |             if (e.type == bitjs.archive.UnarchiveEvent.Type.FINISH) { | ||||||
|  |                 this.worker_.terminate(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             console.log(e); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Starts the unarchive in a separate Web Worker thread and returns immediately. | ||||||
|  |      */ | ||||||
|  |      bitjs.archive.Unarchiver.prototype.start = function() { | ||||||
|  |         var me = this; | ||||||
|  |         var scriptFileName = this.pathToBitJS_ + this.getScriptFileName(); | ||||||
|  |         if (scriptFileName) { | ||||||
|  |             this.worker_ = new Worker(scriptFileName); | ||||||
|  |  | ||||||
|  |             this.worker_.onerror = function(e) { | ||||||
|  |                 console.log('Worker error: message = ' + e.message); | ||||||
|  |                 throw e; | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             this.worker_.onmessage = function(e) { | ||||||
|  |                 if (typeof e.data == 'string') { | ||||||
|  |                     // Just log any strings the workers pump our way. | ||||||
|  |                     console.log(e.data); | ||||||
|  |                 } else { | ||||||
|  |                     // Assume that it is an UnarchiveEvent.  Some browsers preserve the 'type' | ||||||
|  |                     // so that instanceof UnarchiveEvent returns true, but others do not. | ||||||
|  |                     me.handleWorkerEvent_(e.data); | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             this.worker_.postMessage({file: this.ab}); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Terminates the Web Worker for this Unarchiver and returns immediately. | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unarchiver.prototype.stop = function() { | ||||||
|  |         if (this.worker_) { | ||||||
|  |             this.worker_.terminate(); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Unzipper | ||||||
|  |      * @extends {bitjs.archive.Unarchiver} | ||||||
|  |      * @constructor | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unzipper = function(arrayBuffer, opt_pathToBitJS) { | ||||||
|  |         bitjs.base(this, arrayBuffer, opt_pathToBitJS); | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver); | ||||||
|  |     bitjs.archive.Unzipper.prototype.getScriptFileName = function() { return 'unzip.js' }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Unrarrer | ||||||
|  |      * @extends {bitjs.archive.Unarchiver} | ||||||
|  |      * @constructor | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Unrarrer = function(arrayBuffer, opt_pathToBitJS) { | ||||||
|  |         bitjs.base(this, arrayBuffer, opt_pathToBitJS); | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.Unrarrer, bitjs.archive.Unarchiver); | ||||||
|  |     bitjs.archive.Unrarrer.prototype.getScriptFileName = function() { return 'unrar.js' }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Untarrer | ||||||
|  |      * @extends {bitjs.archive.Unarchiver} | ||||||
|  |      * @constructor | ||||||
|  |      */ | ||||||
|  |     bitjs.archive.Untarrer = function(arrayBuffer, opt_pathToBitJS) { | ||||||
|  |         bitjs.base(this, arrayBuffer, opt_pathToBitJS); | ||||||
|  |     }; | ||||||
|  |     bitjs.inherits(bitjs.archive.Untarrer, bitjs.archive.Unarchiver); | ||||||
|  |     bitjs.archive.Untarrer.prototype.getScriptFileName = function() { return 'untar.js' }; | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
| @@ -14,470 +14,469 @@ bitjs.io = bitjs.io || {}; | |||||||
|  |  | ||||||
| (function() { | (function() { | ||||||
|  |  | ||||||
| // mask for getting the Nth bit (zero-based) |     // mask for getting the Nth bit (zero-based) | ||||||
| bitjs.BIT = [	0x01, 0x02, 0x04, 0x08,  |     bitjs.BIT = [	0x01, 0x02, 0x04, 0x08, | ||||||
|     0x10, 0x20, 0x40, 0x80, |         0x10, 0x20, 0x40, 0x80, | ||||||
|     0x100, 0x200, 0x400, 0x800,  |         0x100, 0x200, 0x400, 0x800, | ||||||
|     0x1000, 0x2000, 0x4000, 0x8000]; |         0x1000, 0x2000, 0x4000, 0x8000]; | ||||||
|  |  | ||||||
| // mask for getting N number of bits (0-8) |     // mask for getting N number of bits (0-8) | ||||||
| var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ]; |     var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ]; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * This bit stream peeks and consumes bits out of a binary stream. |      * This bit stream peeks and consumes bits out of a binary stream. | ||||||
|  * |      * | ||||||
|  * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. |      * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. | ||||||
|  * @param {boolean} rtl Whether the stream reads bits from the byte starting |      * @param {boolean} rtl Whether the stream reads bits from the byte starting | ||||||
|  *     from bit 7 to 0 (true) or bit 0 to 7 (false). |      *     from bit 7 to 0 (true) or bit 0 to 7 (false). | ||||||
|  * @param {Number} opt_offset The offset into the ArrayBuffer |      * @param {Number} opt_offset The offset into the ArrayBuffer | ||||||
|  * @param {Number} opt_length The length of this BitStream |      * @param {Number} opt_length The length of this BitStream | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream = function(ab, rtl, opt_offset, opt_length) { |     bitjs.io.BitStream = function(ab, rtl, opt_offset, opt_length) { | ||||||
|   if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") { |         if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") { | ||||||
|     throw "Error! BitArray constructed with an invalid ArrayBuffer object"; |             throw "Error! BitArray constructed with an invalid ArrayBuffer object"; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var offset = opt_offset || 0; |         var offset = opt_offset || 0; | ||||||
|   var length = opt_length || ab.byteLength; |         var length = opt_length || ab.byteLength; | ||||||
|   this.bytes = new Uint8Array(ab, offset, length); |         this.bytes = new Uint8Array(ab, offset, length); | ||||||
|   this.bytePtr = 0; // tracks which byte we are on |         this.bytePtr = 0; // tracks which byte we are on | ||||||
|   this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7) |         this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7) | ||||||
|   this.peekBits = rtl ? this.peekBits_rtl : this.peekBits_ltr; |         this.peekBits = rtl ? this.peekBits_rtl : this.peekBits_ltr; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  *   byte0      byte1      byte2      byte3 |      *   byte0      byte1      byte2      byte3 | ||||||
|  * 7......0 | 7......0 | 7......0 | 7......0 |      * 7......0 | 7......0 | 7......0 | 7......0 | ||||||
|  *  |      * | ||||||
|  * The bit pointer starts at bit0 of byte0 and moves left until it reaches |      * The bit pointer starts at bit0 of byte0 and moves left until it reaches | ||||||
|  * bit7 of byte0, then jumps to bit0 of byte1, etc. |      * bit7 of byte0, then jumps to bit0 of byte1, etc. | ||||||
|  * @param {number} n The number of bits to peek. |      * @param {number} n The number of bits to peek. | ||||||
|  * @param {boolean=} movePointers Whether to move the pointer, defaults false. |      * @param {boolean=} movePointers Whether to move the pointer, defaults false. | ||||||
|  * @return {number} The peeked bits, as an unsigned number. |      * @return {number} The peeked bits, as an unsigned number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream.prototype.peekBits_ltr = function(n, movePointers) { |     bitjs.io.BitStream.prototype.peekBits_ltr = function(n, movePointers) { | ||||||
|   if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n != typeof 1) { | ||||||
|     return 0; |             return 0; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var movePointers = movePointers || false, |         var movePointers = movePointers || false, | ||||||
|     bytePtr = this.bytePtr, |             bytePtr = this.bytePtr, | ||||||
|     bitPtr = this.bitPtr, |             bitPtr = this.bitPtr, | ||||||
|     result = 0, |             result = 0, | ||||||
|     bitsIn = 0, |             bitsIn = 0, | ||||||
|     bytes = this.bytes; |             bytes = this.bytes; | ||||||
|  |  | ||||||
|   // keep going until we have no more bits left to peek at |         // keep going until we have no more bits left to peek at | ||||||
|   // TODO: Consider putting all bits from bytes we will need into a variable and then |         // TODO: Consider putting all bits from bytes we will need into a variable and then | ||||||
|   //       shifting/masking it to just extract the bits we want. |         //       shifting/masking it to just extract the bits we want. | ||||||
|   //       This could be considerably faster when reading more than 3 or 4 bits at a time. |         //       This could be considerably faster when reading more than 3 or 4 bits at a time. | ||||||
|   while (n > 0) { |         while (n > 0) { | ||||||
|     if (bytePtr >= bytes.length) { |             if (bytePtr >= bytes.length) { | ||||||
|       throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + |                 throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + | ||||||
|         bytes.length + ", bitPtr=" + bitPtr; |                     bytes.length + ", bitPtr=" + bitPtr; | ||||||
|       return -1; |                 return -1; | ||||||
|     } |             } | ||||||
|  |  | ||||||
|     var numBitsLeftInThisByte = (8 - bitPtr); |             var numBitsLeftInThisByte = (8 - bitPtr); | ||||||
|     if (n >= numBitsLeftInThisByte) { |             if (n >= numBitsLeftInThisByte) { | ||||||
|       var mask = (BITMASK[numBitsLeftInThisByte] << bitPtr); |                 var mask = (BITMASK[numBitsLeftInThisByte] << bitPtr); | ||||||
|       result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); |                 result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); | ||||||
|  |  | ||||||
|       bytePtr++; |                 bytePtr++; | ||||||
|       bitPtr = 0; |                 bitPtr = 0; | ||||||
|       bitsIn += numBitsLeftInThisByte; |                 bitsIn += numBitsLeftInThisByte; | ||||||
|       n -= numBitsLeftInThisByte; |                 n -= numBitsLeftInThisByte; | ||||||
|     } |             } | ||||||
|     else { |             else { | ||||||
|       var mask = (BITMASK[n] << bitPtr); |                 var mask = (BITMASK[n] << bitPtr); | ||||||
|       result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); |                 result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); | ||||||
|  |  | ||||||
|       bitPtr += n; |                 bitPtr += n; | ||||||
|       bitsIn += n; |                 bitsIn += n; | ||||||
|       n = 0; |                 n = 0; | ||||||
|     } |             } | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   if (movePointers) { |         if (movePointers) { | ||||||
|     this.bitPtr = bitPtr; |             this.bitPtr = bitPtr; | ||||||
|     this.bytePtr = bytePtr; |             this.bytePtr = bytePtr; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   return result; |         return result; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  *   byte0      byte1      byte2      byte3 |      *   byte0      byte1      byte2      byte3 | ||||||
|  * 7......0 | 7......0 | 7......0 | 7......0 |      * 7......0 | 7......0 | 7......0 | 7......0 | ||||||
|  * |      * | ||||||
|  * The bit pointer starts at bit7 of byte0 and moves right until it reaches |      * The bit pointer starts at bit7 of byte0 and moves right until it reaches | ||||||
|  * bit0 of byte0, then goes to bit7 of byte1, etc. |      * bit0 of byte0, then goes to bit7 of byte1, etc. | ||||||
|  * @param {number} n The number of bits to peek. |      * @param {number} n The number of bits to peek. | ||||||
|  * @param {boolean=} movePointers Whether to move the pointer, defaults false. |      * @param {boolean=} movePointers Whether to move the pointer, defaults false. | ||||||
|  * @return {number} The peeked bits, as an unsigned number. |      * @return {number} The peeked bits, as an unsigned number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream.prototype.peekBits_rtl = function(n, movePointers) { |     bitjs.io.BitStream.prototype.peekBits_rtl = function(n, movePointers) { | ||||||
|   if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n != typeof 1) { | ||||||
|     return 0; |             return 0; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var movePointers = movePointers || false, |         var movePointers = movePointers || false, | ||||||
|     bytePtr = this.bytePtr, |             bytePtr = this.bytePtr, | ||||||
|     bitPtr = this.bitPtr, |             bitPtr = this.bitPtr, | ||||||
|     result = 0, |             result = 0, | ||||||
|     bytes = this.bytes; |             bytes = this.bytes; | ||||||
|  |  | ||||||
|   // keep going until we have no more bits left to peek at |         // keep going until we have no more bits left to peek at | ||||||
|   // TODO: Consider putting all bits from bytes we will need into a variable and then |         // TODO: Consider putting all bits from bytes we will need into a variable and then | ||||||
|   //       shifting/masking it to just extract the bits we want. |         //       shifting/masking it to just extract the bits we want. | ||||||
|   //       This could be considerably faster when reading more than 3 or 4 bits at a time. |         //       This could be considerably faster when reading more than 3 or 4 bits at a time. | ||||||
|   while (n > 0) { |         while (n > 0) { | ||||||
|    |  | ||||||
|     if (bytePtr >= bytes.length) { |             if (bytePtr >= bytes.length) { | ||||||
|       throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + |                 throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + | ||||||
|         bytes.length + ", bitPtr=" + bitPtr; |                     bytes.length + ", bitPtr=" + bitPtr; | ||||||
|       return -1; |                 return -1; | ||||||
|     } |             } | ||||||
|  |  | ||||||
|     var numBitsLeftInThisByte = (8 - bitPtr); |             var numBitsLeftInThisByte = (8 - bitPtr); | ||||||
|     if (n >= numBitsLeftInThisByte) { |             if (n >= numBitsLeftInThisByte) { | ||||||
|       result <<= numBitsLeftInThisByte; |                 result <<= numBitsLeftInThisByte; | ||||||
|       result |= (BITMASK[numBitsLeftInThisByte] & bytes[bytePtr]); |                 result |= (BITMASK[numBitsLeftInThisByte] & bytes[bytePtr]); | ||||||
|       bytePtr++; |                 bytePtr++; | ||||||
|       bitPtr = 0; |                 bitPtr = 0; | ||||||
|       n -= numBitsLeftInThisByte; |                 n -= numBitsLeftInThisByte; | ||||||
|     } |             } | ||||||
|     else { |             else { | ||||||
|       result <<= n; |                 result <<= n; | ||||||
|       result |= ((bytes[bytePtr] & (BITMASK[n] << (8 - n - bitPtr))) >> (8 - n - bitPtr)); |                 result |= ((bytes[bytePtr] & (BITMASK[n] << (8 - n - bitPtr))) >> (8 - n - bitPtr)); | ||||||
|  |  | ||||||
|       bitPtr += n; |                 bitPtr += n; | ||||||
|       n = 0; |                 n = 0; | ||||||
|     } |             } | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   if (movePointers) { |         if (movePointers) { | ||||||
|     this.bitPtr = bitPtr; |             this.bitPtr = bitPtr; | ||||||
|     this.bytePtr = bytePtr; |             this.bytePtr = bytePtr; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   return result; |         return result; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Some voodoo magic. |      * Some voodoo magic. | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream.prototype.getBits = function() { |     bitjs.io.BitStream.prototype.getBits = function() { | ||||||
|   return (((((this.bytes[this.bytePtr] & 0xff) << 16) + |         return (((((this.bytes[this.bytePtr] & 0xff) << 16) + | ||||||
|               ((this.bytes[this.bytePtr+1] & 0xff) << 8) + |             ((this.bytes[this.bytePtr+1] & 0xff) << 8) + | ||||||
|               ((this.bytes[this.bytePtr+2] & 0xff))) >>> (8-this.bitPtr)) & 0xffff); |             ((this.bytes[this.bytePtr+2] & 0xff))) >>> (8-this.bitPtr)) & 0xffff); | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Reads n bits out of the stream, consuming them (moving the bit pointer). |      * Reads n bits out of the stream, consuming them (moving the bit pointer). | ||||||
|  * @param {number} n The number of bits to read. |      * @param {number} n The number of bits to read. | ||||||
|  * @return {number} The read bits, as an unsigned number. |      * @return {number} The read bits, as an unsigned number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream.prototype.readBits = function(n) { |     bitjs.io.BitStream.prototype.readBits = function(n) { | ||||||
|   return this.peekBits(n, true); |         return this.peekBits(n, true); | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * This returns n bytes as a sub-array, advancing the pointer if movePointers |      * This returns n bytes as a sub-array, advancing the pointer if movePointers | ||||||
|  * is true.  Only use this for uncompressed blocks as this throws away remaining |      * is true.  Only use this for uncompressed blocks as this throws away remaining | ||||||
|  * bits in the current byte. |      * bits in the current byte. | ||||||
|  * @param {number} n The number of bytes to peek. |      * @param {number} n The number of bytes to peek. | ||||||
|  * @param {boolean=} movePointers Whether to move the pointer, defaults false. |      * @param {boolean=} movePointers Whether to move the pointer, defaults false. | ||||||
|  * @return {Uint8Array} The subarray. |      * @return {Uint8Array} The subarray. | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream.prototype.peekBytes = function(n, movePointers) { |     bitjs.io.BitStream.prototype.peekBytes = function(n, movePointers) { | ||||||
|   if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n != typeof 1) { | ||||||
|     return 0; |             return 0; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   // from http://tools.ietf.org/html/rfc1951#page-11 |         // from http://tools.ietf.org/html/rfc1951#page-11 | ||||||
|   // "Any bits of input up to the next byte boundary are ignored." |         // "Any bits of input up to the next byte boundary are ignored." | ||||||
|   while (this.bitPtr != 0) { |         while (this.bitPtr != 0) { | ||||||
|     this.readBits(1); |             this.readBits(1); | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var movePointers = movePointers || false; |         var movePointers = movePointers || false; | ||||||
|   var bytePtr = this.bytePtr, |         var bytePtr = this.bytePtr, | ||||||
|       bitPtr = this.bitPtr; |             bitPtr = this.bitPtr; | ||||||
|  |  | ||||||
|   var result = this.bytes.subarray(bytePtr, bytePtr + n); |         var result = this.bytes.subarray(bytePtr, bytePtr + n); | ||||||
|  |  | ||||||
|   if (movePointers) { |         if (movePointers) { | ||||||
|     this.bytePtr += n; |             this.bytePtr += n; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   return result; |         return result; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @return {Uint8Array} The subarray. |      * @return {Uint8Array} The subarray. | ||||||
|  */ |      */ | ||||||
| bitjs.io.BitStream.prototype.readBytes = function(n) { |     bitjs.io.BitStream.prototype.readBytes = function(n) { | ||||||
|   return this.peekBytes(n, true); |         return this.peekBytes(n, true); | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * This object allows you to peek and consume bytes as numbers and strings |      * This object allows you to peek and consume bytes as numbers and strings | ||||||
|  * out of an ArrayBuffer.  In this buffer, everything must be byte-aligned. |      * out of an ArrayBuffer.  In this buffer, everything must be byte-aligned. | ||||||
|  * |      * | ||||||
|  * @param {ArrayBuffer} ab The ArrayBuffer object. |      * @param {ArrayBuffer} ab The ArrayBuffer object. | ||||||
|  * @param {number=} opt_offset The offset into the ArrayBuffer |      * @param {number=} opt_offset The offset into the ArrayBuffer | ||||||
|  * @param {number=} opt_length The length of this BitStream |      * @param {number=} opt_length The length of this BitStream | ||||||
|  * @constructor |      * @constructor | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream = function(ab, opt_offset, opt_length) { |     bitjs.io.ByteStream = function(ab, opt_offset, opt_length) { | ||||||
|   var offset = opt_offset || 0; |         var offset = opt_offset || 0; | ||||||
|   var length = opt_length || ab.byteLength; |         var length = opt_length || ab.byteLength; | ||||||
|   this.bytes = new Uint8Array(ab, offset, length); |         this.bytes = new Uint8Array(ab, offset, length); | ||||||
|   this.ptr = 0; |         this.ptr = 0; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Peeks at the next n bytes as an unsigned number but does not advance the |      * Peeks at the next n bytes as an unsigned number but does not advance the | ||||||
|  * pointer |      * pointer | ||||||
|  * TODO: This apparently cannot read more than 4 bytes as a number? |      * TODO: This apparently cannot read more than 4 bytes as a number? | ||||||
|  * @param {number} n The number of bytes to peek at. |      * @param {number} n The number of bytes to peek at. | ||||||
|  * @return {number} The n bytes interpreted as an unsigned number. |      * @return {number} The n bytes interpreted as an unsigned number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.peekNumber = function(n) { |     bitjs.io.ByteStream.prototype.peekNumber = function(n) { | ||||||
|   // TODO: return error if n would go past the end of the stream? |         // TODO: return error if n would go past the end of the stream? | ||||||
|   if (n <= 0 || typeof n != typeof 1) |         if (n <= 0 || typeof n != typeof 1) | ||||||
|     return -1; |             return -1; | ||||||
|  |  | ||||||
|   var result = 0; |         var result = 0; | ||||||
|   // read from last byte to first byte and roll them in |         // read from last byte to first byte and roll them in | ||||||
|   var curByte = this.ptr + n - 1; |         var curByte = this.ptr + n - 1; | ||||||
|   while (curByte >= this.ptr) { |         while (curByte >= this.ptr) { | ||||||
|     result <<= 8; |             result <<= 8; | ||||||
|     result |= this.bytes[curByte]; |             result |= this.bytes[curByte]; | ||||||
|     --curByte; |             --curByte; | ||||||
|   } |         } | ||||||
|   return result; |         return result; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Returns the next n bytes as an unsigned number (or -1 on error) |      * Returns the next n bytes as an unsigned number (or -1 on error) | ||||||
|  * and advances the stream pointer n bytes. |      * and advances the stream pointer n bytes. | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @return {number} The n bytes interpreted as an unsigned number. |      * @return {number} The n bytes interpreted as an unsigned number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.readNumber = function(n) { |     bitjs.io.ByteStream.prototype.readNumber = function(n) { | ||||||
|   var num = this.peekNumber( n ); |         var num = this.peekNumber( n ); | ||||||
|   this.ptr += n; |         this.ptr += n; | ||||||
|   return num; |         return num; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Returns the next n bytes as a signed number but does not advance the |      * Returns the next n bytes as a signed number but does not advance the | ||||||
|  * pointer. |      * pointer. | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @return {number} The bytes interpreted as a signed number. |      * @return {number} The bytes interpreted as a signed number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.peekSignedNumber = function(n) { |     bitjs.io.ByteStream.prototype.peekSignedNumber = function(n) { | ||||||
|   var num = this.peekNumber(n); |         var num = this.peekNumber(n); | ||||||
|   var HALF = Math.pow(2, (n * 8) - 1); |         var HALF = Math.pow(2, (n * 8) - 1); | ||||||
|   var FULL = HALF * 2; |         var FULL = HALF * 2; | ||||||
|  |  | ||||||
|   if (num >= HALF) num -= FULL; |         if (num >= HALF) num -= FULL; | ||||||
|  |  | ||||||
|   return num; |         return num; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Returns the next n bytes as a signed number and advances the stream pointer. |      * Returns the next n bytes as a signed number and advances the stream pointer. | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @return {number} The bytes interpreted as a signed number. |      * @return {number} The bytes interpreted as a signed number. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.readSignedNumber = function(n) { |     bitjs.io.ByteStream.prototype.readSignedNumber = function(n) { | ||||||
|   var num = this.peekSignedNumber(n); |         var num = this.peekSignedNumber(n); | ||||||
|   this.ptr += n; |         this.ptr += n; | ||||||
|   return num; |         return num; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * This returns n bytes as a sub-array, advancing the pointer if movePointers |      * This returns n bytes as a sub-array, advancing the pointer if movePointers | ||||||
|  * is true. |      * is true. | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @param {boolean} movePointers Whether to move the pointers. |      * @param {boolean} movePointers Whether to move the pointers. | ||||||
|  * @return {Uint8Array} The subarray. |      * @return {Uint8Array} The subarray. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.peekBytes = function(n, movePointers) { |     bitjs.io.ByteStream.prototype.peekBytes = function(n, movePointers) { | ||||||
|   if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n != typeof 1) { | ||||||
|     return null; |             return null; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var result = this.bytes.subarray(this.ptr, this.ptr + n); |         var result = this.bytes.subarray(this.ptr, this.ptr + n); | ||||||
|  |  | ||||||
|   if (movePointers) { |         if (movePointers) { | ||||||
|     this.ptr += n; |             this.ptr += n; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   return result; |         return result; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Reads the next n bytes as a sub-array. |      * Reads the next n bytes as a sub-array. | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @return {Uint8Array} The subarray. |      * @return {Uint8Array} The subarray. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.readBytes = function(n) { |     bitjs.io.ByteStream.prototype.readBytes = function(n) { | ||||||
|   return this.peekBytes(n, true); |         return this.peekBytes(n, true); | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Peeks at the next n bytes as a string but does not advance the pointer. |      * Peeks at the next n bytes as a string but does not advance the pointer. | ||||||
|  * @param {number} n The number of bytes to peek at. |      * @param {number} n The number of bytes to peek at. | ||||||
|  * @return {string} The next n bytes as a string. |      * @return {string} The next n bytes as a string. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.peekString = function(n) { |     bitjs.io.ByteStream.prototype.peekString = function(n) { | ||||||
|   if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n != typeof 1) { | ||||||
|     return ""; |             return ""; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var result = ""; |         var result = ""; | ||||||
|   for (var p = this.ptr, end = this.ptr + n; p < end; ++p) { |         for (var p = this.ptr, end = this.ptr + n; p < end; ++p) { | ||||||
|     result += String.fromCharCode(this.bytes[p]); |             result += String.fromCharCode(this.bytes[p]); | ||||||
|   } |         } | ||||||
|   return result; |         return result; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Returns the next n bytes as an ASCII string and advances the stream pointer |      * Returns the next n bytes as an ASCII string and advances the stream pointer | ||||||
|  * n bytes. |      * n bytes. | ||||||
|  * @param {number} n The number of bytes to read. |      * @param {number} n The number of bytes to read. | ||||||
|  * @return {string} The next n bytes as a string. |      * @return {string} The next n bytes as a string. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteStream.prototype.readString = function(n) { |     bitjs.io.ByteStream.prototype.readString = function(n) { | ||||||
|   var strToReturn = this.peekString(n); |         var strToReturn = this.peekString(n); | ||||||
|   this.ptr += n; |         this.ptr += n; | ||||||
|   return strToReturn; |         return strToReturn; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * A write-only Byte buffer which uses a Uint8 Typed Array as a backing store. |      * A write-only Byte buffer which uses a Uint8 Typed Array as a backing store. | ||||||
|  * @param {number} numBytes The number of bytes to allocate. |      * @param {number} numBytes The number of bytes to allocate. | ||||||
|  * @constructor |      * @constructor | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteBuffer = function(numBytes) { |     bitjs.io.ByteBuffer = function(numBytes) { | ||||||
|   if (typeof numBytes != typeof 1 || numBytes <= 0) { |         if (typeof numBytes != typeof 1 || numBytes <= 0) { | ||||||
|     throw "Error! ByteBuffer initialized with '" + numBytes + "'"; |             throw "Error! ByteBuffer initialized with '" + numBytes + "'"; | ||||||
|   } |         } | ||||||
|   this.data = new Uint8Array(numBytes); |         this.data = new Uint8Array(numBytes); | ||||||
|   this.ptr = 0; |         this.ptr = 0; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * @param {number} b The byte to insert. |      * @param {number} b The byte to insert. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteBuffer.prototype.insertByte = function(b) { |     bitjs.io.ByteBuffer.prototype.insertByte = function(b) { | ||||||
|   // TODO: throw if byte is invalid? |         // TODO: throw if byte is invalid? | ||||||
|   this.data[this.ptr++] = b; |         this.data[this.ptr++] = b; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * @param {Array.<number>|Uint8Array|Int8Array} bytes The bytes to insert. |      * @param {Array.<number>|Uint8Array|Int8Array} bytes The bytes to insert. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteBuffer.prototype.insertBytes = function(bytes) { |     bitjs.io.ByteBuffer.prototype.insertBytes = function(bytes) { | ||||||
|   // TODO: throw if bytes is invalid? |         // TODO: throw if bytes is invalid? | ||||||
|   this.data.set(bytes, this.ptr); |         this.data.set(bytes, this.ptr); | ||||||
|   this.ptr += bytes.length; |         this.ptr += bytes.length; | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Writes an unsigned number into the next n bytes.  If the number is too large |      * Writes an unsigned number into the next n bytes.  If the number is too large | ||||||
|  * to fit into n bytes or is negative, an error is thrown. |      * to fit into n bytes or is negative, an error is thrown. | ||||||
|  * @param {number} num The unsigned number to write. |      * @param {number} num The unsigned number to write. | ||||||
|  * @param {number} numBytes The number of bytes to write the number into. |      * @param {number} numBytes The number of bytes to write the number into. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteBuffer.prototype.writeNumber = function(num, numBytes) { |     bitjs.io.ByteBuffer.prototype.writeNumber = function(num, numBytes) { | ||||||
|   if (numBytes < 1) { |         if (numBytes < 1) { | ||||||
|     throw 'Trying to write into too few bytes: ' + numBytes; |             throw 'Trying to write into too few bytes: ' + numBytes; | ||||||
|   } |         } | ||||||
|   if (num < 0) { |         if (num < 0) { | ||||||
|     throw 'Trying to write a negative number (' + num + |             throw 'Trying to write a negative number (' + num + | ||||||
|         ') as an unsigned number to an ArrayBuffer'; |                 ') as an unsigned number to an ArrayBuffer'; | ||||||
|   } |         } | ||||||
|   if (num > (Math.pow(2, numBytes * 8) - 1)) { |         if (num > (Math.pow(2, numBytes * 8) - 1)) { | ||||||
|     throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; |             throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   // Roll 8-bits at a time into an array of bytes. |         // Roll 8-bits at a time into an array of bytes. | ||||||
|   var bytes = []; |         var bytes = []; | ||||||
|   while (numBytes-- > 0) { |         while (numBytes-- > 0) { | ||||||
|     var eightBits = num & 255; |             var eightBits = num & 255; | ||||||
|     bytes.push(eightBits); |             bytes.push(eightBits); | ||||||
|     num >>= 8; |             num >>= 8; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   this.insertBytes(bytes); |         this.insertBytes(bytes); | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * Writes a signed number into the next n bytes.  If the number is too large |      * Writes a signed number into the next n bytes.  If the number is too large | ||||||
|  * to fit into n bytes, an error is thrown. |      * to fit into n bytes, an error is thrown. | ||||||
|  * @param {number} num The signed number to write. |      * @param {number} num The signed number to write. | ||||||
|  * @param {number} numBytes The number of bytes to write the number into. |      * @param {number} numBytes The number of bytes to write the number into. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteBuffer.prototype.writeSignedNumber = function(num, numBytes) { |     bitjs.io.ByteBuffer.prototype.writeSignedNumber = function(num, numBytes) { | ||||||
|   if (numBytes < 1) { |         if (numBytes < 1) { | ||||||
|     throw 'Trying to write into too few bytes: ' + numBytes; |             throw 'Trying to write into too few bytes: ' + numBytes; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   var HALF = Math.pow(2, (numBytes * 8) - 1); |         var HALF = Math.pow(2, (numBytes * 8) - 1); | ||||||
|   if (num >= HALF || num < -HALF) { |         if (num >= HALF || num < -HALF) { | ||||||
|     throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; |             throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   // Roll 8-bits at a time into an array of bytes. |         // Roll 8-bits at a time into an array of bytes. | ||||||
|   var bytes = []; |         var bytes = []; | ||||||
|   while (numBytes-- > 0) { |         while (numBytes-- > 0) { | ||||||
|     var eightBits = num & 255; |             var eightBits = num & 255; | ||||||
|     bytes.push(eightBits); |             bytes.push(eightBits); | ||||||
|     num >>= 8; |             num >>= 8; | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   this.insertBytes(bytes); |         this.insertBytes(bytes); | ||||||
| }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |     /** | ||||||
|  * @param {string} str The ASCII string to write. |      * @param {string} str The ASCII string to write. | ||||||
|  */ |      */ | ||||||
| bitjs.io.ByteBuffer.prototype.writeASCIIString = function(str) { |     bitjs.io.ByteBuffer.prototype.writeASCIIString = function(str) { | ||||||
|   for (var i = 0; i < str.length; ++i) { |         for (var i = 0; i < str.length; ++i) { | ||||||
|     var curByte = str.charCodeAt(i); |             var curByte = str.charCodeAt(i); | ||||||
|     if (curByte < 0 || curByte > 255) { |             if (curByte < 0 || curByte > 255) { | ||||||
|       throw 'Trying to write a non-ASCII string!'; |                 throw 'Trying to write a non-ASCII string!'; | ||||||
|     } |             } | ||||||
|     this.insertByte(curByte); |             this.insertByte(curByte); | ||||||
|   } |         } | ||||||
| }; |     }; | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user
	 OzzieIsaacs
					OzzieIsaacs