Struct iobuf::RWIobuf [] [src]

pub struct RWIobuf<'a> { /* fields omitted */ }

Read-Write Iobuf

An Iobuf which can read and write into a buffer.

Iobufs may be cloned cheaply. When cloned, the data itself is shared and refcounted, and a new copy of the limits and window is made. This can be used to construct multiple views into the same buffer.

poke and fill write a value at a position relative to the start of the window. Only fill advances the window by the amount written. They are meant to be used with try!.

A suffix _be means the data will be read big-endian. A suffix _le means the data will be read little-endian.

The unsafe_ prefix means the function omits bounds checks. Misuse can easily cause security issues. Be careful!

Methods

impl<'a> RWIobuf<'a>
[src]

Constructs a trivially empty Iobuf, limits and window are 0, and there's an empty backing buffer. This will not allocate.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::empty();

assert_eq!(b.len(), 0);
assert_eq!(b.cap(), 0);

Constructs a new Iobuf with a buffer of size len, undefined contents, and the limits and window set to the full size of the buffer.

The maximum length of an Iobuf is approximately 2 GB.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

assert_eq!(b.len(), 10);
assert_eq!(b.cap(), 10);

Constructs a new Iobuf with a buffer of size len, undefined contents, and the limits and window set to the full range of the buffer. The memory will be allocated out of the given allocator, instead of the global heap.

The maximum length of an Iobuf is approximately 2 GB.

Copies a str into a writeable Iobuf. The contents of the str will be copied, so prefer to use the non-copying constructors whenever possible.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::from_str_copy("hello");

assert_eq!(b.poke_be(1, b'4'), Ok(()));

assert_eq!(b.len(), 5);
assert_eq!(b.cap(), 5);
unsafe { assert_eq!(b.as_window_slice(), b"h4llo"); }
unsafe { assert_eq!(b.as_limit_slice(), b"h4llo"); }

Copies a str into a writeable Iobuf, whose memory comes from the given allocator.

Constructs an Iobuf from a slice. The Iobuf will not copy the slice contents, and therefore their lifetimes will be linked.

use iobuf::{RWIobuf,Iobuf};

let mut s = [1,2,3,4];

{
  let mut b = RWIobuf::from_slice(&mut s[..]);

  assert_eq!(b.advance(1), Ok(()));
  assert_eq!(b.peek_be(1), Ok(0x0304u16)); // ...and the Iobuf!
  assert_eq!(b.poke_be(1, 100u8), Ok(()));
}

// We can still use the slice, but only because of the braces above.
assert_eq!(s[2], 100);

Copies a byte vector into a new, writeable Iobuf. The contents of the slice will be copied, so prefer to use the other constructors whenever possible.

use iobuf::{RWIobuf,Iobuf};

let mut v = vec!(1u8, 2, 3, 4, 5, 6, 10);
v[1] = 20;

let mut b = RWIobuf::from_slice_copy(&v[..]);

let expected = [ 1,20,3,4,5,6,10 ];
unsafe { assert_eq!(b.as_window_slice(), expected); }

Copies a byte vector into a new writeable Iobuf, whose memory comes from the given allocator.

Reads the data in the window as a mutable slice. Note that since &mut in rust really means &unique, this function lies. There can exist multiple slices of the same data. Therefore, this function is unsafe.

It may only be used safely if you ensure that the data in the iobuf never interacts with the slice, as they point to the same data. peeking or pokeing the slice returned from this function is a big no-no.

use iobuf::{RWIobuf, Iobuf};

let mut s = [1,2,3];

{
  let mut b = RWIobuf::from_slice(&mut s[..]);

  assert_eq!(b.advance(1), Ok(()));
  unsafe { b.as_mut_window_slice()[1] = 30; }
}

let expected = [ 1,2,30 ];
assert_eq!(s, &expected[..]);

Reads the data in the window as a mutable slice. Note that since &mut in rust really means &unique, this function lies. There can exist multiple slices of the same data. Therefore, this function is unsafe.

It may only be used safely if you ensure that the data in the iobuf never interacts with the slice, as they point to the same data. peeking or pokeing the slice returned from this function is a big no-no.

use iobuf::{RWIobuf, Iobuf};

let mut s = [1,2,3];

{
  let mut b = RWIobuf::from_slice(&mut s[..]);

  assert_eq!(b.advance(1), Ok(()));
  unsafe { b.as_mut_limit_slice()[1] = 20; }
}

assert_eq!(s, &[1,20,3][..]);

Gets a read-only copy of this Iobuf. This is a very cheap operation, as the backing buffers are shared. This can be useful for interfacing with code that only accepts read-only Iobufs.

In general, ROIobuf should never be used as a function parameter. If read-only acceess is all that is required, take a generic <T: Iobuf>.

use iobuf::{ROIobuf,RWIobuf,Iobuf};

let mut s = [1,2,3,4];

let rwb: RWIobuf = RWIobuf::from_slice(&mut s[..]);

// write some data into rwb.

let rb: ROIobuf = rwb.read_only();

// now do read-only ops.
assert_eq!(rb.len(), 4);

Copies data from the window to the lower limit fo the iobuf and sets the window to range from the end of the copied data to the upper limit. This is typically called after a series of Consumes to save unread data and prepare for the next series of Fills and flip_los.

use std::result::Result::{self,Ok};
use iobuf::{RWIobuf,Iobuf};

// A header, saying how many shorts will follow. Unfortunately, our buffer
// isn't big enough for all the shorts! Assume the rest will be sent in a
// later packet.
let mut s = [ 0x02, 0x11, 0x22, 0x33 ];
let mut b = RWIobuf::from_slice(&mut s[..]);

#[derive(Eq, PartialEq, Debug)]
enum ParseState {
  NeedMore(u16), // sum so far
  Done(u16),     // final sum
};

// Returns a pair of the sum of shorts seen so far, and `true` if we're
// finally done parsing. The sum will be partial if parsing is incomplete.
fn parse(b: &mut RWIobuf) -> Result<ParseState, ()> {
  let len: u8 = try!(b.consume_be());
  let mut sum = 0u16;

  for _ in (0u8 .. len) {
    unsafe {
      if b.len() < 2 {
        b.compact();
        return Ok(ParseState::NeedMore(sum));
      }
      sum += b.unsafe_consume_be::<u16>();
    }
  }

  Ok(ParseState::Done(sum))
}

assert_eq!(parse(&mut b), Ok(ParseState::NeedMore(0x1122)));
assert_eq!(b.len(), 3);
assert_eq!(b.cap(), 4);
assert_eq!(b.peek_be(0), Ok(0x11u8));

Writes the bytes at a given offset from the beginning of the window, into the supplied buffer. Either the entire buffer is copied, or an error is returned because bytes outside of the window would be written.

use iobuf::{RWIobuf,Iobuf};

let data = [ 1,2,3,4 ];

let mut b = RWIobuf::new(10);

assert_eq!(b.poke(0, &data[..]), Ok(()));
assert_eq!(b.poke(3, &data[..]), Ok(()));
assert_eq!(b.resize(7), Ok(()));
assert_eq!(b.poke(4, &data[..]), Err(())); // no partial write, just failure

let expected = [ 1,2,3,1,2,3,4 ];
unsafe { assert_eq!(b.as_window_slice(), expected); }

Writes a big-endian primitive at a given offset from the beginning of the window.

An error is returned if bytes outside of the window would be accessed.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

assert_eq!(b.poke_be(0, 0x0304u16), Ok(()));
assert_eq!(b.poke_be(1, 0x0505u16), Ok(()));
assert_eq!(b.poke_be(3, 0x06070809u32), Ok(()));

assert_eq!(b.resize(7), Ok(()));

let expected = [ 3,5,5,6,7,8,9 ];
unsafe { assert_eq!(b.as_window_slice(), expected); }

Writes a little-endian primitive at a given offset from the beginning of the window.

An error is returned if bytes outside of the window would be accessed.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

assert_eq!(b.poke_le(0, 0x0304u16), Ok(()));
assert_eq!(b.poke_le(1, 0x0505u16), Ok(()));
assert_eq!(b.poke_le(3, 0x06070809u32), Ok(()));

assert_eq!(b.resize(7), Ok(()));

unsafe { assert_eq!(b.as_window_slice(), [ 4, 5, 5, 9, 8, 7, 6 ]); }

Writes bytes from the supplied buffer, starting from the front of the window. Either the entire buffer is copied, or an error is returned because bytes outside the window were requested.

After the bytes have been written, the window will be moved to no longer include then.

use iobuf::{RWIobuf,Iobuf};

let data = [ 1, 2, 3, 4 ];

let mut b = RWIobuf::new(10);

assert_eq!(b.fill(&data[..]), Ok(()));
assert_eq!(b.fill(&data[..]), Ok(()));
assert_eq!(b.fill(&data[..]), Err(()));

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), &[ 1,2,3,4,1,2,3,4 ][..]); }

Writes a big-endian primitive into the beginning of the window.

After the primitive has been written, the window will be moved such that it is no longer included.

An error is returned if bytes outside of the window were requested.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

assert_eq!(b.fill_be(0x12345678u32), Ok(()));
assert_eq!(b.fill_be(0x11223344u32), Ok(()));
assert_eq!(b.fill_be(0x54321123u32), Err(()));
assert_eq!(b.fill_be(0x8877u16), Ok(()));

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), [ 0x12, 0x34, 0x56, 0x78
                                         , 0x11, 0x22, 0x33, 0x44
                                         , 0x88, 0x77 ]); }

Writes a little-endian primitive into the beginning of the window.

After the primitive has been written, the window will be moved such that it is no longer included.

An error is returned if bytes outside of the window were requested.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

assert_eq!(b.fill_le(0x12345678u32), Ok(()));
assert_eq!(b.fill_le(0x11223344u32), Ok(()));
assert_eq!(b.fill_le(0x54321123u32), Err(()));
assert_eq!(b.fill_le(0x8877u16), Ok(()));

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), [ 0x78, 0x56, 0x34, 0x12
                                         , 0x44, 0x33, 0x22, 0x11
                                         , 0x77, 0x88 ]); }

Writes the bytes at a given offset from the beginning of the window, into the supplied buffer. It is undefined behavior to write outside the iobuf window.

use iobuf::{RWIobuf,Iobuf};

let data = [ 1,2,3,4 ];

let mut b = RWIobuf::new(10);

unsafe {
  b.check_range_fail(1, 7);

  b.unsafe_advance(1);
  b.narrow();

  b.unsafe_poke(0, &data);
  b.unsafe_poke(3, &data);
  b.unsafe_advance(7);
}

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), [ 1,2,3,1,2,3,4 ]); }

Writes a big-endian primitive at a given offset from the beginning of the window. It is undefined behavior to write outside the iobuf window.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

unsafe {
  b.check_range_fail(0, 7);

  b.unsafe_poke_be(0, 0x0304u16);
  b.unsafe_poke_be(1, 0x0505u16);
  b.unsafe_poke_be(3, 0x06070809u32);
}

assert_eq!(b.resize(7), Ok(()));

unsafe { assert_eq!(b.as_window_slice(), [ 3, 5, 5, 6, 7, 8, 9 ]); }

Writes a little-endian primitive at a given offset from the beginning of the window. It is undefined behavior to write outside the iobuf window.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

unsafe {
  b.check_range_fail(0, 7);

  b.unsafe_poke_le(0, 0x0304u16);
  b.unsafe_poke_le(1, 0x0505u16);
  b.unsafe_poke_le(3, 0x06070809u32);
}

assert_eq!(b.resize(7), Ok(()));

unsafe { assert_eq!(b.as_window_slice(), [ 4, 5, 5, 9, 8, 7, 6 ]); }

Writes bytes from the supplied buffer, starting from the front of the window. It is undefined behavior to write outside the iobuf window.

After the bytes have been written, the window will be moved to no longer include then.

use iobuf::{RWIobuf,Iobuf};

let data = [ 1, 2, 3, 4 ];

let mut b = RWIobuf::new(10);

unsafe {
  b.check_range_fail(0, 8);

  b.unsafe_fill(&data[..]);
  b.unsafe_fill(&data[..]);
}

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), [ 1,2,3,4,1,2,3,4 ]); }

Writes a big-endian primitive into the beginning of the window. It is undefined behavior to write outside the iobuf window.

After the primitive has been written, the window will be moved such that it is no longer included.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

unsafe {
  b.check_range_fail(0, 10);

  b.unsafe_fill_be(0x12345678u32);
  b.unsafe_fill_be(0x11223344u32);
  // b.unsafe_fill_be(0x54321123u32); DO NOT DO THIS. Undefined behavior.
  b.unsafe_fill_be(0x8877u16);
}

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), [ 0x12, 0x34, 0x56, 0x78
                                         , 0x11, 0x22, 0x33, 0x44
                                         , 0x88, 0x77 ]); }

Writes a little-endian primitive into the beginning of the window. It is undefined behavior to write outside the iobuf window.

After the primitive has been written, the window will be moved such that it is no longer included.

use iobuf::{RWIobuf,Iobuf};

let mut b = RWIobuf::new(10);

unsafe {
  b.check_range_fail(0, 10);

  b.unsafe_fill_le(0x12345678u32);
  b.unsafe_fill_le(0x11223344u32);
  // b.unsafe_fill_le(0x54321123u32); DO NOT DO THIS. Undefined behavior.
  b.unsafe_fill_le(0x8877u16);
}

b.flip_lo();

unsafe { assert_eq!(b.as_window_slice(), [ 0x78, 0x56, 0x34, 0x12
                                         , 0x44, 0x33, 0x22, 0x11
                                         , 0x77, 0x88 ]); }

Trait Implementations

impl<'a> Clone for RWIobuf<'a>
[src]

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

impl<'a> Drop for RWIobuf<'a>
[src]

A method called when the value goes out of scope. Read more

impl<'a> Write for RWIobuf<'a>
[src]

Write a buffer into this object, returning how many bytes were written. Read more

Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more

Attempts to write an entire buffer into this write. Read more

Writes a formatted string into this writer, returning any error encountered. Read more

Creates a "by reference" adaptor for this instance of Write. Read more

impl<'a> Iobuf for RWIobuf<'a>
[src]

Copies the data byte-by-byte in the Iobuf into a new, writeable Iobuf. The new Iobuf and the old Iobuf will not share storage. Read more

Copies the data byte-by-byte in the Iobuf into a new, writable Iobuf. The new Iobuf will have storage allocated out of allocator, and will not share the buffer with the original Iobuf. Read more

Returns Ok if the Iobuf is the last to reference the underlying data, and converts it to a UniqueIobuf for sending to another task. This can also be used to safely convert from a ROIobuf to a RWIobuf, and to downgrade atomically refcounted Iobufs to non-atomically refcounted ones. Read more

Returns Ok if the Iobuf is the last to reference the underlying data, and upgrades it to an AROIobuf which can be sent over channels and Arced with impunity. This is extremely useful in situations where Iobufs are created and written in one thread, and consumed in another. Read more

Returns the size of the window. Read more

Returns the size of the limits. The capacity of an iobuf can be reduced via narrow. Read more

true if len() == 0. Read more

Reads the data in the window as an immutable slice. Note that Peeks and Pokes into the iobuf will change the contents of the slice, even though it advertises itself as immutable. Therefore, this function is unsafe. Read more

Reads the data in the limits as an immutable slice. Note that Peeks and Pokes into the iobuf will change the contents of the slice, even though it advertises itself as immutable. Therefore, this function is unsafe. Read more

Changes the Iobuf's bounds to the subrange specified by pos and len, which must lie within the current window. Read more

Changes the Iobuf's bounds to start at pos, and go to the end of the current window. Read more

Changes the Iobuf's bounds to extend for only len bytes. Read more

The same as sub_window, but no bounds checks are performed. You should probably just use sub_window. Read more

The same as sub_window_from, but no bounds checks are performed. You should probably just use sub_window_from. Read more

The same as sub_window_to, but no bounds checks are performed. You should probably just use sub_window_to. Read more

Changes the Iobuf's limits and bounds to the subrange specified by pos and len, which must lie within the current window. Read more

Changes the Iobuf's limits and bounds to start from pos and extend to the end of the current window. Read more

Changes the Iobuf's limits and bounds to start at the beginning of the current window, and extend for len bytes. Read more

The same as sub, but no bounds checks are performed. You should probably just use sub. Read more

The same as sub_from, but no bounds checks are performed. You should probably just use sub_from. Read more

The same as sub_to, but no bounds checks are performed. You should probably just use sub_to. Read more

Overrides the existing limits and window of the Iobuf, returning Err(()) if attempting to widen either of them. Read more

Sets the limits to the current window. Read more

Advances the lower bound of the window by len. Err(()) will be returned if you advance past the upper bound of the window. Read more

Advances the lower bound of the window by len. No bounds checking will be performed. Read more

Advances the upper bound of the window by len. Err(()) will be returned if you advance past the upper limit. Read more

Advances the upper bound of the window by len. No bounds checking will be performed. Read more

Returns true if the other Iobuf's window is the region directly after our window. This does not inspect the buffer -- it only compares raw pointers. Read more

Attempts to extend an Iobuf with the contents of another Iobuf. If this Iobuf's window is not the region directly before the other Iobuf's window, no extension will be performed and Err(()) will be returned. If the operation was successful, Ok(()) will be returned. Read more

Sets the length of the window, provided it does not exceed the limits. Read more

Sets the length of the window. No bounds checking will be performed. Read more

Splits an Iobuf around an index. Read more

Like split_at, but does not perform bounds checking.

Splits out the start of an Iobuf at an index. Read more

Like split_start_at, but does not perform bounds checking.

Sets the lower bound of the window to the lower limit. Read more

Sets the window to the limits. Read more

Sets the window to range from the lower limit to the lower bound of the old window. This is typically called after a series of Fills, to reposition the window in preparation to Consume the newly written data. Read more

Sets the window to range from the upper bound of the old window to the upper limit. This is a dual to flip_lo, and is typically called when the data in the current (narrowed) window has been processed and the window needs to be positioned over the remaining data in the buffer. Read more

Returns the number of bytes between the lower limit and the lower bound. Read more

Returns the number of bytes between the upper bound and the upper limit. Read more

Reads the bytes at a given offset from the beginning of the window, into the supplied buffer. Either the entire buffer is filled, or an error is returned because bytes outside of the window were requested. Read more

Reads a big-endian primitive at a given offset from the beginning of the window. Read more

Reads a little-endian primitive at a given offset from the beginning of the window. Read more

Reads bytes, starting from the front of the window, into the supplied buffer. Either the entire buffer is filled, or an error is returned because bytes outside the window were requested. Read more

Reads a big-endian primitive from the beginning of the window. Read more

Reads a little-endian primitive from the beginning of the window. Read more

Returns an Err(()) if the len bytes, starting at pos, are not all in the window. To be used with the try! macro. Read more

The same as check_range, but with a usize length. If you're checking the range of something which might overflow an i32, use this version instead of check_range. Read more

The same as check_range, but fails if the bounds check returns Err(()). Read more

The same as check_range_usize, but fails if the bounds check returns Err(()). Read more

Reads the bytes at a given offset from the beginning of the window, into the supplied buffer. It is undefined behavior to read outside the iobuf window. Read more

Reads a big-endian primitive at a given offset from the beginning of the window. It is undefined behavior to read outside the iobuf window. Read more

Reads a little-endian primitive at a given offset from the beginning of the window. It is undefined behavior to read outside the iobuf window. Read more

Reads bytes, starting from the front of the window, into the supplied buffer. After the bytes have been read, the window will be moved to no longer include then. Read more

Reads a big-endian primitive at the beginning of the window. Read more

Reads a little-endian primitive at the beginning of the window. Read more

For internal use only.

Checks internal state of the iobuf, to ensure that internal invariants are satisified. Returns Err(msg) if any invariant isn't satisfied. Read more

Gets a pointer to the start of the internal backing buffer. This is extremely low level, and it is not recommended you use this interface. Read more

Returns true if the Iobuf points to owned memory (i.e. has to do a refcount modification on clone or drop) or borrowed memory. Read more

Returns an index into the buffer returned by ptr that represents the inclusive lower bound of the limits. Read more

Returns an index into the buffer returned by ptr that represents the inclusive lower bound of the window. Read more

Returns an index into the buffer returned by ptr that represents the exclusive upper bound of the window. Read more

Returns an index into the buffer returned by ptr that represents the exclusive upper bound of the limits. Read more

impl<'a> Debug for RWIobuf<'a>
[src]

Formats the value using the given formatter.