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