Index: lib/io.js |
=================================================================== |
--- a/lib/io.js |
+++ b/lib/io.js |
@@ -20,16 +20,17 @@ |
*/ |
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
Cu.import("resource://gre/modules/Services.jsm"); |
Cu.import("resource://gre/modules/FileUtils.jsm"); |
Cu.import("resource://gre/modules/NetUtil.jsm"); |
let {TimeLine} = require("timeline"); |
+let {Utils} = require("utils"); |
let IO = exports.IO = |
{ |
/** |
* Retrieves the platform-dependent line break string. |
*/ |
get lineBreak() |
{ |
@@ -67,33 +68,32 @@ let IO = exports.IO = |
* The callback will be called when the operation is done. |
*/ |
readFromFile: function(/**nsIFile|nsIURI*/ file, /**Boolean*/ decode, /**Object*/ listener, /**Function*/ callback, /**String*/ timeLineID) |
{ |
try |
{ |
let processing = false; |
let buffer = ""; |
- let loadEvent = null; |
- let errorEvent = null; |
+ let loaded = false; |
+ let error = Cr.NS_OK; |
let uri = file instanceof Ci.nsIFile ? Services.io.newFileURI(file) : file; |
let request = new XMLHttpRequest(); |
request.mozBackgroundRequest = true; |
request.open("GET", uri.spec); |
request.responseType = "moz-chunked-text"; |
request.overrideMimeType("text/plain" + (decode ? "? charset=utf-8" : "")); |
- let onProgress = function(event) |
+ let onProgress = function(data) |
{ |
if (timeLineID) |
{ |
TimeLine.asyncStart(timeLineID); |
} |
- let data = event.target.response; |
let index = (processing ? -1 : Math.max(data.lastIndexOf("\n"), data.lastIndexOf("\r"))); |
if (index >= 0) |
{ |
// Protect against reentrance in case the listener processes events. |
processing = true; |
try |
{ |
let oldBuffer = buffer; |
@@ -103,52 +103,49 @@ let IO = exports.IO = |
lines.pop(); |
lines[0] = oldBuffer + lines[0]; |
for (let i = 0; i < lines.length; i++) |
listener.process(lines[i]); |
} |
finally |
{ |
processing = false; |
- let e = { |
- target: {response: buffer} |
- }; |
+ data = buffer; |
buffer = ""; |
- onProgress(e); |
+ onProgress(data); |
- if (loadEvent) |
+ if (loaded) |
{ |
- let event = loadEvent; |
- loadEvent = null; |
- onLoad(event); |
+ loaded = false; |
+ onLoad(); |
} |
- if (errorEvent) |
+ if (error != Cr.NS_OK) |
{ |
- let event = errorEvent; |
- errorEvent = null; |
- onError(event); |
+ let param = error; |
+ error = Cr.NS_OK; |
+ onError(param); |
} |
} |
} |
else |
buffer += data; |
if (timeLineID) |
{ |
TimeLine.asyncEnd(timeLineID); |
} |
}; |
- let onLoad = function(event) |
+ let onLoad = function() |
{ |
if (processing) |
{ |
// Still processing data, delay processing this event. |
- loadEvent = event; |
+ loaded = true; |
return; |
} |
if (timeLineID) |
{ |
TimeLine.asyncStart(timeLineID); |
} |
@@ -160,38 +157,47 @@ let IO = exports.IO = |
{ |
TimeLine.asyncEnd(timeLineID); |
TimeLine.asyncDone(timeLineID); |
} |
callback(null); |
}; |
- let onError = function(event) |
+ let onError = function(status) |
{ |
if (processing) |
{ |
// Still processing data, delay processing this event. |
- errorEvent = event; |
+ error = status; |
return; |
} |
let e = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCException); |
- e.initialize("File read operation failed", result, null, Components.stack, file, null); |
+ e.initialize("File read operation failed", status, null, Components.stack, file, null); |
callback(e); |
if (timeLineID) |
{ |
TimeLine.asyncDone(timeLineID); |
} |
}; |
- request.addEventListener("progress", onProgress, false); |
- request.addEventListener("load", onLoad, false); |
- request.addEventListener("error", onError, false); |
+ request.addEventListener("progress", function(event) |
+ { |
+ Utils.runAsync(onProgress.bind(this, event.target.response)); |
+ }, false); |
+ request.addEventListener("load", function(event) |
+ { |
+ Utils.runAsync(onLoad.bind(this)); |
+ }, false); |
+ request.addEventListener("error", function(event) |
+ { |
+ Utils.runAsync(onError.bind(this, event.target.channel.status)); |
+ }, false); |
request.send(null); |
} |
catch (e) |
{ |
callback(e); |
} |
}, |