<commit_before>use beacon_chain::{BeaconChain, BeaconChainTypes};
use environment::RuntimeContext;
use exit_future::Signal;
use futures::{Future, Stream};
use network::Service as NetworkService;
use parking_lot::Mutex;
use slog::{debug, error, info, warn};
use slot_clock::SlotClock;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::timer::Interval;
use types::{EthSpec, Slot};

/// Create a warning log whenever the peer count is at or below this value.
pub const WARN_PEER_COUNT: usize = 1;

const SECS_PER_MINUTE: f64 = 60.0;
const SECS_PER_HOUR: f64 = 3600.0;
const SECS_PER_DAY: f64 = 86400.0; // non-leap
const SECS_PER_WEEK: f64 = 604800.0; // non-leap
const DAYS_PER_WEEK: f64 = 7.0;
const HOURS_PER_DAY: f64 = 24.0;
const MINUTES_PER_HOUR: f64 = 60.0;

/// How long to wait for the lock on `network.libp2p_service()` before we give up.
const LIBP2P_LOCK_TIMEOUT: Duration = Duration::from_millis(50);

/// The number of historical observations that should be used to determine the average sync time.
const SPEEDO_OBSERVATIONS: usize = 4;

/// Spawns a notifier service which periodically logs information about the node.
pub fn spawn_notifier<T: BeaconChainTypes>(
    context: RuntimeContext<T::EthSpec>,
    beacon_chain: Arc<BeaconChain<T>>,
    network: Arc<NetworkService<T>>,
    milliseconds_per_slot: u64,
) -> Result<Signal, String> {
    let log_1 = context.log.clone();
    let log_2 = context.log.clone();

    let slot_duration = Duration::from_millis(milliseconds_per_slot);
    let duration_to_next_slot = beacon_chain
        .slot_clock
        .duration_to_next_slot()
        .ok_or_else(|| "slot_notifier unable to determine time to next slot")?;

    // Run this half way through each slot.
    let start_instant = Instant::now() + duration_to_next_slot + (slot_duration / 2);

    // Run this each slot.
    let interval_duration = slot_duration;

    let speedo = Mutex::new(Speedo::default());

    let interval_future = Interval::new(start_instant, interval_duration)
        .map_err(
            move |e| error!(log_1, "Slot notifier timer failed"; "error" => format!("{:?}", e)),
        )
        .for_each(move |_| {
            let log = log_2.clone();

            let connected_peer_count = if let Some(libp2p) = network
                .libp2p_service()
                .try_lock_until(Instant::now() + LIBP2P_LOCK_TIMEOUT)
            {
                libp2p.swarm.connected_peers()
            } else {
                // Use max_value here and we'll print something pretty later.
                usize::max_value()
            };

            let head = beacon_chain.head()
                .map_err(|e| error!(
                    log,
                    "Failed to get beacon chain head";
                    "error" => format!("{:?}", e)
                ))?;

            let head_slot = head.beacon_block.slot;
            let head_epoch = head_slot.epoch(T::EthSpec::slots_per_epoch());
            let current_slot = beacon_chain.slot().map_err(|e| {
                error!(
                    log,
                    "Unable to read current slot";
                    "error" => format!("{:?}", e)
                )
            })?;
            let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch());
            let finalized_epoch = head.beacon_state.finalized_checkpoint.epoch;
            let finalized_root = head.beacon_state.finalized_checkpoint.root;
            let head_root = head.beacon_block_root;

            let mut speedo = speedo.lock();
            speedo.observe(head_slot, Instant::now());

            // The next two lines take advantage of saturating subtraction on `Slot`.
            let head_distance = current_slot - head_slot;

            if connected_peer_count <= WARN_PEER_COUNT {
                warn!(log, "Low peer count"; "peer_count" => peer_count_pretty(connected_peer_count));
            }

            debug!(
                log,
                "Slot timer";
                "peers" => peer_count_pretty(connected_peer_count),
                "finalized_root" => format!("{}", finalized_root),
                "finalized_epoch" => finalized_epoch,
                "head_block" => format!("{}", head_root),
                "head_slot" => head_slot,
                "current_slot" => current_slot,
            );

            if head_epoch + 1 < current_epoch {
                let distance = format!(
                    "{} slots ({})",
                    head_distance.as_u64(),
                    slot_distance_pretty(head_distance, slot_duration)
                );

                info!(
                    log,
                    "Syncing";
                    "peers" => peer_count_pretty(connected_peer_count),
                    "distance" => distance,
                    "speed" => sync_speed_pretty(speedo.slots_per_second()),
                    "est_time" => estimated_time_pretty(speedo.estimated_time_till_slot(current_slot)),
                );

                return Ok(());
            };

            macro_rules! not_quite_synced_log {
                ($message: expr) => {
                    info!(
                        log_2,
                        $message;
                        "peers" => peer_count_pretty(connected_peer_count),
                        "finalized_root" => format!("{}", finalized_root),
                        "finalized_epoch" => finalized_epoch,
                        "head_slot" => head_slot,
                        "current_slot" => current_slot,
                    );
                }
            }

            if head_epoch + 1 == current_epoch {
                not_quite_synced_log!("Synced to previous epoch")
            } else if head_slot != current_slot {
                not_quite_synced_log!("Synced to current epoch")
            } else {
                info!(
                    log_2,
                    "Synced";
                    "peers" => peer_count_pretty(connected_peer_count),
                    "finalized_root" => format!("{}", finalized_root),
                    "finalized_epoch" => finalized_epoch,
                    "epoch" => current_epoch,
                    "slot" => current_slot,
                );
            };

            Ok(())
        });

    let (exit_signal, exit) = exit_future::signal();
    context
        .executor
        .spawn(exit.until(interval_future).map(|_| ()));

    Ok(exit_signal)
}

/// Returns the peer count, returning something helpful if it's `usize::max_value` (effectively a
/// `None` value).
fn peer_count_pretty(peer_count: usize) -> String {
    if peer_count == usize::max_value() {
        String::from("--")
    } else {
        format!("{}", peer_count)
    }
}

/// Returns a nicely formatted string describing the rate of slot imports per second.
fn sync_speed_pretty(slots_per_second: Option<f64>) -> String {
    if let Some(slots_per_second) = slots_per_second {
        format!("{:.2} slots/sec", slots_per_second)
    } else {
        "--".into()
    }
}

/// Returns a nicely formatted string how long will we reach the target slot.
fn estimated_time_pretty(seconds_till_slot: Option<f64>) -> String {
    if let Some(seconds_till_slot) = seconds_till_slot {
        seconds_pretty(seconds_till_slot)
    } else {
        "--".into()
    }
}

/// Returns a nicely formatted string describing the `slot_span` in terms of weeks, days, hours
/// and/or minutes.
fn slot_distance_pretty(slot_span: Slot, slot_duration: Duration) -> String {
    if slot_duration == Duration::from_secs(0) {
        return String::from("Unknown");
    }

    let secs = (slot_duration * slot_span.as_u64() as u32).as_secs();
    seconds_pretty(secs as f64)
}

/// Returns a nicely formatted string describing the `slot_span` in terms of weeks, days, hours
/// and/or minutes.
fn seconds_pretty(secs: f64) -> String {
    if secs <= 0.0 {
        return "--".into();
    }

    let weeks = secs / SECS_PER_WEEK;
    let days = secs / SECS_PER_DAY;
    let hours = secs / SECS_PER_HOUR;
    let minutes = secs / SECS_PER_MINUTE;

    if weeks.floor() > 0.0 {
        format!(
            "{:.0} weeks {:.0} days",
            weeks,
            (days % DAYS_PER_WEEK).round()
        )
    } else if days.floor() > 0.0 {
        format!(
            "{:.0} days {:.0} hrs",
            days,
            (hours % HOURS_PER_DAY).round()
        )
    } else if hours.floor() > 0.0 {
        format!(
            "{:.0} hrs {:.0} mins",
            hours,
            (minutes % MINUTES_PER_HOUR).round()
        )
    } else {
        format!("{:.0} mins", minutes.round())
    }
}

/// "Speedo" is Australian for speedometer. This struct observes syncing times.
#[derive(Default)]
pub struct Speedo(Vec<(Slot, Instant)>);

impl Speedo {
    /// Observe that we were at some `slot` at the given `instant`.
    pub fn observe(&mut self, slot: Slot, instant: Instant) {
        if self.0.len() > SPEEDO_OBSERVATIONS {
            self.0.remove(0);
        }

        self.0.push((slot, instant));
    }

    /// Returns the average of the speeds between each observation.
    ///
    /// Does not gracefully handle slots that are above `u32::max_value()`.
    pub fn slots_per_second(&self) -> Option<f64> {
        let speeds = self
            .0
            .windows(2)
            .filter_map(|windows| {
                let (slot_a, instant_a) = windows[0];
                let (slot_b, instant_b) = windows[1];

                // Taking advantage of saturating subtraction on `Slot`.
                let distance = f64::from((slot_b - slot_a).as_u64() as u32);

                let seconds = f64::from((instant_b - instant_a).as_millis() as u32) / 1_000.0;

                if seconds > 0.0 {
                    Some(distance / seconds)
                } else {
                    None
                }
            })
            .collect::<Vec<f64>>();

        let count = speeds.len();
        let sum: f64 = speeds.iter().sum();

        if count > 0 {
            Some(sum / f64::from(count as u32))
        } else {
            None
        }
    }

    /// Returns the time we should reach the given `slot`, judging by the latest observation and
    /// historical average syncing time.
    ///
    /// Returns `None` if the slot is prior to our latest observed slot or we have not made any
    /// observations.
    pub fn estimated_time_till_slot(&self, target_slot: Slot) -> Option<f64> {
        let (prev_slot, _) = self.0.last()?;
        let slots_per_second = self.slots_per_second()?;

        if target_slot > *prev_slot && slots_per_second > 0.0 {
            let distance = (target_slot - *prev_slot).as_u64() as f64;
            Some(distance / slots_per_second)
        } else {
            None
        }
    }
}
<commit_msg>Notifier errors (#793)<commit_after>use beacon_chain::{BeaconChain, BeaconChainTypes};
use environment::RuntimeContext;
use exit_future::Signal;
use futures::{Future, Stream};
use network::Service as NetworkService;
use parking_lot::Mutex;
use slog::{debug, error, info, warn};
use slot_clock::SlotClock;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::timer::Interval;
use types::{EthSpec, Slot};

/// Create a warning log whenever the peer count is at or below this value.
pub const WARN_PEER_COUNT: usize = 1;

const SECS_PER_MINUTE: f64 = 60.0;
const SECS_PER_HOUR: f64 = 3600.0;
const SECS_PER_DAY: f64 = 86400.0; // non-leap
const SECS_PER_WEEK: f64 = 604800.0; // non-leap
const DAYS_PER_WEEK: f64 = 7.0;
const HOURS_PER_DAY: f64 = 24.0;
const MINUTES_PER_HOUR: f64 = 60.0;

/// How long to wait for the lock on `network.libp2p_service()` before we give up.
const LIBP2P_LOCK_TIMEOUT: Duration = Duration::from_millis(50);

/// The number of historical observations that should be used to determine the average sync time.
const SPEEDO_OBSERVATIONS: usize = 4;

/// Spawns a notifier service which periodically logs information about the node.
pub fn spawn_notifier<T: BeaconChainTypes>(
    context: RuntimeContext<T::EthSpec>,
    beacon_chain: Arc<BeaconChain<T>>,
    network: Arc<NetworkService<T>>,
    milliseconds_per_slot: u64,
) -> Result<Signal, String> {
    let log_1 = context.log.clone();
    let log_2 = context.log.clone();
    let log_3 = context.log.clone();

    let slot_duration = Duration::from_millis(milliseconds_per_slot);
    let duration_to_next_slot = beacon_chain
        .slot_clock
        .duration_to_next_slot()
        .ok_or_else(|| "slot_notifier unable to determine time to next slot")?;

    // Run this half way through each slot.
    let start_instant = Instant::now() + duration_to_next_slot + (slot_duration / 2);

    // Run this each slot.
    let interval_duration = slot_duration;

    let speedo = Mutex::new(Speedo::default());

    let interval_future = Interval::new(start_instant, interval_duration)
        .map_err(
            move |e| error!(log_1, "Slot notifier timer failed"; "error" => format!("{:?}", e)),
        )
        .for_each(move |_| {
            let log = log_2.clone();

            let connected_peer_count = if let Some(libp2p) = network
                .libp2p_service()
                .try_lock_until(Instant::now() + LIBP2P_LOCK_TIMEOUT)
            {
                libp2p.swarm.connected_peers()
            } else {
                // Use max_value here and we'll print something pretty later.
                usize::max_value()
            };

            let head = beacon_chain.head()
                .map_err(|e| error!(
                    log,
                    "Failed to get beacon chain head";
                    "error" => format!("{:?}", e)
                ))?;

            let head_slot = head.beacon_block.slot;
            let head_epoch = head_slot.epoch(T::EthSpec::slots_per_epoch());
            let current_slot = beacon_chain.slot().map_err(|e| {
                error!(
                    log,
                    "Unable to read current slot";
                    "error" => format!("{:?}", e)
                )
            })?;
            let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch());
            let finalized_epoch = head.beacon_state.finalized_checkpoint.epoch;
            let finalized_root = head.beacon_state.finalized_checkpoint.root;
            let head_root = head.beacon_block_root;

            let mut speedo = speedo.lock();
            speedo.observe(head_slot, Instant::now());

            // The next two lines take advantage of saturating subtraction on `Slot`.
            let head_distance = current_slot - head_slot;

            if connected_peer_count <= WARN_PEER_COUNT {
                warn!(log, "Low peer count"; "peer_count" => peer_count_pretty(connected_peer_count));
            }

            debug!(
                log,
                "Slot timer";
                "peers" => peer_count_pretty(connected_peer_count),
                "finalized_root" => format!("{}", finalized_root),
                "finalized_epoch" => finalized_epoch,
                "head_block" => format!("{}", head_root),
                "head_slot" => head_slot,
                "current_slot" => current_slot,
            );

            if head_epoch + 1 < current_epoch {
                let distance = format!(
                    "{} slots ({})",
                    head_distance.as_u64(),
                    slot_distance_pretty(head_distance, slot_duration)
                );

                info!(
                    log,
                    "Syncing";
                    "peers" => peer_count_pretty(connected_peer_count),
                    "distance" => distance,
                    "speed" => sync_speed_pretty(speedo.slots_per_second()),
                    "est_time" => estimated_time_pretty(speedo.estimated_time_till_slot(current_slot)),
                );

                return Ok(());
            };

            macro_rules! not_quite_synced_log {
                ($message: expr) => {
                    info!(
                        log_2,
                        $message;
                        "peers" => peer_count_pretty(connected_peer_count),
                        "finalized_root" => format!("{}", finalized_root),
                        "finalized_epoch" => finalized_epoch,
                        "head_slot" => head_slot,
                        "current_slot" => current_slot,
                    );
                }
            }

            if head_epoch + 1 == current_epoch {
                not_quite_synced_log!("Synced to previous epoch")
            } else if head_slot != current_slot {
                not_quite_synced_log!("Synced to current epoch")
            } else {
                info!(
                    log_2,
                    "Synced";
                    "peers" => peer_count_pretty(connected_peer_count),
                    "finalized_root" => format!("{}", finalized_root),
                    "finalized_epoch" => finalized_epoch,
                    "epoch" => current_epoch,
                    "slot" => current_slot,
                );
            };

            Ok(())
        })
        .then(move |result| {
            match result {
                Ok(()) => Ok(()),
                Err(e) => Ok(error!(
                    log_3,
                    "Notifier failed to notify";
                    "error" => format!("{:?}", e)
                ))
            }
        });

    let (exit_signal, exit) = exit_future::signal();
    context
        .executor
        .spawn(exit.until(interval_future).map(|_| ()));

    Ok(exit_signal)
}

/// Returns the peer count, returning something helpful if it's `usize::max_value` (effectively a
/// `None` value).
fn peer_count_pretty(peer_count: usize) -> String {
    if peer_count == usize::max_value() {
        String::from("--")
    } else {
        format!("{}", peer_count)
    }
}

/// Returns a nicely formatted string describing the rate of slot imports per second.
fn sync_speed_pretty(slots_per_second: Option<f64>) -> String {
    if let Some(slots_per_second) = slots_per_second {
        format!("{:.2} slots/sec", slots_per_second)
    } else {
        "--".into()
    }
}

/// Returns a nicely formatted string how long will we reach the target slot.
fn estimated_time_pretty(seconds_till_slot: Option<f64>) -> String {
    if let Some(seconds_till_slot) = seconds_till_slot {
        seconds_pretty(seconds_till_slot)
    } else {
        "--".into()
    }
}

/// Returns a nicely formatted string describing the `slot_span` in terms of weeks, days, hours
/// and/or minutes.
fn slot_distance_pretty(slot_span: Slot, slot_duration: Duration) -> String {
    if slot_duration == Duration::from_secs(0) {
        return String::from("Unknown");
    }

    let secs = (slot_duration * slot_span.as_u64() as u32).as_secs();
    seconds_pretty(secs as f64)
}

/// Returns a nicely formatted string describing the `slot_span` in terms of weeks, days, hours
/// and/or minutes.
fn seconds_pretty(secs: f64) -> String {
    if secs <= 0.0 {
        return "--".into();
    }

    let weeks = secs / SECS_PER_WEEK;
    let days = secs / SECS_PER_DAY;
    let hours = secs / SECS_PER_HOUR;
    let minutes = secs / SECS_PER_MINUTE;

    if weeks.floor() > 0.0 {
        format!(
            "{:.0} weeks {:.0} days",
            weeks,
            (days % DAYS_PER_WEEK).round()
        )
    } else if days.floor() > 0.0 {
        format!(
            "{:.0} days {:.0} hrs",
            days,
            (hours % HOURS_PER_DAY).round()
        )
    } else if hours.floor() > 0.0 {
        format!(
            "{:.0} hrs {:.0} mins",
            hours,
            (minutes % MINUTES_PER_HOUR).round()
        )
    } else {
        format!("{:.0} mins", minutes.round())
    }
}

/// "Speedo" is Australian for speedometer. This struct observes syncing times.
#[derive(Default)]
pub struct Speedo(Vec<(Slot, Instant)>);

impl Speedo {
    /// Observe that we were at some `slot` at the given `instant`.
    pub fn observe(&mut self, slot: Slot, instant: Instant) {
        if self.0.len() > SPEEDO_OBSERVATIONS {
            self.0.remove(0);
        }

        self.0.push((slot, instant));
    }

    /// Returns the average of the speeds between each observation.
    ///
    /// Does not gracefully handle slots that are above `u32::max_value()`.
    pub fn slots_per_second(&self) -> Option<f64> {
        let speeds = self
            .0
            .windows(2)
            .filter_map(|windows| {
                let (slot_a, instant_a) = windows[0];
                let (slot_b, instant_b) = windows[1];

                // Taking advantage of saturating subtraction on `Slot`.
                let distance = f64::from((slot_b - slot_a).as_u64() as u32);

                let seconds = f64::from((instant_b - instant_a).as_millis() as u32) / 1_000.0;

                if seconds > 0.0 {
                    Some(distance / seconds)
                } else {
                    None
                }
            })
            .collect::<Vec<f64>>();

        let count = speeds.len();
        let sum: f64 = speeds.iter().sum();

        if count > 0 {
            Some(sum / f64::from(count as u32))
        } else {
            None
        }
    }

    /// Returns the time we should reach the given `slot`, judging by the latest observation and
    /// historical average syncing time.
    ///
    /// Returns `None` if the slot is prior to our latest observed slot or we have not made any
    /// observations.
    pub fn estimated_time_till_slot(&self, target_slot: Slot) -> Option<f64> {
        let (prev_slot, _) = self.0.last()?;
        let slots_per_second = self.slots_per_second()?;

        if target_slot > *prev_slot && slots_per_second > 0.0 {
            let distance = (target_slot - *prev_slot).as_u64() as f64;
            Some(distance / slots_per_second)
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>mod prometheus_handler;

use beacon_chain::{BeaconChain, BeaconChainTypes};
use futures::Future;
use iron::prelude::*;
use iron::{status::Status, Handler, IronResult, Request, Response};
use network::NetworkMessage;
use prometheus_handler::PrometheusHandler;
use router::Router;
use slog::{info, o, warn};
use std::sync::Arc;
use tokio::runtime::TaskExecutor;

#[derive(PartialEq, Clone, Debug)]
pub struct HttpServerConfig {
    pub enabled: bool,
    pub listen_address: String,
    /*
    pub listen_address: Ipv4Addr,
    pub port: u16,
    */
}

impl Default for HttpServerConfig {
    fn default() -> Self {
        Self {
            enabled: false,
            listen_address: "127.0.0.1:5051".to_string(),
            /*
            listen_address: Ipv4Addr::new(127, 0, 0, 1),
            port: 5051,
            */
        }
    }
}

pub struct IndexHandler {
    message: String,
}

impl Handler for IndexHandler {
    fn handle(&self, _: &mut Request) -> IronResult<Response> {
        Ok(Response::with((Status::Ok, self.message.clone())))
    }
}

pub fn create_iron_http_server<T: BeaconChainTypes + 'static>(
    beacon_chain: Arc<BeaconChain<T>>,
) -> Iron<Router> {
    let index_handler = IndexHandler {
        message: "Hello world".to_string(),
    };
    let prom_handler = PrometheusHandler {
        beacon_chain: beacon_chain,
    };

    let mut router = Router::new();
    router.get("/", index_handler, "index");
    router.get("/prometheus/", prom_handler, "prometheus");
    Iron::new(router)
}

pub fn start_service<T: BeaconChainTypes + 'static>(
    config: &HttpServerConfig,
    executor: &TaskExecutor,
    _network_chan: crossbeam_channel::Sender<NetworkMessage>,
    beacon_chain: Arc<BeaconChain<T>>,
    log: &slog::Logger,
) -> exit_future::Signal {
    let log = log.new(o!("Service"=>"HTTP"));

    // Create:
    //  - `shutdown_trigger` a one-shot to shut down this service.
    //  - `wait_for_shutdown` a future that will wait until someone calls shutdown.
    let (shutdown_trigger, wait_for_shutdown) = exit_future::signal();

    // Create an `iron` http, without starting it yet.
    let iron = create_iron_http_server(beacon_chain);

    // Create a HTTP server future.
    //
    // 1. Start the HTTP server
    // 2. Build an exit future that will shutdown the server when requested.
    // 3. Return the exit future, so the caller may shutdown the service when desired.
    let http_service = {
        // Start the HTTP server
        let server_start_result = iron.http(config.listen_address.clone());

        if server_start_result.is_ok() {
            info!(log, "HTTP server running on {}", config.listen_address);
        } else {
            warn!(
                log,
                "HTTP server failed to start on {}", config.listen_address
            );
        }

        // Build a future that will shutdown the HTTP server when the `shutdown_trigger` is
        // triggered.
        wait_for_shutdown.and_then(move |_| {
            info!(log, "HTTP server shutting down");

            if let Ok(mut server) = server_start_result {
                // According to the documentation, this function "doesn't work" and the server
                // keeps listening.
                //
                // It is being called anyway, because it seems like the right thing to do. If you
                // know this has negative side-effects, please create an issue to discuss.
                //
                // See: https://docs.rs/iron/0.6.0/iron/struct.Listening.html#impl
                match server.close() {
                    _ => (),
                };
            }
            info!(log, "HTTP server shutdown complete.");
            Ok(())
        })
    };

    // Attach the HTTP server to the executor.
    executor.spawn(http_service);

    shutdown_trigger
}
<commit_msg>Rename prom HTTP endpoint<commit_after>mod prometheus_handler;

use beacon_chain::{BeaconChain, BeaconChainTypes};
use futures::Future;
use iron::prelude::*;
use iron::{status::Status, Handler, IronResult, Request, Response};
use network::NetworkMessage;
use prometheus_handler::PrometheusHandler;
use router::Router;
use slog::{info, o, warn};
use std::sync::Arc;
use tokio::runtime::TaskExecutor;

#[derive(PartialEq, Clone, Debug)]
pub struct HttpServerConfig {
    pub enabled: bool,
    pub listen_address: String,
    /*
    pub listen_address: Ipv4Addr,
    pub port: u16,
    */
}

impl Default for HttpServerConfig {
    fn default() -> Self {
        Self {
            enabled: false,
            listen_address: "127.0.0.1:5051".to_string(),
            /*
            listen_address: Ipv4Addr::new(127, 0, 0, 1),
            port: 5051,
            */
        }
    }
}

pub struct IndexHandler {
    message: String,
}

impl Handler for IndexHandler {
    fn handle(&self, _: &mut Request) -> IronResult<Response> {
        Ok(Response::with((Status::Ok, self.message.clone())))
    }
}

pub fn create_iron_http_server<T: BeaconChainTypes + 'static>(
    beacon_chain: Arc<BeaconChain<T>>,
) -> Iron<Router> {
    let index_handler = IndexHandler {
        message: "Hello world".to_string(),
    };
    let prom_handler = PrometheusHandler {
        beacon_chain: beacon_chain,
    };

    let mut router = Router::new();
    router.get("/", index_handler, "index");
    router.get("/metrics", prom_handler, "metrics");
    Iron::new(router)
}

pub fn start_service<T: BeaconChainTypes + 'static>(
    config: &HttpServerConfig,
    executor: &TaskExecutor,
    _network_chan: crossbeam_channel::Sender<NetworkMessage>,
    beacon_chain: Arc<BeaconChain<T>>,
    log: &slog::Logger,
) -> exit_future::Signal {
    let log = log.new(o!("Service"=>"HTTP"));

    // Create:
    //  - `shutdown_trigger` a one-shot to shut down this service.
    //  - `wait_for_shutdown` a future that will wait until someone calls shutdown.
    let (shutdown_trigger, wait_for_shutdown) = exit_future::signal();

    // Create an `iron` http, without starting it yet.
    let iron = create_iron_http_server(beacon_chain);

    // Create a HTTP server future.
    //
    // 1. Start the HTTP server
    // 2. Build an exit future that will shutdown the server when requested.
    // 3. Return the exit future, so the caller may shutdown the service when desired.
    let http_service = {
        // Start the HTTP server
        let server_start_result = iron.http(config.listen_address.clone());

        if server_start_result.is_ok() {
            info!(log, "HTTP server running on {}", config.listen_address);
        } else {
            warn!(
                log,
                "HTTP server failed to start on {}", config.listen_address
            );
        }

        // Build a future that will shutdown the HTTP server when the `shutdown_trigger` is
        // triggered.
        wait_for_shutdown.and_then(move |_| {
            info!(log, "HTTP server shutting down");

            if let Ok(mut server) = server_start_result {
                // According to the documentation, this function "doesn't work" and the server
                // keeps listening.
                //
                // It is being called anyway, because it seems like the right thing to do. If you
                // know this has negative side-effects, please create an issue to discuss.
                //
                // See: https://docs.rs/iron/0.6.0/iron/struct.Listening.html#impl
                match server.close() {
                    _ => (),
                };
            }
            info!(log, "HTTP server shutdown complete.");
            Ok(())
        })
    };

    // Attach the HTTP server to the executor.
    executor.spawn(http_service);

    shutdown_trigger
}
<|endoftext|>


<commit_before>use crate::Bytes;
use core::fmt;
use core::marker::PhantomData;
use serde::de::{Error, Visitor};
use serde::Deserializer;

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

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

#[cfg(feature = "alloc")]
use alloc::borrow::Cow;
#[cfg(all(feature = "std", not(feature = "alloc")))]
use std::borrow::Cow;

#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

#[cfg(any(feature = "std", feature = "alloc"))]
use serde::de::SeqAccess;

/// Types that can be deserialized via `#[serde(with = "serde_bytes")]`.
pub trait Deserialize<'de>: Sized {
    #[allow(missing_docs)]
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>;
}

impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // Via the serde::Deserialize impl for &[u8].
        serde::Deserialize::deserialize(deserializer)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Vec<u8> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Deserialize::deserialize(deserializer).map(ByteBuf::into_vec)
    }
}

impl<'de: 'a, '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)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for ByteBuf {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // Via the serde::Deserialize impl for ByteBuf.
        serde::Deserialize::deserialize(deserializer)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct CowVisitor;

        impl<'de> Visitor<'de> for CowVisitor {
            type Value = Cow<'de, [u8]>;

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

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

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

            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v.to_vec()))
            }

            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v.as_bytes().to_vec()))
            }

            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v))
            }

            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v.into_bytes()))
            }

            fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: SeqAccess<'de>,
            {
                let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
                let mut bytes = Vec::with_capacity(len);

                while let Some(b) = visitor.next_element()? {
                    bytes.push(b);
                }

                Ok(Cow::Owned(bytes))
            }
        }

        deserializer.deserialize_bytes(CowVisitor)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, Bytes> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let cow: Cow<[u8]> = Deserialize::deserialize(deserializer)?;
        match cow {
            Cow::Borrowed(bytes) => Ok(Cow::Borrowed(Bytes::new(bytes))),
            Cow::Owned(bytes) => Ok(Cow::Owned(ByteBuf::from(bytes))),
        }
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Box<[u8]> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Deserialize::deserialize(deserializer).map(Vec::into_boxed_slice)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Box<Bytes> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let bytes: Box<[u8]> = Deserialize::deserialize(deserializer)?;
        Ok(bytes.into())
    }
}

impl<'de, T> Deserialize<'de> for Option<T>
where
    T: Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct BytesVisitor<T> {
            out: PhantomData<T>,
        }

        impl<'de, T> Visitor<'de> for BytesVisitor<T>
        where
            T: Deserialize<'de>,
        {
            type Value = Option<T>;

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

            fn visit_unit<E: Error>(self) -> Result<Self::Value, E> {
                Ok(None)
            }

            fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
                Ok(None)
            }

            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                T::deserialize(deserializer).map(Some)
            }
        }

        let visitor = BytesVisitor { out: PhantomData };
        deserializer.deserialize_option(visitor)
    }
}
<commit_msg>fix(de): remove a level of indirection for Bytes deserialization<commit_after>use crate::Bytes;
use core::fmt;
use core::marker::PhantomData;
use serde::de::{Error, Visitor};
use serde::Deserializer;

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

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

#[cfg(feature = "alloc")]
use alloc::borrow::Cow;
#[cfg(all(feature = "std", not(feature = "alloc")))]
use std::borrow::Cow;

#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

#[cfg(any(feature = "std", feature = "alloc"))]
use serde::de::SeqAccess;

/// Types that can be deserialized via `#[serde(with = "serde_bytes")]`.
pub trait Deserialize<'de>: Sized {
    #[allow(missing_docs)]
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>;
}

impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // Via the serde::Deserialize impl for &[u8].
        serde::Deserialize::deserialize(deserializer)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Vec<u8> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Deserialize::deserialize(deserializer).map(ByteBuf::into_vec)
    }
}

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

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for ByteBuf {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // Via the serde::Deserialize impl for ByteBuf.
        serde::Deserialize::deserialize(deserializer)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct CowVisitor;

        impl<'de> Visitor<'de> for CowVisitor {
            type Value = Cow<'de, [u8]>;

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

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

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

            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v.to_vec()))
            }

            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v.as_bytes().to_vec()))
            }

            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v))
            }

            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
            where
                E: Error,
            {
                Ok(Cow::Owned(v.into_bytes()))
            }

            fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: SeqAccess<'de>,
            {
                let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
                let mut bytes = Vec::with_capacity(len);

                while let Some(b) = visitor.next_element()? {
                    bytes.push(b);
                }

                Ok(Cow::Owned(bytes))
            }
        }

        deserializer.deserialize_bytes(CowVisitor)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, Bytes> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let cow: Cow<[u8]> = Deserialize::deserialize(deserializer)?;
        match cow {
            Cow::Borrowed(bytes) => Ok(Cow::Borrowed(Bytes::new(bytes))),
            Cow::Owned(bytes) => Ok(Cow::Owned(ByteBuf::from(bytes))),
        }
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Box<[u8]> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Deserialize::deserialize(deserializer).map(Vec::into_boxed_slice)
    }
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Box<Bytes> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let bytes: Box<[u8]> = Deserialize::deserialize(deserializer)?;
        Ok(bytes.into())
    }
}

impl<'de, T> Deserialize<'de> for Option<T>
where
    T: Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct BytesVisitor<T> {
            out: PhantomData<T>,
        }

        impl<'de, T> Visitor<'de> for BytesVisitor<T>
        where
            T: Deserialize<'de>,
        {
            type Value = Option<T>;

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

            fn visit_unit<E: Error>(self) -> Result<Self::Value, E> {
                Ok(None)
            }

            fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
                Ok(None)
            }

            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                T::deserialize(deserializer).map(Some)
            }
        }

        let visitor = BytesVisitor { out: PhantomData };
        deserializer.deserialize_option(visitor)
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
// Copyright (c) 2017, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#![allow(non_camel_case_types)]

pub struct Writer {
    enc: od_ec_enc
}

pub type od_ec_window = u32;

#[derive(Debug)]
pub struct od_ec_enc {
    /// A buffer for output bytes with their associated carry flags.
    pub precarry: Vec<u16>,
    /// The low end of the current range.
    pub low: od_ec_window,
    /// The number of values in the current range.
    pub rng: u16,
    /// The number of bits of data in the current value.
    pub cnt: i16,
}

impl od_ec_enc {
    fn new() -> od_ec_enc {
        od_ec_enc {
            precarry: Vec::new(),
            low: 0,
            rng: 0x8000,
            // This is initialized to -9 so that it crosses zero after we've
            // accumulated one byte + one carry bit
            cnt: -9,
        }
    }

    /// Encode a single binary value.
    /// `val`: The value to encode (0 or 1).
    /// `f`: The probability that the val is one, scaled by 32768.
    fn od_ec_encode_bool_q15(&mut self, val: bool, f: u16) {
        assert!(0 < f);
        assert!(f < 32768);
        let mut l = self.low;
        let mut r = self.rng as u32;
        assert!(32768 <= r);

        let v = ((r >> 8) * (f as u32)) >> 7;
        if val { l += r - v };
        r = if val { v } else { r - v };

        self.od_ec_enc_normalize(l, r as u16);
    }

    /// Encodes a symbol given a cumulative distribution function (CDF) table in Q15.
    /// `s`: The index of the symbol to encode.
    /// `cdf`: The CDF, such that symbol s falls in the range
    ///        `[s > 0 ? cdf[s - 1] : 0, cdf[s])`.
    ///       The values must be monotonically non-decreasing, and the last value
    ///       must be exactly 32768. There should be at most 16 values.
    fn od_ec_encode_cdf_q15(&mut self, s: usize, cdf: &[u16]) {
        assert!(cdf[cdf.len() - 1] == od_ec_enc::od_icdf(32768));
        self.od_ec_encode_q15(if s > 0 { cdf[s - 1] } else { od_ec_enc::od_icdf(0) }, cdf[s]);
    }

    fn od_icdf(x: u16) -> u16 {
        32768 - x
    }

    /// Encodes a symbol given its frequency in Q15.
    /// `fl`: 32768 minus the cumulative frequency of all symbols that come
    ///       before the one to be encoded.
    /// `fh`: 32768 moinus the cumulative frequency of all symbols up to and
    ///       including the one to be encoded.
    fn od_ec_encode_q15(&mut self, fl: u16, fh: u16) {
        let mut l = self.low;
        let mut r = self.rng as u32;
        let u: u32;
        let v: u32;
        assert!(32768 <= r);

        assert!(fh < fl);
        assert!(fl <= 32768);
        if fl < 32768 {
            u = ((r >> 8) * (fl as u32)) >> 7;
            v = ((r >> 8) * (fh as u32)) >> 7;
            l += r - u;
            r = u - v;
        } else {
            r -= ((r >> 8) * (fh as u32)) >> 7;
        }

        self.od_ec_enc_normalize(l, r as u16);
    }

    fn od_ilog_nz(x: u16) -> u16 {
        16 - (x.leading_zeros() as u16)
    }

    /// Takes updated low and range values, renormalizes them so that
    /// 32768 <= `rng` < 65536 (flushing bytes from low to the pre-carry buffer if
    /// necessary), and stores them back in the encoder context.
    /// `low0`: The new value of low.
    /// `rng`: The new value of the range.
    fn od_ec_enc_normalize(&mut self, low0: od_ec_window, rng: u16) {
        let mut low = low0;
        let mut c = self.cnt;
        let d = 16 - od_ec_enc::od_ilog_nz(rng);
        let mut s = c + (d as i16);

        if s >= 0 {
            c += 16;
            let mut m = (1 << c) - 1;
            if s >= 8 {
                self.precarry.push((low >> c) as u16);
                low &= m;
                c -= 8;
                m >>= 8;
            }
            self.precarry.push((low >> c) as u16);
            s = c + (d as i16) - 24;
            low &= m;
        }
        self.low = low << d;
        self.rng = rng << d;
        self.cnt = s;
    }

    /// Indicates that there are no more symbols to encode.
    /// Returns a vector containing the final bitstream.
    fn od_ec_enc_done(&mut self) -> Vec<u8> {
        // We output the minimum number of bits that ensures that the symbols encoded
        // thus far will be decoded correctly regardless of the bits that follow.
        let l = self.low;
        let r = self.rng as u32;
        let mut c = self.cnt;
        let mut s = 9;
        let mut m = 0x7FFF;
        let mut e = (l + m) & !m;

        while (e | m) >= l + r {
            s += 1;
            m >>= 1;
            e = (l + m) & !m;
        }
        s += c;

        if s > 0 {
            let mut n = (1 << (c + 16)) - 1;

            loop {
                self.precarry.push((e >> (c + 16)) as u16);
                e &= n;
                s -= 8;
                c -= 8;
                n >>= 8;

                if s <= 0 { break; }
            };
        }

        let mut c = 0;
        let mut offs = self.precarry.len();
        let mut out = vec![0 as u8; offs];
        while offs > 0 {
            offs -= 1;
            c = self.precarry[offs] + c;
            out[offs] = c as u8;
            c >>= 8;
        }

        out
    }
}

impl Writer {
    pub fn new() -> Writer {
        Writer { enc: od_ec_enc::new() }
    }
    pub fn done(&mut self) -> Vec<u8> {
        self.enc.od_ec_enc_done()
    }
    pub fn cdf(&mut self, s: u32, cdf: &[u16]) {
        self.enc.od_ec_encode_cdf_q15(s as usize, cdf)
    }
    pub fn bool(&mut self, val: bool, f: u16) {
        self.enc.od_ec_encode_bool_q15(val, f)
    }
    fn update_cdf(cdf: &mut [u16], val: u32, nsymbs: usize) {
        let rate = 4 + if cdf[nsymbs] > 31 { 1 } else { 0 } + (31 ^ (nsymbs as u32).leading_zeros());
        let rate2 = 5;
        let mut tmp: i32;
        let diff: i32;
        let tmp0 = 1 << rate2;
        tmp = 32768 - tmp0;
        diff = ((32768 - ((nsymbs as i32) << rate2)) >> rate) << rate;
        for i in 0..(nsymbs - 1) {
            if i as u32 == val {
                tmp -= diff;
            }
            let prev_cdf = cdf[i] as i32;
            cdf[i] = (prev_cdf + ((tmp - prev_cdf) >> rate)) as u16;
            tmp -= tmp0;
        }
        if cdf[nsymbs] < 32 {
            cdf[nsymbs] += 1;
        }
    }
    pub fn symbol(&mut self, s: u32, cdf: &mut [u16], nsymbs: usize) {
        self.cdf(s, &cdf[..nsymbs]);
        Writer::update_cdf(cdf, s, nsymbs);
    }
}
<commit_msg>Implement od_ec_enc_tell_frac and friends<commit_after>// Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
// Copyright (c) 2017, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#![allow(non_camel_case_types)]

pub const OD_BITRES: u8 = 3;

pub struct Writer {
    enc: od_ec_enc
}

pub type od_ec_window = u32;

#[derive(Debug)]
pub struct od_ec_enc {
    /// A buffer for output bytes with their associated carry flags.
    pub precarry: Vec<u16>,
    /// The low end of the current range.
    pub low: od_ec_window,
    /// The number of values in the current range.
    pub rng: u16,
    /// The number of bits of data in the current value.
    pub cnt: i16,
}

impl od_ec_enc {
    fn new() -> od_ec_enc {
        od_ec_enc {
            precarry: Vec::new(),
            low: 0,
            rng: 0x8000,
            // This is initialized to -9 so that it crosses zero after we've
            // accumulated one byte + one carry bit
            cnt: -9,
        }
    }

    /// Encode a single binary value.
    /// `val`: The value to encode (0 or 1).
    /// `f`: The probability that the val is one, scaled by 32768.
    fn od_ec_encode_bool_q15(&mut self, val: bool, f: u16) {
        assert!(0 < f);
        assert!(f < 32768);
        let mut l = self.low;
        let mut r = self.rng as u32;
        assert!(32768 <= r);

        let v = ((r >> 8) * (f as u32)) >> 7;
        if val { l += r - v };
        r = if val { v } else { r - v };

        self.od_ec_enc_normalize(l, r as u16);
    }

    /// Encodes a symbol given a cumulative distribution function (CDF) table in Q15.
    /// `s`: The index of the symbol to encode.
    /// `cdf`: The CDF, such that symbol s falls in the range
    ///        `[s > 0 ? cdf[s - 1] : 0, cdf[s])`.
    ///       The values must be monotonically non-decreasing, and the last value
    ///       must be exactly 32768. There should be at most 16 values.
    fn od_ec_encode_cdf_q15(&mut self, s: usize, cdf: &[u16]) {
        assert!(cdf[cdf.len() - 1] == od_ec_enc::od_icdf(32768));
        self.od_ec_encode_q15(if s > 0 { cdf[s - 1] } else { od_ec_enc::od_icdf(0) }, cdf[s]);
    }

    fn od_icdf(x: u16) -> u16 {
        32768 - x
    }

    /// Encodes a symbol given its frequency in Q15.
    /// `fl`: 32768 minus the cumulative frequency of all symbols that come
    ///       before the one to be encoded.
    /// `fh`: 32768 moinus the cumulative frequency of all symbols up to and
    ///       including the one to be encoded.
    fn od_ec_encode_q15(&mut self, fl: u16, fh: u16) {
        let mut l = self.low;
        let mut r = self.rng as u32;
        let u: u32;
        let v: u32;
        assert!(32768 <= r);

        assert!(fh < fl);
        assert!(fl <= 32768);
        if fl < 32768 {
            u = ((r >> 8) * (fl as u32)) >> 7;
            v = ((r >> 8) * (fh as u32)) >> 7;
            l += r - u;
            r = u - v;
        } else {
            r -= ((r >> 8) * (fh as u32)) >> 7;
        }

        self.od_ec_enc_normalize(l, r as u16);
    }

    fn od_ilog_nz(x: u16) -> u16 {
        16 - (x.leading_zeros() as u16)
    }

    /// Takes updated low and range values, renormalizes them so that
    /// 32768 <= `rng` < 65536 (flushing bytes from low to the pre-carry buffer if
    /// necessary), and stores them back in the encoder context.
    /// `low0`: The new value of low.
    /// `rng`: The new value of the range.
    fn od_ec_enc_normalize(&mut self, low0: od_ec_window, rng: u16) {
        let mut low = low0;
        let mut c = self.cnt;
        let d = 16 - od_ec_enc::od_ilog_nz(rng);
        let mut s = c + (d as i16);

        if s >= 0 {
            c += 16;
            let mut m = (1 << c) - 1;
            if s >= 8 {
                self.precarry.push((low >> c) as u16);
                low &= m;
                c -= 8;
                m >>= 8;
            }
            self.precarry.push((low >> c) as u16);
            s = c + (d as i16) - 24;
            low &= m;
        }
        self.low = low << d;
        self.rng = rng << d;
        self.cnt = s;
    }

    /// Indicates that there are no more symbols to encode.
    /// Returns a vector containing the final bitstream.
    fn od_ec_enc_done(&mut self) -> Vec<u8> {
        // We output the minimum number of bits that ensures that the symbols encoded
        // thus far will be decoded correctly regardless of the bits that follow.
        let l = self.low;
        let r = self.rng as u32;
        let mut c = self.cnt;
        let mut s = 9;
        let mut m = 0x7FFF;
        let mut e = (l + m) & !m;

        while (e | m) >= l + r {
            s += 1;
            m >>= 1;
            e = (l + m) & !m;
        }
        s += c;

        if s > 0 {
            let mut n = (1 << (c + 16)) - 1;

            loop {
                self.precarry.push((e >> (c + 16)) as u16);
                e &= n;
                s -= 8;
                c -= 8;
                n >>= 8;

                if s <= 0 { break; }
            };
        }

        let mut c = 0;
        let mut offs = self.precarry.len();
        let mut out = vec![0 as u8; offs];
        while offs > 0 {
            offs -= 1;
            c = self.precarry[offs] + c;
            out[offs] = c as u8;
            c >>= 8;
        }

        out
    }

    /// Returns the number of bits "used" by the encoded symbols so far.
    /// This same number can be computed in either the encoder or the decoder, and is
    ///  suitable for making coding decisions.
    /// Return: The number of bits.
    ///         This will always be slightly larger than the exact value (e.g., all
    ///          rounding error is in the positive direction).
    pub fn od_ec_enc_tell(&mut self) -> u32 {
        // The 10 here counteracts the offset of -9 baked into cnt, and adds 1 extra
        // bit, which we reserve for terminating the stream.
        (((self.precarry.len() * 8) as i32) + (self.cnt as i32) + 10) as u32
    }

    /// Returns the number of bits "used" by the encoded symbols so far.
    /// This same number can be computed in either the encoder or the decoder, and is
    /// suitable for making coding decisions.
    /// Return: The number of bits scaled by `2**OD_BITRES`.
    ///         This will always be slightly larger than the exact value (e.g., all
    ///          rounding error is in the positive direction).
    pub fn od_ec_enc_tell_frac(&mut self) -> u32 {
        od_ec_enc::od_ec_tell_frac(self.od_ec_enc_tell(), self.rng as u32)
    }

    /// Given the current total integer number of bits used and the current value of
    /// rng, computes the fraction number of bits used to `OD_BITRES` precision.
    /// This is used by `od_ec_enc_tell_frac()` and `od_ec_dec_tell_frac()`.
    /// `nbits_total`: The number of whole bits currently used, i.e., the value
    ///                returned by `od_ec_enc_tell()` or `od_ec_dec_tell()`.
    /// `rng`: The current value of rng from either the encoder or decoder state.
    /// Return: The number of bits scaled by `2**OD_BITRES`.
    ///         This will always be slightly larger than the exact value (e.g., all
    ///         rounding error is in the positive direction).
    fn od_ec_tell_frac(nbits_total: u32, mut rng: u32) -> u32 {
        // To handle the non-integral number of bits still left in the encoder/decoder
        //  state, we compute the worst-case number of bits of val that must be
        //  encoded to ensure that the value is inside the range for any possible
        //  subsequent bits.
        // The computation here is independent of val itself (the decoder does not
        //  even track that value), even though the real number of bits used after
        //  od_ec_enc_done() may be 1 smaller if rng is a power of two and the
        //  corresponding trailing bits of val are all zeros.
        // If we did try to track that special case, then coding a value with a
        //  probability of 1/(1 << n) might sometimes appear to use more than n bits.
        // This may help explain the surprising result that a newly initialized
        //  encoder or decoder claims to have used 1 bit.
        let nbits = nbits_total << OD_BITRES;
        let mut l = 0;
        let mut i = OD_BITRES;
        while i > 0 {
            i -= 1;
            rng = (rng * rng) >> 15;
            let b = rng >> 16;
            l = (l << 1) | b;
            rng >>= b;
        }
        nbits - l
    }
}

impl Writer {
    pub fn new() -> Writer {
        Writer { enc: od_ec_enc::new() }
    }
    pub fn done(&mut self) -> Vec<u8> {
        self.enc.od_ec_enc_done()
    }
    pub fn cdf(&mut self, s: u32, cdf: &[u16]) {
        self.enc.od_ec_encode_cdf_q15(s as usize, cdf)
    }
    pub fn bool(&mut self, val: bool, f: u16) {
        self.enc.od_ec_encode_bool_q15(val, f)
    }
    fn update_cdf(cdf: &mut [u16], val: u32, nsymbs: usize) {
        let rate = 4 + if cdf[nsymbs] > 31 { 1 } else { 0 } + (31 ^ (nsymbs as u32).leading_zeros());
        let rate2 = 5;
        let mut tmp: i32;
        let diff: i32;
        let tmp0 = 1 << rate2;
        tmp = 32768 - tmp0;
        diff = ((32768 - ((nsymbs as i32) << rate2)) >> rate) << rate;
        for i in 0..(nsymbs - 1) {
            if i as u32 == val {
                tmp -= diff;
            }
            let prev_cdf = cdf[i] as i32;
            cdf[i] = (prev_cdf + ((tmp - prev_cdf) >> rate)) as u16;
            tmp -= tmp0;
        }
        if cdf[nsymbs] < 32 {
            cdf[nsymbs] += 1;
        }
    }
    pub fn symbol(&mut self, s: u32, cdf: &mut [u16], nsymbs: usize) {
        self.cdf(s, &cdf[..nsymbs]);
        Writer::update_cdf(cdf, s, nsymbs);
    }

    #[allow(dead_code)]
    pub fn tell(&mut self) -> u32 {
        self.enc.od_ec_enc_tell_frac()
    }

    pub fn tell_frac(&mut self) -> u32 {
        self.enc.od_ec_enc_tell_frac()
    }
}
<|endoftext|>


<commit_before>//! The module exposes trait implementations that allow the Tokio-based HTTP/2 to hook into
//! `solicit`'s HTTP/2 protocol handling.
//!
//! Namely, this means that it implements the `SendFrame` and `ReceiveFrame` traits, which are
//! provided to the handler methods of `solicit`'s `HttpConnection`.
//!
//! Through these traits, `solicit` remains decoupled from the actual mechanism of performing
//! IO and acts as an "interpreter" of the HTTP/2 protocol itself.
//!
//! While these operations are inherently coupled to the underlying IO mechanism, `solicit`
//! provides helpers (mainly in `solicit::http::frame`) that can be used to avoid re-implementing
//! common pieces, such as the actual frame parsing from raw bytes, once they're obtained from
//! the underlying IO, or serializing a frame into bytes prior to writing them out.

use std::io::{self, Read, Write};

use futures::{Async};
use tokio_core::io::{Io, ReadHalf, WriteHalf};

use solicit::http::{HttpResult};
use solicit::http::frame::{RawFrame, FrameIR};
use solicit::http::connection::{SendFrame, ReceiveFrame, HttpFrame};

/// The struct that implements the `SendFrame` trait.
pub struct FrameSender<T: Io + 'static> {
    /// The write end of a `tokio_core::io::Io` that the sender will attempt to write the raw
    /// bytes to.
    io: WriteHalf<T>,
    /// The current buffer being sent out.
    out_buf: Option<io::Cursor<Vec<u8>>>,
    /// Pending serialized frames
    out_frames: Vec<Vec<u8>>,
}

impl<T: Io + 'static> FrameSender<T> {
    /// Creates a new `FrameSender` that will write onto the given `WriteHalf` of a socket
    /// (or rather `tokio_core::io::Io`).
    pub fn new(io: WriteHalf<T>) -> FrameSender<T> {
        FrameSender {
            io: io,
            out_buf: None,
            out_frames: vec![],
        }
    }

    /// Adds a serialized frame to the pending frame buffer. It does not attempt writing
    /// anything to the underlying socket.
    fn append(&mut self, b: Vec<u8>) {
        self.out_frames.push(b);
    }

    /// Attempts to perform a write of all remaining buffered data. This includes the current
    /// `out_buf`, as well as any pending serialized frames in `out_frames`.
    ///
    /// If it successfully writes all pending data without blocking returns `true`. If it is
    /// unable to write out everything before blocking, returns `false`. Any IO errors (other
    /// than WouldBlock) are propagated out.
    pub fn try_write(&mut self) -> io::Result<bool> {
        trace!("trying to write more buffered data");

        let mut would_block = false;
        while self.prepare_next() {
            match self.io.poll_write() {
                Async::NotReady => {
                    trace!("wouldblock");
                    would_block = true;
                    break;
                }
                Async::Ready(_) => {
                    if !self.write_next()? {
                        // If we didn't manage to write more, break out. We'll try
                        // again later when we get the event-triggered callback.
                        would_block = true;
                        break;
                    }
                }
            }
        }

        // If we didn't block, it means everything got pushed out.
        Ok(!would_block)
    }

    // Returns true if it managed to write some content out.
    // False => nothing written, wouldblock. We'll get a callback scheduled for our
    // troubles to try again later.
    /// Attempts to write as much of the buffered content in `out_buf` as possible.
    ///
    /// Returns `true` if it managed to write anything without blocking. Returns `false`
    /// only if nothing was written out.
    fn write_next(&mut self) -> io::Result<bool> {
        let mut done = false;
        match self.out_buf.as_mut() {
            None => return Ok(true),
            Some(out_buf) => {
                match self.io.write(&out_buf.get_ref()[out_buf.position() as usize..]) {
                    Ok(count) => {
                        debug!("wrote {} bytes", count);

                        let total_written = (out_buf.position() as usize) + count;
                        if total_written == out_buf.get_ref().len() {
                            // All done with the buffer
                            done = true;
                        }
                    },
                    Err(e) => {
                        if e.kind() == io::ErrorKind::WouldBlock {
                            trace!("write would block");
                            return Ok(false);
                        } else {
                            return Err(e);
                        }
                    }
                }
            }
        };

        if done {
            self.out_buf = None;
        }

        Ok(true)
    }

    /// Prepares the `out_buf` for an upcoming write. If the buffer is empty, it attempts to
    /// take the next serialized frame from the pending frames buffer and write that. If there
    /// are still unwritten bytes in the `out_buf`, it immediately returns.
    ///
    /// Returns `true` if there are more bytes to send, which are now ready in `out_buf`.
    /// Returns `false` if there are no more bytes to send.
    fn prepare_next(&mut self) -> bool {
        if self.out_buf.is_none() {
            if self.out_frames.len() == 0 {
                // We've written out everything that we had.
                return false;
            } else {
                // Get the next frame and make it the out buffer.
                // TODO: Should use a more efficient store for the frame buffer; at least a deque.
                let buf = self.out_frames.remove(0);
                self.out_buf = Some(io::Cursor::new(buf));
            }
        }

        true
    }
}

impl<T: Io + 'static> SendFrame for FrameSender<T> {
    fn send_frame<F: FrameIR>(&mut self, frame: F) -> HttpResult<()> {
        // Let solicit's frame serialization do the heavy lifting by serializing the result
        // into a new buffer...
        let mut buf = io::Cursor::new(Vec::with_capacity(1024));
        frame.serialize_into(&mut buf)?;

        // ...and then simply queue that up for the actual wire IO later on.
        self.append(buf.into_inner());

        Ok(())
    }
}

/// A simple wrapper around a parsed `RawFrame`.
///
/// Implements the `ReceiveFrame` trait by trivially yielding the wrapped frame.
///
/// It achieves this without any copies of the original `RawFrame`; if the `RawFrame` is a view
/// over a different buffer (i.e. it borrows it/a part of it), the `FrameContainer` will not
/// cause any copies behind the scenes.
pub struct FrameContainer<'a> {
    frame: RawFrame<'a>,
    size: usize,
}

impl<'a> FrameContainer<'a> {
    /// Creates a new `FrameContainer` that wraps the given `RawFrame`. This frame will be
    /// returned when the `recv_frame` call comes in.
    fn new(frame: RawFrame) -> FrameContainer {
        let size = frame.len();

        FrameContainer {
            frame: frame,
            size: size,
        }
    }

    /// Returns the byte length of the frame that it wraps.
    pub fn len(&self) -> usize {
        self.size
    }
}

impl<'a> ReceiveFrame for FrameContainer<'a> {
    fn recv_frame(&mut self) -> HttpResult<HttpFrame> {
        HttpFrame::from_raw(&self.frame)
    }
}

/// The struct that implements actually parsing a frame off the wire, leveraging tokio_core
/// IO primitives.
pub struct FrameReceiver<T: Io + 'static> {
    /// The ReadHalf of the Tokio `Io` that this receiver will attempt to read from.
    io: ReadHalf<T>,
    /// A buffer of data that has been read so far, but represents an incomplete HTTP/2 frame.
    in_buf: Vec<u8>,
}

impl<T: Io + 'static> FrameReceiver<T> {
    /// Create a new `FrameReceiver` that will use the given `ReadHalf` to read from.
    pub fn new(io: ReadHalf<T>) -> FrameReceiver<T> {
        FrameReceiver {
            io: io,
            in_buf: Vec::new(),
        }
    }

    /// Attempts to read from the underlying socket.
    ///
    /// Returns the number of bytes read. If it would be unable to perform a read without
    /// blocking, immediately returns with 0.
    ///
    /// TODO: This doesn't properly disambiguate between eof and wouldblock.
    pub fn try_read(&mut self) -> io::Result<usize> {
        let mut done = false;
        let initial_size = self.in_buf.len();
        while !done {
            match self.io.read_to_end(&mut self.in_buf) {
                Ok(0) => {
                    // EOF...
                    trace!("eof");
                    done = true;
                },
                Ok(_) => {
                },
                Err(e) => {
                    if e.kind() == io::ErrorKind::WouldBlock {
                        trace!("read - would block");
                        break;
                    } else {
                        return Err(e);
                    }
                }
            };
        }

        // The buffer could have only grown in the meantime, therefore this is safe from
        // underflow.
        let total_read = self.in_buf.len() - initial_size;
        debug!("total bytes read {}", total_read);

        Ok(total_read)
    }

    /// Attempts to parse the current contents of the input buffer for an h2 frame.
    /// If successful returns a FrameContainer wrapping the frame. The returned `FrameContainer`
    /// will be borrowing the content of the internal buffer, i.e. parsing the frame does not
    /// require creating a new temporary copy of the frame in a new buffer.
    pub fn get_next_frame(&mut self) -> Option<FrameContainer> {
        let raw_frame = RawFrame::parse(&self.in_buf);
        raw_frame.map(|raw_frame| FrameContainer::new(raw_frame))
    }

    /// Discards the current frame from the buffered input.
    pub fn discard_frame(&mut self, size: usize) {
        self.in_buf.drain(..size);
    }
}

<commit_msg>io: Use a VecDeque for the out frames queue<commit_after>//! The module exposes trait implementations that allow the Tokio-based HTTP/2 to hook into
//! `solicit`'s HTTP/2 protocol handling.
//!
//! Namely, this means that it implements the `SendFrame` and `ReceiveFrame` traits, which are
//! provided to the handler methods of `solicit`'s `HttpConnection`.
//!
//! Through these traits, `solicit` remains decoupled from the actual mechanism of performing
//! IO and acts as an "interpreter" of the HTTP/2 protocol itself.
//!
//! While these operations are inherently coupled to the underlying IO mechanism, `solicit`
//! provides helpers (mainly in `solicit::http::frame`) that can be used to avoid re-implementing
//! common pieces, such as the actual frame parsing from raw bytes, once they're obtained from
//! the underlying IO, or serializing a frame into bytes prior to writing them out.

use std::io::{self, Read, Write};
use std::collections::VecDeque;

use futures::{Async};
use tokio_core::io::{Io, ReadHalf, WriteHalf};

use solicit::http::{HttpResult};
use solicit::http::frame::{RawFrame, FrameIR};
use solicit::http::connection::{SendFrame, ReceiveFrame, HttpFrame};

/// The struct that implements the `SendFrame` trait.
pub struct FrameSender<T: Io + 'static> {
    /// The write end of a `tokio_core::io::Io` that the sender will attempt to write the raw
    /// bytes to.
    io: WriteHalf<T>,
    /// The current buffer being sent out.
    out_buf: Option<io::Cursor<Vec<u8>>>,
    /// Pending serialized frames
    out_frames: VecDeque<Vec<u8>>,
}

impl<T: Io + 'static> FrameSender<T> {
    /// Creates a new `FrameSender` that will write onto the given `WriteHalf` of a socket
    /// (or rather `tokio_core::io::Io`).
    pub fn new(io: WriteHalf<T>) -> FrameSender<T> {
        FrameSender {
            io: io,
            out_buf: None,
            out_frames: VecDeque::new(),
        }
    }

    /// Adds a serialized frame to the pending frame buffer. It does not attempt writing
    /// anything to the underlying socket.
    fn append(&mut self, b: Vec<u8>) {
        self.out_frames.push_back(b);
    }

    /// Attempts to perform a write of all remaining buffered data. This includes the current
    /// `out_buf`, as well as any pending serialized frames in `out_frames`.
    ///
    /// If it successfully writes all pending data without blocking returns `true`. If it is
    /// unable to write out everything before blocking, returns `false`. Any IO errors (other
    /// than WouldBlock) are propagated out.
    pub fn try_write(&mut self) -> io::Result<bool> {
        trace!("trying to write more buffered data");

        let mut would_block = false;
        while self.prepare_next() {
            match self.io.poll_write() {
                Async::NotReady => {
                    trace!("wouldblock");
                    would_block = true;
                    break;
                }
                Async::Ready(_) => {
                    if !self.write_next()? {
                        // If we didn't manage to write more, break out. We'll try
                        // again later when we get the event-triggered callback.
                        would_block = true;
                        break;
                    }
                }
            }
        }

        // If we didn't block, it means everything got pushed out.
        Ok(!would_block)
    }

    // Returns true if it managed to write some content out.
    // False => nothing written, wouldblock. We'll get a callback scheduled for our
    // troubles to try again later.
    /// Attempts to write as much of the buffered content in `out_buf` as possible.
    ///
    /// Returns `true` if it managed to write anything without blocking. Returns `false`
    /// only if nothing was written out.
    fn write_next(&mut self) -> io::Result<bool> {
        let mut done = false;
        match self.out_buf.as_mut() {
            None => return Ok(true),
            Some(out_buf) => {
                match self.io.write(&out_buf.get_ref()[out_buf.position() as usize..]) {
                    Ok(count) => {
                        debug!("wrote {} bytes", count);

                        let total_written = (out_buf.position() as usize) + count;
                        if total_written == out_buf.get_ref().len() {
                            // All done with the buffer
                            done = true;
                        }
                    },
                    Err(e) => {
                        if e.kind() == io::ErrorKind::WouldBlock {
                            trace!("write would block");
                            return Ok(false);
                        } else {
                            return Err(e);
                        }
                    }
                }
            }
        };

        if done {
            self.out_buf = None;
        }

        Ok(true)
    }

    /// Prepares the `out_buf` for an upcoming write. If the buffer is empty, it attempts to
    /// take the next serialized frame from the pending frames buffer and write that. If there
    /// are still unwritten bytes in the `out_buf`, it immediately returns.
    ///
    /// Returns `true` if there are more bytes to send, which are now ready in `out_buf`.
    /// Returns `false` if there are no more bytes to send.
    fn prepare_next(&mut self) -> bool {
        if self.out_buf.is_none() {
            match self.out_frames.pop_front() {
                // We've written out everything that we had.
                None => false,

                // Get the next frame and make it the out buffer.
                Some(buf) => {
                    self.out_buf = Some(io::Cursor::new(buf));
                    true
                }
            }
        } else {
            // The `out_buf` is still active, so there's obviously more stuff to send.
            true
        }
    }
}

impl<T: Io + 'static> SendFrame for FrameSender<T> {
    fn send_frame<F: FrameIR>(&mut self, frame: F) -> HttpResult<()> {
        // Let solicit's frame serialization do the heavy lifting by serializing the result
        // into a new buffer...
        let mut buf = io::Cursor::new(Vec::with_capacity(1024));
        frame.serialize_into(&mut buf)?;

        // ...and then simply queue that up for the actual wire IO later on.
        self.append(buf.into_inner());

        Ok(())
    }
}

/// A simple wrapper around a parsed `RawFrame`.
///
/// Implements the `ReceiveFrame` trait by trivially yielding the wrapped frame.
///
/// It achieves this without any copies of the original `RawFrame`; if the `RawFrame` is a view
/// over a different buffer (i.e. it borrows it/a part of it), the `FrameContainer` will not
/// cause any copies behind the scenes.
pub struct FrameContainer<'a> {
    frame: RawFrame<'a>,
    size: usize,
}

impl<'a> FrameContainer<'a> {
    /// Creates a new `FrameContainer` that wraps the given `RawFrame`. This frame will be
    /// returned when the `recv_frame` call comes in.
    fn new(frame: RawFrame) -> FrameContainer {
        let size = frame.len();

        FrameContainer {
            frame: frame,
            size: size,
        }
    }

    /// Returns the byte length of the frame that it wraps.
    pub fn len(&self) -> usize {
        self.size
    }
}

impl<'a> ReceiveFrame for FrameContainer<'a> {
    fn recv_frame(&mut self) -> HttpResult<HttpFrame> {
        HttpFrame::from_raw(&self.frame)
    }
}

/// The struct that implements actually parsing a frame off the wire, leveraging tokio_core
/// IO primitives.
pub struct FrameReceiver<T: Io + 'static> {
    /// The ReadHalf of the Tokio `Io` that this receiver will attempt to read from.
    io: ReadHalf<T>,
    /// A buffer of data that has been read so far, but represents an incomplete HTTP/2 frame.
    in_buf: Vec<u8>,
}

impl<T: Io + 'static> FrameReceiver<T> {
    /// Create a new `FrameReceiver` that will use the given `ReadHalf` to read from.
    pub fn new(io: ReadHalf<T>) -> FrameReceiver<T> {
        FrameReceiver {
            io: io,
            in_buf: Vec::new(),
        }
    }

    /// Attempts to read from the underlying socket.
    ///
    /// Returns the number of bytes read. If it would be unable to perform a read without
    /// blocking, immediately returns with 0.
    ///
    /// TODO: This doesn't properly disambiguate between eof and wouldblock.
    pub fn try_read(&mut self) -> io::Result<usize> {
        let mut done = false;
        let initial_size = self.in_buf.len();
        while !done {
            match self.io.read_to_end(&mut self.in_buf) {
                Ok(0) => {
                    // EOF...
                    trace!("eof");
                    done = true;
                },
                Ok(_) => {
                },
                Err(e) => {
                    if e.kind() == io::ErrorKind::WouldBlock {
                        trace!("read - would block");
                        break;
                    } else {
                        return Err(e);
                    }
                }
            };
        }

        // The buffer could have only grown in the meantime, therefore this is safe from
        // underflow.
        let total_read = self.in_buf.len() - initial_size;
        debug!("total bytes read {}", total_read);

        Ok(total_read)
    }

    /// Attempts to parse the current contents of the input buffer for an h2 frame.
    /// If successful returns a FrameContainer wrapping the frame. The returned `FrameContainer`
    /// will be borrowing the content of the internal buffer, i.e. parsing the frame does not
    /// require creating a new temporary copy of the frame in a new buffer.
    pub fn get_next_frame(&mut self) -> Option<FrameContainer> {
        let raw_frame = RawFrame::parse(&self.in_buf);
        raw_frame.map(|raw_frame| FrameContainer::new(raw_frame))
    }

    /// Discards the current frame from the buffered input.
    pub fn discard_frame(&mut self, size: usize) {
        self.in_buf.drain(..size);
    }
}

<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! Extensions to the standard I/O utilities.
//!
//! This module essentially provides useful, RRG-specific utilities that are not
//! available in `std::io`, mostly operating on the standard `Read` and `Write`
//! traits.

use std::io::{Read, Write, Result};

// The same as in the Rust's standard library.
const DEFAULT_BUF_SIZE: usize = 8 * 1024;

/// Copies contents of one buffer into the other until a condition is met.
///
/// This function should behave similarly to the standard `std::io::copy` with
/// the difference that it can be given a condition when copying should stop.
///
/// Note that the predicate is not checked after each copied byte. Therefore,
/// there are no guarantees about when exactly and how often it will be called.
///
/// # Errors
///
/// The errors is reported immediately if there is an error when reading from
/// the input or writing to the output.
///
/// Like `std::io::copy`, this function will retry instances of `Interrupted`
/// errors.
///
/// # Examples
///
/// ```no_run
/// use std::fs::File;
///
/// let mut rand = File::open("/dev/random").unwrap();
/// let mut buf = vec!();
///
/// rrg::io::copy_until(&mut rand, &mut buf, |_, writer| writer.len() >= 1024);
///
/// println!("random bytes: {:?}", buf);
/// ```
pub fn copy_until<R, W, P>(reader: &mut R, writer: &mut W, mut pred: P)
    -> Result<()>
where
    R: Read,
    W: Write,
    P: FnMut(&R, &W) -> bool,
{
    let mut buf = [0; DEFAULT_BUF_SIZE];
    loop {
        if pred(reader, writer) {
            break;
        }

        use std::io::ErrorKind::*;
        let len = match reader.read(&mut buf[..]) {
            Ok(0) => break,
            Ok(len) => len,
            Err(ref error) if error.kind() == Interrupted => continue,
            Err(error) => return Err(error),
        };

        writer.write_all(&buf[..len])?;
    }

    Ok(())
}

struct IterReader<'a, I> {
    iter: I,
    curr: Option<&'a [u8]>,
}

impl<'a, I> IterReader<'a, I>
where
    I: Iterator<Item=&'a [u8]>,
{
    pub fn new(iter: I) -> IterReader<'a, I> {
        IterReader {
            iter: iter,
            curr: None,
        }
    }
}

impl<'a, I> Read for IterReader<'a, I>
where
    I: Iterator<Item=&'a [u8]>,
{
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        loop {
            if self.curr.is_none() {
                self.curr = self.iter.next();
            }

            // If after executing the previous line there is still no current
            // buffer to read from, it means the underlying iterator is finished
            // and there is no more data.
            let curr = match self.curr {
                Some(ref mut buf) => buf,
                None => return Ok(0),
            };

            // If we read 0 bytes from the current buffer, it means it is empty
            // now. By setting it to `None`, we will try to pull a new one in
            // the next iteration.
            match curr.read(buf)? {
                0 => self.curr = None,
                len => return Ok(len),
            }
        }
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn test_copy_until_with_empty_buffer() {
        let mut reader: &[u8] = b"";
        let mut writer = vec!();

        assert!(copy_until(&mut reader, &mut writer, |_, _| false).is_ok());
        assert_eq!(writer, b"");
    }

    #[test]
    fn test_copy_until_begin() {
        let mut reader: &[u8] = b"foobar";
        let mut writer = vec!();

        assert!(copy_until(&mut reader, &mut writer, |_, _| true).is_ok());
        assert_eq!(writer, b"");
    }

    #[test]
    fn test_copy_until_end() {
        let mut reader: &[u8] = b"foobar";
        let mut writer = vec!();

        assert!(copy_until(&mut reader, &mut writer, |_, _| false).is_ok());
        assert_eq!(writer, b"foobar");
    }

    #[test]
    fn test_copy_until_specific_size() {
        let limit = 4 * 1024 * 1024;

        let mut reader = std::io::repeat(0x42);
        let mut writer = vec!();

        // This should verify that copying eventually stops after the condition
        // is met since the reader is infinite.
        assert! {
            copy_until(&mut reader, &mut writer, |_, writer| {
                writer.len() > limit
            }).is_ok()
        };

        assert!(writer.iter().all(|item| *item == 0x42));
        assert!(writer.len() > limit);
    }

    #[test]
    fn test_iter_reader_with_empty_iter() {
        let mut reader = IterReader::new(std::iter::empty());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"");
    }

    #[test]
    fn test_iter_reader_with_empty_iter_items() {
        let items: Vec<&[u8]> = vec!(b"", b"", b"");

        let mut reader = IterReader::new(items.into_iter());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"");
    }

    #[test]
    fn test_iter_reader_with_single_iter_item() {
        let items: Vec<&[u8]> = vec!(b"foo");

        let mut reader = IterReader::new(items.into_iter());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"foo");
    }

    #[test]
    fn test_iter_reader_with_multiple_iter_items() {
        let items: Vec<&[u8]> = vec!(b"foo", b"bar", b"baz");

        let mut reader = IterReader::new(items.into_iter());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"foobarbaz");
    }
}
<commit_msg>Generalize the bytes iterator reader.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! Extensions to the standard I/O utilities.
//!
//! This module essentially provides useful, RRG-specific utilities that are not
//! available in `std::io`, mostly operating on the standard `Read` and `Write`
//! traits.

use std::io::{Read, Write, Result};

// The same as in the Rust's standard library.
const DEFAULT_BUF_SIZE: usize = 8 * 1024;

/// Copies contents of one buffer into the other until a condition is met.
///
/// This function should behave similarly to the standard `std::io::copy` with
/// the difference that it can be given a condition when copying should stop.
///
/// Note that the predicate is not checked after each copied byte. Therefore,
/// there are no guarantees about when exactly and how often it will be called.
///
/// # Errors
///
/// The errors is reported immediately if there is an error when reading from
/// the input or writing to the output.
///
/// Like `std::io::copy`, this function will retry instances of `Interrupted`
/// errors.
///
/// # Examples
///
/// ```no_run
/// use std::fs::File;
///
/// let mut rand = File::open("/dev/random").unwrap();
/// let mut buf = vec!();
///
/// rrg::io::copy_until(&mut rand, &mut buf, |_, writer| writer.len() >= 1024);
///
/// println!("random bytes: {:?}", buf);
/// ```
pub fn copy_until<R, W, P>(reader: &mut R, writer: &mut W, mut pred: P)
    -> Result<()>
where
    R: Read,
    W: Write,
    P: FnMut(&R, &W) -> bool,
{
    let mut buf = [0; DEFAULT_BUF_SIZE];
    loop {
        if pred(reader, writer) {
            break;
        }

        use std::io::ErrorKind::*;
        let len = match reader.read(&mut buf[..]) {
            Ok(0) => break,
            Ok(len) => len,
            Err(ref error) if error.kind() == Interrupted => continue,
            Err(error) => return Err(error),
        };

        writer.write_all(&buf[..len])?;
    }

    Ok(())
}

struct IterReader<I, R> {
    iter: I,
    curr: Option<R>,
}

impl<I, R> IterReader<I, R>
where
    I: Iterator<Item=R>,
    R: Read,
{
    pub fn new(iter: I) -> IterReader<I, R> {
        IterReader {
            iter: iter,
            curr: None,
        }
    }
}

impl<I, R> Read for IterReader<I, R>
where
    I: Iterator<Item=R>,
    R: Read,
{
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        loop {
            if self.curr.is_none() {
                self.curr = self.iter.next();
            }

            // If after executing the previous line there is still no current
            // buffer to read from, it means the underlying iterator is finished
            // and there is no more data.
            let curr = match self.curr {
                Some(ref mut buf) => buf,
                None => return Ok(0),
            };

            // If we read 0 bytes from the current buffer, it means it is empty
            // now. By setting it to `None`, we will try to pull a new one in
            // the next iteration.
            match curr.read(buf)? {
                0 => self.curr = None,
                len => return Ok(len),
            }
        }
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn test_copy_until_with_empty_buffer() {
        let mut reader: &[u8] = b"";
        let mut writer = vec!();

        assert!(copy_until(&mut reader, &mut writer, |_, _| false).is_ok());
        assert_eq!(writer, b"");
    }

    #[test]
    fn test_copy_until_begin() {
        let mut reader: &[u8] = b"foobar";
        let mut writer = vec!();

        assert!(copy_until(&mut reader, &mut writer, |_, _| true).is_ok());
        assert_eq!(writer, b"");
    }

    #[test]
    fn test_copy_until_end() {
        let mut reader: &[u8] = b"foobar";
        let mut writer = vec!();

        assert!(copy_until(&mut reader, &mut writer, |_, _| false).is_ok());
        assert_eq!(writer, b"foobar");
    }

    #[test]
    fn test_copy_until_specific_size() {
        let limit = 4 * 1024 * 1024;

        let mut reader = std::io::repeat(0x42);
        let mut writer = vec!();

        // This should verify that copying eventually stops after the condition
        // is met since the reader is infinite.
        assert! {
            copy_until(&mut reader, &mut writer, |_, writer| {
                writer.len() > limit
            }).is_ok()
        };

        assert!(writer.iter().all(|item| *item == 0x42));
        assert!(writer.len() > limit);
    }

    #[test]
    fn test_iter_reader_with_empty_iter() {
        let mut reader = IterReader::new(std::iter::empty::<&[u8]>());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"");
    }

    #[test]
    fn test_iter_reader_with_empty_iter_items() {
        let items: Vec<&[u8]> = vec!(b"", b"", b"");

        let mut reader = IterReader::new(items.into_iter());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"");
    }

    #[test]
    fn test_iter_reader_with_single_iter_item() {
        let items: Vec<&[u8]> = vec!(b"foo");

        let mut reader = IterReader::new(items.into_iter());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"foo");
    }

    #[test]
    fn test_iter_reader_with_multiple_iter_items() {
        let items: Vec<&[u8]> = vec!(b"foo", b"bar", b"baz");

        let mut reader = IterReader::new(items.into_iter());
        let mut buf = vec!();
        reader.read_to_end(&mut buf).unwrap();

        assert_eq!(buf, b"foobarbaz");
    }
}
<|endoftext|>