diff options
author | Andrew Gallant <jamslam@gmail.com> | 2017-11-29 16:41:53 -0500 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2017-11-29 16:41:53 -0500 |
commit | 27b9144a7ef334c940ba2d133e41df912a673977 (patch) | |
tree | c50ac2a61466c5f5850e1da66f2b4f3b59acaa05 /src | |
parent | cd29ade3b544ecd12a19ccb6009d5c9a449e5b28 (diff) | |
download | byteorder-27b9144a7ef334c940ba2d133e41df912a673977.tar.gz |
remove more unsafe
This removes the `unsafe` annotation from
`read_{f32,f64}_into_unchecked` and deprecates the methods because the
`unchecked` name is no longer appropriate. We in turn add
`read_{f32,f64}_into` methods.
Diffstat (limited to 'src')
-rw-r--r-- | src/io.rs | 117 |
1 files changed, 96 insertions, 21 deletions
@@ -1,6 +1,5 @@ use std::io::{self, Result}; use std::slice; -// use std::mem::transmute; use ByteOrder; @@ -787,11 +786,53 @@ pub trait ReadBytesExt: io::Read { /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// - /// # Safety + /// # Errors /// - /// This method is unsafe because there are no guarantees made about the - /// floating point values. In particular, this method does not check for - /// signaling NaNs, which may result in undefined behavior. + /// This method returns the same errors as [`Read::read_exact`]. + /// + /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact + /// + /// # Examples + /// + /// Read a sequence of big-endian single-precision floating point number + /// from a `Read`: + /// + /// ```rust + /// use std::f32; + /// use std::io::Cursor; + /// + /// use byteorder::{BigEndian, ReadBytesExt}; + /// + /// let mut rdr = Cursor::new(vec![ + /// 0x40, 0x49, 0x0f, 0xdb, + /// 0x3f, 0x80, 0x00, 0x00, + /// ]); + /// let mut dst = [0.0; 2]; + /// rdr.read_f32_into::<BigEndian>(&mut dst).unwrap(); + /// assert_eq!([f32::consts::PI, 1.0], dst); + /// ``` + #[inline] + fn read_f32_into<T: ByteOrder>( + &mut self, + dst: &mut [f32], + ) -> Result<()> { + { + let buf = unsafe { slice_to_u8_mut(dst) }; + try!(self.read_exact(buf)); + } + T::from_slice_f32(dst); + Ok(()) + } + + /// **DEPRECATED**. + /// + /// This method is deprecated. Use `read_f32_into` instead. + /// + /// Reads a sequence of IEEE754 single-precision (4 bytes) floating + /// point numbers from the underlying reader. + /// + /// The given buffer is either filled completely or an error is returned. + /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// @@ -815,24 +856,65 @@ pub trait ReadBytesExt: io::Read { /// 0x3f, 0x80, 0x00, 0x00, /// ]); /// let mut dst = [0.0; 2]; - /// unsafe { - /// rdr.read_f32_into_unchecked::<BigEndian>(&mut dst).unwrap(); - /// } + /// rdr.read_f32_into_unchecked::<BigEndian>(&mut dst).unwrap(); /// assert_eq!([f32::consts::PI, 1.0], dst); /// ``` #[inline] - unsafe fn read_f32_into_unchecked<T: ByteOrder>( + fn read_f32_into_unchecked<T: ByteOrder>( &mut self, dst: &mut [f32], ) -> Result<()> { + self.read_f32_into::<T>(dst) + } + + /// Reads a sequence of IEEE754 double-precision (8 bytes) floating + /// point numbers from the underlying reader. + /// + /// The given buffer is either filled completely or an error is returned. + /// If an error is returned, the contents of `dst` are unspecified. + /// + /// # Errors + /// + /// This method returns the same errors as [`Read::read_exact`]. + /// + /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact + /// + /// # Examples + /// + /// Read a sequence of big-endian single-precision floating point number + /// from a `Read`: + /// + /// ```rust + /// use std::f64; + /// use std::io::Cursor; + /// + /// use byteorder::{BigEndian, ReadBytesExt}; + /// + /// let mut rdr = Cursor::new(vec![ + /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, + /// 0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /// ]); + /// let mut dst = [0.0; 2]; + /// rdr.read_f64_into::<BigEndian>(&mut dst).unwrap(); + /// assert_eq!([f64::consts::PI, 1.0], dst); + /// ``` + #[inline] + fn read_f64_into<T: ByteOrder>( + &mut self, + dst: &mut [f64], + ) -> Result<()> { { - let buf = slice_to_u8_mut(dst); + let buf = unsafe { slice_to_u8_mut(dst) }; try!(self.read_exact(buf)); } - T::from_slice_f32(dst); + T::from_slice_f64(dst); Ok(()) } + /// **DEPRECATED**. + /// + /// This method is deprecated. Use `read_f64_into` instead. + /// /// Reads a sequence of IEEE754 double-precision (8 bytes) floating /// point numbers from the underlying reader. /// @@ -867,22 +949,15 @@ pub trait ReadBytesExt: io::Read { /// 0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// ]); /// let mut dst = [0.0; 2]; - /// unsafe { - /// rdr.read_f64_into_unchecked::<BigEndian>(&mut dst).unwrap(); - /// } + /// rdr.read_f64_into_unchecked::<BigEndian>(&mut dst).unwrap(); /// assert_eq!([f64::consts::PI, 1.0], dst); /// ``` #[inline] - unsafe fn read_f64_into_unchecked<T: ByteOrder>( + fn read_f64_into_unchecked<T: ByteOrder>( &mut self, dst: &mut [f64], ) -> Result<()> { - { - let buf = slice_to_u8_mut(dst); - try!(self.read_exact(buf)); - } - T::from_slice_f64(dst); - Ok(()) + self.read_f64_into::<T>(dst) } } |