From df4fadeaf5ae4007807d18cd9892ec7ba0cf36ba Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Mon, 20 Aug 2012 17:16:04 -0500 Subject: [PATCH] Unknown length support; reports download error --- .../firefox/components/PdfStreamConverter.js | 56 ++++++++++++++----- web/viewer.js | 5 ++ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/extensions/firefox/components/PdfStreamConverter.js b/extensions/firefox/components/PdfStreamConverter.js index bac546c87..10af5f99c 100644 --- a/extensions/firefox/components/PdfStreamConverter.js +++ b/extensions/firefox/components/PdfStreamConverter.js @@ -125,29 +125,56 @@ function getLocalizedString(strings, id, property) { // PDF data storage function PdfDataListener(length) { - this.length = length; - this.data = new Uint8Array(length); + this.length = length; // less than 0, if length is unknown + this.data = new Uint8Array(length >= 0 ? length : 0x10000); } PdfDataListener.prototype = { set: function PdfDataListener_set(chunk, offset) { - this.data.set(chunk, offset); var loaded = offset + chunk.length; - this.onprogress(loaded, this.length); + if (this.length < 0 && this.data.length < loaded) { + // data length is unknown and new chunk will not fit in the existing + // buffer, resizing the buffer by doubling the last its length + var newLength = this.data.length; + for (; newLength < loaded; newLength *= 2) {} + var newData = new Uint8Array(newLength); + newData.set(this.data); + this.data = newData; + } + + this.data.set(chunk, offset); + this.loaded = loaded; + + // not reporting the progress if data length is unknown + if (this.length >= 0) + this.onprogress(loaded, this.length); + }, + getData: function PdfDataListener_getData() { + var data = this.length >= 0 ? this.data : + this.data.subarray(0, this.loaded); + delete this.data; // releasing temporary storage + return data; }, finish: function PdfDataListener_finish() { this.isDataReady = true; if (this.oncompleteCallback) { - this.oncompleteCallback(this.data); - delete this.data; + this.oncompleteCallback(this.getData()); + } + }, + error: function PdfDataListener_error(errorCode) { + this.errorCode = errorCode; + if (this.oncompleteCallback) { + this.oncompleteCallback(null, errorCode); } }, onprogress: function() {}, set oncomplete(value) { this.oncompleteCallback = value; if (this.isDataReady) { - value(this.data); - delete this.data; // releasing temporary storage + value(this.getData()); + } + if (this.errorCode) { + value(null, this.errorCode); } } }; @@ -244,11 +271,12 @@ ChromeActions.prototype = { }; this.dataListener.oncomplete = - function ChromeActions_dataListenerComplete(data) { + function ChromeActions_dataListenerComplete(data, errorCode) { domWindow.postMessage({ pdfjsLoadAction: 'complete', - data: data + data: data, + errorCode: errorCode }, '*'); delete this.dataListener; @@ -445,9 +473,6 @@ PdfStreamConverter.prototype = { if (useFetchByChrome) { // Creating storage for PDF data var contentLength = aRequest.contentLength; - if (contentLength < 0) - throw new 'Unknown length is not supported'; - dataListener = new PdfDataListener(contentLength); this.dataListener = dataListener; this.binaryStream = Cc['@mozilla.org/binaryinputstream;1'] @@ -511,7 +536,10 @@ PdfStreamConverter.prototype = { return; } - this.dataListener.finish(); + if (Components.isSuccessCode(aStatusCode)) + this.dataListener.finish(); + else + this.dataListener.error(aStatusCode); delete this.dataListener; delete this.binaryStream; } diff --git a/web/viewer.js b/web/viewer.js index 92d517909..d1fbeb4ed 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -363,6 +363,11 @@ var PDFView = { PDFView.progress(args.loaded / args.total); break; case 'complete': + if (!args.data) { + PDFView.error(mozL10n.get('loading_error', null, + 'An error occurred while loading the PDF.'), e); + break; + } PDFView.open(args.data, 0); break; }