mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -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> {
|
fn read_to_buf(&self, buf: &mut [u8]) -> FsResult<usize> {
|
||||||
let pos = {
|
let read_pos = {
|
||||||
let mut pos = self.pos.lock();
|
let mut pos = self.pos.lock();
|
||||||
let read_pos = *pos;
|
let read_pos = *pos;
|
||||||
// advance the position due to the read
|
// advance the position due to the read
|
||||||
|
@ -643,12 +643,12 @@ impl FileBackedVfsFile {
|
||||||
};
|
};
|
||||||
self
|
self
|
||||||
.vfs
|
.vfs
|
||||||
.read_file(&self.file, pos, buf)
|
.read_file(&self.file, read_pos, buf)
|
||||||
.map_err(|err| err.into())
|
.map_err(|err| err.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_to_end(&self) -> FsResult<Vec<u8>> {
|
fn read_to_end(&self) -> FsResult<Vec<u8>> {
|
||||||
let pos = {
|
let read_pos = {
|
||||||
let mut pos = self.pos.lock();
|
let mut pos = self.pos.lock();
|
||||||
let read_pos = *pos;
|
let read_pos = *pos;
|
||||||
// todo(dsherret): should this always set it to the end of the file?
|
// todo(dsherret): should this always set it to the end of the file?
|
||||||
|
@ -658,12 +658,12 @@ impl FileBackedVfsFile {
|
||||||
}
|
}
|
||||||
read_pos
|
read_pos
|
||||||
};
|
};
|
||||||
if pos > self.file.len {
|
if read_pos > self.file.len {
|
||||||
return Ok(Vec::new());
|
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];
|
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)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -893,8 +893,9 @@ impl FileBackedVfs {
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
) -> std::io::Result<usize> {
|
) -> std::io::Result<usize> {
|
||||||
let read_range = self.get_read_range(file, pos, buf.len() as u64)?;
|
let read_range = self.get_read_range(file, pos, buf.len() as u64)?;
|
||||||
buf.copy_from_slice(&self.vfs_data[read_range]);
|
let read_len = read_range.len();
|
||||||
Ok(buf.len())
|
buf[..read_len].copy_from_slice(&self.vfs_data[read_range]);
|
||||||
|
Ok(read_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_read_range(
|
fn get_read_range(
|
||||||
|
@ -903,15 +904,15 @@ impl FileBackedVfs {
|
||||||
pos: u64,
|
pos: u64,
|
||||||
len: u64,
|
len: u64,
|
||||||
) -> std::io::Result<Range<usize>> {
|
) -> std::io::Result<Range<usize>> {
|
||||||
let data = &self.vfs_data;
|
if pos > file.len {
|
||||||
let start = self.fs_root.start_file_offset + file.offset + pos;
|
|
||||||
let end = start + len;
|
|
||||||
if end > data.len() as u64 {
|
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
std::io::ErrorKind::UnexpectedEof,
|
std::io::ErrorKind::UnexpectedEof,
|
||||||
"unexpected EOF",
|
"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)
|
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