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

//! Utilities for working with sessions.
//!
//! Sessions are created per action request and should be used as the only way
//! to communicate with the server. Sessions are responsible for handling action
//! errors (when something goes wrong) or notifying the server that the action
//! finished (by sending appropriate status signal).
//!
//! They also keep track of various statistics (such as number of transferred
//! bytes, action runtime, etc.) and stop the execution if they exceed limits
//! for a particular request.

mod demand;
mod error;
mod response;
mod sink;

use std::convert::TryInto;

use log::{error, info};

use crate::action;
use crate::message;
pub use self::demand::{Demand, Header, Payload};
pub use self::error::{Error, ParseError};
use self::response::{Response, Status};
pub use self::sink::{Sink};

/// A specialized `Result` type for sessions.
pub type Result<T> = std::result::Result<T, Error>;

/// Object associating a session with particular action request.
///
/// This is just a convenience type used to avoid threading large numbers of
/// parameters through different function calls.
///
/// Note that the payload can be quite large object, so it should not be stored
/// with the session itself. The payload should be consumed as soon as the
/// request is dispatched to a particular handler and parsed to a concrete type.
pub struct Task<'s, S: Session> {
    /// A session that this task should be run on.
    pub session: &'s mut S,
    /// Serialized data of the action request.
    pub payload: Payload,
}

impl<'s, S: Session> Task<'s, S> {

    /// Executes the task with a particular action handler.
    pub fn execute<R, H>(self, handler: H) -> Result<()>
    where
        R: action::Request,
        H: FnOnce(&mut S, R) -> Result<()>,
    {
        let request = self.payload.parse()?;
        handler(self.session, request)
    }
}

/// Processes given message, handling all errors.
///
/// This function takes a message from the GRR server and interprets it as an
/// action request. It creates a new session object and dispatches the request
/// to an appropriate action handler. Once the action finishes, the function
/// will send a final status message, informing the server about a success
/// or a failure.
///
/// Note that if action execution fails, this function deals with all the errors
/// by sending appropriate information to the server (if possible), logging them
/// and failing hard if a critical error (e.g. communication failure) occurred.
pub fn handle<M>(message: M)
where
    M: TryInto<Demand, Error=ParseError>,
{
    let demand = match message.try_into() {
        Ok(demand) => {
            info!("requested to execute the '{}' action", demand.action);
            demand
        }
        Err(error) => {
            error!("failed to parse the message: {}", error);
            return;
        }
    };

    let mut session = Action::from_demand(&demand);

    let result = action::dispatch(&demand.action, Task {
        session: &mut session,
        payload: demand.payload,
    });

    if let Err(ref error) = result {
        error!("failed to execute the '{}' action: {}", demand.action, error);
    } else {
        info!("finished executing the '{}' action", demand.action);
    }

    let message = match session.status(result).try_into() {
        Ok(message) => message,
        Err(error) => {
            // If we cannot encode the final status message, there is nothing
            // we can do to notify the server, as status is responsible for
            // reporting errors. We can only log the error and carry on.
            error!("failed to encode status message: {}", error);
            return;
        }
    };

    message::send(message);
}

/// Abstraction for various kinds of sessions.
pub trait Session {
    /// Sends a reply to the flow that call the action.
    fn reply<R>(&mut self, response: R) -> Result<()>
    where R: action::Response;

    /// Sends a message to a particular sink.
    fn send<R>(&mut self, sink: Sink, response: R) -> Result<()>
    where R: action::Response;
}

/// A session type for unrequested action executions.
///
/// Certain kind of actions are executed not only when a server flow decides to
/// do so, but also upon particular kind of events (e.g. the agent's startup).
/// In such cases, when one needs to trigger action execution manually, ad-hoc
/// sessions should be used.
pub struct Adhoc;

impl Session for Adhoc {

    // TODO: Session trait should be probably split into two traits and then
    // make the actions that do not care about the `reply` method implement the
    // simpler one.
    fn reply<R>(&mut self, response: R) -> Result<()>
    where
        R: action::Response,
    {
        error!("attempted to reply to an ad-hoc session, dropping response");
        drop(response);

        Ok(())
    }

    fn send<R>(&mut self, sink: Sink, response: R) -> Result<()>
    where
        R: action::Response,
    {
        send(sink.wrap(response))?;

        Ok(())
    }
}

/// A session type for ordinary action requests.
///
/// This is a normal session type that that is associated with some flow on the
/// server. It keeps track of the responses it sends and collects statistics
/// about network and runtime utilization to kill the action if it is needed.
pub struct Action {
    header: Header,
    next_response_id: u64,
}

impl Action {

    /// Constructs a new session for the given `demand` object.
    pub fn from_demand(demand: &Demand) -> Action {
        Action {
            header: demand.header.clone(),
            next_response_id: 0,
        }
    }

    /// Wraps an action response to a session-specific response.
    fn wrap<R>(&self, response: R) -> Response<R>
    where
        R: action::Response
    {
        Response {
            session_id: self.header.session_id.clone(),
            request_id: Some(self.header.request_id),
            response_id: Some(self.next_response_id),
            data: response,
        }
    }

    /// Wraps an action result to a session-specific status response.
    ///
    /// Note that this method consumes the session. The reason for this is that
    /// status response should be obtained as the very last response and no
    /// further replies should be possible after that.
    fn status(self, result: Result<()>) -> Status {
        Status {
            session_id: self.header.session_id,
            request_id: self.header.request_id,
            response_id: self.next_response_id,
            result: result,
        }
    }
}

impl Session for Action {

    fn reply<R: action::Response>(&mut self, response: R) -> Result<()> {
        send(self.wrap(response))?;
        self.next_response_id += 1;

        Ok(())
    }

    fn send<R>(&mut self, sink: Sink, response: R) -> Result<()>
    where
        R: action::Response,
    {
        send(sink.wrap(response))?;

        Ok(())
    }
}

/// Sends a session response to the server.
///
/// Note that this function is not exposed on purpose. Actions should send
/// responses through session objects which introduce a layer of safety. `send`
/// is a low-level utility supposed to be used internally.
fn send<R>(response: Response<R>) -> Result<()>
where
    R: action::Response,
{
    let message = response.try_into()?;
    message::send(message);

    Ok(())
}
<commit_msg>Fix a bug with incorrect initial response id.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! Utilities for working with sessions.
//!
//! Sessions are created per action request and should be used as the only way
//! to communicate with the server. Sessions are responsible for handling action
//! errors (when something goes wrong) or notifying the server that the action
//! finished (by sending appropriate status signal).
//!
//! They also keep track of various statistics (such as number of transferred
//! bytes, action runtime, etc.) and stop the execution if they exceed limits
//! for a particular request.

mod demand;
mod error;
mod response;
mod sink;

use std::convert::TryInto;

use log::{error, info};

use crate::action;
use crate::message;
pub use self::demand::{Demand, Header, Payload};
pub use self::error::{Error, ParseError};
use self::response::{Response, Status};
pub use self::sink::{Sink};

/// A specialized `Result` type for sessions.
pub type Result<T> = std::result::Result<T, Error>;

/// Object associating a session with particular action request.
///
/// This is just a convenience type used to avoid threading large numbers of
/// parameters through different function calls.
///
/// Note that the payload can be quite large object, so it should not be stored
/// with the session itself. The payload should be consumed as soon as the
/// request is dispatched to a particular handler and parsed to a concrete type.
pub struct Task<'s, S: Session> {
    /// A session that this task should be run on.
    pub session: &'s mut S,
    /// Serialized data of the action request.
    pub payload: Payload,
}

impl<'s, S: Session> Task<'s, S> {

    /// Executes the task with a particular action handler.
    pub fn execute<R, H>(self, handler: H) -> Result<()>
    where
        R: action::Request,
        H: FnOnce(&mut S, R) -> Result<()>,
    {
        let request = self.payload.parse()?;
        handler(self.session, request)
    }
}

/// Processes given message, handling all errors.
///
/// This function takes a message from the GRR server and interprets it as an
/// action request. It creates a new session object and dispatches the request
/// to an appropriate action handler. Once the action finishes, the function
/// will send a final status message, informing the server about a success
/// or a failure.
///
/// Note that if action execution fails, this function deals with all the errors
/// by sending appropriate information to the server (if possible), logging them
/// and failing hard if a critical error (e.g. communication failure) occurred.
pub fn handle<M>(message: M)
where
    M: TryInto<Demand, Error=ParseError>,
{
    let demand = match message.try_into() {
        Ok(demand) => {
            info!("requested to execute the '{}' action", demand.action);
            demand
        }
        Err(error) => {
            error!("failed to parse the message: {}", error);
            return;
        }
    };

    let mut session = Action::from_demand(&demand);

    let result = action::dispatch(&demand.action, Task {
        session: &mut session,
        payload: demand.payload,
    });

    if let Err(ref error) = result {
        error!("failed to execute the '{}' action: {}", demand.action, error);
    } else {
        info!("finished executing the '{}' action", demand.action);
    }

    let message = match session.status(result).try_into() {
        Ok(message) => message,
        Err(error) => {
            // If we cannot encode the final status message, there is nothing
            // we can do to notify the server, as status is responsible for
            // reporting errors. We can only log the error and carry on.
            error!("failed to encode status message: {}", error);
            return;
        }
    };

    message::send(message);
}

/// Abstraction for various kinds of sessions.
pub trait Session {
    /// Sends a reply to the flow that call the action.
    fn reply<R>(&mut self, response: R) -> Result<()>
    where R: action::Response;

    /// Sends a message to a particular sink.
    fn send<R>(&mut self, sink: Sink, response: R) -> Result<()>
    where R: action::Response;
}

/// A session type for unrequested action executions.
///
/// Certain kind of actions are executed not only when a server flow decides to
/// do so, but also upon particular kind of events (e.g. the agent's startup).
/// In such cases, when one needs to trigger action execution manually, ad-hoc
/// sessions should be used.
pub struct Adhoc;

impl Session for Adhoc {

    // TODO: Session trait should be probably split into two traits and then
    // make the actions that do not care about the `reply` method implement the
    // simpler one.
    fn reply<R>(&mut self, response: R) -> Result<()>
    where
        R: action::Response,
    {
        error!("attempted to reply to an ad-hoc session, dropping response");
        drop(response);

        Ok(())
    }

    fn send<R>(&mut self, sink: Sink, response: R) -> Result<()>
    where
        R: action::Response,
    {
        send(sink.wrap(response))?;

        Ok(())
    }
}

/// A session type for ordinary action requests.
///
/// This is a normal session type that that is associated with some flow on the
/// server. It keeps track of the responses it sends and collects statistics
/// about network and runtime utilization to kill the action if it is needed.
pub struct Action {
    header: Header,
    next_response_id: u64,
}

impl Action {

    /// Constructs a new session for the given `demand` object.
    pub fn from_demand(demand: &Demand) -> Action {
        // Response identifiers that GRR agents use start at 0. Unfortunately,
        // the server uses this assumption (to determine the number of expected
        // responses when status message is received), so we have to follow this
        // behaviour in RRG as well.
        Action {
            header: demand.header.clone(),
            next_response_id: 1,
        }
    }

    /// Wraps an action response to a session-specific response.
    fn wrap<R>(&self, response: R) -> Response<R>
    where
        R: action::Response
    {
        Response {
            session_id: self.header.session_id.clone(),
            request_id: Some(self.header.request_id),
            response_id: Some(self.next_response_id),
            data: response,
        }
    }

    /// Wraps an action result to a session-specific status response.
    ///
    /// Note that this method consumes the session. The reason for this is that
    /// status response should be obtained as the very last response and no
    /// further replies should be possible after that.
    fn status(self, result: Result<()>) -> Status {
        Status {
            session_id: self.header.session_id,
            request_id: self.header.request_id,
            response_id: self.next_response_id,
            result: result,
        }
    }
}

impl Session for Action {

    fn reply<R: action::Response>(&mut self, response: R) -> Result<()> {
        send(self.wrap(response))?;
        self.next_response_id += 1;

        Ok(())
    }

    fn send<R>(&mut self, sink: Sink, response: R) -> Result<()>
    where
        R: action::Response,
    {
        send(sink.wrap(response))?;

        Ok(())
    }
}

/// Sends a session response to the server.
///
/// Note that this function is not exposed on purpose. Actions should send
/// responses through session objects which introduce a layer of safety. `send`
/// is a low-level utility supposed to be used internally.
fn send<R>(response: Response<R>) -> Result<()>
where
    R: action::Response,
{
    let message = response.try_into()?;
    message::send(message);

    Ok(())
}
<|endoftext|>


<commit_before>
extern crate glium;

// MARK: Exports
pub mod shaders;
pub mod vertex;
pub mod buffer;

pub use self::vertex::Vertex;

use std::time::{Instant, Duration};

// MARK: Loop

pub enum Action {
    Continue,
    Stop,
}

pub fn as_sec(elapsed: Duration) -> f64 {
    elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1000000000.0
}

pub fn start_loop<F>(mut callback: F)
where
    F: FnMut(f64) -> Action,
{
    let mut last = Instant::now();

    loop {
        let curr = Instant::now();
        let delta: f64 = as_sec(curr - last);
        last = curr;

        match callback(delta) {
            Action::Stop => break,
            Action::Continue => (),
        }
    }
}
<commit_msg>Simplified support::start_loop for use in re-export<commit_after>
extern crate glium;

pub mod shaders;
pub mod vertex;
pub mod buffer;

pub use self::vertex::Vertex;

use std::time::Duration;

pub enum Action {
    Continue,
    Stop,
}

pub fn as_sec(elapsed: Duration) -> f64 {
    elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1000000000.0
}

pub fn start_loop<F>(mut callback: F)
where
    F: FnMut() -> Action,
{
    loop {
        match callback() {
            Action::Stop => break,
            Action::Continue => (),
        }
    }
}
<|endoftext|>


<commit_before>///! Syscall handlers

extern crate syscall;

pub use self::syscall::{data, error, flag, io, number, scheme};

pub use self::driver::*;
pub use self::fs::*;
pub use self::futex::futex;
pub use self::privilege::*;
pub use self::process::*;
pub use self::time::*;
pub use self::validate::*;

use self::data::{SigAction, TimeSpec};
use self::error::{Error, Result, ENOSYS};
use self::number::*;

use context::ContextId;
use interrupt::syscall::SyscallStack;
use scheme::{FileHandle, SchemeNamespace};

/// Debug
pub mod debug;

/// Driver syscalls
pub mod driver;

/// Filesystem syscalls
pub mod fs;

/// Fast userspace mutex
pub mod futex;

/// Privilege syscalls
pub mod privilege;

/// Process syscalls
pub mod process;

/// Time syscalls
pub mod time;

/// Validate input
pub mod validate;

//mod print_call;
//use self::print_call::print_call;

#[no_mangle]
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> usize {
    #[inline(always)]
    fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> Result<usize> {
        match a & SYS_CLASS {
            SYS_CLASS_FILE => {
                let fd = FileHandle::from(b);
                match a & SYS_ARG {
                    SYS_ARG_SLICE => file_op_slice(a, fd, validate_slice(c as *const u8, d)?),
                    SYS_ARG_MSLICE => file_op_mut_slice(a, fd, validate_slice_mut(c as *mut u8, d)?),
                    _ => match a {
                        SYS_CLOSE => close(fd),
                        SYS_DUP => dup(fd, validate_slice(c as *const u8, d)?).map(FileHandle::into),
                        SYS_DUP2 => dup2(fd, FileHandle::from(c), validate_slice(d as *const u8, e)?).map(FileHandle::into),
                        SYS_FCNTL => fcntl(fd, c, d),
                        SYS_FEVENT => fevent(fd, c),
                        SYS_FUNMAP => funmap(b),
                        _ => file_op(a, fd, c, d)
                    }
                }
            },
            SYS_CLASS_PATH => match a {
                SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into),
                SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16),
                SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?),
                SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),
                _ => unreachable!()
            },
            _ => match a {
                SYS_YIELD => sched_yield(),
                SYS_NANOSLEEP => nanosleep(
                    validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?,
                    if c == 0 {
                        None
                    } else {
                        Some(validate_slice_mut(c as *mut TimeSpec, 1).map(|rem| &mut rem[0])?)
                    }
                ),
                SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
                SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
                SYS_BRK => brk(b),
                SYS_GETPID => getpid().map(ContextId::into),
                SYS_GETPGID => getpgid(ContextId::from(b)).map(ContextId::into),
                SYS_GETPPID => getppid().map(ContextId::into),
                SYS_CLONE => clone(b, bp).map(ContextId::into),
                SYS_EXIT => exit((b & 0xFF) << 8),
                SYS_KILL => kill(ContextId::from(b), c),
                SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
                SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
                SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
                SYS_IOPL => iopl(b, stack),
                SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
                SYS_GETEGID => getegid(),
                SYS_GETENS => getens(),
                SYS_GETEUID => geteuid(),
                SYS_GETGID => getgid(),
                SYS_GETNS => getns(),
                SYS_GETUID => getuid(),
                SYS_MKNS => mkns(validate_slice(b as *const [usize; 2], c)?),
                SYS_SETPGID => setpgid(ContextId::from(b), ContextId::from(c)),
                SYS_SETREUID => setreuid(b as u32, c as u32),
                SYS_SETRENS => setrens(SchemeNamespace::from(b), SchemeNamespace::from(c)),
                SYS_SETREGID => setregid(b as u32, c as u32),
                SYS_SIGACTION => sigaction(
                    b,
                    if c == 0 {
                        None
                    } else {
                        Some(validate_slice(c as *const SigAction, 1).map(|act| &act[0])?)
                    },
                    if d == 0 {
                        None
                    } else {
                        Some(validate_slice_mut(d as *mut SigAction, 1).map(|oldact| &mut oldact[0])?)
                    },
                    e
                ),
                SYS_SIGRETURN => sigreturn(),
                SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c),
                SYS_PHYSALLOC => physalloc(b),
                SYS_PHYSFREE => physfree(b, c),
                SYS_PHYSMAP => physmap(b, c, d),
                SYS_PHYSUNMAP => physunmap(b),
                SYS_VIRTTOPHYS => virttophys(b),
                _ => Err(Error::new(ENOSYS))
            }
        }
    }

    /*
    let debug = {
        let contexts = ::context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            if unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) } == "file:/bin/acid" {
                if (a == SYS_WRITE || a == SYS_FSYNC) && (b == 1 || b == 2) {
                    false
                } else {
                    true
                }
            } else {
                false
            }
        } else {
            false
        }
    };

    if debug {
        let contexts = ::context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
        }

        let _ = debug::print_call(a, b, c, d, e, f);
        println!("");
    }
    */

    let result = inner(a, b, c, d, e, f, bp, stack);

    /*
    if debug {
        let contexts = ::context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
        }

        let _ = debug::print_call(a, b, c, d, e, f);

        match result {
            Ok(ref ok) => {
                println!(" = Ok({} ({:#X}))", ok, ok);
            },
            Err(ref err) => {
                println!(" = Err({} ({:#X}))", err, err.errno);
            }
        }
    }
    */

    Error::mux(result)
}
<commit_msg>Change unreachable to enosys<commit_after>///! Syscall handlers

extern crate syscall;

pub use self::syscall::{data, error, flag, io, number, scheme};

pub use self::driver::*;
pub use self::fs::*;
pub use self::futex::futex;
pub use self::privilege::*;
pub use self::process::*;
pub use self::time::*;
pub use self::validate::*;

use self::data::{SigAction, TimeSpec};
use self::error::{Error, Result, ENOSYS};
use self::number::*;

use context::ContextId;
use interrupt::syscall::SyscallStack;
use scheme::{FileHandle, SchemeNamespace};

/// Debug
pub mod debug;

/// Driver syscalls
pub mod driver;

/// Filesystem syscalls
pub mod fs;

/// Fast userspace mutex
pub mod futex;

/// Privilege syscalls
pub mod privilege;

/// Process syscalls
pub mod process;

/// Time syscalls
pub mod time;

/// Validate input
pub mod validate;

//mod print_call;
//use self::print_call::print_call;

#[no_mangle]
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> usize {
    #[inline(always)]
    fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> Result<usize> {
        match a & SYS_CLASS {
            SYS_CLASS_FILE => {
                let fd = FileHandle::from(b);
                match a & SYS_ARG {
                    SYS_ARG_SLICE => file_op_slice(a, fd, validate_slice(c as *const u8, d)?),
                    SYS_ARG_MSLICE => file_op_mut_slice(a, fd, validate_slice_mut(c as *mut u8, d)?),
                    _ => match a {
                        SYS_CLOSE => close(fd),
                        SYS_DUP => dup(fd, validate_slice(c as *const u8, d)?).map(FileHandle::into),
                        SYS_DUP2 => dup2(fd, FileHandle::from(c), validate_slice(d as *const u8, e)?).map(FileHandle::into),
                        SYS_FCNTL => fcntl(fd, c, d),
                        SYS_FEVENT => fevent(fd, c),
                        SYS_FUNMAP => funmap(b),
                        _ => file_op(a, fd, c, d)
                    }
                }
            },
            SYS_CLASS_PATH => match a {
                SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into),
                SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16),
                SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?),
                SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),
                _ => Err(Error::new(ENOSYS))
            },
            _ => match a {
                SYS_YIELD => sched_yield(),
                SYS_NANOSLEEP => nanosleep(
                    validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?,
                    if c == 0 {
                        None
                    } else {
                        Some(validate_slice_mut(c as *mut TimeSpec, 1).map(|rem| &mut rem[0])?)
                    }
                ),
                SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
                SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
                SYS_BRK => brk(b),
                SYS_GETPID => getpid().map(ContextId::into),
                SYS_GETPGID => getpgid(ContextId::from(b)).map(ContextId::into),
                SYS_GETPPID => getppid().map(ContextId::into),
                SYS_CLONE => clone(b, bp).map(ContextId::into),
                SYS_EXIT => exit((b & 0xFF) << 8),
                SYS_KILL => kill(ContextId::from(b), c),
                SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
                SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
                SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
                SYS_IOPL => iopl(b, stack),
                SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
                SYS_GETEGID => getegid(),
                SYS_GETENS => getens(),
                SYS_GETEUID => geteuid(),
                SYS_GETGID => getgid(),
                SYS_GETNS => getns(),
                SYS_GETUID => getuid(),
                SYS_MKNS => mkns(validate_slice(b as *const [usize; 2], c)?),
                SYS_SETPGID => setpgid(ContextId::from(b), ContextId::from(c)),
                SYS_SETREUID => setreuid(b as u32, c as u32),
                SYS_SETRENS => setrens(SchemeNamespace::from(b), SchemeNamespace::from(c)),
                SYS_SETREGID => setregid(b as u32, c as u32),
                SYS_SIGACTION => sigaction(
                    b,
                    if c == 0 {
                        None
                    } else {
                        Some(validate_slice(c as *const SigAction, 1).map(|act| &act[0])?)
                    },
                    if d == 0 {
                        None
                    } else {
                        Some(validate_slice_mut(d as *mut SigAction, 1).map(|oldact| &mut oldact[0])?)
                    },
                    e
                ),
                SYS_SIGRETURN => sigreturn(),
                SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c),
                SYS_PHYSALLOC => physalloc(b),
                SYS_PHYSFREE => physfree(b, c),
                SYS_PHYSMAP => physmap(b, c, d),
                SYS_PHYSUNMAP => physunmap(b),
                SYS_VIRTTOPHYS => virttophys(b),
                _ => Err(Error::new(ENOSYS))
            }
        }
    }

    /*
    let debug = {
        let contexts = ::context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            if unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) } == "file:/bin/acid" {
                if (a == SYS_WRITE || a == SYS_FSYNC) && (b == 1 || b == 2) {
                    false
                } else {
                    true
                }
            } else {
                false
            }
        } else {
            false
        }
    };

    if debug {
        let contexts = ::context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
        }

        let _ = debug::print_call(a, b, c, d, e, f);
        println!("");
    }
    */

    let result = inner(a, b, c, d, e, f, bp, stack);

    /*
    if debug {
        let contexts = ::context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
        }

        let _ = debug::print_call(a, b, c, d, e, f);

        match result {
            Ok(ref ok) => {
                println!(" = Ok({} ({:#X}))", ok, ok);
            },
            Err(ref err) => {
                println!(" = Err({} ({:#X}))", err, err.errno);
            }
        }
    }
    */

    Error::mux(result)
}
<|endoftext|>


<commit_before>use std::collections::{BTreeMap, BinaryHeap};
use std::vec::Vec;

/// A limit specification.
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone)]
pub enum Capacity {
    Limit(usize),
    Infinite,
}

pub trait Agenda {
    type Item;

    fn enqueue(&mut self, Self::Item) -> Option<Self::Item>;
    fn dequeue(&mut self) -> Option<Self::Item>;
    fn peek_next(&self) -> Option<&Self::Item>;
    fn is_empty(&self) -> bool;
}

pub trait Weighted {
    type Weight;

    fn get_weight(&self) -> Self::Weight;
}

// #[derive(Debug, PartialEq, Eq)]
pub struct PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    data: BTreeMap<P, Vec<I>>, // The values should always be non-empty.
    capacity: Capacity,
    size: usize,
    last_key: Option<P>, // largest key w.r.t. Ord
                         // pub priority: Box<Fn(&I) -> P + 'a>,
}

impl<P, I> PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    pub fn size(&self) -> usize {
        self.size
    }

    pub fn capacity(&self) -> Capacity {
        self.capacity
    }

    pub fn is_at_capacity(&self) -> bool {
        Capacity::Limit(self.size) == self.capacity
    }
}

impl<I, P: Ord + Clone> Agenda for PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    type Item = I;

    fn enqueue(&mut self, item: I) -> Option<I> {
        let priority = item.get_weight();
        if Capacity::Limit(self.size) < self.capacity {
            self.enqueue_unchecked(priority, item);
            None
        } else if &priority <
                   self.last_key.as_ref().expect(
                "[ERROR] `last_key` should not be `None` when the queue is non-empty.",
            )
        {
            self.enqueue_unchecked(priority, item);
            self.drop_last()
        } else {
            Some(item)
        }
    }

    fn dequeue(&mut self) -> Option<I> {
        match match self.data.iter_mut().next() {
            Some((k, v)) => {
                let res = v.pop();
                if res.is_some() {
                    self.size -= 1;
                    if self.size == 0 {
                        self.last_key = None;
                    }
                }
                let key = if v.is_empty() { Some(k.clone()) } else { None };
                (key, res)
            }
            None => (None, None),
        } {
            (Some(k), res) => {
                self.data.remove(&k);
                res
            }
            (None, res) => res,
        }
    }

    fn peek_next(&self) -> Option<&I> {
        self.data.values().next().and_then(|v| v.last())
    }

    fn is_empty(&self) -> bool {
        self.size == 0
    }
}

impl<P: Ord, I> PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    pub fn new(capacity: Capacity) -> PriorityQueue<P, I> {
        assert!(capacity > Capacity::Limit(0));
        PriorityQueue {
            data: BTreeMap::new(),
            capacity,
            size: 0,
            last_key: None,
        }
    }
}

impl<P: Ord + Clone, I> PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    pub fn set_capacity(&mut self, capacity: usize) -> Vec<I> {
        self.capacity = Capacity::Limit(capacity);
        let mut res = Vec::new();
        while Capacity::Limit(self.size) > self.capacity {
            // TODO optimise to remove entire key-value-pairs at a time
            res.push(self.drop_last().expect(
                "[ERROR] `last_key` should not be `None` when the queue is non-empty.",
            ));
        }
        res.reverse();
        res
    }

    fn enqueue_unchecked(&mut self, priority: P, item: I) {
        self.data
            .entry(priority.clone())
            .or_insert_with(Vec::new)
            .push(item);
        self.last_key = match self.last_key {
            Some(ref lk) if priority < *lk => Some(lk.clone()),
            _ => Some(priority),
        };
        self.size += 1;
    }

    fn drop_last(&mut self) -> Option<I> {
        match self.last_key.clone() {
            Some(key) => {
                let mut vec = self.data.remove(&key).expect(
                    "[ERROR] `last_key` should only hold keys that occur in `data`.",
                );
                let item = vec.pop().expect(
                    "[ERROR] `data` should not contain empty `Vec`tors.",
                );

                if !vec.is_empty() {
                    self.data.insert(key.clone(), vec);
                } else {
                    self.last_key = self.data.keys().next_back().cloned();
                }
                self.size -= 1;

                Some(item)
            }
            None => None,
        }
    }
}

impl<I: Ord> Agenda for BinaryHeap<I> {
    type Item = I;

    fn enqueue(&mut self, item: Self::Item) -> Option<Self::Item> {
        self.push(item);
        None
    }

    fn dequeue(&mut self) -> Option<Self::Item> {
        self.pop()
    }

    fn peek_next(&self) -> Option<&Self::Item> {
        self.peek()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }
}

impl<I> Agenda for Vec<I> {
    type Item = I;

    fn enqueue(&mut self, item: Self::Item) -> Option<Self::Item> {
        self.push(item);
        None
    }

    fn dequeue(&mut self) -> Option<Self::Item> {
        self.pop()
    }

    fn peek_next(&self) -> Option<&Self::Item> {
        self.last()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }
}

#[test]
fn test_bounded_priority_queue() {
    #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
    struct Item(char);
    impl Weighted for Item {
        type Weight = char;
        fn get_weight(&self) -> char {
            match *self {
                Item(c) => c,
            }
        }
    }

    let mut q = PriorityQueue::new(Capacity::Limit(5));

    assert_eq!(q.size(), 0);
    assert!(q.is_empty());

    assert_eq!(q.enqueue(Item('i')), None);
    assert_eq!(q.peek_next(), Some(&Item('i')));
    assert_eq!(q.size(), 1);

    assert_eq!(q.enqueue(Item('h')), None);
    assert_eq!(q.peek_next(), Some(&Item('h')));
    assert_eq!(q.size(), 2);

    assert_eq!(q.enqueue(Item('g')), None);
    assert_eq!(q.peek_next(), Some(&Item('g')));
    assert_eq!(q.size(), 3);

    assert_eq!(q.enqueue(Item('a')), None);
    assert_eq!(q.peek_next(), Some(&Item('a')));
    assert_eq!(q.size(), 4);

    assert_eq!(q.enqueue(Item('f')), None);
    assert_eq!(q.peek_next(), Some(&Item('a')));

    assert_eq!(q.size(), 5);
    assert!(q.is_at_capacity());

    assert_eq!(q.enqueue(Item('e')), Some(Item('i')));

    assert_eq!(q.set_capacity(7), vec![]);

    assert_eq!(q.enqueue(Item('c')), None);
    assert_eq!(q.enqueue(Item('b')), None);

    assert_eq!(q.set_capacity(5), vec![(Item('g')), (Item('h'))]);

    assert_eq!(q.size(), 5);
    assert!(q.is_at_capacity());

    assert_eq!(q.dequeue(), Some(Item('a')));
    assert_eq!(q.dequeue(), Some(Item('b')));
    assert_eq!(q.dequeue(), Some(Item('c')));
    assert_eq!(q.dequeue(), Some(Item('e')));
    assert_eq!(q.dequeue(), Some(Item('f')));
    assert_eq!(q.dequeue(), None);
}
<commit_msg>src/util/agenda.rs: added VecDequeue<commit_after>use std::collections::{BTreeMap, BinaryHeap, VecDeque};
use std::vec::Vec;

/// A limit specification.
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone)]
pub enum Capacity {
    Limit(usize),
    Infinite,
}

pub trait Agenda {
    type Item;

    fn enqueue(&mut self, Self::Item) -> Option<Self::Item>;
    fn dequeue(&mut self) -> Option<Self::Item>;
    fn peek_next(&self) -> Option<&Self::Item>;
    fn is_empty(&self) -> bool;
}

pub trait Weighted {
    type Weight;

    fn get_weight(&self) -> Self::Weight;
}

// #[derive(Debug, PartialEq, Eq)]
pub struct PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    data: BTreeMap<P, Vec<I>>, // The values should always be non-empty.
    capacity: Capacity,
    size: usize,
    last_key: Option<P>, // largest key w.r.t. Ord
                         // pub priority: Box<Fn(&I) -> P + 'a>,
}

impl<P, I> PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    pub fn size(&self) -> usize {
        self.size
    }

    pub fn capacity(&self) -> Capacity {
        self.capacity
    }

    pub fn is_at_capacity(&self) -> bool {
        Capacity::Limit(self.size) == self.capacity
    }
}

impl<I, P: Ord + Clone> Agenda for PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    type Item = I;

    fn enqueue(&mut self, item: I) -> Option<I> {
        let priority = item.get_weight();
        if Capacity::Limit(self.size) < self.capacity {
            self.enqueue_unchecked(priority, item);
            None
        } else if &priority <
                   self.last_key.as_ref().expect(
                "[ERROR] `last_key` should not be `None` when the queue is non-empty.",
            )
        {
            self.enqueue_unchecked(priority, item);
            self.drop_last()
        } else {
            Some(item)
        }
    }

    fn dequeue(&mut self) -> Option<I> {
        match match self.data.iter_mut().next() {
            Some((k, v)) => {
                let res = v.pop();
                if res.is_some() {
                    self.size -= 1;
                    if self.size == 0 {
                        self.last_key = None;
                    }
                }
                let key = if v.is_empty() { Some(k.clone()) } else { None };
                (key, res)
            }
            None => (None, None),
        } {
            (Some(k), res) => {
                self.data.remove(&k);
                res
            }
            (None, res) => res,
        }
    }

    fn peek_next(&self) -> Option<&I> {
        self.data.values().next().and_then(|v| v.last())
    }

    fn is_empty(&self) -> bool {
        self.size == 0
    }
}

impl<P: Ord, I> PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    pub fn new(capacity: Capacity) -> PriorityQueue<P, I> {
        assert!(capacity > Capacity::Limit(0));
        PriorityQueue {
            data: BTreeMap::new(),
            capacity,
            size: 0,
            last_key: None,
        }
    }
}

impl<P: Ord + Clone, I> PriorityQueue<P, I>
where
    I: Weighted<Weight = P>,
{
    pub fn set_capacity(&mut self, capacity: usize) -> Vec<I> {
        self.capacity = Capacity::Limit(capacity);
        let mut res = Vec::new();
        while Capacity::Limit(self.size) > self.capacity {
            // TODO optimise to remove entire key-value-pairs at a time
            res.push(self.drop_last().expect(
                "[ERROR] `last_key` should not be `None` when the queue is non-empty.",
            ));
        }
        res.reverse();
        res
    }

    fn enqueue_unchecked(&mut self, priority: P, item: I) {
        self.data
            .entry(priority.clone())
            .or_insert_with(Vec::new)
            .push(item);
        self.last_key = match self.last_key {
            Some(ref lk) if priority < *lk => Some(lk.clone()),
            _ => Some(priority),
        };
        self.size += 1;
    }

    fn drop_last(&mut self) -> Option<I> {
        match self.last_key.clone() {
            Some(key) => {
                let mut vec = self.data.remove(&key).expect(
                    "[ERROR] `last_key` should only hold keys that occur in `data`.",
                );
                let item = vec.pop().expect(
                    "[ERROR] `data` should not contain empty `Vec`tors.",
                );

                if !vec.is_empty() {
                    self.data.insert(key.clone(), vec);
                } else {
                    self.last_key = self.data.keys().next_back().cloned();
                }
                self.size -= 1;

                Some(item)
            }
            None => None,
        }
    }
}

impl<I: Ord> Agenda for BinaryHeap<I> {
    type Item = I;

    fn enqueue(&mut self, item: Self::Item) -> Option<Self::Item> {
        self.push(item);
        None
    }

    fn dequeue(&mut self) -> Option<Self::Item> {
        self.pop()
    }

    fn peek_next(&self) -> Option<&Self::Item> {
        self.peek()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }
}

impl<I> Agenda for Vec<I> {
    type Item = I;

    fn enqueue(&mut self, item: Self::Item) -> Option<Self::Item> {
        self.push(item);
        None
    }

    fn dequeue(&mut self) -> Option<Self::Item> {
        self.pop()
    }

    fn peek_next(&self) -> Option<&Self::Item> {
        self.last()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }
}

impl<I> Agenda for VecDeque<I> {
    type Item = I;

    fn enqueue(&mut self, item: Self::Item) -> Option<Self::Item> {
        self.push_back(item);
        None
    }

    fn dequeue(&mut self) -> Option<Self::Item> {
        self.pop_front()
    }

    fn peek_next(&self) -> Option<&Self::Item> {
        self.front()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }
}

#[test]
fn test_bounded_priority_queue() {
    #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
    struct Item(char);
    impl Weighted for Item {
        type Weight = char;
        fn get_weight(&self) -> char {
            match *self {
                Item(c) => c,
            }
        }
    }

    let mut q = PriorityQueue::new(Capacity::Limit(5));

    assert_eq!(q.size(), 0);
    assert!(q.is_empty());

    assert_eq!(q.enqueue(Item('i')), None);
    assert_eq!(q.peek_next(), Some(&Item('i')));
    assert_eq!(q.size(), 1);

    assert_eq!(q.enqueue(Item('h')), None);
    assert_eq!(q.peek_next(), Some(&Item('h')));
    assert_eq!(q.size(), 2);

    assert_eq!(q.enqueue(Item('g')), None);
    assert_eq!(q.peek_next(), Some(&Item('g')));
    assert_eq!(q.size(), 3);

    assert_eq!(q.enqueue(Item('a')), None);
    assert_eq!(q.peek_next(), Some(&Item('a')));
    assert_eq!(q.size(), 4);

    assert_eq!(q.enqueue(Item('f')), None);
    assert_eq!(q.peek_next(), Some(&Item('a')));

    assert_eq!(q.size(), 5);
    assert!(q.is_at_capacity());

    assert_eq!(q.enqueue(Item('e')), Some(Item('i')));

    assert_eq!(q.set_capacity(7), vec![]);

    assert_eq!(q.enqueue(Item('c')), None);
    assert_eq!(q.enqueue(Item('b')), None);

    assert_eq!(q.set_capacity(5), vec![(Item('g')), (Item('h'))]);

    assert_eq!(q.size(), 5);
    assert!(q.is_at_capacity());

    assert_eq!(q.dequeue(), Some(Item('a')));
    assert_eq!(q.dequeue(), Some(Item('b')));
    assert_eq!(q.dequeue(), Some(Item('c')));
    assert_eq!(q.dequeue(), Some(Item('e')));
    assert_eq!(q.dequeue(), Some(Item('f')));
    assert_eq!(q.dequeue(), None);
}
<|endoftext|>


<commit_before>use super::gl;
use std::mem;
use std::raw;

pub trait VertexData: Copy {
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
pub enum DataType {
    BYTE = gl::BYTE as isize,
    UNSIGNED_BYTE = gl::UNSIGNED_BYTE as isize,
    SHORT = gl::SHORT as isize,
    UNSIGNED_SHORT = gl::UNSIGNED_SHORT as isize,
    FIXED = gl::FIXED as isize,
    FLOAT = gl::FLOAT as isize
}
pub use self::DataType::*;

pub trait VertexBytes {
    fn vertex_bytes(&self) -> &[u8];
}

impl<T> VertexBytes for T where T: VertexData {
    fn vertex_bytes(&self) -> &[u8] {
        unsafe {
            mem::transmute(raw::Slice::<Self> {
                data: self,
                len: mem::size_of::<Self>()
            })
        }
    }
}

#[macro_export]
macro_rules! vertex_data {
    ($(
        struct $name:ident {
            $($field_name:ident: $field_type:ty),*
        }
    )+) => {
        mod _glitter_vertex_data {
            $(
                #[allow(non_snake_case)]
                pub mod $name {
                    #[repr(C)]
                    #[derive(Debug, Clone, Copy)]
                    pub struct $name {
                        $($field_name: $field_type),*
                    }

                    impl $crate::VertexData for $name {

                    }
                }
            )+
        }

        $(
            #[allow(unused_imports)]
            use self::_glitter_vertex_data::$name::$name;
        )+
    }
}
<commit_msg>Add a `Binder` associated type for `VertexData`<commit_after>use super::gl;
use std::mem;
use std::raw;

pub trait VertexData: Copy {
    type Binder;
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
pub enum DataType {
    BYTE = gl::BYTE as isize,
    UNSIGNED_BYTE = gl::UNSIGNED_BYTE as isize,
    SHORT = gl::SHORT as isize,
    UNSIGNED_SHORT = gl::UNSIGNED_SHORT as isize,
    FIXED = gl::FIXED as isize,
    FLOAT = gl::FLOAT as isize
}
pub use self::DataType::*;

pub trait VertexBytes {
    fn vertex_bytes(&self) -> &[u8];
}

impl<T> VertexBytes for T where T: VertexData {
    fn vertex_bytes(&self) -> &[u8] {
        unsafe {
            mem::transmute(raw::Slice::<Self> {
                data: self,
                len: mem::size_of::<Self>()
            })
        }
    }
}

#[macro_export]
macro_rules! vertex_data {
    ($(
        struct $name:ident {
            $($field_name:ident: $field_type:ty),*
        }
    )+) => {
        mod _glitter_vertex_data {
            $(
                #[allow(non_snake_case)]
                pub mod $name {
                    #[repr(C)]
                    #[derive(Debug, Clone, Copy)]
                    pub struct $name {
                        $($field_name: $field_type),*
                    }

                    pub struct Binder;

                    impl $crate::VertexData for $name {
                        type Binder = Binder;
                    }
                }
            )+
        }

        $(
            #[allow(unused_imports)]
            use self::_glitter_vertex_data::$name::$name;
        )+
    }
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::io::BufReader;
use std::io::SeekFrom;
use std::fs::File;
use std::cmp::Ordering;
use std::mem;
use utils;
use errors::Word2VecError;

pub struct WordVector {
    vocabulary: Vec<(String, Vec<f32>)>,
    vector_size: usize,
    clusters: Option<Vec<String>>
}

impl WordVector{
	pub fn load_from_binary(file_name: &str) -> Result<WordVector, Word2VecError>
	{
		let file = try!(File::open(file_name));
		let mut reader = BufReader::new(file);
		let mut header = String::new();
		try!(reader.read_line(&mut header));
		let header_info = header.split_whitespace().filter_map(|x| x.parse::<usize>().ok()).take(2).collect::<Vec<usize>>();
		if header_info.len() != 2{
			return Err(Word2VecError::WrongHeader)
		}
		let vocabulary_size = header_info[0];
		let vector_size = header_info[1];
		let mut vocabulary: Vec<(String, Vec<f32>)> = Vec::with_capacity(vocabulary_size);
		for _ in 0..vocabulary_size{
			let mut word_bytes: Vec<u8> = Vec::new();
			try!(reader.read_until(b' ', &mut word_bytes));
			word_bytes.pop();
			let word = try!(String::from_utf8(word_bytes));
			let mut current_vector: Vec<f32> = Vec::with_capacity(vector_size);
			for _ in 0..vector_size{
				let mut buf: [u8; 4] = [0; 4];
				try!(reader.read(&mut buf));
				let vec = unsafe{ mem::transmute::<[u8; 4], f32>(buf) };
				current_vector.push(vec);
			}
			current_vector = utils::vector_norm(current_vector);
			vocabulary.push((word, current_vector));
			try!(reader.seek(SeekFrom::Current(1)));
		}
		Ok(WordVector{
			vocabulary: vocabulary,
			vector_size: vector_size,
			clusters: None
		})
	}

	fn get_index(&self, word: &str) -> Option<usize>
	{
		return self.vocabulary.iter().position(|x| x.0 == word);
	}

	pub fn get_vector(&self, word: &str) -> Option<&Vec<f32>>
	{
		let index = self.get_index(word);
		match index {
		    Some(val) => {
		    	return Some(&self.vocabulary[val].1)
		    },
		    None => None,
		}
	}

	pub fn cosine(&self, word: &str, n: usize) -> Option<Vec<(String, f32)>>
	{
		let word_vector = self.get_vector(word);
		match word_vector {
		    Some(val) => {
		        let mut metrics: Vec<(String, f32)> = Vec::with_capacity(self.vocabulary.len());
		        for word in self.vocabulary.iter(){
		    	    metrics.push((word.0.clone(), utils::dot_product(&word.1, val)));
		        }
		        metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
		        metrics.remove(0);
		        metrics.truncate(n);
		        return Some(metrics)
	        },
		    None => None,
		}
	}

	pub fn analogy(&self, pos: Vec<&str>, neg: Vec<&str>, n: usize) -> Option<Vec<(String, f32)>>
	{
		let mut vectors: Vec<Vec<f32>> = Vec::new();
		let mut exclude: Vec<String> = Vec::new();
		for word in pos.iter(){
			exclude.push(word.to_string());
			match self.get_vector(word){
				Some(val) => vectors.push(val.clone()),
				None => {}
			}
		}
		for word in neg.iter(){
			exclude.push(word.to_string());
			match self.get_vector(word) {
			    Some(val) => vectors.push(val.iter().map(|x| -x).collect::<Vec<f32>>()),
			    None => {},
			}
		}
		if exclude.is_empty(){
			return None
		}
		let mut mean: Vec<f32> = Vec::with_capacity(self.vector_size);
		for i in 0..self.vector_size{
			let mut new_vec = Vec::new();
			for vector in vectors.iter(){
				new_vec.push(vector[i]);
			}
			mean.push(utils::mean(new_vec));
		}
		let mut metrics: Vec<(String, f32)> = Vec::new();
		for word in self.vocabulary.iter(){
		    metrics.push((word.0.clone(), utils::dot_product(&word.1, &mean)));
		}
		metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
		metrics.retain(|x| exclude.contains(&x.0) == false);
		metrics.truncate(n);
		return Some(metrics)
	}

}<commit_msg>remove clusters from wordvectors model<commit_after>use std::io::prelude::*;
use std::io::BufReader;
use std::io::SeekFrom;
use std::fs::File;
use std::cmp::Ordering;
use std::mem;
use utils;
use errors::Word2VecError;

pub struct WordVector {
    vocabulary: Vec<(String, Vec<f32>)>,
    vector_size: usize
}

impl WordVector{
	pub fn load_from_binary(file_name: &str) -> Result<WordVector, Word2VecError>
	{
		let file = try!(File::open(file_name));
		let mut reader = BufReader::new(file);
		let mut header = String::new();
		try!(reader.read_line(&mut header));
		let header_info = header.split_whitespace().filter_map(|x| x.parse::<usize>().ok()).take(2).collect::<Vec<usize>>();
		if header_info.len() != 2{
			return Err(Word2VecError::WrongHeader)
		}
		let vocabulary_size = header_info[0];
		let vector_size = header_info[1];
		let mut vocabulary: Vec<(String, Vec<f32>)> = Vec::with_capacity(vocabulary_size);
		for _ in 0..vocabulary_size{
			let mut word_bytes: Vec<u8> = Vec::new();
			try!(reader.read_until(b' ', &mut word_bytes));
			word_bytes.pop();
			let word = try!(String::from_utf8(word_bytes));
			let mut current_vector: Vec<f32> = Vec::with_capacity(vector_size);
			for _ in 0..vector_size{
				let mut buf: [u8; 4] = [0; 4];
				try!(reader.read(&mut buf));
				let vec = unsafe{ mem::transmute::<[u8; 4], f32>(buf) };
				current_vector.push(vec);
			}
			current_vector = utils::vector_norm(current_vector);
			vocabulary.push((word, current_vector));
			try!(reader.seek(SeekFrom::Current(1)));
		}
		Ok(WordVector{
			vocabulary: vocabulary,
			vector_size: vector_size,
			clusters: None
		})
	}

	fn get_index(&self, word: &str) -> Option<usize>
	{
		return self.vocabulary.iter().position(|x| x.0 == word);
	}

	pub fn get_vector(&self, word: &str) -> Option<&Vec<f32>>
	{
		let index = self.get_index(word);
		match index {
		    Some(val) => {
		    	return Some(&self.vocabulary[val].1)
		    },
		    None => None,
		}
	}

	pub fn cosine(&self, word: &str, n: usize) -> Option<Vec<(String, f32)>>
	{
		let word_vector = self.get_vector(word);
		match word_vector {
		    Some(val) => {
		        let mut metrics: Vec<(String, f32)> = Vec::with_capacity(self.vocabulary.len());
		        for word in self.vocabulary.iter(){
		    	    metrics.push((word.0.clone(), utils::dot_product(&word.1, val)));
		        }
		        metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
		        metrics.remove(0);
		        metrics.truncate(n);
		        return Some(metrics)
	        },
		    None => None,
		}
	}

	pub fn analogy(&self, pos: Vec<&str>, neg: Vec<&str>, n: usize) -> Option<Vec<(String, f32)>>
	{
		let mut vectors: Vec<Vec<f32>> = Vec::new();
		let mut exclude: Vec<String> = Vec::new();
		for word in pos.iter(){
			exclude.push(word.to_string());
			match self.get_vector(word){
				Some(val) => vectors.push(val.clone()),
				None => {}
			}
		}
		for word in neg.iter(){
			exclude.push(word.to_string());
			match self.get_vector(word) {
			    Some(val) => vectors.push(val.iter().map(|x| -x).collect::<Vec<f32>>()),
			    None => {},
			}
		}
		if exclude.is_empty(){
			return None
		}
		let mut mean: Vec<f32> = Vec::with_capacity(self.vector_size);
		for i in 0..self.vector_size{
			let mut new_vec = Vec::new();
			for vector in vectors.iter(){
				new_vec.push(vector[i]);
			}
			mean.push(utils::mean(new_vec));
		}
		let mut metrics: Vec<(String, f32)> = Vec::new();
		for word in self.vocabulary.iter(){
		    metrics.push((word.0.clone(), utils::dot_product(&word.1, &mean)));
		}
		metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
		metrics.retain(|x| exclude.contains(&x.0) == false);
		metrics.truncate(n);
		return Some(metrics)
	}

}<|endoftext|>


<commit_before>extern crate rustc_serialize;
use rustc_serialize::json;

#[derive(RustcEncodable)]
pub struct Location {
    address: String,
    lat: f64,
    lon: f64,
}

#[derive(RustcEncodable)]
pub struct State {
    open: bool,
    message: String,
}

#[derive(RustcEncodable)]
pub struct Contact {
    irc: String,
    twitter: String,
    foursquare: String,
    email: String,
}

#[derive(RustcEncodable)]
pub struct SpaceFED {
    spacenet: bool,
    spacesaml: bool,
    spacephone: bool,
}

#[derive(RustcEncodable)]
pub struct Status {
    api: String,
    space: String,
    logo: String,
    url: String,
    location: Location,
    spacefed: SpaceFED,

    state: State,
    contact: Contact,
    issue_report_channels: [&'static str; 2],

    projects: [&'static str; 3],
}

fn main() {

    let status = Status {
        api: "0.13".to_string(),
        space: "coredump".to_string(),
        logo: "https://www.coredump.ch/logo.png".to_string(),
        url: "https://www.coredump.ch/".to_string(),
        location: Location {
            address: "Spinnereistrasse 2, 8640 Rapperswil, Switzerland".to_string(),
            lat: 47.22936,
            lon: 8.82949,
        },
        spacefed: SpaceFED {
            spacenet: false,
            spacesaml: false,
            spacephone: false,
        },
        state: State {
            open: false,
            message: "Open every Monday from 20:00".to_string(),
        },
        contact: Contact {
            irc: "irc://freenode.net/#coredump".to_string(),
            twitter: "@coredump_ch".to_string(),
            foursquare: "525c20e5498e875d8231b1e5".to_string(),
            email: "danilo@coredump.ch".to_string(),
        },
        issue_report_channels: ["email", "twitter"],
        projects: [
            "https://www.coredump.ch/projekte/",
            "https://discourse.coredump.ch/c/projects",
            "https://github.com/coredump-ch/"
        ]
    };
    let encoded = json::encode(&status).unwrap();
    println!("{}", encoded);
}
<commit_msg>Added Feeds<commit_after>extern crate rustc_serialize;
use rustc_serialize::json;

#[derive(RustcEncodable)]
pub struct Location {
    address: String,
    lat: f64,
    lon: f64,
}

#[derive(RustcEncodable)]
pub struct State {
    open: bool,
    message: String,
}

#[derive(RustcEncodable)]
pub struct Contact {
    irc: String,
    twitter: String,
    foursquare: String,
    email: String,
}

#[derive(RustcEncodable)]
pub struct SpaceFED {
    spacenet: bool,
    spacesaml: bool,
    spacephone: bool,
}

#[derive(RustcEncodable)]
pub struct Feed {
    _type: String,  // TODO: Convert this to "type" somehow
    url: String,
}

#[derive(RustcEncodable)]
pub struct Feeds {
    blog: Feed,
}

#[derive(RustcEncodable)]
pub struct Status {
    api: String,
    space: String,
    logo: String,
    url: String,
    location: Location,
    spacefed: SpaceFED,

    state: State,
    contact: Contact,
    issue_report_channels: [&'static str; 2],

    feeds: Feeds,
    projects: [&'static str; 3],
}

fn main() {

    let status = Status {
        api: "0.13".to_string(),
        space: "coredump".to_string(),
        logo: "https://www.coredump.ch/logo.png".to_string(),
        url: "https://www.coredump.ch/".to_string(),
        location: Location {
            address: "Spinnereistrasse 2, 8640 Rapperswil, Switzerland".to_string(),
            lat: 47.22936,
            lon: 8.82949,
        },
        spacefed: SpaceFED {
            spacenet: false,
            spacesaml: false,
            spacephone: false,
        },
        state: State {
            open: false,
            message: "Open every Monday from 20:00".to_string(),
        },
        contact: Contact {
            irc: "irc://freenode.net/#coredump".to_string(),
            twitter: "@coredump_ch".to_string(),
            foursquare: "525c20e5498e875d8231b1e5".to_string(),
            email: "danilo@coredump.ch".to_string(),
        },
        issue_report_channels: ["email", "twitter"],
        feeds: Feeds {
            blog: Feed {
                _type: "rss".to_string(),
                url: "https://www.coredump.ch/feed/".to_string(),
            },
        },
        projects: [
            "https://www.coredump.ch/projekte/",
            "https://discourse.coredump.ch/c/projects",
            "https://github.com/coredump-ch/"
        ]
    };
    let encoded = json::encode(&status).unwrap();
    println!("{}", encoded);
}
<|endoftext|>


<commit_before><commit_msg>subtitle_ocr: Clean up exports<commit_after><|endoftext|>


<commit_before>use piston_window;
use gfx_device_gl::{Resources, Output, CommandBuffer};
use gfx_graphics::GfxGraphics;
use piston_window::Transformed;

pub struct Object {
    x: f64,
    y: f64,
    sprite: Option<piston_window::Texture<Resources>>,
}

impl Object {
    pub fn new() -> Object {
        Object { x: 0., y: 0., sprite: None }
    }

    pub fn mov(&mut self, x: f64, y: f64) {
        self.x += x;
        self.y += y;
    }

    pub fn mov_to(&mut self, x: f64, y: f64) {
        self.x = x;
        self.y = y;
    }

    pub fn set_sprite(&mut self, sprite: Texture<Resources>) {
        self.sprite = Some(sprite);
    }

    pub fn render(&self, graphic: &mut GfxGraphics<Resources, CommandBuffer<Resources>, Output>, view: &piston_window::math::Matrix2d) {\
        match self.sprite {
            None => {
                let red = [1.0, 0.0, 0.0, 1.0];
                let square = piston_window::rectangle::square(0.0, 0.0, 100.0);
                piston_window::rectangle(red, square, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
            Some(ref sprite) => {
                piston_window::image(sprite, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
        }
    }
}
<commit_msg>Build fix<commit_after>use piston_window;
use gfx_device_gl::{Resources, Output, CommandBuffer};
use gfx_graphics::GfxGraphics;
use piston_window::Transformed;

pub struct Object {
    x: f64,
    y: f64,
    sprite: Option<piston_window::Texture<Resources>>,
}

impl Object {
    pub fn new() -> Object {
        Object { x: 0., y: 0., sprite: None }
    }

    pub fn mov(&mut self, x: f64, y: f64) {
        self.x += x;
        self.y += y;
    }

    pub fn mov_to(&mut self, x: f64, y: f64) {
        self.x = x;
        self.y = y;
    }

    pub fn set_sprite(&mut self, sprite: piston_window::Texture<Resources>) {
        self.sprite = Some(sprite);
    }

    pub fn render(&self, graphic: &mut GfxGraphics<Resources, CommandBuffer<Resources>, Output>, view: &piston_window::math::Matrix2d) {
        match self.sprite {
            None => {
                let red = [1.0, 0.0, 0.0, 1.0];
                let square = piston_window::rectangle::square(0.0, 0.0, 100.0);
                piston_window::rectangle(red, square, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
            Some(ref sprite) => {
                piston_window::image(sprite, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
        }
    }
}
<|endoftext|>


<commit_before>// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

pub enum E {
    A,
    B,
}

// CHECK-LABEL: @exhaustive_match
#[no_mangle]
pub fn exhaustive_match(e: E, unit: ()) {
// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
// CHECK-NEXT: ]
// CHECK: [[A]]:
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
// CHECK: [[B]]:
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
// CHECK: [[OTHERWISE]]:
// CHECK-NEXT: unreachable
    match e {
        E::A => unit,
        E::B => unit,
    }
}
<commit_msg>Fix codegen test<commit_after>// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

pub enum E {
    A,
    B,
}

// CHECK-LABEL: @exhaustive_match
#[no_mangle]
pub fn exhaustive_match(e: E, unit: ()) {
// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
// CHECK-NEXT: ]
// CHECK: [[OTHERWISE]]:
// CHECK-NEXT: unreachable
// CHECK: [[A]]:
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
// CHECK: [[B]]:
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
    match e {
        E::A => unit,
        E::B => unit,
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::cmp::Ordering;
use std::io;

pub type LenNum = u64;

#[derive(PartialEq, Debug, Clone, Copy)]
/// An enum representing the length of an ASN.1 element.
pub enum Len {
  /// A Definite length element.
  Def(u64),
  /// An Indefinite length element, not known before decoding.
  Indef,
}

impl From<Option<LenNum>> for Len {
  fn from(len: Option<LenNum>) -> Self {
    match len {
      None => Len::Indef,
      Some(l) => Len::Def(l),
    }
  }
}

impl From<Len> for Option<LenNum> {
  fn from(len: Len) -> Self {
    match len {
      Len::Def(l) => Some(l),
      Len::Indef => None,
    }
  }
}

impl PartialOrd<Len> for Len {
  fn partial_cmp(&self, other: &Len) -> Option<Ordering> {
    match (self, other) {
      (&Len::Def(ref l),
        &Len::Def(ref r)) => Some(l.cmp(r)),
      _ => None,
    }
  }
}

impl PartialEq<LenNum> for Len {
  fn eq(&self, other: &LenNum) -> bool {
    match *self {
      Len::Def(ref l) => l.eq(other),
      Len::Indef => false,
    }
  }
}

impl PartialOrd<LenNum> for Len {
  fn partial_cmp(&self, other: &LenNum) -> Option<Ordering> {
    match *self {
      Len::Def(ref l) => Some(l.cmp(other)),
      Len::Indef => None,
    }
  }
}

impl fmt::Display for Len {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match *self {
      Len::Def(ref l) => write!(f, "{}", l),
      Len::Indef => write!(f, "Indefinite Length"),
    }
  }
}

/// An ASN.1 tag number.
pub type TagNum = u64;

#[derive(PartialEq, Debug, Clone, Copy)]
/// An ASN.1 Class.
pub enum Class {
  /// Universal class.
  Universal,
  /// Application class.
  Application,
  /// Context-specific class.
  ContextSpecific,
  /// Private class.
  Private,
}

impl From<u8> for Class {
  fn from(class: u8) -> Self {
    match class {
      0 => Class::Universal,
      1 => Class::Application,
      2 => Class::ContextSpecific,
      3 => Class::Private,
      _ => unreachable!()
    }
  }
}

impl From<Class> for u8 {
  fn from(class: Class) -> Self {
    match class {
      Class::Universal => 0,
      Class::Application => 1,
      Class::ContextSpecific => 2,
      Class::Private => 3,
    }
  }
}

impl fmt::Display for Class {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}", match *self {
      Class::Universal => "Universal",
      Class::Application => "Application",
      Class::ContextSpecific => "Context-specific",
      Class::Private => "Private",
    })
  }
}

#[derive(Debug, Clone, Copy)]
/// A struct representing an ASN.1 element.
pub struct Tag {
  /// The class of the ASN.1 element.
  pub class: Class,
  /// The tag number of the ASN.1 element.
  pub tagnum: TagNum,
  /// The length of the ASN.1 element.
  pub len: Len,
  /// A flag indicating whether an element is constructed.
  pub constructed: bool,
}

impl Tag {
  /// Returns true when this is a structured type.
  pub fn is_structured(&self) -> bool {
    if self.class == Class::Universal {
      match self.tagnum {
        // SEQUENCE (OF)
        16 => true,
        // SET (OF)
        17 => true,
        _ => false,
      }
    } else {
      false
    }
  }

  /// Decode an ASN.1 tag from a stream.
  pub fn decode_tag<I: Iterator<Item=io::Result<u8>>>(bytes: &mut I) ->
    Result<Self, DecodeError> {
    // Decode tag byte, which includes class, constructed flag, and tag number.
    let tag_byte = try!(read_byte(bytes));
    let class_num = (tag_byte & 0xc0) >> 6;
    let constructed = tag_byte & 0x20 == 0x20;
    // If tag is 0x1F, use extended decode format.
    let tag = if (tag_byte & 0x1f) == 0x1f {
      let mut tag: TagNum = 0;
      loop {
        // Incrementatlly read bytes, adding base-128 to tag.
        let tag_more = try!(read_byte(bytes));
        tag = (tag << 7) + (tag_more & 0x7f) as TagNum;
        // Stop looping when 0x80 bit is set.
        if tag_more & 0x80 == 0x00 {
          break;
        }
      }
      tag
    // Otherwise it's just bits 5-1.
    } else {
      (tag_byte & 0x1f) as TagNum
    };

    // Decode len byte.
    let len_byte = try!(read_byte(bytes));
    let len = match len_byte {
      // When byte is 0x80, this is the start of indefinite length encoding.
      0x80 => Len::Indef,
      // If 0x80 is set, then other bits indicate the number of len bytes.
      l => if (l & 0x80) == 0x80 {
          let mut len: LenNum = 0;
          let byte_count = l & 0x7f;
          // Loop through number of len bytes.
          for _ in 0..byte_count {
            let len_more = try!(read_byte(bytes));
            // Add up each byte base-256.
            len = (len << 8) + len_more as TagNum;
          }
          Len::Def(len)
        // If 0x80 bit is not set, just decode the value.
        } else {
          Len::Def(l as LenNum)
        },
    };

    Ok(Tag {
      class: Class::from(class_num),
      tagnum: tag,
      len: len,
      constructed: constructed,
    })
  }

  /// Encode an ASN.1 stream from a tag.
  pub fn encode_tag<W: io::Write>(self, writer: &mut W) -> Result<LenNum, EncodeError> {
    let (class, tagnum, len, constructed) =
      (self.class, self.tagnum, self.len, self.constructed);

    // Create first tag_byte from class, constructed and tag number.
    let mut tag_byte = u8::from(class) << 6;
    if constructed {
      tag_byte += 0x20;
    }
    // If tag number is <31, add to single byte.
    if tagnum < 31 {
      tag_byte += tagnum as u8 & 0x1f;
      try!(write_byte(writer, tag_byte));
    // Otherwise build additional tag bytes.
    } else {
      tag_byte += 0x1f;
      try!(write_byte(writer, tag_byte));

    }

    Ok(bytes.count)
  }
}

type Type = String;

trait Data {
  fn get_asn1_type() -> Type;

  // /// Create ASN.1 data from this struct.
  // FIXME: Should this use &self?
  // fn into_asn1(&self) -> Result<Data, Error>;

  // /// Create this struct from ASN.1 data.
  // fn from_asn1(slice: Slice) -> Result<Self, Error>;
}

/// A macro to generate a generic Data trait implementation for a struct.
macro_rules! asn1_impl {
  ( $impl_type:ident, $asn1_type:expr,
    $( $name:ident, $rusttype:ident, $asn1type:expr ),*
  ) =>
(

impl Data for $impl_type {
  fn get_asn1_type() -> Type {
    $asn1_type
  }

  fn into_asn1(&self) -> Result<Data, Error> {
    Err(Error::EncodingError)
  }

  fn from_asn1(slice: Slice) -> Result<Self, Error> {
    Err(Error::Invalid)
  }
}

)
}

#[inline]
/// Read a byte from an iterator, and translate Eof into an UnexpectedEof error.
pub fn read_byte<I: Iterator<Item=io::Result<u8>>>(iter: &mut I) -> io::Result<u8> {
  match iter.next() {
    Some(res) => res,
    None => Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Got unexpected EOF while reading stream")),
  }
}

/// A reader to easily read a byte from a reader, while keeping a read count.
pub struct ByteReader<I: Iterator<Item=io::Result<u8>>> {
  reader: I,
  pub count: u64,
}

impl<I: Iterator<Item=io::Result<u8>>> ByteReader<I> {
  /// Create a new ByteReader from an Iterator.
  pub fn new(reader: I) -> ByteReader<I> {
    ByteReader {
      reader: reader,
      count: 0
    }
  }

  /// Read a byte, and translate Eof into an UnxpectedEof error.
  pub fn read(&mut self) -> io::Result<u8> {
    read_byte(self)
  }
}

impl<I: Iterator<Item=io::Result<u8>>> Iterator for ByteReader<I> {
  type Item = io::Result<u8>;

  fn next(&mut self) -> Option<Self::Item> {
    let val = self.reader.next();
    if val.is_some() {
      self.count += 1;
    }
    val
  }
}

impl<I: Iterator<Item=io::Result<u8>>> From<I> for ByteReader<I> {
  fn from(iter: I) -> Self {
    ByteReader::new(iter)
  }
}

#[inline]
/// Write a byte to a writer, and return an error when nothing was written.
pub fn write_byte<W: io::Write>(writer: &mut W, byte: u8) -> io::Result<()> {
  let buf = [byte];
  match try!(writer.write(&buf)) {
    0 => Err(io::Error::new(io::ErrorKind::Other, "Wrote zero bytes")),
    1 => {
      Ok(())
    },
    _ => Err(io::Error::new(io::ErrorKind::Other, "Wrote more than one byte")),
  }
}

/// A writer to easily write a byte to a writer, while keeping a write count.
struct ByteWriter<W: io::Write> {
  writer: W,
  pub count: u64,
}

impl<W: io::Write> ByteWriter<W> {
  pub fn new(writer: W) -> ByteWriter<W> {
    ByteWriter {
      writer: writer,
      count: 0
    }
  }

  /// Write a byte, failing if no data was written.
  pub fn write_byte(&mut self, byte: u8) -> io::Result<()> {
    write_byte(self, byte)
  }
}

impl<W: io::Write> io::Write for ByteWriter<W> {
  fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
    let res = self.writer.write(buf);
    if let Ok(c) = res {
      self.count += c as u64;
    }
    res
  }

  fn flush(&mut self) -> io::Result<()> {
    self.writer.flush()
  }
}

/// A list of errors that can occur decoding or encoding  data.
enum Error {
  /// Invalid  data.
  Invalid,
  /// An error occured while encoding  data.
  EncodingError,
  /// An invalid tag was decoded
  InvalidTag(Tag),
}

#[derive(Debug)]
/// Errors that can occur while decoding an ASN.1 element.
pub enum DecodeError {
  /// Generic IO Error.
  IO(io::Error),
  /// Child element(s) decoded to greater length than the parent's tag.
  GreaterLen,
  /// Primitive value encoded with an indefinite length.
  PrimIndef,
}

impl From<io::Error> for DecodeError {
  fn from(err: io::Error) -> Self {
    DecodeError::IO(err)
  }
}

#[derive(Debug)]
/// Errors that can occur while encoding an ASN.1 element.
pub enum EncodeError {
  /// Generic IO Error.
  IO(io::Error),
}

impl From<io::Error> for EncodeError {
  fn from(err: io::Error) -> Self {
    EncodeError::IO(err)
  }
}
<commit_msg>Add tests for decoding<commit_after>use std::fmt;
use std::cmp::Ordering;
use std::io;
use std::io::Read;

pub type LenNum = u64;

#[derive(PartialEq, Debug, Clone, Copy)]
/// An enum representing the length of an ASN.1 element.
pub enum Len {
  /// A Definite length element.
  Def(u64),
  /// An Indefinite length element, not known before decoding.
  Indef,
}

impl From<Option<LenNum>> for Len {
  fn from(len: Option<LenNum>) -> Self {
    match len {
      None => Len::Indef,
      Some(l) => Len::Def(l),
    }
  }
}

impl From<Len> for Option<LenNum> {
  fn from(len: Len) -> Self {
    match len {
      Len::Def(l) => Some(l),
      Len::Indef => None,
    }
  }
}

impl PartialOrd<Len> for Len {
  fn partial_cmp(&self, other: &Len) -> Option<Ordering> {
    match (self, other) {
      (&Len::Def(ref l),
        &Len::Def(ref r)) => Some(l.cmp(r)),
      _ => None,
    }
  }
}

impl PartialEq<LenNum> for Len {
  fn eq(&self, other: &LenNum) -> bool {
    match *self {
      Len::Def(ref l) => l.eq(other),
      Len::Indef => false,
    }
  }
}

impl PartialOrd<LenNum> for Len {
  fn partial_cmp(&self, other: &LenNum) -> Option<Ordering> {
    match *self {
      Len::Def(ref l) => Some(l.cmp(other)),
      Len::Indef => None,
    }
  }
}

impl fmt::Display for Len {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match *self {
      Len::Def(ref l) => write!(f, "{}", l),
      Len::Indef => write!(f, "Indefinite Length"),
    }
  }
}

/// An ASN.1 tag number.
pub type TagNum = u64;

#[derive(PartialEq, Debug, Clone, Copy)]
/// An ASN.1 Class.
pub enum Class {
  /// Universal class.
  Universal,
  /// Application class.
  Application,
  /// Context-specific class.
  ContextSpecific,
  /// Private class.
  Private,
}

impl From<u8> for Class {
  fn from(class: u8) -> Self {
    match class {
      0 => Class::Universal,
      1 => Class::Application,
      2 => Class::ContextSpecific,
      3 => Class::Private,
      _ => unreachable!()
    }
  }
}

impl From<Class> for u8 {
  fn from(class: Class) -> Self {
    match class {
      Class::Universal => 0,
      Class::Application => 1,
      Class::ContextSpecific => 2,
      Class::Private => 3,
    }
  }
}

impl fmt::Display for Class {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}", match *self {
      Class::Universal => "Universal",
      Class::Application => "Application",
      Class::ContextSpecific => "Context-specific",
      Class::Private => "Private",
    })
  }
}

#[derive(PartialEq, Debug, Clone, Copy)]
/// A struct representing an ASN.1 element.
pub struct Tag {
  /// The class of the ASN.1 element.
  pub class: Class,
  /// The tag number of the ASN.1 element.
  pub tagnum: TagNum,
  /// The length of the ASN.1 element.
  pub len: Len,
  /// A flag indicating whether an element is constructed.
  pub constructed: bool,
}

impl Tag {
  /// Returns true when this is a structured type.
  pub fn is_structured(&self) -> bool {
    if self.class == Class::Universal {
      match self.tagnum {
        // SEQUENCE (OF)
        16 => true,
        // SET (OF)
        17 => true,
        _ => false,
      }
    } else {
      false
    }
  }

  /// Decode an ASN.1 tag from a stream.
  pub fn decode_tag<I: Iterator<Item=io::Result<u8>>>(bytes: &mut I) ->
    Result<Self, DecodeError> {
    // Decode tag byte, which includes class, constructed flag, and tag number.
    let tag_byte = try!(read_byte(bytes));
    let class_num = (tag_byte & 0xc0) >> 6;
    let constructed = tag_byte & 0x20 == 0x20;
    // If tag is 0x1F, use extended decode format.
    let tag = if (tag_byte & 0x1f) == 0x1f {
      let mut tag: TagNum = 0;
      loop {
        // Incrementatlly read bytes, adding base-128 to tag.
        let tag_more = try!(read_byte(bytes));
        tag = (tag << 7) + (tag_more & 0x7f) as TagNum;
        // Stop looping when 0x80 bit is set.
        if tag_more & 0x80 == 0x00 {
          break;
        }
      }
      tag
    // Otherwise it's just bits 5-1.
    } else {
      (tag_byte & 0x1f) as TagNum
    };

    // Decode len byte.
    let len_byte = try!(read_byte(bytes));
    let len = match len_byte {
      // When byte is 0x80, this is the start of indefinite length encoding.
      0x80 => Len::Indef,
      // If 0x80 is set, then other bits indicate the number of len bytes.
      l => if (l & 0x80) == 0x80 {
          let mut len: LenNum = 0;
          let byte_count = l & 0x7f;
          // Loop through number of len bytes.
          for _ in 0..byte_count {
            let len_more = try!(read_byte(bytes));
            // Add up each byte base-256.
            len = (len << 8) + len_more as TagNum;
          }
          Len::Def(len)
        // If 0x80 bit is not set, just decode the value.
        } else {
          Len::Def(l as LenNum)
        },
    };

    Ok(Tag {
      class: Class::from(class_num),
      tagnum: tag,
      len: len,
      constructed: constructed,
    })
  }

  /// Encode an ASN.1 stream from a tag.
  pub fn encode_tag<W: io::Write>(self, writer: &mut W) -> Result<(), EncodeError> {
    let (class, tagnum, len, constructed) =
      (self.class, self.tagnum, self.len, self.constructed);

    // Create first tag_byte from class, constructed and tag number.
    let mut tag_byte = u8::from(class) << 6;
    if constructed {
      tag_byte += 0x20;
    }
    // If tag number is <31, add to single byte.
    if tagnum < 31 {
      tag_byte += tagnum as u8 & 0x1f;
      try!(write_byte(writer, tag_byte));
    // Otherwise build additional tag bytes.
    } else {
      if tagnum & 0x8000000000000000 == 0 {
        panic!("Bit 63 set on asn1 tag. Not handling, since this is \
                impractically huge, and it messes up my nice little algorithm.");
      }
      let mut started = false;
      // Take 7 bit slices eg. 62-55, ..., 6-0.
      // The first non-zero slice marks the start of the int.
      for offset in (0..9).rev() {
        // Get 7 bit slice.
        let mut tag_part: u8 = (tagnum >> (offset * 7)) as u8 & 0x7f;

        if !started {
          if tag_part == 0 {
            continue;
          // TODO: Does tagnum have sign issues like length?
          // Emit an initial zero byte if slice starts with a 1 bit.
          } else if tag_part & 0x40 != 0 {
            try!(write_byte(writer, 0));
          }
          // For all slices except the last, set 7th bit.
          if offset != 0 {
            tag_part |= 0x80;
          }

          try!(write_byte(writer, tag_part));
        }
        // Skip if its zero and we haven't started.
        if tag_part == 0 && !started {
          started = false;
          continue;
        }
      }
    }

    match len {
      Len::Indef => try!(write_byte(writer, 0x80)),
      Len::Def(len_num) => {
        if len_num < 128 {
          try!(write_byte(writer, len_num as u8));
        } else {
        }
      },
    }

    Ok(())
  }
}

type Type = String;

trait Data {
  fn get_asn1_type() -> Type;

  // /// Create ASN.1 data from this struct.
  // FIXME: Should this use &self?
  // fn into_asn1(&self) -> Result<Data, Error>;

  // /// Create this struct from ASN.1 data.
  // fn from_asn1(slice: Slice) -> Result<Self, Error>;
}

/// A macro to generate a generic Data trait implementation for a struct.
macro_rules! asn1_impl {
  ( $impl_type:ident, $asn1_type:expr,
    $( $name:ident, $rusttype:ident, $asn1type:expr ),*
  ) =>
(

impl Data for $impl_type {
  fn get_asn1_type() -> Type {
    $asn1_type
  }

  fn into_asn1(&self) -> Result<Data, Error> {
    Err(Error::EncodingError)
  }

  fn from_asn1(slice: Slice) -> Result<Self, Error> {
    Err(Error::Invalid)
  }
}

)
}

#[inline]
/// Read a byte from an iterator, and translate Eof into an UnexpectedEof error.
pub fn read_byte<I: Iterator<Item=io::Result<u8>>>(iter: &mut I) -> io::Result<u8> {
  match iter.next() {
    Some(res) => res,
    None => Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Got unexpected EOF while reading stream")),
  }
}

/// A reader to easily read a byte from a reader, while keeping a read count.
pub struct ByteReader<I: Iterator<Item=io::Result<u8>>> {
  reader: I,
  pub count: u64,
}

impl<I: Iterator<Item=io::Result<u8>>> ByteReader<I> {
  /// Create a new ByteReader from an Iterator.
  pub fn new(reader: I) -> ByteReader<I> {
    ByteReader {
      reader: reader,
      count: 0
    }
  }

  /// Read a byte, and translate Eof into an UnxpectedEof error.
  pub fn read(&mut self) -> io::Result<u8> {
    read_byte(self)
  }
}

impl<I: Iterator<Item=io::Result<u8>>> Iterator for ByteReader<I> {
  type Item = io::Result<u8>;

  fn next(&mut self) -> Option<Self::Item> {
    let val = self.reader.next();
    if val.is_some() {
      self.count += 1;
    }
    val
  }
}

impl<I: Iterator<Item=io::Result<u8>>> From<I> for ByteReader<I> {
  fn from(iter: I) -> Self {
    ByteReader::new(iter)
  }
}

#[inline]
/// Write a byte to a writer, and return an error when nothing was written.
pub fn write_byte<W: io::Write>(writer: &mut W, byte: u8) -> io::Result<()> {
  let buf = [byte];
  match try!(writer.write(&buf)) {
    0 => Err(io::Error::new(io::ErrorKind::Other, "Wrote zero bytes")),
    1 => {
      Ok(())
    },
    _ => Err(io::Error::new(io::ErrorKind::Other, "Wrote more than one byte")),
  }
}

/// A writer to easily write a byte to a writer, while keeping a write count.
struct ByteWriter<W: io::Write> {
  writer: W,
  pub count: u64,
}

impl<W: io::Write> ByteWriter<W> {
  pub fn new(writer: W) -> ByteWriter<W> {
    ByteWriter {
      writer: writer,
      count: 0
    }
  }

  /// Write a byte, failing if no data was written.
  pub fn write_byte(&mut self, byte: u8) -> io::Result<()> {
    write_byte(self, byte)
  }
}

impl<W: io::Write> io::Write for ByteWriter<W> {
  fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
    let res = self.writer.write(buf);
    if let Ok(c) = res {
      self.count += c as u64;
    }
    res
  }

  fn flush(&mut self) -> io::Result<()> {
    self.writer.flush()
  }
}

/// A list of errors that can occur decoding or encoding  data.
enum Error {
  /// Invalid x data.
  Invalid,
  /// An error occured while encoding  data.
  EncodingError,
  /// An invalid tag was decoded
  InvalidTag(Tag),
}

#[derive(Debug)]
/// Errors that can occur while decoding an ASN.1 element.
pub enum DecodeError {
  /// Generic IO Error.
  IO(io::Error),
  /// Child element(s) decoded to greater length than the parent's tag.
  GreaterLen,
  /// Primitive value encoded with an indefinite length.
  PrimIndef,
}

impl From<io::Error> for DecodeError {
  fn from(err: io::Error) -> Self {
    DecodeError::IO(err)
  }
}

#[derive(Debug)]
/// Errors that can occur while encoding an ASN.1 element.
pub enum EncodeError {
  /// Generic IO Error.
  IO(io::Error),
}

impl From<io::Error> for EncodeError {
  fn from(err: io::Error) -> Self {
    EncodeError::IO(err)
  }
}

#[test]
fn decode_tag_simple() {
  assert_eq!(
    Tag::decode_tag(
      (b"\x02\x00" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 0u8.into(),
      tagnum: 2u8.into(),
      len: Some(0u64).into(),
      constructed: false,
    }
  );
}

#[test]
fn decode_high_tag_class() {
  assert_eq!(
    Tag::decode_tag(
      (b"\x5f\x01\x10" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 1u8.into(),
      tagnum: 1u8.into(),
      len: Some(16u64).into(),
      constructed: false,
    }
  );

  // Test low-tag format matches high-tag format.
  assert_eq!(
    Tag::decode_tag(
      (b"\x5f\x01\x10" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 1u8.into(),
      tagnum: 1u8.into(),
      len: Some(16u64).into(),
      constructed: false,
    }
  );
}

#[test]
fn decode_tag_constructed() {
  assert_eq!(
    Tag::decode_tag(
      (b"\x30\x12" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 0u8.into(),
      tagnum: 16u8.into(),
      len: Some(18u64).into(),
      constructed: true,
    }
  );
}

#[test]
fn decode_tag_indefinite() {
  assert_eq!(
    Tag::decode_tag(
      (b"\x30\x80" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 0u8.into(),
      tagnum: 16u8.into(),
      len: None.into(),
      constructed: true,
    }
  );
}

#[test]
fn decode_tag_long_len() {
  assert_eq!(
    Tag::decode_tag(
      (b"\x30\x81\x11" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 0u8.into(),
      tagnum: 16u8.into(),
      len: Some(17u64).into(),
      constructed: true,
    }
  );

  // Test that short-format matches long-format.
  assert_eq!(
    Tag::decode_tag(
      (b"\x30\x11" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 0u8.into(),
      tagnum: 16u8.into(),
      len: Some(17u64).into(),
      constructed: true,
    }
  );
}

#[test]
fn decode_tag_ridiculous() {
  assert_eq!(
    Tag::decode_tag(
      (b"\x7f\x81\x80\x01\x85\x80\x00\x00\x00\x01" as &[u8]).bytes().by_ref()
    ).unwrap(),
    Tag {
      class: 1u8.into(),
      tagnum: 16u8.into(),
      len: Some(17u64).into(),
      constructed: true,
    }
  );
}
<|endoftext|>