mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
io: migrate the Reader
API to Result
instead of Option
(#15229)
This commit is contained in:
parent
8c33a40c5a
commit
b01f71d9da
@ -36,20 +36,23 @@ pub fn new_buffered_reader(o BufferedReaderConfig) &BufferedReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read fufills the Reader interface
|
// read fufills the Reader interface
|
||||||
pub fn (mut r BufferedReader) read(mut buf []u8) ?int {
|
pub fn (mut r BufferedReader) read(mut buf []u8) !int {
|
||||||
if r.end_of_stream {
|
if r.end_of_stream {
|
||||||
return none
|
return IError(Eof{})
|
||||||
}
|
}
|
||||||
// read data out of the buffer if we dont have any
|
// read data out of the buffer if we dont have any
|
||||||
if r.needs_fill() {
|
if r.needs_fill() {
|
||||||
if !r.fill_buffer() {
|
if !r.fill_buffer() {
|
||||||
// end of stream
|
// end of stream
|
||||||
return none
|
return IError(Eof{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read := copy(mut buf, r.buf[r.offset..r.len])
|
read := copy(mut buf, r.buf[r.offset..r.len])
|
||||||
if read == 0 {
|
if read == 0 {
|
||||||
return none
|
return IError(NotExpected{
|
||||||
|
cause: 'invalid copy of buffer'
|
||||||
|
code: -1
|
||||||
|
})
|
||||||
}
|
}
|
||||||
r.offset += read
|
r.offset += read
|
||||||
return read
|
return read
|
||||||
|
@ -10,12 +10,12 @@ fn imin(a int, b int) int {
|
|||||||
return if a < b { a } else { b }
|
return if a < b { a } else { b }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut s StringReader) read(mut buf []u8) ?int {
|
fn (mut s StringReader) read(mut buf []u8) !int {
|
||||||
$if debug {
|
$if debug {
|
||||||
eprintln('>>>> StringReader.read output buf.len: $buf.len')
|
eprintln('>>>> StringReader.read output buf.len: $buf.len')
|
||||||
}
|
}
|
||||||
if s.place > s.text.len + 1 {
|
if s.place > s.text.len + 1 {
|
||||||
return none
|
return IError(io.Eof{})
|
||||||
}
|
}
|
||||||
mut howmany := imin(buf.len, s.text.len - s.place)
|
mut howmany := imin(buf.len, s.text.len - s.place)
|
||||||
xxx := s.text[s.place..s.place + howmany].bytes()
|
xxx := s.text[s.place..s.place + howmany].bytes()
|
||||||
|
@ -12,9 +12,9 @@ pub mut:
|
|||||||
bytes []u8
|
bytes []u8
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut b Buf) read(mut buf []u8) ?int {
|
fn (mut b Buf) read(mut buf []u8) !int {
|
||||||
if !(b.i < b.bytes.len) {
|
if !(b.i < b.bytes.len) {
|
||||||
return none
|
return IError(io.Eof{})
|
||||||
}
|
}
|
||||||
n := copy(mut buf, b.bytes[b.i..])
|
n := copy(mut buf, b.bytes[b.i..])
|
||||||
b.i += n
|
b.i += n
|
||||||
|
@ -1,13 +1,32 @@
|
|||||||
module io
|
module io
|
||||||
|
|
||||||
|
/// Eof error means that we reach the end of the stream.
|
||||||
|
pub struct Eof {
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotExpected is a generic error that means that we receave a not expecte error.
|
||||||
|
pub struct NotExpected {
|
||||||
|
cause string
|
||||||
|
code int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (err NotExpected) msg() string {
|
||||||
|
return err.cause
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (err NotExpected) code() int {
|
||||||
|
return err.code
|
||||||
|
}
|
||||||
|
|
||||||
// Reader represents a stream of data that can be read
|
// Reader represents a stream of data that can be read
|
||||||
pub interface Reader {
|
pub interface Reader {
|
||||||
// read reads up to buf.len bytes and places
|
// read reads up to buf.len bytes and places
|
||||||
// them into buf.
|
// them into buf.
|
||||||
// A type that implements this should return
|
// A type that implements this should return
|
||||||
// `none` on end of stream (EOF) instead of just returning 0
|
// `io.Eof` on end of stream (EOF) instead of just returning 0
|
||||||
mut:
|
mut:
|
||||||
read(mut buf []u8) ?int
|
read(mut buf []u8) !int
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -50,7 +69,7 @@ pub fn read_any(mut r Reader) ?[]u8 {
|
|||||||
mut b := []u8{len: io.read_all_len}
|
mut b := []u8{len: io.read_all_len}
|
||||||
mut read := 0
|
mut read := 0
|
||||||
for {
|
for {
|
||||||
new_read := r.read(mut b[read..]) or { break }
|
new_read := r.read(mut b[read..]) or { return none }
|
||||||
read += new_read
|
read += new_read
|
||||||
if new_read == 0 {
|
if new_read == 0 {
|
||||||
break
|
break
|
||||||
|
@ -7,9 +7,9 @@ mut:
|
|||||||
i int
|
i int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut b Buf) read(mut buf []u8) ?int {
|
fn (mut b Buf) read(mut buf []u8) !int {
|
||||||
if !(b.i < b.bytes.len) {
|
if !(b.i < b.bytes.len) {
|
||||||
return none
|
return IError(Eof{})
|
||||||
}
|
}
|
||||||
n := copy(mut buf, b.bytes[b.i..])
|
n := copy(mut buf, b.bytes[b.i..])
|
||||||
b.i += n
|
b.i += n
|
||||||
@ -44,9 +44,9 @@ mut:
|
|||||||
place int
|
place int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut s StringReader) read(mut buf []u8) ?int {
|
fn (mut s StringReader) read(mut buf []u8) !int {
|
||||||
if s.place >= s.text.len {
|
if s.place >= s.text.len {
|
||||||
return none
|
return IError(Eof{})
|
||||||
}
|
}
|
||||||
read := copy(mut buf, s.text[s.place..].bytes())
|
read := copy(mut buf, s.text[s.place..].bytes())
|
||||||
s.place += read
|
s.place += read
|
||||||
|
@ -14,7 +14,7 @@ mut:
|
|||||||
w Writer
|
w Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut r ReaderWriterImpl) read(mut buf []u8) ?int {
|
pub fn (mut r ReaderWriterImpl) read(mut buf []u8) !int {
|
||||||
return r.r.read(mut buf)
|
return r.r.read(mut buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ mut:
|
|||||||
place int
|
place int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut s StringReader) read(mut buf []u8) ?int {
|
fn (mut s StringReader) read(mut buf []u8) !int {
|
||||||
if s.place >= s.text.len {
|
if s.place >= s.text.len {
|
||||||
return none
|
return IError(io.Eof{})
|
||||||
}
|
}
|
||||||
max_bytes := 100
|
max_bytes := 100
|
||||||
end := if s.place + max_bytes >= s.text.len { s.text.len } else { s.place + max_bytes }
|
end := if s.place + max_bytes >= s.text.len { s.text.len } else { s.place + max_bytes }
|
||||||
|
@ -180,8 +180,8 @@ pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) ?int {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut s SSLConn) read(mut buffer []u8) ?int {
|
pub fn (mut s SSLConn) read(mut buffer []u8) !int {
|
||||||
res := s.socket_read_into_ptr(&u8(buffer.data), buffer.len)?
|
res := s.socket_read_into_ptr(&u8(buffer.data), buffer.len) or { return err }
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module net
|
module net
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
import io
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -132,8 +133,13 @@ pub fn (c TcpConn) read_ptr(buf_ptr &u8, len int) ?int {
|
|||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c TcpConn) read(mut buf []u8) ?int {
|
pub fn (c TcpConn) read(mut buf []u8) !int {
|
||||||
return c.read_ptr(buf.data, buf.len)
|
return c.read_ptr(buf.data, buf.len) or {
|
||||||
|
return IError(io.NotExpected{
|
||||||
|
cause: 'unexpected error in `read_ptr` function'
|
||||||
|
code: -1
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c TcpConn) read_deadline() ?time.Time {
|
pub fn (mut c TcpConn) read_deadline() ?time.Time {
|
||||||
|
@ -9,10 +9,10 @@ fn (mut ws Client) socket_read(mut buffer []u8) ?int {
|
|||||||
return error('socket_read: trying to read a closed socket')
|
return error('socket_read: trying to read a closed socket')
|
||||||
}
|
}
|
||||||
if ws.is_ssl {
|
if ws.is_ssl {
|
||||||
r := ws.ssl_conn.read(mut buffer)?
|
r := ws.ssl_conn.read(mut buffer) or { return none }
|
||||||
return r
|
return r
|
||||||
} else {
|
} else {
|
||||||
r := ws.conn.read(mut buffer)?
|
r := ws.conn.read(mut buffer) or { return none }
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,24 @@
|
|||||||
module os
|
module os
|
||||||
|
|
||||||
|
/// Eof error means that we reach the end of the file.
|
||||||
|
pub struct Eof {
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotExpected is a generic error that means that we receave a not expecte error.
|
||||||
|
pub struct NotExpected {
|
||||||
|
cause string
|
||||||
|
code int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (err NotExpected) msg() string {
|
||||||
|
return err.cause
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (err NotExpected) code() int {
|
||||||
|
return err.code
|
||||||
|
}
|
||||||
|
|
||||||
pub struct File {
|
pub struct File {
|
||||||
mut:
|
mut:
|
||||||
cfile voidptr // Using void* instead of FILE*
|
cfile voidptr // Using void* instead of FILE*
|
||||||
@ -192,11 +211,16 @@ pub fn (mut f File) reopen(path string, mode string) ? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read implements the Reader interface.
|
// read implements the Reader interface.
|
||||||
pub fn (f &File) read(mut buf []u8) ?int {
|
pub fn (f &File) read(mut buf []u8) !int {
|
||||||
if buf.len == 0 {
|
if buf.len == 0 {
|
||||||
return 0
|
return IError(Eof{})
|
||||||
|
}
|
||||||
|
nbytes := fread(buf.data, 1, buf.len, f.cfile) or {
|
||||||
|
return IError(NotExpected{
|
||||||
|
cause: 'unexpected error from fread'
|
||||||
|
code: -1
|
||||||
|
})
|
||||||
}
|
}
|
||||||
nbytes := fread(buf.data, 1, buf.len, f.cfile)?
|
|
||||||
return nbytes
|
return nbytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +130,11 @@ fn test_read_eof_last_read_partial_buffer_fill() ? {
|
|||||||
f = os.open_file(tfile, 'r')?
|
f = os.open_file(tfile, 'r')?
|
||||||
mut br := []u8{len: 100}
|
mut br := []u8{len: 100}
|
||||||
// Read first 100 bytes of 199 byte file, should fill buffer with no error.
|
// Read first 100 bytes of 199 byte file, should fill buffer with no error.
|
||||||
n0 := f.read(mut br)?
|
n0 := f.read(mut br) or { return error('failed to read 100 bytes') }
|
||||||
assert n0 == 100
|
assert n0 == 100
|
||||||
// Read remaining 99 bytes of 199 byte file, should fill buffer with no
|
// Read remaining 99 bytes of 199 byte file, should fill buffer with no
|
||||||
// error, even though end-of-file was reached.
|
// error, even though end-of-file was reached.
|
||||||
n1 := f.read(mut br)?
|
n1 := f.read(mut br) or { return error('failed to read 100 bytes') }
|
||||||
assert n1 == 99
|
assert n1 == 99
|
||||||
// Read again, end-of-file was previously reached so should return none
|
// Read again, end-of-file was previously reached so should return none
|
||||||
// error.
|
// error.
|
||||||
@ -143,8 +143,8 @@ fn test_read_eof_last_read_partial_buffer_fill() ? {
|
|||||||
// not return a number of bytes read when end-of-file is reached.
|
// not return a number of bytes read when end-of-file is reached.
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
// Expect none to have been returned when end-of-file.
|
// Expected an error when received end-of-file.
|
||||||
assert err is none
|
assert err !is none
|
||||||
}
|
}
|
||||||
f.close()
|
f.close()
|
||||||
}
|
}
|
||||||
@ -162,11 +162,11 @@ fn test_read_eof_last_read_full_buffer_fill() ? {
|
|||||||
f = os.open_file(tfile, 'r')?
|
f = os.open_file(tfile, 'r')?
|
||||||
mut br := []u8{len: 100}
|
mut br := []u8{len: 100}
|
||||||
// Read first 100 bytes of 200 byte file, should fill buffer with no error.
|
// Read first 100 bytes of 200 byte file, should fill buffer with no error.
|
||||||
n0 := f.read(mut br)?
|
n0 := f.read(mut br) or { return error('failed to read 100 bytes') }
|
||||||
assert n0 == 100
|
assert n0 == 100
|
||||||
// Read remaining 100 bytes of 200 byte file, should fill buffer with no
|
// Read remaining 100 bytes of 200 byte file, should fill buffer with no
|
||||||
// error. The end-of-file isn't reached yet, but there is no more data.
|
// error. The end-of-file isn't reached yet, but there is no more data.
|
||||||
n1 := f.read(mut br)?
|
n1 := f.read(mut br) or { return error('failed to read 100 bytes') }
|
||||||
assert n1 == 100
|
assert n1 == 100
|
||||||
// Read again, end-of-file was previously reached so should return none
|
// Read again, end-of-file was previously reached so should return none
|
||||||
// error.
|
// error.
|
||||||
@ -175,8 +175,8 @@ fn test_read_eof_last_read_full_buffer_fill() ? {
|
|||||||
// not return a number of bytes read when end-of-file is reached.
|
// not return a number of bytes read when end-of-file is reached.
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
// Expect none to have been returned when end-of-file.
|
// Expect an error at EOF.
|
||||||
assert err is none
|
assert err !is none
|
||||||
}
|
}
|
||||||
f.close()
|
f.close()
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@ fn test_decode_a() ? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut b TestReader) read(mut buf []u8) ?int {
|
fn (mut b TestReader) read(mut buf []u8) !int {
|
||||||
if !(b.i < b.bytes.len) {
|
if !(b.i < b.bytes.len) {
|
||||||
return none
|
return IError(io.Eof{})
|
||||||
}
|
}
|
||||||
n := copy(mut buf, b.bytes[b.i..])
|
n := copy(mut buf, b.bytes[b.i..])
|
||||||
b.i += n
|
b.i += n
|
||||||
|
Loading…
x
Reference in New Issue
Block a user