1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Utility mixins that apply to all Readers and Writers
13 // XXX: Not sure how this should be structured
14 // XXX: Iteration should probably be considered separately
16 use container::Container;
20 use vec::{OwnedVector, ImmutableVector};
22 /// An iterator that reads a single byte on each iteration,
23 /// until `.read_byte()` returns `None`.
25 /// # Notes about the Iteration Protocol
27 /// The `ByteIterator` may yield `None` and thus terminate
28 /// an iteration, but continue to yield elements if iteration
29 /// is attempted again.
33 /// Raises the same conditions as the `read` method, for
34 /// each call to its `.next()` method.
35 /// Yields `None` if the condition is handled.
36 pub struct ByteIterator<'r, T> {
37 priv reader: &'r mut T,
40 impl<'r, R: Reader> ByteIterator<'r, R> {
41 pub fn new(r: &'r mut R) -> ByteIterator<'r, R> {
42 ByteIterator { reader: r }
46 impl<'r, R: Reader> Iterator<u8> for ByteIterator<'r, R> {
48 fn next(&mut self) -> Option<u8> {
49 self.reader.read_byte()
53 pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
73 let mut bytes: ~[u8] = ~[];
77 bytes.push((n & 255_u64) as u8);
86 pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
90 2u => f(&[(n >> 8) as u8,
92 4u => f(&[(n >> 24) as u8,
96 8u => f(&[(n >> 56) as u8,
105 let mut bytes: ~[u8] = ~[];
108 let shift = ((i - 1u) * 8u) as u64;
109 bytes.push((n >> shift) as u8);
117 pub fn u64_from_be_bytes(data: &[u8],
121 use ptr::{copy_nonoverlapping_memory, offset, mut_offset};
122 use unstable::intrinsics::from_be64;
123 use vec::MutableVector;
127 if data.len() - start < size {
128 fail!("index out of bounds");
131 let mut buf = [0u8, ..8];
133 let ptr = offset(data.as_ptr(), start as int);
134 let out = buf.as_mut_ptr();
135 copy_nonoverlapping_memory(mut_offset(out, (8 - size) as int), ptr, size);
136 from_be64(*(out as *i64)) as u64
142 use unstable::finally::Finally;
144 use io::{MemReader, MemWriter};
145 use io::{io_error, placeholder_error};
147 struct InitialZeroByteReader {
151 impl Reader for InitialZeroByteReader {
152 fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
165 impl Reader for EofReader {
166 fn read(&mut self, _: &mut [u8]) -> Option<uint> {
171 struct ErroringReader;
173 impl Reader for ErroringReader {
174 fn read(&mut self, _: &mut [u8]) -> Option<uint> {
175 io_error::cond.raise(placeholder_error());
180 struct PartialReader {
184 impl Reader for PartialReader {
185 fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
199 struct ErroringLaterReader {
203 impl Reader for ErroringLaterReader {
204 fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
210 io_error::cond.raise(placeholder_error());
216 struct ThreeChunkReader {
220 impl Reader for ThreeChunkReader {
221 fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
227 } else if self.count == 1 {
240 let mut reader = MemReader::new(~[10]);
241 let byte = reader.read_byte();
242 assert!(byte == Some(10));
246 fn read_byte_0_bytes() {
247 let mut reader = InitialZeroByteReader {
250 let byte = reader.read_byte();
251 assert!(byte == Some(10));
256 let mut reader = EofReader;
257 let byte = reader.read_byte();
258 assert!(byte == None);
262 fn read_byte_error() {
263 let mut reader = ErroringReader;
264 io_error::cond.trap(|_| {
266 let byte = reader.read_byte();
267 assert!(byte == None);
273 let mut reader = InitialZeroByteReader {
276 let byte = reader.bytes().next();
277 assert!(byte == Some(10));
282 let mut reader = EofReader;
283 let byte = reader.bytes().next();
284 assert!(byte == None);
289 let mut reader = ErroringReader;
290 let mut it = reader.bytes();
291 io_error::cond.trap(|_| ()).inside(|| {
292 let byte = it.next();
293 assert!(byte == None);
299 let mut reader = MemReader::new(~[10, 11, 12, 13]);
300 let bytes = reader.read_bytes(4);
301 assert!(bytes == ~[10, 11, 12, 13]);
305 fn read_bytes_partial() {
306 let mut reader = PartialReader {
309 let bytes = reader.read_bytes(4);
310 assert!(bytes == ~[10, 11, 12, 13]);
314 fn read_bytes_eof() {
315 let mut reader = MemReader::new(~[10, 11]);
316 io_error::cond.trap(|_| {
318 assert!(reader.read_bytes(4) == ~[10, 11]);
324 let mut reader = MemReader::new(~[10, 11, 12, 13]);
325 let mut buf = ~[8, 9];
326 reader.push_bytes(&mut buf, 4);
327 assert!(buf == ~[8, 9, 10, 11, 12, 13]);
331 fn push_bytes_partial() {
332 let mut reader = PartialReader {
335 let mut buf = ~[8, 9];
336 reader.push_bytes(&mut buf, 4);
337 assert!(buf == ~[8, 9, 10, 11, 12, 13]);
341 fn push_bytes_eof() {
342 let mut reader = MemReader::new(~[10, 11]);
343 let mut buf = ~[8, 9];
344 io_error::cond.trap(|_| {
346 reader.push_bytes(&mut buf, 4);
347 assert!(buf == ~[8, 9, 10, 11]);
352 fn push_bytes_error() {
353 let mut reader = ErroringLaterReader {
356 let mut buf = ~[8, 9];
357 io_error::cond.trap(|_| { } ).inside(|| {
358 reader.push_bytes(&mut buf, 4);
360 assert!(buf == ~[8, 9, 10]);
365 #[ignore] // borrow issues with RefCell
366 fn push_bytes_fail_reset_len() {
367 // push_bytes unsafely sets the vector length. This is testing that
368 // upon failure the length is reset correctly.
369 let reader = ErroringLaterReader {
372 // FIXME (#7049): Figure out some other way to do this.
373 //let buf = RefCell::new(~[8, 9]);
375 //reader.push_bytes(buf.borrow_mut().get(), 4);
377 // NB: Using rtassert here to trigger abort on failure since this is a should_fail test
378 // FIXME: #7049 This fails because buf is still borrowed
379 //rtassert!(buf.borrow().get() == ~[8, 9, 10]);
385 let mut reader = ThreeChunkReader {
388 let buf = reader.read_to_end();
389 assert!(buf == ~[10, 11, 12, 13]);
394 fn read_to_end_error() {
395 let mut reader = ThreeChunkReader {
398 let buf = reader.read_to_end();
399 assert!(buf == ~[10, 11]);
403 fn test_read_write_le_mem() {
404 let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
406 let mut writer = MemWriter::new();
407 for i in uints.iter() {
408 writer.write_le_u64(*i);
411 let mut reader = MemReader::new(writer.unwrap());
412 for i in uints.iter() {
413 assert!(reader.read_le_u64() == *i);
419 fn test_read_write_be() {
420 let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
422 let mut writer = MemWriter::new();
423 for i in uints.iter() {
424 writer.write_be_u64(*i);
427 let mut reader = MemReader::new(writer.unwrap());
428 for i in uints.iter() {
429 assert!(reader.read_be_u64() == *i);
434 fn test_read_be_int_n() {
435 let ints = [::i32::min_value, -123456, -42, -5, 0, 1, ::i32::max_value];
437 let mut writer = MemWriter::new();
438 for i in ints.iter() {
439 writer.write_be_i32(*i);
442 let mut reader = MemReader::new(writer.unwrap());
443 for i in ints.iter() {
444 // this tests that the sign extension is working
445 // (comparing the values as i32 would not test this)
446 assert!(reader.read_be_int_n(4) == *i as i64);
452 //big-endian floating-point 8.1250
453 let buf = ~[0x41, 0x02, 0x00, 0x00];
455 let mut writer = MemWriter::new();
458 let mut reader = MemReader::new(writer.unwrap());
459 let f = reader.read_be_f32();
460 assert!(f == 8.1250);
464 fn test_read_write_f32() {
467 let mut writer = MemWriter::new();
468 writer.write_be_f32(f);
469 writer.write_le_f32(f);
471 let mut reader = MemReader::new(writer.unwrap());
472 assert!(reader.read_be_f32() == 8.1250);
473 assert!(reader.read_le_f32() == 8.1250);
477 fn test_u64_from_be_bytes() {
478 use super::u64_from_be_bytes;
480 let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
483 assert_eq!(u64_from_be_bytes(buf, 0, 0), 0);
484 assert_eq!(u64_from_be_bytes(buf, 0, 1), 0x01);
485 assert_eq!(u64_from_be_bytes(buf, 0, 2), 0x0102);
486 assert_eq!(u64_from_be_bytes(buf, 0, 3), 0x010203);
487 assert_eq!(u64_from_be_bytes(buf, 0, 4), 0x01020304);
488 assert_eq!(u64_from_be_bytes(buf, 0, 5), 0x0102030405);
489 assert_eq!(u64_from_be_bytes(buf, 0, 6), 0x010203040506);
490 assert_eq!(u64_from_be_bytes(buf, 0, 7), 0x01020304050607);
491 assert_eq!(u64_from_be_bytes(buf, 0, 8), 0x0102030405060708);
494 assert_eq!(u64_from_be_bytes(buf, 1, 0), 0);
495 assert_eq!(u64_from_be_bytes(buf, 1, 1), 0x02);
496 assert_eq!(u64_from_be_bytes(buf, 1, 2), 0x0203);
497 assert_eq!(u64_from_be_bytes(buf, 1, 3), 0x020304);
498 assert_eq!(u64_from_be_bytes(buf, 1, 4), 0x02030405);
499 assert_eq!(u64_from_be_bytes(buf, 1, 5), 0x0203040506);
500 assert_eq!(u64_from_be_bytes(buf, 1, 6), 0x020304050607);
501 assert_eq!(u64_from_be_bytes(buf, 1, 7), 0x02030405060708);
502 assert_eq!(u64_from_be_bytes(buf, 1, 8), 0x0203040506070809);
508 use extra::test::BenchHarness;
509 use container::Container;
511 macro_rules! u64_from_be_bytes_bench_impl(
512 ($size:expr, $stride:expr, $start_index:expr) =>
515 use super::u64_from_be_bytes;
517 let data = vec::from_fn($stride*100+$start_index, |i| i as u8);
520 let mut i = $start_index;
521 while (i < data.len()) {
522 sum += u64_from_be_bytes(data, i, $size);
530 fn u64_from_be_bytes_4_aligned(bh: &mut BenchHarness) {
531 u64_from_be_bytes_bench_impl!(4, 4, 0);
535 fn u64_from_be_bytes_4_unaligned(bh: &mut BenchHarness) {
536 u64_from_be_bytes_bench_impl!(4, 4, 1);
540 fn u64_from_be_bytes_7_aligned(bh: &mut BenchHarness) {
541 u64_from_be_bytes_bench_impl!(7, 8, 0);
545 fn u64_from_be_bytes_7_unaligned(bh: &mut BenchHarness) {
546 u64_from_be_bytes_bench_impl!(7, 8, 1);
550 fn u64_from_be_bytes_8_aligned(bh: &mut BenchHarness) {
551 u64_from_be_bytes_bench_impl!(8, 8, 0);
555 fn u64_from_be_bytes_8_unaligned(bh: &mut BenchHarness) {
556 u64_from_be_bytes_bench_impl!(8, 8, 1);