<commit_before>extern crate android_glue;
extern crate native;

use libc;
use {CreationError, OsError, Event, WindowBuilder};

pub struct Window {
    display: ffi::egl::types::EGLDisplay,
    context: ffi::egl::types::EGLContext,
    surface: ffi::egl::types::EGLSurface,
}

pub struct MonitorID;

mod ffi;

compile_warning!("The Android implementation is not fully working yet")

pub fn get_available_monitors() -> Vec<MonitorID> {
    vec![ MonitorID ]
}

pub fn get_primary_monitor() -> MonitorID {
    MonitorID
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("Primary".to_string())
    }

    pub fn get_dimensions(&self) -> (uint, uint) {
        unimplemented!()
    }
}

impl Window {
    pub fn new(_builder: WindowBuilder) -> Result<Window, CreationError> {
        use std::{mem, ptr};

        let native_window = unsafe { android_glue::get_native_window() };
        if native_window.is_null() {
            return Err(OsError(format!("Android's native window is null")));
        }

        let display = unsafe {
            let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
            if display.is_null() {
                return Err(OsError("No EGL display connection available".to_string()));
            }
            display
        };

        android_glue::write_log("eglGetDisplay succeeded");

        let (_major, _minor) = unsafe {
            let mut major: ffi::egl::types::EGLint = mem::uninitialized();
            let mut minor: ffi::egl::types::EGLint = mem::uninitialized();

            if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
                return Err(OsError(format!("eglInitialize failed")))
            }

            (major, minor)
        };

        android_glue::write_log("eglInitialize succeeded");

        let config = unsafe {
            let attribute_list = [
                ffi::egl::RED_SIZE as i32, 1,
                ffi::egl::GREEN_SIZE as i32, 1,
                ffi::egl::BLUE_SIZE as i32, 1,
                ffi::egl::NONE as i32
            ];

            let mut num_config: ffi::egl::types::EGLint = mem::uninitialized();
            let mut config: ffi::egl::types::EGLConfig = mem::uninitialized();
            if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
                &mut num_config) == 0
            {
                return Err(OsError(format!("eglChooseConfig failed")))
            }

            if num_config <= 0 {
                return Err(OsError(format!("eglChooseConfig returned no available config")))
            }

            config
        };

        android_glue::write_log("eglChooseConfig succeeded");

        let context = unsafe {
            let context = ffi::egl::CreateContext(display, config, ptr::null(), ptr::null());
            if context.is_null() {
                return Err(OsError(format!("eglCreateContext failed")))
            }
            context
        };

        android_glue::write_log("eglCreateContext succeeded");

        let surface = unsafe {
            let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
            if surface.is_null() {
                return Err(OsError(format!("eglCreateWindowSurface failed")))
            }
            surface
        };

        android_glue::write_log("eglCreateWindowSurface succeeded");

        Ok(Window {
            display: display,
            context: context,
            surface: surface,
        })
    }

    pub fn is_closed(&self) -> bool {
        false
    }

    pub fn set_title(&self, _: &str) {
    }

    pub fn show(&self) {
    }

    pub fn hide(&self) {
    }

    pub fn get_position(&self) -> Option<(int, int)> {
        None
    }

    pub fn set_position(&self, _x: int, _y: int) {
    }

    pub fn get_inner_size(&self) -> Option<(uint, uint)> {
        let native_window = unsafe { android_glue::get_native_window() };

        if native_window.is_null() {
            None
        } else {
            Some((
                unsafe { ffi::ANativeWindow_getWidth(native_window) } as uint,
                unsafe { ffi::ANativeWindow_getHeight(native_window) } as uint
            ))
        }
    }

    pub fn get_outer_size(&self) -> Option<(uint, uint)> {
        self.get_inner_size()
    }

    pub fn set_inner_size(&self, _x: uint, _y: uint) {
    }

    pub fn poll_events(&self) -> Vec<Event> {
        use std::time::Duration;
        use std::io::timer;
        timer::sleep(Duration::milliseconds(16));
        Vec::new()
    }

    pub fn wait_events(&self) -> Vec<Event> {
        use std::time::Duration;
        use std::io::timer;
        timer::sleep(Duration::milliseconds(16));
        Vec::new()
    }

    pub fn make_current(&self) {
        unsafe {
            ffi::egl::MakeCurrent(self.display, self.surface, self.surface, self.context);
        }
    }

    pub fn get_proc_address(&self, addr: &str) -> *const () {
        use std::c_str::ToCStr;

        unsafe {
            addr.with_c_str(|s| {
                ffi::egl::GetProcAddress(s) as *const ()
            })
        }
    }

    pub fn swap_buffers(&self) {
        unsafe {
            ffi::egl::SwapBuffers(self.display, self.surface);
        }
    }

    pub fn platform_display(&self) -> *mut libc::c_void {
        self.display as *mut libc::c_void
    }
}

#[unsafe_destructor]
impl Drop for Window {
    fn drop(&mut self) {
        use std::ptr;

        unsafe {
            android_glue::write_log("Destroying gl-init window");
            ffi::egl::MakeCurrent(self.display, ptr::null(), ptr::null(), ptr::null());
            ffi::egl::DestroySurface(self.display, self.surface);
            ffi::egl::DestroyContext(self.display, self.context);
            ffi::egl::Terminate(self.display);
        }
    }
}
<commit_msg>Android: Implemented basic inputs<commit_after>extern crate android_glue;
extern crate native;

use libc;
use {CreationError, OsError, Event, WindowBuilder};
use {Pressed, Released, LeftMouseButton, MouseInput, MouseMoved};

pub struct Window {
    display: ffi::egl::types::EGLDisplay,
    context: ffi::egl::types::EGLContext,
    surface: ffi::egl::types::EGLSurface,
    event_rx: Receiver<android_glue::Event>,
}

pub struct MonitorID;

mod ffi;

compile_warning!("The Android implementation is not fully working yet")

pub fn get_available_monitors() -> Vec<MonitorID> {
    vec![ MonitorID ]
}

pub fn get_primary_monitor() -> MonitorID {
    MonitorID
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("Primary".to_string())
    }

    pub fn get_dimensions(&self) -> (uint, uint) {
        unimplemented!()
    }
}

impl Window {
    pub fn new(_builder: WindowBuilder) -> Result<Window, CreationError> {
        use std::{mem, ptr};

        let native_window = unsafe { android_glue::get_native_window() };
        if native_window.is_null() {
            return Err(OsError(format!("Android's native window is null")));
        }

        let display = unsafe {
            let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
            if display.is_null() {
                return Err(OsError("No EGL display connection available".to_string()));
            }
            display
        };

        android_glue::write_log("eglGetDisplay succeeded");

        let (_major, _minor) = unsafe {
            let mut major: ffi::egl::types::EGLint = mem::uninitialized();
            let mut minor: ffi::egl::types::EGLint = mem::uninitialized();

            if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
                return Err(OsError(format!("eglInitialize failed")))
            }

            (major, minor)
        };

        android_glue::write_log("eglInitialize succeeded");

        let config = unsafe {
            let attribute_list = [
                ffi::egl::RED_SIZE as i32, 1,
                ffi::egl::GREEN_SIZE as i32, 1,
                ffi::egl::BLUE_SIZE as i32, 1,
                ffi::egl::NONE as i32
            ];

            let mut num_config: ffi::egl::types::EGLint = mem::uninitialized();
            let mut config: ffi::egl::types::EGLConfig = mem::uninitialized();
            if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
                &mut num_config) == 0
            {
                return Err(OsError(format!("eglChooseConfig failed")))
            }

            if num_config <= 0 {
                return Err(OsError(format!("eglChooseConfig returned no available config")))
            }

            config
        };

        android_glue::write_log("eglChooseConfig succeeded");

        let context = unsafe {
            let context = ffi::egl::CreateContext(display, config, ptr::null(), ptr::null());
            if context.is_null() {
                return Err(OsError(format!("eglCreateContext failed")))
            }
            context
        };

        android_glue::write_log("eglCreateContext succeeded");

        let surface = unsafe {
            let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
            if surface.is_null() {
                return Err(OsError(format!("eglCreateWindowSurface failed")))
            }
            surface
        };

        android_glue::write_log("eglCreateWindowSurface succeeded");

        let (tx, rx) = channel();
        android_glue::add_sender(tx);

        Ok(Window {
            display: display,
            context: context,
            surface: surface,
            event_rx: rx,
        })
    }

    pub fn is_closed(&self) -> bool {
        false
    }

    pub fn set_title(&self, _: &str) {
    }

    pub fn show(&self) {
    }

    pub fn hide(&self) {
    }

    pub fn get_position(&self) -> Option<(int, int)> {
        None
    }

    pub fn set_position(&self, _x: int, _y: int) {
    }

    pub fn get_inner_size(&self) -> Option<(uint, uint)> {
        let native_window = unsafe { android_glue::get_native_window() };

        if native_window.is_null() {
            None
        } else {
            Some((
                unsafe { ffi::ANativeWindow_getWidth(native_window) } as uint,
                unsafe { ffi::ANativeWindow_getHeight(native_window) } as uint
            ))
        }
    }

    pub fn get_outer_size(&self) -> Option<(uint, uint)> {
        self.get_inner_size()
    }

    pub fn set_inner_size(&self, _x: uint, _y: uint) {
    }

    pub fn poll_events(&self) -> Vec<Event> {
        use std::time::Duration;
        use std::io::timer;
        timer::sleep(Duration::milliseconds(16));
        Vec::new()
    }

    pub fn wait_events(&self) -> Vec<Event> {
        use std::time::Duration;
        use std::io::timer;
        timer::sleep(Duration::milliseconds(16));
        let mut events = Vec::new();
        loop {
            match self.event_rx.try_recv() {
                Ok(event) => match event {
                    android_glue::EventDown => {
                        events.push(MouseInput(Pressed, LeftMouseButton));
                    },
                    android_glue::EventUp => {
                        events.push(MouseInput(Released, LeftMouseButton));
                    },
                    android_glue::EventMove(x, y) => {
                        events.push(MouseMoved((x as int, y as int)));
                    },
                },
                Err(_) => {
		    break;
		},
            }
        }
        events
    }

    pub fn make_current(&self) {
        unsafe {
            ffi::egl::MakeCurrent(self.display, self.surface, self.surface, self.context);
        }
    }

    pub fn get_proc_address(&self, addr: &str) -> *const () {
        use std::c_str::ToCStr;

        unsafe {
            addr.with_c_str(|s| {
                ffi::egl::GetProcAddress(s) as *const ()
            })
        }
    }

    pub fn swap_buffers(&self) {
        unsafe {
            ffi::egl::SwapBuffers(self.display, self.surface);
        }
    }

    pub fn platform_display(&self) -> *mut libc::c_void {
        self.display as *mut libc::c_void
    }
}

#[unsafe_destructor]
impl Drop for Window {
    fn drop(&mut self) {
        use std::ptr;

        unsafe {
            android_glue::write_log("Destroying gl-init window");
            ffi::egl::MakeCurrent(self.display, ptr::null(), ptr::null(), ptr::null());
            ffi::egl::DestroySurface(self.display, self.surface);
            ffi::egl::DestroyContext(self.display, self.context);
            ffi::egl::Terminate(self.display);
        }
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="base64", vers="1.0.0", author="Jordy Dickinson")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordy Dickinson <jordy.dickinson@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

#![feature(phase)]
#![feature(macro_rules)]

extern crate serialize;
extern crate getopts;
extern crate libc;
#[phase(syntax, link)] extern crate log;

use std::char;
use std::io::{println, File, stdin, stdout};
use std::os;
use std::str;

use getopts::{
    getopts,
    optflag,
    optopt,
    usage
};
use serialize::base64;
use serialize::base64::{FromBase64, ToBase64};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "base64";

fn main() {
    let args = ~os::args();
    let opts = ~[
        optflag("d", "decode", "decode data"),
        optflag("i", "ignore-garbage", "when decoding, ignore non-alphabetic characters"),
        optopt("w", "wrap",
            "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", "COLS"
        ),
        optflag("h", "help", "display this help text and exit"),
        optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(e) => {
            error!("error: {:s}", e.to_err_msg());
            fail!()
        }
    };

    let progname = args[0].clone();
    let usage = usage("Base64 encode or decode FILE, or standard input, to standard output.", opts);
    let mode = if matches.opt_present("help") {
        Help
    } else if matches.opt_present("version") {
        Version
    } else if matches.opt_present("decode") {
        Decode
    } else {
        Encode
    };
    let ignore_garbage = matches.opt_present("ignore-garbage");
    let line_wrap = match matches.opt_str("wrap") {
        Some(s) => match from_str(s) {
            Some(s) => s,
            None => {
                error!("error: {:s}", "Argument to option 'wrap' improperly formatted.");
                fail!()
            }
        },
        None => 76
    };
    let mut input = if matches.free.is_empty() || matches.free.get(0).as_slice() == "-" {
        ~stdin() as ~Reader
    } else {
        let path = Path::new(matches.free.get(0).clone());
        ~File::open(&path) as ~Reader
    };

    match mode {
        Decode  => decode(input, ignore_garbage),
        Encode  => encode(input, line_wrap),
        Help    => help(progname, usage),
        Version => version()
    }
}

fn decode(input: &mut Reader, ignore_garbage: bool) {
    let mut to_decode = str::from_utf8_owned(match input.read_to_end() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    }).unwrap();

    to_decode = str::replace(to_decode, "\n", "");

    if ignore_garbage {
        let standard_chars: ~[char] =
            bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
            "abcdefghijklmnopqrstuvwxyz",
            "0123456789+/").iter().map(|b| char::from_u32(*b as u32).unwrap()).collect();

        to_decode = to_decode
            .trim_chars(&|c| !standard_chars.contains(&c))
            .to_owned();
    }

    match to_decode.from_base64() {
        Ok(bytes) => {
            let mut out = stdout();

            match out.write(bytes) {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
            match out.flush() {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
        }
        Err(s) => {
            error!("error: {}", s.to_str());
            fail!()
        }
    }
}

fn encode(input: &mut Reader, line_wrap: uint) {
    let b64_conf = base64::Config {
        char_set: base64::Standard,
        pad: true,
        line_length: match line_wrap {
            0 => None,
            _ => Some(line_wrap)
        }
    };
    let to_encode = match input.read_to_end() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };
    let mut encoded = to_encode.to_base64(b64_conf);

    // To my knowledge, RFC 3548 does not specify which line endings to use. It
    // seems that rust's base64 algorithm uses CRLF as prescribed by RFC 2045.
    // However, since GNU base64 outputs only LF (presumably because that is
    // the standard UNIX line ending), we strip CRs from the output to maintain
    // compatibility.
    encoded = encoded.replace("\r", "");

    println(encoded);
}

fn help(progname: &str, usage: &str) {
    println!("Usage: {:s} [OPTION]... [FILE]", progname);
    println!("");
    println(usage);

    let msg = ~"With no FILE, or when FILE is -, read standard input.\n\n\
        The data are encoded as described for the base64 alphabet in RFC \
        3548. When\ndecoding, the input may contain newlines in addition \
        to the bytes of the formal\nbase64 alphabet. Use --ignore-garbage \
        to attempt to recover from any other\nnon-alphabet bytes in the \
        encoded stream.";

    println(msg);
}

fn version() {
    println!("base64 1.0.0");
}

enum Mode {
    Decode,
    Encode,
    Help,
    Version
}

<commit_msg>Update base64 to latest rust<commit_after>#![crate_id(name="base64", vers="1.0.0", author="Jordy Dickinson")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordy Dickinson <jordy.dickinson@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

#![feature(phase)]
#![feature(macro_rules)]

extern crate serialize;
extern crate getopts;
extern crate libc;
#[phase(syntax, link)] extern crate log;

use std::char;
use std::io::{println, File, stdin, stdout};
use std::os;
use std::str;

use getopts::{
    getopts,
    optflag,
    optopt,
    usage
};
use serialize::base64;
use serialize::base64::{FromBase64, ToBase64};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "base64";

fn main() {
    let args = ~os::args();
    let opts = ~[
        optflag("d", "decode", "decode data"),
        optflag("i", "ignore-garbage", "when decoding, ignore non-alphabetic characters"),
        optopt("w", "wrap",
            "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", "COLS"
        ),
        optflag("h", "help", "display this help text and exit"),
        optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(e) => {
            error!("error: {:s}", e.to_err_msg());
            fail!()
        }
    };

    let progname = args[0].clone();
    let usage = usage("Base64 encode or decode FILE, or standard input, to standard output.", opts);
    let mode = if matches.opt_present("help") {
        Help
    } else if matches.opt_present("version") {
        Version
    } else if matches.opt_present("decode") {
        Decode
    } else {
        Encode
    };
    let ignore_garbage = matches.opt_present("ignore-garbage");
    let line_wrap = match matches.opt_str("wrap") {
        Some(s) => match from_str(s) {
            Some(s) => s,
            None => {
                error!("error: {:s}", "Argument to option 'wrap' improperly formatted.");
                fail!()
            }
        },
        None => 76
    };
    let mut input = if matches.free.is_empty() || matches.free.get(0).as_slice() == "-" {
        ~stdin() as ~Reader
    } else {
        let path = Path::new(matches.free.get(0).clone());
        ~File::open(&path) as ~Reader
    };

    match mode {
        Decode  => decode(input, ignore_garbage),
        Encode  => encode(input, line_wrap),
        Help    => help(progname, usage),
        Version => version()
    }
}

fn decode(input: &mut Reader, ignore_garbage: bool) {
    let mut to_decode = match input.read_to_str() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };

    to_decode = str::replace(to_decode, "\n", "");

    if ignore_garbage {
        let standard_chars: ~[char] =
            bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
            "abcdefghijklmnopqrstuvwxyz",
            "0123456789+/").iter().map(|b| char::from_u32(*b as u32).unwrap()).collect();

        to_decode = to_decode
            .trim_chars(|c| !standard_chars.contains(&c))
            .to_owned();
    }

    match to_decode.from_base64() {
        Ok(bytes) => {
            let mut out = stdout();

            match out.write(bytes) {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
            match out.flush() {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
        }
        Err(s) => {
            error!("error: {}", s.to_str());
            fail!()
        }
    }
}

fn encode(input: &mut Reader, line_wrap: uint) {
    let b64_conf = base64::Config {
        char_set: base64::Standard,
        pad: true,
        line_length: match line_wrap {
            0 => None,
            _ => Some(line_wrap)
        }
    };
    let to_encode = match input.read_to_end() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };
    let mut encoded = to_encode.as_slice().to_base64(b64_conf);

    // To my knowledge, RFC 3548 does not specify which line endings to use. It
    // seems that rust's base64 algorithm uses CRLF as prescribed by RFC 2045.
    // However, since GNU base64 outputs only LF (presumably because that is
    // the standard UNIX line ending), we strip CRs from the output to maintain
    // compatibility.
    encoded = encoded.replace("\r", "");

    println(encoded);
}

fn help(progname: &str, usage: &str) {
    println!("Usage: {:s} [OPTION]... [FILE]", progname);
    println!("");
    println(usage);

    let msg = ~"With no FILE, or when FILE is -, read standard input.\n\n\
        The data are encoded as described for the base64 alphabet in RFC \
        3548. When\ndecoding, the input may contain newlines in addition \
        to the bytes of the formal\nbase64 alphabet. Use --ignore-garbage \
        to attempt to recover from any other\nnon-alphabet bytes in the \
        encoded stream.";

    println(msg);
}

fn version() {
    println!("base64 1.0.0");
}

enum Mode {
    Decode,
    Encode,
    Help,
    Version
}

<|endoftext|>


<commit_before>use codegen::gen_increment_mem32;
use cpu2;
use global_pointers;
use wasmgen::wasm_builder::WasmBuilder;

struct Instruction {
    prefixes: Vec<u8>,
    opcode: u8,
    fixed_g: u8,
    is_mem: bool,
    is_0f: bool,
}

fn decode(mut instruction: u32) -> Instruction {
    let mut is_0f = false;
    let mut prefixes = vec![];
    let mut final_opcode = 0;

    for _ in 0..4 {
        let opcode = (instruction & 0xFF) as u8;
        instruction >>= 8;

        // TODO:
        // - If instruction depends on middle bits of modrm_byte, split
        // - Split depending on memory or register variant
        // - If the instruction uses 4 or more prefixes, only the prefixes will be counted

        if is_0f {
            final_opcode = opcode;
            break;
        }
        else {
            if opcode == 0x0F {
                is_0f = true;
            }
            else if opcode == 0x26
                || opcode == 0x2E
                || opcode == 0x36
                || opcode == 0x3E
                || opcode == 0x64
                || opcode == 0x65
                || opcode == 0x66
                || opcode == 0x67
                || opcode == 0xF0
                || opcode == 0xF2
                || opcode == 0xF3
            {
                prefixes.push(opcode);
            }
            else {
                final_opcode = opcode;
                break;
            }
        }
    }

    let has_modrm_byte = if is_0f {
        match final_opcode {
            0x0 | 0x1 | 0x2 | 0x3 | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17
            | 0x18 | 0x19 | 0x20 | 0x21 | 0x22 | 0x23 | 0x28 | 0x29 | 0x40 | 0x41 | 0x42 | 0x43
            | 0x44 | 0x45 | 0x46 | 0x47 | 0x48 | 0x49 | 0x50 | 0x51 | 0x52 | 0x53 | 0x54 | 0x55
            | 0x56 | 0x57 | 0x58 | 0x59 | 0x60 | 0x61 | 0x62 | 0x63 | 0x64 | 0x65 | 0x66 | 0x67
            | 0x68 | 0x69 | 0x70 | 0x71 | 0x72 | 0x73 | 0x74 | 0x75 | 0x76 | 0x90 | 0x91 | 0x92
            | 0x93 | 0x94 | 0x95 | 0x96 | 0x97 | 0x98 | 0x99 | 0x1c | 0x1d | 0x1e | 0x1f | 0x2a
            | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f | 0x4a | 0x4b | 0x4c | 0x4d | 0x4e | 0x4f | 0x5a
            | 0x5b | 0x5c | 0x5d | 0x5e | 0x5f | 0x6a | 0x6b | 0x6c | 0x6d | 0x6e | 0x6f | 0x7e
            | 0x7f | 0x9a | 0x9b | 0x9c | 0x9d | 0x9e | 0x9f | 0xa3 | 0xa4 | 0xa5 | 0xab | 0xac
            | 0xad | 0xae | 0xaf | 0xb0 | 0xb1 | 0xb2 | 0xb3 | 0xb4 | 0xb5 | 0xb6 | 0xb7 | 0xb8
            | 0xba | 0xbb | 0xbc | 0xbd | 0xbe | 0xbf | 0xc0 | 0xc1 | 0xc2 | 0xc3 | 0xc4 | 0xc5
            | 0xc6 | 0xc7 | 0xd1 | 0xd2 | 0xd3 | 0xd4 | 0xd5 | 0xd6 | 0xd7 | 0xd8 | 0xd9 | 0xda
            | 0xdb | 0xdc | 0xdd | 0xde | 0xdf | 0xe0 | 0xe1 | 0xe2 | 0xe3 | 0xe4 | 0xe5 | 0xe6
            | 0xe7 | 0xe8 | 0xe9 | 0xea | 0xeb | 0xec | 0xed | 0xee | 0xef | 0xf1 | 0xf2 | 0xf3
            | 0xf4 | 0xf5 | 0xf6 | 0xf7 | 0xf8 | 0xf9 | 0xfa | 0xfb | 0xfc | 0xfd | 0xfe => true,
            _ => false,
        }
    }
    else {
        match final_opcode {
            0x0 | 0x1 | 0x2 | 0x3 | 0x8 | 0x9 | 0x10 | 0x11 | 0x12 | 0x13 | 0x18 | 0x19 | 0x20
            | 0x21 | 0x22 | 0x23 | 0x28 | 0x29 | 0x30 | 0x31 | 0x32 | 0x33 | 0x38 | 0x39 | 0x62
            | 0x63 | 0x69 | 0x80 | 0x81 | 0x82 | 0x83 | 0x84 | 0x85 | 0x86 | 0x87 | 0x88 | 0x89
            | 0xa | 0xb | 0x1a | 0x1b | 0x2a | 0x2b | 0x3a | 0x3b | 0x6b | 0x8a | 0x8b | 0x8c
            | 0x8d | 0x8e | 0x8f | 0xc0 | 0xc1 | 0xc4 | 0xc5 | 0xc6 | 0xc7 | 0xd0 | 0xd1 | 0xd2
            | 0xd3 | 0xd8 | 0xd9 | 0xda | 0xdb | 0xdc | 0xdd | 0xde | 0xdf | 0xf6 | 0xf7 | 0xfe
            | 0xff => true,
            _ => false,
        }
    };

    let has_fixed_g = if is_0f {
        final_opcode == 0x71
            || final_opcode == 0x72
            || final_opcode == 0x73
            || final_opcode == 0xAE
            || final_opcode == 0xBA
            || final_opcode == 0xC7
    }
    else {
        final_opcode >= 0x80 && final_opcode < 0x84
            || final_opcode >= 0xC0 && final_opcode < 0xC2
            || final_opcode >= 0xD0 && final_opcode < 0xD4
            || final_opcode >= 0xD8 && final_opcode < 0xE0
            || final_opcode >= 0xF6 && final_opcode < 0xF8
            || final_opcode == 0xFE
            || final_opcode == 0xFF
    };

    let mut is_mem = false;
    let mut fixed_g = 0;

    if has_fixed_g {
        dbg_assert!(has_modrm_byte);
        let modrm_byte = (instruction & 0xFF) as u8;
        fixed_g = modrm_byte >> 3 & 7;
        is_mem = modrm_byte < 0xC0
    }
    if has_modrm_byte {
        let modrm_byte = (instruction & 0xFF) as u8;
        is_mem = modrm_byte < 0xC0
    }

    Instruction {
        prefixes,
        opcode: final_opcode,
        is_mem,
        fixed_g,
        is_0f,
    }
}

pub fn gen_opstats(builder: &mut WasmBuilder, opcode: u32) {
    if !cfg!(feature = "profiler") || !cfg!(feature = "profiler_instrument") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        gen_increment_mem32(builder, global_pointers::OPSTATS_BUFFER + 4 * index);
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    gen_increment_mem32(builder, global_pointers::OPSTATS_BUFFER + 4 * index);
}

pub fn record_opstat_compiled(opcode: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe { *cpu2::global_pointers::opstats_compiled_buffer.offset(index as isize) += 1 }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_compiled_buffer.offset(index as isize) += 1 }
}

pub fn record_opstat_jit_exit(opcode: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe { *cpu2::global_pointers::opstats_jit_exit_buffer.offset(index as isize) += 1 }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_jit_exit_buffer.offset(index as isize) += 1 }
}

pub fn record_opstat_unguarded_register(opcode: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe {
            *cpu2::global_pointers::opstats_unguarded_register_buffer.offset(index as isize) += 1
        }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_unguarded_register_buffer.offset(index as isize) += 1 }
}

pub fn gen_opstat_unguarded_register(builder: &mut WasmBuilder, opcode: u32) {
    if !cfg!(feature = "profiler") || !cfg!(feature = "profiler_instrument") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        gen_increment_mem32(
            builder,
            global_pointers::OPSTATS_UNGUARDED_REGISTER_BUFFER + 4 * index,
        );
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    gen_increment_mem32(
        builder,
        global_pointers::OPSTATS_UNGUARDED_REGISTER_BUFFER + 4 * index,
    );
}

pub fn record_opstat_size_wasm(opcode: u32, size: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe { *cpu2::global_pointers::opstats_wasm_size.offset(index as isize) += size }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_wasm_size.offset(index as isize) += size }
}
<commit_msg>Update comment<commit_after>use codegen::gen_increment_mem32;
use cpu2;
use global_pointers;
use wasmgen::wasm_builder::WasmBuilder;

struct Instruction {
    prefixes: Vec<u8>,
    opcode: u8,
    fixed_g: u8,
    is_mem: bool,
    is_0f: bool,
}

fn decode(mut instruction: u32) -> Instruction {
    let mut is_0f = false;
    let mut prefixes = vec![];
    let mut final_opcode = 0;

    for _ in 0..4 {
        let opcode = (instruction & 0xFF) as u8;
        instruction >>= 8;

        // TODO:
        // - If the instruction uses 4 or more prefixes, only the prefixes will be counted

        if is_0f {
            final_opcode = opcode;
            break;
        }
        else {
            if opcode == 0x0F {
                is_0f = true;
            }
            else if opcode == 0x26
                || opcode == 0x2E
                || opcode == 0x36
                || opcode == 0x3E
                || opcode == 0x64
                || opcode == 0x65
                || opcode == 0x66
                || opcode == 0x67
                || opcode == 0xF0
                || opcode == 0xF2
                || opcode == 0xF3
            {
                prefixes.push(opcode);
            }
            else {
                final_opcode = opcode;
                break;
            }
        }
    }

    let has_modrm_byte = if is_0f {
        match final_opcode {
            0x0 | 0x1 | 0x2 | 0x3 | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17
            | 0x18 | 0x19 | 0x20 | 0x21 | 0x22 | 0x23 | 0x28 | 0x29 | 0x40 | 0x41 | 0x42 | 0x43
            | 0x44 | 0x45 | 0x46 | 0x47 | 0x48 | 0x49 | 0x50 | 0x51 | 0x52 | 0x53 | 0x54 | 0x55
            | 0x56 | 0x57 | 0x58 | 0x59 | 0x60 | 0x61 | 0x62 | 0x63 | 0x64 | 0x65 | 0x66 | 0x67
            | 0x68 | 0x69 | 0x70 | 0x71 | 0x72 | 0x73 | 0x74 | 0x75 | 0x76 | 0x90 | 0x91 | 0x92
            | 0x93 | 0x94 | 0x95 | 0x96 | 0x97 | 0x98 | 0x99 | 0x1c | 0x1d | 0x1e | 0x1f | 0x2a
            | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f | 0x4a | 0x4b | 0x4c | 0x4d | 0x4e | 0x4f | 0x5a
            | 0x5b | 0x5c | 0x5d | 0x5e | 0x5f | 0x6a | 0x6b | 0x6c | 0x6d | 0x6e | 0x6f | 0x7e
            | 0x7f | 0x9a | 0x9b | 0x9c | 0x9d | 0x9e | 0x9f | 0xa3 | 0xa4 | 0xa5 | 0xab | 0xac
            | 0xad | 0xae | 0xaf | 0xb0 | 0xb1 | 0xb2 | 0xb3 | 0xb4 | 0xb5 | 0xb6 | 0xb7 | 0xb8
            | 0xba | 0xbb | 0xbc | 0xbd | 0xbe | 0xbf | 0xc0 | 0xc1 | 0xc2 | 0xc3 | 0xc4 | 0xc5
            | 0xc6 | 0xc7 | 0xd1 | 0xd2 | 0xd3 | 0xd4 | 0xd5 | 0xd6 | 0xd7 | 0xd8 | 0xd9 | 0xda
            | 0xdb | 0xdc | 0xdd | 0xde | 0xdf | 0xe0 | 0xe1 | 0xe2 | 0xe3 | 0xe4 | 0xe5 | 0xe6
            | 0xe7 | 0xe8 | 0xe9 | 0xea | 0xeb | 0xec | 0xed | 0xee | 0xef | 0xf1 | 0xf2 | 0xf3
            | 0xf4 | 0xf5 | 0xf6 | 0xf7 | 0xf8 | 0xf9 | 0xfa | 0xfb | 0xfc | 0xfd | 0xfe => true,
            _ => false,
        }
    }
    else {
        match final_opcode {
            0x0 | 0x1 | 0x2 | 0x3 | 0x8 | 0x9 | 0x10 | 0x11 | 0x12 | 0x13 | 0x18 | 0x19 | 0x20
            | 0x21 | 0x22 | 0x23 | 0x28 | 0x29 | 0x30 | 0x31 | 0x32 | 0x33 | 0x38 | 0x39 | 0x62
            | 0x63 | 0x69 | 0x80 | 0x81 | 0x82 | 0x83 | 0x84 | 0x85 | 0x86 | 0x87 | 0x88 | 0x89
            | 0xa | 0xb | 0x1a | 0x1b | 0x2a | 0x2b | 0x3a | 0x3b | 0x6b | 0x8a | 0x8b | 0x8c
            | 0x8d | 0x8e | 0x8f | 0xc0 | 0xc1 | 0xc4 | 0xc5 | 0xc6 | 0xc7 | 0xd0 | 0xd1 | 0xd2
            | 0xd3 | 0xd8 | 0xd9 | 0xda | 0xdb | 0xdc | 0xdd | 0xde | 0xdf | 0xf6 | 0xf7 | 0xfe
            | 0xff => true,
            _ => false,
        }
    };

    let has_fixed_g = if is_0f {
        final_opcode == 0x71
            || final_opcode == 0x72
            || final_opcode == 0x73
            || final_opcode == 0xAE
            || final_opcode == 0xBA
            || final_opcode == 0xC7
    }
    else {
        final_opcode >= 0x80 && final_opcode < 0x84
            || final_opcode >= 0xC0 && final_opcode < 0xC2
            || final_opcode >= 0xD0 && final_opcode < 0xD4
            || final_opcode >= 0xD8 && final_opcode < 0xE0
            || final_opcode >= 0xF6 && final_opcode < 0xF8
            || final_opcode == 0xFE
            || final_opcode == 0xFF
    };

    let mut is_mem = false;
    let mut fixed_g = 0;

    if has_fixed_g {
        dbg_assert!(has_modrm_byte);
        let modrm_byte = (instruction & 0xFF) as u8;
        fixed_g = modrm_byte >> 3 & 7;
        is_mem = modrm_byte < 0xC0
    }
    if has_modrm_byte {
        let modrm_byte = (instruction & 0xFF) as u8;
        is_mem = modrm_byte < 0xC0
    }

    Instruction {
        prefixes,
        opcode: final_opcode,
        is_mem,
        fixed_g,
        is_0f,
    }
}

pub fn gen_opstats(builder: &mut WasmBuilder, opcode: u32) {
    if !cfg!(feature = "profiler") || !cfg!(feature = "profiler_instrument") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        gen_increment_mem32(builder, global_pointers::OPSTATS_BUFFER + 4 * index);
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    gen_increment_mem32(builder, global_pointers::OPSTATS_BUFFER + 4 * index);
}

pub fn record_opstat_compiled(opcode: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe { *cpu2::global_pointers::opstats_compiled_buffer.offset(index as isize) += 1 }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_compiled_buffer.offset(index as isize) += 1 }
}

pub fn record_opstat_jit_exit(opcode: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe { *cpu2::global_pointers::opstats_jit_exit_buffer.offset(index as isize) += 1 }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_jit_exit_buffer.offset(index as isize) += 1 }
}

pub fn record_opstat_unguarded_register(opcode: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe {
            *cpu2::global_pointers::opstats_unguarded_register_buffer.offset(index as isize) += 1
        }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_unguarded_register_buffer.offset(index as isize) += 1 }
}

pub fn gen_opstat_unguarded_register(builder: &mut WasmBuilder, opcode: u32) {
    if !cfg!(feature = "profiler") || !cfg!(feature = "profiler_instrument") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        gen_increment_mem32(
            builder,
            global_pointers::OPSTATS_UNGUARDED_REGISTER_BUFFER + 4 * index,
        );
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    gen_increment_mem32(
        builder,
        global_pointers::OPSTATS_UNGUARDED_REGISTER_BUFFER + 4 * index,
    );
}

pub fn record_opstat_size_wasm(opcode: u32, size: u32) {
    if !cfg!(feature = "profiler") {
        return;
    }

    let instruction = decode(opcode);

    for prefix in instruction.prefixes {
        let index = (prefix as u32) << 4;
        unsafe { *cpu2::global_pointers::opstats_wasm_size.offset(index as isize) += size }
    }

    let index = (instruction.is_0f as u32) << 12
        | (instruction.opcode as u32) << 4
        | (instruction.is_mem as u32) << 3
        | instruction.fixed_g as u32;

    unsafe { *cpu2::global_pointers::opstats_wasm_size.offset(index as isize) += size }
}
<|endoftext|>


<commit_before>use specs::AMQPArgument;
use util::*;

use handlebars::{self, Handlebars, Helper, Renderable, RenderContext, RenderError, to_json};
use serde_json::{self};

use std::collections::BTreeMap;

pub type CodeGenerator = Handlebars;

pub trait HandlebarsAMQPExtension {
    fn register_amqp_helpers(self) -> Self;
}

impl HandlebarsAMQPExtension for CodeGenerator {
    fn register_amqp_helpers(mut self) -> CodeGenerator {
        self.register_escape_fn(handlebars::no_escape);
        self.register_helper("camel",         Box::new(camel_helper));
        self.register_helper("snake",         Box::new(snake_helper));
        self.register_helper("each_argument", Box::new(each_argument_helper));
        self
    }
}

pub fn camel_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to camel").value().as_str().expect("non-string param given to camel");
    rc.writer.write(camel_case(param).as_bytes())?;
    Ok(())
}

pub fn snake_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to snake").value().as_str().expect("non-string param given to snake");
    rc.writer.write(snake_case(param).as_bytes())?;
    Ok(())
}

pub fn each_argument_helper (h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_argument\""))?;

    if let Some(t) = h.template() {
        rc.promote_local_vars();
        let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
        let arguments : Vec<AMQPArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPArgument> for helper \"each_argument\""))?;
        for (index, argument) in arguments.iter().enumerate() {
            let mut local_rc = rc.derive();
            if let Some(ref p) = local_path_root {
                local_rc.push_local_path_root(p.clone());
            }
            local_rc.set_local_var("@index".to_string(), to_json(&index));
            if let Some(inner_path) = value.path() {
                let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                local_rc.set_path(new_path.clone());
            }
            if let Some(block_param) = h.block_param() {
                let mut map = BTreeMap::new();
                match *argument {
                    AMQPArgument::Value(ref v) => map.insert(block_param.to_string(), to_json(v)),
                    AMQPArgument::Flags(ref f) => map.insert(block_param.to_string(), to_json(f)),
                };
                local_rc.push_block_context(&map);
            }
            t.render(r, &mut local_rc)?;
            if h.block_param().is_some() {
                local_rc.pop_block_context();
            }
            if local_path_root.is_some() {
                local_rc.pop_local_path_root();
            }
        }
        rc.demote_local_vars();
    }
    Ok(())
}

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

    use specs::*;

    use amq_protocol_types::types::*;
    use amq_protocol_types::value::*;

    use std::collections::BTreeMap;

    pub const TEMPLATE: &'static str = r#"
{{protocol.name}} - {{protocol.major_version}}.{{protocol.minor_version}}.{{protocol.revision}}
{{protocol.copyright}}
port {{protocol.port}}
{{#each protocol.domains ~}}
{{@key}}: {{this}}
{{/each ~}}
{{#each protocol.constants as |constant| ~}}
{{constant.name}}({{constant.class}}) = {{constant.value}}
{{/each ~}}
{{#each protocol.classes as |class| ~}}
{{class.id}} - {{class.name}}
{{#each class.properties as |property| ~}}
{{property.name}}: {{property.type}}
{{/each ~}}
{{#each class.methods as |method| ~}}
{{method.id}} - {{method.name}}
synchronous: {{method.synchronous}}
{{#each_argument method.arguments as |argument| ~}}
{{argument.name}}({{argument.domain}}): {{argument.type}}
{{/each_argument ~}}
{{/each ~}}
{{/each ~}}
"#;

    fn specs() -> AMQProtocolDefinition {
        let mut domains = BTreeMap::new();
        domains.insert("domain1".to_string(), AMQPType::LongString);
        AMQProtocolDefinition {
            name:          "AMQP".to_string(),
            major_version: 0,
            minor_version: 9,
            revision:      1,
            port:          5672,
            copyright:     "Copyright 1\nCopyright 2".to_string(),
            domains:       domains,
            constants:     vec![
                AMQPConstant {
                    name:  "constant1".to_string(),
                    value: 128,
                    klass: Some("class1".to_string()),
                }
            ],
            classes:       vec![
                AMQPClass {
                    id:            42,
                    methods:       vec![
                        AMQPMethod {
                            id:          64,
                            arguments:   vec![
                                AMQPArgument::Value(AMQPValueArgument {
                                    amqp_type:     AMQPType::LongString,
                                    name:          "argument1".to_string(),
                                    default_value: Some(AMQPValue::LongString("value1".to_string())),
                                    domain:        Some("domain1".to_string()),
                                }),
                                // TODO: add a Flags argument
                            ],
                            name:        "method1".to_string(),
                            synchronous: true,
                        }
                    ],
                    name:          "class1".to_string(),
                    properties:    vec![
                        AMQPProperty {
                            amqp_type: AMQPType::LongString,
                            name:      "property1".to_string(),
                        }
                    ],
                    is_connection: false,
                }
            ],
        }
    }

    #[test]
    fn main_template() {
        let mut data    = BTreeMap::new();
        let mut codegen = CodeGenerator::new().register_amqp_helpers();
        data.insert("protocol".to_string(), specs());
        codegen.register_template_string("main", TEMPLATE.to_string()).unwrap();
        assert_eq!(codegen.render("main", &data).unwrap(), r#"
AMQP - 0.9.1
Copyright 1
Copyright 2
port 5672
domain1: LongString
constant1(class1) = 128
42 - class1
property1: LongString
64 - method1
synchronous: true
argument1(domain1): LongString

"#);
    }
}
<commit_msg>codegen: properly handle flags<commit_after>use specs::{AMQPArgument, AMQPFlagArgument};
use util::*;

use handlebars::{self, Handlebars, Helper, Renderable, RenderContext, RenderError, to_json};
use serde_json::{self};

use std::collections::BTreeMap;

pub type CodeGenerator = Handlebars;

pub trait HandlebarsAMQPExtension {
    fn register_amqp_helpers(self) -> Self;
}

impl HandlebarsAMQPExtension for CodeGenerator {
    fn register_amqp_helpers(mut self) -> CodeGenerator {
        self.register_escape_fn(handlebars::no_escape);
        self.register_helper("camel",         Box::new(camel_helper));
        self.register_helper("snake",         Box::new(snake_helper));
        self.register_helper("each_argument", Box::new(each_argument_helper));
        self.register_helper("each_flag",     Box::new(each_flag_helper));
        self
    }
}

pub fn camel_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to camel").value().as_str().expect("non-string param given to camel");
    rc.writer.write(camel_case(param).as_bytes())?;
    Ok(())
}

pub fn snake_helper (h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let param = h.param(0).expect("no param given to snake").value().as_str().expect("non-string param given to snake");
    rc.writer.write(snake_case(param).as_bytes())?;
    Ok(())
}

pub fn each_argument_helper (h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_argument\""))?;

    if let Some(t) = h.template() {
        rc.promote_local_vars();
        let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
        let arguments : Vec<AMQPArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPArgument> for helper \"each_argument\""))?;
        for (index, argument) in arguments.iter().enumerate() {
            let mut local_rc = rc.derive();
            if let Some(ref p) = local_path_root {
                local_rc.push_local_path_root(p.clone());
            }
            local_rc.set_local_var("@index".to_string(), to_json(&index));
            if let Some(inner_path) = value.path() {
                let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                local_rc.set_path(new_path.clone());
            }
            if let Some(block_param) = h.block_param() {
                let mut map = BTreeMap::new();
                match *argument {
                    AMQPArgument::Value(ref v) => {
                        map.insert(block_param.to_string(), to_json(v));
                        map.insert("argument_is_value".to_string(), to_json(&true));
                    },
                    AMQPArgument::Flags(ref f) => {
                        map.insert(block_param.to_string(), to_json(f));
                        map.insert("argument_is_value".to_string(), to_json(&false));
                    },
                };
                local_rc.push_block_context(&map);
            }
            t.render(r, &mut local_rc)?;
            if h.block_param().is_some() {
                local_rc.pop_block_context();
            }
            if local_path_root.is_some() {
                local_rc.pop_local_path_root();
            }
        }
        rc.demote_local_vars();
    }
    Ok(())
}

pub fn each_flag_helper (h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
    let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_flag\""))?;

    if let Some(t) = h.template() {
        rc.promote_local_vars();
        let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
        let flags : Vec<AMQPFlagArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPFlagArgument> for helper \"each_flag\""))?;
        for (index, flag) in flags.iter().enumerate() {
            let mut local_rc = rc.derive();
            if let Some(ref p) = local_path_root {
                local_rc.push_local_path_root(p.clone());
            }
            local_rc.set_local_var("@index".to_string(), to_json(&index));
            if let Some(inner_path) = value.path() {
                let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                local_rc.set_path(new_path.clone());
            }
            if let Some(block_param) = h.block_param() {
                let mut map = BTreeMap::new();
                map.insert(block_param.to_string(), to_json(flag));
                local_rc.push_block_context(&map);
            }
            t.render(r, &mut local_rc)?;
            if h.block_param().is_some() {
                local_rc.pop_block_context();
            }
            if local_path_root.is_some() {
                local_rc.pop_local_path_root();
            }
        }
        rc.demote_local_vars();
    }
    Ok(())
}

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

    use specs::*;

    use amq_protocol_types::types::*;
    use amq_protocol_types::value::*;

    use std::collections::BTreeMap;

    pub const TEMPLATE: &'static str = r#"
{{protocol.name}} - {{protocol.major_version}}.{{protocol.minor_version}}.{{protocol.revision}}
{{protocol.copyright}}
port {{protocol.port}}
{{#each protocol.domains ~}}
{{@key}}: {{this}}
{{/each ~}}
{{#each protocol.constants as |constant| ~}}
{{constant.name}}({{constant.class}}) = {{constant.value}}
{{/each ~}}
{{#each protocol.classes as |class| ~}}
{{class.id}} - {{class.name}}
{{#each class.properties as |property| ~}}
{{property.name}}: {{property.type}}
{{/each ~}}
{{#each class.methods as |method| ~}}
{{method.id}} - {{method.name}}
synchronous: {{method.synchronous}}
{{#each_argument method.arguments as |argument| ~}}
{{#if argument_is_value ~}}
{{argument.name}}({{argument.domain}}): {{argument.type}}
{{else}}
{{#each_flag argument as |flag| ~}}
{{flag.name}}: {{flag.default_value}}
{{/each_flag ~}}
{{/if ~}}
{{/each_argument ~}}
{{/each ~}}
{{/each ~}}
"#;

    fn specs() -> AMQProtocolDefinition {
        let mut domains = BTreeMap::new();
        domains.insert("domain1".to_string(), AMQPType::LongString);
        AMQProtocolDefinition {
            name:          "AMQP".to_string(),
            major_version: 0,
            minor_version: 9,
            revision:      1,
            port:          5672,
            copyright:     "Copyright 1\nCopyright 2".to_string(),
            domains:       domains,
            constants:     vec![
                AMQPConstant {
                    name:  "constant1".to_string(),
                    value: 128,
                    klass: Some("class1".to_string()),
                }
            ],
            classes:       vec![
                AMQPClass {
                    id:            42,
                    methods:       vec![
                        AMQPMethod {
                            id:          64,
                            arguments:   vec![
                                AMQPArgument::Value(AMQPValueArgument {
                                    amqp_type:     AMQPType::LongString,
                                    name:          "argument1".to_string(),
                                    default_value: Some(AMQPValue::LongString("value1".to_string())),
                                    domain:        Some("domain1".to_string()),
                                }),
                                AMQPArgument::Flags(vec![
                                    AMQPFlagArgument {
                                        name:         "flag1".to_string(),
                                        default_value: true,
                                    },
                                    AMQPFlagArgument {
                                        name:         "flag2".to_string(),
                                        default_value: false,
                                    },
                                ]),
                            ],
                            name:        "method1".to_string(),
                            synchronous: true,
                        }
                    ],
                    name:          "class1".to_string(),
                    properties:    vec![
                        AMQPProperty {
                            amqp_type: AMQPType::LongString,
                            name:      "property1".to_string(),
                        }
                    ],
                    is_connection: false,
                }
            ],
        }
    }

    #[test]
    fn main_template() {
        let mut data    = BTreeMap::new();
        let mut codegen = CodeGenerator::new().register_amqp_helpers();
        data.insert("protocol".to_string(), specs());
        codegen.register_template_string("main", TEMPLATE.to_string()).unwrap();
        assert_eq!(codegen.render("main", &data).unwrap(), r#"
AMQP - 0.9.1
Copyright 1
Copyright 2
port 5672
domain1: LongString
constant1(class1) = 128
42 - class1
property1: LongString
64 - method1
synchronous: true
argument1(domain1): LongString

flag1: true
flag2: false

"#);
    }
}
<|endoftext|>


<commit_before>// Copyright 2019 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 super::{INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING, VIRTIO_MSI_NO_VECTOR};
use crate::pci::MsixConfig;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use sync::Mutex;
use sys_util::EventFd;

pub struct Interrupt {
    interrupt_status: Arc<AtomicUsize>,
    interrupt_evt: EventFd,
    interrupt_resample_evt: EventFd,
    pub msix_config: Option<Arc<Mutex<MsixConfig>>>,
    config_msix_vector: u16,
}

impl Interrupt {
    pub fn new(
        interrupt_status: Arc<AtomicUsize>,
        interrupt_evt: EventFd,
        interrupt_resample_evt: EventFd,
        msix_config: Option<Arc<Mutex<MsixConfig>>>,
        config_msix_vector: u16,
    ) -> Interrupt {
        Interrupt {
            interrupt_status,
            interrupt_evt,
            interrupt_resample_evt,
            msix_config,
            config_msix_vector,
        }
    }

    /// Virtqueue Interrupts From The Device
    ///
    /// If MSI-X is enabled in this device, MSI-X interrupt is preferred.
    /// Write to the irqfd to VMM to deliver virtual interrupt to the guest
    fn signal(&self, vector: u16, interrupt_status_mask: u32) {
        // Don't need to set ISR for MSI-X interrupts
        if let Some(msix_config) = &self.msix_config {
            let mut msix_config = msix_config.lock();
            if msix_config.enabled() {
                if vector != VIRTIO_MSI_NO_VECTOR {
                    msix_config.trigger(vector);
                }
                return;
            }
        }

        // Set bit in ISR and inject the interrupt if it was not already pending.
        // Don't need to inject the interrupt if the guest hasn't processed it.
        if self
            .interrupt_status
            .fetch_or(interrupt_status_mask as usize, Ordering::SeqCst)
            == 0
        {
            // Write to irqfd to inject INTx interrupt
            self.interrupt_evt.write(1).unwrap();
        }
    }

    /// Notify the driver that buffers have been placed in the used queue.
    pub fn signal_used_queue(&self, vector: u16) {
        self.signal(vector, INTERRUPT_STATUS_USED_RING)
    }

    /// Notify the driver that the device configuration has changed.
    pub fn signal_config_changed(&self) {
        self.signal(self.config_msix_vector, INTERRUPT_STATUS_CONFIG_CHANGED)
    }

    /// Handle interrupt resampling event
    pub fn interrupt_resample(&self) {
        let _ = self.interrupt_resample_evt.read();
        if self.interrupt_status.load(Ordering::SeqCst) != 0 {
            self.interrupt_evt.write(1).unwrap();
        }
    }

    /// Return the reference of interrupt_resample_evt
    /// To keep the interface clean, this member is private.
    pub fn get_resample_evt(&self) -> &EventFd {
        &self.interrupt_resample_evt
    }
}
<commit_msg>devices: interrupt: add simple resample<commit_after>// Copyright 2019 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 super::{INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING, VIRTIO_MSI_NO_VECTOR};
use crate::pci::MsixConfig;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use sync::Mutex;
use sys_util::EventFd;

pub struct Interrupt {
    interrupt_status: Arc<AtomicUsize>,
    interrupt_evt: EventFd,
    interrupt_resample_evt: EventFd,
    pub msix_config: Option<Arc<Mutex<MsixConfig>>>,
    config_msix_vector: u16,
}

impl Interrupt {
    pub fn new(
        interrupt_status: Arc<AtomicUsize>,
        interrupt_evt: EventFd,
        interrupt_resample_evt: EventFd,
        msix_config: Option<Arc<Mutex<MsixConfig>>>,
        config_msix_vector: u16,
    ) -> Interrupt {
        Interrupt {
            interrupt_status,
            interrupt_evt,
            interrupt_resample_evt,
            msix_config,
            config_msix_vector,
        }
    }

    /// Virtqueue Interrupts From The Device
    ///
    /// If MSI-X is enabled in this device, MSI-X interrupt is preferred.
    /// Write to the irqfd to VMM to deliver virtual interrupt to the guest
    fn signal(&self, vector: u16, interrupt_status_mask: u32) {
        // Don't need to set ISR for MSI-X interrupts
        if let Some(msix_config) = &self.msix_config {
            let mut msix_config = msix_config.lock();
            if msix_config.enabled() {
                if vector != VIRTIO_MSI_NO_VECTOR {
                    msix_config.trigger(vector);
                }
                return;
            }
        }

        // Set bit in ISR and inject the interrupt if it was not already pending.
        // Don't need to inject the interrupt if the guest hasn't processed it.
        if self
            .interrupt_status
            .fetch_or(interrupt_status_mask as usize, Ordering::SeqCst)
            == 0
        {
            // Write to irqfd to inject INTx interrupt
            self.interrupt_evt.write(1).unwrap();
        }
    }

    /// Notify the driver that buffers have been placed in the used queue.
    pub fn signal_used_queue(&self, vector: u16) {
        self.signal(vector, INTERRUPT_STATUS_USED_RING)
    }

    /// Notify the driver that the device configuration has changed.
    pub fn signal_config_changed(&self) {
        self.signal(self.config_msix_vector, INTERRUPT_STATUS_CONFIG_CHANGED)
    }

    /// Handle interrupt resampling event, reading the value from the event and doing the resample.
    pub fn interrupt_resample(&self) {
        let _ = self.interrupt_resample_evt.read();
        self.do_interrupt_resample();
    }

    /// Read the status and write to the interrupt event. Don't read the resample event, assume the
    /// resample has been requested.
    pub fn do_interrupt_resample(&self) {
        if self.interrupt_status.load(Ordering::SeqCst) != 0 {
            self.interrupt_evt.write(1).unwrap();
        }
    }

    /// Return the reference of interrupt_resample_evt
    /// To keep the interface clean, this member is private.
    pub fn get_resample_evt(&self) -> &EventFd {
        &self.interrupt_resample_evt
    }
}
<|endoftext|>


<commit_before>//! The `filter` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::ValueErrorKind;
use crate::length::*;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::{Parse, ParseValue};
use crate::properties::ComputedValues;
use crate::property_bag::PropertyBag;
use crate::rect::Rect;

/// The <filter> node.
pub struct Filter {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    width: Length<Horizontal>,
    height: Length<Vertical>,
    filterunits: CoordUnits,
    primitiveunits: CoordUnits,
}

impl Default for Filter {
    /// Constructs a new `Filter` with default properties.
    fn default() -> Self {
        Self {
            x: Length::<Horizontal>::parse_str("-10%").unwrap(),
            y: Length::<Vertical>::parse_str("-10%").unwrap(),
            width: Length::<Horizontal>::parse_str("120%").unwrap(),
            height: Length::<Vertical>::parse_str("120%").unwrap(),
            filterunits: CoordUnits::ObjectBoundingBox,
            primitiveunits: CoordUnits::UserSpaceOnUse,
        }
    }
}

impl Filter {
    pub fn get_filter_units(&self) -> CoordUnits {
        self.filterunits
    }

    pub fn get_primitive_units(&self) -> CoordUnits {
        self.primitiveunits
    }

    /// Computes and returns the filter effects region.
    pub fn compute_effects_region(
        &self,
        computed_from_target_node: &ComputedValues,
        draw_ctx: &mut DrawingCtx,
        affine: cairo::Matrix,
        width: f64,
        height: f64,
    ) -> BoundingBox {
        // Filters use the properties of the target node.
        let values = computed_from_target_node;

        let mut bbox = BoundingBox::new();

        // affine is set up in FilterContext::new() in such a way that for
        // filterunits == ObjectBoundingBox affine includes scaling to correct width, height and
        // this is why width and height are set to 1, 1 (and for filterunits ==
        // UserSpaceOnUse affine doesn't include scaling because in this case the correct
        // width, height already happens to be the viewbox width, height).
        //
        // It's done this way because with ObjectBoundingBox, non-percentage values are supposed to
        // represent the fractions of the referenced node, and with width and height = 1, 1 this
        // works out exactly like that.
        let params = if self.filterunits == CoordUnits::ObjectBoundingBox {
            draw_ctx.push_view_box(1.0, 1.0)
        } else {
            draw_ctx.get_view_params()
        };

        // With filterunits == ObjectBoundingBox, lengths represent fractions or percentages of the
        // referencing node. No units are allowed (it's checked during attribute parsing).
        let (x, y, w, h) = if self.filterunits == CoordUnits::ObjectBoundingBox {
            (
                self.x.length,
                self.y.length,
                self.width.length,
                self.height.length,
            )
        } else {
            (
                self.x.normalize(values, &params),
                self.y.normalize(values, &params),
                self.width.normalize(values, &params),
                self.height.normalize(values, &params),
            )
        };

        let rect = Rect::new(x, y, x + w, y + h);
        let other_bbox = BoundingBox::new().with_transform(affine).with_rect(rect);

        // At this point all of the previous viewbox and matrix business gets converted to pixel
        // coordinates in the final surface, because bbox is created with an identity affine.
        bbox.insert(&other_bbox);

        // Finally, clip to the width and height of our surface.
        let rect = Rect::from_size(width, height);
        let other_bbox = BoundingBox::new().with_rect(rect);
        bbox.clip(&other_bbox);

        bbox
    }
}

impl NodeTrait for Filter {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        // Parse filterUnits first as it affects x, y, width, height checks.
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!("", "filterUnits") => self.filterunits = attr.parse(value)?,
                _ => (),
            }
        }

        // With ObjectBoundingBox, only fractions and percents are allowed.
        let no_units_allowed = self.filterunits == CoordUnits::ObjectBoundingBox;

        let check_units_horizontal = |length: Length<Horizontal>| {
            if !no_units_allowed {
                return Ok(length);
            }

            match length.unit {
                LengthUnit::Px | LengthUnit::Percent => Ok(length),
                _ => Err(ValueErrorKind::parse_error(
                    "unit identifiers are not allowed with filterUnits set to objectBoundingBox",
                )),
            }
        };

        let check_units_vertical = |length: Length<Vertical>| {
            if !no_units_allowed {
                return Ok(length);
            }

            match length.unit {
                LengthUnit::Px | LengthUnit::Percent => Ok(length),
                _ => Err(ValueErrorKind::parse_error(
                    "unit identifiers are not allowed with filterUnits set to objectBoundingBox",
                )),
            }
        };

        let check_units_horizontal_and_ensure_nonnegative = |length: Length<Horizontal>| {
            check_units_horizontal(length).and_then(Length::<Horizontal>::check_nonnegative)
        };

        let check_units_vertical_and_ensure_nonnegative = |length: Length<Vertical>| {
            check_units_vertical(length).and_then(Length::<Vertical>::check_nonnegative)
        };

        // Parse the rest of the attributes.
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!("", "x") => {
                    self.x = attr.parse_and_validate(value, check_units_horizontal)?
                }
                expanded_name!("", "y") => {
                    self.y = attr.parse_and_validate(value, check_units_vertical)?
                }
                expanded_name!("", "width") => {
                    self.width = attr
                        .parse_and_validate(value, check_units_horizontal_and_ensure_nonnegative)?
                }
                expanded_name!("", "height") => {
                    self.height =
                        attr.parse_and_validate(value, check_units_vertical_and_ensure_nonnegative)?
                }
                expanded_name!("", "primitiveUnits") => self.primitiveunits = attr.parse(value)?,
                _ => (),
            }
        }

        Ok(())
    }
}
<commit_msg>filter: rename param<commit_after>//! The `filter` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::ValueErrorKind;
use crate::length::*;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::{Parse, ParseValue};
use crate::properties::ComputedValues;
use crate::property_bag::PropertyBag;
use crate::rect::Rect;

/// The <filter> node.
pub struct Filter {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    width: Length<Horizontal>,
    height: Length<Vertical>,
    filterunits: CoordUnits,
    primitiveunits: CoordUnits,
}

impl Default for Filter {
    /// Constructs a new `Filter` with default properties.
    fn default() -> Self {
        Self {
            x: Length::<Horizontal>::parse_str("-10%").unwrap(),
            y: Length::<Vertical>::parse_str("-10%").unwrap(),
            width: Length::<Horizontal>::parse_str("120%").unwrap(),
            height: Length::<Vertical>::parse_str("120%").unwrap(),
            filterunits: CoordUnits::ObjectBoundingBox,
            primitiveunits: CoordUnits::UserSpaceOnUse,
        }
    }
}

impl Filter {
    pub fn get_filter_units(&self) -> CoordUnits {
        self.filterunits
    }

    pub fn get_primitive_units(&self) -> CoordUnits {
        self.primitiveunits
    }

    /// Computes and returns the filter effects region.
    pub fn compute_effects_region(
        &self,
        computed_from_target_node: &ComputedValues,
        draw_ctx: &mut DrawingCtx,
        transform: cairo::Matrix,
        width: f64,
        height: f64,
    ) -> BoundingBox {
        // Filters use the properties of the target node.
        let values = computed_from_target_node;

        let mut bbox = BoundingBox::new();

        // transform is set up in FilterContext::new() in such a way that for
        // filterunits == ObjectBoundingBox it includes scaling to correct width, height and
        // this is why width and height are set to 1, 1 (and for filterunits ==
        // UserSpaceOnUse, transform doesn't include scaling because in this case the correct
        // width, height already happens to be the viewbox width, height).
        //
        // It's done this way because with ObjectBoundingBox, non-percentage values are supposed to
        // represent the fractions of the referenced node, and with width and height = 1, 1 this
        // works out exactly like that.
        let params = if self.filterunits == CoordUnits::ObjectBoundingBox {
            draw_ctx.push_view_box(1.0, 1.0)
        } else {
            draw_ctx.get_view_params()
        };

        // With filterunits == ObjectBoundingBox, lengths represent fractions or percentages of the
        // referencing node. No units are allowed (it's checked during attribute parsing).
        let (x, y, w, h) = if self.filterunits == CoordUnits::ObjectBoundingBox {
            (
                self.x.length,
                self.y.length,
                self.width.length,
                self.height.length,
            )
        } else {
            (
                self.x.normalize(values, &params),
                self.y.normalize(values, &params),
                self.width.normalize(values, &params),
                self.height.normalize(values, &params),
            )
        };

        let rect = Rect::new(x, y, x + w, y + h);
        let other_bbox = BoundingBox::new().with_transform(transform).with_rect(rect);

        // At this point all of the previous viewbox and matrix business gets converted to pixel
        // coordinates in the final surface, because bbox is created with an identity transform.
        bbox.insert(&other_bbox);

        // Finally, clip to the width and height of our surface.
        let rect = Rect::from_size(width, height);
        let other_bbox = BoundingBox::new().with_rect(rect);
        bbox.clip(&other_bbox);

        bbox
    }
}

impl NodeTrait for Filter {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        // Parse filterUnits first as it affects x, y, width, height checks.
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!("", "filterUnits") => self.filterunits = attr.parse(value)?,
                _ => (),
            }
        }

        // With ObjectBoundingBox, only fractions and percents are allowed.
        let no_units_allowed = self.filterunits == CoordUnits::ObjectBoundingBox;

        let check_units_horizontal = |length: Length<Horizontal>| {
            if !no_units_allowed {
                return Ok(length);
            }

            match length.unit {
                LengthUnit::Px | LengthUnit::Percent => Ok(length),
                _ => Err(ValueErrorKind::parse_error(
                    "unit identifiers are not allowed with filterUnits set to objectBoundingBox",
                )),
            }
        };

        let check_units_vertical = |length: Length<Vertical>| {
            if !no_units_allowed {
                return Ok(length);
            }

            match length.unit {
                LengthUnit::Px | LengthUnit::Percent => Ok(length),
                _ => Err(ValueErrorKind::parse_error(
                    "unit identifiers are not allowed with filterUnits set to objectBoundingBox",
                )),
            }
        };

        let check_units_horizontal_and_ensure_nonnegative = |length: Length<Horizontal>| {
            check_units_horizontal(length).and_then(Length::<Horizontal>::check_nonnegative)
        };

        let check_units_vertical_and_ensure_nonnegative = |length: Length<Vertical>| {
            check_units_vertical(length).and_then(Length::<Vertical>::check_nonnegative)
        };

        // Parse the rest of the attributes.
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!("", "x") => {
                    self.x = attr.parse_and_validate(value, check_units_horizontal)?
                }
                expanded_name!("", "y") => {
                    self.y = attr.parse_and_validate(value, check_units_vertical)?
                }
                expanded_name!("", "width") => {
                    self.width = attr
                        .parse_and_validate(value, check_units_horizontal_and_ensure_nonnegative)?
                }
                expanded_name!("", "height") => {
                    self.height =
                        attr.parse_and_validate(value, check_units_vertical_and_ensure_nonnegative)?
                }
                expanded_name!("", "primitiveUnits") => self.primitiveunits = attr.parse(value)?,
                _ => (),
            }
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::rc::Rc;
use std::time::Duration;
use chrono::Local;
use mio::Events;

use super::udp_connection::IDLE_TIMEOUT_SECONDS;
use super::selector::Selector;
use super::tunnel_server::TunnelServer;

const TAG: &'static str = "Relay";
const CLEANING_INTERVAL_SECONDS: i64 = 60;

pub struct Relay {
    port: u16,
}

impl Relay {
    pub fn new(port: u16) -> Self {
        Self { port: port }
    }

    pub fn start(&self) {
        info!(target: TAG, "Starting server...");
        let mut selector = Selector::new().unwrap();
        let tunnel_server =
            TunnelServer::new(self.port, &mut selector).expect("Cannot start tunnel server");
        self.poll_loop(&mut selector, &tunnel_server);
    }

    fn poll_loop(&self, selector: &mut Selector, tunnel_server: &Rc<RefCell<TunnelServer>>) {
        let mut events = Events::with_capacity(1024);
        // no connection may expire before the UDP idle timeout delay
        let mut next_cleaning_deadline = Local::now().timestamp() + IDLE_TIMEOUT_SECONDS as i64;
        loop {
            let timeout_seconds = next_cleaning_deadline - Local::now().timestamp();
            let timeout = if timeout_seconds > 0 {
                Some(Duration::new(timeout_seconds as u64, 0))
            } else {
                None
            };
            selector.poll(&mut events, timeout).expect("Cannot poll");

            let now = Local::now().timestamp();
            if now >= next_cleaning_deadline {
                tunnel_server.borrow_mut().clean_up(selector);
                next_cleaning_deadline = now + CLEANING_INTERVAL_SECONDS;
            } else if events.is_empty() {
                debug!(target: TAG, "Spurious wakeup: poll() returned without any event");
                continue;
            }

            selector.run_handlers(&mut events);
        }
    }
}
<commit_msg>Format code<commit_after>use std::cell::RefCell;
use std::rc::Rc;
use std::time::Duration;
use chrono::Local;
use mio::Events;

use super::udp_connection::IDLE_TIMEOUT_SECONDS;
use super::selector::Selector;
use super::tunnel_server::TunnelServer;

const TAG: &'static str = "Relay";
const CLEANING_INTERVAL_SECONDS: i64 = 60;

pub struct Relay {
    port: u16,
}

impl Relay {
    pub fn new(port: u16) -> Self {
        Self { port: port }
    }

    pub fn start(&self) {
        info!(target: TAG, "Starting server...");
        let mut selector = Selector::new().unwrap();
        let tunnel_server =
            TunnelServer::new(self.port, &mut selector).expect("Cannot start tunnel server");
        self.poll_loop(&mut selector, &tunnel_server);
    }

    fn poll_loop(&self, selector: &mut Selector, tunnel_server: &Rc<RefCell<TunnelServer>>) {
        let mut events = Events::with_capacity(1024);
        // no connection may expire before the UDP idle timeout delay
        let mut next_cleaning_deadline = Local::now().timestamp() + IDLE_TIMEOUT_SECONDS as i64;
        loop {
            let timeout_seconds = next_cleaning_deadline - Local::now().timestamp();
            let timeout = if timeout_seconds > 0 {
                Some(Duration::new(timeout_seconds as u64, 0))
            } else {
                None
            };
            selector.poll(&mut events, timeout).expect("Cannot poll");

            let now = Local::now().timestamp();
            if now >= next_cleaning_deadline {
                tunnel_server.borrow_mut().clean_up(selector);
                next_cleaning_deadline = now + CLEANING_INTERVAL_SECONDS;
            } else if events.is_empty() {
                debug!(
                    target: TAG,
                    "Spurious wakeup: poll() returned without any event"
                );
                continue;
            }

            selector.run_handlers(&mut events);
        }
    }
}
<|endoftext|>


<commit_before>/*!
A binding for SDL2_gfx.
 */

#![crate_name="sdl2_gfx"]
#![crate_type = "lib"]

#![feature(libc)]

extern crate libc;
extern crate sdl2;
extern crate "sdl2-sys" as sys;

// Setup linking for all targets.
#[link(name="SDL2_gfx")]
extern {}

pub mod primitives;
pub mod rotozoom;
pub mod framerate;
pub mod imagefilter;
<commit_msg>Add more features to reduce warnings.<commit_after>/*!
A binding for SDL2_gfx.
 */

#![crate_name="sdl2_gfx"]
#![crate_type = "lib"]

#![feature(libc)]
#![feature(unique)]
#![feature(core)]

extern crate libc;
extern crate sdl2;
extern crate "sdl2-sys" as sys;

// Setup linking for all targets.
#[link(name="SDL2_gfx")]
extern {}

pub mod primitives;
pub mod rotozoom;
pub mod framerate;
pub mod imagefilter;
<|endoftext|>


<commit_before>#![feature(test)]

#![allow(unused_attributes)]

// external crates
extern crate test;

// local crates
extern crate pretty;

// local mod imports
use trees::{
    Tree,
};

// custom mod imports
#[path="../examples/trees.rs"]
mod trees;

#[bench]
fn bench(b: &mut test::Bencher) -> () {
    let bbbbbbs =
        [ Tree::node("ccc")
        , Tree::node("dd")
        ];
    let ffffs =
        [ Tree::node("gg")
        , Tree::node("hhh")
        , Tree::node("ii")
        ];
    let aaas =
        [ Tree::node_with_forest("bbbbbb", &bbbbbbs)
        , Tree::node("eee")
        , Tree::node_with_forest("ffff", &ffffs)
        ];
    let example = Tree::node_with_forest("aaa", &aaas);
    let mut out = std::io::sink();
    let task = || {
        example.pretty().render(70, &mut out).unwrap();
    };
    b.iter(task);
}
<commit_msg>Remove unnecessary attribute; cleanup<commit_after>#![feature(test)]

extern crate test;
extern crate pretty;
use trees::{
    Tree,
};

#[path="../examples/trees.rs"]
mod trees;

#[bench]
fn bench(b: &mut test::Bencher) -> () {
    let bbbbbbs =
        [ Tree::node("ccc")
        , Tree::node("dd")
        ];
    let ffffs =
        [ Tree::node("gg")
        , Tree::node("hhh")
        , Tree::node("ii")
        ];
    let aaas =
        [ Tree::node_with_forest("bbbbbb", &bbbbbbs)
        , Tree::node("eee")
        , Tree::node_with_forest("ffff", &ffffs)
        ];
    let example = Tree::node_with_forest("aaa", &aaas);
    let mut out = std::io::sink();
    let task = || {
        example.pretty().render(70, &mut out).unwrap();
    };
    b.iter(task);
}
<|endoftext|>


<commit_before>extern crate inkwell;

use self::inkwell::context::Context;

use std::ffi::CString;

#[test]
fn test_basic_block_ordering() {
    let context = Context::create();
    let module = context.create_module("test");

    let i128_type = context.i128_type();
    let fn_type = i128_type.fn_type(&[], false);

    let function = module.add_function("testing", &fn_type, None);

    let basic_block = context.append_basic_block(&function, "entry");
    let basic_block4 = context.insert_basic_block_after(&basic_block, "block4");
    let basic_block2 = context.insert_basic_block_after(&basic_block, "block2");
    let basic_block3 = context.prepend_basic_block(&basic_block4, "block3");

    let basic_blocks = function.get_basic_blocks();

    assert_eq!(basic_blocks.len(), 4);
    assert_eq!(basic_blocks[0], basic_block);
    assert_eq!(basic_blocks[1], basic_block2);
    assert_eq!(basic_blocks[2], basic_block3);
    assert_eq!(basic_blocks[3], basic_block4);

    basic_block3.move_before(&basic_block2);
    basic_block.move_after(&basic_block4);

    let basic_block5 = basic_block.prepend_basic_block("block5");
    let basic_blocks = function.get_basic_blocks();

    assert_eq!(basic_blocks.len(), 5);
    assert_eq!(basic_blocks[0], basic_block3);
    assert_eq!(basic_blocks[1], basic_block2);
    assert_eq!(basic_blocks[2], basic_block4);
    assert_eq!(basic_blocks[3], basic_block5);
    assert_eq!(basic_blocks[4], basic_block);

    assert_ne!(basic_blocks[0], basic_block);
    assert_ne!(basic_blocks[1], basic_block3);
    assert_ne!(basic_blocks[2], basic_block2);
    assert_ne!(basic_blocks[3], basic_block4);
    assert_ne!(basic_blocks[4], basic_block5);

    function.append_basic_block("block6");

    let bb1 = function.get_entry_basic_block().unwrap();

    assert_eq!(bb1, basic_block3);
}

#[test]
fn test_get_basic_blocks() {
    let context = Context::create();
    let module = context.create_module("test");

    let bool_type = context.bool_type();
    let fn_type = bool_type.fn_type(&[], false);

    let function = module.add_function("testing", &fn_type, None);

    assert_eq!(function.get_name(), &*CString::new("testing").unwrap());
    assert_eq!(function.get_return_type().into_int_type().get_bit_width(), 1);

    assert!(function.get_last_basic_block().is_none());
    assert_eq!(function.get_basic_blocks().len(), 0);

    let basic_block = context.append_basic_block(&function, "entry");

    let last_basic_block = function.get_last_basic_block()
                                   .expect("Did not find expected basic block");

    assert_eq!(last_basic_block, basic_block);

    let basic_blocks = function.get_basic_blocks();

    assert_eq!(basic_blocks.len(), 1);
    assert_eq!(basic_blocks[0], basic_block);
}
<commit_msg>More basic block tests<commit_after>extern crate inkwell;

use self::inkwell::context::Context;

use std::ffi::CString;

#[test]
fn test_basic_block_ordering() {
    let context = Context::create();
    let module = context.create_module("test");

    let i128_type = context.i128_type();
    let fn_type = i128_type.fn_type(&[], false);

    let function = module.add_function("testing", &fn_type, None);

    let basic_block = context.append_basic_block(&function, "entry");
    let basic_block4 = context.insert_basic_block_after(&basic_block, "block4");
    let basic_block2 = context.insert_basic_block_after(&basic_block, "block2");
    let basic_block3 = context.prepend_basic_block(&basic_block4, "block3");

    let basic_blocks = function.get_basic_blocks();

    assert_eq!(basic_blocks.len(), 4);
    assert_eq!(basic_blocks[0], basic_block);
    assert_eq!(basic_blocks[1], basic_block2);
    assert_eq!(basic_blocks[2], basic_block3);
    assert_eq!(basic_blocks[3], basic_block4);

    basic_block3.move_before(&basic_block2);
    basic_block.move_after(&basic_block4);

    let basic_block5 = basic_block.prepend_basic_block("block5");
    let basic_blocks = function.get_basic_blocks();

    assert_eq!(basic_blocks.len(), 5);
    assert_eq!(basic_blocks[0], basic_block3);
    assert_eq!(basic_blocks[1], basic_block2);
    assert_eq!(basic_blocks[2], basic_block4);
    assert_eq!(basic_blocks[3], basic_block5);
    assert_eq!(basic_blocks[4], basic_block);

    assert_ne!(basic_blocks[0], basic_block);
    assert_ne!(basic_blocks[1], basic_block3);
    assert_ne!(basic_blocks[2], basic_block2);
    assert_ne!(basic_blocks[3], basic_block4);
    assert_ne!(basic_blocks[4], basic_block5);

    function.append_basic_block("block6");

    let bb1 = function.get_entry_basic_block().unwrap();
    let bb4 = basic_block5.get_previous_basic_block().unwrap();

    assert_eq!(bb1, basic_block3);
    assert_eq!(bb4, basic_block4);
    assert!(basic_block3.get_previous_basic_block().is_none());

    bb4.delete();

    let bb2 = basic_block5.get_previous_basic_block().unwrap();

    assert_eq!(bb2, basic_block2);
}

#[test]
fn test_get_basic_blocks() {
    let context = Context::create();
    let module = context.create_module("test");

    let bool_type = context.bool_type();
    let fn_type = bool_type.fn_type(&[], false);

    let function = module.add_function("testing", &fn_type, None);

    assert_eq!(function.get_name(), &*CString::new("testing").unwrap());
    assert_eq!(function.get_return_type().into_int_type().get_bit_width(), 1);

    assert!(function.get_last_basic_block().is_none());
    assert_eq!(function.get_basic_blocks().len(), 0);

    let basic_block = context.append_basic_block(&function, "entry");

    let last_basic_block = function.get_last_basic_block()
                                   .expect("Did not find expected basic block");

    assert_eq!(last_basic_block, basic_block);

    let basic_blocks = function.get_basic_blocks();

    assert_eq!(basic_blocks.len(), 1);
    assert_eq!(basic_blocks[0], basic_block);
}
<|endoftext|>