Bug 761159 - FileHandle: Better handling of the end of file state. r=sicking

This commit is contained in:
Jan Varga 2012-06-17 05:36:54 +02:00
Родитель faa9392008
Коммит 8c778eb7cd
5 изменённых файлов: 156 добавлений и 16 удалений

Просмотреть файл

@ -506,18 +506,39 @@ LockedFile::GetActive(bool* aActive)
}
NS_IMETHODIMP
LockedFile::GetLocation(PRUint64* aLocation)
LockedFile::GetLocation(JSContext* aCx,
jsval* aLocation)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
*aLocation = mLocation;
if (mLocation == LL_MAXUINT) {
*aLocation = JSVAL_NULL;
}
else if (!JS_NewNumberValue(aCx, double(mLocation), aLocation)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
LockedFile::SetLocation(PRUint64 aLocation)
LockedFile::SetLocation(JSContext* aCx,
const jsval& aLocation)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mLocation = aLocation;
// Null means the end-of-file.
if (JSVAL_IS_NULL(aLocation)) {
mLocation = LL_MAXUINT;
return NS_OK;
}
PRUint64 location;
if (!xpc::ValueToUint64(aCx, aLocation, &location)) {
return NS_ERROR_TYPE_ERR;
}
mLocation = location;
return NS_OK;
}
@ -576,6 +597,10 @@ LockedFile::ReadAsArrayBuffer(PRUint64 aSize,
return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
}
if (mLocation == LL_MAXUINT) {
return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
}
if (!aSize) {
return NS_ERROR_TYPE_ERR;
}
@ -614,6 +639,10 @@ LockedFile::ReadAsText(PRUint64 aSize,
return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
}
if (mLocation == LL_MAXUINT) {
return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
}
if (!aSize) {
return NS_ERROR_TYPE_ERR;
}
@ -662,7 +691,7 @@ LockedFile::Append(const jsval& aValue,
}
NS_IMETHODIMP
LockedFile::Truncate(PRUint64 aLocation,
LockedFile::Truncate(PRUint64 aSize,
PRUint8 aOptionalArgCount,
nsIDOMFileRequest** _retval)
{
@ -676,6 +705,19 @@ LockedFile::Truncate(PRUint64 aLocation,
return NS_ERROR_DOM_FILEHANDLE_READ_ONLY_ERR;
}
PRUint64 location;
if (aOptionalArgCount) {
// Just in case someone calls us from C++
NS_ASSERTION(aSize != LL_MAXUINT, "Passed wrong size!");
location = aSize;
}
else {
if (mLocation == LL_MAXUINT) {
return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
}
location = mLocation;
}
// Do nothing if the window is closed
if (!GetOwner()) {
return NS_OK;
@ -684,8 +726,6 @@ LockedFile::Truncate(PRUint64 aLocation,
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
NS_ENSURE_TRUE(fileRequest, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
PRUint64 location = aOptionalArgCount ? aLocation : mLocation;
nsRefPtr<TruncateHelper> helper =
new TruncateHelper(this, fileRequest, location);
@ -693,7 +733,7 @@ LockedFile::Truncate(PRUint64 aLocation,
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
if (aOptionalArgCount) {
mLocation = aLocation;
mLocation = aSize;
}
fileRequest.forget(_retval);
@ -820,6 +860,10 @@ LockedFile::WriteOrAppend(const jsval& aValue,
return NS_ERROR_DOM_FILEHANDLE_READ_ONLY_ERR;
}
if (!aAppend && mLocation == LL_MAXUINT) {
return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
}
// Do nothing if the window is closed
if (!GetOwner()) {
return NS_OK;

Просмотреть файл

@ -16,7 +16,7 @@ dictionary DOMFileMetadataParameters
boolean lastModified;
};
[scriptable, builtinclass, uuid(e1f69cc5-c6ce-4850-bc09-c4211b1d4290)]
[scriptable, builtinclass, uuid(696a4cbf-603d-40e1-840a-e468ee363871)]
interface nsIDOMLockedFile : nsISupports
{
readonly attribute nsIDOMFileHandle fileHandle;
@ -26,7 +26,8 @@ interface nsIDOMLockedFile : nsISupports
readonly attribute boolean active;
attribute unsigned long long location;
[implicit_jscontext]
attribute jsval location;
[implicit_jscontext]
nsIDOMFileRequest
@ -51,7 +52,7 @@ interface nsIDOMLockedFile : nsISupports
[optional_argc]
nsIDOMFileRequest
truncate([optional] in unsigned long long location);
truncate([optional] in unsigned long long size);
nsIDOMFileRequest
flush();

Просмотреть файл

@ -16,6 +16,7 @@ TEST_FILES = \
helpers.js \
test_append_read_data.html \
test_getFileId.html \
test_location.html \
test_lockedfile_lifetimes.html \
test_lockedfile_lifetimes_nested.html \
test_lockedfile_ordering.html \

Просмотреть файл

@ -12,8 +12,6 @@
<script type="text/javascript;version=1.7">
function testSteps()
{
const maxLocation = 18446744073709552000;
var testString = "Lorem ipsum his ponderum delicatissimi ne, at noster dolores urbanitas pro, cibo elaboraret no his. Ea dicunt maiorum usu. Ad appareat facilisis mediocritatem eos. Tale graeci mentitum in eos, hinc insolens at nam. Graecis nominavi aliquyam eu vix. Id solet assentior sadipscing pro. Et per atqui graecis, usu quot viris repudiandae ei, mollis evertitur an nam. At nam dolor ignota, liber labore omnesque ea mei, has movet voluptaria in. Vel an impetus omittantur. Vim movet option salutandi ex, ne mei ignota corrumpit. Mucius comprehensam id per. Est ea putant maiestatis.";
for (let i = 0; i < 5; i++) {
testString += testString;
@ -38,7 +36,7 @@
is(lockedFile.location, location, "Correct location");
request = lockedFile.append(testString);
is(lockedFile.location, maxLocation, "Correct location");
ok(lockedFile.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield;
@ -53,7 +51,7 @@
ok(resultString == testString, "Correct string data");
request = lockedFile.append(testBuffer);
is(lockedFile.location, maxLocation, "Correct location");
ok(lockedFile.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield;
@ -68,7 +66,7 @@
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
request = lockedFile.append(testBlob);
is(lockedFile.location, maxLocation, "Correct location");
ok(lockedFile.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield;

Просмотреть файл

@ -0,0 +1,96 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getFileHandle(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let fileHandle = event.target.result;
fileHandle.onerror = errorHandler;
let lockedFile = fileHandle.open("readwrite");
is(lockedFile.location, 0, "Correct location");
lockedFile.location = 100000;
is(lockedFile.location, 100000, "Correct location");
lockedFile.location = null;
ok(lockedFile.location === null, "Correct location");
try {
lockedFile.readAsArrayBuffer(1);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
try {
lockedFile.readAsText(1);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
try {
lockedFile.write({});
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
request = lockedFile.append("foo");
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(lockedFile.location === null, "Correct location");
try {
lockedFile.truncate();
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
request = lockedFile.truncate(0);
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(lockedFile.location, 0, "Correct location");
}
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>