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