<commit_before>#![allow(unstable)]

extern crate x11;
extern crate libc;

use std::ptr;
use std::ffi;
use std::mem;
use std::str;
use std::slice;
use std::boxed::Box;

use x11::xlib;
use x11::xlib::{ Display, Window };
use libc::{ c_int, c_long, c_uint, c_ulong, c_void };

#[derive(Debug, Copy, Clone)]
pub struct Context {
    display: *mut Display
}

pub fn open_display(name: Option<&str>) -> Option<Context> {
    unsafe{
        let display = match name {
            Some(n) => {
                let s = ffi::CString::new(n).unwrap();
                xlib::XOpenDisplay(s.as_ptr())
            }
            None => { xlib::XOpenDisplay(ptr::null()) }
        };

        if display == ptr::null_mut() {
            None
        }
        else{
            // let b = Some(Box::<Display>::new(*display));
            // xlib::XFree(display as *mut libc::c_void);
            // b
            let c = Context {
                display: display,
            };
            Some(c)
        }
    }
}

pub fn close_display(context: Context) {
    unsafe{
        xlib::XCloseDisplay(context.display);
    }
}

pub fn default_screen(context: Context) -> c_int {
    unsafe{
        xlib::XDefaultScreen(context.display)
    }
}

pub fn root_window(context: Context, screen_num: c_int) -> c_ulong {
    unsafe {
        xlib::XRootWindow(context.display, screen_num)
    }
}

pub fn next_event(context: Context) -> xlib::XEvent {
    unsafe{
        let mut e: xlib::XEvent = mem::zeroed();
        xlib::XNextEvent(context.display, &mut e);
        e
    }
}

pub fn get_atom_name(context: Context, atom: xlib::Atom) -> Option<String> {
    unsafe{
        let name = xlib::XGetAtomName(context.display, atom);
        if name == ptr::null_mut() {
            return None
        }
        let s = ffi::CStr::from_ptr(name);
        let s = s.to_bytes();
        match str::from_utf8(s) {
            Ok(v) => {
                let tmp = Some(v.to_string());
                xlib::XFree(name as *mut libc::c_void);
                tmp
            }
            _ => None
        }
    }
}

pub fn get_atom(context: Context, name: &str) -> xlib::Atom{
    unsafe{
        let cstr = ffi::CString::new(name).unwrap();
        let atom = xlib::XInternAtom(context.display, cstr.as_ptr(), xlib::False);
        atom
    }
}

pub fn get_text_property(context: Context, window: xlib::Window, atom: xlib::Atom) -> Option<String>{
    unsafe{
        let mut prop: xlib::XTextProperty = mem::zeroed();
        let r = xlib::XGetTextProperty(context.display, window, &mut prop, atom);
        if r == 0 || prop.nitems == 0{
            None
        }else{

            // let s = String::from_raw_parts(prop.value, prop.nitems as usize, prop.nitems as usize).clone()
            let s = slice::from_raw_parts(prop.value, prop.nitems as usize).iter().map(|&c| c as u8).collect();
            match String::from_utf8(s) {
                Ok(v) => {
                    xlib::XFree(prop.value as *mut libc::c_void);
                    Some(v)
                }
                _ => None
            }
        }
    }
}

pub fn get_wm_protocols(context: Context, window: Window) -> Vec<xlib::Atom>{
    unsafe{
        let mut atoms: *mut xlib::Atom = ptr::null_mut();
        let mut count = 0;
        let s = xlib::XGetWMProtocols(context.display, window, &mut atoms, &mut count);
        let mut vec: Vec<xlib::Atom> = Vec::new();
        if s > 0 {
            vec = slice::from_raw_parts(atoms, count as usize).iter()
                .map(|&a| a as xlib::Atom).collect();
            xlib::XFree(atoms as *mut c_void);
        }
        vec
    }
}

pub fn get_window_attributes(context: Context, window: Window) -> xlib::XWindowAttributes {
    unsafe{
        let mut attrs: xlib::XWindowAttributes = mem::zeroed();
        xlib::XGetWindowAttributes(context.display, window, &mut attrs);
        attrs
    }
}

pub fn get_transient_for_hint(context: Context, window: Window) -> i32 {
    unsafe{
        let mut window_return: xlib::Window = 0;
        xlib::XGetTransientForHint(context.display, window, &mut window_return)
    }
}

pub fn change_window_attributes(context: Context, window: Window, valuemask: c_ulong, attrs: *mut xlib::XSetWindowAttributes) {
    unsafe{
        xlib::XChangeWindowAttributes(context.display, window, valuemask, attrs);
    }

}

fn get_window_property(context: Context, window: Window, atom: xlib::Atom) {
    unsafe {
        let mut actual_type_return: u64 = 0;
        let mut actual_format_return: i32 = 0;
        let mut nitem_return: libc::c_ulong = 0;
        let mut bytes_after_return: libc::c_ulong = 0;
        let mut prop_return: *mut libc::c_uchar = mem::zeroed();

        let r = xlib::XGetWindowProperty(context.display, window, xlib::XA_WM_NAME,
                                         0, 0xFFFFFFFF, 0, 0,
                                         &mut actual_type_return,
                                         &mut actual_format_return,
                                         &mut nitem_return,
                                         &mut bytes_after_return,
                                         &mut prop_return);

        debug!("result get wp {}", r);
        if r == 0 {

        }else{
            debug!("actual format return {}", actual_format_return);
            if actual_format_return == 0 {

            }
            else {
                // let s = from_raw_parts(prop_return as *const libc::c_ulong, nitems_return as usize).iter()
                //     .map(|&c| c as u64)
                //     .collect();
                let s = String::from_raw_parts(prop_return, nitem_return as usize, nitem_return as usize);
                println!("{}", s);

            }
        }
    }
}

pub fn get_top_window(context: Context, window: Window)-> Option<Window>{
    let mut w = window;
    let mut root = window;
    let mut parent = window;
    unsafe{
        while parent != root {
            w = parent;
            unsafe{
                let res = query_tree(context, w);
                match res {
                    Some((r, p, _)) => {
                        parent = p;
                        root = r;
                    }
                    None => {
                        return None
                    }
                }
            }
        }
        Some(w)
    }
}

pub fn get_children(context: Context, window: Window) -> Option<Vec<Window>> {
    let res = query_tree(context, window);
    match res {
        Some((_, _, v)) => {
            Some(v)
        }
        None => { None }
    }
}

pub fn query_tree(context: Context, window: Window) -> Option<(Window, Window, Vec<Window>)> {
    let mut root: Window = 0;
    let mut parent: Window = window;
    let mut children: *mut Window = ptr::null_mut();
    let mut nchildren: libc::c_uint = 0;
    unsafe{
        let s = xlib::XQueryTree(context.display, window, &mut root, &mut parent, &mut children, &mut nchildren);
        if s > 0 {
            let vec = slice::from_raw_parts(children,
                                            nchildren as usize).iter()
                .map(|&a| a as Window).collect();
            xlib::XFree(children as *mut libc::c_void);
            Some((root, parent, vec))
        }
        else{
            None
        }
    }

}

pub fn lookup_keysym(event: xlib::XKeyEvent, index: c_int) -> c_ulong{
    let mut e = event;
    unsafe{
        xlib::XLookupKeysym(&mut e, index)
    }
}

// pub fn loopup_string(event: xlib::XKeyEvent) -> Option<(c_ulong, String)>{
//     let mut sym: xlib::KeySym = 0;
//     let status: *mut xlib::XComposeStatus = ptr::null_mut();

//     unsafe{
//         let mut e = event;
//         xlib::XLookupString(&mut e, ptr::null_mut(), 0, &mut sym, status);
//     }

// }

pub fn set_input_focus(context: Context, window: Window) {
    let none = 0;
    let pointer_root = 1;
    let parent = 2;
    unsafe{
        let (old, _) = get_input_focus(context);
        debug!("set focus from {} to {}", old, window);
        xlib::XSetInputFocus(context.display, window, none, 0);
    }
}

pub fn get_input_focus(context: Context) -> (Window, c_int){
    let mut window: xlib::Window = 0;
    let mut revert_to: libc::c_int = 0;
    unsafe{
        let s = xlib::XGetInputFocus(context.display, &mut window, &mut revert_to);
    }
    (window, revert_to)
}

pub fn unmap_window(context: Context, window: Window) -> c_int{
    unsafe{
        xlib::XUnmapWindow(context.display, window)
    }
}

pub fn configure_window(context: Context, window: Window, mask:c_uint, mut change: xlib::XWindowChanges) {
    unsafe{
        xlib::XConfigureWindow(context.display, window, mask, &mut change);
    }
}
pub fn map_window(context: Context, window: Window) -> c_int{
    unsafe{
        xlib::XMapWindow(context.display, window)
    }
}

pub fn kill_window(context: Context, window: Window) {
    let mut event: xlib::XClientMessageEvent = unsafe {
        mem::zeroed()
    };

    let display = context.display;
    let wm_delete_window = get_atom(context, "WM_DELETE_WINDOW");
    let wm_protocols = get_atom(context, "WM_PROTOCOLS");
    let protocols = get_wm_protocols(context, window);

    if protocols.iter().any(|&p| p == wm_delete_window){
        event.type_ = xlib::ClientMessage;
        event.message_type = wm_protocols;
        event.format = 32;
        event.window = window;
        event.send_event = xlib::True;
        event.display = display;
        event.data.set_long(0, wm_delete_window as libc::c_long);

        let mut e: xlib::XEvent = From::from(event);
        send_event(context, window, xlib::True, xlib::NoEventMask, e);
    }
    else{
        unsafe{
            xlib::XKillClient(display, window);
        }
    }

}

pub fn send_event(context: Context, window: Window,
                  propagate: c_int, event_mask: c_long,
                  mut event: xlib::XEvent) {
    unsafe{
        xlib::XSendEvent(context.display, window, propagate, event_mask, &mut event);
    }
}

pub fn keysym_to_string(keysym: c_ulong) -> Option<String> {
    let mut sym: xlib::KeySym = 0;
    let status: *mut xlib::XComposeStatus = ptr::null_mut();
    unsafe{
        let s = xlib::XKeysymToString(keysym);
        let cstr = ffi::CStr::from_ptr(s);
        match str::from_utf8(cstr.to_bytes()) {
            Ok(s) => {
                Some(s.to_string())
            }
            _ => {
                None
            }
        }
    }
}

pub fn string_to_keysym(s: &str) -> xlib::KeySym {
    let tmp = ffi::CString::new(s).unwrap();
    unsafe{
        xlib::XStringToKeysym(tmp.as_ptr())
    }

}

pub fn select_input(context: Context, window: Window, mask: c_long) {
    unsafe{
        xlib::XSelectInput(context.display, window, mask);
    }
}

pub fn sync(context: Context, discard: c_int) {
    unsafe {
        xlib::XSync(context.display, discard);
    }
}

pub fn display_height(context: Context, screen_num: c_int) -> c_int{
    unsafe{
        xlib::XDisplayHeight(context.display, screen_num)
    }
}

pub fn display_width(context: Context, screen_num: c_int) -> c_int{
    unsafe{
        xlib::XDisplayWidth(context.display, screen_num)
    }
}

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

#[test]
fn test_open(){
    let display = open_display(None);
    assert!(display.is_some());
}

}
<commit_msg>more wrappers<commit_after>#![allow(unstable)]

extern crate x11;
extern crate libc;

use std::ptr;
use std::ffi;
use std::mem;
use std::str;
use std::slice;
use std::boxed::Box;

use x11::xlib;
use x11::xlib::{ Display, Window };
use libc::{ c_int, c_long, c_uint, c_ulong, c_void };

#[derive(Debug, Copy, Clone)]
pub struct Context {
    display: *mut Display
}

pub fn open_display(name: Option<&str>) -> Option<Context> {
    unsafe{
        let display = match name {
            Some(n) => {
                let s = ffi::CString::new(n).unwrap();
                xlib::XOpenDisplay(s.as_ptr())
            }
            None => { xlib::XOpenDisplay(ptr::null()) }
        };

        if display == ptr::null_mut() {
            None
        }
        else{
            // let b = Some(Box::<Display>::new(*display));
            // xlib::XFree(display as *mut libc::c_void);
            // b
            let c = Context {
                display: display,
            };
            Some(c)
        }
    }
}

pub fn close_display(context: Context) {
    unsafe{
        xlib::XCloseDisplay(context.display);
    }
}

pub fn default_screen(context: Context) -> c_int {
    unsafe{
        xlib::XDefaultScreen(context.display)
    }
}

pub fn root_window(context: Context, screen_num: c_int) -> c_ulong {
    unsafe {
        xlib::XRootWindow(context.display, screen_num)
    }
}

pub fn next_event(context: Context) -> xlib::XEvent {
    unsafe{
        let mut e: xlib::XEvent = mem::zeroed();
        xlib::XNextEvent(context.display, &mut e);
        e
    }
}

pub fn define_cursor(context: Context, window: Window, shape: c_uint) {
    unsafe {
        let cursor = xlib::XCreateFontCursor(context.display, shape);
        xlib::XDefineCursor(context.display, window, cursor);
    }
}

pub fn grab_key(context: Context, keycode: xlib::KeyCode, modifiers: c_uint, window: Window) {
    unsafe {
        xlib::XGrabKey(context.display, keycode as c_int, modifiers, window, 1, xlib::GrabModeAsync, xlib::GrabModeAsync);
    }
}

pub fn grab_button(context: Context, button: c_uint, modifiers: c_uint, window: Window) {
    unsafe {
        xlib::XGrabButton(context.display, button, modifiers, window,
                          0,
                          xlib::ButtonPressMask as c_uint,
                          xlib::GrabModeAsync, xlib::GrabModeAsync,
                          0, 0);
    }
}

pub fn ungrab_button(context: Context, button: c_uint, modifiers: c_uint, window: Window) {
    unsafe{
        xlib::XUngrabButton(context.display, button, modifiers, window);
    }
}

pub fn get_atom_name(context: Context, atom: xlib::Atom) -> Option<String> {
    unsafe{
        let name = xlib::XGetAtomName(context.display, atom);
        if name == ptr::null_mut() {
            return None
        }
        let s = ffi::CStr::from_ptr(name);
        let s = s.to_bytes();
        match str::from_utf8(s) {
            Ok(v) => {
                let tmp = Some(v.to_string());
                xlib::XFree(name as *mut libc::c_void);
                tmp
            }
            _ => None
        }
    }
}

pub fn get_atom(context: Context, name: &str) -> xlib::Atom{
    unsafe{
        let cstr = ffi::CString::new(name).unwrap();
        let atom = xlib::XInternAtom(context.display, cstr.as_ptr(), xlib::False);
        atom
    }
}

pub fn get_text_property(context: Context, window: xlib::Window, atom: xlib::Atom) -> Option<String>{
    unsafe{
        let mut prop: xlib::XTextProperty = mem::zeroed();
        let r = xlib::XGetTextProperty(context.display, window, &mut prop, atom);
        if r == 0 || prop.nitems == 0{
            None
        }else{

            // let s = String::from_raw_parts(prop.value, prop.nitems as usize, prop.nitems as usize).clone()
            let s = slice::from_raw_parts(prop.value, prop.nitems as usize).iter().map(|&c| c as u8).collect();
            match String::from_utf8(s) {
                Ok(v) => {
                    xlib::XFree(prop.value as *mut libc::c_void);
                    Some(v)
                }
                _ => None
            }
        }
    }
}

pub fn get_wm_protocols(context: Context, window: Window) -> Vec<xlib::Atom>{
    unsafe{
        let mut atoms: *mut xlib::Atom = ptr::null_mut();
        let mut count = 0;
        let s = xlib::XGetWMProtocols(context.display, window, &mut atoms, &mut count);
        let mut vec: Vec<xlib::Atom> = Vec::new();
        if s > 0 {
            vec = slice::from_raw_parts(atoms, count as usize).iter()
                .map(|&a| a as xlib::Atom).collect();
            xlib::XFree(atoms as *mut c_void);
        }
        vec
    }
}

pub fn get_window_attributes(context: Context, window: Window) -> xlib::XWindowAttributes {
    unsafe{
        let mut attrs: xlib::XWindowAttributes = mem::zeroed();
        xlib::XGetWindowAttributes(context.display, window, &mut attrs);
        attrs
    }
}

pub fn get_transient_for_hint(context: Context, window: Window) -> i32 {
    unsafe{
        let mut window_return: xlib::Window = 0;
        xlib::XGetTransientForHint(context.display, window, &mut window_return)
    }
}

pub fn change_window_attributes(context: Context, window: Window, valuemask: c_ulong, attrs: *mut xlib::XSetWindowAttributes) {
    unsafe{
        xlib::XChangeWindowAttributes(context.display, window, valuemask, attrs);
    }

}

fn get_window_property(context: Context, window: Window, atom: xlib::Atom) {
    unsafe {
        let mut actual_type_return: u64 = 0;
        let mut actual_format_return: i32 = 0;
        let mut nitem_return: libc::c_ulong = 0;
        let mut bytes_after_return: libc::c_ulong = 0;
        let mut prop_return: *mut libc::c_uchar = mem::zeroed();

        let r = xlib::XGetWindowProperty(context.display, window, xlib::XA_WM_NAME,
                                         0, 0xFFFFFFFF, 0, 0,
                                         &mut actual_type_return,
                                         &mut actual_format_return,
                                         &mut nitem_return,
                                         &mut bytes_after_return,
                                         &mut prop_return);

        debug!("result get wp {}", r);
        if r == 0 {

        }else{
            debug!("actual format return {}", actual_format_return);
            if actual_format_return == 0 {

            }
            else {
                // let s = from_raw_parts(prop_return as *const libc::c_ulong, nitems_return as usize).iter()
                //     .map(|&c| c as u64)
                //     .collect();
                let s = String::from_raw_parts(prop_return, nitem_return as usize, nitem_return as usize);
                println!("{}", s);

            }
        }
    }
}

pub fn get_top_window(context: Context, window: Window)-> Option<Window>{
    let mut w = window;
    let mut root = window;
    let mut parent = window;
    unsafe{
        while parent != root {
            w = parent;
            unsafe{
                let res = query_tree(context, w);
                match res {
                    Some((r, p, _)) => {
                        parent = p;
                        root = r;
                    }
                    None => {
                        return None
                    }
                }
            }
        }
        Some(w)
    }
}

pub fn get_children(context: Context, window: Window) -> Option<Vec<Window>> {
    let res = query_tree(context, window);
    match res {
        Some((_, _, v)) => {
            Some(v)
        }
        None => { None }
    }
}

pub fn query_tree(context: Context, window: Window) -> Option<(Window, Window, Vec<Window>)> {
    let mut root: Window = 0;
    let mut parent: Window = window;
    let mut children: *mut Window = ptr::null_mut();
    let mut nchildren: libc::c_uint = 0;
    unsafe{
        let s = xlib::XQueryTree(context.display, window, &mut root, &mut parent, &mut children, &mut nchildren);
        if s > 0 {
            let vec = slice::from_raw_parts(children,
                                            nchildren as usize).iter()
                .map(|&a| a as Window).collect();
            xlib::XFree(children as *mut libc::c_void);
            Some((root, parent, vec))
        }
        else{
            None
        }
    }

}

pub fn lookup_keysym(event: xlib::XKeyEvent, index: c_int) -> c_ulong{
    let mut e = event;
    unsafe{
        xlib::XLookupKeysym(&mut e, index)
    }
}

// pub fn loopup_string(event: xlib::XKeyEvent) -> Option<(c_ulong, String)>{
//     let mut sym: xlib::KeySym = 0;
//     let status: *mut xlib::XComposeStatus = ptr::null_mut();

//     unsafe{
//         let mut e = event;
//         xlib::XLookupString(&mut e, ptr::null_mut(), 0, &mut sym, status);
//     }

// }

pub fn set_input_focus(context: Context, window: Window) {
    let none = 0;
    let pointer_root = 1;
    let parent = 2;
    unsafe{
        let (old, _) = get_input_focus(context);
        debug!("set focus from {} to {}", old, window);
        xlib::XSetInputFocus(context.display, window, none, 0);
    }
}

pub fn get_input_focus(context: Context) -> (Window, c_int){
    let mut window: xlib::Window = 0;
    let mut revert_to: libc::c_int = 0;
    unsafe{
        let s = xlib::XGetInputFocus(context.display, &mut window, &mut revert_to);
    }
    (window, revert_to)
}

pub fn unmap_window(context: Context, window: Window) -> c_int{
    unsafe{
        xlib::XUnmapWindow(context.display, window)
    }
}

pub fn configure_window(context: Context, window: Window, mask:c_uint, mut change: xlib::XWindowChanges) {
    unsafe{
        xlib::XConfigureWindow(context.display, window, mask, &mut change);
    }
}
pub fn map_window(context: Context, window: Window) -> c_int{
    unsafe{
        xlib::XMapWindow(context.display, window)
    }
}

pub fn kill_window(context: Context, window: Window) {
    let mut event: xlib::XClientMessageEvent = unsafe {
        mem::zeroed()
    };

    let display = context.display;
    let wm_delete_window = get_atom(context, "WM_DELETE_WINDOW");
    let wm_protocols = get_atom(context, "WM_PROTOCOLS");
    let protocols = get_wm_protocols(context, window);

    if protocols.iter().any(|&p| p == wm_delete_window){
        event.type_ = xlib::ClientMessage;
        event.message_type = wm_protocols;
        event.format = 32;
        event.window = window;
        event.send_event = xlib::True;
        event.display = display;
        event.data.set_long(0, wm_delete_window as libc::c_long);

        let mut e: xlib::XEvent = From::from(event);
        send_event(context, window, xlib::True, xlib::NoEventMask, e);
    }
    else{
        unsafe{
            xlib::XKillClient(display, window);
        }
    }

}

pub fn send_event(context: Context, window: Window,
                  propagate: c_int, event_mask: c_long,
                  mut event: xlib::XEvent) {
    unsafe{
        xlib::XSendEvent(context.display, window, propagate, event_mask, &mut event);
    }
}

pub fn keysym_to_string(keysym: c_ulong) -> Option<String> {
    let mut sym: xlib::KeySym = 0;
    let status: *mut xlib::XComposeStatus = ptr::null_mut();
    unsafe{
        let s = xlib::XKeysymToString(keysym);
        let cstr = ffi::CStr::from_ptr(s);
        match str::from_utf8(cstr.to_bytes()) {
            Ok(s) => {
                Some(s.to_string())
            }
            _ => {
                None
            }
        }
    }
}

pub fn keysym_to_keycode(context: Context, keysym: xlib::KeySym) -> xlib::KeyCode {
    unsafe {
        xlib::XKeysymToKeycode(context.display, keysym)
    }
}

pub fn string_to_keysym(s: &str) -> xlib::KeySym {
    let tmp = ffi::CString::new(s).unwrap();
    unsafe{
        xlib::XStringToKeysym(tmp.as_ptr())
    }

}

pub fn select_input(context: Context, window: Window, mask: c_long) {
    unsafe{
        xlib::XSelectInput(context.display, window, mask);
    }
}

pub fn sync(context: Context, discard: c_int) {
    unsafe {
        xlib::XSync(context.display, discard);
    }
}

pub fn display_height(context: Context, screen_num: c_int) -> c_int{
    unsafe{
        xlib::XDisplayHeight(context.display, screen_num)
    }
}

pub fn display_width(context: Context, screen_num: c_int) -> c_int{
    unsafe{
        xlib::XDisplayWidth(context.display, screen_num)
    }
}

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

#[test]
fn test_open(){
    let display = open_display(None);
    assert!(display.is_some());
}

}
<|endoftext|>


<commit_before>// Copyright 2020 The Tink-Rust Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use std::{
    cell::{RefCell, RefMut},
    io,
    rc::Rc,
};

/// Possible states for a [`DecryptReader`].
enum State {
    // Matching primitive not yet determined, raw ciphertext reader available.
    Pending(Box<dyn io::Read>),
    // Matching primitive that correctly decrypts has been found.
    Found(Box<dyn io::Read>),
    // No matching primitive available.
    Failed,
}

/// `DecryptReader` is a reader that tries to find the right key to decrypt ciphertext from the
/// given primitive set.
pub(crate) struct DecryptReader {
    wrapped: crate::WrappedStreamingAead,
    aad: Vec<u8>,
    state: State,
}

impl DecryptReader {
    pub fn new(
        wrapped: crate::WrappedStreamingAead,
        reader: Box<dyn io::Read>,
        aad: &[u8],
    ) -> Self {
        Self {
            wrapped,
            aad: aad.to_vec(),
            state: State::Pending(reader),
        }
    }
}

impl io::Read for DecryptReader {
    fn read(&mut self, p: &mut [u8]) -> io::Result<usize> {
        match &mut self.state {
            State::Found(reader) => return reader.read(p),
            State::Failed => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    "no matching key found for the ciphertext in the stream",
                ))
            }
            State::Pending(_) => {}
        }
        // Move the underlying raw reader out of self and into a `SharedCopyReader`
        let state = std::mem::replace(&mut self.state, State::Failed);
        let raw_reader = match state {
            State::Pending(reader) => reader,
            _ => unreachable!(), // safe: checked above
        };
        let mut copy_reader = SharedCopyReader::new(raw_reader);

        // find proper key to decrypt ciphertext
        let entries = self.wrapped.ps.raw_entries();
        for e in &entries {
            let sa = match &e.primitive {
                tink::Primitive::StreamingAead(p) => p,
                _ => continue,
            };

            // Attempt a decrypting-read from the ciphertext reader `cr`, but also keep a copy of
            // the read data into a buffer so that it can be re-scanned with a different key if
            // decryption fails.
            let mut r = match sa.new_decrypting_reader(Box::new(copy_reader.clone()), &self.aad) {
                Ok(r) => r,
                Err(_) => {
                    copy_reader.rewind();
                    continue;
                }
            };
            let n = match r.read(p) {
                Ok(n) => n,
                Err(_) => {
                    // The read attempt will have consumed some of the underlying reader, but
                    // there is a copy of the data that has been read. Ensure that this already-read
                    // data is re-used next time around.
                    copy_reader.rewind();
                    continue;
                }
            };

            // Reading has succeeded, so use this particular key from now on and no longer need
            // to store copies of read data.
            copy_reader.stop_copying();
            self.state = State::Found(r);
            return Ok(n);
        }
        Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "no matching key found for the ciphertext in the stream",
        ))
    }
}

/// Wrapper around an [`io::Read`] trait object that stores a copy of all of the data
/// read from the underlying object.
struct CopyReader {
    reader: Box<dyn io::Read>,
    copying: bool,
    read_pos: usize,
    copied_data: Vec<u8>,
}

impl std::fmt::Debug for CopyReader {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "CopyReader {{copying={}, read_pos={}, copied_data.len()={}}}",
            self.copying,
            self.read_pos,
            self.copied_data.len(),
        )
    }
}

impl CopyReader {
    fn new(reader: Box<dyn io::Read>) -> Self {
        Self {
            reader,
            copying: true,
            read_pos: 0,
            copied_data: vec![],
        }
    }
    fn rewind(&mut self) {
        self.read_pos = 0;
    }
    fn stop_copying(&mut self) {
        self.copying = false;
        // Buffered data has been consumed, so drop it.
        self.copied_data = vec![];
        self.read_pos = 0;
    }
}

impl io::Read for CopyReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.read_pos < self.copied_data.len() {
            // Read from the buffered copy of the data.
            let available_data = self.copied_data.len() - self.read_pos;
            let n = std::cmp::min(buf.len(), available_data);
            buf[..n].copy_from_slice(&self.copied_data[self.read_pos..self.read_pos + n]);
            self.read_pos += n;
            Ok(n)
        } else {
            // Read from the underlying object
            let n = self.reader.read(buf)?;
            if self.copying {
                // Store a copy of the data read.
                self.copied_data.extend_from_slice(&buf[..n]);
                self.read_pos += n;
            }
            Ok(n)
        }
    }
}

#[derive(Clone, Debug)]
struct SharedCopyReader(Rc<RefCell<CopyReader>>);

impl SharedCopyReader {
    fn new(reader: Box<dyn io::Read>) -> Self {
        Self(Rc::new(RefCell::new(CopyReader::new(reader))))
    }
    fn rewind(&mut self) {
        let mut cr: RefMut<_> = self.0.borrow_mut();
        cr.rewind();
    }
    fn stop_copying(&mut self) {
        let mut cr: RefMut<_> = self.0.borrow_mut();
        cr.stop_copying();
    }
}

impl io::Read for SharedCopyReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut cr: RefMut<_> = self.0.borrow_mut();
        cr.read(buf)
    }
}
<commit_msg>tink-streaming-aead: drop unused Debug impl<commit_after>// Copyright 2020 The Tink-Rust Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use std::{
    cell::{RefCell, RefMut},
    io,
    rc::Rc,
};

/// Possible states for a [`DecryptReader`].
enum State {
    // Matching primitive not yet determined, raw ciphertext reader available.
    Pending(Box<dyn io::Read>),
    // Matching primitive that correctly decrypts has been found.
    Found(Box<dyn io::Read>),
    // No matching primitive available.
    Failed,
}

/// `DecryptReader` is a reader that tries to find the right key to decrypt ciphertext from the
/// given primitive set.
pub(crate) struct DecryptReader {
    wrapped: crate::WrappedStreamingAead,
    aad: Vec<u8>,
    state: State,
}

impl DecryptReader {
    pub fn new(
        wrapped: crate::WrappedStreamingAead,
        reader: Box<dyn io::Read>,
        aad: &[u8],
    ) -> Self {
        Self {
            wrapped,
            aad: aad.to_vec(),
            state: State::Pending(reader),
        }
    }
}

impl io::Read for DecryptReader {
    fn read(&mut self, p: &mut [u8]) -> io::Result<usize> {
        match &mut self.state {
            State::Found(reader) => return reader.read(p),
            State::Failed => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    "no matching key found for the ciphertext in the stream",
                ))
            }
            State::Pending(_) => {}
        }
        // Move the underlying raw reader out of self and into a `SharedCopyReader`
        let state = std::mem::replace(&mut self.state, State::Failed);
        let raw_reader = match state {
            State::Pending(reader) => reader,
            _ => unreachable!(), // safe: checked above
        };
        let mut copy_reader = SharedCopyReader::new(raw_reader);

        // find proper key to decrypt ciphertext
        let entries = self.wrapped.ps.raw_entries();
        for e in &entries {
            let sa = match &e.primitive {
                tink::Primitive::StreamingAead(p) => p,
                _ => continue,
            };

            // Attempt a decrypting-read from the ciphertext reader `cr`, but also keep a copy of
            // the read data into a buffer so that it can be re-scanned with a different key if
            // decryption fails.
            let mut r = match sa.new_decrypting_reader(Box::new(copy_reader.clone()), &self.aad) {
                Ok(r) => r,
                Err(_) => {
                    copy_reader.rewind();
                    continue;
                }
            };
            let n = match r.read(p) {
                Ok(n) => n,
                Err(_) => {
                    // The read attempt will have consumed some of the underlying reader, but
                    // there is a copy of the data that has been read. Ensure that this already-read
                    // data is re-used next time around.
                    copy_reader.rewind();
                    continue;
                }
            };

            // Reading has succeeded, so use this particular key from now on and no longer need
            // to store copies of read data.
            copy_reader.stop_copying();
            self.state = State::Found(r);
            return Ok(n);
        }
        Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "no matching key found for the ciphertext in the stream",
        ))
    }
}

/// Wrapper around an [`io::Read`] trait object that stores a copy of all of the data
/// read from the underlying object.
struct CopyReader {
    reader: Box<dyn io::Read>,
    copying: bool,
    read_pos: usize,
    copied_data: Vec<u8>,
}

impl CopyReader {
    fn new(reader: Box<dyn io::Read>) -> Self {
        Self {
            reader,
            copying: true,
            read_pos: 0,
            copied_data: vec![],
        }
    }
    fn rewind(&mut self) {
        self.read_pos = 0;
    }
    fn stop_copying(&mut self) {
        self.copying = false;
        // Buffered data has been consumed, so drop it.
        self.copied_data = vec![];
        self.read_pos = 0;
    }
}

impl io::Read for CopyReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.read_pos < self.copied_data.len() {
            // Read from the buffered copy of the data.
            let available_data = self.copied_data.len() - self.read_pos;
            let n = std::cmp::min(buf.len(), available_data);
            buf[..n].copy_from_slice(&self.copied_data[self.read_pos..self.read_pos + n]);
            self.read_pos += n;
            Ok(n)
        } else {
            // Read from the underlying object
            let n = self.reader.read(buf)?;
            if self.copying {
                // Store a copy of the data read.
                self.copied_data.extend_from_slice(&buf[..n]);
                self.read_pos += n;
            }
            Ok(n)
        }
    }
}

#[derive(Clone)]
struct SharedCopyReader(Rc<RefCell<CopyReader>>);

impl SharedCopyReader {
    fn new(reader: Box<dyn io::Read>) -> Self {
        Self(Rc::new(RefCell::new(CopyReader::new(reader))))
    }
    fn rewind(&mut self) {
        let mut cr: RefMut<_> = self.0.borrow_mut();
        cr.rewind();
    }
    fn stop_copying(&mut self) {
        let mut cr: RefMut<_> = self.0.borrow_mut();
        cr.stop_copying();
    }
}

impl io::Read for SharedCopyReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut cr: RefMut<_> = self.0.borrow_mut();
        cr.read(buf)
    }
}
<|endoftext|>


<commit_before>
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::Fallible;
use dom::bindings::codegen::CanvasRenderingContext2DBinding;
use dom::window::Window;
use js::jsapi::{JSContext, JSObject};
use dom::bindings::utils::{ErrorResult};

pub struct CanvasRenderingContext2D {
    reflector_: Reflector,
    window: @mut Window,
}

impl CanvasRenderingContext2D {
    pub fn new_inherited(window: @mut Window) -> CanvasRenderingContext2D {
        CanvasRenderingContext2D {
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: @mut Window) -> @mut CanvasRenderingContext2D {
        reflect_dom_object(@mut CanvasRenderingContext2D::new_inherited(window), window, CanvasRenderingContext2DBinding::Wrap)
    }

 pub fn Width(&self) -> u32 {
        0
    }

    pub fn SetWidth(&mut self, _width: u32) -> ErrorResult {
        Ok(())
    }

    pub fn Height(&self) -> u32 {
        0
    }

    pub fn SetHeight(&mut self, _height: u32) -> ErrorResult {
        Ok(())
    }

}

impl CanvasRenderingContext2D {
    pub fn Constructor(window: @mut Window) -> Fallible<@mut CanvasRenderingContext2D> {
        Ok(CanvasRenderingContext2D::new(window))
    }
}

impl Reflectable for CanvasRenderingContext2D {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }

    fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
        unreachable!();
    }

    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> {
        Some(self.window as @mut Reflectable)
    }

}
<commit_msg>Update canvasrenderingcontext2d.rs<commit_after>use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::Fallible;
use dom::bindings::codegen::CanvasRenderingContext2DBinding;
use dom::window::Window;
use js::jsapi::{JSContext, JSObject};
use dom::bindings::utils::{ErrorResult};

pub struct CanvasRenderingContext2D {                           //struct containing Reflector object.
    reflector_: Reflector,
    window: @mut Window,
}

impl CanvasRenderingContext2D {                                 //CanvasRenderingContext2D interface.
    pub fn new_inherited(window: @mut Window) -> CanvasRenderingContext2D {
        CanvasRenderingContext2D {
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: @mut Window) -> @mut CanvasRenderingContext2D {
        reflect_dom_object(@mut CanvasRenderingContext2D::new_inherited(window), window, CanvasRenderingContext2DBinding::Wrap)
    }

 pub fn Width(&self) -> u32 {                    //Width of the canvas
        0
    }

    pub fn SetWidth(&mut self, _width: u32) -> ErrorResult {
        Ok(())
    }

    pub fn Height(&self) -> u32 {                 //Height of the canvas
        0
    }

    pub fn SetHeight(&mut self, _height: u32) -> ErrorResult {
        Ok(())
    }

}

impl CanvasRenderingContext2D {
    pub fn Constructor(window: @mut Window) -> Fallible<@mut CanvasRenderingContext2D> {
        Ok(CanvasRenderingContext2D::new(window))
    }
}

impl Reflectable for CanvasRenderingContext2D {           //implementing the Reflectable.
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }

    fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
        unreachable!();
    }

    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> {
        Some(self.window as @mut Reflectable)
    }

}
<|endoftext|>


<commit_before>//! A module to match and filter Request and Response events

use log_parser::*;

#[derive(Clone)]
#[derive(Debug)]
pub struct RequestResponsePair {
    pub request: log_events::Request,
    pub response: log_events::Response,
}

pub fn extract_matching_request_response_pairs(requests: &mut Vec<log_events::Request>,
                                               responses: &mut Vec<log_events::Response>)
                                               -> Vec<RequestResponsePair> {
    let mut request_response_pairs: Vec<RequestResponsePair> = Vec::new();

    for request_index in 0..requests.len() {
        {
            let request = requests.get(request_index);

            if request.is_none() {
                continue;
            }
        }

        let matching_response_index: Option<usize> = responses.iter()
            .position(|response| requests[request_index].id == response.id);

        if matching_response_index.is_some() {
            let request = requests.remove(request_index);
            let response = responses.remove(matching_response_index.unwrap());

            let pair = RequestResponsePair {
                request: request,
                response: response,
            };

            request_response_pairs.push(pair);
        }
    }

    request_response_pairs
}

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

    #[test]
    fn test_extract_matching_request_response_pairs() {
        let mut requests = vec![log_parser::log_events::Request {
                                    id: 1,
                                    time: DateTime::parse_from_str("08/Apr/2016:09:57:47 +0200",
                                                                   "%d/%b/%Y:%H:%M:%S %z")
                                        .unwrap(),
                                    original_log_line: "whatever".to_string(),
                                },
                                log_parser::log_events::Request {
                                    id: 77,
                                    time: DateTime::parse_from_str("08/Apr/2016:09:57:47 +0200",
                                                                   "%d/%b/%Y:%H:%M:%S %z")
                                        .unwrap(),
                                    original_log_line: "whatever".to_string(),
                                }];

        let mut responses = vec![log_parser::log_events::Response {
                                     id: 1,
                                     response_time: Duration::milliseconds(7),
                                     original_log_line: "whatever".to_string(),
                                 },
                                 log_parser::log_events::Response {
                                     id: 99,
                                     response_time: Duration::milliseconds(10),
                                     original_log_line: "whatever".to_string(),
                                 }];

        let result = extract_matching_request_response_pairs(&mut requests, &mut responses);

        assert_eq!(result.len(), 1);
        assert_eq!(result[0].request.id, 1);
        assert_eq!(result[0].response.id, 1);

        assert_eq!(requests.len(), 1);
        assert_eq!(responses.len(), 1);
    }
}
<commit_msg>Remove unneeded doc comment<commit_after>use log_parser::*;

#[derive(Clone)]
#[derive(Debug)]
pub struct RequestResponsePair {
    pub request: log_events::Request,
    pub response: log_events::Response,
}

pub fn extract_matching_request_response_pairs(requests: &mut Vec<log_events::Request>,
                                               responses: &mut Vec<log_events::Response>)
                                               -> Vec<RequestResponsePair> {
    let mut request_response_pairs: Vec<RequestResponsePair> = Vec::new();

    for request_index in 0..requests.len() {
        {
            let request = requests.get(request_index);

            if request.is_none() {
                continue;
            }
        }

        let matching_response_index: Option<usize> = responses.iter()
            .position(|response| requests[request_index].id == response.id);

        if matching_response_index.is_some() {
            let request = requests.remove(request_index);
            let response = responses.remove(matching_response_index.unwrap());

            let pair = RequestResponsePair {
                request: request,
                response: response,
            };

            request_response_pairs.push(pair);
        }
    }

    request_response_pairs
}

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

    #[test]
    fn test_extract_matching_request_response_pairs() {
        let mut requests = vec![log_parser::log_events::Request {
                                    id: 1,
                                    time: DateTime::parse_from_str("08/Apr/2016:09:57:47 +0200",
                                                                   "%d/%b/%Y:%H:%M:%S %z")
                                        .unwrap(),
                                    original_log_line: "whatever".to_string(),
                                },
                                log_parser::log_events::Request {
                                    id: 77,
                                    time: DateTime::parse_from_str("08/Apr/2016:09:57:47 +0200",
                                                                   "%d/%b/%Y:%H:%M:%S %z")
                                        .unwrap(),
                                    original_log_line: "whatever".to_string(),
                                }];

        let mut responses = vec![log_parser::log_events::Response {
                                     id: 1,
                                     response_time: Duration::milliseconds(7),
                                     original_log_line: "whatever".to_string(),
                                 },
                                 log_parser::log_events::Response {
                                     id: 99,
                                     response_time: Duration::milliseconds(10),
                                     original_log_line: "whatever".to_string(),
                                 }];

        let result = extract_matching_request_response_pairs(&mut requests, &mut responses);

        assert_eq!(result.len(), 1);
        assert_eq!(result[0].request.id, 1);
        assert_eq!(result[0].response.id, 1);

        assert_eq!(requests.len(), 1);
        assert_eq!(responses.len(), 1);
    }
}
<|endoftext|>


<commit_before>use std::cell::Cell;

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ProducerState {
    Started,
    Closed,
}

pub struct Producer {
    func: Box<Fn(ProducerState)>,
    state: Cell<ProducerState>,
}

impl Producer {
    pub fn from_func(func: Box<Fn(ProducerState)>) -> Producer {
        Producer {
            func: func,
            state: Cell::new(ProducerState::Started),
        }
    }

    pub fn new() -> Producer {
        Producer::from_func(Box::new(|_| {}))
    }

    pub fn is_closed(&self) -> bool {
        self.state.get() == ProducerState::Closed
    }

    pub fn close(&self) {
        self.state.set(ProducerState::Closed);
        (self.func)(ProducerState::Closed);
    }
}
<commit_msg>prevent close being invoked multiple time.<commit_after>use std::cell::Cell;

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ProducerState {
    Started,
    Closed,
}

pub struct Producer {
    func: Box<Fn(ProducerState)>,
    state: Cell<ProducerState>,
}

impl Producer {
    pub fn from_func(func: Box<Fn(ProducerState)>) -> Producer {
        Producer {
            func: func,
            state: Cell::new(ProducerState::Started),
        }
    }

    pub fn new() -> Producer {
        Producer::from_func(Box::new(|_| {}))
    }

    pub fn is_closed(&self) -> bool {
        self.state.get() == ProducerState::Closed
    }

    pub fn close(&self) {
        if self.state.get() == ProducerState::Started {
            self.state.set(ProducerState::Closed);
            (self.func)(ProducerState::Closed);
        }
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use std::ops::Index;
use std::ops::IndexMut;
use handle::*;

pub struct Property<H,D> {
    type_ : PhantomData<H>,
    data_ : Vec<D>,
}

impl<T,D> Index<Handle<T> > for Property<Handle<T>,D> {
    type Output = D;

    fn index<'a>(&'a self, _index: Handle<T>) -> &'a D {
        return & self.data_[_index.idx().unwrap()];
    }
}

impl<T,D> IndexMut<Handle<T> > for Property<Handle<T> ,D> {
    fn index_mut<'a>(&'a mut self, _index: Handle<T>) -> &'a mut D {
        return &mut self.data_[_index.idx().unwrap()];
    }
}

impl<H, D : Clone> Property<H,D> {
    pub fn new() -> Property<H,D>{
        Property {
            type_ : PhantomData,
            data_ : Vec::new()
        }
    }

    pub fn reserve(&mut self, size : usize) {
        self.data_.reserve(size);
    }

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

    pub fn resize(&mut self, size : usize, value : D) {
        let n = self.data_.len();
        if n < size {
            self.data_.reserve(size);
            let m = size-n;
            for _ in 0..m {
                self.data_.push(value.clone());
            }
        } else {
            let m = n-size;
            for _ in 0..m {
                self.data_.pop();
            }
        }
    }

    pub fn len(&self) -> usize() {
        self.data_.len()
    }
}

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

    #[test]
    fn reserve() {
        let mut property = Property::<Vertex,u32>::new();
        let cap = 16;
        property.reserve(cap);
        assert!(cap == property.capacity());
    }

    #[test]
    fn resize() {
        let mut property = Property::<Vertex,u32>::new();
        let size = 5;
        let val = 42;
        property.resize(size,val);
        assert!(property.len() == size);
        property.resize(size-3,val);
        assert!(property.len() == size-3);
    }

    #[test]
    fn index() {
        let mut property = Property::new();
        let size = 8;
        let val = 42;
        property.resize(size,val);
        let v1 = Vertex::new(3);
        assert!(property[v1] == 42);
        property[v1] = 23;
        assert!(property[v1] == 23);

        let ref property_const = & property;
        let v2 = Vertex::new(0);
        assert!(property_const[v2] == 42);
    }

    #[test]
    #[should_panic]
    fn index_out_of_bound() {
        let mut property = Property::new();
        let size = 8;
        let val = 42;
        property.resize(size,val);
        let v1 = Vertex::new(8);
        property[v1] = 0;
    }

    #[test]
    #[should_panic]
    fn index_none() {
        let mut property = Property::new();
        let size = 8;
        let val = 42;
        property.resize(size,val);
        let v1 = Vertex::invalid();
        property[v1] = 0;
    }
}
<commit_msg>property : corrects the reserve test + documentation<commit_after>use std::marker::PhantomData;
use std::ops::Index;
use std::ops::IndexMut;
use handle::*;

/// A growable list type, to store data for the different `Handle`.
///
/// `H` is the type of the Handle to acces the data. `D` is the type the data.
pub struct Property<H,D> {
    type_ : PhantomData<H>,
    data_ : Vec<D>,
}

impl<H, D : Clone> Property<H,D> {

    /// Constructs a new `Property<H,D>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::property::Property;
    /// use lwmesh::handle::Vertex;
    ///
    /// let prop = Property::<Vertex,u32>::new();
    /// ```
    pub fn new() -> Property<H,D>{
        Property {
            type_ : PhantomData,
            data_ : Vec::new()
        }
    }

    /// Reserve the minimun capacity to store at least `size` elements in the given `Property<H,D>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::property::Property;
    /// use lwmesh::handle::Vertex;
    ///
    /// let mut prop = Property::<Vertex,u32>::new();
    /// prop.reserve(42);
    /// assert!(prop.capacity() >= 42);
    /// ```
    pub fn reserve(&mut self, size : usize) {
        self.data_.reserve(size);
    }

    /// Returns the number of elements the given `Property<H,D>` can hold without reallocating.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::property::Property;
    /// use lwmesh::handle::Vertex;
    ///
    /// let mut prop = Property::<Vertex,u32>::new();
    /// assert!(prop.capacity() == 0);
    /// prop.reserve(42);
    /// assert!(prop.capacity() >= 42);
    /// ```
    pub fn capacity(& self) -> usize {
        self.data_.capacity()
    }

    /// Resize the given `Property<H,D>` to have exactly `size` elements.
    ///
    /// If the actual size of the property is less than `size`, elements with value `value` are
    /// added to the property so that the size matches. Otherwise elements are removed from the
    /// vector until the size matches.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::property::Property;
    /// use lwmesh::handle::Vertex;
    ///
    /// let mut prop = Property::<Vertex,u32>::new();
    /// prop.resize(13,17);
    /// ```
    pub fn resize(&mut self, size : usize, value : D) {
        let n = self.data_.len();
        if n < size {
            self.data_.reserve(size);
            let m = size-n;
            for _ in 0..m {
                self.data_.push(value.clone());
            }
        } else {
            let m = n-size;
            for _ in 0..m {
                self.data_.pop();
            }
        }
    }

    /// Returns the number of elements in the `Property<H,D>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::property::Property;
    /// use lwmesh::handle::Vertex;
    ///
    /// let mut prop = Property::<Vertex,u32>::new();
    /// assert!(prop.len() == 0);
    /// prop.resize(13,17);
    /// assert!(prop.len() == 13)
    /// ```
    pub fn len(&self) -> usize() {
        self.data_.len()
    }
}

impl<T,D> Index<Handle<T> > for Property<Handle<T>,D> {
    type Output = D;

    fn index<'a>(&'a self, _index: Handle<T>) -> &'a D {
        return & self.data_[_index.idx().unwrap()];
    }
}

impl<T,D> IndexMut<Handle<T> > for Property<Handle<T> ,D> {
    fn index_mut<'a>(&'a mut self, _index: Handle<T>) -> &'a mut D {
        return &mut self.data_[_index.idx().unwrap()];
    }
}

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

    #[test]
    fn reserve() {
        let mut property = Property::<Vertex,u32>::new();
        property.reserve(16);
        assert!(16 <= property.capacity());
        property.reserve(33);
        assert!(33 <= property.capacity());
    }

    #[test]
    fn resize() {
        let mut property = Property::<Vertex,u32>::new();
        let size = 5;
        let val = 42;
        property.resize(size,val);
        assert!(property.len() == size);
        property.resize(size-3,val);
        assert!(property.len() == size-3);
    }

    #[test]
    fn index() {
        let mut property = Property::new();
        let size = 8;
        let val = 42;
        property.resize(size,val);
        let v1 = Vertex::new(3);
        assert!(property[v1] == 42);
        property[v1] = 23;
        assert!(property[v1] == 23);

        let ref property_const = & property;
        let v2 = Vertex::new(0);
        assert!(property_const[v2] == 42);
    }

    #[test]
    #[should_panic]
    fn index_out_of_bound() {
        let mut property = Property::new();
        let size = 8;
        let val = 42;
        property.resize(size,val);
        let v1 = Vertex::new(8);
        property[v1] = 0;
    }

    #[test]
    #[should_panic]
    fn index_none() {
        let mut property = Property::new();
        let size = 8;
        let val = 42;
        property.resize(size,val);
        let v1 = Vertex::invalid();
        property[v1] = 0;
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Sorting_algorithms/Heapsort

/// This is ported from the Dart heap sort implementation
fn heap_sort<T: Ord>(a: &mut [T]) {
    let count = a.len();

    if count == 0 {
        return;
    }

    // first place 'a' in max-heap order
    heapify(a, count);

    let mut end = count - 1;
    while end > 0 {
        // swap the root (maximum value) of the heap with the
        // last element of the heap
        a.swap(0, end);

        // put the heap back in max-heap order
        sift_down(a, 0, end - 1);

        // decrement the size of the heap so that the previous
        // max value will stay in its proper place
        end -= 1;
    }
}

fn heapify<T: Ord>(a: &mut [T], count: usize) {
    if count < 2 {
        return;
    }

    // start is assigned the index in 'a' of the last parent node
    let mut start: i32 = count as i32 - 2 / 2; // binary heap

    while start >= 0 {
        // sift down the node at index 'start' to the proper place
        // such that all nodes below the 'start' index are in heap order
        sift_down(a, start as usize, count - 1);
        start -= 1;
    }
}

fn sift_down<T: Ord>(a: &mut [T], start: usize, end: usize) {
    // end represents the limit of how far down the heap to shift
    let mut root = start;

    // while the root has at least one child
    while (root * 2 + 1) <= end {
        // root*2+1 points to the left child
        let mut child: usize = root * 2 + 1 as usize;

        // if the chile has a sibling and the child's value is less that its sibling's...
        if child + 1 <= end && a[child] < a[child + 1] {
            // .. then point to the right child instead
            child = child + 1;
        }

        // out of max-heap order
        if a[root] < a[child] {
            a.swap(root, child);
            // repeat to continue shifting down the child now
            root = child;
        } else {
            return;
        }
    }
}

pub fn main() {
    let mut arr = [1i32, 5, 2, 7, 3, 9, 4, 6, 8];
    heap_sort(&mut arr);
    println!("After sort: {:?}", arr);

    let mut arr = [1i32, 2, 3, 4, 5, 6, 7, 8, 9];
    heap_sort(&mut arr);
    println!("After sort: {:?}", arr);

    let mut arr = [9i32, 8, 7, 6, 5, 4, 3, 2, 1];
    heap_sort(&mut arr);
    println!("After sort: {:?}", arr);
}

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

    #[test]
    fn sorted() {
        let mut arr = [1i32, 2, 3, 4, 6, 8];
        heap_sort(&mut arr);
        assert_eq!(arr, [1i32, 2, 3, 4, 6, 8]);
    }

    #[test]
    fn reverse() {
        let mut arr = [8i32, 6, 4, 3, 2, 1];
        heap_sort(&mut arr);
        assert_eq!(arr, [1i32, 2, 3, 4, 6, 8]);
    }

    #[test]
    fn random() {
        let mut arr = [12i32, 54, 2, 93, 13, 43, 15, 299, 234];
        heap_sort(&mut arr);
        assert_eq!(arr, [2i32, 12, 13, 15, 43, 54, 93, 234, 299]);
    }

    #[test]
    fn one() {
        let mut arr = [9i32];
        heap_sort(&mut arr);
        assert_eq!(arr, [9i32]);
    }

    #[test]
    fn empty() {
        let mut arr: [i32; 0] = [];
        heap_sort(&mut arr);
        assert!(arr.is_empty());
    }
}
<commit_msg>fix equal expressions used by division operator<commit_after>// http://rosettacode.org/wiki/Sorting_algorithms/Heapsort

/// This is ported from the Dart heap sort implementation
fn heap_sort<T: Ord>(a: &mut [T]) {
    let count = a.len();

    if count == 0 {
        return;
    }

    // first place 'a' in max-heap order
    heapify(a, count);

    let mut end = count - 1;
    while end > 0 {
        // swap the root (maximum value) of the heap with the
        // last element of the heap
        a.swap(0, end);

        // put the heap back in max-heap order
        sift_down(a, 0, end - 1);

        // decrement the size of the heap so that the previous
        // max value will stay in its proper place
        end -= 1;
    }
}

fn heapify<T: Ord>(a: &mut [T], count: usize) {
    if count < 2 {
        return;
    }

    // start is assigned the index in 'a' of the last parent node
    let mut start: i32 = (count as i32 - 2) / 2; // binary heap

    while start >= 0 {
        // sift down the node at index 'start' to the proper place
        // such that all nodes below the 'start' index are in heap order
        sift_down(a, start as usize, count - 1);
        start -= 1;
    }
}

fn sift_down<T: Ord>(a: &mut [T], start: usize, end: usize) {
    // end represents the limit of how far down the heap to shift
    let mut root = start;

    // while the root has at least one child
    while (root * 2 + 1) <= end {
        // root*2+1 points to the left child
        let mut child: usize = root * 2 + 1 as usize;

        // if the chile has a sibling and the child's value is less that its sibling's...
        if child + 1 <= end && a[child] < a[child + 1] {
            // .. then point to the right child instead
            child = child + 1;
        }

        // out of max-heap order
        if a[root] < a[child] {
            a.swap(root, child);
            // repeat to continue shifting down the child now
            root = child;
        } else {
            return;
        }
    }
}

pub fn main() {
    let mut arr = [1i32, 5, 2, 7, 3, 9, 4, 6, 8];
    heap_sort(&mut arr);
    println!("After sort: {:?}", arr);

    let mut arr = [1i32, 2, 3, 4, 5, 6, 7, 8, 9];
    heap_sort(&mut arr);
    println!("After sort: {:?}", arr);

    let mut arr = [9i32, 8, 7, 6, 5, 4, 3, 2, 1];
    heap_sort(&mut arr);
    println!("After sort: {:?}", arr);
}

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

    #[test]
    fn sorted() {
        let mut arr = [1i32, 2, 3, 4, 6, 8];
        heap_sort(&mut arr);
        assert_eq!(arr, [1i32, 2, 3, 4, 6, 8]);
    }

    #[test]
    fn reverse() {
        let mut arr = [8i32, 6, 4, 3, 2, 1];
        heap_sort(&mut arr);
        assert_eq!(arr, [1i32, 2, 3, 4, 6, 8]);
    }

    #[test]
    fn random() {
        let mut arr = [12i32, 54, 2, 93, 13, 43, 15, 299, 234];
        heap_sort(&mut arr);
        assert_eq!(arr, [2i32, 12, 13, 15, 43, 54, 93, 234, 299]);
    }

    #[test]
    fn one() {
        let mut arr = [9i32];
        heap_sort(&mut arr);
        assert_eq!(arr, [9i32]);
    }

    #[test]
    fn empty() {
        let mut arr: [i32; 0] = [];
        heap_sort(&mut arr);
        assert!(arr.is_empty());
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::net::{UnixDatagram, UnixStream};

use libc::{nfds_t, pollfd, poll, POLLIN};

use {Result, errno_result};

/// Trait for file descriptors that can be polled for input.
///
/// This is marked unsafe because the implementation must promise that the returned RawFd is valid
/// for polling purposes and that the lifetime of the returned fd is at least that of the trait
/// object.
pub unsafe trait Pollable {
    /// Gets the file descriptor that can be polled for input.
    fn pollable_fd(&self) -> RawFd;
}

unsafe impl Pollable for UnixStream {
    fn pollable_fd(&self) -> RawFd {
        self.as_raw_fd()
    }
}

unsafe impl Pollable for UnixDatagram {
    fn pollable_fd(&self) -> RawFd {
        self.as_raw_fd()
    }
}

/// Used to poll multiple `Pollable` objects at once.
///
/// # Example
///
/// ```
/// # use sys_util::{Result, EventFd, Poller, Pollable};
/// # fn test() -> Result<()> {
///     let evt1 = EventFd::new()?;
///     let evt2 = EventFd::new()?;
///     evt2.write(1)?;
///
///     let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];
///
///     let mut poller = Poller::new(2);
///     assert_eq!(poller.poll(&pollables[..]), Ok([2].as_ref()));
/// #   Ok(())
/// # }
/// ```
pub struct Poller {
    pollfds: Vec<pollfd>,
    tokens: Vec<u32>,
}

impl Poller {
    /// Constructs a new poller object with the given `capacity` of Pollable objects pre-allocated.
    pub fn new(capacity: usize) -> Poller {
        Poller {
            pollfds: Vec::with_capacity(capacity),
            tokens: Vec::with_capacity(capacity),
        }
    }

    /// Waits for any of the given slice of `token`-`Pollable` tuples to be readable without
    /// blocking and returns the `token` of each that is readable.
    ///
    /// This is guaranteed to not allocate if `pollables.len()` is less than the `capacity` given in
    /// `Poller::new`.
    pub fn poll(&mut self, pollables: &[(u32, &Pollable)]) -> Result<&[u32]> {
        self.pollfds.clear();
        for pollable in pollables.iter() {
            self.pollfds
                .push(pollfd {
                          fd: pollable.1.pollable_fd(),
                          events: POLLIN,
                          revents: 0,
                      });
        }

        // Safe because poll is given the correct length of properly initialized pollfds, and we
        // check the return result.
        let ret = unsafe {
            handle_eintr!(poll(self.pollfds.as_mut_ptr(),
                       self.pollfds.len() as nfds_t,
                       -1))
        };
        if ret < 0 {
            return errno_result();
        }

        self.tokens.clear();
        for (pollfd, pollable) in self.pollfds.iter().zip(pollables.iter()) {
            if (pollfd.revents & POLLIN) != 0 {
                self.tokens.push(pollable.0);
            }
        }

        Ok(&self.tokens)
    }
}

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

    #[test]
    fn poller() {
        let evt1 = EventFd::new().unwrap();
        let evt2 = EventFd::new().unwrap();
        evt2.write(1).unwrap();

        let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];

        let mut poller = Poller::new(2);
        assert_eq!(poller.poll(&pollables[..]), Ok([2].as_ref()));
    }

    #[test]
    fn poller_multi() {
        let evt1 = EventFd::new().unwrap();
        let evt2 = EventFd::new().unwrap();
        evt1.write(1).unwrap();
        evt2.write(1).unwrap();

        let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];

        let mut poller = Poller::new(2);
        assert_eq!(poller.poll(&pollables[..]), Ok([1, 2].as_ref()));
    }
}
<commit_msg>sys_util: add timeout support to Poller<commit_after>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::i64;
use std::time::Duration;
use std::ptr::null;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::net::{UnixDatagram, UnixStream};

use libc::{c_int, c_long, timespec, time_t, nfds_t, sigset_t, pollfd, syscall, SYS_ppoll, POLLIN};

use {Result, errno_result};

// The libc wrapper suppresses the kernel's changes to timeout, so we use the syscall directly.
unsafe fn ppoll(fds: *mut pollfd,
                nfds: nfds_t,
                timeout: *mut timespec,
                sigmask: *const sigset_t,
                sigsetsize: usize)
                -> c_int {
    syscall(SYS_ppoll, fds, nfds, timeout, sigmask, sigsetsize) as c_int
}

/// Trait for file descriptors that can be polled for input.
///
/// This is marked unsafe because the implementation must promise that the returned RawFd is valid
/// for polling purposes and that the lifetime of the returned fd is at least that of the trait
/// object.
pub unsafe trait Pollable {
    /// Gets the file descriptor that can be polled for input.
    fn pollable_fd(&self) -> RawFd;
}

unsafe impl Pollable for UnixStream {
    fn pollable_fd(&self) -> RawFd {
        self.as_raw_fd()
    }
}

unsafe impl Pollable for UnixDatagram {
    fn pollable_fd(&self) -> RawFd {
        self.as_raw_fd()
    }
}

/// Used to poll multiple `Pollable` objects at once.
///
/// # Example
///
/// ```
/// # use sys_util::{Result, EventFd, Poller, Pollable};
/// # fn test() -> Result<()> {
///     let evt1 = EventFd::new()?;
///     let evt2 = EventFd::new()?;
///     evt2.write(1)?;
///
///     let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];
///
///     let mut poller = Poller::new(2);
///     assert_eq!(poller.poll(&pollables[..]), Ok([2].as_ref()));
/// #   Ok(())
/// # }
/// ```
pub struct Poller {
    pollfds: Vec<pollfd>,
    tokens: Vec<u32>,
}

impl Poller {
    /// Constructs a new poller object with the given `capacity` of Pollable objects pre-allocated.
    pub fn new(capacity: usize) -> Poller {
        Poller {
            pollfds: Vec::with_capacity(capacity),
            tokens: Vec::with_capacity(capacity),
        }
    }

    /// Waits for any of the given slice of `token`-`Pollable` tuples to be readable without
    /// blocking and returns the `token` of each that is readable.
    ///
    /// This is guaranteed to not allocate if `pollables.len()` is less than the `capacity` given in
    /// `Poller::new`.
    pub fn poll(&mut self, pollables: &[(u32, &Pollable)]) -> Result<&[u32]> {
        self.poll_timeout(pollables, &mut Duration::new(i64::MAX as u64, 0))
    }

    /// Waits for up to the given timeout for any of the given slice of `token`-`Pollable` tuples to
    /// be readable without blocking and returns the `token` of each that is readable.
    ///
    /// If a timeout duration is given, the duration will be modified to the unused portion of the
    /// timeout, even if an error is returned.
    ///
    /// This is guaranteed to not allocate if `pollables.len()` is less than the `capacity` given in
    /// `Poller::new`.
    pub fn poll_timeout(&mut self,
                        pollables: &[(u32, &Pollable)],
                        timeout: &mut Duration)
                        -> Result<&[u32]> {
        self.pollfds.clear();
        for pollable in pollables.iter() {
            self.pollfds
                .push(pollfd {
                          fd: pollable.1.pollable_fd(),
                          events: POLLIN,
                          revents: 0,
                      });
        }

        let mut timeout_spec = timespec {
            tv_sec: timeout.as_secs() as time_t,
            tv_nsec: timeout.subsec_nanos() as c_long,
        };

        // Safe because poll is given the correct length of properly initialized pollfds, and we
        // check the return result.
        let ret = unsafe {
            handle_eintr!(ppoll(self.pollfds.as_mut_ptr(),
                                self.pollfds.len() as nfds_t,
                                &mut timeout_spec,
                                null(),
                                0))
        };

        *timeout = Duration::new(timeout_spec.tv_sec as u64, timeout_spec.tv_nsec as u32);

        if ret < 0 {
            return errno_result();
        }

        self.tokens.clear();
        for (pollfd, pollable) in self.pollfds.iter().zip(pollables.iter()) {
            if (pollfd.revents & POLLIN) != 0 {
                self.tokens.push(pollable.0);
            }
        }

        Ok(&self.tokens)
    }
}

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

    #[test]
    fn poller() {
        let evt1 = EventFd::new().unwrap();
        let evt2 = EventFd::new().unwrap();
        evt2.write(1).unwrap();

        let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];

        let mut poller = Poller::new(2);
        assert_eq!(poller.poll(&pollables[..]), Ok([2].as_ref()));
    }

    #[test]
    fn poller_multi() {
        let evt1 = EventFd::new().unwrap();
        let evt2 = EventFd::new().unwrap();
        evt1.write(1).unwrap();
        evt2.write(1).unwrap();

        let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];

        let mut poller = Poller::new(2);
        assert_eq!(poller.poll(&pollables[..]), Ok([1, 2].as_ref()));
    }

    #[test]
    fn timeout() {
        let evt1 = EventFd::new().unwrap();
        let initial_dur = Duration::from_millis(10);
        let mut timeout_dur = initial_dur;
        let mut poller = Poller::new(0);
        assert_eq!(poller.poll_timeout(&[(1, &evt1)], &mut timeout_dur),
                   Ok([].as_ref()));
        assert_eq!(timeout_dur, Duration::from_secs(0));
        evt1.write(1).unwrap();
        timeout_dur = initial_dur;
        assert_eq!(poller.poll_timeout(&[(1, &evt1)], &mut timeout_dur),
                   Ok([1].as_ref()));
        assert!(timeout_dur < initial_dur);
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/RSA_code
extern crate num;

use num::bigint::BigUint;
use num::traits::{Zero, One};
use num::integer::Integer;
#[cfg(not(test))]
use std::str::FromStr;

fn mod_exp(b: &BigUint, e: &BigUint, n: &BigUint) -> Result<BigUint, &'static str> {
    if n.is_zero() {
        return Err("modulus is zero");
    }
    if b >= n {
        // base is too large and should be split into blocks
        return Err("base is >= modulus");
    }
    if b.gcd(n) != BigUint::one() {
        return Err("base and modulus are not relatively prime");
    }

    let mut bb = b.clone();
    let mut ee = e.clone();
    let mut result = BigUint::one();
    while !ee.is_zero() {
        if ee.is_odd() {
            result = (result * &bb) % n;
        }
        ee = ee >> 1;
        bb = (&bb * &bb) % n;
    }
    Ok(result)
}

#[cfg(not(test))]
fn main() {
    let msg = "Rosetta Code";

    let n = BigUint::from_str("9516311845790656153499716760847001433441357").unwrap();
    let e = BigUint::from_str("65537").unwrap();
    let d = BigUint::from_str("5617843187844953170308463622230283376298685").unwrap();

    let msg_int = BigUint::from_bytes_be(msg.as_bytes());
    let enc = mod_exp(&msg_int, &e, &n).unwrap();
    let dec = mod_exp(&enc, &d, &n).unwrap();
    let msg_dec = String::from_utf8(dec.to_bytes_be()).unwrap();

    println!("msg as txt: {}", msg);
    println!("msg as num: {}", msg_int);
    println!("enc as num: {}", enc);
    println!("dec as num: {}", dec);
    println!("dec as txt: {}", msg_dec);
}

#[cfg(test)]
mod tests {
    use super::mod_exp;
    use std::str::FromStr;
    use num::bigint::BigUint;
    use num::integer::Integer;
    use num::traits::{Zero, FromPrimitive};

    const N: &'static str = "9516311845790656153499716760847001433441357";
    const E: &'static str = "65537";
    const D: &'static str = "5617843187844953170308463622230283376298685";

    fn rsa_numbers() -> (BigUint, BigUint, BigUint) {
        let n = BigUint::from_str(N).unwrap();
        let e = BigUint::from_str(E).unwrap();
        let d = BigUint::from_str(D).unwrap();
        (n, e, d)
    }

    #[test]
    fn test_enc_dec() {
        let (n, e, d) = rsa_numbers();
        let msg = "Rosetta Code";
        let msg_int = BigUint::from_bytes_be(msg.as_bytes());
        let enc = mod_exp(&msg_int, &e, &n).unwrap();
        let dec = mod_exp(&enc, &d, &n).unwrap();
        let msg_dec = String::from_utf8(dec.to_bytes_be()).unwrap();
        assert_eq!(msg, msg_dec);
    }

    #[test]
    fn test_enc_too_large_base() {
        let (n, e, _) = rsa_numbers();
        let msg = "I am too large for this modulus!";
        let msg_int = BigUint::from_bytes_be(msg.as_bytes());
        assert!(msg_int > n);
        let result = mod_exp(&msg_int, &e, &n);
        assert_eq!(Err("base is >= modulus"), result);
    }

    #[test]
    fn test_enc_zero_modulus() {
        let (_, e, _) = rsa_numbers();
        let msg_int = BigUint::from_bytes_be("msg".as_bytes());
        let result = mod_exp(&msg_int, &e, &BigUint::zero());
        assert_eq!(Err("modulus is zero"), result);
    }

    #[test]
    fn test_base_modulus_not_relatively_prime() {
        let (_, e, _) = rsa_numbers();
        let b = BigUint::from_u8(12).unwrap();
        let n = BigUint::from_u8(18).unwrap();
        assert_eq!(&BigUint::from_u8(6).unwrap(), &b.gcd(&n));
        let result = mod_exp(&b, &e, &n);
        assert_eq!(Err("base and modulus are not relatively prime"), result);
    }
}

<commit_msg>parse() string into BigUint instead of using BigUint::from_str()<commit_after>// Implements http://rosettacode.org/wiki/RSA_code
extern crate num;

use num::bigint::BigUint;
use num::traits::{Zero, One};
use num::integer::Integer;

fn mod_exp(b: &BigUint, e: &BigUint, n: &BigUint) -> Result<BigUint, &'static str> {
    if n.is_zero() {
        return Err("modulus is zero");
    }
    if b >= n {
        // base is too large and should be split into blocks
        return Err("base is >= modulus");
    }
    if b.gcd(n) != BigUint::one() {
        return Err("base and modulus are not relatively prime");
    }

    let mut bb = b.clone();
    let mut ee = e.clone();
    let mut result = BigUint::one();
    while !ee.is_zero() {
        if ee.is_odd() {
            result = (result * &bb) % n;
        }
        ee = ee >> 1;
        bb = (&bb * &bb) % n;
    }
    Ok(result)
}

#[cfg(not(test))]
fn main() {
    let msg = "Rosetta Code";

    let n = "9516311845790656153499716760847001433441357".parse().unwrap();
    let e = "65537".parse().unwrap();
    let d = "5617843187844953170308463622230283376298685".parse().unwrap();

    let msg_int = BigUint::from_bytes_be(msg.as_bytes());
    let enc = mod_exp(&msg_int, &e, &n).unwrap();
    let dec = mod_exp(&enc, &d, &n).unwrap();
    let msg_dec = String::from_utf8(dec.to_bytes_be()).unwrap();

    println!("msg as txt: {}", msg);
    println!("msg as num: {}", msg_int);
    println!("enc as num: {}", enc);
    println!("dec as num: {}", dec);
    println!("dec as txt: {}", msg_dec);
}

#[cfg(test)]
mod tests {
    use super::mod_exp;
    use num::bigint::BigUint;
    use num::integer::Integer;
    use num::traits::{Zero, FromPrimitive};

    const N: &'static str = "9516311845790656153499716760847001433441357";
    const E: &'static str = "65537";
    const D: &'static str = "5617843187844953170308463622230283376298685";

    fn rsa_numbers() -> (BigUint, BigUint, BigUint) {
        let n = N.parse().unwrap();
        let e = E.parse().unwrap();
        let d = D.parse().unwrap();
        (n, e, d)
    }

    #[test]
    fn test_enc_dec() {
        let (n, e, d) = rsa_numbers();
        let msg = "Rosetta Code";
        let msg_int = BigUint::from_bytes_be(msg.as_bytes());
        let enc = mod_exp(&msg_int, &e, &n).unwrap();
        let dec = mod_exp(&enc, &d, &n).unwrap();
        let msg_dec = String::from_utf8(dec.to_bytes_be()).unwrap();
        assert_eq!(msg, msg_dec);
    }

    #[test]
    fn test_enc_too_large_base() {
        let (n, e, _) = rsa_numbers();
        let msg = "I am too large for this modulus!";
        let msg_int = BigUint::from_bytes_be(msg.as_bytes());
        assert!(msg_int > n);
        let result = mod_exp(&msg_int, &e, &n);
        assert_eq!(Err("base is >= modulus"), result);
    }

    #[test]
    fn test_enc_zero_modulus() {
        let (_, e, _) = rsa_numbers();
        let msg_int = BigUint::from_bytes_be("msg".as_bytes());
        let result = mod_exp(&msg_int, &e, &BigUint::zero());
        assert_eq!(Err("modulus is zero"), result);
    }

    #[test]
    fn test_base_modulus_not_relatively_prime() {
        let (_, e, _) = rsa_numbers();
        let b = BigUint::from_u8(12).unwrap();
        let n = BigUint::from_u8(18).unwrap();
        assert_eq!(&BigUint::from_u8(6).unwrap(), &b.gcd(&n));
        let result = mod_exp(&b, &e, &n);
        assert_eq!(Err("base and modulus are not relatively prime"), result);
    }
}

<|endoftext|>


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

include!(concat!(env!("OUT_DIR"), "/grr.rs"));

/// An error type for failures of converting timestamps to microseconds.
#[derive(Clone, Debug)]
pub enum MicrosError {
    /// Attempted to convert pre-epoch system time.
    Epoch(std::time::SystemTimeError),
    /// Attempted to convert a value outside of 64-bit unsigned integer range.
    Overflow(std::num::TryFromIntError),
}

impl std::fmt::Display for MicrosError {

    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
        use MicrosError::*;

        match *self {
            Epoch(ref error) => {
                write!(fmt, "pre-epoch system time: {}", error)
            }
            Overflow(ref error) => {
                write!(fmt, "system time value too big: {}", error)
            }
        }
    }
}

impl std::error::Error for MicrosError {

    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        use MicrosError::*;

        match *self {
            Epoch(ref error) => Some(error),
            Overflow(ref error) => Some(error),
        }
    }
}

impl From<std::time::SystemTimeError> for MicrosError {

    fn from(error: std::time::SystemTimeError) -> MicrosError {
        MicrosError::Epoch(error)
    }
}

impl From<std::num::TryFromIntError> for MicrosError {

    fn from(error: std::num::TryFromIntError) -> MicrosError {
        MicrosError::Overflow(error)
    }
}

/// Converts system time into epoch microseconds.
///
/// Because most GRR messages use epoch microseconds for representing timestamps
/// this function be be useful to convert from more idiomatic representations.
///
/// # Examples
///
/// ```
/// use rrg_proto::micros;
///
/// assert_eq!(micros(std::time::UNIX_EPOCH).unwrap(), 0);
/// ```
pub fn micros(time: std::time::SystemTime) -> Result<u64, MicrosError> {
    let time_micros = time.duration_since(std::time::UNIX_EPOCH)?.as_micros();
    Ok(std::convert::TryInto::try_into(time_micros)?)
}
<commit_msg>Add conversions from Rust types to data blobs.<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.

include!(concat!(env!("OUT_DIR"), "/grr.rs"));

impl Into<DataBlob> for bool {

    fn into(self) -> DataBlob {
        DataBlob {
            boolean: Some(self),
            ..Default::default()
        }
    }
}

impl Into<DataBlob> for i64 {

    fn into(self) -> DataBlob {
        DataBlob {
            integer: Some(self),
            ..Default::default()
        }
    }
}

impl Into<DataBlob> for f32 {

    fn into(self) -> DataBlob {
        DataBlob {
            float: Some(self),
            ..Default::default()
        }
    }
}

impl Into<DataBlob> for Vec<u8> {

    fn into(self) -> DataBlob {
        DataBlob {
            data: Some(self),
            ..Default::default()
        }
    }
}

impl Into<DataBlob> for String {

    fn into(self) -> DataBlob {
        DataBlob {
            string: Some(self),
            ..Default::default()
        }
    }
}

/// An error type for failures of converting timestamps to microseconds.
#[derive(Clone, Debug)]
pub enum MicrosError {
    /// Attempted to convert pre-epoch system time.
    Epoch(std::time::SystemTimeError),
    /// Attempted to convert a value outside of 64-bit unsigned integer range.
    Overflow(std::num::TryFromIntError),
}

impl std::fmt::Display for MicrosError {

    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
        use MicrosError::*;

        match *self {
            Epoch(ref error) => {
                write!(fmt, "pre-epoch system time: {}", error)
            }
            Overflow(ref error) => {
                write!(fmt, "system time value too big: {}", error)
            }
        }
    }
}

impl std::error::Error for MicrosError {

    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        use MicrosError::*;

        match *self {
            Epoch(ref error) => Some(error),
            Overflow(ref error) => Some(error),
        }
    }
}

impl From<std::time::SystemTimeError> for MicrosError {

    fn from(error: std::time::SystemTimeError) -> MicrosError {
        MicrosError::Epoch(error)
    }
}

impl From<std::num::TryFromIntError> for MicrosError {

    fn from(error: std::num::TryFromIntError) -> MicrosError {
        MicrosError::Overflow(error)
    }
}

/// Converts system time into epoch microseconds.
///
/// Because most GRR messages use epoch microseconds for representing timestamps
/// this function be be useful to convert from more idiomatic representations.
///
/// # Examples
///
/// ```
/// use rrg_proto::micros;
///
/// assert_eq!(micros(std::time::UNIX_EPOCH).unwrap(), 0);
/// ```
pub fn micros(time: std::time::SystemTime) -> Result<u64, MicrosError> {
    let time_micros = time.duration_since(std::time::UNIX_EPOCH)?.as_micros();
    Ok(std::convert::TryInto::try_into(time_micros)?)
}
<|endoftext|>