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