зеркало из https://github.com/mozilla/gecko-dev.git
Bug 649672: Make File.slice arguments match Array.slice and prefix File.slice. r=khuey
This commit is contained in:
Родитель
6e8a05de6b
Коммит
3815106388
|
@ -57,6 +57,7 @@ class nsIInputStream;
|
|||
class nsIClassInfo;
|
||||
|
||||
class nsDOMFile : public nsIDOMFile,
|
||||
public nsIDOMBlob_MOZILLA_2_0_BRANCH,
|
||||
public nsIXHRSendable,
|
||||
public nsICharsetDetectionObserver
|
||||
{
|
||||
|
@ -64,6 +65,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)
|
||||
|
@ -149,8 +151,9 @@ public:
|
|||
NS_IMETHOD GetSize(PRUint64*);
|
||||
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
||||
NS_IMETHOD GetMozFullPathInternal(nsAString&);
|
||||
NS_IMETHOD Slice(PRUint64 aStart, PRUint64 aLength,
|
||||
const nsAString& aContentType, nsIDOMBlob **aBlob);
|
||||
NS_IMETHOD MozSlice(PRInt64 aStart, PRInt64 aEnd,
|
||||
const nsAString& aContentType, PRUint8 optional_argc,
|
||||
nsIDOMBlob **aBlob);
|
||||
|
||||
protected:
|
||||
friend class DataOwnerAdapter; // Needs to see DataOwner
|
||||
|
|
|
@ -49,9 +49,9 @@ interface nsIDOMBlob : nsISupports
|
|||
readonly attribute unsigned long long size;
|
||||
readonly attribute DOMString type;
|
||||
|
||||
nsIDOMBlob slice(in unsigned long long start,
|
||||
in unsigned long long length,
|
||||
[optional] in DOMString contentType);
|
||||
[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
|
||||
|
@ -59,6 +59,14 @@ interface nsIDOMBlob : nsISupports
|
|||
[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(ae1405b0-e411-481e-9606-b29ec7982687)]
|
||||
interface nsIDOMFile : nsIDOMBlob
|
||||
{
|
||||
|
|
|
@ -139,6 +139,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)
|
||||
|
@ -245,23 +246,54 @@ nsDOMFile::GetType(nsAString &aType)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Makes sure that aStart and aStart + aLength is less then or equal to aSize
|
||||
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
|
||||
// than 0
|
||||
void
|
||||
ClampToSize(PRUint64 aSize, PRUint64& aStart, PRUint64& aLength)
|
||||
ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
|
||||
{
|
||||
if (aStart > aSize) {
|
||||
aStart = aLength = 0;
|
||||
CheckedInt64 newStartOffset = aStart;
|
||||
if (aStart < -aSize) {
|
||||
newStartOffset = 0;
|
||||
}
|
||||
CheckedUint64 endOffset = aStart;
|
||||
endOffset += aLength;
|
||||
if (!endOffset.valid() || endOffset.value() > aSize) {
|
||||
aLength = aSize - aStart;
|
||||
else if (aStart < 0) {
|
||||
newStartOffset += aSize;
|
||||
}
|
||||
else if (aStart > aSize) {
|
||||
newStartOffset = aSize;
|
||||
}
|
||||
|
||||
CheckedInt64 newEndOffset = aEnd;
|
||||
if (aEnd < -aSize) {
|
||||
newEndOffset = 0;
|
||||
}
|
||||
else if (aEnd < 0) {
|
||||
newEndOffset += aSize;
|
||||
}
|
||||
else if (aEnd > aSize) {
|
||||
newEndOffset = aSize;
|
||||
}
|
||||
|
||||
if (!newStartOffset.valid() || !newEndOffset.valid() ||
|
||||
newStartOffset.value() >= newEndOffset.value()) {
|
||||
aStart = aEnd = 0;
|
||||
}
|
||||
else {
|
||||
aStart = newStartOffset.value();
|
||||
aEnd = newEndOffset.value();
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
nsIDOMBlob **aBlob)
|
||||
{
|
||||
*aBlob = nsnull;
|
||||
|
||||
|
@ -269,10 +301,15 @@ nsDOMFile::Slice(PRUint64 aStart, PRUint64 aLength,
|
|||
PRUint64 thisLength;
|
||||
nsresult rv = GetSize(&thisLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ClampToSize(thisLength, aStart, aLength);
|
||||
|
||||
if (!optional_argc) {
|
||||
aEnd = (PRInt64)thisLength;
|
||||
}
|
||||
|
||||
ParseSize((PRInt64)thisLength, aStart, aEnd);
|
||||
|
||||
// Create the new file
|
||||
NS_ADDREF(*aBlob = new nsDOMFile(this, aStart, aLength, aContentType));
|
||||
NS_ADDREF(*aBlob = new nsDOMFile(this, aStart, aEnd - aStart, aContentType));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -627,16 +664,22 @@ nsDOMMemoryFile::GetSize(PRUint64 *aFileSize)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMemoryFile::Slice(PRUint64 aStart, PRUint64 aLength,
|
||||
const nsAString& aContentType, nsIDOMBlob **aBlob)
|
||||
nsDOMMemoryFile::MozSlice(PRInt64 aStart, PRInt64 aEnd,
|
||||
const nsAString& aContentType, PRUint8 optional_argc,
|
||||
nsIDOMBlob **aBlob)
|
||||
{
|
||||
*aBlob = nsnull;
|
||||
|
||||
if (!optional_argc) {
|
||||
aEnd = (PRInt64)mLength;
|
||||
}
|
||||
|
||||
// Truncate aLength and aStart so that we stay within this file.
|
||||
ClampToSize(mLength, aStart, aLength);
|
||||
ParseSize((PRInt64)mLength, aStart, aEnd);
|
||||
|
||||
// Create the new file
|
||||
NS_ADDREF(*aBlob = new nsDOMMemoryFile(this, aStart, aLength, aContentType));
|
||||
NS_ADDREF(*aBlob = new nsDOMMemoryFile(this, aStart, aEnd - aStart,
|
||||
aContentType));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -69,104 +69,83 @@ ok(size > 65536, "test data sufficiently large");
|
|||
|
||||
|
||||
// Test that basic properties work
|
||||
function testBasics(file, size, type) {
|
||||
is(file.type, type, "[B0] mozGetAsFile type");
|
||||
is(file.size, size, "[B0] file is correct size");
|
||||
ok(file instanceof File, "[B0] file is a File");
|
||||
ok(file instanceof Blob, "[B0] file is also a Blob");
|
||||
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.slice(0, size);
|
||||
is(slice.type, "", "[B1] full-size type");
|
||||
is(slice.size, size, "[B1] full-size size");
|
||||
ok(slice instanceof Blob, "[B1] slice is a Blob");
|
||||
ok(!(slice instanceof File), "[B1] slice is not a File");
|
||||
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.slice(0, 1234);
|
||||
is(slice.type, "", "[B2] sized type");
|
||||
is(slice.size, 1234, "[B2] sized size");
|
||||
ok(slice instanceof Blob, "[B2] slice is a Blob");
|
||||
ok(!(slice instanceof File), "[B2] 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.slice(size-500, 1000);
|
||||
is(slice.type, "", "[B3] end-sized type");
|
||||
is(slice.size, 500, "[B3] end-sized size");
|
||||
|
||||
slice = file.slice(size+500, 1000);
|
||||
is(slice.type, "", "[B4] sized type");
|
||||
is(slice.size, 0, "[B4] sized size");
|
||||
slice = file.mozSlice(0, size, "foo/bar");
|
||||
is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type");
|
||||
|
||||
slice = file.slice(0, 0);
|
||||
is(slice.type, "", "[B5] sized type");
|
||||
is(slice.size, 0, "[B5] sized size");
|
||||
|
||||
slice = file.slice(1000, 0);
|
||||
is(slice.type, "", "[B6] sized type");
|
||||
is(slice.size, 0, "[B6] sized size");
|
||||
slice = file.mozSlice(0, 5432, "foo/bar");
|
||||
is(slice.type, "foo/bar", fileType + " sized slice foo/bar type");
|
||||
|
||||
slice = file.slice(0, size, "foo/bar");
|
||||
is(slice.type, "foo/bar", "[B7] full-size foo/bar type");
|
||||
is(slice.size, size, "[B7] full-size foo/bar size");
|
||||
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");
|
||||
|
||||
slice = file.slice(0, 5432, "foo/bar");
|
||||
is(slice.type, "foo/bar", "[B8] sized foo/bar type");
|
||||
is(slice.size, 5432, "[B8] sized foo/bar 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],
|
||||
];
|
||||
|
||||
is(slice.slice(0, 10).type, "", "[B9] slice-slice type");
|
||||
is(slice.slice(0, 10).size, 10, "[B9] slice-slice size");
|
||||
is(slice.slice(0, 10, "hello/world").type, "hello/world", "[B9] slice-slice hello/world type");
|
||||
is(slice.slice(0, 10, "hello/world").size, 10, "[B9] slice-slice hello/world type");
|
||||
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");
|
||||
}
|
||||
|
||||
testBasics(memFile, size, "image/png");
|
||||
testBasics(fileFile, size, "");
|
||||
|
||||
|
||||
// Test reading various slices
|
||||
|
||||
// Full file
|
||||
testFile(memFile, fileData, "mem file");
|
||||
testFile(fileFile, fileData, "file file");
|
||||
|
||||
// Simple slice
|
||||
testFile(memFile.slice(0, 33000), fileData.substr(0, 33000), "mem file slice");
|
||||
testFile(fileFile.slice(0, 33000), fileData.substr(0, 33000), "file file slice");
|
||||
|
||||
// Simple slice not starting at beginning
|
||||
testFile(memFile.slice(1000, 33000), fileData.substr(1000, 33000), "mem file slice starting at non-zero");
|
||||
testFile(fileFile.slice(1000, 33000), fileData.substr(1000, 33000), "file file slice starting at non-zero");
|
||||
|
||||
// Slice of slice
|
||||
var memSlice = memFile.slice(0, 40000);
|
||||
var fileSlice = fileFile.slice(0, 40000);
|
||||
testFile(memSlice.slice(5000, 37000), fileData.substr(5000, 35000), "mem file slice slice");
|
||||
testFile(fileSlice.slice(5000, 37000), fileData.substr(5000, 35000), "file file slice slice");
|
||||
|
||||
// ...of slice of slice
|
||||
memSlice = memSlice.slice(5000, 37000).slice(400, 300);
|
||||
fileSlice = fileSlice.slice(5000, 37000).slice(400, 300);
|
||||
gc();
|
||||
testFile(memSlice, fileData.substr(5400, 300), "mem file slice slice slice");
|
||||
testFile(fileSlice, fileData.substr(5400, 300), "file file slice slice slice");
|
||||
|
||||
// empty slice
|
||||
testFile(memFile.slice(4711, 0), "", "mem file empty slice (1)");
|
||||
testFile(fileFile.slice(4711, 0), "", "file file empty slice (1)");
|
||||
testFile(memFile.slice(0, 0), "", "mem file empty slice (2)");
|
||||
testFile(fileFile.slice(0, 0), "", "file file empty slice (2)");
|
||||
|
||||
// slice at end
|
||||
testFile(memFile.slice(size-1000, 1000), fileData.substr(size-1000, 1000), "mem file slice at end");
|
||||
testFile(fileFile.slice(size-1000, 1000), fileData.substr(size-1000, 1000), "file file slice at end");
|
||||
|
||||
// slice across end
|
||||
testFile(memFile.slice(size-500, 1000), fileData.substr(size-500, 500), "mem file slice across end");
|
||||
testFile(fileFile.slice(size-500, 1000), fileData.substr(size-500, 500), "file file slice across end");
|
||||
|
||||
// slice past end
|
||||
testFile(memFile.slice(size, 1000), "", "mem file slice past end (1)");
|
||||
testFile(fileFile.slice(size, 1000), "", "file file slice past end (1)");
|
||||
testFile(memFile.slice(size + 1000, 1000), "", "mem file slice past end (2)");
|
||||
testFile(fileFile.slice(size + 1000, 1000), "", "file file slice past end (2)");
|
||||
testFile(memFile, size, "image/png", fileData, "memFile");
|
||||
testFile(fileFile, size, "", fileData, "fileFile");
|
||||
|
||||
|
||||
// Try loading directly from slice into an image
|
||||
|
@ -202,7 +181,7 @@ function imageLoadHandler(event) {
|
|||
var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData);
|
||||
is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)");
|
||||
var img = new Image;
|
||||
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size));
|
||||
img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size));
|
||||
img.onload = imageLoadHandler;
|
||||
expectedTestCount++;
|
||||
|
||||
|
@ -210,7 +189,7 @@ expectedTestCount++;
|
|||
var imgfile = createFileWithData(fileData + testBinaryData);
|
||||
is(imgfile.size, size + testBinaryData.length, "correct file size (start)");
|
||||
var img = new Image;
|
||||
img.src = URL.createObjectURL(imgfile.slice(0, size));
|
||||
img.src = URL.createObjectURL(imgfile.mozSlice(0, size));
|
||||
img.onload = imageLoadHandler;
|
||||
expectedTestCount++;
|
||||
|
||||
|
@ -218,7 +197,7 @@ expectedTestCount++;
|
|||
var imgfile = createFileWithData(testBinaryData + fileData);
|
||||
is(imgfile.size, size + testBinaryData.length, "correct file size (end)");
|
||||
var img = new Image;
|
||||
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size));
|
||||
img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size));
|
||||
img.onload = imageLoadHandler;
|
||||
expectedTestCount++;
|
||||
|
||||
|
@ -226,13 +205,15 @@ expectedTestCount++;
|
|||
var imgfile = createFileWithData(testBinaryData + fileData);
|
||||
is(imgfile.size, size + testBinaryData.length, "correct file size (past end)");
|
||||
var img = new Image;
|
||||
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size + 1000));
|
||||
img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size + 1000));
|
||||
img.onload = imageLoadHandler;
|
||||
expectedTestCount++;
|
||||
|
||||
|
||||
// Utility functions
|
||||
function testFile(file, contents, test) {
|
||||
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);
|
||||
|
|
|
@ -3911,10 +3911,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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче