<commit_before>//
// Copyright 2020 The Project Oak Authors
//
// 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
//
//     http://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 crate::{
    metrics::METRICS,
    node::{grpc::codec::VecCodec, Node},
    pretty_name_for_thread,
    runtime::RuntimeProxy,
    Handle,
};
use hyper::service::Service;
use log::{debug, error, info, warn};
use oak_abi::{
    grpc::encap_request, label::Label, proto::oak::encap::GrpcRequest, ChannelReadStatus, OakStatus,
};
use prost::Message;
use std::{
    fmt::{self, Display, Formatter},
    net::SocketAddr,
    task::{Context, Poll},
    thread::{self, JoinHandle},
};
use tonic::{
    codegen::BoxFuture,
    server::{Grpc, UnaryService},
    transport::{Identity, NamedService},
};

/// Struct that represents a gRPC server pseudo-Node.
///
/// For each gRPC request from a client, gRPC server pseudo-Node creates a pair of temporary
/// channels (to write a request to and to read a response from) and passes corresponding handles to
/// the [`GrpcServerNode::channel_writer`].
#[derive(Clone)]
pub struct GrpcServerNode {
    /// Pseudo-Node name that corresponds to an entry from the [`ApplicationConfiguration`].
    ///
    /// [`ApplicationConfiguration`]: crate::proto::oak::application::ApplicationConfiguration
    config_name: String,
    /// Reference to a Runtime that corresponds to a Node that created a gRPC server pseudo-Node.
    runtime: RuntimeProxy,
    /// Server address to listen client requests on.
    address: SocketAddr,
    /// Loaded files containing a server TLS key and certificates.
    tls_identity: Identity,
    /// Channel handle used for reading a [`GrpcServerNode::channel_writer`] once the gRPC server
    /// pseudo-Node has started.
    initial_reader: Handle,
    /// Channel handle used for writing gRPC invocations.
    /// Is set after the [`GrpcServerNode::init_channel_writer`] is called.
    channel_writer: Option<Handle>,
}

impl Display for GrpcServerNode {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "GrpcServerNode({})", self.config_name)
    }
}

impl GrpcServerNode {
    /// Creates a new [`GrpcServerNode`] instance, but does not start it.
    ///
    /// `channel_writer` and `thread_handle` are initialized with `None`, because they will receive
    /// their values after the gRPC server pseudo-Node has started and a separate thread was
    /// initialized.
    pub fn new(
        config_name: &str,
        runtime: RuntimeProxy,
        address: SocketAddr,
        tls_identity: Identity,
        initial_reader: Handle,
    ) -> Self {
        Self {
            config_name: config_name.to_string(),
            runtime,
            address,
            tls_identity,
            initial_reader,
            channel_writer: None,
        }
    }

    /// Reads a [`Handle`] from a channel specified by [`GrpcServerNode::initial_reader`].
    /// Returns an error if couldn't read from the channel or if received a wrong number of handles
    /// (not equal to 1).
    fn init_channel_writer(&mut self) -> Result<(), OakStatus> {
        let read_status = self
            .runtime
            .wait_on_channels(&[self.initial_reader])
            .map_err(|error| {
                error!("Couldn't wait on the initial reader handle: {:?}", error);
                OakStatus::ErrInternal
            })?;

        let channel_writer = if read_status[0] == ChannelReadStatus::ReadReady {
            self.runtime
                .channel_read(self.initial_reader)
                .map_err(|error| {
                    error!("Couldn't read from the initial reader handle {:?}", error);
                    OakStatus::ErrInternal
                })
                .and_then(|message| {
                    message
                        .ok_or_else(|| {
                            error!("Empty message");
                            OakStatus::ErrInternal
                        })
                        .and_then(|m| {
                            if m.channels.len() == 1 {
                                Ok(m.channels[0])
                            } else {
                                error!(
                                    "gRPC server pseudo-Node should receive a single writer handle, found {}",
                                    m.channels.len()
                                );
                                Err(OakStatus::ErrInternal)
                            }
                        })
                })
        } else {
            error!("Couldn't read channel: {:?}", read_status[0]);
            Err(OakStatus::ErrInternal)
        }?;
        self.channel_writer = Some(channel_writer);

        warn!("Channel writer received: {:?}", self.channel_writer);
        Ok(())
    }

    /// Main Node worker thread.
    fn worker_thread(mut self) {
        let pretty_name = pretty_name_for_thread(&thread::current());

        // Receive a `channel_writer` handle used to pass handles for temporary channels.
        info!("{}: Waiting for a channel writer", pretty_name);
        self.init_channel_writer()
            .expect("Couldn't initialialize a channel writer");

        let handler = HttpRequestHandler {
            runtime: self.runtime.clone(),
            writer: self
                .channel_writer
                .expect("Channel writer is not initialized"),
        };

        // Handles incoming TLS connections, unpacks HTTP/2 requests and forwards them to
        // [`HttpRequestHandler::handle`].
        let server = tonic::transport::Server::builder()
            .tls_config(tonic::transport::ServerTlsConfig::new().identity(self.tls_identity))
            .add_service(handler)
            .serve(self.address);

        // Create an Async runtime for executing futures.
        // https://docs.rs/tokio/
        let mut async_runtime = tokio::runtime::Builder::new()
            // Use simple scheduler that runs all tasks on the current-thread.
            // https://docs.rs/tokio/0.2.16/tokio/runtime/index.html#basic-scheduler
            .basic_scheduler()
            // Enables the I/O driver.
            // Necessary for using net, process, signal, and I/O types on the Tokio runtime.
            .enable_io()
            .build()
            .expect("Couldn't create an Async runtime");

        // Start a gRPC server.
        info!(
            "{}: Starting a gRPC server pseudo-Node on: {}",
            pretty_name, self.address
        );
        let result = async_runtime.block_on(server);
        info!(
            "{}: Exiting gRPC server pseudo-Node thread {:?}",
            pretty_name, result
        );

        self.runtime.exit_node();
    }
}

/// Oak Node implementation for the gRPC server.
impl Node for GrpcServerNode {
    fn start(self: Box<Self>) -> Result<JoinHandle<()>, OakStatus> {
        let thread_handle = thread::Builder::new()
            .name(self.to_string())
            .spawn(move || self.worker_thread())
            .expect("Failed to spawn thread");
        Ok(thread_handle)
    }
}

/// [`HttpRequestHandler`] handles HTTP/2 requests from a client and sends HTTP/2 responses back.
#[derive(Clone)]
struct HttpRequestHandler {
    /// Reference to a Runtime that corresponds to a node that created a gRPC server pseudo-Node.
    runtime: RuntimeProxy,
    /// Channel handle used for writing gRPC invocations.
    writer: Handle,
}

// Set a mandatory prefix for all gRPC requests processed by a gRPC pseudo-Node.
impl NamedService for HttpRequestHandler {
    const NAME: &'static str = "oak";
}

impl Service<http::Request<hyper::Body>> for HttpRequestHandler {
    type Response = http::Response<tonic::body::BoxBody>;
    type Error = http::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        Poll::Ready(Ok(()))
    }

    // Decodes an unary gRPC request using a [`VecCodec`] and processes it with
    // [`tonic::server::Grpc::unary`] and a [`GrpcRequestHandler`].
    fn call(&mut self, request: http::Request<hyper::Body>) -> Self::Future {
        let grpc_handler = GrpcRequestHandler::new(
            self.runtime.clone(),
            self.writer,
            request.uri().path().to_string(),
        );

        let future = async move {
            debug!("Processing an HTTP/2 request: {:?}", request);
            let mut grpc_service = Grpc::new(VecCodec::default());
            let response = grpc_service.unary(grpc_handler, request).await;
            debug!("Sending an HTTP/2 response: {:?}", response);
            Ok(response)
        };

        Box::pin(future)
    }
}

/// [`GrpcRequestHandler`] handles gRPC requests and generates gRPC responses.
#[derive(Clone)]
struct GrpcRequestHandler {
    /// Reference to a Runtime that corresponds to the Node that created a gRPC server pseudo-Node.
    runtime: RuntimeProxy,
    /// Channel handle used for writing gRPC invocations.
    writer: Handle,
    /// Name of the gRPC method that should be invoked.
    method_name: String,
}

impl UnaryService<Vec<u8>> for GrpcRequestHandler {
    type Response = Vec<u8>;
    type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;

    fn call(&mut self, request: tonic::Request<Vec<u8>>) -> Self::Future {
        let handler = self.clone();
        let future = async move {
            debug!("Processing a gRPC request: {:?}", request);
            METRICS.grpc_requests_total.inc();
            let timer = METRICS.grpc_request_duration.start_timer();

            // Decode a gRPC request.
            let grpc_request =
                encap_request(request.get_ref(), &handler.method_name).ok_or_else(|| {
                    let warning = "Failed to parse an incoming Protobuf message";
                    warn!("{}", warning);
                    tonic::Status::new(tonic::Code::InvalidArgument, warning)
                })?;

            let response = handler
                // Handle a gRPC request and send it into the Runtime.
                .handle_grpc_request(grpc_request)
                // Read a gRPC response from the Runtime.
                .and_then(|response_reader| handler.handle_grpc_response(response_reader))
                // Convert an error to a gRPC error status without sending clients descriptions for
                // internal errors.
                // Errors are logged inside inside [`GrpcRequestHandler::handle_grpc_request`] and
                // [`GrpcRequestHandler::handle_grpc_response`].
                .map_err(|_| tonic::Status::new(tonic::Code::Internal, ""))?;

            // Send a gRPC response back to the client.
            debug!("Sending a gRPC response: {:?}", response);
            timer.observe_duration();
            Ok(tonic::Response::new(response))
        };

        Box::pin(future)
    }
}

impl GrpcRequestHandler {
    fn new(runtime: RuntimeProxy, writer: Handle, method_name: String) -> Self {
        Self {
            runtime,
            writer,
            method_name,
        }
    }

    /// Handles a gRPC request, forwards it to a temporary channel and sends handles for this
    /// channel to the [`GrpcServerNode::channel_writer`].
    /// Returns a [`Handle`] for reading a gRPC response from.
    fn handle_grpc_request(&self, request: GrpcRequest) -> Result<Handle, OakStatus> {
        // Create a pair of temporary channels to pass the gRPC request and to receive the response.
        let (request_writer, request_reader) =
            self.runtime.channel_create(&Label::public_trusted());
        let (response_writer, response_reader) =
            self.runtime.channel_create(&Label::public_trusted());

        // Create an invocation message and attach the method-invocation specific channels to it.
        //
        // This message should be in sync with the [`oak::grpc::Invocation`] from the Oak SDK:
        // the order of the `request_reader` and `response_writer` must be consistent.
        let invocation = crate::Message {
            data: vec![],
            channels: vec![request_reader, response_writer],
        };

        // Serialize gRPC request into a message.
        let mut message = crate::Message {
            data: vec![],
            channels: vec![],
        };
        request.encode(&mut message.data).map_err(|error| {
            error!("Couldn't serialize a GrpcRequest message: {}", error);
            OakStatus::ErrInternal
        })?;

        // Send a message to the temporary channel.
        self.runtime
            .channel_write(request_writer, message)
            .map_err(|error| {
                error!(
                    "Couldn't write a message to the temporary channel: {:?}",
                    error
                );
                error
            })?;

        // Send an invocation message (with attached handles) to the Oak Node.
        self.runtime
            .channel_write(self.writer, invocation)
            .map_err(|error| {
                error!("Couldn't write a gRPC invocation message: {:?}", error);
                error
            })?;

        Ok(response_reader)
    }

    /// Handles a gRPC response from a channel represented by `response_reader` and returns a
    /// gRPC response body.
    fn handle_grpc_response(&self, response_reader: Handle) -> Result<Vec<u8>, OakStatus> {
        let read_status = self
            .runtime
            .wait_on_channels(&[response_reader])
            .map_err(|error| {
                error!("Couldn't wait on the temporary gRPC channel: {:?}", error);
                error
            })?;

        if read_status[0] == ChannelReadStatus::ReadReady {
            self.runtime
                .channel_read(response_reader)
                .map_err(|error| {
                    error!("Couldn't read from a temporary gRPC channel: {:?}", error);
                    error
                })
                .map(|message| {
                    // Return an empty HTTP body if the `message` is None.
                    message.map_or(vec![], |m| {
                        METRICS.grpc_response_size.observe(m.data.len() as f64);
                        m.data
                    })
                })
        } else {
            error!(
                "Couldn't read from a temporary gRPC channel: {:?}",
                read_status[0]
            );
            Err(OakStatus::ErrInternal)
        }
    }
}
<commit_msg>Fix gRPC request handling (#952)<commit_after>//
// Copyright 2020 The Project Oak Authors
//
// 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
//
//     http://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 crate::{
    metrics::METRICS,
    node::{grpc::codec::VecCodec, Node},
    pretty_name_for_thread,
    runtime::RuntimeProxy,
    Handle,
};
use hyper::service::Service;
use log::{debug, error, info, warn};
use oak_abi::{label::Label, proto::oak::encap::GrpcRequest, ChannelReadStatus, OakStatus};
use prost::Message;
use std::{
    fmt::{self, Display, Formatter},
    net::SocketAddr,
    task::{Context, Poll},
    thread::{self, JoinHandle},
};
use tonic::{
    codegen::BoxFuture,
    server::{Grpc, UnaryService},
    transport::{Identity, NamedService},
};

/// Struct that represents a gRPC server pseudo-Node.
///
/// For each gRPC request from a client, gRPC server pseudo-Node creates a pair of temporary
/// channels (to write a request to and to read a response from) and passes corresponding handles to
/// the [`GrpcServerNode::channel_writer`].
#[derive(Clone)]
pub struct GrpcServerNode {
    /// Pseudo-Node name that corresponds to an entry from the [`ApplicationConfiguration`].
    ///
    /// [`ApplicationConfiguration`]: crate::proto::oak::application::ApplicationConfiguration
    config_name: String,
    /// Reference to a Runtime that corresponds to a Node that created a gRPC server pseudo-Node.
    runtime: RuntimeProxy,
    /// Server address to listen client requests on.
    address: SocketAddr,
    /// Loaded files containing a server TLS key and certificates.
    tls_identity: Identity,
    /// Channel handle used for reading a [`GrpcServerNode::channel_writer`] once the gRPC server
    /// pseudo-Node has started.
    initial_reader: Handle,
    /// Channel handle used for writing gRPC invocations.
    /// Is set after the [`GrpcServerNode::init_channel_writer`] is called.
    channel_writer: Option<Handle>,
}

impl Display for GrpcServerNode {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "GrpcServerNode({})", self.config_name)
    }
}

impl GrpcServerNode {
    /// Creates a new [`GrpcServerNode`] instance, but does not start it.
    ///
    /// `channel_writer` and `thread_handle` are initialized with `None`, because they will receive
    /// their values after the gRPC server pseudo-Node has started and a separate thread was
    /// initialized.
    pub fn new(
        config_name: &str,
        runtime: RuntimeProxy,
        address: SocketAddr,
        tls_identity: Identity,
        initial_reader: Handle,
    ) -> Self {
        Self {
            config_name: config_name.to_string(),
            runtime,
            address,
            tls_identity,
            initial_reader,
            channel_writer: None,
        }
    }

    /// Reads a [`Handle`] from a channel specified by [`GrpcServerNode::initial_reader`].
    /// Returns an error if couldn't read from the channel or if received a wrong number of handles
    /// (not equal to 1).
    fn init_channel_writer(&mut self) -> Result<(), OakStatus> {
        let read_status = self
            .runtime
            .wait_on_channels(&[self.initial_reader])
            .map_err(|error| {
                error!("Couldn't wait on the initial reader handle: {:?}", error);
                OakStatus::ErrInternal
            })?;

        let channel_writer = if read_status[0] == ChannelReadStatus::ReadReady {
            self.runtime
                .channel_read(self.initial_reader)
                .map_err(|error| {
                    error!("Couldn't read from the initial reader handle {:?}", error);
                    OakStatus::ErrInternal
                })
                .and_then(|message| {
                    message
                        .ok_or_else(|| {
                            error!("Empty message");
                            OakStatus::ErrInternal
                        })
                        .and_then(|m| {
                            if m.channels.len() == 1 {
                                Ok(m.channels[0])
                            } else {
                                error!(
                                    "gRPC server pseudo-Node should receive a single writer handle, found {}",
                                    m.channels.len()
                                );
                                Err(OakStatus::ErrInternal)
                            }
                        })
                })
        } else {
            error!("Couldn't read channel: {:?}", read_status[0]);
            Err(OakStatus::ErrInternal)
        }?;
        self.channel_writer = Some(channel_writer);

        warn!("Channel writer received: {:?}", self.channel_writer);
        Ok(())
    }

    /// Main Node worker thread.
    fn worker_thread(mut self) {
        let pretty_name = pretty_name_for_thread(&thread::current());

        // Receive a `channel_writer` handle used to pass handles for temporary channels.
        info!("{}: Waiting for a channel writer", pretty_name);
        self.init_channel_writer()
            .expect("Couldn't initialialize a channel writer");

        let handler = HttpRequestHandler {
            runtime: self.runtime.clone(),
            writer: self
                .channel_writer
                .expect("Channel writer is not initialized"),
        };

        // Handles incoming TLS connections, unpacks HTTP/2 requests and forwards them to
        // [`HttpRequestHandler::handle`].
        let server = tonic::transport::Server::builder()
            .tls_config(tonic::transport::ServerTlsConfig::new().identity(self.tls_identity))
            .add_service(handler)
            .serve(self.address);

        // Create an Async runtime for executing futures.
        // https://docs.rs/tokio/
        let mut async_runtime = tokio::runtime::Builder::new()
            // Use simple scheduler that runs all tasks on the current-thread.
            // https://docs.rs/tokio/0.2.16/tokio/runtime/index.html#basic-scheduler
            .basic_scheduler()
            // Enables the I/O driver.
            // Necessary for using net, process, signal, and I/O types on the Tokio runtime.
            .enable_io()
            .build()
            .expect("Couldn't create an Async runtime");

        // Start a gRPC server.
        info!(
            "{}: Starting a gRPC server pseudo-Node on: {}",
            pretty_name, self.address
        );
        let result = async_runtime.block_on(server);
        info!(
            "{}: Exiting gRPC server pseudo-Node thread {:?}",
            pretty_name, result
        );

        self.runtime.exit_node();
    }
}

/// Oak Node implementation for the gRPC server.
impl Node for GrpcServerNode {
    fn start(self: Box<Self>) -> Result<JoinHandle<()>, OakStatus> {
        let thread_handle = thread::Builder::new()
            .name(self.to_string())
            .spawn(move || self.worker_thread())
            .expect("Failed to spawn thread");
        Ok(thread_handle)
    }
}

/// [`HttpRequestHandler`] handles HTTP/2 requests from a client and sends HTTP/2 responses back.
#[derive(Clone)]
struct HttpRequestHandler {
    /// Reference to a Runtime that corresponds to a node that created a gRPC server pseudo-Node.
    runtime: RuntimeProxy,
    /// Channel handle used for writing gRPC invocations.
    writer: Handle,
}

// Set a mandatory prefix for all gRPC requests processed by a gRPC pseudo-Node.
impl NamedService for HttpRequestHandler {
    const NAME: &'static str = "oak";
}

impl Service<http::Request<hyper::Body>> for HttpRequestHandler {
    type Response = http::Response<tonic::body::BoxBody>;
    type Error = http::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        Poll::Ready(Ok(()))
    }

    // Decodes an unary gRPC request using a [`VecCodec`] and processes it with
    // [`tonic::server::Grpc::unary`] and a [`GrpcRequestHandler`].
    fn call(&mut self, request: http::Request<hyper::Body>) -> Self::Future {
        let grpc_handler = GrpcRequestHandler::new(
            self.runtime.clone(),
            self.writer,
            request.uri().path().to_string(),
        );

        let future = async move {
            debug!("Processing an HTTP/2 request: {:?}", request);
            let mut grpc_service = Grpc::new(VecCodec::default());
            let response = grpc_service.unary(grpc_handler, request).await;
            debug!("Sending an HTTP/2 response: {:?}", response);
            Ok(response)
        };

        Box::pin(future)
    }
}

/// [`GrpcRequestHandler`] handles gRPC requests and generates gRPC responses.
#[derive(Clone)]
struct GrpcRequestHandler {
    /// Reference to a Runtime that corresponds to the Node that created a gRPC server pseudo-Node.
    runtime: RuntimeProxy,
    /// Channel handle used for writing gRPC invocations.
    writer: Handle,
    /// Name of the gRPC method that should be invoked.
    method_name: String,
}

impl UnaryService<Vec<u8>> for GrpcRequestHandler {
    type Response = Vec<u8>;
    type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;

    fn call(&mut self, request: tonic::Request<Vec<u8>>) -> Self::Future {
        let handler = self.clone();
        let future = async move {
            debug!("Processing a gRPC request: {:?}", request);
            METRICS.grpc_requests_total.inc();
            let timer = METRICS.grpc_request_duration.start_timer();

            // Create a gRPC request.
            // TODO(#953): Add streaming support.
            let grpc_request = GrpcRequest {
                method_name: handler.method_name.to_string(),
                req_msg: request.into_inner(),
                last: true,
            };

            let response = handler
                // Handle a gRPC request and send it into the Runtime.
                .handle_grpc_request(grpc_request)
                // Read a gRPC response from the Runtime.
                .and_then(|response_reader| handler.handle_grpc_response(response_reader))
                // Convert an error to a gRPC error status without sending clients descriptions for
                // internal errors.
                // Errors are logged inside inside [`GrpcRequestHandler::handle_grpc_request`] and
                // [`GrpcRequestHandler::handle_grpc_response`].
                .map_err(|_| tonic::Status::new(tonic::Code::Internal, ""))?;

            // Send a gRPC response back to the client.
            debug!("Sending a gRPC response: {:?}", response);
            timer.observe_duration();
            Ok(tonic::Response::new(response))
        };

        Box::pin(future)
    }
}

impl GrpcRequestHandler {
    fn new(runtime: RuntimeProxy, writer: Handle, method_name: String) -> Self {
        Self {
            runtime,
            writer,
            method_name,
        }
    }

    /// Handles a gRPC request, forwards it to a temporary channel and sends handles for this
    /// channel to the [`GrpcServerNode::channel_writer`].
    /// Returns a [`Handle`] for reading a gRPC response from.
    fn handle_grpc_request(&self, request: GrpcRequest) -> Result<Handle, OakStatus> {
        // Create a pair of temporary channels to pass the gRPC request and to receive the response.
        let (request_writer, request_reader) =
            self.runtime.channel_create(&Label::public_trusted());
        let (response_writer, response_reader) =
            self.runtime.channel_create(&Label::public_trusted());

        // Create an invocation message and attach the method-invocation specific channels to it.
        //
        // This message should be in sync with the [`oak::grpc::Invocation`] from the Oak SDK:
        // the order of the `request_reader` and `response_writer` must be consistent.
        let invocation = crate::Message {
            data: vec![],
            channels: vec![request_reader, response_writer],
        };

        // Serialize gRPC request into a message.
        let mut message = crate::Message {
            data: vec![],
            channels: vec![],
        };
        request.encode(&mut message.data).map_err(|error| {
            error!("Couldn't serialize a GrpcRequest message: {}", error);
            OakStatus::ErrInternal
        })?;

        // Send a message to the temporary channel.
        self.runtime
            .channel_write(request_writer, message)
            .map_err(|error| {
                error!(
                    "Couldn't write a message to the temporary channel: {:?}",
                    error
                );
                error
            })?;

        // Send an invocation message (with attached handles) to the Oak Node.
        self.runtime
            .channel_write(self.writer, invocation)
            .map_err(|error| {
                error!("Couldn't write a gRPC invocation message: {:?}", error);
                error
            })?;

        Ok(response_reader)
    }

    /// Handles a gRPC response from a channel represented by `response_reader` and returns a
    /// gRPC response body.
    fn handle_grpc_response(&self, response_reader: Handle) -> Result<Vec<u8>, OakStatus> {
        let read_status = self
            .runtime
            .wait_on_channels(&[response_reader])
            .map_err(|error| {
                error!("Couldn't wait on the temporary gRPC channel: {:?}", error);
                error
            })?;

        if read_status[0] == ChannelReadStatus::ReadReady {
            self.runtime
                .channel_read(response_reader)
                .map_err(|error| {
                    error!("Couldn't read from a temporary gRPC channel: {:?}", error);
                    error
                })
                .map(|message| {
                    // Return an empty HTTP body if the `message` is None.
                    message.map_or(vec![], |m| {
                        METRICS.grpc_response_size.observe(m.data.len() as f64);
                        m.data
                    })
                })
        } else {
            error!(
                "Couldn't read from a temporary gRPC channel: {:?}",
                read_status[0]
            );
            Err(OakStatus::ErrInternal)
        }
    }
}
<|endoftext|>


<commit_before>use std::alloc::alloc;
use std::alloc::dealloc;
use std::alloc::Layout;
use std::mem::size_of;
use std::ptr::null_mut;

const _PAGE_SIZE: usize = 0x1000;

pub struct _Page {
    current_page: *mut _Page,
    next_object_offset: i32,
    exclusive_pages: i32,
}

impl _Page {
    pub fn reset(&mut self) {
        unsafe {
            *(self.get_extension_page_location()) = null_mut();
        }
        self.next_object_offset = size_of::<_Page>() as i32;
        self.exclusive_pages = 0;
        self.current_page = &mut *self;
    }

    pub fn clear(&mut self) {
        self.deallocate_extensions();
        self.reset();
    }

    pub fn is_oversized(&self) -> bool {
        self.current_page.is_null()
    }

    fn get_extension_page_location(&self) -> *mut *mut _Page {
        // Convert self to page location
        let self_location = self as *const _Page as usize;

        // Advance one page size so we are past the end of our page
        let location_behind_page = (self_location + _PAGE_SIZE) as *mut *mut _Page;

        // Go back one pointer size
        unsafe { location_behind_page.offset(-1) }
    }

    fn get_next_location(&self) -> usize {
        self as *const _Page as usize + self.next_object_offset as usize
    }

    fn set_next_location(&mut self, location: usize) {
        let self_location = self as *const _Page as usize;
        self.next_object_offset = (location - self_location as usize) as i32;
    }

    fn get_next_exclusive_page_location(&self) -> *mut *mut _Page {
        unsafe {
            self.get_extension_page_location()
                .offset(-(self.exclusive_pages as isize + 1))
        }
    }

    pub fn allocate_raw(&mut self, size: usize, align: usize) -> *mut u8 {
        if self as *mut _Page != self.current_page {
            unsafe {
                // We're already known to be full, so we delegate to the current page
                let new_object = (*self.current_page).allocate_raw(size, align);

                // Possibly our current page was also full so we propagate back the new current page
                let allocating_page = _Page::get_page(new_object);
                if allocating_page != self.current_page && (!(*allocating_page).is_oversized()) {
                    self.current_page = allocating_page;
                }
                return new_object;
            }
        }

        // Try to allocate from ourselves
        let location = self.get_next_location();
        let aligned_location = (location + align - 1) & !(align - 1);
        let next_location = aligned_location + size;
        if next_location <= self.get_next_exclusive_page_location() as usize {
            self.set_next_location(next_location);
            return location as *mut u8;
        }

        // So the space did not fit.

        // Calculate gross size to decide whether we're oversized
        if size_of::<_Page>() + size + size_of::<*mut *mut _Page>() > _PAGE_SIZE {
            if self.get_next_location() >= self.get_next_exclusive_page_location() as usize {
                // Allocate an extension page and try again with it
                unsafe {
                    return (*self.allocate_extension_page()).allocate_raw(size, align);
                }
            }

            unsafe {
                // We allocate oversized objects directly.
                let memory = alloc(Layout::from_size_align_unchecked(
                    size + size_of::<_Page>(),
                    _PAGE_SIZE,
                ));

                // Initialize a _Page object at the page start
                let page = memory as *mut _Page;

                // Oversized pages have no current_page
                (*page).current_page = null_mut();

                // Set the size since we will need it when deallocating
                (*page).next_object_offset = (size % 0x100000000) as i32;
                (*page).exclusive_pages = (size / 0x100000000) as i32;

                *(self.get_next_exclusive_page_location()) = page;
                self.exclusive_pages += 1;
                return page.offset(1) as *mut u8;
            }
        }

        // So we're not oversized. Create extension page and let it allocate.
        unsafe { (*self.allocate_extension_page()).allocate_raw(size, align) }
    }

    fn allocate_extension_page(&mut self) -> *mut _Page {
        unsafe {
            let page = _Page::allocate_page();
            *(self.get_extension_page_location()) = page;
            self.current_page = page;
            &mut *page
        }
    }

    fn allocate_page() -> *mut _Page {
        unsafe {
            let page =
                alloc(Layout::from_size_align_unchecked(_PAGE_SIZE, _PAGE_SIZE)) as *mut _Page;
            (*page).reset();
            page
        }
    }

    pub fn allocate_exclusive_page(&mut self) -> *mut _Page {
        unsafe {
            if self as *mut _Page != self.current_page {
                // We're already known to be full, so we delegate to the current page
                return (*self.current_page).allocate_exclusive_page();
            }

            // Check first whether we need an ordinary extension
            if self.get_next_location() as usize >= self.get_next_exclusive_page_location() as usize
            {
                // Allocate an extension page with default size
                return (*self.allocate_extension_page()).allocate_exclusive_page();
            }

            let page = _Page::allocate_page();
            *(self.get_next_exclusive_page_location()) = page;
            self.exclusive_pages += 1;
            &mut *page
        }
    }

    pub fn extend(&mut self, top: usize, size: usize) -> bool {
        if top != self.get_next_location() {
            return false;
        }

        let new_top = top + size;
        if new_top > self.get_next_exclusive_page_location() as usize {
            return false;
        }
        self.set_next_location(new_top);

        true
    }

    fn deallocate_extensions(&mut self) {
        let mut page: *mut _Page = self;
        unsafe {
            while !page.is_null() {
                let extension_pointer = (*page).get_extension_page_location();
                for i in 1..(*page).exclusive_pages {
                    let mut exclusive_page = &mut **(extension_pointer.offset(-(i as isize)));
                    if !exclusive_page.is_oversized() {
                        exclusive_page.deallocate_extensions();
                    }
                    exclusive_page.forget();
                }

                if page != self as *mut _Page {
                    (*page).forget();
                }

                page = *extension_pointer;
            }
        }
    }

    pub fn forget(&self) {
        let size = if self.current_page == null_mut() {
            self.next_object_offset as usize + self.exclusive_pages as usize * 0x100000000
        } else {
            _PAGE_SIZE
        };
        unsafe {
            dealloc(
                self as *const _Page as *mut u8,
                Layout::from_size_align_unchecked(size, _PAGE_SIZE),
            )
        }
    }

    pub fn reclaim_array(&mut self, address: usize) -> bool {
        unsafe {
            let mut page: *mut _Page = self;
            while !page.is_null() {
                if (*page).deallocate_exclusive_page(address as *mut _Page) {
                    return true;
                }
                page = *(*page).get_extension_page_location();
            }
        }

        // If we arrive here, we have a memory leak.
        false
    }

    pub fn get_page(address: *mut u8) -> *mut _Page {
        unsafe { &mut *((address as usize & !_PAGE_SIZE - 1) as *mut _Page) }
    }

    fn deallocate_exclusive_page(&mut self, page: *mut _Page) -> bool {
        unsafe {
            // Find the extension Page pointer
            let mut extension_pointer = self.get_extension_page_location().offset(-1);
            let next_extension_page_location = self.get_next_exclusive_page_location();
            while extension_pointer > next_extension_page_location {
                if *extension_pointer == page {
                    break;
                }
                extension_pointer = extension_pointer.offset(-1);
            }

            // Report if we could not find it
            if extension_pointer == next_extension_page_location {
                return false;
            }

            // Shift the remaining array one position up
            while extension_pointer > next_extension_page_location {
                let pp_page = extension_pointer;
                *pp_page = *(pp_page.offset(-1));
                extension_pointer = extension_pointer.offset(-1);
            }
        }

        // Make room for one more extension
        self.exclusive_pages -= 1;
        unsafe {
            (*page).forget();
        }

        true
    }
}

#[test]
fn test_page() {
    unsafe {
        // Allocate a page
        let memory = alloc(Layout::from_size_align_unchecked(_PAGE_SIZE, _PAGE_SIZE));
        assert_ne!(memory, null_mut());

        // Write some numbers to the page memory
        for i in 0.._PAGE_SIZE {
            let ptr = memory.offset(i as isize);
            *ptr = i as u8
        }

        // Initialize a _Page object at the page start
        let page = &mut *(memory as *mut _Page);

        assert_ne!(page.next_object_offset, 0);
        assert_ne!(page.exclusive_pages, 0);

        page.reset();

        assert_eq!(page.next_object_offset, size_of::<_Page>() as i32);
        assert_eq!(page.exclusive_pages, 0);
        assert_eq!(page.is_oversized(), false);
        assert_eq!(page as *mut _Page, page.current_page);

        {
            let extension_page_location = page.get_extension_page_location();
            assert_eq!(
                extension_page_location as usize,
                page as *const _Page as usize + _PAGE_SIZE - size_of::<*mut *mut _Page>()
            );
        }

        {
            let mut location = page.get_next_location();
            assert_eq!(
                location as usize,
                page as *const _Page as usize + size_of::<_Page>()
            );

            let answer = page.allocate_raw(1, 1);
            location += 1;
            assert_eq!(page.get_next_location(), location);
            *answer = 42;

            let another = page.allocate_raw(1, 2);
            location += 2;
            assert_eq!(page.get_next_location(), location);
            *another = 43;

            let eau = page.allocate_raw(4, 4) as *mut i32;
            location += 5;
            assert_eq!(page.get_next_location(), location);
            *eau = 4711;

            // Allocate an oversized page which should cause allocating an exclusive page
            let array = page.allocate_raw(_PAGE_SIZE, 8) as *mut usize;
            for i in 0.._PAGE_SIZE / size_of::<usize>() - 1 {
                *(array.offset(i as isize)) = i;
            }
            assert_eq!(page.get_next_location(), location);
            assert_eq!(page as *mut _Page, page.current_page);

            // Overflow the page
            for _ in 0.._PAGE_SIZE {
                page.allocate_raw(1, 1);
            }
            assert_ne!(page as *mut _Page, page.current_page);
            assert_eq!(*(page.get_extension_page_location()), page.current_page);
            assert_eq!((*page.current_page).exclusive_pages, 0);
            assert_eq!((*page.current_page).current_page, page.current_page);

            assert_eq!(page.exclusive_pages, 1);
            assert_eq!(*answer, 42);
            assert_eq!(*another, 43);
            assert_eq!(*eau, 4711);

            let exclusive_page = page.get_next_exclusive_page_location().offset(1);
            assert_eq!((**exclusive_page).current_page, null_mut());

            page.clear();
            assert_eq!(page.exclusive_pages, 0);
            page.forget();
        }
    }
}
<commit_msg>fixed get_page<commit_after>use std::alloc::alloc;
use std::alloc::dealloc;
use std::alloc::Layout;
use std::mem::size_of;
use std::ptr::null_mut;

const _PAGE_SIZE: usize = 0x1000;

pub struct _Page {
    current_page: *mut _Page,
    next_object_offset: i32,
    exclusive_pages: i32,
}

impl _Page {
    pub fn reset(&mut self) {
        unsafe {
            *(self.get_extension_page_location()) = null_mut();
        }
        self.next_object_offset = size_of::<_Page>() as i32;
        self.exclusive_pages = 0;
        self.current_page = &mut *self;
    }

    pub fn clear(&mut self) {
        self.deallocate_extensions();
        self.reset();
    }

    pub fn is_oversized(&self) -> bool {
        self.current_page.is_null()
    }

    fn get_extension_page_location(&self) -> *mut *mut _Page {
        // Convert self to page location
        let self_location = self as *const _Page as usize;

        // Advance one page size so we are past the end of our page
        let location_behind_page = (self_location + _PAGE_SIZE) as *mut *mut _Page;

        // Go back one pointer size
        unsafe { location_behind_page.offset(-1) }
    }

    fn get_next_location(&self) -> usize {
        self as *const _Page as usize + self.next_object_offset as usize
    }

    fn set_next_location(&mut self, location: usize) {
        let self_location = self as *const _Page as usize;
        self.next_object_offset = (location - self_location as usize) as i32;
    }

    fn get_next_exclusive_page_location(&self) -> *mut *mut _Page {
        unsafe {
            self.get_extension_page_location()
                .offset(-(self.exclusive_pages as isize + 1))
        }
    }

    pub fn allocate_raw(&mut self, size: usize, align: usize) -> *mut u8 {
        if self as *mut _Page != self.current_page {
            unsafe {
                // We're already known to be full, so we delegate to the current page
                let new_object = (*self.current_page).allocate_raw(size, align);

                // Possibly our current page was also full so we propagate back the new current page
                let allocating_page = _Page::get_page(new_object as usize);
                if allocating_page != self.current_page && (!(*allocating_page).is_oversized()) {
                    self.current_page = allocating_page;
                }
                return new_object;
            }
        }

        // Try to allocate from ourselves
        let location = self.get_next_location();
        let aligned_location = (location + align - 1) & !(align - 1);
        let next_location = aligned_location + size;
        if next_location <= self.get_next_exclusive_page_location() as usize {
            self.set_next_location(next_location);
            return location as *mut u8;
        }

        // So the space did not fit.

        // Calculate gross size to decide whether we're oversized
        if size_of::<_Page>() + size + size_of::<*mut *mut _Page>() > _PAGE_SIZE {
            if self.get_next_location() >= self.get_next_exclusive_page_location() as usize {
                // Allocate an extension page and try again with it
                unsafe {
                    return (*self.allocate_extension_page()).allocate_raw(size, align);
                }
            }

            unsafe {
                // We allocate oversized objects directly.
                let memory = alloc(Layout::from_size_align_unchecked(
                    size + size_of::<_Page>(),
                    _PAGE_SIZE,
                ));

                // Initialize a _Page object at the page start
                let page = memory as *mut _Page;

                // Oversized pages have no current_page
                (*page).current_page = null_mut();

                // Set the size since we will need it when deallocating
                (*page).next_object_offset = (size % 0x100000000) as i32;
                (*page).exclusive_pages = (size / 0x100000000) as i32;

                *(self.get_next_exclusive_page_location()) = page;
                self.exclusive_pages += 1;
                return page.offset(1) as *mut u8;
            }
        }

        // So we're not oversized. Create extension page and let it allocate.
        unsafe { (*self.allocate_extension_page()).allocate_raw(size, align) }
    }

    fn allocate_extension_page(&mut self) -> *mut _Page {
        unsafe {
            let page = _Page::allocate_page();
            *(self.get_extension_page_location()) = page;
            self.current_page = page;
            &mut *page
        }
    }

    fn allocate_page() -> *mut _Page {
        unsafe {
            let page =
                alloc(Layout::from_size_align_unchecked(_PAGE_SIZE, _PAGE_SIZE)) as *mut _Page;
            (*page).reset();
            page
        }
    }

    pub fn allocate_exclusive_page(&mut self) -> *mut _Page {
        unsafe {
            if self as *mut _Page != self.current_page {
                // We're already known to be full, so we delegate to the current page
                return (*self.current_page).allocate_exclusive_page();
            }

            // Check first whether we need an ordinary extension
            if self.get_next_location() as usize >= self.get_next_exclusive_page_location() as usize
            {
                // Allocate an extension page with default size
                return (*self.allocate_extension_page()).allocate_exclusive_page();
            }

            let page = _Page::allocate_page();
            *(self.get_next_exclusive_page_location()) = page;
            self.exclusive_pages += 1;
            &mut *page
        }
    }

    pub fn extend(&mut self, top: usize, size: usize) -> bool {
        if top != self.get_next_location() {
            return false;
        }

        let new_top = top + size;
        if new_top > self.get_next_exclusive_page_location() as usize {
            return false;
        }
        self.set_next_location(new_top);

        true
    }

    fn deallocate_extensions(&mut self) {
        let mut page: *mut _Page = self;
        unsafe {
            while !page.is_null() {
                let extension_pointer = (*page).get_extension_page_location();
                for i in 1..(*page).exclusive_pages {
                    let mut exclusive_page = &mut **(extension_pointer.offset(-(i as isize)));
                    if !exclusive_page.is_oversized() {
                        exclusive_page.deallocate_extensions();
                    }
                    exclusive_page.forget();
                }

                if page != self as *mut _Page {
                    (*page).forget();
                }

                page = *extension_pointer;
            }
        }
    }

    pub fn forget(&self) {
        let size = if self.current_page == null_mut() {
            self.next_object_offset as usize + self.exclusive_pages as usize * 0x100000000
        } else {
            _PAGE_SIZE
        };
        unsafe {
            dealloc(
                self as *const _Page as *mut u8,
                Layout::from_size_align_unchecked(size, _PAGE_SIZE),
            )
        }
    }

    pub fn reclaim_array(&mut self, address: *mut _Page) -> bool {
        unsafe {
            let mut page: *mut _Page = self;
            while !page.is_null() {
                if (*page).deallocate_exclusive_page(address) {
                    return true;
                }
                page = *(*page).get_extension_page_location();
            }
        }

        // If we arrive here, we have a memory leak.
        false
    }

    pub fn get_page(address: usize) -> *mut _Page {
        (address & !(_PAGE_SIZE - 1)) as *mut _Page
    }

    fn deallocate_exclusive_page(&mut self, page: *mut _Page) -> bool {
        unsafe {
            // Find the extension Page pointer
            let mut extension_pointer = self.get_extension_page_location().offset(-1);
            let next_extension_page_location = self.get_next_exclusive_page_location();
            while extension_pointer > next_extension_page_location {
                if *extension_pointer == page {
                    break;
                }
                extension_pointer = extension_pointer.offset(-1);
            }

            // Report if we could not find it
            if extension_pointer == next_extension_page_location {
                return false;
            }

            // Shift the remaining array one position up
            while extension_pointer > next_extension_page_location {
                let pp_page = extension_pointer;
                *pp_page = *(pp_page.offset(-1));
                extension_pointer = extension_pointer.offset(-1);
            }
        }

        // Make room for one more extension
        self.exclusive_pages -= 1;
        unsafe {
            (*page).forget();
        }

        true
    }
}

#[test]
fn test_page() {
    unsafe {
        // Allocate a page
        let memory = alloc(Layout::from_size_align_unchecked(_PAGE_SIZE, _PAGE_SIZE));
        assert_ne!(memory, null_mut());

        // Write some numbers to the page memory
        for i in 0.._PAGE_SIZE {
            let ptr = memory.offset(i as isize);
            *ptr = i as u8
        }

        // Initialize a _Page object at the page start
        let page = &mut *(memory as *mut _Page);

        assert_ne!(page.next_object_offset, 0);
        assert_ne!(page.exclusive_pages, 0);

        page.reset();

        assert_eq!(page.next_object_offset, size_of::<_Page>() as i32);
        assert_eq!(page.exclusive_pages, 0);
        assert_eq!(page.is_oversized(), false);
        assert_eq!(page as *mut _Page, page.current_page);

        {
            let extension_page_location = page.get_extension_page_location();
            assert_eq!(
                extension_page_location as usize,
                page as *const _Page as usize + _PAGE_SIZE - size_of::<*mut *mut _Page>()
            );
        }

        {
            let mut location = page.get_next_location();
            assert_eq!(
                location as usize,
                page as *const _Page as usize + size_of::<_Page>()
            );

            let answer = page.allocate_raw(1, 1);
            location += 1;
            assert_eq!(page.get_next_location(), location);
            *answer = 42;

            let another = page.allocate_raw(1, 2);
            location += 2;
            assert_eq!(page.get_next_location(), location);
            *another = 43;

            let eau = page.allocate_raw(4, 4) as *mut i32;
            location += 5;
            assert_eq!(page.get_next_location(), location);
            *eau = 4711;
            assert_eq!(_Page::get_page(eau as usize), page as *mut _Page);

            // Allocate an oversized page which should cause allocating an exclusive page
            let array = page.allocate_raw(_PAGE_SIZE, 8) as *mut usize;
            for i in 0.._PAGE_SIZE / size_of::<usize>() - 1 {
                *(array.offset(i as isize)) = i;
            }
            assert_eq!(page.get_next_location(), location);
            assert_eq!(page as *mut _Page, page.current_page);

            // Overflow the page
            for _ in 0.._PAGE_SIZE {
                page.allocate_raw(1, 1);
            }
            assert_ne!(page as *mut _Page, page.current_page);
            assert_eq!(*(page.get_extension_page_location()), page.current_page);
            assert_eq!((*page.current_page).exclusive_pages, 0);
            assert_eq!((*page.current_page).current_page, page.current_page);

            assert_eq!(page.exclusive_pages, 1);
            assert_eq!(*answer, 42);
            assert_eq!(*another, 43);
            assert_eq!(*eau, 4711);

            let exclusive_page = page.get_next_exclusive_page_location().offset(1);
            assert_eq!((**exclusive_page).current_page, null_mut());
            assert_eq!(_Page::get_page(array as usize), *exclusive_page);

            let success = page.reclaim_array(_Page::get_page(array as usize));
            assert_eq!(success, true);
            assert_eq!(page.exclusive_pages, 0);

            page.clear();
            page.forget();
        }
    }
}
<|endoftext|>


<commit_before>use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};
use core::ops::{Deref, DerefMut};

#[cfg(feature = "alloc")]
use alloc::borrow::ToOwned;

#[cfg(feature = "alloc")]
use alloc::boxed::Box;

#[cfg(any(feature = "std", feature = "alloc"))]
use crate::ByteBuf;

use serde::de::{Deserialize, Deserializer, Error, Visitor};
use serde::ser::{Serialize, Serializer};

/// Wrapper around `[u8]` to serialize and deserialize efficiently.
///
/// ```
/// use std::collections::HashMap;
/// use std::io;
///
/// use serde_bytes::Bytes;
///
/// fn print_encoded_cache() -> bincode::Result<()> {
///     let mut cache = HashMap::new();
///     cache.insert(3, Bytes::new(b"three"));
///     cache.insert(2, Bytes::new(b"two"));
///     cache.insert(1, Bytes::new(b"one"));
///
///     bincode::serialize_into(&mut io::stdout(), &cache)
/// }
/// #
/// # fn main() {
/// #     print_encoded_cache().unwrap();
/// # }
/// ```
#[derive(Eq, Ord)]
#[repr(C)]
pub struct Bytes {
    bytes: [u8],
}

impl Bytes {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &[u8]) -> &Self {
        unsafe { &*(bytes as *const [u8] as *const Bytes) }
    }
}

impl Debug for Bytes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.bytes, f)
    }
}

impl AsRef<[u8]> for Bytes {
    fn as_ref(&self) -> &[u8] {
        &self.bytes
    }
}

impl AsMut<[u8]> for Bytes {
    fn as_mut(&mut self) -> &mut [u8] {
        &mut self.bytes
    }
}

impl Deref for Bytes {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.bytes
    }
}

impl DerefMut for Bytes {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.bytes
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl ToOwned for Bytes {
    type Owned = ByteBuf;

    fn to_owned(&self) -> Self::Owned {
        ByteBuf::from(&self.bytes)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl From<Box<[u8]>> for Box<Bytes> {
    fn from(bytes: Box<[u8]>) -> Self {
        unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) }
    }
}

impl<'a> Default for &'a Bytes {
    fn default() -> Self {
        Bytes::new(&[])
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl Default for Box<Bytes> {
    fn default() -> Self {
        ByteBuf::new().into_boxed_bytes()
    }
}

impl<Rhs> PartialEq<Rhs> for Bytes
where
    Rhs: ?Sized + AsRef<[u8]>,
{
    fn eq(&self, other: &Rhs) -> bool {
        self.as_ref().eq(other.as_ref())
    }
}

impl<Rhs> PartialOrd<Rhs> for Bytes
where
    Rhs: ?Sized + AsRef<[u8]>,
{
    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
        self.as_ref().partial_cmp(other.as_ref())
    }
}

impl Hash for Bytes {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.bytes.hash(state);
    }
}

impl<'a> IntoIterator for &'a Bytes {
    type Item = &'a u8;
    type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.bytes.iter()
    }
}

impl<'a> IntoIterator for &'a mut Bytes {
    type Item = &'a mut u8;
    type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.bytes.iter_mut()
    }
}

impl Serialize for Bytes {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_bytes(&self.bytes)
    }
}

struct BytesVisitor;

impl<'de> Visitor<'de> for BytesVisitor {
    type Value = &'de Bytes;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a borrowed byte array")
    }

    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
    where
        E: Error,
    {
        Ok(Bytes::new(v))
    }

    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
    where
        E: Error,
    {
        Ok(Bytes::new(v.as_bytes()))
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_bytes(BytesVisitor)
    }
}
<commit_msg>fix(bytes): remove redundant Visitor<commit_after>use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};
use core::ops::{Deref, DerefMut};

#[cfg(feature = "alloc")]
use alloc::borrow::ToOwned;

#[cfg(feature = "alloc")]
use alloc::boxed::Box;

#[cfg(any(feature = "std", feature = "alloc"))]
use crate::ByteBuf;

use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};

/// Wrapper around `[u8]` to serialize and deserialize efficiently.
///
/// ```
/// use std::collections::HashMap;
/// use std::io;
///
/// use serde_bytes::Bytes;
///
/// fn print_encoded_cache() -> bincode::Result<()> {
///     let mut cache = HashMap::new();
///     cache.insert(3, Bytes::new(b"three"));
///     cache.insert(2, Bytes::new(b"two"));
///     cache.insert(1, Bytes::new(b"one"));
///
///     bincode::serialize_into(&mut io::stdout(), &cache)
/// }
/// #
/// # fn main() {
/// #     print_encoded_cache().unwrap();
/// # }
/// ```
#[derive(Eq, Ord)]
#[repr(C)]
pub struct Bytes {
    bytes: [u8],
}

impl Bytes {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &[u8]) -> &Self {
        unsafe { &*(bytes as *const [u8] as *const Bytes) }
    }
}

impl Debug for Bytes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.bytes, f)
    }
}

impl AsRef<[u8]> for Bytes {
    fn as_ref(&self) -> &[u8] {
        &self.bytes
    }
}

impl AsMut<[u8]> for Bytes {
    fn as_mut(&mut self) -> &mut [u8] {
        &mut self.bytes
    }
}

impl Deref for Bytes {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.bytes
    }
}

impl DerefMut for Bytes {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.bytes
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl ToOwned for Bytes {
    type Owned = ByteBuf;

    fn to_owned(&self) -> Self::Owned {
        ByteBuf::from(&self.bytes)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl From<Box<[u8]>> for Box<Bytes> {
    fn from(bytes: Box<[u8]>) -> Self {
        unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) }
    }
}

impl<'a> Default for &'a Bytes {
    fn default() -> Self {
        Bytes::new(&[])
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl Default for Box<Bytes> {
    fn default() -> Self {
        ByteBuf::new().into_boxed_bytes()
    }
}

impl<Rhs> PartialEq<Rhs> for Bytes
where
    Rhs: ?Sized + AsRef<[u8]>,
{
    fn eq(&self, other: &Rhs) -> bool {
        self.as_ref().eq(other.as_ref())
    }
}

impl<Rhs> PartialOrd<Rhs> for Bytes
where
    Rhs: ?Sized + AsRef<[u8]>,
{
    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
        self.as_ref().partial_cmp(other.as_ref())
    }
}

impl Hash for Bytes {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.bytes.hash(state);
    }
}

impl<'a> IntoIterator for &'a Bytes {
    type Item = &'a u8;
    type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.bytes.iter()
    }
}

impl<'a> IntoIterator for &'a mut Bytes {
    type Item = &'a mut u8;
    type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.bytes.iter_mut()
    }
}

impl Serialize for Bytes {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_bytes(&self.bytes)
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Deserialize::deserialize(deserializer).map(Bytes::new)
    }
}
<|endoftext|>


<commit_before>//! This module represents a basic, rule-agnostic 32-cards system.

use rand::{thread_rng, Rng, IsaacRng, SeedableRng};
use std::num::Wrapping;
use std::string::ToString;
use rustc_serialize;

/// One of the four Suits: Heart, Spade, Diamond, Club.
#[derive(PartialEq,Clone,Copy)]
pub struct Suit(u32);

// TODO: Make these associated const when it's stable

/// The Heart suit
pub const HEART: Suit = Suit(1 << 0);
/// The Spade suit
pub const SPADE: Suit = Suit(1 << 8);
/// The Diamond suit
pub const DIAMOND: Suit = Suit(1 << 16);
/// The Club suit
pub const CLUB: Suit = Suit(1 << 24);

impl rustc_serialize::Encodable for Suit {
    fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        match *self {
            HEART | SPADE | DIAMOND | CLUB => self.0.encode(s),
            _ => "??".encode(s),
        }
    }
}

impl Suit {
    /// Returns the suit corresponding to the number:
    ///
    /// * `0`: Heart
    /// * `1`: Spade
    /// * `2`: Diamond
    /// * `3`: Club
    ///
    /// # Panics
    ///
    /// If `n >= 4`.
    pub fn from_n(n: u32) -> Self {
        if n >= 4 {
            panic!("Bad suit number");
        }
        Suit(1 << 8 * n)
    }

    /// Returns a UTF-8 character representing the suit.
    pub fn to_string(self) -> String {
        match self {
            HEART => "♥",
            SPADE => "♠",
            DIAMOND => "♦",
            CLUB => "♣",
            _ => "?",
        }
        .to_string()
    }
}

/// Rank of a card in a suit.
#[derive(PartialEq,Clone,Copy)]
pub struct Rank(u32);
/// 7
pub const RANK_7: Rank = Rank(1 << 0);
/// 8
pub const RANK_8: Rank = Rank(1 << 1);
/// 9
pub const RANK_9: Rank = Rank(1 << 2);
/// Jack
pub const RANK_J: Rank = Rank(1 << 3);
/// Queen
pub const RANK_Q: Rank = Rank(1 << 4);
/// King
pub const RANK_K: Rank = Rank(1 << 5);
/// 10
pub const RANK_X: Rank = Rank(1 << 6);
/// Ace
pub const RANK_A: Rank = Rank(1 << 7);
/// Bit mask over all ranks
pub const RANK_MASK: Rank = Rank(255);

impl Rank {
    /// Returns the rank corresponding to the given number:
    ///
    /// * `0`: 7
    /// * `1`: 8
    /// * `2`: 9
    /// * `3`: Jack
    /// * `4`: Queen
    /// * `5`: King
    /// * `6`: 10
    /// * `7`: Ace
    ///
    /// # Panics
    ///
    /// If `n >= 8`.
    pub fn from_n(n: u32) -> Self {
        if n >= 8 {
            panic!("Invalid rank number: {}", n);
        }
        Rank(1 << n)
    }

    /// Returns a character representing the given rank.
    pub fn to_string(self) -> String {
        match self {
            RANK_7 => "7",
            RANK_8 => "8",
            RANK_9 => "9",
            RANK_J => "J",
            RANK_Q => "Q",
            RANK_K => "K",
            RANK_X => "X",
            RANK_A => "A",
            _ => "?",
        }
        .to_string()
    }
}

/// Represents a single card.
#[derive(PartialEq,Clone,Copy,Debug)]
pub struct Card(u32);

// TODO: Add card constants? (8 of heart, Queen of spades, ...?)

impl rustc_serialize::Encodable for Card {
    fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        self.0.encode(s)
    }
}

impl Card {
    /// Returns the card number (from 0 to 31)
    pub fn id(self) -> u32 {
        let mut i = 0;
        let Card(mut v) = self;
        while v != 0 {
            i += 1;
            v = v >> 1;
        }

        i - 1
    }

    /// Returns the card corresponding to the given number.
    ///
    /// # Panics
    ///
    /// If `id >= 32`
    pub fn from_id(id: u32) -> Self {
        if id > 31 {
            panic!("invalid card id");
        }
        Card(1 << id)
    }

    /// Returns the card's rank
    pub fn rank(self) -> Rank {
        let Card(mut v) = self;
        let mut r: u32 = 0;
        let Rank(mask) = RANK_MASK;

        r |= mask & v;
        v = v >> 8;
        r |= mask & v;
        v = v >> 8;
        r |= mask & v;
        v = v >> 8;
        r |= v;

        Rank(r)
    }

    /// Returns the card's suit.
    pub fn suit(self) -> Suit {
        let Card(v) = self;
        let Rank(r) = self.rank();
        Suit(v / r)
    }

    /// Returns a string representation of the card.
    pub fn to_string(self) -> String {
        let r = self.rank();
        let s = self.suit();
        r.to_string() + &s.to_string()
    }

    /// Creates a card from the given suit and rank
    pub fn new(suit: Suit, rank: Rank) -> Self {
        let Suit(s) = suit;
        let Rank(r) = rank;

        Card(s * r)
    }
}

/// Represents an unordered set of cards
#[derive(PartialEq,Clone,Copy)]
pub struct Hand(u32);

impl rustc_serialize::Encodable for Hand {
    fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        self.0.encode(s)
    }
}

impl Hand {
    /// Returns an empty hand.
    pub fn new() -> Self {
        Hand(0)
    }

    /// Add `card` to `self`.
    ///
    /// No effect if `self` already contains `card`.
    pub fn add(&mut self, card: Card) -> &mut Hand {
        self.0 |= card.0;
        self
    }

    /// Removes `card` from `self`.
    ///
    /// No effect if `self` does not contains `card`.
    pub fn remove(&mut self, card: Card) {
        self.0 &= !card.0;
    }

    /// Remove all cards from `self`.
    pub fn clean(&mut self) {
        *self = Hand::new();
    }

    /// Returns `true` if `self` contains `card`.
    pub fn has(self, card: Card) -> bool {
        (self.0 & card.0) != 0
    }

    /// Returns `true` if the hand contains any card of the given suit.
    pub fn has_any(self, suit: Suit) -> bool {
        (self.0 & (RANK_MASK.0 * suit.0)) != 0
    }

    /// Returns `true` if `self` contains no card.
    pub fn is_empty(self) -> bool {
        self.0 == 0
    }

    /// Returns a card from `self`.
    ///
    /// Returns an invalid card if `self` is empty.
    pub fn get_card(self) -> Card {
        if self.is_empty() {
            return Card(0);
        }

        let Hand(h) = self;
        // Finds the rightmost bit, shifted to the left by 1.
        // let n = 1 << (h.trailing_zeroes());
        let n = Wrapping(h ^ (h - 1)) + Wrapping(1);
        if n.0 == 0 {
            // We got an overflow. This means the desired bit it the leftmost one.
            Card::from_id(31)
        } else {
            // We just need to shift it back.
            Card(n.0 >> 1)
        }
    }

    /// Returns the cards contained in `self` as a `Vec`.
    pub fn list(self) -> Vec<Card> {
        let mut cards = Vec::new();
        let mut h = self;

        while !h.is_empty() {
            let c = h.get_card();
            h.remove(c);
            cards.push(c);
        }

        cards
    }

    /// Returns the number of cards in `self`.
    pub fn size(self) -> usize {
        self.list().len()
    }
}

impl ToString for Hand {
    /// Returns a string representation of `self`.
    fn to_string(&self) -> String {
        let mut s = "[".to_string();

        for c in (*self).list().iter() {
            s = s + &c.to_string();
            s = s + ",";
        }

        s + "]"
    }
}

/// A deck of cards.
pub struct Deck {
    cards: Vec<Card>,
}

impl Deck {
    /// Returns a full, sorted deck of 32 cards.
    pub fn new() -> Self {
        let mut d = Deck { cards: Vec::with_capacity(32) };

        for i in 0..32 {
            d.cards.push(Card::from_id(i));
        }

        d
    }

    /// Shuffle this deck.
    pub fn shuffle(&mut self) {
        self.shuffle_from(thread_rng());
    }

    /// Shuffle this deck with the given random seed.
    ///
    /// Result is determined by the seed.
    pub fn shuffle_seeded(&mut self, seed: &[u32]) {
        let mut rng = IsaacRng::new_unseeded();
        rng.reseed(seed);
        self.shuffle_from(rng);
    }

    fn shuffle_from<RNG: Rng>(&mut self, mut rng: RNG) {
        rng.shuffle(&mut self.cards[..]);
    }

    /// Draw the top card from the deck.
    ///
    /// # Panics
    /// If `self` is empty.
    pub fn draw(&mut self) -> Card {
        self.cards.pop().expect("deck is empty")
    }

    /// Returns `true` if this deck is empty.
    pub fn is_empty(&self) -> bool {
        self.cards.is_empty()
    }

    /// Returns the number of cards left in this deck.
    pub fn len(&self) -> usize {
        self.cards.len()
    }

    /// Deal `n` cards to each hand.
    ///
    /// # Panics
    /// If `self.len() < 4 * n`
    pub fn deal_each(&mut self, hands: &mut [Hand; 4], n: usize) {
        if self.len() < 4 * n {
            panic!("Deck has too few cards!");
        }

        for hand in hands.iter_mut() {
            for _ in 0..n {
                hand.add(self.draw());
            }
        }
    }
}

impl ToString for Deck {
    fn to_string(&self) -> String {
        let mut s = "[".to_string();

        for c in self.cards.iter() {
            s = s + &c.to_string();
            s = s + ",";
        }

        s + "]"
    }
}

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

    #[test]
    fn test_cards() {
        for i in 0..32 {
            let card = Card::from_id(i);
            assert!(i == card.id());
        }

        for s in 0..4 {
            let suit = Suit::from_n(s);
            for r in 0..8 {
                let rank = Rank::from_n(r);
                let card = Card::new(suit, rank);
                assert!(card.rank() == rank);
                assert!(card.suit() == suit);
            }
        }
    }

    #[test]
    fn test_hand() {
        let mut hand = Hand::new();

        let cards: Vec<Card> = vec![
            Card::new(HEART, RANK_7),
            Card::new(HEART, RANK_8),
            Card::new(SPADE, RANK_9),
            Card::new(SPADE, RANK_J),
            Card::new(CLUB, RANK_Q),
            Card::new(CLUB, RANK_K),
            Card::new(DIAMOND, RANK_X),
            Card::new(DIAMOND, RANK_A),
        ];

        assert!(hand.is_empty());

        for card in cards.iter() {
            assert!(!hand.has(*card));
            hand.add(*card);
            assert!(hand.has(*card));
        }

        assert!(hand.size() == cards.len());

        for card in cards.iter() {
            assert!(hand.has(*card));
            hand.remove(*card);
            assert!(!hand.has(*card));
        }
    }

    #[test]
    fn test_deck() {
        let mut deck = Deck::new();
        deck.shuffle();

        assert!(deck.len() == 32);

        let mut count = [0; 32];
        while !deck.is_empty() {
            let card = deck.draw();
            count[card.id() as usize] += 1;
        }

        for c in count.iter() {
            assert!(*c == 1);
        }
    }
}

#[cfg(feature="use_bench")]
mod benchs {
    use test::Bencher;
    use deal_seeded_hands;

    #[bench]
    fn bench_deal(b: &mut Bencher) {
        let seed = &[1, 2, 3, 4, 5];
        b.iter(|| {
            deal_seeded_hands(seed);
        });
    }

    #[bench]
    fn bench_add(b: &mut Bencher) {
        let seed = &[1, 2, 3, 4, 5];
        let hands = deal_seeded_hands(seed);
        b.iter(|| {
            let mut hands = hands.clone();
            for hand in hands.iter_mut() {
                for c in hand.list() {
                    hand.remove(c);
                }
            }
        });
    }
}
<commit_msg>Add hand list benchmark<commit_after>//! This module represents a basic, rule-agnostic 32-cards system.

use rand::{thread_rng, Rng, IsaacRng, SeedableRng};
use std::num::Wrapping;
use std::string::ToString;
use rustc_serialize;

/// One of the four Suits: Heart, Spade, Diamond, Club.
#[derive(PartialEq,Clone,Copy)]
pub struct Suit(u32);

// TODO: Make these associated const when it's stable

/// The Heart suit
pub const HEART: Suit = Suit(1 << 0);
/// The Spade suit
pub const SPADE: Suit = Suit(1 << 8);
/// The Diamond suit
pub const DIAMOND: Suit = Suit(1 << 16);
/// The Club suit
pub const CLUB: Suit = Suit(1 << 24);

impl rustc_serialize::Encodable for Suit {
    fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        match *self {
            HEART | SPADE | DIAMOND | CLUB => self.0.encode(s),
            _ => "??".encode(s),
        }
    }
}

impl Suit {
    /// Returns the suit corresponding to the number:
    ///
    /// * `0`: Heart
    /// * `1`: Spade
    /// * `2`: Diamond
    /// * `3`: Club
    ///
    /// # Panics
    ///
    /// If `n >= 4`.
    pub fn from_n(n: u32) -> Self {
        if n >= 4 {
            panic!("Bad suit number");
        }
        Suit(1 << 8 * n)
    }

    /// Returns a UTF-8 character representing the suit.
    pub fn to_string(self) -> String {
        match self {
            HEART => "♥",
            SPADE => "♠",
            DIAMOND => "♦",
            CLUB => "♣",
            _ => "?",
        }
        .to_string()
    }
}

/// Rank of a card in a suit.
#[derive(PartialEq,Clone,Copy)]
pub struct Rank(u32);
/// 7
pub const RANK_7: Rank = Rank(1 << 0);
/// 8
pub const RANK_8: Rank = Rank(1 << 1);
/// 9
pub const RANK_9: Rank = Rank(1 << 2);
/// Jack
pub const RANK_J: Rank = Rank(1 << 3);
/// Queen
pub const RANK_Q: Rank = Rank(1 << 4);
/// King
pub const RANK_K: Rank = Rank(1 << 5);
/// 10
pub const RANK_X: Rank = Rank(1 << 6);
/// Ace
pub const RANK_A: Rank = Rank(1 << 7);
/// Bit mask over all ranks
pub const RANK_MASK: Rank = Rank(255);

impl Rank {
    /// Returns the rank corresponding to the given number:
    ///
    /// * `0`: 7
    /// * `1`: 8
    /// * `2`: 9
    /// * `3`: Jack
    /// * `4`: Queen
    /// * `5`: King
    /// * `6`: 10
    /// * `7`: Ace
    ///
    /// # Panics
    ///
    /// If `n >= 8`.
    pub fn from_n(n: u32) -> Self {
        if n >= 8 {
            panic!("Invalid rank number: {}", n);
        }
        Rank(1 << n)
    }

    /// Returns a character representing the given rank.
    pub fn to_string(self) -> String {
        match self {
            RANK_7 => "7",
            RANK_8 => "8",
            RANK_9 => "9",
            RANK_J => "J",
            RANK_Q => "Q",
            RANK_K => "K",
            RANK_X => "X",
            RANK_A => "A",
            _ => "?",
        }
        .to_string()
    }
}

/// Represents a single card.
#[derive(PartialEq,Clone,Copy,Debug)]
pub struct Card(u32);

// TODO: Add card constants? (8 of heart, Queen of spades, ...?)

impl rustc_serialize::Encodable for Card {
    fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        self.0.encode(s)
    }
}

impl Card {
    /// Returns the card number (from 0 to 31)
    pub fn id(self) -> u32 {
        let mut i = 0;
        let Card(mut v) = self;
        while v != 0 {
            i += 1;
            v = v >> 1;
        }

        i - 1
    }

    /// Returns the card corresponding to the given number.
    ///
    /// # Panics
    ///
    /// If `id >= 32`
    pub fn from_id(id: u32) -> Self {
        if id > 31 {
            panic!("invalid card id");
        }
        Card(1 << id)
    }

    /// Returns the card's rank
    pub fn rank(self) -> Rank {
        let Card(mut v) = self;
        let mut r: u32 = 0;
        let Rank(mask) = RANK_MASK;

        r |= mask & v;
        v = v >> 8;
        r |= mask & v;
        v = v >> 8;
        r |= mask & v;
        v = v >> 8;
        r |= v;

        Rank(r)
    }

    /// Returns the card's suit.
    pub fn suit(self) -> Suit {
        let Card(v) = self;
        let Rank(r) = self.rank();
        Suit(v / r)
    }

    /// Returns a string representation of the card.
    pub fn to_string(self) -> String {
        let r = self.rank();
        let s = self.suit();
        r.to_string() + &s.to_string()
    }

    /// Creates a card from the given suit and rank
    pub fn new(suit: Suit, rank: Rank) -> Self {
        let Suit(s) = suit;
        let Rank(r) = rank;

        Card(s * r)
    }
}

/// Represents an unordered set of cards
#[derive(PartialEq,Clone,Copy)]
pub struct Hand(u32);

impl rustc_serialize::Encodable for Hand {
    fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        self.0.encode(s)
    }
}

impl Hand {
    /// Returns an empty hand.
    pub fn new() -> Self {
        Hand(0)
    }

    /// Add `card` to `self`.
    ///
    /// No effect if `self` already contains `card`.
    pub fn add(&mut self, card: Card) -> &mut Hand {
        self.0 |= card.0;
        self
    }

    /// Removes `card` from `self`.
    ///
    /// No effect if `self` does not contains `card`.
    pub fn remove(&mut self, card: Card) {
        self.0 &= !card.0;
    }

    /// Remove all cards from `self`.
    pub fn clean(&mut self) {
        *self = Hand::new();
    }

    /// Returns `true` if `self` contains `card`.
    pub fn has(self, card: Card) -> bool {
        (self.0 & card.0) != 0
    }

    /// Returns `true` if the hand contains any card of the given suit.
    pub fn has_any(self, suit: Suit) -> bool {
        (self.0 & (RANK_MASK.0 * suit.0)) != 0
    }

    /// Returns `true` if `self` contains no card.
    pub fn is_empty(self) -> bool {
        self.0 == 0
    }

    /// Returns a card from `self`.
    ///
    /// Returns an invalid card if `self` is empty.
    pub fn get_card(self) -> Card {
        if self.is_empty() {
            return Card(0);
        }

        let Hand(h) = self;
        // Finds the rightmost bit, shifted to the left by 1.
        // let n = 1 << (h.trailing_zeroes());
        let n = Wrapping(h ^ (h - 1)) + Wrapping(1);
        if n.0 == 0 {
            // We got an overflow. This means the desired bit it the leftmost one.
            Card::from_id(31)
        } else {
            // We just need to shift it back.
            Card(n.0 >> 1)
        }
    }

    /// Returns the cards contained in `self` as a `Vec`.
    pub fn list(self) -> Vec<Card> {
        let mut cards = Vec::new();
        let mut h = self;

        while !h.is_empty() {
            let c = h.get_card();
            h.remove(c);
            cards.push(c);
        }

        cards
    }

    /// Returns the number of cards in `self`.
    pub fn size(self) -> usize {
        self.list().len()
    }
}

impl ToString for Hand {
    /// Returns a string representation of `self`.
    fn to_string(&self) -> String {
        let mut s = "[".to_string();

        for c in (*self).list().iter() {
            s = s + &c.to_string();
            s = s + ",";
        }

        s + "]"
    }
}

/// A deck of cards.
pub struct Deck {
    cards: Vec<Card>,
}

impl Deck {
    /// Returns a full, sorted deck of 32 cards.
    pub fn new() -> Self {
        let mut d = Deck { cards: Vec::with_capacity(32) };

        for i in 0..32 {
            d.cards.push(Card::from_id(i));
        }

        d
    }

    /// Shuffle this deck.
    pub fn shuffle(&mut self) {
        self.shuffle_from(thread_rng());
    }

    /// Shuffle this deck with the given random seed.
    ///
    /// Result is determined by the seed.
    pub fn shuffle_seeded(&mut self, seed: &[u32]) {
        let mut rng = IsaacRng::new_unseeded();
        rng.reseed(seed);
        self.shuffle_from(rng);
    }

    fn shuffle_from<RNG: Rng>(&mut self, mut rng: RNG) {
        rng.shuffle(&mut self.cards[..]);
    }

    /// Draw the top card from the deck.
    ///
    /// # Panics
    /// If `self` is empty.
    pub fn draw(&mut self) -> Card {
        self.cards.pop().expect("deck is empty")
    }

    /// Returns `true` if this deck is empty.
    pub fn is_empty(&self) -> bool {
        self.cards.is_empty()
    }

    /// Returns the number of cards left in this deck.
    pub fn len(&self) -> usize {
        self.cards.len()
    }

    /// Deal `n` cards to each hand.
    ///
    /// # Panics
    /// If `self.len() < 4 * n`
    pub fn deal_each(&mut self, hands: &mut [Hand; 4], n: usize) {
        if self.len() < 4 * n {
            panic!("Deck has too few cards!");
        }

        for hand in hands.iter_mut() {
            for _ in 0..n {
                hand.add(self.draw());
            }
        }
    }
}

impl ToString for Deck {
    fn to_string(&self) -> String {
        let mut s = "[".to_string();

        for c in self.cards.iter() {
            s = s + &c.to_string();
            s = s + ",";
        }

        s + "]"
    }
}

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

    #[test]
    fn test_cards() {
        for i in 0..32 {
            let card = Card::from_id(i);
            assert!(i == card.id());
        }

        for s in 0..4 {
            let suit = Suit::from_n(s);
            for r in 0..8 {
                let rank = Rank::from_n(r);
                let card = Card::new(suit, rank);
                assert!(card.rank() == rank);
                assert!(card.suit() == suit);
            }
        }
    }

    #[test]
    fn test_hand() {
        let mut hand = Hand::new();

        let cards: Vec<Card> = vec![
            Card::new(HEART, RANK_7),
            Card::new(HEART, RANK_8),
            Card::new(SPADE, RANK_9),
            Card::new(SPADE, RANK_J),
            Card::new(CLUB, RANK_Q),
            Card::new(CLUB, RANK_K),
            Card::new(DIAMOND, RANK_X),
            Card::new(DIAMOND, RANK_A),
        ];

        assert!(hand.is_empty());

        for card in cards.iter() {
            assert!(!hand.has(*card));
            hand.add(*card);
            assert!(hand.has(*card));
        }

        assert!(hand.size() == cards.len());

        for card in cards.iter() {
            assert!(hand.has(*card));
            hand.remove(*card);
            assert!(!hand.has(*card));
        }
    }

    #[test]
    fn test_deck() {
        let mut deck = Deck::new();
        deck.shuffle();

        assert!(deck.len() == 32);

        let mut count = [0; 32];
        while !deck.is_empty() {
            let card = deck.draw();
            count[card.id() as usize] += 1;
        }

        for c in count.iter() {
            assert!(*c == 1);
        }
    }
}

#[cfg(feature="use_bench")]
mod benchs {
    use test::Bencher;
    use deal_seeded_hands;

    #[bench]
    fn bench_deal(b: &mut Bencher) {
        let seed = &[1, 2, 3, 4, 5];
        b.iter(|| {
            deal_seeded_hands(seed);
        });
    }

    #[bench]
    fn bench_list_hand(b: &mut Bencher) {
        let seed = &[1, 2, 3, 4, 5];
        let hands = deal_seeded_hands(seed);
        b.iter(|| {
            for hand in hands.iter() {
                hand.list().len();
            }
        });
    }

    #[bench]
    fn bench_del_add_check(b: &mut Bencher) {
        let seed = &[1, 2, 3, 4, 5];
        let hands = deal_seeded_hands(seed);
        let cards: Vec<_> = hands.iter().map(|h| h.list()).collect();
        b.iter(|| {
            let mut hands = hands.clone();
            for (hand,cards) in hands.iter_mut().zip(cards.iter()) {
                for c in cards.iter() {
                    hand.remove(*c);
                }
            }
            for (hand,cards) in hands.iter_mut().zip(cards.iter()) {
                for c in cards.iter() {
                    hand.add(*c);
                }
            }

            for (hand,cards) in hands.iter_mut().zip(cards.iter()) {
                for c in cards.iter() {
                    if !hand.has(*c) {
                        panic!("Error!");
                    }
                }
            }
        });
    }
}
<|endoftext|>


<commit_before>use super::error::{JudgeErrorKind, JudgeResult};
use super::judge;
use super::testcase::Cases;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;

pub fn judge(cases: &str, target: &str, args: &[&str]) -> JudgeResult<()> {
    cargo_build_release()?;
    let cases = Cases::load(&cases_path(cases)?)?;
    judge::judge_all(cases, target_path(target)?.as_path(), args)
}

fn cases_path(problem: &str) -> JudgeResult<PathBuf> {
    let mut path = crate_root()?;
    path.push(problem);
    Ok(path)
}

fn cargo_build_release() -> JudgeResult<()> {
    if Command::new("cargo")
        .args(&["build", "--release"])
        .spawn()?
        .wait()?
        .success()
    {
        Ok(())
    } else {
        bail!(JudgeErrorKind::BuildFailed)
    }
}

fn target_path(problem: &str) -> JudgeResult<PathBuf> {
    let mut path = crate_root()?;
    path.push("target");
    path.push("release");
    path.push(problem);
    Ok(path)
}

fn crate_root() -> JudgeResult<PathBuf> {
    fn find_cargo_toml<P: AsRef<Path>>(dir: P) -> JudgeResult<bool> {
        // Doesn't care if "Cargo.toml" is a directory because `cargo build` fails if such a
        // directory exists.
        for entry in fs::read_dir(dir)? {
            if &entry?.file_name() == "Cargo.toml" {
                return Ok(true);
            }
        }
        Ok(false)
    }

    let mut dir = env::current_dir()?;
    loop {
        if find_cargo_toml(&dir)? {
            return Ok(dir);
        } else if !dir.pop() {
            bail!(JudgeErrorKind::ProjectNotFound);
        }
    }
}
<commit_msg>Remove src/cargo.rs, which is no longer used<commit_after><|endoftext|>