1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

os: add fn read_bytes_into with buffer argument (#6365)

This commit is contained in:
Nick Treleaven 2020-09-14 14:34:34 +01:00 committed by GitHub
parent 5c8e1c7eeb
commit b552c29bef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 7 deletions

View File

@ -78,21 +78,42 @@ pub fn (mut f File) write_bytes_at(data voidptr, size, pos int) int {
}
// **************************** Read ops ***************************
// read_bytes reads an amount of bytes from the beginning of the file
// read_bytes reads bytes from the beginning of the file
pub fn (f &File) read_bytes(size int) []byte {
return f.read_bytes_at(size, 0)
}
// read_bytes_at reads an amount of bytes at the given position in the file
// read_bytes_at reads bytes at the given position in the file
pub fn (f &File) read_bytes_at(size, pos int) []byte {
// mut arr := [`0`].repeat(size)
mut arr := []byte{len: size}
C.fseek(f.cfile, pos, C.SEEK_SET)
nreadbytes := C.fread(arr.data, 1, size, f.cfile)
C.fseek(f.cfile, 0, C.SEEK_SET)
nreadbytes := f.read_bytes_into(pos, arr) or {
// return err
return []
}
return arr[0..nreadbytes]
}
// read_bytes_from fills `buf` with bytes at the given position in the file.
// `buf` must have length greater than zero.
// Returns number of bytes read or an error.
pub fn (f &File) read_bytes_into(pos int, mut buf []byte) ?int {
if buf.len == 0 {
panic(@FN + ': `buf.len` == 0')
}
// Note: fseek errors if pos == os.file_size, which we accept
C.fseek(f.cfile, pos, C.SEEK_SET)
// errno is only set if fread fails, so clear it first to tell
C.errno = 0
nbytes := C.fread(buf.data, 1, buf.len, f.cfile)
if C.errno != 0 {
return error(posix_get_error_msg(C.errno))
}
$if debug {
C.fseek(f.cfile, 0, C.SEEK_SET)
}
return nbytes
}
// **************************** Utility ops ***********************
// write any unwritten data in stream's buffer
pub fn (mut f File) flush() {

View File

@ -142,11 +142,19 @@ fn test_write_and_read_bytes() {
// read_bytes_at with second parameter zeroed (size, 0).
rbytes := file_read.read_bytes(5)
file_read.close()
// eprintln('rbytes: $rbytes')
// eprintln('payload: $payload')
assert rbytes == payload
// check that trying to read data from EOF doesn't error and returns 0
mut a := []byte{len: 5}
nread := file_read.read_bytes_into(5, a) or {
eprintln(err)
int(-1)
}
assert nread == 0
file_read.close()
// We finally delete the test file.
os.rm(file_name)
}