byteorder/
io.rs

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