2013-04-17 19:55:21 -05:00
|
|
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// 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
|
|
|
|
|
2013-04-19 14:04:19 -05:00
|
|
|
// XXX: Not sure how this should be structured
|
2013-05-08 12:34:47 -05:00
|
|
|
// XXX: Iteration should probably be considered separately
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-05-13 21:14:14 -05:00
|
|
|
use uint;
|
|
|
|
use int;
|
2013-09-08 10:01:16 -05:00
|
|
|
use iter::Iterator;
|
2013-05-09 19:37:31 -05:00
|
|
|
use vec;
|
2013-09-01 18:30:21 -05:00
|
|
|
use rt::io::{Reader, Writer, Decorator};
|
2013-10-18 13:52:23 -05:00
|
|
|
use rt::io::{io_error, standard_error, EndOfFile, DEFAULT_BUF_SIZE};
|
2013-05-09 19:37:31 -05:00
|
|
|
use option::{Option, Some, None};
|
|
|
|
use unstable::finally::Finally;
|
2013-05-13 21:14:14 -05:00
|
|
|
use cast;
|
|
|
|
use io::{u64_to_le_bytes, u64_to_be_bytes};
|
2013-05-09 19:37:31 -05:00
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
pub trait ReaderUtil {
|
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
/// Reads a single byte. Returns `None` on EOF.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Raises the same conditions as the `read` method. Returns
|
|
|
|
/// `None` if the condition is handled.
|
|
|
|
fn read_byte(&mut self) -> Option<u8>;
|
|
|
|
|
|
|
|
/// Reads `len` bytes and appends them to a vector.
|
|
|
|
///
|
|
|
|
/// May push fewer than the requested number of bytes on error
|
|
|
|
/// or EOF. Returns true on success, false on EOF or error.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
2013-10-18 13:52:23 -05:00
|
|
|
/// Raises the same conditions as `read`. Additionally raises `io_error`
|
|
|
|
/// on EOF. If `io_error` is handled then `push_bytes` may push less
|
2013-05-13 18:56:16 -05:00
|
|
|
/// than the requested number of bytes.
|
2013-05-13 17:23:52 -05:00
|
|
|
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint);
|
2013-05-09 19:37:31 -05:00
|
|
|
|
2013-05-13 17:23:52 -05:00
|
|
|
/// Reads `len` bytes and gives you back a new vector of length `len`
|
2013-04-17 19:55:21 -05:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
2013-10-18 13:52:23 -05:00
|
|
|
/// Raises the same conditions as `read`. Additionally raises `io_error`
|
|
|
|
/// on EOF. If `io_error` is handled then the returned vector may
|
2013-05-13 18:56:16 -05:00
|
|
|
/// contain less than the requested number of bytes.
|
2013-04-17 19:55:21 -05:00
|
|
|
fn read_bytes(&mut self, len: uint) -> ~[u8];
|
|
|
|
|
|
|
|
/// Reads all remaining bytes from the stream.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
2013-05-09 19:37:31 -05:00
|
|
|
/// Raises the same conditions as the `read` method.
|
2013-04-17 19:55:21 -05:00
|
|
|
fn read_to_end(&mut self) -> ~[u8];
|
|
|
|
|
2013-09-01 18:30:21 -05:00
|
|
|
/// Create an iterator that reads a single byte on
|
|
|
|
/// each iteration, until EOF.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Raises the same conditions as the `read` method, for
|
|
|
|
/// each call to its `.next()` method.
|
|
|
|
/// Ends the iteration if the condition is handled.
|
2013-09-03 13:00:32 -05:00
|
|
|
fn bytes(self) -> ByteIterator<Self>;
|
2013-09-01 18:30:21 -05:00
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait ReaderByteConversions {
|
|
|
|
/// Reads `n` little-endian unsigned integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_uint_n_(&mut self, nbytes: uint) -> u64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads `n` little-endian signed integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_int_n_(&mut self, nbytes: uint) -> i64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads `n` big-endian unsigned integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_uint_n_(&mut self, nbytes: uint) -> u64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads `n` big-endian signed integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_int_n_(&mut self, nbytes: uint) -> i64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian unsigned integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_uint_(&mut self) -> uint;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_int_(&mut self) -> int;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian unsigned integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_uint_(&mut self) -> uint;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_int_(&mut self) -> int;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `u64`.
|
|
|
|
///
|
|
|
|
/// `u64`s are 8 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_u64_(&mut self) -> u64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `u32`.
|
|
|
|
///
|
|
|
|
/// `u32`s are 4 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_u32_(&mut self) -> u32;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `u16`.
|
|
|
|
///
|
|
|
|
/// `u16`s are 2 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_u16_(&mut self) -> u16;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `i64`.
|
|
|
|
///
|
|
|
|
/// `i64`s are 8 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_i64_(&mut self) -> i64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `i32`.
|
|
|
|
///
|
|
|
|
/// `i32`s are 4 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_i32_(&mut self) -> i32;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `i16`.
|
|
|
|
///
|
|
|
|
/// `i16`s are 2 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_i16_(&mut self) -> i16;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `f64`.
|
|
|
|
///
|
|
|
|
/// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_f64_(&mut self) -> f64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a big-endian `f32`.
|
|
|
|
///
|
|
|
|
/// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_f32_(&mut self) -> f32;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `u64`.
|
|
|
|
///
|
|
|
|
/// `u64`s are 8 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_u64_(&mut self) -> u64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `u32`.
|
|
|
|
///
|
|
|
|
/// `u32`s are 4 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_u32_(&mut self) -> u32;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `u16`.
|
|
|
|
///
|
|
|
|
/// `u16`s are 2 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_u16_(&mut self) -> u16;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `i64`.
|
|
|
|
///
|
|
|
|
/// `i64`s are 8 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_i64_(&mut self) -> i64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `i32`.
|
|
|
|
///
|
|
|
|
/// `i32`s are 4 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_i32_(&mut self) -> i32;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `i16`.
|
|
|
|
///
|
|
|
|
/// `i16`s are 2 bytes long.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_i16_(&mut self) -> i16;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `f64`.
|
|
|
|
///
|
|
|
|
/// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_f64_(&mut self) -> f64;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Reads a little-endian `f32`.
|
|
|
|
///
|
|
|
|
/// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_f32_(&mut self) -> f32;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Read a u8.
|
|
|
|
///
|
|
|
|
/// `u8`s are 1 byte.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_u8_(&mut self) -> u8;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Read an i8.
|
|
|
|
///
|
|
|
|
/// `i8`s are 1 byte.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_i8_(&mut self) -> i8;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait WriterByteConversions {
|
|
|
|
/// Write the result of passing n through `int::to_str_bytes`.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_int_(&mut self, n: int);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write the result of passing n through `uint::to_str_bytes`.
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_uint_(&mut self, n: uint);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian uint (number of bytes depends on system).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_uint_(&mut self, n: uint);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian int (number of bytes depends on system).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_int_(&mut self, n: int);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian uint (number of bytes depends on system).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_uint_(&mut self, n: uint);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian int (number of bytes depends on system).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_int_(&mut self, n: int);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian u64 (8 bytes).
|
2013-05-13 21:14:14 -05:00
|
|
|
fn write_be_u64_(&mut self, n: u64);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian u32 (4 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_u32_(&mut self, n: u32);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian u16 (2 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_u16_(&mut self, n: u16);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian i64 (8 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_i64_(&mut self, n: i64);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian i32 (4 bytes).
|
2013-07-12 16:43:57 -05:00
|
|
|
fn write_be_i32_(&mut self, n: i32);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian i16 (2 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_i16_(&mut self, n: i16);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_f64_(&mut self, f: f64);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
|
2013-07-12 16:43:57 -05:00
|
|
|
fn write_be_f32_(&mut self, f: f32);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian u64 (8 bytes).
|
2013-05-13 21:14:14 -05:00
|
|
|
fn write_le_u64_(&mut self, n: u64);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian u32 (4 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_u32_(&mut self, n: u32);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian u16 (2 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_u16_(&mut self, n: u16);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian i64 (8 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_i64_(&mut self, n: i64);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian i32 (4 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_i32_(&mut self, n: i32);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian i16 (2 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_i16_(&mut self, n: i16);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a little-endian IEEE754 double-precision floating-point
|
|
|
|
/// (8 bytes).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_f64_(&mut self, f: f64);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-08-17 17:28:04 -05:00
|
|
|
/// Write a little-endian IEEE754 single-precision floating-point
|
2013-04-17 19:55:21 -05:00
|
|
|
/// (4 bytes).
|
2013-07-12 16:43:57 -05:00
|
|
|
fn write_le_f32_(&mut self, f: f32);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a u8 (1 byte).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_u8_(&mut self, n: u8);
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
/// Write a i8 (1 byte).
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_i8_(&mut self, n: i8);
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
2013-05-09 19:37:31 -05:00
|
|
|
|
2013-05-13 18:56:16 -05:00
|
|
|
impl<T: Reader> ReaderUtil for T {
|
|
|
|
fn read_byte(&mut self) -> Option<u8> {
|
|
|
|
let mut buf = [0];
|
|
|
|
match self.read(buf) {
|
|
|
|
Some(0) => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("read 0 bytes. trying again");
|
2013-05-13 18:56:16 -05:00
|
|
|
self.read_byte()
|
|
|
|
}
|
|
|
|
Some(1) => Some(buf[0]),
|
2013-09-19 00:04:03 -05:00
|
|
|
Some(_) => unreachable!(),
|
2013-05-13 18:56:16 -05:00
|
|
|
None => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) {
|
|
|
|
unsafe {
|
|
|
|
let start_len = buf.len();
|
|
|
|
let mut total_read = 0;
|
|
|
|
|
2013-09-10 18:57:08 -05:00
|
|
|
buf.reserve_additional(len);
|
2013-05-13 18:56:16 -05:00
|
|
|
vec::raw::set_len(buf, start_len + len);
|
|
|
|
|
|
|
|
do (|| {
|
|
|
|
while total_read < len {
|
2013-06-15 01:20:06 -05:00
|
|
|
let len = buf.len();
|
2013-06-27 04:48:50 -05:00
|
|
|
let slice = buf.mut_slice(start_len + total_read, len);
|
2013-05-13 18:56:16 -05:00
|
|
|
match self.read(slice) {
|
|
|
|
Some(nread) => {
|
|
|
|
total_read += nread;
|
|
|
|
}
|
|
|
|
None => {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(standard_error(EndOfFile));
|
2013-05-13 18:56:16 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).finally {
|
|
|
|
vec::raw::set_len(buf, start_len + total_read);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_bytes(&mut self, len: uint) -> ~[u8] {
|
|
|
|
let mut buf = vec::with_capacity(len);
|
|
|
|
self.push_bytes(&mut buf, len);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_to_end(&mut self) -> ~[u8] {
|
|
|
|
let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE);
|
|
|
|
let mut keep_reading = true;
|
2013-10-18 13:52:23 -05:00
|
|
|
do io_error::cond.trap(|e| {
|
2013-05-13 18:56:16 -05:00
|
|
|
if e.kind == EndOfFile {
|
|
|
|
keep_reading = false;
|
|
|
|
} else {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(e)
|
2013-05-13 18:56:16 -05:00
|
|
|
}
|
2013-07-31 16:59:59 -05:00
|
|
|
}).inside {
|
2013-05-13 18:56:16 -05:00
|
|
|
while keep_reading {
|
|
|
|
self.push_bytes(&mut buf, DEFAULT_BUF_SIZE)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
2013-09-01 18:30:21 -05:00
|
|
|
|
2013-09-03 13:00:32 -05:00
|
|
|
fn bytes(self) -> ByteIterator<T> {
|
|
|
|
ByteIterator{reader: self}
|
2013-09-01 18:30:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An iterator that reads a single byte on each iteration,
|
2013-09-03 13:00:32 -05:00
|
|
|
/// until `.read_byte()` returns `None`.
|
|
|
|
///
|
|
|
|
/// # Notes about the Iteration Protocol
|
|
|
|
///
|
|
|
|
/// The `ByteIterator` may yield `None` and thus terminate
|
|
|
|
/// an iteration, but continue to yield elements if iteration
|
|
|
|
/// is attempted again.
|
2013-09-01 18:30:21 -05:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Raises the same conditions as the `read` method, for
|
|
|
|
/// each call to its `.next()` method.
|
2013-09-03 13:00:32 -05:00
|
|
|
/// Yields `None` if the condition is handled.
|
|
|
|
pub struct ByteIterator<T> {
|
2013-09-01 18:30:21 -05:00
|
|
|
priv reader: T,
|
|
|
|
}
|
|
|
|
|
2013-09-03 13:00:32 -05:00
|
|
|
impl<R> Decorator<R> for ByteIterator<R> {
|
2013-09-01 18:30:21 -05:00
|
|
|
fn inner(self) -> R { self.reader }
|
|
|
|
fn inner_ref<'a>(&'a self) -> &'a R { &self.reader }
|
|
|
|
fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { &mut self.reader }
|
|
|
|
}
|
|
|
|
|
2013-09-03 13:00:32 -05:00
|
|
|
impl<'self, R: Reader> Iterator<u8> for ByteIterator<R> {
|
2013-09-01 18:30:21 -05:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<u8> {
|
|
|
|
self.reader.read_byte()
|
|
|
|
}
|
2013-05-13 18:56:16 -05:00
|
|
|
}
|
|
|
|
|
2013-05-13 21:14:14 -05:00
|
|
|
impl<T: Reader> ReaderByteConversions for T {
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_uint_n_(&mut self, nbytes: uint) -> u64 {
|
2013-05-13 21:14:14 -05:00
|
|
|
assert!(nbytes > 0 && nbytes <= 8);
|
|
|
|
|
2013-06-06 20:54:14 -05:00
|
|
|
let mut val = 0u64;
|
|
|
|
let mut pos = 0;
|
|
|
|
let mut i = nbytes;
|
2013-05-13 21:14:14 -05:00
|
|
|
while i > 0 {
|
2013-08-19 00:40:04 -05:00
|
|
|
val += (self.read_u8_() as u64) << pos;
|
2013-05-13 21:14:14 -05:00
|
|
|
pos += 8;
|
|
|
|
i -= 1;
|
|
|
|
}
|
|
|
|
val
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_int_n_(&mut self, nbytes: uint) -> i64 {
|
|
|
|
extend_sign(self.read_le_uint_n_(nbytes), nbytes)
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_uint_n_(&mut self, nbytes: uint) -> u64 {
|
2013-05-13 21:14:14 -05:00
|
|
|
assert!(nbytes > 0 && nbytes <= 8);
|
|
|
|
|
2013-06-06 20:54:14 -05:00
|
|
|
let mut val = 0u64;
|
|
|
|
let mut i = nbytes;
|
2013-05-13 21:14:14 -05:00
|
|
|
while i > 0 {
|
|
|
|
i -= 1;
|
2013-08-19 00:40:04 -05:00
|
|
|
val += (self.read_u8_() as u64) << i * 8;
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
val
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_int_n_(&mut self, nbytes: uint) -> i64 {
|
|
|
|
extend_sign(self.read_be_uint_n_(nbytes), nbytes)
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_uint_(&mut self) -> uint {
|
|
|
|
self.read_le_uint_n_(uint::bytes) as uint
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_int_(&mut self) -> int {
|
|
|
|
self.read_le_int_n_(int::bytes) as int
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_uint_(&mut self) -> uint {
|
|
|
|
self.read_be_uint_n_(uint::bytes) as uint
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_int_(&mut self) -> int {
|
|
|
|
self.read_be_int_n_(int::bytes) as int
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_u64_(&mut self) -> u64 {
|
|
|
|
self.read_be_uint_n_(8) as u64
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_u32_(&mut self) -> u32 {
|
|
|
|
self.read_be_uint_n_(4) as u32
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_u16_(&mut self) -> u16 {
|
|
|
|
self.read_be_uint_n_(2) as u16
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_i64_(&mut self) -> i64 {
|
|
|
|
self.read_be_int_n_(8) as i64
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_i32_(&mut self) -> i32 {
|
|
|
|
self.read_be_int_n_(4) as i32
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_i16_(&mut self) -> i16 {
|
|
|
|
self.read_be_int_n_(2) as i16
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_f64_(&mut self) -> f64 {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
2013-08-19 00:40:04 -05:00
|
|
|
cast::transmute::<u64, f64>(self.read_be_u64_())
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_be_f32_(&mut self) -> f32 {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
2013-08-19 00:40:04 -05:00
|
|
|
cast::transmute::<u32, f32>(self.read_be_u32_())
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_u64_(&mut self) -> u64 {
|
|
|
|
self.read_le_uint_n_(8) as u64
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_u32_(&mut self) -> u32 {
|
|
|
|
self.read_le_uint_n_(4) as u32
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_u16_(&mut self) -> u16 {
|
|
|
|
self.read_le_uint_n_(2) as u16
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_i64_(&mut self) -> i64 {
|
|
|
|
self.read_le_int_n_(8) as i64
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_i32_(&mut self) -> i32 {
|
|
|
|
self.read_le_int_n_(4) as i32
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_i16_(&mut self) -> i16 {
|
|
|
|
self.read_le_int_n_(2) as i16
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_f64_(&mut self) -> f64 {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
2013-08-19 00:40:04 -05:00
|
|
|
cast::transmute::<u64, f64>(self.read_le_u64_())
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_le_f32_(&mut self) -> f32 {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
2013-08-19 00:40:04 -05:00
|
|
|
cast::transmute::<u32, f32>(self.read_le_u32_())
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_u8_(&mut self) -> u8 {
|
2013-05-13 21:14:14 -05:00
|
|
|
match self.read_byte() {
|
|
|
|
Some(b) => b as u8,
|
|
|
|
None => 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn read_i8_(&mut self) -> i8 {
|
2013-05-13 21:14:14 -05:00
|
|
|
match self.read_byte() {
|
|
|
|
Some(b) => b as i8,
|
|
|
|
None => 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Writer> WriterByteConversions for T {
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_int_(&mut self, n: int) {
|
2013-05-13 21:14:14 -05:00
|
|
|
int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_uint_(&mut self, n: uint) {
|
2013-05-13 21:14:14 -05:00
|
|
|
uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_uint_(&mut self, n: uint) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_int_(&mut self, n: int) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_uint_(&mut self, n: uint) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_int_(&mut self, n: int) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_be_u64_(&mut self, n: u64) {
|
|
|
|
u64_to_be_bytes(n, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_u32_(&mut self, n: u32) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_u16_(&mut self, n: u16) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_i64_(&mut self, n: i64) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-07-12 16:43:57 -05:00
|
|
|
fn write_be_i32_(&mut self, n: i32) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_i16_(&mut self, n: i16) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_be_f64_(&mut self, f: f64) {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
|
|
|
self.write_be_u64_(cast::transmute(f))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-12 16:43:57 -05:00
|
|
|
fn write_be_f32_(&mut self, f: f32) {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
2013-08-19 00:40:04 -05:00
|
|
|
self.write_be_u32_(cast::transmute(f))
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_le_u64_(&mut self, n: u64) {
|
|
|
|
u64_to_le_bytes(n, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_u32_(&mut self, n: u32) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_u16_(&mut self, n: u16) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_i64_(&mut self, n: i64) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_i32_(&mut self, n: i32) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_i16_(&mut self, n: i16) {
|
2013-05-13 21:14:14 -05:00
|
|
|
u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_le_f64_(&mut self, f: f64) {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
|
|
|
self.write_le_u64_(cast::transmute(f))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-12 16:43:57 -05:00
|
|
|
fn write_le_f32_(&mut self, f: f32) {
|
2013-05-13 21:14:14 -05:00
|
|
|
unsafe {
|
2013-08-19 00:40:04 -05:00
|
|
|
self.write_le_u32_(cast::transmute(f))
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_u8_(&mut self, n: u8) {
|
2013-05-17 20:11:47 -05:00
|
|
|
self.write([n])
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 00:40:04 -05:00
|
|
|
fn write_i8_(&mut self, n: i8) {
|
2013-05-17 20:11:47 -05:00
|
|
|
self.write([n as u8])
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn extend_sign(val: u64, nbytes: uint) -> i64 {
|
|
|
|
let shift = (8 - nbytes) * 8;
|
|
|
|
(val << shift) as i64 >> shift
|
|
|
|
}
|
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2013-05-23 11:39:17 -05:00
|
|
|
use super::ReaderUtil;
|
2013-05-09 19:37:31 -05:00
|
|
|
use option::{Some, None};
|
|
|
|
use cell::Cell;
|
2013-07-12 16:43:57 -05:00
|
|
|
use rt::io::mem::{MemReader, MemWriter};
|
2013-05-13 21:14:14 -05:00
|
|
|
use rt::io::mock::MockReader;
|
2013-10-18 13:52:23 -05:00
|
|
|
use rt::io::{io_error, placeholder_error};
|
2013-05-09 19:37:31 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte() {
|
|
|
|
let mut reader = MemReader::new(~[10]);
|
|
|
|
let byte = reader.read_byte();
|
|
|
|
assert!(byte == Some(10));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte_0_bytes() {
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-09 19:37:31 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
Some(0)
|
|
|
|
} else {
|
|
|
|
buf[0] = 10;
|
|
|
|
Some(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let byte = reader.read_byte();
|
|
|
|
assert!(byte == Some(10));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte_eof() {
|
|
|
|
let mut reader = MockReader::new();
|
|
|
|
reader.read = |_| None;
|
|
|
|
let byte = reader.read_byte();
|
|
|
|
assert!(byte == None);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_byte_error() {
|
|
|
|
let mut reader = MockReader::new();
|
|
|
|
reader.read = |_| {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(placeholder_error());
|
2013-05-09 19:37:31 -05:00
|
|
|
None
|
|
|
|
};
|
2013-10-18 13:52:23 -05:00
|
|
|
do io_error::cond.trap(|_| {
|
2013-07-31 16:59:59 -05:00
|
|
|
}).inside {
|
2013-05-09 19:37:31 -05:00
|
|
|
let byte = reader.read_byte();
|
|
|
|
assert!(byte == None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-01 18:30:21 -05:00
|
|
|
#[test]
|
|
|
|
fn bytes_0_bytes() {
|
|
|
|
let mut reader = MockReader::new();
|
|
|
|
let count = Cell::new(0);
|
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
Some(0)
|
|
|
|
} else {
|
|
|
|
buf[0] = 10;
|
|
|
|
Some(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let byte = reader.bytes().next();
|
|
|
|
assert!(byte == Some(10));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bytes_eof() {
|
|
|
|
let mut reader = MockReader::new();
|
|
|
|
reader.read = |_| None;
|
|
|
|
let byte = reader.bytes().next();
|
|
|
|
assert!(byte == None);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bytes_error() {
|
|
|
|
let mut reader = MockReader::new();
|
|
|
|
reader.read = |_| {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(placeholder_error());
|
2013-09-01 18:30:21 -05:00
|
|
|
None
|
|
|
|
};
|
|
|
|
let mut it = reader.bytes();
|
2013-10-18 13:52:23 -05:00
|
|
|
do io_error::cond.trap(|_| ()).inside {
|
2013-09-01 18:30:21 -05:00
|
|
|
let byte = it.next();
|
|
|
|
assert!(byte == None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
#[test]
|
|
|
|
fn read_bytes() {
|
|
|
|
let mut reader = MemReader::new(~[10, 11, 12, 13]);
|
|
|
|
let bytes = reader.read_bytes(4);
|
|
|
|
assert!(bytes == ~[10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_bytes_partial() {
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-09 19:37:31 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
buf[1] = 11;
|
|
|
|
Some(2)
|
|
|
|
} else {
|
|
|
|
buf[0] = 12;
|
|
|
|
buf[1] = 13;
|
|
|
|
Some(2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let bytes = reader.read_bytes(4);
|
|
|
|
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]);
|
2013-10-18 13:52:23 -05:00
|
|
|
do io_error::cond.trap(|_| {
|
2013-07-31 16:59:59 -05:00
|
|
|
}).inside {
|
2013-05-13 18:56:16 -05:00
|
|
|
assert!(reader.read_bytes(4) == ~[10, 11]);
|
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];
|
2013-05-13 17:23:52 -05:00
|
|
|
reader.push_bytes(&mut buf, 4);
|
2013-05-09 19:37:31 -05:00
|
|
|
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn push_bytes_partial() {
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-09 19:37:31 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
buf[1] = 11;
|
|
|
|
Some(2)
|
|
|
|
} else {
|
|
|
|
buf[0] = 12;
|
|
|
|
buf[1] = 13;
|
|
|
|
Some(2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let mut buf = ~[8, 9];
|
2013-05-13 17:23:52 -05:00
|
|
|
reader.push_bytes(&mut buf, 4);
|
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];
|
2013-10-18 13:52:23 -05:00
|
|
|
do io_error::cond.trap(|_| {
|
2013-07-31 16:59:59 -05:00
|
|
|
}).inside {
|
2013-05-13 17:23:52 -05:00
|
|
|
reader.push_bytes(&mut buf, 4);
|
2013-05-13 18:56:16 -05:00
|
|
|
assert!(buf == ~[8, 9, 10, 11]);
|
2013-05-13 17:23:52 -05:00
|
|
|
}
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn push_bytes_error() {
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-09 19:37:31 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
Some(1)
|
|
|
|
} else {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(placeholder_error());
|
2013-05-09 19:37:31 -05:00
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let mut buf = ~[8, 9];
|
2013-10-18 13:52:23 -05:00
|
|
|
do io_error::cond.trap(|_| { } ).inside {
|
2013-05-13 17:23:52 -05:00
|
|
|
reader.push_bytes(&mut buf, 4);
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
2013-05-13 18:56:16 -05:00
|
|
|
assert!(buf == ~[8, 9, 10]);
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn push_bytes_fail_reset_len() {
|
|
|
|
// push_bytes unsafely sets the vector length. This is testing that
|
|
|
|
// upon failure the length is reset correctly.
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-09 19:37:31 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
Some(1)
|
|
|
|
} else {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(placeholder_error());
|
2013-05-09 19:37:31 -05:00
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let buf = @mut ~[8, 9];
|
|
|
|
do (|| {
|
|
|
|
reader.push_bytes(&mut *buf, 4);
|
|
|
|
}).finally {
|
|
|
|
// NB: Using rtassert here to trigger abort on failure since this is a should_fail test
|
2013-06-10 19:46:49 -05:00
|
|
|
// FIXME: #7049 This fails because buf is still borrowed
|
|
|
|
//rtassert!(*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() {
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-13 18:56:16 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
buf[1] = 11;
|
|
|
|
Some(2)
|
|
|
|
} else if *count == 1 {
|
|
|
|
*count = 2;
|
|
|
|
buf[0] = 12;
|
|
|
|
buf[1] = 13;
|
|
|
|
Some(2)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let buf = reader.read_to_end();
|
|
|
|
assert!(buf == ~[10, 11, 12, 13]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn read_to_end_error() {
|
|
|
|
let mut reader = MockReader::new();
|
2013-06-04 05:03:58 -05:00
|
|
|
let count = Cell::new(0);
|
2013-05-13 18:56:16 -05:00
|
|
|
reader.read = |buf| {
|
|
|
|
do count.with_mut_ref |count| {
|
|
|
|
if *count == 0 {
|
|
|
|
*count = 1;
|
|
|
|
buf[0] = 10;
|
|
|
|
buf[1] = 11;
|
|
|
|
Some(2)
|
|
|
|
} else {
|
2013-10-18 13:52:23 -05:00
|
|
|
io_error::cond.raise(placeholder_error());
|
2013-05-13 18:56:16 -05:00
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let buf = reader.read_to_end();
|
|
|
|
assert!(buf == ~[10, 11]);
|
|
|
|
}
|
|
|
|
|
2013-07-12 16:43:57 -05:00
|
|
|
#[test]
|
|
|
|
fn test_read_write_le_mem() {
|
|
|
|
let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
|
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() {
|
|
|
|
writer.write_le_u64_(*i);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut reader = MemReader::new(writer.inner());
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in uints.iter() {
|
2013-08-19 00:40:04 -05:00
|
|
|
assert!(reader.read_le_u64_() == *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() {
|
2013-07-12 16:43:57 -05:00
|
|
|
let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
|
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() {
|
|
|
|
writer.write_be_u64_(*i);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut reader = MemReader::new(writer.inner());
|
2013-07-12 16:43:57 -05:00
|
|
|
for i in uints.iter() {
|
2013-08-19 00:40:04 -05:00
|
|
|
assert!(reader.read_be_u64_() == *i);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_read_be_int_n() {
|
2013-07-12 16:43:57 -05:00
|
|
|
let ints = [::i32::min_value, -123456, -42, -5, 0, 1, ::i32::max_value];
|
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() {
|
|
|
|
writer.write_be_i32_(*i);
|
2013-05-13 21:14:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut reader = MemReader::new(writer.inner());
|
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)
|
2013-08-19 00:40:04 -05:00
|
|
|
assert!(reader.read_be_int_n_(4) == *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();
|
|
|
|
writer.write(buf);
|
|
|
|
|
|
|
|
let mut reader = MemReader::new(writer.inner());
|
2013-08-19 00:40:04 -05:00
|
|
|
let f = reader.read_be_f32_();
|
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();
|
2013-07-12 16:43:57 -05:00
|
|
|
writer.write_be_f32_(f);
|
|
|
|
writer.write_le_f32_(f);
|
2013-05-13 21:14:14 -05:00
|
|
|
|
|
|
|
let mut reader = MemReader::new(writer.inner());
|
2013-08-19 00:40:04 -05:00
|
|
|
assert!(reader.read_be_f32_() == 8.1250);
|
|
|
|
assert!(reader.read_le_f32_() == 8.1250);
|
2013-07-12 16:43:57 -05:00
|
|
|
}
|
2013-05-13 21:14:14 -05:00
|
|
|
|
2013-05-09 19:37:31 -05:00
|
|
|
}
|