1 // Copyright (c) 2015 Andrew Gallant
2 
3 use std::io;
4 use std::io::Result;
5 use std::ptr::copy_nonoverlapping;
6 
7 #[derive(Copy, Clone)]
8 pub struct LittleEndian;
9 
10 #[derive(Copy, Clone)]
11 pub struct BigEndian;
12 
13 #[cfg(target_endian = "little")]
14 pub type NativeEndian = LittleEndian;
15 
16 #[cfg(target_endian = "big")]
17 pub type NativeEndian = BigEndian;
18 
19 macro_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 
31 macro_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 
42 impl ByteOrder for LittleEndian {
43     #[inline]
read_u16(buf: &[u8]) -> u1644     fn read_u16(buf: &[u8]) -> u16 {
45         read_num_bytes!(u16, 2, buf, to_le)
46     }
47 
48     #[inline]
read_u32(buf: &[u8]) -> u3249     fn read_u32(buf: &[u8]) -> u32 {
50         read_num_bytes!(u32, 4, buf, to_le)
51     }
52 
53     #[inline]
read_u64(buf: &[u8]) -> u6454     fn read_u64(buf: &[u8]) -> u64 {
55         read_num_bytes!(u64, 8, buf, to_le)
56     }
57 
58     #[inline]
write_u16(buf: &mut [u8], n: u16)59     fn write_u16(buf: &mut [u8], n: u16) {
60         write_num_bytes!(u16, 2, n, buf, to_le);
61     }
62 
63     #[inline]
write_u32(buf: &mut [u8], n: u32)64     fn write_u32(buf: &mut [u8], n: u32) {
65         write_num_bytes!(u32, 4, n, buf, to_le);
66     }
67 
68     #[inline]
write_u64(buf: &mut [u8], n: u64)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 
86 impl ByteOrder for BigEndian {
87     #[inline]
read_u16(buf: &[u8]) -> u1688     fn read_u16(buf: &[u8]) -> u16 {
89         read_num_bytes!(u16, 2, buf, to_be)
90     }
91 
92     #[inline]
read_u32(buf: &[u8]) -> u3293     fn read_u32(buf: &[u8]) -> u32 {
94         read_num_bytes!(u32, 4, buf, to_be)
95     }
96 
97     #[inline]
read_u64(buf: &[u8]) -> u6498     fn read_u64(buf: &[u8]) -> u64 {
99         read_num_bytes!(u64, 8, buf, to_be)
100     }
101 
102     #[inline]
write_u16(buf: &mut [u8], n: u16)103     fn write_u16(buf: &mut [u8], n: u16) {
104         write_num_bytes!(u16, 2, n, buf, to_be);
105     }
106 
107     #[inline]
write_u32(buf: &mut [u8], n: u32)108     fn write_u32(buf: &mut [u8], n: u32) {
109         write_num_bytes!(u32, 4, n, buf, to_be);
110     }
111 
112     #[inline]
write_u64(buf: &mut [u8], n: u64)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 
130 pub trait ByteOrder: Clone + Copy {
read_u16(buf: &[u8]) -> u16131     fn read_u16(buf: &[u8]) -> u16;
132 
read_u32(buf: &[u8]) -> u32133     fn read_u32(buf: &[u8]) -> u32;
134 
read_u64(buf: &[u8]) -> u64135     fn read_u64(buf: &[u8]) -> u64;
136 
write_u16(buf: &mut [u8], n: u16)137     fn write_u16(buf: &mut [u8], n: u16);
138 
write_u32(buf: &mut [u8], n: u32)139     fn write_u32(buf: &mut [u8], n: u32);
140 
write_u64(buf: &mut [u8], n: u64)141     fn write_u64(buf: &mut [u8], n: u64);
142 
143     #[inline]
read_i16(buf: &[u8]) -> i16144     fn read_i16(buf: &[u8]) -> i16 {
145         Self::read_u16(buf) as i16
146     }
147 
148     #[inline]
read_i32(buf: &[u8]) -> i32149     fn read_i32(buf: &[u8]) -> i32 {
150         Self::read_u32(buf) as i32
151     }
152 
153     #[inline]
read_i64(buf: &[u8]) -> i64154     fn read_i64(buf: &[u8]) -> i64 {
155         Self::read_u64(buf) as i64
156     }
157 
158     #[inline]
read_f32(buf: &[u8]) -> f32159     fn read_f32(buf: &[u8]) -> f32 {
160         unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) }
161     }
162 
163     #[inline]
read_f64(buf: &[u8]) -> f64164     fn read_f64(buf: &[u8]) -> f64 {
165         unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) }
166     }
167 
168     #[inline]
write_i16(buf: &mut [u8], n: i16)169     fn write_i16(buf: &mut [u8], n: i16) {
170         Self::write_u16(buf, n as u16)
171     }
172 
173     #[inline]
write_i32(buf: &mut [u8], n: i32)174     fn write_i32(buf: &mut [u8], n: i32) {
175         Self::write_u32(buf, n as u32)
176     }
177 
178     #[inline]
write_i64(buf: &mut [u8], n: i64)179     fn write_i64(buf: &mut [u8], n: i64) {
180         Self::write_u64(buf, n as u64)
181     }
182 
183     #[inline]
write_f32(buf: &mut [u8], n: f32)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]
write_f64(buf: &mut [u8], n: f64)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 
211 pub trait ReadBytesExt: io::Read {
212     #[inline]
read_u8(&mut self) -> Result<u8>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]
read_i8(&mut self) -> Result<i8>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]
read_u16<T: ByteOrder>(&mut self) -> Result<u16>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]
read_i16<T: ByteOrder>(&mut self) -> Result<i16>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]
read_u32<T: ByteOrder>(&mut self) -> Result<u32>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]
read_i32<T: ByteOrder>(&mut self) -> Result<i32>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]
read_u64<T: ByteOrder>(&mut self) -> Result<u64>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]
read_i64<T: ByteOrder>(&mut self) -> Result<i64>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]
read_f32<T: ByteOrder>(&mut self) -> Result<f32>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]
read_f64<T: ByteOrder>(&mut self) -> Result<f64>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 
299 impl<R: io::Read + ?Sized> ReadBytesExt for R {}
300 
301 pub trait WriteBytesExt: io::Write {
302     #[inline]
write_u8(&mut self, n: u8) -> Result<()>303     fn write_u8(&mut self, n: u8) -> Result<()> {
304         self.write_all(&[n])
305     }
306 
307     #[inline]
write_i8(&mut self, n: i8) -> Result<()>308     fn write_i8(&mut self, n: i8) -> Result<()> {
309         self.write_all(&[n as u8])
310     }
311 
312     #[inline]
write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()>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]
write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()>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]
write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()>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]
write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()>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]
write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()>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]
write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()>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]
write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()>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]
write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()>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 
385 impl<W: io::Write + ?Sized> WriteBytesExt for W {}
386