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_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 { | ||||
| 	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 { | ||||
| 	// mut arr := [`0`].repeat(size)
 | ||||
| 	mut arr := []byte{len: size} | ||||
| 	C.fseek(f.cfile, pos, C.SEEK_SET) | ||||
| 	nreadbytes := C.fread(arr.data, 1, size, f.cfile) | ||||
| 	C.fseek(f.cfile, 0, C.SEEK_SET) | ||||
| 	nreadbytes := f.read_bytes_into(pos, arr) or { | ||||
| 		// return err
 | ||||
| 		return [] | ||||
| 	} | ||||
| 	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 ***********************
 | ||||
| // write any unwritten data in stream's buffer
 | ||||
| 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).
 | ||||
| 	rbytes := file_read.read_bytes(5) | ||||
| 
 | ||||
| 	file_read.close() | ||||
| 	// eprintln('rbytes: $rbytes')
 | ||||
| 	// eprintln('payload: $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.
 | ||||
| 	os.rm(file_name) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue