<commit_before>extern crate libc;
use libc::{c_char, c_int, uint8_t, uint16_t, uint32_t, c_void, timeval, c_uint, ssize_t, fd_set};

pub const FALSE: c_int = 0;
pub const TRUE: c_int = 1;
pub const OFF: c_int = 0;
pub const ON: c_int = 1;

macro_rules! modbus_enum {
    (pub enum $name:ident { $($variants:tt)* }) => {
        #[allow(non_camel_case_types)]
        #[cfg(target_env = "msvc")]
        pub type $name = i32;
        #[allow(non_camel_case_types)]
        #[cfg(not(target_env = "msvc"))]
        pub type $name = u32;
        modbus_enum!(gen, $name, 0, $($variants)*);
    };
    (pub enum $name:ident: $t:ty { $($variants:tt)* }) => {
        #[allow(non_camel_case_types)]
        pub type $name = $t;
        modbus_enum!(gen, $name, 0, $($variants)*);
    };
    (gen, $name:ident, $val:expr, $variant:ident, $($rest:tt)*) => {
        #[allow(non_camel_case_types)]
        pub const $variant: $name = $val;
        modbus_enum!(gen, $name, $val+1, $($rest)*);
    };
    (gen, $name:ident, $val:expr, $variant:ident = $e:expr, $($rest:tt)*) => {
        #[allow(non_camel_case_types)]
        pub const $variant: $name = $e;
        modbus_enum!(gen, $name, $e+1, $($rest)*);
    };
    (gen, $name:ident, $val:expr, ) => {}
}
modbus_enum! {
    pub enum  modbus_backend_type_t {
        _MODBUS_BACKEND_TYPE_RTU=0,
        _MODBUS_BACKEND_TYPE_TCP,
    }
}

modbus_enum! {
    pub enum modbus_error_recovery_mode {
        MODBUS_ERROR_RECOVERY_NONE          = 0,
        MODBUS_ERROR_RECOVERY_LINK          = (1<<1),
        MODBUS_ERROR_RECOVERY_PROTOCOL      = (1<<2),
    }
}

modbus_enum! {
    pub enum msg_type_t {
        MSG_INDICATION,
        MSG_CONFIRMATION,
    }
}

#[repr(C)]
#[allow(non_camel_case_types)]
pub struct modbus_backend_t {
    backend_type: c_uint,
    header_length: c_uint,
    checksum_length: c_uint,
    max_adu_length: c_uint,
    set_slave: extern fn(ctx: *mut modbus_t, slave: c_int) -> c_int,
    build_request_basis: extern fn(ctx: *mut modbus_t, function: c_int, addr: c_int,
                                nb: c_int, req: *mut uint8_t) -> c_int,
    build_response_basis: extern fn(sft: *mut sft_t, rsp: *mut uint8_t) -> c_int,
    prepare_response_tid: extern fn(req: *const uint8_t, req_length: *mut c_int) -> c_int,
    send_msg_pre: extern fn(req: *mut uint8_t, req_length: c_int) -> c_int,
    send: extern fn(ctx: *mut modbus_t, req: *const uint8_t, req_length: c_int) -> ssize_t,
    receive: extern fn(ctx: *mut modbus_t, req: *mut uint8_t) -> c_int,
    recv: extern fn(ctx: *mut modbus_t, rsp: *mut uint8_t, rsp_length: c_int) -> ssize_t,
    check_integrity: extern fn(ctx: *mut modbus_t, msg: *mut uint8_t,
                            msg_length: *const c_int) -> c_int,
    pre_check_confirmation: extern fn(ctx: *mut modbus_t, req: *const uint8_t,
                                   rsp: *const uint8_t, rsp_length: c_int) -> c_int,
    connect: extern fn(ctx: *mut modbus_t) -> c_int,
    close: extern fn(ctx: *mut modbus_t),
    flush: extern fn(ctx: *mut modbus_t) -> c_int,
    select: extern fn(ctx: *mut modbus_t, rset: *mut fd_set, tv: *mut timeval, msg_length: c_int) -> c_int,
    free: extern fn(ctx: *mut modbus_t),
}

#[repr(C)]
pub struct sft_t {
    slave: c_int,
    function: c_int,
    t_id: c_int,
}

#[repr(C)]
pub struct _modbus {
    /* Slave address */
    slave: c_int,
    /* Socket or file descriptor */
    s: c_int,
    debug: c_int,
    error_recovery: c_int,
    response_timeout: timeval,
    byte_timeout: timeval,
    backend: *const modbus_backend_t,
    backend_data: *mut c_void,
}

#[allow(non_camel_case_types)]
pub type modbus_t = _modbus;

#[repr(C)]
pub struct modbus_mapping_t {
    nb_bits: c_int,
    start_bits: c_int,
    nb_input_bits: c_int,
    start_input_bits: c_int,
    nb_input_registers: c_int,
    start_input_registers: c_int,
    nb_registers: c_int,
    start_registers: c_int,
    tab_bits: *mut uint8_t,
    tab_input_bits: *mut uint8_t,
    tab_input_registers: *mut uint16_t,
    tab_registers: *mut uint16_t,
}

// modbus-rtu.h
pub const MODBUS_RTU_MAX_ADU_LENGTH: c_int = 256;

pub const MODBUS_RTU_RS232: c_int = 0;
pub const MODBUS_RTU_RS485: c_int = 1;

pub const MODBUS_RTU_RTS_NONE: c_int = 0;
pub const MODBUS_RTU_RTS_UP: c_int   = 1;
pub const MODBUS_RTU_RTS_DOWN: c_int = 2;

#[link(name = "modbus")]
extern {
    pub fn modbus_set_slave(ctx: *mut modbus_t, slave: c_int) -> c_int;
    pub fn modbus_set_error_recovery(ctx: *mut modbus_t, error_recovery: modbus_error_recovery_mode) -> c_int;

    pub fn modbus_set_socket(ctx: *mut modbus_t, socket: c_int) -> c_int;
    pub fn modbus_get_socket(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_get_response_timeout(ctx: *mut modbus_t, to_sec: *mut uint32_t, to_usec: *mut uint32_t) -> c_int;
    pub fn modbus_set_response_timeout(ctx: *mut modbus_t, to_sec: uint32_t, to_usec: uint32_t) -> c_int;

    pub fn modbus_get_byte_timeout(ctx: *mut modbus_t, to_sec: *mut uint32_t, to_usec: *mut uint32_t) -> c_int;
    pub fn modbus_set_byte_timeout(ctx: *mut modbus_t, to_sec: uint32_t, to_usec: uint32_t) -> c_int;

    pub fn modbus_get_header_length(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_connect(ctx: *mut modbus_t) -> c_int;
    pub fn modbus_close(ctx: *mut modbus_t);

    pub fn modbus_free(ctx: *mut modbus_t);

    pub fn modbus_flush(ctx: *mut modbus_t) -> c_int;
    pub fn modbus_set_debug(ctx: *mut modbus_t, flag: c_int) -> c_int;

    pub fn modbus_strerror(errnum: c_int) -> *const c_char;

    pub fn modbus_read_bits(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint8_t) -> c_int;
    pub fn modbus_read_input_bits(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint8_t) -> c_int;
    pub fn modbus_read_registers(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint16_t) -> c_int;
    pub fn modbus_read_input_registers(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint16_t) -> c_int;
    pub fn modbus_write_bit(ctx: *mut modbus_t, coil_addr: c_int, status: c_int) -> c_int;
    pub fn modbus_write_register(ctx: *mut modbus_t, reg_addr: c_int, value: c_int) -> c_int;
    pub fn modbus_write_bits(ctx: *mut modbus_t, addr: c_int, nb: c_int, data: *const uint8_t) -> c_int;
    pub fn modbus_write_registers(ctx: *mut modbus_t, addr: c_int, nb: c_int, data: *const uint16_t) -> c_int;
    pub fn modbus_mask_write_register(ctx: *mut modbus_t, addr: c_int, and_mask: uint16_t, or_mask: uint16_t) -> c_int;
    pub fn modbus_write_and_read_registers(ctx: *mut modbus_t, write_addr: c_int, write_nb: c_int,
                                                   src: *const uint16_t, read_addr: c_int, read_nb: c_int,
                                                   dest: *mut uint16_t) -> c_int;
    pub fn modbus_report_slave_id(ctx: *mut modbus_t, max_dest: c_int, dest: *mut uint8_t) -> c_int;

    pub fn modbus_mapping_new_start_address(
        start_bits: c_uint, nb_bits: c_uint,
        start_input_bits: c_uint, nb_input_bits: c_uint,
        start_registers: c_uint, nb_registers: c_uint,
        start_input_registers: c_uint, nb_input_registers: c_uint) -> *mut modbus_mapping_t;

    pub fn modbus_mapping_new(nb_bits: c_int, nb_input_bits: c_int, nb_registers: c_int, nb_input_registers: c_int)  -> *mut modbus_mapping_t;
    pub fn modbus_mapping_free(mb_mapping: *mut modbus_mapping_t);

    pub fn modbus_send_raw_request(ctx: *mut modbus_t, raw_req: *mut uint8_t, raw_req_length: c_int) -> c_int;

    pub fn modbus_receive(ctx: *mut modbus_t, req: *mut uint8_t) -> c_int;

    pub fn modbus_receive_confirmation(ctx: *mut modbus_t, rsp: *mut uint8_t) -> c_int;

    pub fn modbus_reply(ctx: *mut modbus_t, req: *const uint8_t, req_length: c_int, mb_mapping: *mut modbus_mapping_t) -> c_int;
    pub fn modbus_reply_exception(ctx: *mut modbus_t, req: *const uint8_t, exception_code: c_uint) -> c_int;

    pub fn modbus_new_rtu(device: *const c_char, baud: c_int, parity: c_char, data_bit: c_int, stop_bit: c_int) -> *mut modbus_t;

    // modbus-rtu.h
    pub fn modbus_rtu_set_serial_mode(ctx: *mut modbus_t, mode: c_int) -> c_int;
    pub fn modbus_rtu_get_serial_mode(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_rtu_set_rts(ctx: *mut modbus_t, mode: c_int) -> c_int;
    pub fn modbus_rtu_get_rts(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_rtu_set_custom_rts(ctx: *mut modbus_t, set_rts: extern fn(ctx: *mut modbus_t, on: c_int)) -> c_int;

    pub fn modbus_rtu_set_rts_delay(ctx: *mut modbus_t, us: c_int) -> c_int;
    pub fn modbus_rtu_get_rts_delay(ctx: *mut modbus_t) -> c_int;

}

fn main() {
    let device: *const c_char = std::ffi::CString::new(std::env::args().nth(1).unwrap()).unwrap().as_ptr();
    let slave_id: i32 = std::env::args().nth(2).unwrap().parse().unwrap();

    unsafe {
        let mut tab_reg = vec![0u16; 32];

        let ctx = modbus_new_rtu(device, 9600, 'N' as c_char, 8, 1);
        modbus_set_slave(ctx, slave_id);
        modbus_set_debug(ctx, TRUE);

        modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
        modbus_rtu_set_rts(ctx, MODBUS_RTU_RTS_DOWN);

        if  modbus_connect(ctx) == -1 {
            modbus_free(ctx);
            panic!("Connection failed!");
        }
        // https://doc.rust-lang.org/std/primitive.pointer.html
        let rc = modbus_read_registers(ctx, 0, 19, tab_reg.as_mut_ptr());
        if rc == -1 {
            println!("Registers could not be read");
        }

        for i in 0..rc {
            println!("register[{}]=[{}] (0x{})", i, &tab_reg[i as usize], &tab_reg[i as usize]);
        }

    }
}
<commit_msg>Add custom logo, favicon and url to the documentation<commit_after>#![doc(html_logo_url = "https://raw.githubusercontent.com/Kliemann-Service-GmbH/xMZ-Mod-Touch-Server/master/share/xmz-logo.png",
       html_favicon_url = "https://raw.githubusercontent.com/Kliemann-Service-GmbH/xMZ-Mod-Touch-Server/master/share/favicon.ico",
       html_root_url = "https://gaswarnanlagen.com/")]
extern crate libc;
use libc::{c_char, c_int, uint8_t, uint16_t, uint32_t, c_void, timeval, c_uint, ssize_t, fd_set};

pub const FALSE: c_int = 0;
pub const TRUE: c_int = 1;
pub const OFF: c_int = 0;
pub const ON: c_int = 1;

macro_rules! modbus_enum {
    (pub enum $name:ident { $($variants:tt)* }) => {
        #[allow(non_camel_case_types)]
        #[cfg(target_env = "msvc")]
        pub type $name = i32;
        #[allow(non_camel_case_types)]
        #[cfg(not(target_env = "msvc"))]
        pub type $name = u32;
        modbus_enum!(gen, $name, 0, $($variants)*);
    };
    (pub enum $name:ident: $t:ty { $($variants:tt)* }) => {
        #[allow(non_camel_case_types)]
        pub type $name = $t;
        modbus_enum!(gen, $name, 0, $($variants)*);
    };
    (gen, $name:ident, $val:expr, $variant:ident, $($rest:tt)*) => {
        #[allow(non_camel_case_types)]
        pub const $variant: $name = $val;
        modbus_enum!(gen, $name, $val+1, $($rest)*);
    };
    (gen, $name:ident, $val:expr, $variant:ident = $e:expr, $($rest:tt)*) => {
        #[allow(non_camel_case_types)]
        pub const $variant: $name = $e;
        modbus_enum!(gen, $name, $e+1, $($rest)*);
    };
    (gen, $name:ident, $val:expr, ) => {}
}
modbus_enum! {
    pub enum  modbus_backend_type_t {
        _MODBUS_BACKEND_TYPE_RTU=0,
        _MODBUS_BACKEND_TYPE_TCP,
    }
}

modbus_enum! {
    pub enum modbus_error_recovery_mode {
        MODBUS_ERROR_RECOVERY_NONE          = 0,
        MODBUS_ERROR_RECOVERY_LINK          = (1<<1),
        MODBUS_ERROR_RECOVERY_PROTOCOL      = (1<<2),
    }
}

modbus_enum! {
    pub enum msg_type_t {
        MSG_INDICATION,
        MSG_CONFIRMATION,
    }
}

#[repr(C)]
#[allow(non_camel_case_types)]
pub struct modbus_backend_t {
    backend_type: c_uint,
    header_length: c_uint,
    checksum_length: c_uint,
    max_adu_length: c_uint,
    set_slave: extern fn(ctx: *mut modbus_t, slave: c_int) -> c_int,
    build_request_basis: extern fn(ctx: *mut modbus_t, function: c_int, addr: c_int,
                                nb: c_int, req: *mut uint8_t) -> c_int,
    build_response_basis: extern fn(sft: *mut sft_t, rsp: *mut uint8_t) -> c_int,
    prepare_response_tid: extern fn(req: *const uint8_t, req_length: *mut c_int) -> c_int,
    send_msg_pre: extern fn(req: *mut uint8_t, req_length: c_int) -> c_int,
    send: extern fn(ctx: *mut modbus_t, req: *const uint8_t, req_length: c_int) -> ssize_t,
    receive: extern fn(ctx: *mut modbus_t, req: *mut uint8_t) -> c_int,
    recv: extern fn(ctx: *mut modbus_t, rsp: *mut uint8_t, rsp_length: c_int) -> ssize_t,
    check_integrity: extern fn(ctx: *mut modbus_t, msg: *mut uint8_t,
                            msg_length: *const c_int) -> c_int,
    pre_check_confirmation: extern fn(ctx: *mut modbus_t, req: *const uint8_t,
                                   rsp: *const uint8_t, rsp_length: c_int) -> c_int,
    connect: extern fn(ctx: *mut modbus_t) -> c_int,
    close: extern fn(ctx: *mut modbus_t),
    flush: extern fn(ctx: *mut modbus_t) -> c_int,
    select: extern fn(ctx: *mut modbus_t, rset: *mut fd_set, tv: *mut timeval, msg_length: c_int) -> c_int,
    free: extern fn(ctx: *mut modbus_t),
}

#[repr(C)]
pub struct sft_t {
    slave: c_int,
    function: c_int,
    t_id: c_int,
}

#[repr(C)]
pub struct _modbus {
    /* Slave address */
    slave: c_int,
    /* Socket or file descriptor */
    s: c_int,
    debug: c_int,
    error_recovery: c_int,
    response_timeout: timeval,
    byte_timeout: timeval,
    backend: *const modbus_backend_t,
    backend_data: *mut c_void,
}

#[allow(non_camel_case_types)]
pub type modbus_t = _modbus;

#[repr(C)]
pub struct modbus_mapping_t {
    nb_bits: c_int,
    start_bits: c_int,
    nb_input_bits: c_int,
    start_input_bits: c_int,
    nb_input_registers: c_int,
    start_input_registers: c_int,
    nb_registers: c_int,
    start_registers: c_int,
    tab_bits: *mut uint8_t,
    tab_input_bits: *mut uint8_t,
    tab_input_registers: *mut uint16_t,
    tab_registers: *mut uint16_t,
}

// modbus-rtu.h
pub const MODBUS_RTU_MAX_ADU_LENGTH: c_int = 256;

pub const MODBUS_RTU_RS232: c_int = 0;
pub const MODBUS_RTU_RS485: c_int = 1;

pub const MODBUS_RTU_RTS_NONE: c_int = 0;
pub const MODBUS_RTU_RTS_UP: c_int   = 1;
pub const MODBUS_RTU_RTS_DOWN: c_int = 2;

#[link(name = "modbus")]
extern {
    pub fn modbus_set_slave(ctx: *mut modbus_t, slave: c_int) -> c_int;
    pub fn modbus_set_error_recovery(ctx: *mut modbus_t, error_recovery: modbus_error_recovery_mode) -> c_int;

    pub fn modbus_set_socket(ctx: *mut modbus_t, socket: c_int) -> c_int;
    pub fn modbus_get_socket(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_get_response_timeout(ctx: *mut modbus_t, to_sec: *mut uint32_t, to_usec: *mut uint32_t) -> c_int;
    pub fn modbus_set_response_timeout(ctx: *mut modbus_t, to_sec: uint32_t, to_usec: uint32_t) -> c_int;

    pub fn modbus_get_byte_timeout(ctx: *mut modbus_t, to_sec: *mut uint32_t, to_usec: *mut uint32_t) -> c_int;
    pub fn modbus_set_byte_timeout(ctx: *mut modbus_t, to_sec: uint32_t, to_usec: uint32_t) -> c_int;

    pub fn modbus_get_header_length(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_connect(ctx: *mut modbus_t) -> c_int;
    pub fn modbus_close(ctx: *mut modbus_t);

    pub fn modbus_free(ctx: *mut modbus_t);

    pub fn modbus_flush(ctx: *mut modbus_t) -> c_int;
    pub fn modbus_set_debug(ctx: *mut modbus_t, flag: c_int) -> c_int;

    pub fn modbus_strerror(errnum: c_int) -> *const c_char;

    pub fn modbus_read_bits(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint8_t) -> c_int;
    pub fn modbus_read_input_bits(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint8_t) -> c_int;
    pub fn modbus_read_registers(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint16_t) -> c_int;
    pub fn modbus_read_input_registers(ctx: *mut modbus_t, addr: c_int, nb: c_int, dest: *mut uint16_t) -> c_int;
    pub fn modbus_write_bit(ctx: *mut modbus_t, coil_addr: c_int, status: c_int) -> c_int;
    pub fn modbus_write_register(ctx: *mut modbus_t, reg_addr: c_int, value: c_int) -> c_int;
    pub fn modbus_write_bits(ctx: *mut modbus_t, addr: c_int, nb: c_int, data: *const uint8_t) -> c_int;
    pub fn modbus_write_registers(ctx: *mut modbus_t, addr: c_int, nb: c_int, data: *const uint16_t) -> c_int;
    pub fn modbus_mask_write_register(ctx: *mut modbus_t, addr: c_int, and_mask: uint16_t, or_mask: uint16_t) -> c_int;
    pub fn modbus_write_and_read_registers(ctx: *mut modbus_t, write_addr: c_int, write_nb: c_int,
                                                   src: *const uint16_t, read_addr: c_int, read_nb: c_int,
                                                   dest: *mut uint16_t) -> c_int;
    pub fn modbus_report_slave_id(ctx: *mut modbus_t, max_dest: c_int, dest: *mut uint8_t) -> c_int;

    pub fn modbus_mapping_new_start_address(
        start_bits: c_uint, nb_bits: c_uint,
        start_input_bits: c_uint, nb_input_bits: c_uint,
        start_registers: c_uint, nb_registers: c_uint,
        start_input_registers: c_uint, nb_input_registers: c_uint) -> *mut modbus_mapping_t;

    pub fn modbus_mapping_new(nb_bits: c_int, nb_input_bits: c_int, nb_registers: c_int, nb_input_registers: c_int)  -> *mut modbus_mapping_t;
    pub fn modbus_mapping_free(mb_mapping: *mut modbus_mapping_t);

    pub fn modbus_send_raw_request(ctx: *mut modbus_t, raw_req: *mut uint8_t, raw_req_length: c_int) -> c_int;

    pub fn modbus_receive(ctx: *mut modbus_t, req: *mut uint8_t) -> c_int;

    pub fn modbus_receive_confirmation(ctx: *mut modbus_t, rsp: *mut uint8_t) -> c_int;

    pub fn modbus_reply(ctx: *mut modbus_t, req: *const uint8_t, req_length: c_int, mb_mapping: *mut modbus_mapping_t) -> c_int;
    pub fn modbus_reply_exception(ctx: *mut modbus_t, req: *const uint8_t, exception_code: c_uint) -> c_int;

    pub fn modbus_new_rtu(device: *const c_char, baud: c_int, parity: c_char, data_bit: c_int, stop_bit: c_int) -> *mut modbus_t;

    // modbus-rtu.h
    pub fn modbus_rtu_set_serial_mode(ctx: *mut modbus_t, mode: c_int) -> c_int;
    pub fn modbus_rtu_get_serial_mode(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_rtu_set_rts(ctx: *mut modbus_t, mode: c_int) -> c_int;
    pub fn modbus_rtu_get_rts(ctx: *mut modbus_t) -> c_int;

    pub fn modbus_rtu_set_custom_rts(ctx: *mut modbus_t, set_rts: extern fn(ctx: *mut modbus_t, on: c_int)) -> c_int;

    pub fn modbus_rtu_set_rts_delay(ctx: *mut modbus_t, us: c_int) -> c_int;
    pub fn modbus_rtu_get_rts_delay(ctx: *mut modbus_t) -> c_int;

}

fn main() {
    let device: *const c_char = std::ffi::CString::new(std::env::args().nth(1).unwrap()).unwrap().as_ptr();
    let slave_id: i32 = std::env::args().nth(2).unwrap().parse().unwrap();

    unsafe {
        let mut tab_reg = vec![0u16; 32];

        let ctx = modbus_new_rtu(device, 9600, 'N' as c_char, 8, 1);
        modbus_set_slave(ctx, slave_id);
        modbus_set_debug(ctx, TRUE);

        modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
        modbus_rtu_set_rts(ctx, MODBUS_RTU_RTS_DOWN);

        if  modbus_connect(ctx) == -1 {
            modbus_free(ctx);
            panic!("Connection failed!");
        }
        // https://doc.rust-lang.org/std/primitive.pointer.html
        let rc = modbus_read_registers(ctx, 0, 19, tab_reg.as_mut_ptr());
        if rc == -1 {
            println!("Registers could not be read");
        }

        for i in 0..rc {
            println!("register[{}]=[{}] (0x{})", i, &tab_reg[i as usize], &tab_reg[i as usize]);
        }

    }
}
<|endoftext|>


<commit_before>#![cfg(target_os = "linux")]

extern crate polydraw;
extern crate rand;

use std::iter::repeat;
use rand::Rng;

use polydraw::os::xcb;
use polydraw::os::x11;
use polydraw::os::egl;
use polydraw::os::gl;
use polydraw::os::cl;

fn print_screen_info(screen: &xcb::Screen) {
   println!("Informations of screen .... : {}", screen.root());
   println!("   width .................. : {}", screen.width_in_pixels());
   println!("   height ................. : {}", screen.height_in_pixels());
   println!("   white pixel ............ : {}", screen.white_pixel());
   println!("   black pixel ............ : {}", screen.black_pixel());
}

fn print_platforms_info(platforms: &Vec<cl::Platform>) {
   for (i, platform) in platforms.iter().enumerate() {
      println!("CL platform [{}] ........... : {:?}", i, platform.ptr);
      println!("   Name ................... : {}", platform.name().unwrap());
      println!("   Vendor ................. : {}", platform.vendor().unwrap());
      println!("   Profile ................ : {}", platform.profile().unwrap());
      println!("   Version ................ : {}", platform.version().unwrap());
      println!("   Extensions ............. : {}", platform.extensions().unwrap());

      let devices = match platform.all_devices() {
         Ok(devices) => devices,
         Err(e) => {
            panic!(e.description);
         }
      };

      for (j, device) in devices.iter().enumerate() {
         println!("   CL device [{}] .......... : {:?}", j, device.ptr);
         println!("      Name ................ : {}", device.name().unwrap());
         println!("      Vendor .............. : {}", device.vendor().unwrap());
         println!("      Profile ............. : {}", device.profile().unwrap());
         println!("      Version ............. : {}", device.version().unwrap());
         println!("      OpenCL C version .... : {}", device.opencl_c_version().unwrap());
         println!("      Driver version ...... : {}", device.driver_version().unwrap());
         println!("      Built-in kernels .... : {}", device.built_in_kernels().unwrap());
         println!("      Extensions .......... : {}", device.extensions().unwrap());
         println!("      Available ........... : {}", device.available().unwrap());
         println!("      Compiler available .. : {}", device.compiler_available().unwrap());
         println!("      Linker available .... : {}", device.linker_available().unwrap());
         println!("      Little endian ....... : {}", device.endian_little().unwrap());
         println!("      Error correction .... : {}", device.error_correction().unwrap());
         println!("      Unified memory ...... : {}", device.unified_memory().unwrap());
         println!("      Image support ....... : {}", device.image_support().unwrap());
      }
   }
}

fn main() {
   let width: usize = 800;
   let height: usize = 450;

   let platforms = match cl::platforms() {
      Ok(platforms) => platforms,
      Err(e) => {
         panic!(e.description);
      }
   };

   print_platforms_info(&platforms);

   let display = match x11::Display::default() {
      Ok(display) => display,
      Err(e) => {
         panic!(e.description);
      }
   };

   let connection = match display.xcb_connection() {
      Ok(connection) => connection,
      Err(e) => {
         panic!(e.description);
      }
   };

   display.xcb_own_event_queue();

   let default_screen = display.default_screen();

   let scr = connection.screen_of_display(default_screen);

   print_screen_info(&scr);

   let window = connection.generate_id();

   println!("window .................... : {:?}", window);

   connection.create_window(
      window, &scr,
      0, 0, width as u16, height as u16,
   );

   connection.map_window(window);

   if !egl::bind_api(egl::API::OpenGL) {
      panic!("eglBindAPI failed");
   }

   let egl_d = egl::get_display(&display);
   let egl_display = egl_d.ptr;

   println!("egl display ............... : {:?}", egl_display);

   let version = match egl::initialize(&egl_d) {
      Ok(version) => version,
      Err(e) => {
         panic!(e.description);
      }
   };

   println!("egl version ............... : {:?}.{:?}", version.major, version.minor);

   let config = match egl::choose_config(&egl_d) {
      Ok(config) => config,
      Err(e) => {
         panic!(e.description);
      }
   };

   let context = match egl::create_context(&egl_d, &config) {
      Ok(context) => context,
      Err(e) => {
         panic!(e.description);
      }
   };

   println!("context ptr ............... : {:?}", context.ptr);

   let surface = match egl::create_window_surface(&egl_d, &config, &window) {
      Ok(surface) => surface,
      Err(e) => {
         panic!(e.description);
      }
   };

   println!("surface ptr ............... : {:?}", surface.ptr);

   match egl::make_current(&egl_d, &surface, &surface, &context) {
      Ok(_) => {},
      Err(e) => {
         panic!(e.description);
      }
   };

   match egl::query_context(&egl_d, &context) {
      Ok(_) => {},
      Err(e) => {
         panic!(e.description);
      }
   };

   gl::reset_pixelstore_alignment();

   let mut data = repeat(0u8)
      .take(width * height * 3)
      .collect::<Vec<_>>();

   rand::thread_rng().fill_bytes(&mut data);

   let texture = gl::create_texture(width, height, &data);

   println!("GL texture ................ : {:?}", texture);

   let framebuffer = gl::create_framebuffer(texture);

   println!("GL framebuffer ............ : {:?}", framebuffer);

   loop {
      let event = match connection.wait_for_event() {
         None => {
            return;
         },
         Some(event) => event
      };

      let event_type = event.event_type();

      match event_type {
         xcb::EventType::KeyPress => {
            break;
         },
         xcb::EventType::Expose => {
            //gl::clear_color(0.0, 0.7, 1.0, 1.0);
            //gl::clear();

            gl::blit_framebuffer(framebuffer, width, height);

            gl::flush();

            match egl::swap_buffers(&egl_d, &surface) {
               Ok(_) => {},
               Err(e) => {
                  panic!(e.description);
               }
            };
         }
         _ => {}
      }
   }

   connection.destroy_window(window);
}
<commit_msg>Bigger screen size for the window example<commit_after>#![cfg(target_os = "linux")]

extern crate polydraw;
extern crate rand;

use std::iter::repeat;
use rand::Rng;

use polydraw::os::xcb;
use polydraw::os::x11;
use polydraw::os::egl;
use polydraw::os::gl;
use polydraw::os::cl;

fn print_screen_info(screen: &xcb::Screen) {
   println!("Informations of screen .... : {}", screen.root());
   println!("   width .................. : {}", screen.width_in_pixels());
   println!("   height ................. : {}", screen.height_in_pixels());
   println!("   white pixel ............ : {}", screen.white_pixel());
   println!("   black pixel ............ : {}", screen.black_pixel());
}

fn print_platforms_info(platforms: &Vec<cl::Platform>) {
   for (i, platform) in platforms.iter().enumerate() {
      println!("CL platform [{}] ........... : {:?}", i, platform.ptr);
      println!("   Name ................... : {}", platform.name().unwrap());
      println!("   Vendor ................. : {}", platform.vendor().unwrap());
      println!("   Profile ................ : {}", platform.profile().unwrap());
      println!("   Version ................ : {}", platform.version().unwrap());
      println!("   Extensions ............. : {}", platform.extensions().unwrap());

      let devices = match platform.all_devices() {
         Ok(devices) => devices,
         Err(e) => {
            panic!(e.description);
         }
      };

      for (j, device) in devices.iter().enumerate() {
         println!("   CL device [{}] .......... : {:?}", j, device.ptr);
         println!("      Name ................ : {}", device.name().unwrap());
         println!("      Vendor .............. : {}", device.vendor().unwrap());
         println!("      Profile ............. : {}", device.profile().unwrap());
         println!("      Version ............. : {}", device.version().unwrap());
         println!("      OpenCL C version .... : {}", device.opencl_c_version().unwrap());
         println!("      Driver version ...... : {}", device.driver_version().unwrap());
         println!("      Built-in kernels .... : {}", device.built_in_kernels().unwrap());
         println!("      Extensions .......... : {}", device.extensions().unwrap());
         println!("      Available ........... : {}", device.available().unwrap());
         println!("      Compiler available .. : {}", device.compiler_available().unwrap());
         println!("      Linker available .... : {}", device.linker_available().unwrap());
         println!("      Little endian ....... : {}", device.endian_little().unwrap());
         println!("      Error correction .... : {}", device.error_correction().unwrap());
         println!("      Unified memory ...... : {}", device.unified_memory().unwrap());
         println!("      Image support ....... : {}", device.image_support().unwrap());
      }
   }
}

fn main() {
   let width: usize = 1280;
   let height: usize = 720;

   let platforms = match cl::platforms() {
      Ok(platforms) => platforms,
      Err(e) => {
         panic!(e.description);
      }
   };

   print_platforms_info(&platforms);

   let display = match x11::Display::default() {
      Ok(display) => display,
      Err(e) => {
         panic!(e.description);
      }
   };

   let connection = match display.xcb_connection() {
      Ok(connection) => connection,
      Err(e) => {
         panic!(e.description);
      }
   };

   display.xcb_own_event_queue();

   let default_screen = display.default_screen();

   let scr = connection.screen_of_display(default_screen);

   print_screen_info(&scr);

   let window = connection.generate_id();

   println!("window .................... : {:?}", window);

   connection.create_window(
      window, &scr,
      0, 0, width as u16, height as u16,
   );

   connection.map_window(window);

   if !egl::bind_api(egl::API::OpenGL) {
      panic!("eglBindAPI failed");
   }

   let egl_d = egl::get_display(&display);
   let egl_display = egl_d.ptr;

   println!("egl display ............... : {:?}", egl_display);

   let version = match egl::initialize(&egl_d) {
      Ok(version) => version,
      Err(e) => {
         panic!(e.description);
      }
   };

   println!("egl version ............... : {:?}.{:?}", version.major, version.minor);

   let config = match egl::choose_config(&egl_d) {
      Ok(config) => config,
      Err(e) => {
         panic!(e.description);
      }
   };

   let context = match egl::create_context(&egl_d, &config) {
      Ok(context) => context,
      Err(e) => {
         panic!(e.description);
      }
   };

   println!("context ptr ............... : {:?}", context.ptr);

   let surface = match egl::create_window_surface(&egl_d, &config, &window) {
      Ok(surface) => surface,
      Err(e) => {
         panic!(e.description);
      }
   };

   println!("surface ptr ............... : {:?}", surface.ptr);

   match egl::make_current(&egl_d, &surface, &surface, &context) {
      Ok(_) => {},
      Err(e) => {
         panic!(e.description);
      }
   };

   match egl::query_context(&egl_d, &context) {
      Ok(_) => {},
      Err(e) => {
         panic!(e.description);
      }
   };

   gl::reset_pixelstore_alignment();

   let mut data = repeat(0u8)
      .take(width * height * 3)
      .collect::<Vec<_>>();

   rand::thread_rng().fill_bytes(&mut data);

   let texture = gl::create_texture(width, height, &data);

   println!("GL texture ................ : {:?}", texture);

   let framebuffer = gl::create_framebuffer(texture);

   println!("GL framebuffer ............ : {:?}", framebuffer);

   loop {
      let event = match connection.wait_for_event() {
         None => {
            return;
         },
         Some(event) => event
      };

      let event_type = event.event_type();

      match event_type {
         xcb::EventType::KeyPress => {
            break;
         },
         xcb::EventType::Expose => {
            //gl::clear_color(0.0, 0.7, 1.0, 1.0);
            //gl::clear();

            //gl::blit_framebuffer(framebuffer, width, height);

            gl::flush();

            match egl::swap_buffers(&egl_d, &surface) {
               Ok(_) => {},
               Err(e) => {
                  panic!(e.description);
               }
            };
         }
         _ => {}
      }
   }

   connection.destroy_window(window);
}
<|endoftext|>


<commit_before>use error::{Error, Result};

pub struct Attributes<'a> {
    bytes: &'a [u8],
    position: usize,
}

impl<'a> Attributes<'a> {
    pub fn new(buf: &'a [u8], pos: usize) -> Attributes<'a> {
        Attributes {
            bytes: buf,
            position: pos,
        }
    }
}

impl<'a> Iterator for Attributes<'a> {
    type Item = Result<(&'a[u8], &'a str)>;
    fn next(&mut self) -> Option<Self::Item> {

        let len = self.bytes.len();
        let p = self.position;
        let mut iter = self.bytes[p..].iter().cloned().enumerate();

        let start_key = {
            let mut found_space = false;
            let p: usize;
            loop {
                match iter.next() {
                    Some((_, b' '))
                        | Some((_, b'\r'))
                        | Some((_, b'\n'))
                        | Some((_, b'\t')) => if !found_space { found_space = true; },
                    Some((i, _)) => if found_space {
                        p = i;
                        break;
                    },
                    None => {
                        self.position = len;
                        return None;
                    }
                }
            }
            p
        };

        let mut has_equal = false;
        let mut end_key = None;
        let mut start_val = None;
        let mut end_val = None;
        loop {
            match iter.next() {
                Some((i, b' '))
                    | Some((i, b'\r'))
                    | Some((i, b'\n'))
                    | Some((i, b'\t')) => {
                    if end_key.is_none() { end_key = Some(i); }
                },
                Some((i, b'=')) => {
                    if has_equal {
                        debug!("has_equal x2 !");
                        return None; // TODO: return error instead
                    }
                    has_equal = true;
                    if end_key.is_none() {
                        end_key = Some(i);
                    }
                },
                Some((i, b'"')) => {
                    if !has_equal {
                        return Some(Err(Error::Malformed("Unexpected quote before '='".to_owned())));
                    }
                    if start_val.is_none() {
                        start_val = Some(i + 1);
                    } else if end_val.is_none() {
                        end_val = Some(i);
                        break;
                    }
                },
                Some((_, _)) => (),
                None => {
                    self.position = len;
                    return None;
                }
            }
        }
        self.position = end_val.unwrap() + 1;

        match ::std::str::from_utf8(&self.bytes[(p + start_val.unwrap())..(p + end_val.unwrap())]) {
            Ok(s) => Some(Ok((&self.bytes[(p + start_key)..(p + end_key.unwrap())], s))),
            Err(e) => Some(Err(Error::from(e))),
        }
    }
}
<commit_msg>fix infinite loop iter attributes<commit_after>use error::{Error, Result};

pub struct Attributes<'a> {
    bytes: &'a [u8],
    position: usize,
    was_error: bool,
}

impl<'a> Attributes<'a> {
    pub fn new(buf: &'a [u8], pos: usize) -> Attributes<'a> {
        Attributes {
            bytes: buf,
            position: pos,
            was_error: false,
        }
    }
}

impl<'a> Iterator for Attributes<'a> {
    type Item = Result<(&'a[u8], &'a str)>;
    fn next(&mut self) -> Option<Self::Item> {

        if self.was_error { return None; }

        let len = self.bytes.len();
        let p = self.position;
        if len == p { return None; }

        let mut iter = self.bytes[p..].iter().cloned().enumerate();

        let start_key = {
            let mut found_space = false;
            let start: usize;
            loop {
                match iter.next() {
                    Some((_, b' '))
                        | Some((_, b'\r'))
                        | Some((_, b'\n'))
                        | Some((_, b'\t')) => if !found_space { found_space = true; },
                    Some((i, _)) => if found_space {
                        start = i;
                        break;
                    },
                    None => {
                        self.position = len;
                        return None;
                    }
                }
            }
            start
        };

        let mut has_equal = false;
        let mut end_key = None;
        let mut start_val = None;
        let mut end_val = None;
        loop {
            match iter.next() {
                Some((i, b' '))
                    | Some((i, b'\r'))
                    | Some((i, b'\n'))
                    | Some((i, b'\t')) => {
                    if end_key.is_none() { end_key = Some(i); }
                },
                Some((i, b'=')) => {
                    if has_equal {
                        self.was_error = true;
                        return Some(Err(Error::Malformed("Got 2 '=' tokens".to_owned())));
                    }
                    has_equal = true;
                    if end_key.is_none() {
                        end_key = Some(i);
                    }
                },
                Some((i, b'"')) => {
                    if !has_equal {
                        self.was_error = true;
                        return Some(Err(Error::Malformed("Unexpected quote before '='".to_owned())));
                    }
                    if start_val.is_none() {
                        start_val = Some(i + 1);
                    } else if end_val.is_none() {
                        end_val = Some(i);
                        break;
                    }
                },
                None => {
                    self.position = len;
                    return None;
                }
                Some((_, _)) => (),
            }
        }
        self.position += end_val.unwrap() + 1;

        match ::std::str::from_utf8(&self.bytes[(p + start_val.unwrap())..(p + end_val.unwrap())]) {
            Ok(s) => Some(Ok((&self.bytes[(p + start_key)..(p + end_key.unwrap())], s))),
            Err(e) => Some(Err(Error::from(e))),
        }
    }
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate nom;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::Stream;

use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    Stream::from_file(input_file).map_err(hound::Error::IoError)
  };
  let info       = stream.info();
  let frames_len = stream.frames.len();

  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  for sample in stream.iter() {
    try!(output.write_sample(sample));
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<commit_msg>No longer use the frame_len variable for iteration<commit_after>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate nom;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::Stream;

use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    Stream::from_file(input_file).map_err(hound::Error::IoError)
  };

  let info = stream.info();
  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  for sample in stream.iter() {
    try!(output.write_sample(sample));
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<|endoftext|>


<commit_before>extern crate rocks;

use rocks::rocksdb::*;
use std::env;

pub fn escape(data: &[u8]) -> String {
    let mut escaped = Vec::with_capacity(data.len() * 4);
    for &c in data {
        match c {
            b'\n' => escaped.extend_from_slice(br"\n"),
            b'\r' => escaped.extend_from_slice(br"\r"),
            b'\t' => escaped.extend_from_slice(br"\t"),
            b'"' => escaped.extend_from_slice(b"\\\""),
            b'\\' => escaped.extend_from_slice(br"\\"),
            _ => {
                if c >= 0x20 && c < 0x7f {
                    // c is printable
                    escaped.push(c);
                } else {
                    escaped.push(b'\\');
                    escaped.push(b'0' + (c >> 6));
                    escaped.push(b'0' + ((c >> 3) & 7));
                    escaped.push(b'0' + (c & 7));
                }
            }
        }
    }
    escaped.shrink_to_fit();
    unsafe { String::from_utf8_unchecked(escaped) }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = Options::default();

    let db_path = env::args().skip(1).next().expect("usage: ./dumper XXXX");

    let cfs = DB::list_column_families(&opts, &db_path).unwrap();
    let (db, cfs) = DB::open_for_readonly_with_column_families(&DBOptions::default(), &db_path, cfs, false)?;
    println!("DB => {:?}", db);

    for cf in &cfs {
        println!("{:?}", cf);
        let meta = db.get_column_family_metadata(cf);
        println!("{:?}", meta);
        let it = cf.new_iterator(&ReadOptions::default().pin_data(true));
        for (k, val) in it {
            println!("  {:?} => {:?}", escape(k), escape(val));
        }
    }
    Ok(())
}
<commit_msg>docs(examples): minor print style change to dumper<commit_after>extern crate rocks;

use rocks::rocksdb::*;
use std::env;

pub fn escape(data: &[u8]) -> String {
    let mut escaped = Vec::with_capacity(data.len() * 4);
    for &c in data {
        match c {
            b'\n' => escaped.extend_from_slice(br"\n"),
            b'\r' => escaped.extend_from_slice(br"\r"),
            b'\t' => escaped.extend_from_slice(br"\t"),
            b'"' => escaped.extend_from_slice(b"\\\""),
            b'\\' => escaped.extend_from_slice(br"\\"),
            _ => {
                if c >= 0x20 && c < 0x7f {
                    // c is printable
                    escaped.push(c);
                } else {
                    escaped.push(b'\\');
                    escaped.push(b'0' + (c >> 6));
                    escaped.push(b'0' + ((c >> 3) & 7));
                    escaped.push(b'0' + (c & 7));
                }
            }
        }
    }
    escaped.shrink_to_fit();
    unsafe { String::from_utf8_unchecked(escaped) }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = Options::default();

    let db_path = env::args().skip(1).next().expect("usage: ./dumper XXXX");

    let cfs = DB::list_column_families(&opts, &db_path).unwrap();
    let (db, cfs) = DB::open_for_readonly_with_column_families(&DBOptions::default(), &db_path, cfs, false)?;
    println!("DB => {:?}", db);

    for cf in &cfs {
        println!("{:?}", cf);
        let meta = db.get_column_family_metadata(cf);
        println!("{:?}", meta);
        let it = cf.new_iterator(&ReadOptions::default().pin_data(true));
        for (k, val) in it {
            println!(r#"  "{}" => "{}""#, escape(k), escape(val));
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::ptr;
use std::slice;
use std::ffi;
use std::i32;
use std::f32;

use htslib;

pub const MISSING_INTEGER: i32 = i32::MIN;
pub const MISSING_FLOAT: f32 = f32::NAN;
pub const VECTOR_END_INTEGER: i32 = i32::MIN + 1;
pub const VECTOR_END_FLOAT: f32 = 2.139095e+09;

pub struct Record {
    pub inner: *mut htslib::vcf::bcf1_t,
    pub header: *mut htslib::vcf::bcf_hdr_t,
    buffer: *mut ::libc::c_void,
}

impl Record {
    pub fn new() -> Self {
        let inner = unsafe { htslib::vcf::bcf_init() };
        Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
    }

    pub fn inner(&self) -> &htslib::vcf::bcf1_t {
        unsafe { &*self.inner }
    }

    pub fn inner_mut(&mut self) -> &mut htslib::vcf::bcf1_t {
        unsafe { &mut *self.inner }
    }

    pub fn rid(&self) -> Option<u32> {
        match self.inner().rid {
            -1  => None,
            rid => Some(rid as u32)
        }
    }

    // 0-based position.
    pub fn pos(&self) -> u32 {
        self.inner().pos as u32
    }

    pub fn set_pos(&mut self, pos: i32) {
        self.inner_mut().pos = pos;
    }

    pub fn alleles(&self) -> Vec<&[u8]> {
        unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
        let n = self.inner().n_allele as usize;
        let dec = self.inner().d;
        let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
        (0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
    }

    pub fn qual(&self) -> f32 {
        self.inner().qual
    }

    pub fn set_qual(&mut self, qual: f32) {
        self.inner_mut().qual = qual;
    }

    /// Get the value of the given info tag.
    pub fn info<'a>(&'a mut self, tag: &'a [u8]) -> Info {
        Info { record: self, tag: tag }
    }

    pub fn sample_count(&self) -> u32 {
        self.inner().n_fmt_n_sample >> 8
    }

    pub fn allele_count(&self) -> u16 {
        self.inner().n_allele
    }

    /// Get the value of the given format tag for each sample.
    pub fn format<'a>(&'a mut self, tag: &'a [u8]) -> Format {
        Format::new(self, tag)
    }

    /// Add an integer format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_INT)
    }

    /// Add a float format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_float(&mut self, tag: &[u8], data: &[f32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_REAL)
    }

    /// Add a format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    fn push_format<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_format(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Add a info tag.
    pub fn push_info<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_info(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Remove unused alleles.
    pub fn trim_alleles(&mut self) -> Result<(), ()> {
        match unsafe { htslib::vcfutils::bcf_trim_alleles(self.header, self.inner) } {
            -1 => Err(()),
            _  => Ok(())
        }
    }
}

impl Drop for Record {
    fn drop(&mut self) {
        if !self.buffer.is_null() {
            unsafe { ::libc::free(self.buffer) };
        }
        unsafe { htslib::vcf::bcf_destroy(self.inner) };
    }
}

unsafe impl Send for Record {}
unsafe impl Sync for Record {}

pub struct Info<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
}

impl<'a> Info<'a> {
    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_info_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<&[i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            trim_slice(
                unsafe { slice::from_raw_parts(self.record.buffer as *const i32, n) },
                VECTOR_END_INTEGER
            )
        })
    }

    pub fn integer_mut(&mut self) -> Result<&mut [i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut i32, n) }
        })
    }

    pub fn float(&mut self) -> Result<&[f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            trim_slice(
                unsafe { slice::from_raw_parts(self.record.buffer as *const f32, n) },
                VECTOR_END_FLOAT
            )
        })
    }

    pub fn float_mut(&mut self) -> Result<&mut [f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut f32, n) }
        })
    }

    pub fn flag(&mut self) -> Result<bool, TagError> {
        self.data(htslib::vcf::BCF_HT_FLAG).map(|(_, ret)| {
            ret == 1
        })
    }

    pub fn string(&mut self) -> Result<Vec<&[u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, ret)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const u8, ret as usize)
            }.chunks(n).map(|s| {
                // stop at zero character
                s.split(|c| *c == 0u8).next().expect("Bug: returned string should not be empty.")
            }).collect()
        })
    }

    pub fn string_mut(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, ret)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, ret as usize)
            }.chunks_mut(n).collect()
        })
    }
}

unsafe impl<'a> Send for Info<'a> {}
unsafe impl<'a> Sync for Info<'a> {}

fn trim_slice<T: PartialEq>(s: &[T], end_value: T) -> &[T] {
    s.split(|v| *v == end_value).next().expect("Bug: returned slice should not be empty.")
}

// TODO implement format.
pub struct Format<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
    inner: *mut htslib::vcf::bcf_fmt_t,
}

impl<'a> Format<'a> {
    fn new(record: &'a mut Record, tag: &'a [u8]) -> Format<'a> {
        let inner = unsafe { htslib::vcf::bcf_get_fmt(
            record.header,
            record.inner,
            ffi::CString::new(tag).unwrap().as_ptr() as *mut i8
        ) };
        Format { record: record, tag: tag, inner: inner }
    }

    pub fn inner(&self) -> &htslib::vcf::bcf_fmt_t {
        unsafe { &*self.inner }
    }

    pub fn inner_mut(&mut self) -> &mut htslib::vcf::bcf_fmt_t {
        unsafe { &mut *self.inner }
    }

    fn values_per_sample(&self) -> usize {
        self.inner().n as usize
    }

    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_format_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<Vec<&[i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const i32, n)
            }.chunks(self.values_per_sample()).map(|s| trim_slice(s, VECTOR_END_INTEGER)).collect()
        })
    }

    pub fn integer_mut(&mut self) -> Result<Vec<&mut [i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut i32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn float(&mut self) -> Result<Vec<&[f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const f32, n)
            }.chunks(self.values_per_sample()).map(|s| trim_slice(s, VECTOR_END_FLOAT)).collect()
        })
    }

    pub fn float_mut(&mut self) -> Result<Vec<&mut [f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut f32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn string(&mut self) -> Result<Vec<&[u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const u8, n)
            }.chunks(self.values_per_sample()).map(|s| {
                // stop at zero character
                s.split(|c| *c == 0u8).next().expect("Bug: returned string should not be empty.")
            }).collect()
        })
    }

    pub fn string_mut(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }
}

unsafe impl<'a> Send for Format<'a> {}
unsafe impl<'a> Sync for Format<'a> {}

#[derive(Debug)]
pub enum TagError {
    UndefinedTag,
    UnexpectedType,
    MissingTag,
}
<commit_msg>Add integer and float info tags.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::ptr;
use std::slice;
use std::ffi;
use std::i32;
use std::f32;

use htslib;

pub const MISSING_INTEGER: i32 = i32::MIN;
pub const MISSING_FLOAT: f32 = f32::NAN;
pub const VECTOR_END_INTEGER: i32 = i32::MIN + 1;
pub const VECTOR_END_FLOAT: f32 = 2.139095e+09;

pub struct Record {
    pub inner: *mut htslib::vcf::bcf1_t,
    pub header: *mut htslib::vcf::bcf_hdr_t,
    buffer: *mut ::libc::c_void,
}

impl Record {
    pub fn new() -> Self {
        let inner = unsafe { htslib::vcf::bcf_init() };
        Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
    }

    pub fn inner(&self) -> &htslib::vcf::bcf1_t {
        unsafe { &*self.inner }
    }

    pub fn inner_mut(&mut self) -> &mut htslib::vcf::bcf1_t {
        unsafe { &mut *self.inner }
    }

    pub fn rid(&self) -> Option<u32> {
        match self.inner().rid {
            -1  => None,
            rid => Some(rid as u32)
        }
    }

    // 0-based position.
    pub fn pos(&self) -> u32 {
        self.inner().pos as u32
    }

    pub fn set_pos(&mut self, pos: i32) {
        self.inner_mut().pos = pos;
    }

    pub fn alleles(&self) -> Vec<&[u8]> {
        unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
        let n = self.inner().n_allele as usize;
        let dec = self.inner().d;
        let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
        (0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
    }

    pub fn qual(&self) -> f32 {
        self.inner().qual
    }

    pub fn set_qual(&mut self, qual: f32) {
        self.inner_mut().qual = qual;
    }

    /// Get the value of the given info tag.
    pub fn info<'a>(&'a mut self, tag: &'a [u8]) -> Info {
        Info { record: self, tag: tag }
    }

    pub fn sample_count(&self) -> u32 {
        self.inner().n_fmt_n_sample >> 8
    }

    pub fn allele_count(&self) -> u16 {
        self.inner().n_allele
    }

    /// Get the value of the given format tag for each sample.
    pub fn format<'a>(&'a mut self, tag: &'a [u8]) -> Format {
        Format::new(self, tag)
    }

    /// Add an integer format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_INT)
    }

    /// Add a float format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_float(&mut self, tag: &[u8], data: &[f32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_REAL)
    }

    /// Add a format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    fn push_format<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_format(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Add an integer info tag.
    pub fn push_info_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<(), ()> {
        self.push_info(tag, data, htslib::vcf::BCF_HT_INT)
    }

    /// Add a float info tag.
    pub fn push_info_float(&mut self, tag: &[u8], data: &[f32]) -> Result<(), ()> {
        self.push_info(tag, data, htslib::vcf::BCF_HT_REAL)
    }

    /// Add an info tag.
    pub fn push_info<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_info(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Remove unused alleles.
    pub fn trim_alleles(&mut self) -> Result<(), ()> {
        match unsafe { htslib::vcfutils::bcf_trim_alleles(self.header, self.inner) } {
            -1 => Err(()),
            _  => Ok(())
        }
    }
}

impl Drop for Record {
    fn drop(&mut self) {
        if !self.buffer.is_null() {
            unsafe { ::libc::free(self.buffer) };
        }
        unsafe { htslib::vcf::bcf_destroy(self.inner) };
    }
}

unsafe impl Send for Record {}
unsafe impl Sync for Record {}

pub struct Info<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
}

impl<'a> Info<'a> {
    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_info_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<&[i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            trim_slice(
                unsafe { slice::from_raw_parts(self.record.buffer as *const i32, n) },
                VECTOR_END_INTEGER
            )
        })
    }

    pub fn integer_mut(&mut self) -> Result<&mut [i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut i32, n) }
        })
    }

    pub fn float(&mut self) -> Result<&[f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            trim_slice(
                unsafe { slice::from_raw_parts(self.record.buffer as *const f32, n) },
                VECTOR_END_FLOAT
            )
        })
    }

    pub fn float_mut(&mut self) -> Result<&mut [f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut f32, n) }
        })
    }

    pub fn flag(&mut self) -> Result<bool, TagError> {
        self.data(htslib::vcf::BCF_HT_FLAG).map(|(_, ret)| {
            ret == 1
        })
    }

    pub fn string(&mut self) -> Result<Vec<&[u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, ret)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const u8, ret as usize)
            }.chunks(n).map(|s| {
                // stop at zero character
                s.split(|c| *c == 0u8).next().expect("Bug: returned string should not be empty.")
            }).collect()
        })
    }

    pub fn string_mut(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, ret)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, ret as usize)
            }.chunks_mut(n).collect()
        })
    }
}

unsafe impl<'a> Send for Info<'a> {}
unsafe impl<'a> Sync for Info<'a> {}

fn trim_slice<T: PartialEq>(s: &[T], end_value: T) -> &[T] {
    s.split(|v| *v == end_value).next().expect("Bug: returned slice should not be empty.")
}

// TODO implement format.
pub struct Format<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
    inner: *mut htslib::vcf::bcf_fmt_t,
}

impl<'a> Format<'a> {
    fn new(record: &'a mut Record, tag: &'a [u8]) -> Format<'a> {
        let inner = unsafe { htslib::vcf::bcf_get_fmt(
            record.header,
            record.inner,
            ffi::CString::new(tag).unwrap().as_ptr() as *mut i8
        ) };
        Format { record: record, tag: tag, inner: inner }
    }

    pub fn inner(&self) -> &htslib::vcf::bcf_fmt_t {
        unsafe { &*self.inner }
    }

    pub fn inner_mut(&mut self) -> &mut htslib::vcf::bcf_fmt_t {
        unsafe { &mut *self.inner }
    }

    fn values_per_sample(&self) -> usize {
        self.inner().n as usize
    }

    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_format_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<Vec<&[i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const i32, n)
            }.chunks(self.values_per_sample()).map(|s| trim_slice(s, VECTOR_END_INTEGER)).collect()
        })
    }

    pub fn integer_mut(&mut self) -> Result<Vec<&mut [i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut i32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn float(&mut self) -> Result<Vec<&[f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const f32, n)
            }.chunks(self.values_per_sample()).map(|s| trim_slice(s, VECTOR_END_FLOAT)).collect()
        })
    }

    pub fn float_mut(&mut self) -> Result<Vec<&mut [f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut f32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn string(&mut self) -> Result<Vec<&[u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const u8, n)
            }.chunks(self.values_per_sample()).map(|s| {
                // stop at zero character
                s.split(|c| *c == 0u8).next().expect("Bug: returned string should not be empty.")
            }).collect()
        })
    }

    pub fn string_mut(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }
}

unsafe impl<'a> Send for Format<'a> {}
unsafe impl<'a> Sync for Format<'a> {}

#[derive(Debug)]
pub enum TagError {
    UndefinedTag,
    UnexpectedType,
    MissingTag,
}
<|endoftext|>


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

#![allow(dead_code)]

extern crate syntax;
extern crate walkdir;

use std;
use std::env;
use std::process::Command;

use self::walkdir::DirEntry;

pub mod eq;
pub mod parse;

pub fn check_min_stack() {
    let min_stack_value = match env::var("RUST_MIN_STACK") {
        Ok(s) => s,
        Err(_) => {
            env::set_var("RUST_MIN_STACK", 16000000.to_string());
            return;
        }
    };
    let min_stack_value: usize = min_stack_value
        .parse()
        .expect("RUST_MIN_STACK env var should be set since some tests require it.");
    assert!(min_stack_value >= 16_000_000);
}

/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
pub fn abort_after() -> usize {
    match env::var("ABORT_AFTER_FAILURE") {
        Ok(s) => s.parse().expect("failed to parse ABORT_AFTER_FAILURE"),
        Err(_) => std::usize::MAX,
    }
}

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }
    let path_string = path.to_string_lossy();
    let path_string = if cfg!(windows) {
        path_string.replace('\\', "/").into()
    } else {
        path_string
    };
    // TODO assert that parsing fails on the parse-fail cases
    if path_string.starts_with("tests/rust/src/test/parse-fail")
        || path_string.starts_with("tests/rust/src/test/compile-fail")
    {
        return false;
    }

    if path_string.starts_with("tests/rust/src/test/ui") {
        let stderr_path = path.with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    match path_string.as_ref() {
        // TODO better support for attributes
        //
        //      { #![foo] }
        "tests/rust/src/test/pretty/stmt_expr_attributes.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/cfg_stmt_expr.rs" |
        // TODO better support for attributes
        "tests/rust/src/test/run-pass/item-attributes.rs" |
        // Deprecated placement syntax
        "tests/rust/src/test/run-pass/new-box-syntax.rs" |
        // Deprecated placement syntax
        "tests/rust/src/test/run-pass/placement-in-syntax.rs" |
        // TODO inclusive range syntax
        "tests/rust/src/test/run-pass/range-inclusive-pattern-precedence.rs" |
        // TODO feature(extern_in_paths)
        //
        //      use extern::xcrate;
        "tests/rust/src/test/run-make-fulldeps/save-analysis-rfc2126/extern_in_paths.rs" |
        "tests/rust/src/test/run-pass/rfc-2126-extern-absolute-paths/extern.rs" |
        // TODO
        "tests/rust/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs" |
        "tests/rust/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs" |
        "tests/rust/src/test/run-pass/async-await.rs" |
        "tests/rust/src/test/run-pass/issue-49632.rs" |
        "tests/rust/src/test/run-pass/label_break_value.rs" |
        "tests/rust/src/test/run-pass/macros-in-extern.rs" |
        "tests/rust/src/test/run-pass/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs" |
        "tests/rust/src/test/rustfix/missing-comma-in-match.rs" |
        "tests/rust/src/test/rustfix/str-as-char.rs" |
        "tests/rust/src/test/rustfix/tuple-float-index.rs" |
        "tests/rust/src/test/ui/obsolete-in-place/bad.rs" |
        "tests/rust/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs" |
        // not actually test cases
        "tests/rust/src/test/run-pass/auxiliary/macro-comma-support.rs" |
        "tests/rust/src/test/run-pass/auxiliary/macro-include-items-expr.rs" => false,
        _ => true,
    }
}

pub fn clone_rust() {
    let result = Command::new("tests/clone.sh").status().unwrap();
    println!("result: {}", result);
    assert!(result.success());
}
<commit_msg>Triage the ignored test cases<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(dead_code)]

extern crate syntax;
extern crate walkdir;

use std;
use std::env;
use std::process::Command;

use self::walkdir::DirEntry;

pub mod eq;
pub mod parse;

pub fn check_min_stack() {
    let min_stack_value = match env::var("RUST_MIN_STACK") {
        Ok(s) => s,
        Err(_) => {
            env::set_var("RUST_MIN_STACK", 16000000.to_string());
            return;
        }
    };
    let min_stack_value: usize = min_stack_value
        .parse()
        .expect("RUST_MIN_STACK env var should be set since some tests require it.");
    assert!(min_stack_value >= 16_000_000);
}

/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
pub fn abort_after() -> usize {
    match env::var("ABORT_AFTER_FAILURE") {
        Ok(s) => s.parse().expect("failed to parse ABORT_AFTER_FAILURE"),
        Err(_) => std::usize::MAX,
    }
}

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }
    let path_string = path.to_string_lossy();
    let path_string = if cfg!(windows) {
        path_string.replace('\\', "/").into()
    } else {
        path_string
    };
    // TODO assert that parsing fails on the parse-fail cases
    if path_string.starts_with("tests/rust/src/test/parse-fail")
        || path_string.starts_with("tests/rust/src/test/compile-fail")
        || path_string.starts_with("tests/rust/src/test/rustfix")
    {
        return false;
    }

    if path_string.starts_with("tests/rust/src/test/ui") {
        let stderr_path = path.with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    match path_string.as_ref() {
        // TODO outer attributes on literals
        //
        //     #[noop] "Hello, world!"
        //     #[cfg(unset)] 341
        "tests/rust/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs" |
        "tests/rust/src/test/run-pass/cfg_stmt_expr.rs" |
        // TODO outer attributes on closures
        //
        //     #[inline] || {}
        "tests/rust/src/test/run-pass/issue-49632.rs" |
        // TODO inner attributes within expressions
        //
        //     { #![foo] }
        "tests/rust/src/test/pretty/stmt_expr_attributes.rs" |
        // TODO inner attributes within blocks
        //
        //     fn test_fn_inner() { #![inner_fn_attr] }
        "tests/rust/src/test/run-pass/item-attributes.rs" |
        // TODO inclusive range syntax
        "tests/rust/src/test/run-pass/range-inclusive-pattern-precedence.rs" |
        // TODO feature(extern_in_paths)
        //
        //      use extern::xcrate;
        "tests/rust/src/test/run-make-fulldeps/save-analysis-rfc2126/extern_in_paths.rs" |
        "tests/rust/src/test/run-pass/rfc-2126-extern-absolute-paths/extern.rs" |
        // TODO feature(macros_in_extern)
        //
        // https://github.com/dtolnay/syn/issues/390
        "tests/rust/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs" |
        "tests/rust/src/test/run-pass/macros-in-extern.rs" |
        // TODO async closures and async functions
        //
        // https://github.com/dtolnay/syn/issues/396
        // https://github.com/dtolnay/syn/issues/395
        "tests/rust/src/test/run-pass/async-await.rs" |
        // TODO feature(label_break_value)
        //
        //     'block: { break 'block "value" }
        "tests/rust/src/test/run-pass/label_break_value.rs" |
        // TODO unreserve pure, offsetof, sizeof, alignof
        "tests/rust/src/test/run-pass/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs" |
        // TODO where-clause on associated types
        //
        //     impl Foo for Bar {
        //         type Assoc3<T> where T: Iterator = Vec<T>;
        //     }
        "tests/rust/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs" |
        // Deprecated placement syntax
        "tests/rust/src/test/run-pass/new-box-syntax.rs" |
        "tests/rust/src/test/ui/obsolete-in-place/bad.rs" |
        // not actually test cases
        "tests/rust/src/test/run-pass/auxiliary/macro-comma-support.rs" |
        "tests/rust/src/test/run-pass/auxiliary/macro-include-items-expr.rs" => false,
        _ => true,
    }
}

pub fn clone_rust() {
    let result = Command::new("tests/clone.sh").status().unwrap();
    println!("result: {}", result);
    assert!(result.success());
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Hooks for for the RPC system.
//!
//! Roughly corresponds to capability.h in the C++ implementation.

use any_pointer;
use private::capability::{ClientHook, ParamsHook, RequestHook, ResponseHook, ResultsHook};

#[cfg(feature = "rpc")]
pub type Promise<T,E> = ::gj::Promise<T,E>;

/// This fake Promise struct is defined so that the generated code for interfaces
/// can typecheck even if the "rpc" feature is not enabled.
#[cfg(not(feature = "rpc"))]
pub struct Promise<T,E>(::std::result::Result<T,E>);

#[cfg(not(feature = "rpc"))]
impl <T,E> Promise<T,E> {
    pub fn ok(v: T) -> Promise<T,E> {
        Promise(Ok(v))
    }
    pub fn err(e: E) -> Promise<T,E> {
        Promise(Err(e))
    }
    pub fn map<F, R>(self, _func: F) -> Promise<R, E>
        where F: FnOnce(T) -> Result<R, E>,
    {
        unimplemented!()
    }
}

pub struct RemotePromise<Results> where Results: ::traits::Pipelined + for<'a> ::traits::Owned<'a> + 'static {
    pub promise: Promise<Response<Results>, ::Error>,
    pub pipeline: Results::Pipeline,
}

pub struct ReaderCapTable {
    pub hooks: Vec<Option<Box<ClientHook>>>
}

impl ReaderCapTable {
    pub fn new(hooks: Vec<Option<Box<ClientHook>>>) -> ReaderCapTable {
        ReaderCapTable { hooks: hooks }
    }

    // Do I need an Imbueable trait?
    pub fn imbue<'a, T>(&'a self) -> T {
        &self.hooks;
        unimplemented!();
    }
}

pub struct Response<Results> {
    pub marker: ::std::marker::PhantomData<Results>,
    pub hook: Box<ResponseHook>,
}

impl <Results> Response<Results>
    where Results: ::traits::Pipelined + for<'a> ::traits::Owned<'a>
{
    pub fn new(hook: Box<ResponseHook>) -> Response<Results> {
        Response { marker: ::std::marker::PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> ::Result<<Results as ::traits::Owned<'a>>::Reader> {
        try!(self.hook.get()).get_as()
    }
}

pub struct Request<Params, Results> {
    pub marker: ::std::marker::PhantomData<(Params, Results)>,
    pub hook: Box<RequestHook>
}

impl <Params, Results> Request <Params, Results>
    where Params: for<'a> ::traits::Owned<'a>
{
    pub fn new(hook: Box<RequestHook>) -> Request <Params, Results> {
        Request { hook: hook, marker: ::std::marker::PhantomData }
    }

    pub fn get<'a>(&'a mut self) -> <Params as ::traits::Owned<'a>>::Builder {
        self.hook.get().init_as()
    }
}

#[cfg(feature = "rpc")]
impl <Params, Results> Request <Params, Results>
where Results: ::traits::Pipelined + for<'a> ::traits::Owned<'a> + 'static,
      <Results as ::traits::Pipelined>::Pipeline: FromTypelessPipeline
{
    pub fn send(self) -> RemotePromise<Results> {
        let RemotePromise {promise, pipeline, ..} = self.hook.send();
        let typed_promise = promise.map(|response| {
            Ok(Response {hook: response.hook,
                        marker: ::std::marker::PhantomData})
        });
        RemotePromise { promise: typed_promise,
                        pipeline: FromTypelessPipeline::new(pipeline)
                      }
    }
}

pub struct Params<T> {
    pub marker: ::std::marker::PhantomData<T>,
    pub hook: Box<ParamsHook>,
}

impl <T> Params <T> {
    pub fn new(hook: Box<ParamsHook>) -> Params<T> {
        Params { marker: ::std::marker::PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> <T as ::traits::Owned<'a>>::Reader
        where T: ::traits::Owned<'a>
    {
        self.hook.get().unwrap().get_as().unwrap()
    }
}

pub struct Results<T> {
    pub marker: ::std::marker::PhantomData<T>,
    pub hook: Box<ResultsHook>,
}

impl <T> Results<T> {
    pub fn new(hook: Box<ResultsHook>) -> Results<T> {
        Results { marker: ::std::marker::PhantomData, hook: hook }
    }

    pub fn get<'a>(&'a mut self) -> <T as ::traits::Owned<'a>>::Builder
        where T: ::traits::Owned<'a>
    {
        self.hook.get().unwrap().get_as().unwrap()
    }
}

pub trait FromTypelessPipeline {
    fn new (typeless: any_pointer::Pipeline) -> Self;
}

pub trait FromClientHook {
    fn new(Box<ClientHook>) -> Self;
}

pub struct Client {
    pub hook: Box<ClientHook>
}

impl Client {
    pub fn new(hook: Box<ClientHook>) -> Client {
        Client { hook : hook }
    }

    pub fn new_call<Params, Results>(&self,
                                     interface_id : u64,
                                     method_id : u16,
                                     size_hint : Option<::MessageSize>)
                                     -> Request<Params, Results> {
        let typeless = self.hook.new_call(interface_id, method_id, size_hint);
        Request { hook: typeless.hook, marker: ::std::marker::PhantomData }
    }
}

pub trait Server {
    fn dispatch_call(&mut self, interface_id: u64, method_id: u16,
                     params: Params<any_pointer::Owned>,
                     results: Results<any_pointer::Owned>)
                     -> Promise<Results<any_pointer::Owned>, ::Error>;
}

<commit_msg>Make RemotePromise must_use.<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Hooks for for the RPC system.
//!
//! Roughly corresponds to capability.h in the C++ implementation.

use any_pointer;
use private::capability::{ClientHook, ParamsHook, RequestHook, ResponseHook, ResultsHook};

#[cfg(feature = "rpc")]
pub type Promise<T,E> = ::gj::Promise<T,E>;

/// This fake Promise struct is defined so that the generated code for interfaces
/// can typecheck even if the "rpc" feature is not enabled.
#[cfg(not(feature = "rpc"))]
pub struct Promise<T,E>(::std::result::Result<T,E>);

#[cfg(not(feature = "rpc"))]
impl <T,E> Promise<T,E> {
    pub fn ok(v: T) -> Promise<T,E> {
        Promise(Ok(v))
    }
    pub fn err(e: E) -> Promise<T,E> {
        Promise(Err(e))
    }
    pub fn map<F, R>(self, _func: F) -> Promise<R, E>
        where F: FnOnce(T) -> Result<R, E>,
    {
        unimplemented!()
    }
}

#[must_use]
pub struct RemotePromise<Results> where Results: ::traits::Pipelined + for<'a> ::traits::Owned<'a> + 'static {
    pub promise: Promise<Response<Results>, ::Error>,
    pub pipeline: Results::Pipeline,
}

pub struct ReaderCapTable {
    pub hooks: Vec<Option<Box<ClientHook>>>
}

impl ReaderCapTable {
    pub fn new(hooks: Vec<Option<Box<ClientHook>>>) -> ReaderCapTable {
        ReaderCapTable { hooks: hooks }
    }

    // Do I need an Imbueable trait?
    pub fn imbue<'a, T>(&'a self) -> T {
        &self.hooks;
        unimplemented!();
    }
}

pub struct Response<Results> {
    pub marker: ::std::marker::PhantomData<Results>,
    pub hook: Box<ResponseHook>,
}

impl <Results> Response<Results>
    where Results: ::traits::Pipelined + for<'a> ::traits::Owned<'a>
{
    pub fn new(hook: Box<ResponseHook>) -> Response<Results> {
        Response { marker: ::std::marker::PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> ::Result<<Results as ::traits::Owned<'a>>::Reader> {
        try!(self.hook.get()).get_as()
    }
}

pub struct Request<Params, Results> {
    pub marker: ::std::marker::PhantomData<(Params, Results)>,
    pub hook: Box<RequestHook>
}

impl <Params, Results> Request <Params, Results>
    where Params: for<'a> ::traits::Owned<'a>
{
    pub fn new(hook: Box<RequestHook>) -> Request <Params, Results> {
        Request { hook: hook, marker: ::std::marker::PhantomData }
    }

    pub fn get<'a>(&'a mut self) -> <Params as ::traits::Owned<'a>>::Builder {
        self.hook.get().init_as()
    }
}

#[cfg(feature = "rpc")]
impl <Params, Results> Request <Params, Results>
where Results: ::traits::Pipelined + for<'a> ::traits::Owned<'a> + 'static,
      <Results as ::traits::Pipelined>::Pipeline: FromTypelessPipeline
{
    pub fn send(self) -> RemotePromise<Results> {
        let RemotePromise {promise, pipeline, ..} = self.hook.send();
        let typed_promise = promise.map(|response| {
            Ok(Response {hook: response.hook,
                        marker: ::std::marker::PhantomData})
        });
        RemotePromise { promise: typed_promise,
                        pipeline: FromTypelessPipeline::new(pipeline)
                      }
    }
}

pub struct Params<T> {
    pub marker: ::std::marker::PhantomData<T>,
    pub hook: Box<ParamsHook>,
}

impl <T> Params <T> {
    pub fn new(hook: Box<ParamsHook>) -> Params<T> {
        Params { marker: ::std::marker::PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> <T as ::traits::Owned<'a>>::Reader
        where T: ::traits::Owned<'a>
    {
        self.hook.get().unwrap().get_as().unwrap()
    }
}

pub struct Results<T> {
    pub marker: ::std::marker::PhantomData<T>,
    pub hook: Box<ResultsHook>,
}

impl <T> Results<T> {
    pub fn new(hook: Box<ResultsHook>) -> Results<T> {
        Results { marker: ::std::marker::PhantomData, hook: hook }
    }

    pub fn get<'a>(&'a mut self) -> <T as ::traits::Owned<'a>>::Builder
        where T: ::traits::Owned<'a>
    {
        self.hook.get().unwrap().get_as().unwrap()
    }
}

pub trait FromTypelessPipeline {
    fn new (typeless: any_pointer::Pipeline) -> Self;
}

pub trait FromClientHook {
    fn new(Box<ClientHook>) -> Self;
}

pub struct Client {
    pub hook: Box<ClientHook>
}

impl Client {
    pub fn new(hook: Box<ClientHook>) -> Client {
        Client { hook : hook }
    }

    pub fn new_call<Params, Results>(&self,
                                     interface_id : u64,
                                     method_id : u16,
                                     size_hint : Option<::MessageSize>)
                                     -> Request<Params, Results> {
        let typeless = self.hook.new_call(interface_id, method_id, size_hint);
        Request { hook: typeless.hook, marker: ::std::marker::PhantomData }
    }
}

pub trait Server {
    fn dispatch_call(&mut self, interface_id: u64, method_id: u16,
                     params: Params<any_pointer::Owned>,
                     results: Results<any_pointer::Owned>)
                     -> Promise<Results<any_pointer::Owned>, ::Error>;
}

<|endoftext|>