bincode/
byteorder.rs

1// Copyright (c) 2015 Andrew Gallant
2
3use std::io;
4use std::io::Result;
5use std::ptr::copy_nonoverlapping;
6
7#[derive(Copy, Clone)]
8pub struct LittleEndian;
9
10#[derive(Copy, Clone)]
11pub struct BigEndian;
12
13#[cfg(target_endian = "little")]
14pub type NativeEndian = LittleEndian;
15
16#[cfg(target_endian = "big")]
17pub type NativeEndian = BigEndian;
18
19macro_rules! read_num_bytes {
20    ($ty:ty, $size:expr, $src:expr, $which:ident) => {{
21        assert!($size == ::std::mem::size_of::<$ty>());
22        assert!($size <= $src.len());
23        let mut data: $ty = 0;
24        unsafe {
25            copy_nonoverlapping($src.as_ptr(), &mut data as *mut $ty as *mut u8, $size);
26        }
27        data.$which()
28    }};
29}
30
31macro_rules! write_num_bytes {
32    ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => {{
33        assert!($size <= $dst.len());
34        unsafe {
35            // N.B. https://github.com/rust-lang/rust/issues/22776
36            let bytes = *(&$n.$which() as *const _ as *const [u8; $size]);
37            copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
38        }
39    }};
40}
41
42impl ByteOrder for LittleEndian {
43    #[inline]
44    fn read_u16(buf: &[u8]) -> u16 {
45        read_num_bytes!(u16, 2, buf, to_le)
46    }
47
48    #[inline]
49    fn read_u32(buf: &[u8]) -> u32 {
50        read_num_bytes!(u32, 4, buf, to_le)
51    }
52
53    #[inline]
54    fn read_u64(buf: &[u8]) -> u64 {
55        read_num_bytes!(u64, 8, buf, to_le)
56    }
57
58    #[inline]
59    fn write_u16(buf: &mut [u8], n: u16) {
60        write_num_bytes!(u16, 2, n, buf, to_le);
61    }
62
63    #[inline]
64    fn write_u32(buf: &mut [u8], n: u32) {
65        write_num_bytes!(u32, 4, n, buf, to_le);
66    }
67
68    #[inline]
69    fn write_u64(buf: &mut [u8], n: u64) {
70        write_num_bytes!(u64, 8, n, buf, to_le);
71    }
72
73    serde_if_integer128! {
74        #[inline]
75        fn write_u128(buf: &mut [u8], n: u128) {
76            write_num_bytes!(u128, 16, n, buf, to_le);
77        }
78
79        #[inline]
80        fn read_u128(buf: &[u8]) -> u128 {
81            read_num_bytes!(u128, 16, buf, to_le)
82        }
83    }
84}
85
86impl ByteOrder for BigEndian {
87    #[inline]
88    fn read_u16(buf: &[u8]) -> u16 {
89        read_num_bytes!(u16, 2, buf, to_be)
90    }
91
92    #[inline]
93    fn read_u32(buf: &[u8]) -> u32 {
94        read_num_bytes!(u32, 4, buf, to_be)
95    }
96
97    #[inline]
98    fn read_u64(buf: &[u8]) -> u64 {
99        read_num_bytes!(u64, 8, buf, to_be)
100    }
101
102    #[inline]
103    fn write_u16(buf: &mut [u8], n: u16) {
104        write_num_bytes!(u16, 2, n, buf, to_be);
105    }
106
107    #[inline]
108    fn write_u32(buf: &mut [u8], n: u32) {
109        write_num_bytes!(u32, 4, n, buf, to_be);
110    }
111
112    #[inline]
113    fn write_u64(buf: &mut [u8], n: u64) {
114        write_num_bytes!(u64, 8, n, buf, to_be);
115    }
116
117    serde_if_integer128! {
118        #[inline]
119        fn write_u128(buf: &mut [u8], n: u128) {
120            write_num_bytes!(u128, 16, n, buf, to_be);
121        }
122
123        #[inline]
124        fn read_u128(buf: &[u8]) -> u128 {
125            read_num_bytes!(u128, 16, buf, to_be)
126        }
127    }
128}
129
130pub trait ByteOrder: Clone + Copy {
131    fn read_u16(buf: &[u8]) -> u16;
132
133    fn read_u32(buf: &[u8]) -> u32;
134
135    fn read_u64(buf: &[u8]) -> u64;
136
137    fn write_u16(buf: &mut [u8], n: u16);
138
139    fn write_u32(buf: &mut [u8], n: u32);
140
141    fn write_u64(buf: &mut [u8], n: u64);
142
143    #[inline]
144    fn read_i16(buf: &[u8]) -> i16 {
145        Self::read_u16(buf) as i16
146    }
147
148    #[inline]
149    fn read_i32(buf: &[u8]) -> i32 {
150        Self::read_u32(buf) as i32
151    }
152
153    #[inline]
154    fn read_i64(buf: &[u8]) -> i64 {
155        Self::read_u64(buf) as i64
156    }
157
158    #[inline]
159    fn read_f32(buf: &[u8]) -> f32 {
160        unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) }
161    }
162
163    #[inline]
164    fn read_f64(buf: &[u8]) -> f64 {
165        unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) }
166    }
167
168    #[inline]
169    fn write_i16(buf: &mut [u8], n: i16) {
170        Self::write_u16(buf, n as u16)
171    }
172
173    #[inline]
174    fn write_i32(buf: &mut [u8], n: i32) {
175        Self::write_u32(buf, n as u32)
176    }
177
178    #[inline]
179    fn write_i64(buf: &mut [u8], n: i64) {
180        Self::write_u64(buf, n as u64)
181    }
182
183    #[inline]
184    fn write_f32(buf: &mut [u8], n: f32) {
185        let n = unsafe { *(&n as *const f32 as *const u32) };
186        Self::write_u32(buf, n)
187    }
188
189    #[inline]
190    fn write_f64(buf: &mut [u8], n: f64) {
191        let n = unsafe { *(&n as *const f64 as *const u64) };
192        Self::write_u64(buf, n)
193    }
194
195    serde_if_integer128! {
196        fn read_u128(buf: &[u8]) -> u128;
197        fn write_u128(buf: &mut [u8], n: u128);
198
199        #[inline]
200        fn read_i128(buf: &[u8]) -> i128 {
201            Self::read_u128(buf) as i128
202        }
203
204        #[inline]
205        fn write_i128(buf: &mut [u8], n: i128) {
206            Self::write_u128(buf, n as u128)
207        }
208    }
209}
210
211pub trait ReadBytesExt: io::Read {
212    #[inline]
213    fn read_u8(&mut self) -> Result<u8> {
214        let mut buf = [0; 1];
215        try!(self.read_exact(&mut buf));
216        Ok(buf[0])
217    }
218
219    #[inline]
220    fn read_i8(&mut self) -> Result<i8> {
221        let mut buf = [0; 1];
222        try!(self.read_exact(&mut buf));
223        Ok(buf[0] as i8)
224    }
225
226    #[inline]
227    fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
228        let mut buf = [0; 2];
229        try!(self.read_exact(&mut buf));
230        Ok(T::read_u16(&buf))
231    }
232
233    #[inline]
234    fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
235        let mut buf = [0; 2];
236        try!(self.read_exact(&mut buf));
237        Ok(T::read_i16(&buf))
238    }
239
240    #[inline]
241    fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
242        let mut buf = [0; 4];
243        try!(self.read_exact(&mut buf));
244        Ok(T::read_u32(&buf))
245    }
246
247    #[inline]
248    fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
249        let mut buf = [0; 4];
250        try!(self.read_exact(&mut buf));
251        Ok(T::read_i32(&buf))
252    }
253
254    #[inline]
255    fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
256        let mut buf = [0; 8];
257        try!(self.read_exact(&mut buf));
258        Ok(T::read_u64(&buf))
259    }
260
261    #[inline]
262    fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
263        let mut buf = [0; 8];
264        try!(self.read_exact(&mut buf));
265        Ok(T::read_i64(&buf))
266    }
267
268    #[inline]
269    fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
270        let mut buf = [0; 4];
271        try!(self.read_exact(&mut buf));
272        Ok(T::read_f32(&buf))
273    }
274
275    #[inline]
276    fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
277        let mut buf = [0; 8];
278        try!(self.read_exact(&mut buf));
279        Ok(T::read_f64(&buf))
280    }
281
282    serde_if_integer128! {
283        #[inline]
284        fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> {
285            let mut buf = [0; 16];
286            try!(self.read_exact(&mut buf));
287            Ok(T::read_u128(&buf))
288        }
289
290        #[inline]
291        fn read_i128<T: ByteOrder>(&mut self) -> Result<i128> {
292            let mut buf = [0; 16];
293            try!(self.read_exact(&mut buf));
294            Ok(T::read_i128(&buf))
295        }
296    }
297}
298
299impl<R: io::Read + ?Sized> ReadBytesExt for R {}
300
301pub trait WriteBytesExt: io::Write {
302    #[inline]
303    fn write_u8(&mut self, n: u8) -> Result<()> {
304        self.write_all(&[n])
305    }
306
307    #[inline]
308    fn write_i8(&mut self, n: i8) -> Result<()> {
309        self.write_all(&[n as u8])
310    }
311
312    #[inline]
313    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
314        let mut buf = [0; 2];
315        T::write_u16(&mut buf, n);
316        self.write_all(&buf)
317    }
318
319    #[inline]
320    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
321        let mut buf = [0; 2];
322        T::write_i16(&mut buf, n);
323        self.write_all(&buf)
324    }
325
326    #[inline]
327    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
328        let mut buf = [0; 4];
329        T::write_u32(&mut buf, n);
330        self.write_all(&buf)
331    }
332
333    #[inline]
334    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
335        let mut buf = [0; 4];
336        T::write_i32(&mut buf, n);
337        self.write_all(&buf)
338    }
339
340    #[inline]
341    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
342        let mut buf = [0; 8];
343        T::write_u64(&mut buf, n);
344        self.write_all(&buf)
345    }
346
347    #[inline]
348    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
349        let mut buf = [0; 8];
350        T::write_i64(&mut buf, n);
351        self.write_all(&buf)
352    }
353
354    #[inline]
355    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
356        let mut buf = [0; 4];
357        T::write_f32(&mut buf, n);
358        self.write_all(&buf)
359    }
360
361    #[inline]
362    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
363        let mut buf = [0; 8];
364        T::write_f64(&mut buf, n);
365        self.write_all(&buf)
366    }
367
368    serde_if_integer128! {
369        #[inline]
370        fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> {
371            let mut buf = [0; 16];
372            T::write_u128(&mut buf, n);
373            self.write_all(&buf)
374        }
375
376        #[inline]
377        fn write_i128<T: ByteOrder>(&mut self, n: i128) -> Result<()> {
378            let mut buf = [0; 16];
379            T::write_i128(&mut buf, n);
380            self.write_all(&buf)
381        }
382    }
383}
384
385impl<W: io::Write + ?Sized> WriteBytesExt for W {}