<commit_before>use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use parking_lot::{RwLock, Mutex};
use threadpool::ThreadPool;
use num_cpus;
use bifrost_hasher::{hash_str, hash_bytes};
use raft::{RaftService, IS_LEADER};
use rpc;
use utils::bincode;
use serde;
use super::super::{OpType};
use super::super::super::RaftMsg;
use super::*;

lazy_static! {
    pub static ref THREAD_POOL: Mutex<ThreadPool> = Mutex::new(ThreadPool::new(num_cpus::get()));
}

pub struct Subscriber {
    pub session_id: u64,
    pub client: Arc<SyncServiceClient>
}

pub struct Subscriptions {
    next_id: u64,
    subscribers: HashMap<u64, Subscriber>,
    suber_subs: HashMap<u64, HashSet<u64>>, //suber_id -> sub_id
    subscriptions: HashMap<SubKey, HashSet<u64>>, // key -> sub_id
    sub_suber: HashMap<u64, u64>,
    sub_to_key: HashMap<u64, SubKey>, //sub_id -> sub_key
}

impl Subscriptions {

    pub fn new() -> Subscriptions {
        Subscriptions {
            next_id: 0,
            subscribers: HashMap::new(),
            suber_subs: HashMap::new(),
            subscriptions: HashMap::new(),
            sub_suber: HashMap::new(),
            sub_to_key: HashMap::new(),
        }
    }

    pub fn subscribe(&mut self, key: SubKey, address: &String, session_id: u64) -> Result<u64, ()> {
        let sub_service_id = DEFAULT_SERVICE_ID;
        let suber_id = hash_str(address);
        let suber_exists = self.subscribers.contains_key(&suber_id);
        let sub_id = self.next_id;
        let require_reload_suber = if suber_exists {
            let session_match = self.subscribers.get(&suber_id).unwrap().session_id == session_id;
            if !session_match {
                self.remove_subscriber(suber_id);
                true
            } else {false}
        } else {true};
        if !self.subscribers.contains_key(&suber_id) {
            self.subscribers.insert(suber_id, Subscriber {
                session_id: session_id,
                client: {
                    if let Ok(client) = rpc::DEFAULT_CLIENT_POOL.get(address) {
                        SyncServiceClient::new(sub_service_id, &client)
                    } else {
                        return Err(());
                    }
                }
            });
        }
        self.suber_subs.entry(suber_id).or_insert_with(|| HashSet::new()).insert(sub_id);
        self.subscriptions.entry(key).or_insert_with(|| HashSet::new()).insert(sub_id);
        self.sub_to_key.insert(sub_id, key);
        self.sub_suber.insert(sub_id, suber_id);

        self.next_id += 1;
        Ok(sub_id)
    }

    pub fn remove_subscriber(&mut self, suber_id: u64) {
        let suber_subs = if let Some(sub_ids) = self.suber_subs.get(&suber_id) {
            sub_ids.iter().cloned().collect()
        } else {Vec::<u64>::new()};
        for subs_id in suber_subs {
            self.remove_subscription(subs_id)
        }
        self.subscribers.remove(&suber_id);
        self.suber_subs.remove(&suber_id);
    }

    pub fn remove_subscription(&mut self, id: u64) {
        let sub_key = self.sub_to_key.remove(&id);
        if let Some(sub_key) = sub_key {
            if let Some(ref mut sub_subers) = self.subscriptions.get_mut(&sub_key) {
                sub_subers.remove(&id);
                self.sub_suber.remove(&id);
            }
        }
    }
}

pub struct SMCallback {
    pub subscriptions: Arc<RwLock<Subscriptions>>,
    pub raft_service: Arc<RaftService>,
    pub sm_id: u64,
}

impl SMCallback {
    pub fn new(state_machine_id: u64, raft_service: Arc<RaftService>) -> SMCallback {
        let meta = raft_service.meta.read();
        let sm = meta.state_machine.read();
        let subs = sm.configs.subscriptions.clone();
        SMCallback {
            subscriptions: subs,
            raft_service: raft_service.clone(),
            sm_id: state_machine_id,
        }
    }
    pub fn notify<R>(&self, func: &RaftMsg<R>, data: R)
    where R: serde::Serialize + Send + Sync {
        if !IS_LEADER.get() {return;}
        let (fn_id, op_type, pattern_data) = func.encode();
        match op_type {
            OpType::SUBSCRIBE => {
                let pattern_id = hash_bytes(&pattern_data.as_slice());
                let raft_sid = self.raft_service.options.service_id;
                let sm_id = self.sm_id;
                let key = (raft_sid, sm_id, fn_id, pattern_id);
                let svr_subs = self.subscriptions.read();
                if let Some(sub_ids) = svr_subs.subscriptions.get(&key) {
                    let data = bincode::serialize(&data);
                    for sub_id in sub_ids {
                        if let Some(subscriber_id) = svr_subs.sub_suber.get(&sub_id) {
                            if let Some(subscriber) = svr_subs.subscribers.get(&subscriber_id) {
                                let data = data.clone();
                                let client = subscriber.client.clone();
                                THREAD_POOL.lock().execute(move || {
                                    client.notify(&key, &data);
                                });
                            }
                        }
                    }
                }
            },
            _ => {
                panic!("Cannot notify on {:?}")
            }
        }
    }
}

pub fn notify<R, F>(callback: &Option<SMCallback>, func: &RaftMsg<R>, data: F)
    where F: Fn() -> R,
          R: serde::Serialize + Send + Sync {
    if let Some(ref callback) = *callback {
        callback.notify(func, data());
    }
}<commit_msg>revert<commit_after>use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use parking_lot::{RwLock, Mutex};
use num_cpus;
use bifrost_hasher::{hash_str, hash_bytes};
use raft::{RaftService, IS_LEADER};
use rpc;
use utils::bincode;
use serde;
use super::super::{OpType};
use super::super::super::RaftMsg;
use super::*;
use futures::future;

pub struct Subscriber {
    pub session_id: u64,
    pub client: Arc<AsyncServiceClient>
}

pub struct Subscriptions {
    next_id: u64,
    subscribers: HashMap<u64, Subscriber>,
    suber_subs: HashMap<u64, HashSet<u64>>, //suber_id -> sub_id
    subscriptions: HashMap<SubKey, HashSet<u64>>, // key -> sub_id
    sub_suber: HashMap<u64, u64>,
    sub_to_key: HashMap<u64, SubKey>, //sub_id -> sub_key
}

impl Subscriptions {

    pub fn new() -> Subscriptions {
        Subscriptions {
            next_id: 0,
            subscribers: HashMap::new(),
            suber_subs: HashMap::new(),
            subscriptions: HashMap::new(),
            sub_suber: HashMap::new(),
            sub_to_key: HashMap::new(),
        }
    }

    pub fn subscribe(&mut self, key: SubKey, address: &String, session_id: u64) -> Result<u64, ()> {
        let sub_service_id = DEFAULT_SERVICE_ID;
        let suber_id = hash_str(address);
        let suber_exists = self.subscribers.contains_key(&suber_id);
        let sub_id = self.next_id;
        let require_reload_suber = if suber_exists {
            let session_match = self.subscribers.get(&suber_id).unwrap().session_id == session_id;
            if !session_match {
                self.remove_subscriber(suber_id);
                true
            } else {false}
        } else {true};
        if !self.subscribers.contains_key(&suber_id) {
            self.subscribers.insert(suber_id, Subscriber {
                session_id: session_id,
                client: {
                    if let Ok(client) = rpc::DEFAULT_CLIENT_POOL.get(address) {
                        AsyncServiceClient::new(sub_service_id, &client)
                    } else {
                        return Err(());
                    }
                }
            });
        }
        self.suber_subs.entry(suber_id).or_insert_with(|| HashSet::new()).insert(sub_id);
        self.subscriptions.entry(key).or_insert_with(|| HashSet::new()).insert(sub_id);
        self.sub_to_key.insert(sub_id, key);
        self.sub_suber.insert(sub_id, suber_id);

        self.next_id += 1;
        Ok(sub_id)
    }

    pub fn remove_subscriber(&mut self, suber_id: u64) {
        let suber_subs = if let Some(sub_ids) = self.suber_subs.get(&suber_id) {
            sub_ids.iter().cloned().collect()
        } else {Vec::<u64>::new()};
        for subs_id in suber_subs {
            self.remove_subscription(subs_id)
        }
        self.subscribers.remove(&suber_id);
        self.suber_subs.remove(&suber_id);
    }

    pub fn remove_subscription(&mut self, id: u64) {
        let sub_key = self.sub_to_key.remove(&id);
        if let Some(sub_key) = sub_key {
            if let Some(ref mut sub_subers) = self.subscriptions.get_mut(&sub_key) {
                sub_subers.remove(&id);
                self.sub_suber.remove(&id);
            }
        }
    }
}

pub struct SMCallback {
    pub subscriptions: Arc<RwLock<Subscriptions>>,
    pub raft_service: Arc<RaftService>,
    pub sm_id: u64,
}

#[derive(Debug, Clone, Copy)]
pub enum NotifyFailure {
    IsNotLeader,
    OpTypeNotSubscribe,
    CannotFindSubscription,
    CannotFindSubscribers,
    CannotFindSubscriber
}

impl SMCallback {
    pub fn new(state_machine_id: u64, raft_service: Arc<RaftService>) -> SMCallback {
        let meta = raft_service.meta.read();
        let sm = meta.state_machine.read();
        let subs = sm.configs.subscriptions.clone();
        SMCallback {
            subscriptions: subs,
            raft_service: raft_service.clone(),
            sm_id: state_machine_id,
        }
    }
    pub fn notify<R>(&self, func: &RaftMsg<R>, data: R)
        -> Result<(Vec<NotifyFailure>, Vec<rpc::RPCError>), NotifyFailure>
    where R: serde::Serialize + Send + Sync {
        if !IS_LEADER.get() {return Err(NotifyFailure::IsNotLeader);}
        let (fn_id, op_type, pattern_data) = func.encode();
        match op_type {
            OpType::SUBSCRIBE => {
                let pattern_id = hash_bytes(&pattern_data.as_slice());
                let raft_sid = self.raft_service.options.service_id;
                let sm_id = self.sm_id;
                let key = (raft_sid, sm_id, fn_id, pattern_id);
                let svr_subs = self.subscriptions.read();
                if let Some(sub_ids) = svr_subs.subscriptions.get(&key) {
                    let data = bincode::serialize(&data);
                    let sub_result: Vec<_> = sub_ids.iter().map(|sub_id| {
                        if let Some(subscriber_id) = svr_subs.sub_suber.get(&sub_id) {
                            if let Some(subscriber) = svr_subs.subscribers.get(&subscriber_id) {
                                let data = data.clone();
                                let client = subscriber.client.clone();
                                Ok(client.notify(&key, &data))
                            } else {
                                Err(NotifyFailure::CannotFindSubscriber)
                            }
                        } else {
                            Err(NotifyFailure::CannotFindSubscribers)
                        }
                    }).collect();
                    let errors = sub_result.iter()
                        .filter(|r| r.is_err())
                        .map(|r| {if let &Err(e) = r { Some(e) } else { None }})
                        .map(|o| o.clone().unwrap())
                        .collect::<Vec<NotifyFailure>>();
                    let req_errors = sub_result.into_iter()
                        .filter(|r| r.is_ok())
                        .map(|r| r.unwrap())
                        .map(|req| req.wait())
                        .filter(|res| res.is_err())
                        .map(|res| res.err().unwrap())
                        .collect::<Vec<_>>();
                    return Ok((errors, req_errors));
                } else {
                    return Err(NotifyFailure::CannotFindSubscription)
                }
            },
            _ => {
                return Err(NotifyFailure::OpTypeNotSubscribe)
            }
        }
    }
}

pub fn notify<R, F>(callback: &Option<SMCallback>, func: &RaftMsg<R>, data: F)
    where F: Fn() -> R,
          R: serde::Serialize + Send + Sync {
    if let Some(ref callback) = *callback {
        callback.notify(func, data());
    }
}<|endoftext|>


<commit_before>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-pass

fn main() {
    println!("{}", 0u32 - 1);
    //~^ WARN const_err
    //~| WARN const_err
    let _x = 0u32 - 1;
    //~^ WARN const_err
    println!("{}", 1/(1-1));
    //~^ WARN const_err
    //~| WARN const_err
    let _x = 1/(1-1);
    //~^ WARN const_err
    //~| WARN const_err
    println!("{}", 1/(false as u32));
    //~^ WARN const_err
    let _x = 1/(false as u32);
}
<commit_msg>always optimize test<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-pass
// compile-flags: -O
fn main() {
    println!("{}", 0u32 - 1);
    //~^ WARN const_err
    //~| WARN const_err
    let _x = 0u32 - 1;
    //~^ WARN const_err
    println!("{}", 1/(1-1));
    //~^ WARN const_err
    //~| WARN const_err
    let _x = 1/(1-1);
    //~^ WARN const_err
    //~| WARN const_err
    println!("{}", 1/(false as u32));
    //~^ WARN const_err
    let _x = 1/(false as u32);
}
<|endoftext|>


<commit_before>use syntax::ast::{Expr, ExprKind, UnOp};
use rustc::lint::*;
use utils::{snippet, span_lint_and_sugg};

/// **What it does:** Checks for usage of `*&` and `*&mut` in expressions.
///
/// **Why is this bad?** Immediately dereferencing a reference is no-op and
/// makes the code less clear.
///
/// **Known problems:** Multiple dereference/addrof pairs are not handled so
/// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.
///
/// **Example:**
/// ```rust
/// let a = f(*&mut b);
/// let c = *&d;
/// ```
declare_clippy_lint! {
    pub DEREF_ADDROF,
    complexity,
    "use of `*&` or `*&mut` in an expression"
}

pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(DEREF_ADDROF)
    }
}

fn without_parens(mut e: &Expr) -> &Expr {
    while let ExprKind::Paren(ref child_e) = e.node {
        e = child_e;
    }
    e
}

impl EarlyLintPass for Pass {
    fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) {
        if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node {
            if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node {
                span_lint_and_sugg(
                    cx,
                    DEREF_ADDROF,
                    e.span,
                    "immediately dereferencing a reference",
                    "try this",
                    format!("{}", snippet(cx, addrof_target.span, "_")),
                );
            }
        }
    }
}
<commit_msg>Refactored nested if lets to if_chain! macro<commit_after>use syntax::ast::{Expr, ExprKind, UnOp};
use rustc::lint::*;
use utils::{snippet, span_lint_and_sugg};

/// **What it does:** Checks for usage of `*&` and `*&mut` in expressions.
///
/// **Why is this bad?** Immediately dereferencing a reference is no-op and
/// makes the code less clear.
///
/// **Known problems:** Multiple dereference/addrof pairs are not handled so
/// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.
///
/// **Example:**
/// ```rust
/// let a = f(*&mut b);
/// let c = *&d;
/// ```
declare_clippy_lint! {
    pub DEREF_ADDROF,
    complexity,
    "use of `*&` or `*&mut` in an expression"
}

pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(DEREF_ADDROF)
    }
}

fn without_parens(mut e: &Expr) -> &Expr {
    while let ExprKind::Paren(ref child_e) = e.node {
        e = child_e;
    }
    e
}

impl EarlyLintPass for Pass {
    fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) {
        if_chain! {
            if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node;
            if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node;
            then {
                span_lint_and_sugg(
                    cx,
                    DEREF_ADDROF,
                    e.span,
                    "immediately dereferencing a reference",
                    "try this",
                    format!("{}", snippet(cx, addrof_target.span, "_")),
                );
            }
        }
    }
}
<|endoftext|>


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

//! The `ByteString` struct.

use std::borrow::ToOwned;
use std::hash::{Hash, Hasher};
use std::ops;
use std::str;
use std::str::FromStr;

/// Encapsulates the IDL `ByteString` type.
#[derive(Clone,Eq,PartialEq)]
#[jstraceable]
pub struct ByteString(Vec<u8>);

impl ByteString {
    /// Creates a new `ByteString`.
    pub fn new(value: Vec<u8>) -> ByteString {
        ByteString(value)
    }

    /// Returns `self` as a string, if it encodes valid UTF-8, and `None`
    /// otherwise.
    pub fn as_str<'a>(&'a self) -> Option<&'a str> {
        let ByteString(ref vec) = *self;
        str::from_utf8(&vec).ok()
    }

    /// Returns the length.
    pub fn len(&self) -> usize {
        let ByteString(ref vector) = *self;
        vector.len()
    }

    /// Compare `self` to `other`, matching A–Z and a–z as equal.
    pub fn eq_ignore_case(&self, other: &ByteString) -> bool {
        // XXXManishearth make this more efficient
        self.to_lower() == other.to_lower()
    }

    /// Returns `self` with A–Z replaced by a–z.
    pub fn to_lower(&self) -> ByteString {
        let ByteString(ref vec) = *self;
        ByteString::new(vec.iter().map(|&x| {
            if x > 'A' as u8 && x < 'Z' as u8 {
                x + ('a' as u8) - ('A' as u8)
            } else {
                x
            }
        }).collect())
    }

    /// Returns whether `self` is a `token`, as defined by
    /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-17).
    pub fn is_token(&self) -> bool {
        let ByteString(ref vec) = *self;
        if vec.len() == 0 {
            return false; // A token must be at least a single character
        }
        vec.iter().all(|&x| {
            // http://tools.ietf.org/html/rfc2616#section-2.2
            match x {
                0...31 | 127 => false, // CTLs
                40 | 41 | 60 | 62 | 64 |
                44 | 59 | 58 | 92 | 34 |
                47 | 91 | 93 | 63 | 61 |
                123 | 125 | 32  => false, // separators
                x if x > 127 => false, // non-CHARs
                _ => true
            }
        })
    }

    /// Returns whether `self` is a `field-value`, as defined by
    /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-32).
    pub fn is_field_value(&self) -> bool {
        // Classifications of characters necessary for the [CRLF] (SP|HT) rule
        #[derive(PartialEq)]
        enum PreviousCharacter {
            Other,
            CR,
            LF,
            SPHT // SP or HT
        }
        let ByteString(ref vec) = *self;
        let mut prev = PreviousCharacter::Other; // The previous character
        vec.iter().all(|&x| {
            // http://tools.ietf.org/html/rfc2616#section-2.2
            match x {
                13  => { // CR
                    if prev == PreviousCharacter::Other || prev == PreviousCharacter::SPHT {
                        prev = PreviousCharacter::CR;
                        true
                    } else {
                        false
                    }
                },
                10 => { // LF
                    if prev == PreviousCharacter::CR {
                        prev = PreviousCharacter::LF;
                        true
                    } else {
                        false
                    }
                },
                32 => { // SP
                    if prev == PreviousCharacter::LF || prev == PreviousCharacter::SPHT {
                        prev = PreviousCharacter::SPHT;
                        true
                    } else if prev == PreviousCharacter::Other {
                        // Counts as an Other here, since it's not preceded by a CRLF
                        // SP is not a CTL, so it can be used anywhere
                        // though if used immediately after a CR the CR is invalid
                        // We don't change prev since it's already Other
                        true
                    } else {
                        false
                    }
                },
                9 => { // HT
                    if prev == PreviousCharacter::LF || prev == PreviousCharacter::SPHT {
                        prev = PreviousCharacter::SPHT;
                        true
                    } else {
                        false
                    }
                },
                0...31 | 127 => false, // CTLs
                x if x > 127 => false, // non ASCII
                _ if prev == PreviousCharacter::Other || prev == PreviousCharacter::SPHT => {
                    prev = PreviousCharacter::Other;
                    true
                },
                _ => false // Previous character was a CR/LF but not part of the [CRLF] (SP|HT) rule
            }
        })
    }
}

impl Hash for ByteString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        let ByteString(ref vec) = *self;
        vec.hash(state);
    }
}

impl FromStr for ByteString {
    type Err = ();
    fn from_str(s: &str) -> Result<ByteString, ()> {
        Ok(ByteString::new(s.to_owned().into_bytes()))
    }
}

impl ops::Deref for ByteString {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        &self.0
    }
}

/// A string that is constructed from a UCS-2 buffer by replacing invalid code
/// points with the replacement character.
pub struct USVString(pub String);
<commit_msg>Use AsciiExt in ByteString implementations.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! The `ByteString` struct.

use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::hash::{Hash, Hasher};
use std::ops;
use std::str;
use std::str::FromStr;

/// Encapsulates the IDL `ByteString` type.
#[derive(Clone,Eq,PartialEq)]
#[jstraceable]
pub struct ByteString(Vec<u8>);

impl ByteString {
    /// Creates a new `ByteString`.
    pub fn new(value: Vec<u8>) -> ByteString {
        ByteString(value)
    }

    /// Returns `self` as a string, if it encodes valid UTF-8, and `None`
    /// otherwise.
    pub fn as_str<'a>(&'a self) -> Option<&'a str> {
        let ByteString(ref vec) = *self;
        str::from_utf8(&vec).ok()
    }

    /// Returns the length.
    pub fn len(&self) -> usize {
        let ByteString(ref vector) = *self;
        vector.len()
    }

    /// Compare `self` to `other`, matching A–Z and a–z as equal.
    pub fn eq_ignore_case(&self, other: &ByteString) -> bool {
        self.0.eq_ignore_ascii_case(&other.0)
    }

    /// Returns `self` with A–Z replaced by a–z.
    pub fn to_lower(&self) -> ByteString {
        ByteString::new(self.0.to_ascii_lowercase())
    }

    /// Returns whether `self` is a `token`, as defined by
    /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-17).
    pub fn is_token(&self) -> bool {
        let ByteString(ref vec) = *self;
        if vec.len() == 0 {
            return false; // A token must be at least a single character
        }
        vec.iter().all(|&x| {
            // http://tools.ietf.org/html/rfc2616#section-2.2
            match x {
                0...31 | 127 => false, // CTLs
                40 | 41 | 60 | 62 | 64 |
                44 | 59 | 58 | 92 | 34 |
                47 | 91 | 93 | 63 | 61 |
                123 | 125 | 32  => false, // separators
                x if x > 127 => false, // non-CHARs
                _ => true
            }
        })
    }

    /// Returns whether `self` is a `field-value`, as defined by
    /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-32).
    pub fn is_field_value(&self) -> bool {
        // Classifications of characters necessary for the [CRLF] (SP|HT) rule
        #[derive(PartialEq)]
        enum PreviousCharacter {
            Other,
            CR,
            LF,
            SPHT // SP or HT
        }
        let ByteString(ref vec) = *self;
        let mut prev = PreviousCharacter::Other; // The previous character
        vec.iter().all(|&x| {
            // http://tools.ietf.org/html/rfc2616#section-2.2
            match x {
                13  => { // CR
                    if prev == PreviousCharacter::Other || prev == PreviousCharacter::SPHT {
                        prev = PreviousCharacter::CR;
                        true
                    } else {
                        false
                    }
                },
                10 => { // LF
                    if prev == PreviousCharacter::CR {
                        prev = PreviousCharacter::LF;
                        true
                    } else {
                        false
                    }
                },
                32 => { // SP
                    if prev == PreviousCharacter::LF || prev == PreviousCharacter::SPHT {
                        prev = PreviousCharacter::SPHT;
                        true
                    } else if prev == PreviousCharacter::Other {
                        // Counts as an Other here, since it's not preceded by a CRLF
                        // SP is not a CTL, so it can be used anywhere
                        // though if used immediately after a CR the CR is invalid
                        // We don't change prev since it's already Other
                        true
                    } else {
                        false
                    }
                },
                9 => { // HT
                    if prev == PreviousCharacter::LF || prev == PreviousCharacter::SPHT {
                        prev = PreviousCharacter::SPHT;
                        true
                    } else {
                        false
                    }
                },
                0...31 | 127 => false, // CTLs
                x if x > 127 => false, // non ASCII
                _ if prev == PreviousCharacter::Other || prev == PreviousCharacter::SPHT => {
                    prev = PreviousCharacter::Other;
                    true
                },
                _ => false // Previous character was a CR/LF but not part of the [CRLF] (SP|HT) rule
            }
        })
    }
}

impl Hash for ByteString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        let ByteString(ref vec) = *self;
        vec.hash(state);
    }
}

impl FromStr for ByteString {
    type Err = ();
    fn from_str(s: &str) -> Result<ByteString, ()> {
        Ok(ByteString::new(s.to_owned().into_bytes()))
    }
}

impl ops::Deref for ByteString {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        &self.0
    }
}

/// A string that is constructed from a UCS-2 buffer by replacing invalid code
/// points with the replacement character.
pub struct USVString(pub String);
<|endoftext|>


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

extern crate devicemapper;
extern crate env_logger;
extern crate libstratis;
extern crate log;
extern crate serde_json;

mod util;

use std::fs::OpenOptions;
use std::path::{Path, PathBuf};

use serde_json::{Value, from_reader};

use self::devicemapper::{Bytes, Sectors};

use libstratis::consts::IEC;
use libstratis::engine::strat_engine::device::wipe_sectors;

use util::logger::init_logger;
use util::simple_tests::test_basic_metadata;
use util::simple_tests::test_empty_pool;
use util::simple_tests::test_force_flag_dirty;
use util::simple_tests::test_force_flag_stratis;
use util::simple_tests::test_linear_device;
use util::simple_tests::test_pool_blockdevs;
use util::simple_tests::test_setup;
use util::simple_tests::test_teardown;
use util::simple_tests::test_thinpool_device;

/// Set up count devices from configuration file.
/// Wipe first GiB on each device.
fn get_devices(count: u8) -> Option<Vec<PathBuf>> {
    let file = OpenOptions::new()
        .read(true)
        .open("tests/test_config.json")
        .unwrap();
    let config: Value = from_reader(&file).unwrap();
    let devpaths = config
        .get("ok_to_destroy_dev_array_key")
        .unwrap()
        .as_array()
        .unwrap();
    if devpaths.len() < count as usize {
        return None;
    }
    let devices: Vec<PathBuf> = devpaths
        .iter()
        .take(count as usize)
        .map(|x| PathBuf::from(x.as_str().unwrap()))
        .collect();

    let length = Bytes(IEC::Gi as u64).sectors();
    for device in devices.iter() {
        wipe_sectors(device, Sectors(0), length).unwrap();
    }

    Some(devices)
}

/// Run test on count real devices.
fn test_with_spec<F>(count: u8, test: F) -> ()
    where F: Fn(&[&Path]) -> ()
{
    init_logger();
    let devices = get_devices(count).unwrap();
    let device_paths: Vec<&Path> = devices.iter().map(|x| x.as_path()).collect();
    test(&device_paths);
}

#[test]
pub fn real_test_force_flag_stratis() {
    test_with_spec(2, test_force_flag_stratis);
    test_with_spec(3, test_force_flag_stratis);
}

#[test]
pub fn real_test_linear_device() {
    test_with_spec(2, test_linear_device);
    test_with_spec(3, test_linear_device);
}

#[test]
pub fn real_test_thinpool_device() {
    test_with_spec(3, test_thinpool_device);
}

#[test]
pub fn real_test_pool_blockdevs() {
    test_with_spec(3, test_pool_blockdevs);
}

#[test]
pub fn real_test_force_flag_dirty() {
    test_with_spec(3, test_force_flag_dirty);
}

#[test]
pub fn real_test_teardown() {
    test_with_spec(2, test_teardown);
}

#[test]
pub fn real_test_setup() {
    test_with_spec(4, test_setup);
}

#[test]
pub fn real_test_empty_pool() {
    test_with_spec(0, test_empty_pool)
}

#[test]
pub fn real_test_basic_metadata() {
    test_with_spec(4, test_basic_metadata);
}
<commit_msg>decrease the space we wipe on device from 1 GiB to 1 MiB<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

extern crate devicemapper;
extern crate env_logger;
extern crate libstratis;
extern crate log;
extern crate serde_json;

mod util;

use std::fs::OpenOptions;
use std::path::{Path, PathBuf};

use serde_json::{Value, from_reader};

use self::devicemapper::{Bytes, Sectors};

use libstratis::consts::IEC;
use libstratis::engine::strat_engine::device::wipe_sectors;

use util::logger::init_logger;
use util::simple_tests::test_basic_metadata;
use util::simple_tests::test_empty_pool;
use util::simple_tests::test_force_flag_dirty;
use util::simple_tests::test_force_flag_stratis;
use util::simple_tests::test_linear_device;
use util::simple_tests::test_pool_blockdevs;
use util::simple_tests::test_setup;
use util::simple_tests::test_teardown;
use util::simple_tests::test_thinpool_device;

/// Set up count devices from configuration file.
/// Wipe first MiB on each device.
fn get_devices(count: u8) -> Option<Vec<PathBuf>> {
    let file = OpenOptions::new()
        .read(true)
        .open("tests/test_config.json")
        .unwrap();
    let config: Value = from_reader(&file).unwrap();
    let devpaths = config
        .get("ok_to_destroy_dev_array_key")
        .unwrap()
        .as_array()
        .unwrap();
    if devpaths.len() < count as usize {
        return None;
    }
    let devices: Vec<PathBuf> = devpaths
        .iter()
        .take(count as usize)
        .map(|x| PathBuf::from(x.as_str().unwrap()))
        .collect();

    let length = Bytes(IEC::Mi as u64).sectors();
    for device in devices.iter() {
        wipe_sectors(device, Sectors(0), length).unwrap();
    }

    Some(devices)
}

/// Run test on count real devices.
fn test_with_spec<F>(count: u8, test: F) -> ()
    where F: Fn(&[&Path]) -> ()
{
    init_logger();
    let devices = get_devices(count).unwrap();
    let device_paths: Vec<&Path> = devices.iter().map(|x| x.as_path()).collect();
    test(&device_paths);
}

#[test]
pub fn real_test_force_flag_stratis() {
    test_with_spec(2, test_force_flag_stratis);
    test_with_spec(3, test_force_flag_stratis);
}

#[test]
pub fn real_test_linear_device() {
    test_with_spec(2, test_linear_device);
    test_with_spec(3, test_linear_device);
}

#[test]
pub fn real_test_thinpool_device() {
    test_with_spec(3, test_thinpool_device);
}

#[test]
pub fn real_test_pool_blockdevs() {
    test_with_spec(3, test_pool_blockdevs);
}

#[test]
pub fn real_test_force_flag_dirty() {
    test_with_spec(3, test_force_flag_dirty);
}

#[test]
pub fn real_test_teardown() {
    test_with_spec(2, test_teardown);
}

#[test]
pub fn real_test_setup() {
    test_with_spec(4, test_setup);
}

#[test]
pub fn real_test_empty_pool() {
    test_with_spec(0, test_empty_pool)
}

#[test]
pub fn real_test_basic_metadata() {
    test_with_spec(4, test_basic_metadata);
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::net::{TcpListener, SocketAddr, TcpStream};
use std::io::prelude::*;
use std::thread;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::io::BufReader;

pub struct Server {
    messages: Option<Sender<Message>>,
    addr: SocketAddr,
    thread: Option<thread::JoinHandle<()>>,
}

enum Message {
    Read(String),
    Write(String),
}

fn run(listener: &TcpListener, rx: &Receiver<Message>) {
    let mut socket = BufReader::new(listener.accept().unwrap().0);
    for msg in rx.iter() {
        match msg {
            Message::Read(ref expected) => {
                let mut expected = &expected[..];
                let mut expected_headers = HashSet::new();
                while let Some(i) = expected.find("\n") {
                    let line = &expected[..i + 1];
                    expected = &expected[i + 1..];
                    if line == "\r" || line == "" {
                        break
                    }
                    expected_headers.insert(line);
                }
                if expected.len() > 0 {
                    assert!(expected_headers.insert(expected));
                }

                while expected_headers.len() > 0 {
                    let mut actual = String::new();
                    t!(socket.read_line(&mut actual));
                    if !expected_headers.remove(&actual[..]) {
                        panic!("unexpected header: {:?} (remaining headers {:?})",
                               actual, expected_headers);
                    }
                }
                for header in expected_headers {
                    panic!("expected header but not found: {:?}", header);
                }

                let mut buf = vec![0; expected.len()];
                if buf.len() > 0 {
                    t!(socket.read_exact(&mut buf));
                    assert_eq!(buf, expected.as_bytes());
                }
            }
            Message::Write(ref to_write) => {
                t!(socket.get_mut().write_all(to_write.as_bytes()));
                return
            }
        }
    }

    let mut dst = Vec::new();
    t!(socket.read_to_end(&mut dst));
    assert!(dst.len() == 0);
}

impl Server {
    pub fn new() -> Server {
        let listener = t!(TcpListener::bind("127.0.0.1:0"));
        let addr = t!(listener.local_addr());
        let (tx, rx) = channel();
        let thread = thread::spawn(move || run(&listener, &rx));
        Server {
            messages: Some(tx),
            addr: addr,
            thread: Some(thread),
        }
    }

    pub fn receive(&self, msg: &str) {
        let msg = msg.replace("$PORT", &self.addr.port().to_string());
        self.msg(Message::Read(msg));
    }

    pub fn send(&self, msg: &str) {
        let msg = msg.replace("$PORT", &self.addr.port().to_string());
        self.msg(Message::Write(msg));
    }

    fn msg(&self, msg: Message) {
        t!(self.messages.as_ref().unwrap().send(msg));
    }

    pub fn addr(&self) -> &SocketAddr {
        &self.addr
    }

    pub fn url(&self, path: &str) -> String {
        format!("http://{}{}", self.addr, path)
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        drop(TcpStream::connect(&self.addr));
        drop(self.messages.take());
        let res = self.thread.take().unwrap().join();
        if !thread::panicking() {
            t!(res);
        } else if let Err(e) = res {
            println!("child server thread also failed: {:?}", e);
        }
    }
}
<commit_msg>Fix the testing server to correctly look for a body<commit_after>use std::collections::HashSet;
use std::net::{TcpListener, SocketAddr, TcpStream};
use std::io::prelude::*;
use std::thread;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::io::BufReader;

pub struct Server {
    messages: Option<Sender<Message>>,
    addr: SocketAddr,
    thread: Option<thread::JoinHandle<()>>,
}

enum Message {
    Read(String),
    Write(String),
}

fn run(listener: &TcpListener, rx: &Receiver<Message>) {
    let mut socket = BufReader::new(listener.accept().unwrap().0);
    for msg in rx.iter() {
        match msg {
            Message::Read(ref expected) => {
                let mut expected = &expected[..];
                let mut expected_headers = HashSet::new();
                while let Some(i) = expected.find("\n") {
                    let line = &expected[..i + 1];
                    expected = &expected[i + 1..];
                    expected_headers.insert(line);
                    if line == "\r\n" {
                        break
                    }
                }

                while expected_headers.len() > 0 {
                    let mut actual = String::new();
                    t!(socket.read_line(&mut actual));
                    if !expected_headers.remove(&actual[..]) {
                        panic!("unexpected header: {:?} (remaining headers {:?})",
                               actual, expected_headers);
                    }
                }
                for header in expected_headers {
                    panic!("expected header but not found: {:?}", header);
                }

                let mut buf = vec![0; expected.len()];
                if buf.len() > 0 {
                    t!(socket.read_exact(&mut buf));
                    assert_eq!(buf, expected.as_bytes());
                }
            }
            Message::Write(ref to_write) => {
                t!(socket.get_mut().write_all(to_write.as_bytes()));
                return
            }
        }
    }

    let mut dst = Vec::new();
    t!(socket.read_to_end(&mut dst));
    assert!(dst.len() == 0);
}

impl Server {
    pub fn new() -> Server {
        let listener = t!(TcpListener::bind("127.0.0.1:0"));
        let addr = t!(listener.local_addr());
        let (tx, rx) = channel();
        let thread = thread::spawn(move || run(&listener, &rx));
        Server {
            messages: Some(tx),
            addr: addr,
            thread: Some(thread),
        }
    }

    pub fn receive(&self, msg: &str) {
        let msg = msg.replace("$PORT", &self.addr.port().to_string());
        self.msg(Message::Read(msg));
    }

    pub fn send(&self, msg: &str) {
        let msg = msg.replace("$PORT", &self.addr.port().to_string());
        self.msg(Message::Write(msg));
    }

    fn msg(&self, msg: Message) {
        t!(self.messages.as_ref().unwrap().send(msg));
    }

    pub fn addr(&self) -> &SocketAddr {
        &self.addr
    }

    pub fn url(&self, path: &str) -> String {
        format!("http://{}{}", self.addr, path)
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        drop(TcpStream::connect(&self.addr));
        drop(self.messages.take());
        let res = self.thread.take().unwrap().join();
        if !thread::panicking() {
            t!(res);
        } else if let Err(e) = res {
            println!("child server thread also failed: {:?}", e);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added some documentation to the `complete_trait_impl` completion.<commit_after><|endoftext|>


<commit_before>fn main() {
    // Pull in jemalloc when enabled.
    //
    // Note that we're pulling in a static copy of jemalloc which means that to
    // pull it in we need to actually reference its symbols for it to get
    // linked. The two crates we link to here, std and rustc_driver, are both
    // dynamic libraries. That means to pull in jemalloc we need to actually
    // reference allocation symbols one way or another (as this file is the only
    // object code in the rustc executable).
    #[cfg(feature = "jemalloc-sys")]
    {
        use std::os::raw::{c_int, c_void};

        #[used]
        static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc;
        #[used]
        static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int =
            jemalloc_sys::posix_memalign;
        #[used]
        static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc;
        #[used]
        static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc;
        #[used]
        static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
        #[used]
        static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;
    }

    rustc_driver::set_sigpipe_handler();
    rustc_driver::main()
}
<commit_msg>Fix typo<commit_after>fn main() {
    // Pull in jemalloc when enabled.
    //
    // Note that we're pulling in a static copy of jemalloc which means that to
    // pull it in we need to actually reference its symbols for it to get
    // linked. The two crates we link to here, std and rustc_driver, are both
    // dynamic libraries. That means to pull in jemalloc we actually need to
    // reference allocation symbols one way or another (as this file is the only
    // object code in the rustc executable).
    #[cfg(feature = "jemalloc-sys")]
    {
        use std::os::raw::{c_int, c_void};

        #[used]
        static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc;
        #[used]
        static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int =
            jemalloc_sys::posix_memalign;
        #[used]
        static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc;
        #[used]
        static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc;
        #[used]
        static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
        #[used]
        static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;
    }

    rustc_driver::set_sigpipe_handler();
    rustc_driver::main()
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use libra_log_derive::Schema;

#[test]
fn simple() {
    #[derive(Schema)]
    pub struct Test {
        required: usize,
        optional: Option<usize>,
    }

    let t = Test {
        required: 0,
        optional: None,
    };

    t.required(1).optional(2);
}

#[test]
fn lifetime() {
    #[derive(Default, Schema)]
    pub struct Test<'a> {
        s: Option<&'a str>,
    }

    let t = Test::default();

    t.s("foo");
}

#[test]
fn generic() {
    #[derive(Default, Schema)]
    pub struct Test<T: ::serde::Serialize> {
        s: Option<T>,
    }

    let t = Test::default();

    t.s(5);
}

#[test]
fn attrs() {
    #[derive(Default, Schema)]
    pub struct Test {
        #[schema(debug)]
        debug: Option<Vec<usize>>,
        #[schema(display)]
        display: Option<usize>,
    }

    let t = Test::default();

    t.debug(vec![1, 2, 3]).display(4);
}
<commit_msg>logger: add test for Error trait objects<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use libra_log_derive::Schema;

#[test]
fn simple() {
    #[derive(Schema)]
    pub struct Test {
        required: usize,
        optional: Option<usize>,
    }

    let t = Test {
        required: 0,
        optional: None,
    };

    t.required(1).optional(2);
}

#[test]
fn lifetime() {
    #[derive(Default, Schema)]
    pub struct Test<'a> {
        s: Option<&'a str>,
    }

    let t = Test::default();

    t.s("foo");
}

#[test]
fn generic() {
    #[derive(Default, Schema)]
    pub struct Test<T: ::serde::Serialize> {
        s: Option<T>,
    }

    let t = Test::default();

    t.s(5);
}

#[test]
fn attrs() {
    #[derive(Default, Schema)]
    pub struct Test {
        #[schema(debug)]
        debug: Option<Vec<usize>>,
        #[schema(display)]
        display: Option<usize>,
    }

    let t = Test::default();

    t.debug(vec![1, 2, 3]).display(4);
}

#[test]
fn error_trait_object() {
    use std::fmt;

    #[derive(Default, Schema)]
    pub struct Test<'a> {
        #[schema(debug)]
        debug_error: Option<&'a dyn ::std::error::Error>,
        #[schema(display)]
        display_error: Option<&'a dyn ::std::error::Error>,
    }

    #[derive(Debug)]
    struct OurError;

    impl fmt::Display for OurError {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "Custom Error")
        }
    }

    impl ::std::error::Error for OurError {};

    let debug_error = ::std::io::Error::new(::std::io::ErrorKind::Other, "This is an error");
    let display_error = OurError;
    let t = Test::default()
        .debug_error(&debug_error)
        .display_error(&display_error);

    ::libra_logger::info!(t);
}
<|endoftext|>


<commit_before>use std::path::{Path, PathBuf};

use bullet::{Options, Result, System};
use bullet::database::{ColumnKind, ColumnValue, Database};
use bullet::server::Server;

use support;

const HALT_MESSAGE: &'static str = "bullet:halt";

const USAGE: &'static str = "
Usage: bullet power [options]

Options:
    --server   HOST:PORT     Redis server (default 127.0.0.0:6379).
    --queue    NAME          Queue for distributing jobs (default bullet).
    --caching                Enable caching of McPAT optimization results.
    --database PATH          SQLite3 database (default bullet.sqlite3).
    --table    NAME          Table name for dumping results (default bullet).
    --help                   Display this message.
";

pub fn execute(options: &Options) -> Result<()> {
    use mcpat::Component;

    macro_rules! push(
        ($columns:expr, $items:expr) => ({
            for item in $items {
                $columns.push(ColumnValue::Float(item.dynamic_power()));
                $columns.push(ColumnValue::Float(item.leakage_power()));
            }
        });
    );

    if options.get::<bool>("help").unwrap_or(false) {
        ::usage(USAGE);
    }

    try!(System::setup(options));

    let mut server = try!(Server::connect(options));
    let database = try!(Database::open(options));
    let mut recorder = None;

    loop {
        let message = ok!(server.receive());

        match &message[..] {
            HALT_MESSAGE => break,
            _ => {},
        }

        let config = PathBuf::from(message);
        let time = try!(derive_time(&config));
        let system = try!(System::open(&config));

        let recorder = match recorder {
            Some(ref mut recorder) => recorder,
            _ => {
                let (cores, l3s) = (system.cores(), system.l3s());
                let names = support::generate(&[(&["core#_dynamic", "core#_leakage"], cores),
                                                (&["l3#_dynamic", "l3#_leakage"], l3s)]);

                let mut columns = vec![];
                columns.push((ColumnKind::Integer, "time"));
                for name in names.iter() {
                    columns.push((ColumnKind::Float, name));
                }

                recorder = Some(try!(database.record(&columns)));
                recorder.as_mut().unwrap()
            }
        };

        let processor = try!(system.compute());

        let mut columns = vec![ColumnValue::Integer(time as i64)];
        push!(columns, processor.cores());
        push!(columns, processor.l3s());

        try!(recorder.write(&columns));
    }

    Ok(())
}

// Format: power-{start time}-{end time}-{elapsed time}.xml
pub fn derive_time(path: &Path) -> Result<u64> {
    macro_rules! bad(
        () => (raise!("encountered a malformed file path"));
    );
    let mut name = match path.file_name() {
        Some(name) => match name.to_str() {
            Some(name) => name,
            _ => bad!(),
        },
        _ => bad!(),
    };
    if !name.starts_with("power-") || !name.ends_with(".xml") {
        bad!();
    }
    name = &name[6..(name.len() - 4)];
    let i = match name.find('-') {
        Some(i) => i + 1,
        _ => bad!(),
    };
    let j = match name.rfind('-') {
        Some(j) => j,
        _ => bad!(),
    };
    name = &name[i..j];
    match name.parse::<u64>() {
        Ok(time) => Ok(time),
        _ => bad!(),
    }
}
<commit_msg>Update the filename format expected by power<commit_after>use std::path::{Path, PathBuf};

use bullet::{Options, Result, System};
use bullet::database::{ColumnKind, ColumnValue, Database};
use bullet::server::Server;

use support;

const HALT_MESSAGE: &'static str = "bullet:halt";

const USAGE: &'static str = "
Usage: bullet power [options]

Options:
    --server   HOST:PORT     Redis server (default 127.0.0.0:6379).
    --queue    NAME          Queue for distributing jobs (default bullet).
    --caching                Enable caching of McPAT optimization results.
    --database PATH          SQLite3 database (default bullet.sqlite3).
    --table    NAME          Table name for dumping results (default bullet).
    --help                   Display this message.
";

pub fn execute(options: &Options) -> Result<()> {
    use mcpat::Component;

    macro_rules! push(
        ($columns:expr, $items:expr) => ({
            for item in $items {
                $columns.push(ColumnValue::Float(item.dynamic_power()));
                $columns.push(ColumnValue::Float(item.leakage_power()));
            }
        });
    );

    if options.get::<bool>("help").unwrap_or(false) {
        ::usage(USAGE);
    }

    try!(System::setup(options));

    let mut server = try!(Server::connect(options));
    let database = try!(Database::open(options));
    let mut recorder = None;

    loop {
        let message = ok!(server.receive());

        match &message[..] {
            HALT_MESSAGE => break,
            _ => {},
        }

        let config = PathBuf::from(message);
        let time = try!(derive_time(&config));
        let system = try!(System::open(&config));

        let recorder = match recorder {
            Some(ref mut recorder) => recorder,
            _ => {
                let (cores, l3s) = (system.cores(), system.l3s());
                let names = support::generate(&[(&["core#_dynamic", "core#_leakage"], cores),
                                                (&["l3#_dynamic", "l3#_leakage"], l3s)]);

                let mut columns = vec![];
                columns.push((ColumnKind::Integer, "time"));
                for name in names.iter() {
                    columns.push((ColumnKind::Float, name));
                }

                recorder = Some(try!(database.record(&columns)));
                recorder.as_mut().unwrap()
            }
        };

        let processor = try!(system.compute());

        let mut columns = vec![ColumnValue::Integer(time as i64)];
        push!(columns, processor.cores());
        push!(columns, processor.l3s());

        try!(recorder.write(&columns));
    }

    Ok(())
}

// Format: power-{time}-{whatever}.xml
pub fn derive_time(path: &Path) -> Result<u64> {
    macro_rules! bad(
        () => (raise!("encountered a malformed file path"));
    );
    let mut name = match path.file_name() {
        Some(name) => match name.to_str() {
            Some(name) => name,
            _ => bad!(),
        },
        _ => bad!(),
    };
    if !name.starts_with("power-") || !name.ends_with(".xml") {
        bad!();
    }
    name = &name[6..];
    let i = match name.find('-') {
        Some(i) => i,
        _ => bad!(),
    };
    name = &name[..i];
    match name.parse::<u64>() {
        Ok(time) => Ok(time),
        _ => bad!(),
    }
}
<|endoftext|>


<commit_before>//! Callback methods for rustwlc
use rustwlc::handle::{WlcOutput, WlcView};
use rustwlc::types::*;
use rustwlc::input::{pointer, keyboard};

use registry::{self, RegistryGetData};

use rustc_serialize::json::Json;
use std::sync::Arc;

use std::thread;

use compositor;
use super::keys::{self, KeyPress, KeyEvent};
use super::layout::{try_lock_tree, ContainerType};
use super::lua::{self, LuaQuery};
use super::background;

/// If the event is handled by way-cooler
const EVENT_HANDLED: bool = true;

/// If the event should be passed through to clients
const EVENT_PASS_THROUGH: bool = false;

// wlc callbacks

pub extern fn output_created(output: WlcOutput) -> bool {
    trace!("output_created: {:?}: {}", output, output.get_name());
    if let Ok(mut tree) = try_lock_tree() {
        tree.add_output(output).and_then(|_|{
            tree.switch_to_workspace(&"1")
        }).is_ok()
    } else {
        false
    }
}

pub extern fn output_destroyed(output: WlcOutput) {
    trace!("output_destroyed: {:?}", output);
}

pub extern fn output_focus(output: WlcOutput, focused: bool) {
    trace!("output_focus: {:?} focus={}", output, focused);
}

pub extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    trace!("output_resolution: {:?} from  {:?} to {:?}",
           output, *old_size_ptr, *new_size_ptr);
    // Update the resolution of the output and its children
    output.set_resolution(new_size_ptr.clone());
    if let Ok(mut tree) = try_lock_tree() {
        tree.layout_active_of(ContainerType::Output)
            .expect("Could not layout active output");
    }
}

pub extern fn view_created(view: WlcView) -> bool {
    trace!("view_created: {:?}: \"{}\"", view, view.get_title());
    if let Ok(mut tree) = try_lock_tree() {
        tree.add_view(view.clone()).and_then(|_| {
            tree.set_active_view(view)
        }).is_ok()
    } else {
        false
    }
}

pub extern fn view_destroyed(view: WlcView) {
    trace!("view_destroyed: {:?}", view);
    if let Ok(mut tree) = try_lock_tree() {
        tree.remove_view(view.clone()).and_then(|_| {
            tree.layout_active_of(ContainerType::Workspace)
        }).unwrap_or_else(|err| {
            error!("Error in view_destroyed: {}", err);
        });
    } else {
        error!("Could not delete view {:?}", view);
    }
}

pub extern fn view_focus(current: WlcView, focused: bool) {
    trace!("view_focus: {:?} {}", current, focused);
    current.set_state(VIEW_ACTIVATED, focused);
    // set the focus view in the tree
    // If tree is already grabbed,
    // it should have the active container all set
    if let Ok(mut tree) = try_lock_tree() {
        if tree.set_active_view(current.clone()).is_err() {
            error!("Could not layout {:?}", current);
        }
    }
}

pub extern fn view_move_to_output(current: WlcView,
                                  o1: WlcOutput, o2: WlcOutput) {
    trace!("view_move_to_output: {:?}, {:?}, {:?}", current, o1, o2);
}

pub extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    trace!("view_request_geometry: {:?} wants {:?}", view, geometry);
    warn!("Denying view {} request for size", view.get_title());
}

pub extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    trace!("view_request_state: {}, {:?}, handled: {}",
    view.get_title(), state, handled);
    view.set_state(state, handled);
}

pub extern fn view_request_move(view: WlcView, dest: &Point) {
    // Called by views when they have a dang resize mouse thing, we should only
    // let it happen in view floating mode
    compositor::start_interactive_move(&view, dest);
    trace!("view_request_move: to {}", *dest);
}

pub extern fn view_request_resize(view: WlcView,
                              edge: ResizeEdge, location: &Point) {
    compositor::start_interactive_resize(&view, edge, location);
    trace!("view_request_resize: edge {:?}, to {}",
             edge, location);
}

pub extern fn keyboard_key(_view: WlcView, _time: u32, mods: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    if state == KeyState::Pressed {
        // TODO this function will throw an error in Rustwlc right now
        // let mut keys = keyboard::get_current_keys().into_iter()
        //      .map(|&k| Keysym::from(k)).collect();
        let sym = keyboard::get_keysym_for_key(key, &KeyMod::empty());
        let press = KeyPress::new(mods.mods, sym);
        if let Some(action) = keys::get(&press) {
            debug!("[key] Found an action for {}", press);
            match action {
                KeyEvent::Command(func) => {
                    func();
                },
                KeyEvent::Lua => {
                    match lua::send(LuaQuery::HandleKey(press)) {
                        Ok(_) => {},
                        Err(err) => {
                            // We may want to wait for Lua's reply from
                            // keypresses; for example if the table is tampered
                            // with or Lua is restarted or Lua has an error.
                            // ATM Lua asynchronously logs this but in the future
                            // an error popup/etc is a good idea.
                            error!("Error sending keypress: {:?}", err);
                        }
                    }
                }
            }
            return EVENT_HANDLED
        }
    }

    return EVENT_PASS_THROUGH
}

pub extern fn pointer_button(view: WlcView, _time: u32,
                         mods: &KeyboardModifiers, button: u32,
                             state: ButtonState, point: &Point) -> bool {
    compositor::on_pointer_button(view, _time, mods, button, state, point)
}

pub extern fn pointer_scroll(_view: WlcView, _time: u32,
                         _mods_ptr: &KeyboardModifiers, axis: ScrollAxis,
                         heights: [f64; 2]) -> bool {
    trace!("pointer_scroll: {:?} {:?}", axis,
           heights.iter().map(|f| f.clone().round()).collect::<Vec<f64>>());
    false
}

pub extern fn pointer_motion(_view: WlcView, _time: u32, point: &Point) -> bool {
    pointer::set_position(point);
    compositor::on_pointer_motion(_view, _time, point)
}

/*
pub extern fn touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}
*/

pub extern fn compositor_ready() {
    info!("Preparing compositor!");
    info!("Initializing Lua...");
    lua::init();
    info!("Loading background...");
    let maybe_color: Result<Arc<Json>, ()> = registry::get_data("background")
        .map(RegistryGetData::resolve).and_then(|(_, data)| {
            Ok(data)
        }).map_err(|_| ());
    if let Ok(color) = maybe_color {
        match *color {
            Json::F64(hex_color) => {
                for output in WlcOutput::list() {
                    let color = background::Color::from_u32(hex_color as u32);
                    // different thread for each output.
                    thread::spawn(move || {background::generate_solid_background(color, output.clone());});
                }
            }
            _ => {
                error!("Non-solid color backgrounds not yet supported, {:?}", color);
            }
        }
    } else {
        warn!("Couldn't read background value");
    }
}

pub extern fn compositor_terminating() {
    info!("Compositor terminating!");
    lua::send(lua::LuaQuery::Terminate).ok();
    if let Ok(mut tree) = try_lock_tree() {
        if tree.destroy_tree().is_err() {
            error!("Could not destroy tree");
        }
    }

}

pub fn init() {
    use rustwlc::callback;

    callback::output_created(output_created);
    callback::output_destroyed(output_destroyed);
    callback::output_focus(output_focus);
    callback::output_resolution(output_resolution);
    callback::view_created(view_created);
    callback::view_destroyed(view_destroyed);
    callback::view_focus(view_focus);
    callback::view_move_to_output(view_move_to_output);
    callback::view_request_geometry(view_request_geometry);
    callback::view_request_state(view_request_state);
    callback::view_request_move(view_request_move);
    callback::view_request_resize(view_request_resize);
    callback::keyboard_key(keyboard_key);
    callback::pointer_button(pointer_button);
    callback::pointer_scroll(pointer_scroll);
    callback::pointer_motion(pointer_motion);
    callback::compositor_ready(compositor_ready);
    callback::compositor_terminate(compositor_terminating);
    trace!("Registered wlc callbacks");
}
<commit_msg>Log prune in unused/trivial callbacks<commit_after>//! Callback methods for rustwlc
use rustwlc::handle::{WlcOutput, WlcView};
use rustwlc::types::*;
use rustwlc::input::{pointer, keyboard};

use registry::{self, RegistryGetData};

use rustc_serialize::json::Json;
use std::sync::Arc;

use std::thread;

use compositor;
use super::keys::{self, KeyPress, KeyEvent};
use super::layout::{try_lock_tree, ContainerType};
use super::lua::{self, LuaQuery};
use super::background;

/// If the event is handled by way-cooler
const EVENT_HANDLED: bool = true;

/// If the event should be passed through to clients
const EVENT_PASS_THROUGH: bool = false;

// wlc callbacks

pub extern fn output_created(output: WlcOutput) -> bool {
    trace!("output_created: {:?}: {}", output, output.get_name());
    if let Ok(mut tree) = try_lock_tree() {
        tree.add_output(output).and_then(|_|{
            tree.switch_to_workspace(&"1")
        }).is_ok()
    } else {
        false
    }
}

pub extern fn output_destroyed(output: WlcOutput) {
    trace!("output_destroyed: {:?}", output);
}

pub extern fn output_focus(output: WlcOutput, focused: bool) {
    trace!("output_focus: {:?} focus={}", output, focused);
}

pub extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    trace!("output_resolution: {:?} from  {:?} to {:?}",
           output, *old_size_ptr, *new_size_ptr);
    // Update the resolution of the output and its children
    output.set_resolution(new_size_ptr.clone());
    if let Ok(mut tree) = try_lock_tree() {
        tree.layout_active_of(ContainerType::Output)
            .expect("Could not layout active output");
    }
}

pub extern fn view_created(view: WlcView) -> bool {
    trace!("view_created: {:?}: \"{}\"", view, view.get_title());
    if let Ok(mut tree) = try_lock_tree() {
        tree.add_view(view.clone()).and_then(|_| {
            tree.set_active_view(view)
        }).is_ok()
    } else {
        false
    }
}

pub extern fn view_destroyed(view: WlcView) {
    trace!("view_destroyed: {:?}", view);
    if let Ok(mut tree) = try_lock_tree() {
        tree.remove_view(view.clone()).and_then(|_| {
            tree.layout_active_of(ContainerType::Workspace)
        }).unwrap_or_else(|err| {
            error!("Error in view_destroyed: {}", err);
        });
    } else {
        error!("Could not delete view {:?}", view);
    }
}

pub extern fn view_focus(current: WlcView, focused: bool) {
    trace!("view_focus: {:?} {}", current, focused);
    current.set_state(VIEW_ACTIVATED, focused);
    // set the focus view in the tree
    // If tree is already grabbed,
    // it should have the active container all set
    if let Ok(mut tree) = try_lock_tree() {
        if tree.set_active_view(current.clone()).is_err() {
            error!("Could not layout {:?}", current);
        }
    }
}

pub extern fn view_move_to_output(current: WlcView,
                                  o1: WlcOutput, o2: WlcOutput) {
    trace!("view_move_to_output: {:?}, {:?}, {:?}", current, o1, o2);
}

pub extern fn view_request_geometry(_view: WlcView, _geometry: &Geometry) {
}

pub extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    view.set_state(state, handled);
}

pub extern fn view_request_move(view: WlcView, dest: &Point) {
    // Called by views when they have a dang resize mouse thing, we should only
    // let it happen in view floating mode
    compositor::start_interactive_move(&view, dest);
}

pub extern fn view_request_resize(view: WlcView,
                              edge: ResizeEdge, location: &Point) {
    compositor::start_interactive_resize(&view, edge, location);
}

pub extern fn keyboard_key(_view: WlcView, _time: u32, mods: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    if state == KeyState::Pressed {
        // TODO this function will throw an error in Rustwlc right now
        // let mut keys = keyboard::get_current_keys().into_iter()
        //      .map(|&k| Keysym::from(k)).collect();
        let sym = keyboard::get_keysym_for_key(key, &KeyMod::empty());
        let press = KeyPress::new(mods.mods, sym);
        if let Some(action) = keys::get(&press) {
            debug!("[key] Found an action for {}", press);
            match action {
                KeyEvent::Command(func) => {
                    func();
                },
                KeyEvent::Lua => {
                    match lua::send(LuaQuery::HandleKey(press)) {
                        Ok(_) => {},
                        Err(err) => {
                            // We may want to wait for Lua's reply from
                            // keypresses; for example if the table is tampered
                            // with or Lua is restarted or Lua has an error.
                            // ATM Lua asynchronously logs this but in the future
                            // an error popup/etc is a good idea.
                            error!("Error sending keypress: {:?}", err);
                        }
                    }
                }
            }
            return EVENT_HANDLED
        }
    }

    return EVENT_PASS_THROUGH
}

pub extern fn pointer_button(view: WlcView, _time: u32,
                         mods: &KeyboardModifiers, button: u32,
                             state: ButtonState, point: &Point) -> bool {
    compositor::on_pointer_button(view, _time, mods, button, state, point)
}

pub extern fn pointer_scroll(_view: WlcView, _time: u32,
                         _mods_ptr: &KeyboardModifiers, axis: ScrollAxis,
                         heights: [f64; 2]) -> bool {
    false
}

pub extern fn pointer_motion(_view: WlcView, _time: u32, point: &Point) -> bool {
    pointer::set_position(point);
    compositor::on_pointer_motion(_view, _time, point)
}

pub extern fn compositor_ready() {
    info!("Preparing compositor!");
    info!("Initializing Lua...");
    lua::init();
    info!("Loading background...");
    let maybe_color: Result<Arc<Json>, ()> = registry::get_data("background")
        .map(RegistryGetData::resolve).and_then(|(_, data)| {
            Ok(data)
        }).map_err(|_| ());
    if let Ok(color) = maybe_color {
        match *color {
            Json::F64(hex_color) => {
                for output in WlcOutput::list() {
                    let color = background::Color::from_u32(hex_color as u32);
                    // different thread for each output.
                    thread::spawn(move || {background::generate_solid_background(color, output.clone());});
                }
            }
            _ => {
                error!("Non-solid color backgrounds not yet supported, {:?}", color);
            }
        }
    } else {
        warn!("Couldn't read background value");
    }
}

pub extern fn compositor_terminating() {
    info!("Compositor terminating!");
    lua::send(lua::LuaQuery::Terminate).ok();
    if let Ok(mut tree) = try_lock_tree() {
        if tree.destroy_tree().is_err() {
            error!("Could not destroy tree");
        }
    }

}

pub fn init() {
    use rustwlc::callback;

    callback::output_created(output_created);
    callback::output_destroyed(output_destroyed);
    callback::output_focus(output_focus);
    callback::output_resolution(output_resolution);
    callback::view_created(view_created);
    callback::view_destroyed(view_destroyed);
    callback::view_focus(view_focus);
    callback::view_move_to_output(view_move_to_output);
    callback::view_request_geometry(view_request_geometry);
    callback::view_request_state(view_request_state);
    callback::view_request_move(view_request_move);
    callback::view_request_resize(view_request_resize);
    callback::keyboard_key(keyboard_key);
    callback::pointer_button(pointer_button);
    callback::pointer_scroll(pointer_scroll);
    callback::pointer_motion(pointer_motion);
    callback::compositor_ready(compositor_ready);
    callback::compositor_terminate(compositor_terminating);
    trace!("Registered wlc callbacks");
}
<|endoftext|>


<commit_before>pub fn alive_or_dead(o_p: &mut Vec<i32>, t_p: &mut Vec<i32>, status: &mut Vec<i32>) {
    for x in 0..o_p.len() - 1 {
        if t_p[x] == o_p[x] && t_p[x + 1] == o_p[x + 1]{
            status.pop();
            status.push(0);
        } else {
            status.pop();
            status.push(1);
        }
    }
}

// work on deciding to not have trails or to keep trails

// trails are in the combined array

// basic collision is comparing latests positions

// complex collision is checking position to all previous positions

#[test]
fn it_can_tell_if_a_bike_died() {
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut bike_stats = vec![];

    one_pos.push(0);
    one_pos.push(50);
    two_pos.push(0);
    two_pos.push(50);

    alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    assert_eq!(0, bike_stats[0]);
}

#[test]
fn it_can_tell_if_a_bike_is_alive() {
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut bike_stats = vec![];

    one_pos.push(100);
    one_pos.push(50);
    two_pos.push(0);
    two_pos.push(50);

    alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    assert_eq!(1, bike_stats[0]);
}
<commit_msg>removed todo comments<commit_after>pub fn alive_or_dead(o_p: &mut Vec<i32>, t_p: &mut Vec<i32>, status: &mut Vec<i32>) {
    for x in 0..o_p.len() - 1 {
        if t_p[x] == o_p[x] && t_p[x + 1] == o_p[x + 1]{
            status.pop();
            status.push(0);
        } else {
            status.pop();
            status.push(1);
        }
    }
}

#[test]
fn it_can_tell_if_a_bike_died() {
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut bike_stats = vec![];

    one_pos.push(0);
    one_pos.push(50);
    two_pos.push(0);
    two_pos.push(50);

    alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    assert_eq!(0, bike_stats[0]);
}

#[test]
fn it_can_tell_if_a_bike_is_alive() {
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut bike_stats = vec![];

    one_pos.push(100);
    one_pos.push(50);
    two_pos.push(0);
    two_pos.push(50);

    alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    assert_eq!(1, bike_stats[0]);
}
<|endoftext|>


<commit_before>extern crate tinyrsh;

use std::collections::HashMap;
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::io;
use std::os::unix::io::{RawFd, AsRawFd};
use tinyrsh::select::FdSet;
use tinyrsh::child::PersistentChild;
use tinyrsh::fdstore::{FdStore, OnceAction, OnceAccept};

fn greet_client(fdstore: &FdStore, mut stream: &TcpStream) {
   assert_eq!(stream.write(b"hello\n").expect("greet client failed"), 6);
   stream.write(b"Your fellow peers:");
   let mut v = vec![];
   for other in fdstore.clients.keys() {
       v.push(format!("fd {}", other));
   }
   stream.write(v.join(", ").as_bytes());
   stream.write(b"\n");
}

fn read_child<T: Read>(readt: &mut T) {
    let mut buf = [0; 10];
    let n = readt.read(&mut buf).expect("read_child");
    println!("({} bytes) `{}'", n, String::from_utf8_lossy(&buf[..n]));
}

fn forward_to_remotes<T: Read, S>(child_out: &mut T, clients: &HashMap<S, TcpStream>) -> bool
    where S : std::cmp::Eq, S : std::hash::Hash
{
    let mut buf = [0; 10];
    let n = child_out.read(&mut buf).expect("read_child");
    let child_eof = (n == 0);
    if clients.is_empty() {
        println!("Warning: child output but no remote connected");
        println!("{:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    }
    for mut remote in clients.values(){
        //println!("forwarding to {}", remote.peer_addr().unwrap());
        let written = remote.write(&buf[..n]).expect("remote write");
        assert_eq!(n, written);
    }
    child_eof
}

fn copy_to<T: Read, U: Write>(from: &mut T, to: &mut U) -> bool {
    let mut buf = [0; 10];
    let n = from.read(&mut buf).expect("copy_to read");
    //println!("copy_to read {:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    let written = to.write(&buf[..n]).expect("copy_to write");
    to.flush();
    assert_eq!(n, written);

    n != 0
}

fn main() {
    println!("Hello, world!");

    let mut child = PersistentChild::new("../py-ptysh/ptysh.py");

    // TODO linebuffered? how is child output buffered at all?

    let listener = TcpListener::bind("127.0.0.1:6699").unwrap();

    let mut fdstore = FdStore::new(listener);

    for fd in [child.child.stdout.as_ref().unwrap().as_raw_fd(), child.child.stderr.as_ref().unwrap().as_raw_fd()].iter() {
        println!("inserting child fd {}", fd);
        fdstore.all_fdset.insert(*fd);
    };

   println!("select-looping");
   loop {
       //let readfds = fdstore.all_fdset.readfds_select();
       //for fd in readfds {
       let srvacceptfun = | allfd: &FdStore, a: OnceAccept | -> io::Result<TcpStream> {
              println!("Accepting new connection");
              a.do_accept().map( | (mut stream, addr) | {
                      println!("new client: {:?}", addr);
                      greet_client(allfd, &mut stream);
                      stream
              })
           };
       let active_vec = fdstore.select(&srvacceptfun);
       for active in active_vec {
       match active {
          OnceAction::Other(fd) => {
          if child.is_stdout(fd) {
              println!("child fd {} (stdout) got active", fd);
              let child_eof = forward_to_remotes(child.stdout_as_mut(), &fdstore.clients);
              if child_eof {
                  println!("!!!!!!! child exited. pipe will break now");
                  //println!("exit code: {}", child.wait().expect("child unexpected state"));
                  //ahh, ownership!
              }
              assert!(!child_eof, "child exited, unhandled!");
          } else if child.is_stderr(fd) {
              println!("child fd {} (stderr) got active", fd);
              read_child(child.stderr_as_mut());
          } else {
              assert!(fdstore.clients.contains_key(&fd));
              let cont = {
                  //let ref stream = clients[&i];
                  let stream: &mut TcpStream = fdstore.clients.get_mut(&fd).unwrap();
                  //read_client(stream)
                  copy_to(stream, child.stdin_as_mut())
              };
              if !cont {
                  fdstore.del_client(fd);
              };
          }
          }//Other
    } //match
    } //for
    } //loop
}
<commit_msg>got mutable value back<commit_after>extern crate tinyrsh;

use std::collections::HashMap;
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::io;
use std::os::unix::io::{RawFd, AsRawFd};
use tinyrsh::select::FdSet;
use tinyrsh::child::PersistentChild;
use tinyrsh::fdstore::{FdStore, OnceAction, OnceAccept};

fn greet_client(fdstore: &FdStore, mut stream: &TcpStream) {
   assert_eq!(stream.write(b"hello\n").expect("greet client failed"), 6);
   stream.write(b"Your fellow peers:");
   let mut v = vec![];
   for other in fdstore.clients.keys() {
       v.push(format!("fd {}", other));
   }
   stream.write(v.join(", ").as_bytes());
   stream.write(b"\n");
   for mut client in fdstore.clients.values() {
       client.write(b"new client connected\n");
   }
}

fn read_child<T: Read>(readt: &mut T) {
    let mut buf = [0; 10];
    let n = readt.read(&mut buf).expect("read_child");
    println!("({} bytes) `{}'", n, String::from_utf8_lossy(&buf[..n]));
}

fn forward_to_remotes<T: Read, S>(child_out: &mut T, clients: &HashMap<S, TcpStream>) -> bool
    where S : std::cmp::Eq, S : std::hash::Hash
{
    let mut buf = [0; 10];
    let n = child_out.read(&mut buf).expect("read_child");
    let child_eof = (n == 0);
    if clients.is_empty() {
        println!("Warning: child output but no remote connected");
        println!("{:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    }
    for mut remote in clients.values(){
        //println!("forwarding to {}", remote.peer_addr().unwrap());
        let written = remote.write(&buf[..n]).expect("remote write");
        assert_eq!(n, written);
    }
    child_eof
}

fn copy_to<T: Read, U: Write>(from: &mut T, to: &mut U) -> bool {
    let mut buf = [0; 10];
    let n = from.read(&mut buf).expect("copy_to read");
    //println!("copy_to read {:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    let written = to.write(&buf[..n]).expect("copy_to write");
    to.flush();
    assert_eq!(n, written);

    n != 0
}

fn main() {
    println!("Hello, world!");

    let mut child = PersistentChild::new("../py-ptysh/ptysh.py");

    // TODO linebuffered? how is child output buffered at all?

    let listener = TcpListener::bind("127.0.0.1:6699").unwrap();

    let mut fdstore = FdStore::new(listener);

    for fd in [child.child.stdout.as_ref().unwrap().as_raw_fd(), child.child.stderr.as_ref().unwrap().as_raw_fd()].iter() {
        println!("inserting child fd {}", fd);
        fdstore.all_fdset.insert(*fd);
    };

   println!("select-looping");
   loop {
       //let readfds = fdstore.all_fdset.readfds_select();
       //for fd in readfds {
       let srvacceptfun = | allfd: &FdStore, a: OnceAccept | -> io::Result<TcpStream> {
              println!("Accepting new connection");
              a.do_accept().map( | (mut stream, addr) | {
                      println!("new client: {:?}", addr);
                      greet_client(allfd, &mut stream);
                      stream
              })
           };
       let active_vec = fdstore.select(&srvacceptfun);
       for active in active_vec {
       match active {
          OnceAction::Other(fd) => {
          if child.is_stdout(fd) {
              println!("child fd {} (stdout) got active", fd);
              let child_eof = forward_to_remotes(child.stdout_as_mut(), &fdstore.clients);
              if child_eof {
                  println!("!!!!!!! child exited. pipe will break now");
                  //println!("exit code: {}", child.wait().expect("child unexpected state"));
                  //ahh, ownership!
              }
              assert!(!child_eof, "child exited, unhandled!");
          } else if child.is_stderr(fd) {
              println!("child fd {} (stderr) got active", fd);
              read_child(child.stderr_as_mut());
          } else {
              assert!(fdstore.clients.contains_key(&fd));
              let cont = {
                  //let ref stream = clients[&i];
                  let stream: &mut TcpStream = fdstore.clients.get_mut(&fd).unwrap();
                  //read_client(stream)
                  copy_to(stream, child.stdin_as_mut())
              };
              if !cont {
                  fdstore.del_client(fd);
              };
          }
          }//Other
    } //match
    } //for
    } //loop
}
<|endoftext|>


<commit_before>use std::fmt;
use num::FromPrimitive;

#[derive(Debug)]
pub struct FuncConst {
    pub arg_count: u32,
    pub local_count: u32,
    pub body: Vec<u8>
}

#[derive(Default)]
pub struct ConstTable {
    pub funcs: Vec<FuncConst>,
    pub bc_counter: usize
}

impl fmt::Debug for ConstTable {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //TODO
        unimplemented!()
    }
}

pub fn read_const_table(data: &[u8]) -> ConstTable {

    let mut const_table: ConstTable = Default::default();

    macro_rules! get_next_4_bytes {
        () => {{
            let val = (data[const_table.bc_counter] as u32) << 24 |
            (data[const_table.bc_counter + 1] as u32) << 16 |
            (data[const_table.bc_counter + 2] as u32) << 8 |
            (data[const_table.bc_counter + 3] as u32);
            const_table.bc_counter += 4;
            debug!("get_next_4_bytes: 0x{:04X}", val);
            val
        }}
    }

    while const_table.bc_counter != data.len() {
        let instr = ConstInstr::from_u8(data[const_table.bc_counter]);

        const_table.bc_counter += 1;
        if instr.is_none() {
            warn!("Unimplemented constants table instruction: {:04X}", data[const_table.bc_counter - 1]);
            continue;
        }

        let instr = instr.unwrap();

        match instr {
            ConstInstr::FUNC => {
                // TODO: remove this on the compiler end
                get_next_4_bytes!();
                let arg_count = get_next_4_bytes!();
                let local_count = get_next_4_bytes!();
                let bc_length = get_next_4_bytes!() as usize;
                const_table.funcs.push(FuncConst {
                    arg_count: arg_count,
                    local_count: local_count,
                    body: data[const_table.bc_counter..{const_table.bc_counter += bc_length; const_table.bc_counter + 1}].to_vec()
                });
                debug!("Added a function to the constants table");
            },
            ConstInstr::END => {
                debug!("Reached end of constants table");
                break;
            }
        }
    }
    const_table
}

enum_from_primitive! {
    #[allow(non_camel_case_types)]
    #[derive(Debug, PartialEq)]
    pub enum ConstInstr {
        FUNC = 0xF0,
        END = 0xED
    }
}
<commit_msg>suport for strings kinda<commit_after>use std::fmt;
use std::str;
use num::FromPrimitive;

#[derive(Debug, Default, Clone)]
pub struct FuncConst {
    pub name: &'static str,
    pub arg_count: u32,
    pub local_count: u32,
    pub body: Vec<u8>
}

#[derive(Default)]
pub struct ConstTable {
    pub funcs: Vec<FuncConst>,
    pub bc_counter: usize
}

impl fmt::Debug for ConstTable {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //TODO
        unimplemented!()
    }
}

pub fn read_const_table(data: &[u8]) -> ConstTable {

    let mut const_table: ConstTable = Default::default();

    // TODO: Refactor these macros
    macro_rules! get_next_4_bytes {
        () => {{
            let val = (data[const_table.bc_counter] as u32) << 24 |
            (data[const_table.bc_counter + 1] as u32) << 16 |
            (data[const_table.bc_counter + 2] as u32) << 8 |
            (data[const_table.bc_counter + 3] as u32);
            const_table.bc_counter += 4;
            debug!("get_next_4_bytes: 0x{:04X}", val);
            val
        }}
    }

    // Eats a null byte terminated string
    // TODO: Velo, take a look at this one, I'm sure it can be improved
    macro_rules! eat_string {
        () => {{
            let mut str_len = const_table.bc_counter;
            while data[str_len] != 0x00 {
                str_len += 1;
            }
            let string = str::from_utf8(&data[const_table.bc_counter..str_len]);
            const_table.bc_counter = str_len + 1; // + 1 for null byte
            string
        }}
    }

    while const_table.bc_counter != data.len() {
        let instr = ConstInstr::from_u8(data[const_table.bc_counter]);

        const_table.bc_counter += 1;
        if instr.is_none() {
            warn!("Unimplemented constants table instruction: {:04X}", data[const_table.bc_counter - 1]);
            continue;
        }

        let instr = instr.unwrap();

        match instr {
            ConstInstr::FUNC => {
                // TODO: use this id
                let id = get_next_4_bytes!() as usize;
                let name = eat_string!();
                let arg_count = get_next_4_bytes!();
                let local_count = get_next_4_bytes!();
                let bc_length = get_next_4_bytes!() as usize;
                let body = data[const_table.bc_counter..{const_table.bc_counter += bc_length; const_table.bc_counter + 1}].to_vec();
                if id >= const_table.funcs.len() {
                    const_table.funcs.resize(id + 1, FuncConst{..Default::default()})
                }
                const_table.funcs.push(FuncConst {
                    name: name.unwrap(),
                    arg_count: arg_count,
                    local_count: local_count,
                    body: body
                });
                debug!("Added a function to the constants table");
            },
            ConstInstr::END => {
                debug!("Reached end of constants table");
                break;
            }
        }
    }
    const_table
}

enum_from_primitive! {
    #[allow(non_camel_case_types)]
    #[derive(Debug, PartialEq)]
    pub enum ConstInstr {
        FUNC = 0xF0,
        END = 0xED
    }
}
<|endoftext|>


<commit_before>use num::{One, Zero};
use std::cmp;

use math::{LowerBound, UPoint3, UpperBound, UVector3};
use super::space::{AABB, LogWidth, Partition, Spatial};

#[derive(Clone)]
pub struct Cursor {
    origin: UPoint3,
    width: LogWidth,
    span: UVector3,
}

impl Cursor {
    fn new(origin: &UPoint3, width: LogWidth, span: &UVector3) -> Self {
        Cursor {
            origin: origin.clone(),
            width: width,
            span: span.clone(),
        }
    }

    pub fn at_point(point: &UPoint3, width: LogWidth) -> Self {
        Cursor::at_point_with_span(point, width, &UVector3::zero())
    }

    pub fn at_point_with_span(point: &UPoint3, width: LogWidth, span: &UVector3) -> Self {
        let partition = Partition::at_point(point, width);
        Cursor::new(partition.origin(), width, span)
    }

    pub fn from_point_to_point(start: &UPoint3, end: &UPoint3, width: LogWidth) -> Self {
        let (start, end) = {
            (Partition::at_point(&start.lower_bound(end), width),
             Partition::at_point(&start.upper_bound(end), width))
        };
        let span = (end.origin().to_vector() - start.origin().to_vector()) / width.exp();
        Cursor::new(start.origin(), width, &span)
    }

    pub fn at_cube<C>(cube: &C) -> Self
        where C: Spatial
    {
        Cursor::at_point(cube.partition().origin(), cube.partition().width())
    }

    pub fn at_cube_with_span<C>(cube: &C, span: &UVector3) -> Self
        where C: Spatial
    {
        Cursor::at_point_with_span(cube.partition().origin(), cube.partition().width(), span)
    }

    pub fn from_cube_to_cube<S, E>(start: &S, end: &E) -> Self
        where S: Spatial,
              E: Spatial
    {
        let width = cmp::min(start.partition().width(), end.partition().width());
        let aabb = start.aabb().union(&end.aabb());
        Cursor::from_point_to_point(&aabb.origin, &aabb.endpoint(), width)
    }

    pub fn origin(&self) -> &UPoint3 {
        &self.origin
    }

    pub fn width(&self) -> LogWidth {
        self.width
    }

    pub fn span(&self) -> &UVector3 {
        &self.span
    }

    pub fn extent(&self) -> UVector3 {
        ((self.span + UVector3::one()) * self.width.exp()) - UVector3::one()
    }

    pub fn aabb(&self) -> AABB {
        AABB::new(self.origin, self.extent())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
}
<commit_msg>Documentation.<commit_after>use num::{One, Zero};
use std::cmp;

use math::{LowerBound, UPoint3, UpperBound, UVector3};
use super::space::{AABB, LogWidth, Partition, Spatial};

/// A contiguous selection of cubes in a tree.
///
/// A `Cursor` is essentially a bounding box with an associated width
/// (granularity) used to isolate cubes in a tree.
#[derive(Clone)]
pub struct Cursor {
    /// Location of the `Cursor`. Being in the `UScalar` space, `Cursor`s must
    /// extend positively from their origin. The origin is aligned to the width
    /// of the `Cursor`.
    origin: UPoint3,
    /// Target width of the `Cursor`. This is the granularity of the `Cursor`,
    /// and determines the width of the cubes on which it operates.
    width: LogWidth,
    /// The span of the `Cursor` from its origin. This is based on the width of
    /// the `Cursor`, and each component essentially selects a number of cubes
    /// in the positive direction along that axis. The zero vector means only
    /// one cube is selected by the `Cursor`.
    span: UVector3,
}

impl Cursor {
    fn new(origin: &UPoint3, width: LogWidth, span: &UVector3) -> Self {
        Cursor {
            origin: origin.clone(),
            width: width,
            span: span.clone(),
        }
    }

    pub fn at_point(point: &UPoint3, width: LogWidth) -> Self {
        Cursor::at_point_with_span(point, width, &UVector3::zero())
    }

    pub fn at_point_with_span(point: &UPoint3, width: LogWidth, span: &UVector3) -> Self {
        let partition = Partition::at_point(point, width);
        Cursor::new(partition.origin(), width, span)
    }

    pub fn from_point_to_point(start: &UPoint3, end: &UPoint3, width: LogWidth) -> Self {
        let (start, end) = {
            (Partition::at_point(&start.lower_bound(end), width),
             Partition::at_point(&start.upper_bound(end), width))
        };
        let span = (end.origin().to_vector() - start.origin().to_vector()) / width.exp();
        Cursor::new(start.origin(), width, &span)
    }

    pub fn at_cube<C>(cube: &C) -> Self
        where C: Spatial
    {
        Cursor::at_point(cube.partition().origin(), cube.partition().width())
    }

    pub fn at_cube_with_span<C>(cube: &C, span: &UVector3) -> Self
        where C: Spatial
    {
        Cursor::at_point_with_span(cube.partition().origin(), cube.partition().width(), span)
    }

    pub fn from_cube_to_cube<S, E>(start: &S, end: &E) -> Self
        where S: Spatial,
              E: Spatial
    {
        let width = cmp::min(start.partition().width(), end.partition().width());
        let aabb = start.aabb().union(&end.aabb());
        Cursor::from_point_to_point(&aabb.origin, &aabb.endpoint(), width)
    }

    /// Gets the origin of the `Cursor`.
    pub fn origin(&self) -> &UPoint3 {
        &self.origin
    }

    /// Gets the width associated with the `Cursor`, which is the width of the
    /// cubes that it selects.
    pub fn width(&self) -> LogWidth {
        self.width
    }

    /// Gets the span of the `Cursor` from its origin. This is based on the
    /// width of the `Cursor`, and each component essentially selects a number
    /// of cubes in the positive direction along that axis. A span of zero means
    /// that only one cube is selected by the `Cursor`.
    pub fn span(&self) -> &UVector3 {
        &self.span
    }

    /// Gets the extent of the `Cursor` from its origin.
    pub fn extent(&self) -> UVector3 {
        ((self.span + UVector3::one()) * self.width.exp()) - UVector3::one()
    }

    /// Gets the `AABB` of the `Cursor`.
    pub fn aabb(&self) -> AABB {
        AABB::new(self.origin, self.extent())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
}
<|endoftext|>