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