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