os: implement os.write_file_array and os.read_file_array .

pull/5819/head
Delyan Angelov 2020-07-13 10:45:10 +03:00
parent db2346069a
commit 1baa7ef806
2 changed files with 73 additions and 4 deletions

View File

@ -60,18 +60,19 @@ pub fn (mut f File) writeln(s string) {
C.fputs('\n', f.cfile) C.fputs('\n', f.cfile)
} }
pub fn (mut f File) write_bytes(data voidptr, size int) { pub fn (mut f File) write_bytes(data voidptr, size int) int {
C.fwrite(data, 1, size, f.cfile) return C.fwrite(data, 1, size, f.cfile)
} }
pub fn (mut f File) write_bytes_at(data voidptr, size, pos int) { pub fn (mut f File) write_bytes_at(data voidptr, size, pos int) int {
//$if linux { //$if linux {
//} //}
//$else { //$else {
C.fseek(f.cfile, pos, C.SEEK_SET) C.fseek(f.cfile, pos, C.SEEK_SET)
C.fwrite(data, 1, size, f.cfile) res := C.fwrite(data, 1, size, f.cfile)
C.fseek(f.cfile, 0, C.SEEK_END) C.fseek(f.cfile, 0, C.SEEK_END)
//} //}
return res
} }
/***************************** Read ops ****************************/ /***************************** Read ops ****************************/
@ -887,6 +888,35 @@ pub fn write_file(path, text string) ? {
f.close() f.close()
} }
// write_file_array writes the data in `buffer` to a file in `path`.
pub fn write_file_array(path string, buffer array) ? {
mut f := os.create(path) or {
return error(err)
}
f.write_bytes_at(buffer.data, (buffer.len * buffer.element_size), 0)
f.close()
}
// read_file_array reads an array of `T` values from file `path`
pub fn read_file_array<T>(path string) []T {
a := T{}
tsize := int(sizeof(a))
// prepare for reading, get current file size
mut fp := vfopen(path, 'rb')
if isnil(fp) {
return array{}
}
C.fseek(fp, 0, C.SEEK_END)
fsize := C.ftell(fp)
C.rewind(fp)
// read the actual data from the file
len := fsize / tsize
buf := malloc(fsize)
C.fread(buf, fsize, 1, fp)
C.fclose(fp)
return array{element_size: tsize data: buf len: len cap: len }
}
pub fn on_segfault(f voidptr) { pub fn on_segfault(f voidptr) {
$if windows { $if windows {
return return

View File

@ -20,6 +20,7 @@ fn testsuite_end() {
os.chdir( os.wd_at_startup ) os.chdir( os.wd_at_startup )
os.rmdir_all( tfolder ) os.rmdir_all( tfolder )
assert !os.is_dir( tfolder ) assert !os.is_dir( tfolder )
//eprintln('testsuite_end , tfolder = $tfolder removed.')
} }
fn test_open_file() { fn test_open_file() {
@ -352,3 +353,41 @@ fn test_uname() {
assert u.version.len > 0 assert u.version.len > 0
assert u.machine.len > 0 assert u.machine.len > 0
} }
// tests for write_file_array and read_file_array<T>:
const (
maxn = 3
)
struct IntPoint {
x int
y int
}
fn test_write_file_array_bytes() {
fpath := './abytes.bin'
mut arr := []byte{len: maxn}
for i in 0 .. maxn {
arr[i] = 65 + byte(i)
}
os.write_file_array(fpath, arr)
rarr := os.read_bytes(fpath) or {
panic(err)
}
assert arr == rarr
//eprintln(arr.str())
//eprintln(rarr.str())
}
fn test_write_file_array_structs() {
fpath := './astructs.bin'
mut arr := []IntPoint{len: maxn}
for i in 0 .. maxn {
arr[i] = IntPoint{65 + i, 65 + i + 10}
}
os.write_file_array(fpath, arr)
rarr := os.read_file_array<IntPoint>(fpath)
assert rarr == arr
assert rarr.len == maxn
//eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n'))
}