nsresult FileReader::OnLoadEnd(nsresult aStatus) { // Cancel the progress event timer ClearProgressEventTimer(); // FileReader must be in DONE stage after an operation mReadyState = DONE; // Quick return, if failed. if (NS_FAILED(aStatus)) { FreeDataAndDispatchError(aStatus); return NS_OK; } // In case we read a different number of bytes, we can assume that the // underlying storage has changed. We should not continue. if (mDataLen != mTotal) { FreeDataAndDispatchError(NS_ERROR_FAILURE); return NS_OK; } // ArrayBuffer needs a custom handling. if (mDataFormat == FILE_AS_ARRAYBUFFER) { OnLoadEndArrayBuffer(); return NS_OK; } nsresult rv = NS_OK; // We don't do anything special for Binary format. if (mDataFormat == FILE_AS_DATAURL) { rv = GetAsDataURL(mBlob, mFileData, mDataLen, mResult); } else if (mDataFormat == FILE_AS_TEXT) { if (!mFileData && mDataLen) { rv = NS_ERROR_OUT_OF_MEMORY; } else if (!mFileData) { rv = GetAsText(mBlob, mCharset, "", mDataLen, mResult); } else { rv = GetAsText(mBlob, mCharset, mFileData, mDataLen, mResult); } } if (NS_WARN_IF(NS_FAILED(rv))) { FreeDataAndDispatchError(rv); return NS_OK; } FreeDataAndDispatchSuccess(); return NS_OK; }
nsresult FileReader::DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent, nsAString& aTerminationEvent) { // Make sure we drop all the objects that could hold files open now. nsCOMPtr<nsIAsyncInputStream> stream; mAsyncStream.swap(stream); RefPtr<Blob> blob; mBlob.swap(blob); // Clear out the data if necessary if (NS_FAILED(aStatus)) { FreeFileData(); return NS_OK; } // In case we read a different number of bytes, we can assume that the // underlying storage has changed. We should not continue. if (mDataLen != mTotal) { DispatchError(NS_ERROR_FAILURE, aTerminationEvent); FreeFileData(); return NS_ERROR_FAILURE; } aSuccessEvent = NS_LITERAL_STRING(LOAD_STR); aTerminationEvent = NS_LITERAL_STRING(LOADEND_STR); nsresult rv = NS_OK; switch (mDataFormat) { case FILE_AS_ARRAYBUFFER: { AutoJSAPI jsapi; nsCOMPtr<nsIGlobalObject> globalObject; if (NS_IsMainThread()) { globalObject = do_QueryInterface(GetParentObject()); } else { MOZ_ASSERT(mWorkerPrivate); MOZ_ASSERT(mBusyCount); globalObject = mWorkerPrivate->GlobalScope(); } if (!globalObject || !jsapi.Init(globalObject)) { FreeFileData(); return NS_ERROR_FAILURE; } RootResultArrayBuffer(); mResultArrayBuffer = JS_NewArrayBufferWithContents(jsapi.cx(), mDataLen, mFileData); if (!mResultArrayBuffer) { JS_ClearPendingException(jsapi.cx()); rv = NS_ERROR_OUT_OF_MEMORY; } else { mFileData = nullptr; // Transfer ownership } break; } case FILE_AS_BINARY: break; //Already accumulated mResult case FILE_AS_TEXT: if (!mFileData) { if (mDataLen) { rv = NS_ERROR_OUT_OF_MEMORY; break; } rv = GetAsText(blob, mCharset, "", mDataLen, mResult); break; } rv = GetAsText(blob, mCharset, mFileData, mDataLen, mResult); break; case FILE_AS_DATAURL: rv = GetAsDataURL(blob, mFileData, mDataLen, mResult); break; } mResult.SetIsVoid(false); FreeFileData(); return rv; }