aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2017-11-29 16:41:53 -0500
committerAndrew Gallant <jamslam@gmail.com>2017-11-29 16:41:53 -0500
commit27b9144a7ef334c940ba2d133e41df912a673977 (patch)
treec50ac2a61466c5f5850e1da66f2b4f3b59acaa05 /src
parentcd29ade3b544ecd12a19ccb6009d5c9a449e5b28 (diff)
downloadbyteorder-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.rs117
1 files changed, 96 insertions, 21 deletions
diff --git a/src/io.rs b/src/io.rs
index a4c4fb4..c5645fa 100644
--- a/src/io.rs
+++ b/src/io.rs
@@ -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)
}
}