1use std::borrow::Cow;
2use std::fs::File;
3use std::io::prelude::*;
4use std::slice;
5use std::mem::{transmute, size_of, forget};
6use std::io::{Write, Result, Error, ErrorKind};
7
8pub trait VecIO {
11 fn write_slice_to_file<T>(&mut self, data: &[T]) -> Result<()>;
12 fn read_vec_from_file<T>(&mut self) -> Result<Vec<T>>;
13}
14
15impl VecIO for File {
16 fn write_slice_to_file<T>(&mut self, data: &[T]) -> Result<()> {
18 unsafe {
19 self.write_all(slice::from_raw_parts(transmute::<*const T, *const u8>(data.as_ptr()), data.len() * size_of::<T>()))?;
20 }
21 Ok(())
22 }
23 fn read_vec_from_file<T>(&mut self) -> Result<Vec<T>> {
25 let mut buffer: Vec<T> = Vec::new();
26 let length = buffer.len();
27 let capacity = buffer.capacity();
28 unsafe {
29 let mut converted = Vec::<u8>::from_raw_parts(buffer.as_mut_ptr() as *mut u8, length * size_of::<T>(), capacity * size_of::<T>());
30 match self.read_to_end(&mut converted) {
31 Ok(size) => {
32 if converted.len() % size_of::<T>() != 0 {
33 converted.truncate(length * size_of::<T>());
34 forget(converted);
35 return Err(Error::new(
36 ErrorKind::UnexpectedEof,
37 format!("read_file() returned a number of bytes ({}) which is not a multiple of size ({})", size, size_of::<T>())
38 ));
39 }
40 },
41 Err(e) => {
42 converted.truncate(length * size_of::<T>());
43 forget(converted);
44 return Err(e);
45 }
46 }
47 let new_length = converted.len() / size_of::<T>();
48 let new_capacity = converted.len() / size_of::<T>();
49 buffer = Vec::from_raw_parts(converted.as_mut_ptr() as *mut T, new_length, new_capacity);
50 forget(converted);
51 Ok(buffer)
52 }
53 }
54}
55
56pub fn unpack_vec_from_asset<T>(asset: Option<Cow<'static, [u8]>>) -> Result<Vec<T>> {
62 let buffer: Vec<T>;
63 match asset {
64 Some(data) => {
65 unsafe {
66 let mut bytes = data.into_owned();
67 if bytes.len() % size_of::<T>() != 0 {
68 forget(bytes);
69 return Err(Error::new(
70 ErrorKind::UnexpectedEof,
71 format!("read_asset() returned a number of bytes which is not a multiple of size ({})", size_of::<T>())
72 ));
73 }
74 let length = bytes.len() / size_of::<T>();
75 let capacity = bytes.len() / size_of::<T>();
76 buffer = Vec::from_raw_parts(bytes.as_mut_ptr() as *mut T, length, capacity);
77 forget(bytes);
78 }
79 },
80 None => {
81 return Err(Error::new(
82 ErrorKind::NotFound,
83 format!("unable to read asset, file not found")
84 ));
85 }
86 }
87 Ok(buffer)
88}