os.File: add .read_struct_at and .write_struct_at (#9114)
							parent
							
								
									7333b1706c
								
							
						
					
					
						commit
						ce92bf8da0
					
				| 
						 | 
				
			
			@ -337,6 +337,27 @@ pub fn (mut f File) read_struct<T>(mut t T) ? {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// read_struct_at reads a single struct of type `T` at position specified in file
 | 
			
		||||
pub fn (mut f File) read_struct_at<T>(mut t T, pos int) ? {
 | 
			
		||||
	if !f.is_opened {
 | 
			
		||||
		return none
 | 
			
		||||
	}
 | 
			
		||||
	tsize := int(sizeof(*t))
 | 
			
		||||
	if tsize == 0 {
 | 
			
		||||
		return none
 | 
			
		||||
	}
 | 
			
		||||
	C.errno = 0
 | 
			
		||||
	C.fseek(f.cfile, pos, C.SEEK_SET)
 | 
			
		||||
	nbytes := int(C.fread(t, 1, tsize, f.cfile))
 | 
			
		||||
	C.fseek(f.cfile, 0, C.SEEK_END)
 | 
			
		||||
	if C.errno != 0 {
 | 
			
		||||
		return error(posix_get_error_msg(C.errno))
 | 
			
		||||
	}
 | 
			
		||||
	if nbytes != tsize {
 | 
			
		||||
		return error_with_code('incomplete struct read', nbytes)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// write_struct writes a single struct of type `T`
 | 
			
		||||
pub fn (mut f File) write_struct<T>(t &T) ? {
 | 
			
		||||
	if !f.is_opened {
 | 
			
		||||
| 
						 | 
				
			
			@ -355,3 +376,24 @@ pub fn (mut f File) write_struct<T>(t &T) ? {
 | 
			
		|||
		return error_with_code('incomplete struct write', nbytes)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// write_struct_at writes a single struct of type `T` at position specified in file
 | 
			
		||||
pub fn (mut f File) write_struct_at<T>(t &T, pos int) ? {
 | 
			
		||||
	if !f.is_opened {
 | 
			
		||||
		return error('file is not opened')
 | 
			
		||||
	}
 | 
			
		||||
	tsize := int(sizeof(*t))
 | 
			
		||||
	if tsize == 0 {
 | 
			
		||||
		return error('struct size is 0')
 | 
			
		||||
	}
 | 
			
		||||
	C.errno = 0
 | 
			
		||||
	C.fseek(f.cfile, pos, C.SEEK_SET)
 | 
			
		||||
	nbytes := int(C.fwrite(t, 1, tsize, f.cfile))
 | 
			
		||||
	C.fseek(f.cfile, 0, C.SEEK_END)
 | 
			
		||||
	if C.errno != 0 {
 | 
			
		||||
		return error(posix_get_error_msg(C.errno))
 | 
			
		||||
	}
 | 
			
		||||
	if nbytes != tsize {
 | 
			
		||||
		return error_with_code('incomplete struct write', nbytes)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,18 @@ struct Point {
 | 
			
		|||
	z f64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Extended_Point {
 | 
			
		||||
	a f64
 | 
			
		||||
	b f64
 | 
			
		||||
	c f64
 | 
			
		||||
	d f64
 | 
			
		||||
	e f64
 | 
			
		||||
	f f64
 | 
			
		||||
	g f64
 | 
			
		||||
	h f64
 | 
			
		||||
	i f64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const unit_point = Point{1.0, 1.0, 1.0}
 | 
			
		||||
 | 
			
		||||
const tfolder = os.join_path(os.temp_dir(), 'os_file_test')
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +26,8 @@ const tfile = os.join_path(tfolder, 'test_file')
 | 
			
		|||
 | 
			
		||||
const another_point = Point{0.25, 2.25, 6.25}
 | 
			
		||||
 | 
			
		||||
const extended_point = Extended_Point{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}
 | 
			
		||||
 | 
			
		||||
fn testsuite_begin() {
 | 
			
		||||
	os.rmdir_all(tfolder) or { }
 | 
			
		||||
	assert !os.is_dir(tfolder)
 | 
			
		||||
| 
						 | 
				
			
			@ -54,3 +68,29 @@ fn test_read_struct() {
 | 
			
		|||
 | 
			
		||||
	assert p == another_point
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_read_struct_at() {
 | 
			
		||||
	mut f := os.open_file(tfile, 'w') or { panic(err) }
 | 
			
		||||
	f.write([byte(1), 2, 3]) or { panic(err) }
 | 
			
		||||
	f.write_struct(another_point) or { panic(err) }
 | 
			
		||||
	f.close()
 | 
			
		||||
	f = os.open_file(tfile, 'r') or { panic(err) }
 | 
			
		||||
	mut p := Point{}
 | 
			
		||||
	f.read_struct_at(mut p, 3) or { panic(err) }
 | 
			
		||||
	f.close()
 | 
			
		||||
 | 
			
		||||
	assert p == another_point
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_write_struct_at() {
 | 
			
		||||
	mut f := os.open_file(tfile, 'w') or { panic(err) }
 | 
			
		||||
	f.write_struct(extended_point) or { panic(err) }
 | 
			
		||||
	f.write_struct_at(another_point, 3) or { panic(err) }
 | 
			
		||||
	f.close()
 | 
			
		||||
	f = os.open_file(tfile, 'r') or { panic(err) }
 | 
			
		||||
	mut p := Point{}
 | 
			
		||||
	f.read_struct_at(mut p, 3) or { panic(err) }
 | 
			
		||||
	f.close()
 | 
			
		||||
 | 
			
		||||
	assert p == another_point
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue