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 return Err(SerializationError::WrongByteSize);
58 }
59 *pos = head_pos + 2;
60 Ok(())
61 }
62
63 fn from_bytestream(bytestream : &Vec<u8>,
72 pos : &mut usize)
73 -> Result<Self, SerializationError>
74 where Self : Sized;
75
76 fn from_bytestream_alt(bytestream : &Vec<u8>,
86 pos : &mut usize)
87 -> Result<Self, SerializationError>
88 where Self : Sized {
89 Self::from_bytestream(bytestream, pos)
90 }
91
92 fn to_bytestream(&self) -> Vec<u8> {
98 error!("No default implementation for trait!");
99 return Vec::<u8>::new();
100 }
101}
102
103pub fn seek_marker<T: AsRef<[u8]>>(stream : &T, marker : u16, start_pos :usize)
117 -> Result<usize, SerializationError> {
118 let bytestream = stream.as_ref();
120 if bytestream.len() == 0 {
121 error!("Stream empty!");
122 return Err(SerializationError::StreamTooShort);
123 }
124 if start_pos > bytestream.len() - 2 {
125 error!("Start position {} beyond stream capacity {}!", start_pos, bytestream.len() -2);
126 return Err(SerializationError::StreamTooShort);
127 }
128 let mut pos = start_pos;
129 let mut two_bytes : [u8;2];
130 two_bytes = [bytestream[pos], bytestream[pos + 1]];
132 if u16::from_le_bytes(two_bytes) == marker {
134 return Ok(pos);
135 }
136 pos += 1;
139 let mut found = false;
140 for n in pos..bytestream.len() - 1 {
142 two_bytes = [bytestream[n], bytestream[n + 1]];
143 if (u16::from_le_bytes(two_bytes)) == marker {
144 pos = n;
145 found = true;
146 break;
147 }
148 }
149 if !found {
150 let delta = bytestream.len() - start_pos;
151 warn!("Can not find {} in bytestream [-{}:{}]!", marker, delta ,bytestream.len());
152 return Err(SerializationError::ValueNotFound);
153 }
154 trace!("Found {marker} at {pos}");
155 Ok(pos)
156}
157
158#[test]
159fn test_seek_marker() {
160 let mut bytestream = vec![1,2,3,0xAA, 0xAA, 5, 7];
162 let mut pos = seek_marker(&bytestream, 0xaaaa, 0).unwrap();
163 assert_eq!(pos, 3);
164
165 bytestream = vec![1,2,3,244, 16, 32, 0xaa, 0xff, 5, 7];
166 pos = seek_marker(&bytestream, 0xffaa, 1).unwrap();
168 assert_eq!(pos, 6);
169
170 bytestream = vec![0xaa,0xaa,3,244, 16, 32, 0xAA, 0xFF, 5, 7];
171 pos = seek_marker(&bytestream, 0xaaaa, 0).unwrap();
172 assert_eq!(pos, 0);
173}
174