byteorder/
io.rs

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