1use std::collections::HashMap;
5use std::convert::TryInto;
6use std::hash::Hash;
7use std::io::Write;
8use std::mem;
9
10pub use error::*;
11pub use fixed_sized::*;
12
13use crate::{define_serialize_chained, test_serialization, Date, Guid, SliceWrapper};
14#[allow(unused_imports)]
16use crate::collection;
17
18pub mod alignment;
19pub mod error;
20pub mod fixed_sized;
21pub mod testing;
22
23pub type Len = u32;
24pub const LEN_SIZE: usize = mem::size_of::<Len>();
26pub const ENUM_SIZE: usize = 4;
28
29pub trait OwnedRecord: for<'raw> Record<'raw> {}
30impl<T> OwnedRecord for T where T: for<'raw> Record<'raw> {}
31
32pub trait OwnedSubRecord: for<'raw> SubRecord<'raw> {}
33impl<T> OwnedSubRecord for T where T: for<'raw> SubRecord<'raw> {}
34
35pub trait Record<'raw>: SubRecord<'raw> {
37 const OPCODE: Option<u32> = None;
38
39 #[inline(always)]
41 fn deserialize(raw: &'raw [u8]) -> DeResult<Self> {
42 Ok(Self::_deserialize_chained(raw)?.1)
43 }
44
45 #[inline(always)]
81 fn serialize<W: Write>(&self, dest: &mut W) -> SeResult<usize> {
82 Self::_serialize_chained(self, dest)
83 }
84
85 }
88
89pub trait SubRecord<'raw>: Sized {
91 const MIN_SERIALIZED_SIZE: usize;
92 const EXACT_SERIALIZED_SIZE: Option<usize> = None;
93
94 fn serialized_size(&self) -> usize;
98
99 #[inline]
102 fn _serialize_chained<W: Write>(&self, dest: &mut W) -> SeResult<usize> {
103 unsafe { Self::_serialize_chained_unaligned(self, dest) }
104 }
105
106 unsafe fn _serialize_chained_unaligned<W: Write>(
116 zelf: *const Self,
117 dest: &mut W,
118 ) -> SeResult<usize>;
119
120 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)>;
124}
125
126impl<'raw> SubRecord<'raw> for &'raw str {
127 const MIN_SERIALIZED_SIZE: usize = LEN_SIZE;
128
129 #[inline]
130 fn serialized_size(&self) -> usize {
131 self.len() + LEN_SIZE
132 }
133
134 define_serialize_chained!(&str => |zelf, dest| serialize_byte_slice(dest, zelf.as_bytes()));
135
136 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
137 let len = read_len(raw)?;
138 if len + LEN_SIZE > raw.len() {
139 return Err(DeserializeError::MoreDataExpected(
140 len + LEN_SIZE - raw.len(),
141 ));
142 }
143 let raw_str = &raw[LEN_SIZE..len + LEN_SIZE];
144 #[cfg(not(feature = "unchecked"))]
145 {
146 Ok((len + LEN_SIZE, std::str::from_utf8(raw_str)?))
147 }
148 #[cfg(feature = "unchecked")]
149 unsafe {
150 Ok((len + LEN_SIZE, std::str::from_utf8_unchecked(raw_str)))
151 }
152 }
153}
154
155#[test]
156fn out_of_bounds_string() {
157 let buf = [100, 100, 100, 100, 100, 100];
158 let result = <&str>::_deserialize_chained(&buf);
159 assert!(result.is_err());
160}
161
162impl<'raw> SubRecord<'raw> for String {
163 const MIN_SERIALIZED_SIZE: usize = <&str>::MIN_SERIALIZED_SIZE;
164
165 #[inline]
166 fn serialized_size(&self) -> usize {
167 self.len() + LEN_SIZE
168 }
169
170 define_serialize_chained!(String => |zelf, dest| serialize_byte_slice(dest, zelf.as_bytes()));
171
172 #[inline]
173 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
174 <&str>::_deserialize_chained(raw).map(|(c, s)| (c, s.to_owned()))
175 }
176}
177
178test_serialization!(serialization_str, &str, "some random string", 18 + LEN_SIZE);
179test_serialization!(serialization_str_long, &str, "some random string that is a bit longer because I had seem some errors that seemed exclusive to longer string values.", 117 + LEN_SIZE);
180test_serialization!(serialization_str_empty, &str, "", LEN_SIZE);
181
182impl<'raw, T> SubRecord<'raw> for Vec<T>
183where
184 T: SubRecord<'raw>,
185{
186 const MIN_SERIALIZED_SIZE: usize = LEN_SIZE;
187
188 #[inline]
189 fn serialized_size(&self) -> usize {
190 if let Some(size) = T::EXACT_SERIALIZED_SIZE {
191 self.len() * size + LEN_SIZE
192 } else {
193 self.iter().fold(0, |acc, v| acc + v.serialized_size()) + LEN_SIZE
194 }
195 }
196
197 define_serialize_chained!(Vec<T> => |zelf, dest| {
198 write_len(dest, zelf.len())?;
199 let mut i = LEN_SIZE;
200 for v in zelf.iter() {
201 i += v._serialize_chained(dest)?;
202 }
203 Ok(i)
204 });
205
206 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
207 let len = read_len(raw)?;
208 let mut i = LEN_SIZE;
209 let mut v = Vec::with_capacity(len);
210 for _ in 0..len {
211 let slice = &raw.get(i..).ok_or(DeserializeError::CorruptFrame)?;
212 let (read, t) = T::_deserialize_chained(slice)?;
213 i += read;
214 v.push(t);
215 }
216 Ok((i, v))
217 }
218}
219
220test_serialization!(
221 serialization_vec_str,
222 Vec<&str>,
223 vec!["abc", "def", "ghij"],
224 10 + LEN_SIZE * 4
225);
226test_serialization!(
227 serialization_vec_layered,
228 Vec<Vec<Vec<i64>>>,
229 (0..4)
230 .map(|_| (0..4).map(|_| (0..16).collect()).collect())
231 .collect(),
232 8 * 4 * 4 * 16 + LEN_SIZE + LEN_SIZE * 4 + LEN_SIZE * 4 * 4
233);
234test_serialization!(serialization_vec_empty_str, Vec<&str>, Vec::new(), LEN_SIZE);
235test_serialization!(
236 serialization_vec_i16,
237 Vec<i16>,
238 vec![1234, 123, 154, -194, -4234, 432],
239 12 + LEN_SIZE
240);
241test_serialization!(serialization_vec_empty_i16, Vec<i16>, Vec::new(), LEN_SIZE);
242
243#[test]
244fn out_of_bounds_array() {
245 let buf = [100, 100, 100, 100, 100, 100];
246 let result = Vec::<u32>::_deserialize_chained(&buf);
247 assert!(result.is_err());
248}
249
250#[cfg(feature = "sorted_maps")]
251pub trait SubRecordHashMapKey<'raw>: SubRecord<'raw> + Eq + Hash + Ord {}
252#[cfg(not(feature = "sorted_maps"))]
253pub trait SubRecordHashMapKey<'raw>: SubRecord<'raw> + Eq + Hash {}
254
255#[cfg(feature = "sorted_maps")]
256impl<'raw, T> SubRecordHashMapKey<'raw> for T where T: SubRecord<'raw> + Eq + Hash + Ord {}
257#[cfg(not(feature = "sorted_maps"))]
258impl<'raw, T> SubRecordHashMapKey<'raw> for T where T: SubRecord<'raw> + Eq + Hash {}
259
260impl<'raw, K, V> SubRecord<'raw> for HashMap<K, V>
261where
262 K: SubRecordHashMapKey<'raw>,
263 V: SubRecord<'raw>,
264{
265 const MIN_SERIALIZED_SIZE: usize = LEN_SIZE;
266
267 #[inline]
268 fn serialized_size(&self) -> usize {
269 match (K::EXACT_SERIALIZED_SIZE, V::EXACT_SERIALIZED_SIZE) {
270 (Some(k_size), Some(v_size)) => (k_size + v_size) * self.len() + LEN_SIZE,
271 (Some(k_size), None) => {
272 k_size * self.len()
273 + self.values().fold(0, |acc, v| acc + v.serialized_size())
274 + LEN_SIZE
275 }
276 (None, Some(v_size)) => {
277 self.keys().fold(0, |acc, k| acc + k.serialized_size())
278 + v_size * self.len()
279 + LEN_SIZE
280 }
281 (None, None) => {
282 self.keys().fold(0, |acc, k| acc + k.serialized_size())
283 + self.values().fold(0, |acc, v| acc + v.serialized_size())
284 + LEN_SIZE
285 }
286 }
287 }
288
289 define_serialize_chained!(HashMap<K, V> => |zelf, dest| {
290 #[cfg(feature = "sorted_maps")]
291 use itertools::Itertools as _;
292
293 write_len(dest, zelf.len())?;
294 let mut i = LEN_SIZE;
295
296 #[cfg(feature = "sorted_maps")]
297 let iter = zelf
298 .iter()
299 .sorted_unstable_by(|(k1, _), (k2, _)| k1.cmp(k2));
300 #[cfg(not(feature = "sorted_maps"))]
301 let iter = zelf.iter();
302
303 for (k, v) in iter {
304 i += k._serialize_chained(dest)?;
305 i += v._serialize_chained(dest)?;
306 }
307 Ok(i)
308 });
309
310 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
311 let len = read_len(raw)?;
312 let mut i = LEN_SIZE;
313 let mut m = HashMap::with_capacity(len);
314 for _ in 0..len {
315 let (read, k) =
316 K::_deserialize_chained(raw.get(i..).ok_or(DeserializeError::CorruptFrame)?)?;
317 i += read;
318 let (read, v) =
319 V::_deserialize_chained(raw.get(i..).ok_or(DeserializeError::CorruptFrame)?)?;
320 i += read;
321 m.insert(k, v);
322 }
323 Ok((i, m))
324 }
325}
326
327test_serialization!(serialization_map_str_str, HashMap<&str, &str>, collection! { "k1" => "v1", "key2" => "value2" }, 14 + LEN_SIZE * 5);
328test_serialization!(serialization_map_i16_str, HashMap<i16, &str>, collection! { 123 => "abc", -13 => "def", 843 => "ghij" }, 16 + LEN_SIZE * 4);
329test_serialization!(serialization_map_str_i16, HashMap<&str, i16>, collection! { "abc" => 123, "def" => -13, "ghij" => 843 }, 16 + LEN_SIZE * 4);
330test_serialization!(serialization_map_i16_i16, HashMap<i16, i16>, collection! { 23 => 432, -543 => 53, -43 => -12 }, 12 + LEN_SIZE);
331test_serialization!(serialization_map_i16_i16_empty, HashMap<i16, i16>, HashMap::new(), LEN_SIZE);
332test_serialization!(serialization_map_str_str_empty, HashMap<&str, &str>, HashMap::new(), LEN_SIZE);
333test_serialization!(serialization_map_str_vec_empty_vec, HashMap<&str, Vec<i32>>, collection! {"abc" => vec![]}, LEN_SIZE * 3 + 3);
334
335impl<'raw> SubRecord<'raw> for Guid {
336 const MIN_SERIALIZED_SIZE: usize = Self::SERIALIZED_SIZE;
337 const EXACT_SERIALIZED_SIZE: Option<usize> = Some(Self::SERIALIZED_SIZE);
338
339 #[inline]
340 fn serialized_size(&self) -> usize {
341 Self::SERIALIZED_SIZE
342 }
343
344 define_serialize_chained!(*Guid => |zelf, dest| {
345 dest.write_all(&zelf.to_ms_bytes())?;
346 Ok(16)
347 });
348
349 #[inline]
350 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
351 if raw.len() < 16 {
352 return Err(DeserializeError::MoreDataExpected(16 - raw.len()));
353 }
354 Ok((16, Guid::from_ms_bytes(raw[0..16].try_into().unwrap())))
355 }
356}
357
358test_serialization!(
359 serialization_guid,
360 Guid,
361 Guid::from_be_bytes([
362 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
363 0x0f
364 ]),
365 16
366);
367
368#[test]
369fn out_of_bounds_guid() {
370 let buf = [100, 100, 100, 100, 100, 100];
371 let result = Guid::_deserialize_chained(&buf);
372 assert!(result.is_err());
373}
374
375impl<'raw> SubRecord<'raw> for Date {
376 const MIN_SERIALIZED_SIZE: usize = Self::SERIALIZED_SIZE;
377 const EXACT_SERIALIZED_SIZE: Option<usize> = Some(Self::SERIALIZED_SIZE);
378
379 #[inline]
380 fn serialized_size(&self) -> usize {
381 Self::SERIALIZED_SIZE
382 }
383
384 define_serialize_chained!(*Date => |zelf, dest| zelf.to_ticks()._serialize_chained(dest));
385
386 #[inline]
387 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
388 let (read, date) = u64::_deserialize_chained(raw)?;
389 Ok((read, Date::from_ticks(date)))
390 }
391}
392
393test_serialization!(serialization_date, Date, Date::from_ticks(23462356), 8);
394
395impl<'de> SubRecord<'de> for bool {
396 const MIN_SERIALIZED_SIZE: usize = 1;
397 const EXACT_SERIALIZED_SIZE: Option<usize> = Some(bool::SERIALIZED_SIZE);
398
399 #[inline]
400 fn serialized_size(&self) -> usize {
401 bool::SERIALIZED_SIZE
402 }
403
404 define_serialize_chained!(*bool => |zelf, dest| {
405 dest.write_all(&[if zelf { 1 } else { 0 }])?;
406 Ok(1)
407 });
408
409 #[inline]
410 fn _deserialize_chained(raw: &'de [u8]) -> DeResult<(usize, Self)> {
411 if let Some(&b) = raw.first() {
412 Ok((1, b > 0))
413 } else {
414 Err(DeserializeError::MoreDataExpected(1))
415 }
416 }
417}
418
419test_serialization!(serialization_bool_true, bool, true, 1);
420test_serialization!(serialization_bool_false, bool, false, 1);
421
422impl<'raw, T> SubRecord<'raw> for SliceWrapper<'raw, T>
423where
424 T: FixedSized + SubRecord<'raw>,
425{
426 const MIN_SERIALIZED_SIZE: usize = LEN_SIZE;
427
428 #[inline]
429 fn serialized_size(&self) -> usize {
430 self.size() + LEN_SIZE
431 }
432
433 define_serialize_chained!(*SliceWrapper<'raw, T> => |zelf, dest| {
434 write_len(dest, zelf.len())?;
435 match zelf {
436 SliceWrapper::Raw(raw) => {
437 dest.write_all(raw)?;
438 Ok(LEN_SIZE + raw.len())
439 }
440 SliceWrapper::Cooked(ary) => {
441 if cfg!(target_endian = "little") &&
442 mem::size_of::<T>() % mem::align_of::<T>() == 0
443 {
444 let b: &[u8] = unsafe {
447 std::slice::from_raw_parts(
448 ary.as_ptr() as *const u8,
449 ary.len() * mem::size_of::<T>(),
450 )
451 };
452 dest.write_all(b)?;
453 Ok(LEN_SIZE + b.len())
454 } else {
455 let mut i = LEN_SIZE;
457 for v in ary {
458 i += v._serialize_chained(dest)?;
459 }
460 Ok(i)
461 }
462 }
463 }
464 });
465
466 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
467 let len = read_len(raw)?;
468 let bytes = len * mem::size_of::<T>() + LEN_SIZE;
469 if bytes > raw.len() {
470 return Err(DeserializeError::MoreDataExpected(bytes - raw.len()));
471 }
472 Ok((
473 bytes,
474 if mem::size_of::<T>() % mem::align_of::<T>() == 0
475 && raw.as_ptr().align_offset(mem::align_of::<T>()) == 0
476 {
477 SliceWrapper::from_cooked(unsafe {
480 std::slice::from_raw_parts((raw[LEN_SIZE..bytes]).as_ptr() as *const T, len)
481 })
482 } else {
483 SliceWrapper::from_raw(&raw[LEN_SIZE..bytes])
484 },
485 ))
486 }
487}
488
489test_serialization!(
490 serialization_slicewrapper_u8_cooked,
491 SliceWrapper<u8>,
492 SliceWrapper::Cooked(&[1, 2, 3, 4, 5, 6]),
493 6 + LEN_SIZE
494);
495
496#[test]
497fn out_of_bounds_slice_wrapper() {
498 let buf = [100, 100, 100, 100, 100, 100];
499 let result = SliceWrapper::<u8>::_deserialize_chained(&buf);
500 assert!(result.is_err());
501}
502
503#[test]
504fn serialization_slicewrapper_i16_cooked() {
505 let mut buf = Vec::new();
506 const LEN: usize = 10 + LEN_SIZE;
507 let value: SliceWrapper<i16> = SliceWrapper::Cooked(&[12, 32, 543, 652, -23]);
508 assert_eq!(value._serialize_chained(&mut buf).unwrap(), LEN);
509 assert_eq!(buf.len(), LEN);
510 buf.extend_from_slice(&[0x05, 0x01, 0x00, 0x00, 0x13, 0x42, 0x12]);
511 let (read, deserialized) = <SliceWrapper<i16>>::_deserialize_chained(&buf).unwrap();
512 assert_eq!(read, LEN);
513 assert_eq!(
514 deserialized,
515 if cfg!(target_endian = "little") {
516 SliceWrapper::Cooked(&[12, 32, 543, 652, -23])
517 } else {
518 SliceWrapper::Raw(&[12, 0, 32, 0, 31, 2, 140, 2, 233, 255])
519 }
520 );
521}
522
523impl<'raw> SubRecord<'raw> for u8 {
525 const MIN_SERIALIZED_SIZE: usize = Self::SERIALIZED_SIZE;
526 const EXACT_SERIALIZED_SIZE: Option<usize> = Some(Self::SERIALIZED_SIZE);
527
528 #[inline]
529 fn serialized_size(&self) -> usize {
530 Self::SERIALIZED_SIZE
531 }
532
533 #[inline]
534 unsafe fn _serialize_chained_unaligned<W: Write>(
535 zelf: *const Self,
536 dest: &mut W,
537 ) -> SeResult<usize> {
538 dest.write_all(&[*zelf])?;
539 Ok(1)
540 }
541
542 #[inline]
543 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
544 if raw.is_empty() {
545 Err(DeserializeError::MoreDataExpected(1))
546 } else {
547 Ok((1, raw[0]))
548 }
549 }
550}
551
552macro_rules! impl_record_for_num {
553 ($t:ty) => {
554 impl<'raw> SubRecord<'raw> for $t {
555 const MIN_SERIALIZED_SIZE: usize = Self::SERIALIZED_SIZE;
556 const EXACT_SERIALIZED_SIZE: Option<usize> = Some(Self::SERIALIZED_SIZE);
557
558 #[inline]
559 fn serialized_size(&self) -> usize {
560 Self::SERIALIZED_SIZE
561 }
562
563 define_serialize_chained!(*$t => |zelf, dest| {
564 dest.write_all(&zelf.to_le_bytes())?;
565 Ok(mem::size_of::<$t>())
566 });
567
568 #[inline]
569 fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> {
570 if raw.len() < mem::size_of::<$t>() {
571 return Err(DeserializeError::MoreDataExpected(
572 mem::size_of::<$t>() - raw.len(),
573 ));
574 }
575 Ok((
576 mem::size_of::<$t>(),
577 <$t>::from_le_bytes(raw[0..mem::size_of::<$t>()].try_into().unwrap()),
578 ))
579 }
580 }
581 };
582}
583
584impl_record_for_num!(u16);
586impl_record_for_num!(i16);
587impl_record_for_num!(u32);
588impl_record_for_num!(i32);
589impl_record_for_num!(f32);
590impl_record_for_num!(u64);
591impl_record_for_num!(i64);
592impl_record_for_num!(f64);
593
594#[inline(always)]
599pub fn read_len(raw: &[u8]) -> DeResult<usize> {
600 Ok(Len::_deserialize_chained(raw)?.1 as usize)
601}
602
603#[test]
604fn read_len_test() {
605 let buf = [23, 51, 0, 0, 2, 5];
606 assert_eq!(read_len(&buf).unwrap(), 13079);
607 assert_eq!(read_len(&buf[1..]).unwrap(), 33554483);
608 assert_eq!(read_len(&buf[2..]).unwrap(), 84017152);
609}
610
611#[inline(always)]
616pub fn write_len<W: Write>(dest: &mut W, len: usize) -> SeResult<()> {
617 if len > u32::MAX as usize {
618 Err(SerializeError::LengthExceeds32Bits)
619 } else {
620 (len as u32)._serialize_chained(dest)?;
621 Ok(())
622 }
623}
624
625#[test]
626fn write_len_test() {
627 let mut buf = vec![0, 12, 4];
628 write_len(&mut buf, 0).unwrap();
629 write_len(&mut buf, 123).unwrap();
630 write_len(&mut buf, 87543).unwrap();
631 assert_eq!(buf.len(), 3 + LEN_SIZE * 3);
632 assert_eq!(buf[3..7], [0, 0, 0, 0]);
633 assert_eq!(buf[7..11], [123, 0, 0, 0]);
634 assert_eq!(buf[11..], [247, 85, 1, 0]);
635}
636
637#[inline(always)]
638fn serialize_byte_slice<W: Write>(dest: &mut W, raw: &[u8]) -> SeResult<usize> {
639 write_len(dest, raw.len())?;
640 dest.write_all(raw)?;
641 Ok(LEN_SIZE + raw.len())
642}