DataWorker.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. "use strict";
  2. var utils = require("../utils");
  3. var GenericWorker = require("./GenericWorker");
  4. // the size of the generated chunks
  5. // TODO expose this as a public variable
  6. var DEFAULT_BLOCK_SIZE = 16 * 1024;
  7. /**
  8. * A worker that reads a content and emits chunks.
  9. * @constructor
  10. * @param {Promise} dataP the promise of the data to split
  11. */
  12. function DataWorker(dataP) {
  13. GenericWorker.call(this, "DataWorker");
  14. var self = this;
  15. this.dataIsReady = false;
  16. this.index = 0;
  17. this.max = 0;
  18. this.data = null;
  19. this.type = "";
  20. this._tickScheduled = false;
  21. dataP.then(function (data) {
  22. self.dataIsReady = true;
  23. self.data = data;
  24. self.max = data && data.length || 0;
  25. self.type = utils.getTypeOf(data);
  26. if(!self.isPaused) {
  27. self._tickAndRepeat();
  28. }
  29. }, function (e) {
  30. self.error(e);
  31. });
  32. }
  33. utils.inherits(DataWorker, GenericWorker);
  34. /**
  35. * @see GenericWorker.cleanUp
  36. */
  37. DataWorker.prototype.cleanUp = function () {
  38. GenericWorker.prototype.cleanUp.call(this);
  39. this.data = null;
  40. };
  41. /**
  42. * @see GenericWorker.resume
  43. */
  44. DataWorker.prototype.resume = function () {
  45. if(!GenericWorker.prototype.resume.call(this)) {
  46. return false;
  47. }
  48. if (!this._tickScheduled && this.dataIsReady) {
  49. this._tickScheduled = true;
  50. utils.delay(this._tickAndRepeat, [], this);
  51. }
  52. return true;
  53. };
  54. /**
  55. * Trigger a tick a schedule an other call to this function.
  56. */
  57. DataWorker.prototype._tickAndRepeat = function() {
  58. this._tickScheduled = false;
  59. if(this.isPaused || this.isFinished) {
  60. return;
  61. }
  62. this._tick();
  63. if(!this.isFinished) {
  64. utils.delay(this._tickAndRepeat, [], this);
  65. this._tickScheduled = true;
  66. }
  67. };
  68. /**
  69. * Read and push a chunk.
  70. */
  71. DataWorker.prototype._tick = function() {
  72. if(this.isPaused || this.isFinished) {
  73. return false;
  74. }
  75. var size = DEFAULT_BLOCK_SIZE;
  76. var data = null, nextIndex = Math.min(this.max, this.index + size);
  77. if (this.index >= this.max) {
  78. // EOF
  79. return this.end();
  80. } else {
  81. switch(this.type) {
  82. case "string":
  83. data = this.data.substring(this.index, nextIndex);
  84. break;
  85. case "uint8array":
  86. data = this.data.subarray(this.index, nextIndex);
  87. break;
  88. case "array":
  89. case "nodebuffer":
  90. data = this.data.slice(this.index, nextIndex);
  91. break;
  92. }
  93. this.index = nextIndex;
  94. return this.push({
  95. data : data,
  96. meta : {
  97. percent : this.max ? this.index / this.max * 100 : 0
  98. }
  99. });
  100. }
  101. };
  102. module.exports = DataWorker;