Refactors PdfDataLister buffering.

This commit is contained in:
Yury Delendik 2014-10-13 15:27:05 -05:00
parent c8d729ff39
commit 63444aa4b3

View File

@ -177,46 +177,38 @@ function makeContentReadable(obj, window) {
// PDF data storage // PDF data storage
function PdfDataListener(length) { function PdfDataListener(length) {
this.length = length; // less than 0, if length is unknown this.length = length; // less than 0, if length is unknown
this.data = new Uint8Array(length >= 0 ? length : 0x10000); this.buffer = null;
this.position = 0;
this.loaded = 0; this.loaded = 0;
} }
PdfDataListener.prototype = { PdfDataListener.prototype = {
append: function PdfDataListener_append(chunk) { append: function PdfDataListener_append(chunk) {
var willBeLoaded = this.loaded + chunk.length; // In most of the cases we will pass data as we receive it, but at the
if (this.length >= 0 && this.length < willBeLoaded) { // 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 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)); this.onprogress(this.loaded, this.length >= 0 ? this.length : void(0));
}, },
readData: function PdfDataListener_readData() { readData: function PdfDataListener_readData() {
var data = this.data.subarray(this.position, this.loaded); var result = this.buffer;
this.position = this.loaded; this.buffer = null;
return data; return result;
},
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;
}, },
finish: function PdfDataListener_finish() { finish: function PdfDataListener_finish() {
this.isDataReady = true; this.isDataReady = true;
if (this.oncompleteCallback) { if (this.oncompleteCallback) {
this.oncompleteCallback(this.getData()); this.oncompleteCallback(this.readData());
} }
}, },
error: function PdfDataListener_error(errorCode) { error: function PdfDataListener_error(errorCode) {
@ -232,7 +224,7 @@ PdfDataListener.prototype = {
set oncomplete(value) { set oncomplete(value) {
this.oncompleteCallback = value; this.oncompleteCallback = value;
if (this.isDataReady) { if (this.isDataReady) {
value(this.getData()); value(this.readData());
} }
if (this.errorCode) { if (this.errorCode) {
value(null, this.errorCode); value(null, this.errorCode);
@ -607,7 +599,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
if (!this.streamingEnabled) { if (!this.streamingEnabled) {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
this.originalRequest = null; this.originalRequest = null;
data = this.dataListener.getData(); data = this.dataListener.readData();
this.dataListener = null; this.dataListener = null;
} else { } else {
data = this.dataListener.readData(); data = this.dataListener.readData();