Struct iobuf::AROIobuf
[−]
[src]
pub struct AROIobuf { /* fields omitted */ }
Atomic Read-Only Iobuf
An ROIobuf
which is safe to Send
across tasks and Share
with other tasks.
This atomically refcounts the buffer, which has a greater cost on .clone()
,
but provides more flexibility to multithreaded consumers.
To create an AROIobuf
, create a normal Iobuf
and call .atomic_read_only()
.
Below is an example of fill an Iobuf in one thread with the numbers 0x00 to 0xFF, and consuming/validating these numbers in parallel in 4 other threads:
#![feature(std_misc)] use iobuf::{RWIobuf, AROIobuf, Iobuf}; use std::thread; // Write the bytes 0x00 - 0xFF into an Iobuf. fn fill(buf: &mut RWIobuf<'static>) -> Result<(), ()> { for i in 0x00u32 .. 0x100 { try!(buf.fill_be(i as u8)); } Ok(()) } // Validates the contents of buf are `idx`, `idx+1`, `idx+2`, ... // until the buffer is exhausted. fn check(buf: &mut AROIobuf, mut idx: u32) -> Result<(), ()> { loop { let b: u8 = match buf.consume_be::<u8>() { Err(()) => return Ok(()), Ok(b) => b }; if b as u32 == idx { idx += 1; } else { return Err(()) } } } let mut source_b = RWIobuf::new(256); assert_eq!(fill(&mut source_b), Ok(())); // Reset the Iobuf for reading. source_b.flip_lo(); // We can still clone this buffer. It will be non-atomically refcounted for // now. { let _ = source_b.clone(); } // Now prepare it for sending to our 4 subtasks. let shared_b: AROIobuf = source_b.atomic_read_only().ok().unwrap(); let mut tasks = vec!(); for i in 0..4 { // This clone modifies the AROIobuf's atomic refcount. let mut b = shared_b.clone(); tasks.push(thread::spawn(move || { let start = i*0x40; assert_eq!(b.advance(start), Ok(())); assert_eq!(b.resize(0x40), Ok(())); assert_eq!(check(&mut b, start), Ok(())); assert!(b.is_empty()); // This clone will atomically modify refcounts. { let _ = b.clone(); } })); } for mut t in tasks.into_iter() { t.join(); }
Methods
impl AROIobuf
[src]
fn read_only(self) -> Result<ROIobuf<'static>, AROIobuf>
Stops atomically reference counting a unique buffer. This method returns
Ok
if the AROIobuf
is the last of its kind, and Err
if it's not.
use iobuf::{AROIobuf, ROIobuf, Iobuf}; let buf: ROIobuf<'static> = ROIobuf::from_str_copy("hello, world!"); let a_buf: AROIobuf = buf.atomic_read_only().ok().unwrap(); unsafe { assert_eq!(a_buf.as_window_slice(), b"hello, world!"); } let buf: ROIobuf<'static> = a_buf.read_only().ok().unwrap(); // TA-DA! unsafe { assert_eq!(buf.as_window_slice(), b"hello, world!"); }
fn read_write(self) -> Result<RWIobuf<'static>, AROIobuf>
Stops atomically reference counting a unique buffer. This method returns
Ok
if the AROIobuf
is the last of its kind, and Err
if it's not.
use iobuf::{AROIobuf, ROIobuf, RWIobuf, Iobuf}; let buf: ROIobuf<'static> = ROIobuf::from_str_copy("hello, world!"); let a_buf: AROIobuf = buf.atomic_read_only().ok().unwrap(); unsafe { assert_eq!(a_buf.as_window_slice(), b"hello, world!"); } let buf: RWIobuf<'static> = a_buf.read_write().ok().unwrap(); // TA-DA! unsafe { assert_eq!(buf.as_window_slice(), b"hello, world!"); }
Trait Implementations
impl Send for AROIobuf
[src]
impl Sync for AROIobuf
[src]
impl Clone for AROIobuf
[src]
fn clone(&self) -> Self
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
impl Drop for AROIobuf
[src]
impl Iobuf for AROIobuf
[src]
fn deep_clone(&self) -> RWIobuf<'static>
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
fn deep_clone_with_allocator(
&self,
allocator: Arc<Box<Allocator>>
) -> RWIobuf<'static>
&self,
allocator: Arc<Box<Allocator>>
) -> RWIobuf<'static>
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
fn unique(self) -> Result<UniqueIobuf, AROIobuf>
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
fn atomic_read_only(self) -> Result<AROIobuf, AROIobuf>
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 Arc
ed with impunity. This is extremely useful in situations where Iobufs are created and written in one thread, and consumed in another. Read more
fn len(&self) -> u32
Returns the size of the window. Read more
fn cap(&self) -> u32
Returns the size of the limits. The capacity of an iobuf can be reduced via narrow
. Read more
fn is_empty(&self) -> bool
true
if len() == 0
. Read more
unsafe fn as_window_slice<'b>(&'b self) -> &'b [u8]
Reads the data in the window as an immutable slice. Note that Peek
s and Poke
s into the iobuf will change the contents of the slice, even though it advertises itself as immutable. Therefore, this function is unsafe
. Read more
unsafe fn as_limit_slice<'b>(&'b self) -> &'b [u8]
Reads the data in the limits as an immutable slice. Note that Peek
s and Poke
s into the iobuf will change the contents of the slice, even though it advertises itself as immutable. Therefore, this function is unsafe
. Read more
fn sub_window(&mut self, pos: u32, len: u32) -> Result<(), ()>
Changes the Iobuf's bounds to the subrange specified by pos
and len
, which must lie within the current window. Read more
fn sub_window_from(&mut self, pos: u32) -> Result<(), ()>
Changes the Iobuf's bounds to start at pos
, and go to the end of the current window. Read more
fn sub_window_to(&mut self, len: u32) -> Result<(), ()>
Changes the Iobuf's bounds to extend for only len
bytes. Read more
unsafe fn unsafe_sub_window(&mut self, pos: u32, len: u32)
The same as sub_window
, but no bounds checks are performed. You should probably just use sub_window
. Read more
unsafe fn unsafe_sub_window_from(&mut self, pos: u32)
The same as sub_window_from
, but no bounds checks are performed. You should probably just use sub_window_from
. Read more
unsafe fn unsafe_sub_window_to(&mut self, len: u32)
The same as sub_window_to
, but no bounds checks are performed. You should probably just use sub_window_to
. Read more
fn sub(&mut self, pos: u32, len: u32) -> Result<(), ()>
Changes the Iobuf's limits and bounds to the subrange specified by pos
and len
, which must lie within the current window. Read more
fn sub_from(&mut self, pos: u32) -> Result<(), ()>
Changes the Iobuf's limits and bounds to start from pos
and extend to the end of the current window. Read more
fn sub_to(&mut self, len: u32) -> Result<(), ()>
Changes the Iobuf's limits and bounds to start at the beginning of the current window, and extend for len
bytes. Read more
unsafe fn unsafe_sub(&mut self, pos: u32, len: u32)
The same as sub
, but no bounds checks are performed. You should probably just use sub
. Read more
unsafe fn unsafe_sub_from(&mut self, pos: u32)
The same as sub_from
, but no bounds checks are performed. You should probably just use sub_from
. Read more
unsafe fn unsafe_sub_to(&mut self, len: u32)
The same as sub_to
, but no bounds checks are performed. You should probably just use sub_to
. Read more
fn set_limits_and_window(
&mut self,
limits: (u32, u32),
window: (u32, u32)
) -> Result<(), ()>
&mut self,
limits: (u32, u32),
window: (u32, u32)
) -> Result<(), ()>
Overrides the existing limits and window of the Iobuf, returning Err(())
if attempting to widen either of them. Read more
fn narrow(&mut self)
Sets the limits to the current window. Read more
fn advance(&mut self, len: u32) -> Result<(), ()>
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
unsafe fn unsafe_advance(&mut self, len: u32)
Advances the lower bound of the window by len
. No bounds checking will be performed. Read more
fn extend(&mut self, len: u32) -> Result<(), ()>
Advances the upper bound of the window by len
. Err(())
will be returned if you advance past the upper limit. Read more
unsafe fn unsafe_extend(&mut self, len: u32)
Advances the upper bound of the window by len
. No bounds checking will be performed. Read more
fn is_extended_by<Buf: Iobuf>(&self, other: &Buf) -> bool
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
fn extend_with<Buf: Iobuf>(&mut self, other: &Buf) -> Result<(), ()>
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
fn resize(&mut self, len: u32) -> Result<(), ()>
Sets the length of the window, provided it does not exceed the limits. Read more
unsafe fn unsafe_resize(&mut self, len: u32)
Sets the length of the window. No bounds checking will be performed. Read more
fn split_at(&self, pos: u32) -> Result<(Self, Self), ()>
Splits an Iobuf around an index. Read more
unsafe fn unsafe_split_at(&self, pos: u32) -> (Self, Self)
Like split_at
, but does not perform bounds checking.
fn split_start_at(&mut self, pos: u32) -> Result<Self, ()>
Splits out the start of an Iobuf at an index. Read more
unsafe fn unsafe_split_start_at(&mut self, pos: u32) -> Self
Like split_start_at
, but does not perform bounds checking.
fn rewind(&mut self)
Sets the lower bound of the window to the lower limit. Read more
fn reset(&mut self)
Sets the window to the limits. Read more
fn flip_lo(&mut self)
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 Fill
s, to reposition the window in preparation to Consume
the newly written data. Read more
fn flip_hi(&mut self)
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
fn lo_space(&self) -> u32
Returns the number of bytes between the lower limit and the lower bound. Read more
fn hi_space(&self) -> u32
Returns the number of bytes between the upper bound and the upper limit. Read more
fn peek(&self, pos: u32, dst: &mut [u8]) -> Result<(), ()>
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
fn peek_be<T: IntLike>(&self, pos: u32) -> Result<T, ()>
Reads a big-endian primitive at a given offset from the beginning of the window. Read more
fn peek_le<T: IntLike>(&self, pos: u32) -> Result<T, ()>
Reads a little-endian primitive at a given offset from the beginning of the window. Read more
fn consume(&mut self, dst: &mut [u8]) -> Result<(), ()>
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
fn consume_be<T: IntLike>(&mut self) -> Result<T, ()>
Reads a big-endian primitive from the beginning of the window. Read more
fn consume_le<T: IntLike>(&mut self) -> Result<T, ()>
Reads a little-endian primitive from the beginning of the window. Read more
fn check_range(&self, pos: u32, len: u32) -> Result<(), ()>
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
fn check_range_usize(&self, pos: u32, len: usize) -> Result<(), ()>
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
fn check_range_fail(&self, pos: u32, len: u32)
The same as check_range
, but fails if the bounds check returns Err(())
. Read more
fn check_range_usize_fail(&self, pos: u32, len: usize)
The same as check_range_usize
, but fails if the bounds check returns Err(())
. Read more
unsafe fn unsafe_peek(&self, pos: u32, dst: &mut [u8])
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
unsafe fn unsafe_peek_be<T: IntLike>(&self, pos: u32) -> T
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
unsafe fn unsafe_peek_le<T: IntLike>(&self, pos: u32) -> T
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
unsafe fn unsafe_consume(&mut self, dst: &mut [u8])
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
unsafe fn unsafe_consume_be<T: IntLike>(&mut self) -> T
Reads a big-endian primitive at the beginning of the window. Read more
unsafe fn unsafe_consume_le<T: IntLike>(&mut self) -> T
Reads a little-endian primitive at the beginning of the window. Read more
unsafe fn as_raw<'b>(&'b self) -> &'b RawIobuf<'b>
For internal use only.
fn invariant(&self) -> Result<(), Box<String>>
Checks internal state of the iobuf, to ensure that internal invariants are satisified. Returns Err(msg)
if any invariant isn't satisfied. Read more
fn ptr(&self) -> NonZero<*mut u8>
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
fn is_owned(&self) -> bool
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
fn lo_min(&self) -> u32
Returns an index into the buffer returned by ptr
that represents the inclusive lower bound of the limits. Read more
fn lo(&self) -> u32
Returns an index into the buffer returned by ptr
that represents the inclusive lower bound of the window. Read more
fn hi(&self) -> u32
Returns an index into the buffer returned by ptr
that represents the exclusive upper bound of the window. Read more
fn hi_max(&self) -> u32
Returns an index into the buffer returned by ptr
that represents the exclusive upper bound of the limits. Read more