79 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			V
		
	
	
| module io
 | |
| 
 | |
| // Reader represents a stream of data that can be read
 | |
| pub interface Reader {
 | |
| 	// read reads up to buf.len bytes and places
 | |
| 	// them into buf.
 | |
| 	// A type that implements this should return
 | |
| 	// `none` on end of stream (EOF) instead of just returning 0
 | |
| 	read(mut buf []byte) ?int
 | |
| }
 | |
| 
 | |
| // make_reader is a temp that converts a type to a reader
 | |
| // (e.g. for use in struct initialisation)
 | |
| // (this shouldnt need to be a thing but until coercion gets made better
 | |
| // it is required)
 | |
| pub fn make_reader(r Reader) Reader {
 | |
| 	return r
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	read_all_len      = 10 * 1024
 | |
| 	read_all_grow_len = 1024
 | |
| )
 | |
| 
 | |
| // ReadAllConfig allows options to be passed for the behaviour
 | |
| // of read_all
 | |
| pub struct ReadAllConfig {
 | |
| 	reader Reader
 | |
| 	read_to_end_of_stream bool
 | |
| }
 | |
| 
 | |
| // read_all reads all bytes from a reader until either a 0 length read
 | |
| // or if read_to_end_of_stream is true then the end of the stream (`none`)
 | |
| pub fn read_all(config ReadAllConfig) ?[]byte {
 | |
| 	r := config.reader
 | |
| 	read_till_eof := config.read_to_end_of_stream
 | |
| 
 | |
| 	mut b := []byte{len: read_all_len}
 | |
| 	mut read := 0
 | |
| 	for {
 | |
| 		new_read := r.read(mut b[read..]) or {
 | |
| 			break
 | |
| 		}
 | |
| 		read += new_read
 | |
| 		if !read_till_eof && read == 0 {
 | |
| 			break
 | |
| 		}
 | |
| 		if b.len == read {
 | |
| 			unsafe { b.grow_len(read_all_grow_len) }
 | |
| 		}
 | |
| 	}
 | |
| 	return b[..read]
 | |
| }
 | |
| 
 | |
| // read_any reads any available bytes from a reader
 | |
| // (until the reader returns a read of 0 length)
 | |
| pub fn read_any(r Reader) ?[]byte {
 | |
| 	mut b := []byte{len: read_all_len}
 | |
| 	mut read := 0
 | |
| 	for {
 | |
| 		new_read := r.read(mut b[read..]) or {
 | |
| 			break
 | |
| 		}
 | |
| 		read += new_read
 | |
| 		if new_read == 0 {
 | |
| 			break
 | |
| 		}
 | |
| 		if b.len == read {
 | |
| 			unsafe { b.grow_len(read_all_grow_len) }
 | |
| 		}
 | |
| 	}
 | |
| 	return b[..read]
 | |
| }
 | |
| 
 | |
| // RandomReader represents a stream of data that can be read from at a random location
 | |
| interface RandomReader {
 | |
| 	read_from(pos int, mut buf []byte) ?int
 | |
| }
 |