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(())
    }
}