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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
use crate::common::data_format::DataFormat;
mod basic_types;
mod bool;
mod buffers;
mod buffers_8bits;
mod fix_array;
mod ip;
mod string;
mod string_lists;
/// This trait provides the methods needed by FlatMessage to serialize / deserialize an object.
///
/// # Safety
///
/// You should not use this trait directly, insetad you should use the #[derive(FlatMessage)] and derivates instead.
pub unsafe trait SerDe<'a> {
const DATA_FORMAT: DataFormat;
/// This methods creates an object from a buffer (it assumes that the buffer is valid and that the object is at the correct position)
///
/// # Safety
///
/// This method is unsafe because it does not check the buffer bounds and should not be used directly (it will be called from the deserialize_from_unchecked method)
unsafe fn from_buffer_unchecked(buf: &'a [u8], pos: usize) -> Self
where
Self: Sized;
/// This methods creates an object from a buffer (it checks the buffer bounds and returns None if the object is not at the correct position)
///
/// # Safety
///
/// This method is safe because it checks the buffer bounds and returns None if the object is not at the correct position.
/// This method should not be used when directly (it will be called from the deserialize_from method)
fn from_buffer(buf: &'a [u8], pos: usize) -> Option<Self>
where
Self: Sized;
/// This methods writes an object to a buffer (it assumes that the buffer is valid and that the object is at the correct position)
///
/// # Safety
///
/// This method is unsafe and should not be used directly (it will be called from the serialize_to method)
unsafe fn write(obj: &Self, p: *mut u8, pos: usize) -> usize;
fn size(obj: &Self) -> usize;
}
/// This trait provides the methods needed by FlatMessage to serialize / deserialize slices of objects.
///
/// # Safety
///
/// You should not use this trait directly, instead you should use the #[derive(FlatMessage)] and derivates instead.
pub unsafe trait SerDeSlice<'a> {
const DATA_FORMAT: DataFormat;
/// This method creates a slice from a buffer (it assumes that the buffer is valid and that the slice is at the correct position)
///
/// # Safety
///
/// This method is unsafe because it does not check the buffer bounds and should not be used directly (it will be called from the deserialize_from_unchecked method)
unsafe fn from_buffer_unchecked(buf: &'a [u8], pos: usize) -> &'a [Self]
where
Self: Sized;
/// This method creates a slice from a buffer (it checks the buffer bounds and returns None if the slice is not at the correct position)
///
/// # Safety
///
/// This method is safe because it checks the buffer bounds and returns None if the slice is not at the correct position.
/// This method should not be used directly (it will be called from the deserialize_from method)
fn from_buffer(buf: &'a [u8], pos: usize) -> Option<&'a [Self]>
where
Self: Sized;
/// This method writes a slice to a buffer (it assumes that the buffer is valid and that the slice is at the correct position)
///
/// # Safety
///
/// This method is unsafe and should not be used directly (it will be called from the serialize_to method)
unsafe fn write(obj: &[Self], p: *mut u8, pos: usize) -> usize
where
Self: Sized;
/// Returns the serialized size in bytes needed to store the slice
fn size(obj: &[Self]) -> usize
where
Self: Sized;
}
/// This trait provides the methods needed by FlatMessage to serialize / deserialize vectors of objects.
///
/// # Safety
///
/// You should not use this trait directly, instead you should use the #[derive(FlatMessage)] and derivates instead.
pub unsafe trait SerDeVec<'a, TVecType>
where
Self: Sized,
TVecType: SerDeVecType<Self>
{
const DATA_FORMAT: DataFormat;
/// This method creates a vector from a buffer (it assumes that the buffer is valid and that the vector is at the correct position)
///
/// # Safety
///
/// This method is unsafe because it does not check the buffer bounds and should not be used directly (it will be called from the deserialize_from_unchecked method)
unsafe fn from_buffer_unchecked(buf: &'a [u8], pos: usize) -> TVecType
where
Self: Sized;
/// This method creates a vector from a buffer (it checks the buffer bounds and returns None if the vector is not at the correct position)
///
/// # Safety
///
/// This method is safe because it checks the buffer bounds and returns None if the vector is not at the correct position.
/// This method should not be used directly (it will be called from the deserialize_from method)
fn from_buffer(buf: &'a [u8], pos: usize) -> Option<TVecType>
where
Self: Sized;
/// This method writes a vector to a buffer (it assumes that the buffer is valid and that the vector is at the correct position)
///
/// # Safety
///
/// This method is unsafe and should not be used directly (it will be called from the serialize_to method)
unsafe fn write(obj: &TVecType, p: *mut u8, pos: usize) -> usize
where
Self: Sized;
/// Returns the serialized size in bytes needed to store the vector
fn size(obj: &TVecType) -> usize
where
Self: Sized;
}
pub trait SerDeVecType<T> : std::ops::Deref<Target = [T]> {
fn new() -> Self;
fn with_capacity(capacity: usize) -> Self;
fn push(&mut self, value: T);
fn as_slice(&self) -> &[T];
fn len(&self) -> usize;
fn capacity(&self) -> usize;
/// # Safety:
/// See Vec::set_len for requirements.
unsafe fn set_len(&mut self, len: usize);
fn as_mut_ptr(&mut self) -> *mut T;
fn from_slice(slice: &[T]) -> Self
where
T: Clone;
}
impl<T> SerDeVecType<T> for Vec<T> {
fn new() -> Self {
Vec::new()
}
fn with_capacity(capacity: usize) -> Self {
Vec::with_capacity(capacity)
}
fn push(&mut self, value: T) {
self.push(value)
}
fn as_slice(&self) -> &[T] {
self.as_slice()
}
fn len(&self) -> usize {
self.len()
}
fn capacity(&self) -> usize {
self.capacity()
}
unsafe fn set_len(&mut self, len: usize) {
unsafe { self.set_len(len) }
}
fn as_mut_ptr(&mut self) -> *mut T {
self.as_mut_ptr()
}
fn from_slice(slice: &[T]) -> Self
where
T: Clone,
{
slice.to_vec()
}
}
#[cfg(feature = "smallvec")]
impl<T, const N: usize> SerDeVecType<T> for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>, // smallvec does not use const generics so this is required to compile
{
fn new() -> Self {
smallvec::SmallVec::new()
}
fn with_capacity(capacity: usize) -> Self {
smallvec::SmallVec::with_capacity(capacity)
}
fn push(&mut self, value: T) {
self.push(value);
}
fn as_slice(&self) -> &[T] {
self.as_slice()
}
fn len(&self) -> usize {
self.len()
}
fn capacity(&self) -> usize {
self.capacity()
}
unsafe fn set_len(&mut self, len: usize) {
unsafe { self.set_len(len) }
}
fn as_mut_ptr(&mut self) -> *mut T {
self.as_mut_ptr()
}
fn from_slice(slice: &[T]) -> Self
where
T: Clone {
smallvec::SmallVec::from(slice)
}
}