<commit_before>// TODO: use Impls https://github.com/iron/iron/blob/master/src/iron.rs

extern crate collections;

use collections::dlist::DList;
use collections::Deque;

static CHB_MIN_SIZE:uint = 32u;

// TODO: move to utils
fn blit<T:Clone>(src: &[T], src_ofs: uint, dst: &mut [T], dst_ofs: uint, len: uint) {
    if (src_ofs > src.len() - len) || (dst_ofs > dst.len() - len) {
        fail!("blit: invalid argument!");
    }
    let sd = dst.slice_mut(dst_ofs, dst_ofs + len);
    let ss = src.slice(src_ofs, src_ofs + len);
    let _ = sd.clone_from_slice(ss);
}

/// Chained buffer of bytes.
/// Consists of linked list of nodes.
pub struct Chain {
    head: DList<Box<Node>>,
    length: uint
}

impl Chain {
    pub fn new() -> Chain {
        return Chain{
            head: DList::new(),
            length: 0
        }
    }

    // TODO: rename len()?
    pub fn size(&self) -> uint {
        self.length
    }

    // XXX: maybe DEDUP append/prepend?
    // TODO: test: length, capacity, node size
    pub fn append_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.back() {
            Some(nd) => {
                // Check is READONLY
                nd.room() < size
            }
            None => {
                true
            }
        };
        if should_create {
            self.create_node_tail(size);
        }
        // node could not be None here
        let node = self.head.back_mut().unwrap();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6268
        let end = node.end;
        blit(data.as_slice(), 0,
             node.dh.data.as_mut_slice(), end,
             size);
        node.end += size;
        self.length += size;
    }

    // TODO: test: length, capacity, node size
    pub fn prepend_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.front() {
            Some(nd) => {
                // Check is READONLY
                size > nd.start
            }
            None => {
                true
            }
        };
        if should_create {
            self.create_node_head(size);
        }
        // node could not be None here
        let node = self.head.front_mut().unwrap();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6268
        let start = node.start;
        blit(data.as_slice(), 0,
             node.dh.data.as_mut_slice(), start - size,
             size);
        node.start -= size;
        self.length += size;
    }

    pub fn pullup(&mut self, size: uint) -> Option<&[u8]> {
        if size == 0 || size > self.size() {
            return None
        }
        // let node = match chb.head
        None
    }

    // XXX: private

    // TODO: rename _back
    fn add_node_tail(&mut self, node: Box<Node>) {
        self.length += node.size();
        self.head.push(node);
    }

    // TODO: rename _front
    fn add_node_head(&mut self, node: Box<Node>) {
        self.length += node.size();
        self.head.push_front(node);
    }

    // TODO: rename _back
    // TODO: remove?
    fn create_node_tail(&mut self, size: uint) {
        let nsize = if size < CHB_MIN_SIZE {
            size << 1
        } else {
            size
        };
        let node = Node::new(DataHolder::new(nsize)); // Box<Node>
        self.add_node_tail(node);
    }

    // TODO: rename _front
    fn create_node_head(&mut self, size: uint) {
        let nsize = if size < CHB_MIN_SIZE {
            size << 1
        } else {
            size
        };
        let mut node = Node::new(DataHolder::new(nsize)); // Box<Node>
        let r = node.room();
        node.start = r;
        node.end = r;
        self.add_node_head(node);
    }
}

/// Node of chain buffer.
/// Owned by Chain.
struct Node {
    dh: Box<DataHolder>, // можно заменить на RC
    start: uint,
    end: uint
}

impl Node {
    fn new(dh: Box<DataHolder>) -> Box<Node> {
        let n = box Node {
            dh: dh,
            start: 0,
            end: 0
        };
        // TODO: ref dh ? auto, when using RC
        return n;
    }

    fn size(&self) -> uint {
        self.end - self.start
    }

    fn room(&self) -> uint {
        return self.dh.size - self.end;
    }
}

/// Data holder
/// TODO: can be shared among different chains
/// TODO: implement other storages: shmem, mmap
struct DataHolder{
    size: uint,
    data: Vec<u8>
}

impl DataHolder {
    fn new(size: uint) -> Box<DataHolder> {
        let dh = box DataHolder {
            size: size,
            data: Vec::from_elem(size, 0)
        };
        return dh;
    }
}

#[cfg(test)]
mod test {
    use super::Chain;

    #[test]
    fn test_append_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld";
        let ls = s.len();
        chain.append_bytes(s.as_bytes());
        assert_eq!(chain.size(), ls);
    }

    #[test]
    fn test_prepend_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld";
        let ls = s.len();
        chain.prepend_bytes(s.as_bytes());
        assert_eq!(chain.size(), ls);
    }

}
<commit_msg>[refac] remove unused functions<commit_after>// TODO: use Impls https://github.com/iron/iron/blob/master/src/iron.rs

extern crate collections;

use collections::dlist::DList;
use collections::Deque;

static CHB_MIN_SIZE:uint = 32u;

// TODO: move to utils
fn blit<T:Clone>(src: &[T], src_ofs: uint, dst: &mut [T], dst_ofs: uint, len: uint) {
    if (src_ofs > src.len() - len) || (dst_ofs > dst.len() - len) {
        fail!("blit: invalid argument!");
    }
    let sd = dst.slice_mut(dst_ofs, dst_ofs + len);
    let ss = src.slice(src_ofs, src_ofs + len);
    let _ = sd.clone_from_slice(ss);
}

/// Chained buffer of bytes.
/// Consists of linked list of nodes.
pub struct Chain {
    head: DList<Box<Node>>,
    length: uint
}

impl Chain {
    pub fn new() -> Chain {
        return Chain{
            head: DList::new(),
            length: 0
        }
    }

    // TODO: rename len()?
    pub fn size(&self) -> uint {
        self.length
    }

    // XXX: maybe DEDUP append/prepend?
    // TODO: test: length, capacity, node size
    pub fn append_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.back() {
            Some(nd) => {
                // Check is READONLY
                nd.room() < size
            }
            None => {
                true
            }
        };
        if should_create {
            let nsize = if size < CHB_MIN_SIZE { size << 1 } else { size };
            let node = Node::new(DataHolder::new(nsize)); // Box<Node>
            self.add_node_tail(node);
        }
        // node could not be None here
        let node = self.head.back_mut().unwrap();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6268
        let end = node.end;
        blit(data.as_slice(), 0,
             node.dh.data.as_mut_slice(), end,
             size);
        node.end += size;
        self.length += size;
    }

    // TODO: test: length, capacity, node size
    pub fn prepend_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.front() {
            Some(nd) => {
                // Check is READONLY
                size > nd.start
            }
            None => {
                true
            }
        };
        if should_create {
            let nsize = if size < CHB_MIN_SIZE { size << 1 } else { size };
            let mut node = Node::new(DataHolder::new(nsize)); // Box<Node>
            let r = node.room();
            node.start = r;
            node.end = r;
            self.add_node_head(node);
        }
        // node could not be None here
        let node = self.head.front_mut().unwrap();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6268
        let start = node.start;
        blit(data.as_slice(), 0,
             node.dh.data.as_mut_slice(), start - size,
             size);
        node.start -= size;
        self.length += size;
    }

    pub fn pullup(&mut self, size: uint) -> Option<&[u8]> {
        if size == 0 || size > self.size() {
            return None
        }
        // let node = match chb.head
        None
    }

    // XXX: private
    fn add_node_tail(&mut self, node: Box<Node>) {
        self.length += node.size();
        self.head.push(node);
    }

    fn add_node_head(&mut self, node: Box<Node>) {
        self.length += node.size();
        self.head.push_front(node);
    }
}

/// Node of chain buffer.
/// Owned by Chain.
struct Node {
    dh: Box<DataHolder>, // можно заменить на RC
    start: uint,
    end: uint
}

impl Node {
    fn new(dh: Box<DataHolder>) -> Box<Node> {
        let n = box Node {
            dh: dh,
            start: 0,
            end: 0
        };
        // TODO: ref dh ? auto, when using RC
        return n;
    }

    fn size(&self) -> uint {
        self.end - self.start
    }

    fn room(&self) -> uint {
        return self.dh.size - self.end;
    }
}

/// Data holder
/// TODO: can be shared among different chains
/// TODO: implement other storages: shmem, mmap
struct DataHolder{
    size: uint,
    data: Vec<u8>
}

impl DataHolder {
    fn new(size: uint) -> Box<DataHolder> {
        let dh = box DataHolder {
            size: size,
            data: Vec::from_elem(size, 0)
        };
        return dh;
    }
}

#[cfg(test)]
mod test {
    use super::Chain;

    #[test]
    fn test_append_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld";
        let ls = s.len();
        chain.append_bytes(s.as_bytes());
        assert_eq!(chain.size(), ls);
    }

    #[test]
    fn test_prepend_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld";
        let ls = s.len();
        chain.prepend_bytes(s.as_bytes());
        assert_eq!(chain.size(), ls);
    }

}
<|endoftext|>


<commit_before>use std::io::IoResult;

/// A wrapper around any struct implementing the `Reader` trait, additionally
/// allowing for `peek` operations to be performed. Therefore, the
/// `PeekableReader` struct also implements the `Reader` trait.
///
/// The primary invariant of the `PeekableReader` is that after calling the
/// `peek` method, the next `read_byte` call will return the same result as
/// the `peek` does. When the result is a byte (read off the wrapped reader),
/// any read-type method of the `Reader` trait will include the byte as the
/// first one. On the other hand, if the result is an `IoError`, the error
/// will be returned regardless of which read-type method of the `Reader` is
/// invoked. Consecutive `peek`s before any read-type operation is used
/// always return the same `IoResult`.
pub struct PeekableReader<R> {
    inner: R,
    peeked_result: Option<IoResult<u8>>,
}

impl<R: Reader> PeekableReader<R> {
    /// Initializes a new `PeekableReader` which wraps the given underlying
    /// reader.
    pub fn new(reader: R) -> PeekableReader<R> {
        PeekableReader {
            inner: reader,
            peeked_result: None,
        }
    }

    /// Returns the `IoResult` which the Reader will return on the next
    /// `get_byte` call.
    ///
    /// If the `IoResult` is indeed an `IoError`, the error will be returned
    /// for any subsequent read operation invoked upon the `Reader`.
    pub fn peek(&mut self) -> IoResult<u8> {
        // Return either the currently cached peeked byte or obtain a new one
        // from the underlying reader.
        match self.peeked_result {
            Some(ref old_res) => old_res.clone(),
            None => {
                // First get the result of the read from the underlying reader
                self.peeked_result = Some(self.inner.read_byte());

                // Now just return that
                self.peeked_result.clone().unwrap()
            }
        }
    }
}

impl<R: Reader> Reader for PeekableReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        if buf.len() == 0 {
            return Ok(0);
        }

        // First, put the byte that was read off the underlying reader in a
        // (possible) previous peek operation (if such a byte is indeed cached)
        let offset = match self.peeked_result.clone() {
            Some(Err(e)) => {
                self.peeked_result = None;
                return Err(e);
            },
            Some(Ok(b)) => {
                buf[0] = b;
                self.peeked_result = None;
                1
            },
            None => 0,
        };

        if offset == 1 && buf.len() == 1 {
            // We've filled the buffer by using the previously peeked byte
            Ok(1)
        } else {
            // We are still missing more bytes, so we read them from the
            // underlying reader and place them directly in the correct place
            // in the buffer.
            let (_, leftover) = buf.split_at_mut(offset);
            Ok(try!(self.inner.read(leftover)) + offset)
        }
    }
}

mod tests {
    use super::PeekableReader;
    use std::io::{MemReader, IoError, IoErrorKind, IoResult};

    /// A mock implementation of the `Reader` trait that returns a given
    /// IoError after a certain number of bytes has been read. The error is
    /// returned only once, with subsequent read calls completing successfully
    /// again.
    /// When the Reader successfully reads a byte, it is always `0u8`.
    struct MockReaderWithError {
        error: IoError,
        after: uint,
        bytes_read: uint,
        errored: bool,
    }

    impl MockReaderWithError {
        fn new(error: IoError, after: uint) -> MockReaderWithError {
            MockReaderWithError {
                error: error,
                after: after,
                bytes_read: 0,
                errored: false,
            }
        }
    }

    impl Reader for MockReaderWithError {
        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
            self.bytes_read += buf.len();
            if self.bytes_read <= self.after || self.errored {
                for b in buf.iter_mut() {
                    *b = 0;
                }

                Ok(buf.len())
            } else {
                self.errored = true;
                Err(self.error.clone())
            }
        }
    }

    /// Helper function which checks whether the given result indicated EOF.
    fn is_eof<T>(res: IoResult<T>) -> bool {
        match res {
            Err(IoError {
                kind: IoErrorKind::EndOfFile,
                ..
            }) => true,
            _ => false,
        }
    }

    /// Helper function which just checks whether the given IoResult is equal
    /// to the given IoError.
    fn is_err<T>(err: &IoError, res: IoResult<T>) -> bool {
        match res {
            Err(ref result_error) => result_error == err,
            _ => false,
        }
    }

    /// Tests that it is possible to invoke the `peek` method multiple times
    /// with the same effect, when there are no intermediate reads.
    #[test]
    fn multiple_peeks_idempotent() {
        let b = 1;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b, b + 1)));

        // The first peek is correct?
        assert_eq!(b, reader.peek().unwrap());
        // The second peek (with no reads in between) still returns the same
        // byte?
        assert_eq!(b, reader.peek().unwrap());
    }

    /// Tests that the `peek` method correctly returns an IoError returned by
    /// the underlying reader on consecutive peek calls.
    #[test]
    fn peek_result_error() {
        let err = IoError {
            kind: IoErrorKind::OtherIoError,
            desc: "Dummy error",
            detail: None,
        };
        let mut reader = PeekableReader::new(
            MockReaderWithError::new(err.clone(), 0));

        assert!(is_err(&err, reader.peek()),
                "Expected an IoError!");
        assert!(is_err(&err, reader.peek()),
                "Expected an IoError on the second peek too!");
    }

    /// Tests that performing multiple `peek` calls after the `Reader` has
    /// reached EOF always returns EOF.
    #[test]
    fn multiple_peeks_at_eof() {
        let mut reader = PeekableReader::new(MemReader::new(vec!(1)));
        // Read/skip the first byte
        let _ = reader.read_byte();
        // Consume the EOF (and perform a sanity check that we have reached it)
        assert!(is_eof(reader.read_byte()));

        // All subsequent peeks return EOF
        assert!(is_eof(reader.peek()));
        assert!(is_eof(reader.peek()));
    }

    /// Tests that peeks and reads correctly work when the underlying reader
    /// only has a single byte.
    #[test]
    fn single_byte_reader_peek() {
        let b = 5u8;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b)));

        // When we peek, we get the correct byte back?
        assert_eq!(b, reader.peek().unwrap());
        // And now we also read it...
        assert_eq!(b, reader.read_byte().unwrap());
        // After this, both the peek and the read return an EOF?
        assert!(is_eof(reader.peek()));
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that peeks and reads from an empty underlying reader instantly
    /// return EOF.
    #[test]
    fn empty_underlying_reader() {
        let mut reader = PeekableReader::new(MemReader::new(vec!()));

        // Must return EOF since the underlying reader is empty
        assert!(is_eof(reader.peek()));
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that when we peek before every read, we correctly end up reading
    /// the entire contents of the underlying Reader.
    #[test]
    fn peek_read_alternate() {
        let vec: Vec<u8> = range(0u8, 5).collect();
        let mut reader = PeekableReader::new(MemReader::new(vec.clone()));

        for &b in vec.iter() {
            assert_eq!(b, reader.peek().unwrap());
            assert_eq!(b, reader.read_byte().unwrap());
        }
        // Now we're at EOF
        assert!(is_eof(reader.peek()));
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that a peek after the underlying reader has reached EOF fails
    /// with an appropriate error.
    #[test]
    fn peek_after_eof() {
        let mut reader = PeekableReader::new(MemReader::new(vec!(1)));
        // Read both the only byte from the reader and the EOF
        let _ = reader.read_byte();
        assert!(is_eof(reader.read_byte()));

        // Now the peek still correctly returns the EOF
        assert!(is_eof(reader.peek()));
    }

    /// Tests that the PeekableReader behaves correctly when only Reader methods
    /// are used.
    #[test]
    fn sequential_reader() {
        let vec: Vec<u8> = range(0u8, 5).collect();
        let mut reader = PeekableReader::new(MemReader::new(vec.clone()));

        for &b in vec.iter() {
            assert_eq!(b, reader.read_byte().unwrap());
        }
        // Now we're at EOF
        assert!(is_eof(reader.read_byte()));
        // Still EOF...
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that a currently cached peeked byte does not get invalidated when
    /// the read method is invoked with an empty buffer.
    #[test]
    fn zero_length_buffer_read_does_not_invalidate_peek() {
        let vec: Vec<u8> = range(0u8, 5).collect();
        let mut reader = PeekableReader::new(MemReader::new(vec.clone()));
        let first_peek = reader.peek().unwrap();

        let mut buffer = vec!();
        let _ = reader.read(buffer.as_mut_slice());

        assert_eq!(first_peek, reader.peek().unwrap());
    }

    /// Tests that when the underlying `Reader` returns an IoError, the `peek`
    /// method keeps returning the same error for each call until the error is
    /// actually "read" by the client (by invoking one of the read methods of
    /// the `Reader`).
    #[test]
    fn always_returns_same_io_error_on_peek() {
        let err = IoError {
            kind: IoErrorKind::OtherIoError,
            desc: "Dummy error",
            detail: None,
        };
        let mut reader = PeekableReader::new(
            MockReaderWithError::new(err.clone(), 1));
        // Read the first byte (no error)
        assert_eq!(0, reader.read_byte().unwrap());

        // This peek now signals an IoError
        assert!(is_err(&err, reader.peek()),
                "Expected an IoError on the first peek");
        // The next peek still reports the same error...
        assert!(is_err(&err, reader.peek()),
                "Expected an IoError on the second peek too");
        // The read also indicates the same error.
        assert!(is_err(&err, reader.read_byte()),
                "Expected an IoError on the read too");
        // The next peek has to retry the read -- which succeeds
        assert_eq!(0, reader.peek().unwrap());
    }

    /// Test for the MockReaderWithError helper mock class...
    #[test]
    fn mock_sanity_check() {
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 1);

            // First byte is not a problem.
            assert_eq!(0, reader.read_byte().unwrap());
            // However, now the read fails...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // But, already on the next one, we're out of the woods.
            assert_eq!(0, reader.read_byte().unwrap());
        }
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 0);

            // The read fails on the first one...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // ...but now we're good.
            assert_eq!(0, reader.read_byte().unwrap());
        }
    }

}
<commit_msg>Rename the `peek` method to `peek_byte`<commit_after>use std::io::IoResult;

/// A wrapper around any struct implementing the `Reader` trait, additionally
/// allowing for `peek` operations to be performed. Therefore, the
/// `PeekableReader` struct also implements the `Reader` trait.
///
/// The primary invariant of the `PeekableReader` is that after calling the
/// `peek` method, the next `read_byte` call will return the same result as
/// the `peek` does. When the result is a byte (read off the wrapped reader),
/// any read-type method of the `Reader` trait will include the byte as the
/// first one. On the other hand, if the result is an `IoError`, the error
/// will be returned regardless of which read-type method of the `Reader` is
/// invoked. Consecutive `peek`s before any read-type operation is used
/// always return the same `IoResult`.
pub struct PeekableReader<R> {
    inner: R,
    peeked_result: Option<IoResult<u8>>,
}

impl<R: Reader> PeekableReader<R> {
    /// Initializes a new `PeekableReader` which wraps the given underlying
    /// reader.
    pub fn new(reader: R) -> PeekableReader<R> {
        PeekableReader {
            inner: reader,
            peeked_result: None,
        }
    }

    /// Returns the `IoResult` which the Reader will return on the next
    /// `get_byte` call.
    ///
    /// If the `IoResult` is indeed an `IoError`, the error will be returned
    /// for any subsequent read operation invoked upon the `Reader`.
    pub fn peek_byte(&mut self) -> IoResult<u8> {
        // Return either the currently cached peeked byte or obtain a new one
        // from the underlying reader.
        match self.peeked_result {
            Some(ref old_res) => old_res.clone(),
            None => {
                // First get the result of the read from the underlying reader
                self.peeked_result = Some(self.inner.read_byte());

                // Now just return that
                self.peeked_result.clone().unwrap()
            }
        }
    }
}

impl<R: Reader> Reader for PeekableReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        if buf.len() == 0 {
            return Ok(0);
        }

        // First, put the byte that was read off the underlying reader in a
        // (possible) previous peek operation (if such a byte is indeed cached)
        let offset = match self.peeked_result.clone() {
            Some(Err(e)) => {
                self.peeked_result = None;
                return Err(e);
            },
            Some(Ok(b)) => {
                buf[0] = b;
                self.peeked_result = None;
                1
            },
            None => 0,
        };

        if offset == 1 && buf.len() == 1 {
            // We've filled the buffer by using the previously peeked byte
            Ok(1)
        } else {
            // We are still missing more bytes, so we read them from the
            // underlying reader and place them directly in the correct place
            // in the buffer.
            let (_, leftover) = buf.split_at_mut(offset);
            Ok(try!(self.inner.read(leftover)) + offset)
        }
    }
}

mod tests {
    use super::PeekableReader;
    use std::io::{MemReader, IoError, IoErrorKind, IoResult};

    /// A mock implementation of the `Reader` trait that returns a given
    /// IoError after a certain number of bytes has been read. The error is
    /// returned only once, with subsequent read calls completing successfully
    /// again.
    /// When the Reader successfully reads a byte, it is always `0u8`.
    struct MockReaderWithError {
        error: IoError,
        after: uint,
        bytes_read: uint,
        errored: bool,
    }

    impl MockReaderWithError {
        fn new(error: IoError, after: uint) -> MockReaderWithError {
            MockReaderWithError {
                error: error,
                after: after,
                bytes_read: 0,
                errored: false,
            }
        }
    }

    impl Reader for MockReaderWithError {
        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
            self.bytes_read += buf.len();
            if self.bytes_read <= self.after || self.errored {
                for b in buf.iter_mut() {
                    *b = 0;
                }

                Ok(buf.len())
            } else {
                self.errored = true;
                Err(self.error.clone())
            }
        }
    }

    /// Helper function which checks whether the given result indicated EOF.
    fn is_eof<T>(res: IoResult<T>) -> bool {
        match res {
            Err(IoError {
                kind: IoErrorKind::EndOfFile,
                ..
            }) => true,
            _ => false,
        }
    }

    /// Helper function which just checks whether the given IoResult is equal
    /// to the given IoError.
    fn is_err<T>(err: &IoError, res: IoResult<T>) -> bool {
        match res {
            Err(ref result_error) => result_error == err,
            _ => false,
        }
    }

    /// Tests that it is possible to invoke the `peek_byte` method multiple
    /// times with the same effect, when there are no intermediate reads.
    #[test]
    fn multiple_peeks_idempotent() {
        let b = 1;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b, b + 1)));

        // The first peek is correct?
        assert_eq!(b, reader.peek_byte().unwrap());
        // The second peek (with no reads in between) still returns the same
        // byte?
        assert_eq!(b, reader.peek_byte().unwrap());
    }

    /// Tests that the `peek_byte` method correctly returns an IoError
    /// returned by the underlying reader on consecutive peek_byte calls.
    #[test]
    fn peek_result_error() {
        let err = IoError {
            kind: IoErrorKind::OtherIoError,
            desc: "Dummy error",
            detail: None,
        };
        let mut reader = PeekableReader::new(
            MockReaderWithError::new(err.clone(), 0));

        assert!(is_err(&err, reader.peek_byte()),
                "Expected an IoError!");
        assert!(is_err(&err, reader.peek_byte()),
                "Expected an IoError on the second peek too!");
    }

    /// Tests that performing multiple `peek_byte` calls after the `Reader`
    /// has reached EOF always returns EOF.
    #[test]
    fn multiple_peeks_at_eof() {
        let mut reader = PeekableReader::new(MemReader::new(vec!(1)));
        // Read/skip the first byte
        let _ = reader.read_byte();
        // Consume the EOF (and perform a sanity check that we have reached it)
        assert!(is_eof(reader.read_byte()));

        // All subsequent peeks return EOF
        assert!(is_eof(reader.peek_byte()));
        assert!(is_eof(reader.peek_byte()));
    }

    /// Tests that peeks and reads correctly work when the underlying reader
    /// only has a single byte.
    #[test]
    fn single_byte_reader_peek() {
        let b = 5u8;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b)));

        // When we peek, we get the correct byte back?
        assert_eq!(b, reader.peek_byte().unwrap());
        // And now we also read it...
        assert_eq!(b, reader.read_byte().unwrap());
        // After this, both the peek and the read return an EOF?
        assert!(is_eof(reader.peek_byte()));
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that peeks and reads from an empty underlying reader instantly
    /// return EOF.
    #[test]
    fn empty_underlying_reader() {
        let mut reader = PeekableReader::new(MemReader::new(vec!()));

        // Must return EOF since the underlying reader is empty
        assert!(is_eof(reader.peek_byte()));
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that when we peek before every read, we correctly end up reading
    /// the entire contents of the underlying Reader.
    #[test]
    fn peek_read_alternate() {
        let vec: Vec<u8> = range(0u8, 5).collect();
        let mut reader = PeekableReader::new(MemReader::new(vec.clone()));

        for &b in vec.iter() {
            assert_eq!(b, reader.peek_byte().unwrap());
            assert_eq!(b, reader.read_byte().unwrap());
        }
        // Now we're at EOF
        assert!(is_eof(reader.peek_byte()));
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that a peek after the underlying reader has reached EOF fails
    /// with an appropriate error.
    #[test]
    fn peek_after_eof() {
        let mut reader = PeekableReader::new(MemReader::new(vec!(1)));
        // Read both the only byte from the reader and the EOF
        let _ = reader.read_byte();
        assert!(is_eof(reader.read_byte()));

        // Now the peek still correctly returns the EOF
        assert!(is_eof(reader.peek_byte()));
    }

    /// Tests that the PeekableReader behaves correctly when only Reader methods
    /// are used.
    #[test]
    fn sequential_reader() {
        let vec: Vec<u8> = range(0u8, 5).collect();
        let mut reader = PeekableReader::new(MemReader::new(vec.clone()));

        for &b in vec.iter() {
            assert_eq!(b, reader.read_byte().unwrap());
        }
        // Now we're at EOF
        assert!(is_eof(reader.read_byte()));
        // Still EOF...
        assert!(is_eof(reader.read_byte()));
    }

    /// Tests that a currently cached peeked byte does not get invalidated when
    /// the read method is invoked with an empty buffer.
    #[test]
    fn zero_length_buffer_read_does_not_invalidate_peek() {
        let vec: Vec<u8> = range(0u8, 5).collect();
        let mut reader = PeekableReader::new(MemReader::new(vec.clone()));
        let first_peek = reader.peek_byte().unwrap();

        let mut buffer = vec!();
        let _ = reader.read(buffer.as_mut_slice());

        assert_eq!(first_peek, reader.peek_byte().unwrap());
    }

    /// Tests that when the underlying `Reader` returns an IoError, the `peek`
    /// method keeps returning the same error for each call until the error is
    /// actually "read" by the client (by invoking one of the read methods of
    /// the `Reader`).
    #[test]
    fn always_returns_same_io_error_on_peek() {
        let err = IoError {
            kind: IoErrorKind::OtherIoError,
            desc: "Dummy error",
            detail: None,
        };
        let mut reader = PeekableReader::new(
            MockReaderWithError::new(err.clone(), 1));
        // Read the first byte (no error)
        assert_eq!(0, reader.read_byte().unwrap());

        // This peek now signals an IoError
        assert!(is_err(&err, reader.peek_byte()),
                "Expected an IoError on the first peek");
        // The next peek still reports the same error...
        assert!(is_err(&err, reader.peek_byte()),
                "Expected an IoError on the second peek too");
        // The read also indicates the same error.
        assert!(is_err(&err, reader.read_byte()),
                "Expected an IoError on the read too");
        // The next peek has to retry the read -- which succeeds
        assert_eq!(0, reader.peek_byte().unwrap());
    }

    /// Test for the MockReaderWithError helper mock class...
    #[test]
    fn mock_sanity_check() {
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 1);

            // First byte is not a problem.
            assert_eq!(0, reader.read_byte().unwrap());
            // However, now the read fails...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // But, already on the next one, we're out of the woods.
            assert_eq!(0, reader.read_byte().unwrap());
        }
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 0);

            // The read fails on the first one...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // ...but now we're good.
            assert_eq!(0, reader.read_byte().unwrap());
        }
    }

}
<|endoftext|>


<commit_before>#![feature(asm,alloc)]
#![no_std]

extern crate alloc;
extern crate tock;

use alloc::boxed::Box;
use alloc::String;
use alloc::fmt::Write;
use tock::console::Console;
use tock::ipc;
use tock::sensors::*;

fn setup_ipc() -> Result<(ipc::Client, Box<[u8]>), ()> {
    let mut ipc_client = ipc::Client::new(
                String::from("org.tockos.services.ble-ess"))?;
    let shared_vec = ipc_client.share(5)?;
    Ok((ipc_client, shared_vec))
}

fn set_ipc_slice<I: Into<i32>>(slice: &mut [u8], sensor_type: u32, sensor_data: I) {
    let sensor_data = Into::<i32>::into(sensor_data) as u32;
    slice[0..4].copy_from_slice(&[(sensor_type & 0xff) as u8,
                                    ((sensor_type >> 8) & 0xff) as u8,
                                    ((sensor_type >> 16) & 0xff) as u8,
                                    ((sensor_type >> 24) & 0xff) as u8]);
    slice[4..8].copy_from_slice(&[(sensor_data & 0xff) as u8,
                                ((sensor_data >> 8) & 0xff) as u8,
                                ((sensor_data >> 16) & 0xff) as u8,
                                ((sensor_data >> 24) & 0xff) as u8]);
}

fn main() {
    let mut console = Console::new();

    let (mut ipc_client, mut updates) = match setup_ipc() {
        Ok((c, s)) => (c, s),
        _ => {
            write!(&mut console, "BLE IPC Service not installed\n").unwrap();
            return;
        }
    };

    let mut humidity = HumiditySensor;
    let mut temperature = TemperatureSensor;
    let mut light = AmbientLightSensor;
    loop {
        let humid = humidity.read();
        let temp = temperature.read();
        let lx = light.read();
        write!(&mut console, "Humidity:    {}\n", humid).unwrap();
        write!(&mut console, "Temperature: {}\n", temp).unwrap();
        write!(&mut console, "Light:       {}\n", lx).unwrap();

        // Temperature
        set_ipc_slice(&mut *updates, 0, temp);
        if let Err(_) = ipc_client.notify() {
            write!(&mut console, "Failed to send temperature\n").unwrap_or(());
        }

        // Humidity
        set_ipc_slice(&mut *updates, 1, lx);
        if let Err(_) = ipc_client.notify() {
            write!(&mut console, "Failed to send light\n").unwrap_or(());
        }

        // Humidity
        set_ipc_slice(&mut *updates, 2, humid);
        if let Err(_) = ipc_client.notify() {
            write!(&mut console, "Failed to send Humidity\n").unwrap_or(());
        }

        tock::timer::delay_ms(5000);
    }
}

<commit_msg>Some polish to ble_ess example<commit_after>#![feature(asm,alloc)]
#![no_std]

extern crate alloc;
extern crate tock;

use alloc::boxed::Box;
use alloc::String;
use alloc::fmt::Write;
use tock::console::Console;
use tock::ipc;
use tock::sensors::*;

fn setup_ipc() -> Result<(ipc::Client, Box<[u8]>), ()> {
    let mut ipc_client = ipc::Client::new(
                String::from("org.tockos.services.ble-ess"))?;
    let shared_vec = ipc_client.share(5)?;
    Ok((ipc_client, shared_vec))
}

fn set_ipc_slice<I: Into<i32>>(slice: &mut [u8], sensor_type: u32, sensor_data: I) {
    let sensor_data = Into::<i32>::into(sensor_data) as u32;
    slice[0..4].copy_from_slice(&[(sensor_type & 0xff) as u8,
                                    ((sensor_type >> 8) & 0xff) as u8,
                                    ((sensor_type >> 16) & 0xff) as u8,
                                    ((sensor_type >> 24) & 0xff) as u8]);
    slice[4..8].copy_from_slice(&[(sensor_data & 0xff) as u8,
                                ((sensor_data >> 8) & 0xff) as u8,
                                ((sensor_data >> 16) & 0xff) as u8,
                                ((sensor_data >> 24) & 0xff) as u8]);
}

fn main() {
    let mut console = Console::new();
    write!(&mut console, "Starting BLE ESS\n").unwrap();

    let (mut ipc_client, mut updates) = match setup_ipc() {
        Ok((c, s)) => (c, s),
        _ => {
            write!(&mut console, "BLE IPC Service not installed\n").unwrap();
            return;
        }
    };
    write!(&mut console, "Found BLE IPC Service\n").unwrap();

    let mut humidity = HumiditySensor;
    let mut temperature = TemperatureSensor;
    let mut light = AmbientLightSensor;
    loop {

        // Temperature
        let temp = temperature.read();
        write!(&mut console, "Temperature: {}\n", temp).unwrap();
        set_ipc_slice(&mut *updates, 0, temp);
        if let Err(_) = ipc_client.notify() {
            write!(&mut console, "Failed to send temperature\n").unwrap_or(());
        }

        // Light
        let lx = light.read();
        write!(&mut console, "Light:       {}\n", lx).unwrap();
        set_ipc_slice(&mut *updates, 1, lx);
        if let Err(_) = ipc_client.notify() {
            write!(&mut console, "Failed to send light\n").unwrap_or(());
        }

        // Humidity
        let humid = humidity.read();
        write!(&mut console, "Humidity:    {}\n", humid).unwrap();
        set_ipc_slice(&mut *updates, 2, humid);
        if let Err(_) = ipc_client.notify() {
            write!(&mut console, "Failed to send humidity\n").unwrap_or(());
        }

        tock::timer::delay_ms(5000);
    }
}

<|endoftext|>


<commit_before>//! Please contact me on github and file any issues if you find some, I'm also open to PRs or other suggestions.
//! CHANGELOG (0.2.0):
//! If you're upgrading from iron-tera 0.1.4, the API has changed slightly for serialized values.
//! Serde 0.9.0 to_value returns a `Result`, this means you need to handle the possiblity of a serialization failure.
//! Since we're still pre-1.0 and the API isn't completely stable, I've only incremented the minor version number.
//!
//! ## Examples
//! The following is a complete working example that I've tested with serde 0.9.0, tera 0.7.0 and iron-tera 0.2.0
//! ```rust
//! #[macro_use]
//! extern crate tera;
//!
//! extern crate iron;
//! extern crate router;
//! #[macro_use]
//! extern crate serde_json;
//! extern crate iron_tera;
//!
//! use iron::prelude::*;
//! use iron::status;
//! use router::Router;
//! use tera::Context;
//!
//! use iron_tera::{Template, TeraEngine, TemplateMode};
//!
//! fn main() {
//!     let mut router = Router::new();
//!     router.get("/context", context_handler, "context");
//!     router.get("/json", json_handler, "json");
//!
//!     let mut chain = Chain::new(router);
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//! }
//!
//!
//! fn context_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let mut context = Context::new();
//!     context.add("username", &"Bob");
//!     context.add("my_var", &"Thing"); // comment out to see alternate thing
//!     context.add("numbers", &vec![1, 2, 3]);
//!     context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!     resp.set_mut(Template::new("users/profile.html", TemplateMode::from_context(context)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! fn json_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let blob = json!({
//!         "username": "John Doe",
//!         "my_var": "Thing",
//!         "numbers": [
//!             "1",
//!             "+44 2345678",
//!             "3"
//!         ],
//!         "bio": "<script>alert('pwnd');</script>"
//!      });
//!
//!     resp.set_mut(Template::new("users/profile.html",
//!                                TemplateMode::from_serial(&blob).unwrap()))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
//! Creating a template from a struct
//! ```rust
//! // The following uses serde's Serialize
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//! // Rendering from a struct that implements Serialize
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     resp.set_mut(Template::new("product.html", TemplateMode::from_serial(&product).unwrap())) // I made a choice here to return a result and let you handle the serialization error how you see fit.
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
#![allow(dead_code)]
#[macro_use] extern crate serde_json;
#[macro_use] extern crate tera;
extern crate iron;
extern crate serde;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap, status};
use iron::modifier::Modifier;
use iron::headers::ContentType;

use tera::{Tera, Context};

use serde::Serialize;
use serde_json::{Value, to_value};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }
    pub fn from_serial<S: Serialize>(serialized: S) -> Result<TemplateMode, serde_json::Error> {
        Ok(TemplateMode::Serialized(to_value(serialized)?))
    }
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    pub fn new(name: &str, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode: mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice or preferably a `&str`
    pub fn new(dir: &str) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(|t| {
            match t.mode {
                TemplateMode::TeraContext(context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(value) => Some(self.tera.value_render(&t.name, &value)),
            }
        });
        match wrapper {
            Some(result) => {
                result.map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

#[cfg(test)]
mod tests {
    use super::{TeraEngine, Template, TemplateMode};
    use iron::prelude::*;
    use tera::{Tera, Context};

    #[derive(Serialize)]
    struct Product {
        name: String,
        value: i32,
    }

    fn test_resp() -> IronResult<Response> {
        let resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Foo");
        context.add("bio", &"Bar");
        context.add("numbers", &vec![1, 2, 3]);

        Ok(resp.set(Template::new("users/foo.html", TemplateMode::from_context(context))))
    }

    #[test]
    fn example() {
        let mut resp = test_resp().ok().expect("response expected");

        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name.unwrap(), "users/profile.html".to_string());
                assert_eq!(h.value
                               .as_object()
                               .unwrap()
                               .get(&"Foo".to_string())
                               .unwrap()
                               .as_string()
                               .unwrap(),
                           "Bar");
            }
            _ => panic!("template expected"),
        }
        // let teng = TeraEngine::new("src/test_template/**/*");
        // // Context option 1
        // let mut context = Context::new();
        // context.add("firstname", &"Foo");
        // context.add("lastname", &"Bar");
        //
        // let t = Template::new("index", TemplateMode::TeraContext(context));
        //
        // // Context option 2
        // let mut c2 = Context::new();
        // c2.add("firstname", &"Foo");
        // c2.add("lastname", &"Bar");
        //
        // let t4 = Template::new("index", TemplateMode::from_context(c2));
        //
        // // Using serialized values
        // let product = Product {
        //     name: "Foo".into(),
        //     value: 42,
        // };
        // // option 2
        // let t2 = Template::new("index", TemplateMode::from_serial(&product));
    }
}
<commit_msg>changed to ser:Serialize<commit_after>//! Please contact me on github and file any issues if you find some, I'm also open to PRs or other suggestions.
//! CHANGELOG (0.2.0):
//! If you're upgrading from iron-tera 0.1.4, the API has changed slightly for serialized values.
//! Serde 0.9.0 to_value returns a `Result`, this means you need to handle the possiblity of a serialization failure.
//! Since we're still pre-1.0 and the API isn't completely stable, I've only incremented the minor version number.
//!
//! ## Examples
//! The following is a complete working example that I've tested with serde 0.9.0, tera 0.7.0 and iron-tera 0.2.0
//! ```rust
//! #[macro_use]
//! extern crate tera;
//!
//! extern crate iron;
//! extern crate router;
//! #[macro_use]
//! extern crate serde_json;
//! extern crate iron_tera;
//!
//! use iron::prelude::*;
//! use iron::status;
//! use router::Router;
//! use tera::Context;
//!
//! use iron_tera::{Template, TeraEngine, TemplateMode};
//!
//! fn main() {
//!     let mut router = Router::new();
//!     router.get("/context", context_handler, "context");
//!     router.get("/json", json_handler, "json");
//!
//!     let mut chain = Chain::new(router);
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//! }
//!
//!
//! fn context_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let mut context = Context::new();
//!     context.add("username", &"Bob");
//!     context.add("my_var", &"Thing"); // comment out to see alternate thing
//!     context.add("numbers", &vec![1, 2, 3]);
//!     context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!     resp.set_mut(Template::new("users/profile.html", TemplateMode::from_context(context)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! fn json_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let blob = json!({
//!         "username": "John Doe",
//!         "my_var": "Thing",
//!         "numbers": [
//!             "1",
//!             "+44 2345678",
//!             "3"
//!         ],
//!         "bio": "<script>alert('pwnd');</script>"
//!      });
//!
//!     resp.set_mut(Template::new("users/profile.html",
//!                                TemplateMode::from_serial(&blob).unwrap()))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
//! Creating a template from a struct
//! ```rust
//! // The following uses serde's Serialize
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//! // Rendering from a struct that implements Serialize
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     resp.set_mut(Template::new("product.html", TemplateMode::from_serial(&product).unwrap())) // I made a choice here to return a result and let you handle the serialization error how you see fit.
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
#![allow(dead_code)]
#[macro_use] extern crate serde_json;
#[macro_use] extern crate tera;
extern crate iron;
extern crate serde;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap, status};
use iron::modifier::Modifier;
use iron::headers::ContentType;

use tera::{Tera, Context};

use serde::ser::Serialize;
use serde_json::{Value, to_value};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }
    pub fn from_serial<S: Serialize>(serialized: S) -> Result<TemplateMode, serde_json::Error> {
        Ok(TemplateMode::Serialized(to_value(serialized)?))
    }
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    pub fn new(name: &str, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode: mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice or preferably a `&str`
    pub fn new(dir: &str) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(|t| {
            match t.mode {
                TemplateMode::TeraContext(context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(value) => Some(self.tera.value_render(&t.name, &value)),
            }
        });
        match wrapper {
            Some(result) => {
                result.map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

#[cfg(test)]
mod tests {
    use super::{TeraEngine, Template, TemplateMode};
    use iron::prelude::*;
    use tera::{Tera, Context};
    //
    // #[derive(Serialize)]
    // struct Product {
    //     name: String,
    //     value: i32,
    // }

    fn test_resp() -> IronResult<Response> {
        let resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Foo");
        context.add("bio", &"Bar");
        context.add("numbers", &vec![1, 2, 3]);

        Ok(resp.set(Template::new("users/foo.html", TemplateMode::from_context(context))))
    }

    #[test]
    fn example() {
        let mut resp = test_resp().ok().expect("response expected");

        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name, "users/profile.html".to_string());
                assert_eq!(h.name
                               .as_object()
                               .unwrap()
                               .get(&"Foo".to_string())
                               .unwrap()
                               .as_string()
                               .unwrap(),
                           "Bar");
            }
            _ => panic!("template expected"),
        }
        // let teng = TeraEngine::new("src/test_template/**/*");
        // // Context option 1
        // let mut context = Context::new();
        // context.add("firstname", &"Foo");
        // context.add("lastname", &"Bar");
        //
        // let t = Template::new("index", TemplateMode::TeraContext(context));
        //
        // // Context option 2
        // let mut c2 = Context::new();
        // c2.add("firstname", &"Foo");
        // c2.add("lastname", &"Bar");
        //
        // let t4 = Template::new("index", TemplateMode::from_context(c2));
        //
        // // Using serialized values
        // let product = Product {
        //     name: "Foo".into(),
        //     value: 42,
        // };
        // // option 2
        // let t2 = Template::new("index", TemplateMode::from_serial(&product));
    }
}
<|endoftext|>


<commit_before>use std::net::{TcpStream, ToSocketAddrs};
use std::io::{Read, Write};
use std::io;
use std::time::Duration;

pub enum NeedsAck {
    Yes,
    No,
}

#[derive(Copy, Clone, PartialEq)]
pub enum State {
    Disconnected,
    Connected,
    SendingData,
    WaitingForData,
    Close,
}

pub struct GdbRemote {
    stream: Option<TcpStream>,
    temp_string: String,
    needs_ack: NeedsAck,
}

pub struct Memory {
    pub address: u64,
    pub data: Vec<u8>
}

impl Default for GdbRemote {
    fn default() -> Self {
        Self::new()
    }
}

const PACKET_SIZE: usize = 1024;
static HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef";

#[inline]
fn calc_checksum(data: &[u8]) -> u8 {
    let mut checksum = 0u32;
    for i in data {
        checksum += *i as u32;
    }
    (checksum & 0xff) as u8
}

#[inline]
fn get_checksum(checksum: u8) -> (u8, u8) {
    (HEX_CHARS[((checksum >> 4) & 0xf) as usize],
     HEX_CHARS[(checksum & 0xf) as usize])
}

fn from_hex(ch: u8) -> u8 {
    if (ch >= b'a') && (ch <= b'f') {
        return ch - b'a' + 10;
    }

    if (ch >= b'0') && (ch <= b'9') {
        return ch - b'0';
    }

    if (ch >= b'A') && (ch <= b'F') {
        return ch - b'A' + 10;
    }

    0
}

fn from_pair_hex(data: (u8, u8)) -> u8 {
    let t0 = from_hex(data.0);
    let t1 = from_hex(data.1);
    (t0 << 4) | t1
}

impl GdbRemote {
    pub fn new() -> GdbRemote {
        GdbRemote {
            needs_ack: NeedsAck::Yes,
            temp_string: String::with_capacity(PACKET_SIZE + 4), // + 4 for header and checksum
            stream: None,
        }
    }

    pub fn connect<A: ToSocketAddrs>(&mut self, addr: A) -> io::Result<()> {
        let stream = try!(TcpStream::connect(addr));
        // 2 sec of time-out to make sure we never gets infitite blocked
        try!(stream.set_read_timeout(Some(Duration::from_secs(2))));
        self.stream = Some(stream);
        Ok(())
    }

    pub fn build_processed_string(dest: &mut String, source: &str) {
        let checksum = calc_checksum(source.as_bytes());
        let csum = get_checksum(checksum);

        dest.clear();
        dest.push('$');
        dest.push_str(source);
        dest.push('#');
        dest.push(csum.0 as char);
        dest.push(csum.1 as char);
    }

    pub fn send_internal(&mut self) -> io::Result<()> {
        if let Some(ref mut stream) = self.stream {
            stream.write_all(self.temp_string.as_bytes())
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "No connection with a server."))
        }
    }

    pub fn send_command(&mut self, data: &str) -> io::Result<()> {
        Self::build_processed_string(&mut self.temp_string, data);
        self.send_internal()
    }

    fn handle_send_ack(stream: &mut TcpStream, resend_data: &str, dest: &mut [u8]) -> io::Result<usize> {
        loop {
            let mut v = [0; 1];
            try!(stream.read(&mut v));

            match v[0] {
                b'+' => return stream.read(dest),
                b'-' => try!(stream.write_all(resend_data.as_bytes())),
                _ => {
                    return Err(io::Error::new(io::ErrorKind::Other, "Illegal reply from server."))
                }
            }
        }
    }

    pub fn read_reply(&mut self, dest: &mut [u8]) -> io::Result<usize> {
        if let Some(ref mut stream) = self.stream {
            match self.needs_ack {
                NeedsAck::Yes => Self::handle_send_ack(stream, &self.temp_string.clone(), dest),
                NeedsAck::No => stream.read(dest),
            }
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "No connection with a server."))
        }
    }

    fn clone_slice(dst: &mut [u8], src: &[u8]) {
        for (d, s) in dst.iter_mut().zip(src.iter()) {
            *d = *s;
        }
    }

    fn validate_checksum(data: &[u8], len: usize) -> io::Result<usize> {
        // - 3 to skip $xx in the end
        let data_len = len;
        let checksum = calc_checksum(&data[1..len - 3]);
        let data_check = from_pair_hex((data[data_len - 2], data[data_len - 1]));

        if data_check == checksum {
            Ok((data_len))
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "Checksum missmatch for data"))
        }
    }

    fn convert_hex_data_to_binary(dest: &mut [u8], src: &[u8], len: usize) {
        for i in 0..len {
            let v0 = src[(i * 2) + 0];
            let v1 = src[(i * 2) + 1];
            dest[i] = (from_hex(v0) << 4) | (from_hex(v1));
        }
    }

    pub fn send_command_wait_reply_raw(&mut self, res: &mut [u8], command: &str) -> io::Result<usize> {
        let mut temp_buffer = [0; PACKET_SIZE];
        try!(self.send_command(command));
        let len = try!(self.read_reply(&mut temp_buffer));
        try!(Self::validate_checksum(&temp_buffer, len));
        Self::clone_slice(res, &temp_buffer[1..len-3]);
        let t = String::from_utf8_lossy(&res).into_owned();
        println!("clone from slice {} - len {}", t, len-4);
        Ok((len-4))
    }

    pub fn get_supported(&mut self, res: &mut [u8]) -> io::Result<usize> {
        self.send_command_wait_reply_raw(res, "qSupported")
    }

    pub fn step_sync(&mut self, res: &mut [u8]) -> io::Result<usize> {
        self.send_command_wait_reply_raw(res, "s")
    }

    pub fn get_registers(&mut self, res: &mut [u8]) -> io::Result<usize> {
        let mut temp_buffer = [0; PACKET_SIZE];
        let len = try!(self.send_command_wait_reply_raw(&mut temp_buffer, "g"));
        let t = String::from_utf8_lossy(&temp_buffer).into_owned();
        println!("get_regs {} len {}", t, len);
        Self::convert_hex_data_to_binary(res, &temp_buffer, len);
        Ok((len / 2))
    }

    /*
    pub fn get_memory_sync(&mut self, address: u64, size: u64) -> io::Result<usize> {
        let mem_req = format!("m{:x},{:x}", address, size);

        if let Some(data) = self.send_command_sync(&mem_req) {
            let mut memory = Vec::with_capacity((data.len() - 2) / 2);
            let mut index = 1;

            for _ in 0..((data.len() - 2) / 2) {
                let v0 = data[index + 0];
                let v1 = data[index + 1];
                let v = (Self::from_hex(v0) << 4) | (Self::from_hex(v1));
                memory.push(v);
                index += 2;
            }

            Some(Memory {
                address: address as u64,
                data: memory,
            })
        } else {
            None
        }
    }
    */
}
#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::net::{TcpStream, TcpListener};
    use std::sync::{Arc, Mutex};
    use std::io::{Read, Write};
    use std::time::Duration;

    //const NOT_STARTED: u32 = 0;
    const STARTED: u32 = 1;
    const READ_DATA: u32 = 2;
    const SHOULD_QUIT: u32 = 3;
    //const REPLY_SUPPORT: u32 = 2;

    #[test]
    fn test_checksum_calc() {
        let data: [u8; 8] = [32, 32, 32, 32, 64, 64, 64, 64];
        assert_eq!(::calc_checksum(&data), 128);
    }

    #[test]
    fn test_process_string() {
        let mut dest = String::new();
        GdbRemote::build_processed_string(&mut dest, "f");
        assert_eq!(dest, "$f#66");
    }

    fn check_mutex_complete(mutex: &Arc<Mutex<u32>>) -> bool {
        let data = mutex.lock().unwrap();
        if *data != 0 { true } else { false }
    }

    fn update_mutex(mutex: &Arc<Mutex<u32>>, value: u32) {
        let mut data = mutex.lock().unwrap();
        *data = value
    }

    fn get_mutex_value(mutex: &Arc<Mutex<u32>>) -> u32 {
        *mutex.lock().unwrap()
    }

    fn wait_for_thread_init(mutex: &Arc<Mutex<u32>>) {
        loop {
            if check_mutex_complete(mutex) {
                return;
            }

            thread::sleep(Duration::from_millis(1));
        }
    }

    fn setup_listener(server_lock: &Arc<Mutex<u32>>, state: u32, port: u16) {
        let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();
        update_mutex(&server_lock, state as u32);

        loop {
            for stream in listener.incoming() {
                match stream {
                    Ok(stream) => {
                        server(stream, server_lock);
                        return;
                    }
                    _ => (),
                }
            }
        }
    }

    fn get_string_from_buf(buffer: &[u8], size: usize) -> String {
        String::from_utf8_lossy(&buffer[0..size]).into_owned()
    }

    fn server(mut stream: TcpStream, state: &Arc<Mutex<u32>>) {
        let mut buffer = [0; 1024];
        let value = get_mutex_value(state);

        if value == STARTED {
            return;
        }

        let len = stream.read(&mut buffer).unwrap();
        let data = get_string_from_buf(&buffer, len);

        println!("data {}", data);

        match data.as_ref() {
            "qSupported" => {
                let mut dest = String::new();
                GdbRemote::build_processed_string(&mut dest, "PacketSize=1fff");
                stream.write(b"+").unwrap(); // reply that we got the package
                stream.write_all(dest.as_bytes()).unwrap();
            }

            "g" => {
                let mut dest = String::new();
                GdbRemote::build_processed_string(&mut dest, "1122aa");
                stream.write(b"+").unwrap(); // reply that we got the package
                stream.write_all(dest.as_bytes()).unwrap();
            }
            _ => (),
        }

        loop {
            if get_mutex_value(state) == SHOULD_QUIT {
                break;
            }

            thread::sleep(Duration::from_millis(10));
        }
    }

    #[test]
    fn test_connect() {
        let port = 6860u16;
        let lock = Arc::new(Mutex::new(0));
        let thread_lock = lock.clone();

        thread::spawn(move || { setup_listener(&thread_lock, STARTED, port) });
        wait_for_thread_init(&lock);

        let mut gdb = GdbRemote::new();
        gdb.connect(("127.0.0.1", port)).unwrap();
    }

    #[test]
    fn test_qsupported() {
        let mut res = [0; 1024];
        let port = 6861u16;
        let lock = Arc::new(Mutex::new(0));
        let thread_lock = lock.clone();

        thread::spawn(move || { setup_listener(&thread_lock, READ_DATA, port) });
        wait_for_thread_init(&lock);

        let mut gdb = GdbRemote::new();
        gdb.connect(("127.0.0.1", port)).unwrap();
        let size = gdb.get_supported(&mut res).unwrap();

        println!("{:x}", res[0]);

        let supported = get_string_from_buf(&res, size);

        assert_eq!(supported, "PacketSize=1fff");

        update_mutex(&lock, SHOULD_QUIT);
    }

    #[test]
    fn test_registers() {
        let mut res = [0; 1024];
        let port = 6862u16;
        let lock = Arc::new(Mutex::new(0));
        let thread_lock = lock.clone();

        thread::spawn(move || { setup_listener(&thread_lock, READ_DATA, port) });
        wait_for_thread_init(&lock);

        let mut gdb = GdbRemote::new();
        gdb.connect(("127.0.0.1", port)).unwrap();
        let size = gdb.get_registers(&mut res).unwrap();

        assert_eq!(res[0], 0x11);
        assert_eq!(res[1], 0x22);
        assert_eq!(res[2], 0xaa);
        assert_eq!(size, 3);

        update_mutex(&lock, SHOULD_QUIT);
    }
}

<commit_msg>Get correct string on the server side<commit_after>use std::net::{TcpStream, ToSocketAddrs};
use std::io::{Read, Write};
use std::io;
use std::time::Duration;

pub enum NeedsAck {
    Yes,
    No,
}

#[derive(Copy, Clone, PartialEq)]
pub enum State {
    Disconnected,
    Connected,
    SendingData,
    WaitingForData,
    Close,
}

pub struct GdbRemote {
    stream: Option<TcpStream>,
    temp_string: String,
    needs_ack: NeedsAck,
}

pub struct Memory {
    pub address: u64,
    pub data: Vec<u8>
}

impl Default for GdbRemote {
    fn default() -> Self {
        Self::new()
    }
}

const PACKET_SIZE: usize = 1024;
static HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef";

#[inline]
fn calc_checksum(data: &[u8]) -> u8 {
    let mut checksum = 0u32;
    for i in data {
        checksum += *i as u32;
    }
    (checksum & 0xff) as u8
}

#[inline]
fn get_checksum(checksum: u8) -> (u8, u8) {
    (HEX_CHARS[((checksum >> 4) & 0xf) as usize],
     HEX_CHARS[(checksum & 0xf) as usize])
}

fn from_hex(ch: u8) -> u8 {
    if (ch >= b'a') && (ch <= b'f') {
        return ch - b'a' + 10;
    }

    if (ch >= b'0') && (ch <= b'9') {
        return ch - b'0';
    }

    if (ch >= b'A') && (ch <= b'F') {
        return ch - b'A' + 10;
    }

    0
}

fn from_pair_hex(data: (u8, u8)) -> u8 {
    let t0 = from_hex(data.0);
    let t1 = from_hex(data.1);
    (t0 << 4) | t1
}

impl GdbRemote {
    pub fn new() -> GdbRemote {
        GdbRemote {
            needs_ack: NeedsAck::Yes,
            temp_string: String::with_capacity(PACKET_SIZE + 4), // + 4 for header and checksum
            stream: None,
        }
    }

    pub fn connect<A: ToSocketAddrs>(&mut self, addr: A) -> io::Result<()> {
        let stream = try!(TcpStream::connect(addr));
        // 2 sec of time-out to make sure we never gets infitite blocked
        try!(stream.set_read_timeout(Some(Duration::from_secs(2))));
        self.stream = Some(stream);
        Ok(())
    }

    pub fn build_processed_string(dest: &mut String, source: &str) {
        let checksum = calc_checksum(source.as_bytes());
        let csum = get_checksum(checksum);

        dest.clear();
        dest.push('$');
        dest.push_str(source);
        dest.push('#');
        dest.push(csum.0 as char);
        dest.push(csum.1 as char);
    }

    pub fn send_internal(&mut self) -> io::Result<()> {
        if let Some(ref mut stream) = self.stream {
            stream.write_all(self.temp_string.as_bytes())
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "No connection with a server."))
        }
    }

    pub fn send_command(&mut self, data: &str) -> io::Result<()> {
        Self::build_processed_string(&mut self.temp_string, data);
        self.send_internal()
    }

    fn handle_send_ack(stream: &mut TcpStream, resend_data: &str, dest: &mut [u8]) -> io::Result<usize> {
        loop {
            let mut v = [0; 1];
            try!(stream.read(&mut v));

            match v[0] {
                b'+' => return stream.read(dest),
                b'-' => try!(stream.write_all(resend_data.as_bytes())),
                _ => {
                    return Err(io::Error::new(io::ErrorKind::Other, "Illegal reply from server."))
                }
            }
        }
    }

    pub fn read_reply(&mut self, dest: &mut [u8]) -> io::Result<usize> {
        if let Some(ref mut stream) = self.stream {
            match self.needs_ack {
                NeedsAck::Yes => Self::handle_send_ack(stream, &self.temp_string.clone(), dest),
                NeedsAck::No => stream.read(dest),
            }
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "No connection with a server."))
        }
    }

    fn clone_slice(dst: &mut [u8], src: &[u8]) {
        for (d, s) in dst.iter_mut().zip(src.iter()) {
            *d = *s;
        }
    }

    fn validate_checksum(data: &[u8], len: usize) -> io::Result<usize> {
        // - 3 to skip $xx in the end
        let data_len = len;
        let checksum = calc_checksum(&data[1..len - 3]);
        let data_check = from_pair_hex((data[data_len - 2], data[data_len - 1]));

        if data_check == checksum {
            Ok((data_len))
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "Checksum missmatch for data"))
        }
    }

    fn convert_hex_data_to_binary(dest: &mut [u8], src: &[u8], len: usize) {
        for i in 0..len {
            let v0 = src[(i * 2) + 0];
            let v1 = src[(i * 2) + 1];
            dest[i] = (from_hex(v0) << 4) | (from_hex(v1));
        }
    }

    pub fn send_command_wait_reply_raw(&mut self, res: &mut [u8], command: &str) -> io::Result<usize> {
        let mut temp_buffer = [0; PACKET_SIZE];
        try!(self.send_command(command));
        let len = try!(self.read_reply(&mut temp_buffer));
        try!(Self::validate_checksum(&temp_buffer, len));
        Self::clone_slice(res, &temp_buffer[1..len-3]);
        let t = String::from_utf8_lossy(&res).into_owned();
        println!("clone from slice {} - len {}", t, len-4);
        Ok((len-4))
    }

    pub fn get_supported(&mut self, res: &mut [u8]) -> io::Result<usize> {
        self.send_command_wait_reply_raw(res, "qSupported")
    }

    pub fn step_sync(&mut self, res: &mut [u8]) -> io::Result<usize> {
        self.send_command_wait_reply_raw(res, "s")
    }

    pub fn get_registers(&mut self, res: &mut [u8]) -> io::Result<usize> {
        let mut temp_buffer = [0; PACKET_SIZE];
        let len = try!(self.send_command_wait_reply_raw(&mut temp_buffer, "g"));
        let t = String::from_utf8_lossy(&temp_buffer).into_owned();
        println!("get_regs {} len {}", t, len);
        Self::convert_hex_data_to_binary(res, &temp_buffer, len);
        Ok((len / 2))
    }

    /*
    pub fn get_memory_sync(&mut self, address: u64, size: u64) -> io::Result<usize> {
        let mem_req = format!("m{:x},{:x}", address, size);

        if let Some(data) = self.send_command_sync(&mem_req) {
            let mut memory = Vec::with_capacity((data.len() - 2) / 2);
            let mut index = 1;

            for _ in 0..((data.len() - 2) / 2) {
                let v0 = data[index + 0];
                let v1 = data[index + 1];
                let v = (Self::from_hex(v0) << 4) | (Self::from_hex(v1));
                memory.push(v);
                index += 2;
            }

            Some(Memory {
                address: address as u64,
                data: memory,
            })
        } else {
            None
        }
    }
    */
}
#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::net::{TcpStream, TcpListener};
    use std::sync::{Arc, Mutex};
    use std::io::{Read, Write};
    use std::time::Duration;

    //const NOT_STARTED: u32 = 0;
    const STARTED: u32 = 1;
    const READ_DATA: u32 = 2;
    const SHOULD_QUIT: u32 = 3;
    //const REPLY_SUPPORT: u32 = 2;

    #[test]
    fn test_checksum_calc() {
        let data: [u8; 8] = [32, 32, 32, 32, 64, 64, 64, 64];
        assert_eq!(::calc_checksum(&data), 128);
    }

    #[test]
    fn test_process_string() {
        let mut dest = String::new();
        GdbRemote::build_processed_string(&mut dest, "f");
        assert_eq!(dest, "$f#66");
    }

    fn check_mutex_complete(mutex: &Arc<Mutex<u32>>) -> bool {
        let data = mutex.lock().unwrap();
        if *data != 0 { true } else { false }
    }

    fn update_mutex(mutex: &Arc<Mutex<u32>>, value: u32) {
        let mut data = mutex.lock().unwrap();
        *data = value
    }

    fn get_mutex_value(mutex: &Arc<Mutex<u32>>) -> u32 {
        *mutex.lock().unwrap()
    }

    fn wait_for_thread_init(mutex: &Arc<Mutex<u32>>) {
        loop {
            if check_mutex_complete(mutex) {
                return;
            }

            thread::sleep(Duration::from_millis(1));
        }
    }

    fn setup_listener(server_lock: &Arc<Mutex<u32>>, state: u32, port: u16) {
        let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();
        update_mutex(&server_lock, state as u32);

        loop {
            for stream in listener.incoming() {
                match stream {
                    Ok(stream) => {
                        server(stream, server_lock);
                        return;
                    }
                    _ => (),
                }
            }
        }
    }

    fn get_string_from_buf(buffer: &[u8], size: usize) -> String {
        String::from_utf8_lossy(&buffer[0..size]).into_owned()
    }

    fn get_string_from_buf_trim(buffer: &[u8], size: usize) -> String {
        String::from_utf8_lossy(&buffer[1..size-3]).into_owned()
    }

    fn server(mut stream: TcpStream, state: &Arc<Mutex<u32>>) {
        let mut buffer = [0; 1024];
        let value = get_mutex_value(state);

        if value == STARTED {
            return;
        }

        let len = stream.read(&mut buffer).unwrap();
        let data = get_string_from_buf_trim(&buffer, len);

        println!("data {}", data);

        match data.as_ref() {
            "qSupported" => {
                let mut dest = String::new();
                GdbRemote::build_processed_string(&mut dest, "PacketSize=1fff");
                stream.write(b"+").unwrap(); // reply that we got the package
                stream.write_all(dest.as_bytes()).unwrap();
            }

            "g" => {
                let mut dest = String::new();
                GdbRemote::build_processed_string(&mut dest, "1122aa");
                stream.write(b"+").unwrap(); // reply that we got the package
                stream.write_all(dest.as_bytes()).unwrap();
            }
            _ => (),
        }

        loop {
            if get_mutex_value(state) == SHOULD_QUIT {
                break;
            }

            thread::sleep(Duration::from_millis(10));
        }
    }

    #[test]
    fn test_connect() {
        let port = 6860u16;
        let lock = Arc::new(Mutex::new(0));
        let thread_lock = lock.clone();

        thread::spawn(move || { setup_listener(&thread_lock, STARTED, port) });
        wait_for_thread_init(&lock);

        let mut gdb = GdbRemote::new();
        gdb.connect(("127.0.0.1", port)).unwrap();
    }

    #[test]
    fn test_qsupported() {
        let mut res = [0; 1024];
        let port = 6861u16;
        let lock = Arc::new(Mutex::new(0));
        let thread_lock = lock.clone();

        thread::spawn(move || { setup_listener(&thread_lock, READ_DATA, port) });
        wait_for_thread_init(&lock);

        let mut gdb = GdbRemote::new();
        gdb.connect(("127.0.0.1", port)).unwrap();
        let size = gdb.get_supported(&mut res).unwrap();

        println!("{:x}", res[0]);

        let supported = get_string_from_buf(&res, size);

        assert_eq!(supported, "PacketSize=1fff");

        update_mutex(&lock, SHOULD_QUIT);
    }

    #[test]
    fn test_registers() {
        let mut res = [0; 1024];
        let port = 6862u16;
        let lock = Arc::new(Mutex::new(0));
        let thread_lock = lock.clone();

        thread::spawn(move || { setup_listener(&thread_lock, READ_DATA, port) });
        wait_for_thread_init(&lock);

        let mut gdb = GdbRemote::new();
        gdb.connect(("127.0.0.1", port)).unwrap();
        let size = gdb.get_registers(&mut res).unwrap();

        assert_eq!(res[0], 0x11);
        assert_eq!(res[1], 0x22);
        assert_eq!(res[2], 0xaa);
        assert_eq!(size, 3);

        update_mutex(&lock, SHOULD_QUIT);
    }
}

<|endoftext|>


<commit_before>extern crate nock;
extern crate urbit;
extern crate num;

use std::env;
use std::io::prelude::*;
use std::fs::File;
use num::bigint::BigUint;
use num::traits::One;
use nock::{Nock, Noun, Shape};
use urbit::VM;

fn get_size(noun: &Noun) -> BigUint {
    noun.fold(|x| {
        match x {
            Shape::Cell(p, q) => p + q,
            _ => One::one(),
        }
    })
}

fn main() {
    let mut file = File::open(env::args()
                                  .nth(1)
                                  .expect("Usage urbit [urbit.pill]"))
                       .unwrap();

    let mut buf = Vec::new();
    file.read_to_end(&mut buf).unwrap();
    println!("Unpacking pill");
    let pill = urbit::unpack_pill(buf).unwrap();

    // You can't nock the whole pill as an
    let (kernel, arvo) = match pill.get() {
        Shape::Cell(kernel, arvo) => ((*kernel).clone(), (*arvo).clone()),
        _ => panic!("bad"),
    };
    println!("Unpacked pill");

    println!("Kernel has {} atoms", get_size(&kernel));
    println!("Arvo has {} atoms", get_size(&arvo));

    let mut vm = VM::new();

    println!("Nocking kernel");
    let noun = vm.nock_on(Noun::from(0u32), kernel).unwrap();
    vm.print_status();
    println!("Kernel nocked, subject has {} atoms", get_size(&noun));
    println!("{}", noun);

    // FIXME: This isn't the right way to boot...
    println!("Nocking arvo");
    let noun = vm.nock_on(Noun::from(0u32), arvo).unwrap();
    vm.print_status();
    println!("Arvo nocked, subject has {} atoms", get_size(&noun));
    println!("{}", noun);
}
<commit_msg>Don't crash the example with the TODO stuff<commit_after>extern crate nock;
extern crate urbit;
extern crate num;

use std::env;
use std::io::prelude::*;
use std::fs::File;
use num::bigint::BigUint;
use num::traits::One;
use nock::{Nock, Noun, Shape};
use urbit::VM;

fn get_size(noun: &Noun) -> BigUint {
    noun.fold(|x| {
        match x {
            Shape::Cell(p, q) => p + q,
            _ => One::one(),
        }
    })
}

fn main() {
    let mut file = File::open(env::args()
                                  .nth(1)
                                  .expect("Usage urbit [urbit.pill]"))
                       .unwrap();

    let mut buf = Vec::new();
    file.read_to_end(&mut buf).unwrap();
    println!("Unpacking pill");
    let pill = urbit::unpack_pill(buf).unwrap();

    // You can't nock the whole pill as an
    let (kernel, arvo) = match pill.get() {
        Shape::Cell(kernel, arvo) => ((*kernel).clone(), (*arvo).clone()),
        _ => panic!("bad"),
    };
    println!("Unpacked pill");

    println!("Kernel has {} atoms", get_size(&kernel));
    println!("Arvo has {} atoms", get_size(&arvo));

    let mut vm = VM::new();

    println!("Nocking kernel");
    let noun = vm.nock_on(Noun::from(0u32), kernel).unwrap();
    vm.print_status();
    println!("Kernel nocked, subject has {} atoms", get_size(&noun));
    println!("{}", noun);

    println!("TODO: Boot arvo");
    // FIXME: This isn't the right way to boot...
    // println!("Nocking arvo");
    // let noun = vm.nock_on(Noun::from(0u32), arvo).unwrap();
    // vm.print_status();
    // println!("Arvo nocked, subject has {} atoms", get_size(&noun));
    // println!("{}", noun);
}
<|endoftext|>


<commit_before>mod recommendation {
    use std::collections::HashMap;
    use std::collections::HashSet;
    use std::hash::{Hash, Hasher};
    use std::iter::FromIterator;

    #[derive(Debug,Default,Clone)]
    pub struct ItemSet {
        items: HashSet<u64>,
        support: f64,
        count: u64
    }

    impl Hash for ItemSet {
        fn hash<H: Hasher>(&self, state: &mut H) {
            for i in self.items.iter() {
                state.write_u64(*i);
            }
        }
    }
    impl PartialEq for ItemSet {
        fn eq(&self, other: &ItemSet) -> bool {
            self.items == other.items
        }
    }
    impl Eq for ItemSet {}

    fn first_pass(sets: &Vec<Vec<u64>>, min_support: f64) -> (HashSet<ItemSet>, u64) {
        let mut sets_count = 0;
        let large = sets.iter()
            .inspect(|_| sets_count += 1)
            .flat_map(|x| x.iter())
            .fold(HashMap::new(), |mut acc, x| {
                *acc.entry(x).or_insert(0) += 1;
                acc
            })
            .iter()
            .filter(|&(_, &v)| v as f64 / sets_count as f64 > min_support)
            .fold(HashSet::new(), |mut acc, (&k, &v)| {
                acc.insert(
                    ItemSet {
                        items: vec!(*k).into_iter().collect::<HashSet<u64>>(),
                        support: v as f64 / sets_count as f64,
                        count: v,
                        ..Default::default()
                    }
                );

                acc
            }
        );

        (large, sets_count)
    }

    fn generate_subsets(large: HashSet<ItemSet>) -> HashSet<ItemSet> {
        large.iter().fold(HashSet::new(), |mut acc, rit| {
            for lit in large.iter() {
                for i1 in rit.items.difference(&lit.items).cloned() {
                    let mut candidate = lit.items.clone();

                    candidate.insert(i1);
                    acc.insert(ItemSet{items: candidate, ..Default::default()});
                }
            }

            acc
        })
    }

    pub fn apriori(sets: Vec<Vec<u64>>, min_support: f64) -> HashSet<ItemSet> {
        let (mut large, sets_count) = first_pass(&sets, min_support);
        let mut output = HashSet::<ItemSet>::new();

        while !large.is_empty() {
            let mut candidates = generate_subsets(large);

            for set in sets.iter() {
                let hash_set = HashSet::from_iter(set.iter().cloned());

                candidates = candidates.into_iter()
                    .map(|mut x| {
                        if x.items.is_subset(&hash_set) {
                            x.count +=1;
                            x.support = x.count as f64 / sets_count as f64;
                        }

                        x
                    }).collect();
            }

            large = HashSet::from_iter(candidates.iter().cloned().filter(|x| x.support > min_support));

            output.extend(large.clone());
        }

        output
    }

#[cfg(test)]
    mod tests {
        use super::*;

        #[test]
        fn it_works() {
            let sets = vec![
                vec![1,2,3,4],
                vec![1,2,4],
                vec![1,2],
                vec![2,3,4],
                vec![2,3],
                vec![3,4],
                vec![2,4]
            ];

            let output = apriori(sets, 0.42);
            println!("Output: {:?}", output);
        }
    }
}
<commit_msg>Assertions in the test<commit_after>mod recommendation {
    use std::collections::HashMap;
    use std::collections::HashSet;
    use std::hash::{Hash, Hasher};
    use std::iter::FromIterator;

    #[derive(Debug,Default,Clone)]
    pub struct ItemSet {
        pub items: HashSet<u64>,
        pub support: f64,
        pub count: u64
    }

    impl Hash for ItemSet {
        fn hash<H: Hasher>(&self, state: &mut H) {
            for i in self.items.iter() {
                state.write_u64(*i);
            }
        }
    }
    impl PartialEq for ItemSet {
        fn eq(&self, other: &ItemSet) -> bool {
            self.items == other.items
        }
    }
    impl Eq for ItemSet {}

    fn first_pass(sets: &Vec<Vec<u64>>, min_support: f64) -> (HashSet<ItemSet>, u64) {
        let mut sets_count = 0;
        let large = sets.iter()
            .inspect(|_| sets_count += 1)
            .flat_map(|x| x.iter())
            .fold(HashMap::new(), |mut acc, x| {
                *acc.entry(x).or_insert(0) += 1;
                acc
            })
            .iter()
            .filter(|&(_, &v)| v as f64 / sets_count as f64 > min_support)
            .fold(HashSet::new(), |mut acc, (&k, &v)| {
                acc.insert(
                    ItemSet {
                        items: vec!(*k).into_iter().collect::<HashSet<u64>>(),
                        support: v as f64 / sets_count as f64,
                        count: v,
                        ..Default::default()
                    }
                );

                acc
            }
        );

        (large, sets_count)
    }

    fn generate_subsets(large: HashSet<ItemSet>) -> HashSet<ItemSet> {
        large.iter().fold(HashSet::new(), |mut acc, rit| {
            for lit in large.iter() {
                for i1 in rit.items.difference(&lit.items).cloned() {
                    let mut candidate = lit.items.clone();

                    candidate.insert(i1);
                    acc.insert(ItemSet{items: candidate, ..Default::default()});
                }
            }

            acc
        })
    }

    pub fn apriori(sets: Vec<Vec<u64>>, min_support: f64) -> HashSet<ItemSet> {
        let (mut large, sets_count) = first_pass(&sets, min_support);
        let mut output = HashSet::<ItemSet>::new();

        while !large.is_empty() {
            let mut candidates = generate_subsets(large);

            for set in sets.iter() {
                let hash_set = HashSet::from_iter(set.iter().cloned());

                candidates = candidates.into_iter()
                    .map(|mut x| {
                        if x.items.is_subset(&hash_set) {
                            x.count +=1;
                            x.support = x.count as f64 / sets_count as f64;
                        }

                        x
                    }).collect();
            }

            large = HashSet::from_iter(candidates.iter().cloned().filter(|x| x.support > min_support));

            output.extend(large.clone());
        }

        output
    }
}
#[cfg(test)]

mod tests {
    use recommendation::*;

    #[test]
    fn it_works() {
        let sets = vec![
            vec![1,2,3,4],
            vec![1,2,4],
            vec![1,2],
            vec![2,3,4],
            vec![2,3],
            vec![3,4],
            vec![2,4]
        ];

        let output = apriori(sets, 0.42);
        assert!(output.len() == 4);

        let set1output = output.get(&ItemSet {items: vec!(4,2).into_iter().collect(), ..Default::default()});
        let set2output = output.get(&ItemSet {items: vec!(3,2).into_iter().collect(), ..Default::default()});
        let set3output = output.get(&ItemSet {items: vec!(1,2).into_iter().collect(), ..Default::default()});
        let set4output = output.get(&ItemSet {items: vec!(3,4).into_iter().collect(), ..Default::default()});

        assert!(set1output.is_some());
        assert!(set2output.is_some());
        assert!(set3output.is_some());
        assert!(set4output.is_some());

        println!("Output: {:?}", output);
    }
}
<|endoftext|>


<commit_before>extern crate hyper;

mod contentlength;
pub mod http_version;

/// Represents a byte, in `u64`.
type Byte = u64;
<commit_msg>Add new mod in lib.rs to run unit tests<commit_after>extern crate hyper;

mod contentlength;
pub mod http_version;
pub mod download;

/// Represents a byte, in `u64`.
type Byte = u64;
<|endoftext|>