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}