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 |
Definitions
- LittleEndian
- BigEndian
- NativeEndian
- read_num_bytes
- write_num_bytes
- read_u16
- read_u32
- read_u64
- write_u16
- write_u32
- write_u64
- write_u128
- read_u128
- read_u16
- read_u32
- read_u64
- write_u16
- write_u32
- write_u64
- write_u128
- read_u128
- ByteOrder
- read_u16
- read_u32
- read_u64
- write_u16
- write_u32
- write_u64
- read_i16
- read_i32
- read_i64
- read_f32
- read_f64
- write_i16
- write_i32
- write_i64
- write_f32
- write_f64
- read_u128
- write_u128
- read_i128
- write_i128
- ReadBytesExt
- read_u8
- read_i8
- read_u16
- read_i16
- read_u32
- read_i32
- read_u64
- read_i64
- read_f32
- read_f64
- read_u128
- read_i128
- WriteBytesExt
- write_u8
- write_i8
- write_u16
- write_i16
- write_u32
- write_i32
- write_u64
- write_i64
- write_f32
- write_f64
- write_u128
Learn Rust with the experts
Find out more