mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1075438 - Removed readTo function from two files and fixed read function to work without readTo.Also removed the test for readTo function from mochi and xpcshell tests. r=Yoric
This commit is contained in:
parent
9bddd229c3
commit
cd3b29d584
@ -618,39 +618,6 @@ File.prototype = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a number of bytes from the file and into a buffer.
|
|
||||||
*
|
|
||||||
* @param {Typed array | C pointer} buffer This buffer will be
|
|
||||||
* modified by another thread. Using this buffer before the |read|
|
|
||||||
* operation has completed is a BAD IDEA.
|
|
||||||
* @param {JSON} options
|
|
||||||
*
|
|
||||||
* @return {promise}
|
|
||||||
* @resolves {number} The number of bytes effectively read.
|
|
||||||
* @rejects {OS.File.Error}
|
|
||||||
*/
|
|
||||||
readTo: function readTo(buffer, options = {}) {
|
|
||||||
// If |buffer| is a typed array and there is no |bytes| options, we
|
|
||||||
// need to extract the |byteLength| now, as it will be lost by
|
|
||||||
// communication.
|
|
||||||
// Options might be a nullish value, so better check for that before using
|
|
||||||
// the |in| operator.
|
|
||||||
if (isTypedArray(buffer) && !(options && "bytes" in options)) {
|
|
||||||
// Preserve reference to option |outExecutionDuration|, if it is passed.
|
|
||||||
options = clone(options, ["outExecutionDuration"]);
|
|
||||||
options.bytes = buffer.byteLength;
|
|
||||||
}
|
|
||||||
// Note: Type.void_t.out_ptr.toMsg ensures that
|
|
||||||
// - the buffer is effectively shared (not neutered) between both
|
|
||||||
// threads;
|
|
||||||
// - we take care of any |byteOffset|.
|
|
||||||
return Scheduler.post("File_prototype_readTo",
|
|
||||||
[this._fdmsg,
|
|
||||||
Type.void_t.out_ptr.toMsg(buffer),
|
|
||||||
options],
|
|
||||||
buffer/*Ensure that |buffer| is not gc-ed*/);
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Write bytes from a buffer to this file.
|
* Write bytes from a buffer to this file.
|
||||||
*
|
*
|
||||||
|
@ -52,43 +52,22 @@ AbstractFile.prototype = {
|
|||||||
/**
|
/**
|
||||||
* Read bytes from this file to a new buffer.
|
* Read bytes from this file to a new buffer.
|
||||||
*
|
*
|
||||||
* @param {number=} bytes If unspecified, read all the remaining bytes from
|
* @param {number=} maybeBytes (deprecated, please use options.bytes)
|
||||||
* this file. If specified, read |bytes| bytes, or less if the file does notclone
|
|
||||||
* contain that many bytes.
|
|
||||||
* @param {JSON} options
|
* @param {JSON} options
|
||||||
* @return {Uint8Array} An array containing the bytes read.
|
* @return {Uint8Array} An array containing the bytes read.
|
||||||
*/
|
*/
|
||||||
read: function read(bytes, options = {}) {
|
read: function read(maybeBytes, options = {}) {
|
||||||
options = clone(options);
|
if (typeof maybeBytes === "object") {
|
||||||
options.bytes = bytes == null ? this.stat().size : bytes;
|
// Caller has skipped `maybeBytes` and provided an options object.
|
||||||
let buffer = new Uint8Array(options.bytes);
|
options = clone(maybeBytes);
|
||||||
let size = this.readTo(buffer, options);
|
maybeBytes = null;
|
||||||
if (size == options.bytes) {
|
|
||||||
return buffer;
|
|
||||||
} else {
|
} else {
|
||||||
return buffer.subarray(0, size);
|
options = clone(options || {});
|
||||||
}
|
}
|
||||||
},
|
if(!("bytes" in options)) {
|
||||||
|
options.bytes = maybeBytes == null ? this.stat().size : maybeBytes;
|
||||||
/**
|
}
|
||||||
* Read bytes from this file to an existing buffer.
|
let buffer = new Uint8Array(options.bytes);
|
||||||
*
|
|
||||||
* Note that, by default, this function may perform several I/O
|
|
||||||
* operations to ensure that the buffer is as full as possible.
|
|
||||||
*
|
|
||||||
* @param {Typed Array | C pointer} buffer The buffer in which to
|
|
||||||
* store the bytes. The buffer must be large enough to
|
|
||||||
* accomodate |bytes| bytes.
|
|
||||||
* @param {*=} options Optionally, an object that may contain the
|
|
||||||
* following fields:
|
|
||||||
* - {number} bytes The number of |bytes| to write from the buffer. If
|
|
||||||
* unspecified, this is |buffer.byteLength|. Note that |bytes| is required
|
|
||||||
* if |buffer| is a C pointer.
|
|
||||||
*
|
|
||||||
* @return {number} The number of bytes actually read, which may be
|
|
||||||
* less than |bytes| if the file did not contain that many bytes left.
|
|
||||||
*/
|
|
||||||
readTo: function readTo(buffer, options = {}) {
|
|
||||||
let {ptr, bytes} = SharedAll.normalizeToPointer(buffer, options.bytes);
|
let {ptr, bytes} = SharedAll.normalizeToPointer(buffer, options.bytes);
|
||||||
let pos = 0;
|
let pos = 0;
|
||||||
while (pos < bytes) {
|
while (pos < bytes) {
|
||||||
@ -99,8 +78,11 @@ AbstractFile.prototype = {
|
|||||||
pos += chunkSize;
|
pos += chunkSize;
|
||||||
ptr = SharedAll.offsetBy(ptr, chunkSize);
|
ptr = SharedAll.offsetBy(ptr, chunkSize);
|
||||||
}
|
}
|
||||||
|
if (pos == options.bytes) {
|
||||||
return pos;
|
return buffer;
|
||||||
|
} else {
|
||||||
|
return buffer.subarray(0, pos);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +152,6 @@ let test = maketest("Main", function main(test) {
|
|||||||
yield test_stat();
|
yield test_stat();
|
||||||
yield test_debug();
|
yield test_debug();
|
||||||
yield test_info_features_detect();
|
yield test_info_features_detect();
|
||||||
yield test_read_write();
|
|
||||||
yield test_position();
|
yield test_position();
|
||||||
yield test_iter();
|
yield test_iter();
|
||||||
yield test_exists();
|
yield test_exists();
|
||||||
@ -220,62 +219,6 @@ let test_info_features_detect = maketest("features_detect", function features_de
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Test OS.File.prototype.{read, readTo, write}
|
|
||||||
*/
|
|
||||||
let test_read_write = maketest("read_write", function read_write(test) {
|
|
||||||
return Task.spawn(function() {
|
|
||||||
// Test readTo/write
|
|
||||||
let currentDir = yield OS.File.getCurrentDirectory();
|
|
||||||
let pathSource = OS.Path.join(currentDir, EXISTING_FILE);
|
|
||||||
let pathDest = OS.Path.join(OS.Constants.Path.tmpDir,
|
|
||||||
"osfile async test.tmp");
|
|
||||||
|
|
||||||
let fileSource = yield OS.File.open(pathSource);
|
|
||||||
test.info("Input file opened");
|
|
||||||
let fileDest = yield OS.File.open(pathDest,
|
|
||||||
{ truncate: true, read: true, write: true});
|
|
||||||
test.info("Output file opened");
|
|
||||||
|
|
||||||
let stat = yield fileSource.stat();
|
|
||||||
test.info("Input stat worked");
|
|
||||||
let size = stat.size;
|
|
||||||
let array = new Uint8Array(size);
|
|
||||||
|
|
||||||
try {
|
|
||||||
test.info("Now calling readTo");
|
|
||||||
let readLength = yield fileSource.readTo(array);
|
|
||||||
test.info("ReadTo worked");
|
|
||||||
test.is(readLength, size, "ReadTo got all bytes");
|
|
||||||
let writeLength = yield fileDest.write(array);
|
|
||||||
test.info("Write worked");
|
|
||||||
test.is(writeLength, size, "Write wrote all bytes");
|
|
||||||
|
|
||||||
// Test read
|
|
||||||
yield fileSource.setPosition(0);
|
|
||||||
let readAllResult = yield fileSource.read();
|
|
||||||
test.info("ReadAll worked");
|
|
||||||
test.is(readAllResult.length, size, "ReadAll read all bytes");
|
|
||||||
test.is(Array.prototype.join.call(readAllResult),
|
|
||||||
Array.prototype.join.call(array),
|
|
||||||
"ReadAll result is correct");
|
|
||||||
} finally {
|
|
||||||
// Close stuff
|
|
||||||
yield fileSource.close();
|
|
||||||
yield fileDest.close();
|
|
||||||
test.info("Files are closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
stat = yield OS.File.stat(pathDest);
|
|
||||||
test.is(stat.size, size, "Both files have the same size");
|
|
||||||
yield reference_compare_files(pathSource, pathDest, test);
|
|
||||||
|
|
||||||
// Cleanup.
|
|
||||||
OS.File.remove(pathDest);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test file.{getPosition, setPosition}
|
* Test file.{getPosition, setPosition}
|
||||||
*/
|
*/
|
||||||
@ -284,13 +227,8 @@ let test_position = maketest("position", function position(test) {
|
|||||||
let file = yield OS.File.open(EXISTING_FILE);
|
let file = yield OS.File.open(EXISTING_FILE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let stat = yield file.stat();
|
let view = yield file.read();
|
||||||
test.info("Obtained file length");
|
|
||||||
|
|
||||||
let view = new Uint8Array(stat.size);
|
|
||||||
yield file.readTo(view);
|
|
||||||
test.info("First batch of content read");
|
test.info("First batch of content read");
|
||||||
|
|
||||||
let CHUNK_SIZE = 178;// An arbitrary number of bytes to read from the file
|
let CHUNK_SIZE = 178;// An arbitrary number of bytes to read from the file
|
||||||
let pos = yield file.getPosition();
|
let pos = yield file.getPosition();
|
||||||
test.info("Obtained position");
|
test.info("Obtained position");
|
||||||
@ -299,8 +237,7 @@ let test_position = maketest("position", function position(test) {
|
|||||||
test.info("Changed position");
|
test.info("Changed position");
|
||||||
test.is(pos, view.byteLength - CHUNK_SIZE, "setPosition returned the correct position");
|
test.is(pos, view.byteLength - CHUNK_SIZE, "setPosition returned the correct position");
|
||||||
|
|
||||||
let view2 = new Uint8Array(CHUNK_SIZE);
|
let view2 = yield file.read();
|
||||||
yield file.readTo(view2);
|
|
||||||
test.info("Read the end of the file");
|
test.info("Read the end of the file");
|
||||||
for (let i = 0; i < CHUNK_SIZE; ++i) {
|
for (let i = 0; i < CHUNK_SIZE; ++i) {
|
||||||
if (view2[i] != view[i + view.byteLength - CHUNK_SIZE]) {
|
if (view2[i] != view[i + view.byteLength - CHUNK_SIZE]) {
|
||||||
|
@ -27,7 +27,6 @@ self.onmessage = function onmessage_start(msg) {
|
|||||||
test_open_non_existing_file();
|
test_open_non_existing_file();
|
||||||
test_flush_open_file();
|
test_flush_open_file();
|
||||||
test_copy_existing_file();
|
test_copy_existing_file();
|
||||||
test_readall_writeall_file();
|
|
||||||
test_position();
|
test_position();
|
||||||
test_move_file();
|
test_move_file();
|
||||||
test_iter_dir();
|
test_iter_dir();
|
||||||
@ -184,190 +183,6 @@ function compare_files(test, sourcePath, destPath, prefix)
|
|||||||
info(test + ": Comparison complete");
|
info(test + ": Comparison complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_readall_writeall_file()
|
|
||||||
{
|
|
||||||
let src_file_name =
|
|
||||||
OS.Path.join("chrome", "toolkit", "components", "osfile", "tests", "mochi",
|
|
||||||
"worker_test_osfile_front.js");
|
|
||||||
let tmp_file_name =
|
|
||||||
OS.Path.join(OS.Constants.Path.tmpDir, "test_osfile_front.tmp");
|
|
||||||
info("Starting test_readall_writeall_file");
|
|
||||||
|
|
||||||
// read, ArrayBuffer
|
|
||||||
|
|
||||||
let source = OS.File.open(src_file_name);
|
|
||||||
let dest = OS.File.open(tmp_file_name, {write: true, trunc:true});
|
|
||||||
let size = source.stat().size;
|
|
||||||
|
|
||||||
let buf = new Uint8Array(size);
|
|
||||||
let readResult = source.readTo(buf);
|
|
||||||
is(readResult, size, "test_readall_writeall_file: read the right number of bytes");
|
|
||||||
|
|
||||||
dest.write(buf);
|
|
||||||
|
|
||||||
info("test_readall_writeall_file: copy complete (manual allocation)");
|
|
||||||
source.close();
|
|
||||||
dest.close();
|
|
||||||
|
|
||||||
compare_files("test_readall_writeall_file (manual allocation)", src_file_name, tmp_file_name);
|
|
||||||
OS.File.remove(tmp_file_name);
|
|
||||||
|
|
||||||
// read, C buffer
|
|
||||||
source = OS.File.open(src_file_name);
|
|
||||||
dest = OS.File.open(tmp_file_name, {write: true, trunc:true});
|
|
||||||
buf = new ArrayBuffer(size);
|
|
||||||
let ptr = OS.Shared.Type.voidptr_t.implementation(buf);
|
|
||||||
readResult = source.readTo(ptr, {bytes: size});
|
|
||||||
is(readResult, size, "test_readall_writeall_file: read the right number of bytes (C buffer)");
|
|
||||||
|
|
||||||
dest.write(ptr, {bytes: size});
|
|
||||||
|
|
||||||
info("test_readall_writeall_file: copy complete (C buffer)");
|
|
||||||
source.close();
|
|
||||||
dest.close();
|
|
||||||
|
|
||||||
compare_files("test_readall_writeall_file (C buffer)", src_file_name, tmp_file_name);
|
|
||||||
OS.File.remove(tmp_file_name);
|
|
||||||
|
|
||||||
// read/write, C buffer, missing |bytes| option
|
|
||||||
source = OS.File.open(src_file_name);
|
|
||||||
dest = OS.File.open(tmp_file_name, {write: true, trunc:true});
|
|
||||||
let exn = should_throw(function() { source.readTo(ptr); });
|
|
||||||
ok(exn != null && exn instanceof TypeError, "test_readall_writeall_file: read with C pointer and without bytes fails with the correct error");
|
|
||||||
exn = should_throw(function() { dest.write(ptr); });
|
|
||||||
ok(exn != null && exn instanceof TypeError, "test_readall_writeall_file: write with C pointer and without bytes fails with the correct error");
|
|
||||||
|
|
||||||
source.close();
|
|
||||||
dest.close();
|
|
||||||
|
|
||||||
// readTo, ArrayBuffer + offset
|
|
||||||
let OFFSET = 12;
|
|
||||||
let LEFT = size - OFFSET;
|
|
||||||
buf = new ArrayBuffer(size);
|
|
||||||
let offset_view = new Uint8Array(buf, OFFSET);
|
|
||||||
source = OS.File.open(src_file_name);
|
|
||||||
dest = OS.File.open(tmp_file_name, {write: true, trunc:true});
|
|
||||||
|
|
||||||
readResult = source.readTo(offset_view);
|
|
||||||
is(readResult, LEFT, "test_readall_writeall_file: read the right number of bytes (with offset)");
|
|
||||||
|
|
||||||
dest.write(offset_view);
|
|
||||||
is(dest.stat().size, LEFT, "test_readall_writeall_file: wrote the right number of bytes (with offset)");
|
|
||||||
|
|
||||||
info("test_readall_writeall_file: copy complete (with offset)");
|
|
||||||
source.close();
|
|
||||||
dest.close();
|
|
||||||
|
|
||||||
compare_files("test_readall_writeall_file (with offset)", src_file_name, tmp_file_name, LEFT);
|
|
||||||
OS.File.remove(tmp_file_name);
|
|
||||||
|
|
||||||
// read
|
|
||||||
buf = new Uint8Array(size);
|
|
||||||
source = OS.File.open(src_file_name);
|
|
||||||
dest = OS.File.open(tmp_file_name, {write: true, trunc:true});
|
|
||||||
|
|
||||||
readResult = source.read();
|
|
||||||
is(readResult.length, size, "test_readall_writeall_file: read the right number of bytes (auto allocation)");
|
|
||||||
|
|
||||||
dest.write(readResult);
|
|
||||||
|
|
||||||
info("test_readall_writeall_file: copy complete (auto allocation)");
|
|
||||||
source.close();
|
|
||||||
dest.close();
|
|
||||||
|
|
||||||
compare_files("test_readall_writeall_file (auto allocation)", src_file_name, tmp_file_name);
|
|
||||||
OS.File.remove(tmp_file_name);
|
|
||||||
|
|
||||||
// File.readAll
|
|
||||||
readResult = OS.File.read(src_file_name);
|
|
||||||
is(readResult.length, size, "test_readall_writeall_file: read the right number of bytes (OS.File.readAll)");
|
|
||||||
|
|
||||||
// File.writeAtomic on top of nothing
|
|
||||||
OS.File.writeAtomic(tmp_file_name, readResult,
|
|
||||||
{tmpPath: tmp_file_name + ".tmp"});
|
|
||||||
try {
|
|
||||||
let stat = OS.File.stat(tmp_file_name);
|
|
||||||
info("readAll + writeAtomic created a file");
|
|
||||||
is(stat.size, size, "readAll + writeAtomic created a file of the right size");
|
|
||||||
} catch (x) {
|
|
||||||
ok(false, "readAll + writeAtomic somehow failed");
|
|
||||||
if(x.becauseNoSuchFile) {
|
|
||||||
ok(false, "readAll + writeAtomic did not create file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compare_files("test_readall_writeall_file (OS.File.readAll + writeAtomic)",
|
|
||||||
src_file_name, tmp_file_name);
|
|
||||||
exn = null;
|
|
||||||
try {
|
|
||||||
let stat = OS.File.stat(tmp_file_name + ".tmp");
|
|
||||||
} catch (x) {
|
|
||||||
exn = x;
|
|
||||||
}
|
|
||||||
ok(!!exn, "readAll + writeAtomic cleaned up after itself");
|
|
||||||
|
|
||||||
// File.writeAtomic on top of existing file
|
|
||||||
// Remove content and set arbitrary size, to avoid potential false negatives
|
|
||||||
dest = OS.File.open(tmp_file_name, {write: true, trunc:true});
|
|
||||||
dest.setPosition(1234);
|
|
||||||
dest.close();
|
|
||||||
|
|
||||||
OS.File.writeAtomic(tmp_file_name, readResult,
|
|
||||||
{tmpPath: tmp_file_name + ".tmp"});
|
|
||||||
compare_files("test_readall_writeall_file (OS.File.readAll + writeAtomic 2)",
|
|
||||||
src_file_name, tmp_file_name);
|
|
||||||
|
|
||||||
// File.writeAtomic on top of existing file but without overwritten the file
|
|
||||||
exn = null;
|
|
||||||
try {
|
|
||||||
let view = new Uint8Array(readResult.buffer, 10, 200);
|
|
||||||
OS.File.writeAtomic(tmp_file_name, view,
|
|
||||||
{ tmpPath: tmp_file_name + ".tmp", noOverwrite: true});
|
|
||||||
} catch (x) {
|
|
||||||
exn = x;
|
|
||||||
}
|
|
||||||
ok(exn && exn instanceof OS.File.Error && exn.becauseExists, "writeAtomic fails if file already exists with noOverwrite option");
|
|
||||||
// Check file was not overwritten.
|
|
||||||
compare_files("test_readall_writeall_file (OS.File.readAll + writeAtomic check file was not overwritten)",
|
|
||||||
src_file_name, tmp_file_name);
|
|
||||||
|
|
||||||
// Ensure that File.writeAtomic fails if no temporary file name is provided
|
|
||||||
// (FIXME: Remove this test as part of bug 793660)
|
|
||||||
|
|
||||||
exn = null;
|
|
||||||
try {
|
|
||||||
OS.File.writeAtomic(tmp_file_name, readResult.buffer,
|
|
||||||
{bytes: readResult.length});
|
|
||||||
} catch (x) {
|
|
||||||
exn = x;
|
|
||||||
}
|
|
||||||
ok(!!exn && exn instanceof TypeError, "writeAtomic fails if tmpPath is not provided");
|
|
||||||
|
|
||||||
// Check that writeAtomic fails when destination path is undefined
|
|
||||||
exn = null;
|
|
||||||
try {
|
|
||||||
let path = undefined;
|
|
||||||
let options = {tmpPath: tmp_file_name};
|
|
||||||
OS.File.writeAtomic(path, readResult.buffer, options);
|
|
||||||
} catch (x) {
|
|
||||||
exn = x;
|
|
||||||
}
|
|
||||||
ok(!!exn && exn instanceof TypeError, "writeAtomic fails if path is undefined");
|
|
||||||
|
|
||||||
// Check that writeAtomic fails when destination path is an empty string
|
|
||||||
exn = null;
|
|
||||||
try {
|
|
||||||
let path = "";
|
|
||||||
let options = {tmpPath: tmp_file_name};
|
|
||||||
OS.File.writeAtomic(path, readResult.buffer, options);
|
|
||||||
} catch (x) {
|
|
||||||
exn = x;
|
|
||||||
}
|
|
||||||
ok(!!exn && exn instanceof TypeError, "writeAtomic fails if path is an empty string");
|
|
||||||
|
|
||||||
// Cleanup.
|
|
||||||
OS.File.remove(tmp_file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that copying a file using |copy| works.
|
* Test that copying a file using |copy| works.
|
||||||
*/
|
*/
|
||||||
|
@ -9,7 +9,7 @@ function run_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test to ensure that {bytes:} in options to |readTo| and |write| are correctly
|
* Test to ensure that {bytes:} in options to |write| is correctly
|
||||||
* preserved.
|
* preserved.
|
||||||
*/
|
*/
|
||||||
add_task(function* test_bytes() {
|
add_task(function* test_bytes() {
|
||||||
@ -23,12 +23,7 @@ add_task(function* test_bytes() {
|
|||||||
yield file.write(new Uint8Array(2048), {bytes: 1024});
|
yield file.write(new Uint8Array(2048), {bytes: 1024});
|
||||||
do_check_eq((yield file.stat()).size, 1024);
|
do_check_eq((yield file.stat()).size, 1024);
|
||||||
|
|
||||||
// 2. Test same for |readTo|.
|
// 2. Test that passing nullish values for |options| still works.
|
||||||
yield file.setPosition(0, OS.File.POS_START);
|
|
||||||
let read = yield file.readTo(new Uint8Array(1024), {bytes: 512});
|
|
||||||
do_check_eq(read, 512);
|
|
||||||
|
|
||||||
// 3. Test that passing nullish values for |options| still works.
|
|
||||||
yield file.setPosition(0, OS.File.POS_END);
|
yield file.setPosition(0, OS.File.POS_END);
|
||||||
yield file.write(new Uint8Array(1024), null);
|
yield file.write(new Uint8Array(1024), null);
|
||||||
yield file.write(new Uint8Array(1024), undefined);
|
yield file.write(new Uint8Array(1024), undefined);
|
||||||
|
Loading…
Reference in New Issue
Block a user