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