<commit_before><commit_msg>Add test for texture drawing<commit_after>#![feature(plugin)]
#![feature(unboxed_closures)]

#[plugin]
extern crate glium_macros;

extern crate glutin;

#[macro_use]
extern crate glium;

use std::default::Default;
use glium::Surface;

mod support;

#[test]
fn texture_2d_draw() {
    let display = support::build_display();
    let (vb, ib) = support::build_rectangle_vb_ib(&display);

    let texture = glium::texture::Texture2d::new(&display, vec![
        vec![(255, 0, 0, 255), (255, 0, 0, 255)],
        vec![(255, 0, 0, 255), (255, 0, 0, 255u8)],
    ]);

    let program = glium::Program::from_source(&display,
        "
            #version 110

            attribute vec2 position;

            void main() {
                gl_Position = vec4(position, 0.0, 1.0);
            }
        ",
        "
            #version 110

            uniform sampler2D texture;

            void main() {
                gl_FragColor = texture2D(texture, vec2(0.5, 0.5));
            }
        ",
        None).unwrap();

    let output = support::build_renderable_texture(&display);
    output.as_surface().clear_color(0.0, 0.0, 0.0, 0.0);
    output.as_surface().draw(&vb, &ib, &program, &uniform!{ texture: &texture },
                             &Default::default()).unwrap();

    let data: Vec<Vec<(f32, f32, f32, f32)>> = output.read();
    for row in data.iter() {
        for pixel in row.iter() {
            assert_eq!(pixel, &(1.0, 0.0, 0.0, 1.0));
        }
    }

    display.assert_no_error();
}
<|endoftext|>


<commit_before><commit_msg>recfactored tests<commit_after><|endoftext|>


<commit_before><commit_msg>Fix Hash vs PartialEq bug found by Clippy<commit_after><|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

pub static DEFAULT_ENTRY: &'static str = "\
---\
[imag]\
links = []\
version = \"0.4.0\"\
---";

/// Generator helper macro for mock app (for testing only)
///
/// Requires the following crates in scope:
///
/// * std
/// * libimagrt
/// * clap
///
#[macro_export]
macro_rules! make_mock_app {
    {
        app $appname:expr;
        module $module:ident;
        version $version:expr;
    } => {
        make_mock_app! {
            app $appname;
            module $module;
            version $version;
            with help "This is a mocking app";
        }
    };

    {
        app $appname:expr;
        modulename $module:ident;
        version $version:expr;
        with help $help:expr;
    }=> {
        mod $module {
            use clap::{App, ArgMatches};
            use libimagrt::spec::CliSpec;
            use libimagrt::runtime::Runtime;
            use libimagrt::error::RuntimeError;
            use libimagrt::configuration::{Configuration, InternalConfiguration};

            #[derive(Clone)]
            struct MockLinkApp<'a> {
                args: Vec<&'static str>,
                inner: App<'a, 'a>,
            }

            impl<'a> MockLinkApp<'a> {
                fn new(args: Vec<&'static str>) -> Self {
                    MockLinkApp {
                        args: args,
                        inner: ::build_ui(Runtime::get_default_cli_builder($appname, $version, $help)),
                    }
                }
            }

            impl<'a> CliSpec<'a> for MockLinkApp<'a> {
                fn name(&self) -> &str {
                    self.inner.get_name()
                }

                fn matches(self) -> ArgMatches<'a> {
                    self.inner.get_matches_from(self.args)
                }
            }

            impl<'a> InternalConfiguration for MockLinkApp<'a> {
                fn enable_logging(&self) -> bool {
                    false
                }

                fn use_inmemory_fs(&self) -> bool {
                    true
                }
            }

            pub fn generate_minimal_test_config() -> Option<Configuration> { ::toml::de::from_str("[store]\nimplicit-create=true")
                            .map(Configuration::with_value)
                            .ok()
            }

            pub fn generate_test_runtime<'a>(mut args: Vec<&'static str>) -> Result<Runtime<'a>, RuntimeError> {
                let mut cli_args = vec!["imag-link", "--rtp", "/tmp"];

                cli_args.append(&mut args);

                let cli_app = MockLinkApp::new(cli_args);
                Runtime::with_configuration(cli_app, generate_minimal_test_config())
            }
        }
    };

}

<commit_msg>Bugfix: Fix macro to use the appname instead of hardcoded values<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

pub static DEFAULT_ENTRY: &'static str = "\
---\
[imag]\
links = []\
version = \"0.4.0\"\
---";

/// Generator helper macro for mock app (for testing only)
///
/// Requires the following crates in scope:
///
/// * std
/// * libimagrt
/// * clap
///
#[macro_export]
macro_rules! make_mock_app {
    {
        app $appname:expr;
        module $module:ident;
        version $version:expr;
    } => {
        make_mock_app! {
            app $appname;
            module $module;
            version $version;
            with help "This is a mocking app";
        }
    };

    {
        app $appname:expr;
        modulename $module:ident;
        version $version:expr;
        with help $help:expr;
    }=> {
        mod $module {
            use clap::{App, ArgMatches};
            use libimagrt::spec::CliSpec;
            use libimagrt::runtime::Runtime;
            use libimagrt::error::RuntimeError;
            use libimagrt::configuration::{Configuration, InternalConfiguration};

            #[derive(Clone)]
            struct MockLinkApp<'a> {
                args: Vec<&'static str>,
                inner: App<'a, 'a>,
            }

            impl<'a> MockLinkApp<'a> {
                fn new(args: Vec<&'static str>) -> Self {
                    MockLinkApp {
                        args: args,
                        inner: ::build_ui(Runtime::get_default_cli_builder($appname, $version, $help)),
                    }
                }
            }

            impl<'a> CliSpec<'a> for MockLinkApp<'a> {
                fn name(&self) -> &str {
                    self.inner.get_name()
                }

                fn matches(self) -> ArgMatches<'a> {
                    self.inner.get_matches_from(self.args)
                }
            }

            impl<'a> InternalConfiguration for MockLinkApp<'a> {
                fn enable_logging(&self) -> bool {
                    false
                }

                fn use_inmemory_fs(&self) -> bool {
                    true
                }
            }

            pub fn generate_minimal_test_config() -> Option<Configuration> { ::toml::de::from_str("[store]\nimplicit-create=true")
                            .map(Configuration::with_value)
                            .ok()
            }

            pub fn generate_test_runtime<'a>(mut args: Vec<&'static str>) -> Result<Runtime<'a>, RuntimeError> {
                let mut cli_args = vec![$appname, "--rtp", "/tmp"];

                cli_args.append(&mut args);

                let cli_app = MockLinkApp::new(cli_args);
                Runtime::with_configuration(cli_app, generate_minimal_test_config())
            }
        }
    };

}

<|endoftext|>


<commit_before><commit_msg>impl Deserialize for m.room.canonical_alias<commit_after><|endoftext|>


<commit_before>use regex::Regex;

use std::convert::Into;
use std::convert::From;

use std::option::Option;

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct KeyValue<K, V> {
    k: K,
    v: V,
}

impl<K, V> KeyValue<K, V> {

    pub fn new(k: K, v: V) -> KeyValue<K, V> {
        KeyValue { k: k, v: v }
    }

    pub fn key(&self) -> &K {
        &self.k
    }

    pub fn value(&self) -> &V {
        &self.v
    }

}

impl<K, V> Into<(K, V)> for KeyValue<K, V> {

    fn into(self) -> (K, V) {
        (self.k, self.v)
    }

}

pub trait IntoKeyValue<K, V> {
    fn into_kv(self) -> Option<KeyValue<K, V>>;
}

impl IntoKeyValue<String, String> for String {

    fn into_kv(self) -> Option<KeyValue<String, String>> {
        let key = {
            let r = "^(?P<KEY>([^=]*))=(.*)$";
            let r = Regex::new(r).unwrap();
            r.captures(&self[..])
                .and_then(|caps| caps.name("KEY"))
        };

        let value = {
            let r = "(.*)=(\"(?P<QVALUE>([^\"]*))\"|(?P<VALUE>(.*)))$";
            let r = Regex::new(r).unwrap();
            r.captures(&self[..])
                .map(|caps| {
                    caps.name("VALUE")
                        .or(caps.name("QVALUE"))
                        .unwrap_or("")
                })
        };

        key.and_then(|k| {
            value.and_then(|v| {
                Some(KeyValue::new(String::from(k), String::from(v)))
            })
        })
    }

}

#[cfg(test)]
mod test {
    use super::{KeyValue, IntoKeyValue};

    #[test]
    fn test_single_quoted() {
        assert!(String::from("foo='bar'").into_kv().is_none());
    }

    #[test]
    fn test_double_quoted() {
        let s = String::from("foo=\"bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

    #[test]
    fn test_double_and_single_quoted() {
        assert!(String::from("foo=\"bar\'").into_kv().is_none());
    }

    #[test]
    fn test_single_and_double_quoted() {
        assert!(String::from("foo=\'bar\"").into_kv().is_none());
    }

    #[test]
    fn test_not_quoted() {
        let s = String::from("foo=bar").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

}

<commit_msg>tests: Allow quotes in keys<commit_after>use regex::Regex;

use std::convert::Into;
use std::convert::From;

use std::option::Option;

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct KeyValue<K, V> {
    k: K,
    v: V,
}

impl<K, V> KeyValue<K, V> {

    pub fn new(k: K, v: V) -> KeyValue<K, V> {
        KeyValue { k: k, v: v }
    }

    pub fn key(&self) -> &K {
        &self.k
    }

    pub fn value(&self) -> &V {
        &self.v
    }

}

impl<K, V> Into<(K, V)> for KeyValue<K, V> {

    fn into(self) -> (K, V) {
        (self.k, self.v)
    }

}

pub trait IntoKeyValue<K, V> {
    fn into_kv(self) -> Option<KeyValue<K, V>>;
}

impl IntoKeyValue<String, String> for String {

    fn into_kv(self) -> Option<KeyValue<String, String>> {
        let key = {
            let r = "^(?P<KEY>([^=]*))=(.*)$";
            let r = Regex::new(r).unwrap();
            r.captures(&self[..])
                .and_then(|caps| caps.name("KEY"))
        };

        let value = {
            let r = "(.*)=(\"(?P<QVALUE>([^\"]*))\"|(?P<VALUE>(.*)))$";
            let r = Regex::new(r).unwrap();
            r.captures(&self[..])
                .map(|caps| {
                    caps.name("VALUE")
                        .or(caps.name("QVALUE"))
                        .unwrap_or("")
                })
        };

        key.and_then(|k| {
            value.and_then(|v| {
                Some(KeyValue::new(String::from(k), String::from(v)))
            })
        })
    }

}

#[cfg(test)]
mod test {
    use super::{KeyValue, IntoKeyValue};

    #[test]
    fn test_single_quoted() {
        let s = String::from("foo='bar'").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\'bar\'")), s);
    }

    #[test]
    fn test_double_quoted() {
        let s = String::from("foo=\"bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

    #[test]
    fn test_double_and_single_quoted() {
        let s = String::from("foo=\"bar\'").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\"bar\'")), s);
    }

    #[test]
    fn test_single_and_double_quoted() {
        let s = String::from("foo=\'bar\"").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("\'bar\"")), s);
    }

    #[test]
    fn test_not_quoted() {
        let s = String::from("foo=bar").into_kv().unwrap();
        assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
    }

}

<|endoftext|>


<commit_before><commit_msg>Added Caesar Shift<commit_after>fn caesar_shift(m:&[u8], d:int)->Vec<u8>{
    m.iter()
        .map(|x| x.to_int().unwrap())
        .map(|x| ((x + d) % 256) as u8)
        .collect::<Vec<u8>>()
}

fn main(){

    // Same as caesar_shift, but closure
    let cz = | m:&[u8], d:int |
        m.iter()
            .map(|x| x.to_int().unwrap())
            .map(|x| ((x + d) % 256) as u8)
            .collect::<Vec<u8>>();

    let input = "abcdef".as_bytes();
    let key =5;
    let enc_str = cz(input, key);
    let dec_str = cz(enc_str.as_slice(), -key);
    println!("{} -> {} -> {}", input , enc_str, dec_str);

    println!("-------------------------");
    println!("Char by char test");

    for i in range(0i,256) {
        let ip = i as u8;
        let enc = cz([ip], key);
        let dec = cz(enc.as_slice(), -key);
        println!("{} -> {} -> {}", ip , enc, dec);
    }
}<|endoftext|>


<commit_before><commit_msg>Add a reduction example.<commit_after>extern crate mpi;

use mpi::traits::*;
use mpi::topology::Rank;
use mpi::collective::{self, SystemOperation};

fn main() {
    let universe = mpi::initialize().unwrap();
    let world = universe.world();
    let rank = world.rank();
    let size = world.size();
    let root_rank = 0;

    let mut sum: Rank = 0;

    world.process_at_rank(root_rank).reduce_into(&rank, Some(&mut sum), SystemOperation::sum());

    if rank == root_rank {
        assert_eq!(sum, size * (size - 1) / 2);
    }

    let mut max: Rank = -1;

    world.all_reduce_into(&rank, &mut max, SystemOperation::max());
    assert_eq!(max, size - 1);

    let a: u64 = 0b0000111111110000;
    let b: u64 = 0b0011110000111100;

    let mut c = b;
    collective::reduce_local_into(&a, &mut c, SystemOperation::bitwise_and());
    assert_eq!(c, 0b0000110000110000);

    let mut d = b;
    collective::reduce_local_into(&a, &mut d, SystemOperation::bitwise_or());
    assert_eq!(d, 0b0011111111111100);

    let mut e = b;
    collective::reduce_local_into(&a, &mut e, SystemOperation::bitwise_xor());
    assert_eq!(e, 0b0011001111001100);
}
<|endoftext|>


<commit_before><commit_msg>Remove needless references<commit_after><|endoftext|>


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

use eutil::fptr_is_null;
use libc::{c_int};
use std::mem;
use string::{cef_string_userfree_utf8_alloc,cef_string_userfree_utf8_free,cef_string_utf8_set};
use types::{cef_string_list_t,cef_string_t};

//cef_string_list

#[no_mangle]
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
    unsafe {
         let lt: Box<Vec<*mut cef_string_t>> = box vec!();
         mem::transmute(lt)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_size(lt: *mut cef_string_list_t) -> c_int {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return 0; }
        let v: *mut Vec<*mut cef_string_t> = mem::transmute(lt);
        (*v).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *const cef_string_t) {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return; }
        let v: *mut Vec<*mut cef_string_t> = mem::transmute(lt);
        let cs = cef_string_userfree_utf8_alloc();
        cef_string_utf8_set(mem::transmute((*value).str), (*value).length, cs, 1);
        (*v).push(cs);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || fptr_is_null(mem::transmute(lt)) { return 0; }
        let v: *mut Vec<*mut cef_string_t> = mem::transmute(lt);
        if index as uint > (*v).len() - 1 { return 0; }
        let cs = (*v).get(index as uint);
        cef_string_utf8_set(mem::transmute((**cs).str), (**cs).length, value, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return; }
        let v: *mut Vec<*mut cef_string_t> = mem::transmute(lt);
        if (*v).len() == 0 { return; }
        let mut cs;
        while (*v).len() != 0 {
            cs = (*v).pop();
            cef_string_userfree_utf8_free(cs.unwrap());
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return; }
        let v: Box<Vec<*mut cef_string_t>> = mem::transmute(lt);
        cef_string_list_clear(lt);
        drop(v);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_string_list_t {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return 0 as *mut cef_string_list_t; }
        let v: *mut Vec<*mut cef_string_t> = mem::transmute(lt);
        let lt2 = cef_string_list_alloc();
        for cs in (*v).iter() {
            cef_string_list_append(lt2, mem::transmute((*cs)));
        }
        lt2
    }
}
<commit_msg>embedding: add string_map_to_vec() to reduce transmute calls<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::fptr_is_null;
use libc::{c_int};
use std::mem;
use string::{cef_string_userfree_utf8_alloc,cef_string_userfree_utf8_free,cef_string_utf8_set};
use types::{cef_string_list_t,cef_string_t};

fn string_map_to_vec(lt: *mut cef_string_list_t) -> *mut Vec<*mut cef_string_t> {
    lt as *mut Vec<*mut cef_string_t>
}

//cef_string_list

#[no_mangle]
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
    unsafe {
         let lt: Box<Vec<*mut cef_string_t>> = box vec!();
         mem::transmute(lt)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_size(lt: *mut cef_string_list_t) -> c_int {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return 0; }
        let v = string_map_to_vec(lt);
        (*v).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *const cef_string_t) {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return; }
        let v = string_map_to_vec(lt);
        let cs = cef_string_userfree_utf8_alloc();
        cef_string_utf8_set(mem::transmute((*value).str), (*value).length, cs, 1);
        (*v).push(cs);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || fptr_is_null(mem::transmute(lt)) { return 0; }
        let v = string_map_to_vec(lt);
        if index as uint > (*v).len() - 1 { return 0; }
        let cs = (*v).get(index as uint);
        cef_string_utf8_set(mem::transmute((**cs).str), (**cs).length, value, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return; }
        let v = string_map_to_vec(lt);
        if (*v).len() == 0 { return; }
        let mut cs;
        while (*v).len() != 0 {
            cs = (*v).pop();
            cef_string_userfree_utf8_free(cs.unwrap());
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return; }
        let v: Box<Vec<*mut cef_string_t>> = mem::transmute(lt);
        cef_string_list_clear(lt);
        drop(v);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_string_list_t {
    unsafe {
        if fptr_is_null(mem::transmute(lt)) { return 0 as *mut cef_string_list_t; }
        let v = string_map_to_vec(lt);
        let lt2 = cef_string_list_alloc();
        for cs in (*v).iter() {
            cef_string_list_append(lt2, mem::transmute((*cs)));
        }
        lt2
    }
}
<|endoftext|>


<commit_before><commit_msg>Add failing ui test showing unsafety of fn ptr not enforced<commit_after>#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        fn f(callback: fn(p: *const u8));
    }
}

fn main() {}
<|endoftext|>


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

extern crate devicemapper;
extern crate env_logger;
extern crate libstratis;
extern crate log;
extern crate loopdev;
extern crate tempdir;

mod util;

use std::fs::OpenOptions;
use std::io::{Seek, Write, SeekFrom};
use std::path::{Path, PathBuf};

use devicemapper::{Bytes, Sectors};
use loopdev::{LoopControl, LoopDevice};
use tempdir::TempDir;

use libstratis::engine::IEC;
use libstratis::engine::strat_engine::device::wipe_sectors;

use util::logger::init_logger;
use util::simple_tests::test_basic_metadata;
use util::simple_tests::test_empty_pool;
use util::simple_tests::test_force_flag_dirty;
use util::simple_tests::test_force_flag_stratis;
use util::simple_tests::test_linear_device;
use util::simple_tests::test_pool_blockdevs;
use util::simple_tests::test_setup;
use util::simple_tests::test_teardown;
use util::simple_tests::test_thinpool_device;

/// Setup count loop backed devices in dir.
/// Make sure each loop device is backed by a 1 GiB file.
/// Wipe the first 1 MiB of the file.
fn get_devices(count: u8, dir: &TempDir) -> Vec<LoopDevice> {
    let lc = LoopControl::open().unwrap();
    let mut loop_devices = Vec::new();

    let length = Bytes(IEC::Gi);
    let wipe_length = Bytes(IEC::Mi).sectors();
    for index in 0..count {
        let subdir = TempDir::new_in(dir, &index.to_string()).unwrap();
        let path = subdir.path().join("store");
        let mut f = OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open(&path)
            .unwrap();

        // the proper way to do this is fallocate, but nix doesn't implement yet.
        // TODO: see https://github.com/nix-rust/nix/issues/596
        f.seek(SeekFrom::Start(*length)).unwrap();
        f.write(&[0]).unwrap();
        f.flush().unwrap();

        // Wipe 1 MiB at the beginning, as data sits around on the files.
        OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open(&path)
            .unwrap();
        wipe_sectors(&path, Sectors(0), wipe_length).unwrap();

        let ld = lc.next_free().unwrap();
        ld.attach(path, 0).unwrap();
        loop_devices.push(ld);
    }
    loop_devices
}

/// Set up count loopbacked devices.
/// Then, run the designated test.
/// Then, take down the loop devices.
fn test_with_spec<F>(count: u8, test: F) -> ()
    where F: Fn(&[&Path]) -> ()
{
    init_logger();
    let tmpdir = TempDir::new("stratis").unwrap();
    let loop_devices: Vec<LoopDevice> = get_devices(count, &tmpdir);
    let device_paths: Vec<PathBuf> = loop_devices
        .iter()
        .map(|x| x.get_path().unwrap())
        .collect();
    let device_paths: Vec<&Path> = device_paths.iter().map(|x| x.as_path()).collect();

    test(&device_paths);

    for dev in loop_devices {
        dev.detach().unwrap();
    }

    // Explicitly delete the temporary directory with all its contents.
    // Allowing it to be deleted on drop will cause any errors to be suppressed.
    // This may alert us to some problem with the underlying infrastructure
    // of the tests.
    tmpdir.close().unwrap();
}

#[test]
pub fn loop_test_force_flag_stratis() {
    test_with_spec(1, test_force_flag_stratis);
    test_with_spec(2, test_force_flag_stratis);
    test_with_spec(3, test_force_flag_stratis);
}

#[test]
pub fn loop_test_linear_device() {
    test_with_spec(2, test_linear_device);
    test_with_spec(3, test_linear_device);
}

#[test]
pub fn loop_test_thinpool_device() {
    test_with_spec(3, test_thinpool_device);
}

#[test]
pub fn loop_test_pool_blockdevs() {
    test_with_spec(3, test_pool_blockdevs);
}

#[test]
pub fn loop_test_force_flag_dirty() {
    test_with_spec(3, test_force_flag_dirty);
}

#[test]
pub fn loop_test_teardown() {
    test_with_spec(2, test_teardown);
}

#[test]
pub fn loop_test_setup() {
    test_with_spec(4, test_setup);
}

#[test]
pub fn loop_test_empty_pool() {
    test_with_spec(0, test_empty_pool);
}

#[test]
pub fn loop_test_basic_metadata() {
    test_with_spec(4, test_basic_metadata);
}
<commit_msg>wrap LoopDevice in a struct that implements drop<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

extern crate devicemapper;
extern crate env_logger;
extern crate libstratis;
extern crate log;
extern crate loopdev;
extern crate tempdir;

mod util;

use std::fs::OpenOptions;
use std::io::{Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};

use devicemapper::{Bytes, Sectors};
use loopdev::{LoopControl, LoopDevice};
use tempdir::TempDir;

use libstratis::engine::IEC;
use libstratis::engine::strat_engine::device::wipe_sectors;

use util::logger::init_logger;
use util::simple_tests::test_basic_metadata;
use util::simple_tests::test_empty_pool;
use util::simple_tests::test_force_flag_dirty;
use util::simple_tests::test_force_flag_stratis;
use util::simple_tests::test_linear_device;
use util::simple_tests::test_pool_blockdevs;
use util::simple_tests::test_setup;
use util::simple_tests::test_teardown;
use util::simple_tests::test_thinpool_device;

pub struct LoopTestDev {
    ld: LoopDevice,
}

impl LoopTestDev {
    pub fn new(lc: &LoopControl, path: &Path) -> LoopTestDev {
        OpenOptions::new()
            .read(true)
            .write(true)
            .open(path)
            .unwrap();

        let ld = lc.next_free().unwrap();
        ld.attach(path, 0).unwrap();
        // Wipe 1 MiB at the beginning, as data sits around on the files.
        wipe_sectors(&ld.get_path().unwrap(),
                     Sectors(0),
                     Bytes(IEC::Mi).sectors())
                .unwrap();

        LoopTestDev { ld: ld }
    }

    fn get_path(&self) -> PathBuf {
        self.ld.get_path().unwrap()
    }

    pub fn detach(&self) {
        self.ld.detach().unwrap()
    }
}

impl Drop for LoopTestDev {
    fn drop(&mut self) {
        self.detach()
    }
}

/// Setup count loop backed devices in dir.
/// Make sure each loop device is backed by a 1 GiB file.
/// Wipe the first 1 MiB of the file.
fn get_devices(count: u8, dir: &TempDir) -> Vec<LoopTestDev> {
    let lc = LoopControl::open().unwrap();
    let mut loop_devices = Vec::new();

    for index in 0..count {
        let path = dir.path().join(format!("store{}", &index));
        let mut f = OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open(&path)
            .unwrap();

        // the proper way to do this is fallocate, but nix doesn't implement yet.
        // TODO: see https://github.com/nix-rust/nix/issues/596
        f.seek(SeekFrom::Start(IEC::Gi)).unwrap();
        f.write(&[0]).unwrap();
        f.flush().unwrap();

        let ltd = LoopTestDev::new(&lc, &path);

        loop_devices.push(ltd);
    }
    loop_devices
}

/// Set up count loopbacked devices.
/// Then, run the designated test.
/// Then, take down the loop devices.
fn test_with_spec<F>(count: u8, test: F) -> ()
    where F: Fn(&[&Path]) -> ()
{
    init_logger();
    let tmpdir = TempDir::new("stratis").unwrap();
    let loop_devices: Vec<LoopTestDev> = get_devices(count, &tmpdir);
    let device_paths: Vec<PathBuf> = loop_devices.iter().map(|x| x.get_path()).collect();
    let device_paths: Vec<&Path> = device_paths.iter().map(|x| x.as_path()).collect();

    test(&device_paths);

}

#[test]
pub fn loop_test_force_flag_stratis() {
    test_with_spec(1, test_force_flag_stratis);
    test_with_spec(2, test_force_flag_stratis);
    test_with_spec(3, test_force_flag_stratis);
}

#[test]
pub fn loop_test_linear_device() {
    test_with_spec(2, test_linear_device);
    test_with_spec(3, test_linear_device);
}

#[test]
pub fn loop_test_thinpool_device() {
    test_with_spec(3, test_thinpool_device);
}

#[test]
pub fn loop_test_pool_blockdevs() {
    test_with_spec(3, test_pool_blockdevs);
}

#[test]
pub fn loop_test_force_flag_dirty() {
    test_with_spec(3, test_force_flag_dirty);
}

#[test]
pub fn loop_test_teardown() {
    test_with_spec(2, test_teardown);
}

#[test]
pub fn loop_test_setup() {
    test_with_spec(4, test_setup);
}

#[test]
pub fn loop_test_empty_pool() {
    test_with_spec(0, test_empty_pool);
}

#[test]
pub fn loop_test_basic_metadata() {
    test_with_spec(4, test_basic_metadata);
}
<|endoftext|>


<commit_before>//! Operations on manifest files.

use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::io::{self, BufRead};
use std::num::ParseIntError;
use std::path::Path;
use std::str::{self, FromStr};
use std::string::FromUtf8Error;
use std::usize;

use rawpath::RawPath;

/// Manifest file info.
pub struct Manifest {
    hostname: String,
    local_dir: RawPath,
    volumes: Vec<Option<Volume>>,
}

/// Volume info.
pub struct Volume {
    start_path: PathBlock,
    end_path: PathBlock,
    hash_type: String,
    hash: Vec<u8>,
}

/// wip
#[derive(Debug)]
pub enum ParseError {
    /// wip
    Io(io::Error),
    /// wip
    MissingKeyword(String),
    /// wip
    ParseInt(ParseIntError),
    /// wip
    Utf8(FromUtf8Error),
}

struct PathBlock {
    path: RawPath,
    block: Option<usize>,
}

struct ManifestParser<R> {
    input: R,
    buf: Vec<u8>,
}

impl Manifest {
    /// Parses a stream to get a manifest.
    pub fn parse<R: BufRead>(m: &mut R) -> Result<Self, ParseError> {
        let parser = ManifestParser::new(m);
        parser.parse()
    }

    /// wip
    pub fn hostname(&self) -> Option<&str> {
        Some(&self.hostname)
    }

    /// wip
    pub fn local_dir(&self) -> Option<&Path> {
        self.local_dir.as_path()
    }

    /// wip
    pub fn max_vol_num(&self) -> usize {
        self.volumes.len()
    }

    /// wip
    pub fn volume(&self, num: usize) -> Option<&Volume> {
        self.volumes.get(num).and_then(|v| v.as_ref())
    }
}

impl Volume {
    /// wip
    pub fn start_path(&self) -> Option<&Path> {
        self.start_path.path.as_path()
    }

    /// wip
    pub fn end_path(&self) -> Option<&Path> {
        self.end_path.path.as_path()
    }

    /// wip
    pub fn start_path_bytes(&self) -> &[u8] {
        self.start_path.path.as_bytes()
    }

    /// wip
    pub fn end_path_bytes(&self) -> &[u8] {
        self.end_path.path.as_bytes()
    }

    /// wip
    pub fn start_block(&self) -> Option<usize> {
        self.start_path.block
    }

    /// wip
    pub fn end_block(&self) -> Option<usize> {
        self.end_path.block
    }

    /// wip
    pub fn hash_type(&self) -> &str {
        &self.hash_type
    }

    /// wip
    pub fn hash(&self) -> &[u8] {
        &self.hash
    }
}

impl Error for ParseError {
    fn description(&self) -> &str {
        match *self {
            ParseError::Io(ref err) => err.description(),
            ParseError::MissingKeyword(_) => "missing keyword in manifest",
            ParseError::ParseInt(ref err) => err.description(),
            ParseError::Utf8(ref err) => err.description(),
        }
    }
}

impl Display for ParseError {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        match *self {
            ParseError::Io(ref e) => write!(fmt, "{}", e),
            ParseError::MissingKeyword(ref e) => write!(fmt, "missing keyword '{}' in manifest", e),
            ParseError::ParseInt(ref e) => write!(fmt, "{}", e),
            ParseError::Utf8(ref e) => write!(fmt, "{}", e),
        }
    }
}

impl From<io::Error> for ParseError {
    fn from(err: io::Error) -> ParseError {
        ParseError::Io(err)
    }
}

impl From<ParseIntError> for ParseError {
    fn from(err: ParseIntError) -> ParseError {
        ParseError::ParseInt(err)
    }
}

impl From<FromUtf8Error> for ParseError {
    fn from(err: FromUtf8Error) -> ParseError {
        ParseError::Utf8(err)
    }
}

impl<R: BufRead> ManifestParser<R> {
    pub fn new(input: R) -> Self {
        ManifestParser {
            input: input,
            buf: vec![],
        }
    }

    pub fn parse(mut self) -> Result<Manifest, ParseError> {
        let hostname = try!(self.read_param_str("Hostname"));
        let local_dir = RawPath::with_bytes(try!(self.read_param_bytes("Localdir")));

        let mut volumes = Vec::new();
        while let Some((vol, i)) = try!(self.read_volume()) {
            // resize volumes if necessary
            if i >= volumes.len() {
                volumes.reserve(i + 1);
                for _ in volumes.len()..i + 1 {
                    volumes.push(None);
                }
            }
            volumes[i] = Some(vol);
        }

        Ok(Manifest {
            hostname: hostname,
            local_dir: local_dir,
            volumes: volumes,
        })
    }

    fn read_volume(&mut self) -> Result<Option<(Volume, usize)>, ParseError> {
        // volume number
        let mut param = try!(self.read_param_str("Volume"));
        if param.ends_with(":") {
            param.pop();
        }
        let num = try!(usize::from_str(&param));
        let start_path = try!(self.read_path_block("StartingPath"));
        let end_path = try!(self.read_path_block("EndingPath"));
        let (htype, h) = try!(self.read_hash_param());

        let vol = Volume {
            start_path: start_path,
            end_path: end_path,
            hash_type: htype,
            hash: h,
        };
        Ok(Some((vol, num)))
    }

    fn read_path_block(&mut self, key: &str) -> Result<PathBlock, ParseError> {
        try!(self.consume_whitespace());
        if !try!(self.consume_keyword(key)) {
            return Err(ParseError::MissingKeyword(key.to_owned()));
        }
        try!(self.consume_whitespace());
        let path = try!(self.read_param_value());
        try!(self.consume_whitespace());
        let block = if !try!(self.consume_byte(b'\n')) {
            let bytes = try!(self.read_param_value());
            let s = try!(String::from_utf8(bytes));
            let num = try!(usize::from_str(&s));
            Some(num)
        } else {
            None
        };
        Ok(PathBlock {
            path: RawPath::with_bytes(path),
            block: block,
        })
    }

    fn read_hash_param(&mut self) -> Result<(String, Vec<u8>), ParseError> {
        try!(self.consume_whitespace());
        if !try!(self.consume_keyword("Hash")) {
            return Err(ParseError::MissingKeyword("Hash".to_owned()));
        }
        try!(self.consume_whitespace());
        let htype = try!(self.read_param_value_str());
        try!(self.consume_whitespace());
        let mut hash = try!(self.read_param_value());
        for b in &mut hash {
            *b -= b'0'
        }
        try!(self.consume_newline());

        Ok((htype, hash))
    }

    fn read_param_bytes(&mut self, key: &str) -> Result<Vec<u8>, ParseError> {
        try!(self.consume_whitespace());
        if !try!(self.consume_keyword(key)) {
            return Err(ParseError::MissingKeyword(key.to_owned()));
        }
        try!(self.consume_whitespace());
        match self.read_param_value() {
            Ok(res) => {
                try!(self.consume_newline());
                Ok(res)
            }
            Err(e) => Err(From::from(e)),
        }
    }

    fn read_param_str(&mut self, key: &str) -> Result<String, ParseError> {
        let bytes = try!(self.read_param_bytes(key));
        String::from_utf8(bytes).map_err(From::from)
    }

    fn consume_keyword(&mut self, key: &str) -> io::Result<bool> {
        let mut size = try!(self.input.read_until(b' ', &mut self.buf));
        if size > 0 && self.buf[size - 1] == b' ' {
            size -= 1
        }
        Ok(match_keyword(&self.buf[..size], key))
    }

    fn consume_newline(&mut self) -> io::Result<()> {
        self.consume_until(|b| {
            match b {
                b' ' | b'\t' | b'\r' | b'\n' => false,
                _ => true,
            }
        })
    }

    fn consume_whitespace(&mut self) -> io::Result<()> {
        self.consume_until(|b| {
            match b {
                b' ' | b'\t' => false,
                _ => true,
            }
        })
    }

    fn consume_until<F>(&mut self, mut f: F) -> io::Result<()>
        where F: FnMut(u8) -> bool
    {
        loop {
            let (pos, end) = {
                let buf = try!(self.input.fill_buf());
                match buf.iter().cloned().position(&mut f) {
                    Some(p) => (p, true),
                    None => (buf.len(), buf.is_empty()),
                }
            };
            self.input.consume(pos);
            if end {
                return Ok(());
            }
        }
    }

    fn read_param_value_str(&mut self) -> Result<String, ParseError> {
        let bytes = try!(self.read_param_value());
        String::from_utf8(bytes).map_err(From::from)
    }

    fn read_param_value(&mut self) -> io::Result<Vec<u8>> {
        if try!(self.consume_byte(b'"')) {
            try!(self.input.read_until(b'"', &mut self.buf));
        } else {
            try!(self.input.read_until(b'\n', &mut self.buf));
        }
        let mut result = Vec::with_capacity(self.buf.len());
        // unescape
        for (i, b) in self.buf.iter().cloned().enumerate() {
            if b != b'\\' {
                result.push(b);
            } else {
                // expects a \xNN where NN is a number string representing the escaped char in hex
                // e.g. \x20 is the space ' '
                if self.buf.len() - i >= 4 && self.buf[i + 1] == b'x' {
                    let num = ((self.buf[i + 2] - b'0') << 4) + self.buf[i + 3] - b'0';
                    result.push(num);
                }
            }
        }
        Ok(result)
    }

    fn consume_byte(&mut self, expected: u8) -> io::Result<bool> {
        let found = {
            let buf = try!(self.input.fill_buf());
            buf.first().map_or(false, |b| *b == expected)
        };
        if found {
            self.input.consume(1);
        }
        Ok(found)
    }
}

#[inline]
fn match_keyword(buf: &[u8], key: &str) -> bool {
    str::from_utf8(&buf).ok().map_or(false, |s| s == key)
}

#[cfg(test)]
mod test {
    use super::*;
    use std::fs::File;
    use std::io::BufReader;

    #[test]
    fn parse_no_err() {
        let file = File::open("tests/manifest/full1.manifest").unwrap();
        let mut bfile = BufReader::new(file);
        Manifest::parse(&mut bfile).unwrap();
    }
}
<commit_msg>Fixed read_param_value<commit_after>//! Operations on manifest files.

use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::io::{self, BufRead};
use std::num::ParseIntError;
use std::path::Path;
use std::str::{self, FromStr};
use std::string::FromUtf8Error;
use std::usize;

use rawpath::RawPath;

/// Manifest file info.
pub struct Manifest {
    hostname: String,
    local_dir: RawPath,
    volumes: Vec<Option<Volume>>,
}

/// Volume info.
pub struct Volume {
    start_path: PathBlock,
    end_path: PathBlock,
    hash_type: String,
    hash: Vec<u8>,
}

/// wip
#[derive(Debug)]
pub enum ParseError {
    /// wip
    Io(io::Error),
    /// wip
    MissingKeyword(String),
    /// wip
    ParseInt(ParseIntError),
    /// wip
    Utf8(FromUtf8Error),
}

struct PathBlock {
    path: RawPath,
    block: Option<usize>,
}

struct ManifestParser<R> {
    input: R,
    buf: Vec<u8>,
}

impl Manifest {
    /// Parses a stream to get a manifest.
    pub fn parse<R: BufRead>(m: &mut R) -> Result<Self, ParseError> {
        let parser = ManifestParser::new(m);
        parser.parse()
    }

    /// wip
    pub fn hostname(&self) -> Option<&str> {
        Some(&self.hostname)
    }

    /// wip
    pub fn local_dir(&self) -> Option<&Path> {
        self.local_dir.as_path()
    }

    /// wip
    pub fn max_vol_num(&self) -> usize {
        self.volumes.len()
    }

    /// wip
    pub fn volume(&self, num: usize) -> Option<&Volume> {
        self.volumes.get(num).and_then(|v| v.as_ref())
    }
}

impl Volume {
    /// wip
    pub fn start_path(&self) -> Option<&Path> {
        self.start_path.path.as_path()
    }

    /// wip
    pub fn end_path(&self) -> Option<&Path> {
        self.end_path.path.as_path()
    }

    /// wip
    pub fn start_path_bytes(&self) -> &[u8] {
        self.start_path.path.as_bytes()
    }

    /// wip
    pub fn end_path_bytes(&self) -> &[u8] {
        self.end_path.path.as_bytes()
    }

    /// wip
    pub fn start_block(&self) -> Option<usize> {
        self.start_path.block
    }

    /// wip
    pub fn end_block(&self) -> Option<usize> {
        self.end_path.block
    }

    /// wip
    pub fn hash_type(&self) -> &str {
        &self.hash_type
    }

    /// wip
    pub fn hash(&self) -> &[u8] {
        &self.hash
    }
}

impl Error for ParseError {
    fn description(&self) -> &str {
        match *self {
            ParseError::Io(ref err) => err.description(),
            ParseError::MissingKeyword(_) => "missing keyword in manifest",
            ParseError::ParseInt(ref err) => err.description(),
            ParseError::Utf8(ref err) => err.description(),
        }
    }
}

impl Display for ParseError {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        match *self {
            ParseError::Io(ref e) => write!(fmt, "{}", e),
            ParseError::MissingKeyword(ref e) => write!(fmt, "missing keyword '{}' in manifest", e),
            ParseError::ParseInt(ref e) => write!(fmt, "{}", e),
            ParseError::Utf8(ref e) => write!(fmt, "{}", e),
        }
    }
}

impl From<io::Error> for ParseError {
    fn from(err: io::Error) -> ParseError {
        ParseError::Io(err)
    }
}

impl From<ParseIntError> for ParseError {
    fn from(err: ParseIntError) -> ParseError {
        ParseError::ParseInt(err)
    }
}

impl From<FromUtf8Error> for ParseError {
    fn from(err: FromUtf8Error) -> ParseError {
        ParseError::Utf8(err)
    }
}

impl<R: BufRead> ManifestParser<R> {
    pub fn new(input: R) -> Self {
        ManifestParser {
            input: input,
            buf: vec![],
        }
    }

    pub fn parse(mut self) -> Result<Manifest, ParseError> {
        let hostname = try!(self.read_param_str("Hostname"));
        let local_dir = RawPath::with_bytes(try!(self.read_param_bytes("Localdir")));

        let mut volumes = Vec::new();
        while let Some((vol, i)) = try!(self.read_volume()) {
            // resize volumes if necessary
            if i >= volumes.len() {
                volumes.reserve(i + 1);
                for _ in volumes.len()..i + 1 {
                    volumes.push(None);
                }
            }
            volumes[i] = Some(vol);
        }

        Ok(Manifest {
            hostname: hostname,
            local_dir: local_dir,
            volumes: volumes,
        })
    }

    fn read_volume(&mut self) -> Result<Option<(Volume, usize)>, ParseError> {
        // volume number
        let mut param = try!(self.read_param_str("Volume"));
        if param.ends_with(":") {
            param.pop();
        }
        let num = try!(usize::from_str(&param));
        let start_path = try!(self.read_path_block("StartingPath"));
        let end_path = try!(self.read_path_block("EndingPath"));
        let (htype, h) = try!(self.read_hash_param());

        let vol = Volume {
            start_path: start_path,
            end_path: end_path,
            hash_type: htype,
            hash: h,
        };
        Ok(Some((vol, num)))
    }

    fn read_path_block(&mut self, key: &str) -> Result<PathBlock, ParseError> {
        try!(self.consume_whitespace());
        if !try!(self.consume_keyword(key)) {
            return Err(ParseError::MissingKeyword(key.to_owned()));
        }
        try!(self.consume_whitespace());
        let path = try!(self.read_param_value());
        try!(self.consume_whitespace());
        let block = if !try!(self.consume_byte(b'\n')) {
            let bytes = try!(self.read_param_value());
            let s = try!(String::from_utf8(bytes));
            let num = try!(usize::from_str(&s));
            Some(num)
        } else {
            None
        };
        Ok(PathBlock {
            path: RawPath::with_bytes(path),
            block: block,
        })
    }

    fn read_hash_param(&mut self) -> Result<(String, Vec<u8>), ParseError> {
        try!(self.consume_whitespace());
        if !try!(self.consume_keyword("Hash")) {
            return Err(ParseError::MissingKeyword("Hash".to_owned()));
        }
        try!(self.consume_whitespace());
        let htype = try!(self.read_param_value_str());
        try!(self.consume_whitespace());
        let mut hash = try!(self.read_param_value());
        for b in &mut hash {
            *b -= b'0'
        }
        try!(self.consume_newline());

        Ok((htype, hash))
    }

    fn read_param_bytes(&mut self, key: &str) -> Result<Vec<u8>, ParseError> {
        try!(self.consume_whitespace());
        if !try!(self.consume_keyword(key)) {
            return Err(ParseError::MissingKeyword(key.to_owned()));
        }
        try!(self.consume_whitespace());
        match self.read_param_value() {
            Ok(res) => {
                try!(self.consume_newline());
                Ok(res)
            }
            Err(e) => Err(From::from(e)),
        }
    }

    fn read_param_str(&mut self, key: &str) -> Result<String, ParseError> {
        let bytes = try!(self.read_param_bytes(key));
        String::from_utf8(bytes).map_err(From::from)
    }

    fn consume_keyword(&mut self, key: &str) -> io::Result<bool> {
        let mut size = try!(self.input.read_until(b' ', &mut self.buf));
        if size > 0 && self.buf[size - 1] == b' ' {
            size -= 1
        }
        Ok(match_keyword(&self.buf[..size], key))
    }

    fn consume_newline(&mut self) -> io::Result<()> {
        self.consume_until(|b| {
            match b {
                b' ' | b'\t' | b'\r' | b'\n' => false,
                _ => true,
            }
        })
    }

    fn consume_whitespace(&mut self) -> io::Result<()> {
        self.consume_until(|b| {
            match b {
                b' ' | b'\t' => false,
                _ => true,
            }
        })
    }

    fn consume_until<F>(&mut self, mut f: F) -> io::Result<()>
        where F: FnMut(u8) -> bool
    {
        loop {
            let (pos, end) = {
                let buf = try!(self.input.fill_buf());
                match buf.iter().cloned().position(&mut f) {
                    Some(p) => (p, true),
                    None => (buf.len(), buf.is_empty()),
                }
            };
            self.input.consume(pos);
            if end {
                return Ok(());
            }
        }
    }

    fn read_param_value_str(&mut self) -> Result<String, ParseError> {
        let bytes = try!(self.read_param_value());
        String::from_utf8(bytes).map_err(From::from)
    }

    fn read_param_value(&mut self) -> io::Result<Vec<u8>> {
        let (mut size, term) = {
            if try!(self.consume_byte(b'"')) {
                let s = try!(self.input.read_until(b'"', &mut self.buf));
                (s, b'"')
            } else {
                let s = try!(self.input.read_until(b'\n', &mut self.buf));
                (s, b'\n')
            }
        };
        if size > 0 && self.buf[size - 1] == term {
            size -= 1;
        }
        let buf = &self.buf[..size];
        let mut result = Vec::with_capacity(size);
        // unescape
        for (i, b) in buf.iter().cloned().enumerate() {
            if b != b'\\' {
                result.push(b);
            } else {
                // expects a \xNN where NN is a number string representing the escaped char in hex
                // e.g. \x20 is the space ' '
                if buf.len() - i >= 4 && self.buf[i + 1] == b'x' {
                    let num = ((buf[i + 2] - b'0') << 4) + buf[i + 3] - b'0';
                    result.push(num);
                }
            }
        }
        Ok(result)
    }

    fn consume_byte(&mut self, expected: u8) -> io::Result<bool> {
        let found = {
            let buf = try!(self.input.fill_buf());
            buf.first().map_or(false, |b| *b == expected)
        };
        if found {
            self.input.consume(1);
        }
        Ok(found)
    }
}

#[inline]
fn match_keyword(buf: &[u8], key: &str) -> bool {
    str::from_utf8(&buf).ok().map_or(false, |s| s == key)
}

#[cfg(test)]
mod test {
    use super::*;
    use std::fs::File;
    use std::io::BufReader;

    #[test]
    fn parse_no_err() {
        let file = File::open("tests/manifest/full1.manifest").unwrap();
        let mut bfile = BufReader::new(file);
        Manifest::parse(&mut bfile).unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Added opponent.rs; completely untested!<commit_after><|endoftext|>


<commit_before>use std::{fmt};
use os::token::Token;

#[deriving(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct PollOpt(uint);

pub const EDGE: PollOpt    = PollOpt(0x020);
pub const LEVEL: PollOpt   = PollOpt(0x040);
pub const ONESHOT: PollOpt = PollOpt(0x080);

impl PollOpt {
    #[inline]
    pub fn edge() -> PollOpt {
        EDGE | ONESHOT
    }

    #[inline]
    pub fn empty() -> PollOpt {
        PollOpt(0)
    }

    #[inline]
    pub fn all() -> PollOpt {
        EDGE | LEVEL | ONESHOT
    }

    #[inline]
    pub fn bits(&self) -> uint {
        let PollOpt(bits) = *self;
        bits
    }

    #[inline]
    pub fn contains(&self, other: PollOpt) -> bool {
        (*self & other) == other
    }
}

impl BitOr<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn bitor(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() | other.bits())
    }
}

impl BitXor<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn bitxor(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() ^ other.bits())
    }
}

impl BitAnd<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn bitand(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() & other.bits())
    }
}

impl Sub<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn sub(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() & !other.bits())
    }
}

impl Not<PollOpt> for PollOpt {
    #[inline]
    fn not(&self) -> PollOpt {
        PollOpt(!self.bits() & PollOpt::all().bits())
    }
}

impl fmt::Show for PollOpt {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (EDGE, "Edge-Triggered"),
            (LEVEL, "Level-Triggered"),
            (ONESHOT, "OneShot")];

        for &(flag, msg) in flags.iter() {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        Ok(())
    }
}

bitflags!(
    #[deriving(Copy)]
    flags Interest: uint {
        const READABLE = 0x001,
        const WRITABLE = 0x002,
        const ERROR    = 0x004,
        const HUP      = 0x008,
        const HINTED   = 0x010,
        const ALL      = 0x001 | 0x002 | 0x008  //epoll checks for ERROR no matter what
    }
)

impl fmt::Show for Interest {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (READABLE, "Readable"),
            (WRITABLE, "Writable"),
            (ERROR,    "Error"),
            (HUP,      "HupHint"),
            (HINTED,   "Hinted")];

        for &(flag, msg) in flags.iter() {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        Ok(())
    }
}

bitflags!(
    #[deriving(Copy)]
    flags ReadHint: uint {
        const DATAHINT    = 0x001,
        const HUPHINT     = 0x002,
        const ERRORHINT   = 0x004
    }
)

impl fmt::Show for ReadHint {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (DATAHINT, "DataHint"),
            (HUPHINT, "HupHint"),
            (ERRORHINT, "ErrorHint")];

        for &(flag, msg) in flags.iter() {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        Ok(())
    }
}

#[deriving(Copy, Show)]
pub struct IoEvent {
    kind: Interest,
    token: Token
}

/// IoEvent represents the raw event that the OS-specific selector
/// returned. An event can represent more than one kind (such as
/// readable or writable) at a time.
///
/// These IoEvent objects are created by the OS-specific concrete
/// Selector when they have events to report.
impl IoEvent {
    /// Create a new IoEvent.
    pub fn new(kind: Interest, token: uint) -> IoEvent {
        IoEvent {
            kind: kind,
            token: Token(token)
        }
    }

    pub fn token(&self) -> Token {
        self.token
    }

    /// Return an optional hint for a readable  handle. Currently,
    /// this method supports the HupHint, which indicates that the
    /// kernel reported that the remote side hung up. This allows a
    /// consumer to avoid reading in order to discover the hangup.
    pub fn read_hint(&self) -> ReadHint {
        let mut hint = ReadHint::empty();

        // The backend doesn't support hinting
        if !self.kind.contains(HINTED) {
            return hint;
        }

        if self.kind.contains(HUP) {
            hint = hint | HUPHINT
        }

        if self.kind.contains(READABLE) {
            hint = hint | DATAHINT
        }

        if self.kind.contains(ERROR) {
            hint = hint | ERRORHINT
        }

        hint
    }

    /// This event indicated that the  handle is now readable
    pub fn is_readable(&self) -> bool {
        self.kind.contains(READABLE) || self.kind.contains(HUP)
    }

    /// This event indicated that the  handle is now writable
    pub fn is_writable(&self) -> bool {
        self.kind.contains(WRITABLE)
    }

    /// This event indicated that the  handle had an error
    pub fn is_error(&self) -> bool {
        self.kind.contains(ERROR)
    }
}
<commit_msg>event: bitflags! now derives copy on its own.<commit_after>use std::{fmt};
use os::token::Token;

#[deriving(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct PollOpt(uint);

pub const EDGE: PollOpt    = PollOpt(0x020);
pub const LEVEL: PollOpt   = PollOpt(0x040);
pub const ONESHOT: PollOpt = PollOpt(0x080);

impl PollOpt {
    #[inline]
    pub fn edge() -> PollOpt {
        EDGE | ONESHOT
    }

    #[inline]
    pub fn empty() -> PollOpt {
        PollOpt(0)
    }

    #[inline]
    pub fn all() -> PollOpt {
        EDGE | LEVEL | ONESHOT
    }

    #[inline]
    pub fn bits(&self) -> uint {
        let PollOpt(bits) = *self;
        bits
    }

    #[inline]
    pub fn contains(&self, other: PollOpt) -> bool {
        (*self & other) == other
    }
}

impl BitOr<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn bitor(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() | other.bits())
    }
}

impl BitXor<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn bitxor(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() ^ other.bits())
    }
}

impl BitAnd<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn bitand(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() & other.bits())
    }
}

impl Sub<PollOpt, PollOpt> for PollOpt {
    #[inline]
    fn sub(self, other: PollOpt) -> PollOpt {
        PollOpt(self.bits() & !other.bits())
    }
}

impl Not<PollOpt> for PollOpt {
    #[inline]
    fn not(&self) -> PollOpt {
        PollOpt(!self.bits() & PollOpt::all().bits())
    }
}

impl fmt::Show for PollOpt {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (EDGE, "Edge-Triggered"),
            (LEVEL, "Level-Triggered"),
            (ONESHOT, "OneShot")];

        for &(flag, msg) in flags.iter() {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        Ok(())
    }
}

bitflags!(
    flags Interest: uint {
        const READABLE = 0x001,
        const WRITABLE = 0x002,
        const ERROR    = 0x004,
        const HUP      = 0x008,
        const HINTED   = 0x010,
        const ALL      = 0x001 | 0x002 | 0x008  //epoll checks for ERROR no matter what
    }
)

impl fmt::Show for Interest {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (READABLE, "Readable"),
            (WRITABLE, "Writable"),
            (ERROR,    "Error"),
            (HUP,      "HupHint"),
            (HINTED,   "Hinted")];

        for &(flag, msg) in flags.iter() {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        Ok(())
    }
}

bitflags!(
    flags ReadHint: uint {
        const DATAHINT    = 0x001,
        const HUPHINT     = 0x002,
        const ERRORHINT   = 0x004
    }
)

impl fmt::Show for ReadHint {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (DATAHINT, "DataHint"),
            (HUPHINT, "HupHint"),
            (ERRORHINT, "ErrorHint")];

        for &(flag, msg) in flags.iter() {
            if self.contains(flag) {
                if one { try!(write!(fmt, " | ")) }
                try!(write!(fmt, "{}", msg));

                one = true
            }
        }

        Ok(())
    }
}

#[deriving(Copy, Show)]
pub struct IoEvent {
    kind: Interest,
    token: Token
}

/// IoEvent represents the raw event that the OS-specific selector
/// returned. An event can represent more than one kind (such as
/// readable or writable) at a time.
///
/// These IoEvent objects are created by the OS-specific concrete
/// Selector when they have events to report.
impl IoEvent {
    /// Create a new IoEvent.
    pub fn new(kind: Interest, token: uint) -> IoEvent {
        IoEvent {
            kind: kind,
            token: Token(token)
        }
    }

    pub fn token(&self) -> Token {
        self.token
    }

    /// Return an optional hint for a readable  handle. Currently,
    /// this method supports the HupHint, which indicates that the
    /// kernel reported that the remote side hung up. This allows a
    /// consumer to avoid reading in order to discover the hangup.
    pub fn read_hint(&self) -> ReadHint {
        let mut hint = ReadHint::empty();

        // The backend doesn't support hinting
        if !self.kind.contains(HINTED) {
            return hint;
        }

        if self.kind.contains(HUP) {
            hint = hint | HUPHINT
        }

        if self.kind.contains(READABLE) {
            hint = hint | DATAHINT
        }

        if self.kind.contains(ERROR) {
            hint = hint | ERRORHINT
        }

        hint
    }

    /// This event indicated that the  handle is now readable
    pub fn is_readable(&self) -> bool {
        self.kind.contains(READABLE) || self.kind.contains(HUP)
    }

    /// This event indicated that the  handle is now writable
    pub fn is_writable(&self) -> bool {
        self.kind.contains(WRITABLE)
    }

    /// This event indicated that the  handle had an error
    pub fn is_error(&self) -> bool {
        self.kind.contains(ERROR)
    }
}
<|endoftext|>


<commit_before>//! Iron's HTTP Response representation and associated methods.

use std::io::{self, Write};
use std::fmt::{self, Debug};
use std::fs::File;

use typemap::TypeMap;
use plugin::Extensible;
use modifier::{Set, Modifier};
use hyper::header::Headers;

use status::{self, Status};
use {Plugin, headers};

pub use hyper::server::response::Response as HttpResponse;
use hyper::net::Fresh;

/// A `Write`r of HTTP response bodies.
pub struct ResponseBody<'a>(Box<Write + 'a>);

impl<'a> ResponseBody<'a> {
    /// Create a new ResponseBody, mostly for use in mocking.
    pub fn new<W: Write + 'a>(writer: W) -> ResponseBody<'a> {
        ResponseBody(Box::new(writer))
    }
}

impl<'a> Write for ResponseBody<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

/// Wrapper type to set `Read`ers as response bodies
pub struct BodyReader<R: Send>(pub R);

/// A trait which writes the body of an HTTP response.
pub trait WriteBody: Send {
    /// Writes the body to the provided `ResponseBody`.
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()>;
}

impl WriteBody for String {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        self.as_bytes().write_body(res)
    }
}

impl<'a> WriteBody for &'a str {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        self.as_bytes().write_body(res)
    }
}

impl WriteBody for Vec<u8> {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        res.write_all(self)
    }
}

impl<'a> WriteBody for &'a [u8] {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        res.write_all(self)
    }
}

impl WriteBody for File {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(self, res).map(|_| ())
    }
}

impl WriteBody for Box<io::Read + Send> {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(self, res).map(|_| ())
    }
}

impl <R: io::Read + Send> WriteBody for BodyReader<R> {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(&mut self.0, res).map(|_| ())
    }
}

/* Needs specialization :(
impl<R: Read + Send> WriteBody for R {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(self, res)
    }
}
*/

/// The response representation given to `Middleware`
pub struct Response {
    /// The response status-code.
    pub status: Option<Status>,

    /// The headers of the response.
    pub headers: Headers,

    /// A TypeMap to be used as an extensible storage for data
    /// associated with this Response.
    pub extensions: TypeMap,

    /// The body of the response.
    pub body: Option<Box<WriteBody>>
}

impl Response {
    /// Construct a blank Response
    pub fn new() -> Response {
        Response {
            status: None, // Start with no response code.
            body: None, // Start with no body.
            headers: Headers::new(),
            extensions: TypeMap::new()
        }
    }

    /// Construct a Response with the specified modifier pre-applied.
    pub fn with<M: Modifier<Response>>(m: M) -> Response {
        Response::new().set(m)
    }

    // `write_back` is used to put all the data added to `self`
    // back onto an `HttpResponse` so that it is sent back to the
    // client.
    //
    // `write_back` consumes the `Response`.
    #[doc(hidden)]
    pub fn write_back(self, mut http_res: HttpResponse<Fresh>) {
        *http_res.headers_mut() = self.headers;

        // Default to a 404 if no response code was set
        *http_res.status_mut() = self.status.clone().unwrap_or(status::NotFound);

        let out = match self.body {
            Some(body) => write_with_body(http_res, body),
            None => {
                http_res.headers_mut().set(headers::ContentLength(0));
                http_res.start().and_then(|res| res.end())
            }
        };

        if let Err(e) = out {
            error!("Error writing response: {}", e);
        }
    }
}

fn write_with_body(mut res: HttpResponse<Fresh>, mut body: Box<WriteBody>)
                   -> io::Result<()> {
    let content_type = res.headers().get::<headers::ContentType>()
                           .map_or_else(|| headers::ContentType("text/plain".parse().unwrap()),
                                        |cx| cx.clone());
    res.headers_mut().set(content_type);

    let mut raw_res = try!(res.start());
    try!(body.write_body(&mut ResponseBody::new(&mut raw_res)));
    raw_res.end()
}

impl Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "HTTP/1.1 {} {}\n{}",
            self.status.unwrap_or(status::NotFound),
            self.status.unwrap_or(status::NotFound).canonical_reason().unwrap(),
            self.headers
        )
    }
}

impl fmt::Display for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

// Allow plugins to attach to responses.
impl Extensible for Response {
    fn extensions(&self) -> &TypeMap {
        &self.extensions
    }

    fn extensions_mut(&mut self) -> &mut TypeMap {
        &mut self.extensions
    }
}

impl Plugin for Response {}
impl Set for Response {}
<commit_msg>(fix) update Response status code display<commit_after>//! Iron's HTTP Response representation and associated methods.

use std::io::{self, Write};
use std::fmt::{self, Debug};
use std::fs::File;

use typemap::TypeMap;
use plugin::Extensible;
use modifier::{Set, Modifier};
use hyper::header::Headers;

use status::{self, Status};
use {Plugin, headers};

pub use hyper::server::response::Response as HttpResponse;
use hyper::net::Fresh;

/// A `Write`r of HTTP response bodies.
pub struct ResponseBody<'a>(Box<Write + 'a>);

impl<'a> ResponseBody<'a> {
    /// Create a new ResponseBody, mostly for use in mocking.
    pub fn new<W: Write + 'a>(writer: W) -> ResponseBody<'a> {
        ResponseBody(Box::new(writer))
    }
}

impl<'a> Write for ResponseBody<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

/// Wrapper type to set `Read`ers as response bodies
pub struct BodyReader<R: Send>(pub R);

/// A trait which writes the body of an HTTP response.
pub trait WriteBody: Send {
    /// Writes the body to the provided `ResponseBody`.
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()>;
}

impl WriteBody for String {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        self.as_bytes().write_body(res)
    }
}

impl<'a> WriteBody for &'a str {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        self.as_bytes().write_body(res)
    }
}

impl WriteBody for Vec<u8> {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        res.write_all(self)
    }
}

impl<'a> WriteBody for &'a [u8] {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        res.write_all(self)
    }
}

impl WriteBody for File {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(self, res).map(|_| ())
    }
}

impl WriteBody for Box<io::Read + Send> {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(self, res).map(|_| ())
    }
}

impl <R: io::Read + Send> WriteBody for BodyReader<R> {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(&mut self.0, res).map(|_| ())
    }
}

/* Needs specialization :(
impl<R: Read + Send> WriteBody for R {
    fn write_body(&mut self, res: &mut ResponseBody) -> io::Result<()> {
        io::copy(self, res)
    }
}
*/

/// The response representation given to `Middleware`
pub struct Response {
    /// The response status-code.
    pub status: Option<Status>,

    /// The headers of the response.
    pub headers: Headers,

    /// A TypeMap to be used as an extensible storage for data
    /// associated with this Response.
    pub extensions: TypeMap,

    /// The body of the response.
    pub body: Option<Box<WriteBody>>
}

impl Response {
    /// Construct a blank Response
    pub fn new() -> Response {
        Response {
            status: None, // Start with no response code.
            body: None, // Start with no body.
            headers: Headers::new(),
            extensions: TypeMap::new()
        }
    }

    /// Construct a Response with the specified modifier pre-applied.
    pub fn with<M: Modifier<Response>>(m: M) -> Response {
        Response::new().set(m)
    }

    // `write_back` is used to put all the data added to `self`
    // back onto an `HttpResponse` so that it is sent back to the
    // client.
    //
    // `write_back` consumes the `Response`.
    #[doc(hidden)]
    pub fn write_back(self, mut http_res: HttpResponse<Fresh>) {
        *http_res.headers_mut() = self.headers;

        // Default to a 404 if no response code was set
        *http_res.status_mut() = self.status.clone().unwrap_or(status::NotFound);

        let out = match self.body {
            Some(body) => write_with_body(http_res, body),
            None => {
                http_res.headers_mut().set(headers::ContentLength(0));
                http_res.start().and_then(|res| res.end())
            }
        };

        if let Err(e) = out {
            error!("Error writing response: {}", e);
        }
    }
}

fn write_with_body(mut res: HttpResponse<Fresh>, mut body: Box<WriteBody>)
                   -> io::Result<()> {
    let content_type = res.headers().get::<headers::ContentType>()
                           .map_or_else(|| headers::ContentType("text/plain".parse().unwrap()),
                                        |cx| cx.clone());
    res.headers_mut().set(content_type);

    let mut raw_res = try!(res.start());
    try!(body.write_body(&mut ResponseBody::new(&mut raw_res)));
    raw_res.end()
}

impl Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "HTTP/1.1 {}\n{}",
            self.status.unwrap_or(status::NotFound),
            self.headers
        )
    }
}

impl fmt::Display for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

// Allow plugins to attach to responses.
impl Extensible for Response {
    fn extensions(&self) -> &TypeMap {
        &self.extensions
    }

    fn extensions_mut(&mut self) -> &mut TypeMap {
        &mut self.extensions
    }
}

impl Plugin for Response {}
impl Set for Response {}
<|endoftext|>


<commit_before><commit_msg>submit commit<commit_after>#![feature(proc_macro, plugin, custom_attribute, custom_derive, plugin)]
#![plugin(serde_derive)]

extern crate serde_json as json;
extern crate tin_can_telephone as tct;

use json::ser::{to_vec};
use json::de::{from_slice};

use tct::stanza::Stanza;

#[test]
fn stanza_message_format() {

    let message : Stanza = from_slice(
        "{\"Message\":{\"to\":\"colin\",\"from\":\"joe\",\"msg\":\"body example\"}}"
        .as_bytes()).unwrap();

    let matching_to = "colin".to_string();
    let matching_from = "joe".to_string();
    let matching_msg = "body example".to_string();

    if let Stanza::Message{ to, from, msg } = message {
        assert_eq!(to, matching_to);
        assert_eq!(from, matching_from);
        assert_eq!(msg, matching_msg);
    }

    let group_message : Stanza = from_slice(
        "{\"GroupMessage\":{\"to\":\"colin\",\"from\":\"joesteam\",\"msg\":\"body example\"}}"
        .as_bytes()).unwrap();

    let matching_to = "colin".to_string();
    let matching_from = "joesteam".to_string();
    let matching_msg = "body example".to_string();

    if let Stanza::GroupMessage{ to, from, msg, .. } = group_message {
        assert_eq!(to, matching_to);
        assert_eq!(from, matching_from);
        assert_eq!(msg, matching_msg);
    }

}

#[test]
/// This will test the format we use for requesting data from the server.
fn stanza_req_res_format() {

    use tct::stanza::{RequestKind, ResponseKind};
    use std::collections::{HashMap};

    let req : Stanza = from_slice(
        "{\"Request\":{\"to\":\"him\",\
        \"from\":\"her\",\"kind\":\"UserInfo\"}}"
        .as_bytes()).unwrap();

    let matching_to = "him".to_string();
    let matching_from = "her".to_string();
    let matching_kind = RequestKind::UserInfo; // Where UserInfo is a variant of an enum

    if let Stanza::Request{ to, from, kind } = req {
        assert_eq!(to, matching_to);
        assert_eq!(from, matching_from);
        assert_eq!(kind, matching_kind);
    }

    let res : Stanza = from_slice(
        "{\"Response\":{\"to\":\"guy\",\
        \"from\":\"girl\",\"kind\":{\"\
        UserInfo\":{\"one\":\"one_back\", \"two\":\"two_back\"}}}}"
        .as_bytes()).unwrap();

    let matching_to = "guy".to_string();
    let matching_from = "girl".to_string();
    let mut map : HashMap<String, String> = HashMap::new();
    map.insert("one".to_string(), "one_back".to_string());
    map.insert("two".to_string(), "two_back".to_string());

    if let Stanza::Response{ to, from, kind } = res {
        assert_eq!(to, matching_to);
        assert_eq!(from, matching_from);
        if let ResponseKind::UserInfo(res_map) = kind {
            assert_eq!(map.get("one"), res_map.get("one"));
            assert_eq!(map.get("two"), res_map.get("two"));
        }
    }

}

<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

use std::io;
use std::process::Command;
use target::TargetOptions;

use self::Arch::*;

#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum Arch {
    Armv7,
    Armv7s,
    Arm64,
    I386,
    X86_64
}

impl Arch {
    pub fn to_string(&self) -> &'static str {
        match self {
            &Armv7 => "armv7",
            &Armv7s => "armv7s",
            &Arm64 => "arm64",
            &I386 => "i386",
            &X86_64 => "x86_64"
        }
    }
}

pub fn get_sdk_root(sdk_name: &str) -> String {
    let res = Command::new("xcrun")
                      .arg("--show-sdk-path")
                      .arg("-sdk")
                      .arg(sdk_name)
                      .output()
                      .and_then(|output| {
                          if output.status.success() {
                              Ok(String::from_utf8(output.stdout).unwrap())
                          } else {
                              let error = String::from_utf8(output.stderr);
                              let error = format!("process exit with error: {}",
                                                  error.unwrap());
                              Err(io::Error::new(io::ErrorKind::Other,
                                                 &error[..]))
                          }
                      });

    match res {
        Ok(output) => output.trim().to_string(),
        Err(e) => panic!("failed to get {} SDK path: {}", sdk_name, e)
    }
}

fn pre_link_args(arch: Arch) -> Vec<String> {
    let sdk_name = match arch {
        Armv7 | Armv7s | Arm64 => "iphoneos",
        I386 | X86_64 => "iphonesimulator"
    };

    let arch_name = arch.to_string();

    vec!["-arch".to_string(), arch_name.to_string(),
         "-Wl,-syslibroot".to_string(), get_sdk_root(sdk_name)]
}

fn target_cpu(arch: Arch) -> String {
    match arch {
        Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
        Armv7s => "cortex-a9",
        Arm64 => "cyclone",
        I386 => "generic",
        X86_64 => "x86-64",
    }.to_string()
}

pub fn opts(arch: Arch) -> TargetOptions {
    TargetOptions {
        cpu: target_cpu(arch),
        dynamic_linking: false,
        executables: true,
        pre_link_args: pre_link_args(arch),
        .. super::apple_base::opts()
    }
}
<commit_msg>Use correct target CPU for iOS simulator.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

use std::io;
use std::process::Command;
use target::TargetOptions;

use self::Arch::*;

#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum Arch {
    Armv7,
    Armv7s,
    Arm64,
    I386,
    X86_64
}

impl Arch {
    pub fn to_string(&self) -> &'static str {
        match self {
            &Armv7 => "armv7",
            &Armv7s => "armv7s",
            &Arm64 => "arm64",
            &I386 => "i386",
            &X86_64 => "x86_64"
        }
    }
}

pub fn get_sdk_root(sdk_name: &str) -> String {
    let res = Command::new("xcrun")
                      .arg("--show-sdk-path")
                      .arg("-sdk")
                      .arg(sdk_name)
                      .output()
                      .and_then(|output| {
                          if output.status.success() {
                              Ok(String::from_utf8(output.stdout).unwrap())
                          } else {
                              let error = String::from_utf8(output.stderr);
                              let error = format!("process exit with error: {}",
                                                  error.unwrap());
                              Err(io::Error::new(io::ErrorKind::Other,
                                                 &error[..]))
                          }
                      });

    match res {
        Ok(output) => output.trim().to_string(),
        Err(e) => panic!("failed to get {} SDK path: {}", sdk_name, e)
    }
}

fn pre_link_args(arch: Arch) -> Vec<String> {
    let sdk_name = match arch {
        Armv7 | Armv7s | Arm64 => "iphoneos",
        I386 | X86_64 => "iphonesimulator"
    };

    let arch_name = arch.to_string();

    vec!["-arch".to_string(), arch_name.to_string(),
         "-Wl,-syslibroot".to_string(), get_sdk_root(sdk_name)]
}

fn target_cpu(arch: Arch) -> String {
    match arch {
        Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
        Armv7s => "cortex-a9",
        Arm64 => "cyclone",
        I386 => "yonah",
        X86_64 => "core2",
    }.to_string()
}

pub fn opts(arch: Arch) -> TargetOptions {
    TargetOptions {
        cpu: target_cpu(arch),
        dynamic_linking: false,
        executables: true,
        pre_link_args: pre_link_args(arch),
        .. super::apple_base::opts()
    }
}
<|endoftext|>