зеркало из https://github.com/mozilla/gecko-dev.git
Back it all out on this CLOSED TREE. a=mfbt
This commit is contained in:
Коммит
3e8fcba590
|
@ -40,7 +40,6 @@
|
|||
#define nsDOMFile_h__
|
||||
|
||||
#include "nsICharsetDetectionObserver.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsIDOMFileError.h"
|
||||
|
@ -57,12 +56,9 @@
|
|||
class nsIFile;
|
||||
class nsIInputStream;
|
||||
class nsIClassInfo;
|
||||
class nsIBlobBuilder;
|
||||
|
||||
nsresult NS_NewBlobBuilder(nsISupports* *aSupports);
|
||||
void ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd);
|
||||
|
||||
class nsDOMFile : public nsIDOMFile,
|
||||
public nsIDOMBlob_MOZILLA_2_0_BRANCH,
|
||||
public nsIXHRSendable,
|
||||
public nsICharsetDetectionObserver,
|
||||
public nsIJSNativeInitializer
|
||||
|
@ -71,6 +67,7 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMBLOB
|
||||
NS_DECL_NSIDOMFILE
|
||||
NS_DECL_NSIDOMBLOB_MOZILLA_2_0_BRANCH
|
||||
NS_DECL_NSIXHRSENDABLE
|
||||
|
||||
nsDOMFile(nsIFile *aFile, const nsAString& aContentType)
|
||||
|
|
|
@ -37,33 +37,37 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
%{C++
|
||||
#include "jsapi.h"
|
||||
%}
|
||||
|
||||
interface nsIDOMFileError;
|
||||
interface nsIInputStream;
|
||||
interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface nsIDOMBlob;
|
||||
|
||||
[scriptable, uuid(d5237f31-443a-460b-9e42-449a135346f0)]
|
||||
[scriptable, uuid(5822776a-049c-4de7-adb6-dd9efc39d082)]
|
||||
interface nsIDOMBlob : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long long size;
|
||||
readonly attribute DOMString type;
|
||||
|
||||
[noscript] nsIDOMBlob slice(in unsigned long long start,
|
||||
in unsigned long long length,
|
||||
[optional] in DOMString contentType);
|
||||
|
||||
[noscript] readonly attribute nsIInputStream internalStream;
|
||||
// The caller is responsible for releasing the internalUrl from the
|
||||
// moz-filedata: protocol handler
|
||||
[noscript] DOMString getInternalUrl(in nsIPrincipal principal);
|
||||
};
|
||||
|
||||
[scriptable, uuid(cb5b4191-a555-4e57-b8d2-88091184b59f)]
|
||||
interface nsIDOMBlob_MOZILLA_2_0_BRANCH : nsISupports
|
||||
{
|
||||
[optional_argc] nsIDOMBlob mozSlice(in long long start,
|
||||
[optional] in long long end,
|
||||
[optional] in DOMString contentType);
|
||||
};
|
||||
|
||||
[scriptable, uuid(91c9ebd9-2a4a-4a38-9412-ef492a2799be)]
|
||||
[scriptable, uuid(ae1405b0-e411-481e-9606-b29ec7982687)]
|
||||
interface nsIDOMFile : nsIDOMBlob
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
@ -80,10 +84,3 @@ interface nsIDOMFile : nsIDOMBlob
|
|||
DOMString getAsDataURL(); // raises(FileException) on retrieval
|
||||
DOMString getAsBinary(); // raises(FileException) on retrieval
|
||||
};
|
||||
|
||||
[scriptable, uuid(c4a77171-039b-4f84-97f9-820fb51626af)]
|
||||
interface nsIDOMBlobBuilder : nsISupports
|
||||
{
|
||||
nsIDOMBlob getBlob([optional] in DOMString contentType);
|
||||
[implicit_jscontext] void append(in jsval data);
|
||||
};
|
||||
|
|
|
@ -92,7 +92,6 @@ CPPSRCS = \
|
|||
nsDataDocumentContentPolicy.cpp \
|
||||
nsDOMAttribute.cpp \
|
||||
nsDOMAttributeMap.cpp \
|
||||
nsDOMBlobBuilder.cpp \
|
||||
nsDOMDocumentType.cpp \
|
||||
nsDOMEventTargetWrapperCache.cpp \
|
||||
nsDOMFile.cpp \
|
||||
|
|
|
@ -1,399 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla File API.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Kyle Huey <me@kylehuey.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jstypedarray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsIMultiplexInputStream.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "CheckedInt.h"
|
||||
|
||||
// XXXkhuey shamelessly stolen from VideoUtils.h. We should patch NSPR.
|
||||
#define PR_INT64_MAX (~((PRInt64)(1) << 63))
|
||||
#define PR_INT64_MIN (-PR_INT64_MAX - 1)
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsDOMMultipartBlob : public nsDOMFile
|
||||
{
|
||||
public:
|
||||
nsDOMMultipartBlob(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
|
||||
const nsAString& aContentType)
|
||||
: nsDOMFile(nsnull, aContentType),
|
||||
mBlobs(aBlobs)
|
||||
{
|
||||
mIsFullFile = false;
|
||||
mStart = 0;
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetSize(PRUint64*);
|
||||
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
||||
NS_IMETHOD MozSlice(PRInt64 aStart, PRInt64 aEnd,
|
||||
const nsAString& aContentType, PRUint8 optional_argc,
|
||||
nsIDOMBlob **aBlob);
|
||||
|
||||
protected:
|
||||
nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMultipartBlob::GetSize(PRUint64* aLength)
|
||||
{
|
||||
nsresult rv;
|
||||
*aLength = 0;
|
||||
|
||||
if (mLength) {
|
||||
*aLength = mLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CheckedUint64 length = 0;
|
||||
|
||||
PRUint32 i;
|
||||
PRUint32 len = mBlobs.Length();
|
||||
for (i = 0; i < len; i++) {
|
||||
nsIDOMBlob* blob = mBlobs.ElementAt(i).get();
|
||||
PRUint64 l = 0;
|
||||
|
||||
rv = blob->GetSize(&l);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
length += l;
|
||||
}
|
||||
|
||||
if (!length.valid())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mLength = length.value();
|
||||
*aLength = mLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMultipartBlob::GetInternalStream(nsIInputStream** aStream)
|
||||
{
|
||||
nsresult rv;
|
||||
*aStream = nsnull;
|
||||
|
||||
nsCOMPtr<nsIMultiplexInputStream> stream =
|
||||
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
|
||||
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < mBlobs.Length(); i++) {
|
||||
nsCOMPtr<nsIInputStream> scratchStream;
|
||||
nsIDOMBlob* blob = mBlobs.ElementAt(i).get();
|
||||
|
||||
rv = blob->GetInternalStream(getter_AddRefs(scratchStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stream->AppendStream(scratchStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return CallQueryInterface(stream, aStream);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMultipartBlob::MozSlice(PRInt64 aStart, PRInt64 aEnd,
|
||||
const nsAString& aContentType,
|
||||
PRUint8 optional_argc,
|
||||
nsIDOMBlob **aBlob)
|
||||
{
|
||||
nsresult rv;
|
||||
*aBlob = nsnull;
|
||||
|
||||
// Truncate aStart and aEnd so that we stay within this file.
|
||||
PRUint64 thisLength;
|
||||
rv = GetSize(&thisLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!optional_argc) {
|
||||
aEnd = (PRInt64)thisLength;
|
||||
}
|
||||
|
||||
ParseSize((PRInt64)thisLength, aStart, aEnd);
|
||||
|
||||
// If we clamped to nothing we create an empty blob
|
||||
nsTArray<nsCOMPtr<nsIDOMBlob> > blobs;
|
||||
|
||||
PRInt64 length = aEnd - aStart;
|
||||
PRUint64 finalLength = length;
|
||||
PRUint64 skipStart = aStart;
|
||||
|
||||
NS_ABORT_IF_FALSE(aStart + length <= thisLength, "Er, what?");
|
||||
|
||||
// Prune the list of blobs if we can
|
||||
PRUint32 i;
|
||||
for (i = 0; length && skipStart && i < mBlobs.Length(); i++) {
|
||||
nsIDOMBlob* blob = mBlobs[i].get();
|
||||
|
||||
PRUint64 l;
|
||||
rv = blob->GetSize(&l);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (skipStart < l) {
|
||||
PRInt64 upperBound = NS_MIN<PRInt64>(l - skipStart, length);
|
||||
|
||||
nsCOMPtr<nsIDOMBlob> firstBlob;
|
||||
rv = mBlobs.ElementAt(i)->MozSlice(skipStart, skipStart + upperBound,
|
||||
aContentType, 2,
|
||||
getter_AddRefs(firstBlob));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Avoid wrapping a single blob inside an nsDOMMultipartBlob
|
||||
if (length == upperBound) {
|
||||
firstBlob.forget(aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
blobs.AppendElement(firstBlob);
|
||||
length -= upperBound;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
skipStart -= l;
|
||||
}
|
||||
|
||||
// Now append enough blobs until we're done
|
||||
for (; length && i < mBlobs.Length(); i++) {
|
||||
nsIDOMBlob* blob = mBlobs[i].get();
|
||||
|
||||
PRUint64 l;
|
||||
rv = blob->GetSize(&l);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (length < l) {
|
||||
nsCOMPtr<nsIDOMBlob> lastBlob;
|
||||
rv = mBlobs.ElementAt(i)->MozSlice(0, length, aContentType, 2,
|
||||
getter_AddRefs(lastBlob));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
blobs.AppendElement(lastBlob);
|
||||
} else {
|
||||
blobs.AppendElement(blob);
|
||||
}
|
||||
length -= NS_MIN<PRInt64>(l, length);
|
||||
}
|
||||
|
||||
// we can create our blob now
|
||||
nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartBlob(blobs, aContentType);
|
||||
blob.forget(aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class nsDOMBlobBuilder : public nsIDOMBlobBuilder
|
||||
{
|
||||
public:
|
||||
nsDOMBlobBuilder()
|
||||
: mData(nsnull), mDataLen(0), mDataBufferLen(0)
|
||||
{}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMBLOBBUILDER
|
||||
protected:
|
||||
nsresult AppendVoidPtr(void* aData, PRUint32 aLength);
|
||||
nsresult AppendString(JSString* aString, JSContext* aCx);
|
||||
nsresult AppendBlob(nsIDOMBlob* aBlob);
|
||||
nsresult AppendArrayBuffer(js::ArrayBuffer* aBuffer);
|
||||
|
||||
bool ExpandBufferSize(PRUint64 aSize)
|
||||
{
|
||||
if (mDataBufferLen >= mDataLen + aSize) {
|
||||
mDataLen += aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start at 1 or we'll loop forever.
|
||||
CheckedUint32 bufferLen = NS_MAX<PRUint32>(mDataBufferLen, 1);
|
||||
while (bufferLen.valid() && bufferLen.value() < mDataLen + aSize)
|
||||
bufferLen *= 2;
|
||||
|
||||
if (!bufferLen.valid())
|
||||
return false;
|
||||
|
||||
// PR_ memory functions are still fallible
|
||||
void* data = PR_Realloc(mData, bufferLen.value());
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
mData = data;
|
||||
mDataBufferLen = bufferLen.value();
|
||||
mDataLen += aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Flush() {
|
||||
if (mData) {
|
||||
// If we have some data, create a blob for it
|
||||
// and put it on the stack
|
||||
|
||||
nsCOMPtr<nsIDOMBlob> blob =
|
||||
new nsDOMMemoryFile(mData, mDataLen, EmptyString(), EmptyString());
|
||||
mBlobs.AppendElement(blob);
|
||||
mData = nsnull; // The nsDOMMemoryFile takes ownership of the buffer
|
||||
mDataLen = 0;
|
||||
mDataBufferLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
|
||||
void* mData;
|
||||
PRUint64 mDataLen;
|
||||
PRUint64 mDataBufferLen;
|
||||
};
|
||||
|
||||
DOMCI_DATA(MozBlobBuilder, nsDOMBlobBuilder)
|
||||
|
||||
NS_IMPL_ADDREF(nsDOMBlobBuilder)
|
||||
NS_IMPL_RELEASE(nsDOMBlobBuilder)
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMBlobBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMBlobBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozBlobBuilder)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsresult
|
||||
nsDOMBlobBuilder::AppendVoidPtr(void* aData, PRUint32 aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aData);
|
||||
|
||||
PRUint64 offset = mDataLen;
|
||||
|
||||
if (!ExpandBufferSize(aLength))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
memcpy((char*)mData + offset, aData, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMBlobBuilder::AppendString(JSString* aString, JSContext* aCx)
|
||||
{
|
||||
nsDependentJSString xpcomStr;
|
||||
if (!xpcomStr.init(aCx, aString)) {
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8Str(xpcomStr);
|
||||
|
||||
return AppendVoidPtr((void*)utf8Str.Data(),
|
||||
utf8Str.Length());
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMBlobBuilder::AppendBlob(nsIDOMBlob* aBlob)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aBlob);
|
||||
|
||||
Flush();
|
||||
mBlobs.AppendElement(aBlob);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMBlobBuilder::AppendArrayBuffer(js::ArrayBuffer* aBuffer)
|
||||
{
|
||||
return AppendVoidPtr(aBuffer->data, aBuffer->byteLength);
|
||||
}
|
||||
|
||||
/* nsIDOMBlob getBlob ([optional] in DOMString contentType); */
|
||||
NS_IMETHODIMP
|
||||
nsDOMBlobBuilder::GetBlob(const nsAString& aContentType,
|
||||
nsIDOMBlob** aBlob)
|
||||
{
|
||||
NS_ENSURE_ARG(aBlob);
|
||||
|
||||
Flush();
|
||||
|
||||
nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartBlob(mBlobs,
|
||||
aContentType);
|
||||
blob.forget(aBlob);
|
||||
|
||||
// NB: This is a willful violation of the spec. The spec says that
|
||||
// the existing contents of the BlobBuilder should be included
|
||||
// in the next blob produced. This seems silly and has been raised
|
||||
// on the WHATWG listserv.
|
||||
mBlobs.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [implicit_jscontext] void append (in jsval data); */
|
||||
NS_IMETHODIMP
|
||||
nsDOMBlobBuilder::Append(const jsval& aData, JSContext* aCx)
|
||||
{
|
||||
// We need to figure out what our jsval is
|
||||
|
||||
// Is it an object?
|
||||
if (JSVAL_IS_OBJECT(aData)) {
|
||||
JSObject* obj = JSVAL_TO_OBJECT(aData);
|
||||
NS_ASSERTION(obj, "Er, what?");
|
||||
|
||||
// Is it a Blob?
|
||||
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
|
||||
nsContentUtils::XPConnect()->
|
||||
GetNativeOfWrapper(aCx, obj));
|
||||
if (blob)
|
||||
return AppendBlob(blob);
|
||||
|
||||
// Is it an array buffer?
|
||||
if (js_IsArrayBuffer(obj)) {
|
||||
js::ArrayBuffer* buffer = js::ArrayBuffer::fromJSObject(obj);
|
||||
if (buffer)
|
||||
return AppendArrayBuffer(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// If it's not a Blob or an ArrayBuffer, coerce it to a string
|
||||
JSString* str = JS_ValueToString(aCx, aData);
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
|
||||
|
||||
return AppendString(str, aCx);
|
||||
}
|
||||
|
||||
nsresult NS_NewBlobBuilder(nsISupports* *aSupports)
|
||||
{
|
||||
nsDOMBlobBuilder* builder = new nsDOMBlobBuilder();
|
||||
return CallQueryInterface(builder, aSupports);
|
||||
}
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsIConverterInputStream.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
|
@ -139,6 +140,7 @@ DOMCI_DATA(Blob, nsDOMFile)
|
|||
NS_INTERFACE_MAP_BEGIN(nsDOMFile)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMBlob_MOZILLA_2_0_BRANCH)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFullFile)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
|
||||
|
@ -291,6 +293,13 @@ ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFile::Slice(PRUint64 aStart, PRUint64 aLength,
|
||||
const nsAString& aContentType, nsIDOMBlob **aBlob)
|
||||
{
|
||||
return MozSlice(aStart, aStart + aLength, aContentType, 2, aBlob);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFile::MozSlice(PRInt64 aStart, PRInt64 aEnd,
|
||||
const nsAString& aContentType, PRUint8 optional_argc,
|
||||
|
@ -298,7 +307,7 @@ nsDOMFile::MozSlice(PRInt64 aStart, PRInt64 aEnd,
|
|||
{
|
||||
*aBlob = nsnull;
|
||||
|
||||
// Truncate aStart and aEnd so that we stay within this file.
|
||||
// Truncate aLength and aStart so that we stay within this file.
|
||||
PRUint64 thisLength;
|
||||
nsresult rv = GetSize(&thisLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -481,8 +481,6 @@ _TEST_FILES2 = \
|
|||
bug638112-response.txt \
|
||||
bug638112.sjs \
|
||||
test_bug656283.html \
|
||||
test_blobbuilder.html \
|
||||
fileutils.js \
|
||||
$(NULL)
|
||||
|
||||
# This test fails on the Mac for some reason
|
||||
|
|
|
@ -1,272 +0,0 @@
|
|||
// Utility functions
|
||||
var testRanCounter = 0;
|
||||
var expectedTestCount = 0;
|
||||
|
||||
function testHasRun() {
|
||||
//alert(testRanCounter);
|
||||
++testRanCounter;
|
||||
if (testRanCounter == expectedTestCount) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testFile(file, contents, test) {
|
||||
SimpleTest.requestLongerTimeout(2);
|
||||
|
||||
// Load file using FileReader
|
||||
var r = new FileReader();
|
||||
r.onload = getFileReaderLoadHandler(contents, contents.length, "FileReader.readAsBinaryString of " + test);
|
||||
r.readAsBinaryString(file);
|
||||
expectedTestCount++;
|
||||
|
||||
// Load file using URL.createObjectURL and XMLHttpRequest
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", URL.createObjectURL(file));
|
||||
xhr.onload = getXHRLoadHandler(contents, contents.length, false,
|
||||
"XMLHttpRequest load of " + test);
|
||||
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
xhr.send();
|
||||
expectedTestCount++;
|
||||
|
||||
// Send file to server using FormData and XMLHttpRequest
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onload = function(event) {
|
||||
checkMPSubmission(JSON.parse(event.target.responseText),
|
||||
[{ name: "hello", value: "world"},
|
||||
{ name: "myfile",
|
||||
value: contents,
|
||||
fileName: file.name || "",
|
||||
contentType: file.type || "application/octet-stream" }]);
|
||||
testHasRun();
|
||||
}
|
||||
xhr.open("POST", "../../html/content/test/form_submit_server.sjs");
|
||||
var fd = new FormData;
|
||||
fd.append("hello", "world");
|
||||
fd.append("myfile", file);
|
||||
xhr.send(fd);
|
||||
expectedTestCount++;
|
||||
|
||||
// Send file to server using plain XMLHttpRequest
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("POST", "file_XHRSendData.sjs");
|
||||
xhr.onload = function (event) {
|
||||
is(event.target.getResponseHeader("Result-Content-Type"),
|
||||
file.type ? file.type : null,
|
||||
"request content-type in XMLHttpRequest send of " + test);
|
||||
is(event.target.getResponseHeader("Result-Content-Length"),
|
||||
file.size,
|
||||
"request content-length in XMLHttpRequest send of " + test);
|
||||
};
|
||||
xhr.addEventListener("load",
|
||||
getXHRLoadHandler(contents, contents.length, true,
|
||||
"XMLHttpRequest send of " + test),
|
||||
false);
|
||||
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
xhr.send(file);
|
||||
expectedTestCount++;
|
||||
}
|
||||
|
||||
function getFileReaderLoadHandler(expectedResult, expectedLength, testName) {
|
||||
return function (event) {
|
||||
is(event.target.readyState, FileReader.DONE,
|
||||
"[FileReader] readyState in test " + testName);
|
||||
is(event.target.error, null,
|
||||
"[FileReader] no error in test " + testName);
|
||||
// Do not use |is(event.target.result, expectedResult, "...");| that may output raw binary data.
|
||||
is(event.target.result.length, expectedResult.length,
|
||||
"[FileReader] Length of result in test " + testName);
|
||||
ok(event.target.result == expectedResult,
|
||||
"[FileReader] Content of result in test " + testName);
|
||||
is(event.lengthComputable, true,
|
||||
"[FileReader] lengthComputable in test " + testName);
|
||||
is(event.loaded, expectedLength,
|
||||
"[FileReader] Loaded length in test " + testName);
|
||||
is(event.total, expectedLength,
|
||||
"[FileReader] Total length in test " + testName);
|
||||
testHasRun();
|
||||
}
|
||||
}
|
||||
|
||||
function getXHRLoadHandler(expectedResult, expectedLength, statusWorking, testName) {
|
||||
return function (event) {
|
||||
is(event.target.readyState, 4,
|
||||
"[XHR] readyState in test " + testName);
|
||||
if (statusWorking) {
|
||||
is(event.target.status, 200,
|
||||
"[XHR] no error in test " + testName);
|
||||
}
|
||||
else {
|
||||
todo(event.target.status, 200,
|
||||
"[XHR] no error in test " + testName);
|
||||
}
|
||||
// Do not use |is(convertXHRBinary(event.target.responseText), expectedResult, "...");| that may output raw binary data.
|
||||
var convertedData = convertXHRBinary(event.target.responseText);
|
||||
is(convertedData.length, expectedResult.length,
|
||||
"[XHR] Length of result in test " + testName);
|
||||
ok(convertedData == expectedResult,
|
||||
"[XHR] Content of result in test " + testName);
|
||||
is(event.lengthComputable, true,
|
||||
"[XHR] lengthComputable in test " + testName);
|
||||
is(event.loaded, expectedLength,
|
||||
"[XHR] Loaded length in test " + testName);
|
||||
is(event.total, expectedLength,
|
||||
"[XHR] Total length in test " + testName);
|
||||
|
||||
testHasRun();
|
||||
}
|
||||
}
|
||||
|
||||
function convertXHRBinary(s) {
|
||||
var res = "";
|
||||
for (var i = 0; i < s.length; ++i) {
|
||||
res += String.fromCharCode(s.charCodeAt(i) & 255);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function testHasRun() {
|
||||
//alert(testRanCounter);
|
||||
++testRanCounter;
|
||||
if (testRanCounter == expectedTestCount) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function createFileWithData(fileData) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
testFile.append("fileAPItestfile2-" + fileNum);
|
||||
fileNum++;
|
||||
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
|
||||
0666, 0);
|
||||
outStream.write(fileData, fileData.length);
|
||||
outStream.close();
|
||||
|
||||
var fileList = document.getElementById('fileList');
|
||||
fileList.value = testFile.path;
|
||||
|
||||
return fileList.files[0];
|
||||
}
|
||||
|
||||
function gc() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.garbageCollect();
|
||||
}
|
||||
|
||||
function checkMPSubmission(sub, expected) {
|
||||
function getPropCount(o) {
|
||||
var x, l = 0;
|
||||
for (x in o) ++l;
|
||||
return l;
|
||||
}
|
||||
|
||||
is(sub.length, expected.length,
|
||||
"Correct number of items");
|
||||
var i;
|
||||
for (i = 0; i < expected.length; ++i) {
|
||||
if (!("fileName" in expected[i])) {
|
||||
is(sub[i].headers["Content-Disposition"],
|
||||
"form-data; name=\"" + expected[i].name + "\"",
|
||||
"Correct name (A)");
|
||||
is (getPropCount(sub[i].headers), 1,
|
||||
"Wrong number of headers (A)");
|
||||
}
|
||||
else {
|
||||
is(sub[i].headers["Content-Disposition"],
|
||||
"form-data; name=\"" + expected[i].name + "\"; filename=\"" +
|
||||
expected[i].fileName + "\"",
|
||||
"Correct name (B)");
|
||||
is(sub[i].headers["Content-Type"],
|
||||
expected[i].contentType,
|
||||
"Correct content type (B)");
|
||||
is (getPropCount(sub[i].headers), 2,
|
||||
"Wrong number of headers (B)");
|
||||
}
|
||||
// Do not use |is(sub[i].body, expected[i].value, "...");| that may output raw binary data.
|
||||
is(sub[i].body.length, expected[i].value.length,
|
||||
"Length of correct value");
|
||||
ok(sub[i].body == expected[i].value,
|
||||
"Content of correct value");
|
||||
}
|
||||
}
|
||||
|
||||
function testSlice(file, size, type, contents, fileType) {
|
||||
is(file.type, type, fileType + " file is correct type");
|
||||
is(file.size, size, fileType + " file is correct size");
|
||||
ok(file instanceof File, fileType + " file is a File");
|
||||
ok(file instanceof Blob, fileType + " file is also a Blob");
|
||||
|
||||
var slice = file.mozSlice(0, size);
|
||||
ok(slice instanceof Blob, fileType + " fullsize slice is a Blob");
|
||||
ok(!(slice instanceof File), fileType + " fullsize slice is not a File");
|
||||
|
||||
slice = file.mozSlice(0, 1234);
|
||||
ok(slice instanceof Blob, fileType + " sized slice is a Blob");
|
||||
ok(!(slice instanceof File), fileType + " sized slice is not a File");
|
||||
|
||||
slice = file.mozSlice(0, size, "foo/bar");
|
||||
is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type");
|
||||
|
||||
slice = file.mozSlice(0, 5432, "foo/bar");
|
||||
is(slice.type, "foo/bar", fileType + " sized slice foo/bar type");
|
||||
|
||||
is(slice.mozSlice(0, 10).type, "", fileType + " slice-slice type");
|
||||
is(slice.mozSlice(0, 10).size, 10, fileType + " slice-slice size");
|
||||
is(slice.mozSlice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type");
|
||||
is(slice.mozSlice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size");
|
||||
|
||||
var indexes = [[0, size, size],
|
||||
[0, 1234, 1234],
|
||||
[size-500, size, 500],
|
||||
[size-500, size+500, 500],
|
||||
[size+500, size+1500, 0],
|
||||
[0, 0, 0],
|
||||
[1000, 1000, 0],
|
||||
[size, size, 0],
|
||||
[0, undefined, size],
|
||||
[100, undefined, size-100],
|
||||
[-100, undefined, 100],
|
||||
[100, -100, size-200],
|
||||
[-size-100, undefined, size],
|
||||
[-2*size-100, 500, 500],
|
||||
[0, -size-100, 0],
|
||||
[100, -size-100, 0],
|
||||
[50, -size+100, 50],
|
||||
[0, 33000, 33000],
|
||||
[1000, 34000, 33000],
|
||||
];
|
||||
|
||||
for (var i = 0; i < indexes.length; ++i) {
|
||||
var sliceContents;
|
||||
var testName;
|
||||
if (indexes[i][1] == undefined) {
|
||||
slice = file.mozSlice(indexes[i][0]);
|
||||
sliceContents = contents.slice(indexes[i][0]);
|
||||
testName = fileType + " slice(" + indexes[i][0] + ")";
|
||||
}
|
||||
else {
|
||||
slice = file.mozSlice(indexes[i][0], indexes[i][1]);
|
||||
sliceContents = contents.slice(indexes[i][0], indexes[i][1]);
|
||||
testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")";
|
||||
}
|
||||
is(slice.type, "", testName + " type");
|
||||
is(slice.size, indexes[i][2], testName + " size");
|
||||
is(sliceContents.length, indexes[i][2], testName + " data size");
|
||||
testFile(slice, sliceContents, testName);
|
||||
}
|
||||
|
||||
// Slice of slice
|
||||
var slice = file.mozSlice(0, 40000);
|
||||
testFile(slice.mozSlice(5000, 42000), contents.slice(5000, 40000), "file slice slice");
|
||||
|
||||
// ...of slice of slice
|
||||
slice = slice.mozSlice(5000, 42000).mozSlice(400, 700);
|
||||
SpecialPowers.gc();
|
||||
testFile(slice, contents.slice(5400, 5700), "file slice slice slice");
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=648997
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 648997</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="fileutils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=648997">Mozilla Bug 648997</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
// We're prefixing still
|
||||
window.BlobBuilder = window.MozBlobBuilder;
|
||||
|
||||
/** Test for Bug 648997 **/
|
||||
var blobBuilder = BlobBuilder();
|
||||
ok(blobBuilder, "BlobBuilder should exist");
|
||||
|
||||
ok(blobBuilder.append, "BlobBuilder should have an append method");
|
||||
ok(blobBuilder.getBlob, "BlobBuilder should have a getBlob method");
|
||||
|
||||
try {
|
||||
blobBuilder.append();
|
||||
ok(false, "NOT REACHED");
|
||||
} catch(e) {
|
||||
ok(true, "an empty argument to append should throw");
|
||||
}
|
||||
|
||||
blobBuilder.append("squiggle");
|
||||
let blob1 = blobBuilder.getBlob();
|
||||
blobBuilder.append("ohai");
|
||||
let blob2 = blobBuilder.getBlob();
|
||||
|
||||
let aB = new ArrayBuffer(16);
|
||||
var int8View = new Int8Array(aB);
|
||||
for (var i = 0; i < 16; i++) {
|
||||
int8View[i] = i+65;
|
||||
}
|
||||
|
||||
let testData =
|
||||
[
|
||||
// Test 3 strings
|
||||
[["foo", "bar", "baz"], [{start: 0, length: 9, contents: "foobarbaz"},
|
||||
{start: 0, length: 3, contents: "foo"},
|
||||
{start: 3, length:6, contents: "barbaz"},
|
||||
{start: 6, length: 3, contents: "baz"},
|
||||
{start: 6, length: 6, elength: 3, contents: "baz"},
|
||||
{start: 0, length: 9, contents: "foobarbaz"},
|
||||
{start: 0, length: 11, elength: 9, contents: "foobarbaz"},
|
||||
{start: 10, length: 5, elength: 0, contents: ""}]],
|
||||
// Test string, Blob, string
|
||||
[["foo", blob1, "baz"], [{start: 0, length: 3, contents: "foo"},
|
||||
{start: 3, length: 8, contents: "squiggle"},
|
||||
{start: 2, length: 2, contents: "os"},
|
||||
{start: 10, length: 2, contents: "eb"}]],
|
||||
// Test blob, string, blob
|
||||
[[blob1, "foo", blob1], [{start: 0, length: 8, contents: "squiggle"},
|
||||
{start: 7, length: 2, contents: "ef"},
|
||||
{start: 10, length: 2, contents: "os"},
|
||||
{start: 1, length: 3, contents: "qui"},
|
||||
{start: 12, length: 3, contents: "qui"},
|
||||
{start: 40, length: 20, elength: 0, contents: ""}]],
|
||||
// Test blobs all the way down
|
||||
[[blob2, blob1, blob2], [{start: 0, length: 4, contents: "ohai"},
|
||||
{start: 4, length: 8, contents: "squiggle"},
|
||||
{start: 12, length: 4, contents: "ohai"},
|
||||
{start: 1, length: 2, contents: "ha"},
|
||||
{start: 5, length: 4, contents: "quig"}]],
|
||||
// Test an array buffer
|
||||
[[aB, blob1, "foo"], [{start: 0, length: 8, contents: "ABCDEFGH"},
|
||||
{start: 8, length:10, contents: "IJKLMNOPsq"},
|
||||
{start: 17, length: 3, contents: "qui"},
|
||||
{start: 4, length: 8, contents: "EFGHIJKL"}]],
|
||||
// Test type coercion of a number
|
||||
[[3, aB, "foo"], [{start: 0, length: 8, contents: "3ABCDEFG"},
|
||||
{start: 8, length:10, contents: "HIJKLMNOPf"},
|
||||
{start: 17, length: 4, elength: 3, contents: "foo"},
|
||||
{start: 4, length: 8, contents: "DEFGHIJK"}]]
|
||||
];
|
||||
|
||||
let testCounter = 0;
|
||||
|
||||
function doTest(data) {
|
||||
testCounter++;
|
||||
|
||||
[blobs, tests] = data;
|
||||
|
||||
function runTest(test) {
|
||||
|
||||
let bb = new BlobBuilder();
|
||||
ok(bb, "BlobBuilder should exist");
|
||||
|
||||
function doAppend(blob) {
|
||||
bb.append(blob);
|
||||
blob.expando = bb; // Do we leak?
|
||||
}
|
||||
|
||||
blobs.forEach(doAppend);
|
||||
ok(true, "Test " + testCounter + " appended all successfully");
|
||||
let blob = bb.getBlob();
|
||||
ok(blob, "Test " + testCounter + " got blob");
|
||||
ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob");
|
||||
//ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File");
|
||||
|
||||
let slice = blob.mozSlice(test.start, test.start + test.length);
|
||||
ok(slice, "Test " + testCounter + " got slice");
|
||||
ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob");
|
||||
//ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File");
|
||||
is(slice.size,"elength" in test ? test.elength : test.length,
|
||||
"Test " + testCounter + " slice is correct size");
|
||||
|
||||
testFile(slice, test.contents, "Test " + testCounter,
|
||||
"elength" in test ? test.elength : test.length);
|
||||
}
|
||||
tests.forEach(runTest);
|
||||
SpecialPowers.gc();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
testData.forEach(doTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=575946
|
|||
<title>Test for Bug 575946</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="fileutils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
|
||||
|
@ -24,6 +23,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=575946
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var fileNum = 1;
|
||||
var testRanCounter = 0;
|
||||
var expectedTestCount = 0;
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Create files containing data we'll test with. We'll want long
|
||||
|
@ -68,8 +69,83 @@ ok(size > 65536, "test data sufficiently large");
|
|||
|
||||
|
||||
// Test that basic properties work
|
||||
testSlice(memFile, size, "image/png", fileData, "memFile");
|
||||
testSlice(fileFile, size, "", fileData, "fileFile");
|
||||
function testFile(file, size, type, contents, fileType) {
|
||||
is(file.type, type, fileType + " file is correct type");
|
||||
is(file.size, size, fileType + " file is correct size");
|
||||
ok(file instanceof File, fileType + " file is a File");
|
||||
ok(file instanceof Blob, fileType + " file is also a Blob");
|
||||
|
||||
var slice = file.mozSlice(0, size);
|
||||
ok(slice instanceof Blob, fileType + " fullsize slice is a Blob");
|
||||
ok(!(slice instanceof File), fileType + " fullsize slice is not a File");
|
||||
|
||||
slice = file.mozSlice(0, 1234);
|
||||
ok(slice instanceof Blob, fileType + " sized slice is a Blob");
|
||||
ok(!(slice instanceof File), fileType + " sized slice is not a File");
|
||||
|
||||
slice = file.mozSlice(0, size, "foo/bar");
|
||||
is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type");
|
||||
|
||||
slice = file.mozSlice(0, 5432, "foo/bar");
|
||||
is(slice.type, "foo/bar", fileType + " sized slice foo/bar type");
|
||||
|
||||
is(slice.mozSlice(0, 10).type, "", fileType + " slice-slice type");
|
||||
is(slice.mozSlice(0, 10).size, 10, fileType + " slice-slice size");
|
||||
is(slice.mozSlice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type");
|
||||
is(slice.mozSlice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size");
|
||||
|
||||
var indexes = [[0, size, size],
|
||||
[0, 1234, 1234],
|
||||
[size-500, size, 500],
|
||||
[size-500, size+500, 500],
|
||||
[size+500, size+1500, 0],
|
||||
[0, 0, 0],
|
||||
[1000, 1000, 0],
|
||||
[size, size, 0],
|
||||
[0, undefined, size],
|
||||
[100, undefined, size-100],
|
||||
[-100, undefined, 100],
|
||||
[100, -100, size-200],
|
||||
[-size-100, undefined, size],
|
||||
[-2*size-100, 500, 500],
|
||||
[0, -size-100, 0],
|
||||
[100, -size-100, 0],
|
||||
[50, -size+100, 50],
|
||||
[0, 33000, 33000],
|
||||
[1000, 34000, 33000],
|
||||
];
|
||||
|
||||
for (var i = 0; i < indexes.length; ++i) {
|
||||
var sliceContents;
|
||||
var testName;
|
||||
if (indexes[i][1] == undefined) {
|
||||
slice = file.mozSlice(indexes[i][0]);
|
||||
sliceContents = contents.slice(indexes[i][0]);
|
||||
testName = fileType + " slice(" + indexes[i][0] + ")";
|
||||
}
|
||||
else {
|
||||
slice = file.mozSlice(indexes[i][0], indexes[i][1]);
|
||||
sliceContents = contents.slice(indexes[i][0], indexes[i][1]);
|
||||
testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")";
|
||||
}
|
||||
is(slice.type, "", testName + " type");
|
||||
is(slice.size, indexes[i][2], testName + " size");
|
||||
is(sliceContents.length, indexes[i][2], testName + " data size");
|
||||
checkFileContents(slice, sliceContents, testName);
|
||||
}
|
||||
|
||||
// Slice of slice
|
||||
var slice = file.mozSlice(0, 40000);
|
||||
checkFileContents(slice.mozSlice(5000, 42000), contents.slice(5000, 40000), "file slice slice");
|
||||
|
||||
// ...of slice of slice
|
||||
slice = slice.mozSlice(5000, 42000).mozSlice(400, 700);
|
||||
gc();
|
||||
checkFileContents(slice, contents.slice(5400, 5700), "file slice slice slice");
|
||||
}
|
||||
|
||||
testFile(memFile, size, "image/png", fileData, "memFile");
|
||||
testFile(fileFile, size, "", fileData, "fileFile");
|
||||
|
||||
|
||||
// Try loading directly from slice into an image
|
||||
|
@ -133,6 +209,192 @@ img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinary
|
|||
img.onload = imageLoadHandler;
|
||||
expectedTestCount++;
|
||||
|
||||
|
||||
// Utility functions
|
||||
function checkFileContents(file, contents, test) {
|
||||
SimpleTest.requestLongerTimeout(2);
|
||||
|
||||
// Load file using FileReader
|
||||
var r = new FileReader();
|
||||
r.onload = getFileReaderLoadHandler(contents, contents.length, "FileReader.readAsBinaryString of " + test);
|
||||
r.readAsBinaryString(file);
|
||||
expectedTestCount++;
|
||||
|
||||
// Load file using URL.createObjectURL and XMLHttpRequest
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", URL.createObjectURL(file));
|
||||
xhr.onload = getXHRLoadHandler(contents, contents.length, false,
|
||||
"XMLHttpRequest load of " + test);
|
||||
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
xhr.send();
|
||||
expectedTestCount++;
|
||||
|
||||
// Send file to server using FormData and XMLHttpRequest
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onload = function(event) {
|
||||
checkMPSubmission(JSON.parse(event.target.responseText),
|
||||
[{ name: "hello", value: "world"},
|
||||
{ name: "myfile",
|
||||
value: contents,
|
||||
fileName: file.name || "",
|
||||
contentType: file.type || "application/octet-stream" }]);
|
||||
testHasRun();
|
||||
}
|
||||
xhr.open("POST", "../../html/content/test/form_submit_server.sjs");
|
||||
var fd = new FormData;
|
||||
fd.append("hello", "world");
|
||||
fd.append("myfile", file);
|
||||
xhr.send(fd);
|
||||
expectedTestCount++;
|
||||
|
||||
// Send file to server using plain XMLHttpRequest
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("POST", "file_XHRSendData.sjs");
|
||||
xhr.onload = function (event) {
|
||||
is(event.target.getResponseHeader("Result-Content-Type"),
|
||||
file.type ? file.type : null,
|
||||
"request content-type in XMLHttpRequest send of " + test);
|
||||
is(event.target.getResponseHeader("Result-Content-Length"),
|
||||
file.size,
|
||||
"request content-length in XMLHttpRequest send of " + test);
|
||||
};
|
||||
xhr.addEventListener("load",
|
||||
getXHRLoadHandler(contents, contents.length, true,
|
||||
"XMLHttpRequest send of " + test),
|
||||
false);
|
||||
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
xhr.send(file);
|
||||
expectedTestCount++;
|
||||
}
|
||||
|
||||
function getFileReaderLoadHandler(expectedResult, expectedLength, testName) {
|
||||
return function (event) {
|
||||
is(event.target.readyState, FileReader.DONE,
|
||||
"[FileReader] readyState in test " + testName);
|
||||
is(event.target.error, null,
|
||||
"[FileReader] no error in test " + testName);
|
||||
// Do not use |is(event.target.result, expectedResult, "...");| that may output raw binary data.
|
||||
is(event.target.result.length, expectedResult.length,
|
||||
"[FileReader] Length of result in test " + testName);
|
||||
ok(event.target.result == expectedResult,
|
||||
"[FileReader] Content of result in test " + testName);
|
||||
is(event.lengthComputable, true,
|
||||
"[FileReader] lengthComputable in test " + testName);
|
||||
is(event.loaded, expectedLength,
|
||||
"[FileReader] Loaded length in test " + testName);
|
||||
is(event.total, expectedLength,
|
||||
"[FileReader] Total length in test " + testName);
|
||||
testHasRun();
|
||||
}
|
||||
}
|
||||
|
||||
function getXHRLoadHandler(expectedResult, expectedLength, statusWorking, testName) {
|
||||
return function (event) {
|
||||
is(event.target.readyState, 4,
|
||||
"[XHR] readyState in test " + testName);
|
||||
if (statusWorking) {
|
||||
is(event.target.status, 200,
|
||||
"[XHR] no error in test " + testName);
|
||||
}
|
||||
else {
|
||||
todo(event.target.status, 200,
|
||||
"[XHR] no error in test " + testName);
|
||||
}
|
||||
// Do not use |is(convertXHRBinary(event.target.responseText), expectedResult, "...");| that may output raw binary data.
|
||||
var convertedData = convertXHRBinary(event.target.responseText);
|
||||
is(convertedData.length, expectedResult.length,
|
||||
"[XHR] Length of result in test " + testName);
|
||||
ok(convertedData == expectedResult,
|
||||
"[XHR] Content of result in test " + testName);
|
||||
is(event.lengthComputable, true,
|
||||
"[XHR] lengthComputable in test " + testName);
|
||||
is(event.loaded, expectedLength,
|
||||
"[XHR] Loaded length in test " + testName);
|
||||
is(event.total, expectedLength,
|
||||
"[XHR] Total length in test " + testName);
|
||||
|
||||
testHasRun();
|
||||
}
|
||||
}
|
||||
|
||||
function convertXHRBinary(s) {
|
||||
var res = "";
|
||||
for (var i = 0; i < s.length; ++i) {
|
||||
res += String.fromCharCode(s.charCodeAt(i) & 255);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function testHasRun() {
|
||||
//alert(testRanCounter);
|
||||
++testRanCounter;
|
||||
if (testRanCounter == expectedTestCount) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function createFileWithData(fileData) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
testFile.append("fileAPItestfile2-" + fileNum);
|
||||
fileNum++;
|
||||
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
|
||||
0666, 0);
|
||||
outStream.write(fileData, fileData.length);
|
||||
outStream.close();
|
||||
|
||||
var fileList = document.getElementById('fileList');
|
||||
fileList.value = testFile.path;
|
||||
|
||||
return fileList.files[0];
|
||||
}
|
||||
|
||||
function gc() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.garbageCollect();
|
||||
}
|
||||
|
||||
function checkMPSubmission(sub, expected) {
|
||||
function getPropCount(o) {
|
||||
var x, l = 0;
|
||||
for (x in o) ++l;
|
||||
return l;
|
||||
}
|
||||
|
||||
is(sub.length, expected.length,
|
||||
"Correct number of items");
|
||||
var i;
|
||||
for (i = 0; i < expected.length; ++i) {
|
||||
if (!("fileName" in expected[i])) {
|
||||
is(sub[i].headers["Content-Disposition"],
|
||||
"form-data; name=\"" + expected[i].name + "\"",
|
||||
"Correct name (A)");
|
||||
is (getPropCount(sub[i].headers), 1,
|
||||
"Wrong number of headers (A)");
|
||||
}
|
||||
else {
|
||||
is(sub[i].headers["Content-Disposition"],
|
||||
"form-data; name=\"" + expected[i].name + "\"; filename=\"" +
|
||||
expected[i].fileName + "\"",
|
||||
"Correct name (B)");
|
||||
is(sub[i].headers["Content-Type"],
|
||||
expected[i].contentType,
|
||||
"Correct content type (B)");
|
||||
is (getPropCount(sub[i].headers), 2,
|
||||
"Wrong number of headers (B)");
|
||||
}
|
||||
// Do not use |is(sub[i].body, expected[i].value, "...");| that may output raw binary data.
|
||||
is(sub[i].body.length, expected[i].value.length,
|
||||
"Length of correct value");
|
||||
ok(sub[i].body == expected[i].value,
|
||||
"Content of correct value");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body> </html>
|
||||
|
|
|
@ -1331,8 +1331,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
|
||||
NS_DEFINE_CLASSINFO_DATA(XULCommandEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MozBlobBuilder, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(CommandEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
@ -1577,7 +1575,6 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
|
|||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Worker, nsDOMWorker::NewWorker)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(ChromeWorker, nsDOMWorker::NewChromeWorker)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMFile::NewFile)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozBlobBuilder, NS_NewBlobBuilder)
|
||||
};
|
||||
|
||||
nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
|
||||
|
@ -4004,10 +4001,12 @@ nsDOMClassInfo::Init()
|
|||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob_MOZILLA_2_0_BRANCH)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(File, nsIDOMFile)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob_MOZILLA_2_0_BRANCH)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
|
@ -4032,10 +4031,6 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMStringMap)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozBlobBuilder, nsIDOMBlobBuilder)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlobBuilder)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow)
|
||||
|
|
|
@ -406,7 +406,6 @@ DOMCI_CLASS(FileException)
|
|||
DOMCI_CLASS(FileError)
|
||||
DOMCI_CLASS(FileReader)
|
||||
DOMCI_CLASS(MozURLProperty)
|
||||
DOMCI_CLASS(MozBlobBuilder)
|
||||
|
||||
DOMCI_CLASS(DOMStringMap)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче