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

vlib/net: add buffered IO, x.net -> net (#6754)

This commit is contained in:
Emily Hudson
2020-11-15 20:54:47 +00:00
committed by GitHub
parent 20bec81678
commit cd2a2cef25
55 changed files with 741 additions and 1648 deletions

View File

@@ -1,7 +1,5 @@
module os
import strings
pub struct File {
cfile voidptr // Using void* instead of FILE*
pub:
@@ -17,12 +15,13 @@ struct FileInfo {
[deprecated]
pub fn (f File) is_opened() bool {
eprintln('warning: `file.is_opened()` has been deprecated, use `file.is_opened` instead')
eprintln('warning: `File.is_opened()` has been deprecated, use `File.is_opened` instead')
return f.is_opened
}
// **************************** Write ops ***************************
pub fn (mut f File) write(s string) ?int {
// write implements the Writer interface
pub fn (mut f File) write(buf []byte) ?int {
if !f.is_opened {
return error('file is not opened')
}
@@ -34,8 +33,8 @@ pub fn (mut f File) write(s string) ?int {
}
}
*/
written := C.fwrite(s.str, s.len, 1, f.cfile)
if written == 0 && s.len != 0 {
written := C.fwrite(buf.data, buf.len, 1, f.cfile)
if written == 0 && buf.len != 0 {
return error('0 bytes written')
}
return written
@@ -66,11 +65,23 @@ pub fn (mut f File) writeln(s string) ?int {
return (written + 1)
}
// write_to implements the RandomWriter interface
pub fn (mut f File) write_to(pos int, buf []byte) ?int {
C.fseek(f.cfile, pos, C.SEEK_SET)
res := C.fwrite(buf.data, 1, buf.len, f.cfile)
C.fseek(f.cfile, 0, C.SEEK_END)
return res
}
[deprecated]
pub fn (mut f File) write_bytes(data voidptr, size int) int {
eprintln('warning `File.write_bytes()` has been deprecated, use `File.write` instead')
return C.fwrite(data, 1, size, f.cfile)
}
[deprecated]
pub fn (mut f File) write_bytes_at(data voidptr, size int, pos int) int {
eprintln('warning `File.write_bytes_at()` has been deprecated, use `File.write_at` instead')
C.fseek(f.cfile, pos, C.SEEK_SET)
res := C.fwrite(data, 1, size, f.cfile)
C.fseek(f.cfile, 0, C.SEEK_END)
@@ -79,12 +90,16 @@ pub fn (mut f File) write_bytes_at(data voidptr, size int, pos int) int {
// **************************** Read ops ***************************
// read_bytes reads bytes from the beginning of the file
[deprecated]
pub fn (f &File) read_bytes(size int) []byte {
eprintln('warning `File.read_bytes()` has been deprecated, use `File.read` instead')
return f.read_bytes_at(size, 0)
}
// read_bytes_at reads bytes at the given position in the file
[deprecated]
pub fn (f &File) read_bytes_at(size int, pos int) []byte {
eprintln('warning `File.read_bytes_at()` has been deprecated, use `File.read_at` instead')
mut arr := []byte{len: size}
nreadbytes := f.read_bytes_into(pos, mut arr) or {
// return err
@@ -96,7 +111,9 @@ pub fn (f &File) read_bytes_at(size int, pos int) []byte {
// 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.
[deprecated]
pub fn (f &File) read_bytes_into(pos int, mut buf []byte) ?int {
eprintln('warning `File.read_bytes_into()` has been deprecated, use `File.read_from_into` instead')
if buf.len == 0 {
panic(@FN + ': `buf.len` == 0')
}
@@ -114,8 +131,35 @@ pub fn (f &File) read_bytes_into(pos int, mut buf []byte) ?int {
return nbytes
}
// read implements the Reader interface
pub fn (f &File) read(mut buf []byte) ?int {
if buf.len == 0 {
return 0
}
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))
}
return nbytes
}
// read_at reads buf.len bytes from pos in the file
pub fn (f &File) read_at(pos int, mut buf []byte) ?int {
if buf.len == 0 {
return 0
}
C.fseek(f.cfile, pos, C.SEEK_SET)
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))
}
return nbytes
}
// **************************** Utility ops ***********************
// write any unwritten data in stream's buffer
// flush writes any unwritten data in stream's buffer
pub fn (mut f File) flush() {
if !f.is_opened {
return
@@ -133,52 +177,24 @@ pub fn open_stdin() File {
}
// File.get_line - get a single line from the file. NB: the ending newline is *included*.
[deprecated]
pub fn (mut f File) get_line() ?string {
eprintln('File.get_line() is deprecated... Use a BufferedReader instead')
if !f.is_opened {
return error('file is closed')
}
$if !windows {
mut zbuf := byteptr(0)
mut zblen := size_t(0)
mut zx := 0
unsafe {
zx = C.getline(&charptr(&zbuf), &zblen, f.cfile)
if zx == -1 {
C.free(zbuf)
if C.errno == 0 {
return error('end of file')
}
return error(posix_get_error_msg(C.errno))
}
return zbuf.vstring_with_len(zx)
}
}
//
// using C.fgets is less efficient than f.get_line_getline,
// but is available everywhere, while C.getline does not work
// on windows
//
buf := [4096]byte{}
mut res := strings.new_builder(1024)
mut x := charptr(0)
for {
unsafe {
x = C.fgets(charptr(buf), 4096, f.cfile)
}
if x == 0 {
if res.len > 0 {
break
}
return error('end of file')
}
bufbp := byteptr(buf)
mut blen := vstrlen(bufbp)
res.write_bytes(bufbp, blen)
unsafe {
if blen == 0 || bufbp[blen - 1] == `\n` || bufbp[blen - 1] == `\r` {
break
}
}
}
return res.str()
return error('use io.new_buffered_reader')
/*
mut reader := io.new_buffered_reader({
reader: io.make_reader(f)
})
return reader.read_line()
*/
}
pub fn (mut f File) write_str(s string) ? {
if !f.is_opened {
return error('file is closed')
}
f.write(s.bytes()) ?
}

View File

@@ -860,7 +860,7 @@ pub fn home_dir() string {
// write_file writes `text` data to a file in `path`.
pub fn write_file(path string, text string) ? {
mut f := os.create(path)?
f.write(text)
f.write(text.bytes())
f.close()
}

View File

@@ -33,7 +33,7 @@ fn test_open_file() {
mut file := os.open_file(filename, 'w+', 0o666) or {
panic(err)
}
file.write(hello)
file.write_str(hello)
file.close()
assert hello.len == os.file_size(filename)
read_hello := os.read_file(filename) or {
@@ -64,26 +64,26 @@ fn test_open_file_binary() {
os.rm(filename)
}
fn test_file_get_line() {
filename := './fgetline.txt'
os.write_file(filename, 'line 1\nline 2')
mut f := os.open_file(filename, 'r', 0) or {
assert false
return
}
line1 := f.get_line() or {
''
}
line2 := f.get_line() or {
''
}
f.close()
//
// eprintln('line1: $line1')
// eprintln('line2: $line2')
assert line1 == 'line 1\n'
assert line2 == 'line 2'
}
// fn test_file_get_line() {
// filename := './fgetline.txt'
// os.write_file(filename, 'line 1\nline 2')
// mut f := os.open_file(filename, 'r', 0) or {
// assert false
// return
// }
// line1 := f.get_line() or {
// ''
// }
// line2 := f.get_line() or {
// ''
// }
// f.close()
// //
// eprintln('line1: $line1 $line1.bytes()')
// eprintln('line2: $line2 $line2.bytes()')
// assert line1 == 'line 1\n'
// assert line2 == 'line 2'
// }
fn test_create_file() {
filename := './test1.txt'
@@ -91,7 +91,7 @@ fn test_create_file() {
mut f := os.create(filename) or {
panic(err)
}
f.write(hello)
f.write_str(hello)
f.close()
assert hello.len == os.file_size(filename)
os.rm(filename)