зеркало из https://github.com/mozilla/gecko-dev.git
Bug 761159 - FileHandle: Better handling of the end of file state. r=sicking
This commit is contained in:
Родитель
faa9392008
Коммит
8c778eb7cd
|
@ -506,18 +506,39 @@ LockedFile::GetActive(bool* aActive)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
LockedFile::GetLocation(PRUint64* aLocation)
|
LockedFile::GetLocation(JSContext* aCx,
|
||||||
|
jsval* aLocation)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
LockedFile::SetLocation(PRUint64 aLocation)
|
LockedFile::SetLocation(JSContext* aCx,
|
||||||
|
const jsval& aLocation)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +597,10 @@ LockedFile::ReadAsArrayBuffer(PRUint64 aSize,
|
||||||
return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
|
return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mLocation == LL_MAXUINT) {
|
||||||
|
return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!aSize) {
|
if (!aSize) {
|
||||||
return NS_ERROR_TYPE_ERR;
|
return NS_ERROR_TYPE_ERR;
|
||||||
}
|
}
|
||||||
|
@ -614,6 +639,10 @@ LockedFile::ReadAsText(PRUint64 aSize,
|
||||||
return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
|
return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mLocation == LL_MAXUINT) {
|
||||||
|
return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!aSize) {
|
if (!aSize) {
|
||||||
return NS_ERROR_TYPE_ERR;
|
return NS_ERROR_TYPE_ERR;
|
||||||
}
|
}
|
||||||
|
@ -662,7 +691,7 @@ LockedFile::Append(const jsval& aValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
LockedFile::Truncate(PRUint64 aLocation,
|
LockedFile::Truncate(PRUint64 aSize,
|
||||||
PRUint8 aOptionalArgCount,
|
PRUint8 aOptionalArgCount,
|
||||||
nsIDOMFileRequest** _retval)
|
nsIDOMFileRequest** _retval)
|
||||||
{
|
{
|
||||||
|
@ -676,6 +705,19 @@ LockedFile::Truncate(PRUint64 aLocation,
|
||||||
return NS_ERROR_DOM_FILEHANDLE_READ_ONLY_ERR;
|
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
|
// Do nothing if the window is closed
|
||||||
if (!GetOwner()) {
|
if (!GetOwner()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -684,8 +726,6 @@ LockedFile::Truncate(PRUint64 aLocation,
|
||||||
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
|
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
|
||||||
NS_ENSURE_TRUE(fileRequest, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
NS_ENSURE_TRUE(fileRequest, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||||
|
|
||||||
PRUint64 location = aOptionalArgCount ? aLocation : mLocation;
|
|
||||||
|
|
||||||
nsRefPtr<TruncateHelper> helper =
|
nsRefPtr<TruncateHelper> helper =
|
||||||
new TruncateHelper(this, fileRequest, location);
|
new TruncateHelper(this, fileRequest, location);
|
||||||
|
|
||||||
|
@ -693,7 +733,7 @@ LockedFile::Truncate(PRUint64 aLocation,
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||||
|
|
||||||
if (aOptionalArgCount) {
|
if (aOptionalArgCount) {
|
||||||
mLocation = aLocation;
|
mLocation = aSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileRequest.forget(_retval);
|
fileRequest.forget(_retval);
|
||||||
|
@ -820,6 +860,10 @@ LockedFile::WriteOrAppend(const jsval& aValue,
|
||||||
return NS_ERROR_DOM_FILEHANDLE_READ_ONLY_ERR;
|
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
|
// Do nothing if the window is closed
|
||||||
if (!GetOwner()) {
|
if (!GetOwner()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -16,7 +16,7 @@ dictionary DOMFileMetadataParameters
|
||||||
boolean lastModified;
|
boolean lastModified;
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(e1f69cc5-c6ce-4850-bc09-c4211b1d4290)]
|
[scriptable, builtinclass, uuid(696a4cbf-603d-40e1-840a-e468ee363871)]
|
||||||
interface nsIDOMLockedFile : nsISupports
|
interface nsIDOMLockedFile : nsISupports
|
||||||
{
|
{
|
||||||
readonly attribute nsIDOMFileHandle fileHandle;
|
readonly attribute nsIDOMFileHandle fileHandle;
|
||||||
|
@ -26,7 +26,8 @@ interface nsIDOMLockedFile : nsISupports
|
||||||
|
|
||||||
readonly attribute boolean active;
|
readonly attribute boolean active;
|
||||||
|
|
||||||
attribute unsigned long long location;
|
[implicit_jscontext]
|
||||||
|
attribute jsval location;
|
||||||
|
|
||||||
[implicit_jscontext]
|
[implicit_jscontext]
|
||||||
nsIDOMFileRequest
|
nsIDOMFileRequest
|
||||||
|
@ -51,7 +52,7 @@ interface nsIDOMLockedFile : nsISupports
|
||||||
|
|
||||||
[optional_argc]
|
[optional_argc]
|
||||||
nsIDOMFileRequest
|
nsIDOMFileRequest
|
||||||
truncate([optional] in unsigned long long location);
|
truncate([optional] in unsigned long long size);
|
||||||
|
|
||||||
nsIDOMFileRequest
|
nsIDOMFileRequest
|
||||||
flush();
|
flush();
|
||||||
|
|
|
@ -16,6 +16,7 @@ TEST_FILES = \
|
||||||
helpers.js \
|
helpers.js \
|
||||||
test_append_read_data.html \
|
test_append_read_data.html \
|
||||||
test_getFileId.html \
|
test_getFileId.html \
|
||||||
|
test_location.html \
|
||||||
test_lockedfile_lifetimes.html \
|
test_lockedfile_lifetimes.html \
|
||||||
test_lockedfile_lifetimes_nested.html \
|
test_lockedfile_lifetimes_nested.html \
|
||||||
test_lockedfile_ordering.html \
|
test_lockedfile_ordering.html \
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
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.";
|
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++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
testString += testString;
|
testString += testString;
|
||||||
|
@ -38,7 +36,7 @@
|
||||||
is(lockedFile.location, location, "Correct location");
|
is(lockedFile.location, location, "Correct location");
|
||||||
|
|
||||||
request = lockedFile.append(testString);
|
request = lockedFile.append(testString);
|
||||||
is(lockedFile.location, maxLocation, "Correct location");
|
ok(lockedFile.location === null, "Correct location");
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
|
@ -53,7 +51,7 @@
|
||||||
ok(resultString == testString, "Correct string data");
|
ok(resultString == testString, "Correct string data");
|
||||||
|
|
||||||
request = lockedFile.append(testBuffer);
|
request = lockedFile.append(testBuffer);
|
||||||
is(lockedFile.location, maxLocation, "Correct location");
|
ok(lockedFile.location === null, "Correct location");
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
|
@ -68,7 +66,7 @@
|
||||||
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
|
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
|
||||||
|
|
||||||
request = lockedFile.append(testBlob);
|
request = lockedFile.append(testBlob);
|
||||||
is(lockedFile.location, maxLocation, "Correct location");
|
ok(lockedFile.location === null, "Correct location");
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
event = yield;
|
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>
|
Загрузка…
Ссылка в новой задаче