v2 / vlib / io / reader.v
91 lines · 80 sloc · 2.13 KB · 114ae6d4a297538895253a0ae37bd0411187c19f
Raw
1module io
2
3// Eof error means that we reach the end of the stream.
4pub struct Eof {
5 Error
6}
7
8// NotExpected is a generic error that means that we receave a not expected error.
9pub struct NotExpected {
10 cause string
11 code int
12}
13
14fn (err NotExpected) msg() string {
15 return err.cause
16}
17
18fn (err NotExpected) code() int {
19 return err.code
20}
21
22// Reader represents a stream of data that can be read.
23pub interface Reader {
24 // read reads up to buf.len bytes and places
25 // them into buf.
26 // A type that implements this should return
27 // `io.Eof` on end of stream (EOF) instead of just returning 0
28mut:
29 read(mut buf []u8) !int
30}
31
32pub const read_all_len = 10 * 1024
33pub const read_all_grow_len = 1024
34
35// ReadAllConfig allows options to be passed for the behaviour
36// of read_all.
37pub struct ReadAllConfig {
38pub:
39 read_to_end_of_stream bool
40 reader Reader
41}
42
43// read_all reads all bytes from a reader until either a 0 length read
44// or if read_to_end_of_stream is true then the end of the stream (`none`).
45pub fn read_all(config ReadAllConfig) ![]u8 {
46 mut r := config.reader
47 read_till_eof := config.read_to_end_of_stream
48
49 mut b := []u8{len: read_all_len}
50 mut read := 0
51 for {
52 new_read := r.read(mut b[read..]) or { break }
53 if new_read < 0 {
54 return error('io.read_all: reader returned a negative read count (${new_read})')
55 }
56 read += new_read
57 if !read_till_eof && new_read == 0 {
58 break
59 }
60 if b.len == read {
61 unsafe { b.grow_len(read_all_grow_len) }
62 }
63 }
64 return b[..read]
65}
66
67// read_any reads any available bytes from a reader
68// (until the reader returns a read of 0 length).
69pub fn read_any(mut r Reader) ![]u8 {
70 mut b := []u8{len: read_all_len}
71 mut read := 0
72 for {
73 new_read := r.read(mut b[read..]) or { return error('none') }
74 if new_read < 0 {
75 return error('io.read_any: reader returned a negative read count (${new_read})')
76 }
77 read += new_read
78 if new_read == 0 {
79 break
80 }
81 if b.len == read {
82 unsafe { b.grow_len(read_all_grow_len) }
83 }
84 }
85 return b[..read]
86}
87
88// RandomReader represents a stream of readable data from at a random location.
89pub interface RandomReader {
90 read_from(pos u64, mut buf []u8) !int
91}
92