<commit_before>//! Handle process life-time and message passing for proc-macro client

use std::{
    convert::{TryFrom, TryInto},
    ffi::{OsStr, OsString},
    fmt,
    io::{self, BufRead, BufReader, Write},
    path::{Path, PathBuf},
    process::{Child, ChildStdin, ChildStdout, Command, Stdio},
    sync::Mutex,
};

use stdx::JodChild;

use crate::{
    msg::{ErrorCode, Message, Request, Response, ResponseError},
    rpc::{ListMacrosResult, ListMacrosTask, ProcMacroKind},
};

pub(crate) struct ProcMacroProcessSrv {
    process: Mutex<Process>,
    stdio: Mutex<(ChildStdin, BufReader<ChildStdout>)>,
}

impl fmt::Debug for ProcMacroProcessSrv {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ProcMacroProcessSrv").field("process", &self.process).finish()
    }
}

impl ProcMacroProcessSrv {
    pub(crate) fn run(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<ProcMacroProcessSrv> {
        let mut process = Process::run(process_path, args)?;
        let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");

        let srv = ProcMacroProcessSrv {
            process: Mutex::new(process),
            stdio: Mutex::new((stdin, stdout)),
        };

        Ok(srv)
    }

    pub(crate) fn find_proc_macros(
        &self,
        dylib_path: &Path,
    ) -> Result<Vec<(String, ProcMacroKind)>, tt::ExpansionError> {
        let task = ListMacrosTask { lib: dylib_path.to_path_buf() };

        let result: ListMacrosResult = self.send_task(Request::ListMacro(task))?;
        Ok(result.macros)
    }

    pub(crate) fn send_task<R>(&self, req: Request) -> Result<R, tt::ExpansionError>
    where
        R: TryFrom<Response, Error = &'static str>,
    {
        let mut guard = self.stdio.lock().unwrap_or_else(|e| e.into_inner());
        let stdio = &mut *guard;
        let (stdin, stdout) = (&mut stdio.0, &mut stdio.1);

        let mut buf = String::new();
        let res = match send_request(stdin, stdout, req, &mut buf) {
            Ok(res) => res,
            Err(err) => {
                let mut process = self.process.lock().unwrap_or_else(|e| e.into_inner());
                log::error!(
                    "proc macro server crashed, server process state: {:?}, server request error: {:?}",
                    process.child.try_wait(),
                    err
                );
                let res = Response::Error(ResponseError {
                    code: ErrorCode::ServerErrorEnd,
                    message: "proc macro server crashed".into(),
                });
                Some(res)
            }
        };

        match res {
            Some(Response::Error(err)) => Err(tt::ExpansionError::ExpansionError(err.message)),
            Some(res) => Ok(res.try_into().map_err(|err| {
                tt::ExpansionError::Unknown(format!("Fail to get response, reason : {:#?} ", err))
            })?),
            None => Err(tt::ExpansionError::Unknown("Empty result".into())),
        }
    }
}

#[derive(Debug)]
struct Process {
    child: JodChild,
}

impl Process {
    fn run(
        path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<Process> {
        let args: Vec<OsString> = args.into_iter().map(|s| s.as_ref().into()).collect();
        let child = JodChild(mk_child(&path, &args)?);
        Ok(Process { child })
    }

    fn stdio(&mut self) -> Option<(ChildStdin, BufReader<ChildStdout>)> {
        let stdin = self.child.stdin.take()?;
        let stdout = self.child.stdout.take()?;
        let read = BufReader::new(stdout);

        Some((stdin, read))
    }
}

fn mk_child(path: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> io::Result<Child> {
    Command::new(&path)
        .args(args)
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
}

fn send_request(
    mut writer: &mut impl Write,
    mut reader: &mut impl BufRead,
    req: Request,
    buf: &mut String,
) -> io::Result<Option<Response>> {
    req.write(&mut writer)?;
    Response::read(&mut reader, buf)
}
<commit_msg>Use `#[derive(Debug)]`<commit_after>//! Handle process life-time and message passing for proc-macro client

use std::{
    convert::{TryFrom, TryInto},
    ffi::{OsStr, OsString},
    io::{self, BufRead, BufReader, Write},
    path::{Path, PathBuf},
    process::{Child, ChildStdin, ChildStdout, Command, Stdio},
    sync::Mutex,
};

use stdx::JodChild;

use crate::{
    msg::{ErrorCode, Message, Request, Response, ResponseError},
    rpc::{ListMacrosResult, ListMacrosTask, ProcMacroKind},
};

#[derive(Debug)]
pub(crate) struct ProcMacroProcessSrv {
    process: Mutex<Process>,
    stdio: Mutex<(ChildStdin, BufReader<ChildStdout>)>,
}

impl ProcMacroProcessSrv {
    pub(crate) fn run(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<ProcMacroProcessSrv> {
        let mut process = Process::run(process_path, args)?;
        let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");

        let srv = ProcMacroProcessSrv {
            process: Mutex::new(process),
            stdio: Mutex::new((stdin, stdout)),
        };

        Ok(srv)
    }

    pub(crate) fn find_proc_macros(
        &self,
        dylib_path: &Path,
    ) -> Result<Vec<(String, ProcMacroKind)>, tt::ExpansionError> {
        let task = ListMacrosTask { lib: dylib_path.to_path_buf() };

        let result: ListMacrosResult = self.send_task(Request::ListMacro(task))?;
        Ok(result.macros)
    }

    pub(crate) fn send_task<R>(&self, req: Request) -> Result<R, tt::ExpansionError>
    where
        R: TryFrom<Response, Error = &'static str>,
    {
        let mut guard = self.stdio.lock().unwrap_or_else(|e| e.into_inner());
        let stdio = &mut *guard;
        let (stdin, stdout) = (&mut stdio.0, &mut stdio.1);

        let mut buf = String::new();
        let res = match send_request(stdin, stdout, req, &mut buf) {
            Ok(res) => res,
            Err(err) => {
                let mut process = self.process.lock().unwrap_or_else(|e| e.into_inner());
                log::error!(
                    "proc macro server crashed, server process state: {:?}, server request error: {:?}",
                    process.child.try_wait(),
                    err
                );
                let res = Response::Error(ResponseError {
                    code: ErrorCode::ServerErrorEnd,
                    message: "proc macro server crashed".into(),
                });
                Some(res)
            }
        };

        match res {
            Some(Response::Error(err)) => Err(tt::ExpansionError::ExpansionError(err.message)),
            Some(res) => Ok(res.try_into().map_err(|err| {
                tt::ExpansionError::Unknown(format!("Fail to get response, reason : {:#?} ", err))
            })?),
            None => Err(tt::ExpansionError::Unknown("Empty result".into())),
        }
    }
}

#[derive(Debug)]
struct Process {
    child: JodChild,
}

impl Process {
    fn run(
        path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<Process> {
        let args: Vec<OsString> = args.into_iter().map(|s| s.as_ref().into()).collect();
        let child = JodChild(mk_child(&path, &args)?);
        Ok(Process { child })
    }

    fn stdio(&mut self) -> Option<(ChildStdin, BufReader<ChildStdout>)> {
        let stdin = self.child.stdin.take()?;
        let stdout = self.child.stdout.take()?;
        let read = BufReader::new(stdout);

        Some((stdin, read))
    }
}

fn mk_child(path: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> io::Result<Child> {
    Command::new(&path)
        .args(args)
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
}

fn send_request(
    mut writer: &mut impl Write,
    mut reader: &mut impl BufRead,
    req: Request,
    buf: &mut String,
) -> io::Result<Option<Response>> {
    req.write(&mut writer)?;
    Response::read(&mut reader, buf)
}
<|endoftext|>


<commit_before>error_chain!();
<commit_msg>fix warning<commit_after>#![allow(unused_doc_comment)]
error_chain!();
<|endoftext|>


<commit_before>#[cfg(feature = "egg-mode")]
extern crate egg_mode;
#[cfg(feature = "tweetust")]
extern crate tweetust;

use hyper::header::{Authorization, Scheme};
use oauthcli::{
    OAuthAuthorizationHeader,
    OAuthAuthorizationHeaderBuilder,
    ParseOAuthAuthorizationHeaderError,
    SignatureMethod,
};
use std::borrow::Cow;
use std::fmt::{self, Formatter};
use std::str::FromStr;
use types::RequestMethod;
use url::Url;

/// A token used to log into Twitter.
#[cfg_attr(feature = "tweetust", doc = "

This implements `tweetust::conn::Authenticator` so you can pass it to `tweetust::TwitterClient`
as if it were `tweetust::OAuthAuthenticator`"
)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Token<'a> {
    pub consumer_key: Cow<'a, str>,
    pub consumer_secret: Cow<'a, str>,
    pub access_key: Cow<'a, str>,
    pub access_secret: Cow<'a, str>,
}

#[derive(Clone, Debug)]
pub struct OAuthHeaderWrapper(pub OAuthAuthorizationHeader);

impl<'a> Token<'a> {
    pub fn new<CK, CS, AK, AS>(consumer_key: CK, consumer_secret: CS, access_key: AK, access_secret: AS) -> Self
        where CK: Into<Cow<'a, str>>, CS: Into<Cow<'a, str>>, AK: Into<Cow<'a, str>>, AS: Into<Cow<'a, str>>
    {
        Token {
            consumer_key: consumer_key.into(),
            consumer_secret: consumer_secret.into(),
            access_key: access_key.into(),
            access_secret: access_secret.into(),
        }
    }
}

#[cfg(feature = "egg-mode")]
impl<'a> From<Token<'a>> for egg_mode::Token<'a> {
    fn from(t: Token<'a>) -> Self {
        egg_mode::Token::Access {
            consumer: egg_mode::KeyPair::new(t.consumer_key, t.consumer_secret),
            access: egg_mode::KeyPair::new(t.access_key, t.access_secret),
        }
    }
}

#[cfg(feature = "tweetust")]
impl<'a> tweetust::conn::Authenticator for Token<'a> {
    type Scheme = OAuthAuthorizationHeader;

    fn create_authorization_header(&self, request: &tweetust::conn::Request) -> Option<OAuthAuthorizationHeader> {
        let params = if let tweetust::conn::RequestContent::WwwForm(ref params) = request.content {
            Some(params.as_ref().iter().map(|&(ref k, ref v)| (k.as_ref(), v.as_ref())))
        } else {
            None
        };

        Some(authorize(self, request.method.as_ref(), &request.url, params))
    }
}

impl FromStr for OAuthHeaderWrapper {
    type Err = ParseOAuthAuthorizationHeaderError;

    fn from_str(s: &str) -> Result<Self, ParseOAuthAuthorizationHeaderError> {
        Ok(OAuthHeaderWrapper(OAuthAuthorizationHeader::from_str(s)?))
    }
}

impl Scheme for OAuthHeaderWrapper {
    fn scheme() -> Option<&'static str> {
        Some("OAuth")
    }

    fn fmt_scheme(&self, f: &mut Formatter) -> fmt::Result {
        f.write_str(self.0.auth_param())
    }
}

pub fn create_authorization_header<'a>(token: &Token<'a>, method: &RequestMethod, url: &Url, params: Option<&[u8]>)
    -> Authorization<OAuthHeaderWrapper>
{
    use url::form_urlencoded;

    Authorization(OAuthHeaderWrapper(
        authorize(token, method.as_ref(), url, params.map(form_urlencoded::parse))
    ))
}

fn authorize<'a, K, V, P>(token: &'a Token<'a>, method: &'a str, url: &'a Url, params: Option<P>)
    -> OAuthAuthorizationHeader
    where K: Into<Cow<'a, str>>, V: Into<Cow<'a, str>>, P: Iterator<Item=(K, V)>
{
    let mut oauth = OAuthAuthorizationHeaderBuilder::new(
        method, url, token.consumer_key.as_ref(), token.consumer_secret.as_ref(), SignatureMethod::HmacSha1
    );
    oauth.token(token.access_key.as_ref(), token.access_secret.as_ref());

    if let Some(p) = params {
        oauth.request_parameters(p);
    }

    oauth.finish_for_twitter()
}
<commit_msg>Tweak the document<commit_after>#[cfg(feature = "egg-mode")]
extern crate egg_mode;
#[cfg(feature = "tweetust")]
extern crate tweetust;

use hyper::header::{Authorization, Scheme};
use oauthcli::{
    OAuthAuthorizationHeader,
    OAuthAuthorizationHeaderBuilder,
    ParseOAuthAuthorizationHeaderError,
    SignatureMethod,
};
use std::borrow::Cow;
use std::fmt::{self, Formatter};
use std::str::FromStr;
use types::RequestMethod;
use url::Url;

/// An OAuth token used to log into Twitter.
#[cfg_attr(feature = "tweetust", doc = "

This implements `tweetust::conn::Authenticator` so you can pass it to `tweetust::TwitterClient`
as if it were `tweetust::OAuthAuthenticator`"
)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Token<'a> {
    pub consumer_key: Cow<'a, str>,
    pub consumer_secret: Cow<'a, str>,
    pub access_key: Cow<'a, str>,
    pub access_secret: Cow<'a, str>,
}

#[derive(Clone, Debug)]
pub struct OAuthHeaderWrapper(pub OAuthAuthorizationHeader);

impl<'a> Token<'a> {
    pub fn new<CK, CS, AK, AS>(consumer_key: CK, consumer_secret: CS, access_key: AK, access_secret: AS) -> Self
        where CK: Into<Cow<'a, str>>, CS: Into<Cow<'a, str>>, AK: Into<Cow<'a, str>>, AS: Into<Cow<'a, str>>
    {
        Token {
            consumer_key: consumer_key.into(),
            consumer_secret: consumer_secret.into(),
            access_key: access_key.into(),
            access_secret: access_secret.into(),
        }
    }
}

#[cfg(feature = "egg-mode")]
impl<'a> From<Token<'a>> for egg_mode::Token<'a> {
    fn from(t: Token<'a>) -> Self {
        egg_mode::Token::Access {
            consumer: egg_mode::KeyPair::new(t.consumer_key, t.consumer_secret),
            access: egg_mode::KeyPair::new(t.access_key, t.access_secret),
        }
    }
}

#[cfg(feature = "tweetust")]
impl<'a> tweetust::conn::Authenticator for Token<'a> {
    type Scheme = OAuthAuthorizationHeader;

    fn create_authorization_header(&self, request: &tweetust::conn::Request) -> Option<OAuthAuthorizationHeader> {
        let params = if let tweetust::conn::RequestContent::WwwForm(ref params) = request.content {
            Some(params.as_ref().iter().map(|&(ref k, ref v)| (k.as_ref(), v.as_ref())))
        } else {
            None
        };

        Some(authorize(self, request.method.as_ref(), &request.url, params))
    }
}

impl FromStr for OAuthHeaderWrapper {
    type Err = ParseOAuthAuthorizationHeaderError;

    fn from_str(s: &str) -> Result<Self, ParseOAuthAuthorizationHeaderError> {
        Ok(OAuthHeaderWrapper(OAuthAuthorizationHeader::from_str(s)?))
    }
}

impl Scheme for OAuthHeaderWrapper {
    fn scheme() -> Option<&'static str> {
        Some("OAuth")
    }

    fn fmt_scheme(&self, f: &mut Formatter) -> fmt::Result {
        f.write_str(self.0.auth_param())
    }
}

pub fn create_authorization_header<'a>(token: &Token<'a>, method: &RequestMethod, url: &Url, params: Option<&[u8]>)
    -> Authorization<OAuthHeaderWrapper>
{
    use url::form_urlencoded;

    Authorization(OAuthHeaderWrapper(
        authorize(token, method.as_ref(), url, params.map(form_urlencoded::parse))
    ))
}

fn authorize<'a, K, V, P>(token: &'a Token<'a>, method: &'a str, url: &'a Url, params: Option<P>)
    -> OAuthAuthorizationHeader
    where K: Into<Cow<'a, str>>, V: Into<Cow<'a, str>>, P: Iterator<Item=(K, V)>
{
    let mut oauth = OAuthAuthorizationHeaderBuilder::new(
        method, url, token.consumer_key.as_ref(), token.consumer_secret.as_ref(), SignatureMethod::HmacSha1
    );
    oauth.token(token.access_key.as_ref(), token.access_secret.as_ref());

    if let Some(p) = params {
        oauth.request_parameters(p);
    }

    oauth.finish_for_twitter()
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

// this file defines CGFloat, as well as stubbed data types.

#![allow(non_camel_case_types)]

use libc;

#[cfg(target_pointer_width = "32")]
pub type boolean_t = i32;
#[cfg(target_pointer_width = "64")]
pub type boolean_t = u32;

// TODO: this is actually a libc::c_float on 32bit
pub type CGFloat = libc::c_double;
pub type CGError = libc::int32_t;

pub type CGAffineTransform = ();

<commit_msg>Fix CGFloat type definition for 32-bit.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

// this file defines CGFloat, as well as stubbed data types.

#![allow(non_camel_case_types)]

use libc;

#[cfg(any(target_arch = "x86",
          target_arch = "arm",
          target_arch = "aarch64"))]
pub type boolean_t = libc::c_int;
#[cfg(target_arch = "x86_64")]
pub type boolean_t = libc::c_uint;

#[cfg(target_pointer_width = "64")]
pub type CGFloat = libc::c_double;
#[cfg(not(target_pointer_width = "64"))]
pub type CGFloat = libc::c_float;

pub type CGError = libc::int32_t;

pub type CGAffineTransform = ();

<|endoftext|>


<commit_before>// Copyright © 2017 Mozilla Foundation
//
// This program is made available under an ISC-style license.  See the
// accompanying file LICENSE for details.

use std::os::raw::{c_char, c_void};
use backend;
use cubeb;

extern "C" fn capi_init(c: *mut *mut cubeb::Context, context_name: *const c_char) -> i32
{
    unsafe {
        match backend::Context::new(context_name) {
            Ok(ctx) => { *c = Box::into_raw(ctx) as *mut _; cubeb::OK }
            Err(e) => e
        }
    }
}

extern "C" fn capi_get_backend_id(_: *mut cubeb::Context) -> *const c_char
{
    "pulse-rust\0".as_ptr() as *const c_char
}

extern "C" fn capi_get_max_channel_count(c: *mut cubeb::Context, max_channels: *mut u32) -> i32
{
    let ctx = unsafe { &*(c as *mut backend::Context) };

    match ctx.max_channel_count() {
        Ok(mc) => { unsafe { *max_channels = mc }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_get_min_latency(c: *mut cubeb::Context,
                                   param: cubeb::StreamParams,
                                   latency_frames: *mut u32) -> i32
{
    let ctx = unsafe { &*(c as *mut backend::Context) };

    match ctx.min_latency(&param) {
        Ok(l) => { unsafe { *latency_frames = l }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_get_preferred_sample_rate(c: *mut cubeb::Context, rate: *mut u32) -> i32
{
    let ctx = unsafe { &*(c as *mut backend::Context) };

    match ctx.preferred_sample_rate() {
        Ok(r) => { unsafe { *rate = r }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_get_preferred_channel_layout(c: *mut cubeb::Context, layout: *mut cubeb::ChannelLayout) -> i32
{
    let ctx = unsafe { &*(c as *mut backend::Context) };

    match ctx.preferred_channel_layout() {
        Ok(l) => { unsafe { *layout = l }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_enumerate_devices(c: *mut cubeb::Context,
                                     devtype: cubeb::DeviceType,
                                     collection: *mut *mut cubeb::DeviceCollection) -> i32
{
    let ctx = unsafe { &*(c as *mut backend::Context) };

    match ctx.enumerate_devices(devtype) {
        Ok(dc) => { unsafe { *collection = dc }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_destroy(c: *mut cubeb::Context) {
    let _: Box<backend::Context> = unsafe { Box::from_raw(c as *mut _) };
}

extern "C" fn capi_stream_init(c: *mut cubeb::Context,
                               s: *mut *mut cubeb::Stream,
                               stream_name: *const c_char,
                               input_device: cubeb::DeviceId,
                               input_stream_params: *mut cubeb::StreamParams,
                               output_device: cubeb::DeviceId,
                               output_stream_params: *mut cubeb::StreamParams,
                               latency_frames: u32,
                               data_callback: cubeb::DataCallback,
                               state_callback: cubeb::StateCallback,
                               user_ptr: *mut c_void) -> i32
{
    let mut ctx = unsafe { &mut *(c as *mut backend::Context) };

    match ctx.new_stream(stream_name,
                         input_device,
                         if input_stream_params.is_null() { None } else { unsafe { Some(*input_stream_params) } },
                         output_device,
                         if output_stream_params.is_null() { None } else { unsafe { Some(*output_stream_params) } },
                         latency_frames,
                         data_callback,
                         state_callback,
                         user_ptr as _) {
        Ok(stm) => { unsafe { *s = Box::into_raw(stm) as *mut _ }; cubeb::OK }
        Err(e) => e
    }
}

extern "C" fn capi_stream_destroy(s: *mut cubeb::Stream)
{
    let _ = unsafe { Box::from_raw(s as *mut backend::Stream) };
}

extern "C" fn capi_stream_start(s: *mut cubeb::Stream) -> i32
{
    let mut stm = unsafe { &mut *(s as *mut backend::Stream) };

    stm.start()
}

extern "C" fn capi_stream_stop(s: *mut cubeb::Stream) -> i32
{
    let mut stm = unsafe { &mut *(s as *mut backend::Stream) };

    stm.stop()
}

extern "C" fn capi_stream_get_position(s: *mut cubeb::Stream,
                                       position: *mut u64) -> i32
{
    let stm = unsafe { &*(s as *mut backend::Stream) };

    match stm.position() {
        Ok(pos) => { unsafe { *position = pos }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_stream_get_latency(s: *mut cubeb::Stream,
                                      latency: *mut u32) -> i32
{
    let stm = unsafe { &*(s as *mut backend::Stream) };

    match stm.latency() {
        Ok(lat) => { unsafe { *latency = lat }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_stream_set_volume(s: *mut cubeb::Stream, volume: f32) -> i32
{
    let stm = unsafe { &mut *(s as *mut backend::Stream) };

    stm.set_volume(volume)
}

extern "C" fn capi_stream_set_panning(s: *mut cubeb::Stream, panning: f32) -> i32
{
    let stm = unsafe { &mut *(s as *mut backend::Stream) };

    stm.set_panning(panning)
}

extern "C" fn capi_stream_get_current_device(s: *mut cubeb::Stream, device: *mut *const cubeb::Device) -> i32
{
    let stm = unsafe { &*(s as *mut backend::Stream) };

    match stm.current_device() {
        Ok(d) => { unsafe { *device = Box::into_raw(d) as *mut _ }; cubeb::OK },
        Err(e) => e
    }
}

extern "C" fn capi_stream_device_destroy(_: *mut cubeb::Stream, device: *mut cubeb::Device) -> i32
{
    let _: Box<backend::Device> = unsafe { Box::from_raw(device as *mut backend::Device) };
    cubeb::OK
}

extern "C" fn capi_register_device_collection_changed(c: *mut cubeb::Context,
                                                      devtype: cubeb::DeviceType,
                                                      collection_changed_callback: cubeb::DeviceCollectionChangedCallback,
                                                      user_ptr: *mut c_void) -> i32
{
    let mut ctx = unsafe { &mut *(c as *mut backend::Context) };
    ctx.register_device_collection_changed(devtype, collection_changed_callback, user_ptr as _)
}

pub const PULSE_OPS: cubeb::Ops = cubeb::Ops {
  init: Some(capi_init),
  get_backend_id: Some(capi_get_backend_id),
  get_max_channel_count: Some(capi_get_max_channel_count),
  get_min_latency: Some(capi_get_min_latency),
  get_preferred_sample_rate: Some(capi_get_preferred_sample_rate),
  get_preferred_channel_layout: Some(capi_get_preferred_channel_layout),
  enumerate_devices: Some(capi_enumerate_devices),
  destroy: Some(capi_destroy),
  stream_init: Some(capi_stream_init),
  stream_destroy: Some(capi_stream_destroy),
  stream_start: Some(capi_stream_start),
  stream_stop: Some(capi_stream_stop),
  stream_get_position: Some(capi_stream_get_position),
  stream_get_latency: Some(capi_stream_get_latency),
  stream_set_volume: Some(capi_stream_set_volume),
  stream_set_panning: Some(capi_stream_set_panning),
  stream_get_current_device: Some(capi_stream_get_current_device),
  stream_device_destroy: Some(capi_stream_device_destroy),
  stream_register_device_changed_callback: None,
  register_device_collection_changed: Some(capi_register_device_collection_changed)
};

#[no_mangle]
pub extern "C" fn pulse_rust_init(c: *mut *mut cubeb::Context, context_name: *const c_char) -> i32 {
    capi_init(c, context_name)
}
<commit_msg>make all functions exposed to cubeb C ops tables unsafe.<commit_after>// Copyright © 2017 Mozilla Foundation
//
// This program is made available under an ISC-style license.  See the
// accompanying file LICENSE for details.

use std::os::raw::{c_char, c_void};
use backend;
use cubeb;

unsafe extern "C" fn capi_init(c: *mut *mut cubeb::Context, context_name: *const c_char) -> i32
{
    match backend::Context::new(context_name) {
        Ok(ctx) => { *c = Box::into_raw(ctx) as *mut _; cubeb::OK }
        Err(e) => e
    }
}

extern "C" fn capi_get_backend_id(_: *mut cubeb::Context) -> *const c_char
{
    "pulse-rust\0".as_ptr() as *const c_char
}

unsafe extern "C" fn capi_get_max_channel_count(c: *mut cubeb::Context, max_channels: *mut u32) -> i32
{
    let ctx = &*(c as *mut backend::Context);

    match ctx.max_channel_count() {
        Ok(mc) => { *max_channels = mc; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_get_min_latency(c: *mut cubeb::Context,
                                   param: cubeb::StreamParams,
                                   latency_frames: *mut u32) -> i32
{
    let ctx = &*(c as *mut backend::Context);

    match ctx.min_latency(&param) {
        Ok(l) => { *latency_frames = l; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_get_preferred_sample_rate(c: *mut cubeb::Context, rate: *mut u32) -> i32
{
    let ctx = &*(c as *mut backend::Context);

    match ctx.preferred_sample_rate() {
        Ok(r) => { *rate = r; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_get_preferred_channel_layout(c: *mut cubeb::Context, layout: *mut cubeb::ChannelLayout) -> i32
{
    let ctx = &*(c as *mut backend::Context);

    match ctx.preferred_channel_layout() {
        Ok(l) => { *layout = l; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_enumerate_devices(c: *mut cubeb::Context,
                                     devtype: cubeb::DeviceType,
                                     collection: *mut *mut cubeb::DeviceCollection) -> i32
{
    let ctx = &*(c as *mut backend::Context);

    match ctx.enumerate_devices(devtype) {
        Ok(dc) => { *collection = dc; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_destroy(c: *mut cubeb::Context) {
    let _: Box<backend::Context> = Box::from_raw(c as *mut _);
}

unsafe extern "C" fn capi_stream_init(c: *mut cubeb::Context,
                                      s: *mut *mut cubeb::Stream,
                                      stream_name: *const c_char,
                                      input_device: cubeb::DeviceId,
                                      input_stream_params: *mut cubeb::StreamParams,
                                      output_device: cubeb::DeviceId,
                                      output_stream_params: *mut cubeb::StreamParams,
                                      latency_frames: u32,
                                      data_callback: cubeb::DataCallback,
                                      state_callback: cubeb::StateCallback,
                                      user_ptr: *mut c_void) -> i32
{
    let mut ctx = &mut *(c as *mut backend::Context);

    match ctx.new_stream(stream_name,
                         input_device,
                         if input_stream_params.is_null() { None } else { Some(*input_stream_params) },
                         output_device,
                         if output_stream_params.is_null() { None } else { Some(*output_stream_params) },
                         latency_frames,
                         data_callback,
                         state_callback,
                         user_ptr as _) {
        Ok(stm) => { *s = Box::into_raw(stm) as *mut _; cubeb::OK }
        Err(e) => e
    }
}

unsafe extern "C" fn capi_stream_destroy(s: *mut cubeb::Stream)
{
    let _ = Box::from_raw(s as *mut backend::Stream);
}

unsafe extern "C" fn capi_stream_start(s: *mut cubeb::Stream) -> i32
{
    let mut stm = &mut *(s as *mut backend::Stream);

    stm.start()
}

unsafe extern "C" fn capi_stream_stop(s: *mut cubeb::Stream) -> i32
{
    let mut stm = &mut *(s as *mut backend::Stream);

    stm.stop()
}

unsafe extern "C" fn capi_stream_get_position(s: *mut cubeb::Stream,
                                       position: *mut u64) -> i32
{
    let stm = &*(s as *mut backend::Stream);

    match stm.position() {
        Ok(pos) => { *position = pos; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_stream_get_latency(s: *mut cubeb::Stream,
                                      latency: *mut u32) -> i32
{
    let stm = &*(s as *mut backend::Stream);

    match stm.latency() {
        Ok(lat) => { *latency = lat; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_stream_set_volume(s: *mut cubeb::Stream, volume: f32) -> i32
{
    let stm = &mut *(s as *mut backend::Stream);

    stm.set_volume(volume)
}

unsafe extern "C" fn capi_stream_set_panning(s: *mut cubeb::Stream, panning: f32) -> i32
{
    let stm = &mut *(s as *mut backend::Stream);

    stm.set_panning(panning)
}

unsafe extern "C" fn capi_stream_get_current_device(s: *mut cubeb::Stream, device: *mut *const cubeb::Device) -> i32
{
    let stm = &*(s as *mut backend::Stream);

    match stm.current_device() {
        Ok(d) => { *device = Box::into_raw(d) as *mut _; cubeb::OK },
        Err(e) => e
    }
}

unsafe extern "C" fn capi_stream_device_destroy(_: *mut cubeb::Stream, device: *mut cubeb::Device) -> i32
{
    let _: Box<backend::Device> = Box::from_raw(device as *mut backend::Device);
    cubeb::OK
}

unsafe extern "C" fn capi_register_device_collection_changed(c: *mut cubeb::Context,
                                                      devtype: cubeb::DeviceType,
                                                      collection_changed_callback: cubeb::DeviceCollectionChangedCallback,
                                                      user_ptr: *mut c_void) -> i32
{
    let mut ctx = &mut *(c as *mut backend::Context);
    ctx.register_device_collection_changed(devtype, collection_changed_callback, user_ptr as _)
}

pub const PULSE_OPS: cubeb::Ops = cubeb::Ops {
  init: Some(capi_init),
  get_backend_id: Some(capi_get_backend_id),
  get_max_channel_count: Some(capi_get_max_channel_count),
  get_min_latency: Some(capi_get_min_latency),
  get_preferred_sample_rate: Some(capi_get_preferred_sample_rate),
  get_preferred_channel_layout: Some(capi_get_preferred_channel_layout),
  enumerate_devices: Some(capi_enumerate_devices),
  destroy: Some(capi_destroy),
  stream_init: Some(capi_stream_init),
  stream_destroy: Some(capi_stream_destroy),
  stream_start: Some(capi_stream_start),
  stream_stop: Some(capi_stream_stop),
  stream_get_position: Some(capi_stream_get_position),
  stream_get_latency: Some(capi_stream_get_latency),
  stream_set_volume: Some(capi_stream_set_volume),
  stream_set_panning: Some(capi_stream_set_panning),
  stream_get_current_device: Some(capi_stream_get_current_device),
  stream_device_destroy: Some(capi_stream_device_destroy),
  stream_register_device_changed_callback: None,
  register_device_collection_changed: Some(capi_register_device_collection_changed)
};

#[no_mangle]
pub unsafe extern "C" fn pulse_rust_init(c: *mut *mut cubeb::Context, context_name: *const c_char) -> i32 {
    capi_init(c, context_name)
}
<|endoftext|>


<commit_before>extern crate std;
extern crate hyper;
extern crate serde_json;

use std::string::String;
use std::io::Read;
use self::serde_json::Value;

#[derive(Debug)]
pub struct GithubError;

impl From<hyper::error::Error> for GithubError {
    fn from(_: hyper::error::Error) -> Self {
        GithubError
    }
}

impl From<serde_json::error::Error> for GithubError {
    fn from(_: serde_json::error::Error) -> Self {
        GithubError
    }
}

impl From<std::io::Error> for GithubError {
    fn from(_: std::io::Error) -> Self {
        GithubError
    }
}

pub fn get_display_text(user: &str, repo: &str, issue: &str, printurl: bool)
    -> Result<String, GithubError> {

    let url = format!("https://api.github.com/repos/{}/{}/issues/{}",
                      user, repo, issue);
    let client = hyper::client::Client::new();
    let mut resp = try!(client
        .get(&url)
        .header(hyper::header::UserAgent("ids1024".to_owned()))
        .send());

    let mut body = String::new();
    try!(resp.read_to_string(&mut body));
    let data: Value = try!(serde_json::from_str(&body));
    let obj = try!(data.as_object().ok_or(GithubError));

    let title = try!(try!(obj.get("title").ok_or(GithubError))
                     .as_string().ok_or(GithubError));
    let state = try!(try!(obj.get("state").ok_or(GithubError))
                     .as_string().ok_or(GithubError));
    let url = try!(try!(obj.get("html_url").ok_or(GithubError))
                        .as_string().ok_or(GithubError));
    let issuetype = match obj.get("pull_request") {
        Some(..) => "pull request",
        None => "issue",
    };

    if printurl {
        Ok(format!("[{}] [{}] {}\n{}", issuetype, state, title, url))
    } else {
        Ok(format!("[{}] [{}] {}", issuetype, state, title))
    }
}
<commit_msg>Change user agent to idsbot<commit_after>extern crate std;
extern crate hyper;
extern crate serde_json;

use std::string::String;
use std::io::Read;
use self::serde_json::Value;

#[derive(Debug)]
pub struct GithubError;

impl From<hyper::error::Error> for GithubError {
    fn from(_: hyper::error::Error) -> Self {
        GithubError
    }
}

impl From<serde_json::error::Error> for GithubError {
    fn from(_: serde_json::error::Error) -> Self {
        GithubError
    }
}

impl From<std::io::Error> for GithubError {
    fn from(_: std::io::Error) -> Self {
        GithubError
    }
}

pub fn get_display_text(user: &str, repo: &str, issue: &str, printurl: bool)
    -> Result<String, GithubError> {

    let url = format!("https://api.github.com/repos/{}/{}/issues/{}",
                      user, repo, issue);
    let client = hyper::client::Client::new();
    let mut resp = try!(client
        .get(&url)
        .header(hyper::header::UserAgent("idsbot".to_owned()))
        .send());

    let mut body = String::new();
    try!(resp.read_to_string(&mut body));
    let data: Value = try!(serde_json::from_str(&body));
    let obj = try!(data.as_object().ok_or(GithubError));

    let title = try!(try!(obj.get("title").ok_or(GithubError))
                     .as_string().ok_or(GithubError));
    let state = try!(try!(obj.get("state").ok_or(GithubError))
                     .as_string().ok_or(GithubError));
    let url = try!(try!(obj.get("html_url").ok_or(GithubError))
                        .as_string().ok_or(GithubError));
    let issuetype = match obj.get("pull_request") {
        Some(..) => "pull request",
        None => "issue",
    };

    if printurl {
        Ok(format!("[{}] [{}] {}\n{}", issuetype, state, title, url))
    } else {
        Ok(format!("[{}] [{}] {}", issuetype, state, title))
    }
}
<|endoftext|>


<commit_before>//! C API for mp4parse module.
//!
//! Parses ISO Base Media Format aka video/mp4 streams.
//!
//! # Examples
//!
//! ```rust
//! extern crate mp4parse;
//!
//! // Minimal valid mp4 containing no tracks.
//! let data = b"\0\0\0\x0cftypmp42";
//!
//! let context = mp4parse::mp4parse_new();
//! unsafe {
//!     let rv = mp4parse::mp4parse_read(context, data.as_ptr(), data.len());
//!     assert_eq!(0, rv);
//!     mp4parse::mp4parse_free(context);
//! }
//! ```

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

use std;
use std::io::Cursor;

// Symbols we need from our rust api.
use MediaContext;
use TrackType;
use read_mp4;
use Error;
use media_time_to_ms;
use track_time_to_ms;
use SampleEntry;

// These constants *must* match those in include/mp4parse.h.

/// Map Error to int32 return codes.
const MP4PARSE_OK: i32 = 0;
const MP4PARSE_ERROR_BADARG: i32 = 1;
const MP4PARSE_ERROR_INVALID: i32 = 2;
const MP4PARSE_ERROR_UNSUPPORTED: i32 = 3;
const MP4PARSE_ERROR_EOF: i32 = 4;
const MP4PARSE_ASSERT: i32 = 5;
const MP4PARSE_ERROR_IO: i32 = 6;

/// Map TrackType to uint32 constants.
const TRACK_TYPE_H264: u32 = 0;
const TRACK_TYPE_AAC: u32 = 1;

// These structs *must* match those declared in include/mp4parse.h.

#[repr(C)]
pub struct TrackInfo {
    track_type: u32,
    track_id: u32,
    duration: u64,
    media_time: i64, // wants to be u64? understand how elst adjustment works
    // TODO(kinetik): include crypto guff
}

#[repr(C)]
pub struct TrackAudioInfo {
    channels: u16,
    bit_depth: u16,
    sample_rate: u32,
    // TODO(kinetik):
    // int32_t profile;
    // int32_t extended_profile; // check types
    // extra_data
    // codec_specific_config
}

#[repr(C)]
pub struct TrackVideoInfo {
    display_width: u32,
    display_height: u32,
    image_width: u16,
    image_height: u16,
    // TODO(kinetik):
    // extra_data
    // codec_specific_config
}

// C API wrapper functions.

/// Allocate an opaque rust-side parser context.
#[no_mangle]
pub extern "C" fn mp4parse_new() -> *mut MediaContext {
    let context = Box::new(MediaContext::new());
    Box::into_raw(context)
}

/// Free a rust-side parser context.
#[no_mangle]
pub unsafe extern "C" fn mp4parse_free(context: *mut MediaContext) {
    assert!(!context.is_null());
    let _ = Box::from_raw(context);
}

/// Feed a buffer through `read_mp4()` with the given rust-side
/// parser context, returning success or an error code.
///
/// This is safe to call with NULL arguments but will crash
/// if given invalid pointers, as is usual for C.
#[no_mangle]
pub unsafe extern "C" fn mp4parse_read(context: *mut MediaContext, buffer: *const u8, size: usize) -> i32 {
    // Validate arguments from C.
    if context.is_null() || buffer.is_null() || size < 8 {
        return MP4PARSE_ERROR_BADARG;
    }

    let mut context: &mut MediaContext = &mut *context;

    // Wrap the buffer we've been give in a slice.
    let b = std::slice::from_raw_parts(buffer, size);
    let mut c = Cursor::new(b);

    // Parse in a subthread to catch any panics.
    let task = std::thread::spawn(move || read_mp4(&mut c, &mut context));
    // The task's JoinHandle will return an error result if the
    // thread panicked, and will wrap the closure's return'd
    // result in an Ok(..) otherwise, meaning we could see
    // Ok(Err(Error::..)) here. So map thread failures back
    // to an mp4parse::Error before converting to a C return value.
    match task.join().or(Err(Error::AssertCaught)) {
        Ok(_) => MP4PARSE_OK,
        Err(Error::InvalidData) => MP4PARSE_ERROR_INVALID,
        Err(Error::Unsupported) => MP4PARSE_ERROR_UNSUPPORTED,
        Err(Error::UnexpectedEOF) => MP4PARSE_ERROR_EOF,
        Err(Error::AssertCaught) => MP4PARSE_ASSERT,
        Err(Error::Io(_)) => MP4PARSE_ERROR_IO,
    }
}

/// Return the number of tracks parsed by previous `read_mp4()` calls.
#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_count(context: *const MediaContext) -> u32 {
    // Validate argument from C.
    assert!(!context.is_null());
    let context = &*context;

    // Make sure the track count fits in a u32.
    assert!(context.tracks.len() < u32::max_value() as usize);
    context.tracks.len() as u32
}

#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_info(context: *mut MediaContext, track: u32, info: *mut TrackInfo) -> i32 {
    if context.is_null() || info.is_null() {
        return MP4PARSE_ERROR_BADARG;
    }

    let context: &mut MediaContext = &mut *context;
    let track_index: usize = track as usize;
    let info: &mut TrackInfo = &mut *info;

    if track_index >= context.tracks.len() {
        return MP4PARSE_ERROR_BADARG;
    }

    info.track_type = match context.tracks[track_index].track_type {
        TrackType::Video => TRACK_TYPE_H264,
        TrackType::Audio => TRACK_TYPE_AAC,
        TrackType::Unknown => return MP4PARSE_ERROR_UNSUPPORTED,
    };

    // Maybe context & track should just have a single simple is_valid() instead?
    if context.timescale.is_none() ||
       context.tracks[track_index].timescale.is_none() ||
       context.tracks[track_index].duration.is_none() ||
       context.tracks[track_index].track_id.is_none() {
        return MP4PARSE_ERROR_INVALID;
    }

    std::thread::spawn(move || {
        let track = &context.tracks[track_index];
        let empty_duration = if track.empty_duration.is_some() {
            media_time_to_ms(track.empty_duration.unwrap(), context.timescale.unwrap())
        } else {
            0
        };
        info.media_time = if track.media_time.is_some() {
            track_time_to_ms(track.media_time.unwrap(), track.timescale.unwrap()) as i64 - empty_duration as i64
        } else {
            0
        };
        info.duration = track_time_to_ms(track.duration.unwrap(), track.timescale.unwrap());
        info.track_id = track.track_id.unwrap();
        MP4PARSE_OK
    }).join().unwrap_or(MP4PARSE_ERROR_INVALID)
}

#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_audio_info(context: *mut MediaContext, track: u32, info: *mut TrackAudioInfo) -> i32 {
    if context.is_null() || info.is_null() {
        return MP4PARSE_ERROR_BADARG;
    }

    let context: &mut MediaContext = &mut *context;

    if track as usize >= context.tracks.len() {
        return MP4PARSE_ERROR_BADARG;
    }

    let track = &context.tracks[track as usize];

    match track.track_type {
        TrackType::Audio => {}
        _ => return MP4PARSE_ERROR_INVALID,
    };

    let audio = match track.data {
        Some(ref data) => data,
        None => return MP4PARSE_ERROR_INVALID,
    };

    let audio = match *audio {
        SampleEntry::Audio(ref x) => x,
        _ => return MP4PARSE_ERROR_INVALID,
    };

    (*info).channels = audio.channelcount;
    (*info).bit_depth = audio.samplesize;
    (*info).sample_rate = audio.samplerate >> 16; // 16.16 fixed point

    MP4PARSE_OK
}

#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_video_info(context: *mut MediaContext, track: u32, info: *mut TrackVideoInfo) -> i32 {
    if context.is_null() || info.is_null() {
        return MP4PARSE_ERROR_BADARG;
    }

    let context: &mut MediaContext = &mut *context;

    if track as usize >= context.tracks.len() {
        return MP4PARSE_ERROR_BADARG;
    }

    let track = &context.tracks[track as usize];

    match track.track_type {
        TrackType::Video => {}
        _ => return MP4PARSE_ERROR_INVALID,
    };

    let video = match track.data {
        Some(ref data) => data,
        None => return MP4PARSE_ERROR_INVALID,
    };

    let video = match *video {
        SampleEntry::Video(ref x) => x,
        _ => return MP4PARSE_ERROR_INVALID,
    };

    if let Some(ref tkhd) = track.tkhd {
        (*info).display_width = tkhd.width >> 16; // 16.16 fixed point
        (*info).display_height = tkhd.height >> 16; // 16.16 fixed point
    } else {
        return MP4PARSE_ERROR_INVALID;
    }
    (*info).image_width = video.width;
    (*info).image_width = video.height;

    MP4PARSE_OK
}

#[test]
fn new_context() {
    let context = mp4parse_new();
    assert!(!context.is_null());
    unsafe {
        mp4parse_free(context);
    }
}

#[test]
#[should_panic(expected = "assertion failed")]
fn free_null_context() {
    unsafe {
        mp4parse_free(std::ptr::null_mut());
    }
}

#[test]
fn arg_validation() {
    let null_buffer = std::ptr::null();
    let null_context = std::ptr::null_mut();

    let context = mp4parse_new();
    assert!(!context.is_null());

    let buffer = vec![0u8; 8];

    unsafe {
        assert_eq!(MP4PARSE_ERROR_BADARG,
                   mp4parse_read(null_context, null_buffer, 0));
        assert_eq!(MP4PARSE_ERROR_BADARG,
                   mp4parse_read(context, null_buffer, 0));
    }

    for size in 0..buffer.len() {
        println!("testing buffer length {}", size);
        unsafe {
            assert_eq!(MP4PARSE_ERROR_BADARG,
                       mp4parse_read(context, buffer.as_ptr(), size));
        }
    }

    unsafe {
        mp4parse_free(context);
    }
}
<commit_msg>Unwrap the JoinHandle's result so we can match on its contents.<commit_after>//! C API for mp4parse module.
//!
//! Parses ISO Base Media Format aka video/mp4 streams.
//!
//! # Examples
//!
//! ```rust
//! extern crate mp4parse;
//!
//! // Minimal valid mp4 containing no tracks.
//! let data = b"\0\0\0\x0cftypmp42";
//!
//! let context = mp4parse::mp4parse_new();
//! unsafe {
//!     let rv = mp4parse::mp4parse_read(context, data.as_ptr(), data.len());
//!     assert_eq!(0, rv);
//!     mp4parse::mp4parse_free(context);
//! }
//! ```

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

use std;
use std::io::Cursor;

// Symbols we need from our rust api.
use MediaContext;
use TrackType;
use read_mp4;
use Error;
use media_time_to_ms;
use track_time_to_ms;
use SampleEntry;

// These constants *must* match those in include/mp4parse.h.

/// Map Error to int32 return codes.
const MP4PARSE_OK: i32 = 0;
const MP4PARSE_ERROR_BADARG: i32 = 1;
const MP4PARSE_ERROR_INVALID: i32 = 2;
const MP4PARSE_ERROR_UNSUPPORTED: i32 = 3;
const MP4PARSE_ERROR_EOF: i32 = 4;
const MP4PARSE_ASSERT: i32 = 5;
const MP4PARSE_ERROR_IO: i32 = 6;

/// Map TrackType to uint32 constants.
const TRACK_TYPE_H264: u32 = 0;
const TRACK_TYPE_AAC: u32 = 1;

// These structs *must* match those declared in include/mp4parse.h.

#[repr(C)]
pub struct TrackInfo {
    track_type: u32,
    track_id: u32,
    duration: u64,
    media_time: i64, // wants to be u64? understand how elst adjustment works
    // TODO(kinetik): include crypto guff
}

#[repr(C)]
pub struct TrackAudioInfo {
    channels: u16,
    bit_depth: u16,
    sample_rate: u32,
    // TODO(kinetik):
    // int32_t profile;
    // int32_t extended_profile; // check types
    // extra_data
    // codec_specific_config
}

#[repr(C)]
pub struct TrackVideoInfo {
    display_width: u32,
    display_height: u32,
    image_width: u16,
    image_height: u16,
    // TODO(kinetik):
    // extra_data
    // codec_specific_config
}

// C API wrapper functions.

/// Allocate an opaque rust-side parser context.
#[no_mangle]
pub extern "C" fn mp4parse_new() -> *mut MediaContext {
    let context = Box::new(MediaContext::new());
    Box::into_raw(context)
}

/// Free a rust-side parser context.
#[no_mangle]
pub unsafe extern "C" fn mp4parse_free(context: *mut MediaContext) {
    assert!(!context.is_null());
    let _ = Box::from_raw(context);
}

/// Feed a buffer through `read_mp4()` with the given rust-side
/// parser context, returning success or an error code.
///
/// This is safe to call with NULL arguments but will crash
/// if given invalid pointers, as is usual for C.
#[no_mangle]
pub unsafe extern "C" fn mp4parse_read(context: *mut MediaContext, buffer: *const u8, size: usize) -> i32 {
    // Validate arguments from C.
    if context.is_null() || buffer.is_null() || size < 8 {
        return MP4PARSE_ERROR_BADARG;
    }

    let mut context: &mut MediaContext = &mut *context;

    // Wrap the buffer we've been give in a slice.
    let b = std::slice::from_raw_parts(buffer, size);
    let mut c = Cursor::new(b);

    // Parse in a subthread to catch any panics.
    let task = std::thread::spawn(move || read_mp4(&mut c, &mut context));
    // The task's JoinHandle will return an error result if the
    // thread panicked, and will wrap the closure's return'd
    // result in an Ok(..) otherwise, meaning we could see
    // Ok(Err(Error::..)) here. So map thread failures back
    // to an mp4parse::Error before converting to a C return value.
    match task.join().unwrap_or(Err(Error::AssertCaught)) {
        Ok(_) => MP4PARSE_OK,
        Err(Error::InvalidData) => MP4PARSE_ERROR_INVALID,
        Err(Error::Unsupported) => MP4PARSE_ERROR_UNSUPPORTED,
        Err(Error::UnexpectedEOF) => MP4PARSE_ERROR_EOF,
        Err(Error::AssertCaught) => MP4PARSE_ASSERT,
        Err(Error::Io(_)) => MP4PARSE_ERROR_IO,
    }
}

/// Return the number of tracks parsed by previous `read_mp4()` calls.
#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_count(context: *const MediaContext) -> u32 {
    // Validate argument from C.
    assert!(!context.is_null());
    let context = &*context;

    // Make sure the track count fits in a u32.
    assert!(context.tracks.len() < u32::max_value() as usize);
    context.tracks.len() as u32
}

#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_info(context: *mut MediaContext, track: u32, info: *mut TrackInfo) -> i32 {
    if context.is_null() || info.is_null() {
        return MP4PARSE_ERROR_BADARG;
    }

    let context: &mut MediaContext = &mut *context;
    let track_index: usize = track as usize;
    let info: &mut TrackInfo = &mut *info;

    if track_index >= context.tracks.len() {
        return MP4PARSE_ERROR_BADARG;
    }

    info.track_type = match context.tracks[track_index].track_type {
        TrackType::Video => TRACK_TYPE_H264,
        TrackType::Audio => TRACK_TYPE_AAC,
        TrackType::Unknown => return MP4PARSE_ERROR_UNSUPPORTED,
    };

    // Maybe context & track should just have a single simple is_valid() instead?
    if context.timescale.is_none() ||
       context.tracks[track_index].timescale.is_none() ||
       context.tracks[track_index].duration.is_none() ||
       context.tracks[track_index].track_id.is_none() {
        return MP4PARSE_ERROR_INVALID;
    }

    std::thread::spawn(move || {
        let track = &context.tracks[track_index];
        let empty_duration = if track.empty_duration.is_some() {
            media_time_to_ms(track.empty_duration.unwrap(), context.timescale.unwrap())
        } else {
            0
        };
        info.media_time = if track.media_time.is_some() {
            track_time_to_ms(track.media_time.unwrap(), track.timescale.unwrap()) as i64 - empty_duration as i64
        } else {
            0
        };
        info.duration = track_time_to_ms(track.duration.unwrap(), track.timescale.unwrap());
        info.track_id = track.track_id.unwrap();
        MP4PARSE_OK
    }).join().unwrap_or(MP4PARSE_ERROR_INVALID)
}

#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_audio_info(context: *mut MediaContext, track: u32, info: *mut TrackAudioInfo) -> i32 {
    if context.is_null() || info.is_null() {
        return MP4PARSE_ERROR_BADARG;
    }

    let context: &mut MediaContext = &mut *context;

    if track as usize >= context.tracks.len() {
        return MP4PARSE_ERROR_BADARG;
    }

    let track = &context.tracks[track as usize];

    match track.track_type {
        TrackType::Audio => {}
        _ => return MP4PARSE_ERROR_INVALID,
    };

    let audio = match track.data {
        Some(ref data) => data,
        None => return MP4PARSE_ERROR_INVALID,
    };

    let audio = match *audio {
        SampleEntry::Audio(ref x) => x,
        _ => return MP4PARSE_ERROR_INVALID,
    };

    (*info).channels = audio.channelcount;
    (*info).bit_depth = audio.samplesize;
    (*info).sample_rate = audio.samplerate >> 16; // 16.16 fixed point

    MP4PARSE_OK
}

#[no_mangle]
pub unsafe extern "C" fn mp4parse_get_track_video_info(context: *mut MediaContext, track: u32, info: *mut TrackVideoInfo) -> i32 {
    if context.is_null() || info.is_null() {
        return MP4PARSE_ERROR_BADARG;
    }

    let context: &mut MediaContext = &mut *context;

    if track as usize >= context.tracks.len() {
        return MP4PARSE_ERROR_BADARG;
    }

    let track = &context.tracks[track as usize];

    match track.track_type {
        TrackType::Video => {}
        _ => return MP4PARSE_ERROR_INVALID,
    };

    let video = match track.data {
        Some(ref data) => data,
        None => return MP4PARSE_ERROR_INVALID,
    };

    let video = match *video {
        SampleEntry::Video(ref x) => x,
        _ => return MP4PARSE_ERROR_INVALID,
    };

    if let Some(ref tkhd) = track.tkhd {
        (*info).display_width = tkhd.width >> 16; // 16.16 fixed point
        (*info).display_height = tkhd.height >> 16; // 16.16 fixed point
    } else {
        return MP4PARSE_ERROR_INVALID;
    }
    (*info).image_width = video.width;
    (*info).image_width = video.height;

    MP4PARSE_OK
}

#[test]
fn new_context() {
    let context = mp4parse_new();
    assert!(!context.is_null());
    unsafe {
        mp4parse_free(context);
    }
}

#[test]
#[should_panic(expected = "assertion failed")]
fn free_null_context() {
    unsafe {
        mp4parse_free(std::ptr::null_mut());
    }
}

#[test]
fn arg_validation() {
    let null_buffer = std::ptr::null();
    let null_context = std::ptr::null_mut();

    let context = mp4parse_new();
    assert!(!context.is_null());

    let buffer = vec![0u8; 8];

    unsafe {
        assert_eq!(MP4PARSE_ERROR_BADARG,
                   mp4parse_read(null_context, null_buffer, 0));
        assert_eq!(MP4PARSE_ERROR_BADARG,
                   mp4parse_read(context, null_buffer, 0));
    }

    for size in 0..buffer.len() {
        println!("testing buffer length {}", size);
        unsafe {
            assert_eq!(MP4PARSE_ERROR_BADARG,
                       mp4parse_read(context, buffer.as_ptr(), size));
        }
    }

    unsafe {
        mp4parse_free(context);
    }
}
<|endoftext|>


<commit_before>
use BuildQuery;
use Groups;

// https://docs.gitlab.com/ce/api/groups.html
// List groups:                 GET /groups
// List owned groups:           GET /groups/owned
// List a group's projects:     GET /groups/:id/projects
// Details of a group:          GET /groups/:id
// New group:                   POST /groups
// Transfer project to group:   POST  /groups/:id/projects/:project_id
// Update group:                PUT /groups/:id
// Remove group:                DELETE /groups/:id
// Search for group:            GET /groups?search=foobar

// https://docs.gitlab.com/ce/api/groups.html#list-groups

#[derive(Debug, Copy, Clone)]
enum GroupListerOptionsOrderBy {
    Name,
    Path,
}

// impl Default for GroupListerOptionsOrderBy {
//     fn default() -> GroupListerOptionsOrderBy { GroupListerOptionsOrderBy::Name }
// }

#[derive(Debug, Copy, Clone)]
enum GroupListerOptionsSort {
    Asc,
    Desc,
}

// impl Default for GroupListerOptionsSort {
//     fn default() -> GroupListerOptionsSort { GroupListerOptionsSort::Asc }
// }

fn append_group_lister_options_order_by(order_by: GroupListerOptionsOrderBy, s: &mut String) {
    s.push_str(match order_by {
        GroupListerOptionsOrderBy::Name => "name",
        GroupListerOptionsOrderBy::Path => "path",
    });
}

fn append_group_lister_options_sort(order_by: GroupListerOptionsSort, s: &mut String) {
    s.push_str(match order_by {
        GroupListerOptionsSort::Asc => "asc",
        GroupListerOptionsSort::Desc => "desc",
    });
}

/// https://docs.gitlab.com/ce/api/groups.html#list-groups
#[derive(Default, Debug)]
struct GroupListerOptions {
    /// Skip the group IDs passes
    pub skip_groups: Option<Vec<i64>>,
    /// Show all the groups you have access to
    pub all_available: Option<bool>,
    /// Return list of authorized groups matching the search criteria
    pub search: Option<String>,
    /// Order groups by `name` or `path`. Default is `name`
    pub order_by: Option<GroupListerOptionsOrderBy>,
    /// Order groups in `asc` or `desc` order. Default is `asc`
    pub sort: Option<GroupListerOptionsSort>,
}

#[derive(Default, Debug)]
pub struct GroupListing {
    options: GroupListerOptions,
}

impl BuildQuery for GroupListing {
    fn build_query(&self) -> String {
        let options = &self.options;

        let mut query = String::from("groups");

        // Append a "?", only if one of the `Option` is `Some(_)`
        query.push_str(match (&options.skip_groups,
                              &options.all_available,
                              &options.search,
                              &options.order_by,
                              &options.sort) {
            (&None, &None, &None, &None, &None) => "",
            _ => "?",
        });

        options.all_available.map(|all_available| {
            if all_available {
                query.push_str("all_available=true")
            } else {
                query.push_str("all_available=false")
            }
        });

        options.order_by.map(|order_by| {
            query.push_str("order_by=");
            append_group_lister_options_order_by(order_by, &mut query);
        });

        query
    }
}

impl GroupListing {
    fn list(&self) -> Groups {
        let groups: Groups = vec![];

        groups
    }
}

#[test]
fn test_append_group_lister_options_order_by() {
    let expected_string = "Initialnamepathpathname";

    let mut s = String::from("Initial");

    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Name, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Path, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Path, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Name, &mut s);

    assert_eq!(s, expected_string);
}

#[test]
fn test_append_group_lister_options_sort() {
    let expected_string = "Initialascdescascdesc";

    let mut s = String::from("Initial");

    append_group_lister_options_sort(GroupListerOptionsSort::Asc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Desc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Asc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Desc, &mut s);

    assert_eq!(s, expected_string);
}

#[test]
fn test_group_lister_build_query() {
    // use BuildQuery;
    // use Groups;

    let expected_string = "groups";
    let listing: GroupListing = Default::default();
    let query = listing.build_query();
    assert_eq!(query, expected_string);

    let expected_string = "groups";
    let listing = GroupListing { options: Default::default() };
    let query = listing.build_query();
    assert_eq!(query, expected_string);

    let expected_string = "groups?order_by=name";
    let listing = GroupListing {
        options: GroupListerOptions { order_by: Some(GroupListerOptionsOrderBy::Name), ..Default::default() },
    };
    println!("listing: {:?}", listing);
    let query = listing.build_query();
    assert_eq!(query, expected_string);

    let expected_string = "groups?order_by=path";
    let listing = GroupListing {
        options: GroupListerOptions { order_by: Some(GroupListerOptionsOrderBy::Path), ..Default::default() },
    };
    println!("listing: {:?}", listing);
    let query = listing.build_query();
    assert_eq!(query, expected_string);
}
<commit_msg>fmt on GroupListing<commit_after>
use BuildQuery;
use Groups;

// https://docs.gitlab.com/ce/api/groups.html
// List groups:                 GET /groups
// List owned groups:           GET /groups/owned
// List a group's projects:     GET /groups/:id/projects
// Details of a group:          GET /groups/:id
// New group:                   POST /groups
// Transfer project to group:   POST  /groups/:id/projects/:project_id
// Update group:                PUT /groups/:id
// Remove group:                DELETE /groups/:id
// Search for group:            GET /groups?search=foobar

// https://docs.gitlab.com/ce/api/groups.html#list-groups

#[derive(Debug, Copy, Clone)]
enum GroupListerOptionsOrderBy {
    Name,
    Path,
}

// impl Default for GroupListerOptionsOrderBy {
//     fn default() -> GroupListerOptionsOrderBy { GroupListerOptionsOrderBy::Name }
// }

#[derive(Debug, Copy, Clone)]
enum GroupListerOptionsSort {
    Asc,
    Desc,
}

// impl Default for GroupListerOptionsSort {
//     fn default() -> GroupListerOptionsSort { GroupListerOptionsSort::Asc }
// }

fn append_group_lister_options_order_by(order_by: GroupListerOptionsOrderBy, s: &mut String) {
    s.push_str(match order_by {
        GroupListerOptionsOrderBy::Name => "name",
        GroupListerOptionsOrderBy::Path => "path",
    });
}

fn append_group_lister_options_sort(order_by: GroupListerOptionsSort, s: &mut String) {
    s.push_str(match order_by {
        GroupListerOptionsSort::Asc => "asc",
        GroupListerOptionsSort::Desc => "desc",
    });
}

/// https://docs.gitlab.com/ce/api/groups.html#list-groups
#[derive(Default, Debug)]
struct GroupListerOptions {
    /// Skip the group IDs passes
    pub skip_groups: Option<Vec<i64>>,
    /// Show all the groups you have access to
    pub all_available: Option<bool>,
    /// Return list of authorized groups matching the search criteria
    pub search: Option<String>,
    /// Order groups by `name` or `path`. Default is `name`
    pub order_by: Option<GroupListerOptionsOrderBy>,
    /// Order groups in `asc` or `desc` order. Default is `asc`
    pub sort: Option<GroupListerOptionsSort>,
}

#[derive(Default, Debug)]
pub struct GroupListing {
    options: GroupListerOptions,
}

impl BuildQuery for GroupListing {
    fn build_query(&self) -> String {
        let options = &self.options;

        let mut query = String::from("groups");

        // Append a "?", only if one of the `Option` is `Some(_)`
        query.push_str(match (&options.skip_groups,
                              &options.all_available,
                              &options.search,
                              &options.order_by,
                              &options.sort) {
            (&None, &None, &None, &None, &None) => "",
            _ => "?",
        });

        options.all_available.map(|all_available| {
            if all_available {
                query.push_str("all_available=true")
            } else {
                query.push_str("all_available=false")
            }
        });

        options.order_by.map(|order_by| {
            query.push_str("order_by=");
            append_group_lister_options_order_by(order_by, &mut query);
        });

        query
    }
}

impl GroupListing {
    fn list(&self) -> Groups {
        let groups: Groups = vec![];

        groups
    }
}

#[test]
fn test_append_group_lister_options_order_by() {
    let expected_string = "Initialnamepathpathname";

    let mut s = String::from("Initial");

    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Name, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Path, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Path, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Name, &mut s);

    assert_eq!(s, expected_string);
}

#[test]
fn test_append_group_lister_options_sort() {
    let expected_string = "Initialascdescascdesc";

    let mut s = String::from("Initial");

    append_group_lister_options_sort(GroupListerOptionsSort::Asc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Desc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Asc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Desc, &mut s);

    assert_eq!(s, expected_string);
}

#[test]
fn test_group_lister_build_query() {
    // use BuildQuery;
    // use Groups;

    let expected_string = "groups";
    let listing: GroupListing = Default::default();
    let query = listing.build_query();
    assert_eq!(query, expected_string);

    let expected_string = "groups";
    let listing = GroupListing { options: Default::default() };
    let query = listing.build_query();
    assert_eq!(query, expected_string);

    let expected_string = "groups?order_by=name";
    let listing = GroupListing {
        options: GroupListerOptions {
            order_by: Some(GroupListerOptionsOrderBy::Name),
            ..Default::default()
        },
    };
    println!("listing: {:?}", listing);
    let query = listing.build_query();
    assert_eq!(query, expected_string);

    let expected_string = "groups?order_by=path";
    let listing = GroupListing {
        options: GroupListerOptions {
            order_by: Some(GroupListerOptionsOrderBy::Path),
            ..Default::default()
        },
    };
    println!("listing: {:?}", listing);
    let query = listing.build_query();
    assert_eq!(query, expected_string);
}
<|endoftext|>


<commit_before>use std::num::Float;

use super::{Item, ItemSchedData};
use time::now_utc;

static INITIAL_FF: f64 = 2.5;

pub fn init_item() -> ItemSchedData {
    ItemSchedData {
        last_reviewed: now_utc().to_timespec(),
        ff: INITIAL_FF,
        int_step: 0,
        iri: 0.0,
    }
}

pub fn assess_item(data: &ItemSchedData, fam: u8) -> ItemSchedData {
    let int_step = if fam < 2 {
        1
    } else {
        data.int_step + 1
    };

    let iri = match int_step {
        1 => 1.0,
        2 => 3.0,
        _ => data.iri + data.ff
    };

    // SM-2 algorithm says only to adjust if familiar was above a certain
    // threshold. haven't thought about what effect this has yet.
    // TODO: revisit

    let ff = data.ff + match fam {
        0 => 0.,
        1 => 0.,
        2 => -0.32,
        3 => -0.14,
        4 => 0.,
        5 => 0.1,
        _ => unreachable!("Internal error: managed to reach unreachable code. I'm impressed.")
    };

    ItemSchedData {
        last_reviewed: now_utc().to_timespec(),
        ff: ff,
        int_step: int_step,
        iri: iri,
    }
}

pub fn list_display_item(item: Item) -> String {
    format!("{:3} : {}", item.id, item.desc)
}

pub fn full_display_item(item: Item) -> String {
    format!("{:3} : {}\nLast reviewed: {}\nFF: {}\nint_step: {}\nIRI: {}",
            item.id, item.desc, item.data.last_reviewed.sec, item.data.ff,
            item.data.int_step, item.data.iri)
}

pub fn filter_review_items(items: Vec<Item>) -> Vec<Item> {
    let curr_time = now_utc().to_timespec();

    fn days_to_seconds(days: f64) -> i64 {
        (days * 86400.0).round() as i64
    }

    items.into_iter()
         .filter(|i| (curr_time - i.data.last_reviewed).num_seconds() > days_to_seconds(i.data.iri))
         .collect()
}

pub fn review_display_item(review_num: usize, item: &Item) -> String {
    format!("\n{:3} - {} (id: {})\n\n0-5 or 's' to skip item or 'q' to quit > ",
            review_num, item.desc, item.id)
}
<commit_msg>Improve view by showing hours since last review, not merely the timestamp of the last review<commit_after>use std::num::Float;

use super::{Item, ItemSchedData};
use time::now_utc;

static INITIAL_FF: f64 = 2.5;

pub fn init_item() -> ItemSchedData {
    ItemSchedData {
        last_reviewed: now_utc().to_timespec(),
        ff: INITIAL_FF,
        int_step: 0,
        iri: 0.0,
    }
}

pub fn assess_item(data: &ItemSchedData, fam: u8) -> ItemSchedData {
    let int_step = if fam < 2 {
        1
    } else {
        data.int_step + 1
    };

    let iri = match int_step {
        1 => 1.0,
        2 => 3.0,
        _ => data.iri + data.ff
    };

    // SM-2 algorithm says only to adjust if familiar was above a certain
    // threshold. haven't thought about what effect this has yet.
    // TODO: revisit

    let ff = data.ff + match fam {
        0 => 0.,
        1 => 0.,
        2 => -0.32,
        3 => -0.14,
        4 => 0.,
        5 => 0.1,
        _ => unreachable!("Internal error: managed to reach unreachable code. I'm impressed.")
    };

    ItemSchedData {
        last_reviewed: now_utc().to_timespec(),
        ff: ff,
        int_step: int_step,
        iri: iri,
    }
}

pub fn list_display_item(item: Item) -> String {
    format!("{:3} : {}", item.id, item.desc)
}

pub fn full_display_item(item: Item) -> String {
    let dur = now_utc().to_timespec() - item.data.last_reviewed;
    format!("{:3} : {}\nLast reviewed: {} hours ago\nFF: {}\nint_step: {}\nIRI: {}",
            item.id, item.desc, dur.num_hours(), item.data.ff,
            item.data.int_step, item.data.iri)
}

pub fn filter_review_items(items: Vec<Item>) -> Vec<Item> {
    let curr_time = now_utc().to_timespec();

    fn days_to_seconds(days: f64) -> i64 {
        (days * 86400.0).round() as i64
    }

    items.into_iter()
         .filter(|i| (curr_time - i.data.last_reviewed).num_seconds() > days_to_seconds(i.data.iri))
         .collect()
}

pub fn review_display_item(review_num: usize, item: &Item) -> String {
    format!("\n{:3} - {} (id: {})\n\n0-5 or 's' to skip item or 'q' to quit > ",
            review_num, item.desc, item.id)
}
<|endoftext|>


<commit_before>use {Error, Result, Board, board, is_root};
use bcm270x::{GPIO, PinOptions};
use sys;

pub struct CuPi {
    pub board: Board,
    pub is_root: bool,
    gpio: Option<GPIO>
}

impl CuPi {
    pub fn new() -> Result<CuPi> {
        let board = try!(board());
        let is_root = is_root();
        let gpio = match is_root {
            true => Some(try!(GPIO::new(board.cpu))),
            false => None,
        };

        let cupi = CuPi {
            board: board,
            is_root: is_root,
            gpio: gpio
        };

        Ok(cupi)
    }

    pub fn pin(&self, pin: usize) -> Result<PinOptions> {
        let gpio_pin = try!(self.board.pin_to_gpio(pin));
        match self.gpio {
            Some(ref gpio) => Ok(unsafe { gpio.pin(gpio_pin) }),
            None           => Err(Error::RootRequired),
        }
    }

    pub fn pin_sys(&self, pin: usize) -> Result<sys::Pin> {
        let gpio_pin = try!(self.board.pin_to_gpio(pin));
        Ok(unsafe { sys::Pin::new(gpio_pin) })
    }
}
<commit_msg>is_root() always real<commit_after>use {Error, Result, Board, board, is_root};
use bcm270x::{GPIO, PinOptions};
use sys;

pub struct CuPi {
    pub board: Board,
    gpio: Option<GPIO>
}

impl CuPi {
    pub fn new() -> Result<CuPi> {
        let board = try!(board());
        let gpio = match is_root() {
            true => Some(try!(GPIO::new(board.cpu))),
            false => None,
        };

        let cupi = CuPi {
            board: board,
            gpio: gpio
        };

        Ok(cupi)
    }

    pub fn pin(&self, pin: usize) -> Result<PinOptions> {
        let gpio_pin = try!(self.board.pin_to_gpio(pin));
        match self.gpio {
            Some(ref gpio) => Ok(unsafe { gpio.pin(gpio_pin) }),
            None           => Err(Error::RootRequired),
        }
    }

    pub fn pin_sys(&self, pin: usize) -> Result<sys::Pin> {
        let gpio_pin = try!(self.board.pin_to_gpio(pin));
        Ok(unsafe { sys::Pin::new(gpio_pin) })
    }
}
<|endoftext|>


<commit_before>// Copyright © 2015; Connor Hilarides
// Licensed under the MIT License <LICENSE.md>
//! Mappings for the contents of dxgi.h
STRUCT!{struct DXGI_FRAME_STATISTICS {
    PresentCount: ::UINT,
    PresentRefreshCount: ::UINT,
    SyncRefreshCount: ::UINT,
    SyncQPCTime: ::LARGE_INTEGER,
    SyncGPUTime: ::LARGE_INTEGER,
}}
STRUCT!{struct DXGI_MAPPED_RECT {
    Pitch: ::INT,
    pBits: *mut ::BYTE,
}}
STRUCT!{nodebug struct DXGI_ADAPTER_DESC {
    Description: [::WCHAR; 128],
    VectorId: ::UINT,
    DeviceId: ::UINT,
    SubSysId: ::UINT,
    Revision: ::UINT,
    DedicatedVideoMemory: ::SIZE_T,
    DedicatedSystemMemory: ::SIZE_T,
    SharedSystemMemory: ::SIZE_T,
    AdapterLuid: ::LUID,
}}
STRUCT!{nodebug struct DXGI_OUTPUT_DESC {
    DeviceName: [::WCHAR; 32],
    DesktopCoordinates: ::RECT,
    AttachedToDesktop: ::BOOL,
    Rotation: ::DXGI_MODE_ROTATION,
    Monitor: ::HMONITOR,
}}
STRUCT!{struct DXGI_SHARED_RESOURCE {
    Handle: ::HANDLE,
}}
pub const DXGI_RESOURCE_PRIORITY_MINIMUM: ::DWORD = 0x28000000;
pub const DXGI_RESOURCE_PRIORITY_LOW: ::DWORD = 0x50000000;
pub const DXGI_RESOURCE_PRIORITY_NORMAL: ::DWORD = 0x78000000;
pub const DXGI_RESOURCE_PRIORITY_HIGH: ::DWORD = 0xa0000000;
pub const DXGI_RESOURCE_PRIORITY_MAXIMUM: ::DWORD = 0xc8000000;
ENUM!{enum DXGI_RESIDENCY {
    DXGI_RESIDENCY_FULLY_RESIDENT = 1,
    DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2,
    DXGI_RESIDENCY_EVICTED_TO_DISK = 3,
}}
STRUCT!{struct DXGI_SURFACE_DESC {
    Width: ::UINT,
    Height: ::UINT,
    Format: ::DXGI_FORMAT,
    SampleDesc: ::DXGI_SAMPLE_DESC,
}}
ENUM!{enum DXGI_SWAP_EFFECT {
    DXGI_SWAP_EFFECT_DISCARD = 0,
    DXGI_SWAP_EFFECT_SEQUENTIAL = 1,
    DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3,
}}
FLAGS!{enum DXGI_SWAP_CHAIN_FLAG {
    DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1,
    DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2,
    DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4,
    DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8,
    DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 16,
    DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 32,
    DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 64,
    DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 128,
    DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 256,
    DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 512,
}}
STRUCT!{struct DXGI_SWAP_CHAIN_DESC {
    BufferDesc: ::DXGI_MODE_DESC,
    SampleDesc: ::DXGI_SAMPLE_DESC,
    BufferUsage: ::DXGI_USAGE,
    BufferCount: ::UINT,
    OutputWindow: ::HWND,
    Windowed: ::BOOL,
    SwapEffect: DXGI_SWAP_EFFECT,
    Flags: ::UINT,
}}
RIDL!(
interface IDXGIObject(IDXGIObjectVtbl): IUnknown(IUnknownVtbl) {
    fn SetPrivateData(
        &mut self, Name: ::REFGUID, DataSize: ::UINT, pData: *const ::c_void
    ) -> ::HRESULT,
    fn SetPrivateDataInterface(&mut self, Name: ::REFGUID, pUnknown: *const ::IUnknown) -> ::HRESULT,
    fn GetPrivateData(
        &mut self, Name: ::REFGUID, pDataSize: *mut ::UINT, pData: *mut ::c_void
    ) -> ::HRESULT,
    fn GetParent(
        &mut self, riid: ::REFIID, ppParent: *mut *mut ::c_void
    ) -> ::HRESULT
});
RIDL!(
interface IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn GetDevice(&mut self, riid: ::REFIID, ppDevice: *mut *mut ::c_void) -> ::HRESULT
});
RIDL!(
interface IDXGIResource(IDXGIResourceVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn GetSharedHandle(&mut self, pSharedHandle: *mut ::HANDLE) -> ::HRESULT,
    fn GetUsage(&mut self, pUsage: *mut ::DXGI_USAGE) -> ::HRESULT,
    fn SetEvictionPriority(&mut self, EvictionPriority: ::UINT) -> ::HRESULT,
    fn GetEvictionPriority(&mut self, pEvictionPriority: *mut ::UINT) -> ::HRESULT
});
RIDL!(
interface IDXGIKeyedMutex(IDXGIKeyedMutexVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn AcquireSync(&mut self, Key: ::UINT64, dwMilliseconds: ::DWORD) -> ::HRESULT,
    fn ReleaseSync(&mut self, Key: ::UINT64) -> ::HRESULT
});
RIDL!(
interface IDXGISurface(IDXGISurfaceVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn GetDesc(&mut self, pDesc: *mut DXGI_SURFACE_DESC) -> ::HRESULT,
    fn Map(&mut self, pLockedRect: *mut DXGI_MAPPED_RECT, MapFlags: ::UINT) -> ::HRESULT,
    fn Unmap(&mut self) -> ::HRESULT
});
RIDL!(
interface IDXGISurface1(IDXGISurface1Vtbl): IDXGISurface(IDXGISurfaceVtbl) {
    fn GetDC(&mut self, Discard: ::BOOL, phdc: *mut ::HDC) -> ::HRESULT,
    fn ReleaseDC(&mut self, pDirtyRect: *mut ::RECT) -> ::HRESULT
});
RIDL!(
interface IDXGIAdapter(IDXGIAdapterVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn EnumOutputs(&mut self, Output: ::UINT, ppOutput: *mut *mut IDXGIOutput) -> ::HRESULT,
    fn GetDesc(&mut self, pDesc: *mut DXGI_ADAPTER_DESC) -> ::HRESULT,
    fn CheckInterfaceSupport(
        &mut self, InterfaceName: ::REFGUID, pUMDVersion: *mut ::LARGE_INTEGER
    ) -> ::HRESULT
});
RIDL!(
interface IDXGIOutput(IDXGIOutputVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn GetDesc(&mut self, pDesc: *mut DXGI_OUTPUT_DESC) -> ::HRESULT,
    fn GetDisplayModeList(
        &mut self, EnumFormat: ::DXGI_FORMAT, Flags: ::UINT, pNumModes: *mut ::UINT,
        pDesc: *mut ::DXGI_MODE_DESC
    ) -> ::HRESULT,
    fn FindClosestMatchingMode(
        &mut self, pModeToMatch: *const ::DXGI_MODE_DESC, pClosestMatch: *mut ::DXGI_MODE_DESC,
        pConcernedDevice: *mut ::IUnknown
    ) -> ::HRESULT,
    fn WaitForVBlank(&mut self) -> ::HRESULT,
    fn TakeOwnership(&mut self, pDevice: *mut ::IUnknown, Exclusive: ::BOOL) -> ::HRESULT,
    fn ReleaseOwnership(&mut self) -> (),
    fn GetGammaControlCapabilities(
        &mut self, pGammaCaps: *mut ::DXGI_GAMMA_CONTROL_CAPABILITIES
    ) -> ::HRESULT,
    fn SetGammaControl(&mut self, pArray: *const ::DXGI_GAMMA_CONTROL) -> ::HRESULT,
    fn GetGammaControl(&mut self, pArray: *mut ::DXGI_GAMMA_CONTROL) -> ::HRESULT,
    fn SetDisplaySurface(&mut self, pScanoutSurface: *mut IDXGISurface) -> ::HRESULT,
    fn GetDisplaySurfaceData(&mut self, pDestination: *mut IDXGISurface) -> ::HRESULT,
    fn GetFrameStatistics(&mut self, pStats: *mut DXGI_FRAME_STATISTICS) -> ::HRESULT
});
pub const DXGI_MAX_SWAP_CHAIN_BUFFERS: ::DWORD = 16;
pub const DXGI_PRESENT_TEST: ::DWORD = 0x00000001;
pub const DXGI_PRESENT_DO_NOT_SEQUENCE: ::DWORD = 0x00000002;
pub const DXGI_PRESENT_RESTART: ::DWORD = 0x00000004;
pub const DXGI_PRESENT_DO_NOT_WAIT: ::DWORD = 0x00000008;
pub const DXGI_PRESENT_STEREO_PREFER_RIGHT: ::DWORD = 0x00000010;
pub const DXGI_PRESENT_STEREO_TEMPORARY_MONO: ::DWORD = 0x00000020;
pub const DXGI_PRESENT_RESTRICT_TO_OUTPUT: ::DWORD = 0x00000040;
pub const DXGI_PRESENT_USE_DURATION: ::DWORD = 0x00000100;
RIDL!(
interface IDXGISwapChain(IDXGISwapChainVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn Present(&mut self, SyncInterval: ::UINT, Flags: ::UINT) -> ::HRESULT,
    fn GetBuffer(
        &mut self, Buffer: ::UINT, riid: ::REFIID, ppSurface: *mut *mut ::c_void
    ) -> ::HRESULT,
    fn SetFullscreenState(&mut self, Fullscreen: ::BOOL, pTarget: *mut IDXGIOutput) -> ::HRESULT,
    fn GetFullscreenState(
        &mut self, pFullscreen: *mut ::BOOL, ppTarget: *mut *mut IDXGIOutput
    ) -> ::HRESULT,
    fn GetDesc(&mut self, pDesc: *mut DXGI_SWAP_CHAIN_DESC) -> ::HRESULT,
    fn ResizeBuffers(
        &mut self, BufferCount: ::UINT, Width: ::UINT, Height: ::UINT, NewFormat: ::DXGI_FORMAT,
        SwapChainFlags: ::UINT
    ) -> ::HRESULT,
    fn ResizeTarget(&mut self, pNewTargetParameters: *const ::DXGI_MODE_DESC) -> ::HRESULT,
    fn GetContainingOutput(&mut self, ppOutput: *mut *mut IDXGIOutput) -> ::HRESULT,
    fn GetFrameStatistics(&mut self, pStats: *mut DXGI_FRAME_STATISTICS) -> ::HRESULT,
    fn GetLastPresentCount(&mut self, pLastPresentCount: *mut ::UINT) -> ::HRESULT
});
RIDL!(
interface IDXGIFactory(IDXGIFactoryVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn EnumAdapters(&mut self, Adapter: ::UINT, ppAdapter: *mut *mut IDXGIAdapter) -> ::HRESULT,
    fn MakeWindowAssociation(&mut self, WindowHandle: ::HWND, Flags: ::UINT) -> ::HRESULT,
    fn GetWindowAssociation(&mut self, pWindowHandle: *mut ::HWND) -> ::HRESULT,
    fn CreateSwapChain(
        &mut self, pDevice: *mut ::IUnknown, pDesc: *mut DXGI_SWAP_CHAIN_DESC,
        ppSwapChain: *mut *mut IDXGISwapChain
    ) -> ::HRESULT,
    fn CreateSoftwareAdapter(
        &mut self, Module: ::HMODULE, ppAdapter: *mut *mut IDXGIAdapter
    ) -> ::HRESULT
});
RIDL!(
interface IDXGIDevice(IDXGIDeviceVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn GetAdapter(&mut self, pAdapter: *mut *mut IDXGIAdapter) -> ::HRESULT,
    fn CreateSurface(
        &mut self, pDesc: *const DXGI_SURFACE_DESC, NumSurfaces: ::UINT, Usage: ::DXGI_USAGE,
        pSharedResource: *const DXGI_SHARED_RESOURCE, ppSurface: *mut *mut IDXGISurface
    ) -> ::HRESULT,
    fn QueryResourceResidency(
        &mut self, ppResources: *const *mut ::IUnknown, pResidencyStatus: *mut DXGI_RESIDENCY,
        NumResources: ::UINT
    ) -> ::HRESULT,
    fn SetGPUThreadPriority(&mut self, Priority: ::INT) -> ::HRESULT,
    fn GetGPUThreadPriority(&mut self, pPriority: *mut ::INT) -> ::HRESULT
});
ENUM!{enum DXGI_ADAPTER_FLAG {
    DXGI_ADAPTER_FLAG_NONE,
    DXGI_ADAPTER_FLAG_REMOTE,
    DXGI_ADAPTER_FLAG_SOFTWARE,
}}
STRUCT!{nodebug struct DXGI_ADAPTER_DESC1 {
    Description: [::WCHAR; 128],
    VendorId: ::UINT,
    DeviceId: ::UINT,
    SubSysId: ::UINT,
    Revision: ::UINT,
    DedicatedVideoMemory: ::SIZE_T,
    DedicatedSystemMemory: ::SIZE_T,
    SharedSystemMemory: ::SIZE_T,
    AdapterLuid: ::LUID,
    Flags: ::UINT,
}}
STRUCT!{struct DXGI_DISPLAY_COLOR_SPACE {
    PrimaryCoordinates: [[::FLOAT; 2]; 8],
    WhitePoints: [[::FLOAT; 2]; 16],
}}
RIDL!(
interface IDXGIFactory1(IDXGIFactory1Vtbl): IDXGIFactory(IDXGIFactoryVtbl) {
    fn EnumAdapters1(&mut self, Adapter: ::UINT, ppAdapter: *mut *mut IDXGIAdapter1) -> ::HRESULT,
    fn IsCurrent(&mut self) -> ::BOOL
});
RIDL!(
interface IDXGIAdapter1(IDXGIAdapter1Vtbl): IDXGIAdapter(IDXGIAdapterVtbl) {
    fn GetDesc1(&mut self, pDesc: *mut DXGI_ADAPTER_DESC1) -> ::HRESULT
});
RIDL!(
interface IDXGIDevice1(IDXGIDevice1Vtbl): IDXGIDevice(IDXGIDeviceVtbl) {
    fn SetMaximumFrameLatency(&mut self, MaxLatency: ::UINT) -> ::HRESULT,
    fn GetMaximumFrameLatency(&mut self, pMaxLatency: *mut ::UINT) -> ::HRESULT
});
<commit_msg>Add DXGI_SWAP_EFFECT_FLIP_DISCARD<commit_after>// Copyright © 2015; Connor Hilarides
// Licensed under the MIT License <LICENSE.md>
//! Mappings for the contents of dxgi.h
STRUCT!{struct DXGI_FRAME_STATISTICS {
    PresentCount: ::UINT,
    PresentRefreshCount: ::UINT,
    SyncRefreshCount: ::UINT,
    SyncQPCTime: ::LARGE_INTEGER,
    SyncGPUTime: ::LARGE_INTEGER,
}}
STRUCT!{struct DXGI_MAPPED_RECT {
    Pitch: ::INT,
    pBits: *mut ::BYTE,
}}
STRUCT!{nodebug struct DXGI_ADAPTER_DESC {
    Description: [::WCHAR; 128],
    VectorId: ::UINT,
    DeviceId: ::UINT,
    SubSysId: ::UINT,
    Revision: ::UINT,
    DedicatedVideoMemory: ::SIZE_T,
    DedicatedSystemMemory: ::SIZE_T,
    SharedSystemMemory: ::SIZE_T,
    AdapterLuid: ::LUID,
}}
STRUCT!{nodebug struct DXGI_OUTPUT_DESC {
    DeviceName: [::WCHAR; 32],
    DesktopCoordinates: ::RECT,
    AttachedToDesktop: ::BOOL,
    Rotation: ::DXGI_MODE_ROTATION,
    Monitor: ::HMONITOR,
}}
STRUCT!{struct DXGI_SHARED_RESOURCE {
    Handle: ::HANDLE,
}}
pub const DXGI_RESOURCE_PRIORITY_MINIMUM: ::DWORD = 0x28000000;
pub const DXGI_RESOURCE_PRIORITY_LOW: ::DWORD = 0x50000000;
pub const DXGI_RESOURCE_PRIORITY_NORMAL: ::DWORD = 0x78000000;
pub const DXGI_RESOURCE_PRIORITY_HIGH: ::DWORD = 0xa0000000;
pub const DXGI_RESOURCE_PRIORITY_MAXIMUM: ::DWORD = 0xc8000000;
ENUM!{enum DXGI_RESIDENCY {
    DXGI_RESIDENCY_FULLY_RESIDENT = 1,
    DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2,
    DXGI_RESIDENCY_EVICTED_TO_DISK = 3,
}}
STRUCT!{struct DXGI_SURFACE_DESC {
    Width: ::UINT,
    Height: ::UINT,
    Format: ::DXGI_FORMAT,
    SampleDesc: ::DXGI_SAMPLE_DESC,
}}
ENUM!{enum DXGI_SWAP_EFFECT {
    DXGI_SWAP_EFFECT_DISCARD = 0,
    DXGI_SWAP_EFFECT_SEQUENTIAL = 1,
    DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3,
    DXGI_SWAP_EFFECT_FLIP_DISCARD = 4,
}}
FLAGS!{enum DXGI_SWAP_CHAIN_FLAG {
    DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1,
    DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2,
    DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4,
    DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8,
    DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 16,
    DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 32,
    DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 64,
    DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 128,
    DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 256,
    DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 512,
}}
STRUCT!{struct DXGI_SWAP_CHAIN_DESC {
    BufferDesc: ::DXGI_MODE_DESC,
    SampleDesc: ::DXGI_SAMPLE_DESC,
    BufferUsage: ::DXGI_USAGE,
    BufferCount: ::UINT,
    OutputWindow: ::HWND,
    Windowed: ::BOOL,
    SwapEffect: DXGI_SWAP_EFFECT,
    Flags: ::UINT,
}}
RIDL!(
interface IDXGIObject(IDXGIObjectVtbl): IUnknown(IUnknownVtbl) {
    fn SetPrivateData(
        &mut self, Name: ::REFGUID, DataSize: ::UINT, pData: *const ::c_void
    ) -> ::HRESULT,
    fn SetPrivateDataInterface(&mut self, Name: ::REFGUID, pUnknown: *const ::IUnknown) -> ::HRESULT,
    fn GetPrivateData(
        &mut self, Name: ::REFGUID, pDataSize: *mut ::UINT, pData: *mut ::c_void
    ) -> ::HRESULT,
    fn GetParent(
        &mut self, riid: ::REFIID, ppParent: *mut *mut ::c_void
    ) -> ::HRESULT
});
RIDL!(
interface IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn GetDevice(&mut self, riid: ::REFIID, ppDevice: *mut *mut ::c_void) -> ::HRESULT
});
RIDL!(
interface IDXGIResource(IDXGIResourceVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn GetSharedHandle(&mut self, pSharedHandle: *mut ::HANDLE) -> ::HRESULT,
    fn GetUsage(&mut self, pUsage: *mut ::DXGI_USAGE) -> ::HRESULT,
    fn SetEvictionPriority(&mut self, EvictionPriority: ::UINT) -> ::HRESULT,
    fn GetEvictionPriority(&mut self, pEvictionPriority: *mut ::UINT) -> ::HRESULT
});
RIDL!(
interface IDXGIKeyedMutex(IDXGIKeyedMutexVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn AcquireSync(&mut self, Key: ::UINT64, dwMilliseconds: ::DWORD) -> ::HRESULT,
    fn ReleaseSync(&mut self, Key: ::UINT64) -> ::HRESULT
});
RIDL!(
interface IDXGISurface(IDXGISurfaceVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn GetDesc(&mut self, pDesc: *mut DXGI_SURFACE_DESC) -> ::HRESULT,
    fn Map(&mut self, pLockedRect: *mut DXGI_MAPPED_RECT, MapFlags: ::UINT) -> ::HRESULT,
    fn Unmap(&mut self) -> ::HRESULT
});
RIDL!(
interface IDXGISurface1(IDXGISurface1Vtbl): IDXGISurface(IDXGISurfaceVtbl) {
    fn GetDC(&mut self, Discard: ::BOOL, phdc: *mut ::HDC) -> ::HRESULT,
    fn ReleaseDC(&mut self, pDirtyRect: *mut ::RECT) -> ::HRESULT
});
RIDL!(
interface IDXGIAdapter(IDXGIAdapterVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn EnumOutputs(&mut self, Output: ::UINT, ppOutput: *mut *mut IDXGIOutput) -> ::HRESULT,
    fn GetDesc(&mut self, pDesc: *mut DXGI_ADAPTER_DESC) -> ::HRESULT,
    fn CheckInterfaceSupport(
        &mut self, InterfaceName: ::REFGUID, pUMDVersion: *mut ::LARGE_INTEGER
    ) -> ::HRESULT
});
RIDL!(
interface IDXGIOutput(IDXGIOutputVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn GetDesc(&mut self, pDesc: *mut DXGI_OUTPUT_DESC) -> ::HRESULT,
    fn GetDisplayModeList(
        &mut self, EnumFormat: ::DXGI_FORMAT, Flags: ::UINT, pNumModes: *mut ::UINT,
        pDesc: *mut ::DXGI_MODE_DESC
    ) -> ::HRESULT,
    fn FindClosestMatchingMode(
        &mut self, pModeToMatch: *const ::DXGI_MODE_DESC, pClosestMatch: *mut ::DXGI_MODE_DESC,
        pConcernedDevice: *mut ::IUnknown
    ) -> ::HRESULT,
    fn WaitForVBlank(&mut self) -> ::HRESULT,
    fn TakeOwnership(&mut self, pDevice: *mut ::IUnknown, Exclusive: ::BOOL) -> ::HRESULT,
    fn ReleaseOwnership(&mut self) -> (),
    fn GetGammaControlCapabilities(
        &mut self, pGammaCaps: *mut ::DXGI_GAMMA_CONTROL_CAPABILITIES
    ) -> ::HRESULT,
    fn SetGammaControl(&mut self, pArray: *const ::DXGI_GAMMA_CONTROL) -> ::HRESULT,
    fn GetGammaControl(&mut self, pArray: *mut ::DXGI_GAMMA_CONTROL) -> ::HRESULT,
    fn SetDisplaySurface(&mut self, pScanoutSurface: *mut IDXGISurface) -> ::HRESULT,
    fn GetDisplaySurfaceData(&mut self, pDestination: *mut IDXGISurface) -> ::HRESULT,
    fn GetFrameStatistics(&mut self, pStats: *mut DXGI_FRAME_STATISTICS) -> ::HRESULT
});
pub const DXGI_MAX_SWAP_CHAIN_BUFFERS: ::DWORD = 16;
pub const DXGI_PRESENT_TEST: ::DWORD = 0x00000001;
pub const DXGI_PRESENT_DO_NOT_SEQUENCE: ::DWORD = 0x00000002;
pub const DXGI_PRESENT_RESTART: ::DWORD = 0x00000004;
pub const DXGI_PRESENT_DO_NOT_WAIT: ::DWORD = 0x00000008;
pub const DXGI_PRESENT_STEREO_PREFER_RIGHT: ::DWORD = 0x00000010;
pub const DXGI_PRESENT_STEREO_TEMPORARY_MONO: ::DWORD = 0x00000020;
pub const DXGI_PRESENT_RESTRICT_TO_OUTPUT: ::DWORD = 0x00000040;
pub const DXGI_PRESENT_USE_DURATION: ::DWORD = 0x00000100;
RIDL!(
interface IDXGISwapChain(IDXGISwapChainVtbl): IDXGIDeviceSubObject(IDXGIDeviceSubObjectVtbl) {
    fn Present(&mut self, SyncInterval: ::UINT, Flags: ::UINT) -> ::HRESULT,
    fn GetBuffer(
        &mut self, Buffer: ::UINT, riid: ::REFIID, ppSurface: *mut *mut ::c_void
    ) -> ::HRESULT,
    fn SetFullscreenState(&mut self, Fullscreen: ::BOOL, pTarget: *mut IDXGIOutput) -> ::HRESULT,
    fn GetFullscreenState(
        &mut self, pFullscreen: *mut ::BOOL, ppTarget: *mut *mut IDXGIOutput
    ) -> ::HRESULT,
    fn GetDesc(&mut self, pDesc: *mut DXGI_SWAP_CHAIN_DESC) -> ::HRESULT,
    fn ResizeBuffers(
        &mut self, BufferCount: ::UINT, Width: ::UINT, Height: ::UINT, NewFormat: ::DXGI_FORMAT,
        SwapChainFlags: ::UINT
    ) -> ::HRESULT,
    fn ResizeTarget(&mut self, pNewTargetParameters: *const ::DXGI_MODE_DESC) -> ::HRESULT,
    fn GetContainingOutput(&mut self, ppOutput: *mut *mut IDXGIOutput) -> ::HRESULT,
    fn GetFrameStatistics(&mut self, pStats: *mut DXGI_FRAME_STATISTICS) -> ::HRESULT,
    fn GetLastPresentCount(&mut self, pLastPresentCount: *mut ::UINT) -> ::HRESULT
});
RIDL!(
interface IDXGIFactory(IDXGIFactoryVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn EnumAdapters(&mut self, Adapter: ::UINT, ppAdapter: *mut *mut IDXGIAdapter) -> ::HRESULT,
    fn MakeWindowAssociation(&mut self, WindowHandle: ::HWND, Flags: ::UINT) -> ::HRESULT,
    fn GetWindowAssociation(&mut self, pWindowHandle: *mut ::HWND) -> ::HRESULT,
    fn CreateSwapChain(
        &mut self, pDevice: *mut ::IUnknown, pDesc: *mut DXGI_SWAP_CHAIN_DESC,
        ppSwapChain: *mut *mut IDXGISwapChain
    ) -> ::HRESULT,
    fn CreateSoftwareAdapter(
        &mut self, Module: ::HMODULE, ppAdapter: *mut *mut IDXGIAdapter
    ) -> ::HRESULT
});
RIDL!(
interface IDXGIDevice(IDXGIDeviceVtbl): IDXGIObject(IDXGIObjectVtbl) {
    fn GetAdapter(&mut self, pAdapter: *mut *mut IDXGIAdapter) -> ::HRESULT,
    fn CreateSurface(
        &mut self, pDesc: *const DXGI_SURFACE_DESC, NumSurfaces: ::UINT, Usage: ::DXGI_USAGE,
        pSharedResource: *const DXGI_SHARED_RESOURCE, ppSurface: *mut *mut IDXGISurface
    ) -> ::HRESULT,
    fn QueryResourceResidency(
        &mut self, ppResources: *const *mut ::IUnknown, pResidencyStatus: *mut DXGI_RESIDENCY,
        NumResources: ::UINT
    ) -> ::HRESULT,
    fn SetGPUThreadPriority(&mut self, Priority: ::INT) -> ::HRESULT,
    fn GetGPUThreadPriority(&mut self, pPriority: *mut ::INT) -> ::HRESULT
});
ENUM!{enum DXGI_ADAPTER_FLAG {
    DXGI_ADAPTER_FLAG_NONE,
    DXGI_ADAPTER_FLAG_REMOTE,
    DXGI_ADAPTER_FLAG_SOFTWARE,
}}
STRUCT!{nodebug struct DXGI_ADAPTER_DESC1 {
    Description: [::WCHAR; 128],
    VendorId: ::UINT,
    DeviceId: ::UINT,
    SubSysId: ::UINT,
    Revision: ::UINT,
    DedicatedVideoMemory: ::SIZE_T,
    DedicatedSystemMemory: ::SIZE_T,
    SharedSystemMemory: ::SIZE_T,
    AdapterLuid: ::LUID,
    Flags: ::UINT,
}}
STRUCT!{struct DXGI_DISPLAY_COLOR_SPACE {
    PrimaryCoordinates: [[::FLOAT; 2]; 8],
    WhitePoints: [[::FLOAT; 2]; 16],
}}
RIDL!(
interface IDXGIFactory1(IDXGIFactory1Vtbl): IDXGIFactory(IDXGIFactoryVtbl) {
    fn EnumAdapters1(&mut self, Adapter: ::UINT, ppAdapter: *mut *mut IDXGIAdapter1) -> ::HRESULT,
    fn IsCurrent(&mut self) -> ::BOOL
});
RIDL!(
interface IDXGIAdapter1(IDXGIAdapter1Vtbl): IDXGIAdapter(IDXGIAdapterVtbl) {
    fn GetDesc1(&mut self, pDesc: *mut DXGI_ADAPTER_DESC1) -> ::HRESULT
});
RIDL!(
interface IDXGIDevice1(IDXGIDevice1Vtbl): IDXGIDevice(IDXGIDeviceVtbl) {
    fn SetMaximumFrameLatency(&mut self, MaxLatency: ::UINT) -> ::HRESULT,
    fn GetMaximumFrameLatency(&mut self, pMaxLatency: *mut ::UINT) -> ::HRESULT
});
<|endoftext|>


<commit_before>//! This is documentation for the `file` module.
//!
//! # Examples

use std::io::prelude::Read;
use std::error::Error;
use std::fs::File;
use std::fs;
use std::path::Path;

/// Read Text File
///
/// # Examples
///
/// ```
/// use zwreec::file;
///
/// let stringContent = file::open_source_file("../README.md");
/// ```
pub fn open_source_file(source_file_name: &str) -> String {

    let path = Path::new(source_file_name);
    let display = path.display();

    // Open the path in read-only mode, returns `io::Result<File>`
    let mut file = match File::open(&path) {
        // The `description` method of `io::Error` returns a string that
        // describes the error
        Err(why) => panic!("couldn't open {}: {}", display,
                                                   Error::description(&why)),
        Ok(file) => file,
    };

    let mut content = String::new();
    match file.read_to_string(&mut content) {
        Err(why) => panic!("couldn't read {}: {}", display,
                                                   Error::description(&why)),
        Ok(_) => print!("{} contains:\n-------\n{}\n----\n", display, content),
    }

    content
}

pub fn save_target_file(target_file_name: &str) {
    // saving
    println!("save to file: {}", target_file_name)
}

pub fn temp_print_current_directory_files() {
    let paths = fs::read_dir(&Path::new(".")).unwrap();

    for path in paths {
        println!("Name: {}", path.unwrap().path().display())
    }
}

pub fn temp_hello() -> String {
    "hello from file".to_string()
}

#[test]
fn it_works() {
    assert!(true);
}
<commit_msg>Make tests work. Ignore non working example<commit_after>//! This is documentation for the `file` module.
//!
//! # Examples

use std::io::prelude::Read;
use std::error::Error;
use std::fs::File;
use std::fs;
use std::path::Path;

/// Read Text File
///
/// # Examples
///
/// ```ignore
/// use zwreec::file;
///
/// let stringContent = file::open_source_file("../README.md");
/// ```
pub fn open_source_file(source_file_name: &str) -> String {

    let path = Path::new(source_file_name);
    let display = path.display();

    // Open the path in read-only mode, returns `io::Result<File>`
    let mut file = match File::open(&path) {
        // The `description` method of `io::Error` returns a string that
        // describes the error
        Err(why) => panic!("couldn't open {}: {}", display,
                                                   Error::description(&why)),
        Ok(file) => file,
    };

    let mut content = String::new();
    match file.read_to_string(&mut content) {
        Err(why) => panic!("couldn't read {}: {}", display,
                                                   Error::description(&why)),
        Ok(_) => print!("{} contains:\n-------\n{}\n----\n", display, content),
    }

    content
}

pub fn save_target_file(target_file_name: &str) {
    // saving
    println!("save to file: {}", target_file_name)
}

pub fn temp_print_current_directory_files() {
    let paths = fs::read_dir(&Path::new(".")).unwrap();

    for path in paths {
        println!("Name: {}", path.unwrap().path().display())
    }
}

pub fn temp_hello() -> String {
    "hello from file".to_string()
}

#[test]
fn it_works() {
    assert!(true);
}
<|endoftext|>