1 /*!
2 This crate provides convenience methods for encoding and decoding numbers in
3 either [big-endian or little-endian order].
4 
5 The organization of the crate is pretty simple. A trait, [`ByteOrder`], specifies
6 byte conversion methods for each type of number in Rust (sans numbers that have
7 a platform dependent size like `usize` and `isize`). Two types, [`BigEndian`]
8 and [`LittleEndian`] implement these methods. Finally, [`ReadBytesExt`] and
9 [`WriteBytesExt`] provide convenience methods available to all types that
10 implement [`Read`] and [`Write`].
11 
12 An alias, [`NetworkEndian`], for [`BigEndian`] is provided to help improve
13 code clarity.
14 
15 An additional alias, [`NativeEndian`], is provided for the endianness of the
16 local platform. This is convenient when serializing data for use and
17 conversions are not desired.
18 
19 # Examples
20 
21 Read unsigned 16 bit big-endian integers from a [`Read`] type:
22 
23 ```rust
24 use std::io::Cursor;
25 use byteorder::{BigEndian, ReadBytesExt};
26 
27 let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
28 // Note that we use type parameters to indicate which kind of byte order
29 // we want!
30 assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
31 assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
32 ```
33 
34 Write unsigned 16 bit little-endian integers to a [`Write`] type:
35 
36 ```rust
37 use byteorder::{LittleEndian, WriteBytesExt};
38 
39 let mut wtr = vec![];
40 wtr.write_u16::<LittleEndian>(517).unwrap();
41 wtr.write_u16::<LittleEndian>(768).unwrap();
42 assert_eq!(wtr, vec![5, 2, 0, 3]);
43 ```
44 
45 # Optional Features
46 
47 This crate optionally provides support for 128 bit values (`i128` and `u128`)
48 when built with the `i128` feature enabled.
49 
50 This crate can also be used without the standard library.
51 
52 # Alternatives
53 
54 Note that as of Rust 1.32, the standard numeric types provide built-in methods
55 like `to_le_bytes` and `from_le_bytes`, which support some of the same use
56 cases.
57 
58 [big-endian or little-endian order]: https://en.wikipedia.org/wiki/Endianness
59 [`ByteOrder`]: trait.ByteOrder.html
60 [`BigEndian`]: enum.BigEndian.html
61 [`LittleEndian`]: enum.LittleEndian.html
62 [`ReadBytesExt`]: trait.ReadBytesExt.html
63 [`WriteBytesExt`]: trait.WriteBytesExt.html
64 [`NetworkEndian`]: type.NetworkEndian.html
65 [`NativeEndian`]: type.NativeEndian.html
66 [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
67 [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
68 */
69 
70 #![deny(missing_docs)]
71 #![cfg_attr(not(feature = "std"), no_std)]
72 
73 #[cfg(feature = "std")]
74 extern crate core;
75 
76 #[cfg(test)]
77 #[macro_use]
78 extern crate doc_comment;
79 
80 #[cfg(test)]
81 doctest!("../README.md");
82 
83 use core::fmt::Debug;
84 use core::hash::Hash;
85 use core::ptr::copy_nonoverlapping;
86 use core::slice;
87 
88 #[cfg(feature = "std")]
89 pub use io::{ReadBytesExt, WriteBytesExt};
90 
91 #[cfg(feature = "std")]
92 mod io;
93 
94 #[inline]
extend_sign(val: u64, nbytes: usize) -> i6495 fn extend_sign(val: u64, nbytes: usize) -> i64 {
96     let shift = (8 - nbytes) * 8;
97     (val << shift) as i64 >> shift
98 }
99 
100 #[cfg(byteorder_i128)]
101 #[inline]
extend_sign128(val: u128, nbytes: usize) -> i128102 fn extend_sign128(val: u128, nbytes: usize) -> i128 {
103     let shift = (16 - nbytes) * 8;
104     (val << shift) as i128 >> shift
105 }
106 
107 #[inline]
unextend_sign(val: i64, nbytes: usize) -> u64108 fn unextend_sign(val: i64, nbytes: usize) -> u64 {
109     let shift = (8 - nbytes) * 8;
110     (val << shift) as u64 >> shift
111 }
112 
113 #[cfg(byteorder_i128)]
114 #[inline]
unextend_sign128(val: i128, nbytes: usize) -> u128115 fn unextend_sign128(val: i128, nbytes: usize) -> u128 {
116     let shift = (16 - nbytes) * 8;
117     (val << shift) as u128 >> shift
118 }
119 
120 #[inline]
pack_size(n: u64) -> usize121 fn pack_size(n: u64) -> usize {
122     if n < 1 << 8 {
123         1
124     } else if n < 1 << 16 {
125         2
126     } else if n < 1 << 24 {
127         3
128     } else if n < 1 << 32 {
129         4
130     } else if n < 1 << 40 {
131         5
132     } else if n < 1 << 48 {
133         6
134     } else if n < 1 << 56 {
135         7
136     } else {
137         8
138     }
139 }
140 
141 #[cfg(byteorder_i128)]
142 #[inline]
pack_size128(n: u128) -> usize143 fn pack_size128(n: u128) -> usize {
144     if n < 1 << 8 {
145         1
146     } else if n < 1 << 16 {
147         2
148     } else if n < 1 << 24 {
149         3
150     } else if n < 1 << 32 {
151         4
152     } else if n < 1 << 40 {
153         5
154     } else if n < 1 << 48 {
155         6
156     } else if n < 1 << 56 {
157         7
158     } else if n < 1 << 64 {
159         8
160     } else if n < 1 << 72 {
161         9
162     } else if n < 1 << 80 {
163         10
164     } else if n < 1 << 88 {
165         11
166     } else if n < 1 << 96 {
167         12
168     } else if n < 1 << 104 {
169         13
170     } else if n < 1 << 112 {
171         14
172     } else if n < 1 << 120 {
173         15
174     } else {
175         16
176     }
177 }
178 
179 mod private {
180     /// Sealed stops crates other than byteorder from implementing any traits
181     /// that use it.
182     pub trait Sealed{}
183     impl Sealed for super::LittleEndian {}
184     impl Sealed for super::BigEndian {}
185 }
186 
187 /// `ByteOrder` describes types that can serialize integers as bytes.
188 ///
189 /// Note that `Self` does not appear anywhere in this trait's definition!
190 /// Therefore, in order to use it, you'll need to use syntax like
191 /// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
192 ///
193 /// This crate provides two types that implement `ByteOrder`: [`BigEndian`]
194 /// and [`LittleEndian`].
195 /// This trait is sealed and cannot be implemented for callers to avoid
196 /// breaking backwards compatibility when adding new derived traits.
197 ///
198 /// # Examples
199 ///
200 /// Write and read `u32` numbers in little endian order:
201 ///
202 /// ```rust
203 /// use byteorder::{ByteOrder, LittleEndian};
204 ///
205 /// let mut buf = [0; 4];
206 /// LittleEndian::write_u32(&mut buf, 1_000_000);
207 /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
208 /// ```
209 ///
210 /// Write and read `i16` numbers in big endian order:
211 ///
212 /// ```rust
213 /// use byteorder::{ByteOrder, BigEndian};
214 ///
215 /// let mut buf = [0; 2];
216 /// BigEndian::write_i16(&mut buf, -5_000);
217 /// assert_eq!(-5_000, BigEndian::read_i16(&buf));
218 /// ```
219 ///
220 /// [`BigEndian`]: enum.BigEndian.html
221 /// [`LittleEndian`]: enum.LittleEndian.html
222 pub trait ByteOrder
223     : Clone + Copy + Debug + Default + Eq + Hash + Ord + PartialEq + PartialOrd
224     + private::Sealed
225 {
226     /// Reads an unsigned 16 bit integer from `buf`.
227     ///
228     /// # Panics
229     ///
230     /// Panics when `buf.len() < 2`.
read_u16(buf: &[u8]) -> u16231     fn read_u16(buf: &[u8]) -> u16;
232 
233     /// Reads an unsigned 24 bit integer from `buf`, stored in u32.
234     ///
235     /// # Panics
236     ///
237     /// Panics when `buf.len() < 3`.
238     ///
239     /// # Examples
240     ///
241     /// Write and read 24 bit `u32` numbers in little endian order:
242     ///
243     /// ```rust
244     /// use byteorder::{ByteOrder, LittleEndian};
245     ///
246     /// let mut buf = [0; 3];
247     /// LittleEndian::write_u24(&mut buf, 1_000_000);
248     /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf));
249     /// ```
read_u24(buf: &[u8]) -> u32250     fn read_u24(buf: &[u8]) -> u32 {
251         Self::read_uint(buf, 3) as u32
252     }
253 
254     /// Reads an unsigned 32 bit integer from `buf`.
255     ///
256     /// # Panics
257     ///
258     /// Panics when `buf.len() < 4`.
259     ///
260     /// # Examples
261     ///
262     /// Write and read `u32` numbers in little endian order:
263     ///
264     /// ```rust
265     /// use byteorder::{ByteOrder, LittleEndian};
266     ///
267     /// let mut buf = [0; 4];
268     /// LittleEndian::write_u32(&mut buf, 1_000_000);
269     /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
270     /// ```
read_u32(buf: &[u8]) -> u32271     fn read_u32(buf: &[u8]) -> u32;
272 
273     /// Reads an unsigned 48 bit integer from `buf`, stored in u64.
274     ///
275     /// # Panics
276     ///
277     /// Panics when `buf.len() < 6`.
278     ///
279     /// # Examples
280     ///
281     /// Write and read 48 bit `u64` numbers in little endian order:
282     ///
283     /// ```rust
284     /// use byteorder::{ByteOrder, LittleEndian};
285     ///
286     /// let mut buf = [0; 6];
287     /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000);
288     /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf));
289     /// ```
read_u48(buf: &[u8]) -> u64290     fn read_u48(buf: &[u8]) -> u64 {
291         Self::read_uint(buf, 6) as u64
292     }
293 
294     /// Reads an unsigned 64 bit integer from `buf`.
295     ///
296     /// # Panics
297     ///
298     /// Panics when `buf.len() < 8`.
299     ///
300     /// # Examples
301     ///
302     /// Write and read `u64` numbers in little endian order:
303     ///
304     /// ```rust
305     /// use byteorder::{ByteOrder, LittleEndian};
306     ///
307     /// let mut buf = [0; 8];
308     /// LittleEndian::write_u64(&mut buf, 1_000_000);
309     /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf));
310     /// ```
read_u64(buf: &[u8]) -> u64311     fn read_u64(buf: &[u8]) -> u64;
312 
313     /// Reads an unsigned 128 bit integer from `buf`.
314     ///
315     /// # Panics
316     ///
317     /// Panics when `buf.len() < 16`.
318     ///
319     /// # Examples
320     ///
321     /// Write and read `u128` numbers in little endian order:
322     ///
323     /// ```rust
324     /// use byteorder::{ByteOrder, LittleEndian};
325     ///
326     /// let mut buf = [0; 16];
327     /// LittleEndian::write_u128(&mut buf, 1_000_000);
328     /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf));
329     /// ```
330     #[cfg(byteorder_i128)]
read_u128(buf: &[u8]) -> u128331     fn read_u128(buf: &[u8]) -> u128;
332 
333     /// Reads an unsigned n-bytes integer from `buf`.
334     ///
335     /// # Panics
336     ///
337     /// Panics when `nbytes < 1` or `nbytes > 8` or
338     /// `buf.len() < nbytes`
339     ///
340     /// # Examples
341     ///
342     /// Write and read an n-byte number in little endian order:
343     ///
344     /// ```rust
345     /// use byteorder::{ByteOrder, LittleEndian};
346     ///
347     /// let mut buf = [0; 3];
348     /// LittleEndian::write_uint(&mut buf, 1_000_000, 3);
349     /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3));
350     /// ```
read_uint(buf: &[u8], nbytes: usize) -> u64351     fn read_uint(buf: &[u8], nbytes: usize) -> u64;
352 
353     /// Reads an unsigned n-bytes integer from `buf`.
354     ///
355     /// # Panics
356     ///
357     /// Panics when `nbytes < 1` or `nbytes > 16` or
358     /// `buf.len() < nbytes`
359     ///
360     /// # Examples
361     ///
362     /// Write and read an n-byte number in little endian order:
363     ///
364     /// ```rust
365     /// use byteorder::{ByteOrder, LittleEndian};
366     ///
367     /// let mut buf = [0; 3];
368     /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3);
369     /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3));
370     /// ```
371     #[cfg(byteorder_i128)]
read_uint128(buf: &[u8], nbytes: usize) -> u128372     fn read_uint128(buf: &[u8], nbytes: usize) -> u128;
373 
374     /// Writes an unsigned 16 bit integer `n` to `buf`.
375     ///
376     /// # Panics
377     ///
378     /// Panics when `buf.len() < 2`.
379     ///
380     /// # Examples
381     ///
382     /// Write and read `u16` numbers in little endian order:
383     ///
384     /// ```rust
385     /// use byteorder::{ByteOrder, LittleEndian};
386     ///
387     /// let mut buf = [0; 2];
388     /// LittleEndian::write_u16(&mut buf, 1_000);
389     /// assert_eq!(1_000, LittleEndian::read_u16(&buf));
390     /// ```
write_u16(buf: &mut [u8], n: u16)391     fn write_u16(buf: &mut [u8], n: u16);
392 
393     /// Writes an unsigned 24 bit integer `n` to `buf`, stored in u32.
394     ///
395     /// # Panics
396     ///
397     /// Panics when `buf.len() < 3`.
398     ///
399     /// # Examples
400     ///
401     /// Write and read 24 bit `u32` numbers in little endian order:
402     ///
403     /// ```rust
404     /// use byteorder::{ByteOrder, LittleEndian};
405     ///
406     /// let mut buf = [0; 3];
407     /// LittleEndian::write_u24(&mut buf, 1_000_000);
408     /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf));
409     /// ```
write_u24(buf: &mut [u8], n: u32)410     fn write_u24(buf: &mut [u8], n: u32) {
411         Self::write_uint(buf, n as u64, 3)
412     }
413 
414     /// Writes an unsigned 32 bit integer `n` to `buf`.
415     ///
416     /// # Panics
417     ///
418     /// Panics when `buf.len() < 4`.
419     ///
420     /// # Examples
421     ///
422     /// Write and read `u32` numbers in little endian order:
423     ///
424     /// ```rust
425     /// use byteorder::{ByteOrder, LittleEndian};
426     ///
427     /// let mut buf = [0; 4];
428     /// LittleEndian::write_u32(&mut buf, 1_000_000);
429     /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
430     /// ```
write_u32(buf: &mut [u8], n: u32)431     fn write_u32(buf: &mut [u8], n: u32);
432 
433     /// Writes an unsigned 48 bit integer `n` to `buf`, stored in u64.
434     ///
435     /// # Panics
436     ///
437     /// Panics when `buf.len() < 6`.
438     ///
439     /// # Examples
440     ///
441     /// Write and read 48 bit `u64` numbers in little endian order:
442     ///
443     /// ```rust
444     /// use byteorder::{ByteOrder, LittleEndian};
445     ///
446     /// let mut buf = [0; 6];
447     /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000);
448     /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf));
449     /// ```
write_u48(buf: &mut [u8], n: u64)450     fn write_u48(buf: &mut [u8], n: u64) {
451         Self::write_uint(buf, n as u64, 6)
452     }
453 
454     /// Writes an unsigned 64 bit integer `n` to `buf`.
455     ///
456     /// # Panics
457     ///
458     /// Panics when `buf.len() < 8`.
459     ///
460     /// # Examples
461     ///
462     /// Write and read `u64` numbers in little endian order:
463     ///
464     /// ```rust
465     /// use byteorder::{ByteOrder, LittleEndian};
466     ///
467     /// let mut buf = [0; 8];
468     /// LittleEndian::write_u64(&mut buf, 1_000_000);
469     /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf));
470     /// ```
write_u64(buf: &mut [u8], n: u64)471     fn write_u64(buf: &mut [u8], n: u64);
472 
473     /// Writes an unsigned 128 bit integer `n` to `buf`.
474     ///
475     /// # Panics
476     ///
477     /// Panics when `buf.len() < 16`.
478     ///
479     /// # Examples
480     ///
481     /// Write and read `u128` numbers in little endian order:
482     ///
483     /// ```rust
484     /// use byteorder::{ByteOrder, LittleEndian};
485     ///
486     /// let mut buf = [0; 16];
487     /// LittleEndian::write_u128(&mut buf, 1_000_000);
488     /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf));
489     /// ```
490     #[cfg(byteorder_i128)]
write_u128(buf: &mut [u8], n: u128)491     fn write_u128(buf: &mut [u8], n: u128);
492 
493     /// Writes an unsigned integer `n` to `buf` using only `nbytes`.
494     ///
495     /// # Panics
496     ///
497     /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
498     /// this method panics.
499     ///
500     /// # Examples
501     ///
502     /// Write and read an n-byte number in little endian order:
503     ///
504     /// ```rust
505     /// use byteorder::{ByteOrder, LittleEndian};
506     ///
507     /// let mut buf = [0; 3];
508     /// LittleEndian::write_uint(&mut buf, 1_000_000, 3);
509     /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3));
510     /// ```
write_uint(buf: &mut [u8], n: u64, nbytes: usize)511     fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
512 
513     /// Writes an unsigned integer `n` to `buf` using only `nbytes`.
514     ///
515     /// # Panics
516     ///
517     /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then
518     /// this method panics.
519     ///
520     /// # Examples
521     ///
522     /// Write and read an n-byte number in little endian order:
523     ///
524     /// ```rust
525     /// use byteorder::{ByteOrder, LittleEndian};
526     ///
527     /// let mut buf = [0; 3];
528     /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3);
529     /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3));
530     /// ```
531     #[cfg(byteorder_i128)]
write_uint128(buf: &mut [u8], n: u128, nbytes: usize)532     fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize);
533 
534     /// Reads a signed 16 bit integer from `buf`.
535     ///
536     /// # Panics
537     ///
538     /// Panics when `buf.len() < 2`.
539     ///
540     /// # Examples
541     ///
542     /// Write and read `i16` numbers in little endian order:
543     ///
544     /// ```rust
545     /// use byteorder::{ByteOrder, LittleEndian};
546     ///
547     /// let mut buf = [0; 2];
548     /// LittleEndian::write_i16(&mut buf, -1_000);
549     /// assert_eq!(-1_000, LittleEndian::read_i16(&buf));
550     /// ```
551     #[inline]
read_i16(buf: &[u8]) -> i16552     fn read_i16(buf: &[u8]) -> i16 {
553         Self::read_u16(buf) as i16
554     }
555 
556     /// Reads a signed 24 bit integer from `buf`, stored in i32.
557     ///
558     /// # Panics
559     ///
560     /// Panics when `buf.len() < 3`.
561     ///
562     /// # Examples
563     ///
564     /// Write and read 24 bit `i32` numbers in little endian order:
565     ///
566     /// ```rust
567     /// use byteorder::{ByteOrder, LittleEndian};
568     ///
569     /// let mut buf = [0; 3];
570     /// LittleEndian::write_i24(&mut buf, -1_000_000);
571     /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf));
572     /// ```
573     #[inline]
read_i24(buf: &[u8]) -> i32574     fn read_i24(buf: &[u8]) -> i32 {
575         Self::read_int(buf, 3) as i32
576     }
577 
578     /// Reads a signed 32 bit integer from `buf`.
579     ///
580     /// # Panics
581     ///
582     /// Panics when `buf.len() < 4`.
583     ///
584     /// # Examples
585     ///
586     /// Write and read `i32` numbers in little endian order:
587     ///
588     /// ```rust
589     /// use byteorder::{ByteOrder, LittleEndian};
590     ///
591     /// let mut buf = [0; 4];
592     /// LittleEndian::write_i32(&mut buf, -1_000_000);
593     /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf));
594     /// ```
595     #[inline]
read_i32(buf: &[u8]) -> i32596     fn read_i32(buf: &[u8]) -> i32 {
597         Self::read_u32(buf) as i32
598     }
599 
600     /// Reads a signed 48 bit integer from `buf`, stored in i64.
601     ///
602     /// # Panics
603     ///
604     /// Panics when `buf.len() < 6`.
605     ///
606     /// # Examples
607     ///
608     /// Write and read 48 bit `i64` numbers in little endian order:
609     ///
610     /// ```rust
611     /// use byteorder::{ByteOrder, LittleEndian};
612     ///
613     /// let mut buf = [0; 6];
614     /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000);
615     /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf));
616     /// ```
617     #[inline]
read_i48(buf: &[u8]) -> i64618     fn read_i48(buf: &[u8]) -> i64 {
619         Self::read_int(buf, 6) as i64
620     }
621 
622     /// Reads a signed 64 bit integer from `buf`.
623     ///
624     /// # Panics
625     ///
626     /// Panics when `buf.len() < 8`.
627     ///
628     /// # Examples
629     ///
630     /// Write and read `i64` numbers in little endian order:
631     ///
632     /// ```rust
633     /// use byteorder::{ByteOrder, LittleEndian};
634     ///
635     /// let mut buf = [0; 8];
636     /// LittleEndian::write_i64(&mut buf, -1_000_000_000);
637     /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf));
638     /// ```
639     #[inline]
read_i64(buf: &[u8]) -> i64640     fn read_i64(buf: &[u8]) -> i64 {
641         Self::read_u64(buf) as i64
642     }
643 
644     /// Reads a signed 128 bit integer from `buf`.
645     ///
646     /// # Panics
647     ///
648     /// Panics when `buf.len() < 16`.
649     ///
650     /// # Examples
651     ///
652     /// Write and read `i128` numbers in little endian order:
653     ///
654     /// ```rust
655     /// use byteorder::{ByteOrder, LittleEndian};
656     ///
657     /// let mut buf = [0; 16];
658     /// LittleEndian::write_i128(&mut buf, -1_000_000_000);
659     /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf));
660     /// ```
661     #[cfg(byteorder_i128)]
662     #[inline]
read_i128(buf: &[u8]) -> i128663     fn read_i128(buf: &[u8]) -> i128 {
664         Self::read_u128(buf) as i128
665     }
666 
667     /// Reads a signed n-bytes integer from `buf`.
668     ///
669     /// # Panics
670     ///
671     /// Panics when `nbytes < 1` or `nbytes > 8` or
672     /// `buf.len() < nbytes`
673     ///
674     /// # Examples
675     ///
676     /// Write and read n-length signed numbers in little endian order:
677     ///
678     /// ```rust
679     /// use byteorder::{ByteOrder, LittleEndian};
680     ///
681     /// let mut buf = [0; 3];
682     /// LittleEndian::write_int(&mut buf, -1_000, 3);
683     /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3));
684     /// ```
685     #[inline]
read_int(buf: &[u8], nbytes: usize) -> i64686     fn read_int(buf: &[u8], nbytes: usize) -> i64 {
687         extend_sign(Self::read_uint(buf, nbytes), nbytes)
688     }
689 
690     /// Reads a signed n-bytes integer from `buf`.
691     ///
692     /// # Panics
693     ///
694     /// Panics when `nbytes < 1` or `nbytes > 16` or
695     /// `buf.len() < nbytes`
696     ///
697     /// # Examples
698     ///
699     /// Write and read n-length signed numbers in little endian order:
700     ///
701     /// ```rust
702     /// use byteorder::{ByteOrder, LittleEndian};
703     ///
704     /// let mut buf = [0; 3];
705     /// LittleEndian::write_int128(&mut buf, -1_000, 3);
706     /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3));
707     /// ```
708     #[cfg(byteorder_i128)]
709     #[inline]
read_int128(buf: &[u8], nbytes: usize) -> i128710     fn read_int128(buf: &[u8], nbytes: usize) -> i128 {
711         extend_sign128(Self::read_uint128(buf, nbytes), nbytes)
712     }
713 
714     /// Reads a IEEE754 single-precision (4 bytes) floating point number.
715     ///
716     /// # Panics
717     ///
718     /// Panics when `buf.len() < 4`.
719     ///
720     /// # Examples
721     ///
722     /// Write and read `f32` numbers in little endian order:
723     ///
724     /// ```rust
725     /// use byteorder::{ByteOrder, LittleEndian};
726     ///
727     /// let e = 2.71828;
728     /// let mut buf = [0; 4];
729     /// LittleEndian::write_f32(&mut buf, e);
730     /// assert_eq!(e, LittleEndian::read_f32(&buf));
731     /// ```
732     #[inline]
read_f32(buf: &[u8]) -> f32733     fn read_f32(buf: &[u8]) -> f32 {
734         unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) }
735     }
736 
737     /// Reads a IEEE754 double-precision (8 bytes) floating point number.
738     ///
739     /// # Panics
740     ///
741     /// Panics when `buf.len() < 8`.
742     ///
743     /// # Examples
744     ///
745     /// Write and read `f64` numbers in little endian order:
746     ///
747     /// ```rust
748     /// use byteorder::{ByteOrder, LittleEndian};
749     ///
750     /// let phi = 1.6180339887;
751     /// let mut buf = [0; 8];
752     /// LittleEndian::write_f64(&mut buf, phi);
753     /// assert_eq!(phi, LittleEndian::read_f64(&buf));
754     /// ```
755     #[inline]
read_f64(buf: &[u8]) -> f64756     fn read_f64(buf: &[u8]) -> f64 {
757         unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) }
758     }
759 
760     /// Writes a signed 16 bit integer `n` to `buf`.
761     ///
762     /// # Panics
763     ///
764     /// Panics when `buf.len() < 2`.
765     ///
766     /// # Examples
767     ///
768     /// Write and read `i16` numbers in little endian order:
769     ///
770     /// ```rust
771     /// use byteorder::{ByteOrder, LittleEndian};
772     ///
773     /// let mut buf = [0; 2];
774     /// LittleEndian::write_i16(&mut buf, -1_000);
775     /// assert_eq!(-1_000, LittleEndian::read_i16(&buf));
776     /// ```
777     #[inline]
write_i16(buf: &mut [u8], n: i16)778     fn write_i16(buf: &mut [u8], n: i16) {
779         Self::write_u16(buf, n as u16)
780     }
781 
782     /// Writes a signed 24 bit integer `n` to `buf`, stored in i32.
783     ///
784     /// # Panics
785     ///
786     /// Panics when `buf.len() < 3`.
787     ///
788     /// # Examples
789     ///
790     /// Write and read 24 bit `i32` numbers in little endian order:
791     ///
792     /// ```rust
793     /// use byteorder::{ByteOrder, LittleEndian};
794     ///
795     /// let mut buf = [0; 3];
796     /// LittleEndian::write_i24(&mut buf, -1_000_000);
797     /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf));
798     /// ```
799     #[inline]
write_i24(buf: &mut [u8], n: i32)800     fn write_i24(buf: &mut [u8], n: i32) {
801         Self::write_int(buf, n as i64, 3)
802     }
803 
804     /// Writes a signed 32 bit integer `n` to `buf`.
805     ///
806     /// # Panics
807     ///
808     /// Panics when `buf.len() < 4`.
809     ///
810     /// # Examples
811     ///
812     /// Write and read `i32` numbers in little endian order:
813     ///
814     /// ```rust
815     /// use byteorder::{ByteOrder, LittleEndian};
816     ///
817     /// let mut buf = [0; 4];
818     /// LittleEndian::write_i32(&mut buf, -1_000_000);
819     /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf));
820     /// ```
821     #[inline]
write_i32(buf: &mut [u8], n: i32)822     fn write_i32(buf: &mut [u8], n: i32) {
823         Self::write_u32(buf, n as u32)
824     }
825 
826     /// Writes a signed 48 bit integer `n` to `buf`, stored in i64.
827     ///
828     /// # Panics
829     ///
830     /// Panics when `buf.len() < 6`.
831     ///
832     /// # Examples
833     ///
834     /// Write and read 48 bit `i64` numbers in little endian order:
835     ///
836     /// ```rust
837     /// use byteorder::{ByteOrder, LittleEndian};
838     ///
839     /// let mut buf = [0; 6];
840     /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000);
841     /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf));
842     /// ```
843     #[inline]
write_i48(buf: &mut [u8], n: i64)844     fn write_i48(buf: &mut [u8], n: i64) {
845         Self::write_int(buf, n as i64, 6)
846     }
847 
848     /// Writes a signed 64 bit integer `n` to `buf`.
849     ///
850     /// # Panics
851     ///
852     /// Panics when `buf.len() < 8`.
853     ///
854     /// # Examples
855     ///
856     /// Write and read `i64` numbers in little endian order:
857     ///
858     /// ```rust
859     /// use byteorder::{ByteOrder, LittleEndian};
860     ///
861     /// let mut buf = [0; 8];
862     /// LittleEndian::write_i64(&mut buf, -1_000_000_000);
863     /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf));
864     /// ```
865     #[inline]
write_i64(buf: &mut [u8], n: i64)866     fn write_i64(buf: &mut [u8], n: i64) {
867         Self::write_u64(buf, n as u64)
868     }
869 
870     /// Writes a signed 128 bit integer `n` to `buf`.
871     ///
872     /// # Panics
873     ///
874     /// Panics when `buf.len() < 16`.
875     ///
876     /// # Examples
877     ///
878     /// Write and read n-byte `i128` numbers in little endian order:
879     ///
880     /// ```rust
881     /// use byteorder::{ByteOrder, LittleEndian};
882     ///
883     /// let mut buf = [0; 16];
884     /// LittleEndian::write_i128(&mut buf, -1_000_000_000);
885     /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf));
886     /// ```
887     #[cfg(byteorder_i128)]
888     #[inline]
write_i128(buf: &mut [u8], n: i128)889     fn write_i128(buf: &mut [u8], n: i128) {
890         Self::write_u128(buf, n as u128)
891     }
892 
893     /// Writes a signed integer `n` to `buf` using only `nbytes`.
894     ///
895     /// # Panics
896     ///
897     /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
898     /// this method panics.
899     ///
900     /// # Examples
901     ///
902     /// Write and read an n-byte number in little endian order:
903     ///
904     /// ```rust
905     /// use byteorder::{ByteOrder, LittleEndian};
906     ///
907     /// let mut buf = [0; 3];
908     /// LittleEndian::write_int(&mut buf, -1_000, 3);
909     /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3));
910     /// ```
911     #[inline]
write_int(buf: &mut [u8], n: i64, nbytes: usize)912     fn write_int(buf: &mut [u8], n: i64, nbytes: usize) {
913         Self::write_uint(buf, unextend_sign(n, nbytes), nbytes)
914     }
915 
916     /// Writes a signed integer `n` to `buf` using only `nbytes`.
917     ///
918     /// # Panics
919     ///
920     /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then
921     /// this method panics.
922     ///
923     /// # Examples
924     ///
925     /// Write and read n-length signed numbers in little endian order:
926     ///
927     /// ```rust
928     /// use byteorder::{ByteOrder, LittleEndian};
929     ///
930     /// let mut buf = [0; 3];
931     /// LittleEndian::write_int128(&mut buf, -1_000, 3);
932     /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3));
933     /// ```
934     #[cfg(byteorder_i128)]
935     #[inline]
write_int128(buf: &mut [u8], n: i128, nbytes: usize)936     fn write_int128(buf: &mut [u8], n: i128, nbytes: usize) {
937         Self::write_uint128(buf, unextend_sign128(n, nbytes), nbytes)
938     }
939 
940     /// Writes a IEEE754 single-precision (4 bytes) floating point number.
941     ///
942     /// # Panics
943     ///
944     /// Panics when `buf.len() < 4`.
945     ///
946     /// # Examples
947     ///
948     /// Write and read `f32` numbers in little endian order:
949     ///
950     /// ```rust
951     /// use byteorder::{ByteOrder, LittleEndian};
952     ///
953     /// let e = 2.71828;
954     /// let mut buf = [0; 4];
955     /// LittleEndian::write_f32(&mut buf, e);
956     /// assert_eq!(e, LittleEndian::read_f32(&buf));
957     /// ```
958     #[inline]
write_f32(buf: &mut [u8], n: f32)959     fn write_f32(buf: &mut [u8], n: f32) {
960         let n = unsafe { *(&n as *const f32 as *const u32) };
961         Self::write_u32(buf, n)
962     }
963 
964     /// Writes a IEEE754 double-precision (8 bytes) floating point number.
965     ///
966     /// # Panics
967     ///
968     /// Panics when `buf.len() < 8`.
969     ///
970     /// # Examples
971     ///
972     /// Write and read `f64` numbers in little endian order:
973     ///
974     /// ```rust
975     /// use byteorder::{ByteOrder, LittleEndian};
976     ///
977     /// let phi = 1.6180339887;
978     /// let mut buf = [0; 8];
979     /// LittleEndian::write_f64(&mut buf, phi);
980     /// assert_eq!(phi, LittleEndian::read_f64(&buf));
981     /// ```
982     #[inline]
write_f64(buf: &mut [u8], n: f64)983     fn write_f64(buf: &mut [u8], n: f64) {
984         let n = unsafe { *(&n as *const f64 as *const u64) };
985         Self::write_u64(buf, n)
986     }
987 
988     /// Reads unsigned 16 bit integers from `src` into `dst`.
989     ///
990     /// # Panics
991     ///
992     /// Panics when `src.len() != 2*dst.len()`.
993     ///
994     /// # Examples
995     ///
996     /// Write and read `u16` numbers in little endian order:
997     ///
998     /// ```rust
999     /// use byteorder::{ByteOrder, LittleEndian};
1000     ///
1001     /// let mut bytes = [0; 8];
1002     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1003     /// LittleEndian::write_u16_into(&numbers_given, &mut bytes);
1004     ///
1005     /// let mut numbers_got = [0; 4];
1006     /// LittleEndian::read_u16_into(&bytes, &mut numbers_got);
1007     /// assert_eq!(numbers_given, numbers_got);
1008     /// ```
read_u16_into(src: &[u8], dst: &mut [u16])1009     fn read_u16_into(src: &[u8], dst: &mut [u16]);
1010 
1011     /// Reads unsigned 32 bit integers from `src` into `dst`.
1012     ///
1013     /// # Panics
1014     ///
1015     /// Panics when `src.len() != 4*dst.len()`.
1016     ///
1017     /// # Examples
1018     ///
1019     /// Write and read `u32` numbers in little endian order:
1020     ///
1021     /// ```rust
1022     /// use byteorder::{ByteOrder, LittleEndian};
1023     ///
1024     /// let mut bytes = [0; 16];
1025     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1026     /// LittleEndian::write_u32_into(&numbers_given, &mut bytes);
1027     ///
1028     /// let mut numbers_got = [0; 4];
1029     /// LittleEndian::read_u32_into(&bytes, &mut numbers_got);
1030     /// assert_eq!(numbers_given, numbers_got);
1031     /// ```
read_u32_into(src: &[u8], dst: &mut [u32])1032     fn read_u32_into(src: &[u8], dst: &mut [u32]);
1033 
1034     /// Reads unsigned 64 bit integers from `src` into `dst`.
1035     ///
1036     /// # Panics
1037     ///
1038     /// Panics when `src.len() != 8*dst.len()`.
1039     ///
1040     /// # Examples
1041     ///
1042     /// Write and read `u64` numbers in little endian order:
1043     ///
1044     /// ```rust
1045     /// use byteorder::{ByteOrder, LittleEndian};
1046     ///
1047     /// let mut bytes = [0; 32];
1048     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1049     /// LittleEndian::write_u64_into(&numbers_given, &mut bytes);
1050     ///
1051     /// let mut numbers_got = [0; 4];
1052     /// LittleEndian::read_u64_into(&bytes, &mut numbers_got);
1053     /// assert_eq!(numbers_given, numbers_got);
1054     /// ```
read_u64_into(src: &[u8], dst: &mut [u64])1055     fn read_u64_into(src: &[u8], dst: &mut [u64]);
1056 
1057     /// Reads unsigned 128 bit integers from `src` into `dst`.
1058     ///
1059     /// # Panics
1060     ///
1061     /// Panics when `src.len() != 16*dst.len()`.
1062     ///
1063     /// # Examples
1064     ///
1065     /// Write and read `u128` numbers in little endian order:
1066     ///
1067     /// ```rust
1068     /// use byteorder::{ByteOrder, LittleEndian};
1069     ///
1070     /// let mut bytes = [0; 64];
1071     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1072     /// LittleEndian::write_u128_into(&numbers_given, &mut bytes);
1073     ///
1074     /// let mut numbers_got = [0; 4];
1075     /// LittleEndian::read_u128_into(&bytes, &mut numbers_got);
1076     /// assert_eq!(numbers_given, numbers_got);
1077     /// ```
1078     #[cfg(byteorder_i128)]
read_u128_into(src: &[u8], dst: &mut [u128])1079     fn read_u128_into(src: &[u8], dst: &mut [u128]);
1080 
1081     /// Reads signed 16 bit integers from `src` to `dst`.
1082     ///
1083     /// # Panics
1084     ///
1085     /// Panics when `buf.len() != 2*dst.len()`.
1086     ///
1087     /// # Examples
1088     ///
1089     /// Write and read `i16` numbers in little endian order:
1090     ///
1091     /// ```rust
1092     /// use byteorder::{ByteOrder, LittleEndian};
1093     ///
1094     /// let mut bytes = [0; 8];
1095     /// let numbers_given = [1, 2, 0x0f, 0xee];
1096     /// LittleEndian::write_i16_into(&numbers_given, &mut bytes);
1097     ///
1098     /// let mut numbers_got = [0; 4];
1099     /// LittleEndian::read_i16_into(&bytes, &mut numbers_got);
1100     /// assert_eq!(numbers_given, numbers_got);
1101     /// ```
1102     #[inline]
read_i16_into(src: &[u8], dst: &mut [i16])1103     fn read_i16_into(src: &[u8], dst: &mut [i16]) {
1104         let dst = unsafe {
1105             slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u16, dst.len())
1106         };
1107         Self::read_u16_into(src, dst)
1108     }
1109 
1110     /// Reads signed 32 bit integers from `src` into `dst`.
1111     ///
1112     /// # Panics
1113     ///
1114     /// Panics when `src.len() != 4*dst.len()`.
1115     ///
1116     /// # Examples
1117     ///
1118     /// Write and read `i32` numbers in little endian order:
1119     ///
1120     /// ```rust
1121     /// use byteorder::{ByteOrder, LittleEndian};
1122     ///
1123     /// let mut bytes = [0; 16];
1124     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1125     /// LittleEndian::write_i32_into(&numbers_given, &mut bytes);
1126     ///
1127     /// let mut numbers_got = [0; 4];
1128     /// LittleEndian::read_i32_into(&bytes, &mut numbers_got);
1129     /// assert_eq!(numbers_given, numbers_got);
1130     /// ```
1131     #[inline]
read_i32_into(src: &[u8], dst: &mut [i32])1132     fn read_i32_into(src: &[u8], dst: &mut [i32]) {
1133         let dst = unsafe {
1134             slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
1135         };
1136         Self::read_u32_into(src, dst);
1137     }
1138 
1139     /// Reads signed 64 bit integers from `src` into `dst`.
1140     ///
1141     /// # Panics
1142     ///
1143     /// Panics when `src.len() != 8*dst.len()`.
1144     ///
1145     /// # Examples
1146     ///
1147     /// Write and read `i64` numbers in little endian order:
1148     ///
1149     /// ```rust
1150     /// use byteorder::{ByteOrder, LittleEndian};
1151     ///
1152     /// let mut bytes = [0; 32];
1153     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1154     /// LittleEndian::write_i64_into(&numbers_given, &mut bytes);
1155     ///
1156     /// let mut numbers_got = [0; 4];
1157     /// LittleEndian::read_i64_into(&bytes, &mut numbers_got);
1158     /// assert_eq!(numbers_given, numbers_got);
1159     /// ```
1160     #[inline]
read_i64_into(src: &[u8], dst: &mut [i64])1161     fn read_i64_into(src: &[u8], dst: &mut [i64]) {
1162         let dst = unsafe {
1163             slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
1164         };
1165         Self::read_u64_into(src, dst);
1166     }
1167 
1168     /// Reads signed 128 bit integers from `src` into `dst`.
1169     ///
1170     /// # Panics
1171     ///
1172     /// Panics when `src.len() != 16*dst.len()`.
1173     ///
1174     /// # Examples
1175     ///
1176     /// Write and read `i128` numbers in little endian order:
1177     ///
1178     /// ```rust
1179     /// use byteorder::{ByteOrder, LittleEndian};
1180     ///
1181     /// let mut bytes = [0; 64];
1182     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1183     /// LittleEndian::write_i128_into(&numbers_given, &mut bytes);
1184     ///
1185     /// let mut numbers_got = [0; 4];
1186     /// LittleEndian::read_i128_into(&bytes, &mut numbers_got);
1187     /// assert_eq!(numbers_given, numbers_got);
1188     /// ```
1189     #[cfg(byteorder_i128)]
1190     #[inline]
read_i128_into(src: &[u8], dst: &mut [i128])1191     fn read_i128_into(src: &[u8], dst: &mut [i128]) {
1192         let dst = unsafe {
1193             slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u128, dst.len())
1194         };
1195         Self::read_u128_into(src, dst);
1196     }
1197 
1198     /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
1199     /// `src` into `dst`.
1200     ///
1201     /// # Panics
1202     ///
1203     /// Panics when `src.len() != 4*dst.len()`.
1204     ///
1205     /// # Examples
1206     ///
1207     /// Write and read `f32` numbers in little endian order:
1208     ///
1209     /// ```rust
1210     /// use byteorder::{ByteOrder, LittleEndian};
1211     ///
1212     /// let mut bytes = [0; 16];
1213     /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
1214     /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
1215     ///
1216     /// let mut numbers_got = [0.0; 4];
1217     /// LittleEndian::read_f32_into(&bytes, &mut numbers_got);
1218     /// assert_eq!(numbers_given, numbers_got);
1219     /// ```
1220     #[inline]
read_f32_into(src: &[u8], dst: &mut [f32])1221     fn read_f32_into(src: &[u8], dst: &mut [f32]) {
1222         let dst = unsafe {
1223             slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
1224         };
1225         Self::read_u32_into(src, dst);
1226     }
1227 
1228     /// **DEPRECATED**.
1229     ///
1230     /// This method is deprecated. Use `read_f32_into` instead.
1231     /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
1232     /// `src` into `dst`.
1233     ///
1234     /// # Panics
1235     ///
1236     /// Panics when `src.len() != 4*dst.len()`.
1237     ///
1238     /// # Examples
1239     ///
1240     /// Write and read `f32` numbers in little endian order:
1241     ///
1242     /// ```rust
1243     /// use byteorder::{ByteOrder, LittleEndian};
1244     ///
1245     /// let mut bytes = [0; 16];
1246     /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
1247     /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
1248     ///
1249     /// let mut numbers_got = [0.0; 4];
1250     /// LittleEndian::read_f32_into_unchecked(&bytes, &mut numbers_got);
1251     /// assert_eq!(numbers_given, numbers_got);
1252     /// ```
1253     #[inline]
1254     #[deprecated(since="1.3.0", note="please use `read_f32_into` instead")]
read_f32_into_unchecked(src: &[u8], dst: &mut [f32])1255     fn read_f32_into_unchecked(src: &[u8], dst: &mut [f32]) {
1256         Self::read_f32_into(src, dst);
1257     }
1258 
1259     /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
1260     /// `src` into `dst`.
1261     ///
1262     /// # Panics
1263     ///
1264     /// Panics when `src.len() != 8*dst.len()`.
1265     ///
1266     /// # Examples
1267     ///
1268     /// Write and read `f64` numbers in little endian order:
1269     ///
1270     /// ```rust
1271     /// use byteorder::{ByteOrder, LittleEndian};
1272     ///
1273     /// let mut bytes = [0; 32];
1274     /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
1275     /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
1276     ///
1277     /// let mut numbers_got = [0.0; 4];
1278     /// LittleEndian::read_f64_into(&bytes, &mut numbers_got);
1279     /// assert_eq!(numbers_given, numbers_got);
1280     /// ```
1281     #[inline]
read_f64_into(src: &[u8], dst: &mut [f64])1282     fn read_f64_into(src: &[u8], dst: &mut [f64]) {
1283         let dst = unsafe {
1284             slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
1285         };
1286         Self::read_u64_into(src, dst);
1287     }
1288 
1289     /// **DEPRECATED**.
1290     ///
1291     /// This method is deprecated. Use `read_f64_into` instead.
1292     ///
1293     /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
1294     /// `src` into `dst`.
1295     ///
1296     /// # Panics
1297     ///
1298     /// Panics when `src.len() != 8*dst.len()`.
1299     ///
1300     /// # Examples
1301     ///
1302     /// Write and read `f64` numbers in little endian order:
1303     ///
1304     /// ```rust
1305     /// use byteorder::{ByteOrder, LittleEndian};
1306     ///
1307     /// let mut bytes = [0; 32];
1308     /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
1309     /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
1310     ///
1311     /// let mut numbers_got = [0.0; 4];
1312     /// LittleEndian::read_f64_into_unchecked(&bytes, &mut numbers_got);
1313     /// assert_eq!(numbers_given, numbers_got);
1314     /// ```
1315     #[inline]
1316     #[deprecated(since="1.3.0", note="please use `read_f64_into` instead")]
read_f64_into_unchecked(src: &[u8], dst: &mut [f64])1317     fn read_f64_into_unchecked(src: &[u8], dst: &mut [f64]) {
1318         Self::read_f64_into(src, dst);
1319     }
1320 
1321     /// Writes unsigned 16 bit integers from `src` into `dst`.
1322     ///
1323     /// # Panics
1324     ///
1325     /// Panics when `dst.len() != 2*src.len()`.
1326     ///
1327     /// # Examples
1328     ///
1329     /// Write and read `u16` numbers in little endian order:
1330     ///
1331     /// ```rust
1332     /// use byteorder::{ByteOrder, LittleEndian};
1333     ///
1334     /// let mut bytes = [0; 8];
1335     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1336     /// LittleEndian::write_u16_into(&numbers_given, &mut bytes);
1337     ///
1338     /// let mut numbers_got = [0; 4];
1339     /// LittleEndian::read_u16_into(&bytes, &mut numbers_got);
1340     /// assert_eq!(numbers_given, numbers_got);
1341     /// ```
write_u16_into(src: &[u16], dst: &mut [u8])1342     fn write_u16_into(src: &[u16], dst: &mut [u8]);
1343 
1344     /// Writes unsigned 32 bit integers from `src` into `dst`.
1345     ///
1346     /// # Panics
1347     ///
1348     /// Panics when `dst.len() != 4*src.len()`.
1349     ///
1350     /// # Examples
1351     ///
1352     /// Write and read `u32` numbers in little endian order:
1353     ///
1354     /// ```rust
1355     /// use byteorder::{ByteOrder, LittleEndian};
1356     ///
1357     /// let mut bytes = [0; 16];
1358     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1359     /// LittleEndian::write_u32_into(&numbers_given, &mut bytes);
1360     ///
1361     /// let mut numbers_got = [0; 4];
1362     /// LittleEndian::read_u32_into(&bytes, &mut numbers_got);
1363     /// assert_eq!(numbers_given, numbers_got);
1364     /// ```
write_u32_into(src: &[u32], dst: &mut [u8])1365     fn write_u32_into(src: &[u32], dst: &mut [u8]);
1366 
1367     /// Writes unsigned 64 bit integers from `src` into `dst`.
1368     ///
1369     /// # Panics
1370     ///
1371     /// Panics when `dst.len() != 8*src.len()`.
1372     ///
1373     /// # Examples
1374     ///
1375     /// Write and read `u64` numbers in little endian order:
1376     ///
1377     /// ```rust
1378     /// use byteorder::{ByteOrder, LittleEndian};
1379     ///
1380     /// let mut bytes = [0; 32];
1381     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1382     /// LittleEndian::write_u64_into(&numbers_given, &mut bytes);
1383     ///
1384     /// let mut numbers_got = [0; 4];
1385     /// LittleEndian::read_u64_into(&bytes, &mut numbers_got);
1386     /// assert_eq!(numbers_given, numbers_got);
1387     /// ```
write_u64_into(src: &[u64], dst: &mut [u8])1388     fn write_u64_into(src: &[u64], dst: &mut [u8]);
1389 
1390     /// Writes unsigned 128 bit integers from `src` into `dst`.
1391     ///
1392     /// # Panics
1393     ///
1394     /// Panics when `dst.len() != 16*src.len()`.
1395     ///
1396     /// # Examples
1397     ///
1398     /// Write and read `u128` numbers in little endian order:
1399     ///
1400     /// ```rust
1401     /// use byteorder::{ByteOrder, LittleEndian};
1402     ///
1403     /// let mut bytes = [0; 64];
1404     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1405     /// LittleEndian::write_u128_into(&numbers_given, &mut bytes);
1406     ///
1407     /// let mut numbers_got = [0; 4];
1408     /// LittleEndian::read_u128_into(&bytes, &mut numbers_got);
1409     /// assert_eq!(numbers_given, numbers_got);
1410     /// ```
1411     #[cfg(byteorder_i128)]
write_u128_into(src: &[u128], dst: &mut [u8])1412     fn write_u128_into(src: &[u128], dst: &mut [u8]);
1413 
1414     /// Writes signed 16 bit integers from `src` into `dst`.
1415     ///
1416     /// # Panics
1417     ///
1418     /// Panics when `buf.len() != 2*src.len()`.
1419     ///
1420     /// # Examples
1421     ///
1422     /// Write and read `i16` numbers in little endian order:
1423     ///
1424     /// ```rust
1425     /// use byteorder::{ByteOrder, LittleEndian};
1426     ///
1427     /// let mut bytes = [0; 8];
1428     /// let numbers_given = [1, 2, 0x0f, 0xee];
1429     /// LittleEndian::write_i16_into(&numbers_given, &mut bytes);
1430     ///
1431     /// let mut numbers_got = [0; 4];
1432     /// LittleEndian::read_i16_into(&bytes, &mut numbers_got);
1433     /// assert_eq!(numbers_given, numbers_got);
1434     /// ```
write_i16_into(src: &[i16], dst: &mut [u8])1435     fn write_i16_into(src: &[i16], dst: &mut [u8]) {
1436         let src = unsafe {
1437             slice::from_raw_parts(src.as_ptr() as *const u16, src.len())
1438         };
1439         Self::write_u16_into(src, dst);
1440     }
1441 
1442     /// Writes signed 32 bit integers from `src` into `dst`.
1443     ///
1444     /// # Panics
1445     ///
1446     /// Panics when `dst.len() != 4*src.len()`.
1447     ///
1448     /// # Examples
1449     ///
1450     /// Write and read `i32` numbers in little endian order:
1451     ///
1452     /// ```rust
1453     /// use byteorder::{ByteOrder, LittleEndian};
1454     ///
1455     /// let mut bytes = [0; 16];
1456     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1457     /// LittleEndian::write_i32_into(&numbers_given, &mut bytes);
1458     ///
1459     /// let mut numbers_got = [0; 4];
1460     /// LittleEndian::read_i32_into(&bytes, &mut numbers_got);
1461     /// assert_eq!(numbers_given, numbers_got);
1462     /// ```
write_i32_into(src: &[i32], dst: &mut [u8])1463     fn write_i32_into(src: &[i32], dst: &mut [u8]) {
1464         let src = unsafe {
1465             slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
1466         };
1467         Self::write_u32_into(src, dst);
1468     }
1469 
1470     /// Writes signed 64 bit integers from `src` into `dst`.
1471     ///
1472     /// # Panics
1473     ///
1474     /// Panics when `dst.len() != 8*src.len()`.
1475     ///
1476     /// # Examples
1477     ///
1478     /// Write and read `i64` numbers in little endian order:
1479     ///
1480     /// ```rust
1481     /// use byteorder::{ByteOrder, LittleEndian};
1482     ///
1483     /// let mut bytes = [0; 32];
1484     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1485     /// LittleEndian::write_i64_into(&numbers_given, &mut bytes);
1486     ///
1487     /// let mut numbers_got = [0; 4];
1488     /// LittleEndian::read_i64_into(&bytes, &mut numbers_got);
1489     /// assert_eq!(numbers_given, numbers_got);
1490     /// ```
write_i64_into(src: &[i64], dst: &mut [u8])1491     fn write_i64_into(src: &[i64], dst: &mut [u8]) {
1492         let src = unsafe {
1493             slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
1494         };
1495         Self::write_u64_into(src, dst);
1496     }
1497 
1498     /// Writes signed 128 bit integers from `src` into `dst`.
1499     ///
1500     /// # Panics
1501     ///
1502     /// Panics when `dst.len() != 16*src.len()`.
1503     ///
1504     /// # Examples
1505     ///
1506     /// Write and read `i128` numbers in little endian order:
1507     ///
1508     /// ```rust
1509     /// use byteorder::{ByteOrder, LittleEndian};
1510     ///
1511     /// let mut bytes = [0; 64];
1512     /// let numbers_given = [1, 2, 0xf00f, 0xffee];
1513     /// LittleEndian::write_i128_into(&numbers_given, &mut bytes);
1514     ///
1515     /// let mut numbers_got = [0; 4];
1516     /// LittleEndian::read_i128_into(&bytes, &mut numbers_got);
1517     /// assert_eq!(numbers_given, numbers_got);
1518     /// ```
1519     #[cfg(byteorder_i128)]
write_i128_into(src: &[i128], dst: &mut [u8])1520     fn write_i128_into(src: &[i128], dst: &mut [u8]) {
1521         let src = unsafe {
1522             slice::from_raw_parts(src.as_ptr() as *const u128, src.len())
1523         };
1524         Self::write_u128_into(src, dst);
1525     }
1526 
1527     /// Writes IEEE754 single-precision (4 bytes) floating point numbers from
1528     /// `src` into `dst`.
1529     ///
1530     /// # Panics
1531     ///
1532     /// Panics when `src.len() != 4*dst.len()`.
1533     ///
1534     /// # Examples
1535     ///
1536     /// Write and read `f32` numbers in little endian order:
1537     ///
1538     /// ```rust
1539     /// use byteorder::{ByteOrder, LittleEndian};
1540     ///
1541     /// let mut bytes = [0; 16];
1542     /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
1543     /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
1544     ///
1545     /// let mut numbers_got = [0.0; 4];
1546     /// unsafe {
1547     ///     LittleEndian::read_f32_into(&bytes, &mut numbers_got);
1548     /// }
1549     /// assert_eq!(numbers_given, numbers_got);
1550     /// ```
write_f32_into(src: &[f32], dst: &mut [u8])1551     fn write_f32_into(src: &[f32], dst: &mut [u8]) {
1552         let src = unsafe {
1553             slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
1554         };
1555         Self::write_u32_into(src, dst);
1556     }
1557 
1558     /// Writes IEEE754 double-precision (8 bytes) floating point numbers from
1559     /// `src` into `dst`.
1560     ///
1561     /// # Panics
1562     ///
1563     /// Panics when `src.len() != 8*dst.len()`.
1564     ///
1565     /// # Examples
1566     ///
1567     /// Write and read `f64` numbers in little endian order:
1568     ///
1569     /// ```rust
1570     /// use byteorder::{ByteOrder, LittleEndian};
1571     ///
1572     /// let mut bytes = [0; 32];
1573     /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
1574     /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
1575     ///
1576     /// let mut numbers_got = [0.0; 4];
1577     /// unsafe {
1578     ///     LittleEndian::read_f64_into(&bytes, &mut numbers_got);
1579     /// }
1580     /// assert_eq!(numbers_given, numbers_got);
1581     /// ```
write_f64_into(src: &[f64], dst: &mut [u8])1582     fn write_f64_into(src: &[f64], dst: &mut [u8]) {
1583         let src = unsafe {
1584             slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
1585         };
1586         Self::write_u64_into(src, dst);
1587     }
1588 
1589     /// Converts the given slice of unsigned 16 bit integers to a particular
1590     /// endianness.
1591     ///
1592     /// If the endianness matches the endianness of the host platform, then
1593     /// this is a no-op.
1594     ///
1595     /// # Examples
1596     ///
1597     /// Convert the host platform's endianness to big-endian:
1598     ///
1599     /// ```rust
1600     /// use byteorder::{ByteOrder, BigEndian};
1601     ///
1602     /// let mut numbers = [5, 65000];
1603     /// BigEndian::from_slice_u16(&mut numbers);
1604     /// assert_eq!(numbers, [5u16.to_be(), 65000u16.to_be()]);
1605     /// ```
from_slice_u16(numbers: &mut [u16])1606     fn from_slice_u16(numbers: &mut [u16]);
1607 
1608     /// Converts the given slice of unsigned 32 bit integers to a particular
1609     /// endianness.
1610     ///
1611     /// If the endianness matches the endianness of the host platform, then
1612     /// this is a no-op.
1613     ///
1614     /// # Examples
1615     ///
1616     /// Convert the host platform's endianness to big-endian:
1617     ///
1618     /// ```rust
1619     /// use byteorder::{ByteOrder, BigEndian};
1620     ///
1621     /// let mut numbers = [5, 65000];
1622     /// BigEndian::from_slice_u32(&mut numbers);
1623     /// assert_eq!(numbers, [5u32.to_be(), 65000u32.to_be()]);
1624     /// ```
from_slice_u32(numbers: &mut [u32])1625     fn from_slice_u32(numbers: &mut [u32]);
1626 
1627     /// Converts the given slice of unsigned 64 bit integers to a particular
1628     /// endianness.
1629     ///
1630     /// If the endianness matches the endianness of the host platform, then
1631     /// this is a no-op.
1632     ///
1633     /// # Examples
1634     ///
1635     /// Convert the host platform's endianness to big-endian:
1636     ///
1637     /// ```rust
1638     /// use byteorder::{ByteOrder, BigEndian};
1639     ///
1640     /// let mut numbers = [5, 65000];
1641     /// BigEndian::from_slice_u64(&mut numbers);
1642     /// assert_eq!(numbers, [5u64.to_be(), 65000u64.to_be()]);
1643     /// ```
from_slice_u64(numbers: &mut [u64])1644     fn from_slice_u64(numbers: &mut [u64]);
1645 
1646     /// Converts the given slice of unsigned 128 bit integers to a particular
1647     /// endianness.
1648     ///
1649     /// If the endianness matches the endianness of the host platform, then
1650     /// this is a no-op.
1651     ///
1652     /// # Examples
1653     ///
1654     /// Convert the host platform's endianness to big-endian:
1655     ///
1656     /// ```rust
1657     /// use byteorder::{ByteOrder, BigEndian};
1658     ///
1659     /// let mut numbers = [5, 65000];
1660     /// BigEndian::from_slice_u128(&mut numbers);
1661     /// assert_eq!(numbers, [5u128.to_be(), 65000u128.to_be()]);
1662     /// ```
1663     #[cfg(byteorder_i128)]
from_slice_u128(numbers: &mut [u128])1664     fn from_slice_u128(numbers: &mut [u128]);
1665 
1666     /// Converts the given slice of signed 16 bit integers to a particular
1667     /// endianness.
1668     ///
1669     /// If the endianness matches the endianness of the host platform, then
1670     /// this is a no-op.
1671     ///
1672     /// # Examples
1673     ///
1674     /// Convert the host platform's endianness to big-endian:
1675     ///
1676     /// ```rust
1677     /// use byteorder::{ByteOrder, BigEndian};
1678     ///
1679     /// let mut numbers = [5, 6500];
1680     /// BigEndian::from_slice_i16(&mut numbers);
1681     /// assert_eq!(numbers, [5i16.to_be(), 6500i16.to_be()]);
1682     /// ```
1683     #[inline]
from_slice_i16(src: &mut [i16])1684     fn from_slice_i16(src: &mut [i16]) {
1685         let src = unsafe {
1686             slice::from_raw_parts_mut(src.as_ptr() as *mut u16, src.len())
1687         };
1688         Self::from_slice_u16(src);
1689     }
1690 
1691     /// Converts the given slice of signed 32 bit integers to a particular
1692     /// endianness.
1693     ///
1694     /// If the endianness matches the endianness of the host platform, then
1695     /// this is a no-op.
1696     ///
1697     /// # Examples
1698     ///
1699     /// Convert the host platform's endianness to big-endian:
1700     ///
1701     /// ```rust
1702     /// use byteorder::{ByteOrder, BigEndian};
1703     ///
1704     /// let mut numbers = [5, 65000];
1705     /// BigEndian::from_slice_i32(&mut numbers);
1706     /// assert_eq!(numbers, [5i32.to_be(), 65000i32.to_be()]);
1707     /// ```
1708     #[inline]
from_slice_i32(src: &mut [i32])1709     fn from_slice_i32(src: &mut [i32]) {
1710         let src = unsafe {
1711             slice::from_raw_parts_mut(src.as_ptr() as *mut u32, src.len())
1712         };
1713         Self::from_slice_u32(src);
1714     }
1715 
1716     /// Converts the given slice of signed 64 bit integers to a particular
1717     /// endianness.
1718     ///
1719     /// If the endianness matches the endianness of the host platform, then
1720     /// this is a no-op.
1721     ///
1722     /// # Examples
1723     ///
1724     /// Convert the host platform's endianness to big-endian:
1725     ///
1726     /// ```rust
1727     /// use byteorder::{ByteOrder, BigEndian};
1728     ///
1729     /// let mut numbers = [5, 65000];
1730     /// BigEndian::from_slice_i64(&mut numbers);
1731     /// assert_eq!(numbers, [5i64.to_be(), 65000i64.to_be()]);
1732     /// ```
1733     #[inline]
from_slice_i64(src: &mut [i64])1734     fn from_slice_i64(src: &mut [i64]) {
1735         let src = unsafe {
1736             slice::from_raw_parts_mut(src.as_ptr() as *mut u64, src.len())
1737         };
1738         Self::from_slice_u64(src);
1739     }
1740 
1741     /// Converts the given slice of signed 128 bit integers to a particular
1742     /// endianness.
1743     ///
1744     /// If the endianness matches the endianness of the host platform, then
1745     /// this is a no-op.
1746     ///
1747     /// # Examples
1748     ///
1749     /// Convert the host platform's endianness to big-endian:
1750     ///
1751     /// ```rust
1752     /// use byteorder::{ByteOrder, BigEndian};
1753     ///
1754     /// let mut numbers = [5, 65000];
1755     /// BigEndian::from_slice_i128(&mut numbers);
1756     /// assert_eq!(numbers, [5i128.to_be(), 65000i128.to_be()]);
1757     /// ```
1758     #[cfg(byteorder_i128)]
1759     #[inline]
from_slice_i128(src: &mut [i128])1760     fn from_slice_i128(src: &mut [i128]) {
1761         let src = unsafe {
1762             slice::from_raw_parts_mut(src.as_ptr() as *mut u128, src.len())
1763         };
1764         Self::from_slice_u128(src);
1765     }
1766 
1767     /// Converts the given slice of IEEE754 single-precision (4 bytes) floating
1768     /// point numbers to a particular endianness.
1769     ///
1770     /// If the endianness matches the endianness of the host platform, then
1771     /// this is a no-op.
from_slice_f32(numbers: &mut [f32])1772     fn from_slice_f32(numbers: &mut [f32]);
1773 
1774     /// Converts the given slice of IEEE754 double-precision (8 bytes) floating
1775     /// point numbers to a particular endianness.
1776     ///
1777     /// If the endianness matches the endianness of the host platform, then
1778     /// this is a no-op.
from_slice_f64(numbers: &mut [f64])1779     fn from_slice_f64(numbers: &mut [f64]);
1780 }
1781 
1782 /// Defines big-endian serialization.
1783 ///
1784 /// Note that this type has no value constructor. It is used purely at the
1785 /// type level.
1786 ///
1787 /// # Examples
1788 ///
1789 /// Write and read `u32` numbers in big endian order:
1790 ///
1791 /// ```rust
1792 /// use byteorder::{ByteOrder, BigEndian};
1793 ///
1794 /// let mut buf = [0; 4];
1795 /// BigEndian::write_u32(&mut buf, 1_000_000);
1796 /// assert_eq!(1_000_000, BigEndian::read_u32(&buf));
1797 /// ```
1798 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1799 pub enum BigEndian {}
1800 
1801 impl Default for BigEndian {
default() -> BigEndian1802     fn default() -> BigEndian {
1803         panic!("BigEndian default")
1804     }
1805 }
1806 
1807 /// A type alias for [`BigEndian`].
1808 ///
1809 /// [`BigEndian`]: enum.BigEndian.html
1810 pub type BE = BigEndian;
1811 
1812 /// Defines little-endian serialization.
1813 ///
1814 /// Note that this type has no value constructor. It is used purely at the
1815 /// type level.
1816 ///
1817 /// # Examples
1818 ///
1819 /// Write and read `u32` numbers in little endian order:
1820 ///
1821 /// ```rust
1822 /// use byteorder::{ByteOrder, LittleEndian};
1823 ///
1824 /// let mut buf = [0; 4];
1825 /// LittleEndian::write_u32(&mut buf, 1_000_000);
1826 /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
1827 /// ```
1828 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1829 pub enum LittleEndian {}
1830 
1831 impl Default for LittleEndian {
default() -> LittleEndian1832     fn default() -> LittleEndian {
1833         panic!("LittleEndian default")
1834     }
1835 }
1836 
1837 /// A type alias for [`LittleEndian`].
1838 ///
1839 /// [`LittleEndian`]: enum.LittleEndian.html
1840 pub type LE = LittleEndian;
1841 
1842 /// Defines network byte order serialization.
1843 ///
1844 /// Network byte order is defined by [RFC 1700][1] to be big-endian, and is
1845 /// referred to in several protocol specifications.  This type is an alias of
1846 /// [`BigEndian`].
1847 ///
1848 /// [1]: https://tools.ietf.org/html/rfc1700
1849 ///
1850 /// Note that this type has no value constructor. It is used purely at the
1851 /// type level.
1852 ///
1853 /// # Examples
1854 ///
1855 /// Write and read `i16` numbers in big endian order:
1856 ///
1857 /// ```rust
1858 /// use byteorder::{ByteOrder, NetworkEndian, BigEndian};
1859 ///
1860 /// let mut buf = [0; 2];
1861 /// BigEndian::write_i16(&mut buf, -5_000);
1862 /// assert_eq!(-5_000, NetworkEndian::read_i16(&buf));
1863 /// ```
1864 ///
1865 /// [`BigEndian`]: enum.BigEndian.html
1866 pub type NetworkEndian = BigEndian;
1867 
1868 /// Defines system native-endian serialization.
1869 ///
1870 /// Note that this type has no value constructor. It is used purely at the
1871 /// type level.
1872 ///
1873 /// On this platform, this is an alias for [`LittleEndian`].
1874 ///
1875 /// [`LittleEndian`]: enum.LittleEndian.html
1876 #[cfg(target_endian = "little")]
1877 pub type NativeEndian = LittleEndian;
1878 
1879 /// Defines system native-endian serialization.
1880 ///
1881 /// Note that this type has no value constructor. It is used purely at the
1882 /// type level.
1883 ///
1884 /// On this platform, this is an alias for [`BigEndian`].
1885 ///
1886 /// [`BigEndian`]: enum.BigEndian.html
1887 #[cfg(target_endian = "big")]
1888 pub type NativeEndian = BigEndian;
1889 
1890 macro_rules! read_num_bytes {
1891     ($ty:ty, $size:expr, $src:expr, $which:ident) => ({
1892         assert!($size == ::core::mem::size_of::<$ty>());
1893         assert!($size <= $src.len());
1894         let mut data: $ty = 0;
1895         unsafe {
1896             copy_nonoverlapping(
1897                 $src.as_ptr(),
1898                 &mut data as *mut $ty as *mut u8,
1899                 $size);
1900         }
1901         data.$which()
1902     });
1903 }
1904 
1905 macro_rules! write_num_bytes {
1906     ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => ({
1907         assert!($size <= $dst.len());
1908         unsafe {
1909             // N.B. https://github.com/rust-lang/rust/issues/22776
1910             let bytes = *(&$n.$which() as *const _ as *const [u8; $size]);
1911             copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
1912         }
1913     });
1914 }
1915 
1916 macro_rules! read_slice {
1917     ($src:expr, $dst:expr, $size:expr, $which:ident) => {{
1918         assert_eq!($src.len(), $size * $dst.len());
1919 
1920         unsafe {
1921             copy_nonoverlapping(
1922                 $src.as_ptr(),
1923                 $dst.as_mut_ptr() as *mut u8,
1924                 $src.len());
1925         }
1926         for v in $dst.iter_mut() {
1927             *v = v.$which();
1928         }
1929     }};
1930 }
1931 
1932 macro_rules! write_slice_native {
1933     ($src:expr, $dst:expr, $ty:ty, $size:expr) => {{
1934         assert!($size == ::core::mem::size_of::<$ty>());
1935         assert_eq!($size * $src.len(), $dst.len());
1936 
1937         unsafe {
1938             copy_nonoverlapping(
1939                 $src.as_ptr() as *const u8,
1940                 $dst.as_mut_ptr(),
1941                 $dst.len());
1942         }
1943     }};
1944 }
1945 
1946 macro_rules! write_slice {
1947     ($src:expr, $dst:expr, $ty:ty, $size:expr, $write:expr) => ({
1948         assert!($size == ::core::mem::size_of::<$ty>());
1949         assert_eq!($size * $src.len(), $dst.len());
1950 
1951         for (&n, chunk) in $src.iter().zip($dst.chunks_mut($size)) {
1952             $write(chunk, n);
1953         }
1954     });
1955 }
1956 
1957 impl ByteOrder for BigEndian {
1958     #[inline]
read_u16(buf: &[u8]) -> u161959     fn read_u16(buf: &[u8]) -> u16 {
1960         read_num_bytes!(u16, 2, buf, to_be)
1961     }
1962 
1963     #[inline]
read_u32(buf: &[u8]) -> u321964     fn read_u32(buf: &[u8]) -> u32 {
1965         read_num_bytes!(u32, 4, buf, to_be)
1966     }
1967 
1968     #[inline]
read_u64(buf: &[u8]) -> u641969     fn read_u64(buf: &[u8]) -> u64 {
1970         read_num_bytes!(u64, 8, buf, to_be)
1971     }
1972 
1973     #[cfg(byteorder_i128)]
1974     #[inline]
read_u128(buf: &[u8]) -> u1281975     fn read_u128(buf: &[u8]) -> u128 {
1976         read_num_bytes!(u128, 16, buf, to_be)
1977     }
1978 
1979     #[inline]
read_uint(buf: &[u8], nbytes: usize) -> u641980     fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
1981         assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
1982         let mut out = [0u8; 8];
1983         let ptr_out = out.as_mut_ptr();
1984         unsafe {
1985             copy_nonoverlapping(
1986                 buf.as_ptr(), ptr_out.offset((8 - nbytes) as isize), nbytes);
1987             (*(ptr_out as *const u64)).to_be()
1988         }
1989     }
1990 
1991     #[cfg(byteorder_i128)]
1992     #[inline]
read_uint128(buf: &[u8], nbytes: usize) -> u1281993     fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
1994         assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
1995         let mut out = [0u8; 16];
1996         let ptr_out = out.as_mut_ptr();
1997         unsafe {
1998             copy_nonoverlapping(
1999                 buf.as_ptr(), ptr_out.offset((16 - nbytes) as isize), nbytes);
2000             (*(ptr_out as *const u128)).to_be()
2001         }
2002     }
2003 
2004     #[inline]
write_u16(buf: &mut [u8], n: u16)2005     fn write_u16(buf: &mut [u8], n: u16) {
2006         write_num_bytes!(u16, 2, n, buf, to_be);
2007     }
2008 
2009     #[inline]
write_u32(buf: &mut [u8], n: u32)2010     fn write_u32(buf: &mut [u8], n: u32) {
2011         write_num_bytes!(u32, 4, n, buf, to_be);
2012     }
2013 
2014     #[inline]
write_u64(buf: &mut [u8], n: u64)2015     fn write_u64(buf: &mut [u8], n: u64) {
2016         write_num_bytes!(u64, 8, n, buf, to_be);
2017     }
2018 
2019     #[cfg(byteorder_i128)]
2020     #[inline]
write_u128(buf: &mut [u8], n: u128)2021     fn write_u128(buf: &mut [u8], n: u128) {
2022         write_num_bytes!(u128, 16, n, buf, to_be);
2023     }
2024 
2025     #[inline]
write_uint(buf: &mut [u8], n: u64, nbytes: usize)2026     fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
2027         assert!(pack_size(n) <= nbytes && nbytes <= 8);
2028         assert!(nbytes <= buf.len());
2029         unsafe {
2030             let bytes = *(&n.to_be() as *const u64 as *const [u8; 8]);
2031             copy_nonoverlapping(
2032                 bytes.as_ptr().offset((8 - nbytes) as isize),
2033                 buf.as_mut_ptr(),
2034                 nbytes);
2035         }
2036     }
2037 
2038     #[cfg(byteorder_i128)]
2039     #[inline]
write_uint128(buf: &mut [u8], n: u128, nbytes: usize)2040     fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) {
2041         assert!(pack_size128(n) <= nbytes && nbytes <= 16);
2042         assert!(nbytes <= buf.len());
2043         unsafe {
2044             let bytes = *(&n.to_be() as *const u128 as *const [u8; 16]);
2045             copy_nonoverlapping(
2046                 bytes.as_ptr().offset((16 - nbytes) as isize),
2047                 buf.as_mut_ptr(),
2048                 nbytes);
2049         }
2050     }
2051 
2052     #[inline]
read_u16_into(src: &[u8], dst: &mut [u16])2053     fn read_u16_into(src: &[u8], dst: &mut [u16]) {
2054         read_slice!(src, dst, 2, to_be);
2055     }
2056 
2057     #[inline]
read_u32_into(src: &[u8], dst: &mut [u32])2058     fn read_u32_into(src: &[u8], dst: &mut [u32]) {
2059         read_slice!(src, dst, 4, to_be);
2060     }
2061 
2062     #[inline]
read_u64_into(src: &[u8], dst: &mut [u64])2063     fn read_u64_into(src: &[u8], dst: &mut [u64]) {
2064         read_slice!(src, dst, 8, to_be);
2065     }
2066 
2067     #[cfg(byteorder_i128)]
2068     #[inline]
read_u128_into(src: &[u8], dst: &mut [u128])2069     fn read_u128_into(src: &[u8], dst: &mut [u128]) {
2070         read_slice!(src, dst, 16, to_be);
2071     }
2072 
2073     #[inline]
write_u16_into(src: &[u16], dst: &mut [u8])2074     fn write_u16_into(src: &[u16], dst: &mut [u8]) {
2075         if cfg!(target_endian = "big") {
2076             write_slice_native!(src, dst, u16, 2);
2077         } else {
2078             write_slice!(src, dst, u16, 2, Self::write_u16);
2079         }
2080     }
2081 
2082     #[inline]
write_u32_into(src: &[u32], dst: &mut [u8])2083     fn write_u32_into(src: &[u32], dst: &mut [u8]) {
2084         if cfg!(target_endian = "big") {
2085             write_slice_native!(src, dst, u32, 4);
2086         } else {
2087             write_slice!(src, dst, u32, 4, Self::write_u32);
2088         }
2089     }
2090 
2091     #[inline]
write_u64_into(src: &[u64], dst: &mut [u8])2092     fn write_u64_into(src: &[u64], dst: &mut [u8]) {
2093         if cfg!(target_endian = "big") {
2094             write_slice_native!(src, dst, u64, 8);
2095         } else {
2096             write_slice!(src, dst, u64, 8, Self::write_u64);
2097         }
2098     }
2099 
2100     #[cfg(byteorder_i128)]
2101     #[inline]
write_u128_into(src: &[u128], dst: &mut [u8])2102     fn write_u128_into(src: &[u128], dst: &mut [u8]) {
2103         if cfg!(target_endian = "big") {
2104             write_slice_native!(src, dst, u128, 16);
2105         } else {
2106             write_slice!(src, dst, u128, 16, Self::write_u128);
2107         }
2108     }
2109 
2110     #[inline]
from_slice_u16(numbers: &mut [u16])2111     fn from_slice_u16(numbers: &mut [u16]) {
2112         if cfg!(target_endian = "little") {
2113             for n in numbers {
2114                 *n = n.to_be();
2115             }
2116         }
2117     }
2118 
2119     #[inline]
from_slice_u32(numbers: &mut [u32])2120     fn from_slice_u32(numbers: &mut [u32]) {
2121         if cfg!(target_endian = "little") {
2122             for n in numbers {
2123                 *n = n.to_be();
2124             }
2125         }
2126     }
2127 
2128     #[inline]
from_slice_u64(numbers: &mut [u64])2129     fn from_slice_u64(numbers: &mut [u64]) {
2130         if cfg!(target_endian = "little") {
2131             for n in numbers {
2132                 *n = n.to_be();
2133             }
2134         }
2135     }
2136 
2137     #[cfg(byteorder_i128)]
2138     #[inline]
from_slice_u128(numbers: &mut [u128])2139     fn from_slice_u128(numbers: &mut [u128]) {
2140         if cfg!(target_endian = "little") {
2141             for n in numbers {
2142                 *n = n.to_be();
2143             }
2144         }
2145     }
2146 
2147     #[inline]
from_slice_f32(numbers: &mut [f32])2148     fn from_slice_f32(numbers: &mut [f32]) {
2149         if cfg!(target_endian = "little") {
2150             for n in numbers {
2151                 unsafe {
2152                     let int = *(n as *const f32 as *const u32);
2153                     *n = *(&int.to_be() as *const u32 as *const f32);
2154                 }
2155             }
2156         }
2157     }
2158 
2159     #[inline]
from_slice_f64(numbers: &mut [f64])2160     fn from_slice_f64(numbers: &mut [f64]) {
2161         if cfg!(target_endian = "little") {
2162             for n in numbers {
2163                 unsafe {
2164                     let int = *(n as *const f64 as *const u64);
2165                     *n = *(&int.to_be() as *const u64 as *const f64);
2166                 }
2167             }
2168         }
2169     }
2170 }
2171 
2172 impl ByteOrder for LittleEndian {
2173     #[inline]
read_u16(buf: &[u8]) -> u162174     fn read_u16(buf: &[u8]) -> u16 {
2175         read_num_bytes!(u16, 2, buf, to_le)
2176     }
2177 
2178     #[inline]
read_u32(buf: &[u8]) -> u322179     fn read_u32(buf: &[u8]) -> u32 {
2180         read_num_bytes!(u32, 4, buf, to_le)
2181     }
2182 
2183     #[inline]
read_u64(buf: &[u8]) -> u642184     fn read_u64(buf: &[u8]) -> u64 {
2185         read_num_bytes!(u64, 8, buf, to_le)
2186     }
2187 
2188     #[cfg(byteorder_i128)]
2189     #[inline]
read_u128(buf: &[u8]) -> u1282190     fn read_u128(buf: &[u8]) -> u128 {
2191         read_num_bytes!(u128, 16, buf, to_le)
2192     }
2193 
2194     #[inline]
read_uint(buf: &[u8], nbytes: usize) -> u642195     fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
2196         assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
2197         let mut out = [0u8; 8];
2198         let ptr_out = out.as_mut_ptr();
2199         unsafe {
2200             copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
2201             (*(ptr_out as *const u64)).to_le()
2202         }
2203     }
2204 
2205     #[cfg(byteorder_i128)]
2206     #[inline]
read_uint128(buf: &[u8], nbytes: usize) -> u1282207     fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
2208         assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
2209         let mut out = [0u8; 16];
2210         let ptr_out = out.as_mut_ptr();
2211         unsafe {
2212             copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
2213             (*(ptr_out as *const u128)).to_le()
2214         }
2215     }
2216 
2217     #[inline]
write_u16(buf: &mut [u8], n: u16)2218     fn write_u16(buf: &mut [u8], n: u16) {
2219         write_num_bytes!(u16, 2, n, buf, to_le);
2220     }
2221 
2222     #[inline]
write_u32(buf: &mut [u8], n: u32)2223     fn write_u32(buf: &mut [u8], n: u32) {
2224         write_num_bytes!(u32, 4, n, buf, to_le);
2225     }
2226 
2227     #[inline]
write_u64(buf: &mut [u8], n: u64)2228     fn write_u64(buf: &mut [u8], n: u64) {
2229         write_num_bytes!(u64, 8, n, buf, to_le);
2230     }
2231 
2232     #[cfg(byteorder_i128)]
2233     #[inline]
write_u128(buf: &mut [u8], n: u128)2234     fn write_u128(buf: &mut [u8], n: u128) {
2235         write_num_bytes!(u128, 16, n, buf, to_le);
2236     }
2237 
2238     #[inline]
write_uint(buf: &mut [u8], n: u64, nbytes: usize)2239     fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
2240         assert!(pack_size(n as u64) <= nbytes && nbytes <= 8);
2241         assert!(nbytes <= buf.len());
2242         unsafe {
2243             let bytes = *(&n.to_le() as *const u64 as *const [u8; 8]);
2244             copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
2245         }
2246     }
2247 
2248     #[cfg(byteorder_i128)]
2249     #[inline]
write_uint128(buf: &mut [u8], n: u128, nbytes: usize)2250     fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) {
2251         assert!(pack_size128(n as u128) <= nbytes && nbytes <= 16);
2252         assert!(nbytes <= buf.len());
2253         unsafe {
2254             let bytes = *(&n.to_le() as *const u128 as *const [u8; 16]);
2255             copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
2256         }
2257     }
2258 
2259     #[inline]
read_u16_into(src: &[u8], dst: &mut [u16])2260     fn read_u16_into(src: &[u8], dst: &mut [u16]) {
2261         read_slice!(src, dst, 2, to_le);
2262     }
2263 
2264     #[inline]
read_u32_into(src: &[u8], dst: &mut [u32])2265     fn read_u32_into(src: &[u8], dst: &mut [u32]) {
2266         read_slice!(src, dst, 4, to_le);
2267     }
2268 
2269     #[inline]
read_u64_into(src: &[u8], dst: &mut [u64])2270     fn read_u64_into(src: &[u8], dst: &mut [u64]) {
2271         read_slice!(src, dst, 8, to_le);
2272     }
2273 
2274     #[cfg(byteorder_i128)]
2275     #[inline]
read_u128_into(src: &[u8], dst: &mut [u128])2276     fn read_u128_into(src: &[u8], dst: &mut [u128]) {
2277         read_slice!(src, dst, 16, to_le);
2278     }
2279 
2280     #[inline]
write_u16_into(src: &[u16], dst: &mut [u8])2281     fn write_u16_into(src: &[u16], dst: &mut [u8]) {
2282         if cfg!(target_endian = "little") {
2283             write_slice_native!(src, dst, u16, 2);
2284         } else {
2285             write_slice!(src, dst, u16, 2, Self::write_u16);
2286         }
2287     }
2288 
2289     #[inline]
write_u32_into(src: &[u32], dst: &mut [u8])2290     fn write_u32_into(src: &[u32], dst: &mut [u8]) {
2291         if cfg!(target_endian = "little") {
2292             write_slice_native!(src, dst, u32, 4);
2293         } else {
2294             write_slice!(src, dst, u32, 4, Self::write_u32);
2295         }
2296     }
2297 
2298     #[inline]
write_u64_into(src: &[u64], dst: &mut [u8])2299     fn write_u64_into(src: &[u64], dst: &mut [u8]) {
2300         if cfg!(target_endian = "little") {
2301             write_slice_native!(src, dst, u64, 8);
2302         } else {
2303             write_slice!(src, dst, u64, 8, Self::write_u64);
2304         }
2305     }
2306 
2307     #[cfg(byteorder_i128)]
2308     #[inline]
write_u128_into(src: &[u128], dst: &mut [u8])2309     fn write_u128_into(src: &[u128], dst: &mut [u8]) {
2310         if cfg!(target_endian = "little") {
2311             write_slice_native!(src, dst, u128, 16);
2312         } else {
2313             write_slice!(src, dst, u128, 16, Self::write_u128);
2314         }
2315     }
2316 
2317     #[inline]
from_slice_u16(numbers: &mut [u16])2318     fn from_slice_u16(numbers: &mut [u16]) {
2319         if cfg!(target_endian = "big") {
2320             for n in numbers {
2321                 *n = n.to_le();
2322             }
2323         }
2324     }
2325 
2326     #[inline]
from_slice_u32(numbers: &mut [u32])2327     fn from_slice_u32(numbers: &mut [u32]) {
2328         if cfg!(target_endian = "big") {
2329             for n in numbers {
2330                 *n = n.to_le();
2331             }
2332         }
2333     }
2334 
2335     #[inline]
from_slice_u64(numbers: &mut [u64])2336     fn from_slice_u64(numbers: &mut [u64]) {
2337         if cfg!(target_endian = "big") {
2338             for n in numbers {
2339                 *n = n.to_le();
2340             }
2341         }
2342     }
2343 
2344     #[cfg(byteorder_i128)]
2345     #[inline]
from_slice_u128(numbers: &mut [u128])2346     fn from_slice_u128(numbers: &mut [u128]) {
2347         if cfg!(target_endian = "big") {
2348             for n in numbers {
2349                 *n = n.to_le();
2350             }
2351         }
2352     }
2353 
2354     #[inline]
from_slice_f32(numbers: &mut [f32])2355     fn from_slice_f32(numbers: &mut [f32]) {
2356         if cfg!(target_endian = "big") {
2357             for n in numbers {
2358                 unsafe {
2359                     let int = *(n as *const f32 as *const u32);
2360                     *n = *(&int.to_le() as *const u32 as *const f32);
2361                 }
2362             }
2363         }
2364     }
2365 
2366     #[inline]
from_slice_f64(numbers: &mut [f64])2367     fn from_slice_f64(numbers: &mut [f64]) {
2368         if cfg!(target_endian = "big") {
2369             for n in numbers {
2370                 unsafe {
2371                     let int = *(n as *const f64 as *const u64);
2372                     *n = *(&int.to_le() as *const u64 as *const f64);
2373                 }
2374             }
2375         }
2376     }
2377 }
2378 
2379 #[cfg(test)]
2380 mod test {
2381     extern crate quickcheck;
2382     extern crate rand;
2383 
2384     use self::quickcheck::{QuickCheck, StdGen, Testable};
2385     use self::rand::thread_rng;
2386     #[cfg(byteorder_i128)]
2387     use self::rand::Rng;
2388     #[cfg(byteorder_i128)]
2389     use self::quickcheck::{Arbitrary, Gen};
2390 
2391     pub const U24_MAX: u32 = 16_777_215;
2392     pub const I24_MAX: i32 = 8_388_607;
2393     pub const U48_MAX: u64 = 281_474_976_710_655;
2394     pub const I48_MAX: i64 = 140_737_488_355_327;
2395 
2396     pub const U64_MAX: u64 = ::core::u64::MAX;
2397     pub const I64_MAX: u64 = ::core::i64::MAX as u64;
2398 
2399     macro_rules! calc_max {
2400         ($max:expr, $bytes:expr) => { calc_max!($max, $bytes, 8) };
2401         ($max:expr, $bytes:expr, $maxbytes:expr) => {
2402             ($max - 1) >> (8 * ($maxbytes - $bytes))
2403         };
2404     }
2405 
2406     #[derive(Clone, Debug)]
2407     pub struct Wi128<T>(pub T);
2408 
2409     #[cfg(byteorder_i128)]
2410     impl<T: Clone> Wi128<T> {
clone(&self) -> T2411         pub fn clone(&self) -> T {
2412             self.0.clone()
2413         }
2414     }
2415 
2416     impl<T: PartialEq> PartialEq<T> for Wi128<T> {
eq(&self, other: &T) -> bool2417         fn eq(&self, other: &T) -> bool {
2418             self.0.eq(other)
2419         }
2420     }
2421 
2422     #[cfg(byteorder_i128)]
2423     impl Arbitrary for Wi128<u128> {
arbitrary<G: Gen>(gen: &mut G) -> Wi128<u128>2424         fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<u128> {
2425             let max = calc_max!(::core::u128::MAX, gen.size(), 16);
2426             let output =
2427                 (gen.gen::<u64>() as u128) |
2428                 ((gen.gen::<u64>() as u128) << 64);
2429             Wi128(output & (max - 1))
2430         }
2431     }
2432 
2433     #[cfg(byteorder_i128)]
2434     impl Arbitrary for Wi128<i128> {
arbitrary<G: Gen>(gen: &mut G) -> Wi128<i128>2435         fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<i128> {
2436             let max = calc_max!(::core::i128::MAX, gen.size(), 16);
2437             let output =
2438                 (gen.gen::<i64>() as i128) |
2439                 ((gen.gen::<i64>() as i128) << 64);
2440             Wi128(output & (max - 1))
2441         }
2442     }
2443 
qc_sized<A: Testable>(f: A, size: u64)2444     pub fn qc_sized<A: Testable>(f: A, size: u64) {
2445         QuickCheck::new()
2446             .gen(StdGen::new(thread_rng(), size as usize))
2447             .tests(1_00)
2448             .max_tests(10_000)
2449             .quickcheck(f);
2450     }
2451 
2452     macro_rules! qc_byte_order {
2453         ($name:ident, $ty_int:ty, $max:expr,
2454          $bytes:expr, $read:ident, $write:ident) => (
2455             mod $name {
2456                 use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
2457                 #[allow(unused_imports)] use super::{ qc_sized, Wi128 };
2458 
2459                 #[test]
2460                 fn big_endian() {
2461                     fn prop(n: $ty_int) -> bool {
2462                         let mut buf = [0; 16];
2463                         BigEndian::$write(&mut buf, n.clone(), $bytes);
2464                         n == BigEndian::$read(&mut buf[..$bytes], $bytes)
2465                     }
2466                     qc_sized(prop as fn($ty_int) -> bool, $max);
2467                 }
2468 
2469                 #[test]
2470                 fn little_endian() {
2471                     fn prop(n: $ty_int) -> bool {
2472                         let mut buf = [0; 16];
2473                         LittleEndian::$write(&mut buf, n.clone(), $bytes);
2474                         n == LittleEndian::$read(&mut buf[..$bytes], $bytes)
2475                     }
2476                     qc_sized(prop as fn($ty_int) -> bool, $max);
2477                 }
2478 
2479                 #[test]
2480                 fn native_endian() {
2481                     fn prop(n: $ty_int) -> bool {
2482                         let mut buf = [0; 16];
2483                         NativeEndian::$write(&mut buf, n.clone(), $bytes);
2484                         n == NativeEndian::$read(&mut buf[..$bytes], $bytes)
2485                     }
2486                     qc_sized(prop as fn($ty_int) -> bool, $max);
2487                 }
2488             }
2489         );
2490         ($name:ident, $ty_int:ty, $max:expr,
2491          $read:ident, $write:ident) => (
2492             mod $name {
2493                 use core::mem::size_of;
2494                 use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
2495                 #[allow(unused_imports)] use super::{ qc_sized, Wi128 };
2496 
2497                 #[test]
2498                 fn big_endian() {
2499                     fn prop(n: $ty_int) -> bool {
2500                         let bytes = size_of::<$ty_int>();
2501                         let mut buf = [0; 16];
2502                         BigEndian::$write(&mut buf[16 - bytes..], n.clone());
2503                         n == BigEndian::$read(&mut buf[16 - bytes..])
2504                     }
2505                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
2506                 }
2507 
2508                 #[test]
2509                 fn little_endian() {
2510                     fn prop(n: $ty_int) -> bool {
2511                         let bytes = size_of::<$ty_int>();
2512                         let mut buf = [0; 16];
2513                         LittleEndian::$write(&mut buf[..bytes], n.clone());
2514                         n == LittleEndian::$read(&mut buf[..bytes])
2515                     }
2516                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
2517                 }
2518 
2519                 #[test]
2520                 fn native_endian() {
2521                     fn prop(n: $ty_int) -> bool {
2522                         let bytes = size_of::<$ty_int>();
2523                         let mut buf = [0; 16];
2524                         NativeEndian::$write(&mut buf[..bytes], n.clone());
2525                         n == NativeEndian::$read(&mut buf[..bytes])
2526                     }
2527                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
2528                 }
2529             }
2530         );
2531     }
2532 
2533     qc_byte_order!(prop_u16, u16, ::core::u16::MAX as u64, read_u16, write_u16);
2534     qc_byte_order!(prop_i16, i16, ::core::i16::MAX as u64, read_i16, write_i16);
2535     qc_byte_order!(prop_u24, u32, ::test::U24_MAX as u64, read_u24, write_u24);
2536     qc_byte_order!(prop_i24, i32, ::test::I24_MAX as u64, read_i24, write_i24);
2537     qc_byte_order!(prop_u32, u32, ::core::u32::MAX as u64, read_u32, write_u32);
2538     qc_byte_order!(prop_i32, i32, ::core::i32::MAX as u64, read_i32, write_i32);
2539     qc_byte_order!(prop_u48, u64, ::test::U48_MAX as u64, read_u48, write_u48);
2540     qc_byte_order!(prop_i48, i64, ::test::I48_MAX as u64, read_i48, write_i48);
2541     qc_byte_order!(prop_u64, u64, ::core::u64::MAX as u64, read_u64, write_u64);
2542     qc_byte_order!(prop_i64, i64, ::core::i64::MAX as u64, read_i64, write_i64);
2543     qc_byte_order!(prop_f32, f32, ::core::u64::MAX as u64, read_f32, write_f32);
2544     qc_byte_order!(prop_f64, f64, ::core::i64::MAX as u64, read_f64, write_f64);
2545 
2546     #[cfg(byteorder_i128)]
2547     qc_byte_order!(prop_u128, Wi128<u128>, 16 + 1, read_u128, write_u128);
2548     #[cfg(byteorder_i128)]
2549     qc_byte_order!(prop_i128, Wi128<i128>, 16 + 1, read_i128, write_i128);
2550 
2551     qc_byte_order!(prop_uint_1,
2552         u64, calc_max!(super::U64_MAX, 1), 1, read_uint, write_uint);
2553     qc_byte_order!(prop_uint_2,
2554         u64, calc_max!(super::U64_MAX, 2), 2, read_uint, write_uint);
2555     qc_byte_order!(prop_uint_3,
2556         u64, calc_max!(super::U64_MAX, 3), 3, read_uint, write_uint);
2557     qc_byte_order!(prop_uint_4,
2558         u64, calc_max!(super::U64_MAX, 4), 4, read_uint, write_uint);
2559     qc_byte_order!(prop_uint_5,
2560         u64, calc_max!(super::U64_MAX, 5), 5, read_uint, write_uint);
2561     qc_byte_order!(prop_uint_6,
2562         u64, calc_max!(super::U64_MAX, 6), 6, read_uint, write_uint);
2563     qc_byte_order!(prop_uint_7,
2564         u64, calc_max!(super::U64_MAX, 7), 7, read_uint, write_uint);
2565     qc_byte_order!(prop_uint_8,
2566         u64, calc_max!(super::U64_MAX, 8), 8, read_uint, write_uint);
2567 
2568     #[cfg(byteorder_i128)]
2569     qc_byte_order!(prop_uint128_1,
2570         Wi128<u128>, 1, 1, read_uint128, write_uint128);
2571     #[cfg(byteorder_i128)]
2572     qc_byte_order!(prop_uint128_2,
2573         Wi128<u128>, 2, 2, read_uint128, write_uint128);
2574     #[cfg(byteorder_i128)]
2575     qc_byte_order!(prop_uint128_3,
2576         Wi128<u128>, 3, 3, read_uint128, write_uint128);
2577     #[cfg(byteorder_i128)]
2578     qc_byte_order!(prop_uint128_4,
2579         Wi128<u128>, 4, 4, read_uint128, write_uint128);
2580     #[cfg(byteorder_i128)]
2581     qc_byte_order!(prop_uint128_5,
2582         Wi128<u128>, 5, 5, read_uint128, write_uint128);
2583     #[cfg(byteorder_i128)]
2584     qc_byte_order!(prop_uint128_6,
2585         Wi128<u128>, 6, 6, read_uint128, write_uint128);
2586     #[cfg(byteorder_i128)]
2587     qc_byte_order!(prop_uint128_7,
2588         Wi128<u128>, 7, 7, read_uint128, write_uint128);
2589     #[cfg(byteorder_i128)]
2590     qc_byte_order!(prop_uint128_8,
2591         Wi128<u128>, 8, 8, read_uint128, write_uint128);
2592     #[cfg(byteorder_i128)]
2593     qc_byte_order!(prop_uint128_9,
2594         Wi128<u128>, 9, 9, read_uint128, write_uint128);
2595     #[cfg(byteorder_i128)]
2596     qc_byte_order!(prop_uint128_10,
2597         Wi128<u128>, 10, 10, read_uint128, write_uint128);
2598     #[cfg(byteorder_i128)]
2599     qc_byte_order!(prop_uint128_11,
2600         Wi128<u128>, 11, 11, read_uint128, write_uint128);
2601     #[cfg(byteorder_i128)]
2602     qc_byte_order!(prop_uint128_12,
2603         Wi128<u128>, 12, 12, read_uint128, write_uint128);
2604     #[cfg(byteorder_i128)]
2605     qc_byte_order!(prop_uint128_13,
2606         Wi128<u128>, 13, 13, read_uint128, write_uint128);
2607     #[cfg(byteorder_i128)]
2608     qc_byte_order!(prop_uint128_14,
2609         Wi128<u128>, 14, 14, read_uint128, write_uint128);
2610     #[cfg(byteorder_i128)]
2611     qc_byte_order!(prop_uint128_15,
2612         Wi128<u128>, 15, 15, read_uint128, write_uint128);
2613     #[cfg(byteorder_i128)]
2614     qc_byte_order!(prop_uint128_16,
2615         Wi128<u128>, 16, 16, read_uint128, write_uint128);
2616 
2617     qc_byte_order!(prop_int_1,
2618         i64, calc_max!(super::I64_MAX, 1), 1, read_int, write_int);
2619     qc_byte_order!(prop_int_2,
2620         i64, calc_max!(super::I64_MAX, 2), 2, read_int, write_int);
2621     qc_byte_order!(prop_int_3,
2622         i64, calc_max!(super::I64_MAX, 3), 3, read_int, write_int);
2623     qc_byte_order!(prop_int_4,
2624         i64, calc_max!(super::I64_MAX, 4), 4, read_int, write_int);
2625     qc_byte_order!(prop_int_5,
2626         i64, calc_max!(super::I64_MAX, 5), 5, read_int, write_int);
2627     qc_byte_order!(prop_int_6,
2628         i64, calc_max!(super::I64_MAX, 6), 6, read_int, write_int);
2629     qc_byte_order!(prop_int_7,
2630         i64, calc_max!(super::I64_MAX, 7), 7, read_int, write_int);
2631     qc_byte_order!(prop_int_8,
2632         i64, calc_max!(super::I64_MAX, 8), 8, read_int, write_int);
2633 
2634     #[cfg(byteorder_i128)]
2635     qc_byte_order!(prop_int128_1,
2636         Wi128<i128>, 1, 1, read_int128, write_int128);
2637     #[cfg(byteorder_i128)]
2638     qc_byte_order!(prop_int128_2,
2639         Wi128<i128>, 2, 2, read_int128, write_int128);
2640     #[cfg(byteorder_i128)]
2641     qc_byte_order!(prop_int128_3,
2642         Wi128<i128>, 3, 3, read_int128, write_int128);
2643     #[cfg(byteorder_i128)]
2644     qc_byte_order!(prop_int128_4,
2645         Wi128<i128>, 4, 4, read_int128, write_int128);
2646     #[cfg(byteorder_i128)]
2647     qc_byte_order!(prop_int128_5,
2648         Wi128<i128>, 5, 5, read_int128, write_int128);
2649     #[cfg(byteorder_i128)]
2650     qc_byte_order!(prop_int128_6,
2651         Wi128<i128>, 6, 6, read_int128, write_int128);
2652     #[cfg(byteorder_i128)]
2653     qc_byte_order!(prop_int128_7,
2654         Wi128<i128>, 7, 7, read_int128, write_int128);
2655     #[cfg(byteorder_i128)]
2656     qc_byte_order!(prop_int128_8,
2657         Wi128<i128>, 8, 8, read_int128, write_int128);
2658     #[cfg(byteorder_i128)]
2659     qc_byte_order!(prop_int128_9,
2660         Wi128<i128>, 9, 9, read_int128, write_int128);
2661     #[cfg(byteorder_i128)]
2662     qc_byte_order!(prop_int128_10,
2663         Wi128<i128>, 10, 10, read_int128, write_int128);
2664     #[cfg(byteorder_i128)]
2665     qc_byte_order!(prop_int128_11,
2666         Wi128<i128>, 11, 11, read_int128, write_int128);
2667     #[cfg(byteorder_i128)]
2668     qc_byte_order!(prop_int128_12,
2669         Wi128<i128>, 12, 12, read_int128, write_int128);
2670     #[cfg(byteorder_i128)]
2671     qc_byte_order!(prop_int128_13,
2672         Wi128<i128>, 13, 13, read_int128, write_int128);
2673     #[cfg(byteorder_i128)]
2674     qc_byte_order!(prop_int128_14,
2675         Wi128<i128>, 14, 14, read_int128, write_int128);
2676     #[cfg(byteorder_i128)]
2677     qc_byte_order!(prop_int128_15,
2678         Wi128<i128>, 15, 15, read_int128, write_int128);
2679     #[cfg(byteorder_i128)]
2680     qc_byte_order!(prop_int128_16,
2681         Wi128<i128>, 16, 16, read_int128, write_int128);
2682 
2683 
2684     // Test that all of the byte conversion functions panic when given a
2685     // buffer that is too small.
2686     //
2687     // These tests are critical to ensure safety, otherwise we might end up
2688     // with a buffer overflow.
2689     macro_rules! too_small {
2690         ($name:ident, $maximally_small:expr, $zero:expr,
2691          $read:ident, $write:ident) => (
2692             mod $name {
2693                 use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
2694 
2695                 #[test]
2696                 #[should_panic]
2697                 fn read_big_endian() {
2698                     let buf = [0; $maximally_small];
2699                     BigEndian::$read(&buf);
2700                 }
2701 
2702                 #[test]
2703                 #[should_panic]
2704                 fn read_little_endian() {
2705                     let buf = [0; $maximally_small];
2706                     LittleEndian::$read(&buf);
2707                 }
2708 
2709                 #[test]
2710                 #[should_panic]
2711                 fn read_native_endian() {
2712                     let buf = [0; $maximally_small];
2713                     NativeEndian::$read(&buf);
2714                 }
2715 
2716                 #[test]
2717                 #[should_panic]
2718                 fn write_big_endian() {
2719                     let mut buf = [0; $maximally_small];
2720                     BigEndian::$write(&mut buf, $zero);
2721                 }
2722 
2723                 #[test]
2724                 #[should_panic]
2725                 fn write_little_endian() {
2726                     let mut buf = [0; $maximally_small];
2727                     LittleEndian::$write(&mut buf, $zero);
2728                 }
2729 
2730                 #[test]
2731                 #[should_panic]
2732                 fn write_native_endian() {
2733                     let mut buf = [0; $maximally_small];
2734                     NativeEndian::$write(&mut buf, $zero);
2735                 }
2736             }
2737         );
2738         ($name:ident, $maximally_small:expr, $read:ident) => (
2739             mod $name {
2740                 use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
2741 
2742                 #[test]
2743                 #[should_panic]
2744                 fn read_big_endian() {
2745                     let buf = [0; $maximally_small];
2746                     BigEndian::$read(&buf, $maximally_small + 1);
2747                 }
2748 
2749                 #[test]
2750                 #[should_panic]
2751                 fn read_little_endian() {
2752                     let buf = [0; $maximally_small];
2753                     LittleEndian::$read(&buf, $maximally_small + 1);
2754                 }
2755 
2756                 #[test]
2757                 #[should_panic]
2758                 fn read_native_endian() {
2759                     let buf = [0; $maximally_small];
2760                     NativeEndian::$read(&buf, $maximally_small + 1);
2761                 }
2762             }
2763         );
2764     }
2765 
2766     too_small!(small_u16, 1, 0, read_u16, write_u16);
2767     too_small!(small_i16, 1, 0, read_i16, write_i16);
2768     too_small!(small_u32, 3, 0, read_u32, write_u32);
2769     too_small!(small_i32, 3, 0, read_i32, write_i32);
2770     too_small!(small_u64, 7, 0, read_u64, write_u64);
2771     too_small!(small_i64, 7, 0, read_i64, write_i64);
2772     too_small!(small_f32, 3, 0.0, read_f32, write_f32);
2773     too_small!(small_f64, 7, 0.0, read_f64, write_f64);
2774     #[cfg(byteorder_i128)]
2775     too_small!(small_u128, 15, 0, read_u128, write_u128);
2776     #[cfg(byteorder_i128)]
2777     too_small!(small_i128, 15, 0, read_i128, write_i128);
2778 
2779     too_small!(small_uint_1, 1, read_uint);
2780     too_small!(small_uint_2, 2, read_uint);
2781     too_small!(small_uint_3, 3, read_uint);
2782     too_small!(small_uint_4, 4, read_uint);
2783     too_small!(small_uint_5, 5, read_uint);
2784     too_small!(small_uint_6, 6, read_uint);
2785     too_small!(small_uint_7, 7, read_uint);
2786 
2787     #[cfg(byteorder_i128)]
2788     too_small!(small_uint128_1, 1, read_uint128);
2789     #[cfg(byteorder_i128)]
2790     too_small!(small_uint128_2, 2, read_uint128);
2791     #[cfg(byteorder_i128)]
2792     too_small!(small_uint128_3, 3, read_uint128);
2793     #[cfg(byteorder_i128)]
2794     too_small!(small_uint128_4, 4, read_uint128);
2795     #[cfg(byteorder_i128)]
2796     too_small!(small_uint128_5, 5, read_uint128);
2797     #[cfg(byteorder_i128)]
2798     too_small!(small_uint128_6, 6, read_uint128);
2799     #[cfg(byteorder_i128)]
2800     too_small!(small_uint128_7, 7, read_uint128);
2801     #[cfg(byteorder_i128)]
2802     too_small!(small_uint128_8, 8, read_uint128);
2803     #[cfg(byteorder_i128)]
2804     too_small!(small_uint128_9, 9, read_uint128);
2805     #[cfg(byteorder_i128)]
2806     too_small!(small_uint128_10, 10, read_uint128);
2807     #[cfg(byteorder_i128)]
2808     too_small!(small_uint128_11, 11, read_uint128);
2809     #[cfg(byteorder_i128)]
2810     too_small!(small_uint128_12, 12, read_uint128);
2811     #[cfg(byteorder_i128)]
2812     too_small!(small_uint128_13, 13, read_uint128);
2813     #[cfg(byteorder_i128)]
2814     too_small!(small_uint128_14, 14, read_uint128);
2815     #[cfg(byteorder_i128)]
2816     too_small!(small_uint128_15, 15, read_uint128);
2817 
2818     too_small!(small_int_1, 1, read_int);
2819     too_small!(small_int_2, 2, read_int);
2820     too_small!(small_int_3, 3, read_int);
2821     too_small!(small_int_4, 4, read_int);
2822     too_small!(small_int_5, 5, read_int);
2823     too_small!(small_int_6, 6, read_int);
2824     too_small!(small_int_7, 7, read_int);
2825 
2826     #[cfg(byteorder_i128)]
2827     too_small!(small_int128_1, 1, read_int128);
2828     #[cfg(byteorder_i128)]
2829     too_small!(small_int128_2, 2, read_int128);
2830     #[cfg(byteorder_i128)]
2831     too_small!(small_int128_3, 3, read_int128);
2832     #[cfg(byteorder_i128)]
2833     too_small!(small_int128_4, 4, read_int128);
2834     #[cfg(byteorder_i128)]
2835     too_small!(small_int128_5, 5, read_int128);
2836     #[cfg(byteorder_i128)]
2837     too_small!(small_int128_6, 6, read_int128);
2838     #[cfg(byteorder_i128)]
2839     too_small!(small_int128_7, 7, read_int128);
2840     #[cfg(byteorder_i128)]
2841     too_small!(small_int128_8, 8, read_int128);
2842     #[cfg(byteorder_i128)]
2843     too_small!(small_int128_9, 9, read_int128);
2844     #[cfg(byteorder_i128)]
2845     too_small!(small_int128_10, 10, read_int128);
2846     #[cfg(byteorder_i128)]
2847     too_small!(small_int128_11, 11, read_int128);
2848     #[cfg(byteorder_i128)]
2849     too_small!(small_int128_12, 12, read_int128);
2850     #[cfg(byteorder_i128)]
2851     too_small!(small_int128_13, 13, read_int128);
2852     #[cfg(byteorder_i128)]
2853     too_small!(small_int128_14, 14, read_int128);
2854     #[cfg(byteorder_i128)]
2855     too_small!(small_int128_15, 15, read_int128);
2856 
2857     // Test that reading/writing slices enforces the correct lengths.
2858     macro_rules! slice_lengths {
2859         ($name:ident, $read:ident, $write:ident,
2860          $num_bytes:expr, $numbers:expr) => {
2861             mod $name {
2862                 use {ByteOrder, BigEndian, NativeEndian, LittleEndian};
2863 
2864                 #[test]
2865                 #[should_panic]
2866                 fn read_big_endian() {
2867                     let bytes = [0; $num_bytes];
2868                     let mut numbers = $numbers;
2869                     BigEndian::$read(&bytes, &mut numbers);
2870                 }
2871 
2872                 #[test]
2873                 #[should_panic]
2874                 fn read_little_endian() {
2875                     let bytes = [0; $num_bytes];
2876                     let mut numbers = $numbers;
2877                     LittleEndian::$read(&bytes, &mut numbers);
2878                 }
2879 
2880                 #[test]
2881                 #[should_panic]
2882                 fn read_native_endian() {
2883                     let bytes = [0; $num_bytes];
2884                     let mut numbers = $numbers;
2885                     NativeEndian::$read(&bytes, &mut numbers);
2886                 }
2887 
2888                 #[test]
2889                 #[should_panic]
2890                 fn write_big_endian() {
2891                     let mut bytes = [0; $num_bytes];
2892                     let numbers = $numbers;
2893                     BigEndian::$write(&numbers, &mut bytes);
2894                 }
2895 
2896                 #[test]
2897                 #[should_panic]
2898                 fn write_little_endian() {
2899                     let mut bytes = [0; $num_bytes];
2900                     let numbers = $numbers;
2901                     LittleEndian::$write(&numbers, &mut bytes);
2902                 }
2903 
2904                 #[test]
2905                 #[should_panic]
2906                 fn write_native_endian() {
2907                     let mut bytes = [0; $num_bytes];
2908                     let numbers = $numbers;
2909                     NativeEndian::$write(&numbers, &mut bytes);
2910                 }
2911             }
2912         }
2913     }
2914 
2915     slice_lengths!(
2916         slice_len_too_small_u16, read_u16_into, write_u16_into, 3, [0, 0]);
2917     slice_lengths!(
2918         slice_len_too_big_u16, read_u16_into, write_u16_into, 5, [0, 0]);
2919     slice_lengths!(
2920         slice_len_too_small_i16, read_i16_into, write_i16_into, 3, [0, 0]);
2921     slice_lengths!(
2922         slice_len_too_big_i16, read_i16_into, write_i16_into, 5, [0, 0]);
2923 
2924     slice_lengths!(
2925         slice_len_too_small_u32, read_u32_into, write_u32_into, 7, [0, 0]);
2926     slice_lengths!(
2927         slice_len_too_big_u32, read_u32_into, write_u32_into, 9, [0, 0]);
2928     slice_lengths!(
2929         slice_len_too_small_i32, read_i32_into, write_i32_into, 7, [0, 0]);
2930     slice_lengths!(
2931         slice_len_too_big_i32, read_i32_into, write_i32_into, 9, [0, 0]);
2932 
2933     slice_lengths!(
2934         slice_len_too_small_u64, read_u64_into, write_u64_into, 15, [0, 0]);
2935     slice_lengths!(
2936         slice_len_too_big_u64, read_u64_into, write_u64_into, 17, [0, 0]);
2937     slice_lengths!(
2938         slice_len_too_small_i64, read_i64_into, write_i64_into, 15, [0, 0]);
2939     slice_lengths!(
2940         slice_len_too_big_i64, read_i64_into, write_i64_into, 17, [0, 0]);
2941 
2942     #[cfg(byteorder_i128)]
2943     slice_lengths!(
2944         slice_len_too_small_u128, read_u128_into, write_u128_into, 31, [0, 0]);
2945     #[cfg(byteorder_i128)]
2946     slice_lengths!(
2947         slice_len_too_big_u128, read_u128_into, write_u128_into, 33, [0, 0]);
2948     #[cfg(byteorder_i128)]
2949     slice_lengths!(
2950         slice_len_too_small_i128, read_i128_into, write_i128_into, 31, [0, 0]);
2951     #[cfg(byteorder_i128)]
2952     slice_lengths!(
2953         slice_len_too_big_i128, read_i128_into, write_i128_into, 33, [0, 0]);
2954 
2955     #[test]
uint_bigger_buffer()2956     fn uint_bigger_buffer() {
2957         use {ByteOrder, LittleEndian};
2958         let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
2959         assert_eq!(n, 0x0504030201);
2960     }
2961 }
2962 
2963 #[cfg(test)]
2964 #[cfg(feature = "std")]
2965 mod stdtests {
2966     extern crate quickcheck;
2967     extern crate rand;
2968 
2969     use self::quickcheck::{QuickCheck, StdGen, Testable};
2970     use self::rand::thread_rng;
2971 
qc_unsized<A: Testable>(f: A)2972     fn qc_unsized<A: Testable>(f: A) {
2973 
2974         QuickCheck::new()
2975             .gen(StdGen::new(thread_rng(), 16))
2976             .tests(1_00)
2977             .max_tests(10_000)
2978             .quickcheck(f);
2979     }
2980 
2981     macro_rules! calc_max {
2982         ($max:expr, $bytes:expr) => { ($max - 1) >> (8 * (8 - $bytes)) };
2983     }
2984 
2985     macro_rules! qc_bytes_ext {
2986         ($name:ident, $ty_int:ty, $max:expr,
2987          $bytes:expr, $read:ident, $write:ident) => (
2988             mod $name {
2989                 use std::io::Cursor;
2990                 use {
2991                     ReadBytesExt, WriteBytesExt,
2992                     BigEndian, NativeEndian, LittleEndian,
2993                 };
2994                 #[allow(unused_imports)] use test::{qc_sized, Wi128};
2995 
2996                 #[test]
2997                 fn big_endian() {
2998                     fn prop(n: $ty_int) -> bool {
2999                         let mut wtr = vec![];
3000                         wtr.$write::<BigEndian>(n.clone()).unwrap();
3001                         let offset = wtr.len() - $bytes;
3002                         let mut rdr = Cursor::new(&mut wtr[offset..]);
3003                         n == rdr.$read::<BigEndian>($bytes).unwrap()
3004                     }
3005                     qc_sized(prop as fn($ty_int) -> bool, $max);
3006                 }
3007 
3008                 #[test]
3009                 fn little_endian() {
3010                     fn prop(n: $ty_int) -> bool {
3011                         let mut wtr = vec![];
3012                         wtr.$write::<LittleEndian>(n.clone()).unwrap();
3013                         let mut rdr = Cursor::new(wtr);
3014                         n == rdr.$read::<LittleEndian>($bytes).unwrap()
3015                     }
3016                     qc_sized(prop as fn($ty_int) -> bool, $max);
3017                 }
3018 
3019                 #[test]
3020                 fn native_endian() {
3021                     fn prop(n: $ty_int) -> bool {
3022                         let mut wtr = vec![];
3023                         wtr.$write::<NativeEndian>(n.clone()).unwrap();
3024                         let offset = if cfg!(target_endian = "big") {
3025                             wtr.len() - $bytes
3026                         } else {
3027                             0
3028                         };
3029                         let mut rdr = Cursor::new(&mut wtr[offset..]);
3030                         n == rdr.$read::<NativeEndian>($bytes).unwrap()
3031                     }
3032                     qc_sized(prop as fn($ty_int) -> bool, $max);
3033                 }
3034             }
3035         );
3036         ($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => (
3037             mod $name {
3038                 use std::io::Cursor;
3039                 use {
3040                     ReadBytesExt, WriteBytesExt,
3041                     BigEndian, NativeEndian, LittleEndian,
3042                 };
3043                 #[allow(unused_imports)] use test::{qc_sized, Wi128};
3044 
3045                 #[test]
3046                 fn big_endian() {
3047                     fn prop(n: $ty_int) -> bool {
3048                         let mut wtr = vec![];
3049                         wtr.$write::<BigEndian>(n.clone()).unwrap();
3050                         let mut rdr = Cursor::new(wtr);
3051                         n == rdr.$read::<BigEndian>().unwrap()
3052                     }
3053                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
3054                 }
3055 
3056                 #[test]
3057                 fn little_endian() {
3058                     fn prop(n: $ty_int) -> bool {
3059                         let mut wtr = vec![];
3060                         wtr.$write::<LittleEndian>(n.clone()).unwrap();
3061                         let mut rdr = Cursor::new(wtr);
3062                         n == rdr.$read::<LittleEndian>().unwrap()
3063                     }
3064                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
3065                 }
3066 
3067                 #[test]
3068                 fn native_endian() {
3069                     fn prop(n: $ty_int) -> bool {
3070                         let mut wtr = vec![];
3071                         wtr.$write::<NativeEndian>(n.clone()).unwrap();
3072                         let mut rdr = Cursor::new(wtr);
3073                         n == rdr.$read::<NativeEndian>().unwrap()
3074                     }
3075                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
3076                 }
3077             }
3078         );
3079     }
3080 
3081     qc_bytes_ext!(prop_ext_u16,
3082         u16, ::std::u16::MAX as u64, read_u16, write_u16);
3083     qc_bytes_ext!(prop_ext_i16,
3084         i16, ::std::i16::MAX as u64, read_i16, write_i16);
3085     qc_bytes_ext!(prop_ext_u32,
3086         u32, ::std::u32::MAX as u64, read_u32, write_u32);
3087     qc_bytes_ext!(prop_ext_i32,
3088         i32, ::std::i32::MAX as u64, read_i32, write_i32);
3089     qc_bytes_ext!(prop_ext_u64,
3090         u64, ::std::u64::MAX as u64, read_u64, write_u64);
3091     qc_bytes_ext!(prop_ext_i64,
3092         i64, ::std::i64::MAX as u64, read_i64, write_i64);
3093     qc_bytes_ext!(prop_ext_f32,
3094         f32, ::std::u64::MAX as u64, read_f32, write_f32);
3095     qc_bytes_ext!(prop_ext_f64,
3096         f64, ::std::i64::MAX as u64, read_f64, write_f64);
3097 
3098     #[cfg(byteorder_i128)]
3099     qc_bytes_ext!(prop_ext_u128, Wi128<u128>, 16 + 1, read_u128, write_u128);
3100     #[cfg(byteorder_i128)]
3101     qc_bytes_ext!(prop_ext_i128, Wi128<i128>, 16 + 1, read_i128, write_i128);
3102 
3103     qc_bytes_ext!(prop_ext_uint_1,
3104         u64, calc_max!(::test::U64_MAX, 1), 1, read_uint, write_u64);
3105     qc_bytes_ext!(prop_ext_uint_2,
3106         u64, calc_max!(::test::U64_MAX, 2), 2, read_uint, write_u64);
3107     qc_bytes_ext!(prop_ext_uint_3,
3108         u64, calc_max!(::test::U64_MAX, 3), 3, read_uint, write_u64);
3109     qc_bytes_ext!(prop_ext_uint_4,
3110         u64, calc_max!(::test::U64_MAX, 4), 4, read_uint, write_u64);
3111     qc_bytes_ext!(prop_ext_uint_5,
3112         u64, calc_max!(::test::U64_MAX, 5), 5, read_uint, write_u64);
3113     qc_bytes_ext!(prop_ext_uint_6,
3114         u64, calc_max!(::test::U64_MAX, 6), 6, read_uint, write_u64);
3115     qc_bytes_ext!(prop_ext_uint_7,
3116         u64, calc_max!(::test::U64_MAX, 7), 7, read_uint, write_u64);
3117     qc_bytes_ext!(prop_ext_uint_8,
3118         u64, calc_max!(::test::U64_MAX, 8), 8, read_uint, write_u64);
3119 
3120     #[cfg(byteorder_i128)]
3121     qc_bytes_ext!(prop_ext_uint128_1,
3122         Wi128<u128>, 1, 1, read_uint128, write_u128);
3123     #[cfg(byteorder_i128)]
3124     qc_bytes_ext!(prop_ext_uint128_2,
3125         Wi128<u128>, 2, 2, read_uint128, write_u128);
3126     #[cfg(byteorder_i128)]
3127     qc_bytes_ext!(prop_ext_uint128_3,
3128         Wi128<u128>, 3, 3, read_uint128, write_u128);
3129     #[cfg(byteorder_i128)]
3130     qc_bytes_ext!(prop_ext_uint128_4,
3131         Wi128<u128>, 4, 4, read_uint128, write_u128);
3132     #[cfg(byteorder_i128)]
3133     qc_bytes_ext!(prop_ext_uint128_5,
3134         Wi128<u128>, 5, 5, read_uint128, write_u128);
3135     #[cfg(byteorder_i128)]
3136     qc_bytes_ext!(prop_ext_uint128_6,
3137         Wi128<u128>, 6, 6, read_uint128, write_u128);
3138     #[cfg(byteorder_i128)]
3139     qc_bytes_ext!(prop_ext_uint128_7,
3140         Wi128<u128>, 7, 7, read_uint128, write_u128);
3141     #[cfg(byteorder_i128)]
3142     qc_bytes_ext!(prop_ext_uint128_8,
3143         Wi128<u128>, 8, 8, read_uint128, write_u128);
3144     #[cfg(byteorder_i128)]
3145     qc_bytes_ext!(prop_ext_uint128_9,
3146         Wi128<u128>, 9, 9, read_uint128, write_u128);
3147     #[cfg(byteorder_i128)]
3148     qc_bytes_ext!(prop_ext_uint128_10,
3149         Wi128<u128>, 10, 10, read_uint128, write_u128);
3150     #[cfg(byteorder_i128)]
3151     qc_bytes_ext!(prop_ext_uint128_11,
3152         Wi128<u128>, 11, 11, read_uint128, write_u128);
3153     #[cfg(byteorder_i128)]
3154     qc_bytes_ext!(prop_ext_uint128_12,
3155         Wi128<u128>, 12, 12, read_uint128, write_u128);
3156     #[cfg(byteorder_i128)]
3157     qc_bytes_ext!(prop_ext_uint128_13,
3158         Wi128<u128>, 13, 13, read_uint128, write_u128);
3159     #[cfg(byteorder_i128)]
3160     qc_bytes_ext!(prop_ext_uint128_14,
3161         Wi128<u128>, 14, 14, read_uint128, write_u128);
3162     #[cfg(byteorder_i128)]
3163     qc_bytes_ext!(prop_ext_uint128_15,
3164         Wi128<u128>, 15, 15, read_uint128, write_u128);
3165     #[cfg(byteorder_i128)]
3166     qc_bytes_ext!(prop_ext_uint128_16,
3167         Wi128<u128>, 16, 16, read_uint128, write_u128);
3168 
3169     qc_bytes_ext!(prop_ext_int_1,
3170         i64, calc_max!(::test::I64_MAX, 1), 1, read_int, write_i64);
3171     qc_bytes_ext!(prop_ext_int_2,
3172         i64, calc_max!(::test::I64_MAX, 2), 2, read_int, write_i64);
3173     qc_bytes_ext!(prop_ext_int_3,
3174         i64, calc_max!(::test::I64_MAX, 3), 3, read_int, write_i64);
3175     qc_bytes_ext!(prop_ext_int_4,
3176         i64, calc_max!(::test::I64_MAX, 4), 4, read_int, write_i64);
3177     qc_bytes_ext!(prop_ext_int_5,
3178         i64, calc_max!(::test::I64_MAX, 5), 5, read_int, write_i64);
3179     qc_bytes_ext!(prop_ext_int_6,
3180         i64, calc_max!(::test::I64_MAX, 6), 6, read_int, write_i64);
3181     qc_bytes_ext!(prop_ext_int_7,
3182         i64, calc_max!(::test::I64_MAX, 1), 7, read_int, write_i64);
3183     qc_bytes_ext!(prop_ext_int_8,
3184         i64, calc_max!(::test::I64_MAX, 8), 8, read_int, write_i64);
3185 
3186     #[cfg(byteorder_i128)]
3187     qc_bytes_ext!(prop_ext_int128_1,
3188         Wi128<i128>, 1, 1, read_int128, write_i128);
3189     #[cfg(byteorder_i128)]
3190     qc_bytes_ext!(prop_ext_int128_2,
3191         Wi128<i128>, 2, 2, read_int128, write_i128);
3192     #[cfg(byteorder_i128)]
3193     qc_bytes_ext!(prop_ext_int128_3,
3194         Wi128<i128>, 3, 3, read_int128, write_i128);
3195     #[cfg(byteorder_i128)]
3196     qc_bytes_ext!(prop_ext_int128_4,
3197         Wi128<i128>, 4, 4, read_int128, write_i128);
3198     #[cfg(byteorder_i128)]
3199     qc_bytes_ext!(prop_ext_int128_5,
3200         Wi128<i128>, 5, 5, read_int128, write_i128);
3201     #[cfg(byteorder_i128)]
3202     qc_bytes_ext!(prop_ext_int128_6,
3203         Wi128<i128>, 6, 6, read_int128, write_i128);
3204     #[cfg(byteorder_i128)]
3205     qc_bytes_ext!(prop_ext_int128_7,
3206         Wi128<i128>, 7, 7, read_int128, write_i128);
3207     #[cfg(byteorder_i128)]
3208     qc_bytes_ext!(prop_ext_int128_8,
3209         Wi128<i128>, 8, 8, read_int128, write_i128);
3210     #[cfg(byteorder_i128)]
3211     qc_bytes_ext!(prop_ext_int128_9,
3212         Wi128<i128>, 9, 9, read_int128, write_i128);
3213     #[cfg(byteorder_i128)]
3214     qc_bytes_ext!(prop_ext_int128_10,
3215         Wi128<i128>, 10, 10, read_int128, write_i128);
3216     #[cfg(byteorder_i128)]
3217     qc_bytes_ext!(prop_ext_int128_11,
3218         Wi128<i128>, 11, 11, read_int128, write_i128);
3219     #[cfg(byteorder_i128)]
3220     qc_bytes_ext!(prop_ext_int128_12,
3221         Wi128<i128>, 12, 12, read_int128, write_i128);
3222     #[cfg(byteorder_i128)]
3223     qc_bytes_ext!(prop_ext_int128_13,
3224         Wi128<i128>, 13, 13, read_int128, write_i128);
3225     #[cfg(byteorder_i128)]
3226     qc_bytes_ext!(prop_ext_int128_14,
3227         Wi128<i128>, 14, 14, read_int128, write_i128);
3228     #[cfg(byteorder_i128)]
3229     qc_bytes_ext!(prop_ext_int128_15,
3230         Wi128<i128>, 15, 15, read_int128, write_i128);
3231     #[cfg(byteorder_i128)]
3232     qc_bytes_ext!(prop_ext_int128_16,
3233         Wi128<i128>, 16, 16, read_int128, write_i128);
3234 
3235     // Test slice serialization/deserialization.
3236     macro_rules! qc_slice {
3237         ($name:ident, $ty_int:ty, $read:ident, $write:ident, $zero:expr) => {
3238             mod $name {
3239                 use core::mem::size_of;
3240                 use {ByteOrder, BigEndian, NativeEndian, LittleEndian};
3241                 use super::qc_unsized;
3242                 #[allow(unused_imports)]
3243                 use test::Wi128;
3244 
3245                 #[test]
3246                 fn big_endian() {
3247                     #[allow(unused_unsafe)]
3248                     fn prop(numbers: Vec<$ty_int>) -> bool {
3249                         let numbers: Vec<_> = numbers
3250                             .into_iter()
3251                             .map(|x| x.clone())
3252                             .collect();
3253                         let num_bytes = size_of::<$ty_int>() * numbers.len();
3254                         let mut bytes = vec![0; num_bytes];
3255 
3256                         BigEndian::$write(&numbers, &mut bytes);
3257 
3258                         let mut got = vec![$zero; numbers.len()];
3259                         unsafe { BigEndian::$read(&bytes, &mut got); }
3260 
3261                         numbers == got
3262                     }
3263                     qc_unsized(prop as fn(_) -> bool);
3264                 }
3265 
3266                 #[test]
3267                 fn little_endian() {
3268                     #[allow(unused_unsafe)]
3269                     fn prop(numbers: Vec<$ty_int>) -> bool {
3270                         let numbers: Vec<_> = numbers
3271                             .into_iter()
3272                             .map(|x| x.clone())
3273                             .collect();
3274                         let num_bytes = size_of::<$ty_int>() * numbers.len();
3275                         let mut bytes = vec![0; num_bytes];
3276 
3277                         LittleEndian::$write(&numbers, &mut bytes);
3278 
3279                         let mut got = vec![$zero; numbers.len()];
3280                         unsafe { LittleEndian::$read(&bytes, &mut got); }
3281 
3282                         numbers == got
3283                     }
3284                     qc_unsized(prop as fn(_) -> bool);
3285                 }
3286 
3287                 #[test]
3288                 fn native_endian() {
3289                     #[allow(unused_unsafe)]
3290                     fn prop(numbers: Vec<$ty_int>) -> bool {
3291                         let numbers: Vec<_> = numbers
3292                             .into_iter()
3293                             .map(|x| x.clone())
3294                             .collect();
3295                         let num_bytes = size_of::<$ty_int>() * numbers.len();
3296                         let mut bytes = vec![0; num_bytes];
3297 
3298                         NativeEndian::$write(&numbers, &mut bytes);
3299 
3300                         let mut got = vec![$zero; numbers.len()];
3301                         unsafe { NativeEndian::$read(&bytes, &mut got); }
3302 
3303                         numbers == got
3304                     }
3305                     qc_unsized(prop as fn(_) -> bool);
3306                 }
3307             }
3308         }
3309     }
3310 
3311     qc_slice!(prop_slice_u16, u16, read_u16_into, write_u16_into, 0);
3312     qc_slice!(prop_slice_i16, i16, read_i16_into, write_i16_into, 0);
3313     qc_slice!(prop_slice_u32, u32, read_u32_into, write_u32_into, 0);
3314     qc_slice!(prop_slice_i32, i32, read_i32_into, write_i32_into, 0);
3315     qc_slice!(prop_slice_u64, u64, read_u64_into, write_u64_into, 0);
3316     qc_slice!(prop_slice_i64, i64, read_i64_into, write_i64_into, 0);
3317     #[cfg(byteorder_i128)]
3318     qc_slice!(
3319         prop_slice_u128, Wi128<u128>, read_u128_into, write_u128_into, 0);
3320     #[cfg(byteorder_i128)]
3321     qc_slice!(
3322         prop_slice_i128, Wi128<i128>, read_i128_into, write_i128_into, 0);
3323 
3324     qc_slice!(
3325         prop_slice_f32, f32, read_f32_into, write_f32_into, 0.0);
3326     qc_slice!(
3327         prop_slice_f64, f64, read_f64_into, write_f64_into, 0.0);
3328 }
3329