<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// 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; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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

use ffi;
use types::{gchar,gsize};
use types::{gpointer};

use alloc::libc_heap::malloc_raw;
use libc;
use libc::c_char;
use std::c_str::{CString,ToCStr};
use std::kinds::marker;
use std::mem::transmute;
use std::ptr::copy_nonoverlapping_memory;
use std::slice;
use std::str;
use std::string;

pub struct UTF8Chars<'a> {
    data: *const gchar,
    lifetime: marker::ContravariantLifetime<'a>
}

impl<'a> UTF8Chars<'a> {
    pub unsafe fn wrap(ptr: *const gchar) -> UTF8Chars<'a> {
        UTF8Chars { data: ptr, lifetime: marker::ContravariantLifetime }
    }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf(self.data as *const u8)
        }
    }
}

impl<'a> Iterator<char> for UTF8Chars<'a> {
    fn next(&mut self) -> Option<char> {
        let first_byte = unsafe { *self.data as u8 };
        if first_byte == 0 {
            return None;
        }
        if first_byte < 0x80 {
            unsafe {
                self.data = self.data.offset(1);
            }
            return Some(first_byte as char);
        }
        unsafe {
            let mut p = self.data.offset(1);
            let mut wc: u32 = (first_byte & 0x1F) as u32 << 6;
            wc |= (*p as u8 & 0x3F) as u32;
            if first_byte >= 0xE0 {
                p = p.offset(1);
                wc = (wc << 6) & 0xFFFF;
                wc |= (*p as u8 & 0x3F) as u32;
                if first_byte >= 0xF0 {
                    p = p.offset(1);
                    wc = (wc << 6) & 0x1FFFFF;
                    wc |= (*p as u8 & 0x3F) as u32;
                }
            }
            self.data = p.offset(1);
            Some(transmute(wc))
        }
    }
}

unsafe fn dup_to_c_str(source: *const c_char, len: uint) -> CString {
    let copy = malloc_raw(len + 1) as *mut c_char;
    copy_nonoverlapping_memory(copy, source, len + 1);
    CString::new(copy as *const c_char, true)
}

impl<'a> ToCStr for UTF8Chars<'a> {

    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        let src = self.data as *const c_char;
        let len = libc::strlen(src) as uint;
        dup_to_c_str(src, len)
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }
}

pub struct UTF8Buf {
    data: *mut gchar,
}

impl UTF8Buf {

    pub unsafe fn wrap(data: *mut gchar) -> UTF8Buf {
        UTF8Buf { data: data }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> {
        unsafe { UTF8Chars::wrap(self.data as *const gchar) }
    }

    pub fn into_collection(self) -> UTF8Str {
        unsafe {
            let len = libc::strlen(self.data as *const c_char);
            UTF8Str { buf: transmute(self), len: len as uint }
        }
    }

    #[inline]
    pub fn to_string(&self) -> String { self.chars().to_string() }

    #[inline]
    pub fn to_owned(&self) -> String { self.to_string() }

    #[inline]
    pub fn into_string(self) -> String { self.to_string() }

    #[inline]
    pub fn into_owned(self) -> String { self.to_string() }

    pub fn is_empty(&self) -> bool { unsafe { *self.data == 0 } }
}

impl Drop for UTF8Buf {
    fn drop(&mut self) {
        unsafe { ffi::g_free(self.data as gpointer) }
    }
}

impl Clone for UTF8Buf {
    fn clone(&self) -> UTF8Buf {
        unsafe {
            UTF8Buf::wrap(ffi::g_strdup(self.data as *const gchar))
        }
    }
}

impl ToCStr for UTF8Buf {

    fn to_c_str(&self) -> CString {
        self.chars().to_c_str()
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        self.chars().to_c_str_unchecked()
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }
}

pub struct UTF8Str {
    buf: UTF8Buf,
    len: uint
}

static NUL: gchar = 0;

impl UTF8Str {

    pub unsafe fn wrap(data: *mut gchar, len: uint) -> UTF8Str {
        UTF8Str { buf: UTF8Buf::wrap(data), len: len }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> { self.buf.chars() }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf_len(self.buf.data as *const u8, self.len)
        }
    }
}

impl Clone for UTF8Str {
    fn clone(&self) -> UTF8Str {
        unsafe {
            let copy = ffi::g_malloc((self.len + 1) as gsize) as *mut gchar;
            copy_nonoverlapping_memory(copy,
                    self.buf.data as *const gchar, self.len);
            *copy.offset(self.len as int) = NUL;
            UTF8Str::wrap(copy, self.len)
        }
    }
}

impl Str for UTF8Str {
    fn as_slice<'a>(&'a self) -> &'a str {
        unsafe {
            slice::raw::buf_as_slice(
                self.buf.data as *const u8,
                self.len,
                |bytes| {
                    let s = str::raw::from_utf8(bytes);
                    transmute(s)
                })
        }
    }
}

impl StrAllocating for UTF8Str {
    fn into_string(self) -> String { self.to_string() }
}

impl Collection for UTF8Str {

    // Common sense says we should return the UTF-8 length,
    // but &str returns length in bytes, so...
    fn len(&self) -> uint { return self.len }

    fn is_empty(&self) -> bool { return self.len == 0 }
}

impl ToCStr for UTF8Str {

    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        dup_to_c_str(self.buf.data as *const c_char, self.len)
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        self.buf.with_c_str(f)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        self.buf.with_c_str_unchecked(f)
    }
}

impl PartialEq for UTF8Str {
    fn eq(&self, other: &UTF8Str) -> bool {
        self.as_slice() == other.as_slice()
    }
}

impl Eq for UTF8Str { }

impl<S: Str> Equiv<S> for UTF8Str {
    fn equiv(&self, other: &S) -> bool {
        self.as_slice() == other.as_slice()
    }
}

pub trait WithUTF8 {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T;
}

impl<'a> WithUTF8 for UTF8Chars<'a> {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data)
    }
}

impl WithUTF8 for UTF8Buf {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data as *const gchar)
    }
}

impl WithUTF8 for UTF8Str {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.buf.with_utf8_c_str(f)
    }
}

impl<'a> WithUTF8 for &'a str {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}

impl WithUTF8 for String {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}
<commit_msg>Assert invalid UTF-8 sequences in UTF8Chars<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// 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; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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

use ffi;
use types::{gchar,gsize};
use types::{gpointer};

use alloc::libc_heap::malloc_raw;
use libc;
use libc::c_char;
use std::c_str::{CString,ToCStr};
use std::kinds::marker;
use std::mem::transmute;
use std::ptr::copy_nonoverlapping_memory;
use std::slice;
use std::str;
use std::string;

pub struct UTF8Chars<'a> {
    data: *const gchar,
    lifetime: marker::ContravariantLifetime<'a>
}

impl<'a> UTF8Chars<'a> {
    pub unsafe fn wrap(ptr: *const gchar) -> UTF8Chars<'a> {
        UTF8Chars { data: ptr, lifetime: marker::ContravariantLifetime }
    }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf(self.data as *const u8)
        }
    }
}

#[inline]
unsafe fn utf8_cont_byte(p: *const gchar) -> u8 {
    let byte = *p as u8;
    debug_assert!((byte & 0xC0) == 0x80);
    byte & 0x3F
}

impl<'a> Iterator<char> for UTF8Chars<'a> {
    fn next(&mut self) -> Option<char> {
        let first_byte = unsafe { *self.data as u8 };
        if first_byte == 0 {
            return None;
        }
        if first_byte < 0x80 {
            unsafe {
                self.data = self.data.offset(1);
            }
            return Some(first_byte as char);
        }
        unsafe {
            let mut p = self.data.offset(1);
            let mut wc: u32 = (first_byte & 0x1F) as u32 << 6;
            wc |= utf8_cont_byte(p) as u32;
            if first_byte >= 0xE0 {
                p = p.offset(1);
                wc = (wc << 6) & 0xFFFF;
                wc |= utf8_cont_byte(p) as u32;
                if first_byte >= 0xF0 {
                    debug_assert!(first_byte < 0xF8);
                    p = p.offset(1);
                    wc = (wc << 6) & 0x1FFFFF;
                    wc |= utf8_cont_byte(p) as u32;
                    debug_assert!(wc >= 0x010000 && wc <= 0x10FFFF);
                } else {
                    debug_assert!(wc >= 0x0800);
                    debug_assert!((wc & 0xF800) != 0xD800);
                }
            } else {
                debug_assert!(wc >= 0x80);
            }
            self.data = p.offset(1);
            Some(transmute(wc))
        }
    }
}

unsafe fn dup_to_c_str(source: *const c_char, len: uint) -> CString {
    let copy = malloc_raw(len + 1) as *mut c_char;
    copy_nonoverlapping_memory(copy, source, len + 1);
    CString::new(copy as *const c_char, true)
}

impl<'a> ToCStr for UTF8Chars<'a> {

    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        let src = self.data as *const c_char;
        let len = libc::strlen(src) as uint;
        dup_to_c_str(src, len)
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }
}

pub struct UTF8Buf {
    data: *mut gchar,
}

impl UTF8Buf {

    pub unsafe fn wrap(data: *mut gchar) -> UTF8Buf {
        UTF8Buf { data: data }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> {
        unsafe { UTF8Chars::wrap(self.data as *const gchar) }
    }

    pub fn into_collection(self) -> UTF8Str {
        unsafe {
            let len = libc::strlen(self.data as *const c_char);
            UTF8Str { buf: transmute(self), len: len as uint }
        }
    }

    #[inline]
    pub fn to_string(&self) -> String { self.chars().to_string() }

    #[inline]
    pub fn to_owned(&self) -> String { self.to_string() }

    #[inline]
    pub fn into_string(self) -> String { self.to_string() }

    #[inline]
    pub fn into_owned(self) -> String { self.to_string() }

    pub fn is_empty(&self) -> bool { unsafe { *self.data == 0 } }
}

impl Drop for UTF8Buf {
    fn drop(&mut self) {
        unsafe { ffi::g_free(self.data as gpointer) }
    }
}

impl Clone for UTF8Buf {
    fn clone(&self) -> UTF8Buf {
        unsafe {
            UTF8Buf::wrap(ffi::g_strdup(self.data as *const gchar))
        }
    }
}

impl ToCStr for UTF8Buf {

    fn to_c_str(&self) -> CString {
        self.chars().to_c_str()
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        self.chars().to_c_str_unchecked()
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }
}

pub struct UTF8Str {
    buf: UTF8Buf,
    len: uint
}

static NUL: gchar = 0;

impl UTF8Str {

    pub unsafe fn wrap(data: *mut gchar, len: uint) -> UTF8Str {
        UTF8Str { buf: UTF8Buf::wrap(data), len: len }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> { self.buf.chars() }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf_len(self.buf.data as *const u8, self.len)
        }
    }
}

impl Clone for UTF8Str {
    fn clone(&self) -> UTF8Str {
        unsafe {
            let copy = ffi::g_malloc((self.len + 1) as gsize) as *mut gchar;
            copy_nonoverlapping_memory(copy,
                    self.buf.data as *const gchar, self.len);
            *copy.offset(self.len as int) = NUL;
            UTF8Str::wrap(copy, self.len)
        }
    }
}

impl Str for UTF8Str {
    fn as_slice<'a>(&'a self) -> &'a str {
        unsafe {
            slice::raw::buf_as_slice(
                self.buf.data as *const u8,
                self.len,
                |bytes| {
                    let s = str::raw::from_utf8(bytes);
                    transmute(s)
                })
        }
    }
}

impl StrAllocating for UTF8Str {
    fn into_string(self) -> String { self.to_string() }
}

impl Collection for UTF8Str {

    // Common sense says we should return the UTF-8 length,
    // but &str returns length in bytes, so...
    fn len(&self) -> uint { return self.len }

    fn is_empty(&self) -> bool { return self.len == 0 }
}

impl ToCStr for UTF8Str {

    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        dup_to_c_str(self.buf.data as *const c_char, self.len)
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        self.buf.with_c_str(f)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        self.buf.with_c_str_unchecked(f)
    }
}

impl PartialEq for UTF8Str {
    fn eq(&self, other: &UTF8Str) -> bool {
        self.as_slice() == other.as_slice()
    }
}

impl Eq for UTF8Str { }

impl<S: Str> Equiv<S> for UTF8Str {
    fn equiv(&self, other: &S) -> bool {
        self.as_slice() == other.as_slice()
    }
}

pub trait WithUTF8 {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T;
}

impl<'a> WithUTF8 for UTF8Chars<'a> {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data)
    }
}

impl WithUTF8 for UTF8Buf {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data as *const gchar)
    }
}

impl WithUTF8 for UTF8Str {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.buf.with_utf8_c_str(f)
    }
}

impl<'a> WithUTF8 for &'a str {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}

impl WithUTF8 for String {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

extern crate blas;
extern crate num;

use std::num::NumCast;
use std::ops::{
    Add,
    Mul,
};
use std::vec::Vec as StdVec;
use self::blas::Vector;
use self::blas::default::Default;
use self::blas::matrix_vector::ops::{
    Ger,
    Gerc,
};
use self::blas::vector::ops::{
    Axpy,
    Copy,
    Dot,
    Dotc,
    Scal,
};
use mat::Mat;

pub struct Vec<T> {
    inc: i32,
    data: StdVec<T>,
}

pub enum TransVec<T> {
    T(Vec<T>),
    H(Vec<T>),
}

impl<T> Vec<T> {
    pub fn from_vec(vec: StdVec<T>) -> Vec<T> {
        Vec {
            inc: 1i32,
            data: vec,
        }
    }

    pub fn as_vec(&self) -> &StdVec<T> {
        &self.data
    }
}

impl<T> TransVec<T> {
    pub fn as_vec(&self) -> &Vec<T> {
        match self {
            &TransVec::T(ref v) => v,
            &TransVec::H(ref v) => v,
        }
    }
}

impl<T> Vector<T> for Vec<T> {
    #[inline]
    fn inc(&self) -> i32 { self.inc }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.data.len());
        l.unwrap()
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.data.as_slice().as_ptr() }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.data.as_mut_slice().as_mut_ptr() }
}

impl<T: Copy> Clone for Vec<T> {
    fn clone(&self) -> Vec<T> {
        let n = self.data.len();
        let mut result = Vec {
            inc: self.inc,
            data: StdVec::with_capacity(n),
        };
        Copy::copy(self, &mut result);
        unsafe { result.data.set_len(n); }

        result
    }
}

impl<T> Add<Vec<T>, Vec<T>> for Vec<T>
where T: Axpy + Copy + Default {
    fn add(&self, x: &Vec<T>) -> Vec<T> {
        let mut result = self.clone();
        Axpy::axpy(&Default::one(), x, &mut result);
        result
    }
}

impl<T> Mul<T, Vec<T>> for Vec<T>
where T: Copy + Scal {
    fn mul(&self, alpha: &T) -> Vec<T> {
        let mut result = self.clone();
        Scal::scal(alpha, &mut result);
        result
    }
}

impl<T> Mul<TransVec<T>, Mat<T>> for Vec<T>
where T: Copy + Default + Ger + Gerc {
    fn mul(&self, x: &TransVec<T>) -> Mat<T> {
        let v = x.as_vec();
        let rows = self.data.len();
        let cols = v.data.len();
        let mut result = Mat::zero(rows, cols);

        match x {
            &TransVec::T(_) => Ger::ger(&Default::one(), self, v, &mut result),
            &TransVec::H(_) => Gerc::gerc(&Default::one(), self, v, &mut result),
        }

        result
    }
}

impl<T> Mul<Vec<T>, T> for TransVec<T>
where T: Copy + Dot + Dotc {
    fn mul(&self, x: &Vec<T>) -> T {
        match *self {
            TransVec::T(ref v) => Dot::dot(v, x),
            TransVec::H(ref v) => Dotc::dotc(v, x),
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate num;

    use self::num::complex::Complex;
    use vec::Vec;
    use vec::TransVec::{
        T,
        H,
    };

    #[test]
    fn add() {
        let x = Vec::from_vec(vec![1f32, 2f32]);
        let y = Vec::from_vec(vec![-1f32, 2f32]);

        assert_eq!((x + y).as_vec(), &vec![0f32, 4f32]);
    }

    #[test]
    fn scalar_mul() {
        let x = Vec::from_vec(vec![1f32, 2f32]);

        assert_eq!((x * 3.0).as_vec(), &vec![3f32, 6f32]);
    }

    #[test]
    fn dot_mul() {
        let x = Vec::from_vec(vec![1f32, 2f32]);
        let y = Vec::from_vec(vec![-1f32, 2f32]);

        assert_eq!(T(x) * y, 3.0);
    }

    #[test]
    fn complex_conj() {
        let x = Vec::from_vec(vec![Complex::new(1f32, -1f32), Complex::new(1f32, -3f32)]);
        let y = Vec::from_vec(vec![Complex::new(1f32, 2f32), Complex::new(1f32, 3f32)]);

        assert_eq!(H(x) * y, Complex::new(-9f32, 9f32));
    }
}
<commit_msg>Rename as_vec to into_innner<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

extern crate blas;
extern crate num;

use std::num::NumCast;
use std::ops::{
    Add,
    Mul,
};
use std::vec::Vec as StdVec;
use self::blas::Vector;
use self::blas::default::Default;
use self::blas::matrix_vector::ops::{
    Ger,
    Gerc,
};
use self::blas::vector::ops::{
    Axpy,
    Copy,
    Dot,
    Dotc,
    Scal,
};
use mat::Mat;

pub struct Vec<T> {
    inc: i32,
    data: StdVec<T>,
}

pub enum TransVec<T> {
    T(Vec<T>),
    H(Vec<T>),
}

impl<T> Vec<T> {
    pub fn from_vec(vec: StdVec<T>) -> Vec<T> {
        Vec {
            inc: 1i32,
            data: vec,
        }
    }

    pub fn as_vec(&self) -> &StdVec<T> {
        &self.data
    }
}

impl<T> TransVec<T> {
    pub fn into_inner(&self) -> &Vec<T> {
        match self {
            &TransVec::T(ref v) => v,
            &TransVec::H(ref v) => v,
        }
    }
}

impl<T> Vector<T> for Vec<T> {
    #[inline]
    fn inc(&self) -> i32 { self.inc }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.data.len());
        l.unwrap()
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.data.as_slice().as_ptr() }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.data.as_mut_slice().as_mut_ptr() }
}

impl<T: Copy> Clone for Vec<T> {
    fn clone(&self) -> Vec<T> {
        let n = self.data.len();
        let mut result = Vec {
            inc: self.inc,
            data: StdVec::with_capacity(n),
        };
        Copy::copy(self, &mut result);
        unsafe { result.data.set_len(n); }

        result
    }
}

impl<T> Add<Vec<T>, Vec<T>> for Vec<T>
where T: Axpy + Copy + Default {
    fn add(&self, x: &Vec<T>) -> Vec<T> {
        let mut result = self.clone();
        Axpy::axpy(&Default::one(), x, &mut result);
        result
    }
}

impl<T> Mul<T, Vec<T>> for Vec<T>
where T: Copy + Scal {
    fn mul(&self, alpha: &T) -> Vec<T> {
        let mut result = self.clone();
        Scal::scal(alpha, &mut result);
        result
    }
}

impl<T> Mul<TransVec<T>, Mat<T>> for Vec<T>
where T: Copy + Default + Ger + Gerc {
    fn mul(&self, x: &TransVec<T>) -> Mat<T> {
        let v = x.into_inner();
        let rows = self.data.len();
        let cols = v.data.len();
        let mut result = Mat::zero(rows, cols);

        match x {
            &TransVec::T(_) => Ger::ger(&Default::one(), self, v, &mut result),
            &TransVec::H(_) => Gerc::gerc(&Default::one(), self, v, &mut result),
        }

        result
    }
}

impl<T> Mul<Vec<T>, T> for TransVec<T>
where T: Copy + Dot + Dotc {
    fn mul(&self, x: &Vec<T>) -> T {
        match *self {
            TransVec::T(ref v) => Dot::dot(v, x),
            TransVec::H(ref v) => Dotc::dotc(v, x),
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate num;

    use self::num::complex::Complex;
    use vec::Vec;
    use vec::TransVec::{
        T,
        H,
    };

    #[test]
    fn add() {
        let x = Vec::from_vec(vec![1f32, 2f32]);
        let y = Vec::from_vec(vec![-1f32, 2f32]);

        assert_eq!((x + y).as_vec(), &vec![0f32, 4f32]);
    }

    #[test]
    fn scalar_mul() {
        let x = Vec::from_vec(vec![1f32, 2f32]);

        assert_eq!((x * 3.0).as_vec(), &vec![3f32, 6f32]);
    }

    #[test]
    fn dot_mul() {
        let x = Vec::from_vec(vec![1f32, 2f32]);
        let y = Vec::from_vec(vec![-1f32, 2f32]);

        assert_eq!(T(x) * y, 3.0);
    }

    #[test]
    fn complex_conj() {
        let x = Vec::from_vec(vec![Complex::new(1f32, -1f32), Complex::new(1f32, -3f32)]);
        let y = Vec::from_vec(vec![Complex::new(1f32, 2f32), Complex::new(1f32, 3f32)]);

        assert_eq!(H(x) * y, Complex::new(-9f32, 9f32));
    }
}
<|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 cc;
extern crate gl_generator;

use gl_generator::{Api, Fallbacks, Profile, Registry};
use std::env;
use std::fs::File;
use std::path::Path;

fn main() {
    let target = env::var("TARGET").unwrap();
    if target.contains("android") {
        android_main()
    }
    generate_gl_bindings(&target);
}

fn android_main() {
    // Get the NDK path from NDK_HOME env.
    let ndk_path = env::var_os("ANDROID_NDK").expect("Please set the ANDROID_NDK environment variable");
    let ndk_path = Path::new(&ndk_path);

    let target = env::var("TARGET").unwrap();
    let arch = if target.contains("arm") {
        "arch-arm"
    } else if target.contains("aarch64") {
        "arch-arm64"
    } else if target.contains("x86") || target.contains("i686") {
        "arch-x86"
    } else if target.contains("mips") {
        "arch-mips"
    } else {
        panic!("Invalid target architecture {}", target);
    };

    let platform = if target.contains("aarch64") {
        "android-21"
    } else {
        "android-18"
    };

    // compiling android_native_app_glue.c
    let c_file = ndk_path.join("sources").join("android").join("native_app_glue").join("android_native_app_glue.c");
    let sysroot = ndk_path.join("platforms").join(platform).join(arch);
    cc::Build::new()
        .file(c_file)
        .flag("--sysroot")
        .flag(sysroot.to_str().unwrap())
        .warnings(false)
        .compile("android_native_app_glue");

    // Get the output directory.
    let out_dir = env::var("OUT_DIR").expect("Cargo should have set the OUT_DIR environment variable");

    println!("cargo:rustc-link-lib=static=android_native_app_glue");
    println!("cargo:rustc-link-search=native={}", out_dir);
    println!("cargo:rustc-link-lib=log");
    println!("cargo:rustc-link-lib=android");

}

fn generate_gl_bindings(target: &str) {
    // For now, we only support EGL, and only on Windows and Android.
    if target.contains("android") || target.contains("windows") {
        let dest = env::var("OUT_DIR").unwrap();
        let mut file = File::create(&Path::new(&dest).join("egl_bindings.rs")).unwrap();
        if target.contains("android") {
            Registry::new(Api::Egl, (1, 5), Profile::Core, Fallbacks::All, [])
                .write_bindings(gl_generator::StaticStructGenerator, &mut file)
                .unwrap();
        }
        if target.contains("windows") {
            Registry::new(Api::Egl, (1, 5), Profile::Core, Fallbacks::All, [])
                .write_bindings(gl_generator::StructGenerator, &mut file)
                .unwrap();
        };
    }
}
<commit_msg>Format ports/libsimpleservo<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 cc;
extern crate gl_generator;

use gl_generator::{Api, Fallbacks, Profile, Registry};
use std::env;
use std::fs::File;
use std::path::Path;

fn main() {
    let target = env::var("TARGET").unwrap();
    if target.contains("android") {
        android_main()
    }
    generate_gl_bindings(&target);
}

fn android_main() {
    // Get the NDK path from NDK_HOME env.
    let ndk_path =
        env::var_os("ANDROID_NDK").expect("Please set the ANDROID_NDK environment variable");
    let ndk_path = Path::new(&ndk_path);

    let target = env::var("TARGET").unwrap();
    let arch = if target.contains("arm") {
        "arch-arm"
    } else if target.contains("aarch64") {
        "arch-arm64"
    } else if target.contains("x86") || target.contains("i686") {
        "arch-x86"
    } else if target.contains("mips") {
        "arch-mips"
    } else {
        panic!("Invalid target architecture {}", target);
    };

    let platform = if target.contains("aarch64") {
        "android-21"
    } else {
        "android-18"
    };

    // compiling android_native_app_glue.c
    let c_file = ndk_path
        .join("sources")
        .join("android")
        .join("native_app_glue")
        .join("android_native_app_glue.c");
    let sysroot = ndk_path.join("platforms").join(platform).join(arch);
    cc::Build::new()
        .file(c_file)
        .flag("--sysroot")
        .flag(sysroot.to_str().unwrap())
        .warnings(false)
        .compile("android_native_app_glue");

    // Get the output directory.
    let out_dir =
        env::var("OUT_DIR").expect("Cargo should have set the OUT_DIR environment variable");

    println!("cargo:rustc-link-lib=static=android_native_app_glue");
    println!("cargo:rustc-link-search=native={}", out_dir);
    println!("cargo:rustc-link-lib=log");
    println!("cargo:rustc-link-lib=android");
}

fn generate_gl_bindings(target: &str) {
    // For now, we only support EGL, and only on Windows and Android.
    if target.contains("android") || target.contains("windows") {
        let dest = env::var("OUT_DIR").unwrap();
        let mut file = File::create(&Path::new(&dest).join("egl_bindings.rs")).unwrap();
        if target.contains("android") {
            Registry::new(Api::Egl, (1, 5), Profile::Core, Fallbacks::All, [])
                .write_bindings(gl_generator::StaticStructGenerator, &mut file)
                .unwrap();
        }
        if target.contains("windows") {
            Registry::new(Api::Egl, (1, 5), Profile::Core, Fallbacks::All, [])
                .write_bindings(gl_generator::StructGenerator, &mut file)
                .unwrap();
        };
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Alexander Reece
//
// 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::borrow::Cow;
use std::time::{SystemTime, UNIX_EPOCH};

use Encodable;
use super::MAX_SHORTSTR_LEN;
use super::{TableEntries, List};

///
/// Basic "field" that essentially represents dynamic-types in the AMQP protocol.
///
#[derive(Debug, PartialEq, Clone)]
pub enum Value<'a> {
    Void,
    Bool(bool),

    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),

    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),

    F32(f32),
    F64(f64),

    Decimal(u8, u32),
    ShortString(Cow<'a, str>),
    LongString(Cow<'a, [u8]>),
    Timestamp(u64),

    List(List<'a>),
    Table(TableEntries<'a>),
}

impl<'a> Value<'a> {

    pub fn id(&self) -> char {
        match *self {
            Value::Table(_)       => 'F',
            Value::Bool(_)        => 't',
            Value::I8(_)          => 'b',
            Value::U8(_)          => 'B',
            Value::I16(_)         => 'U',
            Value::U16(_)         => 'u',
            Value::I32(_)         => 'I',
            Value::U32(_)         => 'i',
            Value::I64(_)         => 'L',
            Value::U64(_)         => 'l',
            Value::F32(_)         => 'd',
            Value::F64(_)         => 'f',
            Value::Timestamp(_)   => 'T',
            Value::Decimal(_, _)  => 'D',
            Value::ShortString(_) => 's',
            Value::LongString(_)  => 'S',
            Value::List(_)        => 'A',
            Value::Void           => 'V',
        }
    }

    pub fn into_static(self) -> Value<'static> {
        match self {
            Value::Bool(val)           => Value::Bool(val),
            Value::I8(val)             => Value::I8(val),
            Value::U8(val)             => Value::U8(val),
            Value::I16(val)            => Value::I16(val),
            Value::U16(val)            => Value::U16(val),
            Value::I32(val)            => Value::I32(val),
            Value::U32(val)            => Value::U32(val),
            Value::I64(val)            => Value::I64(val),
            Value::U64(val)            => Value::U64(val),
            Value::F32(val)            => Value::F32(val),
            Value::F64(val)            => Value::F64(val),
            Value::Timestamp(val)      => Value::Timestamp(val),
            Value::Decimal(s, b)       => Value::Decimal(s, b),
            Value::ShortString(string) => Value::ShortString(Cow::Owned(string.into_owned())),
            Value::LongString(bytes)   => Value::LongString(Cow::Owned(bytes.into_owned())),
            Value::List(list)          => Value::List(list.into_static()),
            Value::Table(entries)      => Value::Table(entries.into_static()),
            Value::Void                => Value::Void,
        }
    }
}

impl<'a> Encodable for Value<'a> {
    fn encoded_size(&self) -> usize {
        match *self {
            Value::Void => 0,
            Value::Bool(_) | Value::I8(_)  | Value::U8(_)  => 1,
            Value::I16(_) | Value::U16(_) => 2,
            Value::I32(_) | Value::U32(_) | Value::F32(_) | Value::Timestamp(_) => 4,
            Value::I64(_) | Value::U64(_) | Value::F64(_) => 8,
            Value::Decimal(_, _) => 3,
            Value::ShortString(ref value) => value.len(),
            Value::LongString(ref value) => value.len(),
            Value::List(ref entries) => entries.iter().map(|e| e.encoded_size()).sum(),
            Value::Table(ref table) => table.encoded_size(),
        }
    }
}

impl<'a> From<TableEntries<'a>> for Value<'a> {
    fn from(entries: TableEntries<'a>) -> Self {
        Value::Table(entries)
    }
}

impl From<SystemTime> for Value<'static> {
    fn from(time: SystemTime) -> Value<'static> {
        let result = time.duration_since(UNIX_EPOCH);
        let duration = match result {
            Ok(duration) => duration,
            Err(e) => e.duration(),
        };
        Value::Timestamp(duration.as_secs())
    }
}

macro_rules! impl_from_primitive {
    ($from:ty, $to:expr) => {
        impl From<$from> for Value<'static> {
            fn from(value: $from) -> Self {
                $to(value)
            }
        }
    }
}

impl_from_primitive!(bool, Value::Bool);
impl_from_primitive!(u8, Value::U8);
impl_from_primitive!(i8, Value::I8);
impl_from_primitive!(u16, Value::U16);
impl_from_primitive!(i16, Value::I16);

impl_from_primitive!(u32, Value::U32);
impl_from_primitive!(i32, Value::I32);
impl_from_primitive!(f32, Value::F32);

impl_from_primitive!(u64, Value::U64);
impl_from_primitive!(i64, Value::I64);
impl_from_primitive!(f64, Value::F64);

impl From<()> for Value<'static> {
    fn from(_: ()) -> Self {
        Value::Void
    }
}

impl<'a> From<List<'a>> for Value<'a> {
    fn from(value: List<'a>) -> Self {
        Value::List(value)
    }
}

impl From<String> for Value<'static> {
    fn from(value: String) -> Self {
        if value.len() <= MAX_SHORTSTR_LEN {
            Value::ShortString(Cow::Owned(value))
        }
        else {
            Value::LongString(Cow::Owned(value.into_bytes()))
        }
    }
}

impl<'a> From<&'a str> for Value<'a> {
    fn from(value: &'a str) -> Self {
        if value.len() <= MAX_SHORTSTR_LEN {
            Value::ShortString(Cow::Borrowed(value))
        }
        else {
            Value::LongString(Cow::Borrowed(value.as_bytes()))
        }
    }
}

impl<'a> From<Cow<'a, str>> for Value<'a> {
    fn from(value: Cow<'a, str>) -> Self {
        if value.len() <= MAX_SHORTSTR_LEN {
            Value::ShortString(value)
        }
        else {
            match value {
                Cow::Borrowed(s) => s.into(),
                Cow::Owned(s) => s.into(),
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::borrow::Cow;
    use field::{Value, List, TableEntries};

    macro_rules! test_from_primitive {
        ($name:ident, $from:ty, $to:expr, $value:expr) => {
            #[test]
            fn $name() {
                let primitive: $from = $value;
                let value: Value = primitive.into();

                assert_eq!(value, $to($value));
            }
        }
    }

    test_from_primitive!(test_from_bool, bool, Value::Bool, true);

    test_from_primitive!(test_from_u8, u8, Value::U8, 1);
    test_from_primitive!(test_from_i8, i8, Value::I8, 2);
    test_from_primitive!(test_from_u16, u16, Value::U16, 3);
    test_from_primitive!(test_from_i16, i16, Value::I16, 4);
    test_from_primitive!(test_from_u32, u32, Value::U32, 5);
    test_from_primitive!(test_from_i32, i32, Value::I32, 6);
    test_from_primitive!(test_from_u64, u64, Value::U64, 7);
    test_from_primitive!(test_from_i64, i64, Value::I64, 8);

    test_from_primitive!(test_from_f32, f32, Value::F32, 99.99);
    test_from_primitive!(test_from_f64, f64, Value::F64, 999.99);

    #[test]
    fn test_from_empty_tuple() {
        assert_eq!(Value::Void, ().into())
    }

    #[test]
    fn test_from_short_string() {
        let val_str: Value = "short".into();
        assert_eq!(val_str, Value::ShortString(Cow::Borrowed("short")));

        let val_string: Value = "owned".to_owned().into();
        match val_string {
            Value::ShortString(Cow::Owned(ref s)) if s == "owned" => (),
            v => panic!("expected lshortstring val, got {:?}", v),
        }

        let cow_str: Cow<str> = "cow".into();
        let val_cow: Value = cow_str.into();
        assert_eq!(val_cow, Value::ShortString(Cow::Borrowed("cow")));
    }

    #[test]
    fn test_from_long_string() {
        let long = (0..1024).map(|_| "X").collect::<String>();
        let val_str: Value = long.as_str().into();
        assert_eq!(val_str, Value::LongString(Cow::Borrowed(long.as_str().as_bytes())));

        let val_string: Value = long.clone().into();
        match val_string {
            Value::LongString(Cow::Owned(ref s)) if s[..] == long.as_str().as_bytes()[..] => (),
            v => panic!("expected longstring val, got {:?}", v),
        }

        let cow_str: Cow<str> = long.as_str().into();
        let val_cow: Value = cow_str.into();
        assert_eq!(val_cow, Value::LongString(Cow::Borrowed(long.as_str().as_bytes())));
    }

    #[test]
    fn test_from_list() {
        let value: Value = List::new().into();
        match value {
            Value::List(_) => (),
            v => panic!("expected list value, got {:?}", v),
        }
    }

    #[test]
    fn test_from_table_entries() {
        let value: Value = TableEntries::new().into();
        match value {
            Value::Table(_) => (),
            v => panic!("expected table value, got {:?}", v),
        }
    }
}
<commit_msg>[primitives] Update Value::id() to return a `& 'static str` instead of `char`<commit_after>// Copyright 2016 Alexander Reece
//
// 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::borrow::Cow;
use std::time::{SystemTime, UNIX_EPOCH};

use Encodable;
use super::MAX_SHORTSTR_LEN;
use super::{TableEntries, List};

///
/// Basic "field" that essentially represents dynamic-types in the AMQP protocol.
///
#[derive(Debug, PartialEq, Clone)]
pub enum Value<'a> {
    Void,
    Bool(bool),

    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),

    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),

    F32(f32),
    F64(f64),

    Decimal(u8, u32),
    ShortString(Cow<'a, str>),
    LongString(Cow<'a, [u8]>),
    Timestamp(u64),

    List(List<'a>),
    Table(TableEntries<'a>),
}

impl<'a> Value<'a> {

    pub fn id(&self) -> &'static str {
        match *self {
            Value::Table(_)       => "F",
            Value::Bool(_)        => "t",
            Value::I8(_)          => "b",
            Value::U8(_)          => "B",
            Value::I16(_)         => "U",
            Value::U16(_)         => "u",
            Value::I32(_)         => "I",
            Value::U32(_)         => "i",
            Value::I64(_)         => "L",
            Value::U64(_)         => "l",
            Value::F32(_)         => "d",
            Value::F64(_)         => "f",
            Value::Timestamp(_)   => "T",
            Value::Decimal(_, _)  => "D"    ,
            Value::ShortString(_) => "s",
            Value::LongString(_)  => "S",
            Value::List(_)        => "A",
            Value::Void           => "V",
        }
    }

    pub fn into_static(self) -> Value<'static> {
        match self {
            Value::Bool(val)           => Value::Bool(val),
            Value::I8(val)             => Value::I8(val),
            Value::U8(val)             => Value::U8(val),
            Value::I16(val)            => Value::I16(val),
            Value::U16(val)            => Value::U16(val),
            Value::I32(val)            => Value::I32(val),
            Value::U32(val)            => Value::U32(val),
            Value::I64(val)            => Value::I64(val),
            Value::U64(val)            => Value::U64(val),
            Value::F32(val)            => Value::F32(val),
            Value::F64(val)            => Value::F64(val),
            Value::Timestamp(val)      => Value::Timestamp(val),
            Value::Decimal(s, b)       => Value::Decimal(s, b),
            Value::ShortString(string) => Value::ShortString(Cow::Owned(string.into_owned())),
            Value::LongString(bytes)   => Value::LongString(Cow::Owned(bytes.into_owned())),
            Value::List(list)          => Value::List(list.into_static()),
            Value::Table(entries)      => Value::Table(entries.into_static()),
            Value::Void                => Value::Void,
        }
    }
}

impl<'a> Encodable for Value<'a> {
    fn encoded_size(&self) -> usize {
        match *self {
            Value::Void => 0,
            Value::Bool(_) | Value::I8(_)  | Value::U8(_)  => 1,
            Value::I16(_) | Value::U16(_) => 2,
            Value::I32(_) | Value::U32(_) | Value::F32(_) | Value::Timestamp(_) => 4,
            Value::I64(_) | Value::U64(_) | Value::F64(_) => 8,
            Value::Decimal(_, _) => 3,
            Value::ShortString(ref value) => value.len(),
            Value::LongString(ref value) => value.len(),
            Value::List(ref entries) => entries.iter().map(|e| e.encoded_size()).sum(),
            Value::Table(ref table) => table.encoded_size(),
        }
    }
}

impl<'a> From<TableEntries<'a>> for Value<'a> {
    fn from(entries: TableEntries<'a>) -> Self {
        Value::Table(entries)
    }
}

impl From<SystemTime> for Value<'static> {
    fn from(time: SystemTime) -> Value<'static> {
        let result = time.duration_since(UNIX_EPOCH);
        let duration = match result {
            Ok(duration) => duration,
            Err(e) => e.duration(),
        };
        Value::Timestamp(duration.as_secs())
    }
}

macro_rules! impl_from_primitive {
    ($from:ty, $to:expr) => {
        impl From<$from> for Value<'static> {
            fn from(value: $from) -> Self {
                $to(value)
            }
        }
    }
}

impl_from_primitive!(bool, Value::Bool);
impl_from_primitive!(u8, Value::U8);
impl_from_primitive!(i8, Value::I8);
impl_from_primitive!(u16, Value::U16);
impl_from_primitive!(i16, Value::I16);

impl_from_primitive!(u32, Value::U32);
impl_from_primitive!(i32, Value::I32);
impl_from_primitive!(f32, Value::F32);

impl_from_primitive!(u64, Value::U64);
impl_from_primitive!(i64, Value::I64);
impl_from_primitive!(f64, Value::F64);

impl From<()> for Value<'static> {
    fn from(_: ()) -> Self {
        Value::Void
    }
}

impl<'a> From<List<'a>> for Value<'a> {
    fn from(value: List<'a>) -> Self {
        Value::List(value)
    }
}

impl From<String> for Value<'static> {
    fn from(value: String) -> Self {
        if value.len() <= MAX_SHORTSTR_LEN {
            Value::ShortString(Cow::Owned(value))
        }
        else {
            Value::LongString(Cow::Owned(value.into_bytes()))
        }
    }
}

impl<'a> From<&'a str> for Value<'a> {
    fn from(value: &'a str) -> Self {
        if value.len() <= MAX_SHORTSTR_LEN {
            Value::ShortString(Cow::Borrowed(value))
        }
        else {
            Value::LongString(Cow::Borrowed(value.as_bytes()))
        }
    }
}

impl<'a> From<Cow<'a, str>> for Value<'a> {
    fn from(value: Cow<'a, str>) -> Self {
        if value.len() <= MAX_SHORTSTR_LEN {
            Value::ShortString(value)
        }
        else {
            match value {
                Cow::Borrowed(s) => s.into(),
                Cow::Owned(s) => s.into(),
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::borrow::Cow;
    use field::{Value, List, TableEntries};

    macro_rules! test_from_primitive {
        ($name:ident, $from:ty, $to:expr, $value:expr) => {
            #[test]
            fn $name() {
                let primitive: $from = $value;
                let value: Value = primitive.into();

                assert_eq!(value, $to($value));
            }
        }
    }

    test_from_primitive!(test_from_bool, bool, Value::Bool, true);

    test_from_primitive!(test_from_u8, u8, Value::U8, 1);
    test_from_primitive!(test_from_i8, i8, Value::I8, 2);
    test_from_primitive!(test_from_u16, u16, Value::U16, 3);
    test_from_primitive!(test_from_i16, i16, Value::I16, 4);
    test_from_primitive!(test_from_u32, u32, Value::U32, 5);
    test_from_primitive!(test_from_i32, i32, Value::I32, 6);
    test_from_primitive!(test_from_u64, u64, Value::U64, 7);
    test_from_primitive!(test_from_i64, i64, Value::I64, 8);

    test_from_primitive!(test_from_f32, f32, Value::F32, 99.99);
    test_from_primitive!(test_from_f64, f64, Value::F64, 999.99);

    #[test]
    fn test_from_empty_tuple() {
        assert_eq!(Value::Void, ().into())
    }

    #[test]
    fn test_from_short_string() {
        let val_str: Value = "short".into();
        assert_eq!(val_str, Value::ShortString(Cow::Borrowed("short")));

        let val_string: Value = "owned".to_owned().into();
        match val_string {
            Value::ShortString(Cow::Owned(ref s)) if s == "owned" => (),
            v => panic!("expected lshortstring val, got {:?}", v),
        }

        let cow_str: Cow<str> = "cow".into();
        let val_cow: Value = cow_str.into();
        assert_eq!(val_cow, Value::ShortString(Cow::Borrowed("cow")));
    }

    #[test]
    fn test_from_long_string() {
        let long = (0..1024).map(|_| "X").collect::<String>();
        let val_str: Value = long.as_str().into();
        assert_eq!(val_str, Value::LongString(Cow::Borrowed(long.as_str().as_bytes())));

        let val_string: Value = long.clone().into();
        match val_string {
            Value::LongString(Cow::Owned(ref s)) if s[..] == long.as_str().as_bytes()[..] => (),
            v => panic!("expected longstring val, got {:?}", v),
        }

        let cow_str: Cow<str> = long.as_str().into();
        let val_cow: Value = cow_str.into();
        assert_eq!(val_cow, Value::LongString(Cow::Borrowed(long.as_str().as_bytes())));
    }

    #[test]
    fn test_from_list() {
        let value: Value = List::new().into();
        match value {
            Value::List(_) => (),
            v => panic!("expected list value, got {:?}", v),
        }
    }

    #[test]
    fn test_from_table_entries() {
        let value: Value = TableEntries::new().into();
        match value {
            Value::Table(_) => (),
            v => panic!("expected table value, got {:?}", v),
        }
    }
}
<|endoftext|>


<commit_before>use {alloc, Bytes, SeqByteStr, MAX_CAPACITY};
use traits::{Buf, MutBuf, MutBufExt, ByteStr};
use std::{cmp, ptr};
use std::num::UnsignedInt;

/*
 *
 * ===== ByteBuf =====
 *
 */

/// A `Buf` backed by a contiguous region of memory.
pub struct ByteBuf {
    mem: alloc::MemRef,
    cap: u32,
    pos: u32,
    lim: u32
}

impl ByteBuf {
    /// Create a new `ByteBuf` by copying the contents of the given slice.
    pub fn from_slice(bytes: &[u8]) -> ByteBuf {
        let mut buf = ByteBuf::mut_with_capacity(bytes.len());
        buf.write(bytes).ok().expect("unexpected failure");
        buf.flip()
    }

    pub fn mut_with_capacity(capacity: usize) -> MutByteBuf {
        assert!(capacity <= MAX_CAPACITY);
        MutByteBuf { buf: ByteBuf::new(capacity as u32) }
    }

    pub fn none() -> ByteBuf {
        ByteBuf {
            mem: alloc::MemRef::none(),
            cap: 0,
            pos: 0,
            lim: 0,
        }
    }

    pub unsafe fn from_mem_ref(mem: alloc::MemRef, cap: u32, pos: u32, lim: u32) -> ByteBuf {
        debug_assert!(pos <= lim && lim <= cap, "invalid arguments; cap={}; pos={}; lim={}", cap, pos, lim);

        ByteBuf {
            mem: mem,
            cap: cap,
            pos: pos,
            lim: lim,
        }
    }

    fn new(mut capacity: u32) -> ByteBuf {
        // Handle 0 capacity case
        if capacity == 0 {
            return ByteBuf::none();
        }

        // Round the capacity to the closest power of 2
        capacity = UnsignedInt::next_power_of_two(capacity);

        // Allocate the memory
        let mem = alloc::HEAP.allocate(capacity as usize);

        // If the allocation failed, return a blank buf
        if mem.is_none() {
            return ByteBuf::none();
        }

        ByteBuf {
            mem: mem,
            cap: capacity,
            pos: 0,
            lim: capacity
        }
    }

    pub fn capacity(&self) -> usize {
        self.cap as usize
    }

    pub fn flip(self) -> MutByteBuf {
        let mut buf = MutByteBuf { buf: self };
        buf.clear();
        buf
    }

    pub fn read_slice(&mut self, dst: &mut [u8]) -> usize {
        let len = cmp::min(dst.len(), self.remaining());
        let cnt = len as u32;

        unsafe {
            ptr::copy_nonoverlapping_memory(
                dst.as_mut_ptr(),
                self.mem.ptr().offset(self.pos as isize), len);
        }

        self.pos += cnt;
        len
    }

    pub fn to_seq_byte_str(self) -> SeqByteStr {
        unsafe {
            let ByteBuf { mem, pos, lim, .. } = self;
            SeqByteStr::from_mem_ref(
                mem, pos, lim - pos)
        }
    }

    #[inline]
    pub fn to_bytes(self) -> Bytes {
        Bytes::of(self.to_seq_byte_str())
    }

    #[inline]
    fn pos(&self) -> usize {
        self.pos as usize
    }

    #[inline]
    fn lim(&self) -> usize {
        self.lim as usize
    }

    #[inline]
    fn remaining_u32(&self) -> u32 {
        self.lim - self.pos
    }
}

impl Buf for ByteBuf {

    #[inline]
    fn remaining(&self) -> usize {
        self.remaining_u32() as usize
    }

    #[inline]
    fn bytes<'a>(&'a self) -> &'a [u8] {
        &self.mem.bytes()[self.pos()..self.lim()]
    }

    #[inline]
    fn advance(&mut self, mut cnt: usize) {
        cnt = cmp::min(cnt, self.remaining());
        self.pos += cnt as u32;
    }

    #[inline]
    fn read_slice(&mut self, dst: &mut [u8]) -> usize {
        ByteBuf::read_slice(self, dst)
    }
}

unsafe impl Send for ByteBuf { }

/*
 *
 * ===== ROByteBuf =====
 *
 */

/// Same as `ByteBuf` but cannot be flipped to a `MutByteBuf`.
pub struct ROByteBuf {
    buf: ByteBuf,
}

impl ROByteBuf {
    pub unsafe fn from_mem_ref(mem: alloc::MemRef, cap: u32, pos: u32, lim: u32) -> ROByteBuf {
        ROByteBuf {
            buf: ByteBuf::from_mem_ref(mem, cap, pos, lim)
        }
    }

    pub fn to_seq_byte_str(self) -> SeqByteStr {
        self.buf.to_seq_byte_str()
    }

    pub fn to_bytes(self) -> Bytes {
        self.buf.to_bytes()
    }
}

impl Buf for ROByteBuf {

    fn remaining(&self) -> usize {
        self.buf.remaining()
    }

    fn bytes<'a>(&'a self) -> &'a [u8] {
        self.buf.bytes()
    }

    fn advance(&mut self, cnt: usize) {
        self.buf.advance(cnt)
    }

    fn read_slice(&mut self, dst: &mut [u8]) -> usize {
        self.buf.read_slice(dst)
    }
}

/*
 *
 * ===== MutByteBuf =====
 *
 */

pub struct MutByteBuf {
    buf: ByteBuf,
}

impl MutByteBuf {
    pub fn capacity(&self) -> usize {
        self.buf.capacity() as usize
    }

    pub fn flip(self) -> ByteBuf {
        let mut buf = self.buf;

        buf.lim = buf.pos;
        buf.pos = 0;
        buf
    }

    pub fn clear(&mut self) {
        self.buf.pos = 0;
        self.buf.lim = self.buf.cap;
    }

    #[inline]
    pub fn write_slice(&mut self, src: &[u8]) -> usize {
        let cnt = src.len() as u32;
        let rem = self.buf.remaining_u32();

        if rem < cnt {
            self.write_ptr(src.as_ptr(), rem)
        } else {
            self.write_ptr(src.as_ptr(), cnt)
        }
    }

    #[inline]
    fn write_ptr(&mut self, src: *const u8, len: u32) -> usize {
        unsafe {
            ptr::copy_nonoverlapping_memory(
                self.buf.mem.ptr().offset(self.buf.pos as isize),
                src, len as usize);

            self.buf.pos += len;
            len as usize
        }
    }
}

impl MutBuf for MutByteBuf {
    fn remaining(&self) -> usize {
        self.buf.remaining()
    }

    fn advance(&mut self, cnt: usize) {
        self.buf.advance(cnt)
    }

    fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
        let pos = self.buf.pos();
        let lim = self.buf.lim();
        &mut self.buf.mem.bytes_mut()[pos..lim]
    }
}
<commit_msg>Remove unnecessary Send impl<commit_after>use {alloc, Bytes, SeqByteStr, MAX_CAPACITY};
use traits::{Buf, MutBuf, MutBufExt, ByteStr};
use std::{cmp, ptr};
use std::num::UnsignedInt;

/*
 *
 * ===== ByteBuf =====
 *
 */

/// A `Buf` backed by a contiguous region of memory.
pub struct ByteBuf {
    mem: alloc::MemRef,
    cap: u32,
    pos: u32,
    lim: u32
}

impl ByteBuf {
    /// Create a new `ByteBuf` by copying the contents of the given slice.
    pub fn from_slice(bytes: &[u8]) -> ByteBuf {
        let mut buf = ByteBuf::mut_with_capacity(bytes.len());
        buf.write(bytes).ok().expect("unexpected failure");
        buf.flip()
    }

    pub fn mut_with_capacity(capacity: usize) -> MutByteBuf {
        assert!(capacity <= MAX_CAPACITY);
        MutByteBuf { buf: ByteBuf::new(capacity as u32) }
    }

    pub fn none() -> ByteBuf {
        ByteBuf {
            mem: alloc::MemRef::none(),
            cap: 0,
            pos: 0,
            lim: 0,
        }
    }

    pub unsafe fn from_mem_ref(mem: alloc::MemRef, cap: u32, pos: u32, lim: u32) -> ByteBuf {
        debug_assert!(pos <= lim && lim <= cap, "invalid arguments; cap={}; pos={}; lim={}", cap, pos, lim);

        ByteBuf {
            mem: mem,
            cap: cap,
            pos: pos,
            lim: lim,
        }
    }

    fn new(mut capacity: u32) -> ByteBuf {
        // Handle 0 capacity case
        if capacity == 0 {
            return ByteBuf::none();
        }

        // Round the capacity to the closest power of 2
        capacity = UnsignedInt::next_power_of_two(capacity);

        // Allocate the memory
        let mem = alloc::HEAP.allocate(capacity as usize);

        // If the allocation failed, return a blank buf
        if mem.is_none() {
            return ByteBuf::none();
        }

        ByteBuf {
            mem: mem,
            cap: capacity,
            pos: 0,
            lim: capacity
        }
    }

    pub fn capacity(&self) -> usize {
        self.cap as usize
    }

    pub fn flip(self) -> MutByteBuf {
        let mut buf = MutByteBuf { buf: self };
        buf.clear();
        buf
    }

    pub fn read_slice(&mut self, dst: &mut [u8]) -> usize {
        let len = cmp::min(dst.len(), self.remaining());
        let cnt = len as u32;

        unsafe {
            ptr::copy_nonoverlapping_memory(
                dst.as_mut_ptr(),
                self.mem.ptr().offset(self.pos as isize), len);
        }

        self.pos += cnt;
        len
    }

    pub fn to_seq_byte_str(self) -> SeqByteStr {
        unsafe {
            let ByteBuf { mem, pos, lim, .. } = self;
            SeqByteStr::from_mem_ref(
                mem, pos, lim - pos)
        }
    }

    #[inline]
    pub fn to_bytes(self) -> Bytes {
        Bytes::of(self.to_seq_byte_str())
    }

    #[inline]
    fn pos(&self) -> usize {
        self.pos as usize
    }

    #[inline]
    fn lim(&self) -> usize {
        self.lim as usize
    }

    #[inline]
    fn remaining_u32(&self) -> u32 {
        self.lim - self.pos
    }
}

impl Buf for ByteBuf {

    #[inline]
    fn remaining(&self) -> usize {
        self.remaining_u32() as usize
    }

    #[inline]
    fn bytes<'a>(&'a self) -> &'a [u8] {
        &self.mem.bytes()[self.pos()..self.lim()]
    }

    #[inline]
    fn advance(&mut self, mut cnt: usize) {
        cnt = cmp::min(cnt, self.remaining());
        self.pos += cnt as u32;
    }

    #[inline]
    fn read_slice(&mut self, dst: &mut [u8]) -> usize {
        ByteBuf::read_slice(self, dst)
    }
}

/*
 *
 * ===== ROByteBuf =====
 *
 */

/// Same as `ByteBuf` but cannot be flipped to a `MutByteBuf`.
pub struct ROByteBuf {
    buf: ByteBuf,
}

impl ROByteBuf {
    pub unsafe fn from_mem_ref(mem: alloc::MemRef, cap: u32, pos: u32, lim: u32) -> ROByteBuf {
        ROByteBuf {
            buf: ByteBuf::from_mem_ref(mem, cap, pos, lim)
        }
    }

    pub fn to_seq_byte_str(self) -> SeqByteStr {
        self.buf.to_seq_byte_str()
    }

    pub fn to_bytes(self) -> Bytes {
        self.buf.to_bytes()
    }
}

impl Buf for ROByteBuf {

    fn remaining(&self) -> usize {
        self.buf.remaining()
    }

    fn bytes<'a>(&'a self) -> &'a [u8] {
        self.buf.bytes()
    }

    fn advance(&mut self, cnt: usize) {
        self.buf.advance(cnt)
    }

    fn read_slice(&mut self, dst: &mut [u8]) -> usize {
        self.buf.read_slice(dst)
    }
}

/*
 *
 * ===== MutByteBuf =====
 *
 */

pub struct MutByteBuf {
    buf: ByteBuf,
}

impl MutByteBuf {
    pub fn capacity(&self) -> usize {
        self.buf.capacity() as usize
    }

    pub fn flip(self) -> ByteBuf {
        let mut buf = self.buf;

        buf.lim = buf.pos;
        buf.pos = 0;
        buf
    }

    pub fn clear(&mut self) {
        self.buf.pos = 0;
        self.buf.lim = self.buf.cap;
    }

    #[inline]
    pub fn write_slice(&mut self, src: &[u8]) -> usize {
        let cnt = src.len() as u32;
        let rem = self.buf.remaining_u32();

        if rem < cnt {
            self.write_ptr(src.as_ptr(), rem)
        } else {
            self.write_ptr(src.as_ptr(), cnt)
        }
    }

    #[inline]
    fn write_ptr(&mut self, src: *const u8, len: u32) -> usize {
        unsafe {
            ptr::copy_nonoverlapping_memory(
                self.buf.mem.ptr().offset(self.buf.pos as isize),
                src, len as usize);

            self.buf.pos += len;
            len as usize
        }
    }
}

impl MutBuf for MutByteBuf {
    fn remaining(&self) -> usize {
        self.buf.remaining()
    }

    fn advance(&mut self, cnt: usize) {
        self.buf.advance(cnt)
    }

    fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
        let pos = self.buf.pos();
        let lim = self.buf.lim();
        &mut self.buf.mem.bytes_mut()[pos..lim]
    }
}
<|endoftext|>


<commit_before>extern crate winapi;
extern crate kernel32;

use self::super::Size;

/// Gets the current terminal size
pub fn get() -> Option<Size> {
    //http://rosettacode.org/wiki/Terminal_control/Dimensions#Windows
    use self::winapi::{DWORD, HANDLE};
    use self::kernel32::{GetStdHandle, GetConsoleScreenBufferInfo};
    use self::winapi::{
        CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
        STD_INPUT_HANDLE, STD_OUTPUT_HANDLE
    };
    let stdout: HANDLE = unsafe {
        GetStdHandle(STD_OUTPUT_HANDLE)
    };
    let zc = COORD { X: 0, Y: 0 };
    let mut info = CONSOLE_SCREEN_BUFFER_INFO {
        dwSize: zc.clone(),
        dwCursorPosition: zc.clone(),
        wAttributes: 0,
        srWindow: SMALL_RECT { Left:0, Top: 0, Right: 0, Bottom: 0 },
        dwMaximumWindowSize: zc
    };
    let success: bool = unsafe {
        GetConsoleScreenBufferInfo(stdout, &mut info) != 0
    };
    if success {
        Some(
            Size {
                rows: (info.srWindow.Bottom - info.srWindow.Top + 1) as u16,
                cols: (info.srWindow.Right - info.srWindow.Left + 1) as u16
            }
        )
    } else {
        None
    }
}
<commit_msg>remove unused imports<commit_after>extern crate winapi;
extern crate kernel32;

use self::super::Size;

/// Gets the current terminal size
pub fn get() -> Option<Size> {
    //http://rosettacode.org/wiki/Terminal_control/Dimensions#Windows
    use self::winapi::HANDLE;
    use self::kernel32::{GetStdHandle, GetConsoleScreenBufferInfo};
    use self::winapi::{
        CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
        STD_OUTPUT_HANDLE
    };
    let stdout: HANDLE = unsafe {
        GetStdHandle(STD_OUTPUT_HANDLE)
    };
    let zc = COORD { X: 0, Y: 0 };
    let mut info = CONSOLE_SCREEN_BUFFER_INFO {
        dwSize: zc.clone(),
        dwCursorPosition: zc.clone(),
        wAttributes: 0,
        srWindow: SMALL_RECT { Left:0, Top: 0, Right: 0, Bottom: 0 },
        dwMaximumWindowSize: zc
    };
    let success: bool = unsafe {
        GetConsoleScreenBufferInfo(stdout, &mut info) != 0
    };
    if success {
        Some(
            Size {
                rows: (info.srWindow.Bottom - info.srWindow.Top + 1) as u16,
                cols: (info.srWindow.Right - info.srWindow.Left + 1) as u16
            }
        )
    } else {
        None
    }
}
<|endoftext|>


<commit_before>#![feature(convert)]
use std::io;
use std::fmt;
use std::error;
use std::vec::Vec;
use byteorder;
use byteorder::{BigEndian,ReadBytesExt,WriteBytesExt};

#[derive(Debug)]
pub enum Error {
	Io(byteorder::Error),
	InvalidValue,
	InvalidType
}

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

impl From<Error> for byteorder::Error {
	fn from(err: Error) -> byteorder::Error {
		match err {
			Error::Io(err) => err,
			Error::InvalidValue => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid value")),
			Error::InvalidType => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid type")),
		}
	}
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
	        match *self {
				Error::InvalidValue => write!(f, "Invalid value."),
				Error::InvalidType => write!(f, "Invalid type."),
				Error::Io(ref err) => err.fmt(f),
			}
	}
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::InvalidValue => "Invalid value.",
            Error::InvalidType => "Invalid type.",
            Error::Io(ref err) => error::Error::description(err),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::InvalidValue => None,
            Error::InvalidType => None,
            Error::Io(ref err) => err.cause(),
        }
    }
}

pub struct XdrReader<'a> {
	reader : io::Cursor<&'a [u8]>
}

pub struct XdrWriter {
	writer : io::Cursor<Vec<u8>>
}

impl XdrWriter {
	pub fn new() -> XdrWriter {
		let v : Vec<u8>= Vec::new();
		XdrWriter{ writer: io::Cursor::new(v)}
	}

	pub fn get_buffer(self) -> Vec<u8> {
		self.writer.into_inner()
	}

	pub fn pack<T:XdrPrimitive>(&mut self, x:T) {
		XdrPrimitive::write_to_xdr(self, x)
	}

}
impl<'a> XdrReader<'a> {
	pub fn new(x:&'a Vec<u8>) -> XdrReader<'a> {
		XdrReader{ reader : io::Cursor::new(x.as_slice()) }
	}

	pub fn from_array(x: &'a [u8]) -> XdrReader<'a> {
		XdrReader{ reader: io::Cursor::new(x) }
	}

	pub fn unpack<T: XdrPrimitive>(&mut self) -> Result<T,Error> {
		T::read_from_xdr(self)
	}
}

pub trait XdrPrimitive {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>;
	fn write_to_xdr(x: &mut XdrWriter, v: Self);
}

impl<T:XdrPrimitive> XdrPrimitive for Vec<T> {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>{
		let count = x.unpack::<u32>().unwrap() as usize;
		let mut result : Vec<T> = Vec::with_capacity(count);

		for _ in 0..count {
			result.push(x.unpack::<T>().unwrap());
		};
		Ok(result)
	}
	fn write_to_xdr(x: &mut XdrWriter, v: Self) {
		x.pack( v.len() as u32 );
		for t in v {
			x.pack(t);
		};
	}
}

impl XdrPrimitive for u32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u32, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for u16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u16, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u16),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v as u32).unwrap();
	}
}
impl XdrPrimitive for u8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u8, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u8),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v as u32).unwrap();
	}
}
impl XdrPrimitive for i8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i8, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i8),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v as i32).unwrap();
	}
}
impl XdrPrimitive for i16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i16, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i16),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v as i32).unwrap();
	}
}
impl XdrPrimitive for i32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i32, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for i64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i64, Error>{
		match x.reader.read_i64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i64::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for u64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u64, Error>{
		match x.reader.read_u64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u64::<byteorder::BigEndian>(v).unwrap();
	}

}

impl XdrPrimitive for f32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f32, Error>{
		match x.reader.read_f32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_f32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for f64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f64, Error>{
		match x.reader.read_f64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_f64::<byteorder::BigEndian>(v).unwrap();
	}
}

impl XdrPrimitive for bool {
	fn read_from_xdr(x: &mut XdrReader) -> Result<bool, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(0) => Ok(false),
			Ok(1) => Ok(true),
			Ok(_) => Err(Error::InvalidValue),
			Err(v) => Err(Error::Io(v))
		}
	}

	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		match v {
			true => x.writer.write_u32::<byteorder::BigEndian>(1).unwrap(),
			false => x.writer.write_u32::<byteorder::BigEndian>(0).unwrap(),
		}
	}
}
<commit_msg>remove feature(convert) from non-root scope<commit_after>use std::io;
use std::fmt;
use std::error;
use std::vec::Vec;
use byteorder;
use byteorder::{BigEndian,ReadBytesExt,WriteBytesExt};

#[derive(Debug)]
pub enum Error {
	Io(byteorder::Error),
	InvalidValue,
	InvalidType
}

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

impl From<Error> for byteorder::Error {
	fn from(err: Error) -> byteorder::Error {
		match err {
			Error::Io(err) => err,
			Error::InvalidValue => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid value")),
			Error::InvalidType => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid type")),
		}
	}
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
	        match *self {
				Error::InvalidValue => write!(f, "Invalid value."),
				Error::InvalidType => write!(f, "Invalid type."),
				Error::Io(ref err) => err.fmt(f),
			}
	}
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::InvalidValue => "Invalid value.",
            Error::InvalidType => "Invalid type.",
            Error::Io(ref err) => error::Error::description(err),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::InvalidValue => None,
            Error::InvalidType => None,
            Error::Io(ref err) => err.cause(),
        }
    }
}

pub struct XdrReader<'a> {
	reader : io::Cursor<&'a [u8]>
}

pub struct XdrWriter {
	writer : io::Cursor<Vec<u8>>
}

impl XdrWriter {
	pub fn new() -> XdrWriter {
		let v : Vec<u8>= Vec::new();
		XdrWriter{ writer: io::Cursor::new(v)}
	}

	pub fn get_buffer(self) -> Vec<u8> {
		self.writer.into_inner()
	}

	pub fn pack<T:XdrPrimitive>(&mut self, x:T) {
		XdrPrimitive::write_to_xdr(self, x)
	}

}
impl<'a> XdrReader<'a> {
	pub fn new(x:&'a Vec<u8>) -> XdrReader<'a> {
		XdrReader{ reader : io::Cursor::new(x.as_slice()) }
	}

	pub fn from_array(x: &'a [u8]) -> XdrReader<'a> {
		XdrReader{ reader: io::Cursor::new(x) }
	}

	pub fn unpack<T: XdrPrimitive>(&mut self) -> Result<T,Error> {
		T::read_from_xdr(self)
	}
}

pub trait XdrPrimitive {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>;
	fn write_to_xdr(x: &mut XdrWriter, v: Self);
}

impl<T:XdrPrimitive> XdrPrimitive for Vec<T> {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>{
		let count = x.unpack::<u32>().unwrap() as usize;
		let mut result : Vec<T> = Vec::with_capacity(count);

		for _ in 0..count {
			result.push(x.unpack::<T>().unwrap());
		};
		Ok(result)
	}
	fn write_to_xdr(x: &mut XdrWriter, v: Self) {
		x.pack( v.len() as u32 );
		for t in v {
			x.pack(t);
		};
	}
}

impl XdrPrimitive for u32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u32, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for u16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u16, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u16),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v as u32).unwrap();
	}
}
impl XdrPrimitive for u8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u8, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u8),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v as u32).unwrap();
	}
}
impl XdrPrimitive for i8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i8, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i8),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v as i32).unwrap();
	}
}
impl XdrPrimitive for i16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i16, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i16),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v as i32).unwrap();
	}
}
impl XdrPrimitive for i32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i32, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for i64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i64, Error>{
		match x.reader.read_i64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i64::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for u64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u64, Error>{
		match x.reader.read_u64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u64::<byteorder::BigEndian>(v).unwrap();
	}

}

impl XdrPrimitive for f32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f32, Error>{
		match x.reader.read_f32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_f32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for f64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f64, Error>{
		match x.reader.read_f64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}

	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_f64::<byteorder::BigEndian>(v).unwrap();
	}
}

impl XdrPrimitive for bool {
	fn read_from_xdr(x: &mut XdrReader) -> Result<bool, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(0) => Ok(false),
			Ok(1) => Ok(true),
			Ok(_) => Err(Error::InvalidValue),
			Err(v) => Err(Error::Io(v))
		}
	}

	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		match v {
			true => x.writer.write_u32::<byteorder::BigEndian>(1).unwrap(),
			false => x.writer.write_u32::<byteorder::BigEndian>(0).unwrap(),
		}
	}
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

extern crate libc;

use self::libc::execvp;
use std::{env, thread};
use std::ptr::null;
use std::ffi::CString;
use std::process::Command;
use std::io::prelude::*;
use std::path::Path;
use std::fs::OpenOptions;
use config::Config;
use layout::LayoutMsg;
use xlib_window_system::XlibWindowSystem;
use workspaces::{Workspaces, MoveOp};
use xlib::Window;
use failure::*;

pub enum Cmd {
    Exec(String),
    SwitchWorkspace(usize),
    SwitchScreen(usize),
    MoveToWorkspace(usize),
    MoveToScreen(usize),
    SendLayoutMsg(LayoutMsg),
    Reload,
    Exit,
    KillClient,
    FocusUp,
    FocusDown,
    FocusMaster,
    SwapUp,
    SwapDown,
    SwapMaster,
}

impl Cmd {
    pub fn call(&self, ws: &XlibWindowSystem, workspaces: &mut Workspaces, config: &Config) -> Result<(), Error> {
        match *self {
            Cmd::Exec(ref cmd) => {
                debug!("Cmd::Exec: {}", cmd);
                exec(cmd.clone());
            }
            Cmd::SwitchWorkspace(index) => {
                debug!("Cmd::SwitchWorkspace: {}", index);
                workspaces.switch_to(ws, config, index - 1, true);
            }
            Cmd::SwitchScreen(screen) => {
                debug!("Cmd::SwitchScreen: {}", screen);
                workspaces.switch_to_screen(ws, config, screen - 1);
            }
            Cmd::MoveToWorkspace(index) => {
                debug!("Cmd::MoveToWorkspace: {}", index);
                workspaces.move_window_to(ws, config, index - 1);
            }
            Cmd::MoveToScreen(screen) => {
                debug!("Cmd::MoveToScreen: {}", screen);
                workspaces.move_window_to_screen(ws, config, screen - 1);
            }
            Cmd::SendLayoutMsg(ref msg) => {
                debug!("Cmd::SendLayoutMsg::{:?}", msg);
                workspaces.current_mut().send_layout_message(msg.clone());
                workspaces.current().redraw(ws, config);
            }
            Cmd::Reload => {
                debug!("Cmd::Reload");
                reload(workspaces)
                    .context("failed to reload xr3wm")?;
            }
            Cmd::Exit => {
                debug!("Cmd::Exit");
                ws.close();
            }
            Cmd::KillClient => {
                debug!("Cmd::KillClient: {}",
                       workspaces.current_mut().focused_window());
                ws.kill_window(workspaces.current_mut().focused_window());
            }
            Cmd::FocusUp => {
                debug!("Cmd::FocusUp: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_focus(ws, config, MoveOp::Up);
            }
            Cmd::FocusDown => {
                debug!("Cmd::FocusDown: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_focus(ws, config, MoveOp::Down);
            }
            Cmd::FocusMaster => {
                debug!("Cmd::FocusMaster: {}",
                workspaces.current().focused_window());
                workspaces.current_mut().move_focus(ws, config, MoveOp::Swap);
            }
            Cmd::SwapUp => {
                debug!("Cmd::SwapUp: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_window(ws, config, MoveOp::Up);
            }
            Cmd::SwapDown => {
                debug!("Cmd::SwapDown: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_window(ws, config, MoveOp::Down);
            }
            Cmd::SwapMaster => {
                debug!("Cmd::SwapMaster: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_window(ws, config, MoveOp::Swap);
            }
        }
        Ok(())
    }
}

fn reload(workspaces: &mut Workspaces) -> Result<(), Error> {
    info!("recompiling...");

    let config_build_dir = concat!(env!("HOME"), "/.xr3wm/.build");
    let mut cmd = Command::new("cargo");

    let output = cmd.current_dir(&config_build_dir)
        .arg("build")
        .env("RUST_LOG", "none")
        .output()
        .context("failed to run cargo")?;

    if !output.status.success() {
        let stderr_msg = String::from_utf8(output.stderr)
            .context("failed to convert cargo stderr to UTF-8")?;
        bail!(format_err!("failed to recompile: {}", stderr_msg))
    }

    debug!("Cmd::Reload: restarting xr3wm...");

    let path = Path::new(concat!(env!("HOME"), "/.xr3wm/.tmp"));

    // save current workspace state to load on restart
    let mut file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(&path)
        .context("failed to open workspace state tmp file")?;
    file.write_all(workspaces.serialize().as_bytes())
        .context("failed to save workspace state")?;
    file.flush()
        .context("failed to flush workspace tmp file")?;

    let mut args: Vec<*const libc::c_char> = env::args()
        .filter_map(|x| CString::new(x).ok())
        .map(|x| x.into_raw() as *const libc::c_char)
        .collect();
    args.push(null());

    unsafe {
        execvp(args[0] as *const libc::c_char, args.as_ptr());
    }

    Ok(())
}

pub struct ManageHook {
    pub class_name: String,
    pub cmd: CmdManage,
}

pub enum CmdManage {
    Move(usize),
    Float,
    Fullscreen,
    Ignore,
}

impl CmdManage {
    pub fn call(&self,
                ws: &XlibWindowSystem,
                workspaces: &mut Workspaces,
                config: &Config,
                window: Window) {
        match *self {
            CmdManage::Move(index) => {
                if let Some(parent) = ws.transient_for(window) {
                    if let Some(workspace) = workspaces.find_window(parent) {
                        workspace.add_window(ws, config, window);
                        workspace.focus_window(ws, config, window);
                    }
                } else {
                    debug!("CmdManage::Move: {}, {}", window, index);
                    workspaces.get_mut(index - 1).add_window(ws, config, window);
                    workspaces.get_mut(index - 1).focus_window(ws, config, window);
                }
            }
            CmdManage::Float => {
                debug!("CmdManage::Float");
                unimplemented!()
            }
            CmdManage::Fullscreen => {
                debug!("CmdManage::Fullscreen");
                unimplemented!()
            }
            CmdManage::Ignore => {
                debug!("CmdManage::Ignore");
                unimplemented!()
            }
        }
    }
}

fn exec(cmd: String) {
    thread::spawn(move || {
        let args: Vec<&str> = cmd[..].split(' ').collect();

        if !args.is_empty() {
            let mut cmd = Command::new(args[0]);

            if args.len() > 1 {
                cmd.args(&args[1..]);
            }

            match cmd.output() {
                Ok(_) => (),
                _ => panic!("failed to start \"{:?}\"", cmd),
            }
        }
    });
}
<commit_msg>Add error message on reload failure<commit_after>#![allow(dead_code)]

extern crate libc;

use self::libc::execvp;
use std::{env, thread};
use std::ptr::null;
use std::ffi::CString;
use std::process::Command;
use std::io::prelude::*;
use std::path::Path;
use std::fs::OpenOptions;
use config::Config;
use layout::LayoutMsg;
use xlib_window_system::XlibWindowSystem;
use workspaces::{Workspaces, MoveOp};
use xlib::Window;
use failure::*;

pub enum Cmd {
    Exec(String),
    SwitchWorkspace(usize),
    SwitchScreen(usize),
    MoveToWorkspace(usize),
    MoveToScreen(usize),
    SendLayoutMsg(LayoutMsg),
    Reload,
    Exit,
    KillClient,
    FocusUp,
    FocusDown,
    FocusMaster,
    SwapUp,
    SwapDown,
    SwapMaster,
}

impl Cmd {
    pub fn call(&self, ws: &XlibWindowSystem, workspaces: &mut Workspaces, config: &Config) -> Result<(), Error> {
        match *self {
            Cmd::Exec(ref cmd) => {
                debug!("Cmd::Exec: {}", cmd);
                exec(cmd.clone());
            }
            Cmd::SwitchWorkspace(index) => {
                debug!("Cmd::SwitchWorkspace: {}", index);
                workspaces.switch_to(ws, config, index - 1, true);
            }
            Cmd::SwitchScreen(screen) => {
                debug!("Cmd::SwitchScreen: {}", screen);
                workspaces.switch_to_screen(ws, config, screen - 1);
            }
            Cmd::MoveToWorkspace(index) => {
                debug!("Cmd::MoveToWorkspace: {}", index);
                workspaces.move_window_to(ws, config, index - 1);
            }
            Cmd::MoveToScreen(screen) => {
                debug!("Cmd::MoveToScreen: {}", screen);
                workspaces.move_window_to_screen(ws, config, screen - 1);
            }
            Cmd::SendLayoutMsg(ref msg) => {
                debug!("Cmd::SendLayoutMsg::{:?}", msg);
                workspaces.current_mut().send_layout_message(msg.clone());
                workspaces.current().redraw(ws, config);
            }
            Cmd::Reload => {
                debug!("Cmd::Reload");
                reload(workspaces)
                    .context("failed to reload xr3wm")?;
            }
            Cmd::Exit => {
                debug!("Cmd::Exit");
                ws.close();
            }
            Cmd::KillClient => {
                debug!("Cmd::KillClient: {}",
                       workspaces.current_mut().focused_window());
                ws.kill_window(workspaces.current_mut().focused_window());
            }
            Cmd::FocusUp => {
                debug!("Cmd::FocusUp: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_focus(ws, config, MoveOp::Up);
            }
            Cmd::FocusDown => {
                debug!("Cmd::FocusDown: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_focus(ws, config, MoveOp::Down);
            }
            Cmd::FocusMaster => {
                debug!("Cmd::FocusMaster: {}",
                workspaces.current().focused_window());
                workspaces.current_mut().move_focus(ws, config, MoveOp::Swap);
            }
            Cmd::SwapUp => {
                debug!("Cmd::SwapUp: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_window(ws, config, MoveOp::Up);
            }
            Cmd::SwapDown => {
                debug!("Cmd::SwapDown: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_window(ws, config, MoveOp::Down);
            }
            Cmd::SwapMaster => {
                debug!("Cmd::SwapMaster: {}", workspaces.current().focused_window());
                workspaces.current_mut().move_window(ws, config, MoveOp::Swap);
            }
        }
        Ok(())
    }
}

fn reload(workspaces: &mut Workspaces) -> Result<(), Error> {
    info!("recompiling...");

    let config_build_dir = concat!(env!("HOME"), "/.xr3wm/.build");
    let mut cmd = Command::new("cargo");

    let output = cmd.current_dir(&config_build_dir)
        .arg("build")
        .env("RUST_LOG", "none")
        .output()
        .context("failed to run cargo")?;

    if !output.status.success() {
        let stderr_msg = String::from_utf8(output.stderr)
            .context("failed to convert cargo stderr to UTF-8")?;
        bail!(format_err!("failed to recompile: {}", stderr_msg))
    }

    debug!("Cmd::Reload: restarting xr3wm...");

    let path = Path::new(concat!(env!("HOME"), "/.xr3wm/.tmp"));

    // save current workspace state to load on restart
    let mut file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(&path)
        .context("failed to open workspace state tmp file")?;
    file.write_all(workspaces.serialize().as_bytes())
        .context("failed to save workspace state")?;
    file.flush()
        .context("failed to flush workspace tmp file")?;

    let mut args: Vec<*const libc::c_char> = env::args()
        .filter_map(|x| CString::new(x).ok())
        .map(|x| x.into_raw() as *const libc::c_char)
        .collect();
    args.push(null());

    unsafe {
        execvp(args[0] as *const libc::c_char, args.as_ptr());
        // execvp returns only if an error has occurred
        error!("failed to reload: {}", ::std::io::Error::last_os_error());
    }

    Ok(())
}

pub struct ManageHook {
    pub class_name: String,
    pub cmd: CmdManage,
}

pub enum CmdManage {
    Move(usize),
    Float,
    Fullscreen,
    Ignore,
}

impl CmdManage {
    pub fn call(&self,
                ws: &XlibWindowSystem,
                workspaces: &mut Workspaces,
                config: &Config,
                window: Window) {
        match *self {
            CmdManage::Move(index) => {
                if let Some(parent) = ws.transient_for(window) {
                    if let Some(workspace) = workspaces.find_window(parent) {
                        workspace.add_window(ws, config, window);
                        workspace.focus_window(ws, config, window);
                    }
                } else {
                    debug!("CmdManage::Move: {}, {}", window, index);
                    workspaces.get_mut(index - 1).add_window(ws, config, window);
                    workspaces.get_mut(index - 1).focus_window(ws, config, window);
                }
            }
            CmdManage::Float => {
                debug!("CmdManage::Float");
                unimplemented!()
            }
            CmdManage::Fullscreen => {
                debug!("CmdManage::Fullscreen");
                unimplemented!()
            }
            CmdManage::Ignore => {
                debug!("CmdManage::Ignore");
                unimplemented!()
            }
        }
    }
}

fn exec(cmd: String) {
    thread::spawn(move || {
        let args: Vec<&str> = cmd[..].split(' ').collect();

        if !args.is_empty() {
            let mut cmd = Command::new(args[0]);

            if args.len() > 1 {
                cmd.args(&args[1..]);
            }

            match cmd.output() {
                Ok(_) => (),
                _ => panic!("failed to start \"{:?}\"", cmd),
            }
        }
    });
}
<|endoftext|>