Bug 1175322 - Import byteorder crate. r=k17e
authorRalph Giles <giles@mozilla.com>
Tue, 16 Jun 2015 15:51:00 -0700
changeset 249205 758e4197540257606a0d817855a1d294d53316a0
parent 249204 8d802bb49f338f87e72117baa2f35d62dad736fe
child 249206 5988e0ef6cef730019c7e6649865c031879b50da
push id61172
push userrgiles@mozilla.com
push dateTue, 16 Jun 2015 23:24:38 +0000
treeherdermozilla-inbound@5988e0ef6cef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersk17e
bugs1175322
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1175322 - Import byteorder crate. r=k17e This is the source of Andrew Gallant's byteorder crate, used end the MIT license. It has been slightly modified to re-export the new sub-module so it can be built as a mod inside our MP4Metadata crate since we don't currently support crate dependencies.
media/libstagefright/binding/MP4Metadata.rs
media/libstagefright/binding/byteorder/mod.rs
media/libstagefright/binding/byteorder/new.rs
--- a/media/libstagefright/binding/MP4Metadata.rs
+++ b/media/libstagefright/binding/MP4Metadata.rs
@@ -36,17 +36,17 @@ pub struct TrackHeaderBox {
     pub name: u32,
     pub size: u64,
     pub track_id: u32,
     pub duration: u64,
     pub width: u32,
     pub height: u32,
 }
 
-extern crate byteorder;
+mod byteorder;
 use byteorder::{BigEndian, ReadBytesExt};
 use std::io::{Read, Result, Seek, SeekFrom, Take};
 use std::io::Cursor;
 
 /// Parse a box out of a data buffer.
 pub fn read_box_header<T: ReadBytesExt>(src: &mut T) -> Result<BoxHeader> {
     let tmp_size = try!(src.read_u32::<BigEndian>());
     let name = try!(src.read_u32::<BigEndian>());
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/byteorder/mod.rs
@@ -0,0 +1,698 @@
+/*!
+This crate provides convenience methods for encoding and decoding numbers
+in either big-endian or little-endian order.
+
+The organization of the crate is pretty simple. A trait, `ByteOrder`, specifies
+byte conversion methods for each type of number in Rust (sans numbers that have
+a platform dependent size like `usize` and `isize`). Two types, `BigEndian`
+and `LittleEndian` implement these methods. Finally, `ReadBytesExt` and
+`WriteBytesExt` provide convenience methods available to all types that
+implement `Read` and `Write`.
+
+# Examples
+
+Read unsigned 16 bit big-endian integers from a `Read` type:
+
+```rust
+use std::io::Cursor;
+use byteorder::{BigEndian, ReadBytesExt};
+
+let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+// Note that we use type parameters to indicate which kind of byte order
+// we want!
+assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
+assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
+```
+
+Write unsigned 16 bit little-endian integers to a `Write` type:
+
+```rust
+use byteorder::{LittleEndian, WriteBytesExt};
+
+let mut wtr = vec![];
+wtr.write_u16::<LittleEndian>(517).unwrap();
+wtr.write_u16::<LittleEndian>(768).unwrap();
+assert_eq!(wtr, vec![5, 2, 0, 3]);
+```
+*/
+
+#![crate_name = "byteorder"]
+#![doc(html_root_url = "http://burntsushi.net/rustdoc/byteorder")]
+
+#![deny(missing_docs)]
+
+use std::mem::transmute;
+
+pub use byteorder::new::{ReadBytesExt, WriteBytesExt, Error, Result};
+
+// Re-export new so gecko and build us as a mod intead of a crate.
+pub mod new;
+
+fn extend_sign(val: u64, nbytes: usize) -> i64 {
+    let shift  = (8 - nbytes) * 8;
+    (val << shift) as i64 >> shift
+}
+
+/// ByteOrder describes types that can serialize integers as bytes.
+///
+/// Note that `Self` does not appear anywhere in this trait's definition!
+/// Therefore, in order to use it, you'll need to use syntax like
+/// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
+///
+/// This crate provides two types that implement `ByteOrder`: `BigEndian`
+/// and `LittleEndian`.
+///
+/// # Examples
+///
+/// Write and read `u32` numbers in little endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, LittleEndian};
+///
+/// let mut buf = [0; 4];
+/// LittleEndian::write_u32(&mut buf, 1_000_000);
+/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
+/// ```
+///
+/// Write and read `i16` numbers in big endian order:
+///
+/// ```rust
+/// use byteorder::{ByteOrder, BigEndian};
+///
+/// let mut buf = [0; 2];
+/// BigEndian::write_i16(&mut buf, -50_000);
+/// assert_eq!(-50_000, BigEndian::read_i16(&buf));
+/// ```
+pub trait ByteOrder {
+    /// Reads an unsigned 16 bit integer from `buf`.
+    ///
+    /// Panics when `buf.len() < 2`.
+    fn read_u16(buf: &[u8]) -> u16;
+
+    /// Reads an unsigned 32 bit integer from `buf`.
+    ///
+    /// Panics when `buf.len() < 4`.
+    fn read_u32(buf: &[u8]) -> u32;
+
+    /// Reads an unsigned 64 bit integer from `buf`.
+    ///
+    /// Panics when `buf.len() < 8`.
+    fn read_u64(buf: &[u8]) -> u64;
+
+    /// Reads an unsigned n-bytes integer from `buf`.
+    ///
+    /// Panics when `nbytes < 1` or `nbytes > 8` or
+    /// `buf.len() < nbytes`
+    fn read_uint(buf: &[u8], nbytes: usize) -> u64;
+
+    /// Writes an unsigned 16 bit integer `n` to `buf`.
+    ///
+    /// Panics when `buf.len() < 2`.
+    fn write_u16(buf: &mut [u8], n: u16);
+
+    /// Writes an unsigned 32 bit integer `n` to `buf`.
+    ///
+    /// Panics when `buf.len() < 4`.
+    fn write_u32(buf: &mut [u8], n: u32);
+
+    /// Writes an unsigned 64 bit integer `n` to `buf`.
+    ///
+    /// Panics when `buf.len() < 8`.
+    fn write_u64(buf: &mut [u8], n: u64);
+
+    /// Reads a signed 16 bit integer from `buf`.
+    ///
+    /// Panics when `buf.len() < 2`.
+    fn read_i16(buf: &[u8]) -> i16 {
+        Self::read_u16(buf) as i16
+    }
+
+    /// Reads a signed 32 bit integer from `buf`.
+    ///
+    /// Panics when `buf.len() < 4`.
+    fn read_i32(buf: &[u8]) -> i32 {
+        Self::read_u32(buf) as i32
+    }
+
+    /// Reads a signed 64 bit integer from `buf`.
+    ///
+    /// Panics when `buf.len() < 8`.
+    fn read_i64(buf: &[u8]) -> i64 {
+        Self::read_u64(buf) as i64
+    }
+
+    /// Reads a signed n-bytes integer from `buf`.
+    ///
+    /// Panics when `nbytes < 1` or `nbytes > 8` or
+    /// `buf.len() < nbytes`
+    fn read_int(buf: &[u8], nbytes: usize) -> i64 {
+        extend_sign(Self::read_uint(buf, nbytes), nbytes)
+    }
+
+    /// Reads a IEEE754 single-precision (4 bytes) floating point number.
+    ///
+    /// Panics when `buf.len() < 4`.
+    fn read_f32(buf: &[u8]) -> f32 {
+        unsafe { transmute(Self::read_u32(buf)) }
+    }
+
+    /// Reads a IEEE754 double-precision (8 bytes) floating point number.
+    ///
+    /// Panics when `buf.len() < 8`.
+    fn read_f64(buf: &[u8]) -> f64 {
+        unsafe { transmute(Self::read_u64(buf)) }
+    }
+
+    /// Writes a signed 16 bit integer `n` to `buf`.
+    ///
+    /// Panics when `buf.len() < 2`.
+    fn write_i16(buf: &mut [u8], n: i16) {
+        Self::write_u16(buf, n as u16)
+    }
+
+    /// Writes a signed 32 bit integer `n` to `buf`.
+    ///
+    /// Panics when `buf.len() < 4`.
+    fn write_i32(buf: &mut [u8], n: i32) {
+        Self::write_u32(buf, n as u32)
+    }
+
+    /// Writes a signed 64 bit integer `n` to `buf`.
+    ///
+    /// Panics when `buf.len() < 8`.
+    fn write_i64(buf: &mut [u8], n: i64) {
+        Self::write_u64(buf, n as u64)
+    }
+
+    /// Writes a IEEE754 single-precision (4 bytes) floating point number.
+    ///
+    /// Panics when `buf.len() < 4`.
+    fn write_f32(buf: &mut [u8], n: f32) {
+        Self::write_u32(buf, unsafe { transmute(n) })
+    }
+
+    /// Writes a IEEE754 double-precision (8 bytes) floating point number.
+    ///
+    /// Panics when `buf.len() < 8`.
+    fn write_f64(buf: &mut [u8], n: f64) {
+        Self::write_u64(buf, unsafe { transmute(n) })
+    }
+}
+
+/// Defines big-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+#[allow(missing_copy_implementations)] pub enum BigEndian {}
+
+/// Defines little-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+#[allow(missing_copy_implementations)] pub enum LittleEndian {}
+
+/// Defines system native-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+#[cfg(target_endian = "little")]
+pub type NativeEndian = LittleEndian;
+
+/// Defines system native-endian serialization.
+///
+/// Note that this type has no value constructor. It is used purely at the
+/// type level.
+#[cfg(target_endian = "big")]
+pub type NativeEndian = BigEndian;
+
+macro_rules! read_num_bytes {
+    ($ty:ty, $size:expr, $src:expr, $which:ident) => ({
+        assert!($src.len() >= $size); // critical for memory safety!
+        unsafe {
+            (*($src.as_ptr() as *const $ty)).$which()
+        }
+    });
+    ($ty:ty, $size:expr, le $bytes:expr, $src:expr, $which:ident) => ({
+        use std::ptr::copy_nonoverlapping;
+
+        assert!($bytes > 0 && $bytes < 9 && $bytes <= $src.len());
+        let mut out = [0u8; $size];
+        let ptr_out = out.as_mut_ptr();
+        unsafe {
+            copy_nonoverlapping($src.as_ptr(), ptr_out, $bytes);
+            (*(ptr_out as *const $ty)).$which()
+        }
+    });
+    ($ty:ty, $size:expr, be $bytes:expr, $src:expr, $which:ident) => ({
+        use std::ptr::copy_nonoverlapping;
+
+        assert!($bytes > 0 && $bytes < 9 && $bytes <= $src.len());
+        let mut out = [0u8; $size];
+        let ptr_out = out.as_mut_ptr();
+        unsafe {
+            copy_nonoverlapping($src.as_ptr(),
+                                ptr_out.offset((8 - $bytes) as isize), $bytes);
+            (*(ptr_out as *const $ty)).$which()
+        }
+    });
+}
+
+macro_rules! write_num_bytes {
+    ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => ({
+        use std::ptr::copy_nonoverlapping;
+
+        assert!($dst.len() >= $size); // critical for memory safety!
+        unsafe {
+            // N.B. https://github.com/rust-lang/rust/issues/22776
+            let bytes = transmute::<_, [u8; $size]>($n.$which());
+            copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
+        }
+    });
+}
+
+impl ByteOrder for BigEndian {
+    fn read_u16(buf: &[u8]) -> u16 {
+        read_num_bytes!(u16, 2, buf, to_be)
+    }
+
+    fn read_u32(buf: &[u8]) -> u32 {
+        read_num_bytes!(u32, 4, buf, to_be)
+    }
+
+    fn read_u64(buf: &[u8]) -> u64 {
+        read_num_bytes!(u64, 8, buf, to_be)
+    }
+
+    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
+        read_num_bytes!(u64, 8, be nbytes, buf, to_be)
+    }
+
+    fn write_u16(buf: &mut [u8], n: u16) {
+        write_num_bytes!(u16, 2, n, buf, to_be);
+    }
+
+    fn write_u32(buf: &mut [u8], n: u32) {
+        write_num_bytes!(u32, 4, n, buf, to_be);
+    }
+
+    fn write_u64(buf: &mut [u8], n: u64) {
+        write_num_bytes!(u64, 8, n, buf, to_be);
+    }
+}
+
+impl ByteOrder for LittleEndian {
+    fn read_u16(buf: &[u8]) -> u16 {
+        read_num_bytes!(u16, 2, buf, to_le)
+    }
+
+    fn read_u32(buf: &[u8]) -> u32 {
+        read_num_bytes!(u32, 4, buf, to_le)
+    }
+
+    fn read_u64(buf: &[u8]) -> u64 {
+        read_num_bytes!(u64, 8, buf, to_le)
+    }
+
+    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
+        read_num_bytes!(u64, 8, le nbytes, buf, to_le)
+    }
+
+    fn write_u16(buf: &mut [u8], n: u16) {
+        write_num_bytes!(u16, 2, n, buf, to_le);
+    }
+
+    fn write_u32(buf: &mut [u8], n: u32) {
+        write_num_bytes!(u32, 4, n, buf, to_le);
+    }
+
+    fn write_u64(buf: &mut [u8], n: u64) {
+        write_num_bytes!(u64, 8, n, buf, to_le);
+    }
+}
+
+#[cfg(test)]
+mod test {
+    extern crate quickcheck;
+    extern crate rand;
+
+    use test::rand::thread_rng;
+    use test::quickcheck::{QuickCheck, StdGen, Testable};
+
+    const U64_MAX: u64 = ::std::u64::MAX;
+    const I64_MAX: u64 = ::std::i64::MAX as u64;
+
+    fn qc_sized<A: Testable>(f: A, size: u64) {
+        QuickCheck::new()
+            .gen(StdGen::new(thread_rng(), size as usize))
+            .tests(1_00)
+            .max_tests(10_000)
+            .quickcheck(f);
+    }
+
+    macro_rules! qc_byte_order {
+        ($name:ident, $ty_int:ident, $max:expr,
+         $bytes:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+                use super::qc_sized;
+
+                #[test]
+                fn big_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut buf = [0; 8];
+                        BigEndian::$write(&mut buf, n);
+                        n == BigEndian::$read(&mut buf[8 - $bytes..], $bytes)
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+
+                #[test]
+                fn little_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut buf = [0; 8];
+                        LittleEndian::$write(&mut buf, n);
+                        n == LittleEndian::$read(&mut buf[..$bytes], $bytes)
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+
+                #[test]
+                fn native_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut buf = [0; 8];
+                        NativeEndian::$write(&mut buf, n);
+                        n == NativeEndian::$read(&mut buf[..$bytes], $bytes)
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+            }
+        );
+        ($name:ident, $ty_int:ident, $max:expr,
+         $read:ident, $write:ident) => (
+            mod $name {
+                use std::mem::size_of;
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+                use super::qc_sized;
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let bytes = size_of::<$ty_int>();
+                        let mut buf = [0; 8];
+                        BigEndian::$write(&mut buf[8 - bytes..], n);
+                        n == BigEndian::$read(&mut buf[8 - bytes..])
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let bytes = size_of::<$ty_int>();
+                        let mut buf = [0; 8];
+                        LittleEndian::$write(&mut buf[..bytes], n);
+                        n == LittleEndian::$read(&mut buf[..bytes])
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let bytes = size_of::<$ty_int>();
+                        let mut buf = [0; 8];
+                        NativeEndian::$write(&mut buf[..bytes], n);
+                        n == NativeEndian::$read(&mut buf[..bytes])
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+            }
+        );
+    }
+
+    qc_byte_order!(prop_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
+    qc_byte_order!(prop_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
+    qc_byte_order!(prop_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
+    qc_byte_order!(prop_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
+    qc_byte_order!(prop_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
+    qc_byte_order!(prop_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
+    qc_byte_order!(prop_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
+    qc_byte_order!(prop_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
+
+    qc_byte_order!(prop_uint_1, u64, super::U64_MAX, 1, read_uint, write_u64);
+    qc_byte_order!(prop_uint_2, u64, super::U64_MAX, 2, read_uint, write_u64);
+    qc_byte_order!(prop_uint_3, u64, super::U64_MAX, 3, read_uint, write_u64);
+    qc_byte_order!(prop_uint_4, u64, super::U64_MAX, 4, read_uint, write_u64);
+    qc_byte_order!(prop_uint_5, u64, super::U64_MAX, 5, read_uint, write_u64);
+    qc_byte_order!(prop_uint_6, u64, super::U64_MAX, 6, read_uint, write_u64);
+    qc_byte_order!(prop_uint_7, u64, super::U64_MAX, 7, read_uint, write_u64);
+    qc_byte_order!(prop_uint_8, u64, super::U64_MAX, 8, read_uint, write_u64);
+
+    qc_byte_order!(prop_int_1, i64, super::I64_MAX, 1, read_int, write_i64);
+    qc_byte_order!(prop_int_2, i64, super::I64_MAX, 2, read_int, write_i64);
+    qc_byte_order!(prop_int_3, i64, super::I64_MAX, 3, read_int, write_i64);
+    qc_byte_order!(prop_int_4, i64, super::I64_MAX, 4, read_int, write_i64);
+    qc_byte_order!(prop_int_5, i64, super::I64_MAX, 5, read_int, write_i64);
+    qc_byte_order!(prop_int_6, i64, super::I64_MAX, 6, read_int, write_i64);
+    qc_byte_order!(prop_int_7, i64, super::I64_MAX, 7, read_int, write_i64);
+    qc_byte_order!(prop_int_8, i64, super::I64_MAX, 8, read_int, write_i64);
+
+    macro_rules! qc_bytes_ext {
+        ($name:ident, $ty_int:ident, $max:expr,
+         $bytes:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use std::io::Cursor;
+                use {
+                    ReadBytesExt, WriteBytesExt,
+                    BigEndian, NativeEndian, LittleEndian,
+                };
+                use super::qc_sized;
+
+                #[test]
+                fn big_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<BigEndian>(n).unwrap();
+                        let mut rdr = Vec::new();
+                        rdr.extend(wtr[8 - $bytes..].iter().map(|&x|x));
+                        let mut rdr = Cursor::new(rdr);
+                        n == rdr.$read::<BigEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+
+                #[test]
+                fn little_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<LittleEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<LittleEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+
+                #[test]
+                fn native_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<NativeEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<NativeEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+            }
+        );
+        ($name:ident, $ty_int:ident, $max:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use std::io::Cursor;
+                use {
+                    ReadBytesExt, WriteBytesExt,
+                    BigEndian, NativeEndian, LittleEndian,
+                };
+                use super::qc_sized;
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<BigEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<BigEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<LittleEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<LittleEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<NativeEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<NativeEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+            }
+        );
+    }
+
+    qc_bytes_ext!(prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
+    qc_bytes_ext!(prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
+    qc_bytes_ext!(prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
+    qc_bytes_ext!(prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
+    qc_bytes_ext!(prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
+    qc_bytes_ext!(prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
+    qc_bytes_ext!(prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
+    qc_bytes_ext!(prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
+
+    qc_bytes_ext!(prop_ext_uint_1, u64, super::U64_MAX, 1, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_2, u64, super::U64_MAX, 2, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_3, u64, super::U64_MAX, 3, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_4, u64, super::U64_MAX, 4, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_5, u64, super::U64_MAX, 5, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_6, u64, super::U64_MAX, 6, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_7, u64, super::U64_MAX, 7, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_8, u64, super::U64_MAX, 8, read_uint, write_u64);
+
+    qc_bytes_ext!(prop_ext_int_1, i64, super::I64_MAX, 1, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_2, i64, super::I64_MAX, 2, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_3, i64, super::I64_MAX, 3, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_4, i64, super::I64_MAX, 4, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_5, i64, super::I64_MAX, 5, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_6, i64, super::I64_MAX, 6, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_7, i64, super::I64_MAX, 7, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_8, i64, super::I64_MAX, 8, read_int, write_i64);
+
+    // Test that all of the byte conversion functions panic when given a
+    // buffer that is too small.
+    //
+    // These tests are critical to ensure safety, otherwise we might end up
+    // with a buffer overflow.
+    macro_rules! too_small {
+        ($name:ident, $maximally_small:expr, $zero:expr,
+         $read:ident, $write:ident) => (
+            mod $name {
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+
+                #[test]
+                #[should_panic]
+                fn read_big_endian() {
+                    let buf = [0; $maximally_small];
+                    BigEndian::$read(&buf);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_little_endian() {
+                    let buf = [0; $maximally_small];
+                    LittleEndian::$read(&buf);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_native_endian() {
+                    let buf = [0; $maximally_small];
+                    NativeEndian::$read(&buf);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_big_endian() {
+                    let mut buf = [0; $maximally_small];
+                    BigEndian::$write(&mut buf, $zero);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_little_endian() {
+                    let mut buf = [0; $maximally_small];
+                    LittleEndian::$write(&mut buf, $zero);
+                }
+
+                #[test]
+                #[should_panic]
+                fn write_native_endian() {
+                    let mut buf = [0; $maximally_small];
+                    NativeEndian::$write(&mut buf, $zero);
+                }
+            }
+        );
+        ($name:ident, $maximally_small:expr, $read:ident) => (
+            mod $name {
+                use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
+
+                #[test]
+                #[should_panic]
+                fn read_big_endian() {
+                    let buf = [0; $maximally_small];
+                    BigEndian::$read(&buf, $maximally_small + 1);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_little_endian() {
+                    let buf = [0; $maximally_small];
+                    LittleEndian::$read(&buf, $maximally_small + 1);
+                }
+
+                #[test]
+                #[should_panic]
+                fn read_native_endian() {
+                    let buf = [0; $maximally_small];
+                    NativeEndian::$read(&buf, $maximally_small + 1);
+                }
+            }
+        );
+    }
+
+    too_small!(small_u16, 1, 0, read_u16, write_u16);
+    too_small!(small_i16, 1, 0, read_i16, write_i16);
+    too_small!(small_u32, 3, 0, read_u32, write_u32);
+    too_small!(small_i32, 3, 0, read_i32, write_i32);
+    too_small!(small_u64, 7, 0, read_u64, write_u64);
+    too_small!(small_i64, 7, 0, read_i64, write_i64);
+    too_small!(small_f32, 3, 0.0, read_f32, write_f32);
+    too_small!(small_f64, 7, 0.0, read_f64, write_f64);
+
+    too_small!(small_uint_1, 1, read_uint);
+    too_small!(small_uint_2, 2, read_uint);
+    too_small!(small_uint_3, 3, read_uint);
+    too_small!(small_uint_4, 4, read_uint);
+    too_small!(small_uint_5, 5, read_uint);
+    too_small!(small_uint_6, 6, read_uint);
+    too_small!(small_uint_7, 7, read_uint);
+
+    too_small!(small_int_1, 1, read_int);
+    too_small!(small_int_2, 2, read_int);
+    too_small!(small_int_3, 3, read_int);
+    too_small!(small_int_4, 4, read_int);
+    too_small!(small_int_5, 5, read_int);
+    too_small!(small_int_6, 6, read_int);
+    too_small!(small_int_7, 7, read_int);
+
+    #[test]
+    fn uint_bigger_buffer() {
+        use {ByteOrder, LittleEndian};
+        let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
+        assert_eq!(n, 0x0504030201);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/byteorder/new.rs
@@ -0,0 +1,297 @@
+use std::error;
+use std::fmt;
+use std::io;
+use std::result;
+
+use byteorder::ByteOrder;
+
+/// A short-hand for `result::Result<T, byteorder::Error>`.
+pub type Result<T> = result::Result<T, Error>;
+
+/// An error type for reading bytes.
+///
+/// This is a thin wrapper over the standard `io::Error` type. Namely, it
+/// adds one additional error case: an unexpected EOF.
+///
+/// Note that this error is also used for the `write` methods to keep things
+/// consistent.
+#[derive(Debug)]
+pub enum Error {
+    /// An unexpected EOF.
+    ///
+    /// This occurs when a call to the underlying reader returns `0` bytes,
+    /// but more bytes are required to decode a meaningful value.
+    UnexpectedEOF,
+    /// Any underlying IO error that occurs while reading bytes.
+    Io(io::Error),
+}
+
+impl From<io::Error> for Error {
+    fn from(err: io::Error) -> Error { Error::Io(err) }
+}
+
+impl From<Error> for io::Error {
+    fn from(err: Error) -> io::Error {
+        match err {
+            Error::Io(err) => err,
+            Error::UnexpectedEOF => io::Error::new(io::ErrorKind::Other,
+                                                   "unexpected EOF")
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Error::UnexpectedEOF => write!(f, "Unexpected end of file."),
+            Error::Io(ref err) => err.fmt(f),
+        }
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        match *self {
+            Error::UnexpectedEOF => "Unexpected end of file.",
+            Error::Io(ref err) => error::Error::description(err),
+        }
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        match *self {
+            Error::UnexpectedEOF => None,
+            Error::Io(ref err) => err.cause(),
+        }
+    }
+}
+
+/// Extends `Read` with methods for reading numbers. (For `std::io`.)
+///
+/// Most of the methods defined here have an unconstrained type parameter that
+/// must be explicitly instantiated. Typically, it is instantiated with either
+/// the `BigEndian` or `LittleEndian` types defined in this crate.
+///
+/// # Examples
+///
+/// Read unsigned 16 bit big-endian integers from a `Read`:
+///
+/// ```rust
+/// use std::io::Cursor;
+/// use byteorder::{BigEndian, ReadBytesExt};
+///
+/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
+/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
+/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
+/// ```
+pub trait ReadBytesExt: io::Read {
+    /// Reads an unsigned 8 bit integer from the underlying reader.
+    ///
+    /// Note that since this reads a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    fn read_u8(&mut self) -> Result<u8> {
+        let mut buf = [0; 1];
+        try!(read_full(self, &mut buf));
+        Ok(buf[0])
+    }
+
+    /// Reads a signed 8 bit integer from the underlying reader.
+    ///
+    /// Note that since this reads a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    fn read_i8(&mut self) -> Result<i8> {
+        let mut buf = [0; 1];
+        try!(read_full(self, &mut buf));
+        Ok(buf[0] as i8)
+    }
+
+    /// Reads an unsigned 16 bit integer from the underlying reader.
+    fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
+        let mut buf = [0; 2];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_u16(&buf))
+    }
+
+    /// Reads a signed 16 bit integer from the underlying reader.
+    fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
+        let mut buf = [0; 2];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_i16(&buf))
+    }
+
+    /// Reads an unsigned 32 bit integer from the underlying reader.
+    fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
+        let mut buf = [0; 4];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_u32(&buf))
+    }
+
+    /// Reads a signed 32 bit integer from the underlying reader.
+    fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
+        let mut buf = [0; 4];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_i32(&buf))
+    }
+
+    /// Reads an unsigned 64 bit integer from the underlying reader.
+    fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
+        let mut buf = [0; 8];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_u64(&buf))
+    }
+
+    /// Reads a signed 64 bit integer from the underlying reader.
+    fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
+        let mut buf = [0; 8];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_i64(&buf))
+    }
+
+    /// Reads an unsigned n-bytes integer from the underlying reader.
+    fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
+        let mut buf = [0; 8];
+        try!(read_full(self, &mut buf[..nbytes]));
+        Ok(T::read_uint(&buf[..nbytes], nbytes))
+    }
+
+    /// Reads a signed n-bytes integer from the underlying reader.
+    fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
+        let mut buf = [0; 8];
+        try!(read_full(self, &mut buf[..nbytes]));
+        Ok(T::read_int(&buf[..nbytes], nbytes))
+    }
+
+    /// Reads a IEEE754 single-precision (4 bytes) floating point number from
+    /// the underlying reader.
+    fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
+        let mut buf = [0; 4];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_f32(&buf))
+    }
+
+    /// Reads a IEEE754 double-precision (8 bytes) floating point number from
+    /// the underlying reader.
+    fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
+        let mut buf = [0; 8];
+        try!(read_full(self, &mut buf));
+        Ok(T::read_f64(&buf))
+    }
+}
+
+/// All types that implement `Read` get methods defined in `ReadBytesExt`
+/// for free.
+impl<R: io::Read + ?Sized> ReadBytesExt for R {}
+
+fn read_full<R: io::Read + ?Sized>(rdr: &mut R, buf: &mut [u8]) -> Result<()> {
+    let mut nread = 0usize;
+    while nread < buf.len() {
+        match rdr.read(&mut buf[nread..]) {
+            Ok(0) => return Err(Error::UnexpectedEOF),
+            Ok(n) => nread += n,
+            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
+            Err(e) => return Err(From::from(e))
+        }
+    }
+    Ok(())
+}
+
+fn write_all<W: io::Write + ?Sized>(wtr: &mut W, buf: &[u8]) -> Result<()> {
+    wtr.write_all(buf).map_err(From::from)
+}
+
+/// Extends `Write` with methods for writing numbers. (For `std::io`.)
+///
+/// Most of the methods defined here have an unconstrained type parameter that
+/// must be explicitly instantiated. Typically, it is instantiated with either
+/// the `BigEndian` or `LittleEndian` types defined in this crate.
+///
+/// # Examples
+///
+/// Write unsigned 16 bit big-endian integers to a `Write`:
+///
+/// ```rust
+/// use byteorder::{BigEndian, WriteBytesExt};
+///
+/// let mut wtr = vec![];
+/// wtr.write_u16::<BigEndian>(517).unwrap();
+/// wtr.write_u16::<BigEndian>(768).unwrap();
+/// assert_eq!(wtr, vec![2, 5, 3, 0]);
+/// ```
+pub trait WriteBytesExt: io::Write {
+    /// Writes an unsigned 8 bit integer to the underlying writer.
+    ///
+    /// Note that since this writes a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    fn write_u8(&mut self, n: u8) -> Result<()> {
+        write_all(self, &[n])
+    }
+
+    /// Writes a signed 8 bit integer to the underlying writer.
+    ///
+    /// Note that since this writes a single byte, no byte order conversions
+    /// are used. It is included for completeness.
+    fn write_i8(&mut self, n: i8) -> Result<()> {
+        write_all(self, &[n as u8])
+    }
+
+    /// Writes an unsigned 16 bit integer to the underlying writer.
+    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
+        let mut buf = [0; 2];
+        T::write_u16(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes a signed 16 bit integer to the underlying writer.
+    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
+        let mut buf = [0; 2];
+        T::write_i16(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes an unsigned 32 bit integer to the underlying writer.
+    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
+        let mut buf = [0; 4];
+        T::write_u32(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes a signed 32 bit integer to the underlying writer.
+    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
+        let mut buf = [0; 4];
+        T::write_i32(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes an unsigned 64 bit integer to the underlying writer.
+    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_u64(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes a signed 64 bit integer to the underlying writer.
+    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_i64(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes a IEEE754 single-precision (4 bytes) floating point number to
+    /// the underlying writer.
+    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
+        let mut buf = [0; 4];
+        T::write_f32(&mut buf, n);
+        write_all(self, &buf)
+    }
+
+    /// Writes a IEEE754 double-precision (8 bytes) floating point number to
+    /// the underlying writer.
+    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
+        let mut buf = [0; 8];
+        T::write_f64(&mut buf, n);
+        write_all(self, &buf)
+    }
+}
+
+/// All types that implement `Write` get methods defined in `WriteBytesExt`
+/// for free.
+impl<W: io::Write + ?Sized> WriteBytesExt for W {}