From c23155790ad65896ec6d5a46c05a6813a969014c Mon Sep 17 00:00:00 2001 From: Enrico Lefass Date: Sun, 20 Oct 2019 19:45:16 +0200 Subject: [PATCH] os: add pub fn read_bytes and pub fn read_bytes_at --- vlib/os/os.v | 21 +++++++++++++++++++++ vlib/os/os_test.v | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/vlib/os/os.v b/vlib/os/os.v index 1c58b7995f..77b040f0a4 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -71,6 +71,27 @@ fn C.ftell(fp voidptr) int fn C.getenv(byteptr) byteptr fn C.sigaction(int, voidptr, int) +// read_bytes reads an amount of 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 +pub fn (f File) read_bytes_at(size, pos int) []byte { + mut data := malloc(size) + mut arr := [`0`].repeat(size) + + C.fseek(f.cfile, pos, C.SEEK_SET) + C.fread(data, 1, size, f.cfile) + C.fseek(f.cfile, 0, C.SEEK_SET) + + for e := 0; e < size; e++ { + arr[e] = data[e] + } + + return arr +} + // read_file reads the file in `path` and returns the contents. pub fn read_file(path string) ?string { mode := 'rb' diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index f66322a86c..a0d64c35d1 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -33,6 +33,42 @@ fn test_write_and_read_string_to_file() { os.rm(filename) } +// test_write_and_read_bytes checks for regressions made in the functions +// read_bytes, read_bytes_at and write_bytes. +fn test_write_and_read_bytes() { + file_name := './byte_reader_writer.tst' + payload := [`I`, `D`, `D`, `Q`, `D`] + + file_write := os.create(os.realpath(file_name)) or { + eprintln('failed to create file $file_name') + return + } + + // We use the standard write_bytes function to write the payload and + // compare the length of the array with the file size (have to match). + file_write.write_bytes(payload.data, 5) + + file_write.close() + + assert payload.len == os.file_size(file_name) + + file_read := os.open(os.realpath(file_name)) or { + eprintln('failed to open file $file_name') + return + } + + // We only need to test read_bytes because this function calls + // read_bytes_at with second parameter zeroed (size, 0). + red_bytes := file_read.read_bytes(5) + + file_read.close() + + assert red_bytes.str() == payload.str() + + // We finally delete the test file. + os.rm(file_name) +} + fn test_create_and_delete_folder() { folder := './test1' os.mkdir(folder)