mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 16:49:18 -05:00
fix(compile): correct buffered reading of assets and files (#27008)
Closes #27006
This commit is contained in:
parent
9c0e6369b2
commit
4ded7519e9
14 changed files with 104 additions and 12 deletions
|
@ -634,7 +634,7 @@ impl FileBackedVfsFile {
|
|||
}
|
||||
|
||||
fn read_to_buf(&self, buf: &mut [u8]) -> FsResult<usize> {
|
||||
let pos = {
|
||||
let read_pos = {
|
||||
let mut pos = self.pos.lock();
|
||||
let read_pos = *pos;
|
||||
// advance the position due to the read
|
||||
|
@ -643,12 +643,12 @@ impl FileBackedVfsFile {
|
|||
};
|
||||
self
|
||||
.vfs
|
||||
.read_file(&self.file, pos, buf)
|
||||
.read_file(&self.file, read_pos, buf)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn read_to_end(&self) -> FsResult<Vec<u8>> {
|
||||
let pos = {
|
||||
let read_pos = {
|
||||
let mut pos = self.pos.lock();
|
||||
let read_pos = *pos;
|
||||
// todo(dsherret): should this always set it to the end of the file?
|
||||
|
@ -658,12 +658,12 @@ impl FileBackedVfsFile {
|
|||
}
|
||||
read_pos
|
||||
};
|
||||
if pos > self.file.len {
|
||||
if read_pos > self.file.len {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
let size = (self.file.len - pos) as usize;
|
||||
let size = (self.file.len - read_pos) as usize;
|
||||
let mut buf = vec![0; size];
|
||||
self.vfs.read_file(&self.file, pos, &mut buf)?;
|
||||
self.vfs.read_file(&self.file, read_pos, &mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
@ -893,8 +893,9 @@ impl FileBackedVfs {
|
|||
buf: &mut [u8],
|
||||
) -> std::io::Result<usize> {
|
||||
let read_range = self.get_read_range(file, pos, buf.len() as u64)?;
|
||||
buf.copy_from_slice(&self.vfs_data[read_range]);
|
||||
Ok(buf.len())
|
||||
let read_len = read_range.len();
|
||||
buf[..read_len].copy_from_slice(&self.vfs_data[read_range]);
|
||||
Ok(read_len)
|
||||
}
|
||||
|
||||
fn get_read_range(
|
||||
|
@ -903,15 +904,15 @@ impl FileBackedVfs {
|
|||
pos: u64,
|
||||
len: u64,
|
||||
) -> std::io::Result<Range<usize>> {
|
||||
let data = &self.vfs_data;
|
||||
let start = self.fs_root.start_file_offset + file.offset + pos;
|
||||
let end = start + len;
|
||||
if end > data.len() as u64 {
|
||||
if pos > file.len {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::UnexpectedEof,
|
||||
"unexpected EOF",
|
||||
));
|
||||
}
|
||||
let file_offset = self.fs_root.start_file_offset + file.offset;
|
||||
let start = file_offset + pos;
|
||||
let end = file_offset + std::cmp::min(pos + len, file.len);
|
||||
Ok(start as usize..end as usize)
|
||||
}
|
||||
|
||||
|
|
27
tests/specs/compile/include/buffered_reads/__test__.jsonc
Normal file
27
tests/specs/compile/include/buffered_reads/__test__.jsonc
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"steps": [{
|
||||
"args": "run -A setup.js",
|
||||
"output": "[WILDCARD]"
|
||||
}, {
|
||||
"if": "unix",
|
||||
"args": "compile --allow-read=data --include data --output main main.ts",
|
||||
"output": "[WILDCARD]"
|
||||
}, {
|
||||
"if": "unix",
|
||||
"commandName": "./main",
|
||||
"args": [],
|
||||
"output": "[WILDCARD]",
|
||||
"exitCode": 0
|
||||
}, {
|
||||
"if": "windows",
|
||||
"args": "compile --allow-read=data --include data --output main.exe main.ts",
|
||||
"output": "[WILDCARD]"
|
||||
}, {
|
||||
"if": "windows",
|
||||
"commandName": "./main.exe",
|
||||
"args": [],
|
||||
"output": "[WILDCARD]",
|
||||
"exitCode": 0
|
||||
}]
|
||||
}
|
57
tests/specs/compile/include/buffered_reads/main.ts
Normal file
57
tests/specs/compile/include/buffered_reads/main.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
// buffer larger than file
|
||||
{
|
||||
using file = Deno.openSync(import.meta.dirname + "/data/1.txt");
|
||||
const data = new Uint8Array(13);
|
||||
const len = file.readSync(data);
|
||||
if (len !== 13) {
|
||||
throw new Error("Unexpected read length");
|
||||
}
|
||||
if (file.readSync(new Uint8Array(1024)) !== null) {
|
||||
throw new Error("Unexpected.");
|
||||
}
|
||||
const textData = new TextDecoder().decode(data);
|
||||
if (textData !== "Hello, world!") {
|
||||
throw new Error("Unexpected file data (1): " + textData);
|
||||
}
|
||||
}
|
||||
|
||||
// buffer smaller than file
|
||||
{
|
||||
using file = Deno.openSync(import.meta.dirname + "/data/1.txt");
|
||||
const finalData = new Uint8Array(13);
|
||||
const data = new Uint8Array(2);
|
||||
let pos = 0;
|
||||
while (true) {
|
||||
const len = file.readSync(data);
|
||||
if (len === 0 || len == null) {
|
||||
break;
|
||||
}
|
||||
finalData.set(data.subarray(0, len), pos);
|
||||
pos += len;
|
||||
}
|
||||
const textData = new TextDecoder().decode(finalData);
|
||||
if (textData !== "Hello, world!") {
|
||||
throw new Error("Unexpected file data (2): " + textData);
|
||||
}
|
||||
}
|
||||
|
||||
// large amount of data, small reads
|
||||
{
|
||||
const bytes = new Uint8Array((1024 ** 2) * 20);
|
||||
using file = Deno.openSync(import.meta.dirname + "/data/2.dat");
|
||||
const buffer = new Uint8Array(2);
|
||||
let pos = 0;
|
||||
while (true) {
|
||||
const len = file.readSync(buffer);
|
||||
if (len === 0 || len == null) {
|
||||
break;
|
||||
}
|
||||
bytes.set(buffer.subarray(0, len), pos);
|
||||
pos += len;
|
||||
}
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
if (bytes[i] !== i % 256) {
|
||||
throw new Error("Unexpected data.");
|
||||
}
|
||||
}
|
||||
}
|
7
tests/specs/compile/include/buffered_reads/setup.js
Normal file
7
tests/specs/compile/include/buffered_reads/setup.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
Deno.mkdirSync("data");
|
||||
Deno.writeTextFileSync("data/1.txt", "Hello, world!");
|
||||
const bytes = new Uint8Array((1024 ** 2) * 20);
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = i % 256;
|
||||
}
|
||||
Deno.writeFileSync("data/2.dat", bytes);
|
Loading…
Reference in a new issue