<commit_before>//! The `Client` allows users of the `raft` library to connect to remote `Server` instances and
//! issue commands to be applied to the `StateMachine`.

use std::collections::HashSet;
use std::fmt;
use std::io::Write;
use std::net::SocketAddr;
use std::net::TcpStream;
use std::str::FromStr;

use bufstream::BufStream;
use capnp::{serialize, MessageReader, ReaderOptions, MallocMessageBuilder};

use messages_capnp::{client_response, command_response};
use messages;
use ClientId;
use Result;
use RaftError;

/// The representation of a Client connection to the cluster.
pub struct Client {
    /// The `Uuid` of the client, should be unique in the cluster.
    pub id: ClientId,
    /// The current connection to the current leader.
    /// If it is `None`, there may be no established leader, or a connection
    /// issue.
    leader_connection: Option<BufStream<TcpStream>>,
    /// A lookup for the cluster's nodes.
    cluster: HashSet<SocketAddr>,
}

impl Client {

    /// Creates a new client.
    pub fn new(cluster: HashSet<SocketAddr>) -> Client {
        Client {
            id: ClientId::new(),
            leader_connection: None,
            cluster: cluster,
        }
    }

    /// Proposes an entry to be appended to the replicated log. This will only
    /// return once the entry has been durably committed.
    /// Returns `Error` when the entire cluster has an unknown leader. Try proposing again later.
    pub fn propose(&mut self, entry: &[u8]) -> Result<Vec<u8>> {
        scoped_trace!("{:?}: propose", self);
        let mut message = messages::proposal_request(entry);
        self.send_message(&mut message)
    }

    /// Queries an entry from the state machine. This is non-mutating and doesn't go through the
    /// durable log. Like `.propose()` this will only communicate with the leader of the cluster.
    pub fn query(&mut self, query: &[u8]) -> Result<Vec<u8>> {
        scoped_trace!("{:?}: query", self);
        let mut message = messages::query_request(query);
        self.send_message(&mut message)
    }

    fn send_message(&mut self, message: &mut MallocMessageBuilder) -> Result<Vec<u8>> {
        let mut members = self.cluster.iter().cloned();

        loop {
            let mut connection = match self.leader_connection.take() {
                Some(cxn) => {
                    scoped_debug!("had existing connection {:?}", cxn.get_ref().peer_addr());
                    cxn
                },
                None => {
                    let leader = try!(members.next().ok_or(RaftError::LeaderSearchExhausted));
                    scoped_debug!("connecting to potential leader {}", leader);
                    // Send the preamble.
                    let preamble = messages::client_connection_preamble(self.id);
                    let mut stream = BufStream::new(try!(TcpStream::connect(leader)));
                    scoped_debug!("connected");
                    try!(serialize::write_message(&mut stream, &*preamble));
                    stream
                }
            };
            try!(serialize::write_message(&mut connection, message));
            try!(connection.flush());
            scoped_debug!("awaiting response from connection");
            let response = try!(serialize::read_message(&mut connection, ReaderOptions::new()));
            match try!(response.get_root::<client_response::Reader>()).which().unwrap() {
                client_response::Which::Proposal(Ok(response)) => {
                    match response.which().unwrap() {
                        command_response::Which::Success(data) => {
                            scoped_debug!("received response Success");
                            self.leader_connection = Some(connection);
                            return data
                                .map(|v| Vec::from(v))
                                .map_err(|e| e.into()) // Exit the function.
                        },
                        command_response::Which::UnknownLeader(()) => {
                            scoped_debug!("received response UnknownLeader");
                            () // Keep looping.
                        },
                        command_response::Which::NotLeader(leader) => {
                            scoped_debug!("received response NotLeader");
                            let leader_str = try!(leader);
                            if !self.cluster.contains(&try!(SocketAddr::from_str(leader_str))) {
                                scoped_debug!("cluster violation detected");
                                return Err(RaftError::ClusterViolation.into()) // Exit the function.
                            }
                            let mut connection: TcpStream = try!(TcpStream::connect(leader_str));
                            let preamble = messages::client_connection_preamble(self.id);
                            try!(serialize::write_message(&mut connection, &*preamble));
                            self.leader_connection = Some(BufStream::new(connection));
                        }
                    }
                },
                _ => panic!("Unexpected message type"), // TODO: return a proper error
            }
        }
    }
}

impl fmt::Debug for Client {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "Client({})", self.id)
    }
}

#[cfg(test)]
mod tests {
    extern crate env_logger;

    use std::collections::HashSet;
    use std::io::Write;
    use std::net::{TcpStream, TcpListener};
    use std::thread;

    use uuid::Uuid;
    use capnp::{serialize, ReaderOptions};
    use capnp::message::MessageReader;
    use bufstream::BufStream;

    use {Client, messages, Result};
    use messages_capnp::{connection_preamble, client_request};

    fn expect_preamble(connection: &mut TcpStream, client_id: Uuid) -> Result<bool> {
        let message = try!(serialize::read_message(connection, ReaderOptions::new()));
        let preamble = try!(message.get_root::<connection_preamble::Reader>());
        // Test to make sure preamble has the right id.
        if let connection_preamble::id::Which::Client(Ok(id)) = try!(preamble.get_id().which()) {
            Ok(Uuid::from_bytes(id).unwrap() == client_id)
        } else {
            Ok(false)
        }
    }

    fn expect_proposal(connection: &mut TcpStream, value: &[u8]) -> Result<bool> {
        let message = try!(serialize::read_message(connection, ReaderOptions::new()));
        let request = try!(message.get_root::<client_request::Reader>());
        // Test to make sure request has the right value.
        if let client_request::Which::Proposal(Ok(proposal)) = try!(request.which()) {
            Ok(proposal.get_entry().unwrap() == value)
        } else {
            Ok(false)
        }
    }

    #[test]
    fn test_proposal_success() {
        setup_test!("test_proposal_success");
        // Start up the cluster and get what we need.
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let mut client = Client::new(cluster);
        let client_id = client.id.0.clone();
        let to_propose = b"Bears";

        // The client connects on the proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            let (mut connection, _)  = test_server.accept().unwrap();

            // Proposal should be fine, no errors.
            scoped_debug!("Should get preamble and proposal. Responds Success");
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();
            // Send response! (success!)
            let response = messages::command_response_success(b"Foxes");
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();
        });

        // Propose. It's a marriage made in heaven! :)
        // Should be ok
        assert_eq!(client.propose(to_propose).unwrap(), b"Foxes");
        assert!(client.leader_connection.is_some());

        child.join().unwrap();
    }

    #[test]
    fn test_proposal_unknown_leader() {
        setup_test!("test_proposal_unknown_leader");
        // Start up the cluster and get what we need.
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let mut client = Client::new(cluster);
        let to_propose = b"Bears";

        // The client connects on the proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            let (mut connection, _)  = test_server.accept().unwrap();

            // Proposal should report unknown leader, and have the client return error.
            scoped_debug!("Should get proposal. Responds UnknownLeader");
            expect_proposal(&mut connection, to_propose).unwrap();
            // Send response! (unknown leader!) Client should drop connection.
            let response = messages::command_response_unknown_leader();
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();
        });

        // Propose. It's a marriage made in heaven! :)
        assert!(client.propose(to_propose).is_err());

        child.join().unwrap();
    }

    #[test]
    fn test_proposal_not_leader() {
        setup_test!("test_proposal_not_leader");
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let second_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let second_addr = second_server.local_addr().unwrap();
        cluster.insert(second_addr);

        let mut client = Client::new(cluster);
        let client_id = client.id.0.clone();
        let to_propose = b"Bears";

        // The client connects on the first proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            // Proposal should report NotLeader. Client should choose the server we direct it to.
            scoped_debug!("Should get preamble and proposal. Responds NotLeader.");
            let (mut connection, _)  = test_server.accept().unwrap();
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();

            // Send response! (not leader!)
            let response = messages::command_response_not_leader(&second_addr);
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();

            // Test that it seeks out other server and proposes.
            scoped_debug!("Second server should get preamble and proposal. Responds Success.");
            let (mut connection, _)  = second_server.accept().unwrap();
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();

            // Send final response! (Success!)
            let response = messages::command_response_success(b"Foxes");
            serialize::write_message(&mut connection, &*response).unwrap();
        });

        // Workaround to set up rigged selection of servers.
        client.leader_connection = {
            let preamble = messages::client_connection_preamble(client.id);
            let mut stream = BufStream::new(TcpStream::connect(test_addr).unwrap());
            serialize::write_message(&mut stream, &*preamble).unwrap();
            Some(stream)
        };

        // Should be ok, change leader connection.
        assert_eq!(client.propose(to_propose).unwrap(), b"Foxes");
        assert!(client.leader_connection.is_some());

        child.join().unwrap();
    }

    /// This test makes sure that the client cannot be redirected to a leader which exists outside
    /// the cluster. This is a necessary test since it would introduce error into the cluster.
    #[test]
    fn test_proposal_leader_not_in_cluster() {
        setup_test!("test_proposal_leader_not_in_cluster");
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let second_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let second_addr = second_server.local_addr().unwrap();
        // cluster.insert(second_addr); <--- NOT in cluster.

        let mut client = Client::new(cluster);
        let client_id = client.id.0.clone();
        let to_propose = b"Bears";

        // The client connects on the first proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            // Proposal should report NotLeader. Client should choose the server we direct it to.
            scoped_debug!("Should get preamble and proposal. Responds NotLeader.");
            let (mut connection, _)  = test_server.accept().unwrap();
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();

            // Send response! (not leader!)
            let response = messages::command_response_not_leader(&second_addr);
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();

            // No more...
        });

        // Workaround to set up rigged selection of servers.
        client.leader_connection = {
            let preamble = messages::client_connection_preamble(client.id);
            let mut stream = BufStream::new(TcpStream::connect(test_addr).unwrap());
            serialize::write_message(&mut stream, &*preamble).unwrap();
            Some(stream)
        };

        // Should be err, change leader connectio but to wrong ip..
        assert!(client.propose(to_propose).is_err());
        assert!(client.leader_connection.is_none());

        child.join().unwrap();
    }
}
<commit_msg>Improves client connection happening.<commit_after>//! The `Client` allows users of the `raft` library to connect to remote `Server` instances and
//! issue commands to be applied to the `StateMachine`.

use std::collections::HashSet;
use std::fmt;
use std::io::Write;
use std::net::SocketAddr;
use std::net::TcpStream;
use std::str::FromStr;

use bufstream::BufStream;
use capnp::{serialize, MessageReader, ReaderOptions, MallocMessageBuilder};

use messages_capnp::{client_response, command_response};
use messages;
use ClientId;
use Result;
use RaftError;

/// The representation of a Client connection to the cluster.
pub struct Client {
    /// The `Uuid` of the client, should be unique in the cluster.
    pub id: ClientId,
    /// The current connection to the current leader.
    /// If it is `None`, there may be no established leader, or a connection
    /// issue.
    leader_connection: Option<BufStream<TcpStream>>,
    /// A lookup for the cluster's nodes.
    cluster: HashSet<SocketAddr>,
}

impl Client {

    /// Creates a new client.
    pub fn new(cluster: HashSet<SocketAddr>) -> Client {
        Client {
            id: ClientId::new(),
            leader_connection: None,
            cluster: cluster,
        }
    }

    /// Proposes an entry to be appended to the replicated log. This will only
    /// return once the entry has been durably committed.
    /// Returns `Error` when the entire cluster has an unknown leader. Try proposing again later.
    pub fn propose(&mut self, entry: &[u8]) -> Result<Vec<u8>> {
        scoped_trace!("{:?}: propose", self);
        let mut message = messages::proposal_request(entry);
        self.send_message(&mut message)
    }

    /// Queries an entry from the state machine. This is non-mutating and doesn't go through the
    /// durable log. Like `.propose()` this will only communicate with the leader of the cluster.
    pub fn query(&mut self, query: &[u8]) -> Result<Vec<u8>> {
        scoped_trace!("{:?}: query", self);
        let mut message = messages::query_request(query);
        self.send_message(&mut message)
    }

    fn send_message(&mut self, message: &mut MallocMessageBuilder) -> Result<Vec<u8>> {
        let mut members = self.cluster.iter().cloned();

        loop {
            // We presume in this loop that most errors are temporary and it may take a redirect
            // (or more!) to find a leader in bad network conditions.
            // TODO: Have timouts.
            let mut connection = match self.leader_connection.take() {
                Some(cxn) => {
                    scoped_debug!("had existing connection {:?}", cxn.get_ref().peer_addr());
                    cxn
                },
                None => {
                    let leader = try!(members.next().ok_or(RaftError::LeaderSearchExhausted));
                    scoped_debug!("connecting to potential leader {}", leader);
                    // Send the preamble.
                    let preamble = messages::client_connection_preamble(self.id);
                    let mut stream = match TcpStream::connect(leader) {
                        Ok(stream) => BufStream::new(stream),
                        Err(_) => continue,
                    };
                    scoped_debug!("connected");
                    if let Err(_) = serialize::write_message(&mut stream, &*preamble) { continue };
                    stream
                }
            };
            if let Err(_) = serialize::write_message(&mut connection, message) { continue };
            if let Err(_) = connection.flush() { continue };
            scoped_debug!("awaiting response from connection");
            let response = match serialize::read_message(&mut connection, ReaderOptions::new()) {
                Ok(res) => res,
                Err(_) => continue,
            };
            let reader = match response.get_root::<client_response::Reader>() {
                Ok(reader) => reader,
                Err(_) => continue,
            };
            match reader.which() {
                Ok(client_response::Which::Proposal(Ok(status))) => {
                    match status.which() {
                        Ok(command_response::Which::Success(data)) => {
                            scoped_debug!("received response Success");
                            self.leader_connection = Some(connection);
                            return data
                                .map(|v| Vec::from(v))
                                .map_err(|e| e.into()) // Exit the function.
                        },
                        Ok(command_response::Which::UnknownLeader(())) => {
                            scoped_debug!("received response UnknownLeader");
                            () // Keep looping.
                        },
                        Ok(command_response::Which::NotLeader(leader)) => {
                            scoped_debug!("received response NotLeader");
                            let leader_str = try!(leader);
                            if !self.cluster.contains(&try!(SocketAddr::from_str(leader_str))) {
                                scoped_debug!("cluster violation detected");
                                return Err(RaftError::ClusterViolation.into()) // Exit the function.
                            }
                            let mut connection: TcpStream = try!(TcpStream::connect(leader_str));
                            let preamble = messages::client_connection_preamble(self.id);
                            if let Err(_) = serialize::write_message(&mut connection, &*preamble) {
                                continue
                            };
                            self.leader_connection = Some(BufStream::new(connection));
                        },
                        Err(_) => continue,
                    }
                },
                _ => panic!("Unexpected message type"), // TODO: return a proper error
            };
        }
    }
}

impl fmt::Debug for Client {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "Client({})", self.id)
    }
}

#[cfg(test)]
mod tests {
    extern crate env_logger;

    use std::collections::HashSet;
    use std::io::Write;
    use std::net::{TcpStream, TcpListener};
    use std::thread;

    use uuid::Uuid;
    use capnp::{serialize, ReaderOptions};
    use capnp::message::MessageReader;
    use bufstream::BufStream;

    use {Client, messages, Result};
    use messages_capnp::{connection_preamble, client_request};

    fn expect_preamble(connection: &mut TcpStream, client_id: Uuid) -> Result<bool> {
        let message = try!(serialize::read_message(connection, ReaderOptions::new()));
        let preamble = try!(message.get_root::<connection_preamble::Reader>());
        // Test to make sure preamble has the right id.
        if let connection_preamble::id::Which::Client(Ok(id)) = try!(preamble.get_id().which()) {
            Ok(Uuid::from_bytes(id).unwrap() == client_id)
        } else {
            Ok(false)
        }
    }

    fn expect_proposal(connection: &mut TcpStream, value: &[u8]) -> Result<bool> {
        let message = try!(serialize::read_message(connection, ReaderOptions::new()));
        let request = try!(message.get_root::<client_request::Reader>());
        // Test to make sure request has the right value.
        if let client_request::Which::Proposal(Ok(proposal)) = try!(request.which()) {
            Ok(proposal.get_entry().unwrap() == value)
        } else {
            Ok(false)
        }
    }

    #[test]
    fn test_proposal_success() {
        setup_test!("test_proposal_success");
        // Start up the cluster and get what we need.
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let mut client = Client::new(cluster);
        let client_id = client.id.0.clone();
        let to_propose = b"Bears";

        // The client connects on the proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            let (mut connection, _)  = test_server.accept().unwrap();

            // Proposal should be fine, no errors.
            scoped_debug!("Should get preamble and proposal. Responds Success");
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();
            // Send response! (success!)
            let response = messages::command_response_success(b"Foxes");
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();
        });

        // Propose. It's a marriage made in heaven! :)
        // Should be ok
        assert_eq!(client.propose(to_propose).unwrap(), b"Foxes");
        assert!(client.leader_connection.is_some());

        child.join().unwrap();
    }

    #[test]
    fn test_proposal_unknown_leader() {
        setup_test!("test_proposal_unknown_leader");
        // Start up the cluster and get what we need.
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let mut client = Client::new(cluster);
        let to_propose = b"Bears";

        // The client connects on the proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            let (mut connection, _)  = test_server.accept().unwrap();

            // Proposal should report unknown leader, and have the client return error.
            scoped_debug!("Should get proposal. Responds UnknownLeader");
            expect_proposal(&mut connection, to_propose).unwrap();
            // Send response! (unknown leader!) Client should drop connection.
            let response = messages::command_response_unknown_leader();
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();
        });

        // Propose. It's a marriage made in heaven! :)
        assert!(client.propose(to_propose).is_err());

        child.join().unwrap();
    }

    #[test]
    fn test_proposal_not_leader() {
        setup_test!("test_proposal_not_leader");
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let second_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let second_addr = second_server.local_addr().unwrap();
        cluster.insert(second_addr);

        let mut client = Client::new(cluster);
        let client_id = client.id.0.clone();
        let to_propose = b"Bears";

        // The client connects on the first proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            // Proposal should report NotLeader. Client should choose the server we direct it to.
            scoped_debug!("Should get preamble and proposal. Responds NotLeader.");
            let (mut connection, _)  = test_server.accept().unwrap();
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();

            // Send response! (not leader!)
            let response = messages::command_response_not_leader(&second_addr);
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();

            // Test that it seeks out other server and proposes.
            scoped_debug!("Second server should get preamble and proposal. Responds Success.");
            let (mut connection, _)  = second_server.accept().unwrap();
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();

            // Send final response! (Success!)
            let response = messages::command_response_success(b"Foxes");
            serialize::write_message(&mut connection, &*response).unwrap();
        });

        // Workaround to set up rigged selection of servers.
        client.leader_connection = {
            let preamble = messages::client_connection_preamble(client.id);
            let mut stream = BufStream::new(TcpStream::connect(test_addr).unwrap());
            serialize::write_message(&mut stream, &*preamble).unwrap();
            Some(stream)
        };

        // Should be ok, change leader connection.
        assert_eq!(client.propose(to_propose).unwrap(), b"Foxes");
        assert!(client.leader_connection.is_some());

        child.join().unwrap();
    }

    /// This test makes sure that the client cannot be redirected to a leader which exists outside
    /// the cluster. This is a necessary test since it would introduce error into the cluster.
    #[test]
    fn test_proposal_leader_not_in_cluster() {
        setup_test!("test_proposal_leader_not_in_cluster");
        let mut cluster = HashSet::new();
        let test_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let test_addr = test_server.local_addr().unwrap();
        cluster.insert(test_addr);

        let second_server = TcpListener::bind("127.0.0.1:0").unwrap();
        let second_addr = second_server.local_addr().unwrap();
        // cluster.insert(second_addr); <--- NOT in cluster.

        let mut client = Client::new(cluster);
        let client_id = client.id.0.clone();
        let to_propose = b"Bears";

        // The client connects on the first proposal.
        // Wait for it.
        let child = thread::spawn(move || {
            // Proposal should report NotLeader. Client should choose the server we direct it to.
            scoped_debug!("Should get preamble and proposal. Responds NotLeader.");
            let (mut connection, _)  = test_server.accept().unwrap();
            expect_preamble(&mut connection, client_id).unwrap();
            expect_proposal(&mut connection, to_propose).unwrap();

            // Send response! (not leader!)
            let response = messages::command_response_not_leader(&second_addr);
            serialize::write_message(&mut connection, &*response).unwrap();
            connection.flush().unwrap();

            // No more...
        });

        // Workaround to set up rigged selection of servers.
        client.leader_connection = {
            let preamble = messages::client_connection_preamble(client.id);
            let mut stream = BufStream::new(TcpStream::connect(test_addr).unwrap());
            serialize::write_message(&mut stream, &*preamble).unwrap();
            Some(stream)
        };

        // Should be err, change leader connectio but to wrong ip..
        assert!(client.propose(to_propose).is_err());
        assert!(client.leader_connection.is_none());

        child.join().unwrap();
    }
}
<|endoftext|>


<commit_before>use hyper::{Client, Url};
use hyper::client::RequestBuilder;
use hyper::header::{Authorization, UserAgent};
use hyper::method::Method;

use std::sync::Arc;
use std::clone;

pub use hyper::client::Body;

/// Internal HttpClient to build requests: wraps `hyper` client
pub struct HttpClient{
    pub base_url: String,
    api_key: String,
    hyper_client: Arc<Client>,
    user_agent: String,
}

impl HttpClient {
    /// Instantiate an HttpClient - creates a new `hyper` client
    pub fn new(api_key: String, base_url: String) -> HttpClient {
        HttpClient {
            api_key: api_key,
            base_url: base_url,
            hyper_client: Arc::new(Client::new()),
            user_agent: format!("algorithmia-rust/{} (Rust {}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"), option_env!("CFG_RELEASE").unwrap_or("unknown")),
        }
    }

    /// Helper to make Algorithmia GET requests with the API key
    pub fn get(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Get, url)
    }

    /// Helper to make Algorithmia GET requests with the API key
    pub fn head(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Head, url)
    }

    /// Helper to make Algorithmia POST requests with the API key
    pub fn post(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Post, url)
    }

    /// Helper to make Algorithmia PUT requests with the API key
    pub fn put(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Put, url)
    }

    /// Helper to make Algorithmia POST requests with the API key
    pub fn delete(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Delete, url)
    }

    fn build_request(&self, verb: Method, url: Url) -> RequestBuilder<Url> {
        let req = self.hyper_client.request(verb, url);

        // TODO: Support Secure Auth
        req.header(UserAgent(self.user_agent.clone()))
           .header(Authorization(format!("Simple {}", self.api_key)))
    }
}

/// Allow cloning in order to reuse http client (and API key) for multiple connections
impl clone::Clone for HttpClient {
    fn clone(&self) -> HttpClient {
        HttpClient {
            api_key: self.api_key.clone(),
            base_url: self.base_url.clone(),
            hyper_client: self.hyper_client.clone(),
            user_agent: self.user_agent.clone(),
        }
    }
}

<commit_msg>Reexport hyper's Response struct<commit_after>pub use hyper::client::response::Response;
use hyper::{Client, Url};
use hyper::client::RequestBuilder;
use hyper::header::{Authorization, UserAgent};
use hyper::method::Method;

use std::sync::Arc;
use std::clone;

pub use hyper::client::Body;

/// Internal HttpClient to build requests: wraps `hyper` client
pub struct HttpClient{
    pub base_url: String,
    api_key: String,
    hyper_client: Arc<Client>,
    user_agent: String,
}

impl HttpClient {
    /// Instantiate an HttpClient - creates a new `hyper` client
    pub fn new(api_key: String, base_url: String) -> HttpClient {
        HttpClient {
            api_key: api_key,
            base_url: base_url,
            hyper_client: Arc::new(Client::new()),
            user_agent: format!("algorithmia-rust/{} (Rust {}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"), option_env!("CFG_RELEASE").unwrap_or("unknown")),
        }
    }

    /// Helper to make Algorithmia GET requests with the API key
    pub fn get(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Get, url)
    }

    /// Helper to make Algorithmia GET requests with the API key
    pub fn head(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Head, url)
    }

    /// Helper to make Algorithmia POST requests with the API key
    pub fn post(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Post, url)
    }

    /// Helper to make Algorithmia PUT requests with the API key
    pub fn put(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Put, url)
    }

    /// Helper to make Algorithmia POST requests with the API key
    pub fn delete(&self, url: Url) -> RequestBuilder<Url> {
        self.build_request(Method::Delete, url)
    }

    fn build_request(&self, verb: Method, url: Url) -> RequestBuilder<Url> {
        let req = self.hyper_client.request(verb, url);

        // TODO: Support Secure Auth
        req.header(UserAgent(self.user_agent.clone()))
           .header(Authorization(format!("Simple {}", self.api_key)))
    }
}

/// Allow cloning in order to reuse http client (and API key) for multiple connections
impl clone::Clone for HttpClient {
    fn clone(&self) -> HttpClient {
        HttpClient {
            api_key: self.api_key.clone(),
            base_url: self.base_url.clone(),
            hyper_client: self.hyper_client.clone(),
            user_agent: self.user_agent.clone(),
        }
    }
}

<|endoftext|>


<commit_before>use ffi;

use libc;

use std::slice;
use std::str;
use std::ptr;
use std::ffi::CStr;

pub fn decode_c_str(c_str: *const ffi::yaml_char_t) -> Option<String> {
    if c_str == ptr::null() {
        None
    } else {
        unsafe {
            let i8_str = c_str as *const i8;
            str::from_utf8(CStr::from_ptr(i8_str).to_bytes()).map(|s| s.to_string()).ok()
        }
    }
}

pub fn decode_buf(buf: *const ffi::yaml_char_t, length: libc::size_t) -> Option<String> {
    if buf == ptr::null() {
        None
    } else {
        unsafe {
            str::from_utf8(slice::from_raw_parts(buf, length as usize)).map(|s| { s.to_string() }).ok()
        }
    }
}
<commit_msg>Use c_char instead of i8 for ffi<commit_after>use ffi;

use libc;

use std::slice;
use std::str;
use std::ptr;
use std::ffi::CStr;
use std::os::raw::c_char;

pub fn decode_c_str(c_str: *const ffi::yaml_char_t) -> Option<String> {
    if c_str == ptr::null() {
        None
    } else {
        unsafe {
            let c_char_str = c_str as *const c_char;
            str::from_utf8(CStr::from_ptr(c_char_str).to_bytes()).map(|s| s.to_string()).ok()
        }
    }
}

pub fn decode_buf(buf: *const ffi::yaml_char_t, length: libc::size_t) -> Option<String> {
    if buf == ptr::null() {
        None
    } else {
        unsafe {
            str::from_utf8(slice::from_raw_parts(buf, length as usize)).map(|s| { s.to_string() }).ok()
        }
    }
}
<|endoftext|>


<commit_before>//!
//! The main `Desync` struct
//!

use super::scheduler::*;

use std::sync::Arc;
use std::ops::{Deref, DerefMut};
use std::marker::{PhantomData};
use futures::channel::oneshot;
use futures::future::{Future, FutureObj};

///
/// A data storage structure used to govern synchronous and asynchronous access to an underlying object.
///
pub struct Desync<T: Send> {
    /// Queue used for scheduling runtime for this object
    queue:  Arc<JobQueue>,

    /// Data for this object. Boxed so the pointer remains the same through the lifetime of the object.
    data:   Box<T>
}

// Rust actually derives this anyway at the moment
unsafe impl<T: Send> Send for Desync<T> {}

// True iff queue: Sync
unsafe impl<T: Send> Sync for Desync<T> {}

///
/// Used for passing the data pointer through to the queue
///
/// 'Safe' because the queue is synchronised during drop, so we can never use the pointer
/// if the object does not exist.
///
struct DataRef<T: Send>(*const T);
unsafe impl<T: Send> Send for DataRef<T> {}

///
/// A mutable reference to the data contained within a desync, used to retrieve or modify its value during a future
///
pub struct DesyncRef<'a, T: Send> {
    data: DataRef<T>,
    phantom_lifetime: PhantomData<&'a T>
}

// Desync guarantees that while the future is running, nothing else can access the reference (it does this through ordering operations
// rather than mutual exclusion)
unsafe impl<'a, T: Send> Send for DesyncRef<'a, T> {}

impl<'a, T: Send> Deref for DesyncRef<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.data.0 }
    }
}

impl<'a, T: Send> DerefMut for DesyncRef<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *(self.data.0 as *mut T) }
    }
}

// TODO: we can change DataRef to Shared (https://doc.rust-lang.org/std/ptr/struct.Shared.html in the future)

// TODO: T does not need to be static as we know that its lifetime is at least the lifetime of Desync<T> and hence the queue
impl<T: 'static+Send> Desync<T> {
    ///
    /// Creates a new Desync object
    ///
    pub fn new(data: T) -> Desync<T> {
        let queue = queue();

        Desync {
            queue:  queue,
            data:   Box::new(data)
        }
    }

    ///
    /// Performs an operation asynchronously on this item. This function will return
    /// immediately and the job will happen on a separate thread at some time in the
    /// future (generally fairly soon).
    ///
    /// Jobs are always performed in the order that they are queued and are always
    /// performed synchronously with respect to this object.
    ///
    #[inline]
    #[deprecated(since="0.3.0", note="please use `desync` instead")]
    pub fn r#async<TFn>(&self, job: TFn)
    where TFn: 'static+Send+FnOnce(&mut T) -> () {
        self.desync(job)
    }

    ///
    /// Performs an operation asynchronously on this item. This function will return
    /// immediately and the job will happen on a separate thread at some time in the
    /// future (generally fairly soon).
    ///
    /// Jobs are always performed in the order that they are queued and are always
    /// performed synchronously with respect to this object.
    ///
    pub fn desync<TFn>(&self, job: TFn)
    where TFn: 'static+Send+FnOnce(&mut T) -> () {
        // As drop() is the last thing called, we know that this object will still exist at the point where the queue makes the asynchronous callback
        let data = DataRef(&*self.data);

        desync(&self.queue, move || {
            let data = data.0 as *mut T;
            job(unsafe { &mut *data });
        })
    }

    ///
    /// Performs an operation synchronously on this item. This will be queued with any other
    /// jobs that this item may be performing, and this function will not return until the
    /// job is complete and the result is available.
    ///
    pub fn sync<TFn, Result>(&self, job: TFn) -> Result
    where TFn: Send+FnOnce(&mut T) -> Result, Result: Send {
        let result = unsafe {
            // As drop() is the last thing called, we know that this object will still exist at the point where the callback occurs
            let data = DataRef(&*self.data);

            sync(&self.queue, move || {
                let data = data.0 as *mut T;
                job(&mut *data)
            })
        };

        result
    }

    ///
    /// Performs an operation asynchronously on the contents of this item, returning the
    /// result via a future.
    ///
    pub fn future2<TFn, Item>(&self, job: TFn) -> impl Future<Output=Result<Item, oneshot::Canceled>>+Send
    where   for<'a> TFn:    'static+Send+FnOnce(DesyncRef<'a, T>) -> FutureObj<'a, Item>,
            Item:           'static+Send {
        let data = DataRef(&*self.data);
        let data = DesyncRef { data: data, phantom_lifetime: PhantomData };

        scheduler().future(&self.queue, move || {
            async {
                let job     = job(data);
                job.await
            }
        })
    }

    ///
    /// Performs an operation asynchronously on the contents of this item, returning the
    /// result via a future.
    ///
    pub fn future<TFn, Item: 'static+Send>(&self, job: TFn) -> impl Future<Output=Result<Item, oneshot::Canceled>>+Send
    where TFn: 'static+Send+FnOnce(&mut T) -> Item {
        let (send, receive) = oneshot::channel();

        self.desync(|data| {
            let result = job(data);

            if let Err(_result) = send.send(result) {
                // The listening side disconnected: we'll throw away the result and act like a normal desync instead
            }
        });

        receive
    }

    ///
    /// After the pending operations for this item are performed, waits for the
    /// supplied future to complete and then calls the specified function
    ///
    pub fn after<'a, TFn, Res: 'static+Send, Fut: 'static+Future+Send>(&self, after: Fut, job: TFn) -> impl 'static+Future<Output=Result<Res, oneshot::Canceled>>+Send
    where TFn: 'static+Send+FnOnce(&mut T, Fut::Output) -> Res {
        // As drop() is the last thing called, we know that this object will still exist at the point where the callback occurs
        // Also, we'll have exclusive access to this object when the callback occurs
        let data = DataRef(&*self.data);

        scheduler().after(&self.queue, after, move |future_result| {
            let data = data.0 as *mut T;
            job(unsafe { &mut *data }, future_result)
        })
    }
}

impl<T: Send> Drop for Desync<T> {
    fn drop(&mut self) {
        // Ensure that everything on the queue has committed by queueing a last synchronous event
        // (Not synchronising the queue would make this unsafe as we would hold on to a pointer to
        // the internal data structure)
        sync(&self.queue, || {});
    }
}
<commit_msg>Revert "Add a new version of Future that uses desync's ordering guarantees to provide access to the data for the lifetime of the future that's returned."<commit_after>//!
//! The main `Desync` struct
//!

use super::scheduler::*;

use std::sync::Arc;
use futures::channel::oneshot;
use futures::future::Future;

///
/// A data storage structure used to govern synchronous and asynchronous access to an underlying object.
///
pub struct Desync<T: Send> {
    /// Queue used for scheduling runtime for this object
    queue:  Arc<JobQueue>,

    /// Data for this object. Boxed so the pointer remains the same through the lifetime of the object.
    data:   Box<T>
}

// Rust actually derives this anyway at the moment
unsafe impl<T: Send> Send for Desync<T> {}

// True iff queue: Sync
unsafe impl<T: Send> Sync for Desync<T> {}

///
/// Used for passing the data pointer through to the queue
///
/// 'Safe' because the queue is synchronised during drop, so we can never use the pointer
/// if the object does not exist.
///
struct DataRef<T: Send>(*const T);
unsafe impl<T: Send> Send for DataRef<T> {}

// TODO: we can change DataRef to Shared (https://doc.rust-lang.org/std/ptr/struct.Shared.html in the future)

// TODO: T does not need to be static as we know that its lifetime is at least the lifetime of Desync<T> and hence the queue
impl<T: 'static+Send> Desync<T> {
    ///
    /// Creates a new Desync object
    ///
    pub fn new(data: T) -> Desync<T> {
        let queue = queue();

        Desync {
            queue:  queue,
            data:   Box::new(data)
        }
    }

    ///
    /// Performs an operation asynchronously on this item. This function will return
    /// immediately and the job will happen on a separate thread at some time in the
    /// future (generally fairly soon).
    ///
    /// Jobs are always performed in the order that they are queued and are always
    /// performed synchronously with respect to this object.
    ///
    #[inline]
    #[deprecated(since="0.3.0", note="please use `desync` instead")]
    pub fn r#async<TFn>(&self, job: TFn)
    where TFn: 'static+Send+FnOnce(&mut T) -> () {
        self.desync(job)
    }

    ///
    /// Performs an operation asynchronously on this item. This function will return
    /// immediately and the job will happen on a separate thread at some time in the
    /// future (generally fairly soon).
    ///
    /// Jobs are always performed in the order that they are queued and are always
    /// performed synchronously with respect to this object.
    ///
    pub fn desync<TFn>(&self, job: TFn)
    where TFn: 'static+Send+FnOnce(&mut T) -> () {
        // As drop() is the last thing called, we know that this object will still exist at the point where the queue makes the asynchronous callback
        let data = DataRef(&*self.data);

        desync(&self.queue, move || {
            let data = data.0 as *mut T;
            job(unsafe { &mut *data });
        })
    }

    ///
    /// Performs an operation synchronously on this item. This will be queued with any other
    /// jobs that this item may be performing, and this function will not return until the
    /// job is complete and the result is available.
    ///
    pub fn sync<TFn, Result>(&self, job: TFn) -> Result
    where TFn: Send+FnOnce(&mut T) -> Result, Result: Send {
        let result = unsafe {
            // As drop() is the last thing called, we know that this object will still exist at the point where the callback occurs
            let data = DataRef(&*self.data);

            sync(&self.queue, move || {
                let data = data.0 as *mut T;
                job(&mut *data)
            })
        };

        result
    }

    ///
    /// Performs an operation asynchronously on the contents of this item, returning the
    /// result via a future.
    ///
    pub fn future<TFn, Item: 'static+Send>(&self, job: TFn) -> impl Future<Output=Result<Item, oneshot::Canceled>>+Send
    where TFn: 'static+Send+FnOnce(&mut T) -> Item {
        let (send, receive) = oneshot::channel();

        self.desync(|data| {
            let result = job(data);

            if let Err(_result) = send.send(result) {
                // The listening side disconnected: we'll throw away the result and act like a normal desync instead
            }
        });

        receive
    }

    ///
    /// After the pending operations for this item are performed, waits for the
    /// supplied future to complete and then calls the specified function
    ///
    pub fn after<'a, TFn, Res: 'static+Send, Fut: 'static+Future+Send>(&self, after: Fut, job: TFn) -> impl 'static+Future<Output=Result<Res, oneshot::Canceled>>+Send
    where TFn: 'static+Send+FnOnce(&mut T, Fut::Output) -> Res {
        // As drop() is the last thing called, we know that this object will still exist at the point where the callback occurs
        // Also, we'll have exclusive access to this object when the callback occurs
        let data = DataRef(&*self.data);

        scheduler().after(&self.queue, after, move |future_result| {
            let data = data.0 as *mut T;
            job(unsafe { &mut *data }, future_result)
        })
    }
}

impl<T: Send> Drop for Desync<T> {
    fn drop(&mut self) {
        // Ensure that everything on the queue has committed by queueing a last synchronous event
        // (Not synchronising the queue would make this unsafe as we would hold on to a pointer to
        // the internal data structure)
        sync(&self.queue, || {});
    }
}
<|endoftext|>


<commit_before>// Regression tests from American Fuzzy Lop test cases.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

extern crate mp4parse;

use std::io::Cursor;

/// https://github.com/mozilla/mp4parse-rust/issues/2
#[test]
fn fuzz_2() {
    let mut c = Cursor::new(b"\x00\x00\x00\x04\xa6\x00\x04\xa6".to_vec());
    let mut context = mp4parse::MediaContext::new();
    let _ = mp4parse::read_box(&mut c, &mut context);
}
<commit_msg>Add regression test from fuzzing test cases.<commit_after>// Regression tests from American Fuzzy Lop test cases.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

extern crate mp4parse;

use std::io::Cursor;

/// https://github.com/mozilla/mp4parse-rust/issues/2
#[test]
fn fuzz_2() {
    let mut c = Cursor::new(b"\x00\x00\x00\x04\xa6\x00\x04\xa6".to_vec());
    let mut context = mp4parse::MediaContext::new();
    let _ = mp4parse::read_box(&mut c, &mut context);
}

/// https://github.com/mozilla/mp4parse-rust/issues/4
#[test]
fn fuzz_4() {
    let mut c = Cursor::new(b"\x00\x00\x00\x01\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x00\x00".to_vec());
    let mut context = mp4parse::MediaContext::new();
    let _ = mp4parse::read_box(&mut c, &mut context);
}
<|endoftext|>


<commit_before>use core::mem::transmute;
use core::ptr::{set_memory, copy_memory, offset};
use core::i32::ctlz32;
use core::fail::out_of_memory;

use kernel::ptr::mut_offset;

#[repr(u8)]
enum Node {
    UNUSED = 0,
    USED = 1,
    SPLIT = 2,
    FULL = 3
}

pub trait Allocator {
    fn alloc(&mut self, size: uint) -> (*mut u8, uint);

    fn zero_alloc(&mut self, s: uint) -> (*mut u8, uint) {
        let (ptr, size) = self.alloc(s);
        unsafe { set_memory(ptr, 0, size); }
        (ptr, size)
    }

    fn realloc(&mut self, src: *mut u8, size: uint) -> (*mut u8, uint) {
        self.free(src);
        let (ptr, sz) = self.alloc(size);
        unsafe { copy_memory(ptr, src as *u8, sz); }
        (ptr, sz)
    }

    fn free(&mut self, ptr: *mut u8);
}

trait BitvTrait {
    fn get(&self, i: uint) -> Node;
    fn set(&self, i: uint, x: Node);
    fn to_bytes(&self) -> *mut u8;
    fn size(&self) -> uint;
}

static BITV_SIZE: uint = 0x10_000;
pub type BitvStorage = *mut [u32, ..BITV_SIZE / 4];

// vector of 2-bit
pub struct Bitv {
    storage: BitvStorage
}

impl BitvTrait for Bitv {
    #[inline]
    fn get(&self, i: uint) -> Node {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { transmute(((*self.storage)[w] as uint >> b) as u8 & 3) }
    }

    #[inline]
    fn set(&self, i: uint, x: Node) {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { (*self.storage)[w] = (((*self.storage)[w] & !(3 << b)) | (x as u32 << b)); }
    }

    #[inline]
    fn to_bytes(&self) -> *mut u8 {
        self.storage as *mut u8
    }

    #[inline]
    fn size(&self) -> uint {
        BITV_SIZE
    }
}

pub struct BuddyAlloc {
    order: uint,
    tree: Bitv
}

pub struct Alloc {
    parent: BuddyAlloc,
    base: *mut u8,
    el_size: uint
}

impl BuddyAlloc {
    pub fn new(order: uint, storage: Bitv) -> BuddyAlloc {
        unsafe { set_memory(storage.to_bytes(), 0, storage.size()); }

        BuddyAlloc { order: order, tree: storage }
    }

    #[inline]
    fn offset(&self, index: uint, level: uint) -> uint {
        /* unsafe { - unnecessary */
            (index + 1 - (1 << (self.order - level))) << level
        /* } */
    }

    fn alloc(&mut self, mut size: uint) -> (uint, uint) {
        if size == 0 {
            size = 1;
        }
        // smallest power of 2 >= size
        let lg2_size = 32 - unsafe { ctlz32(size as i32 - 1) } as uint;

        let mut index = 0; // points to current tree node
        let mut level = self.order; // current height

        loop {
            match (self.tree.get(index), level == lg2_size) {
                (UNUSED, true) => {
                    // Found appropriate unused node
                    self.tree.set(index, USED); // use

                    let mut parent = index;
                    loop {
                        let buddy = parent - 1 + (parent & 1) * 2;
                        match self.tree.get(buddy) {
                            USED | FULL if parent > 0 => {
                                parent = (parent + 1) / 2 - 1;
                                self.tree.set(parent, FULL);
                            }
                            _ => break
                        }
                    }
                    return (
                        self.offset(index, level),
                        1 << lg2_size
                    );
                }
                (UNUSED, false) => {
                    // This large node is unused, split it!
                    self.tree.set(index, SPLIT);
                    self.tree.set(index*2 + 1, UNUSED);
                    self.tree.set(index*2 + 2, UNUSED);
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                (SPLIT, false) => {
                    // Traverse children
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                _ => loop {
                    // Go either right or back up
                    if index & 1 == 1 {
                        // right sibling
                        index += 1;
                        break;
                    }

                    // go up by one level
                    level += 1;

                    if index == 0 {
                        // out of memory -- back at tree's root after traversal
			         //out_of_memory();
                        return (0, 0);
                    }

                    index = (index + 1) / 2 - 1; // parent
                }
            }
        }
    }

    fn free(&mut self, offset: uint) {
        let mut length = 1 << self.order;
        let mut left = 0;
        let mut index = 0;

        loop {
            match self.tree.get(index) {
                UNUSED => return,
                USED =>
                loop {
                    if index == 0 {
                        self.tree.set(0, UNUSED);
                        return;
                    }

                    let buddy = index - 1 + (index & 1) * 2;
                    match self.tree.get(buddy) {
                        UNUSED => {}
                        _ => {
                            self.tree.set(index, UNUSED);
                            loop {
                                let parent = (index + 1) / 2 - 1; // parent
                                match self.tree.get(parent) {
                                    FULL if index > 0 => {
                                        self.tree.set(parent, SPLIT);
                                    }
                                    _ => return
                                }
                                index = parent;
                            }
                        }
                    }
                    index = (index + 1) / 2 - 1; // parent
                },
                _ => {
                    length /= 2;
                    if offset < left + length {
                        index = index * 2 + 1; // left child
                    }
                    else {
                        left += length;
                        index = index * 2 + 2; // right child
                    }
                }
            }
        }
    }
}

impl Allocator for Alloc {
    fn alloc(&mut self, size: uint) -> (*mut u8, uint) {
        let (offset, size) = self.parent.alloc(size);
        unsafe {
            return (
                mut_offset(self.base, (offset << self.el_size) as int),
                size << self.el_size
            )
        }
    }

    fn free(&mut self, ptr: *mut u8) {
        let length = 1 << self.parent.order << self.el_size;

        unsafe {
            if ptr < self.base || ptr >= mut_offset(self.base, length) {
                return;
            }
        }

        let offset = (ptr as uint - self.base as uint) >> self.el_size;
        self.parent.free(offset);
    }
}
<commit_msg>memory stuff<commit_after>use core::mem::transmute;
use core::ptr::{set_memory, copy_memory, offset};
use core::i32::ctlz32;
use core::fail::out_of_memory;

use kernel::ptr::mut_offset;

#[repr(u8)]
enum Node {
    UNUSED = 0,
    USED = 1,
    SPLIT = 2,
    FULL = 3
}

pub trait Allocator {
    fn alloc(&mut self, size: uint) -> (*mut u8, uint);

    fn zero_alloc(&mut self, s: uint) -> (*mut u8, uint) {
        let (ptr, size) = self.alloc(s);
        unsafe { set_memory(ptr, 0, size); }
        (ptr, size)
    }

    fn realloc(&mut self, src: *mut u8, size: uint) -> (*mut u8, uint) {
        self.free(src);
        let (ptr, sz) = self.alloc(size);
        unsafe { copy_memory(ptr, src as *u8, sz); }
        (ptr, sz)
    }

    fn free(&mut self, ptr: *mut u8);
}

trait BitvTrait {
    fn get(&self, i: uint) -> Node;
    fn set(&self, i: uint, x: Node);
    fn to_bytes(&self) -> *mut u8;
    fn size(&self) -> uint;
}

static BITV_SIZE: uint = 0x10_000;
pub type BitvStorage = *mut [u32, ..BITV_SIZE / 4];

// vector of 2-bit
pub struct Bitv {
    storage: BitvStorage
}

impl BitvTrait for Bitv {
    #[inline]
    fn get(&self, i: uint) -> Node {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { transmute(((*self.storage)[w] as uint >> b) as u8 & 3) }
    }

    #[inline]
    fn set(&self, i: uint, x: Node) {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { (*self.storage)[w] = (((*self.storage)[w] & !(3 << b)) | (x as u32 << b)); }
    }

    #[inline]
    fn to_bytes(&self) -> *mut u8 {
        self.storage as *mut u8
    }

    #[inline]
    fn size(&self) -> uint {
        BITV_SIZE
    }
}

pub struct BuddyAlloc {
    order: uint,
    tree: Bitv
}

pub struct Alloc {
    parent: BuddyAlloc,
    base: *mut u8,
    el_size: uint
}

impl BuddyAlloc {
    pub fn new(order: uint, storage: Bitv) -> BuddyAlloc {
        unsafe { set_memory(storage.to_bytes(), 0, storage.size()); }

        BuddyAlloc { order: order, tree: storage }
    }

    #[inline]
    fn offset(&self, index: uint, level: uint) -> uint {
        /* unsafe { - unnecessary */
            (index + 1 - (1 << (self.order - level))) << level
        /* } */
    }

    fn alloc(&mut self, mut size: uint) -> (uint, uint) {
        if size == 0 {
            size = 1;
        }
        // smallest power of 2 >= size
        let lg2_size = 32 - unsafe { ctlz32(size as i32 - 1) } as uint;

        let mut index = 0; // points to current tree node
        let mut level = self.order; // current height

        loop {
            match (self.tree.get(index), level == lg2_size) {
                (UNUSED, true) => {
                    // Found appropriate unused node
                    self.tree.set(index, USED); // use

                    let mut parent = index;
                    loop {
                        let buddy = parent - 1 + (parent & 1) * 2;
                        match self.tree.get(buddy) {
                            USED | FULL if parent > 0 => {
                                parent = (parent + 1) / 2 - 1;
                                self.tree.set(parent, FULL);
                            }
                            _ => break
                        }
                    }
                    return (
                        self.offset(index, level),
                        1 << lg2_size
                    );
                }
                (UNUSED, false) => {
                    // This large node is unused, split it!
                    self.tree.set(index, SPLIT);
                    self.tree.set(index*2 + 1, UNUSED);
                    self.tree.set(index*2 + 2, UNUSED);
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                (SPLIT, false) => {
                    // Traverse children
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                _ => loop {
                    // Go either right or back up
                    if index & 1 == 1 {
                        // right sibling
                        index += 1;
                        break;
                    }

                    // go up by one level
                    level += 1;

                    if index == 0 {
                        // out of memory -- back at tree's root after traversal
			         //out_of_memory();
                        return (0, 0);
                    }

                    index = (index + 1) / 2 - 1; // parent
                }
            }
        }
    }

    fn free(&mut self, offset: uint) {
        let mut length = 1 << self.order;
        let mut left = 0;
        let mut index = 0;

        loop {
            match self.tree.get(index) {
                UNUSED => return,
                USED =>
                loop {
                    //base case - top of tree
                    if index == 0 {
                        self.tree.set(index, UNUSED);
                        return;
                    }
                    //otherwise, find buddy (account for finding first OR second buddy)
                    let buddy = index - 1 + (index & 1) * 2;
                    match self.tree.get(buddy) {
                        UNUSED => {} // buddy isn't used - keep moving up (parent combined)
                        _ => {  // any other case - set current index to unused
                            self.tree.set(index, UNUSED);
                            loop {
                                let parent = (index + 1) / 2 - 1; // parent because of integer division
                                match (self.tree.get(parent), index > 0) {
                                    (FULL, true) => {
                                        // if parent was full, mark it as split (because only one child block is being used)
                                        self.tree.set(parent, SPLIT);
                                    }
                                    (_, _) => return
                                }
                                index = parent;                 // move up the tree
                            }
                        }
                    }
                    index = (index + 1) / 2 - 1; // parent
                },
                _ => {
                    length /= 2;
                    if offset < left + length {
                        index = index * 2 + 1; // left child
                    }
                    else {
                        left += length;
                        index = index * 2 + 2; // right child
                    }
                }
            }
        }
    }
}

impl Allocator for Alloc {
    fn alloc(&mut self, size: uint) -> (*mut u8, uint) {
        let (offset, size) = self.parent.alloc(size);
        unsafe {
            return (
                mut_offset(self.base, (offset << self.el_size) as int),
                size << self.el_size
            )
        }
    }

    fn free(&mut self, ptr: *mut u8) {
        let length = 1 << self.parent.order << self.el_size;

        unsafe {
            if ptr < self.base || ptr >= mut_offset(self.base, length) {
                return;
            }
        }

        let offset = (ptr as uint - self.base as uint) >> self.el_size;
        self.parent.free(offset);
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLPreElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLPreElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLPreElement {
    pub htmlelement: HTMLElement,
}

impl HTMLPreElementDerived for EventTarget {
    fn is_htmlpreelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLPreElementTypeId))
    }
}

impl HTMLPreElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLPreElement {
        HTMLPreElement {
            htmlelement: HTMLElement::new_inherited(HTMLPreElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLPreElement> {
        let element = HTMLPreElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLPreElementBinding::Wrap)
    }
}

pub trait HTMLPreElementMethods {
    fn Width(&self) -> i32;
    fn SetWidth(&mut self, _width: i32) -> ErrorResult;
}

impl<'a> HTMLPreElementMethods for JSRef<'a, HTMLPreElement> {
    fn Width(&self) -> i32 {
        0
    }

    fn SetWidth(&mut self, _width: i32) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLPreElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLPreElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLPreElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLPreElement {
    pub htmlelement: HTMLElement,
}

impl HTMLPreElementDerived for EventTarget {
    fn is_htmlpreelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLPreElementTypeId))
    }
}

impl HTMLPreElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLPreElement {
        HTMLPreElement {
            htmlelement: HTMLElement::new_inherited(HTMLPreElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLPreElement> {
        let element = HTMLPreElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLPreElementBinding::Wrap)
    }
}

pub trait HTMLPreElementMethods {
    fn Width(&self) -> i32;
    fn SetWidth(&self, _width: i32) -> ErrorResult;
}

impl<'a> HTMLPreElementMethods for JSRef<'a, HTMLPreElement> {
    fn Width(&self) -> i32 {
        0
    }

    fn SetWidth(&self, _width: i32) -> ErrorResult {
        Ok(())
    }
}
<|endoftext|>


<commit_before>extern crate rusty_trap;
use std::path::Path;

#[test]
fn it_can_exec () {
    let inferior = rusty_trap::trap_inferior_exec(Path::new("./target/debug/twelve"),&[])
        .unwrap();
    assert_eq!(12, rusty_trap::trap_inferior_continue(inferior, &mut |_, _| {}));
}

#[test]
fn it_can_set_breakpoints () {
    let mut breakpoint_count: i32 = 0;

    let inferior = rusty_trap::trap_inferior_exec(Path::new("./target/debug/twelve"), &[])
        .unwrap();
    let bp = rusty_trap::trap_inferior_set_breakpoint(inferior, 0x555555559000);
    rusty_trap::trap_inferior_continue(inferior, &mut |passed_inferior, passed_bp| {
        assert_eq!(passed_inferior, inferior);
        assert_eq!(passed_bp, bp);
        breakpoint_count += 1;
    });

    assert_eq!(breakpoint_count, 1);
}
<commit_msg>Update fixed address.<commit_after>extern crate rusty_trap;
use std::path::Path;

#[test]
fn it_can_exec () {
    let inferior = rusty_trap::trap_inferior_exec(Path::new("./target/debug/twelve"),&[])
        .unwrap();
    assert_eq!(12, rusty_trap::trap_inferior_continue(inferior, &mut |_, _| {}));
}

#[test]
fn it_can_set_breakpoints () {
    let mut breakpoint_count: i32 = 0;

    let inferior = rusty_trap::trap_inferior_exec(Path::new("./target/debug/twelve"), &[])
        .unwrap();
    let bp = rusty_trap::trap_inferior_set_breakpoint(inferior, 0x00005555555587c0);
    rusty_trap::trap_inferior_continue(inferior, &mut |passed_inferior, passed_bp| {
        assert_eq!(passed_inferior, inferior);
        assert_eq!(passed_bp, bp);
        breakpoint_count += 1;
    });

    assert_eq!(breakpoint_count, 1);
}
<|endoftext|>


<commit_before>//! Provides number theory utility functions

/// Provides a trait for the canonical modulus operation
/// since % is technically the remainder operation
pub trait Modulus {
    fn modulus(self, divisor: Self) -> Self;
}

impl Modulus for f64 {
    fn modulus(self, divisor: f64) -> f64 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for f32 {
    fn modulus(self, divisor: f32) -> f32 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for i64 {
    fn modulus(self, divisor: i64) -> i64 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for i32 {
    fn modulus(self, divisor: i32) -> i32 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for u64 {
    fn modulus(self, divisor: u64) -> u64 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for u32 {
    fn modulus(self, divisor: u32) -> u32 {
        ((self % divisor) + divisor) % divisor
    }
}
<commit_msg>doc comments for modulus trait<commit_after>//! Provides number theory utility functions

/// Provides a trait for the canonical modulus operation
/// since % is technically the remainder operation
pub trait Modulus {
    /// Performs a canonical modulus operation between `self` and
    /// `divisor`.
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::euclid::Modulus;
    ///
    /// let x = 4i64.modulus(5);
    /// assert_eq!(x, 4);
    ///
    /// let y = -4i64.modulus(5);
    /// assert_eq!(x, 4);
    /// ```
    fn modulus(self, divisor: Self) -> Self;
}

impl Modulus for f64 {
    fn modulus(self, divisor: f64) -> f64 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for f32 {
    fn modulus(self, divisor: f32) -> f32 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for i64 {
    fn modulus(self, divisor: i64) -> i64 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for i32 {
    fn modulus(self, divisor: i32) -> i32 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for u64 {
    fn modulus(self, divisor: u64) -> u64 {
        ((self % divisor) + divisor) % divisor
    }
}

impl Modulus for u32 {
    fn modulus(self, divisor: u32) -> u32 {
        ((self % divisor) + divisor) % divisor
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the MIT License, <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

use {serde, tokio_core};
use bincode::{SizeLimit, serde as bincode};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{self, Cursor};
use std::marker::PhantomData;
use std::mem;
use tokio_core::io::{EasyBuf, Framed, Io};
use tokio_proto::streaming::multiplex::{self, RequestId};
use tokio_proto::multiplex::{ClientProto, ServerProto};
use util::Never;

/// The type of message sent and received by the transport.
pub type Frame<T> = multiplex::Frame<T, Never, io::Error>;

// `T` is the type that `Codec` parses.
pub struct Codec<Req, Resp> {
    state: CodecState,
    _phantom_data: PhantomData<(Req, Resp)>,
}

enum CodecState {
    Id,
    Len { id: u64 },
    Payload { id: u64, len: u64 },
}

impl<Req, Resp> Codec<Req, Resp> {
    fn new() -> Self {
        Codec {
            state: CodecState::Id,
            _phantom_data: PhantomData,
        }
    }
}

impl<Req, Resp> tokio_core::io::Codec for Codec<Req, Resp>
    where Req: serde::Deserialize,
          Resp: serde::Serialize,
{
    type Out = (RequestId, Resp);
    type In = (RequestId, Result<Req, bincode::DeserializeError>);

    fn encode(&mut self, (id, message): Self::Out, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.write_u64::<BigEndian>(id).unwrap();
        buf.write_u64::<BigEndian>(bincode::serialized_size(&message)).unwrap();
        bincode::serialize_into(buf,
                                &message,
                                SizeLimit::Infinite)
                 // TODO(tikue): handle err
                 .expect("In bincode::serialize_into");
        Ok(())
    }

    fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<Self::In>, io::Error> {
        use self::CodecState::*;

        loop {
            match self.state {
                Id if buf.len() < mem::size_of::<u64>() => return Ok(None),
                Id => {
                    self.state = Len { id: Cursor::new(&*buf.get_mut()).read_u64::<BigEndian>()? };
                    *buf = buf.split_off(mem::size_of::<u64>());
                }
                Len { .. } if buf.len() < mem::size_of::<u64>() => return Ok(None),
                Len { id } => {
                    self.state = Payload {
                        id: id,
                        len: Cursor::new(&*buf.get_mut()).read_u64::<BigEndian>()?,
                    };
                    *buf = buf.split_off(mem::size_of::<u64>());
                }
                Payload { len, .. } if buf.len() < len as usize => return Ok(None),
                Payload { id, .. } => {
                    let mut buf = buf.get_mut();
                    let result = bincode::deserialize_from(&mut Cursor::new(&mut *buf),
                                                           SizeLimit::Infinite);
                    // Clear any unread bytes so we don't read garbage on next request.
                    buf.clear();
                    // Reset the state machine because, either way, we're done processing this
                    // message.
                    self.state = Id;

                    return Ok(Some((id, result)));
                }
            }
        }
    }
}

/// Implements the `multiplex::ServerProto` trait.
pub struct Proto<Req, Resp>(PhantomData<(Req, Resp)>);

impl<Req, Resp> Proto<Req, Resp> {
    /// Returns a new `Proto`.
    pub fn new() -> Self {
        Proto(PhantomData)
    }
}

impl<T, Req, Resp> ServerProto<T> for Proto<Req, Resp>
    where T: Io + 'static,
          Req: serde::Deserialize + 'static,
          Resp: serde::Serialize + 'static,
{
    type Response = Resp;
    type Request = Result<Req, bincode::DeserializeError>;
    type Error = io::Error;
    type Transport = Framed<T, Codec<Req, Resp>>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(Codec::new()))
    }
}

impl<T, Req, Resp> ClientProto<T> for Proto<Req, Resp>
    where T: Io + 'static,
          Req: serde::Serialize + 'static,
          Resp: serde::Deserialize + 'static,
{
    type Response = Result<Resp, bincode::DeserializeError>;
    type Request = Req;
    type Error = io::Error;
    type Transport = Framed<T, Codec<Resp, Req>>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(Codec::new()))
    }
}

#[test]
fn serialize() {
    use tokio_core::io::Codec as TokioCodec;

    const MSG: (u64, (char, char, char)) = (4, ('a', 'b', 'c'));
    let mut buf = EasyBuf::new();
    let mut vec = Vec::new();

    // Serialize twice to check for idempotence.
    for _ in 0..2 {
        let mut codec: Codec<(char, char, char), (char, char, char)> = Codec::new();
        codec.encode(MSG, &mut vec).unwrap();
        buf.get_mut().append(&mut vec);
        let actual: Result<Option<(u64, Result<(char, char, char), bincode::DeserializeError>)>, io::Error> =
            codec.decode(&mut buf);

        match actual {
            Ok(Some((id, ref v))) if id == MSG.0 && *v.as_ref().unwrap() == MSG.1 => {}
            bad => panic!("Expected {:?}, but got {:?}", Some(MSG), bad),
        }

        assert!(buf.get_mut().is_empty(),
                "Expected empty buf but got {:?}",
                *buf.get_mut());
    }
}
<commit_msg>Small refactor<commit_after>// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the MIT License, <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

use {serde, tokio_core};
use bincode::{SizeLimit, serde as bincode};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{self, Cursor};
use std::marker::PhantomData;
use std::mem;
use tokio_core::io::{EasyBuf, Framed, Io};
use tokio_proto::streaming::multiplex::{self, RequestId};
use tokio_proto::multiplex::{ClientProto, ServerProto};
use util::Never;

/// The type of message sent and received by the transport.
pub type Frame<T> = multiplex::Frame<T, Never, io::Error>;

// `T` is the type that `Codec` parses.
pub struct Codec<Req, Resp> {
    state: CodecState,
    _phantom_data: PhantomData<(Req, Resp)>,
}

enum CodecState {
    Id,
    Len { id: u64 },
    Payload { id: u64, len: u64 },
}

impl<Req, Resp> Codec<Req, Resp> {
    fn new() -> Self {
        Codec {
            state: CodecState::Id,
            _phantom_data: PhantomData,
        }
    }
}

impl<Req, Resp> tokio_core::io::Codec for Codec<Req, Resp>
    where Req: serde::Deserialize,
          Resp: serde::Serialize,
{
    type Out = (RequestId, Resp);
    type In = (RequestId, Result<Req, bincode::DeserializeError>);

    fn encode(&mut self, (id, message): Self::Out, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.write_u64::<BigEndian>(id).unwrap();
        buf.write_u64::<BigEndian>(bincode::serialized_size(&message)).unwrap();
        bincode::serialize_into(buf,
                                &message,
                                SizeLimit::Infinite)
                 // TODO(tikue): handle err
                 .expect("In bincode::serialize_into");
        Ok(())
    }

    fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<Self::In>, io::Error> {
        use self::CodecState::*;

        loop {
            match self.state {
                Id if buf.len() < mem::size_of::<u64>() => return Ok(None),
                Id => {
                    let id_buf = buf.drain_to(mem::size_of::<u64>());
                    self.state = Len { id: Cursor::new(id_buf).read_u64::<BigEndian>()? };
                }
                Len { .. } if buf.len() < mem::size_of::<u64>() => return Ok(None),
                Len { id } => {
                    let len_buf = buf.drain_to(mem::size_of::<u64>());
                    self.state = Payload {
                        id: id,
                        len: Cursor::new(len_buf).read_u64::<BigEndian>()?,
                    };
                }
                Payload { len, .. } if buf.len() < len as usize => return Ok(None),
                Payload { id, .. } => {
                    let mut buf = buf.get_mut();
                    let result = bincode::deserialize_from(&mut Cursor::new(&mut *buf),
                                                           SizeLimit::Infinite);
                    // Clear any unread bytes so we don't read garbage on next request.
                    buf.clear();
                    // Reset the state machine because, either way, we're done processing this
                    // message.
                    self.state = Id;

                    return Ok(Some((id, result)));
                }
            }
        }
    }
}

/// Implements the `multiplex::ServerProto` trait.
pub struct Proto<Req, Resp>(PhantomData<(Req, Resp)>);

impl<Req, Resp> Proto<Req, Resp> {
    /// Returns a new `Proto`.
    pub fn new() -> Self {
        Proto(PhantomData)
    }
}

impl<T, Req, Resp> ServerProto<T> for Proto<Req, Resp>
    where T: Io + 'static,
          Req: serde::Deserialize + 'static,
          Resp: serde::Serialize + 'static,
{
    type Response = Resp;
    type Request = Result<Req, bincode::DeserializeError>;
    type Error = io::Error;
    type Transport = Framed<T, Codec<Req, Resp>>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(Codec::new()))
    }
}

impl<T, Req, Resp> ClientProto<T> for Proto<Req, Resp>
    where T: Io + 'static,
          Req: serde::Serialize + 'static,
          Resp: serde::Deserialize + 'static,
{
    type Response = Result<Resp, bincode::DeserializeError>;
    type Request = Req;
    type Error = io::Error;
    type Transport = Framed<T, Codec<Resp, Req>>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(Codec::new()))
    }
}

#[test]
fn serialize() {
    use tokio_core::io::Codec as TokioCodec;

    const MSG: (u64, (char, char, char)) = (4, ('a', 'b', 'c'));
    let mut buf = EasyBuf::new();
    let mut vec = Vec::new();

    // Serialize twice to check for idempotence.
    for _ in 0..2 {
        let mut codec: Codec<(char, char, char), (char, char, char)> = Codec::new();
        codec.encode(MSG, &mut vec).unwrap();
        buf.get_mut().append(&mut vec);
        let actual: Result<Option<(u64, Result<(char, char, char), bincode::DeserializeError>)>, io::Error> =
            codec.decode(&mut buf);

        match actual {
            Ok(Some((id, ref v))) if id == MSG.0 && *v.as_ref().unwrap() == MSG.1 => {}
            bad => panic!("Expected {:?}, but got {:?}", Some(MSG), bad),
        }

        assert!(buf.get_mut().is_empty(),
                "Expected empty buf but got {:?}",
                *buf.get_mut());
    }
}
<|endoftext|>


<commit_before>
pub use descartes::{N, P3, P2, V3, V4, M4, Iso3, Persp3, ToHomogeneous, Norm, Into2d, Into3d,
                    WithUniqueOrthogonal, Inverse, Rotate};
use kay::{Recipient, Fate};

use {Renderer, Eye};

#[derive(Copy, Clone)]
pub enum Movement {
    Shift(V3),
    Zoom(N, P3),
    Yaw(N),
    Pitch(N),
}

#[derive(Copy, Clone)]
pub struct MoveEye {
    pub scene_id: usize,
    pub movement: Movement,
}
#[derive(Copy, Clone)]
pub struct EyeMoved {
    pub eye: Eye,
    pub movement: Movement,
}

impl Recipient<MoveEye> for Renderer {
    fn receive(&mut self, msg: &MoveEye) -> Fate {
        match *msg {
            MoveEye { scene_id, movement } => {
                match movement {
                    Movement::Shift(delta) => self.movement_shift(scene_id, delta),
                    Movement::Zoom(delta, mouse_position) => {
                        self.movement_zoom(scene_id, delta, mouse_position)
                    }
                    Movement::Yaw(delta) => self.movement_yaw(scene_id, delta),
                    Movement::Pitch(delta) => self.movement_pitch(scene_id, delta),
                }

                for &id in &self.scenes[scene_id].eye_listeners {
                    id <<
                    EyeMoved {
                        eye: self.scenes[scene_id].eye,
                        movement: movement,
                    };
                }
                Fate::Live
            }
        }
    }
}

impl Renderer {
    fn movement_shift(&mut self, scene_id: usize, delta: V3) {
        let eye = &mut self.scenes[scene_id].eye;
        let eye_direction_2d = (eye.target - eye.position).into_2d().normalize();
        let absolute_delta = delta.x * eye_direction_2d.into_3d() +
                             delta.y * eye_direction_2d.orthogonal().into_3d() +
                             V3::new(0.0, 0.0, delta.z);

        let dist_to_target = (eye.target - eye.position).norm();

        eye.position += absolute_delta * (dist_to_target / 500.0);
        eye.target += absolute_delta * (dist_to_target / 500.0);
    }

    fn movement_zoom(&mut self, scene_id: usize, delta: N, zoom_point: P3) {
        let eye = &mut self.scenes[scene_id].eye;

        // Cache common calculations
        let zoom_direction = (zoom_point - eye.position).normalize();
        let zoom_distance = (zoom_point - eye.position).norm();

        // Move eye.position towards zoom_point
        if zoom_distance > 30.0 || delta < 0.0 {
            eye.position += (zoom_direction * delta * zoom_distance) / 300.0;
        }

        let new_zoom_distance = (zoom_point - eye.position).norm();

        // Scale the distance from eye.target to zoom_point with the scale between zoom_point distances
        eye.target = ((new_zoom_distance * (eye.target - zoom_point)) / zoom_distance +
                      zoom_point.to_vector())
            .to_point();
    }

    fn movement_yaw(&mut self, scene_id: usize, delta: N) {
        let eye = &mut self.scenes[scene_id].eye;
        let relative_eye_position = eye.position - eye.target;
        let iso = Iso3::new(V3::new(0.0, 0.0, 0.0), V3::new(0.0, 0.0, delta));
        let rotated_relative_eye_position = iso.rotate(&relative_eye_position);

        eye.position = eye.target + rotated_relative_eye_position;
    }

    fn movement_pitch(&mut self, scene_id: usize, delta: N) {
        let eye = &mut self.scenes[scene_id].eye;
        let relative_eye_position = eye.position - eye.target;

        // Convert relative eye position to spherical coordinates
        let r = relative_eye_position.norm();
        let mut inc = (relative_eye_position.z / r).acos();
        let azi = relative_eye_position.y.atan2(relative_eye_position.x);

        // Add delta to the inclination
        inc += delta;

        // Clamp the inclination to within 0;1.5 radians
        inc = if inc < 0.0001 { 0.0001 } else { inc }; // Check lower bounds
        inc = if inc > 1.5 { 1.5 } else { inc }; // Check upper bounds;

        // Convert spherical coordinates back into carteesiam coordinates
        let x = r * inc.sin() * azi.cos();
        let y = r * inc.sin() * azi.sin();
        let z = r * inc.cos();

        // The spherical coordinates are calculated relative to the target.
        eye.position = eye.target + V3::new(x, y, z);
    }
}
<commit_msg>Fixed comment exceeding max line length<commit_after>
pub use descartes::{N, P3, P2, V3, V4, M4, Iso3, Persp3, ToHomogeneous, Norm, Into2d, Into3d,
                    WithUniqueOrthogonal, Inverse, Rotate};
use kay::{Recipient, Fate};

use {Renderer, Eye};

#[derive(Copy, Clone)]
pub enum Movement {
    Shift(V3),
    Zoom(N, P3),
    Yaw(N),
    Pitch(N),
}

#[derive(Copy, Clone)]
pub struct MoveEye {
    pub scene_id: usize,
    pub movement: Movement,
}
#[derive(Copy, Clone)]
pub struct EyeMoved {
    pub eye: Eye,
    pub movement: Movement,
}

impl Recipient<MoveEye> for Renderer {
    fn receive(&mut self, msg: &MoveEye) -> Fate {
        match *msg {
            MoveEye { scene_id, movement } => {
                match movement {
                    Movement::Shift(delta) => self.movement_shift(scene_id, delta),
                    Movement::Zoom(delta, mouse_position) => {
                        self.movement_zoom(scene_id, delta, mouse_position)
                    }
                    Movement::Yaw(delta) => self.movement_yaw(scene_id, delta),
                    Movement::Pitch(delta) => self.movement_pitch(scene_id, delta),
                }

                for &id in &self.scenes[scene_id].eye_listeners {
                    id <<
                    EyeMoved {
                        eye: self.scenes[scene_id].eye,
                        movement: movement,
                    };
                }
                Fate::Live
            }
        }
    }
}

impl Renderer {
    fn movement_shift(&mut self, scene_id: usize, delta: V3) {
        let eye = &mut self.scenes[scene_id].eye;
        let eye_direction_2d = (eye.target - eye.position).into_2d().normalize();
        let absolute_delta = delta.x * eye_direction_2d.into_3d() +
                             delta.y * eye_direction_2d.orthogonal().into_3d() +
                             V3::new(0.0, 0.0, delta.z);

        let dist_to_target = (eye.target - eye.position).norm();

        eye.position += absolute_delta * (dist_to_target / 500.0);
        eye.target += absolute_delta * (dist_to_target / 500.0);
    }

    fn movement_zoom(&mut self, scene_id: usize, delta: N, zoom_point: P3) {
        let eye = &mut self.scenes[scene_id].eye;

        // Cache common calculations
        let zoom_direction = (zoom_point - eye.position).normalize();
        let zoom_distance = (zoom_point - eye.position).norm();

        // Move eye.position towards zoom_point
        if zoom_distance > 30.0 || delta < 0.0 {
            eye.position += (zoom_direction * delta * zoom_distance) / 300.0;
        }

        let new_zoom_distance = (zoom_point - eye.position).norm();

        // Scale the distance from eye.target to zoom_point
        // with the scale between zoom distances
        eye.target = ((new_zoom_distance * (eye.target - zoom_point)) / zoom_distance +
                      zoom_point.to_vector())
            .to_point();
    }

    fn movement_yaw(&mut self, scene_id: usize, delta: N) {
        let eye = &mut self.scenes[scene_id].eye;
        let relative_eye_position = eye.position - eye.target;
        let iso = Iso3::new(V3::new(0.0, 0.0, 0.0), V3::new(0.0, 0.0, delta));
        let rotated_relative_eye_position = iso.rotate(&relative_eye_position);

        eye.position = eye.target + rotated_relative_eye_position;
    }

    fn movement_pitch(&mut self, scene_id: usize, delta: N) {
        let eye = &mut self.scenes[scene_id].eye;
        let relative_eye_position = eye.position - eye.target;

        // Convert relative eye position to spherical coordinates
        let r = relative_eye_position.norm();
        let mut inc = (relative_eye_position.z / r).acos();
        let azi = relative_eye_position.y.atan2(relative_eye_position.x);

        // Add delta to the inclination
        inc += delta;

        // Clamp the inclination to within 0;1.5 radians
        inc = if inc < 0.0001 { 0.0001 } else { inc }; // Check lower bounds
        inc = if inc > 1.5 { 1.5 } else { inc }; // Check upper bounds;

        // Convert spherical coordinates back into carteesiam coordinates
        let x = r * inc.sin() * azi.cos();
        let y = r * inc.sin() * azi.sin();
        let z = r * inc.cos();

        // The spherical coordinates are calculated relative to the target.
        eye.position = eye.target + V3::new(x, y, z);
    }
}
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashMap;

use syn::Ident;

use crate::{
    conversion::{
        api::{Api, ApiDetail},
        error_reporter::convert_item_apis,
        ConvertError,
    },
    types::{validate_ident_ok_for_rust, QualifiedName},
};

use super::fun::FnAnalysis;

/// If any items have names which can't be represented by cxx,
/// abort.
pub(crate) fn check_names(apis: Vec<Api<FnAnalysis>>) -> Vec<Api<FnAnalysis>> {
    let mut intermediate = Vec::new();
    convert_item_apis(apis, &mut intermediate, |api| match api.detail {
        ApiDetail::Typedef { .. }
        | ApiDetail::ForwardDeclaration
        | ApiDetail::Const { .. }
        | ApiDetail::Enum { .. }
        | ApiDetail::Struct { .. } => {
            let cxx_name = api
                .cpp_name
                .as_ref()
                .map(|s|
                    QualifiedName::new_from_cpp_name(&s)
                )
                .unwrap_or_else(|| api.name.clone());
            for seg in cxx_name.segment_iter() {
                validate_ident_ok_for_rust(&seg)?;
            }
            Ok(Some(api))
        }
        ApiDetail::Function { .. } // we don't handle functions here because
            // the function analysis does an equivalent check. Instead of just rejecting
            // the function, it creates a wrapper function instead with a more
            // palatable name. That's preferable to rejecting the API entirely.
        | ApiDetail::ConcreteType  { .. }
        | ApiDetail::CType { .. }
        | ApiDetail::StringConstructor
        | ApiDetail::IgnoredItem { .. } => Ok(Some(api)),
    });

    // Reject any names which are duplicates within the cxx bridge mod,
    // that has a flat namespace.
    let mut names_found: HashMap<Ident, usize> = HashMap::new();
    for api in &intermediate {
        let my_name = cxxbridge_name(api);
        if let Some(name) = my_name {
            let e = names_found.entry(name).or_default();
            *e += 1usize;
        }
    }
    let mut results = Vec::new();
    convert_item_apis(intermediate, &mut results, |api| {
        let my_name = cxxbridge_name(&api);
        if let Some(name) = my_name {
            if *names_found.entry(name).or_default() > 1usize {
                Err(ConvertError::DuplicateCxxBridgeName)
            } else {
                Ok(Some(api))
            }
        } else {
            Ok(Some(api))
        }
    });
    results
}

fn cxxbridge_name(api: &Api<FnAnalysis>) -> Option<Ident> {
    match api.detail {
        ApiDetail::Function { ref analysis, .. } => Some(analysis.cxxbridge_name.clone()),
        ApiDetail::Enum { .. }
        | ApiDetail::ForwardDeclaration
        | ApiDetail::ConcreteType { .. }
        | ApiDetail::Typedef { .. }
        | ApiDetail::Struct { .. }
        | ApiDetail::CType { .. } => Some(api.name().get_final_ident()),
        ApiDetail::StringConstructor | ApiDetail::Const { .. } | ApiDetail::IgnoredItem { .. } => {
            None
        }
    }
}
<commit_msg>Validate namespace path elements.<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashMap;

use syn::Ident;

use crate::{
    conversion::{
        api::{Api, ApiDetail},
        error_reporter::convert_item_apis,
        ConvertError,
    },
    types::{validate_ident_ok_for_cxx, QualifiedName},
};

use super::fun::FnAnalysis;

/// If any items have names which can't be represented by cxx,
/// abort.
pub(crate) fn check_names(apis: Vec<Api<FnAnalysis>>) -> Vec<Api<FnAnalysis>> {
    let mut intermediate = Vec::new();
    convert_item_apis(apis, &mut intermediate, |api| match api.detail {
        ApiDetail::Typedef { .. }
        | ApiDetail::ForwardDeclaration
        | ApiDetail::Const { .. }
        | ApiDetail::Enum { .. }
        | ApiDetail::Struct { .. } => {
            validate_all_segments_ok_for_cxx(api.name.segment_iter())?;
            if let Some(ref cpp_name) = api.cpp_name {
                // The C++ name might itself be outer_type::inner_type and thus may
                // have multiple segments.
                validate_all_segments_ok_for_cxx(QualifiedName::new_from_cpp_name(cpp_name).segment_iter())?;
            }
            Ok(Some(api))
        }
        ApiDetail::Function { .. } // we don't handle functions here because
            // the function analysis does an equivalent check. Instead of just rejecting
            // the function, it creates a wrapper function instead with a more
            // palatable name. That's preferable to rejecting the API entirely.
        | ApiDetail::ConcreteType  { .. }
        | ApiDetail::CType { .. }
        | ApiDetail::StringConstructor
        | ApiDetail::IgnoredItem { .. } => Ok(Some(api)),
    });

    // Reject any names which are duplicates within the cxx bridge mod,
    // that has a flat namespace.
    let mut names_found: HashMap<Ident, usize> = HashMap::new();
    for api in &intermediate {
        let my_name = cxxbridge_name(api);
        if let Some(name) = my_name {
            let e = names_found.entry(name).or_default();
            *e += 1usize;
        }
    }
    let mut results = Vec::new();
    convert_item_apis(intermediate, &mut results, |api| {
        let my_name = cxxbridge_name(&api);
        if let Some(name) = my_name {
            if *names_found.entry(name).or_default() > 1usize {
                Err(ConvertError::DuplicateCxxBridgeName)
            } else {
                Ok(Some(api))
            }
        } else {
            Ok(Some(api))
        }
    });
    results
}

fn validate_all_segments_ok_for_cxx(
    items: impl Iterator<Item = String>,
) -> Result<(), ConvertError> {
    for seg in items {
        validate_ident_ok_for_cxx(&seg)?;
    }
    Ok(())
}

fn cxxbridge_name(api: &Api<FnAnalysis>) -> Option<Ident> {
    match api.detail {
        ApiDetail::Function { ref analysis, .. } => Some(analysis.cxxbridge_name.clone()),
        ApiDetail::Enum { .. }
        | ApiDetail::ForwardDeclaration
        | ApiDetail::ConcreteType { .. }
        | ApiDetail::Typedef { .. }
        | ApiDetail::Struct { .. }
        | ApiDetail::CType { .. } => Some(api.name().get_final_ident()),
        ApiDetail::StringConstructor | ApiDetail::Const { .. } | ApiDetail::IgnoredItem { .. } => {
            None
        }
    }
}
<|endoftext|>


<commit_before>// run-pass
// Test use of stabilized const fns in std formerly using individual feature gates.

use std::cell::Cell;

const CELL: Cell<i32> = Cell::new(42);

fn main() {
    let v = CELL.get();
    CELL.set(v+1);

    assert_eq!(CELL.get(), v);
}
<commit_msg>Rollup merge of #79227 - sasurau4:test/move-cell-test-to-lib-core, r=jyn514<commit_after><|endoftext|>