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
//! Bytestream reader functionality.

// TODO: arch-specific version
// TODO: aligned/non-aligned version

/// Reads the first byte of a buffer.
#[inline]
pub fn get_u8(buf: &[u8]) -> u8 {
    assert!(!buf.is_empty());
    buf[0] as u8
}

/// Reads the first byte of a buffer and returns it as an `i8`.
#[inline]
pub fn get_i8(buf: &[u8]) -> i8 {
    assert!(!buf.is_empty());
    buf[0] as i8
}

/// Reads the first 2 bytes of a buffer and stores them
/// in a little-endian order.
#[inline]
pub fn get_u16l(buf: &[u8]) -> u16 {
    assert!(buf.len() > 1);
    let data = [buf[0], buf[1]];
    u16::from_le_bytes(data)
}

/// Reads the first 2 bytes of a buffer and stores them in a big-endian order.
#[inline]
pub fn get_u16b(buf: &[u8]) -> u16 {
    assert!(buf.len() > 1);
    let data = [buf[0], buf[1]];
    u16::from_be_bytes(data)
}

/// Reads the first 4 bytes of a buffer and stores them
/// in a little-endian order.
#[inline]
pub fn get_u32l(buf: &[u8]) -> u32 {
    assert!(buf.len() > 3);
    let data = [buf[0], buf[1], buf[2], buf[3]];
    u32::from_le_bytes(data)
}

/// Reads the first 4 bytes of a buffer and stores them in a big-endian order.
#[inline]
pub fn get_u32b(buf: &[u8]) -> u32 {
    assert!(buf.len() > 3);
    let data = [buf[0], buf[1], buf[2], buf[3]];
    u32::from_be_bytes(data)
}

/// Reads the first 8 bytes of a buffer and stores them
/// in a little-endian order.
#[inline]
pub fn get_u64l(buf: &[u8]) -> u64 {
    assert!(buf.len() > 7);
    let data = [
        buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
    ];
    u64::from_le_bytes(data)
}

/// Reads the first 8 bytes of a buffer and stores them in a big-endian order.
#[inline]
pub fn get_u64b(buf: &[u8]) -> u64 {
    assert!(buf.len() > 7);
    let data = [
        buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
    ];
    u64::from_be_bytes(data)
}

/// Reads the first 2 bytes of a buffer, stores them in a little-endian order,
/// and returns them as an `i16`.
#[inline]
pub fn get_i16l(buf: &[u8]) -> i16 {
    get_u16l(buf) as i16
}

/// Reads the first 2 bytes of a buffer, stores them in a big-endian order,
/// and returns them as an `i16`.
#[inline]
pub fn get_i16b(buf: &[u8]) -> i16 {
    get_u16b(buf) as i16
}

/// Reads the first 4 bytes of a buffer, stores them in a little-endian order,
/// and returns them as an `i32`.
#[inline]
pub fn get_i32l(buf: &[u8]) -> i32 {
    get_u32l(buf) as i32
}

/// Reads the first 4 bytes of a buffer, stores them in a big-endian order,
/// and returns them as an `i32`.
#[inline]
pub fn get_i32b(buf: &[u8]) -> i32 {
    get_u32b(buf) as i32
}

/// Reads the first 8 bytes of a buffer, stores them in a little-endian order,
/// and returns them as an `i64`.
#[inline]
pub fn get_i64l(buf: &[u8]) -> i64 {
    get_u64l(buf) as i64
}

/// Reads the first 8 bytes of a buffer, stores them in a big-endian order,
/// and returns them as an `i64`.
#[inline]
pub fn get_i64b(buf: &[u8]) -> i64 {
    get_u64b(buf) as i64
}

/// Reads the first 4 bytes of a buffer, stores them in a little-endian order,
/// and returns them as an `f32`.
#[inline]
pub fn get_f32l(buf: &[u8]) -> f32 {
    f32::from_bits(get_u32l(buf))
}

/// Reads the first 4 bytes of a buffer, stores them in a big-endian order,
/// and returns them as an `f32`.
#[inline]
pub fn get_f32b(buf: &[u8]) -> f32 {
    f32::from_bits(get_u32b(buf))
}

/// Reads the first 8 bytes of a buffer, stores them in a little-endian order,
/// and returns them as an `f64`.
#[inline]
pub fn get_f64l(buf: &[u8]) -> f64 {
    f64::from_bits(get_u64l(buf))
}

/// Reads the first 8 bytes of a buffer, stores them in a big-endian order,
/// and returns them as an `f64`.
#[inline]
pub fn get_f64b(buf: &[u8]) -> f64 {
    f64::from_bits(get_u64b(buf))
}