1 #[derive(Copy, Clone, Debug)]
2 /// The endianness for integer and floating-point numbers in SPSS system files.
4 /// SPSS system files can declare IBM 370 and DEC VAX floating-point
5 /// representations, but no file that uses either of these has ever been found
6 /// in the wild, so this code does not handle them.
8 /// Big-endian: MSB at lowest address.
11 /// Little-endian: LSB at lowest address.
16 pub fn identify_u32(expected_value: u32, bytes: [u8; 4]) -> Option<Self> {
17 let as_big: u32 = Endian::Big.parse(bytes);
18 let as_little: u32 = Endian::Little.parse(bytes);
19 match (as_big == expected_value, as_little == expected_value) {
20 (true, false) => Some(Endian::Big),
21 (false, true) => Some(Endian::Little),
26 pub fn identify_f64(expected_value: f64, bytes: [u8; 8]) -> Option<Self> {
27 let as_big: f64 = Endian::Big.parse(bytes);
28 let as_little: f64 = Endian::Little.parse(bytes);
29 match (as_big == expected_value, as_little == expected_value) {
30 (true, false) => Some(Endian::Big),
31 (false, true) => Some(Endian::Little),
37 /// Parses an `N`-byte slice in one of the supported formats into native format
39 pub trait Parse<T, const N: usize> {
40 /// Given 'bytes', returns `T`.
41 fn parse(self, bytes: [u8; N]) -> T;
43 impl Parse<u64, 8> for Endian {
44 fn parse(self, bytes: [u8; 8]) -> u64 {
46 Endian::Big => u64::from_be_bytes(bytes),
47 Endian::Little => u64::from_le_bytes(bytes),
51 impl Parse<u32, 4> for Endian {
52 fn parse(self, bytes: [u8; 4]) -> u32 {
54 Endian::Big => u32::from_be_bytes(bytes),
55 Endian::Little => u32::from_le_bytes(bytes),
59 impl Parse<u16, 2> for Endian {
60 fn parse(self, bytes: [u8; 2]) -> u16 {
62 Endian::Big => u16::from_be_bytes(bytes),
63 Endian::Little => u16::from_le_bytes(bytes),
67 impl Parse<u8, 1> for Endian {
68 fn parse(self, bytes: [u8; 1]) -> u8 {
70 Endian::Big => u8::from_be_bytes(bytes),
71 Endian::Little => u8::from_le_bytes(bytes),
75 impl Parse<i64, 8> for Endian {
76 fn parse(self, bytes: [u8; 8]) -> i64 {
78 Endian::Big => i64::from_be_bytes(bytes),
79 Endian::Little => i64::from_le_bytes(bytes),
83 impl Parse<i32, 4> for Endian {
84 fn parse(self, bytes: [u8; 4]) -> i32 {
86 Endian::Big => i32::from_be_bytes(bytes),
87 Endian::Little => i32::from_le_bytes(bytes),
91 impl Parse<i16, 2> for Endian {
92 fn parse(self, bytes: [u8; 2]) -> i16 {
94 Endian::Big => i16::from_be_bytes(bytes),
95 Endian::Little => i16::from_le_bytes(bytes),
99 impl Parse<i8, 1> for Endian {
100 fn parse(self, bytes: [u8; 1]) -> i8 {
102 Endian::Big => i8::from_be_bytes(bytes),
103 Endian::Little => i8::from_le_bytes(bytes),
107 impl Parse<f64, 8> for Endian {
108 fn parse(self, bytes: [u8; 8]) -> f64 {
110 Endian::Big => f64::from_be_bytes(bytes),
111 Endian::Little => f64::from_le_bytes(bytes),