byteorder/
io.rs

1use std::{
2    io::{self, Result},
3    slice,
4};
5
6use crate::ByteOrder;
7
8/// Extends [`Read`] with methods for reading numbers. (For `std::io`.)
9///
10/// Most of the methods defined here have an unconstrained type parameter that
11/// must be explicitly instantiated. Typically, it is instantiated with either
12/// the [`BigEndian`] or [`LittleEndian`] types defined in this crate.
13///
14/// # Examples
15///
16/// Read unsigned 16 bit big-endian integers from a [`Read`]:
17///
18/// ```rust
19/// use std::io::Cursor;
20/// use byteorder::{BigEndian, ReadBytesExt};
21///
22/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
23/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
24/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
25/// ```
26///
27/// [`BigEndian`]: enum.BigEndian.html
28/// [`LittleEndian`]: enum.LittleEndian.html
29/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
30pub trait ReadBytesExt: io::Read {
31    /// Reads an unsigned 8 bit integer from the underlying reader.
32    ///
33    /// Note that since this reads a single byte, no byte order conversions
34    /// are used. It is included for completeness.
35    ///
36    /// # Errors
37    ///
38    /// This method returns the same errors as [`Read::read_exact`].
39    ///
40    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
41    ///
42    /// # Examples
43    ///
44    /// Read unsigned 8 bit integers from a `Read`:
45    ///
46    /// ```rust
47    /// use std::io::Cursor;
48    /// use byteorder::ReadBytesExt;
49    ///
50    /// let mut rdr = Cursor::new(vec![2, 5]);
51    /// assert_eq!(2, rdr.read_u8().unwrap());
52    /// assert_eq!(5, rdr.read_u8().unwrap());
53    /// ```
54    #[inline]
55    fn read_u8(&mut self) -> Result<u8> {
56        let mut buf = [0; 1];
57        self.read_exact(&mut buf)?;
58        Ok(buf[0])
59    }
60
61    /// Reads a signed 8 bit integer from the underlying reader.
62    ///
63    /// Note that since this reads a single byte, no byte order conversions
64    /// are used. It is included for completeness.
65    ///
66    /// # Errors
67    ///
68    /// This method returns the same errors as [`Read::read_exact`].
69    ///
70    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
71    ///
72    /// # Examples
73    ///
74    /// Read signed 8 bit integers from a `Read`:
75    ///
76    /// ```rust
77    /// use std::io::Cursor;
78    /// use byteorder::ReadBytesExt;
79    ///
80    /// let mut rdr = Cursor::new(vec![0x02, 0xfb]);
81    /// assert_eq!(2, rdr.read_i8().unwrap());
82    /// assert_eq!(-5, rdr.read_i8().unwrap());
83    /// ```
84    #[inline]
85    fn read_i8(&mut self) -> Result<i8> {
86        let mut buf = [0; 1];
87        self.read_exact(&mut buf)?;
88        Ok(buf[0] as i8)
89    }
90
91    /// Reads an unsigned 16 bit integer from the underlying reader.
92    ///
93    /// # Errors
94    ///
95    /// This method returns the same errors as [`Read::read_exact`].
96    ///
97    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
98    ///
99    /// # Examples
100    ///
101    /// Read unsigned 16 bit big-endian integers from a `Read`:
102    ///
103    /// ```rust
104    /// use std::io::Cursor;
105    /// use byteorder::{BigEndian, ReadBytesExt};
106    ///
107    /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
108    /// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
109    /// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
110    /// ```
111    #[inline]
112    fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
113        let mut buf = [0; 2];
114        self.read_exact(&mut buf)?;
115        Ok(T::read_u16(&buf))
116    }
117
118    /// Reads a signed 16 bit integer from the underlying reader.
119    ///
120    /// # Errors
121    ///
122    /// This method returns the same errors as [`Read::read_exact`].
123    ///
124    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
125    ///
126    /// # Examples
127    ///
128    /// Read signed 16 bit big-endian integers from a `Read`:
129    ///
130    /// ```rust
131    /// use std::io::Cursor;
132    /// use byteorder::{BigEndian, ReadBytesExt};
133    ///
134    /// let mut rdr = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]);
135    /// assert_eq!(193, rdr.read_i16::<BigEndian>().unwrap());
136    /// assert_eq!(-132, rdr.read_i16::<BigEndian>().unwrap());
137    /// ```
138    #[inline]
139    fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
140        let mut buf = [0; 2];
141        self.read_exact(&mut buf)?;
142        Ok(T::read_i16(&buf))
143    }
144
145    /// Reads an unsigned 24 bit integer from the underlying reader.
146    ///
147    /// # Errors
148    ///
149    /// This method returns the same errors as [`Read::read_exact`].
150    ///
151    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
152    ///
153    /// # Examples
154    ///
155    /// Read unsigned 24 bit big-endian integers from a `Read`:
156    ///
157    /// ```rust
158    /// use std::io::Cursor;
159    /// use byteorder::{BigEndian, ReadBytesExt};
160    ///
161    /// let mut rdr = Cursor::new(vec![0x00, 0x01, 0x0b]);
162    /// assert_eq!(267, rdr.read_u24::<BigEndian>().unwrap());
163    /// ```
164    #[inline]
165    fn read_u24<T: ByteOrder>(&mut self) -> Result<u32> {
166        let mut buf = [0; 3];
167        self.read_exact(&mut buf)?;
168        Ok(T::read_u24(&buf))
169    }
170
171    /// Reads a signed 24 bit integer from the underlying reader.
172    ///
173    /// # Errors
174    ///
175    /// This method returns the same errors as [`Read::read_exact`].
176    ///
177    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
178    ///
179    /// # Examples
180    ///
181    /// Read signed 24 bit big-endian integers from a `Read`:
182    ///
183    /// ```rust
184    /// use std::io::Cursor;
185    /// use byteorder::{BigEndian, ReadBytesExt};
186    ///
187    /// let mut rdr = Cursor::new(vec![0xff, 0x7a, 0x33]);
188    /// assert_eq!(-34253, rdr.read_i24::<BigEndian>().unwrap());
189    /// ```
190    #[inline]
191    fn read_i24<T: ByteOrder>(&mut self) -> Result<i32> {
192        let mut buf = [0; 3];
193        self.read_exact(&mut buf)?;
194        Ok(T::read_i24(&buf))
195    }
196
197    /// Reads an unsigned 32 bit integer from the underlying reader.
198    ///
199    /// # Errors
200    ///
201    /// This method returns the same errors as [`Read::read_exact`].
202    ///
203    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
204    ///
205    /// # Examples
206    ///
207    /// Read unsigned 32 bit big-endian integers from a `Read`:
208    ///
209    /// ```rust
210    /// use std::io::Cursor;
211    /// use byteorder::{BigEndian, ReadBytesExt};
212    ///
213    /// let mut rdr = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]);
214    /// assert_eq!(267, rdr.read_u32::<BigEndian>().unwrap());
215    /// ```
216    #[inline]
217    fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
218        let mut buf = [0; 4];
219        self.read_exact(&mut buf)?;
220        Ok(T::read_u32(&buf))
221    }
222
223    /// Reads a signed 32 bit integer from the underlying reader.
224    ///
225    /// # Errors
226    ///
227    /// This method returns the same errors as [`Read::read_exact`].
228    ///
229    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
230    ///
231    /// # Examples
232    ///
233    /// Read signed 32 bit big-endian integers from a `Read`:
234    ///
235    /// ```rust
236    /// use std::io::Cursor;
237    /// use byteorder::{BigEndian, ReadBytesExt};
238    ///
239    /// let mut rdr = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]);
240    /// assert_eq!(-34253, rdr.read_i32::<BigEndian>().unwrap());
241    /// ```
242    #[inline]
243    fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
244        let mut buf = [0; 4];
245        self.read_exact(&mut buf)?;
246        Ok(T::read_i32(&buf))
247    }
248
249    /// Reads an unsigned 48 bit integer from the underlying reader.
250    ///
251    /// # Errors
252    ///
253    /// This method returns the same errors as [`Read::read_exact`].
254    ///
255    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
256    ///
257    /// # Examples
258    ///
259    /// Read unsigned 48 bit big-endian integers from a `Read`:
260    ///
261    /// ```rust
262    /// use std::io::Cursor;
263    /// use byteorder::{BigEndian, ReadBytesExt};
264    ///
265    /// let mut rdr = Cursor::new(vec![0xb6, 0x71, 0x6b, 0xdc, 0x2b, 0x31]);
266    /// assert_eq!(200598257150769, rdr.read_u48::<BigEndian>().unwrap());
267    /// ```
268    #[inline]
269    fn read_u48<T: ByteOrder>(&mut self) -> Result<u64> {
270        let mut buf = [0; 6];
271        self.read_exact(&mut buf)?;
272        Ok(T::read_u48(&buf))
273    }
274
275    /// Reads a signed 48 bit integer from the underlying reader.
276    ///
277    /// # Errors
278    ///
279    /// This method returns the same errors as [`Read::read_exact`].
280    ///
281    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
282    ///
283    /// # Examples
284    ///
285    /// Read signed 48 bit big-endian integers from a `Read`:
286    ///
287    /// ```rust
288    /// use std::io::Cursor;
289    /// use byteorder::{BigEndian, ReadBytesExt};
290    ///
291    /// let mut rdr = Cursor::new(vec![0x9d, 0x71, 0xab, 0xe7, 0x97, 0x8f]);
292    /// assert_eq!(-108363435763825, rdr.read_i48::<BigEndian>().unwrap());
293    /// ```
294    #[inline]
295    fn read_i48<T: ByteOrder>(&mut self) -> Result<i64> {
296        let mut buf = [0; 6];
297        self.read_exact(&mut buf)?;
298        Ok(T::read_i48(&buf))
299    }
300
301    /// Reads an unsigned 64 bit integer from the underlying reader.
302    ///
303    /// # Errors
304    ///
305    /// This method returns the same errors as [`Read::read_exact`].
306    ///
307    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
308    ///
309    /// # Examples
310    ///
311    /// Read an unsigned 64 bit big-endian integer from a `Read`:
312    ///
313    /// ```rust
314    /// use std::io::Cursor;
315    /// use byteorder::{BigEndian, ReadBytesExt};
316    ///
317    /// let mut rdr = Cursor::new(vec![0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83]);
318    /// assert_eq!(918733457491587, rdr.read_u64::<BigEndian>().unwrap());
319    /// ```
320    #[inline]
321    fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
322        let mut buf = [0; 8];
323        self.read_exact(&mut buf)?;
324        Ok(T::read_u64(&buf))
325    }
326
327    /// Reads a signed 64 bit integer from the underlying reader.
328    ///
329    /// # Errors
330    ///
331    /// This method returns the same errors as [`Read::read_exact`].
332    ///
333    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
334    ///
335    /// # Examples
336    ///
337    /// Read a signed 64 bit big-endian integer from a `Read`:
338    ///
339    /// ```rust
340    /// use std::io::Cursor;
341    /// use byteorder::{BigEndian, ReadBytesExt};
342    ///
343    /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]);
344    /// assert_eq!(i64::min_value(), rdr.read_i64::<BigEndian>().unwrap());
345    /// ```
346    #[inline]
347    fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
348        let mut buf = [0; 8];
349        self.read_exact(&mut buf)?;
350        Ok(T::read_i64(&buf))
351    }
352
353    /// Reads an unsigned 128 bit integer from the underlying reader.
354    ///
355    /// # Errors
356    ///
357    /// This method returns the same errors as [`Read::read_exact`].
358    ///
359    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
360    ///
361    /// # Examples
362    ///
363    /// Read an unsigned 128 bit big-endian integer from a `Read`:
364    ///
365    /// ```rust
366    /// use std::io::Cursor;
367    /// use byteorder::{BigEndian, ReadBytesExt};
368    ///
369    /// let mut rdr = Cursor::new(vec![
370    ///     0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83,
371    ///     0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83
372    /// ]);
373    /// assert_eq!(16947640962301618749969007319746179, rdr.read_u128::<BigEndian>().unwrap());
374    /// ```
375    #[inline]
376    fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> {
377        let mut buf = [0; 16];
378        self.read_exact(&mut buf)?;
379        Ok(T::read_u128(&buf))
380    }
381
382    /// Reads a signed 128 bit integer from the underlying reader.
383    ///
384    /// # Errors
385    ///
386    /// This method returns the same errors as [`Read::read_exact`].
387    ///
388    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
389    ///
390    /// # Examples
391    ///
392    /// Read a signed 128 bit big-endian integer from a `Read`:
393    ///
394    /// ```rust
395    /// use std::io::Cursor;
396    /// use byteorder::{BigEndian, ReadBytesExt};
397    ///
398    /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
399    /// assert_eq!(i128::min_value(), rdr.read_i128::<BigEndian>().unwrap());
400    /// ```
401    #[inline]
402    fn read_i128<T: ByteOrder>(&mut self) -> Result<i128> {
403        let mut buf = [0; 16];
404        self.read_exact(&mut buf)?;
405        Ok(T::read_i128(&buf))
406    }
407
408    /// Reads an unsigned n-bytes integer from the underlying reader.
409    ///
410    /// # Errors
411    ///
412    /// This method returns the same errors as [`Read::read_exact`].
413    ///
414    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
415    ///
416    /// # Examples
417    ///
418    /// Read an unsigned n-byte big-endian integer from a `Read`:
419    ///
420    /// ```rust
421    /// use std::io::Cursor;
422    /// use byteorder::{BigEndian, ReadBytesExt};
423    ///
424    /// let mut rdr = Cursor::new(vec![0x80, 0x74, 0xfa]);
425    /// assert_eq!(8418554, rdr.read_uint::<BigEndian>(3).unwrap());
426    #[inline]
427    fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
428        let mut buf = [0; 8];
429        self.read_exact(&mut buf[..nbytes])?;
430        Ok(T::read_uint(&buf[..nbytes], nbytes))
431    }
432
433    /// Reads a signed n-bytes integer from the underlying reader.
434    ///
435    /// # Errors
436    ///
437    /// This method returns the same errors as [`Read::read_exact`].
438    ///
439    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
440    ///
441    /// # Examples
442    ///
443    /// Read an unsigned n-byte big-endian integer from a `Read`:
444    ///
445    /// ```rust
446    /// use std::io::Cursor;
447    /// use byteorder::{BigEndian, ReadBytesExt};
448    ///
449    /// let mut rdr = Cursor::new(vec![0xc1, 0xff, 0x7c]);
450    /// assert_eq!(-4063364, rdr.read_int::<BigEndian>(3).unwrap());
451    #[inline]
452    fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
453        let mut buf = [0; 8];
454        self.read_exact(&mut buf[..nbytes])?;
455        Ok(T::read_int(&buf[..nbytes], nbytes))
456    }
457
458    /// Reads an unsigned n-bytes integer from the underlying reader.
459    #[inline]
460    fn read_uint128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u128> {
461        let mut buf = [0; 16];
462        self.read_exact(&mut buf[..nbytes])?;
463        Ok(T::read_uint128(&buf[..nbytes], nbytes))
464    }
465
466    /// Reads a signed n-bytes integer from the underlying reader.
467    #[inline]
468    fn read_int128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i128> {
469        let mut buf = [0; 16];
470        self.read_exact(&mut buf[..nbytes])?;
471        Ok(T::read_int128(&buf[..nbytes], nbytes))
472    }
473
474    /// Reads a IEEE754 single-precision (4 bytes) floating point number from
475    /// the underlying reader.
476    ///
477    /// # Errors
478    ///
479    /// This method returns the same errors as [`Read::read_exact`].
480    ///
481    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
482    ///
483    /// # Examples
484    ///
485    /// Read a big-endian single-precision floating point number from a `Read`:
486    ///
487    /// ```rust
488    /// use std::f32;
489    /// use std::io::Cursor;
490    ///
491    /// use byteorder::{BigEndian, ReadBytesExt};
492    ///
493    /// let mut rdr = Cursor::new(vec![
494    ///     0x40, 0x49, 0x0f, 0xdb,
495    /// ]);
496    /// assert_eq!(f32::consts::PI, rdr.read_f32::<BigEndian>().unwrap());
497    /// ```
498    #[inline]
499    fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
500        let mut buf = [0; 4];
501        self.read_exact(&mut buf)?;
502        Ok(T::read_f32(&buf))
503    }
504
505    /// Reads a IEEE754 double-precision (8 bytes) floating point number from
506    /// the underlying reader.
507    ///
508    /// # Errors
509    ///
510    /// This method returns the same errors as [`Read::read_exact`].
511    ///
512    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
513    ///
514    /// # Examples
515    ///
516    /// Read a big-endian double-precision floating point number from a `Read`:
517    ///
518    /// ```rust
519    /// use std::f64;
520    /// use std::io::Cursor;
521    ///
522    /// use byteorder::{BigEndian, ReadBytesExt};
523    ///
524    /// let mut rdr = Cursor::new(vec![
525    ///     0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
526    /// ]);
527    /// assert_eq!(f64::consts::PI, rdr.read_f64::<BigEndian>().unwrap());
528    /// ```
529    #[inline]
530    fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
531        let mut buf = [0; 8];
532        self.read_exact(&mut buf)?;
533        Ok(T::read_f64(&buf))
534    }
535
536    /// Reads a sequence of unsigned 16 bit integers from the underlying
537    /// reader.
538    ///
539    /// The given buffer is either filled completely or an error is returned.
540    /// If an error is returned, the contents of `dst` are unspecified.
541    ///
542    /// # Errors
543    ///
544    /// This method returns the same errors as [`Read::read_exact`].
545    ///
546    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
547    ///
548    /// # Examples
549    ///
550    /// Read a sequence of unsigned 16 bit big-endian integers from a `Read`:
551    ///
552    /// ```rust
553    /// use std::io::Cursor;
554    /// use byteorder::{BigEndian, ReadBytesExt};
555    ///
556    /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
557    /// let mut dst = [0; 2];
558    /// rdr.read_u16_into::<BigEndian>(&mut dst).unwrap();
559    /// assert_eq!([517, 768], dst);
560    /// ```
561    #[inline]
562    fn read_u16_into<T: ByteOrder>(&mut self, dst: &mut [u16]) -> Result<()> {
563        {
564            let buf = unsafe { slice_to_u8_mut(dst) };
565            self.read_exact(buf)?;
566        }
567        T::from_slice_u16(dst);
568        Ok(())
569    }
570
571    /// Reads a sequence of unsigned 32 bit integers from the underlying
572    /// reader.
573    ///
574    /// The given buffer is either filled completely or an error is returned.
575    /// If an error is returned, the contents of `dst` are unspecified.
576    ///
577    /// # Errors
578    ///
579    /// This method returns the same errors as [`Read::read_exact`].
580    ///
581    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
582    ///
583    /// # Examples
584    ///
585    /// Read a sequence of unsigned 32 bit big-endian integers from a `Read`:
586    ///
587    /// ```rust
588    /// use std::io::Cursor;
589    /// use byteorder::{BigEndian, ReadBytesExt};
590    ///
591    /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]);
592    /// let mut dst = [0; 2];
593    /// rdr.read_u32_into::<BigEndian>(&mut dst).unwrap();
594    /// assert_eq!([517, 768], dst);
595    /// ```
596    #[inline]
597    fn read_u32_into<T: ByteOrder>(&mut self, dst: &mut [u32]) -> Result<()> {
598        {
599            let buf = unsafe { slice_to_u8_mut(dst) };
600            self.read_exact(buf)?;
601        }
602        T::from_slice_u32(dst);
603        Ok(())
604    }
605
606    /// Reads a sequence of unsigned 64 bit integers from the underlying
607    /// reader.
608    ///
609    /// The given buffer is either filled completely or an error is returned.
610    /// If an error is returned, the contents of `dst` are unspecified.
611    ///
612    /// # Errors
613    ///
614    /// This method returns the same errors as [`Read::read_exact`].
615    ///
616    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
617    ///
618    /// # Examples
619    ///
620    /// Read a sequence of unsigned 64 bit big-endian integers from a `Read`:
621    ///
622    /// ```rust
623    /// use std::io::Cursor;
624    /// use byteorder::{BigEndian, ReadBytesExt};
625    ///
626    /// let mut rdr = Cursor::new(vec![
627    ///     0, 0, 0, 0, 0, 0, 2, 5,
628    ///     0, 0, 0, 0, 0, 0, 3, 0,
629    /// ]);
630    /// let mut dst = [0; 2];
631    /// rdr.read_u64_into::<BigEndian>(&mut dst).unwrap();
632    /// assert_eq!([517, 768], dst);
633    /// ```
634    #[inline]
635    fn read_u64_into<T: ByteOrder>(&mut self, dst: &mut [u64]) -> Result<()> {
636        {
637            let buf = unsafe { slice_to_u8_mut(dst) };
638            self.read_exact(buf)?;
639        }
640        T::from_slice_u64(dst);
641        Ok(())
642    }
643
644    /// Reads a sequence of unsigned 128 bit integers from the underlying
645    /// reader.
646    ///
647    /// The given buffer is either filled completely or an error is returned.
648    /// If an error is returned, the contents of `dst` are unspecified.
649    ///
650    /// # Errors
651    ///
652    /// This method returns the same errors as [`Read::read_exact`].
653    ///
654    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
655    ///
656    /// # Examples
657    ///
658    /// Read a sequence of unsigned 128 bit big-endian integers from a `Read`:
659    ///
660    /// ```rust
661    /// use std::io::Cursor;
662    /// use byteorder::{BigEndian, ReadBytesExt};
663    ///
664    /// let mut rdr = Cursor::new(vec![
665    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
666    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
667    /// ]);
668    /// let mut dst = [0; 2];
669    /// rdr.read_u128_into::<BigEndian>(&mut dst).unwrap();
670    /// assert_eq!([517, 768], dst);
671    /// ```
672    #[inline]
673    fn read_u128_into<T: ByteOrder>(
674        &mut self,
675        dst: &mut [u128],
676    ) -> Result<()> {
677        {
678            let buf = unsafe { slice_to_u8_mut(dst) };
679            self.read_exact(buf)?;
680        }
681        T::from_slice_u128(dst);
682        Ok(())
683    }
684
685    /// Reads a sequence of signed 8 bit integers from the underlying reader.
686    ///
687    /// The given buffer is either filled completely or an error is returned.
688    /// If an error is returned, the contents of `dst` are unspecified.
689    ///
690    /// Note that since each `i8` is a single byte, no byte order conversions
691    /// are used. This method is included because it provides a safe, simple
692    /// way for the caller to read into a `&mut [i8]` buffer. (Without this
693    /// method, the caller would have to either use `unsafe` code or convert
694    /// each byte to `i8` individually.)
695    ///
696    /// # Errors
697    ///
698    /// This method returns the same errors as [`Read::read_exact`].
699    ///
700    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
701    ///
702    /// # Examples
703    ///
704    /// Read a sequence of signed 8 bit integers from a `Read`:
705    ///
706    /// ```rust
707    /// use std::io::Cursor;
708    /// use byteorder::{BigEndian, ReadBytesExt};
709    ///
710    /// let mut rdr = Cursor::new(vec![2, 251, 3]);
711    /// let mut dst = [0; 3];
712    /// rdr.read_i8_into(&mut dst).unwrap();
713    /// assert_eq!([2, -5, 3], dst);
714    /// ```
715    #[inline]
716    fn read_i8_into(&mut self, dst: &mut [i8]) -> Result<()> {
717        let buf = unsafe { slice_to_u8_mut(dst) };
718        self.read_exact(buf)
719    }
720
721    /// Reads a sequence of signed 16 bit integers from the underlying
722    /// reader.
723    ///
724    /// The given buffer is either filled completely or an error is returned.
725    /// If an error is returned, the contents of `dst` are unspecified.
726    ///
727    /// # Errors
728    ///
729    /// This method returns the same errors as [`Read::read_exact`].
730    ///
731    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
732    ///
733    /// # Examples
734    ///
735    /// Read a sequence of signed 16 bit big-endian integers from a `Read`:
736    ///
737    /// ```rust
738    /// use std::io::Cursor;
739    /// use byteorder::{BigEndian, ReadBytesExt};
740    ///
741    /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
742    /// let mut dst = [0; 2];
743    /// rdr.read_i16_into::<BigEndian>(&mut dst).unwrap();
744    /// assert_eq!([517, 768], dst);
745    /// ```
746    #[inline]
747    fn read_i16_into<T: ByteOrder>(&mut self, dst: &mut [i16]) -> Result<()> {
748        {
749            let buf = unsafe { slice_to_u8_mut(dst) };
750            self.read_exact(buf)?;
751        }
752        T::from_slice_i16(dst);
753        Ok(())
754    }
755
756    /// Reads a sequence of signed 32 bit integers from the underlying
757    /// reader.
758    ///
759    /// The given buffer is either filled completely or an error is returned.
760    /// If an error is returned, the contents of `dst` are unspecified.
761    ///
762    /// # Errors
763    ///
764    /// This method returns the same errors as [`Read::read_exact`].
765    ///
766    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
767    ///
768    /// # Examples
769    ///
770    /// Read a sequence of signed 32 bit big-endian integers from a `Read`:
771    ///
772    /// ```rust
773    /// use std::io::Cursor;
774    /// use byteorder::{BigEndian, ReadBytesExt};
775    ///
776    /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]);
777    /// let mut dst = [0; 2];
778    /// rdr.read_i32_into::<BigEndian>(&mut dst).unwrap();
779    /// assert_eq!([517, 768], dst);
780    /// ```
781    #[inline]
782    fn read_i32_into<T: ByteOrder>(&mut self, dst: &mut [i32]) -> Result<()> {
783        {
784            let buf = unsafe { slice_to_u8_mut(dst) };
785            self.read_exact(buf)?;
786        }
787        T::from_slice_i32(dst);
788        Ok(())
789    }
790
791    /// Reads a sequence of signed 64 bit integers from the underlying
792    /// reader.
793    ///
794    /// The given buffer is either filled completely or an error is returned.
795    /// If an error is returned, the contents of `dst` are unspecified.
796    ///
797    /// # Errors
798    ///
799    /// This method returns the same errors as [`Read::read_exact`].
800    ///
801    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
802    ///
803    /// # Examples
804    ///
805    /// Read a sequence of signed 64 bit big-endian integers from a `Read`:
806    ///
807    /// ```rust
808    /// use std::io::Cursor;
809    /// use byteorder::{BigEndian, ReadBytesExt};
810    ///
811    /// let mut rdr = Cursor::new(vec![
812    ///     0, 0, 0, 0, 0, 0, 2, 5,
813    ///     0, 0, 0, 0, 0, 0, 3, 0,
814    /// ]);
815    /// let mut dst = [0; 2];
816    /// rdr.read_i64_into::<BigEndian>(&mut dst).unwrap();
817    /// assert_eq!([517, 768], dst);
818    /// ```
819    #[inline]
820    fn read_i64_into<T: ByteOrder>(&mut self, dst: &mut [i64]) -> Result<()> {
821        {
822            let buf = unsafe { slice_to_u8_mut(dst) };
823            self.read_exact(buf)?;
824        }
825        T::from_slice_i64(dst);
826        Ok(())
827    }
828
829    /// Reads a sequence of signed 128 bit integers from the underlying
830    /// reader.
831    ///
832    /// The given buffer is either filled completely or an error is returned.
833    /// If an error is returned, the contents of `dst` are unspecified.
834    ///
835    /// # Errors
836    ///
837    /// This method returns the same errors as [`Read::read_exact`].
838    ///
839    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
840    ///
841    /// # Examples
842    ///
843    /// Read a sequence of signed 128 bit big-endian integers from a `Read`:
844    ///
845    /// ```rust
846    /// use std::io::Cursor;
847    /// use byteorder::{BigEndian, ReadBytesExt};
848    ///
849    /// let mut rdr = Cursor::new(vec![
850    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
851    ///     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
852    /// ]);
853    /// let mut dst = [0; 2];
854    /// rdr.read_i128_into::<BigEndian>(&mut dst).unwrap();
855    /// assert_eq!([517, 768], dst);
856    /// ```
857    #[inline]
858    fn read_i128_into<T: ByteOrder>(
859        &mut self,
860        dst: &mut [i128],
861    ) -> Result<()> {
862        {
863            let buf = unsafe { slice_to_u8_mut(dst) };
864            self.read_exact(buf)?;
865        }
866        T::from_slice_i128(dst);
867        Ok(())
868    }
869
870    /// Reads a sequence of IEEE754 single-precision (4 bytes) floating
871    /// point numbers from the underlying reader.
872    ///
873    /// The given buffer is either filled completely or an error is returned.
874    /// If an error is returned, the contents of `dst` are unspecified.
875    ///
876    /// # Errors
877    ///
878    /// This method returns the same errors as [`Read::read_exact`].
879    ///
880    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
881    ///
882    /// # Examples
883    ///
884    /// Read a sequence of big-endian single-precision floating point number
885    /// from a `Read`:
886    ///
887    /// ```rust
888    /// use std::f32;
889    /// use std::io::Cursor;
890    ///
891    /// use byteorder::{BigEndian, ReadBytesExt};
892    ///
893    /// let mut rdr = Cursor::new(vec![
894    ///     0x40, 0x49, 0x0f, 0xdb,
895    ///     0x3f, 0x80, 0x00, 0x00,
896    /// ]);
897    /// let mut dst = [0.0; 2];
898    /// rdr.read_f32_into::<BigEndian>(&mut dst).unwrap();
899    /// assert_eq!([f32::consts::PI, 1.0], dst);
900    /// ```
901    #[inline]
902    fn read_f32_into<T: ByteOrder>(&mut self, dst: &mut [f32]) -> Result<()> {
903        {
904            let buf = unsafe { slice_to_u8_mut(dst) };
905            self.read_exact(buf)?;
906        }
907        T::from_slice_f32(dst);
908        Ok(())
909    }
910
911    /// **DEPRECATED**.
912    ///
913    /// This method is deprecated. Use `read_f32_into` instead.
914    ///
915    /// Reads a sequence of IEEE754 single-precision (4 bytes) floating
916    /// point numbers from the underlying reader.
917    ///
918    /// The given buffer is either filled completely or an error is returned.
919    /// If an error is returned, the contents of `dst` are unspecified.
920    ///
921    /// # Errors
922    ///
923    /// This method returns the same errors as [`Read::read_exact`].
924    ///
925    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
926    ///
927    /// # Examples
928    ///
929    /// Read a sequence of big-endian single-precision floating point number
930    /// from a `Read`:
931    ///
932    /// ```rust
933    /// use std::f32;
934    /// use std::io::Cursor;
935    ///
936    /// use byteorder::{BigEndian, ReadBytesExt};
937    ///
938    /// let mut rdr = Cursor::new(vec![
939    ///     0x40, 0x49, 0x0f, 0xdb,
940    ///     0x3f, 0x80, 0x00, 0x00,
941    /// ]);
942    /// let mut dst = [0.0; 2];
943    /// rdr.read_f32_into_unchecked::<BigEndian>(&mut dst).unwrap();
944    /// assert_eq!([f32::consts::PI, 1.0], dst);
945    /// ```
946    #[inline]
947    #[deprecated(since = "1.2.0", note = "please use `read_f32_into` instead")]
948    fn read_f32_into_unchecked<T: ByteOrder>(
949        &mut self,
950        dst: &mut [f32],
951    ) -> Result<()> {
952        self.read_f32_into::<T>(dst)
953    }
954
955    /// Reads a sequence of IEEE754 double-precision (8 bytes) floating
956    /// point numbers from the underlying reader.
957    ///
958    /// The given buffer is either filled completely or an error is returned.
959    /// If an error is returned, the contents of `dst` are unspecified.
960    ///
961    /// # Errors
962    ///
963    /// This method returns the same errors as [`Read::read_exact`].
964    ///
965    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
966    ///
967    /// # Examples
968    ///
969    /// Read a sequence of big-endian single-precision floating point number
970    /// from a `Read`:
971    ///
972    /// ```rust
973    /// use std::f64;
974    /// use std::io::Cursor;
975    ///
976    /// use byteorder::{BigEndian, ReadBytesExt};
977    ///
978    /// let mut rdr = Cursor::new(vec![
979    ///     0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
980    ///     0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
981    /// ]);
982    /// let mut dst = [0.0; 2];
983    /// rdr.read_f64_into::<BigEndian>(&mut dst).unwrap();
984    /// assert_eq!([f64::consts::PI, 1.0], dst);
985    /// ```
986    #[inline]
987    fn read_f64_into<T: ByteOrder>(&mut self, dst: &mut [f64]) -> Result<()> {
988        {
989            let buf = unsafe { slice_to_u8_mut(dst) };
990            self.read_exact(buf)?;
991        }
992        T::from_slice_f64(dst);
993        Ok(())
994    }
995
996    /// **DEPRECATED**.
997    ///
998    /// This method is deprecated. Use `read_f64_into` instead.
999    ///
1000    /// Reads a sequence of IEEE754 double-precision (8 bytes) floating
1001    /// point numbers from the underlying reader.
1002    ///
1003    /// The given buffer is either filled completely or an error is returned.
1004    /// If an error is returned, the contents of `dst` are unspecified.
1005    ///
1006    /// # Safety
1007    ///
1008    /// This method is unsafe because there are no guarantees made about the
1009    /// floating point values. In particular, this method does not check for
1010    /// signaling NaNs, which may result in undefined behavior.
1011    ///
1012    /// # Errors
1013    ///
1014    /// This method returns the same errors as [`Read::read_exact`].
1015    ///
1016    /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
1017    ///
1018    /// # Examples
1019    ///
1020    /// Read a sequence of big-endian single-precision floating point number
1021    /// from a `Read`:
1022    ///
1023    /// ```rust
1024    /// use std::f64;
1025    /// use std::io::Cursor;
1026    ///
1027    /// use byteorder::{BigEndian, ReadBytesExt};
1028    ///
1029    /// let mut rdr = Cursor::new(vec![
1030    ///     0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
1031    ///     0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1032    /// ]);
1033    /// let mut dst = [0.0; 2];
1034    /// rdr.read_f64_into_unchecked::<BigEndian>(&mut dst).unwrap();
1035    /// assert_eq!([f64::consts::PI, 1.0], dst);
1036    /// ```
1037    #[inline]
1038    #[deprecated(since = "1.2.0", note = "please use `read_f64_into` instead")]
1039    fn read_f64_into_unchecked<T: ByteOrder>(
1040        &mut self,
1041        dst: &mut [f64],
1042    ) -> Result<()> {
1043        self.read_f64_into::<T>(dst)
1044    }
1045}
1046
1047/// All types that implement `Read` get methods defined in `ReadBytesExt`
1048/// for free.
1049impl<R: io::Read + ?Sized> ReadBytesExt for R {}
1050
1051/// Extends [`Write`] with methods for writing numbers. (For `std::io`.)
1052///
1053/// Most of the methods defined here have an unconstrained type parameter that
1054/// must be explicitly instantiated. Typically, it is instantiated with either
1055/// the [`BigEndian`] or [`LittleEndian`] types defined in this crate.
1056///
1057/// # Examples
1058///
1059/// Write unsigned 16 bit big-endian integers to a [`Write`]:
1060///
1061/// ```rust
1062/// use byteorder::{BigEndian, WriteBytesExt};
1063///
1064/// let mut wtr = vec![];
1065/// wtr.write_u16::<BigEndian>(517).unwrap();
1066/// wtr.write_u16::<BigEndian>(768).unwrap();
1067/// assert_eq!(wtr, vec![2, 5, 3, 0]);
1068/// ```
1069///
1070/// [`BigEndian`]: enum.BigEndian.html
1071/// [`LittleEndian`]: enum.LittleEndian.html
1072/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
1073pub trait WriteBytesExt: io::Write {
1074    /// Writes an unsigned 8 bit integer to the underlying writer.
1075    ///
1076    /// Note that since this writes a single byte, no byte order conversions
1077    /// are used. It is included for completeness.
1078    ///
1079    /// # Errors
1080    ///
1081    /// This method returns the same errors as [`Write::write_all`].
1082    ///
1083    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1084    ///
1085    /// # Examples
1086    ///
1087    /// Write unsigned 8 bit integers to a `Write`:
1088    ///
1089    /// ```rust
1090    /// use byteorder::WriteBytesExt;
1091    ///
1092    /// let mut wtr = Vec::new();
1093    /// wtr.write_u8(2).unwrap();
1094    /// wtr.write_u8(5).unwrap();
1095    /// assert_eq!(wtr, b"\x02\x05");
1096    /// ```
1097    #[inline]
1098    fn write_u8(&mut self, n: u8) -> Result<()> {
1099        self.write_all(&[n])
1100    }
1101
1102    /// Writes a signed 8 bit integer to the underlying writer.
1103    ///
1104    /// Note that since this writes a single byte, no byte order conversions
1105    /// are used. It is included for completeness.
1106    ///
1107    /// # Errors
1108    ///
1109    /// This method returns the same errors as [`Write::write_all`].
1110    ///
1111    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1112    ///
1113    /// # Examples
1114    ///
1115    /// Write signed 8 bit integers to a `Write`:
1116    ///
1117    /// ```rust
1118    /// use byteorder::WriteBytesExt;
1119    ///
1120    /// let mut wtr = Vec::new();
1121    /// wtr.write_i8(2).unwrap();
1122    /// wtr.write_i8(-5).unwrap();
1123    /// assert_eq!(wtr, b"\x02\xfb");
1124    /// ```
1125    #[inline]
1126    fn write_i8(&mut self, n: i8) -> Result<()> {
1127        self.write_all(&[n as u8])
1128    }
1129
1130    /// Writes an unsigned 16 bit integer to the underlying writer.
1131    ///
1132    /// # Errors
1133    ///
1134    /// This method returns the same errors as [`Write::write_all`].
1135    ///
1136    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1137    ///
1138    /// # Examples
1139    ///
1140    /// Write unsigned 16 bit big-endian integers to a `Write`:
1141    ///
1142    /// ```rust
1143    /// use byteorder::{BigEndian, WriteBytesExt};
1144    ///
1145    /// let mut wtr = Vec::new();
1146    /// wtr.write_u16::<BigEndian>(517).unwrap();
1147    /// wtr.write_u16::<BigEndian>(768).unwrap();
1148    /// assert_eq!(wtr, b"\x02\x05\x03\x00");
1149    /// ```
1150    #[inline]
1151    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
1152        let mut buf = [0; 2];
1153        T::write_u16(&mut buf, n);
1154        self.write_all(&buf)
1155    }
1156
1157    /// Writes a signed 16 bit integer to the underlying writer.
1158    ///
1159    /// # Errors
1160    ///
1161    /// This method returns the same errors as [`Write::write_all`].
1162    ///
1163    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1164    ///
1165    /// # Examples
1166    ///
1167    /// Write signed 16 bit big-endian integers to a `Write`:
1168    ///
1169    /// ```rust
1170    /// use byteorder::{BigEndian, WriteBytesExt};
1171    ///
1172    /// let mut wtr = Vec::new();
1173    /// wtr.write_i16::<BigEndian>(193).unwrap();
1174    /// wtr.write_i16::<BigEndian>(-132).unwrap();
1175    /// assert_eq!(wtr, b"\x00\xc1\xff\x7c");
1176    /// ```
1177    #[inline]
1178    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
1179        let mut buf = [0; 2];
1180        T::write_i16(&mut buf, n);
1181        self.write_all(&buf)
1182    }
1183
1184    /// Writes an unsigned 24 bit integer to the underlying writer.
1185    ///
1186    /// # Errors
1187    ///
1188    /// This method returns the same errors as [`Write::write_all`].
1189    ///
1190    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1191    ///
1192    /// # Examples
1193    ///
1194    /// Write unsigned 24 bit big-endian integers to a `Write`:
1195    ///
1196    /// ```rust
1197    /// use byteorder::{BigEndian, WriteBytesExt};
1198    ///
1199    /// let mut wtr = Vec::new();
1200    /// wtr.write_u24::<BigEndian>(267).unwrap();
1201    /// wtr.write_u24::<BigEndian>(120111).unwrap();
1202    /// assert_eq!(wtr, b"\x00\x01\x0b\x01\xd5\x2f");
1203    /// ```
1204    #[inline]
1205    fn write_u24<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
1206        let mut buf = [0; 3];
1207        T::write_u24(&mut buf, n);
1208        self.write_all(&buf)
1209    }
1210
1211    /// Writes a signed 24 bit integer to the underlying writer.
1212    ///
1213    /// # Errors
1214    ///
1215    /// This method returns the same errors as [`Write::write_all`].
1216    ///
1217    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1218    ///
1219    /// # Examples
1220    ///
1221    /// Write signed 24 bit big-endian integers to a `Write`:
1222    ///
1223    /// ```rust
1224    /// use byteorder::{BigEndian, WriteBytesExt};
1225    ///
1226    /// let mut wtr = Vec::new();
1227    /// wtr.write_i24::<BigEndian>(-34253).unwrap();
1228    /// wtr.write_i24::<BigEndian>(120111).unwrap();
1229    /// assert_eq!(wtr, b"\xff\x7a\x33\x01\xd5\x2f");
1230    /// ```
1231    #[inline]
1232    fn write_i24<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
1233        let mut buf = [0; 3];
1234        T::write_i24(&mut buf, n);
1235        self.write_all(&buf)
1236    }
1237
1238    /// Writes an unsigned 32 bit integer to the underlying writer.
1239    ///
1240    /// # Errors
1241    ///
1242    /// This method returns the same errors as [`Write::write_all`].
1243    ///
1244    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1245    ///
1246    /// # Examples
1247    ///
1248    /// Write unsigned 32 bit big-endian integers to a `Write`:
1249    ///
1250    /// ```rust
1251    /// use byteorder::{BigEndian, WriteBytesExt};
1252    ///
1253    /// let mut wtr = Vec::new();
1254    /// wtr.write_u32::<BigEndian>(267).unwrap();
1255    /// wtr.write_u32::<BigEndian>(1205419366).unwrap();
1256    /// assert_eq!(wtr, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66");
1257    /// ```
1258    #[inline]
1259    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
1260        let mut buf = [0; 4];
1261        T::write_u32(&mut buf, n);
1262        self.write_all(&buf)
1263    }
1264
1265    /// Writes a signed 32 bit integer to the underlying writer.
1266    ///
1267    /// # Errors
1268    ///
1269    /// This method returns the same errors as [`Write::write_all`].
1270    ///
1271    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1272    ///
1273    /// # Examples
1274    ///
1275    /// Write signed 32 bit big-endian integers to a `Write`:
1276    ///
1277    /// ```rust
1278    /// use byteorder::{BigEndian, WriteBytesExt};
1279    ///
1280    /// let mut wtr = Vec::new();
1281    /// wtr.write_i32::<BigEndian>(-34253).unwrap();
1282    /// wtr.write_i32::<BigEndian>(1205419366).unwrap();
1283    /// assert_eq!(wtr, b"\xff\xff\x7a\x33\x47\xd9\x3d\x66");
1284    /// ```
1285    #[inline]
1286    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
1287        let mut buf = [0; 4];
1288        T::write_i32(&mut buf, n);
1289        self.write_all(&buf)
1290    }
1291
1292    /// Writes an unsigned 48 bit integer to the underlying writer.
1293    ///
1294    /// # Errors
1295    ///
1296    /// This method returns the same errors as [`Write::write_all`].
1297    ///
1298    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1299    ///
1300    /// # Examples
1301    ///
1302    /// Write unsigned 48 bit big-endian integers to a `Write`:
1303    ///
1304    /// ```rust
1305    /// use byteorder::{BigEndian, WriteBytesExt};
1306    ///
1307    /// let mut wtr = Vec::new();
1308    /// wtr.write_u48::<BigEndian>(52360336390828).unwrap();
1309    /// wtr.write_u48::<BigEndian>(541).unwrap();
1310    /// assert_eq!(wtr, b"\x2f\x9f\x17\x40\x3a\xac\x00\x00\x00\x00\x02\x1d");
1311    /// ```
1312    #[inline]
1313    fn write_u48<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
1314        let mut buf = [0; 6];
1315        T::write_u48(&mut buf, n);
1316        self.write_all(&buf)
1317    }
1318
1319    /// Writes a signed 48 bit integer to the underlying writer.
1320    ///
1321    /// # Errors
1322    ///
1323    /// This method returns the same errors as [`Write::write_all`].
1324    ///
1325    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1326    ///
1327    /// # Examples
1328    ///
1329    /// Write signed 48 bit big-endian integers to a `Write`:
1330    ///
1331    /// ```rust
1332    /// use byteorder::{BigEndian, WriteBytesExt};
1333    ///
1334    /// let mut wtr = Vec::new();
1335    /// wtr.write_i48::<BigEndian>(-108363435763825).unwrap();
1336    /// wtr.write_i48::<BigEndian>(77).unwrap();
1337    /// assert_eq!(wtr, b"\x9d\x71\xab\xe7\x97\x8f\x00\x00\x00\x00\x00\x4d");
1338    /// ```
1339    #[inline]
1340    fn write_i48<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
1341        let mut buf = [0; 6];
1342        T::write_i48(&mut buf, n);
1343        self.write_all(&buf)
1344    }
1345
1346    /// Writes an unsigned 64 bit integer to the underlying writer.
1347    ///
1348    /// # Errors
1349    ///
1350    /// This method returns the same errors as [`Write::write_all`].
1351    ///
1352    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1353    ///
1354    /// # Examples
1355    ///
1356    /// Write unsigned 64 bit big-endian integers to a `Write`:
1357    ///
1358    /// ```rust
1359    /// use byteorder::{BigEndian, WriteBytesExt};
1360    ///
1361    /// let mut wtr = Vec::new();
1362    /// wtr.write_u64::<BigEndian>(918733457491587).unwrap();
1363    /// wtr.write_u64::<BigEndian>(143).unwrap();
1364    /// assert_eq!(wtr, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f");
1365    /// ```
1366    #[inline]
1367    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
1368        let mut buf = [0; 8];
1369        T::write_u64(&mut buf, n);
1370        self.write_all(&buf)
1371    }
1372
1373    /// Writes a signed 64 bit integer to the underlying writer.
1374    ///
1375    /// # Errors
1376    ///
1377    /// This method returns the same errors as [`Write::write_all`].
1378    ///
1379    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1380    ///
1381    /// # Examples
1382    ///
1383    /// Write signed 64 bit big-endian integers to a `Write`:
1384    ///
1385    /// ```rust
1386    /// use byteorder::{BigEndian, WriteBytesExt};
1387    ///
1388    /// let mut wtr = Vec::new();
1389    /// wtr.write_i64::<BigEndian>(i64::min_value()).unwrap();
1390    /// wtr.write_i64::<BigEndian>(i64::max_value()).unwrap();
1391    /// assert_eq!(wtr, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff");
1392    /// ```
1393    #[inline]
1394    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
1395        let mut buf = [0; 8];
1396        T::write_i64(&mut buf, n);
1397        self.write_all(&buf)
1398    }
1399
1400    /// Writes an unsigned 128 bit integer to the underlying writer.
1401    #[inline]
1402    fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> {
1403        let mut buf = [0; 16];
1404        T::write_u128(&mut buf, n);
1405        self.write_all(&buf)
1406    }
1407
1408    /// Writes a signed 128 bit integer to the underlying writer.
1409    #[inline]
1410    fn write_i128<T: ByteOrder>(&mut self, n: i128) -> Result<()> {
1411        let mut buf = [0; 16];
1412        T::write_i128(&mut buf, n);
1413        self.write_all(&buf)
1414    }
1415
1416    /// Writes an unsigned n-bytes integer to the underlying writer.
1417    ///
1418    /// # Errors
1419    ///
1420    /// This method returns the same errors as [`Write::write_all`].
1421    ///
1422    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1423    ///
1424    /// # Panics
1425    ///
1426    /// If the given integer is not representable in the given number of bytes,
1427    /// this method panics. If `nbytes > 8`, this method panics.
1428    ///
1429    /// # Examples
1430    ///
1431    /// Write unsigned 40 bit big-endian integers to a `Write`:
1432    ///
1433    /// ```rust
1434    /// use byteorder::{BigEndian, WriteBytesExt};
1435    ///
1436    /// let mut wtr = Vec::new();
1437    /// wtr.write_uint::<BigEndian>(312550384361, 5).unwrap();
1438    /// wtr.write_uint::<BigEndian>(43, 5).unwrap();
1439    /// assert_eq!(wtr, b"\x48\xc5\x74\x62\xe9\x00\x00\x00\x00\x2b");
1440    /// ```
1441    #[inline]
1442    fn write_uint<T: ByteOrder>(
1443        &mut self,
1444        n: u64,
1445        nbytes: usize,
1446    ) -> Result<()> {
1447        let mut buf = [0; 8];
1448        T::write_uint(&mut buf, n, nbytes);
1449        self.write_all(&buf[0..nbytes])
1450    }
1451
1452    /// Writes a signed n-bytes integer to the underlying writer.
1453    ///
1454    /// # Errors
1455    ///
1456    /// This method returns the same errors as [`Write::write_all`].
1457    ///
1458    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1459    ///
1460    /// # Panics
1461    ///
1462    /// If the given integer is not representable in the given number of bytes,
1463    /// this method panics. If `nbytes > 8`, this method panics.
1464    ///
1465    /// # Examples
1466    ///
1467    /// Write signed 56 bit big-endian integers to a `Write`:
1468    ///
1469    /// ```rust
1470    /// use byteorder::{BigEndian, WriteBytesExt};
1471    ///
1472    /// let mut wtr = Vec::new();
1473    /// wtr.write_int::<BigEndian>(-3548172039376767, 7).unwrap();
1474    /// wtr.write_int::<BigEndian>(43, 7).unwrap();
1475    /// assert_eq!(wtr, b"\xf3\x64\xf4\xd1\xfd\xb0\x81\x00\x00\x00\x00\x00\x00\x2b");
1476    /// ```
1477    #[inline]
1478    fn write_int<T: ByteOrder>(
1479        &mut self,
1480        n: i64,
1481        nbytes: usize,
1482    ) -> Result<()> {
1483        let mut buf = [0; 8];
1484        T::write_int(&mut buf, n, nbytes);
1485        self.write_all(&buf[0..nbytes])
1486    }
1487
1488    /// Writes an unsigned n-bytes integer to the underlying writer.
1489    ///
1490    /// If the given integer is not representable in the given number of bytes,
1491    /// this method panics. If `nbytes > 16`, this method panics.
1492    #[inline]
1493    fn write_uint128<T: ByteOrder>(
1494        &mut self,
1495        n: u128,
1496        nbytes: usize,
1497    ) -> Result<()> {
1498        let mut buf = [0; 16];
1499        T::write_uint128(&mut buf, n, nbytes);
1500        self.write_all(&buf[0..nbytes])
1501    }
1502
1503    /// Writes a signed n-bytes integer to the underlying writer.
1504    ///
1505    /// If the given integer is not representable in the given number of bytes,
1506    /// this method panics. If `nbytes > 16`, this method panics.
1507    #[inline]
1508    fn write_int128<T: ByteOrder>(
1509        &mut self,
1510        n: i128,
1511        nbytes: usize,
1512    ) -> Result<()> {
1513        let mut buf = [0; 16];
1514        T::write_int128(&mut buf, n, nbytes);
1515        self.write_all(&buf[0..nbytes])
1516    }
1517
1518    /// Writes a IEEE754 single-precision (4 bytes) floating point number to
1519    /// the underlying writer.
1520    ///
1521    /// # Errors
1522    ///
1523    /// This method returns the same errors as [`Write::write_all`].
1524    ///
1525    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1526    ///
1527    /// # Examples
1528    ///
1529    /// Write a big-endian single-precision floating point number to a `Write`:
1530    ///
1531    /// ```rust
1532    /// use std::f32;
1533    ///
1534    /// use byteorder::{BigEndian, WriteBytesExt};
1535    ///
1536    /// let mut wtr = Vec::new();
1537    /// wtr.write_f32::<BigEndian>(f32::consts::PI).unwrap();
1538    /// assert_eq!(wtr, b"\x40\x49\x0f\xdb");
1539    /// ```
1540    #[inline]
1541    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
1542        let mut buf = [0; 4];
1543        T::write_f32(&mut buf, n);
1544        self.write_all(&buf)
1545    }
1546
1547    /// Writes a IEEE754 double-precision (8 bytes) floating point number to
1548    /// the underlying writer.
1549    ///
1550    /// # Errors
1551    ///
1552    /// This method returns the same errors as [`Write::write_all`].
1553    ///
1554    /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
1555    ///
1556    /// # Examples
1557    ///
1558    /// Write a big-endian double-precision floating point number to a `Write`:
1559    ///
1560    /// ```rust
1561    /// use std::f64;
1562    ///
1563    /// use byteorder::{BigEndian, WriteBytesExt};
1564    ///
1565    /// let mut wtr = Vec::new();
1566    /// wtr.write_f64::<BigEndian>(f64::consts::PI).unwrap();
1567    /// assert_eq!(wtr, b"\x40\x09\x21\xfb\x54\x44\x2d\x18");
1568    /// ```
1569    #[inline]
1570    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
1571        let mut buf = [0; 8];
1572        T::write_f64(&mut buf, n);
1573        self.write_all(&buf)
1574    }
1575}
1576
1577/// All types that implement `Write` get methods defined in `WriteBytesExt`
1578/// for free.
1579impl<W: io::Write + ?Sized> WriteBytesExt for W {}
1580
1581/// Convert a slice of T (where T is plain old data) to its mutable binary
1582/// representation.
1583///
1584/// This function is wildly unsafe because it permits arbitrary modification of
1585/// the binary representation of any `Copy` type. Use with care. It's intended
1586/// to be called only where `T` is a numeric type.
1587unsafe fn slice_to_u8_mut<T: Copy>(slice: &mut [T]) -> &mut [u8] {
1588    use std::mem::size_of;
1589
1590    let len = size_of::<T>() * slice.len();
1591    slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, len)
1592}