/rust/registry/src/index.crates.io-1949cf8c6b5b557f/integer-encoding-3.0.4/src/fixed.rs
Line | Count | Source |
1 | | use std::mem::{size_of, transmute}; |
2 | | |
3 | | /// `FixedInt` provides encoding/decoding to and from fixed int representations. |
4 | | /// |
5 | | /// The emitted bytestring contains the bytes of the integer in machine endianness. |
6 | | pub trait FixedInt: Sized + Copy { |
7 | | const REQUIRED_SPACE: usize; |
8 | | /// Returns how many bytes are required to represent the given type. |
9 | | fn required_space() -> usize; |
10 | | /// Encode a value into the given slice. `dst` must be exactly `REQUIRED_SPACE` bytes. |
11 | | fn encode_fixed(self, dst: &mut [u8]); |
12 | | /// Decode a value from the given slice. `src` must be exactly `REQUIRED_SPACE` bytes. |
13 | | fn decode_fixed(src: &[u8]) -> Self; |
14 | | /// Perform a transmute, i.e. return a "view" into the integer's memory, which is faster than |
15 | | /// performing a copy. |
16 | | fn encode_fixed_light<'a>(&'a self) -> &'a [u8]; |
17 | | |
18 | | /// Helper: Encode the value and return a Vec. |
19 | 0 | fn encode_fixed_vec(self) -> Vec<u8> { |
20 | 0 | let mut v = Vec::new(); |
21 | 0 | v.resize(Self::required_space(), 0); |
22 | 0 | self.encode_fixed(&mut v[..]); |
23 | 0 | v |
24 | 0 | } |
25 | | /// Helper: Decode the value from the Vec. |
26 | 0 | fn decode_fixed_vec(v: &Vec<u8>) -> Self { |
27 | 0 | assert_eq!(v.len(), Self::required_space()); |
28 | 0 | Self::decode_fixed(&v[..]) |
29 | 0 | } |
30 | | } |
31 | | |
32 | | macro_rules! impl_fixedint { |
33 | | ($t:ty) => { |
34 | | impl FixedInt for $t { |
35 | | const REQUIRED_SPACE: usize = size_of::<Self>(); |
36 | | |
37 | 0 | fn required_space() -> usize { |
38 | 0 | Self::REQUIRED_SPACE |
39 | 0 | } Unexecuted instantiation: <usize as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <u32 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <u16 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <u8 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <isize as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <i64 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <i32 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <i16 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <i8 as integer_encoding::fixed::FixedInt>::required_space Unexecuted instantiation: <u64 as integer_encoding::fixed::FixedInt>::required_space |
40 | | |
41 | 0 | fn encode_fixed_light<'a>(&'a self) -> &'a [u8] { |
42 | | return unsafe { |
43 | 0 | std::slice::from_raw_parts( |
44 | 0 | transmute::<&$t, *const u8>(&self), |
45 | 0 | Self::REQUIRED_SPACE, |
46 | 0 | ) |
47 | | }; |
48 | 0 | } Unexecuted instantiation: <usize as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <u32 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <u16 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <u8 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <isize as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <i64 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <i32 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <i16 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <i8 as integer_encoding::fixed::FixedInt>::encode_fixed_light Unexecuted instantiation: <u64 as integer_encoding::fixed::FixedInt>::encode_fixed_light |
49 | | |
50 | 0 | fn encode_fixed(self, dst: &mut [u8]) { |
51 | 0 | assert_eq!(dst.len(), Self::REQUIRED_SPACE); |
52 | | |
53 | | #[allow(unused_mut)] |
54 | 0 | let mut encoded = |
55 | 0 | unsafe { &*(&self as *const $t as *const [u8; Self::REQUIRED_SPACE]) }; |
56 | | |
57 | | #[cfg(target_endian = "big")] |
58 | | if Self::REQUIRED_SPACE > 1 { |
59 | | let mut encoded_rev = [0 as u8; Self::REQUIRED_SPACE]; |
60 | | encoded_rev.copy_from_slice(encoded); |
61 | | encoded_rev.reverse(); |
62 | | dst.clone_from_slice(&encoded_rev); |
63 | | return; |
64 | | } |
65 | | |
66 | 0 | dst.clone_from_slice(encoded); |
67 | 0 | } Unexecuted instantiation: <usize as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <u32 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <u16 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <u8 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <isize as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <i64 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <i32 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <i16 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <i8 as integer_encoding::fixed::FixedInt>::encode_fixed Unexecuted instantiation: <u64 as integer_encoding::fixed::FixedInt>::encode_fixed |
68 | | |
69 | | #[cfg(target_endian = "little")] |
70 | 0 | fn decode_fixed(src: &[u8]) -> $t { |
71 | 0 | unsafe { (src.as_ptr() as *const $t).read_unaligned() } |
72 | 0 | } Unexecuted instantiation: <usize as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <u32 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <u16 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <u8 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <isize as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <i64 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <i32 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <i16 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <i8 as integer_encoding::fixed::FixedInt>::decode_fixed Unexecuted instantiation: <u64 as integer_encoding::fixed::FixedInt>::decode_fixed |
73 | | |
74 | | #[cfg(target_endian = "big")] |
75 | | fn decode_fixed(src: &[u8]) -> $t { |
76 | | match Self::REQUIRED_SPACE { |
77 | | 1 => unsafe { (src.as_ptr() as *const $t).read_unaligned() }, |
78 | | _ => { |
79 | | let mut src_fin = [0 as u8; Self::REQUIRED_SPACE]; |
80 | | src_fin.copy_from_slice(src); |
81 | | src_fin.reverse(); |
82 | | unsafe { (src_fin.as_ptr() as *const $t).read_unaligned() } |
83 | | } |
84 | | } |
85 | | } |
86 | | } |
87 | | }; |
88 | | } |
89 | | |
90 | | impl_fixedint!(usize); |
91 | | impl_fixedint!(u64); |
92 | | impl_fixedint!(u32); |
93 | | impl_fixedint!(u16); |
94 | | impl_fixedint!(u8); |
95 | | impl_fixedint!(isize); |
96 | | impl_fixedint!(i64); |
97 | | impl_fixedint!(i32); |
98 | | impl_fixedint!(i16); |
99 | | impl_fixedint!(i8); |