diff --git a/extensions/firefox/content/PdfStreamConverter.jsm b/extensions/firefox/content/PdfStreamConverter.jsm index 4dd26a4a0..491c7f3a0 100644 --- a/extensions/firefox/content/PdfStreamConverter.jsm +++ b/extensions/firefox/content/PdfStreamConverter.jsm @@ -177,46 +177,38 @@ function makeContentReadable(obj, window) { // PDF data storage function PdfDataListener(length) { this.length = length; // less than 0, if length is unknown - this.data = new Uint8Array(length >= 0 ? length : 0x10000); - this.position = 0; + this.buffer = null; this.loaded = 0; } PdfDataListener.prototype = { append: function PdfDataListener_append(chunk) { - var willBeLoaded = this.loaded + chunk.length; - if (this.length >= 0 && this.length < willBeLoaded) { + // In most of the cases we will pass data as we receive it, but at the + // beginning of the loading we may accumulate some data. + if (!this.buffer) { + this.buffer = new Uint8Array(chunk); + } else { + var buffer = this.buffer; + var newBuffer = new Uint8Array(buffer.length + chunk.length); + newBuffer.set(buffer); + newBuffer.set(chunk, buffer.length); + this.buffer = newBuffer; + } + this.loaded += chunk.length; + if (this.length >= 0 && this.length < this.loaded) { this.length = -1; // reset the length, server is giving incorrect one } - if (this.length < 0 && this.data.length < willBeLoaded) { - // data length is unknown and new chunk will not fit in the existing - // buffer, resizing the buffer by doubling the its last length - var newLength = this.data.length; - for (; newLength < willBeLoaded; newLength *= 2) {} - var newData = new Uint8Array(newLength); - newData.set(this.data); - this.data = newData; - } - this.data.set(chunk, this.loaded); - this.loaded = willBeLoaded; this.onprogress(this.loaded, this.length >= 0 ? this.length : void(0)); }, readData: function PdfDataListener_readData() { - var data = this.data.subarray(this.position, this.loaded); - this.position = this.loaded; - return data; - }, - getData: function PdfDataListener_getData() { - var data = this.data; - if (this.loaded != data.length) - data = data.subarray(0, this.loaded); - delete this.data; // releasing temporary storage - return data; + var result = this.buffer; + this.buffer = null; + return result; }, finish: function PdfDataListener_finish() { this.isDataReady = true; if (this.oncompleteCallback) { - this.oncompleteCallback(this.getData()); + this.oncompleteCallback(this.readData()); } }, error: function PdfDataListener_error(errorCode) { @@ -232,7 +224,7 @@ PdfDataListener.prototype = { set oncomplete(value) { this.oncompleteCallback = value; if (this.isDataReady) { - value(this.getData()); + value(this.readData()); } if (this.errorCode) { value(null, this.errorCode); @@ -607,7 +599,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { if (!this.streamingEnabled) { this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest = null; - data = this.dataListener.getData(); + data = this.dataListener.readData(); this.dataListener = null; } else { data = this.dataListener.readData();