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 ]
|
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 |
|
86 | impl 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 |
|
130 | pub 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 |
|
211 | pub 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 |
|
299 | impl<R: io::Read + ?Sized> ReadBytesExt for R {}
|
300 |
|
301 | pub 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 |
|
385 | impl<W: io::Write + ?Sized> WriteBytesExt for W {}
|
386 | |