<commit_before>extern crate xmltree;
extern crate tempfile;

use xmltree::Element;
use xmltree::ParseError;
use std::fs::File;
use tempfile::TempFile;

#[test]
fn test_01() {
    let e: Element = Element::parse(File::open("tests/data/01.xml").unwrap()).unwrap();
    println!("E:=======\n{:#?}", e);
    assert_eq!(e.name, "project");
    let e2: &Element = e.get_child("libraries").expect("Missing libraries child element");
    assert_eq!(e2.name, "libraries");

    assert!(e.get_child("doesnotexist").is_none());

    let mut tmp = TempFile::shared(2).unwrap();
    let t1 = tmp.remove(0);
    let t2 = tmp.remove(0);
    e.write(t1);

    let e2 = Element::parse(t2).unwrap();
    println!("E2:======\n{:#?}", e2);

    assert_eq!(e, e2);
}

#[test]
fn test_02() {
    let e: Element = Element::parse(File::open("tests/data/02.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_03() {
    let e: Element = Element::parse(File::open("tests/data/03.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_04() {
    let e: Element = Element::parse(File::open("tests/data/04.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_rw() {

    let e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();

    let mut tmp = TempFile::shared(2).unwrap();
    let t1 = tmp.remove(0);
    let t2 = tmp.remove(0);
    e.write(t1);

    let e2 = Element::parse(t2).unwrap();

    assert_eq!(e, e2);
}

#[test]
fn test_mut() {

    let mut e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();
    {
        let name = e.get_mut_child("name").unwrap();
        name.attributes.insert("suffix".to_owned(), "mr".to_owned());
    }
}

#[test]
fn test_mal_01() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones />
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_02() {
    // some tests for error handling

    let data = r##"
            this is not even close
            to XML
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_03() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></badtag>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}
<commit_msg>small new test for take_child<commit_after>extern crate xmltree;
extern crate tempfile;

use xmltree::Element;
use xmltree::ParseError;
use std::fs::File;
use tempfile::TempFile;

#[test]
fn test_01() {
    let e: Element = Element::parse(File::open("tests/data/01.xml").unwrap()).unwrap();
    println!("E:=======\n{:#?}", e);
    assert_eq!(e.name, "project");
    let e2: &Element = e.get_child("libraries").expect("Missing libraries child element");
    assert_eq!(e2.name, "libraries");

    assert!(e.get_child("doesnotexist").is_none());

    let mut tmp = TempFile::shared(2).unwrap();
    let t1 = tmp.remove(0);
    let t2 = tmp.remove(0);
    e.write(t1);

    let e2 = Element::parse(t2).unwrap();
    println!("E2:======\n{:#?}", e2);

    assert_eq!(e, e2);
}

#[test]
fn test_02() {
    let e: Element = Element::parse(File::open("tests/data/02.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_03() {
    let e: Element = Element::parse(File::open("tests/data/03.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_04() {
    let e: Element = Element::parse(File::open("tests/data/04.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_rw() {

    let e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();

    let mut tmp = TempFile::shared(2).unwrap();
    let t1 = tmp.remove(0);
    let t2 = tmp.remove(0);
    e.write(t1);

    let e2 = Element::parse(t2).unwrap();

    assert_eq!(e, e2);
}

#[test]
fn test_mut() {

    let mut e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();
    {
        let name = e.get_mut_child("name").unwrap();
        name.attributes.insert("suffix".to_owned(), "mr".to_owned());
    }
}

#[test]
fn test_mal_01() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones />
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_02() {
    // some tests for error handling

    let data = r##"
            this is not even close
            to XML
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_03() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></badtag>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_take() {
    let data_xml_1 = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></name>
            <name first="elizabeth" last="smith" />
            <remove_me key="value">
                <child />
            </remove_me>
        </names>
    "##;

    let data_xml_2 = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></name>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let mut data_1 = Element::parse(data_xml_1.as_bytes()).unwrap();
    let data_2 = Element::parse(data_xml_2.as_bytes()).unwrap();

    if let Some(removed) = data_1.take_child("remove_me") {
        assert_eq!(removed.children.len(), 1);

    } else {
        panic!("take_child failed");
    }

    assert_eq!(data_1, data_2);
}
<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

import bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGetWindow, glutInit};
import bindgen::{glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc, glutReshapeWindow};
import bindgen::{glutSetWindow, glutSwapBuffers, glutTimerFunc};
import libc::*;
import dvec::dvec;
import ptr::{addr_of, null};
import str::bytes;
import task::{local_data_get, local_data_set};
import unsafe::reinterpret_cast;
import vec::unsafe::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

type GLenum = i32;
type GLint = i32;
type GLfloat = f32;
type GLdouble = f64;

enum Window = c_int;

const DOUBLE: c_uint = 2 as c_uint;

fn destroy<T>(-_value: ~[T]) {
    // let it drop
}

fn init() unsafe {
    let argc = 0 as c_int;
    let command = bytes(~"glut");
    let argv: (*u8, *u8) = (to_ptr(command), null());
    let argv_p = reinterpret_cast(addr_of(argv));

    glutInit(addr_of(argc), argv_p);

    destroy(command);
}

fn create_window(name: ~str) -> Window unsafe {
    let bytes = str::bytes(name);
    return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
}

fn destroy_window(window: Window) unsafe {
    glutDestroyWindow(*window);
}

fn reshape_window(window: Window, width: c_int, height: c_int) unsafe {
    let current_window = glutGetWindow();
    glutSetWindow(*window);
    glutReshapeWindow(width, height);
    glutSetWindow(current_window);
}

fn display_callback_tls_key(+_callback: @fn@()) {
    // Empty.
}

extern fn display_callback() unsafe {
    let callback = local_data_get(display_callback_tls_key).get();
    (*callback)();
}

fn display_func(callback: fn@()) unsafe {
    local_data_set(display_callback_tls_key, @callback);
    glutDisplayFunc(display_callback);
}

fn timer_callback_tls_key(+_callback: @dvec<fn@()>) {
    // Empty.
}

extern fn timer_callback(index: int) unsafe {
    let callbacks = local_data_get(timer_callback_tls_key).get();
    ((*callbacks)[index as uint])();
}

fn timer_func(msecs: u32, callback: fn@()) unsafe {
    let callbacks;
    match local_data_get(timer_callback_tls_key) {
        none => {
            callbacks = @dvec();
            local_data_set(timer_callback_tls_key, copy callbacks);
        }
        some(existing_callbacks) => {
            callbacks = existing_callbacks;
        }
    }

    callbacks.push(callback);
    let index = (callbacks.len() - 1) as c_int;
    glutTimerFunc(msecs, timer_callback, index);
}

fn reshape_callback_tls_key(+_callback: @fn@(++c_int, ++c_int)) {
    // Empty.
}

extern fn reshape_callback(++width: c_int, ++height: c_int) unsafe {
    let callback = local_data_get(reshape_callback_tls_key).get();
    (*callback)(width, height);
}

fn reshape_func(window: Window, callback: fn@(++c_int, ++c_int)) unsafe {
    local_data_set(reshape_callback_tls_key, @callback);
    glutReshapeFunc(reshape_callback);
}

#[cfg(target_os="macos")]
fn check_loop() unsafe {
    ext::glutCheckLoop();
}

#[cfg(target_os="linux")]
fn check_loop() unsafe {
    ext::glutMainLoopEvent();
}

fn init_display_mode(mode: c_uint) unsafe {
    glutInitDisplayMode(mode);
}

fn swap_buffers() unsafe {
    glutSwapBuffers();
}

fn post_redisplay() unsafe {
    glutPostRedisplay();
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
extern mod bindgen {

fn glutInit(++argcp: *c_int, ++argv: **c_char);

fn glutInitDisplayMode(++mode: c_uint);

fn glutInitDisplayString(++string: *c_char);

fn glutInitWindowPosition(++x: c_int, ++y: c_int);

fn glutInitWindowSize(++width: c_int, ++height: c_int);

fn glutMainLoop();

fn glutCreateWindow(++title: *c_char) -> c_int;

fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

fn glutDestroyWindow(++win: c_int);

fn glutPostRedisplay();

fn glutPostWindowRedisplay(++win: c_int);

fn glutSwapBuffers();

fn glutGetWindow() -> c_int;

fn glutSetWindow(++win: c_int);

fn glutSetWindowTitle(++title: *c_char);

fn glutSetIconTitle(++title: *c_char);

fn glutPositionWindow(++x: c_int, ++y: c_int);

fn glutReshapeWindow(++width: c_int, ++height: c_int);

fn glutPopWindow();

fn glutPushWindow();

fn glutIconifyWindow();

fn glutShowWindow();

fn glutHideWindow();

fn glutFullScreen();

fn glutSetCursor(++cursor: c_int);

fn glutWarpPointer(++x: c_int, ++y: c_int);

fn glutEstablishOverlay();

fn glutRemoveOverlay();

fn glutUseLayer(++layer: GLenum);

fn glutPostOverlayRedisplay();

fn glutPostWindowOverlayRedisplay(++win: c_int);

fn glutShowOverlay();

fn glutHideOverlay();

fn glutCreateMenu(++arg1: *u8) -> c_int;

fn glutDestroyMenu(++menu: c_int);

fn glutGetMenu() -> c_int;

fn glutSetMenu(++menu: c_int);

fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

fn glutRemoveMenuItem(++item: c_int);

fn glutAttachMenu(++button: c_int);

fn glutDetachMenu(++button: c_int);

fn glutDisplayFunc(++func: *u8);

fn glutReshapeFunc(++func: *u8);

fn glutKeyboardFunc(++func: *u8);

fn glutMouseFunc(++func: *u8);

fn glutMotionFunc(++func: *u8);

fn glutPassiveMotionFunc(++func: *u8);

fn glutEntryFunc(++func: *u8);

fn glutVisibilityFunc(++func: *u8);

fn glutIdleFunc(++func: *u8);

fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

fn glutMenuStateFunc(++func: *u8);

fn glutSpecialFunc(++func: *u8);

fn glutSpaceballMotionFunc(++func: *u8);

fn glutSpaceballRotateFunc(++func: *u8);

fn glutSpaceballButtonFunc(++func: *u8);

fn glutButtonBoxFunc(++func: *u8);

fn glutDialsFunc(++func: *u8);

fn glutTabletMotionFunc(++func: *u8);

fn glutTabletButtonFunc(++func: *u8);

fn glutMenuStatusFunc(++func: *u8);

fn glutOverlayDisplayFunc(++func: *u8);

fn glutWindowStatusFunc(++func: *u8);

fn glutKeyboardUpFunc(++func: *u8);

fn glutSpecialUpFunc(++func: *u8);

fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

fn glutCopyColormap(++win: c_int);

fn glutGet(++_type: GLenum) -> c_int;

fn glutDeviceGet(++_type: GLenum) -> c_int;

fn glutExtensionSupported(++name: *c_char) -> c_int;

fn glutGetModifiers() -> c_int;

fn glutLayerGet(++_type: GLenum) -> c_int;

fn glutGetProcAddress(++procName: *c_char) -> *c_void;

fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCube(++size: GLdouble);

fn glutSolidCube(++size: GLdouble);

fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutWireDodecahedron();

fn glutSolidDodecahedron();

fn glutWireTeapot(++size: GLdouble);

fn glutSolidTeapot(++size: GLdouble);

fn glutWireOctahedron();

fn glutSolidOctahedron();

fn glutWireTetrahedron();

fn glutSolidTetrahedron();

fn glutWireIcosahedron();

fn glutSolidIcosahedron();

fn glutVideoResizeGet(++param: GLenum) -> c_int;

fn glutSetupVideoResizing();

fn glutStopVideoResizing();

fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutReportErrors();

fn glutIgnoreKeyRepeat(++ignore: c_int);

fn glutSetKeyRepeat(++repeatMode: c_int);

fn glutForceJoystickFunc();

fn glutGameModeString(++string: *c_char);

fn glutEnterGameMode() -> c_int;

fn glutLeaveGameMode();

fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<commit_msg>Fix breakage<commit_after>/* automatically generated by rust-bindgen */

import bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGetWindow, glutInit};
import bindgen::{glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc, glutReshapeWindow};
import bindgen::{glutSetWindow, glutSwapBuffers, glutTimerFunc};
import libc::*;
import dvec::{DVec, dvec};
import ptr::{addr_of, null};
import str::bytes;
import task::{local_data_get, local_data_set};
import unsafe::reinterpret_cast;
import vec::unsafe::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

type GLenum = i32;
type GLint = i32;
type GLfloat = f32;
type GLdouble = f64;

enum Window = c_int;

const DOUBLE: c_uint = 2 as c_uint;

fn destroy<T>(-_value: ~[T]) {
    // let it drop
}

fn init() unsafe {
    let argc = 0 as c_int;
    let command = bytes(~"glut");
    let argv: (*u8, *u8) = (to_ptr(command), null());
    let argv_p = reinterpret_cast(addr_of(argv));

    glutInit(addr_of(argc), argv_p);

    destroy(command);
}

fn create_window(name: ~str) -> Window unsafe {
    let bytes = str::bytes(name);
    return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
}

fn destroy_window(window: Window) unsafe {
    glutDestroyWindow(*window);
}

fn reshape_window(window: Window, width: c_int, height: c_int) unsafe {
    let current_window = glutGetWindow();
    glutSetWindow(*window);
    glutReshapeWindow(width, height);
    glutSetWindow(current_window);
}

fn display_callback_tls_key(+_callback: @fn@()) {
    // Empty.
}

extern fn display_callback() unsafe {
    let callback = local_data_get(display_callback_tls_key).get();
    (*callback)();
}

fn display_func(callback: fn@()) unsafe {
    local_data_set(display_callback_tls_key, @callback);
    glutDisplayFunc(display_callback);
}

fn timer_callback_tls_key(+_callback: @DVec<fn@()>) {
    // Empty.
}

extern fn timer_callback(index: int) unsafe {
    let callbacks = local_data_get(timer_callback_tls_key).get();
    ((*callbacks)[index as uint])();
}

fn timer_func(msecs: u32, callback: fn@()) unsafe {
    let callbacks;
    match local_data_get(timer_callback_tls_key) {
        none => {
            callbacks = @dvec();
            local_data_set(timer_callback_tls_key, copy callbacks);
        }
        some(existing_callbacks) => {
            callbacks = existing_callbacks;
        }
    }

    callbacks.push(callback);
    let index = (callbacks.len() - 1) as c_int;
    glutTimerFunc(msecs, timer_callback, index);
}

fn reshape_callback_tls_key(+_callback: @fn@(++c_int, ++c_int)) {
    // Empty.
}

extern fn reshape_callback(++width: c_int, ++height: c_int) unsafe {
    let callback = local_data_get(reshape_callback_tls_key).get();
    (*callback)(width, height);
}

fn reshape_func(window: Window, callback: fn@(++c_int, ++c_int)) unsafe {
    local_data_set(reshape_callback_tls_key, @callback);
    glutReshapeFunc(reshape_callback);
}

#[cfg(target_os="macos")]
fn check_loop() unsafe {
    ext::glutCheckLoop();
}

#[cfg(target_os="linux")]
fn check_loop() unsafe {
    ext::glutMainLoopEvent();
}

fn init_display_mode(mode: c_uint) unsafe {
    glutInitDisplayMode(mode);
}

fn swap_buffers() unsafe {
    glutSwapBuffers();
}

fn post_redisplay() unsafe {
    glutPostRedisplay();
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
extern mod bindgen {

fn glutInit(++argcp: *c_int, ++argv: **c_char);

fn glutInitDisplayMode(++mode: c_uint);

fn glutInitDisplayString(++string: *c_char);

fn glutInitWindowPosition(++x: c_int, ++y: c_int);

fn glutInitWindowSize(++width: c_int, ++height: c_int);

fn glutMainLoop();

fn glutCreateWindow(++title: *c_char) -> c_int;

fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

fn glutDestroyWindow(++win: c_int);

fn glutPostRedisplay();

fn glutPostWindowRedisplay(++win: c_int);

fn glutSwapBuffers();

fn glutGetWindow() -> c_int;

fn glutSetWindow(++win: c_int);

fn glutSetWindowTitle(++title: *c_char);

fn glutSetIconTitle(++title: *c_char);

fn glutPositionWindow(++x: c_int, ++y: c_int);

fn glutReshapeWindow(++width: c_int, ++height: c_int);

fn glutPopWindow();

fn glutPushWindow();

fn glutIconifyWindow();

fn glutShowWindow();

fn glutHideWindow();

fn glutFullScreen();

fn glutSetCursor(++cursor: c_int);

fn glutWarpPointer(++x: c_int, ++y: c_int);

fn glutEstablishOverlay();

fn glutRemoveOverlay();

fn glutUseLayer(++layer: GLenum);

fn glutPostOverlayRedisplay();

fn glutPostWindowOverlayRedisplay(++win: c_int);

fn glutShowOverlay();

fn glutHideOverlay();

fn glutCreateMenu(++arg1: *u8) -> c_int;

fn glutDestroyMenu(++menu: c_int);

fn glutGetMenu() -> c_int;

fn glutSetMenu(++menu: c_int);

fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

fn glutRemoveMenuItem(++item: c_int);

fn glutAttachMenu(++button: c_int);

fn glutDetachMenu(++button: c_int);

fn glutDisplayFunc(++func: *u8);

fn glutReshapeFunc(++func: *u8);

fn glutKeyboardFunc(++func: *u8);

fn glutMouseFunc(++func: *u8);

fn glutMotionFunc(++func: *u8);

fn glutPassiveMotionFunc(++func: *u8);

fn glutEntryFunc(++func: *u8);

fn glutVisibilityFunc(++func: *u8);

fn glutIdleFunc(++func: *u8);

fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

fn glutMenuStateFunc(++func: *u8);

fn glutSpecialFunc(++func: *u8);

fn glutSpaceballMotionFunc(++func: *u8);

fn glutSpaceballRotateFunc(++func: *u8);

fn glutSpaceballButtonFunc(++func: *u8);

fn glutButtonBoxFunc(++func: *u8);

fn glutDialsFunc(++func: *u8);

fn glutTabletMotionFunc(++func: *u8);

fn glutTabletButtonFunc(++func: *u8);

fn glutMenuStatusFunc(++func: *u8);

fn glutOverlayDisplayFunc(++func: *u8);

fn glutWindowStatusFunc(++func: *u8);

fn glutKeyboardUpFunc(++func: *u8);

fn glutSpecialUpFunc(++func: *u8);

fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

fn glutCopyColormap(++win: c_int);

fn glutGet(++_type: GLenum) -> c_int;

fn glutDeviceGet(++_type: GLenum) -> c_int;

fn glutExtensionSupported(++name: *c_char) -> c_int;

fn glutGetModifiers() -> c_int;

fn glutLayerGet(++_type: GLenum) -> c_int;

fn glutGetProcAddress(++procName: *c_char) -> *c_void;

fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCube(++size: GLdouble);

fn glutSolidCube(++size: GLdouble);

fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutWireDodecahedron();

fn glutSolidDodecahedron();

fn glutWireTeapot(++size: GLdouble);

fn glutSolidTeapot(++size: GLdouble);

fn glutWireOctahedron();

fn glutSolidOctahedron();

fn glutWireTetrahedron();

fn glutSolidTetrahedron();

fn glutWireIcosahedron();

fn glutSolidIcosahedron();

fn glutVideoResizeGet(++param: GLenum) -> c_int;

fn glutSetupVideoResizing();

fn glutStopVideoResizing();

fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutReportErrors();

fn glutIgnoreKeyRepeat(++ignore: c_int);

fn glutSetKeyRepeat(++repeatMode: c_int);

fn glutForceJoystickFunc();

fn glutGameModeString(++string: *c_char);

fn glutEnterGameMode() -> c_int;

fn glutLeaveGameMode();

fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::marker::PhantomData;

use serde::{Deserialize, Deserializer, Error as SerdeError};
use serde::de::{Visitor, MapVisitor};

use generator::capitalize_first;

pub trait ShapeName: Sized {
    fn deserialize_shape_name<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer;
}

struct ShapeNameVisitor;

impl Visitor for ShapeNameVisitor {
    type Value = String;

    fn visit_str<E>(&mut self, v: &str) -> Result<Self::Value, E>
        where E: SerdeError,
    {
        Ok(capitalize_first(v))
    }
}

impl ShapeName for String {
    fn deserialize_shape_name<D>(deserializer: &mut D) -> Result<String, D::Error>
        where D: Deserializer,
    {
        deserializer.deserialize_string(ShapeNameVisitor)
    }
}

pub trait ShapesMap: Sized {
    fn deserialize_shapes_map<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer;
}

struct ShapesMapVisitor<V> {
    marker: PhantomData<BTreeMap<String, V>>,
}

impl<V> ShapesMapVisitor<V> {
    pub fn new() -> Self {
        ShapesMapVisitor {
            marker: PhantomData,
        }
    }
}

impl<V> Visitor for ShapesMapVisitor<V>
    where V: Deserialize,
{
    type Value = BTreeMap<String, V>;

    fn visit_unit<E>(&mut self) -> Result<BTreeMap<String, V>, E>
        where E: SerdeError,
    {
        Ok(BTreeMap::new())
    }

    fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<Self::Value, Visitor::Error>
        where Visitor: MapVisitor,
    {
        let mut values = BTreeMap::new();

        while let Some((key, value)) = try!(visitor.visit()) {
            let key: String = key;
            values.insert(capitalize_first(key.as_str()), value);
        }

        try!(visitor.end());

        Ok(values)
    }
}

impl<V> ShapesMap for BTreeMap<String, V>
    where String: Deserialize,
          V: Deserialize,
{
    fn deserialize_shapes_map<D>(deserializer: &mut D) -> Result<BTreeMap<String, V>, D::Error>
        where D: Deserializer,
    {
        deserializer.deserialize(ShapesMapVisitor::new())
    }
}
<commit_msg>doc: document purpose of manual deserializers<commit_after>// This file provides a custom deserializer for `String` and
// `BTreeMap<String, V>`, which function identically to the built-in serde
// deserializers, except for the fact that `String`s deserialized with these
// deserializers get their first letter capitalized.
//
// This is necessary for proper deserialization of `Shape` names from their
// botocore definitions in certain edge cases. Particularly, IAM shape names use
// "camelCase" instead of "CamelCase".
use std::collections::BTreeMap;
use std::marker::PhantomData;

use serde::{Deserialize, Deserializer, Error as SerdeError};
use serde::de::{Visitor, MapVisitor};

use generator::capitalize_first;

pub trait ShapeName: Sized {
    fn deserialize_shape_name<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer;
}

struct ShapeNameVisitor;

impl Visitor for ShapeNameVisitor {
    type Value = String;

    fn visit_str<E>(&mut self, v: &str) -> Result<Self::Value, E>
        where E: SerdeError,
    {
        Ok(capitalize_first(v))
    }
}

impl ShapeName for String {
    fn deserialize_shape_name<D>(deserializer: &mut D) -> Result<String, D::Error>
        where D: Deserializer,
    {
        deserializer.deserialize_string(ShapeNameVisitor)
    }
}

pub trait ShapesMap: Sized {
    fn deserialize_shapes_map<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer;
}

struct ShapesMapVisitor<V> {
    marker: PhantomData<BTreeMap<String, V>>,
}

impl<V> ShapesMapVisitor<V> {
    pub fn new() -> Self {
        ShapesMapVisitor {
            marker: PhantomData,
        }
    }
}

impl<V> Visitor for ShapesMapVisitor<V>
    where V: Deserialize,
{
    type Value = BTreeMap<String, V>;

    fn visit_unit<E>(&mut self) -> Result<BTreeMap<String, V>, E>
        where E: SerdeError,
    {
        Ok(BTreeMap::new())
    }

    fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<Self::Value, Visitor::Error>
        where Visitor: MapVisitor,
    {
        let mut values = BTreeMap::new();

        while let Some((key, value)) = try!(visitor.visit()) {
            let key: String = key;
            values.insert(capitalize_first(key.as_str()), value);
        }

        try!(visitor.end());

        Ok(values)
    }
}

impl<V> ShapesMap for BTreeMap<String, V>
    where String: Deserialize,
          V: Deserialize,
{
    fn deserialize_shapes_map<D>(deserializer: &mut D) -> Result<BTreeMap<String, V>, D::Error>
        where D: Deserializer,
    {
        deserializer.deserialize(ShapesMapVisitor::new())
    }
}
<|endoftext|>


<commit_before>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

#![feature(phase)]

#[phase(plugin, link)] extern crate itertools;

use std::iter::order;
use itertools::Itertools;
use itertools::Stride;
use itertools::Interleave;
use itertools::BoxIter;

use it = itertools;

#[test]
fn product2() {
    let s = "αβ";

    let mut prod = iproduct!(s.chars(), range(0, 2i));
    assert!(prod.next() == Some(('α', 0)));
    assert!(prod.next() == Some(('α', 1)));
    assert!(prod.next() == Some(('β', 0)));
    assert!(prod.next() == Some(('β', 1)));
    assert!(prod.next() == None);
}

#[test]
fn product3() {
    let mut prod = iproduct!(range(0, 3i), range(0, 2i), range(0, 2i));
    assert_eq!(prod.size_hint(), (12, Some(12)));
    let v = prod.collect::<Vec<_>>();
    for i in range(0,3i) {
        for j in range(0, 2i) {
            for k in range(0, 2i) {
                assert!((i, j, k) == v[(i * 2 * 2 + j * 2 + k) as uint]);
            }
        }
    }
    for (a, b, c, d) in iproduct!(range(0, 3i), range(0, 2i), range(0, 2i), range(0, 3i)) {
        /* test compiles */
    }
}

#[test]
fn izip3() {
    let mut zip = izip!(range(0, 3u), range(0, 2i), range(0, 2i8));
    for i in range(0, 2i) {
        assert!((i as uint, i, i as i8) == zip.next().unwrap());
    }
    assert!(zip.next().is_none());

    let xs: [int, ..0] = [];
    let mut zip = izip!(range(0, 3u), range(0, 2i), range(0, 2i8), xs.iter());
    assert!(zip.next().is_none());

    for (a, b, c, d) in izip!(range(0, 3i), range(0, 2i), range(0, 2i), range(0, 3i)) {
        /* test compiles */
    }
}

#[test]
fn fn_map() {
    let xs = [0, 1, 2i];
    fn mapper(x: &int) -> String { x.to_string() }
    let it = xs.iter().fn_map(mapper);
    let jt = it.clone();
    assert!(it.zip(jt).all(|(x,y)| x == y));
}

#[test]
fn write_to() {
    let xs = [7i, 9, 8];
    let mut ys = [0i, ..5];
    let cnt = xs.iter().map(|x| *x).write_to(ys.mut_iter());
    assert!(cnt == xs.len());
    assert!(ys == &[7i, 9, 8, 0, 0]);

    let cnt = range(0,10i).write_to(ys.mut_iter());
    assert!(cnt == ys.len());
    assert!(ys == &[0, 1, 2, 3, 4]);
}

#[test]
fn stride_uneven() {
    let xs = [7i, 9, 8];
    let mut it = Stride::from_slice(xs, 2);
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 7);
    assert!(*it.next().unwrap() == 8);
    assert!(it.next().is_none());

    let xs = [7i, 9, 8, 10];
    let mut it = Stride::from_slice(xs.slice_from(1), 2);
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 9);
    assert!(*it.next().unwrap() == 10);
    assert!(it.next().is_none());
}

#[test]
fn stride() {
    let xs: [u8, ..0]  = [];
    let mut it = Stride::from_slice(xs, 1);
    assert!(it.size_hint() == (0, Some(0)));
    assert!(it.next().is_none());

    let xs = [7i, 9, 8, 10];
    let mut it = Stride::from_slice(xs, 2);
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 7);
    assert!(*it.next().unwrap() == 8);
    assert!(it.next().is_none());

    let mut it = Stride::from_slice(xs, 2).rev();
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 7);
    assert!(it.next().is_none());

    let xs = [7i, 9, 8, 10];
    let mut it = Stride::from_slice(xs, 1);
    assert!(it.size_hint() == (4, Some(4)));
    assert!(*it.next().unwrap() == 7);
    assert!(*it.next().unwrap() == 9);
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 10);
    assert!(it.next().is_none());

    let mut it = Stride::from_slice(xs, 1).rev();
    assert!(it.size_hint() == (4, Some(4)));
    assert!(*it.next().unwrap() == 10);
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 9);
    assert!(*it.next().unwrap() == 7);
    assert!(it.next().is_none());

    let mut it = Stride::from_slice(xs, 2);
    it.swap_ends();
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 7);
    assert!(it.next().is_none());
}

#[test]
fn interleave() {
    let xs: [u8, ..0]  = [];
    let ys = [7u8, 9, 8, 10];
    let zs = [2u8, 77];
    let it = Interleave::new(xs.iter(), ys.iter());
    assert!(order::eq(it, ys.iter()));

    let rs = [7u8, 2, 9, 77, 8, 10];
    let it = Interleave::new(ys.iter(), zs.iter());
    assert!(order::eq(it, rs.iter()));
}

#[test]
fn boxiter() {
    let ys = vec![1,2,3i];
    let it = BoxIter::from_iter(ys.move_iter());
    assert!(it.size_hint().val0() == 3);
    assert!(order::eq(it, range(1i, 4)));
}

#[test]
fn times() {
    assert!(it::times(0).count() == 0);
    assert!(it::times(5).count() == 5);
}

#[test]
fn drain() {
    let xs = [1i,2,3];
    let mut sum = 0;
    xs.iter().map(|elt| sum += *elt).drain();
    assert!(sum == 6);
}

#[test]
fn apply() {
    let xs = [1i, 2, 3];
    let mut sum = 0;
    xs.iter().apply(|elt| sum += *elt);
    assert!(sum == 6);
}

#[test]
fn dropn() {
    let xs = [1i, 2, 3];
    let mut it = xs.iter();
    assert!(it.dropn(2) == 2);
    assert!(it.next().is_some());
    assert!(it.next().is_none());
    let mut it = xs.iter();
    assert!(it.dropn(5) == 3);
    assert!(it.next().is_none());
}

#[test]
fn intersperse() {
    let xs = ["a", "", "b", "c"];
    let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
    let text = v.concat();
    assert_eq!(text, "a, , b, c".to_string());

    let ys = [0, 1, 2, 3i];
    let mut it = ys.slice_to(0).iter().map(|x| *x).intersperse(1i);
    assert!(it.next() == None);
}
<commit_msg>Add benchmark for Stride<commit_after>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

#![feature(phase)]

#[phase(plugin, link)] extern crate itertools;

extern crate test;

use std::iter::order;
use itertools::Itertools;
use itertools::Stride;
use itertools::Interleave;
use itertools::BoxIter;

use it = itertools;

#[test]
fn product2() {
    let s = "αβ";

    let mut prod = iproduct!(s.chars(), range(0, 2i));
    assert!(prod.next() == Some(('α', 0)));
    assert!(prod.next() == Some(('α', 1)));
    assert!(prod.next() == Some(('β', 0)));
    assert!(prod.next() == Some(('β', 1)));
    assert!(prod.next() == None);
}

#[test]
fn product3() {
    let mut prod = iproduct!(range(0, 3i), range(0, 2i), range(0, 2i));
    assert_eq!(prod.size_hint(), (12, Some(12)));
    let v = prod.collect::<Vec<_>>();
    for i in range(0,3i) {
        for j in range(0, 2i) {
            for k in range(0, 2i) {
                assert!((i, j, k) == v[(i * 2 * 2 + j * 2 + k) as uint]);
            }
        }
    }
    for (a, b, c, d) in iproduct!(range(0, 3i), range(0, 2i), range(0, 2i), range(0, 3i)) {
        /* test compiles */
    }
}

#[test]
fn izip3() {
    let mut zip = izip!(range(0, 3u), range(0, 2i), range(0, 2i8));
    for i in range(0, 2i) {
        assert!((i as uint, i, i as i8) == zip.next().unwrap());
    }
    assert!(zip.next().is_none());

    let xs: [int, ..0] = [];
    let mut zip = izip!(range(0, 3u), range(0, 2i), range(0, 2i8), xs.iter());
    assert!(zip.next().is_none());

    for (a, b, c, d) in izip!(range(0, 3i), range(0, 2i), range(0, 2i), range(0, 3i)) {
        /* test compiles */
    }
}

#[test]
fn fn_map() {
    let xs = [0, 1, 2i];
    fn mapper(x: &int) -> String { x.to_string() }
    let it = xs.iter().fn_map(mapper);
    let jt = it.clone();
    assert!(it.zip(jt).all(|(x,y)| x == y));
}

#[test]
fn write_to() {
    let xs = [7i, 9, 8];
    let mut ys = [0i, ..5];
    let cnt = xs.iter().map(|x| *x).write_to(ys.mut_iter());
    assert!(cnt == xs.len());
    assert!(ys == &[7i, 9, 8, 0, 0]);

    let cnt = range(0,10i).write_to(ys.mut_iter());
    assert!(cnt == ys.len());
    assert!(ys == &[0, 1, 2, 3, 4]);
}

#[test]
fn stride_uneven() {
    let xs = [7i, 9, 8];
    let mut it = Stride::from_slice(xs, 2);
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 7);
    assert!(*it.next().unwrap() == 8);
    assert!(it.next().is_none());

    let xs = [7i, 9, 8, 10];
    let mut it = Stride::from_slice(xs.slice_from(1), 2);
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 9);
    assert!(*it.next().unwrap() == 10);
    assert!(it.next().is_none());
}

#[test]
fn stride() {
    let xs: [u8, ..0]  = [];
    let mut it = Stride::from_slice(xs, 1);
    assert!(it.size_hint() == (0, Some(0)));
    assert!(it.next().is_none());

    let xs = [7i, 9, 8, 10];
    let mut it = Stride::from_slice(xs, 2);
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 7);
    assert!(*it.next().unwrap() == 8);
    assert!(it.next().is_none());

    let mut it = Stride::from_slice(xs, 2).rev();
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 7);
    assert!(it.next().is_none());

    let xs = [7i, 9, 8, 10];
    let mut it = Stride::from_slice(xs, 1);
    assert!(it.size_hint() == (4, Some(4)));
    assert!(*it.next().unwrap() == 7);
    assert!(*it.next().unwrap() == 9);
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 10);
    assert!(it.next().is_none());

    let mut it = Stride::from_slice(xs, 1).rev();
    assert!(it.size_hint() == (4, Some(4)));
    assert!(*it.next().unwrap() == 10);
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 9);
    assert!(*it.next().unwrap() == 7);
    assert!(it.next().is_none());

    let mut it = Stride::from_slice(xs, 2);
    it.swap_ends();
    assert!(it.size_hint() == (2, Some(2)));
    assert!(*it.next().unwrap() == 8);
    assert!(*it.next().unwrap() == 7);
    assert!(it.next().is_none());
}

#[test]
fn interleave() {
    let xs: [u8, ..0]  = [];
    let ys = [7u8, 9, 8, 10];
    let zs = [2u8, 77];
    let it = Interleave::new(xs.iter(), ys.iter());
    assert!(order::eq(it, ys.iter()));

    let rs = [7u8, 2, 9, 77, 8, 10];
    let it = Interleave::new(ys.iter(), zs.iter());
    assert!(order::eq(it, rs.iter()));
}

#[test]
fn boxiter() {
    let ys = vec![1,2,3i];
    let it = BoxIter::from_iter(ys.move_iter());
    assert!(it.size_hint().val0() == 3);
    assert!(order::eq(it, range(1i, 4)));
}

#[test]
fn times() {
    assert!(it::times(0).count() == 0);
    assert!(it::times(5).count() == 5);
}

#[test]
fn drain() {
    let xs = [1i,2,3];
    let mut sum = 0;
    xs.iter().map(|elt| sum += *elt).drain();
    assert!(sum == 6);
}

#[test]
fn apply() {
    let xs = [1i, 2, 3];
    let mut sum = 0;
    xs.iter().apply(|elt| sum += *elt);
    assert!(sum == 6);
}

#[test]
fn dropn() {
    let xs = [1i, 2, 3];
    let mut it = xs.iter();
    assert!(it.dropn(2) == 2);
    assert!(it.next().is_some());
    assert!(it.next().is_none());
    let mut it = xs.iter();
    assert!(it.dropn(5) == 3);
    assert!(it.next().is_none());
}

#[test]
fn intersperse() {
    let xs = ["a", "", "b", "c"];
    let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
    let text = v.concat();
    assert_eq!(text, "a, , b, c".to_string());

    let ys = [0, 1, 2, 3i];
    let mut it = ys.slice_to(0).iter().map(|x| *x).intersperse(1i);
    assert!(it.next() == None);
}

#[bench]
fn reg_iter(b: &mut test::Bencher)
{
    let xs = Vec::from_elem(20u, 20u);
    b.iter(|| for elt in xs.as_slice().iter() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs = Vec::from_elem(20u, 20u);
    b.iter(|| for elt in Stride::from_slice(xs.as_slice(), 1) {
        test::black_box(elt);
    })
}
<|endoftext|>


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

use devtools_traits::{CachedConsoleMessage, CachedConsoleMessageTypes, PAGE_ERROR, CONSOLE_API};
use devtools_traits::{EvaluateJSReply, NodeInfo, Modification, TimelineMarker, TimelineMarkerType};
use devtools_traits::{ConsoleAPI, PageError, ScriptToDevtoolsControlMsg};
use dom::bindings::conversions::jsstring_to_str;
use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::js::Root;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods};
use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods};
use dom::bindings::global::GlobalRef;
use dom::node::{Node, NodeHelpers};
use dom::window::{WindowHelpers, ScriptHelpers};
use dom::document::DocumentHelpers;
use page::{IterablePage, Page};
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use script_task::{get_page, ScriptTask};
use js::jsapi::{ObjectClassName, RootedObject, RootedValue};
use js::jsval::UndefinedValue;
use std::ffi::CStr;
use std::rc::Rc;
use std::str;
use uuid::Uuid;

#[allow(unsafe_code)]
pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<EvaluateJSReply>) {
    let cx = global.get_cx();
    let mut rval = RootedValue::new(cx, UndefinedValue());
    global.evaluate_js_on_global_with_result(&eval, rval.handle_mut());

    reply.send(if rval.ptr.is_undefined() {
        EvaluateJSReply::VoidValue
    } else if rval.ptr.is_boolean() {
        EvaluateJSReply::BooleanValue(rval.ptr.to_boolean())
    } else if rval.ptr.is_double() || rval.ptr.is_int32() {
        EvaluateJSReply::NumberValue(
            FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap())
    } else if rval.ptr.is_string() {
        EvaluateJSReply::StringValue(jsstring_to_str(cx, rval.ptr.to_string()))
    } else if rval.ptr.is_null() {
        EvaluateJSReply::NullValue
    } else {
        assert!(rval.ptr.is_object());

        let obj = RootedObject::new(cx, rval.ptr.to_object());
        let class_name = unsafe { CStr::from_ptr(ObjectClassName(cx, obj.handle())) };
        let class_name = str::from_utf8(class_name.to_bytes()).unwrap();

        EvaluateJSReply::ActorValue {
            class: class_name.to_owned(),
            uuid: Uuid::new_v4().to_string(),
        }
    }).unwrap();
}

pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
    let page = get_page(&*page, pipeline);
    let document = page.document();

    let node = NodeCast::from_ref(document.r());
    reply.send(node.summarize()).unwrap();
}

pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
    let page = get_page(&*page, pipeline);
    let document = page.document();
    let document_element = document.r().GetDocumentElement().unwrap();

    let node = NodeCast::from_ref(document_element.r());
    reply.send(node.summarize()).unwrap();
}

fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Root<Node> {
    let page = get_page(&*page, pipeline);
    let document = page.document();
    let node = NodeCast::from_ref(document.r());

    for candidate in node.traverse_preorder() {
        if candidate.r().get_unique_id() == node_id {
            return candidate;
        }
    }

    panic!("couldn't find node with unique id {}", node_id)
}

pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: IpcSender<Vec<NodeInfo>>) {
    let parent = find_node_by_unique_id(&*page, pipeline, node_id);
    let children = parent.r().children().map(|child| {
        child.r().summarize()
    }).collect();
    reply.send(children).unwrap();
}

pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: IpcSender<(f32, f32)>) {
    let node = find_node_by_unique_id(&*page, pipeline, node_id);
    let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
    let rect = elem.GetBoundingClientRect();
    let width = *rect.r().Width();
    let height = *rect.r().Height();
    reply.send((width, height)).unwrap();
}

pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
                                  message_types: CachedConsoleMessageTypes,
                                  reply: IpcSender<Vec<CachedConsoleMessage>>) {
    //TODO: check the messageTypes against a global Cache for console messages and page exceptions
    let mut messages = Vec::new();
    if message_types.contains(PAGE_ERROR) {
        //TODO: make script error reporter pass all reported errors
        //      to devtools and cache them for returning here.
        let msg = PageError {
            _type: "PageError".to_owned(),
            errorMessage: "page error test".to_owned(),
            sourceName: String::new(),
            lineText: String::new(),
            lineNumber: 0,
            columnNumber: 0,
            category: String::new(),
            timeStamp: 0,
            error: false,
            warning: false,
            exception: false,
            strict: false,
            private: false,
        };
        messages.push(CachedConsoleMessage::PageError(msg));
    }
    if message_types.contains(CONSOLE_API) {
        //TODO: do for real
        let msg = ConsoleAPI {
            _type: "ConsoleAPI".to_owned(),
            level: "error".to_owned(),
            filename: "http://localhost/~mihai/mozilla/test.html".to_owned(),
            lineNumber: 0,
            functionName: String::new(),
            timeStamp: 0,
            private: false,
            arguments: vec!["console error test".to_owned()],
        };
        messages.push(CachedConsoleMessage::ConsoleAPI(msg));
    }
    reply.send(messages).unwrap();
}

pub fn handle_modify_attribute(page: &Rc<Page>,
                               pipeline: PipelineId,
                               node_id: String,
                               modifications: Vec<Modification>) {
    let node = find_node_by_unique_id(&*page, pipeline, node_id);
    let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");

    for modification in modifications.iter(){
        match modification.newValue {
            Some(ref string) => {
                let _ = elem.SetAttribute(modification.attributeName.clone(), string.clone());
            },
            None => elem.RemoveAttribute(modification.attributeName.clone()),
        }
    }
}

pub fn handle_wants_live_notifications(global: &GlobalRef, send_notifications: bool) {
    global.set_devtools_wants_updates(send_notifications);
}

pub fn handle_set_timeline_markers(page: &Rc<Page>,
                                   script_task: &ScriptTask,
                                   marker_types: Vec<TimelineMarkerType>,
                                   reply: IpcSender<TimelineMarker>) {
    for marker_type in &marker_types {
        match *marker_type {
            TimelineMarkerType::Reflow => {
                let window = page.window();
                window.r().set_devtools_timeline_marker(TimelineMarkerType::Reflow, reply.clone());
            }
            TimelineMarkerType::DOMEvent => {
                script_task.set_devtools_timeline_marker(TimelineMarkerType::DOMEvent, reply.clone());
            }
        }
    }
}

pub fn handle_drop_timeline_markers(page: &Rc<Page>,
                                    script_task: &ScriptTask,
                                    marker_types: Vec<TimelineMarkerType>) {
    let window = page.window();
    for marker_type in &marker_types {
        match *marker_type {
            TimelineMarkerType::Reflow => {
                window.r().drop_devtools_timeline_markers();
            }
            TimelineMarkerType::DOMEvent => {
                script_task.drop_devtools_timeline_markers();
            }
        }
    }
}

pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, actor_name: String) {
    let page = page.find(id).expect("There is no such page");
    let doc = page.document();
    let devtools_sender = page.window().devtools_chan();
    doc.r().request_animation_frame(box move |time| {
        devtools_sender.unwrap()
                       .send(ScriptToDevtoolsControlMsg::FramerateTick(actor_name, time))
                       .unwrap();
    });
}
<commit_msg>fixup! Simplify devtools frame marker notification. Record each frame tick based on a single message sent from the script task that ticked.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use devtools_traits::{CachedConsoleMessage, CachedConsoleMessageTypes, PAGE_ERROR, CONSOLE_API};
use devtools_traits::{EvaluateJSReply, NodeInfo, Modification, TimelineMarker, TimelineMarkerType};
use devtools_traits::{ConsoleAPI, PageError, ScriptToDevtoolsControlMsg};
use dom::bindings::conversions::jsstring_to_str;
use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::js::Root;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods};
use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods};
use dom::bindings::global::GlobalRef;
use dom::node::{Node, NodeHelpers};
use dom::window::{WindowHelpers, ScriptHelpers};
use dom::document::DocumentHelpers;
use page::{IterablePage, Page};
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use script_task::{get_page, ScriptTask};
use js::jsapi::{ObjectClassName, RootedObject, RootedValue};
use js::jsval::UndefinedValue;
use std::ffi::CStr;
use std::rc::Rc;
use std::str;
use uuid::Uuid;

#[allow(unsafe_code)]
pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<EvaluateJSReply>) {
    let cx = global.get_cx();
    let mut rval = RootedValue::new(cx, UndefinedValue());
    global.evaluate_js_on_global_with_result(&eval, rval.handle_mut());

    reply.send(if rval.ptr.is_undefined() {
        EvaluateJSReply::VoidValue
    } else if rval.ptr.is_boolean() {
        EvaluateJSReply::BooleanValue(rval.ptr.to_boolean())
    } else if rval.ptr.is_double() || rval.ptr.is_int32() {
        EvaluateJSReply::NumberValue(
            FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap())
    } else if rval.ptr.is_string() {
        EvaluateJSReply::StringValue(jsstring_to_str(cx, rval.ptr.to_string()))
    } else if rval.ptr.is_null() {
        EvaluateJSReply::NullValue
    } else {
        assert!(rval.ptr.is_object());

        let obj = RootedObject::new(cx, rval.ptr.to_object());
        let class_name = unsafe { CStr::from_ptr(ObjectClassName(cx, obj.handle())) };
        let class_name = str::from_utf8(class_name.to_bytes()).unwrap();

        EvaluateJSReply::ActorValue {
            class: class_name.to_owned(),
            uuid: Uuid::new_v4().to_string(),
        }
    }).unwrap();
}

pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
    let page = get_page(&*page, pipeline);
    let document = page.document();

    let node = NodeCast::from_ref(document.r());
    reply.send(node.summarize()).unwrap();
}

pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
    let page = get_page(&*page, pipeline);
    let document = page.document();
    let document_element = document.r().GetDocumentElement().unwrap();

    let node = NodeCast::from_ref(document_element.r());
    reply.send(node.summarize()).unwrap();
}

fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Root<Node> {
    let page = get_page(&*page, pipeline);
    let document = page.document();
    let node = NodeCast::from_ref(document.r());

    for candidate in node.traverse_preorder() {
        if candidate.r().get_unique_id() == node_id {
            return candidate;
        }
    }

    panic!("couldn't find node with unique id {}", node_id)
}

pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: IpcSender<Vec<NodeInfo>>) {
    let parent = find_node_by_unique_id(&*page, pipeline, node_id);
    let children = parent.r().children().map(|child| {
        child.r().summarize()
    }).collect();
    reply.send(children).unwrap();
}

pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: IpcSender<(f32, f32)>) {
    let node = find_node_by_unique_id(&*page, pipeline, node_id);
    let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
    let rect = elem.GetBoundingClientRect();
    let width = *rect.r().Width();
    let height = *rect.r().Height();
    reply.send((width, height)).unwrap();
}

pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
                                  message_types: CachedConsoleMessageTypes,
                                  reply: IpcSender<Vec<CachedConsoleMessage>>) {
    //TODO: check the messageTypes against a global Cache for console messages and page exceptions
    let mut messages = Vec::new();
    if message_types.contains(PAGE_ERROR) {
        //TODO: make script error reporter pass all reported errors
        //      to devtools and cache them for returning here.
        let msg = PageError {
            _type: "PageError".to_owned(),
            errorMessage: "page error test".to_owned(),
            sourceName: String::new(),
            lineText: String::new(),
            lineNumber: 0,
            columnNumber: 0,
            category: String::new(),
            timeStamp: 0,
            error: false,
            warning: false,
            exception: false,
            strict: false,
            private: false,
        };
        messages.push(CachedConsoleMessage::PageError(msg));
    }
    if message_types.contains(CONSOLE_API) {
        //TODO: do for real
        let msg = ConsoleAPI {
            _type: "ConsoleAPI".to_owned(),
            level: "error".to_owned(),
            filename: "http://localhost/~mihai/mozilla/test.html".to_owned(),
            lineNumber: 0,
            functionName: String::new(),
            timeStamp: 0,
            private: false,
            arguments: vec!["console error test".to_owned()],
        };
        messages.push(CachedConsoleMessage::ConsoleAPI(msg));
    }
    reply.send(messages).unwrap();
}

pub fn handle_modify_attribute(page: &Rc<Page>,
                               pipeline: PipelineId,
                               node_id: String,
                               modifications: Vec<Modification>) {
    let node = find_node_by_unique_id(&*page, pipeline, node_id);
    let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");

    for modification in modifications.iter(){
        match modification.newValue {
            Some(ref string) => {
                let _ = elem.SetAttribute(modification.attributeName.clone(), string.clone());
            },
            None => elem.RemoveAttribute(modification.attributeName.clone()),
        }
    }
}

pub fn handle_wants_live_notifications(global: &GlobalRef, send_notifications: bool) {
    global.set_devtools_wants_updates(send_notifications);
}

pub fn handle_set_timeline_markers(page: &Rc<Page>,
                                   script_task: &ScriptTask,
                                   marker_types: Vec<TimelineMarkerType>,
                                   reply: IpcSender<TimelineMarker>) {
    for marker_type in &marker_types {
        match *marker_type {
            TimelineMarkerType::Reflow => {
                let window = page.window();
                window.r().set_devtools_timeline_marker(TimelineMarkerType::Reflow, reply.clone());
            }
            TimelineMarkerType::DOMEvent => {
                script_task.set_devtools_timeline_marker(TimelineMarkerType::DOMEvent, reply.clone());
            }
        }
    }
}

pub fn handle_drop_timeline_markers(page: &Rc<Page>,
                                    script_task: &ScriptTask,
                                    marker_types: Vec<TimelineMarkerType>) {
    let window = page.window();
    for marker_type in &marker_types {
        match *marker_type {
            TimelineMarkerType::Reflow => {
                window.r().drop_devtools_timeline_markers();
            }
            TimelineMarkerType::DOMEvent => {
                script_task.drop_devtools_timeline_markers();
            }
        }
    }
}

pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, actor_name: String) {
    let page = page.find(id).expect("There is no such page");
    let doc = page.document();
    let devtools_sender = page.window().devtools_chan().unwrap();
    doc.r().request_animation_frame(box move |time| {
        let msg = ScriptToDevtoolsControlMsg::FramerateTick(actor_name, time);
        devtools_sender.send(msg).unwrap();
    });
}
<|endoftext|>


<commit_before>// Copyright 2022 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.

pub mod vfio_wrapper;

use std::cell::RefCell;
use std::collections::BTreeMap;
use std::fs::File;
use std::rc::Rc;
use std::sync::Arc;

use base::error;
use base::MemoryMappingBuilder;
use base::TubeError;
use cros_async::AsyncTube;
use cros_async::Executor;
use hypervisor::MemSlot;
use sync::Mutex;
use vm_control::VirtioIOMMURequest;
use vm_control::VirtioIOMMUResponse;
use vm_control::VirtioIOMMUVfioCommand;
use vm_control::VirtioIOMMUVfioResult;

use self::vfio_wrapper::VfioWrapper;
use crate::virtio::iommu::ipc_memory_mapper::IommuRequest;
use crate::virtio::iommu::ipc_memory_mapper::IommuResponse;
use crate::virtio::iommu::DmabufRegionEntry;
use crate::virtio::iommu::Result;
use crate::virtio::iommu::State;
use crate::virtio::IommuError;
use crate::VfioContainer;

const VIRTIO_IOMMU_PAGE_SHIFT: u32 = 12;

impl State {
    pub(in crate::virtio::iommu) fn handle_add_vfio_device(
        &mut self,
        endpoint_addr: u32,
        wrapper: VfioWrapper,
    ) -> VirtioIOMMUVfioResult {
        let exists = |endpoint_addr: u32| -> bool {
            for endpoints_range in self.hp_endpoints_ranges.iter() {
                if endpoints_range.contains(&endpoint_addr) {
                    return true;
                }
            }
            false
        };

        if !exists(endpoint_addr) {
            return VirtioIOMMUVfioResult::NotInPCIRanges;
        }

        self.endpoints
            .insert(endpoint_addr, Arc::new(Mutex::new(Box::new(wrapper))));
        VirtioIOMMUVfioResult::Ok
    }

    pub(in crate::virtio::iommu) fn handle_del_vfio_device(
        &mut self,
        pci_address: u32,
    ) -> VirtioIOMMUVfioResult {
        if self.endpoints.remove(&pci_address).is_none() {
            error!("There is no vfio container of {}", pci_address);
            return VirtioIOMMUVfioResult::NoSuchDevice;
        }
        if let Some(domain) = self.endpoint_map.remove(&pci_address) {
            self.domain_map.remove(&domain);
        }
        VirtioIOMMUVfioResult::Ok
    }

    pub(in crate::virtio::iommu) fn handle_map_dmabuf(
        &mut self,
        mem_slot: MemSlot,
        gfn: u64,
        size: u64,
        dma_buf: File,
    ) -> VirtioIOMMUVfioResult {
        let mmap = match MemoryMappingBuilder::new(size as usize)
            .from_file(&dma_buf)
            .build()
        {
            Ok(v) => v,
            Err(_) => {
                error!("failed to mmap dma_buf");
                return VirtioIOMMUVfioResult::InvalidParam;
            }
        };
        self.dmabuf_mem.insert(
            gfn << VIRTIO_IOMMU_PAGE_SHIFT,
            DmabufRegionEntry {
                mmap,
                mem_slot,
                len: size,
            },
        );

        VirtioIOMMUVfioResult::Ok
    }

    pub(in crate::virtio::iommu) fn handle_unmap_dmabuf(
        &mut self,
        mem_slot: MemSlot,
    ) -> VirtioIOMMUVfioResult {
        if let Some(range) = self
            .dmabuf_mem
            .iter()
            .find(|(_, dmabuf_entry)| dmabuf_entry.mem_slot == mem_slot)
            .map(|entry| *entry.0)
        {
            self.dmabuf_mem.remove(&range);
            VirtioIOMMUVfioResult::Ok
        } else {
            VirtioIOMMUVfioResult::NoSuchMappedDmabuf
        }
    }

    pub(in crate::virtio::iommu) fn handle_vfio(
        &mut self,
        vfio_cmd: VirtioIOMMUVfioCommand,
    ) -> VirtioIOMMUResponse {
        use VirtioIOMMUVfioCommand::*;
        let vfio_result = match vfio_cmd {
            VfioDeviceAdd {
                wrapper_id,
                container,
                endpoint_addr,
            } => match VfioContainer::new_from_container(container) {
                Ok(vfio_container) => {
                    let wrapper =
                        VfioWrapper::new_with_id(vfio_container, wrapper_id, self.mem.clone());
                    self.handle_add_vfio_device(endpoint_addr, wrapper)
                }
                Err(e) => {
                    error!("failed to verify the new container: {}", e);
                    VirtioIOMMUVfioResult::NoAvailableContainer
                }
            },
            VfioDeviceDel { endpoint_addr } => self.handle_del_vfio_device(endpoint_addr),
            VfioDmabufMap {
                mem_slot,
                gfn,
                size,
                dma_buf,
            } => self.handle_map_dmabuf(mem_slot, gfn, size, File::from(dma_buf)),
            VfioDmabufUnmap(mem_slot) => self.handle_unmap_dmabuf(mem_slot),
        };
        VirtioIOMMUResponse::VfioResponse(vfio_result)
    }
}

pub(in crate::virtio::iommu) async fn handle_command_tube(
    state: &Rc<RefCell<State>>,
    command_tube: AsyncTube,
) -> Result<()> {
    loop {
        match command_tube.next::<VirtioIOMMURequest>().await {
            Ok(command) => {
                let response: VirtioIOMMUResponse = match command {
                    VirtioIOMMURequest::VfioCommand(vfio_cmd) => {
                        state.borrow_mut().handle_vfio(vfio_cmd)
                    }
                };
                if let Err(e) = command_tube.send(response).await {
                    error!("{}", IommuError::VirtioIOMMUResponseError(e));
                }
            }
            Err(e) => {
                return Err(IommuError::VirtioIOMMUReqError(e));
            }
        }
    }
}

pub(in crate::virtio::iommu) async fn handle_translate_request(
    ex: &Executor,
    state: &Rc<RefCell<State>>,
    request_tube: Option<AsyncTube>,
    response_tubes: Option<BTreeMap<u32, AsyncTube>>,
) -> Result<()> {
    let request_tube = match request_tube {
        Some(r) => r,
        None => {
            let () = futures::future::pending().await;
            return Ok(());
        }
    };
    let response_tubes = response_tubes.unwrap();
    loop {
        let req: IommuRequest = match request_tube.next().await {
            Ok(req) => req,
            Err(TubeError::Disconnected) => {
                // This means the process on the other side of the tube went away. That's
                // not a problem with virtio-iommu itself, so just exit this callback
                // and wait for crosvm to exit.
                return Ok(());
            }
            Err(e) => {
                return Err(IommuError::Tube(e));
            }
        };
        let state = state.borrow_mut();
        let resp = match state.endpoints.get(&req.get_endpoint_id()) {
            Some(mapper) => match req {
                IommuRequest::Export { iova, size, .. } => {
                    mapper.lock().export(iova, size).map(IommuResponse::Export)
                }
                IommuRequest::Release { iova, size, .. } => mapper
                    .lock()
                    .release(iova, size)
                    .map(|_| IommuResponse::Release),
                IommuRequest::StartExportSession { .. } => mapper
                    .lock()
                    .start_export_session(ex)
                    .map(IommuResponse::StartExportSession),
            },
            None => {
                error!("endpoint {} not found", req.get_endpoint_id());
                continue;
            }
        };
        let resp: IommuResponse = match resp {
            Ok(resp) => resp,
            Err(e) => IommuResponse::Err(format!("{:?}", e)),
        };
        response_tubes
            .get(&req.get_endpoint_id())
            .unwrap()
            .send(resp)
            .await
            .map_err(IommuError::Tube)?;
    }
}
<commit_msg>devices: virtio-iommu: do not hold RefCell across await<commit_after>// Copyright 2022 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.

pub mod vfio_wrapper;

use std::cell::RefCell;
use std::collections::BTreeMap;
use std::fs::File;
use std::rc::Rc;
use std::sync::Arc;

use base::error;
use base::MemoryMappingBuilder;
use base::TubeError;
use cros_async::AsyncTube;
use cros_async::Executor;
use hypervisor::MemSlot;
use sync::Mutex;
use vm_control::VirtioIOMMURequest;
use vm_control::VirtioIOMMUResponse;
use vm_control::VirtioIOMMUVfioCommand;
use vm_control::VirtioIOMMUVfioResult;

use self::vfio_wrapper::VfioWrapper;
use crate::virtio::iommu::ipc_memory_mapper::IommuRequest;
use crate::virtio::iommu::ipc_memory_mapper::IommuResponse;
use crate::virtio::iommu::DmabufRegionEntry;
use crate::virtio::iommu::Result;
use crate::virtio::iommu::State;
use crate::virtio::IommuError;
use crate::VfioContainer;

const VIRTIO_IOMMU_PAGE_SHIFT: u32 = 12;

impl State {
    pub(in crate::virtio::iommu) fn handle_add_vfio_device(
        &mut self,
        endpoint_addr: u32,
        wrapper: VfioWrapper,
    ) -> VirtioIOMMUVfioResult {
        let exists = |endpoint_addr: u32| -> bool {
            for endpoints_range in self.hp_endpoints_ranges.iter() {
                if endpoints_range.contains(&endpoint_addr) {
                    return true;
                }
            }
            false
        };

        if !exists(endpoint_addr) {
            return VirtioIOMMUVfioResult::NotInPCIRanges;
        }

        self.endpoints
            .insert(endpoint_addr, Arc::new(Mutex::new(Box::new(wrapper))));
        VirtioIOMMUVfioResult::Ok
    }

    pub(in crate::virtio::iommu) fn handle_del_vfio_device(
        &mut self,
        pci_address: u32,
    ) -> VirtioIOMMUVfioResult {
        if self.endpoints.remove(&pci_address).is_none() {
            error!("There is no vfio container of {}", pci_address);
            return VirtioIOMMUVfioResult::NoSuchDevice;
        }
        if let Some(domain) = self.endpoint_map.remove(&pci_address) {
            self.domain_map.remove(&domain);
        }
        VirtioIOMMUVfioResult::Ok
    }

    pub(in crate::virtio::iommu) fn handle_map_dmabuf(
        &mut self,
        mem_slot: MemSlot,
        gfn: u64,
        size: u64,
        dma_buf: File,
    ) -> VirtioIOMMUVfioResult {
        let mmap = match MemoryMappingBuilder::new(size as usize)
            .from_file(&dma_buf)
            .build()
        {
            Ok(v) => v,
            Err(_) => {
                error!("failed to mmap dma_buf");
                return VirtioIOMMUVfioResult::InvalidParam;
            }
        };
        self.dmabuf_mem.insert(
            gfn << VIRTIO_IOMMU_PAGE_SHIFT,
            DmabufRegionEntry {
                mmap,
                mem_slot,
                len: size,
            },
        );

        VirtioIOMMUVfioResult::Ok
    }

    pub(in crate::virtio::iommu) fn handle_unmap_dmabuf(
        &mut self,
        mem_slot: MemSlot,
    ) -> VirtioIOMMUVfioResult {
        if let Some(range) = self
            .dmabuf_mem
            .iter()
            .find(|(_, dmabuf_entry)| dmabuf_entry.mem_slot == mem_slot)
            .map(|entry| *entry.0)
        {
            self.dmabuf_mem.remove(&range);
            VirtioIOMMUVfioResult::Ok
        } else {
            VirtioIOMMUVfioResult::NoSuchMappedDmabuf
        }
    }

    pub(in crate::virtio::iommu) fn handle_vfio(
        &mut self,
        vfio_cmd: VirtioIOMMUVfioCommand,
    ) -> VirtioIOMMUResponse {
        use VirtioIOMMUVfioCommand::*;
        let vfio_result = match vfio_cmd {
            VfioDeviceAdd {
                wrapper_id,
                container,
                endpoint_addr,
            } => match VfioContainer::new_from_container(container) {
                Ok(vfio_container) => {
                    let wrapper =
                        VfioWrapper::new_with_id(vfio_container, wrapper_id, self.mem.clone());
                    self.handle_add_vfio_device(endpoint_addr, wrapper)
                }
                Err(e) => {
                    error!("failed to verify the new container: {}", e);
                    VirtioIOMMUVfioResult::NoAvailableContainer
                }
            },
            VfioDeviceDel { endpoint_addr } => self.handle_del_vfio_device(endpoint_addr),
            VfioDmabufMap {
                mem_slot,
                gfn,
                size,
                dma_buf,
            } => self.handle_map_dmabuf(mem_slot, gfn, size, File::from(dma_buf)),
            VfioDmabufUnmap(mem_slot) => self.handle_unmap_dmabuf(mem_slot),
        };
        VirtioIOMMUResponse::VfioResponse(vfio_result)
    }
}

pub(in crate::virtio::iommu) async fn handle_command_tube(
    state: &Rc<RefCell<State>>,
    command_tube: AsyncTube,
) -> Result<()> {
    loop {
        match command_tube.next::<VirtioIOMMURequest>().await {
            Ok(command) => {
                let response: VirtioIOMMUResponse = match command {
                    VirtioIOMMURequest::VfioCommand(vfio_cmd) => {
                        state.borrow_mut().handle_vfio(vfio_cmd)
                    }
                };
                if let Err(e) = command_tube.send(response).await {
                    error!("{}", IommuError::VirtioIOMMUResponseError(e));
                }
            }
            Err(e) => {
                return Err(IommuError::VirtioIOMMUReqError(e));
            }
        }
    }
}

pub(in crate::virtio::iommu) async fn handle_translate_request(
    ex: &Executor,
    state: &Rc<RefCell<State>>,
    request_tube: Option<AsyncTube>,
    response_tubes: Option<BTreeMap<u32, AsyncTube>>,
) -> Result<()> {
    let request_tube = match request_tube {
        Some(r) => r,
        None => {
            let () = futures::future::pending().await;
            return Ok(());
        }
    };
    let response_tubes = response_tubes.unwrap();
    loop {
        let req: IommuRequest = match request_tube.next().await {
            Ok(req) => req,
            Err(TubeError::Disconnected) => {
                // This means the process on the other side of the tube went away. That's
                // not a problem with virtio-iommu itself, so just exit this callback
                // and wait for crosvm to exit.
                return Ok(());
            }
            Err(e) => {
                return Err(IommuError::Tube(e));
            }
        };
        let resp = if let Some(mapper) = state.borrow().endpoints.get(&req.get_endpoint_id()) {
            match req {
                IommuRequest::Export { iova, size, .. } => {
                    mapper.lock().export(iova, size).map(IommuResponse::Export)
                }
                IommuRequest::Release { iova, size, .. } => mapper
                    .lock()
                    .release(iova, size)
                    .map(|_| IommuResponse::Release),
                IommuRequest::StartExportSession { .. } => mapper
                    .lock()
                    .start_export_session(ex)
                    .map(IommuResponse::StartExportSession),
            }
        } else {
            error!("endpoint {} not found", req.get_endpoint_id());
            continue;
        };
        let resp: IommuResponse = match resp {
            Ok(resp) => resp,
            Err(e) => IommuResponse::Err(format!("{:?}", e)),
        };
        response_tubes
            .get(&req.get_endpoint_id())
            .unwrap()
            .send(resp)
            .await
            .map_err(IommuError::Tube)?;
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate syn;

use syn::{
    parse::{Parse, ParseStream},
    parse::discouraged::Speculative,
    Result,
};

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_between_sources() {
    // don't do this ever this is very unsafe and fails anyway
    struct Smuggled(ParseStream<'static>);
    impl Parse for Smuggled {
        fn parse(input: ParseStream) -> Result<Self> {
            Ok(Smuggled(unsafe { std::mem::transmute_copy(input) }))
        }
    }

    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let Smuggled(fork) = syn::parse_str("").unwrap();
            input.advance_to(fork);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("").unwrap();
}

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_between_brackets() {
    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let a;
            let b;
            parenthesized!(a in input);
            parenthesized!(b in input);
            a.advance_to(&b);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("()()").unwrap();
}
<commit_msg>Add speculative smuggling test into bracket context<commit_after>#[macro_use]
extern crate syn;

use syn::{
    parse::{Parse, ParseStream},
    parse::discouraged::Speculative,
    Result,
};

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_between_sources() {
    // don't do this ever this is very unsafe and fails anyway
    struct Smuggled(ParseStream<'static>);
    impl Parse for Smuggled {
        fn parse(input: ParseStream) -> Result<Self> {
            Ok(Smuggled(unsafe { std::mem::transmute_copy(input) }))
        }
    }

    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let Smuggled(fork) = syn::parse_str("").unwrap();
            input.advance_to(fork);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("").unwrap();
}

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_between_brackets() {
    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let a;
            let b;
            parenthesized!(a in input);
            parenthesized!(b in input);
            a.advance_to(&b);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("()()").unwrap();
}

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_into_brackets() {
    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let a;
            parenthesized!(a in input);
            input.advance_to(&a);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("()").unwrap();
}
<|endoftext|>


<commit_before>use cfg;
use clap::ArgMatches;
use std::collections::HashSet;

pub fn actions_get(matches: &ArgMatches) -> HashSet<String> {
    let mut hs_actions = HashSet::<String>::new();

    if let Some(_) = matches.values_of("list-provides") {
        let bill = String::from("load-jobs");
        hs_actions.insert(bill);
        let list_provides = String::from("list-provides");
        hs_actions.insert(list_provides);
    }
    if let Some(_) = matches.values_of("list-target") {
        let bill = String::from("load-jobs");
        hs_actions.insert(bill);
        let list_provides = String::from("list-target");
        hs_actions.insert(list_provides);
    }
    if let Some(_) = matches.values_of("session") {
        let bill = String::from("load-jobs");
        hs_actions.insert(bill);
        let str_load_scripts = String::from("load-scripts");
        hs_actions.insert(str_load_scripts);
        let session = String::from("session");
        hs_actions.insert(session);
    }
    return hs_actions;
}

pub fn cfg_actions_update_clap(fred: &mut cfg::Config, matches: &ArgMatches) {
    if let Some(_) = matches.values_of("list-provides") {
        fred.actions.insert(cfg::Action::DbConnect);
        fred.actions.insert(cfg::Action::LoadJobs);
        fred.actions.insert(cfg::Action::ListProvides);
    }
    if let Some(_) = matches.values_of("list-target") {
        fred.actions.insert(cfg::Action::DbConnect);
        fred.actions.insert(cfg::Action::LoadJobs);
        fred.actions.insert(cfg::Action::ListTarget);
    }
    if let Some(_) = matches.values_of("session") {
        fred.actions.insert(cfg::Action::DbConnect);
        fred.actions.insert(cfg::Action::LoadJobs);
        fred.actions.insert(cfg::Action::LoadScripts);
        fred.actions.insert(cfg::Action::SessionStart);
    }
    if let Some(jobs_dir_it) = matches.values_of("dir-jobs") {
        for jobs_dir in jobs_dir_it {
            fred.path_jobs.push(jobs_dir.to_string());
        }
    }
    if let Some(jobs_dir_it) = matches.values_of("dir-sh") {
        for jobs_dir in jobs_dir_it {
            fred.path_shell.push(jobs_dir.to_string());
        }
    }

    if let Some(jobs_dir_it) = matches.values_of("dir-py") {
        for jobs_dir in jobs_dir_it {
            fred.path_python.push(jobs_dir.to_string());
        }
    }
    if fred.actions.contains(&cfg::Action::LoadScripts) {}

    if let Some(in_v) = matches.values_of("rdbms") {
        for enviroment_variable in in_v {
            fred.rdbms_connection_uri = Some(enviroment_variable.to_string());
        }
    } else {
        fred.rdbms_connection_uri = None;
    }
}
<commit_msg>cfg-to-arc:Arc<Mutex<cfg::Config>> Conversion<commit_after>use cfg;
use clap::ArgMatches;
use std::collections::HashSet;
use std::sync::Arc;
use std::sync::Mutex;

pub fn actions_get(matches: &ArgMatches) -> HashSet<String> {
    let mut hs_actions = HashSet::<String>::new();

    if let Some(_) = matches.values_of("list-provides") {
        let bill = String::from("load-jobs");
        hs_actions.insert(bill);
        let list_provides = String::from("list-provides");
        hs_actions.insert(list_provides);
    }
    if let Some(_) = matches.values_of("list-target") {
        let bill = String::from("load-jobs");
        hs_actions.insert(bill);
        let list_provides = String::from("list-target");
        hs_actions.insert(list_provides);
    }
    if let Some(_) = matches.values_of("session") {
        let bill = String::from("load-jobs");
        hs_actions.insert(bill);
        let str_load_scripts = String::from("load-scripts");
        hs_actions.insert(str_load_scripts);
        let session = String::from("session");
        hs_actions.insert(session);
    }
    return hs_actions;
}

pub fn cfg_actions_update_clap(freds: &Arc<Mutex<cfg::Config>>, matches: &ArgMatches) {
    let mut fred = freds.lock().unwrap();
    if let Some(_) = matches.values_of("list-provides") {
        fred.actions.insert(cfg::Action::DbConnect);
        fred.actions.insert(cfg::Action::LoadJobs);
        fred.actions.insert(cfg::Action::ListProvides);
    }
    if let Some(_) = matches.values_of("list-target") {
        fred.actions.insert(cfg::Action::DbConnect);
        fred.actions.insert(cfg::Action::LoadJobs);
        fred.actions.insert(cfg::Action::ListTarget);
    }
    if let Some(_) = matches.values_of("session") {
        fred.actions.insert(cfg::Action::DbConnect);
        fred.actions.insert(cfg::Action::LoadJobs);
        fred.actions.insert(cfg::Action::LoadScripts);
        fred.actions.insert(cfg::Action::SessionStart);
    }
    if let Some(jobs_dir_it) = matches.values_of("dir-jobs") {
        for jobs_dir in jobs_dir_it {
            fred.path_jobs.push(jobs_dir.to_string());
        }
    }
    if let Some(jobs_dir_it) = matches.values_of("dir-sh") {
        for jobs_dir in jobs_dir_it {
            fred.path_shell.push(jobs_dir.to_string());
        }
    }

    if let Some(jobs_dir_it) = matches.values_of("dir-py") {
        for jobs_dir in jobs_dir_it {
            fred.path_python.push(jobs_dir.to_string());
        }
    }
    if fred.actions.contains(&cfg::Action::LoadScripts) {}

    if let Some(in_v) = matches.values_of("rdbms") {
        for enviroment_variable in in_v {
            fred.rdbms_connection_uri = Some(enviroment_variable.to_string());
        }
    } else {
        fred.rdbms_connection_uri = None;
    }
}
<|endoftext|>


<commit_before>use utils::json::{JsonEncodable, JsonDecodable};

#[derive(Serialize, Deserialize, Clone)]
pub struct MyDidInfo {
    pub did: Option<String>,
    pub seed: Option<String>,
    pub crypto_type: Option<String>
}

impl MyDidInfo {
    pub fn new(did: Option<String>, seed: Option<String>, crypto_type: Option<String>) -> MyDidInfo {
        MyDidInfo {
            did,
            seed,
            crypto_type
        }
    }
}

impl JsonEncodable for MyDidInfo {}

impl<'a> JsonDecodable<'a> for MyDidInfo {}

#[derive(Serialize, Deserialize)]
pub struct MyKyesInfo {
    pub seed: Option<String>,
    pub crypto_type: Option<String>
}

impl MyKyesInfo {
    pub fn new(seed: Option<String>, crypto_type: Option<String>) -> MyKyesInfo {
        MyKyesInfo {
            seed: seed,
            crypto_type: crypto_type
        }
    }
}

impl JsonEncodable for MyKyesInfo {}

impl<'a> JsonDecodable<'a> for MyKyesInfo {}

#[derive(Serialize, Deserialize, Clone)]
pub struct MyDid {
    pub did: String,
    pub crypto_type: String,
    pub pk: String,
    pub sk: String,
    pub verkey: String,
    pub signkey: String
}

impl MyDid {
    pub fn new(did: String, crypto_type: String, pk: String, sk: String, verkey: String, signkey: String) -> MyDid {
        MyDid {
            did: did,
            crypto_type: crypto_type,
            pk: pk,
            sk: sk,
            verkey: verkey,
            signkey: signkey
        }
    }
}

impl JsonEncodable for MyDid {}

impl<'a> JsonDecodable<'a> for MyDid {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDidInfo {
    pub did: String,
    pub crypto_type: Option<String>,
    pub verkey: Option<String>
}

impl TheirDidInfo {
    pub fn new(did: String, crypto_type: Option<String>, verkey: Option<String>) -> TheirDidInfo {
        TheirDidInfo {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey
        }
    }
}

impl JsonEncodable for TheirDidInfo {}

impl<'a> JsonDecodable<'a> for TheirDidInfo {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDid {
    pub did: String,
    pub crypto_type: String,
    pub verkey: Option<String>,
    pub pk: Option<String>
}

impl TheirDid {
    pub fn new(did: String, crypto_type: String, verkey: Option<String>, pk: Option<String>) -> TheirDid {
        TheirDid {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey,
            pk: pk
        }
    }
}

impl JsonEncodable for TheirDid {}

impl<'a> JsonDecodable<'a> for TheirDid {}<commit_msg>* Avoid structs shortage to be comatible with older rust versions<commit_after>use utils::json::{JsonEncodable, JsonDecodable};

#[derive(Serialize, Deserialize, Clone)]
pub struct MyDidInfo {
    pub did: Option<String>,
    pub seed: Option<String>,
    pub crypto_type: Option<String>
}

impl MyDidInfo {
    pub fn new(did: Option<String>, seed: Option<String>, crypto_type: Option<String>) -> MyDidInfo {
        MyDidInfo {
            did: did,
            seed: seed,
            crypto_type: crypto_type
        }
    }
}

impl JsonEncodable for MyDidInfo {}

impl<'a> JsonDecodable<'a> for MyDidInfo {}

#[derive(Serialize, Deserialize)]
pub struct MyKyesInfo {
    pub seed: Option<String>,
    pub crypto_type: Option<String>
}

impl MyKyesInfo {
    pub fn new(seed: Option<String>, crypto_type: Option<String>) -> MyKyesInfo {
        MyKyesInfo {
            seed: seed,
            crypto_type: crypto_type
        }
    }
}

impl JsonEncodable for MyKyesInfo {}

impl<'a> JsonDecodable<'a> for MyKyesInfo {}

#[derive(Serialize, Deserialize, Clone)]
pub struct MyDid {
    pub did: String,
    pub crypto_type: String,
    pub pk: String,
    pub sk: String,
    pub verkey: String,
    pub signkey: String
}

impl MyDid {
    pub fn new(did: String, crypto_type: String, pk: String, sk: String, verkey: String, signkey: String) -> MyDid {
        MyDid {
            did: did,
            crypto_type: crypto_type,
            pk: pk,
            sk: sk,
            verkey: verkey,
            signkey: signkey
        }
    }
}

impl JsonEncodable for MyDid {}

impl<'a> JsonDecodable<'a> for MyDid {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDidInfo {
    pub did: String,
    pub crypto_type: Option<String>,
    pub verkey: Option<String>
}

impl TheirDidInfo {
    pub fn new(did: String, crypto_type: Option<String>, verkey: Option<String>) -> TheirDidInfo {
        TheirDidInfo {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey
        }
    }
}

impl JsonEncodable for TheirDidInfo {}

impl<'a> JsonDecodable<'a> for TheirDidInfo {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDid {
    pub did: String,
    pub crypto_type: String,
    pub verkey: Option<String>,
    pub pk: Option<String>
}

impl TheirDid {
    pub fn new(did: String, crypto_type: String, verkey: Option<String>, pk: Option<String>) -> TheirDid {
        TheirDid {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey,
            pk: pk
        }
    }
}

impl JsonEncodable for TheirDid {}

impl<'a> JsonDecodable<'a> for TheirDid {}<|endoftext|>