os: add fn `read_bytes_into` with buffer argument (#6365)
							parent
							
								
									5c8e1c7eeb
								
							
						
					
					
						commit
						b552c29bef
					
				|  | @ -78,21 +78,42 @@ pub fn (mut f File) write_bytes_at(data voidptr, size, pos int) int { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // **************************** Read ops  ***************************
 | // **************************** Read ops  ***************************
 | ||||||
| // read_bytes reads an amount of bytes from the beginning of the file
 | // read_bytes reads bytes from the beginning of the file
 | ||||||
| pub fn (f &File) read_bytes(size int) []byte { | pub fn (f &File) read_bytes(size int) []byte { | ||||||
| 	return f.read_bytes_at(size, 0) | 	return f.read_bytes_at(size, 0) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // read_bytes_at reads an amount of bytes at the given position in the file
 | // read_bytes_at reads bytes at the given position in the file
 | ||||||
| pub fn (f &File) read_bytes_at(size, pos int) []byte { | pub fn (f &File) read_bytes_at(size, pos int) []byte { | ||||||
| 	// mut arr := [`0`].repeat(size)
 |  | ||||||
| 	mut arr := []byte{len: size} | 	mut arr := []byte{len: size} | ||||||
| 	C.fseek(f.cfile, pos, C.SEEK_SET) | 	nreadbytes := f.read_bytes_into(pos, arr) or { | ||||||
| 	nreadbytes := C.fread(arr.data, 1, size, f.cfile) | 		// return err
 | ||||||
| 	C.fseek(f.cfile, 0, C.SEEK_SET) | 		return [] | ||||||
|  | 	} | ||||||
| 	return arr[0..nreadbytes] | 	return arr[0..nreadbytes] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // 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.
 | ||||||
|  | pub fn (f &File) read_bytes_into(pos int, mut buf []byte) ?int { | ||||||
|  | 	if buf.len == 0 { | ||||||
|  | 		panic(@FN + ': `buf.len` == 0') | ||||||
|  | 	} | ||||||
|  | 	// Note: fseek errors if pos == os.file_size, which we accept
 | ||||||
|  | 	C.fseek(f.cfile, pos, C.SEEK_SET) | ||||||
|  | 	// errno is only set if fread fails, so clear it first to tell
 | ||||||
|  | 	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)) | ||||||
|  | 	} | ||||||
|  | 	$if debug { | ||||||
|  | 		C.fseek(f.cfile, 0, C.SEEK_SET) | ||||||
|  | 	} | ||||||
|  | 	return nbytes | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // **************************** Utility  ops ***********************
 | // **************************** Utility  ops ***********************
 | ||||||
| // write any unwritten data in stream's buffer
 | // write any unwritten data in stream's buffer
 | ||||||
| pub fn (mut f File) flush() { | pub fn (mut f File) flush() { | ||||||
|  |  | ||||||
|  | @ -142,11 +142,19 @@ fn test_write_and_read_bytes() { | ||||||
| 	// read_bytes_at with second parameter zeroed (size, 0).
 | 	// read_bytes_at with second parameter zeroed (size, 0).
 | ||||||
| 	rbytes := file_read.read_bytes(5) | 	rbytes := file_read.read_bytes(5) | ||||||
| 
 | 
 | ||||||
| 	file_read.close() |  | ||||||
| 	// eprintln('rbytes: $rbytes')
 | 	// eprintln('rbytes: $rbytes')
 | ||||||
| 	// eprintln('payload: $payload')
 | 	// eprintln('payload: $payload')
 | ||||||
| 	assert rbytes == payload | 	assert rbytes == payload | ||||||
| 
 | 
 | ||||||
|  | 	// check that trying to read data from EOF doesn't error and returns 0
 | ||||||
|  | 	mut a := []byte{len: 5} | ||||||
|  | 	nread := file_read.read_bytes_into(5, a) or { | ||||||
|  | 		eprintln(err) | ||||||
|  | 		int(-1) | ||||||
|  | 	} | ||||||
|  | 	assert nread == 0 | ||||||
|  | 
 | ||||||
|  | 	file_read.close() | ||||||
| 	// We finally delete the test file.
 | 	// We finally delete the test file.
 | ||||||
| 	os.rm(file_name) | 	os.rm(file_name) | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue