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