Struct chainbuf::Chain[][src]

pub struct Chain<'src> { /* fields omitted */ }

Chained buffer of bytes.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
let some_bytes = chain.pullup(2);

Details of implementation

Chainbuf consists of linked list of nodes, with start and end offsets and a reference counted pointer to DataHolder. DataHolders can be shared across different chains, so for mutation new nodes and data holders are created (as in Copy-On-Write).

Methods

impl<'src> Chain<'src>
[src]

Creates new, empty chainbuf. Chainbuf will not allocate any nodes until something are pushed onto it.

Example

use chainbuf::Chain;
let mut chain = Chain::new();

Constructs new chainbuf from another chainbuf, destroying it.

Example

use chainbuf::Chain;
let mut chain1 = Chain::new();
chain1.append_bytes("helloworld".as_bytes());
let mut chain2 = Chain::from_foreign(chain1);
println!("{}", chain2.len()); // should print 10
// println!("{}", chain1.len()); // should produce error `use of moved value`

Returns number of bytes stored in chainbuf.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
println!("{}", chain.len()); // should print 10

Copies bytes from a slice, and appends them to the end of chain, creating new node, if data holder in last node does not have enough room for data or shared across several chains.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
println!("{}", chain.len()); // should print 10

Copies bytes from a slice, and prepends them to the begining of chain, creating new node, if data holder in last node does not have enough room for data or shared across several chains.

Appends unowned slice to the chain without copy. Chain lifetime became bound to one of the slice. Example

use chainbuf::Chain;
let mut chain = Chain::new();
let s = "HelloWorld";
chain.append_slice(s.as_bytes());
println!("{}", chain.len()); // should print 10

Returns size bytes from the beginning of chain or None, if chain does not have enough data.

Note

If data of requested size span multiple nodes, new node, containing all requested data will be created instead.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes()); // new node created
chain.append_bytes("helloworldhelloworld".as_bytes()); // new node created
assert_eq!(chain.pullup(100), None);
assert_eq!(chain.pullup(2).unwrap(), "he".as_bytes()); // does not create new node
assert_eq!(chain.pullup(25).unwrap(), "helloworldhelloworldhello".as_bytes()); // create new node

Returns slice of requested size starting from specified offset.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
let res = chain.pullup_from(2, 4);
assert!(res.is_some());
assert_eq!(res.unwrap(), "llow".as_bytes());

Finds first occurence of needle inside chain and returns data from the beginning of chain to the end of found sequence. Returns None if nothing was found.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
let res = chain.pullup_to("wor".as_bytes());
assert_eq!(res.unwrap(), "hellowor".as_bytes());

Shortcut for chain.pullup(chain.len()).

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
let buf = chain.pullup_all();
assert_eq!(buf.unwrap().len(), 10);

Pulls all data and returns it as utf8 str or None if chain is empty or contains invalid utf8 data.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
let res = chain.to_utf8_str();
assert!(res.is_some());
assert!(res.unwrap().is_ok());
assert_eq!(res.unwrap().ok().unwrap(), "helloworld");

Consumes another chain and moves all data from it to itself.

Example

use chainbuf::Chain;
let mut chain1 = Chain::new();
let mut chain2 = Chain::new();
chain1.append_bytes("hello".as_bytes());
chain2.append_bytes("world".as_bytes());
chain1.concat(chain2);
assert_eq!(chain1.pullup(10).unwrap(), "helloworld".as_bytes());

Discards all data in chain, deletes all nodes and set length to 0.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
assert_eq!(chain.len(), 10);
chain.reset();
assert_eq!(chain.len(), 0);

Appends data from another chain to itself.

Note

This method creates new nodes with same offsets and pointer as in src node. No data copy happens.

Example

use chainbuf::Chain;
let mut chain1 = Chain::new();
let mut chain2 = Chain::new();
chain2.append_bytes("helloworld".as_bytes());
chain1.append(&chain2);
assert_eq!(chain1.len(), chain2.len());

Moves at most size bytes from another chain and returns number of bytes moved.

Example

use chainbuf::Chain;
let mut chain1 = Chain::new();
let mut chain2 = Chain::new();
chain1.append_bytes("helloworld".as_bytes());
let moved = chain2.move_from(&mut chain1, 3);
assert_eq!(moved, 3);
let moved_more = chain2.move_from(&mut chain1, 10);
assert_eq!(moved_more, 7);

Moves all data from sourche chain to itself.

This operation should compute in O(1).

Example

use chainbuf::Chain;
let mut chain1 = Chain::new();
let mut chain2 = Chain::new();
chain1.append_bytes("helloworld".as_bytes());
chain2.move_all_from(&mut chain1);
assert_eq!(chain1.len(), 0);
assert_eq!(chain2.len(), 10);

Returns mutable slice of requested size that points to empty area in DataHolder. If requested size greater than available room in existing node, new node will be created.

Usage

After writing data to buffer .written(size) should be calling to move offsets.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
let buf = chain.reserve(10);
assert_eq!(buf.len(), 10);

Changes offsets in chain to specified number of bytes. Should be used in conjuction with .reserve().

Example

use chainbuf::Chain;
let mut chain = Chain::new();
{
    let buf = chain.reserve(2);
    buf[0] = 'h' as u8;
    buf[1] = 'i' as u8;
}
chain.written(2);
assert_eq!(chain.len(), 2);

Removes requested number of bytes from chain, by changing offsets.

Note

If requested size greater than size of node it will be removed and data will be fred if no other chain shares it.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("somebinaryprotocol".as_bytes());
{
    let head = chain.pullup(2); // parse header
}
chain.drain(2); // header parsed and no longer needed
assert_eq!(chain.len(), 16);

Finds sequence of bytes inside the chain and returns offset to first symbol of sequence or None if nothing found.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
let res = chain.find("owo".as_bytes());
assert!(res.is_some());
assert_eq!(res.unwrap(), 4);

Copy size bytes from chain starting from specified offset.

Example

use chainbuf::Chain;
let mut chain = Chain::new();
chain.append_bytes("helloworld".as_bytes());
assert_eq!(chain.copy_bytes_from(2, 2), "ll".as_bytes().to_vec());

Writes content of chain to specified file descriptor fd. Amount of successfully written bytes are then drained out of the chain and returned. Optional nodes and size allow to control amount of nodes that will be written. nodes specifies exact number of nodes to be written. size specifies minimum number of bytes that should be present in nodes.

Note

It uses writev underneath, each node's content will go in corresponding iovec struct in array of iovecs.

Example

extern crate nix;
extern crate chainbuf;
use chainbuf::Chain;
use nix::unistd::{pipe, close, read};
use std::iter::{repeat};
fn main() {
    let (reader, writer) = pipe().unwrap();
    let mut chain = Chain::new();
    let d = "HelloWorld".as_bytes();
    chain.append_bytes(d);
    let written = chain.write_to_fd(writer, None, None).ok().unwrap();
    close(writer);
    let mut read_buf:Vec<u8> = repeat(0u8).take(written).collect();
    let read = read(reader, &mut read_buf[..]).ok().unwrap();
    assert_eq!(read, written);
    assert_eq!(&read_buf[..], d);
    close(reader);
}

Appends file on path to chainbuf by memory mapping it. File will be closed and unmapped when node freshly created read-only node will be dropped.

Example:

This example is not tested
use chainbuf::Chain;
let path = b"/tmp/path";
let mut chain = Chain::new();
chain.append_file(path);
println!("{}", chain.len());
assert!(chain.len() > 0);

Trait Implementations

impl<'src> PartialEq for Chain<'src>
[src]

Chains are considered equal iff they have same content inside. Memory layout is not important.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

Auto Trait Implementations

impl<'src> !Send for Chain<'src>

impl<'src> !Sync for Chain<'src>