byteorder/
lib.rs

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