<commit_before>// Copyright 2012-2015 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.

//! Crate docs

#![allow(bad_style, raw_pointer_derive, improper_ctypes)]
#![cfg_attr(dox, feature(no_core, lang_items))]
#![cfg_attr(dox, no_core)]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico")]

#![cfg_attr(all(target_os = "linux", target_arch = "x86_64"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "x86"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "arm"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/arm-unknown-linux-gnueabihf"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "mips"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/mips-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "aarch64"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/aarch64-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_env = "musl"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-unknown-linux-musl"
))]
#![cfg_attr(all(target_os = "macos", target_arch = "x86_64"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-apple-darwin"
))]
#![cfg_attr(all(target_os = "macos", target_arch = "x86"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-apple-darwin"
))]
#![cfg_attr(all(windows, target_arch = "x86_64", target_env = "gnu"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-pc-windows-gnu"
))]
#![cfg_attr(all(windows, target_arch = "x86", target_env = "gnu"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-pc-windows-gnu"
))]
#![cfg_attr(all(windows, target_arch = "x86_64", target_env = "msvc"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-pc-windows-msvc"
))]
#![cfg_attr(all(windows, target_arch = "x86", target_env = "msvc"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-pc-windows-msvc"
))]
#![cfg_attr(all(target_os = "android"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/arm-linux-androideabi"
))]

#[macro_use] mod macros;
mod dox;

#[repr(u8)]
pub enum c_void {
    // Two dummy variants so the #[repr] attribute can be used
    #[doc(hidden)]
    __variant1,
    #[doc(hidden)]
    __variant2,
}

pub type int8_t = i8;
pub type int16_t = i16;
pub type int32_t = i32;
pub type int64_t = i64;
pub type uint8_t = u8;
pub type uint16_t = u16;
pub type uint32_t = u32;
pub type uint64_t = u64;

pub type c_schar = i8;
pub type c_uchar = u8;
pub type c_short = i16;
pub type c_ushort = u16;
pub type c_int = i32;
pub type c_uint = u32;
pub type c_float = f32;
pub type c_double = f64;
pub type c_longlong = i64;
pub type c_ulonglong = u64;
pub type intmax_t = i64;
pub type uintmax_t = u64;

pub type size_t = usize;
pub type ptrdiff_t = isize;
pub type intptr_t = isize;
pub type uintptr_t = usize;
pub type ssize_t = isize;

pub enum FILE {}
pub enum fpos_t {}
pub enum DIR {}
pub enum dirent {}

extern {
    pub fn isalnum(c: c_int) -> c_int;
    pub fn isalpha(c: c_int) -> c_int;
    pub fn iscntrl(c: c_int) -> c_int;
    pub fn isdigit(c: c_int) -> c_int;
    pub fn isgraph(c: c_int) -> c_int;
    pub fn islower(c: c_int) -> c_int;
    pub fn isprint(c: c_int) -> c_int;
    pub fn ispunct(c: c_int) -> c_int;
    pub fn isspace(c: c_int) -> c_int;
    pub fn isupper(c: c_int) -> c_int;
    pub fn isxdigit(c: c_int) -> c_int;
    pub fn tolower(c: c_int) -> c_int;
    pub fn toupper(c: c_int) -> c_int;

    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "fopen$UNIX2003")]
    pub fn fopen(filename: *const c_char,
                 mode: *const c_char) -> *mut FILE;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "freopen$UNIX2003")]
    pub fn freopen(filename: *const c_char, mode: *const c_char,
                   file: *mut FILE) -> *mut FILE;
    pub fn fflush(file: *mut FILE) -> c_int;
    pub fn fclose(file: *mut FILE) -> c_int;
    pub fn remove(filename: *const c_char) -> c_int;
    pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int;
    pub fn tmpfile() -> *mut FILE;
    pub fn setvbuf(stream: *mut FILE,
                   buffer: *mut c_char,
                   mode: c_int,
                   size: size_t) -> c_int;
    pub fn setbuf(stream: *mut FILE, buf: *mut c_char);
    pub fn fgetc(stream: *mut FILE) -> c_int;
    pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char;
    pub fn fputc(c: c_int, stream: *mut FILE) -> c_int;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "fputs$UNIX2003")]
    pub fn fputs(s: *const c_char, stream: *mut FILE)-> c_int;
    pub fn puts(s: *const c_char) -> c_int;
    pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int;
    pub fn fread(ptr: *mut c_void,
                 size: size_t,
                 nobj: size_t,
                 stream: *mut FILE)
                 -> size_t;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "fwrite$UNIX2003")]
    pub fn fwrite(ptr: *const c_void,
                  size: size_t,
                  nobj: size_t,
                  stream: *mut FILE)
                  -> size_t;
    pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int;
    pub fn ftell(stream: *mut FILE) -> c_long;
    pub fn rewind(stream: *mut FILE);
    pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int;
    pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int;
    pub fn feof(stream: *mut FILE) -> c_int;
    pub fn ferror(stream: *mut FILE) -> c_int;
    pub fn perror(s: *const c_char);
    pub fn atoi(s: *const c_char) -> c_int;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "strtod$UNIX2003")]
    pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double;
    pub fn strtol(s: *const c_char,
                  endp: *mut *mut c_char, base: c_int) -> c_long;
    pub fn strtoul(s: *const c_char, endp: *mut *mut c_char,
                   base: c_int) -> c_ulong;
    pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void;
    pub fn malloc(size: size_t) -> *mut c_void;
    pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
    pub fn free(p: *mut c_void);
    pub fn exit(status: c_int) -> !;
    pub fn _exit(status: c_int) -> !;
    pub fn atexit(cb: extern fn()) -> c_int;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "system$UNIX2003")]
    pub fn system(s: *const c_char) -> c_int;
    pub fn getenv(s: *const c_char) -> *mut c_char;

    pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char;
    pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t)
                   -> *mut c_char;
    pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char;
    pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char;
    pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int;
    pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int;
    pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int;
    pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char;
    pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char;
    pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t;
    pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t;
    pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char;
    pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char;
    pub fn strlen(cs: *const c_char) -> size_t;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "strerror$UNIX2003")]
    pub fn strerror(n: c_int) -> *mut c_char;
    pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char;
    pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t;
    pub fn wcslen(buf: *const wchar_t) -> size_t;

    pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int;
    pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void;
}

// These are all inline functions on android
#[cfg(not(target_os = "android"))]
extern {
    pub fn abs(i: c_int) -> c_int;
    pub fn atof(s: *const c_char) -> c_double;
    pub fn labs(i: c_long) -> c_long;
    pub fn rand() -> c_int;
    pub fn srand(seed: c_uint);
}

cfg_if! {
    if #[cfg(windows)] {
        mod windows;
        pub use windows::*;
    } else {
        mod unix;
        pub use unix::*;
    }
}
<commit_msg>Explain weirdness of c_void and android missing fns<commit_after>// Copyright 2012-2015 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.

//! Crate docs

#![allow(bad_style, raw_pointer_derive, improper_ctypes)]
#![cfg_attr(dox, feature(no_core, lang_items))]
#![cfg_attr(dox, no_core)]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico")]

#![cfg_attr(all(target_os = "linux", target_arch = "x86_64"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "x86"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "arm"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/arm-unknown-linux-gnueabihf"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "mips"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/mips-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_arch = "aarch64"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/aarch64-unknown-linux-gnu"
))]
#![cfg_attr(all(target_os = "linux", target_env = "musl"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-unknown-linux-musl"
))]
#![cfg_attr(all(target_os = "macos", target_arch = "x86_64"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-apple-darwin"
))]
#![cfg_attr(all(target_os = "macos", target_arch = "x86"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-apple-darwin"
))]
#![cfg_attr(all(windows, target_arch = "x86_64", target_env = "gnu"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-pc-windows-gnu"
))]
#![cfg_attr(all(windows, target_arch = "x86", target_env = "gnu"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-pc-windows-gnu"
))]
#![cfg_attr(all(windows, target_arch = "x86_64", target_env = "msvc"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/x86_64-pc-windows-msvc"
))]
#![cfg_attr(all(windows, target_arch = "x86", target_env = "msvc"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/i686-pc-windows-msvc"
))]
#![cfg_attr(all(target_os = "android"), doc(
    html_root_url = "https://doc.rust-lang.org/libc/arm-linux-androideabi"
))]

#[macro_use] mod macros;
mod dox;

// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
// more optimization opportunities around it recognizing things like
// malloc/free.
#[repr(u8)]
pub enum c_void {
    // Two dummy variants so the #[repr] attribute can be used.
    #[doc(hidden)]
    __variant1,
    #[doc(hidden)]
    __variant2,
}

pub type int8_t = i8;
pub type int16_t = i16;
pub type int32_t = i32;
pub type int64_t = i64;
pub type uint8_t = u8;
pub type uint16_t = u16;
pub type uint32_t = u32;
pub type uint64_t = u64;

pub type c_schar = i8;
pub type c_uchar = u8;
pub type c_short = i16;
pub type c_ushort = u16;
pub type c_int = i32;
pub type c_uint = u32;
pub type c_float = f32;
pub type c_double = f64;
pub type c_longlong = i64;
pub type c_ulonglong = u64;
pub type intmax_t = i64;
pub type uintmax_t = u64;

pub type size_t = usize;
pub type ptrdiff_t = isize;
pub type intptr_t = isize;
pub type uintptr_t = usize;
pub type ssize_t = isize;

pub enum FILE {}
pub enum fpos_t {}
pub enum DIR {}
pub enum dirent {}

extern {
    pub fn isalnum(c: c_int) -> c_int;
    pub fn isalpha(c: c_int) -> c_int;
    pub fn iscntrl(c: c_int) -> c_int;
    pub fn isdigit(c: c_int) -> c_int;
    pub fn isgraph(c: c_int) -> c_int;
    pub fn islower(c: c_int) -> c_int;
    pub fn isprint(c: c_int) -> c_int;
    pub fn ispunct(c: c_int) -> c_int;
    pub fn isspace(c: c_int) -> c_int;
    pub fn isupper(c: c_int) -> c_int;
    pub fn isxdigit(c: c_int) -> c_int;
    pub fn tolower(c: c_int) -> c_int;
    pub fn toupper(c: c_int) -> c_int;

    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "fopen$UNIX2003")]
    pub fn fopen(filename: *const c_char,
                 mode: *const c_char) -> *mut FILE;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "freopen$UNIX2003")]
    pub fn freopen(filename: *const c_char, mode: *const c_char,
                   file: *mut FILE) -> *mut FILE;
    pub fn fflush(file: *mut FILE) -> c_int;
    pub fn fclose(file: *mut FILE) -> c_int;
    pub fn remove(filename: *const c_char) -> c_int;
    pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int;
    pub fn tmpfile() -> *mut FILE;
    pub fn setvbuf(stream: *mut FILE,
                   buffer: *mut c_char,
                   mode: c_int,
                   size: size_t) -> c_int;
    pub fn setbuf(stream: *mut FILE, buf: *mut c_char);
    pub fn fgetc(stream: *mut FILE) -> c_int;
    pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char;
    pub fn fputc(c: c_int, stream: *mut FILE) -> c_int;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "fputs$UNIX2003")]
    pub fn fputs(s: *const c_char, stream: *mut FILE)-> c_int;
    pub fn puts(s: *const c_char) -> c_int;
    pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int;
    pub fn fread(ptr: *mut c_void,
                 size: size_t,
                 nobj: size_t,
                 stream: *mut FILE)
                 -> size_t;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "fwrite$UNIX2003")]
    pub fn fwrite(ptr: *const c_void,
                  size: size_t,
                  nobj: size_t,
                  stream: *mut FILE)
                  -> size_t;
    pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int;
    pub fn ftell(stream: *mut FILE) -> c_long;
    pub fn rewind(stream: *mut FILE);
    pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int;
    pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int;
    pub fn feof(stream: *mut FILE) -> c_int;
    pub fn ferror(stream: *mut FILE) -> c_int;
    pub fn perror(s: *const c_char);
    pub fn atoi(s: *const c_char) -> c_int;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "strtod$UNIX2003")]
    pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double;
    pub fn strtol(s: *const c_char,
                  endp: *mut *mut c_char, base: c_int) -> c_long;
    pub fn strtoul(s: *const c_char, endp: *mut *mut c_char,
                   base: c_int) -> c_ulong;
    pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void;
    pub fn malloc(size: size_t) -> *mut c_void;
    pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
    pub fn free(p: *mut c_void);
    pub fn exit(status: c_int) -> !;
    pub fn _exit(status: c_int) -> !;
    pub fn atexit(cb: extern fn()) -> c_int;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "system$UNIX2003")]
    pub fn system(s: *const c_char) -> c_int;
    pub fn getenv(s: *const c_char) -> *mut c_char;

    pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char;
    pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t)
                   -> *mut c_char;
    pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char;
    pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char;
    pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int;
    pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int;
    pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int;
    pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char;
    pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char;
    pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t;
    pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t;
    pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char;
    pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char;
    pub fn strlen(cs: *const c_char) -> size_t;
    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
               link_name = "strerror$UNIX2003")]
    pub fn strerror(n: c_int) -> *mut c_char;
    pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char;
    pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t;
    pub fn wcslen(buf: *const wchar_t) -> size_t;

    pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int;
    pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void;
}

// These are all inline functions on android, so they end up just being entirely
// missing on that platform.
#[cfg(not(target_os = "android"))]
extern {
    pub fn abs(i: c_int) -> c_int;
    pub fn atof(s: *const c_char) -> c_double;
    pub fn labs(i: c_long) -> c_long;
    pub fn rand() -> c_int;
    pub fn srand(seed: c_uint);
}

cfg_if! {
    if #[cfg(windows)] {
        mod windows;
        pub use windows::*;
    } else {
        mod unix;
        pub use unix::*;
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[deny(missing_docs)]

extern crate gfx;
extern crate gfx_device_gl;
extern crate glfw;

use gfx::tex::Size;
use glfw::Context;

/// A wrapper around the window that implements `Output`.
pub struct Wrap<R: gfx::Resources> {
    /// Glutin window in the open.
    pub window: glfw::Window,
    frame: gfx::FrameBufferHandle<R>,
    mask: gfx::Mask,
    gamma: gfx::Gamma,
}

impl<R: gfx::Resources> gfx::Output<R> for Wrap<R> {
    fn get_handle(&self) -> Option<&gfx::FrameBufferHandle<R>> {
        Some(&self.frame)
    }

    fn get_size(&self) -> (Size, Size) {
        let (w, h) = self.window.get_framebuffer_size();
        (w as Size, h as Size)
    }

    fn get_mask(&self) -> gfx::Mask {
        self.mask
    }

    fn get_gamma(&self) -> gfx::Gamma {
        self.gamma
    }
}

impl<R: gfx::Resources> gfx::Window<R> for Wrap<R> {
    fn swap_buffers(&mut self) {
        self.window.swap_buffers();
    }
}

/// Result of successful context initialization.
pub type Success = (
    Wrap<gfx_device_gl::Resources>,
    gfx_device_gl::Device,
    gfx_device_gl::Factory,
);

/// Initialize with a window.
pub fn init(mut window: glfw::Window) -> Success {
    window.make_current();
    let (device, factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let wrap = Wrap {
        window: window,
        frame: factory.get_main_frame_buffer(),
        mask: gfx::COLOR | gfx::DEPTH | gfx::STENCIL, //TODO
        gamma: gfx::Gamma::Original, //TODO
    };
    (wrap, device, factory)
}
<commit_msg>Updated the handle names<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[deny(missing_docs)]

extern crate gfx;
extern crate gfx_device_gl;
extern crate glfw;

use gfx::tex::Size;
use glfw::Context;

/// A wrapper around the window that implements `Output`.
pub struct Wrap<R: gfx::Resources> {
    /// Glutin window in the open.
    pub window: glfw::Window,
    frame: gfx::handle::FrameBuffer<R>,
    mask: gfx::Mask,
    gamma: gfx::Gamma,
}

impl<R: gfx::Resources> gfx::Output<R> for Wrap<R> {
    fn get_handle(&self) -> Option<&gfx::handle::FrameBuffer<R>> {
        Some(&self.frame)
    }

    fn get_size(&self) -> (Size, Size) {
        let (w, h) = self.window.get_framebuffer_size();
        (w as Size, h as Size)
    }

    fn get_mask(&self) -> gfx::Mask {
        self.mask
    }

    fn get_gamma(&self) -> gfx::Gamma {
        self.gamma
    }
}

impl<R: gfx::Resources> gfx::Window<R> for Wrap<R> {
    fn swap_buffers(&mut self) {
        self.window.swap_buffers();
    }
}

/// Result of successful context initialization.
pub type Success = (
    Wrap<gfx_device_gl::Resources>,
    gfx_device_gl::Device,
    gfx_device_gl::Factory,
);

/// Initialize with a window.
pub fn init(mut window: glfw::Window) -> Success {
    window.make_current();
    let (device, factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let wrap = Wrap {
        window: window,
        frame: factory.get_main_frame_buffer(),
        mask: gfx::COLOR | gfx::DEPTH | gfx::STENCIL, //TODO
        gamma: gfx::Gamma::Original, //TODO
    };
    (wrap, device, factory)
}
<|endoftext|>


<commit_before><commit_msg>remove Display from PortMidiError<commit_after><|endoftext|>


<commit_before><commit_msg>Replaced piston-current with piston-quack<commit_after><|endoftext|>


<commit_before><commit_msg>Note about nightly<commit_after><|endoftext|>


<commit_before><commit_msg>Reading the compression from the bitmap header.<commit_after><|endoftext|>


<commit_before><commit_msg>Correctly initialize grip space<commit_after><|endoftext|>


<commit_before><commit_msg>Added RPN version of 24 game<commit_after>// Implements http://rosettacode.org/wiki/24_game
// Uses RPN expression
// Runs with rustc 0.12.0-pre-nightly (2e92c67dc 2014-08-28 23:56:20 +0000)

use std::io;
use std::rand::{task_rng, Rng};

#[cfg(not(test))]
fn main() {
    // generating 4 numbers
    let mut rng = task_rng();
    let choices: Vec<uint> = range(1u, 5).map(|_| rng.gen_range(1u, 10)).collect();
    println!("Make 24 with the following numbers");

    // start the game loop
    loop {
        print!("Your numbers: {}, {}, {}, {}\n", choices[0], choices[1], choices[2], choices[3]);
        let expr = io::stdin().read_line().ok().expect("Failed to read line!");
        if check_input(expr, &choices) { break; }
        print!("Try again? (y/n): ");
        let choice = io::stdin().read_line().ok().expect("Failed to read line!");
        if choice.as_slice().trim() != "y" { break; }
    }
}

fn check_input(expr: String, choices: &Vec<uint>) -> bool {
    let mut stack: Vec<uint> = Vec::new();
    for token in expr.as_slice().words() {
        if is_operator(token) {
            let (a, b) = (stack.pop(), stack.pop());
            match (a, b) {
                (Some(x), Some(y)) => stack.push(evaluate(y, x, token)),
                (_, _) => {
                    println!("Not a valid RPN expression!");
                    return false ;
                }
            }
        } else {
            let v: Option<uint> = from_str(token);
            match v {
                Some(n) => {
                    if !is_valid_number(n, choices) {
                        println!("Cannot use {}", n);
                        return false;
                    }
                    stack.push(n)
                },
                None => {
                    println!("Invalid input: {}", token);
                    return false;
                }
            }
        }
    }

    let ans = stack.pop();
    if stack.len() > 0 {
        println!("Not a valid RPN expression!");
        return false;
    }
    match ans {
        Some(x) => {
            if x == 24 {
                println!("Good job!");
                return true;
            }
            println!("Wrong answer. Result: {}", x);
        }
        None => println!("Error encountered!"),
    }
    false
}

// since evaluate is wrapped in is_operator the last
// pattern has to be "/"
fn evaluate(a: uint, b: uint, op: &str) -> uint {
    match op {
        "+" => a + b,
        "-" => a - b,
        "*" => a * b,
         _  => a / b, // has to be /
    }
}

fn is_operator(op: &str) -> bool {
    match op {
        "*" | "-" | "+" | "/" => true,
        _                     => false
    }
}

fn is_valid_number(n: uint, choices: &Vec<uint>) -> bool {
    for i in choices.iter() {
        if n == *i { return true }
    }
    false
}

#[test]
fn test_check_input() {
    let v1: Vec<uint> = vec![4, 3, 6, 2];

    // correct result
    let result1 = check_input("4 3 * 6 2 * +".to_string(), &v1);
    assert!(result1);

    // incorrect result
    let result2 = check_input("4 3 + 2 6 + -".to_string(), &v1);
    assert!(!result2);

    // wrong numbers in input
    let result3 = check_input("4 5 + 6 2 * -".to_string(), &v1);
    assert!(!result3);

    // invalid chars in input
    let result4 = check_input("4 ) + _ 2 * -".to_string(), &v1);
    assert!(!result4);

    // invalid RPN expression
    let result5 = check_input("4 3 + 6 2 *".to_string(), &v1);
    assert!(!result5);
}
<|endoftext|>


<commit_before><commit_msg>chotto dake<commit_after><|endoftext|>


<commit_before><commit_msg>Read all header from a Fits file<commit_after>extern crate nom;
extern crate fits_rs;

use std::env;
use std::fs::File;
use std::io::Read;
use std::str::FromStr;
use nom::IResult;
use fits_rs::parser::fits;
use fits_rs::types::Header;

fn main() {
    let args: Vec<String> = env::args().collect();
    let filename = &args[1];
    let header_index = u64::from_str(&args[2]).expect("second argument should be a non-negative number");

    let mut f = File::open(filename).expect("file not found");
    let mut buffer: Vec<u8> = vec!();
    let _ = f.read_to_end(&mut buffer);

    let result = fits(&buffer);

    match result {
        IResult::Done(_, trappist1) => {
            let header: &Header = if header_index == 0 {
                &trappist1.primary_hdu.header
            } else {
                &trappist1.extensions[0].header
            };

            for ref record in &header.keyword_records {
                println!("{}", record);
            }
        },
        _ => panic!("Whoops, something went wrong")
    }
}
<|endoftext|>


<commit_before>use std::env::*;
use std::env;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::ascii::AsciiExt;
use hyper::Client;
use hyper::header::Connection;
// use hyper::client::response::Response;

extern crate rustc_serialize;
use self::rustc_serialize::json::*;

extern crate chrono;
use self::chrono::*;

#[derive(Clone, Debug)]
pub struct AWSCredentials {
    key: String,
    secret: String,
    token: String,
    expires_at: DateTime<UTC>
}

impl AWSCredentials {
    pub fn new(key:&str, secret:&str, token:&str, expires_at:DateTime<UTC>) -> AWSCredentials {
        AWSCredentials {
            key: key.to_string(),
            secret: secret.to_string(),
            token: token.to_string(),
            expires_at: expires_at,
        }
    }

    pub fn get_aws_access_key_id(&self) -> &str {
    	&self.key
    }

    pub fn get_aws_secret_key(&self) -> &str {
    	&self.secret
    }

    pub fn get_expires_at(&self) -> &DateTime<UTC> {
        &self.expires_at
    }

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

    fn credentials_are_expired(&self) -> bool {
        println!("Seeing if creds of {:?} are expired compared to {:?}", self.expires_at, UTC::now() + Duration::seconds(20));
        // This is a rough hack to hopefully avoid someone requesting creds then sitting on them
        // before issuing the request:
        if self.expires_at < UTC::now() + Duration::seconds(20) {
            return true;
        }
        return false;
    }
}

// TODO: refactor get_credentials to return std::result
pub trait AWSCredentialsProvider {
    fn new() -> Self;
	fn get_credentials(&mut self) -> &AWSCredentials;
	fn refresh(&mut self);
}

pub struct EnvironmentCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for EnvironmentCredentialsProvider {
    fn new() -> EnvironmentCredentialsProvider {
        return EnvironmentCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        let env_key = match var("AWS_ACCESS_KEY_ID") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };
        let env_secret = match var("AWS_SECRET_ACCESS_KEY") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };

        self.credentials = AWSCredentials{key: env_key, secret: env_secret,
             token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600)};
	}

	fn get_credentials(&mut self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct FileCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for FileCredentialsProvider {
    fn new() -> FileCredentialsProvider {
        return FileCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // Default credentials file location:
        // ~/.aws/credentials (Linux/Mac)
        // %USERPROFILE%\.aws\credentials  (Windows)
        let mut profile_location = String::new();
        match env::home_dir() {
            Some(ref p) => profile_location = p.display().to_string() + "/.aws/credentials",
            None => {
                println!("Couldn't get your home dir.");
                self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(),
                     token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };
                return;
            }
        }
        let credentials = get_credentials_from_file(profile_location);
        self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
            secret: credentials.get_aws_secret_key().to_string(), token: "".to_string(),
            expires_at: UTC::now() + Duration::seconds(600) };
    }

    fn get_credentials(&mut self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// Finds and uses the first "aws_access_key_id" and "aws_secret_access_key" in the file.
fn get_credentials_from_file(file_with_path: String) -> AWSCredentials {
    println!("Looking for credentials file at {}", file_with_path);
    let path = Path::new(&file_with_path);
    let display = path.display();

    let mut found_file = false;

    match fs::metadata(&path) {
        Err(why) => println!("Couldn't get metadata for file: {}", why),
        Ok(metadata) => found_file = metadata.is_file()
    };

    // bail early.  Should be converted to a return type.
    if !found_file {
        return AWSCredentials{ key: "".to_string(), secret: "".to_string(),
             token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };
    }

    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(opened_file) => opened_file,
    };

    let mut access_key = String::new();
    let mut secret_key = String::new();
    let file_lines = BufReader::new(&file);
    for line in file_lines.lines() {
        let unwrapped_line : String = line.unwrap();
        // Skip line if it starts with a comment ('#')
        if unwrapped_line.starts_with('#') {
            continue;
        }

        let lower_case_line = unwrapped_line.to_ascii_lowercase().to_string();

        if lower_case_line.contains("aws_access_key_id") {
            if access_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    access_key = "".to_string();
                } else {
                    access_key = v[1].trim_matches(' ').to_string();
                }
            }
        } else if lower_case_line.contains("aws_secret_access_key") {
            if secret_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    secret_key = "".to_string();
                } else {
                    secret_key = v[1].trim_matches(' ').to_string();
                }
            }
        }
    }

    return AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string(),
         token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };
}

// class for IAM role
pub struct IAMRoleCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for IAMRoleCredentialsProvider {
    fn new() -> IAMRoleCredentialsProvider {
        return IAMRoleCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
        secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // call instance metadata to get iam role
        // for "real" use: http://169.254.169.254/latest/meta-data/iam/security-credentials/
        let mut address : String = "http://169.254.169.254/latest/meta-data/iam/security-credentials".to_string();
        let client = Client::new();
        let mut response;
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(why) => {
                    println!("boo, request failed: {}", why);
                    return;
                }
                Ok(received_response) => response = received_response
            };

        let mut body = String::new();
        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading response: {}", why),
            Ok(_) => (),
        };

        // use results to make another call:
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/fooprofile

        // sample results:
        // {
        //   "Code" : "Success",
        //   "LastUpdated" : "2015-08-04T00:09:23Z",
        //   "Type" : "AWS-HMAC",
        //   "AccessKeyId" : "AAAAAA",
        //   "SecretAccessKey" : "AAAAA",
        //   "Token" : "AAAAA",
        //   "Expiration" : "2015-08-04T06:32:37Z"
        // }
        //  let format = "%Y-%m-%d %T.%f";

        address.push_str("/");
        address.push_str(&body);
        body = String::new();
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(_) => return,
                Ok(received_response) => response = received_response
            };

        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading iam role response: {}", why),
            Ok(_) => (),
        };

        let json_object : Json;
        match Json::from_str(&body) {
            Err(why) => {
                println!("Error: {}", why);
                return;
            }
            Ok(val) => json_object = val
        };

        let mut access_key = String::new();
        match json_object.find("AccessKeyId") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => access_key = val.to_string().replace("\"", "")
        };

        let mut secret_key = String::new();
        match json_object.find("SecretAccessKey") {
            None => {
                println!("Error finding SecretAccessKey");
                return;
            }
            Some(val) => secret_key = val.to_string().replace("\"", "")
        };

        let mut expiration = String::new();
        match json_object.find("Expiration") {
            None => {
                println!("Error finding Expiration");
                return;
            }
            Some(val) => expiration = val.to_string().replace("\"", "")
        };

        let mut expiration_time;
        match expiration.parse::<DateTime<UTC>>() {
            Err(why) => panic!("Kabloey on parse: {}", why),
            Ok(val) => expiration_time = val
        };

        let mut token_from_response = String::new();
        match json_object.find("Token") {
            None => {
                println!("Error finding Token");
                return;
            }
            Some(val) => token_from_response = val.to_string().replace("\"", "")
        };

        self.credentials = AWSCredentials{ key: access_key.to_string(),
            secret: secret_key.to_string(),  token: token_from_response.to_string(), expires_at: expiration_time };
    }

    // This seems a bit convoluted: try to reused expired instead of making a new var.
    fn get_credentials(&mut self) -> &AWSCredentials {
        let expired = &self.credentials.credentials_are_expired();
        if *expired {
            println!("Creds are expired, refreshing.");
            &self.refresh();
            let new_expired = &self.credentials.credentials_are_expired();
            if *new_expired {
                panic!("Credentials were expired and couldn't fetch fresh ones.");
            }
        }
		return &self.credentials;
	}
}

pub struct DefaultAWSCredentialsProviderChain {
    credentials: AWSCredentials
}

// Chain the providers:
impl DefaultAWSCredentialsProviderChain {
    pub fn new() -> DefaultAWSCredentialsProviderChain {
        return DefaultAWSCredentialsProviderChain {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

    pub fn get_credentials(&mut self) -> &AWSCredentials {
        return &self.credentials;
    }

    // This is getting a bit out of control with nested if/else: should try doing something else for flow control.
    pub fn refresh(&mut self) {
        // fetch creds in order: env, file, IAM
        self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(),
            token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };

        let mut env_provider = EnvironmentCredentialsProvider::new();
        env_provider.refresh();
        let credentials = env_provider.get_credentials();

        if creds_have_values(credentials) {
            println!("using creds from env: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
            self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                secret: credentials.get_aws_secret_key().to_string(), token: "".to_string(),
                expires_at: UTC::now() + Duration::seconds(600) };
            return;
        } else {
            // try the file provider
            let mut file_provider = FileCredentialsProvider::new();
            file_provider.refresh();
            let credentials = file_provider.get_credentials();
            println!("using creds from file: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());

            if creds_have_values(credentials) {
                self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                    secret: credentials.get_aws_secret_key().to_string(), token: "".to_string(),
                    expires_at: UTC::now() + Duration::seconds(600) };
            } else {
                let mut iam_provider = IAMRoleCredentialsProvider::new();
                iam_provider.refresh();
                let credentials = iam_provider.get_credentials();
                if creds_have_values(credentials) {
                    println!("using creds from IAM: {}, {}, {}", credentials.get_aws_access_key_id(),
                        credentials.get_aws_secret_key(), credentials.get_token());
                    self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                        secret: credentials.get_aws_secret_key().to_string(), token: credentials.get_token().to_string(),
                        expires_at: UTC::now() + Duration::seconds(600) };
                    return;
                } else {
                    // We're out of options
                    panic!("Couldn't find AWS credentials in environment, default credential file location or IAM role.");
                }
            }
        }
    }
}

fn creds_have_values(creds: &AWSCredentials) -> bool {
    if creds.get_aws_access_key_id().len() > 0 && creds.get_aws_secret_key().len() > 0 {
        return true;
    }
    return false;
}
<commit_msg>Minor cleanup of comments in credentials.<commit_after>use std::env::*;
use std::env;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::ascii::AsciiExt;
use hyper::Client;
use hyper::header::Connection;
// use hyper::client::response::Response;

extern crate rustc_serialize;
use self::rustc_serialize::json::*;

extern crate chrono;
use self::chrono::*;

#[derive(Clone, Debug)]
pub struct AWSCredentials {
    key: String,
    secret: String,
    token: String,
    expires_at: DateTime<UTC>
}

impl AWSCredentials {
    pub fn new(key:&str, secret:&str, token:&str, expires_at:DateTime<UTC>) -> AWSCredentials {
        AWSCredentials {
            key: key.to_string(),
            secret: secret.to_string(),
            token: token.to_string(),
            expires_at: expires_at,
        }
    }

    pub fn get_aws_access_key_id(&self) -> &str {
    	&self.key
    }

    pub fn get_aws_secret_key(&self) -> &str {
    	&self.secret
    }

    pub fn get_expires_at(&self) -> &DateTime<UTC> {
        &self.expires_at
    }

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

    fn credentials_are_expired(&self) -> bool {
        println!("Seeing if creds of {:?} are expired compared to {:?}", self.expires_at, UTC::now() + Duration::seconds(20));
        // This is a rough hack to hopefully avoid someone requesting creds then sitting on them
        // before issuing the request:
        if self.expires_at < UTC::now() + Duration::seconds(20) {
            return true;
        }
        return false;
    }
}

// TODO: refactor get_credentials to return std::result
pub trait AWSCredentialsProvider {
    fn new() -> Self;
	fn get_credentials(&mut self) -> &AWSCredentials;
	fn refresh(&mut self);
}

pub struct EnvironmentCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for EnvironmentCredentialsProvider {
    fn new() -> EnvironmentCredentialsProvider {
        return EnvironmentCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        let env_key = match var("AWS_ACCESS_KEY_ID") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };
        let env_secret = match var("AWS_SECRET_ACCESS_KEY") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };

        self.credentials = AWSCredentials{key: env_key, secret: env_secret,
             token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600)};
	}

	fn get_credentials(&mut self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct FileCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for FileCredentialsProvider {
    fn new() -> FileCredentialsProvider {
        return FileCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // Default credentials file location:
        // ~/.aws/credentials (Linux/Mac)
        // %USERPROFILE%\.aws\credentials  (Windows)
        let mut profile_location = String::new();
        match env::home_dir() {
            Some(ref p) => profile_location = p.display().to_string() + "/.aws/credentials",
            None => {
                println!("Couldn't get your home dir.");
                self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(),
                     token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };
                return;
            }
        }
        let credentials = get_credentials_from_file(profile_location);
        self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
            secret: credentials.get_aws_secret_key().to_string(), token: "".to_string(),
            expires_at: UTC::now() + Duration::seconds(600) };
    }

    fn get_credentials(&mut self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// Finds and uses the first "aws_access_key_id" and "aws_secret_access_key" in the file.
fn get_credentials_from_file(file_with_path: String) -> AWSCredentials {
    println!("Looking for credentials file at {}", file_with_path);
    let path = Path::new(&file_with_path);
    let display = path.display();

    let mut found_file = false;

    match fs::metadata(&path) {
        Err(why) => println!("Couldn't get metadata for file: {}", why),
        Ok(metadata) => found_file = metadata.is_file()
    };

    // bail early.  Should be converted to a return type.
    if !found_file {
        return AWSCredentials{ key: "".to_string(), secret: "".to_string(),
             token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };
    }

    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(opened_file) => opened_file,
    };

    let mut access_key = String::new();
    let mut secret_key = String::new();
    let file_lines = BufReader::new(&file);
    for line in file_lines.lines() {
        let unwrapped_line : String = line.unwrap();
        // Skip line if it starts with a comment ('#')
        if unwrapped_line.starts_with('#') {
            continue;
        }

        let lower_case_line = unwrapped_line.to_ascii_lowercase().to_string();

        if lower_case_line.contains("aws_access_key_id") {
            if access_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    access_key = "".to_string();
                } else {
                    access_key = v[1].trim_matches(' ').to_string();
                }
            }
        } else if lower_case_line.contains("aws_secret_access_key") {
            if secret_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    secret_key = "".to_string();
                } else {
                    secret_key = v[1].trim_matches(' ').to_string();
                }
            }
        }
    }

    return AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string(),
         token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };
}

// class for IAM role
pub struct IAMRoleCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for IAMRoleCredentialsProvider {
    fn new() -> IAMRoleCredentialsProvider {
        return IAMRoleCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
        secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // for "real" use: http://169.254.169.254/latest/meta-data/iam/security-credentials/
        let mut address : String = "http://169.254.169.254/latest/meta-data/iam/security-credentials".to_string();
        let client = Client::new();
        let mut response;
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(why) => {
                    println!("boo, request failed: {}", why);
                    return;
                }
                Ok(received_response) => response = received_response
            };

        let mut body = String::new();
        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading response: {}", why),
            Ok(_) => (),
        };

        address.push_str("/");
        address.push_str(&body);
        body = String::new();
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(_) => return,
                Ok(received_response) => response = received_response
            };

        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading iam role response: {}", why),
            Ok(_) => (),
        };

        let json_object : Json;
        match Json::from_str(&body) {
            Err(why) => {
                println!("Error: {}", why);
                return;
            }
            Ok(val) => json_object = val
        };

        let mut access_key = String::new();
        match json_object.find("AccessKeyId") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => access_key = val.to_string().replace("\"", "")
        };

        let mut secret_key = String::new();
        match json_object.find("SecretAccessKey") {
            None => {
                println!("Error finding SecretAccessKey");
                return;
            }
            Some(val) => secret_key = val.to_string().replace("\"", "")
        };

        let mut expiration = String::new();
        match json_object.find("Expiration") {
            None => {
                println!("Error finding Expiration");
                return;
            }
            Some(val) => expiration = val.to_string().replace("\"", "")
        };

        let mut expiration_time;
        match expiration.parse::<DateTime<UTC>>() {
            Err(why) => panic!("Kabloey on parse: {}", why),
            Ok(val) => expiration_time = val
        };

        let mut token_from_response = String::new();
        match json_object.find("Token") {
            None => {
                println!("Error finding Token");
                return;
            }
            Some(val) => token_from_response = val.to_string().replace("\"", "")
        };

        self.credentials = AWSCredentials{ key: access_key.to_string(),
            secret: secret_key.to_string(),  token: token_from_response.to_string(), expires_at: expiration_time };
    }

    // This seems a bit convoluted: try to reused expired instead of making a new var.
    fn get_credentials(&mut self) -> &AWSCredentials {
        let expired = &self.credentials.credentials_are_expired();
        if *expired {
            println!("Creds are expired, refreshing.");
            &self.refresh();
            let new_expired = &self.credentials.credentials_are_expired();
            if *new_expired {
                panic!("Credentials were expired and couldn't fetch fresh ones.");
            }
        }
		return &self.credentials;
	}
}

pub struct DefaultAWSCredentialsProviderChain {
    credentials: AWSCredentials
}

// Chain the providers:
impl DefaultAWSCredentialsProviderChain {
    pub fn new() -> DefaultAWSCredentialsProviderChain {
        return DefaultAWSCredentialsProviderChain {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

    pub fn get_credentials(&mut self) -> &AWSCredentials {
        return &self.credentials;
    }

    // This is getting a bit out of control with nested if/else: should try doing something else for flow control.
    pub fn refresh(&mut self) {
        // fetch creds in order: env, file, IAM
        self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(),
            token: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };

        let mut env_provider = EnvironmentCredentialsProvider::new();
        env_provider.refresh();
        let credentials = env_provider.get_credentials();

        if creds_have_values(credentials) {
            println!("using creds from env: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
            self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                secret: credentials.get_aws_secret_key().to_string(), token: "".to_string(),
                expires_at: UTC::now() + Duration::seconds(600) };
            return;
        } else {
            // try the file provider
            let mut file_provider = FileCredentialsProvider::new();
            file_provider.refresh();
            let credentials = file_provider.get_credentials();
            println!("using creds from file: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());

            if creds_have_values(credentials) {
                self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                    secret: credentials.get_aws_secret_key().to_string(), token: "".to_string(),
                    expires_at: UTC::now() + Duration::seconds(600) };
            } else {
                let mut iam_provider = IAMRoleCredentialsProvider::new();
                iam_provider.refresh();
                let credentials = iam_provider.get_credentials();
                if creds_have_values(credentials) {
                    println!("using creds from IAM: {}, {}, {}", credentials.get_aws_access_key_id(),
                        credentials.get_aws_secret_key(), credentials.get_token());
                    self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                        secret: credentials.get_aws_secret_key().to_string(), token: credentials.get_token().to_string(),
                        expires_at: UTC::now() + Duration::seconds(600) };
                    return;
                } else {
                    // We're out of options
                    panic!("Couldn't find AWS credentials in environment, default credential file location or IAM role.");
                }
            }
        }
    }
}

fn creds_have_values(creds: &AWSCredentials) -> bool {
    if creds.get_aws_access_key_id().len() > 0 && creds.get_aws_secret_key().len() > 0 {
        return true;
    }
    return false;
}
<|endoftext|>


<commit_before><commit_msg>Activity for 1.2.3<commit_after><|endoftext|>


<commit_before>use std::io;
use std::cmp;
use std::str;
use std::slice;
use std::io::IoResult;
use std::io::MemReader;

use colortype;
use hash::Crc32;
use zlib::ZlibDecoder;

use image;
use image::ImageResult;
use image::ImageDecoder;

use super::filter::unfilter;
use super::PNGSIGNATURE;

macro_rules! io_try(
    ($e:expr) => (
    	match $e {
    		Ok(e) => e,
    		Err(_) => return Err(image::IoError)
    	}
    )
)

#[deriving(PartialEq)]
enum PNGState {
	Start,
	HaveSignature,
	HaveIHDR,
	HavePLTE,
	HaveFirstIDat,
	HaveLastIDat,
	HaveIEND
}

/// The representation of a PNG decoder
///
/// Currently does not support decoding of interlaced images
pub struct PNGDecoder<R> {
	z: ZlibDecoder<IDATReader<R>>,
	crc: Crc32,
	previous: Vec<u8>,
	state: PNGState,

	width: u32,
	height: u32,

	bit_depth: u8,
	colour_type: u8,
	pixel_type: colortype::ColorType,

	palette: Option<Vec<(u8, u8, u8)>>,

	interlace_method: u8,

	chunk_length: u32,
	chunk_type: Vec<u8>,

	bpp: uint,
	rlength: uint,
	decoded_rows: u32,
}

impl<R: Reader> PNGDecoder<R> {
	/// Create a new decoder that decodes from the stream ```r```
	pub fn new(r: R) -> PNGDecoder<R> {
		let idat_reader = IDATReader::new(r);
		PNGDecoder {
			pixel_type: colortype::Grey(1),
			palette: None,

			previous: Vec::new(),
			state: Start,
			z: ZlibDecoder::new(idat_reader),
			crc: Crc32::new(),

			width: 0,
			height: 0,
			bit_depth: 0,
			colour_type: 0,
			interlace_method: 0,

			chunk_length: 0,
			chunk_type: Vec::new(),
			bpp: 0,
			rlength: 0,
			decoded_rows: 0,
		}
	}

	///Returns a reference to the color palette used for indexed
	///color images.
	///Each array element is a tuple of RGB values.
	pub fn palette<'a>(&'a self) -> &'a [(u8, u8, u8)] {
		match self.palette {
			Some(ref p) => p.as_slice(),
			None        => &[]
		}
	}

	fn read_signature(&mut self) -> ImageResult<bool> {
		let png = io_try!(self.z.inner().r.read_exact(8));

		Ok(png.as_slice() == PNGSIGNATURE)
	}

	fn parse_ihdr(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());
		let mut m = MemReader::new(buf);

		self.width = m.read_be_u32().unwrap();
		self.height = m.read_be_u32().unwrap();

		self.bit_depth = m.read_byte().unwrap();
		self.colour_type = m.read_byte().unwrap();

		self.pixel_type = match (self.colour_type, self.bit_depth) {
			(0, 1)  => colortype::Grey(1),
			(0, 2)  => colortype::Grey(2),
			(0, 4)  => colortype::Grey(4),
			(0, 8)  => colortype::Grey(8),
			(0, 16) => colortype::Grey(16),
			(2, 8)  => colortype::RGB(8),
			(2, 16) => colortype::RGB(16),
			(3, 1)  => colortype::RGB(8),
			(3, 2)  => colortype::RGB(8),
			(3, 4)  => colortype::RGB(8),
			(3, 8)  => colortype::RGB(8),
			(4, 8)  => colortype::GreyA(8),
			(4, 16) => colortype::GreyA(16),
			(6, 8)  => colortype::RGBA(8),
			(6, 16) => colortype::RGBA(16),
			(_, _)  => return Err(image::FormatError)
		};

		let compression_method = m.read_byte().unwrap();
		if compression_method != 0 {
			return Err(image::UnsupportedError)
		}

		let filter_method = m.read_byte().unwrap();
		if filter_method != 0 {
			return Err(image::UnsupportedError)
		}

		self.interlace_method = m.read_byte().unwrap();
		if self.interlace_method != 0 {
			return Err(image::UnsupportedError)
		}

		let channels = match self.colour_type {
			0 => 1,
			2 => 3,
			3 => 1,
			4 => 2,
			6 => 4,
			_ => return Err(image::FormatError)
		};

		let bits_per_pixel = channels * self.bit_depth as uint;

		self.rlength = (bits_per_pixel * self.width as uint + 7) / 8;
		self.bpp = (bits_per_pixel + 7) / 8;
		self.previous = Vec::from_elem(self.rlength as uint, 0u8);

		Ok(())
	}

	fn parse_plte(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());

		let len = buf.len() / 3;

		if len > 256 || len > (1 << self.bit_depth) || buf.len() % 3 != 0{
			return Err(image::FormatError)
		}

		let p = Vec::from_fn(256, |i| {
			if i < len {
				let r = buf.as_slice()[3 * i];
				let g = buf.as_slice()[3 * i + 1];
				let b = buf.as_slice()[3 * i + 2];

				(r, g, b)
			}
			else {
				(0, 0, 0)
			}
		});

		self.palette = Some(p);

		Ok(())
	}

	fn read_metadata(&mut self) -> ImageResult<()> {
		if !try!(self.read_signature()) {
			return Err(image::FormatError)
		}

		self.state = HaveSignature;

		loop {
			let length = io_try!(self.z.inner().r.read_be_u32());
			let chunk  = io_try!(self.z.inner().r.read_exact(4));

			self.chunk_length = length;
			self.chunk_type   = chunk.clone();

			self.crc.update(chunk);

			let s = {
				let a = str::from_utf8_owned(self.chunk_type.clone());
				a.unwrap()
			};

			match (s.as_slice(), self.state) {
				("IHDR", HaveSignature) => {
					if length != 13 {
						return Err(image::FormatError)
					}

					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_ihdr(d));

					self.state = HaveIHDR;
				}

				("PLTE", HaveIHDR) => {
					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_plte(d));
					self.state = HavePLTE;
				}

				("tRNS", HavePLTE) => {
					return Err(image::UnsupportedError)
				}

				("IDAT", HaveIHDR) if self.colour_type != 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				("IDAT", HavePLTE) if self.colour_type == 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				_ => {
					let b = io_try!(self.z.inner().r.read_exact(length as uint));
					self.crc.update(b);
				}
			}

			let chunk_crc = io_try!(self.z.inner().r.read_be_u32());
			let crc = self.crc.checksum();

			if crc != chunk_crc {
				return Err(image::FormatError)
			}

			self.crc.reset();
		}

		Ok(())
	}
}

impl<R: Reader> ImageDecoder for PNGDecoder<R> {
	fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok((self.width, self.height))
	}

	fn colortype(&mut self) -> ImageResult<colortype::ColorType> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok(self.pixel_type)
	}

	fn row_len(&mut self) -> ImageResult<uint> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let bits = colortype::bits_per_pixel(self.pixel_type);

		Ok((bits * self.width as uint + 7) / 8)
	}

	fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let filter_type = match FromPrimitive::from_u8(io_try!(self.z.read_byte())) {
			Some(v) => v,
			_ => return Err(image::FormatError)
		};

		let mut read = 0;
		while read < self.rlength {
			let r = io_try!(self.z.read(buf.mut_slice_from(read)));
			read += r;
		}

		unfilter(filter_type, self.bpp, self.previous.as_slice(), buf.mut_slice_to(self.rlength));
		slice::bytes::copy_memory(self.previous.as_mut_slice(), buf.slice_to(self.rlength));

		if self.palette.is_some() {
			let s = (*self.palette.get_ref()).as_slice();
			expand_palette(buf, s, self.rlength);
		}

		self.decoded_rows += 1;

		Ok(self.decoded_rows)
	}

	fn read_image(&mut self) -> ImageResult<Vec<u8>> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let rowlen  = try!(self.row_len());
		let mut buf = Vec::from_elem(rowlen * self.height as uint, 0u8);

		for chunk in buf.as_mut_slice().mut_chunks(rowlen) {
			let _ = try!(self.read_scanline(chunk));
		}

		Ok(buf)
	}
}

fn expand_palette(buf: &mut[u8], palette: &[(u8, u8, u8)], entries: uint) {
	assert!(buf.len() == entries * 3);
	let tmp = Vec::from_fn(entries, |i| buf[i]);

	for (chunk, &i) in buf.mut_chunks(3).zip(tmp.iter()) {
		let (r, g, b) = palette[i as uint];
		chunk[0] = r;
		chunk[1] = g;
		chunk[2] = b;
	}
}

pub struct IDATReader<R> {
	pub r: R,
	pub crc: Crc32,

	eof: bool,
	chunk_length: u32,
}

impl<R:Reader> IDATReader<R> {
	pub fn new(r: R) -> IDATReader<R> {
		IDATReader {
			r: r,
			crc: Crc32::new(),
			eof: false,
			chunk_length: 0,
		}
	}

	pub fn set_inital_length(&mut self, len: u32) {
		self.chunk_length = len;
	}
}

impl<R: Reader> Reader for IDATReader<R> {
	fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
		if self.eof {
			return Err(io::standard_error(io::EndOfFile))
		}

		let len = buf.len();
		let mut start = 0;

		while start < len {
			let m = cmp::min(len - start, self.chunk_length as uint);

			let slice = buf.mut_slice(start, start + m);
			let r = try!(self.r.read(slice));

			start += r;

			self.chunk_length -= r as u32;
			self.crc.update(slice.as_slice());

			if self.chunk_length == 0 {
				let chunk_crc = try!(self.r.read_be_u32());
				let crc = self.crc.checksum();
				if crc != chunk_crc {
					return Err(io::standard_error(io::InvalidInput))
				}

				self.crc.reset();

				self.chunk_length = try!(self.r.read_be_u32());

				let v = try!(self.r.read_exact(4));
				self.crc.update(v.as_slice());

				match str::from_utf8(v.as_slice()) {
					Some("IDAT") => (),
					_ 	     => {
						self.eof = true;
						break
					}
				}
			}
		}
		Ok(start)
	}
}<commit_msg>Prevent failure on strange chunk types<commit_after>use std::io;
use std::cmp;
use std::str;
use std::slice;
use std::io::IoResult;
use std::io::MemReader;

use colortype;
use hash::Crc32;
use zlib::ZlibDecoder;

use image;
use image::ImageResult;
use image::ImageDecoder;

use super::filter::unfilter;
use super::PNGSIGNATURE;

macro_rules! io_try(
    ($e:expr) => (
    	match $e {
    		Ok(e) => e,
    		Err(_) => return Err(image::IoError)
    	}
    )
)

#[deriving(PartialEq)]
enum PNGState {
	Start,
	HaveSignature,
	HaveIHDR,
	HavePLTE,
	HaveFirstIDat,
	HaveLastIDat,
	HaveIEND
}

/// The representation of a PNG decoder
///
/// Currently does not support decoding of interlaced images
pub struct PNGDecoder<R> {
	z: ZlibDecoder<IDATReader<R>>,
	crc: Crc32,
	previous: Vec<u8>,
	state: PNGState,

	width: u32,
	height: u32,

	bit_depth: u8,
	colour_type: u8,
	pixel_type: colortype::ColorType,

	palette: Option<Vec<(u8, u8, u8)>>,

	interlace_method: u8,

	chunk_length: u32,
	chunk_type: Vec<u8>,

	bpp: uint,
	rlength: uint,
	decoded_rows: u32,
}

impl<R: Reader> PNGDecoder<R> {
	/// Create a new decoder that decodes from the stream ```r```
	pub fn new(r: R) -> PNGDecoder<R> {
		let idat_reader = IDATReader::new(r);
		PNGDecoder {
			pixel_type: colortype::Grey(1),
			palette: None,

			previous: Vec::new(),
			state: Start,
			z: ZlibDecoder::new(idat_reader),
			crc: Crc32::new(),

			width: 0,
			height: 0,
			bit_depth: 0,
			colour_type: 0,
			interlace_method: 0,

			chunk_length: 0,
			chunk_type: Vec::new(),
			bpp: 0,
			rlength: 0,
			decoded_rows: 0,
		}
	}

	///Returns a reference to the color palette used for indexed
	///color images.
	///Each array element is a tuple of RGB values.
	pub fn palette<'a>(&'a self) -> &'a [(u8, u8, u8)] {
		match self.palette {
			Some(ref p) => p.as_slice(),
			None        => &[]
		}
	}

	fn read_signature(&mut self) -> ImageResult<bool> {
		let png = io_try!(self.z.inner().r.read_exact(8));

		Ok(png.as_slice() == PNGSIGNATURE)
	}

	fn parse_ihdr(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());
		let mut m = MemReader::new(buf);

		self.width = m.read_be_u32().unwrap();
		self.height = m.read_be_u32().unwrap();

		self.bit_depth = m.read_byte().unwrap();
		self.colour_type = m.read_byte().unwrap();

		self.pixel_type = match (self.colour_type, self.bit_depth) {
			(0, 1)  => colortype::Grey(1),
			(0, 2)  => colortype::Grey(2),
			(0, 4)  => colortype::Grey(4),
			(0, 8)  => colortype::Grey(8),
			(0, 16) => colortype::Grey(16),
			(2, 8)  => colortype::RGB(8),
			(2, 16) => colortype::RGB(16),
			(3, 1)  => colortype::RGB(8),
			(3, 2)  => colortype::RGB(8),
			(3, 4)  => colortype::RGB(8),
			(3, 8)  => colortype::RGB(8),
			(4, 8)  => colortype::GreyA(8),
			(4, 16) => colortype::GreyA(16),
			(6, 8)  => colortype::RGBA(8),
			(6, 16) => colortype::RGBA(16),
			(_, _)  => return Err(image::FormatError)
		};

		let compression_method = m.read_byte().unwrap();
		if compression_method != 0 {
			return Err(image::UnsupportedError)
		}

		let filter_method = m.read_byte().unwrap();
		if filter_method != 0 {
			return Err(image::UnsupportedError)
		}

		self.interlace_method = m.read_byte().unwrap();
		if self.interlace_method != 0 {
			return Err(image::UnsupportedError)
		}

		let channels = match self.colour_type {
			0 => 1,
			2 => 3,
			3 => 1,
			4 => 2,
			6 => 4,
			_ => return Err(image::FormatError)
		};

		let bits_per_pixel = channels * self.bit_depth as uint;

		self.rlength = (bits_per_pixel * self.width as uint + 7) / 8;
		self.bpp = (bits_per_pixel + 7) / 8;
		self.previous = Vec::from_elem(self.rlength as uint, 0u8);

		Ok(())
	}

	fn parse_plte(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());

		let len = buf.len() / 3;

		if len > 256 || len > (1 << self.bit_depth) || buf.len() % 3 != 0{
			return Err(image::FormatError)
		}

		let p = Vec::from_fn(256, |i| {
			if i < len {
				let r = buf.as_slice()[3 * i];
				let g = buf.as_slice()[3 * i + 1];
				let b = buf.as_slice()[3 * i + 2];

				(r, g, b)
			}
			else {
				(0, 0, 0)
			}
		});

		self.palette = Some(p);

		Ok(())
	}

	fn read_metadata(&mut self) -> ImageResult<()> {
		if !try!(self.read_signature()) {
			return Err(image::FormatError)
		}

		self.state = HaveSignature;

		loop {
			let length = io_try!(self.z.inner().r.read_be_u32());
			let chunk  = io_try!(self.z.inner().r.read_exact(4));

			self.chunk_length = length;
			self.chunk_type   = chunk.clone();

			self.crc.update(chunk);

			let s =  str::from_utf8_owned(self.chunk_type.clone())
				.unwrap_or(String::from_str(""));

			match (s.as_slice(), self.state) {
				("IHDR", HaveSignature) => {
					if length != 13 {
						return Err(image::FormatError)
					}

					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_ihdr(d));

					self.state = HaveIHDR;
				}

				("PLTE", HaveIHDR) => {
					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_plte(d));
					self.state = HavePLTE;
				}

				("tRNS", HavePLTE) => {
					return Err(image::UnsupportedError)
				}

				("IDAT", HaveIHDR) if self.colour_type != 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				("IDAT", HavePLTE) if self.colour_type == 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				_ => {
					let b = io_try!(self.z.inner().r.read_exact(length as uint));
					self.crc.update(b);
				}
			}

			let chunk_crc = io_try!(self.z.inner().r.read_be_u32());
			let crc = self.crc.checksum();

			if crc != chunk_crc {
				return Err(image::FormatError)
			}

			self.crc.reset();
		}

		Ok(())
	}
}

impl<R: Reader> ImageDecoder for PNGDecoder<R> {
	fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok((self.width, self.height))
	}

	fn colortype(&mut self) -> ImageResult<colortype::ColorType> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok(self.pixel_type)
	}

	fn row_len(&mut self) -> ImageResult<uint> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let bits = colortype::bits_per_pixel(self.pixel_type);

		Ok((bits * self.width as uint + 7) / 8)
	}

	fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let filter_type = match FromPrimitive::from_u8(io_try!(self.z.read_byte())) {
			Some(v) => v,
			_ => return Err(image::FormatError)
		};

		let mut read = 0;
		while read < self.rlength {
			let r = io_try!(self.z.read(buf.mut_slice_from(read)));
			read += r;
		}

		unfilter(filter_type, self.bpp, self.previous.as_slice(), buf.mut_slice_to(self.rlength));
		slice::bytes::copy_memory(self.previous.as_mut_slice(), buf.slice_to(self.rlength));

		if self.palette.is_some() {
			let s = (*self.palette.get_ref()).as_slice();
			expand_palette(buf, s, self.rlength);
		}

		self.decoded_rows += 1;

		Ok(self.decoded_rows)
	}

	fn read_image(&mut self) -> ImageResult<Vec<u8>> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let rowlen  = try!(self.row_len());
		let mut buf = Vec::from_elem(rowlen * self.height as uint, 0u8);

		for chunk in buf.as_mut_slice().mut_chunks(rowlen) {
			let _ = try!(self.read_scanline(chunk));
		}

		Ok(buf)
	}
}

fn expand_palette(buf: &mut[u8], palette: &[(u8, u8, u8)], entries: uint) {
	assert!(buf.len() == entries * 3);
	let tmp = Vec::from_fn(entries, |i| buf[i]);

	for (chunk, &i) in buf.mut_chunks(3).zip(tmp.iter()) {
		let (r, g, b) = palette[i as uint];
		chunk[0] = r;
		chunk[1] = g;
		chunk[2] = b;
	}
}

pub struct IDATReader<R> {
	pub r: R,
	pub crc: Crc32,

	eof: bool,
	chunk_length: u32,
}

impl<R:Reader> IDATReader<R> {
	pub fn new(r: R) -> IDATReader<R> {
		IDATReader {
			r: r,
			crc: Crc32::new(),
			eof: false,
			chunk_length: 0,
		}
	}

	pub fn set_inital_length(&mut self, len: u32) {
		self.chunk_length = len;
	}
}

impl<R: Reader> Reader for IDATReader<R> {
	fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
		if self.eof {
			return Err(io::standard_error(io::EndOfFile))
		}

		let len = buf.len();
		let mut start = 0;

		while start < len {
			let m = cmp::min(len - start, self.chunk_length as uint);

			let slice = buf.mut_slice(start, start + m);
			let r = try!(self.r.read(slice));

			start += r;

			self.chunk_length -= r as u32;
			self.crc.update(slice.as_slice());

			if self.chunk_length == 0 {
				let chunk_crc = try!(self.r.read_be_u32());
				let crc = self.crc.checksum();
				if crc != chunk_crc {
					return Err(io::standard_error(io::InvalidInput))
				}

				self.crc.reset();

				self.chunk_length = try!(self.r.read_be_u32());

				let v = try!(self.r.read_exact(4));
				self.crc.update(v.as_slice());

				match str::from_utf8(v.as_slice()) {
					Some("IDAT") => (),
					_ 	     => {
						self.eof = true;
						break
					}
				}
			}
		}
		Ok(start)
	}
}<|endoftext|>


<commit_before>// Copyright 2013-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.

//! Terminal formatting library.
//!
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
//! Termina][ansi] to provide color printing, among other things. There are two implementations,
//! the `TerminfoTerminal`, which uses control characters from a
//! [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
//! API][win].
//!
//! ## Example
//!
//! ```rust
//! extern crate term;
//!
//! fn main() {
//!     let mut t = term::stdout().unwrap();
//!     t.fg(term::color::GREEN).unwrap();
//!     println!("hello, ");
//!     t.fg(term::color::RED).unwrap();
//!     println!("world!");
//!     t.reset().unwrap();
//! }
//! ```
//!
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo

#![crate_id = "term#0.11.0-pre"]
#![comment = "Simple ANSI color library"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]

#![feature(macro_rules, phase)]

#![deny(missing_doc)]

#[phase(syntax, link)] extern crate log;
extern crate collections;

pub use terminfo::TerminfoTerminal;
#[cfg(windows)]
pub use win::WinConsole;

use std::io::IoResult;

pub mod terminfo;

#[cfg(windows)]
mod win;

#[cfg(not(windows))]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<Terminal<Box<Writer:Send>>:Send>> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stdout() as Box<Writer:Send>);
    ti.map(|t| box t as Box<Terminal<Box<Writer:Send>:Send>:Send>)
}

#[cfg(windows)]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<Terminal<Box<Writer:Send>:Send>:Send>> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stdout() as Box<Writer:Send>);

    match ti {
        Some(t) => Some(box t as Box<Terminal<Box<Writer:Send>:Send>:Send>),
        None => {
            let wc: Option<WinConsole<Box<Writer:Send>>>
                = Terminal::new(box std::io::stdout() as Box<Writer:Send>);
            wc.map(|w| box w as Box<Terminal<Box<Writer:Send>:Send>:Send>)
        }
    }
}

#[cfg(not(windows))]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<Terminal<Box<Writer:Send>:Send>:Send>:Send> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stderr() as Box<Writer:Send>);
    ti.map(|t| box t as Box<Terminal<Box<Writer:Send>:Send>:Send>)
}

#[cfg(windows)]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<Terminal<Box<Writer:Send>:Send>:Send>> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stderr() as Box<Writer:Send>);

    match ti {
        Some(t) => Some(box t as Box<Terminal<Box<Writer:Send>:Send>:Send>),
        None => {
            let wc: Option<WinConsole<Box<Writer:Send>>>
                = Terminal::new(box std::io::stderr() as Box<Writer:Send>);
            wc.map(|w| box w as Box<Terminal<Box<Writer:Send>:Send>:Send>)
        }
    }
}

/// Terminal color definitions
pub mod color {
    /// Number for a terminal color
    pub type Color = u16;

    pub static BLACK:   Color = 0u16;
    pub static RED:     Color = 1u16;
    pub static GREEN:   Color = 2u16;
    pub static YELLOW:  Color = 3u16;
    pub static BLUE:    Color = 4u16;
    pub static MAGENTA: Color = 5u16;
    pub static CYAN:    Color = 6u16;
    pub static WHITE:   Color = 7u16;

    pub static BRIGHT_BLACK:   Color = 8u16;
    pub static BRIGHT_RED:     Color = 9u16;
    pub static BRIGHT_GREEN:   Color = 10u16;
    pub static BRIGHT_YELLOW:  Color = 11u16;
    pub static BRIGHT_BLUE:    Color = 12u16;
    pub static BRIGHT_MAGENTA: Color = 13u16;
    pub static BRIGHT_CYAN:    Color = 14u16;
    pub static BRIGHT_WHITE:   Color = 15u16;
}

/// Terminal attributes
pub mod attr {
    /// Terminal attributes for use with term.attr().
    ///
    /// Most attributes can only be turned on and must be turned off with term.reset().
    /// The ones that can be turned off explicitly take a boolean value.
    /// Color is also represented as an attribute for convenience.
    pub enum Attr {
        /// Bold (or possibly bright) mode
        Bold,
        /// Dim mode, also called faint or half-bright. Often not supported
        Dim,
        /// Italics mode. Often not supported
        Italic(bool),
        /// Underline mode
        Underline(bool),
        /// Blink mode
        Blink,
        /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
        Standout(bool),
        /// Reverse mode, inverts the foreground and background colors
        Reverse,
        /// Secure mode, also called invis mode. Hides the printed text
        Secure,
        /// Convenience attribute to set the foreground color
        ForegroundColor(super::color::Color),
        /// Convenience attribute to set the background color
        BackgroundColor(super::color::Color)
    }
}

/// A terminal with similar capabilities to an ANSI Terminal
/// (foreground/background colors etc).
pub trait Terminal<T: Writer>: Writer {
    /// Returns `None` whenever the terminal cannot be created for some
    /// reason.
    fn new(out: T) -> Option<Self>;

    /// Sets the foreground color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn fg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the background color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn bg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the given terminal attribute, if supported.  Returns `Ok(true)`
    /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
    /// there was an I/O error.
    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool>;

    /// Returns whether the given terminal attribute is supported.
    fn supports_attr(&self, attr: attr::Attr) -> bool;

    /// Resets all terminal attributes and color to the default.
    /// Returns `Ok()`.
    fn reset(&mut self) -> IoResult<()>;

    /// Returns the contained stream, destroying the `Terminal`
    fn unwrap(self) -> T;

    /// Gets an immutable reference to the stream inside
    fn get_ref<'a>(&'a self) -> &'a T;

    /// Gets a mutable reference to the stream inside
    fn get_mut<'a>(&'a mut self) -> &'a mut T;
}
<commit_msg>term: Don't run the code example, just compile it<commit_after>// Copyright 2013-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.

//! Terminal formatting library.
//!
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
//! Termina][ansi] to provide color printing, among other things. There are two implementations,
//! the `TerminfoTerminal`, which uses control characters from a
//! [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
//! API][win].
//!
//! ## Example
//!
//! ```no_run
//! extern crate term;
//!
//! fn main() {
//!     let mut t = term::stdout().unwrap();
//!     t.fg(term::color::GREEN).unwrap();
//!     println!("hello, ");
//!     t.fg(term::color::RED).unwrap();
//!     println!("world!");
//!     t.reset().unwrap();
//! }
//! ```
//!
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo

#![crate_id = "term#0.11.0-pre"]
#![comment = "Simple ANSI color library"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]

#![feature(macro_rules, phase)]

#![deny(missing_doc)]

#[phase(syntax, link)] extern crate log;
extern crate collections;

pub use terminfo::TerminfoTerminal;
#[cfg(windows)]
pub use win::WinConsole;

use std::io::IoResult;

pub mod terminfo;

#[cfg(windows)]
mod win;

#[cfg(not(windows))]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<Terminal<Box<Writer:Send>>:Send>> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stdout() as Box<Writer:Send>);
    ti.map(|t| box t as Box<Terminal<Box<Writer:Send>:Send>:Send>)
}

#[cfg(windows)]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<Terminal<Box<Writer:Send>:Send>:Send>> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stdout() as Box<Writer:Send>);

    match ti {
        Some(t) => Some(box t as Box<Terminal<Box<Writer:Send>:Send>:Send>),
        None => {
            let wc: Option<WinConsole<Box<Writer:Send>>>
                = Terminal::new(box std::io::stdout() as Box<Writer:Send>);
            wc.map(|w| box w as Box<Terminal<Box<Writer:Send>:Send>:Send>)
        }
    }
}

#[cfg(not(windows))]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<Terminal<Box<Writer:Send>:Send>:Send>:Send> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stderr() as Box<Writer:Send>);
    ti.map(|t| box t as Box<Terminal<Box<Writer:Send>:Send>:Send>)
}

#[cfg(windows)]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<Terminal<Box<Writer:Send>:Send>:Send>> {
    let ti: Option<TerminfoTerminal<Box<Writer:Send>>>
        = Terminal::new(box std::io::stderr() as Box<Writer:Send>);

    match ti {
        Some(t) => Some(box t as Box<Terminal<Box<Writer:Send>:Send>:Send>),
        None => {
            let wc: Option<WinConsole<Box<Writer:Send>>>
                = Terminal::new(box std::io::stderr() as Box<Writer:Send>);
            wc.map(|w| box w as Box<Terminal<Box<Writer:Send>:Send>:Send>)
        }
    }
}

/// Terminal color definitions
pub mod color {
    /// Number for a terminal color
    pub type Color = u16;

    pub static BLACK:   Color = 0u16;
    pub static RED:     Color = 1u16;
    pub static GREEN:   Color = 2u16;
    pub static YELLOW:  Color = 3u16;
    pub static BLUE:    Color = 4u16;
    pub static MAGENTA: Color = 5u16;
    pub static CYAN:    Color = 6u16;
    pub static WHITE:   Color = 7u16;

    pub static BRIGHT_BLACK:   Color = 8u16;
    pub static BRIGHT_RED:     Color = 9u16;
    pub static BRIGHT_GREEN:   Color = 10u16;
    pub static BRIGHT_YELLOW:  Color = 11u16;
    pub static BRIGHT_BLUE:    Color = 12u16;
    pub static BRIGHT_MAGENTA: Color = 13u16;
    pub static BRIGHT_CYAN:    Color = 14u16;
    pub static BRIGHT_WHITE:   Color = 15u16;
}

/// Terminal attributes
pub mod attr {
    /// Terminal attributes for use with term.attr().
    ///
    /// Most attributes can only be turned on and must be turned off with term.reset().
    /// The ones that can be turned off explicitly take a boolean value.
    /// Color is also represented as an attribute for convenience.
    pub enum Attr {
        /// Bold (or possibly bright) mode
        Bold,
        /// Dim mode, also called faint or half-bright. Often not supported
        Dim,
        /// Italics mode. Often not supported
        Italic(bool),
        /// Underline mode
        Underline(bool),
        /// Blink mode
        Blink,
        /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
        Standout(bool),
        /// Reverse mode, inverts the foreground and background colors
        Reverse,
        /// Secure mode, also called invis mode. Hides the printed text
        Secure,
        /// Convenience attribute to set the foreground color
        ForegroundColor(super::color::Color),
        /// Convenience attribute to set the background color
        BackgroundColor(super::color::Color)
    }
}

/// A terminal with similar capabilities to an ANSI Terminal
/// (foreground/background colors etc).
pub trait Terminal<T: Writer>: Writer {
    /// Returns `None` whenever the terminal cannot be created for some
    /// reason.
    fn new(out: T) -> Option<Self>;

    /// Sets the foreground color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn fg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the background color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn bg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the given terminal attribute, if supported.  Returns `Ok(true)`
    /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
    /// there was an I/O error.
    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool>;

    /// Returns whether the given terminal attribute is supported.
    fn supports_attr(&self, attr: attr::Attr) -> bool;

    /// Resets all terminal attributes and color to the default.
    /// Returns `Ok()`.
    fn reset(&mut self) -> IoResult<()>;

    /// Returns the contained stream, destroying the `Terminal`
    fn unwrap(self) -> T;

    /// Gets an immutable reference to the stream inside
    fn get_ref<'a>(&'a self) -> &'a T;

    /// Gets a mutable reference to the stream inside
    fn get_mut<'a>(&'a mut self) -> &'a mut T;
}
<|endoftext|>


<commit_before><commit_msg>tweaks to parser<commit_after><|endoftext|>


<commit_before><commit_msg>Added a driver for comparing packing performance<commit_after>extern crate gemm_oxide;
extern crate core;
extern crate typenum;
extern crate hwloc;
extern crate libc;

use std::time::{Instant};
use std::ffi::{CString};
use self::libc::{c_double, int64_t, c_char};
use typenum::{U1};

//use gemm_oxide::kern::hsw::{Ukernel, KernelMN, KernelNM, GemvAL1};
use gemm_oxide::kern::snb;
pub use gemm_oxide::matrix::{Scalar, Mat, ColumnPanelMatrix, RowPanelMatrix, Matrix, Hierarch};
pub use gemm_oxide::composables::{GemmNode, AlgorithmStep, PartM, PartN, PartK, PackA, PackB, SpawnThreads, ParallelM, ParallelN, Nwayer};
pub use gemm_oxide::thread_comm::ThreadInfo;
pub use gemm_oxide::triple_loop::TripleLoop;

extern{
    fn dgemm_( transa: *const c_char, transb: *const c_char,
               m: *const int64_t, n: *const int64_t, k: *const int64_t,
               alpha: *const c_double,
               a: *const c_double, lda: *const int64_t,
               b: *const c_double, ldb: *const int64_t,
               beta: *const c_double,
               c: *mut c_double, ldc: *const int64_t );
}

fn blas_dgemm( a: &mut Matrix<f64>, b: &mut Matrix<f64>, c: &mut Matrix<f64> )
{
    unsafe{
        let transa = CString::new("N").unwrap();
        let transb = CString::new("N").unwrap();
        let ap = a.get_mut_buffer();
        let bp = b.get_buffer();
        let cp = c.get_buffer();

        let lda = a.get_column_stride() as int64_t;
        let ldb = b.get_column_stride() as int64_t;
        let ldc = c.get_column_stride() as int64_t;

        let m = c.height() as int64_t;
        let n = b.width() as int64_t;
        let k = a.width() as int64_t;

        let alpha: f64 = 1.0;
        let beta: f64 = 1.0;

        dgemm_( transa.as_ptr() as *const c_char, transb.as_ptr() as *const c_char,
                &m, &n, &k,
                &alpha as *const c_double,
                ap as *const c_double, &lda,
                bp as *const c_double, &ldb,
                &beta as *const c_double,
                cp as *mut c_double, &ldc );
    }
}

fn test_c_eq_a_b<T:Scalar, At:Mat<T>, Bt:Mat<T>, Ct:Mat<T>>( a: &mut At, b: &mut Bt, c: &mut Ct ) -> T {
    let mut ref_gemm : TripleLoop = TripleLoop{};

    let m = c.height();
    let n = b.width();
    let k = a.width();

    let mut w : Matrix<T> = Matrix::new(n, 1);
    let mut bw : Matrix<T> = Matrix::new(k, 1);
    let mut abw : Matrix<T> = Matrix::new(m, 1);
    let mut cw : Matrix<T> = Matrix::new(m, 1);
    w.fill_rand();
    cw.fill_zero();
    bw.fill_zero();
    abw.fill_zero();

    //Do bw = Bw, then abw = A*(Bw)
    unsafe {
        ref_gemm.run( b, &mut w, &mut bw, &ThreadInfo::single_thread() );
        ref_gemm.run( a, &mut bw, &mut abw, &ThreadInfo::single_thread() );
    }

    //Do cw = Cw
    unsafe {
        ref_gemm.run( c, &mut w, &mut cw, &ThreadInfo::single_thread() );
    }

    //Cw -= abw
    cw.axpy( T::zero() - T::one(), &abw );
    cw.frosqr()
}

fn dur_seconds(start: Instant) -> f64 {
    let dur = start.elapsed();
    let time_secs = dur.as_secs() as f64;
    let time_nanos = dur.subsec_nanos() as f64;
    time_nanos / 1E9 + time_secs
}

fn gflops(m: usize, n: usize, k: usize, seconds: f64) -> f64 {
    let nflops = (m * n * k) as f64;
    2.0 * nflops / seconds / 1E9
}

fn pin_to_core(core: usize) {
    use self::hwloc::{Topology, CPUBIND_THREAD, ObjectType};
    let mut topo = Topology::new();
    let tid = unsafe { libc::pthread_self() };

    let bind_to = {
        let cores = topo.objects_with_type(&ObjectType::Core).unwrap();
        match cores.get(core) {
            Some(val) => val.cpuset().unwrap(),
            None => panic!("No Core found with id {}", core)
        }
    };
    let _ = topo.set_cpubind_for_thread(tid, bind_to, CPUBIND_THREAD);
}

fn compare_packing() {
    type KC = typenum::U256;
    type MC = typenum::U96;
    type NR = typenum::U4;
    type MR = typenum::U8;
    type HierA<T> = Hierarch<T, MR, KC, U1, MR>;
    type HierB<T> = Hierarch<T, KC, NR, NR, U1>;
    type HierC<T> = Hierarch<T, MR, NR, NR, U1>;

    type GotoH<T:Scalar,MTA:Mat<T>,MTB:Mat<T>,MTC:Mat<T>>
        = PartK<T, MTA, MTB, MTC, KC,
          PackB<T, MTA, MTB, MTC, Hierarch<T, KC, NR, NR, U1>,
          PartM<T, MTA, Hierarch<T, KC, NR, NR, U1>, MTC, MC,
          PackA<T, MTA, Hierarch<T, KC, NR, NR, U1>, MTC, Hierarch<T, MR, KC, U1, MR>,
          PartN<T, Hierarch<T, MR, KC, U1, MR>, Hierarch<T, KC, NR, NR, U1>, MTC, NR,
          PartM<T, Hierarch<T, MR, KC, U1, MR>, Hierarch<T, KC, NR, NR, U1>, MTC, MR,
          snb::Ukernel<T, Hierarch<T, MR, KC, U1, MR>, Hierarch<T, KC, NR, NR, U1>, MTC>>>>>>>;

//          KernelNM<T, Hierarch<T, MR, KC, U1, MR>, Hierarch<T, KC, NR, NR, U1>, MTC, NR, MR>>>>>;

    type Goto<T:Scalar,MTA:Mat<T>,MTB:Mat<T>,MTC:Mat<T>>
        = PartK<T, MTA, MTB, MTC, KC,
          PackB<T, MTA, MTB, MTC, ColumnPanelMatrix<T,NR>,
          PartM<T, MTA, ColumnPanelMatrix<T,NR>, MTC, MC,
          PackA<T, MTA, ColumnPanelMatrix<T,NR>, MTC, RowPanelMatrix<T,MR>,
          PartN<T, RowPanelMatrix<T,MR>, ColumnPanelMatrix<T,NR>, MTC, NR,
          PartM<T, RowPanelMatrix<T,MR>, ColumnPanelMatrix<T,NR>, MTC, MR,
          snb::Ukernel<T, RowPanelMatrix<T,MR>, ColumnPanelMatrix<T,NR>, MTC>>>>>>>;

    type GotoOrig  = Goto<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
    type GotoHier  = GotoH<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>>;

    let mut goto  : GotoOrig = GotoOrig::new();
    let mut gotoh : GotoHier = GotoHier::new();
    //let algo_desc = GotoHier::hierarchy_description();

    pin_to_core(0);

    for index in 1..128 {
        let mut best_time: f64 = 9999999999.0;
        let mut best_time_2: f64 = 9999999999.0;
        let mut worst_err: f64 = 0.0;
        let mut worst_err_2: f64 = 0.0;
        let size = index*8;
        let (m, n, k) = (size, size, size);

        let n_reps = 5;
        for _ in 0..n_reps {
            let mut a : Matrix<f64> = Matrix::new(m, k);
            let mut b : Matrix<f64> = Matrix::new(k, n);
            let mut c : Matrix<f64> = Matrix::new(m, n);
            a.fill_rand(); b.fill_rand(); c.fill_zero();
            c.transpose();

            let mut start = Instant::now();
            unsafe{
                goto.run( &mut a, &mut b, &mut c, &ThreadInfo::single_thread() );
            }
            best_time = best_time.min(dur_seconds(start));
            let err = test_c_eq_a_b( &mut a, &mut b, &mut c);
            worst_err = worst_err.max(err);

            c.fill_zero();
            start = Instant::now();
            unsafe{
                gotoh.run( &mut a, &mut b, &mut c, &ThreadInfo::single_thread() );
            }
            best_time_2 = best_time_2.min(dur_seconds(start));
            let err = test_c_eq_a_b( &mut a, &mut b, &mut c);
            worst_err_2 = worst_err_2.max(err);
        }
        println!("{}\t{}\t{}\t{}\t{}\t{}\t{}",
                 m, n, k,
                 gflops(m,n,k,best_time),
                 gflops(m,n,k,best_time_2),
                 format!("{:e}", worst_err.sqrt()),
                 format!("{:e}", worst_err_2.sqrt()));

    }
}

fn main() {
    compare_packing();
}
<|endoftext|>