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 {}
386