<commit_before>extern crate regex;

mod matching;
mod support;
mod tokens;
mod lexer;
mod files;
mod symbol_table;
mod plp;
mod compiler;

use std::vec::Vec;
use tokens::*;
use symbol_table::symbol_table::*;
use lexer::*;
use support::*;
use compiler::*;

fn main()
{
    let source_file = "sampleData/BasicArithmatic.java";
    let lex_output_file = "sampleData/output/stable/BasicArithmatic.java.lexed";
    let preprocessed_output_file = "sampleData/output/stable/BasicArithmatic.java.preprocessed";

    let mut tokens: Vec<Token> = lex_file(source_file);

    println!("\n\nFound Tokens:");
    tokens.print_to(lex_output_file, true);

    remove_meta(&mut tokens);
    println!("\n\nPerged Tokens:");
    tokens.print_to(preprocessed_output_file, true);

    let mut symbols_table: SymbolTable = SymbolTable::new();
    let class_structure = parse_class(&tokens, 1, &mut symbols_table);

    if tokens[0].value != "class"
    {
        panic!("Unexpected token: {}: {}", tokens[0].value, tokens[0].name);
    }

    let (last_index, asm_string) = compile_class(&tokens, 1);
}

fn parse_class(tokens: &Vec<Token>, start_index: usize, symbols_table: &mut SymbolTable) -> ClassStructure
{
    let mut class_structure: ClassStructure = ClassStructure::new();

    println!("\n<------------ Parse Class --------------->");
    let mut min_value = 0;
    let mut skip_amount = 0;

    for (index, token) in tokens.iter().enumerate()
    {
        if min_value != 0
        {
            min_value -= 1;
            continue;
        }
        //Static Variable/Method/Class
        if token.name == "mod.access"
        {
            skip_amount = 3;
            if tokens[index + skip_amount].name.starts_with("operator")
            {
                //TODO account for final
                println!("------Incoming Static Variable Decl!");

                let low = index + 1;
                let high = find_next(tokens, low, ";").unwrap() + 1;

                class_structure.static_variables.push(MemberBlock (low, high, tokens[index + 2].value.clone()));

                min_value =  low;
                min_value -= index;
            }
            else if tokens[index + skip_amount].name == "identifier"
            {
                //TODO account for final
                println!("------Incoming Static Variable Decl!");

                let low = index + 2;
                let high = find_next(tokens, low, ";").unwrap() + 1;
                class_structure.static_variables.push(MemberBlock (low, high, tokens[index + 3].value.clone()));

                min_value =  low;
                min_value -= index;
            }
            else if tokens[index + 1].name.starts_with("construct")
            {
                if tokens[index + skip_amount].name.starts_with("control")
                {
                    //TODO account for final
                    println!("------Incoming Static Class Decl!");
                    let starting_point = find_next(tokens, index, "{").unwrap() + 1;
                    min_value = identify_body_bounds(tokens, starting_point, ("{", "}")).unwrap() + 1;
                    class_structure.static_classes.push(MemberBlock (starting_point - 1, min_value, tokens[index + 2].value.clone()));
                    min_value -= index + 1;
                }
                else
                {
                    panic!("Unsupported or Unexpected token: {} + {}.", tokens[index + skip_amount].value, tokens[index + skip_amount].name);
                }
            }
            else if tokens[index + skip_amount].name.starts_with("control")
            {
                //TODO account for final
                println!("------Incoming Static Method Decl!");
                let starting_point = find_next(tokens, index, "{").unwrap() + 1;
                min_value = identify_body_bounds(tokens, starting_point, ("{", "}")).unwrap() + 1;
                class_structure.static_methods.push(MemberBlock (starting_point - 1, min_value, tokens[index + 2].value.clone()));
                min_value -=  index + 1;
            }
            else
            {
                panic!("Unsupported or Unexpected token: {}: {}.", tokens[index + skip_amount].value, tokens[index + skip_amount].name);
            }

        }
        //Non-Static Variable/Method/Class
        else if token.name.starts_with("construct")
        {
            skip_amount = 2;
            if tokens[index + skip_amount].name.starts_with("control")
            {
                //TODO account for final
                println!("------Incoming Non-Static Class Decl!");
                let index_after_brace = index + skip_amount + 1;
                min_value = identify_body_bounds(tokens, index_after_brace, ("{", "}")).unwrap() + 1;
                class_structure.non_static_classes.push(MemberBlock (index_after_brace - 1, min_value, tokens[index + 1].value.clone()));
                //TODO parse_class(tokens, index, symbols_table);
                min_value = 0;
            }
            else
            {
                panic!("Unsupported or Unexpected token: {} + {}.", tokens[index + skip_amount].value, tokens[index + skip_amount].name);
            }
        }
        //Non-Static Variable/Method/Class
        else if token.name == "type"
        {
            skip_amount = 2;

            if tokens[index + skip_amount].name.starts_with("control")
            {
                //TODO account for final
                println!("------Incoming Non-Static Method Decl!");
                let starting_point = find_next(tokens, index, "{").unwrap() + 1;
                min_value = identify_body_bounds(tokens, starting_point, ("{", "}")).unwrap() + 1;
                class_structure.non_static_methods.push(MemberBlock (starting_point - 1, min_value, tokens[index + 1].value.clone()));
                min_value -= index + 1;
                //check for control
            }
            else if tokens[index + skip_amount].name.starts_with("operator")
            {
                //TODO account for final
                println!("------Incoming Non-Static Variable Decl!");
                min_value =  find_next(tokens, index, ";").unwrap() + 1;
                class_structure.non_static_variables.push(MemberBlock (index, min_value, tokens[index + 1].value.clone()));
                min_value -= index + 1;
            }
        }
        println!("\tIndex: {} | Token -> {} : {}", index, token.value, token.name );
        //deal with parameters
    }
    println!("\n<---------------- Static Variables --------------->");
    for member_block in class_structure.static_variables.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Static Classes ----------------->");
    for member_block in class_structure.static_classes.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Static Methods ----------------->");
    for member_block in class_structure.static_methods.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Non-Static Variables --------------->");
    for member_block in class_structure.non_static_variables.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Non-Static Classes ----------------->");
    for member_block in class_structure.non_static_classes.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Non-Static Methods ----------------->");
    for member_block in class_structure.non_static_methods.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }
    println!("\n");

    class_structure
}

/// Removes all meta tokens from the give Vector
/// Meta tokens include:
/// * comments
/// * imports
/// * permission modifiers (public, private, protected)
///
/// Note that in future versions, imports will not be removed.
fn remove_meta(tokens: &mut Vec<Token>)
{
    // Indecies of tokens vector to be removed
    let mut invalid_indecies: Vec<usize> = Vec::new();

    let mut min_index: usize = 0;
    for (index, token) in tokens.iter().enumerate()
    {
        // Allow forward skipping (by setting min_index)
        if index < min_index
        {
            invalid_indecies.push(index);
        }
        // Remove imports
        else if token.name == "special.import"
        {
            invalid_indecies.push(index);
            min_index = index + 2; // skip the next token (semi-colon)
        }
        // Remove comments
        else if token.name.starts_with("comment")
        {
            invalid_indecies.push(index);
        }
        // Remove all permission modifiers (public, private, protected)
        else if token.name == "mod.permission"
        {
            invalid_indecies.push(index);
        }
    }

    // count := how many indecies have already been removed
    // index := the index in the original tokens vector that should be removed
    for (count, index) in invalid_indecies.iter().enumerate()
    {
        // "index" refers to the index before any others were removed. Therefore, it must be offset by the number of removed tokens
        tokens.remove(index - count);
    }
}
<commit_msg>Validate tokens during purge<commit_after>extern crate regex;

mod matching;
mod support;
mod tokens;
mod lexer;
mod files;
mod symbol_table;
mod plp;
mod compiler;

use std::vec::Vec;
use tokens::*;
use symbol_table::symbol_table::*;
use lexer::*;
use support::*;
use compiler::*;

fn main()
{
    let source_file = "sampleData/BasicArithmatic.java";
    let lex_output_file = "sampleData/output/stable/BasicArithmatic.java.lexed";
    let preprocessed_output_file = "sampleData/output/stable/BasicArithmatic.java.preprocessed";

    let mut tokens: Vec<Token> = lex_file(source_file);

    println!("\n\nFound Tokens:");
    tokens.print_to(lex_output_file, true);

    remove_meta(&mut tokens);
    println!("\n\nPerged Tokens:");
    tokens.print_to(preprocessed_output_file, true);

    let mut symbols_table: SymbolTable = SymbolTable::new();
    let class_structure = parse_class(&tokens, 1, &mut symbols_table);

    if tokens[0].value != "class"
    {
        panic!("Unexpected token: {}: {}", tokens[0].value, tokens[0].name);
    }

    // let (last_index, asm_string) = compile_class(&tokens, 1);
}

fn parse_class(tokens: &Vec<Token>, start_index: usize, symbols_table: &mut SymbolTable) -> ClassStructure
{
    let mut class_structure: ClassStructure = ClassStructure::new();

    println!("\n<------------ Parse Class --------------->");
    let mut min_value = 0;
    let mut skip_amount = 0;

    for (index, token) in tokens.iter().enumerate()
    {
        if min_value != 0
        {
            min_value -= 1;
            continue;
        }
        //Static Variable/Method/Class
        if token.name == "mod.access"
        {
            skip_amount = 3;
            if tokens[index + skip_amount].name.starts_with("operator")
            {
                //TODO account for final
                println!("------Incoming Static Variable Decl!");

                let low = index + 1;
                let high = find_next(tokens, low, ";").unwrap() + 1;

                class_structure.static_variables.push(MemberBlock (low, high, tokens[index + 2].value.clone()));

                min_value =  low;
                min_value -= index;
            }
            else if tokens[index + skip_amount].name == "identifier"
            {
                //TODO account for final
                println!("------Incoming Static Variable Decl!");

                let low = index + 2;
                let high = find_next(tokens, low, ";").unwrap() + 1;
                class_structure.static_variables.push(MemberBlock (low, high, tokens[index + 3].value.clone()));

                min_value =  low;
                min_value -= index;
            }
            else if tokens[index + 1].name.starts_with("construct")
            {
                if tokens[index + skip_amount].name.starts_with("control")
                {
                    //TODO account for final
                    println!("------Incoming Static Class Decl!");
                    let starting_point = find_next(tokens, index, "{").unwrap() + 1;
                    min_value = identify_body_bounds(tokens, starting_point, ("{", "}")).unwrap() + 1;
                    class_structure.static_classes.push(MemberBlock (starting_point - 1, min_value, tokens[index + 2].value.clone()));
                    min_value -= index + 1;
                }
                else
                {
                    panic!("Unsupported or Unexpected token: {} + {}.", tokens[index + skip_amount].value, tokens[index + skip_amount].name);
                }
            }
            else if tokens[index + skip_amount].name.starts_with("control")
            {
                //TODO account for final
                println!("------Incoming Static Method Decl!");
                let starting_point = find_next(tokens, index, "{").unwrap() + 1;
                min_value = identify_body_bounds(tokens, starting_point, ("{", "}")).unwrap() + 1;
                class_structure.static_methods.push(MemberBlock (starting_point - 1, min_value, tokens[index + 2].value.clone()));
                min_value -=  index + 1;
            }
            else
            {
                panic!("Unsupported or Unexpected token: {}: {}.", tokens[index + skip_amount].value, tokens[index + skip_amount].name);
            }

        }
        //Non-Static Variable/Method/Class
        else if token.name.starts_with("construct")
        {
            skip_amount = 2;
            if tokens[index + skip_amount].name.starts_with("control")
            {
                //TODO account for final
                println!("------Incoming Non-Static Class Decl!");
                let index_after_brace = index + skip_amount + 1;
                min_value = identify_body_bounds(tokens, index_after_brace, ("{", "}")).unwrap() + 1;
                class_structure.non_static_classes.push(MemberBlock (index_after_brace - 1, min_value, tokens[index + 1].value.clone()));
                //TODO parse_class(tokens, index, symbols_table);
                min_value = 0;
            }
            else
            {
                panic!("Unsupported or Unexpected token: {} + {}.", tokens[index + skip_amount].value, tokens[index + skip_amount].name);
            }
        }
        //Non-Static Variable/Method/Class
        else if token.name == "type"
        {
            skip_amount = 2;

            if tokens[index + skip_amount].name.starts_with("control")
            {
                //TODO account for final
                println!("------Incoming Non-Static Method Decl!");
                let starting_point = find_next(tokens, index, "{").unwrap() + 1;
                min_value = identify_body_bounds(tokens, starting_point, ("{", "}")).unwrap() + 1;
                class_structure.non_static_methods.push(MemberBlock (starting_point - 1, min_value, tokens[index + 1].value.clone()));
                min_value -= index + 1;
                //check for control
            }
            else if tokens[index + skip_amount].name.starts_with("operator")
            {
                //TODO account for final
                println!("------Incoming Non-Static Variable Decl!");
                min_value =  find_next(tokens, index, ";").unwrap() + 1;
                class_structure.non_static_variables.push(MemberBlock (index, min_value, tokens[index + 1].value.clone()));
                min_value -= index + 1;
            }
        }
        println!("\tIndex: {} | Token -> {} : {}", index, token.value, token.name );
        //deal with parameters
    }
    println!("\n<---------------- Static Variables --------------->");
    for member_block in class_structure.static_variables.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Static Classes ----------------->");
    for member_block in class_structure.static_classes.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Static Methods ----------------->");
    for member_block in class_structure.static_methods.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Non-Static Variables --------------->");
    for member_block in class_structure.non_static_variables.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Non-Static Classes ----------------->");
    for member_block in class_structure.non_static_classes.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }

    println!("\n<---------------- Non-Static Methods ----------------->");
    for member_block in class_structure.non_static_methods.iter()
    {
        println!("Start/End {}/{}: {}", member_block.0, member_block.1, member_block.2);
    }
    println!("\n");

    class_structure
}

/// Removes all meta tokens from the give Vector
/// Meta tokens include:
/// * comments
/// * imports
/// * permission modifiers (public, private, protected)
///
/// Note that in future versions, imports will not be removed.
fn remove_meta(tokens: &mut Vec<Token>)
{
    // Indecies of tokens vector to be removed
    let mut invalid_indecies: Vec<usize> = Vec::new();

    let invalid_types = get_invalid_token_types();
    let invalid_values = get_invalid_token_values();

    for (index, token) in tokens.iter().enumerate()
    {
        // Panic on invalid tokens
        if invalid_types.contains(&token.name) || invalid_values.contains(&&*token.value)
        {
            panic!("Unsupported token: {}: {}", token.value, token.name);
        }
        // Remove imports
        else if token.name == "special.import"
        {
            // invalidate import
            invalid_indecies.push(index);
            // invalidate the semi-colon after the semi-colon
            invalid_indecies.push(index + 1);
        }
        // Remove comments
        else if token.name.starts_with("comment")
        {
            invalid_indecies.push(index);
        }
        // Remove all permission modifiers (public, private, protected)
        else if token.name == "mod.permission"
        {
            invalid_indecies.push(index);
        }
    }

    // count := how many indecies have already been removed
    // index := the index in the original tokens vector that should be removed
    for (count, index) in invalid_indecies.iter().enumerate()
    {
        // "index" refers to the index before any others were removed. Therefore, it must be offset by the number of removed tokens
        tokens.remove(index - count);
    }
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![crate_name = "bitcoin-secp256k1-rs"]
#![comment = "Bindings and wrapper functions for bitcoin secp256k1 library."]
#![feature(phase)]

extern crate libc;
extern crate sync;

use std::rand;
use std::rand::Rng;

use libc::{c_int, c_uchar};
use sync::one::{Once, ONCE_INIT};

#[link(name = "secp256k1")]
extern "C" {
    pub fn secp256k1_start();
    pub fn secp256k1_stop();
    pub fn secp256k1_ecdsa_verify(
        msg : *const c_uchar, msglen : c_int,
        sig : *const c_uchar, siglen : c_int,
        pubkey : *const c_uchar, pubkeylen : c_int
        ) -> c_int;

    pub fn secp256k1_ecdsa_pubkey_create(
        pubkey : *mut c_uchar,
        pubkeylen : *mut c_int,
        seckey : *const c_uchar,
        compressed : c_int
        ) -> c_int;

    pub fn secp256k1_ecdsa_sign(
        msg : *const c_uchar, msglen : c_int,
        sig : *mut c_uchar, siglen : *mut c_int,
        seckey : *const c_uchar,
        nonce : *const c_uchar
        ) -> c_int;

    pub fn secp256k1_ecdsa_sign_compact(
        msg : *const c_uchar, msglen : c_int,
        sig64 : *mut c_uchar,
        seckey : *const c_uchar,
        nonce : *const c_uchar,
        recid : *mut c_int
        ) -> c_int;

    pub fn secp256k1_ecdsa_recover_compact(
        msg : *const c_uchar, msglen : c_int,
        sig64 : *const c_uchar,
        pubkey : *mut c_uchar,
        pubkeylen : *mut c_int,
        compressed : c_int,
        recid : c_int
        ) -> c_int;
}

pub type Nonce = [u8, ..32];
pub type SecKey = [u8, ..32];
pub type PubKeyCompressed = [u8, ..33];
pub type PubKeyUncompressed = [u8, ..65];
pub enum PubKey {
    Compressed(PubKeyCompressed),
    Uncompressed(PubKeyUncompressed)
}
pub type Signature = Vec<u8>;

#[deriving(Show)]
#[deriving(Eq)]
#[deriving(PartialEq)]
pub enum Error {
    InvalidPublicKey,
    InvalidSignature,
    InvalidSecretKey,
    InvalidNonce,
}

#[deriving(Eq)]
#[deriving(PartialEq)]
pub type VerifyResult = Result<bool, Error>;

static mut Secp256k1_init : Once = ONCE_INIT;

pub struct Secp256k1;

impl Secp256k1 {
    pub fn new() -> Secp256k1 {
        unsafe {
            Secp256k1_init.doit(|| {
                secp256k1_start();
            });
        }
        Secp256k1
    }

    pub fn pubkey_create(
        &self,
        pubkey : &mut PubKey,
        seckey : &SecKey
        ) -> Result<(), Error> {

        let (compressed, pub_ptr, pub_len) = match *pubkey {
            Uncompressed(ref mut key) => (false, key.as_mut_ptr(), key.len()),
            Compressed(ref mut key) => (true, key.as_mut_ptr(), key.len()),
        };
        let mut len = pub_len as c_int;
        let res = unsafe {
            secp256k1_ecdsa_pubkey_create(
                pub_ptr, &mut len,
                seckey.as_ptr(),
                if compressed {1} else {0}
                )
        };

        assert_eq!(pub_len as i32, len);

        match res {
            0 => Err(InvalidSecretKey),
            1 => Ok(()),
            _ => fail!("secp256k1_ecdsa_pubkey_create invalid return value"),
        }
    }

    pub fn sign(&self, sig : &mut Signature, msg : &[u8], seckey : &SecKey, nonce : &Nonce) -> Result<(), Error> {

        let origlen = 72u;
        let mut siglen = origlen as c_int;

        if sig.len() != origlen {
            fail!("invalid length of signature buffer");
        }

        let res = unsafe {
            secp256k1_ecdsa_sign(
                msg.as_ptr(), msg.len() as c_int,
                sig.as_mut_ptr(), &mut siglen,
                seckey.as_ptr(),
                nonce.as_ptr()
                )
        };

        if (origlen as c_int) < siglen {
            fail!("secp256k1_ecdsa_sign wrong return len");
        }

        match res {
            0 => Err(InvalidNonce),
            1 => { sig.truncate(siglen as uint); Ok(()) },
            _ => fail!("secp256k1_ecdsa_sign invalid return value"),
        }
    }

    pub fn sign_compact(
        &self,
        sig : &mut [u8],
        msg : &[u8],
        seckey : &SecKey,
        nonce : &Nonce
        ) -> Result<i32, Error> {

        let origlen = 64u;

        if sig.len() != origlen {
            fail!("invalid length of signature buffer");
        }

        let mut recid = 0;

        let res = unsafe {
            secp256k1_ecdsa_sign_compact(
                msg.as_ptr(), msg.len() as c_int,
                sig.as_mut_ptr(),
                seckey.as_ptr(),
                nonce.as_ptr(),
                &mut recid
                )
        };

        match res {
            0 => Err(InvalidNonce),
            1 => { Ok(recid) },
            _ => fail!("secp256k1_ecdsa_sign_compact invalid return value"),
        }
    }

    pub fn recover_compact(
        &self,
        msg : &[u8],
        sig : &[u8],
        pubkey : &mut PubKey,
        recid : i32
        ) -> Result<(), Error> {

        let (compressed, pub_ptr, pub_len) = match *pubkey {
            Uncompressed(ref mut key) => (false, key.as_mut_ptr(), key.len()),
            Compressed(ref mut key) => (true, key.as_mut_ptr(), key.len()),
        };

        let origlen = 64u;

        if sig.len() != origlen {
            fail!("invalid length of signature buffer");
        }

        let mut len = pub_len as c_int;
        let res = unsafe {
            secp256k1_ecdsa_recover_compact(
                msg.as_ptr(), msg.len() as i32,
                sig.as_ptr(),
                pub_ptr, &mut len,
                if compressed {1} else {0},
                recid
                )
        };

        assert_eq!(pub_len as i32, len);

        match res {
            0 => Err(InvalidSignature),
            1 => Ok(()),
            _ => fail!("secp256k1_ecdsa_recover_compact invalid return value"),
        }
    }

    pub fn verify(&self, msg : &[u8], sig : &[u8], pubkey : &PubKey) -> VerifyResult {

        let (pub_ptr, pub_len) = match *pubkey {
            Uncompressed(ref key) => (key.as_ptr(), key.len()),
            Compressed(ref key) => (key.as_ptr(), key.len()),
        };

        let res = unsafe {
            secp256k1_ecdsa_verify(
                msg.as_ptr(), msg.len() as c_int,
                sig.as_ptr(), sig.len() as c_int,
                pub_ptr, pub_len as c_int
                )
        };

        match res {
            1 => Ok(true),
            0 => Ok(false),
            -1 => Err(InvalidPublicKey),
            -2 => Err(InvalidSignature),
            _ => fail!("secp256k1_ecdsa_verify() invalid return value")
        }
    }
}

#[test]
fn invalid_pubkey() {
    let s = Secp256k1::new();

    let mut msg = Vec::from_elem(32, 0u8);
    let sig = Vec::from_elem(32, 0u8);
    let pubkey = Compressed([0u8, .. 33]);

    rand::task_rng().fill_bytes(msg.as_mut_slice());

    assert_eq!(s.verify(msg.as_mut_slice(), sig.as_slice(), &pubkey), Err(InvalidPublicKey));
}

#[test]
fn valid_pubkey_uncompressed() {
    let s = Secp256k1::new();

    let seckey = [0u8, ..32];
    let mut pubkey = Uncompressed([0u8, ..65]);
    s.pubkey_create(&mut pubkey, &seckey).unwrap();
    let mut msg = Vec::from_elem(32, 0u8);
    let sig = Vec::from_elem(32, 0u8);

    rand::task_rng().fill_bytes(msg.as_mut_slice());

    assert_eq!(s.verify(msg.as_mut_slice(), sig.as_slice(), &pubkey), Err(InvalidSignature));
}

#[test]
fn valid_pubkey_compressed() {
    let s = Secp256k1::new();

    let seckey = [0u8, ..32];
    let mut pubkey = Compressed([0u8, .. 33]);
    s.pubkey_create(&mut pubkey, &seckey).unwrap();
    let mut msg = Vec::from_elem(32, 0u8);
    let sig = Vec::from_elem(32, 0u8);

    rand::task_rng().fill_bytes(msg.as_mut_slice());

    assert_eq!(s.verify(msg.as_mut_slice(), sig.as_slice(), &pubkey), Err(InvalidSignature));
}

#[test]
fn sign() {
    let s = Secp256k1::new();

    let mut msg = [0u8, ..32];
    let mut seckey = [0u8, ..32];
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(72, 0u8);
    rand::task_rng().fill_bytes(msg);
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.sign(&mut sig, msg.as_slice(), &seckey, &nonce).unwrap();
}

#[test]
fn sign_and_verify() {
    let s = Secp256k1::new();

    let mut msg = Vec::from_elem(32, 0u8);
    let mut seckey = [0u8, ..32];
    let mut pubkey = Compressed([0u8, .. 33]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(72, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();

    s.sign(&mut sig, msg.as_slice(), &seckey, &nonce).unwrap();

    assert_eq!(s.verify(msg.as_slice(), sig.as_slice(), &pubkey), Ok(true));
}

#[test]
fn sign_and_verify_fail() {
    let s = Secp256k1::new();

    let mut msg = Vec::from_elem(32, 0u8);
    let mut seckey = [0u8, ..32];
    let mut pubkey = Compressed([0u8, .. 33]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(72, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();
    s.sign(&mut sig, msg.as_slice(), &seckey, &nonce).unwrap();

    rand::task_rng().fill_bytes(msg.as_mut_slice());
    assert_eq!(s.verify(msg.as_slice(), sig.as_slice(), &pubkey), Ok(false));
}

#[test]
fn sign_compact() {
    let s = Secp256k1::new();

    let mut msg = [0u8, ..32];
    let mut seckey = [0u8, ..32];
    let mut pubkey = Uncompressed([0u8, ..65]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(64, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();

    let _ = s.sign_compact(sig.as_mut_slice(), msg.as_slice(), &seckey, &nonce).unwrap();

    assert_eq!(s.verify(msg.as_slice(), sig.as_slice(), &pubkey), Ok(true));
}

#[test]
fn sign_compact_with_recovery() {
    let s = Secp256k1::new();

    let mut msg = [0u8, ..32];
    let mut seckey = [0u8, ..32];
    let mut pubkey = Uncompressed([0u8, ..65]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(64, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();

    let recid = s.sign_compact(sig.as_mut_slice(), msg.as_slice(), &seckey, &nonce).unwrap();

    s.recover_compact(msg.as_slice(), sig.as_slice(), &mut pubkey, recid).unwrap();

    assert_eq!(s.verify(msg.as_slice(), sig.as_slice(), &pubkey), Ok(true));
}

<commit_msg>Fix tests cases.<commit_after>#![crate_type = "lib"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![crate_name = "bitcoin-secp256k1-rs"]
#![comment = "Bindings and wrapper functions for bitcoin secp256k1 library."]
#![feature(phase)]

extern crate libc;
extern crate sync;

use std::rand;
use std::rand::Rng;

use libc::{c_int, c_uchar};
use sync::one::{Once, ONCE_INIT};

#[link(name = "secp256k1")]
extern "C" {
    pub fn secp256k1_start();
    pub fn secp256k1_stop();
    pub fn secp256k1_ecdsa_verify(
        msg : *const c_uchar, msglen : c_int,
        sig : *const c_uchar, siglen : c_int,
        pubkey : *const c_uchar, pubkeylen : c_int
        ) -> c_int;

    pub fn secp256k1_ecdsa_pubkey_create(
        pubkey : *mut c_uchar,
        pubkeylen : *mut c_int,
        seckey : *const c_uchar,
        compressed : c_int
        ) -> c_int;

    pub fn secp256k1_ecdsa_sign(
        msg : *const c_uchar, msglen : c_int,
        sig : *mut c_uchar, siglen : *mut c_int,
        seckey : *const c_uchar,
        nonce : *const c_uchar
        ) -> c_int;

    pub fn secp256k1_ecdsa_sign_compact(
        msg : *const c_uchar, msglen : c_int,
        sig64 : *mut c_uchar,
        seckey : *const c_uchar,
        nonce : *const c_uchar,
        recid : *mut c_int
        ) -> c_int;

    pub fn secp256k1_ecdsa_recover_compact(
        msg : *const c_uchar, msglen : c_int,
        sig64 : *const c_uchar,
        pubkey : *mut c_uchar,
        pubkeylen : *mut c_int,
        compressed : c_int,
        recid : c_int
        ) -> c_int;
}

pub type Nonce = [u8, ..32];
pub type SecKey = [u8, ..32];
pub type PubKeyCompressed = [u8, ..33];
pub type PubKeyUncompressed = [u8, ..65];
pub enum PubKey {
    Compressed(PubKeyCompressed),
    Uncompressed(PubKeyUncompressed)
}
pub type Signature = Vec<u8>;

#[deriving(Show)]
#[deriving(Eq)]
#[deriving(PartialEq)]
pub enum Error {
    InvalidPublicKey,
    InvalidSignature,
    InvalidSecretKey,
    InvalidNonce,
}

#[deriving(Eq)]
#[deriving(PartialEq)]
pub type VerifyResult = Result<bool, Error>;

static mut Secp256k1_init : Once = ONCE_INIT;

pub struct Secp256k1;

impl Secp256k1 {
    pub fn new() -> Secp256k1 {
        unsafe {
            Secp256k1_init.doit(|| {
                secp256k1_start();
            });
        }
        Secp256k1
    }

    pub fn pubkey_create(
        &self,
        pubkey : &mut PubKey,
        seckey : &SecKey
        ) -> Result<(), Error> {

        let (compressed, pub_ptr, pub_len) = match *pubkey {
            Uncompressed(ref mut key) => (false, key.as_mut_ptr(), key.len()),
            Compressed(ref mut key) => (true, key.as_mut_ptr(), key.len()),
        };
        let mut len = pub_len as c_int;
        let res = unsafe {
            secp256k1_ecdsa_pubkey_create(
                pub_ptr, &mut len,
                seckey.as_ptr(),
                if compressed {1} else {0}
                )
        };

        assert_eq!(pub_len as i32, len);

        match res {
            0 => Err(InvalidSecretKey),
            1 => Ok(()),
            _ => fail!("secp256k1_ecdsa_pubkey_create invalid return value"),
        }
    }

    pub fn sign(&self, sig : &mut Signature, msg : &[u8], seckey : &SecKey, nonce : &Nonce) -> Result<(), Error> {

        let origlen = 72u;
        let mut siglen = origlen as c_int;

        if sig.len() != origlen {
            fail!("invalid length of signature buffer");
        }

        let res = unsafe {
            secp256k1_ecdsa_sign(
                msg.as_ptr(), msg.len() as c_int,
                sig.as_mut_ptr(), &mut siglen,
                seckey.as_ptr(),
                nonce.as_ptr()
                )
        };

        if (origlen as c_int) < siglen {
            fail!("secp256k1_ecdsa_sign wrong return len");
        }

        match res {
            0 => Err(InvalidNonce),
            1 => { sig.truncate(siglen as uint); Ok(()) },
            _ => fail!("secp256k1_ecdsa_sign invalid return value"),
        }
    }

    pub fn sign_compact(
        &self,
        sig : &mut [u8],
        msg : &[u8],
        seckey : &SecKey,
        nonce : &Nonce
        ) -> Result<i32, Error> {

        let origlen = 64u;

        if sig.len() != origlen {
            fail!("invalid length of signature buffer");
        }

        let mut recid = 0;

        let res = unsafe {
            secp256k1_ecdsa_sign_compact(
                msg.as_ptr(), msg.len() as c_int,
                sig.as_mut_ptr(),
                seckey.as_ptr(),
                nonce.as_ptr(),
                &mut recid
                )
        };

        match res {
            0 => Err(InvalidNonce),
            1 => { Ok(recid) },
            _ => fail!("secp256k1_ecdsa_sign_compact invalid return value"),
        }
    }

    pub fn recover_compact(
        &self,
        msg : &[u8],
        sig : &[u8],
        pubkey : &mut PubKey,
        recid : i32
        ) -> Result<(), Error> {

        let (compressed, pub_ptr, pub_len) = match *pubkey {
            Uncompressed(ref mut key) => (false, key.as_mut_ptr(), key.len()),
            Compressed(ref mut key) => (true, key.as_mut_ptr(), key.len()),
        };

        let origlen = 64u;

        if sig.len() != origlen {
            fail!("invalid length of signature buffer");
        }

        let mut len = pub_len as c_int;
        let res = unsafe {
            secp256k1_ecdsa_recover_compact(
                msg.as_ptr(), msg.len() as i32,
                sig.as_ptr(),
                pub_ptr, &mut len,
                if compressed {1} else {0},
                recid
                )
        };

        assert_eq!(pub_len as i32, len);

        match res {
            0 => Err(InvalidSignature),
            1 => Ok(()),
            _ => fail!("secp256k1_ecdsa_recover_compact invalid return value"),
        }
    }

    pub fn verify(&self, msg : &[u8], sig : &[u8], pubkey : &PubKey) -> VerifyResult {

        let (pub_ptr, pub_len) = match *pubkey {
            Uncompressed(ref key) => (key.as_ptr(), key.len()),
            Compressed(ref key) => (key.as_ptr(), key.len()),
        };

        let res = unsafe {
            secp256k1_ecdsa_verify(
                msg.as_ptr(), msg.len() as c_int,
                sig.as_ptr(), sig.len() as c_int,
                pub_ptr, pub_len as c_int
                )
        };

        match res {
            1 => Ok(true),
            0 => Ok(false),
            -1 => Err(InvalidPublicKey),
            -2 => Err(InvalidSignature),
            _ => fail!("secp256k1_ecdsa_verify() invalid return value")
        }
    }
}

#[test]
fn invalid_pubkey() {
    let s = Secp256k1::new();

    let mut msg = Vec::from_elem(32, 0u8);
    let sig = Vec::from_elem(32, 0u8);
    let pubkey = Compressed([0u8, .. 33]);

    rand::task_rng().fill_bytes(msg.as_mut_slice());

    assert_eq!(s.verify(msg.as_mut_slice(), sig.as_slice(), &pubkey), Err(InvalidPublicKey));
}

#[test]
fn valid_pubkey_uncompressed() {
    let s = Secp256k1::new();

    let seckey = [0u8, ..32];
    let mut pubkey = Uncompressed([0u8, ..65]);
    s.pubkey_create(&mut pubkey, &seckey).unwrap();
    let mut msg = Vec::from_elem(32, 0u8);
    let sig = Vec::from_elem(32, 0u8);

    rand::task_rng().fill_bytes(msg.as_mut_slice());

    assert_eq!(s.verify(msg.as_mut_slice(), sig.as_slice(), &pubkey), Err(InvalidSignature));
}

#[test]
fn valid_pubkey_compressed() {
    let s = Secp256k1::new();

    let seckey = [0u8, ..32];
    let mut pubkey = Compressed([0u8, .. 33]);
    s.pubkey_create(&mut pubkey, &seckey).unwrap();
    let mut msg = Vec::from_elem(32, 0u8);
    let sig = Vec::from_elem(32, 0u8);

    rand::task_rng().fill_bytes(msg.as_mut_slice());

    assert_eq!(s.verify(msg.as_mut_slice(), sig.as_slice(), &pubkey), Err(InvalidSignature));
}

#[test]
fn sign() {
    let s = Secp256k1::new();

    let mut msg = [0u8, ..32];
    let mut seckey = [0u8, ..32];
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(72, 0u8);
    rand::task_rng().fill_bytes(msg);
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.sign(&mut sig, msg.as_slice(), &seckey, &nonce).unwrap();
}

#[test]
fn sign_and_verify() {
    let s = Secp256k1::new();

    let mut msg = Vec::from_elem(32, 0u8);
    let mut seckey = [0u8, ..32];
    let mut pubkey = Compressed([0u8, .. 33]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(72, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();

    s.sign(&mut sig, msg.as_slice(), &seckey, &nonce).unwrap();

    assert_eq!(s.verify(msg.as_slice(), sig.as_slice(), &pubkey), Ok(true));
}

#[test]
fn sign_and_verify_fail() {
    let s = Secp256k1::new();

    let mut msg = Vec::from_elem(32, 0u8);
    let mut seckey = [0u8, ..32];
    let mut pubkey = Compressed([0u8, .. 33]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(72, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();
    s.sign(&mut sig, msg.as_slice(), &seckey, &nonce).unwrap();

    rand::task_rng().fill_bytes(msg.as_mut_slice());
    assert_eq!(s.verify(msg.as_slice(), sig.as_slice(), &pubkey), Ok(false));
}

#[test]
fn sign_compact_with_recovery() {
    let s = Secp256k1::new();

    let mut msg = [0u8, ..32];
    let mut seckey = [0u8, ..32];
    let mut pubkey = Uncompressed([0u8, ..65]);
    let mut nonce = [0u8, ..32];
    let mut sig = Vec::from_elem(64, 0u8);
    rand::task_rng().fill_bytes(msg.as_mut_slice());
    rand::task_rng().fill_bytes(nonce);
    rand::task_rng().fill_bytes(seckey);

    s.pubkey_create(&mut pubkey, &seckey).unwrap();

    let recid = s.sign_compact(sig.as_mut_slice(), msg.as_slice(), &seckey, &nonce).unwrap();

    assert_eq!(s.recover_compact(msg.as_slice(), sig.as_slice(), &mut pubkey, recid), Ok(()));
}

<|endoftext|>


<commit_before>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use slog::{Drain, Key, OwnedKVList, Record, KV};
use std::{fmt, io, sync::Mutex};

#[derive(Debug, Default)]
pub struct MemDrain {
    buffer: Mutex<Vec<String>>,
    logging: bool,
}

impl MemDrain {
    pub fn clear(&self) {
        self.buffer.lock().unwrap().clear();
    }

    pub fn start_logging(&mut self) {
        self.logging = true;
    }

    pub fn stop_logging(&mut self) {
        self.logging = false;
    }

    pub fn to_string(&self) -> String {
        let buffer = self.buffer.lock().unwrap();
        buffer.join("\n")
    }
}

impl Drain for MemDrain {
    type Err = io::Error;
    type Ok = ();

    fn log(&self, record: &Record, kvs: &OwnedKVList) -> io::Result<()> {
        if self.logging {
            let mut buffer = self.buffer.lock().unwrap();
            const TIMESTAMP_FORMAT: &str = "%b %d %H:%M:%S%.3f";
            let mut serializer = Serializer::new(fmt::format(*record.msg()));

            record.kv().serialize(record, &mut serializer)?;
            kvs.serialize(record, &mut serializer)?;
            let line = format!(
                "{} {} {}",
                chrono::Local::now().format(TIMESTAMP_FORMAT),
                record.level().as_short_str(),
                serializer.text,
            );

            buffer.push(line);
        }
        Ok(())
    }
}

struct Serializer {
    text: String,
}

impl Serializer {
    fn new(text: String) -> Self {
        Serializer { text }
    }
}

impl slog::ser::Serializer for Serializer {
    fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
        self.text = self.text.replace(key, &format!("{:?}", val));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use slog::{o, slog_debug, slog_info, Logger};
    use std::sync::Arc;

    #[test]
    fn drain_storage_log() {
        let s1 = "Multiple log messages should";
        let s2 = "all be find inside log string";
        let drain = Arc::new(Mutex::new(MemDrain::default()));
        let r_vec = drain.clone();
        drain.lock().unwrap().start_logging();
        let log = Logger::root(drain.fuse(), o!());
        slog_info!(log, "{}", s1);
        slog_info!(log, "{}", s2);
        let result = format!("{}", r_vec.lock().unwrap().to_string());
        assert!(result.contains(s1));
        assert!(result.contains(s2));
    }

    #[test]
    fn drain_format() {
        let s1 = "Log should contain message type";
        let s2 = "Type strings are shorten";
        let drain = Arc::new(Mutex::new(MemDrain::default()));
        let r_vec = drain.clone();
        drain.lock().unwrap().start_logging();
        let log = Logger::root(drain.fuse(), o!());
        slog_info!(log, "{}", s1);
        slog_debug!(log, "{}", s2);
        let result = format!("{}", r_vec.lock().unwrap().to_string());
        assert!(result.contains("INFO"));
        assert!(result.contains("DEBG"));
    }

    #[test]
    fn drain_key_values() {
        let txt = "Key values should be swapped, LOGGER and RECORD";
        let logger_value = "when defined on logger";
        let macro_value = "when defined on record";
        let drain = Arc::new(Mutex::new(MemDrain::default()));
        let r_vec = drain.clone();
        drain.lock().unwrap().start_logging();
        let log = Logger::root(drain.fuse(), o!("LOGGER" => logger_value));
        slog_info!(log, "{}", txt; "RECORD" => macro_value);
        let result = format!("{}", r_vec.lock().unwrap().to_string());
        assert!(result.contains(logger_value));
        assert!(result.contains(macro_value));
    }
}
<commit_msg>mem_drain: Remove `TIMESTAMP_FORMAT` `const` as it is used once<commit_after>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use slog::{Drain, Key, OwnedKVList, Record, KV};
use std::{fmt, io, sync::Mutex};

#[derive(Debug, Default)]
pub struct MemDrain {
    buffer: Mutex<Vec<String>>,
    logging: bool,
}

impl MemDrain {
    pub fn clear(&self) {
        self.buffer.lock().unwrap().clear();
    }

    pub fn start_logging(&mut self) {
        self.logging = true;
    }

    pub fn stop_logging(&mut self) {
        self.logging = false;
    }

    pub fn to_string(&self) -> String {
        let buffer = self.buffer.lock().unwrap();
        buffer.join("\n")
    }
}

impl Drain for MemDrain {
    type Err = io::Error;
    type Ok = ();

    fn log(&self, record: &Record, kvs: &OwnedKVList) -> io::Result<()> {
        if self.logging {
            let mut buffer = self.buffer.lock().unwrap();
            let mut serializer = Serializer::new(fmt::format(*record.msg()));

            record.kv().serialize(record, &mut serializer)?;
            kvs.serialize(record, &mut serializer)?;
            let line = format!(
                "{} {} {}",
                chrono::Local::now().format("%b %d %H:%M:%S%.3f"),
                record.level().as_short_str(),
                serializer.text,
            );

            buffer.push(line);
        }
        Ok(())
    }
}

struct Serializer {
    text: String,
}

impl Serializer {
    fn new(text: String) -> Self {
        Serializer { text }
    }
}

impl slog::ser::Serializer for Serializer {
    fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
        self.text = self.text.replace(key, &format!("{:?}", val));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use slog::{o, slog_debug, slog_info, Logger};
    use std::sync::Arc;

    #[test]
    fn drain_storage_log() {
        let s1 = "Multiple log messages should";
        let s2 = "all be find inside log string";
        let drain = Arc::new(Mutex::new(MemDrain::default()));
        let r_vec = drain.clone();
        drain.lock().unwrap().start_logging();
        let log = Logger::root(drain.fuse(), o!());
        slog_info!(log, "{}", s1);
        slog_info!(log, "{}", s2);
        let result = format!("{}", r_vec.lock().unwrap().to_string());
        assert!(result.contains(s1));
        assert!(result.contains(s2));
    }

    #[test]
    fn drain_format() {
        let s1 = "Log should contain message type";
        let s2 = "Type strings are shorten";
        let drain = Arc::new(Mutex::new(MemDrain::default()));
        let r_vec = drain.clone();
        drain.lock().unwrap().start_logging();
        let log = Logger::root(drain.fuse(), o!());
        slog_info!(log, "{}", s1);
        slog_debug!(log, "{}", s2);
        let result = format!("{}", r_vec.lock().unwrap().to_string());
        assert!(result.contains("INFO"));
        assert!(result.contains("DEBG"));
    }

    #[test]
    fn drain_key_values() {
        let txt = "Key values should be swapped, LOGGER and RECORD";
        let logger_value = "when defined on logger";
        let macro_value = "when defined on record";
        let drain = Arc::new(Mutex::new(MemDrain::default()));
        let r_vec = drain.clone();
        drain.lock().unwrap().start_logging();
        let log = Logger::root(drain.fuse(), o!("LOGGER" => logger_value));
        slog_info!(log, "{}", txt; "RECORD" => macro_value);
        let result = format!("{}", r_vec.lock().unwrap().to_string());
        assert!(result.contains(logger_value));
        assert!(result.contains(macro_value));
    }
}
<|endoftext|>


<commit_before>use {Errno, Result};
use libc::{self, c_int};
use std::os::unix::io::RawFd;

bitflags!(
    #[repr(C)]
    flags EpollEventKind: u32 {
        const EPOLLIN = 0x001,
        const EPOLLPRI = 0x002,
        const EPOLLOUT = 0x004,
        const EPOLLRDNORM = 0x040,
        const EPOLLRDBAND = 0x080,
        const EPOLLWRNORM = 0x100,
        const EPOLLWRBAND = 0x200,
        const EPOLLMSG = 0x400,
        const EPOLLERR = 0x008,
        const EPOLLHUP = 0x010,
        const EPOLLRDHUP = 0x2000,
        const EPOLLEXCLUSIVE = 1 << 28,
        const EPOLLWAKEUP = 1 << 29,
        const EPOLLONESHOT = 1 << 30,
        const EPOLLET = 1 << 31
    }
);

#[derive(Clone, Copy)]
#[repr(C)]
pub enum EpollOp {
    EpollCtlAdd = 1,
    EpollCtlDel = 2,
    EpollCtlMod = 3
}

#[derive(Clone, Copy)]
#[repr(C)]
pub struct EpollEvent {
    event: libc::epoll_event,
}

impl EpollEvent {
    pub fn new(events: EpollEventKind, data: u64) -> EpollEvent {
        EpollEvent { event: libc::epoll_event { events: events.bits(), u64: data } }
    }

    pub fn events(&self) -> EpollEventKind {
        EpollEventKind::from_bits(self.event.events).unwrap()
    }

    pub fn data(&self) -> u64 {
        self.event.u64
    }
}

#[inline]
pub fn epoll_create() -> Result<RawFd> {
    let res = unsafe { libc::epoll_create(1024) };

    Errno::result(res)
}

#[inline]
pub fn epoll_create1(flags: c_int) -> Result<RawFd> {
    let res = unsafe { libc::epoll_create1(flags) };

    Errno::result(res)
}

#[inline]
pub fn epoll_ctl(epfd: RawFd, op: EpollOp, fd: RawFd, event: &mut EpollEvent) -> Result<()> {
    let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) };

    Errno::result(res).map(drop)
}

#[inline]
pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result<usize> {
    let res = unsafe {
        libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int)
    };

    Errno::result(res).map(|r| r as usize)
}
<commit_msg>Add EpollCrateFlags bitflag type.<commit_after>use {Errno, Result};
use libc::{self, c_int};
use std::os::unix::io::RawFd;

bitflags!(
    #[repr(C)]
    flags EpollEventKind: u32 {
        const EPOLLIN = 0x001,
        const EPOLLPRI = 0x002,
        const EPOLLOUT = 0x004,
        const EPOLLRDNORM = 0x040,
        const EPOLLRDBAND = 0x080,
        const EPOLLWRNORM = 0x100,
        const EPOLLWRBAND = 0x200,
        const EPOLLMSG = 0x400,
        const EPOLLERR = 0x008,
        const EPOLLHUP = 0x010,
        const EPOLLRDHUP = 0x2000,
        const EPOLLEXCLUSIVE = 1 << 28,
        const EPOLLWAKEUP = 1 << 29,
        const EPOLLONESHOT = 1 << 30,
        const EPOLLET = 1 << 31
    }
);

#[derive(Clone, Copy)]
#[repr(C)]
pub enum EpollOp {
    EpollCtlAdd = 1,
    EpollCtlDel = 2,
    EpollCtlMod = 3
}

libc_bitflags!{
    flags EpollCreateFlags: c_int {
        EPOLL_CLOEXEC,
    }
}

#[derive(Clone, Copy)]
#[repr(C)]
pub struct EpollEvent {
    event: libc::epoll_event,
}

impl EpollEvent {
    pub fn new(events: EpollEventKind, data: u64) -> EpollEvent {
        EpollEvent { event: libc::epoll_event { events: events.bits(), u64: data } }
    }

    pub fn events(&self) -> EpollEventKind {
        EpollEventKind::from_bits(self.event.events).unwrap()
    }

    pub fn data(&self) -> u64 {
        self.event.u64
    }
}

#[inline]
pub fn epoll_create() -> Result<RawFd> {
    let res = unsafe { libc::epoll_create(1024) };

    Errno::result(res)
}

#[inline]
pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
    let res = unsafe { libc::epoll_create1(flags.bits()) };

    Errno::result(res)
}

#[inline]
pub fn epoll_ctl(epfd: RawFd, op: EpollOp, fd: RawFd, event: &mut EpollEvent) -> Result<()> {
    let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) };

    Errno::result(res).map(drop)
}

#[inline]
pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result<usize> {
    let res = unsafe {
        libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int)
    };

    Errno::result(res).map(|r| r as usize)
}
<|endoftext|>


<commit_before>/// generates images used to test NMF

use std::ops::{Index, IndexMut, Mul, Add};

use std;

use std::cmp::PartialOrd;

use std::ops::Range;
use std::iter::{Map, Rev, once, Once, Chain};

extern crate num;
use num::traits::{Zero, One, FromPrimitive, ToPrimitive, Float};

extern crate nalgebra;
use nalgebra::{DMat, DVec, Norm, BaseFloat};

extern crate image;
use self::image::{ImageBuffer, Luma, DynamicImage};

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        /// an error has occured when opening the file
        Io(err: std::io::Error) {}
        /// an error has occured when writing the image into the file
        Image(err: image::ImageError) {}
    }
}

// TODO move the type constraints back up here
pub trait Testimage {
    type Item;
    /// returns a testimage that has `1` in `row` for all `cols` and `0` everywhere else
    ///
    /// ```
    /// Testimage::new_horizontal_line(9, 0..5);
    /// ```
    fn new_horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Self where Self::Item: Clone + Copy + Zero + One;
    /// returns a testimage that has `1` in `col` for all `rows` and `0` everywhere else
    ///
    /// ```
    /// Testimage::new_vertical_line(5..10, 0);
    /// ```
    fn new_vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Self where Self::Item: Clone + Copy + Zero + One;
    /// # Panics
    /// panics unless all the values in `self` are between
    /// `0` (inclusive) and `1` (inclusive)
    fn luma01_to_image(&self) -> DynamicImage where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float;
    /// # Panics
    /// panics unless all the values in `self` are between
    /// `0` (inclusive) and `1` (inclusive)
    fn save_luma01_to_png(&self, filename: &str) -> Result<(), ImageSaveError> where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float;
    fn static_factors()
        -> Chain<Chain<Chain<Once<Self>, Map<Rev<Range<usize>>, fn(usize) -> Self>>, Once<Self>>,
                 Map<Range<usize>, fn(usize) -> Self>>
        where Self: Sized,
              Self::Item: Clone + Copy + Zero + One;
    fn horizontal_evolving_factors() -> Map<Range<usize>, fn(usize) -> Self> where Self::Item: Clone + Copy + Zero + One;
    fn vertical_evolving_factors() -> Map<Rev<Range<usize>>, fn(usize) -> Self> where Self::Item: Clone + Copy + Zero + One;
    fn linear_combination<C>(factors: &[Self], coefficients: &[C]) -> Self
        where C: Clone,
              Self: Sized + Mul<C, Output = Self>,
              Self::Item: Clone + Copy + Zero;
    fn normalize(&self) -> Self where Self::Item: Clone + BaseFloat;
// fn testimages() -> Box<Iterator<Item=Self>> where Self: Sized, Self::Item: Clone + Copy + Zero + One + BaseFloat;
}

impl<T> Testimage for DMat<T> {
    type Item = T;

    fn new_horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Self
        where Self::Item: Clone + Copy + Zero + One
    {
        let mut factor: DMat<Self::Item> = DMat::new_zeros(10, 10);
        for col in cols {
            *factor.index_mut((row, col)) = Self::Item::one();
        }
        factor
    }

    fn new_vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Self
        where Self::Item: Clone + Copy + Zero + One
    {
        let mut factor: DMat<Self::Item> = DMat::new_zeros(10, 10);
        for row in rows {
            *factor.index_mut((row, col)) = Self::Item::one();
        }
        factor
    }

    fn luma01_to_image(&self) -> DynamicImage
        where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float
    {
        let mut image_buffer = ImageBuffer::new(self.ncols() as u32, self.nrows() as u32);
        for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
            let value = self.index((y as usize, x as usize));
            assert!(Self::Item::zero() <= *value);
            assert!(*value <= Self::Item::one());
            let max = Self::Item::from_u8(std::u8::MAX).unwrap();
            let byte = (*value * max).round().to_u8().unwrap();
            *pixel = Luma([byte]);
        }
        DynamicImage::ImageLuma8(image_buffer)
    }

    fn save_luma01_to_png(&self, filename: &str) -> Result<(), ImageSaveError>
        where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float
    {
        let image = self.luma01_to_image();
        let path = std::path::Path::new(filename);
        let mut file = try!(std::fs::File::create(&path).map_err(ImageSaveError::Io));
        image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
    }

    fn static_factors()
        -> Chain<Chain<Chain<Once<Self>, Map<Rev<Range<usize>>, fn(usize) -> Self>>, Once<Self>>,
                 Map<Range<usize>, fn(usize) -> Self>>
        where Self::Item: Clone + Copy + Zero + One
    {
        fn helper_horizontal<U: Clone + Copy + Zero + One>(row: usize) -> DMat<U> {
            Testimage::new_horizontal_line(row, 0..10)
        }
        fn helper_vertical<U: Clone + Copy + Zero + One>(col: usize) -> DMat<U> {
            Testimage::new_vertical_line(0..10, col)
        }
        once(Testimage::new_horizontal_line(9, 0..5))
            .chain((0..9).rev().map(helper_horizontal as fn(usize) -> Self))
            .chain(once(Testimage::new_vertical_line(5..10, 0)))
            .chain((1..10).map(helper_vertical as fn(usize) -> Self))
    }

    fn horizontal_evolving_factors() -> Map<Range<usize>, fn(usize) -> Self>
        where Self::Item: Clone + Copy + Zero + One
    {
        fn helper<U: Clone + Copy + Zero + One>(start_col: usize) -> DMat<U> {
            Testimage::new_horizontal_line(9, start_col..(start_col + 5))
        }
        (0..6).map(helper)
    }

    fn vertical_evolving_factors() -> Map<Rev<Range<usize>>, fn(usize) -> Self>
        where Self::Item: Clone + Copy + Zero + One
    {
        fn helper<U: Clone + Copy + Zero + One>(start_row: usize) -> DMat<U> {
            Testimage::new_vertical_line(start_row..(start_row + 5), 0)
        }
        (0..6).rev().map(helper)
    }

    fn linear_combination<C>(factors: &[Self], coefficients: &[C]) -> Self
        where C: Clone,
              Self: Mul<C, Output = Self>,
              Self::Item: Clone + Copy + Zero
    {
        assert!(0 < factors.len());
        assert_eq!(factors.len(), coefficients.len());
        let nrows = factors[0].nrows();
        let ncols = factors[0].ncols();
        let mut result = DMat::new_zeros(nrows, ncols);
        for (factor, coefficient) in factors.iter().zip(coefficients.iter()) {
            assert_eq!(factor.nrows(), nrows);
            assert_eq!(factor.ncols(), ncols);
            result = result.add(factor.clone().mul(coefficient.clone()));
        }
        result
    }

    fn normalize(&self) -> Self
        where Self::Item: Clone + BaseFloat
    {
        let nrows = self.nrows();
        let ncols = self.ncols();
        let mut vec = DVec::from_slice(nrows * ncols, self.as_vec());
        vec.normalize_mut();
        DMat::from_col_vec(nrows, ncols, vec.as_slice())
    }

// fn testimages() -> Box<Iterator<Item=Self>>
//     where Self: Sized, Self::Item: Clone + Copy + Zero + One + BaseFloat
// {
//     let () =
//     // let static_factors: Vec<Self> = Testimage::static_factors();
//     // horizontal does not survive this scope
//     // Box is returned and contains horizontal
//     let horizontal: Box<Iterator<Item=Self>> =
//         Testimage::horizontal_evolving_factors();
//     let vertical: Box<Iterator<Item=Self>> =
//         Testimage::vertical_evolving_factors();
//     // using `move` and `into_iter` we move everything
//     // into the `Box` so it's still around when this function returns
//     Box::new(horizontal.clone())
//     // Box::new(
//     //     horizontal
//     //     .zip(vertical)
//     //     .enumerate()
//     //     .map(|(step, (horizontal, vertical))| {
//     //         // let h: Self = horizontal;
//     //         // // let cloned: Self = (*horizontal).clone::<Self>();
//     //         // let foo = h.add(vertical);
//     //         // let result: Self = foo.normalize::<Self>();
//     //         // result
//     //         horizontal.clone()
//     //     }))
// }
}

// fn random_coefficient<R: Rng>(rng: &mut R) -> FloatType {
//     let Closed01(random) = rng.gen::<Closed01<FloatType>>();
//     random
// }
//
// fn random_coefficients<R: Rng>(rng: &mut R, count: usize) -> DVec<FloatType> {
//     let mut coefficients: DVec<FloatType> = DVec::new_zeros(count);
//     for i in 0..count {
//         coefficients[i] = random_coefficient(rng);
//     }
//     coefficients
// }
<commit_msg>cleanup complex types<commit_after>/// generates images used to test NMF

use std::ops::{Index, IndexMut, Mul, Add};

use std;

use std::cmp::PartialOrd;

use std::ops::Range;
use std::iter::{Map, Rev, once, Once, Chain};

extern crate num;
use num::traits::{Zero, One, FromPrimitive, ToPrimitive, Float};

extern crate nalgebra;
use nalgebra::{DMat, DVec, Norm, BaseFloat};

extern crate image;
use self::image::{ImageBuffer, Luma, DynamicImage};

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        /// an error has occured when opening the file
        Io(err: std::io::Error) {}
        /// an error has occured when writing the image into the file
        Image(err: image::ImageError) {}
    }
}

pub type Horizontal<T> = Map<Range<usize>, fn(usize) -> T>;
pub type Vertical<T> = Map<Rev<Range<usize>>, fn(usize) -> T>;
pub type Static<T> = Chain<Chain<Chain<Once<T>, Vertical<T>>, Once<T>>, Horizontal<T>>;

// TODO move the type constraints back up here
pub trait Testimage {
    type Item;

    /// returns a testimage that has `1` in `row` for all `cols` and `0` everywhere else
    ///
    /// ```
    /// Testimage::new_horizontal_line(9, 0..5);
    /// ```
    fn new_horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Self where Self::Item: Clone + Copy + Zero + One;
    /// returns a testimage that has `1` in `col` for all `rows` and `0` everywhere else
    ///
    /// ```
    /// Testimage::new_vertical_line(5..10, 0);
    /// ```
    fn new_vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Self where Self::Item: Clone + Copy + Zero + One;
    /// # Panics
    /// panics unless all the values in `self` are between
    /// `0` (inclusive) and `1` (inclusive)
    fn luma01_to_image(&self) -> DynamicImage where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float;
    /// # Panics
    /// panics unless all the values in `self` are between
    /// `0` (inclusive) and `1` (inclusive)
    fn save_luma01_to_png(&self, filename: &str) -> Result<(), ImageSaveError> where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float;
    fn static_factors() -> Static<Self>
        where Self: Sized,
              Self::Item: Clone + Copy + Zero + One;
    fn horizontal_evolving_factors() -> Horizontal<Self> where Self::Item: Clone + Copy + Zero + One;
    fn vertical_evolving_factors() -> Vertical<Self> where Self::Item: Clone + Copy + Zero + One;
    fn linear_combination<C>(factors: &[Self], coefficients: &[C]) -> Self
        where C: Clone,
              Self: Sized + Mul<C, Output = Self>,
              Self::Item: Clone + Copy + Zero;
    fn normalize(&self) -> Self where Self::Item: Clone + BaseFloat;
    // fn testimages() -> Box<Iterator<Item=Self>> where Self: Sized, Self::Item: Clone + Copy + Zero + One + BaseFloat;
}

impl<T> Testimage for DMat<T> {
    type Item = T;

    fn new_horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Self
        where Self::Item: Clone + Copy + Zero + One
        {
            let mut factor: DMat<Self::Item> = DMat::new_zeros(10, 10);
            for col in cols {
                *factor.index_mut((row, col)) = Self::Item::one();
            }
            factor
        }

    fn new_vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Self
        where Self::Item: Clone + Copy + Zero + One
        {
            let mut factor: DMat<Self::Item> = DMat::new_zeros(10, 10);
            for row in rows {
                *factor.index_mut((row, col)) = Self::Item::one();
            }
            factor
        }

    fn luma01_to_image(&self) -> DynamicImage
        where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float
        {
            let mut image_buffer = ImageBuffer::new(self.ncols() as u32, self.nrows() as u32);
            for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
                let value = self.index((y as usize, x as usize));
                assert!(Self::Item::zero() <= *value);
                assert!(*value <= Self::Item::one());
                let max = Self::Item::from_u8(std::u8::MAX).unwrap();
                let byte = (*value * max).round().to_u8().unwrap();
                *pixel = Luma([byte]);
            }
            DynamicImage::ImageLuma8(image_buffer)
        }

    fn save_luma01_to_png(&self, filename: &str) -> Result<(), ImageSaveError>
        where Self::Item: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float
        {
            let image = self.luma01_to_image();
            let path = std::path::Path::new(filename);
            let mut file = try!(std::fs::File::create(&path).map_err(ImageSaveError::Io));
            image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
        }

    fn static_factors() -> Static<Self>
        where Self::Item: Clone + Copy + Zero + One
        {
            fn helper_horizontal<U: Clone + Copy + Zero + One>(row: usize) -> DMat<U> {
                Testimage::new_horizontal_line(row, 0..10)
            }
            fn helper_vertical<U: Clone + Copy + Zero + One>(col: usize) -> DMat<U> {
                Testimage::new_vertical_line(0..10, col)
            }
            once(Testimage::new_horizontal_line(9, 0..5))
                .chain((0..9).rev().map(helper_horizontal as fn(usize) -> Self))
                .chain(once(Testimage::new_vertical_line(5..10, 0)))
                .chain((1..10).map(helper_vertical as fn(usize) -> Self))
        }

    fn horizontal_evolving_factors() -> Horizontal<Self>
        where Self::Item: Clone + Copy + Zero + One
        {
            fn helper<U: Clone + Copy + Zero + One>(start_col: usize) -> DMat<U> {
                Testimage::new_horizontal_line(9, start_col..(start_col + 5))
            }
            (0..6).map(helper)
        }

    fn vertical_evolving_factors() -> Vertical<Self>
        where Self::Item: Clone + Copy + Zero + One
        {
            fn helper<U: Clone + Copy + Zero + One>(start_row: usize) -> DMat<U> {
                Testimage::new_vertical_line(start_row..(start_row + 5), 0)
            }
            (0..6).rev().map(helper)
        }

    fn linear_combination<C>(factors: &[Self], coefficients: &[C]) -> Self
        where C: Clone,
              Self: Mul<C, Output = Self>,
              Self::Item: Clone + Copy + Zero
              {
                  assert!(0 < factors.len());
                  assert_eq!(factors.len(), coefficients.len());
                  let nrows = factors[0].nrows();
                  let ncols = factors[0].ncols();
                  let mut result = DMat::new_zeros(nrows, ncols);
                  for (factor, coefficient) in factors.iter().zip(coefficients.iter()) {
                      assert_eq!(factor.nrows(), nrows);
                      assert_eq!(factor.ncols(), ncols);
                      result = result.add(factor.clone().mul(coefficient.clone()));
                  }
                  result
              }

    fn normalize(&self) -> Self
        where Self::Item: Clone + BaseFloat
        {
            let nrows = self.nrows();
            let ncols = self.ncols();
            let mut vec = DVec::from_slice(nrows * ncols, self.as_vec());
            vec.normalize_mut();
            DMat::from_col_vec(nrows, ncols, vec.as_slice())
        }

// fn testimages() -> Box<Iterator<Item=Self>>
//     where Self: Sized, Self::Item: Clone + Copy + Zero + One + BaseFloat
// {
//     let () =
//     // let static_factors: Vec<Self> = Testimage::static_factors();
//     // horizontal does not survive this scope
//     // Box is returned and contains horizontal
//     let horizontal: Box<Iterator<Item=Self>> =
//         Testimage::horizontal_evolving_factors();
//     let vertical: Box<Iterator<Item=Self>> =
//         Testimage::vertical_evolving_factors();
//     // using `move` and `into_iter` we move everything
//     // into the `Box` so it's still around when this function returns
//     Box::new(horizontal.clone())
//     // Box::new(
//     //     horizontal
//     //     .zip(vertical)
//     //     .enumerate()
//     //     .map(|(step, (horizontal, vertical))| {
//     //         // let h: Self = horizontal;
//     //         // // let cloned: Self = (*horizontal).clone::<Self>();
//     //         // let foo = h.add(vertical);
//     //         // let result: Self = foo.normalize::<Self>();
//     //         // result
//     //         horizontal.clone()
//     //     }))
// }
}

// fn random_coefficient<R: Rng>(rng: &mut R) -> FloatType {
//     let Closed01(random) = rng.gen::<Closed01<FloatType>>();
//     random
// }
//
// fn random_coefficients<R: Rng>(rng: &mut R, count: usize) -> DVec<FloatType> {
//     let mut coefficients: DVec<FloatType> = DVec::new_zeros(count);
//     for i in 0..count {
//         coefficients[i] = random_coefficient(rng);
//     }
//     coefficients
// }
<|endoftext|>


<commit_before>
use vertex::{RawVertex, Vertex};
use edge::{Edge, EdgeProxy};
use graph::TraversableToVertex;
use path::{Path, Element};

// use std::iter::Iterator;

// define a traversal as a series of stages

pub struct GraphQuery {
	// many paths
    pub paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<Vertex>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
			let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

	pub fn get_paths(&self) -> &Vec<Path> {
		&self.paths
	}
	pub fn push(&mut self, path:Path) {
		self.paths.push(path)
	}

	/*
	generic mapper for our queries
	future this may use worker threads to perform
	traversals
	 */
    fn map<F: Fn(&Path) -> &[Element]>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
		for path in self.paths.iter() {
			let mut tmp = closure(path);
            // currently gets back a Vec<Path> but what if it gets Elements?
            let new_elements = path.permute(tmp);
            result.paths.push_all(&new_elements);
        }
		result
    }

    pub fn outV(&self) -> GraphQuery {
        // needs to be modified to return a Vec of elements or a slice?
        // map can figure out the rest
		let f = |path: &Path| {
			println!("applying outV");
			//take the final element in the path
			let element = path.last().unwrap();

			let result : &[Element] = match element {
				&Element::Vertex(ref v) => {
					let tmp : &[Element] = v.outV().iter().map(|&v| Element::Vertex(v));
                    &tmp
				},
				&Element::Edge(ref e) => {
                    &[]
				}
			};
			// apply outV
			result
		};
		self.map(f)
    }

//	pub fn inV(&self) -> GraphQuery {
//		let g = GraphQuery::empty();
//		let f = |element: &Element| {
//			element.inV()
//		};
//		self.map(f)
//	}
}
<commit_msg>bare bones<commit_after>
use vertex::{RawVertex, Vertex};
use edge::{Edge, EdgeProxy};
use graph::TraversableToVertex;
use path::{Path, Element};

// use std::iter::Iterator;

// define a traversal as a series of stages

pub struct GraphQuery {
	// many paths
    pub paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<Vertex>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
			let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

	pub fn get_paths(&self) -> &Vec<Path> {
		&self.paths
	}
	pub fn push(&mut self, path:Path) {
		self.paths.push(path)
	}

	/*
	generic mapper for our queries
	future this may use worker threads to perform
	traversals
	 */
    fn map<F: Fn(&Path) -> &[Element]>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
		for path in self.paths.iter() {
			let mut tmp = closure(path);
            // currently gets back a Vec<Path> but what if it gets Elements?
            let new_elements = path.permute(tmp);
            result.paths.push_all(&new_elements);
        }
		result
    }

    pub fn outV(&self) -> GraphQuery {
        // needs to be modified to return a Vec of elements or a slice?
        // map can figure out the rest
		let f = |path: &Path| {
			println!("applying outV");
			//take the final element in the path
			let element = path.last().unwrap();

			let result : &[Element] = match element {
				&Element::Vertex(ref v) => {
					v.outV().iter().map(|&v| Element::Vertex(v)).collect()
				},
				&Element::Edge(ref e) => {
                    &[]
				}
			};
			// apply outV
			result
		};
		self.map(f)
    }

//	pub fn inV(&self) -> GraphQuery {
//		let g = GraphQuery::empty();
//		let f = |element: &Element| {
//			element.inV()
//		};
//		self.map(f)
//	}
}
<|endoftext|>


<commit_before>use std::mem;
use std::os::unix::prelude::AsRawFd;
use std::slice;
use std::ops;
use std::fs::File;
use std::marker::PhantomData;

use mmap;

pub struct TypedMemoryMap<T:Copy> {
    map:    mmap::MemoryMap,    // mapped file
    len:    usize,              // in bytes (needed because map extends to full block)
    phn:    PhantomData<T>,
}

impl<T:Copy> TypedMemoryMap<T> {
    pub fn new(filename: String) -> TypedMemoryMap<T> {
        let file = File::open(filename).ok().expect("error opening file");
        let size = file.metadata().ok().expect("error reading metadata").len() as usize;
        TypedMemoryMap {
            map: mmap::MemoryMap::new(size, &[mmap::MapOption::MapReadable,
                                              mmap::MapOption::MapFd(file.as_raw_fd())]).ok().expect("error mapping memory"),
            len: size / mem::size_of::<T>(),
            phn: PhantomData,
        }
    }
}

impl<T:Copy> ops::Index<ops::RangeFull> for TypedMemoryMap<T> {
    type Output = [T];
    #[inline]
    fn index(&self, _index: ops::RangeFull) -> &[T] {
        unsafe { slice::from_raw_parts(self.map.data() as *const T, self.len) }
    }
}
<commit_msg>better error information<commit_after>use std::mem;
use std::os::unix::prelude::AsRawFd;
use std::slice;
use std::ops;
use std::fs::File;
use std::marker::PhantomData;

use mmap;

pub struct TypedMemoryMap<T:Copy> {
    map:    mmap::MemoryMap,    // mapped file
    len:    usize,              // in bytes (needed because map extends to full block)
    phn:    PhantomData<T>,
}

impl<T:Copy> TypedMemoryMap<T> {
    pub fn new(filename: String) -> TypedMemoryMap<T> {
        println!("attempting to open {}", filename);
        let file = File::open(filename).ok().expect("error opening file");
        let size = file.metadata().ok().expect("error reading metadata").len() as usize;
        TypedMemoryMap {
            map: mmap::MemoryMap::new(size, &[mmap::MapOption::MapReadable,
                                              mmap::MapOption::MapFd(file.as_raw_fd())]).ok().expect("error mapping memory"),
            len: size / mem::size_of::<T>(),
            phn: PhantomData,
        }
    }
}

impl<T:Copy> ops::Index<ops::RangeFull> for TypedMemoryMap<T> {
    type Output = [T];
    #[inline]
    fn index(&self, _index: ops::RangeFull) -> &[T] {
        unsafe { slice::from_raw_parts(self.map.data() as *const T, self.len) }
    }
}
<|endoftext|>


<commit_before>use ::{
    NifEnv,
    NifTerm,
    NifResult,
};

#[macro_use]
pub mod atom;
pub mod binary;
pub mod list;
pub mod map;
pub mod primitive;
pub mod string;
pub mod tuple;
pub mod pid;

pub mod elixir_struct;

pub trait NifEncoder {
    fn encode<'a>(&self, env: NifEnv<'a>) -> NifTerm<'a>;
}
pub trait NifDecoder<'a>: Sized+'a {
    fn decode(term: NifTerm<'a>) -> NifResult<Self>;
}

impl<'a> NifEncoder for NifTerm<'a> {
    fn encode<'b>(&self, env: NifEnv<'b>) -> NifTerm<'b> {
        self.in_env(env)
    }
}
impl<'a> NifDecoder<'a> for NifTerm<'a> {
    fn decode(term: NifTerm<'a>) -> NifResult<Self> {
        Ok(term)
    }
}

impl<'a, T> NifEncoder for &'a T where T: NifEncoder {
    fn encode<'c>(&self, env: NifEnv<'c>) -> NifTerm<'c> {
        <T as NifEncoder>::encode(self, env)
    }
}
<commit_msg>implement NifEncoder for Option<T> and Result<T,E> (#94)<commit_after>use ::{
    NifEnv,
    NifTerm,
    NifResult,
};

#[macro_use]
pub mod atom;
pub mod binary;
pub mod list;
pub mod map;
pub mod primitive;
pub mod string;
pub mod tuple;
pub mod pid;

pub mod elixir_struct;

pub trait NifEncoder {
    fn encode<'a>(&self, env: NifEnv<'a>) -> NifTerm<'a>;
}
pub trait NifDecoder<'a>: Sized+'a {
    fn decode(term: NifTerm<'a>) -> NifResult<Self>;
}

impl<'a> NifEncoder for NifTerm<'a> {
    fn encode<'b>(&self, env: NifEnv<'b>) -> NifTerm<'b> {
        self.in_env(env)
    }
}
impl<'a> NifDecoder<'a> for NifTerm<'a> {
    fn decode(term: NifTerm<'a>) -> NifResult<Self> {
        Ok(term)
    }
}

impl<'a, T> NifEncoder for &'a T where T: NifEncoder {
    fn encode<'c>(&self, env: NifEnv<'c>) -> NifTerm<'c> {
        <T as NifEncoder>::encode(self, env)
    }
}

impl<T> NifEncoder for Option<T> where T: NifEncoder {
    fn encode<'c>(&self, env: NifEnv<'c>) -> NifTerm<'c> {
        match *self {
            Some(ref value) => value.encode(env),
            None => atom::nil().encode(env),
        }
    }
}

impl<T, E> NifEncoder for Result<T, E> where T: NifEncoder, E: NifEncoder {
    fn encode<'c>(&self, env: NifEnv<'c>) -> NifTerm<'c> {
        match *self {
            Ok(ref value) => (atom::ok().encode(env), value.encode(env)).encode(env),
            Err(ref err) => (atom::error().encode(env), err.encode(env)).encode(env),
        }
    }
}
<|endoftext|>


<commit_before>use ast::AST;
use env::CellEnv;
use errors::Error;
use instructions::{Instruction, Bytecode};
use memory::Memory;
use primitives;
use values::{RcValue, Value};
use std::collections::LinkedList;
use std::rc::Rc;

pub type Rib = Vec<RcValue>;
pub type Stack = LinkedList<Frame>;

struct Frame {
    rib: Rib,
}

impl Frame {
    pub fn from(rib: &Rib) -> Frame {
        Frame {
            rib: rib.clone(),
        }
    }
}

pub struct VM {
    pub acc: RcValue,
    pub memory: Memory,
    pub rib: Rib,
    pub env: CellEnv,
    pub stack: Stack,
}

impl VM {
    pub fn new() -> VM {
        let memory = Memory::new();

        let mut vm = VM {
            acc: memory.unspecified(),
            memory: memory,
            stack: LinkedList::new(),
            rib: Vec::new(),
            env: CellEnv::new(),
        };

        vm.init_primitives();

        vm
    }

    pub fn execute<'a, I>(&mut self, mut instructions: I) -> Result<RcValue, Error>
        where I: Iterator<Item = &'a Instruction>
    {
        loop {
            match instructions.next() {
                Some(instr) =>
                    match instr {
                        &Instruction::LoadConstant { ref value } =>
                            self.load_constant(value),
                        &Instruction::Jump { offset } =>
                            VM::jump(&mut instructions, offset),
                        &Instruction::JumpOnFalse { offset } =>
                            self.jump_on_false(&mut instructions, offset),
                        &Instruction::JumpOnTrue { offset } =>
                            self.jump_on_true(&mut instructions, offset),
                        &Instruction::LoadReference { ref reference } =>
                            try!(self.load_reference(reference)),
                        &Instruction::Assignment { ref reference } =>
                            self.assignment(reference),
                        &Instruction::LoadUnspecified =>
                            self.load_unspecified(),
                        &Instruction::Apply =>
                            try!(self.apply()),
                        &Instruction::Argument =>
                            self.argument(),
                        &Instruction::Frame =>
                            self.push_frame(),
                        &Instruction::Close { ref args, ref body } =>
                            self.push_closure(args, body),
                    },
                None =>
                    break,
            }
        }

        Ok(self.acc.clone())
    }

    fn load_constant(&mut self, ast: &AST) {
        self.acc = Value::from_ast(ast, &mut self.memory);
    }

    fn jump_on_false<I>(&mut self, iter: &mut I, times: usize) where I: Iterator {
        if self.acc == self.memory.b_false() {
            VM::jump(iter, times);
        }
    }

    fn jump_on_true<I>(&mut self, iter: &mut I, times: usize) where I: Iterator {
        if self.acc != self.memory.b_false() {
            VM::jump(iter, times);
        }
    }

    fn jump<I>(iter: &mut I, times: usize) where I: Iterator {
        for _ in (0..times) {
            iter.next();
        }
    }

    fn load_reference(&mut self, reference: &String) -> Result<(), Error> {
        match self.env.get(reference) {
            Some(value) => Ok(self.acc = value),
            None        => Err(Error::UnboundVariable(reference.clone())),
        }
    }

    fn assignment(&mut self, reference: &String) {
        self.env.set(reference.clone(), self.acc.clone());
        self.load_unspecified();
    }

    fn load_unspecified(&mut self) {
        self.acc = self.memory.unspecified();
    }

    fn push_frame(&mut self) {
        self.stack.push_back(Frame::from(&self.rib));
        self.rib = Vec::new();
    }

    fn pop_frame(&mut self) -> Result<(), Error> {
        let frame = try!(
            self.stack
                .pop_back()
                .ok_or(Error::CannotPopLastFrame)
        );

        self.rib = frame.rib;

        Ok(())
    }

    fn apply(&mut self) -> Result<(), Error> {
        match *self.acc.clone() {
            Value::PrimitiveFn(ref name) => {
                let result = try!(
                    primitives::apply(name, &self.rib, &mut self.memory)
                );

                try!(self.pop_frame());

                Ok(self.acc = result)
            }
            Value::Closure(ref args, ref body) => {
                Ok(())
            }
            _ =>
                return Err(Error::UnappliableValue(self.acc.clone()))
        }
    }

    fn push_closure(&mut self, args: &Vec<String>, body: &Bytecode) {
        self.acc = Rc::new(Value::Closure(args.clone(), body.clone()));
    }

    fn argument(&mut self) {
        self.rib.push(self.acc.clone());
    }

    fn init_primitives(&mut self) {
        for name in primitives::PRIMITIVES.iter() {
            let primitive = self.memory.primitive(name.to_string());
            self.env.set(name.to_string(), primitive);
        }
    }
}
<commit_msg>Added env to Frame.<commit_after>use ast::AST;
use env::CellEnv;
use errors::Error;
use instructions::{Instruction, Bytecode};
use memory::Memory;
use primitives;
use values::{RcValue, Value};
use std::collections::LinkedList;
use std::rc::Rc;

pub type Rib = Vec<RcValue>;
pub type Stack = LinkedList<Frame>;

struct Frame {
    rib: Rib,
    env: CellEnv,
}

impl Frame {
    pub fn new(rib: &Rib, env: &CellEnv) -> Frame {
        Frame {
            rib: rib.clone(),
            env: env.clone(),
        }
    }
}

pub struct VM {
    pub acc: RcValue,
    pub memory: Memory,
    pub rib: Rib,
    pub env: CellEnv,
    pub stack: Stack,
}

impl VM {
    pub fn new() -> VM {
        let memory = Memory::new();

        let mut vm = VM {
            acc: memory.unspecified(),
            memory: memory,
            stack: LinkedList::new(),
            rib: Vec::new(),
            env: CellEnv::new(),
        };

        vm.init_primitives();

        vm
    }

    pub fn execute<'a, I>(&mut self, mut instructions: I) -> Result<RcValue, Error>
        where I: Iterator<Item = &'a Instruction>
    {
        loop {
            match instructions.next() {
                Some(instr) =>
                    match instr {
                        &Instruction::LoadConstant { ref value } =>
                            self.load_constant(value),
                        &Instruction::Jump { offset } =>
                            VM::jump(&mut instructions, offset),
                        &Instruction::JumpOnFalse { offset } =>
                            self.jump_on_false(&mut instructions, offset),
                        &Instruction::JumpOnTrue { offset } =>
                            self.jump_on_true(&mut instructions, offset),
                        &Instruction::LoadReference { ref reference } =>
                            try!(self.load_reference(reference)),
                        &Instruction::Assignment { ref reference } =>
                            self.assignment(reference),
                        &Instruction::LoadUnspecified =>
                            self.load_unspecified(),
                        &Instruction::Apply =>
                            try!(self.apply()),
                        &Instruction::Argument =>
                            self.argument(),
                        &Instruction::Frame =>
                            self.push_frame(),
                        &Instruction::Close { ref args, ref body } =>
                            self.push_closure(args, body),
                    },
                None =>
                    break,
            }
        }

        Ok(self.acc.clone())
    }

    fn load_constant(&mut self, ast: &AST) {
        self.acc = Value::from_ast(ast, &mut self.memory);
    }

    fn jump_on_false<I>(&mut self, iter: &mut I, times: usize) where I: Iterator {
        if self.acc == self.memory.b_false() {
            VM::jump(iter, times);
        }
    }

    fn jump_on_true<I>(&mut self, iter: &mut I, times: usize) where I: Iterator {
        if self.acc != self.memory.b_false() {
            VM::jump(iter, times);
        }
    }

    fn jump<I>(iter: &mut I, times: usize) where I: Iterator {
        for _ in (0..times) {
            iter.next();
        }
    }

    fn load_reference(&mut self, reference: &String) -> Result<(), Error> {
        match self.env.get(reference) {
            Some(value) => Ok(self.acc = value),
            None        => Err(Error::UnboundVariable(reference.clone())),
        }
    }

    fn assignment(&mut self, reference: &String) {
        self.env.set(reference.clone(), self.acc.clone());
        self.load_unspecified();
    }

    fn load_unspecified(&mut self) {
        self.acc = self.memory.unspecified();
    }

    fn push_frame(&mut self) {
        self.stack.push_back(
            Frame::new(&self.rib, &self.env)
        );

        self.rib = Vec::new();
    }

    fn pop_frame(&mut self) -> Result<(), Error> {
        let frame = try!(
            self.stack
                .pop_back()
                .ok_or(Error::CannotPopLastFrame)
        );

        self.rib = frame.rib;
        self.env = frame.env;

        Ok(())
    }

    fn apply(&mut self) -> Result<(), Error> {
        match *self.acc.clone() {
            Value::PrimitiveFn(ref name) => {
                let result = try!(
                    primitives::apply(name, &self.rib, &mut self.memory)
                );

                try!(self.pop_frame());

                Ok(self.acc = result)
            }
            Value::Closure(ref args, ref body) => {
                Ok(())
            }
            _ =>
                return Err(Error::UnappliableValue(self.acc.clone()))
        }
    }

    fn push_closure(&mut self, args: &Vec<String>, body: &Bytecode) {
        self.acc = Rc::new(Value::Closure(args.clone(), body.clone()));
    }

    fn argument(&mut self) {
        self.rib.push(self.acc.clone());
    }

    fn init_primitives(&mut self) {
        for name in primitives::PRIMITIVES.iter() {
            let primitive = self.memory.primitive(name.to_string());
            self.env.set(name.to_string(), primitive);
        }
    }
}
<|endoftext|>