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