2014-01-25 01:37:51 -06:00
|
|
|
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
2013-04-17 19:55:21 -05:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
//! Utility mixins that apply to all Readers and Writers
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
#[allow(missing_doc)];
|
|
|
|
|
2014-01-26 02:43:42 -06:00
|
|
|
// FIXME: Not sure how this should be structured
|
|
|
|
// FIXME: Iteration should probably be considered separately
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2014-01-09 03:35:36 -06:00
|
|
|
use container::Container;
|
2013-09-08 10:01:16 -05:00
|
|
|
use iter::Iterator;
|
2014-02-19 20:53:46 -06:00
|
|
|
use option::{Option, Some, None};
|
|
|
|
use result::{Ok, Err};
|
|
|
|
use io;
|
|
|
|
use io::{IoError, IoResult, Reader};
|
2014-01-09 03:35:36 -06:00
|
|
|
use vec::{OwnedVector, ImmutableVector};
|
2014-02-10 15:50:42 -06:00
|
|
|
use ptr::RawPtr;
|
2013-09-01 18:30:21 -05:00
|
|
|
|
|
|
|
/// An iterator that reads a single byte on each iteration,
|
2014-02-19 20:53:46 -06:00
|
|
|
/// until `.read_byte()` returns `EndOfFile`.
|
2013-09-03 13:00:32 -05:00
|
|
|
///
|
|
|
|
/// # Notes about the Iteration Protocol
|
|
|
|
///
|
2014-01-14 21:32:24 -06:00
|
|
|
/// The `Bytes` may yield `None` and thus terminate
|
2013-09-03 13:00:32 -05:00
|
|
|
/// an iteration, but continue to yield elements if iteration
|
|
|
|
/// is attempted again.
|
2013-09-01 18:30:21 -05:00
|
|
|
///
|
2014-02-19 20:53:46 -06:00
|
|
|
/// # Error
|
2013-09-01 18:30:21 -05:00
|
|
|
///
|
2014-02-19 20:53:46 -06:00
|
|
|
/// Any error other than `EndOfFile` that is produced by the underlying Reader
|
|
|
|
/// is returned by the iterator and should be handled by the caller.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct Bytes<'r, T> {
|
2013-12-08 01:12:07 -06:00
|
|
|
priv reader: &'r mut T,
|
2013-09-01 18:30:21 -05:00
|
|
|
}
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
impl<'r, R: Reader> Bytes<'r, R> {
|
|
|
|
pub fn new(r: &'r mut R) -> Bytes<'r, R> {
|
|
|
|
Bytes { reader: r }
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-19 20:53:46 -06:00
|
|
|
impl<'r, R: Reader> Iterator<IoResult<u8>> for Bytes<'r, R> {
|
2013-09-01 18:30:21 -05:00
|
|
|
#[inline]
|
2014-02-19 20:53:46 -06:00
|
|
|
fn next(&mut self) -> Option<IoResult<u8>> {
|
|
|
|
match self.reader.read_byte() {
|
|
|
|
Ok(x) => Some(Ok(x)),
|
|
|
|
Err(IoError { kind: io::EndOfFile, .. }) => None,
|
|
|
|
Err(e) => Some(Err(e))
|
|
|
|
}
|
2013-09-01 18:30:21 -05:00
|
|
|
}
|
2013-05-13 18:56:16 -05:00
|
|
|
}
|
|
|
|
|
2013-11-18 23:15:42 -06:00
|
|
|
pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
|
2014-02-09 02:17:37 -06:00
|
|
|
use mem::{to_le16, to_le32, to_le64};
|
2014-02-01 07:56:51 -06:00
|
|
|
use cast::transmute;
|
|
|
|
|
|
|
|
// LLVM fails to properly optimize this when using shifts instead of the to_le* intrinsics
|
2013-10-22 01:06:12 -05:00
|
|
|
assert!(size <= 8u);
|
|
|
|
match size {
|
|
|
|
1u => f(&[n as u8]),
|
2014-02-01 07:56:51 -06:00
|
|
|
2u => f(unsafe { transmute::<i16, [u8, ..2]>(to_le16(n as i16)) }),
|
|
|
|
4u => f(unsafe { transmute::<i32, [u8, ..4]>(to_le32(n as i32)) }),
|
|
|
|
8u => f(unsafe { transmute::<i64, [u8, ..8]>(to_le64(n as i64)) }),
|
2013-10-22 01:06:12 -05:00
|
|
|
_ => {
|
|
|
|
|
|
|
|
let mut bytes: ~[u8] = ~[];
|
|
|
|
let mut i = size;
|
|
|
|
let mut n = n;
|
|
|
|
while i > 0u {
|
|
|
|
bytes.push((n & 255_u64) as u8);
|
|
|
|
n >>= 8_u64;
|
|
|
|
i -= 1u;
|
|
|
|
}
|
|
|
|
f(bytes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-18 23:15:42 -06:00
|
|
|
pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
|
2014-02-09 02:17:37 -06:00
|
|
|
use mem::{to_be16, to_be32, to_be64};
|
2014-02-01 07:56:51 -06:00
|
|
|
use cast::transmute;
|
|
|
|
|
|
|
|
// LLVM fails to properly optimize this when using shifts instead of the to_be* intrinsics
|
2013-10-22 01:06:12 -05:00
|
|
|
assert!(size <= 8u);
|
|
|
|
match size {
|
|
|
|
1u => f(&[n as u8]),
|
2014-02-01 07:56:51 -06:00
|
|
|
2u => f(unsafe { transmute::<i16, [u8, ..2]>(to_be16(n as i16)) }),
|
|
|
|
4u => f(unsafe { transmute::<i32, [u8, ..4]>(to_be32(n as i32)) }),
|
|
|
|
8u => f(unsafe { transmute::<i64, [u8, ..8]>(to_be64(n as i64)) }),
|
2013-10-22 01:06:12 -05:00
|
|
|
_ => {
|
|
|
|
let mut bytes: ~[u8] = ~[];
|
|
|
|
let mut i = size;
|
|
|
|
while i > 0u {
|
|
|
|
let shift = ((i - 1u) * 8u) as u64;
|
|
|
|
bytes.push((n >> shift) as u8);
|
|
|
|
i -= 1u;
|
|
|
|
}
|
|
|
|
f(bytes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn u64_from_be_bytes(data: &[u8],
|
|
|
|
start: uint,
|
|
|
|
size: uint)
|
|
|
|
-> u64 {
|
2014-02-10 15:50:42 -06:00
|
|
|
use ptr::{copy_nonoverlapping_memory};
|
2014-02-09 02:17:37 -06:00
|
|
|
use mem::from_be64;
|
2014-01-09 03:35:36 -06:00
|
|
|
use vec::MutableVector;
|
|
|
|
|
|
|
|
assert!(size <= 8u);
|
|
|
|
|
|
|
|
if data.len() - start < size {
|
|
|
|
fail!("index out of bounds");
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut buf = [0u8, ..8];
|
|
|
|
unsafe {
|
2014-02-10 15:50:42 -06:00
|
|
|
let ptr = data.as_ptr().offset(start as int);
|
2014-01-09 03:35:36 -06:00
|
|
|
let out = buf.as_mut_ptr();
|
2014-02-10 15:50:42 -06:00
|
|
|
copy_nonoverlapping_memory(out.offset((8 - size) as int), ptr, size);
|
2014-01-09 03:35:36 -06:00
|
|
|
from_be64(*(out as *i64)) as u64
|
2013-10-22 01:06:12 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2014-01-07 00:33:37 -06:00
|
|
|
use prelude::*;
|
2014-01-30 16:10:53 -06:00
|
|
|
use io;
|
2014-01-15 15:25:09 -06:00
|
|
|
use io::{MemReader, MemWriter};
|
2013-10-30 20:28:37 -05:00
|
|
|
|
|
|
|
struct InitialZeroByteReader {
|
|
|
|
count: int,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Reader for InitialZeroByteReader {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-10-30 20:28:37 -05:00
|
|
|
if self.count == 0 {
|
|
|
|
self.count = 1;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(0)
|
2013-10-30 20:28:37 -05:00
|
|
|
} else {
|
|
|
|
buf[0] = 10;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(1)
|
2013-10-30 20:28:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct EofReader;
|
|
|
|
|
|
|
|
impl Reader for EofReader {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
|
|
|
Err(io::standard_error(io::EndOfFile))
|
2013-10-30 20:28:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ErroringReader;
|
|
|
|
|
|
|
|
impl Reader for ErroringReader {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
|
|
|
Err(io::standard_error(io::InvalidInput))
|
2013-10-30 20:28:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct PartialReader {
|
|
|
|
count: int,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Reader for PartialReader {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-10-30 20:28:37 -05:00
|
|
|
if self.count == 0 {
|
|
|
|
self.count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
buf[1] = 11;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(2)
|
2013-10-30 20:28:37 -05:00
|
|
|
} else {
|
|
|
|
buf[0] = 12;
|
|
|
|
buf[1] = 13;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(2)
|
2013-10-30 20:28:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ErroringLaterReader {
|
|
|
|
count: int,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Reader for ErroringLaterReader {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-10-30 20:28:37 -05:00
|
|
|
if self.count == 0 {
|
|
|
|
self.count = 1;
|
|
|
|
buf[0] = 10;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(1)
|
2013-10-30 20:28:37 -05:00
|
|
|
} else {
|
2014-01-30 16:10:53 -06:00
|
|
|
Err(io::standard_error(io::InvalidInput))
|
2013-10-30 20:28:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ThreeChunkReader {
|
|
|
|
count: int,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Reader for ThreeChunkReader {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-10-30 20:28:37 -05:00
|
|
|
if self.count == 0 {
|
|
|
|
self.count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
buf[1] = 11;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(2)
|
2013-10-30 20:28:37 -05:00
|
|
|
} else if self.count == 1 {
|
|
|
|
self.count = 2;
|
|
|
|
buf[0] = 12;
|
|
|
|
buf[1] = 13;
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(2)
|
2013-10-30 20:28:37 -05:00
|
|
|
} else {
|
2014-01-30 16:10:53 -06:00
|
|
|
Err(io::standard_error(io::EndOfFile))
|
2013-10-30 20:28:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-05-09 19:37:31 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte() {
|
|
|
|
let mut reader = MemReader::new(~[10]);
|
|
|
|
let byte = reader.read_byte();
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(byte == Ok(10));
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte_0_bytes() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = InitialZeroByteReader {
|
|
|
|
count: 0,
|
2013-05-09 19:37:31 -05:00
|
|
|
};
|
|
|
|
let byte = reader.read_byte();
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(byte == Ok(10));
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte_eof() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = EofReader;
|
2013-05-09 19:37:31 -05:00
|
|
|
let byte = reader.read_byte();
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(byte.is_err());
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte_error() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = ErroringReader;
|
2014-01-30 16:10:53 -06:00
|
|
|
let byte = reader.read_byte();
|
|
|
|
assert!(byte.is_err());
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
2013-09-01 18:30:21 -05:00
|
|
|
#[test]
|
|
|
|
fn bytes_0_bytes() {
|
2013-12-08 01:12:07 -06:00
|
|
|
let mut reader = InitialZeroByteReader {
|
2013-10-30 20:28:37 -05:00
|
|
|
count: 0,
|
2013-09-01 18:30:21 -05:00
|
|
|
};
|
|
|
|
let byte = reader.bytes().next();
|
2014-02-19 20:53:46 -06:00
|
|
|
assert!(byte == Some(Ok(10)));
|
2013-09-01 18:30:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bytes_eof() {
|
2013-12-08 01:12:07 -06:00
|
|
|
let mut reader = EofReader;
|
2013-09-01 18:30:21 -05:00
|
|
|
let byte = reader.bytes().next();
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(byte.is_none());
|
2013-09-01 18:30:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bytes_error() {
|
2013-12-08 01:12:07 -06:00
|
|
|
let mut reader = ErroringReader;
|
2013-09-01 18:30:21 -05:00
|
|
|
let mut it = reader.bytes();
|
2014-01-30 16:10:53 -06:00
|
|
|
let byte = it.next();
|
2014-02-19 20:53:46 -06:00
|
|
|
assert!(byte.unwrap().is_err());
|
2013-09-01 18:30:21 -05:00
|
|
|
}
|
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
#[test]
|
|
|
|
fn read_bytes() {
|
|
|
|
let mut reader = MemReader::new(~[10, 11, 12, 13]);
|
2014-01-30 16:10:53 -06:00
|
|
|
let bytes = reader.read_bytes(4).unwrap();
|
2013-05-09 19:37:31 -05:00
|
|
|
assert!(bytes == ~[10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_bytes_partial() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = PartialReader {
|
|
|
|
count: 0,
|
2013-05-09 19:37:31 -05:00
|
|
|
};
|
2014-01-30 16:10:53 -06:00
|
|
|
let bytes = reader.read_bytes(4).unwrap();
|
2013-05-09 19:37:31 -05:00
|
|
|
assert!(bytes == ~[10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
2013-05-13 17:23:52 -05:00
|
|
|
#[test]
|
|
|
|
fn read_bytes_eof() {
|
|
|
|
let mut reader = MemReader::new(~[10, 11]);
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.read_bytes(4).is_err());
|
2013-05-13 17:23:52 -05:00
|
|
|
}
|
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
#[test]
|
|
|
|
fn push_bytes() {
|
|
|
|
let mut reader = MemReader::new(~[10, 11, 12, 13]);
|
|
|
|
let mut buf = ~[8, 9];
|
2014-01-30 16:10:53 -06:00
|
|
|
reader.push_bytes(&mut buf, 4).unwrap();
|
2013-05-09 19:37:31 -05:00
|
|
|
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn push_bytes_partial() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = PartialReader {
|
|
|
|
count: 0,
|
2013-05-09 19:37:31 -05:00
|
|
|
};
|
|
|
|
let mut buf = ~[8, 9];
|
2014-01-30 16:10:53 -06:00
|
|
|
reader.push_bytes(&mut buf, 4).unwrap();
|
2013-05-09 19:37:31 -05:00
|
|
|
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn push_bytes_eof() {
|
|
|
|
let mut reader = MemReader::new(~[10, 11]);
|
|
|
|
let mut buf = ~[8, 9];
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.push_bytes(&mut buf, 4).is_err());
|
|
|
|
assert!(buf == ~[8, 9, 10, 11]);
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn push_bytes_error() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = ErroringLaterReader {
|
|
|
|
count: 0,
|
2013-05-09 19:37:31 -05:00
|
|
|
};
|
|
|
|
let mut buf = ~[8, 9];
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.push_bytes(&mut buf, 4).is_err());
|
2013-05-13 18:56:16 -05:00
|
|
|
assert!(buf == ~[8, 9, 10]);
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
2013-05-13 18:56:16 -05:00
|
|
|
#[test]
|
|
|
|
fn read_to_end() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = ThreeChunkReader {
|
|
|
|
count: 0,
|
2013-05-13 18:56:16 -05:00
|
|
|
};
|
2014-01-30 16:10:53 -06:00
|
|
|
let buf = reader.read_to_end().unwrap();
|
2013-05-13 18:56:16 -05:00
|
|
|
assert!(buf == ~[10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn read_to_end_error() {
|
2013-10-30 20:28:37 -05:00
|
|
|
let mut reader = ThreeChunkReader {
|
|
|
|
count: 0,
|
2013-05-13 18:56:16 -05:00
|
|
|
};
|
2014-01-30 16:10:53 -06:00
|
|
|
let buf = reader.read_to_end().unwrap();
|
2013-05-13 18:56:16 -05:00
|
|
|
assert!(buf == ~[10, 11]);
|
|
|
|
}
|
|
|
|
|
2013-07-12 16:43:57 -05:00
|
|
|
#[test]
|
|
|
|
fn test_read_write_le_mem() {
|
2014-01-25 01:37:51 -06:00
|
|
|
let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::MAX];
|
2013-05-13 21:14:14 -05:00
|
|
|
|
|
|
|
let mut writer = MemWriter::new();
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in uints.iter() {
|
2014-01-30 16:10:53 -06:00
|
|
|
writer.write_le_u64(*i).unwrap();
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2014-01-07 22:05:33 -06:00
|
|
|
let mut reader = MemReader::new(writer.unwrap());
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in uints.iter() {
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.read_le_u64().unwrap() == *i);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-12 16:43:57 -05:00
|
|
|
|
2013-05-13 21:14:14 -05:00
|
|
|
#[test]
|
|
|
|
fn test_read_write_be() {
|
2014-01-25 01:37:51 -06:00
|
|
|
let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::MAX];
|
2013-05-13 21:14:14 -05:00
|
|
|
|
|
|
|
let mut writer = MemWriter::new();
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in uints.iter() {
|
2014-01-30 16:10:53 -06:00
|
|
|
writer.write_be_u64(*i).unwrap();
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2014-01-07 22:05:33 -06:00
|
|
|
let mut reader = MemReader::new(writer.unwrap());
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in uints.iter() {
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.read_be_u64().unwrap() == *i);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_read_be_int_n() {
|
2014-01-25 01:37:51 -06:00
|
|
|
let ints = [::i32::MIN, -123456, -42, -5, 0, 1, ::i32::MAX];
|
2013-05-13 21:14:14 -05:00
|
|
|
|
|
|
|
let mut writer = MemWriter::new();
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in ints.iter() {
|
2014-01-30 16:10:53 -06:00
|
|
|
writer.write_be_i32(*i).unwrap();
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2014-01-07 22:05:33 -06:00
|
|
|
let mut reader = MemReader::new(writer.unwrap());
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in ints.iter() {
|
2013-05-13 21:14:14 -05:00
|
|
|
// this tests that the sign extension is working
|
|
|
|
// (comparing the values as i32 would not test this)
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.read_be_int_n(4).unwrap() == *i as i64);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_read_f32() {
|
|
|
|
//big-endian floating-point 8.1250
|
|
|
|
let buf = ~[0x41, 0x02, 0x00, 0x00];
|
|
|
|
|
|
|
|
let mut writer = MemWriter::new();
|
2014-01-30 16:10:53 -06:00
|
|
|
writer.write(buf).unwrap();
|
2013-05-13 21:14:14 -05:00
|
|
|
|
2014-01-07 22:05:33 -06:00
|
|
|
let mut reader = MemReader::new(writer.unwrap());
|
2014-01-30 16:10:53 -06:00
|
|
|
let f = reader.read_be_f32().unwrap();
|
2013-05-13 21:14:14 -05:00
|
|
|
assert!(f == 8.1250);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_read_write_f32() {
|
|
|
|
let f:f32 = 8.1250;
|
|
|
|
|
|
|
|
let mut writer = MemWriter::new();
|
2014-01-30 16:10:53 -06:00
|
|
|
writer.write_be_f32(f).unwrap();
|
|
|
|
writer.write_le_f32(f).unwrap();
|
2013-05-13 21:14:14 -05:00
|
|
|
|
2014-01-07 22:05:33 -06:00
|
|
|
let mut reader = MemReader::new(writer.unwrap());
|
2014-01-30 16:10:53 -06:00
|
|
|
assert!(reader.read_be_f32().unwrap() == 8.1250);
|
|
|
|
assert!(reader.read_le_f32().unwrap() == 8.1250);
|
2013-07-12 16:43:57 -05:00
|
|
|
}
|
2013-05-13 21:14:14 -05:00
|
|
|
|
2014-01-08 17:20:14 -06:00
|
|
|
#[test]
|
|
|
|
fn test_u64_from_be_bytes() {
|
|
|
|
use super::u64_from_be_bytes;
|
|
|
|
|
|
|
|
let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
|
|
|
|
|
|
|
|
// Aligned access
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 0), 0);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 1), 0x01);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 2), 0x0102);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 3), 0x010203);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 4), 0x01020304);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 5), 0x0102030405);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 6), 0x010203040506);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 7), 0x01020304050607);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 0, 8), 0x0102030405060708);
|
|
|
|
|
|
|
|
// Unaligned access
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 0), 0);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 1), 0x02);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 2), 0x0203);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 3), 0x020304);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 4), 0x02030405);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 5), 0x0203040506);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 6), 0x020304050607);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 7), 0x02030405060708);
|
|
|
|
assert_eq!(u64_from_be_bytes(buf, 1, 8), 0x0203040506070809);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod bench {
|
2014-02-13 19:49:11 -06:00
|
|
|
extern crate test;
|
|
|
|
use self::test::BenchHarness;
|
2014-01-08 17:20:14 -06:00
|
|
|
use container::Container;
|
|
|
|
|
|
|
|
macro_rules! u64_from_be_bytes_bench_impl(
|
|
|
|
($size:expr, $stride:expr, $start_index:expr) =>
|
|
|
|
({
|
|
|
|
use vec;
|
|
|
|
use super::u64_from_be_bytes;
|
|
|
|
|
|
|
|
let data = vec::from_fn($stride*100+$start_index, |i| i as u8);
|
|
|
|
let mut sum = 0u64;
|
|
|
|
bh.iter(|| {
|
|
|
|
let mut i = $start_index;
|
2014-01-19 02:21:14 -06:00
|
|
|
while i < data.len() {
|
2014-01-08 17:20:14 -06:00
|
|
|
sum += u64_from_be_bytes(data, i, $size);
|
|
|
|
i += $stride;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn u64_from_be_bytes_4_aligned(bh: &mut BenchHarness) {
|
|
|
|
u64_from_be_bytes_bench_impl!(4, 4, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn u64_from_be_bytes_4_unaligned(bh: &mut BenchHarness) {
|
|
|
|
u64_from_be_bytes_bench_impl!(4, 4, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn u64_from_be_bytes_7_aligned(bh: &mut BenchHarness) {
|
|
|
|
u64_from_be_bytes_bench_impl!(7, 8, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn u64_from_be_bytes_7_unaligned(bh: &mut BenchHarness) {
|
|
|
|
u64_from_be_bytes_bench_impl!(7, 8, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn u64_from_be_bytes_8_aligned(bh: &mut BenchHarness) {
|
|
|
|
u64_from_be_bytes_bench_impl!(8, 8, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn u64_from_be_bytes_8_unaligned(bh: &mut BenchHarness) {
|
|
|
|
u64_from_be_bytes_bench_impl!(8, 8, 1);
|
|
|
|
}
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|