| 'use strict'; |
| |
| var utils = require('../utils'); |
| var GenericWorker = require('./GenericWorker'); |
| |
| // the size of the generated chunks |
| // TODO expose this as a public variable |
| var DEFAULT_BLOCK_SIZE = 16 * 1024; |
| |
| /** |
| * A worker that reads a content and emits chunks. |
| * @constructor |
| * @param {Promise} dataP the promise of the data to split |
| */ |
| function DataWorker(dataP) { |
| GenericWorker.call(this, "DataWorker"); |
| var self = this; |
| this.dataIsReady = false; |
| this.index = 0; |
| this.max = 0; |
| this.data = null; |
| this.type = ""; |
| |
| this._tickScheduled = false; |
| |
| dataP.then(function (data) { |
| self.dataIsReady = true; |
| self.data = data; |
| self.max = data && data.length || 0; |
| self.type = utils.getTypeOf(data); |
| if(!self.isPaused) { |
| self._tickAndRepeat(); |
| } |
| }, function (e) { |
| self.error(e); |
| }); |
| } |
| |
| utils.inherits(DataWorker, GenericWorker); |
| |
| /** |
| * @see GenericWorker.cleanUp |
| */ |
| DataWorker.prototype.cleanUp = function () { |
| GenericWorker.prototype.cleanUp.call(this); |
| this.data = null; |
| }; |
| |
| /** |
| * @see GenericWorker.resume |
| */ |
| DataWorker.prototype.resume = function () { |
| if(!GenericWorker.prototype.resume.call(this)) { |
| return false; |
| } |
| |
| if (!this._tickScheduled && this.dataIsReady) { |
| this._tickScheduled = true; |
| utils.delay(this._tickAndRepeat, [], this); |
| } |
| return true; |
| }; |
| |
| /** |
| * Trigger a tick a schedule an other call to this function. |
| */ |
| DataWorker.prototype._tickAndRepeat = function() { |
| this._tickScheduled = false; |
| if(this.isPaused || this.isFinished) { |
| return; |
| } |
| this._tick(); |
| if(!this.isFinished) { |
| utils.delay(this._tickAndRepeat, [], this); |
| this._tickScheduled = true; |
| } |
| }; |
| |
| /** |
| * Read and push a chunk. |
| */ |
| DataWorker.prototype._tick = function() { |
| |
| if(this.isPaused || this.isFinished) { |
| return false; |
| } |
| |
| var size = DEFAULT_BLOCK_SIZE; |
| var data = null, nextIndex = Math.min(this.max, this.index + size); |
| if (this.index >= this.max) { |
| // EOF |
| return this.end(); |
| } else { |
| switch(this.type) { |
| case "string": |
| data = this.data.substring(this.index, nextIndex); |
| break; |
| case "uint8array": |
| data = this.data.subarray(this.index, nextIndex); |
| break; |
| case "array": |
| case "nodebuffer": |
| data = this.data.slice(this.index, nextIndex); |
| break; |
| } |
| this.index = nextIndex; |
| return this.push({ |
| data : data, |
| meta : { |
| percent : this.max ? this.index / this.max * 100 : 0 |
| } |
| }); |
| } |
| }; |
| |
| module.exports = DataWorker; |