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`
 | // write_struct writes a single struct of type `T`
 | ||||||
| pub fn (mut f File) write_struct<T>(t &T) ? { | pub fn (mut f File) write_struct<T>(t &T) ? { | ||||||
| 	if !f.is_opened { | 	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) | 		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 | 	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 unit_point = Point{1.0, 1.0, 1.0} | ||||||
| 
 | 
 | ||||||
| const tfolder = os.join_path(os.temp_dir(), 'os_file_test') | 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 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() { | fn testsuite_begin() { | ||||||
| 	os.rmdir_all(tfolder) or { } | 	os.rmdir_all(tfolder) or { } | ||||||
| 	assert !os.is_dir(tfolder) | 	assert !os.is_dir(tfolder) | ||||||
|  | @ -54,3 +68,29 @@ fn test_read_struct() { | ||||||
| 
 | 
 | ||||||
| 	assert p == another_point | 	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