1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use std::marker::PhantomData; use std::io; use std::str::FromStr; use std::fmt::Debug; trait LocalMemory { fn set_offset(&mut self, new_offsets: [usize; 10]); fn read(&self) -> Result<String, io::Error>; fn write(&self, value: &str) -> Result<(), io::Error>; } #[derive(Debug)] pub struct LocalMember<T> { offsets: Vec<usize>, _phantom: PhantomData<*const T>, } impl<T> LocalMember<T> where T: Default + ToString + FromStr, <T as FromStr>::Err: Debug { pub fn new() -> LocalMember<T> { LocalMember { offsets: Vec::new(), _phantom: PhantomData } } pub fn get_offset(&self) -> usize { use std::ptr::copy_nonoverlapping; let mut offset = 0usize; for i in 0..self.offsets.len()-1 { offset += self.offsets[i]; unsafe { copy_nonoverlapping(offset as *const usize, &mut offset, 1); } } offset += self.offsets[self.offsets.len()-1]; offset } } impl LocalMemory for LocalMember<String> { fn set_offset(&mut self, new_offsets: [usize; 10]) { self.offsets.clear(); for &i in new_offsets.iter() { if i != 0 { self.offsets.push(i); } } } fn read(&self) -> Result<String, io::Error> { use std::ptr::copy_nonoverlapping; let offset = self.get_offset(); let mut parts = Vec::<u8>::new(); let mut addition_offset = 0usize; loop { let mut byte = 0u8; unsafe { copy_nonoverlapping((offset + addition_offset) as *const u8, &mut byte, 1); } if byte == 0 { break; } addition_offset += 1; parts.push(byte); } Ok(String::from_utf8(parts).unwrap()) } fn write(&self, value: &str) -> Result<(), io::Error> { use std::ptr::copy_nonoverlapping; let offset = self.get_offset(); let bytes = value.as_bytes(); unsafe { copy_nonoverlapping(&bytes, offset as *mut &[u8], bytes.len()); copy_nonoverlapping(&0u8, (offset + bytes.len()) as *mut u8, 1); } Ok(()) } } impl<T> LocalMemory for LocalMember<T> where T: Default + ToString + FromStr, <T as FromStr>::Err: Debug { default fn set_offset(&mut self, new_offsets: [usize; 10]) { self.offsets.clear(); for &i in new_offsets.iter() { if i != 0 { self.offsets.push(i); } } } default fn read(&self) -> Result<String, io::Error> { use std::ptr::copy_nonoverlapping; let offset = self.get_offset(); let mut out : T = T::default(); unsafe { copy_nonoverlapping(offset as *const T, &mut out, 1usize); } Ok(out.to_string()) } default fn write(&self, value: &str) -> Result<(), io::Error> { use std::ptr::copy_nonoverlapping; let offset = self.get_offset(); let out : T = value.parse().unwrap(); unsafe { copy_nonoverlapping(&out, offset as *mut T, 1usize); } Ok(()) } }