gondola_core/io/
serialization.rs1use crate::prelude::*;
5
6pub use crate::io::caraspace::{
7 Frameable
8};
9
10pub trait Serialization {
13
14 const HEAD: u16 = 0xAAAA;
16 const TAIL: u16 = 0x5555;
18 const SIZE: usize = 0;
24
25 fn guess_size(stream : &Vec<u8>,
31 pos : usize,
32 offset : usize)
33 -> Result<(usize,usize,usize), SerializationError> {
34 let head_pos = seek_marker(stream, Self::HEAD, pos)?;
35 let tail_pos = seek_marker(stream, Self::TAIL, pos+ offset)?;
36 Ok((tail_pos + 2 - head_pos, head_pos, tail_pos))
37 }
38
39 fn verify_fixed(stream : &Vec<u8>,
44 pos : &mut usize) -> Result<(), SerializationError> {
45 if !Self::SIZE == 0 {
46 panic!("Self::verify_fixed can be only used for structs with a fixed size! In case you are convinced, that your struct has indeed a fixed size, please implement trait Serialization::SIZE with the serialized size in bytes including 4 bytes for header and footer!");
49 }
50 if stream.len() < Self::SIZE {
51 return Err(SerializationError::StreamTooShort);
52 }
53 let head_pos = seek_marker(stream, Self::HEAD, *pos)?;
54 let tail_pos = seek_marker(stream, Self::TAIL, head_pos + Self::SIZE-2)?;
55 if tail_pos + 2 - head_pos != Self::SIZE {
56 *pos = head_pos + 2;
57 let actual = tail_pos + 2 - head_pos;
58 error!("Seeing {} bytes between HEAD and TAIL, expecting {}", actual, Self::SIZE);
59 return Err(SerializationError::WrongByteSize);
60 }
61 *pos = head_pos + 2;
62 Ok(())
63 }
64
65 fn from_bytestream(bytestream : &Vec<u8>,
74 pos : &mut usize)
75 -> Result<Self, SerializationError>
76 where Self : Sized;
77
78 fn from_bytestream_alt(bytestream : &Vec<u8>,
88 pos : &mut usize)
89 -> Result<Self, SerializationError>
90 where Self : Sized {
91 Self::from_bytestream(bytestream, pos)
92 }
93
94 fn to_bytestream(&self) -> Vec<u8> {
100 error!("No default implementation for trait!");
101 return Vec::<u8>::new();
102 }
103}
104
105pub fn seek_marker<T: AsRef<[u8]>>(stream : &T, marker : u16, start_pos :usize)
119 -> Result<usize, SerializationError> {
120 let bytestream = stream.as_ref();
122 if bytestream.len() == 0 {
123 error!("Stream empty!");
124 return Err(SerializationError::StreamTooShort);
125 }
126 if start_pos > bytestream.len() - 2 {
127 error!("Start position {} beyond stream capacity {}!", start_pos, bytestream.len() -2);
128 return Err(SerializationError::StreamTooShort);
129 }
130 let mut pos = start_pos;
131 let mut two_bytes : [u8;2];
132 two_bytes = [bytestream[pos], bytestream[pos + 1]];
134 if u16::from_le_bytes(two_bytes) == marker {
136 return Ok(pos);
137 }
138 pos += 1;
141 let mut found = false;
142 for n in pos..bytestream.len() - 1 {
144 two_bytes = [bytestream[n], bytestream[n + 1]];
145 if (u16::from_le_bytes(two_bytes)) == marker {
146 pos = n;
147 found = true;
148 break;
149 }
150 }
151 if !found {
152 let delta = bytestream.len() - start_pos;
153 warn!("Can not find {} in bytestream [-{}:{}]!", marker, delta ,bytestream.len());
154 return Err(SerializationError::ValueNotFound);
155 }
156 trace!("Found {marker} at {pos}");
157 Ok(pos)
158}
159
160#[test]
161fn test_seek_marker() {
162 let mut bytestream = vec![1,2,3,0xAA, 0xAA, 5, 7];
164 let mut pos = seek_marker(&bytestream, 0xaaaa, 0).unwrap();
165 assert_eq!(pos, 3);
166
167 bytestream = vec![1,2,3,244, 16, 32, 0xaa, 0xff, 5, 7];
168 pos = seek_marker(&bytestream, 0xffaa, 1).unwrap();
170 assert_eq!(pos, 6);
171
172 bytestream = vec![0xaa,0xaa,3,244, 16, 32, 0xAA, 0xFF, 5, 7];
173 pos = seek_marker(&bytestream, 0xaaaa, 0).unwrap();
174 assert_eq!(pos, 0);
175}
176