<commit_before><commit_msg>working on example<commit_after>extern crate azure_sdk_for_rust;

extern crate chrono;
extern crate env_logger;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate tokio_core;

use std::error::Error;

use futures::future::*;
use tokio_core::reactor::Core;

use azure_sdk_for_rust::{
    core::errors::AzureError, core::lease::{LeaseAction, LeaseState, LeaseStatus},
    storage::blob::{
        Blob, BlobType, LEASE_BLOB_OPTIONS_DEFAULT, LIST_BLOB_OPTIONS_DEFAULT,
        PUT_BLOCK_OPTIONS_DEFAULT,
    },
    storage::client::Client,
};

use azure_sdk_for_rust::storage::blob::{BlobBlockType, BlockList};

use std::fs::metadata;
use std::fs::File;
use std::path;

use hyper::mime::Mime;
use std::io::Read;

fn main() {
    env_logger::init();
    code().unwrap();
}

// We run a separate method to use the elegant quotation mark operator.
// A series of unwrap(), unwrap() would have achieved the same result.
fn code() -> Result<(), Box<Error>> {
    // First we retrieve the account name and master key from environment variables.
    let account =
        std::env::var("STORAGE_ACCOUNT").expect("Set env variable STORAGE_ACCOUNT first!");
    let master_key =
        std::env::var("STORAGE_MASTER_KEY").expect("Set env variable STORAGE_MASTER_KEY first!");

    let container_name = std::env::args()
        .nth(1)
        .expect("please specify container name as first command line parameter");

    let mut core = Core::new()?;

    let client = Client::new(&core.handle(), &account, &master_key)?;

    let name = "asdkrustputblock.txt";

    let contents1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    let contents2 = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
    let contents3 = "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";

    let new_blob = Blob {
        name: name.to_owned(),
        container_name: container_name.to_owned(),
        snapshot_time: None,
        last_modified: chrono::Utc::now(),
        etag: "".to_owned(),
        content_length: 0,
        // here we pass text/plain as content_type. This means your browser will
        // try to show you the file if you click on it in the Azure portal.
        // Make sure to send a text file :)
        content_type: Some("text/plain".parse::<Mime>().unwrap()),
        content_encoding: None,
        content_language: None,
        content_md5: None,
        cache_control: None,
        x_ms_blob_sequence_number: None,
        blob_type: BlobType::BlockBlob,
        lease_status: LeaseStatus::Unlocked,
        lease_state: LeaseState::Available,
        lease_duration: None,
        copy_id: None,
        copy_status: None,
        copy_source: None,
        copy_progress: None,
        copy_completion: None,
        copy_status_description: None,
    };

    let future = new_blob
        .put_block(
            &client,
            "block1",
            &PUT_BLOCK_OPTIONS_DEFAULT,
            &contents1.as_bytes(),
        )
        .map(|_| {
            println!("block1 blob for blob {} created", name);
        })
        .and_then(|_| {
            new_blob
                .put_block(
                    &client,
                    "block2",
                    &PUT_BLOCK_OPTIONS_DEFAULT,
                    &contents2.as_bytes(),
                )
                .map(|_| println!("block2 blob for blob {} created", name))
        })
        .and_then(|_| {
            new_blob
                .put_block(
                    &client,
                    "block3",
                    &PUT_BLOCK_OPTIONS_DEFAULT,
                    &contents3.as_bytes(),
                )
                .map(|_| println!("block3 blob for blob {} created", name))
        });

    core.run(future)?;

    // this will fail because we did not specify a valid leaseID.
    let future =
        Blob::delete(&client, &container_name, &name, None).map(|_| println!("Blob deleted!"));

    core.run(future)?;

    Ok(())
}
<|endoftext|>


<commit_before>use core::cmp::min;
use core::intrinsics;
use core::mem::size_of;
use core::ops::{Index, IndexMut};
use core::ptr;

use common::scheduler::*;

pub const PAGE_DIRECTORY: usize = 0x300000;
pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * 4;
pub const PAGE_SIZE: usize = 4 * 1024;

pub const CLUSTER_ADDRESS: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * 4 ;
pub const CLUSTER_COUNT: usize = 1024 * 1024; // 4 GiB
pub const CLUSTER_SIZE: usize = 4 * 1024; // Of 4 K chunks

#[repr(packed)]
struct MemoryMapEntry {
    base: u64,
    len: u64,
    class: u32,
    acpi: u32,
}

pub struct Memory<T> {
    pub ptr: *mut T,
}

impl<T> Memory<T> {
    pub fn new(count: usize) -> Option<Self> {
        let alloc = unsafe { alloc(count * size_of::<T>()) };
        if alloc > 0 {
            Some(Memory { ptr: alloc as *mut T })
        } else {
            None
        }
    }

    pub fn renew(&mut self, count: usize) -> bool {
        let address = unsafe { realloc(self.ptr as usize, count * size_of::<T>()) };
        if address > 0 {
            self.ptr = address as *mut T;
            true
        } else {
            false
        }
    }

    // The size in bytes
    pub fn size(&self) -> usize {
        unsafe { alloc_size(self.ptr as usize) }
    }

    // The length in T elements
    pub fn length(&self) -> usize {
        unsafe { alloc_size(self.ptr as usize) / size_of::<T>() }
    }

    pub unsafe fn address(&self) -> usize {
        self.ptr as usize
    }

    pub unsafe fn read(&self, i: usize) -> T {
        ptr::read(self.ptr.offset(i as isize))
    }

    pub unsafe fn load(&self, i: usize) -> T {
        intrinsics::atomic_load(self.ptr.offset(i as isize))
    }

    pub unsafe fn write(&mut self, i: usize, value: T) {
        ptr::write(self.ptr.offset(i as isize), value);
    }

    pub unsafe fn store(&mut self, i: usize, value: T) {
        intrinsics::atomic_store(self.ptr.offset(i as isize), value);
    }
}

impl<T> Drop for Memory<T> {
    fn drop(&mut self) {
        unsafe { unalloc(self.ptr as usize) }
    }
}

impl<T> Index<usize> for Memory<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: usize) -> &'a T {
        unsafe { &*self.ptr.offset(_index as isize) }
    }
}

impl<T> IndexMut<usize> for Memory<T> {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut T {
        unsafe { &mut *self.ptr.offset(_index as isize) }
    }
}

const MEMORY_MAP: *const MemoryMapEntry = 0x500 as *const MemoryMapEntry;

pub unsafe fn cluster(number: usize) -> usize {
    if number < CLUSTER_COUNT {
        ptr::read((CLUSTER_ADDRESS + number * size_of::<usize>()) as *const usize)
    } else {
        0
    }
}

pub unsafe fn set_cluster(number: usize, address: usize) {
    if number < CLUSTER_COUNT {
        ptr::write((CLUSTER_ADDRESS + number * size_of::<usize>()) as *mut usize,
                   address);
    }
}

pub unsafe fn address_to_cluster(address: usize) -> usize {
    if address >= CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() {
        (address - CLUSTER_ADDRESS - CLUSTER_COUNT * size_of::<usize>()) / CLUSTER_SIZE
    } else {
        0
    }
}

pub unsafe fn cluster_to_address(number: usize) -> usize {
    CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() + number * CLUSTER_SIZE
}

pub unsafe fn cluster_init() {
    //First, set all clusters to the not present value
    for cluster in 0..CLUSTER_COUNT {
        set_cluster(cluster, 0xFFFFFFFF);
    }

    //Next, set all valid clusters to the free value
    //TODO: Optimize this function
    for i in 0..((0x5000 - 0x500) / size_of::<MemoryMapEntry>()) {
        let entry = &*MEMORY_MAP.offset(i as isize);
        if entry.len > 0 && entry.class == 1 {
            for cluster in 0..CLUSTER_COUNT {
                let address = cluster_to_address(cluster);
                if address as u64 >= entry.base &&
                   (address as u64 + CLUSTER_SIZE as u64) <= (entry.base + entry.len) {
                    set_cluster(cluster, 0);
                }
            }
        }
    }
}

pub unsafe fn alloc(size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_aligned(size: usize, align: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 && cluster_to_address(i) % align == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_type<T>() -> *mut T {
    alloc(size_of::<T>()) as *mut T
}

pub unsafe fn alloc_size(ptr: usize) -> usize {
    let mut size = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                size += CLUSTER_SIZE;
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    size
}

pub unsafe fn unalloc(ptr: usize) {
    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                set_cluster(i, 0);
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);
}

pub unsafe fn realloc(ptr: usize, size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size == 0 {
        if ptr > 0 {
            unalloc(ptr);
        }
    } else {
        let old_size = alloc_size(ptr);
        if size <= old_size {
            ret = ptr;
        } else {
            ret = alloc(size);
            if ptr > 0 {
                if ret > 0 {
                    let copy_size = min(old_size, size);

                    ::memmove(ret as *mut u8, ptr as *const u8, copy_size);
                }
                unalloc(ptr);
            }
        }
    }

    end_no_ints(reenable);

    ret
}

pub unsafe fn realloc_inplace(ptr: usize, size: usize) -> usize {
    let old_size = alloc_size(ptr);
    if size <= old_size {
        size
    } else {
        old_size
    }
}

pub fn memory_used() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) != 0 && cluster(i) != 0xFFFFFFFF {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}

pub fn memory_free() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}
<commit_msg>Use `intrinsics::atomic_singlethreadfence` instead of `atomic_{load,store}`<commit_after>use core::cmp::min;
use core::intrinsics;
use core::mem::size_of;
use core::ops::{Index, IndexMut};
use core::ptr;

use common::scheduler::*;

pub const PAGE_DIRECTORY: usize = 0x300000;
pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * 4;
pub const PAGE_SIZE: usize = 4 * 1024;

pub const CLUSTER_ADDRESS: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * 4 ;
pub const CLUSTER_COUNT: usize = 1024 * 1024; // 4 GiB
pub const CLUSTER_SIZE: usize = 4 * 1024; // Of 4 K chunks

#[repr(packed)]
struct MemoryMapEntry {
    base: u64,
    len: u64,
    class: u32,
    acpi: u32,
}

pub struct Memory<T> {
    pub ptr: *mut T,
}

impl<T> Memory<T> {
    pub fn new(count: usize) -> Option<Self> {
        let alloc = unsafe { alloc(count * size_of::<T>()) };
        if alloc > 0 {
            Some(Memory { ptr: alloc as *mut T })
        } else {
            None
        }
    }

    pub fn renew(&mut self, count: usize) -> bool {
        let address = unsafe { realloc(self.ptr as usize, count * size_of::<T>()) };
        if address > 0 {
            self.ptr = address as *mut T;
            true
        } else {
            false
        }
    }

    // The size in bytes
    pub fn size(&self) -> usize {
        unsafe { alloc_size(self.ptr as usize) }
    }

    // The length in T elements
    pub fn length(&self) -> usize {
        unsafe { alloc_size(self.ptr as usize) / size_of::<T>() }
    }

    pub unsafe fn address(&self) -> usize {
        self.ptr as usize
    }

    pub unsafe fn read(&self, i: usize) -> T {
        ptr::read(self.ptr.offset(i as isize))
    }

    pub unsafe fn load(&self, i: usize) -> T {
        intrinsics::atomic_singlethreadfence();
        ptr::read(self.ptr.offset(i as isize))
    }

    pub unsafe fn write(&mut self, i: usize, value: T) {
        ptr::write(self.ptr.offset(i as isize), value);
    }

    pub unsafe fn store(&mut self, i: usize, value: T) {
        intrinsics::atomic_singlethreadfence();
        ptr::write(self.ptr.offset(i as isize), value)
    }
}

impl<T> Drop for Memory<T> {
    fn drop(&mut self) {
        unsafe { unalloc(self.ptr as usize) }
    }
}

impl<T> Index<usize> for Memory<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: usize) -> &'a T {
        unsafe { &*self.ptr.offset(_index as isize) }
    }
}

impl<T> IndexMut<usize> for Memory<T> {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut T {
        unsafe { &mut *self.ptr.offset(_index as isize) }
    }
}

const MEMORY_MAP: *const MemoryMapEntry = 0x500 as *const MemoryMapEntry;

pub unsafe fn cluster(number: usize) -> usize {
    if number < CLUSTER_COUNT {
        ptr::read((CLUSTER_ADDRESS + number * size_of::<usize>()) as *const usize)
    } else {
        0
    }
}

pub unsafe fn set_cluster(number: usize, address: usize) {
    if number < CLUSTER_COUNT {
        ptr::write((CLUSTER_ADDRESS + number * size_of::<usize>()) as *mut usize,
                   address);
    }
}

pub unsafe fn address_to_cluster(address: usize) -> usize {
    if address >= CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() {
        (address - CLUSTER_ADDRESS - CLUSTER_COUNT * size_of::<usize>()) / CLUSTER_SIZE
    } else {
        0
    }
}

pub unsafe fn cluster_to_address(number: usize) -> usize {
    CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() + number * CLUSTER_SIZE
}

pub unsafe fn cluster_init() {
    //First, set all clusters to the not present value
    for cluster in 0..CLUSTER_COUNT {
        set_cluster(cluster, 0xFFFFFFFF);
    }

    //Next, set all valid clusters to the free value
    //TODO: Optimize this function
    for i in 0..((0x5000 - 0x500) / size_of::<MemoryMapEntry>()) {
        let entry = &*MEMORY_MAP.offset(i as isize);
        if entry.len > 0 && entry.class == 1 {
            for cluster in 0..CLUSTER_COUNT {
                let address = cluster_to_address(cluster);
                if address as u64 >= entry.base &&
                   (address as u64 + CLUSTER_SIZE as u64) <= (entry.base + entry.len) {
                    set_cluster(cluster, 0);
                }
            }
        }
    }
}

pub unsafe fn alloc(size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_aligned(size: usize, align: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 && cluster_to_address(i) % align == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_type<T>() -> *mut T {
    alloc(size_of::<T>()) as *mut T
}

pub unsafe fn alloc_size(ptr: usize) -> usize {
    let mut size = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                size += CLUSTER_SIZE;
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    size
}

pub unsafe fn unalloc(ptr: usize) {
    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                set_cluster(i, 0);
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);
}

pub unsafe fn realloc(ptr: usize, size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size == 0 {
        if ptr > 0 {
            unalloc(ptr);
        }
    } else {
        let old_size = alloc_size(ptr);
        if size <= old_size {
            ret = ptr;
        } else {
            ret = alloc(size);
            if ptr > 0 {
                if ret > 0 {
                    let copy_size = min(old_size, size);

                    ::memmove(ret as *mut u8, ptr as *const u8, copy_size);
                }
                unalloc(ptr);
            }
        }
    }

    end_no_ints(reenable);

    ret
}

pub unsafe fn realloc_inplace(ptr: usize, size: usize) -> usize {
    let old_size = alloc_size(ptr);
    if size <= old_size {
        size
    } else {
        old_size
    }
}

pub fn memory_used() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) != 0 && cluster(i) != 0xFFFFFFFF {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}

pub fn memory_free() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}
<|endoftext|>


<commit_before>use core::clone::Clone;
use core::cmp::PartialEq;
use core::iter::Iterator;
use core::ops::{Add, Index};
use core::option::Option;
use core::ptr;
use core::slice::SliceExt;
use core::str::StrExt;

use common::debug::*;
use common::memory::*;
use common::vec::*;

/// A trait for types that can be converted to `String`
pub trait ToString {
    /// Convert the type to strings
    fn to_string(&self) -> String;
}

impl ToString for &'static str {
    /// Convert the type to `String`
    fn to_string(&self) -> String {
        String::from_str(self)
    }
}

/// An iterator over unicode characters
pub struct Chars<'a> {
    /// The string iterating over
    string: &'a String,
    /// The offset of the iterator
    offset: usize,
}

impl <'a> Iterator for Chars<'a> {
    type Item = char;

    fn next(&mut self) -> Option<Self::Item> {
        if self.offset < self.string.len() {
            let ret = Some(self.string[self.offset]);
            self.offset += 1;
            ret
        } else {
            None
        }
    }
}

/// A split
pub struct Split<'a> {
    /// The string being split
    string: &'a String,
    /// The offset of the split
    offset: usize,
    /// The string seperator
    seperator: String,
}

impl <'a> Iterator for Split<'a> {
    type Item = String;
    fn next(&mut self) -> Option<Self::Item> {
        if self.offset < self.string.len() {
            let start = self.offset;
            let mut len = 0;
            for i in start..self.string.len() {
                if self.seperator == self.string.substr(i, self.seperator.len()) {
                    self.offset += self.seperator.len();
                    break;
                } else {
                    self.offset += 1;
                    len += 1;
                }
            }
            Some(self.string.substr(start, len))
        } else {
            None
        }
    }
}

/// A heap allocated, owned string.
pub struct String {
    /// The vector of the chars
    pub vec: Vec<char>,
}

impl String {
    /// Create a new empty `String`
    pub fn new() -> Self {
        String { vec: Vec::new() }
    }

    // TODO FromStr trait
    /// Convert a string literal to a `String`
    pub fn from_str(s: &str) -> Self {
        let mut vec: Vec<char> = Vec::new();

        for c in s.chars() {
            vec.push(c);
        }

        String { vec: vec }
    }

    /// Convert a c-style string slice to a String
    pub fn from_c_slice(s: &[u8]) -> Self {
        let mut vec: Vec<char> = Vec::new();

        for b in s {
            let c = *b as char;
            if c == '\0' {
                break;
            }
            vec.push(c);
        }

        String { vec: vec }
    }

    /// Convert a utf8 vector to a string
    // Why &Vec?
    pub fn from_utf8(utf_vec: &Vec<u8>) -> Self {
        let mut vec: Vec<char> = Vec::new();

        //TODO: better UTF support
        for b in utf_vec.iter() {
            let c = *b as char;
            if c == '\0' {
                break;
            }
            vec.push(c);
        }

        String { vec: vec }
    }

    /// Convert a C-style string literal to a `String`
    pub unsafe fn from_c_str(s: *const u8) -> Self {
        let mut vec: Vec<char> = Vec::new();

        let mut i = 0;
        loop {
            let c = ptr::read(s.offset(i)) as char;
            if c == '\0' {
                break;
            }
            vec.push(c);
            i += 1;
        }

        String { vec: vec }
    }

    /// Convert an integer to a String using a given radix
    pub fn from_num_radix(num: usize, radix: usize) -> Self {
        if radix == 0 {
            return String::new();
        }

        let mut vec: Vec<char> = Vec::new();

        let mut digit_num = num;
        loop {
            let mut digit = (digit_num % radix) as u8;
            if digit > 9 {
                digit += 'A' as u8 - 10;
            } else {
                digit += '0' as u8;
            }

            vec.insert(0, digit as char);

            if digit_num < radix {
                break;
            }

            digit_num /= radix;
        }

        String { vec: vec }
    }

    /// Convert a signed integer to a String
    // TODO: Consider using `int` instead of `num`
    pub fn from_num_radix_signed(num: isize, radix: usize) -> Self {
        if num >= 0 {
            String::from_num_radix(num as usize, radix)
        } else {
            "-".to_string() + String::from_num_radix((-num) as usize, radix)
        }
    }

    /// Convert a `char` to a string
    pub fn from_char(c: char) -> Self {
        if c == '\0' {
            return String::new();
        }

        let mut vec: Vec<char> = Vec::new();
        vec.push(c);

        String { vec: vec }
    }

    /// Convert an unsigned integer to a `String` in base 10
    pub fn from_num(num: usize) -> Self {
        String::from_num_radix(num, 10)
    }

    /// Convert a signed int to a `String` in base 10
    pub fn from_num_signed(num: isize) -> Self {
        String::from_num_radix_signed(num, 10)
    }

    /// Get a substring
    // TODO: Consider to use a string slice
    pub fn substr(&self, start: usize, len: usize) -> Self {
        let mut i = start;
        if i > self.len() {
            i = self.len();
        }

        let mut j = i + len;
        if j > self.len() {
            j = self.len();
        }

        let mut vec: Vec<char> = Vec::new();

        for k in i..j {
            vec.push(self[k]);
        }

        String { vec: vec }
    }

    /// Find the index of a substring in a string
    pub fn find(&self, other: Self) -> Option<usize> {
        if self.len() >= other.len() {
            for i in 0..self.len() + 1 - other.len() {
                if self.substr(i, other.len()) == other {
                    return Some(i);
                }
            }
        }
        None
    }

    /// Check if the string starts with a given string
    pub fn starts_with(&self, other: Self) -> bool {
        if self.len() >= other.len() {
            // FIXME: This is inefficient
            self.substr(0, other.len()) == other
        } else {
            false
        }
    }

    /// Check if a string ends with another string
    pub fn ends_with(&self, other: Self) -> bool {
        if self.len() >= other.len() {
            // FIXME: Inefficient
            self.substr(self.len() - other.len(), other.len()) == other
        } else {
            false
        }
    }

    /// Get the length of the string
    pub fn len(&self) -> usize {
        self.vec.len()
    }

    /// Get a iterator over the chars of the string
    pub fn chars(&self) -> Chars {
        Chars {
            string: &self,
            offset: 0,
        }
    }

    /// Get a iterator of the splits of the string (by a seperator)
    pub fn split(&self, seperator: Self) -> Split {
        Split {
            string: &self,
            offset: 0,
            seperator: seperator,
        }
    }

    /// Convert the string to UTF-8
    pub fn to_utf8(&self) -> Vec<u8> {
        let mut vec: Vec<u8> = Vec::new();

        for c in self.chars() {
            let u = c as usize;
            if u < 0x80 {
                vec.push(u as u8);
            } else if u < 0x800 {
                vec.push(0b11000000 | ((u >> 6) as u8 & 0b00011111));
                vec.push(0b10000000 | (u as u8 & 0b00111111));
            } else if u < 0x10000 {
                vec.push(0b11100000 | ((u >> 12) as u8 & 0b00001111));
                vec.push(0b10000000 | ((u >> 6) as u8 & 0b00111111));
                vec.push(0b10000000 | (u as u8 & 0b00111111));
            } else {
                d("Unhandled to_utf8 code ");
                dh(u);
                dl();
                unsafe {
                    dh(self.vec.as_ptr() as usize);
                }
                d(" ");
                dd(self.vec.len());
                d(" to ");
                unsafe {
                    dh(vec.as_ptr() as usize);
                }
                d(" ");
                dd(vec.len());
                dl();
                break;
            }
        }

        vec
    }

    /// Convert the string to a C-style string
    pub unsafe fn to_c_str(&self) -> *const u8 {
        let length = self.len() + 1;

        let data = alloc(length) as *mut u8;

        for i in 0..self.len() {
            ptr::write(data.offset(i as isize), self[i] as u8);
        }
        ptr::write(data.offset(self.len() as isize), 0);

        data
    }

    /// Parse the string to a integer using a given radix
    pub fn to_num_radix(&self, radix: usize) -> usize {
        if radix == 0 {
            return 0;
        }

        let mut num = 0;
        for c in self.chars() {
            let digit;
            if c >= '0' && c <= '9' {
                digit = c as usize - '0' as usize
            } else if c >= 'A' && c <= 'Z' {
                digit = c as usize - 'A' as usize + 10
            } else if c >= 'a' && c <= 'z' {
                digit = c as usize - 'a' as usize + 10
            } else {
                break;
            }

            if digit >= radix {
                break;
            }

            num *= radix;
            num += digit;
        }

        num
    }

    /// Parse the string as a signed integer using a given radix
    pub fn to_num_radix_signed(&self, radix: usize) -> isize {
        if self[0] == '-' {
            -(self.substr(1, self.len() - 1).to_num_radix(radix) as isize)
        } else {
            self.to_num_radix(radix) as isize
        }
    }

    /// Parse it as a unsigned integer in base 10
    pub fn to_num(&self) -> usize {
        self.to_num_radix(10)
    }

    /// Parse it as a signed integer in base 10
    pub fn to_num_signed(&self) -> isize {
        self.to_num_radix_signed(10)
    }

    /// Debug
    pub fn d(&self) {
        for c in self.chars() {
            dc(c);
        }
    }
}

static NULL_CHAR: char = '\0';

impl Index<usize> for String {
    type Output = char;
    fn index<'a>(&'a self, i: usize) -> &'a Self::Output {
        match self.vec.get(i) {
            Some(c) => c,
            None => &NULL_CHAR,
        }
    }
}

impl PartialEq for String {
    fn eq(&self, other: &Self) -> bool {
        if self.len() == other.len() {
            for i in 0..self.len() {
                if self[i] != other[i] {
                    return false;
                }
            }

            true
        } else {
            false
        }
    }
}

impl Clone for String {
    fn clone(&self) -> Self {
        self.substr(0, self.len())
    }
}

impl<'a> Add<&'a String> for String {
    type Output = String;
    fn add(mut self, other: &'a Self) -> Self {
        self.vec.push_all(&other.vec);
        self
    }
}

impl<'a> Add<&'a mut String> for String {
    type Output = String;
    fn add(mut self, other: &'a mut Self) -> Self {
        self.vec.push_all(&other.vec);
        self
    }
}

impl Add for String {
    type Output = String;
    fn add(mut self, other: Self) -> Self {
        self.vec.push_all(&other.vec);
        self
    }
}

impl<'a> Add<&'a str> for String {
    type Output = String;
    fn add(self, other: &'a str) -> Self {
        self + String::from_str(other)
    }
}

impl Add<char> for String {
    type Output = String;
    fn add(mut self, other: char) -> Self {
        self.vec.push(other);
        self
    }
}

impl Add<usize> for String {
    type Output = String;
    fn add(self, other: usize) -> Self {
        self + String::from_num(other)
    }
}

impl Add<isize> for String {
    type Output = String;
    fn add(self, other: isize) -> Self {
        self + String::from_num_signed(other)
    }
}

// Slightly modified version of the impl_eq found in the std collections String
// Ideally, we'd compare these as arrays. However, we'd need to flesh out String a bit more
macro_rules! impl_chars_eq {
    ($lhs:ty, $rhs: ty) => {
        impl<'a> PartialEq<$rhs> for $lhs {
            #[inline]
            fn eq(&self, other: &$rhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
            #[inline]
            fn ne(&self, other: &$rhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
        }

        impl<'a> PartialEq<$lhs> for $rhs {
            #[inline]
            fn eq(&self, other: &$lhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
            #[inline]
            fn ne(&self, other: &$lhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
        }

    }
}

impl_chars_eq! { String, str }
impl_chars_eq! { String, &'a str }
<commit_msg>Added Lines-Iterator to String<commit_after>use core::clone::Clone;
use core::cmp::PartialEq;
use core::iter::Iterator;
use core::ops::{Add, Index};
use core::option::Option;
use core::ptr;
use core::slice::SliceExt;
use core::str::StrExt;

use common::debug::*;
use common::memory::*;
use common::vec::*;

/// A trait for types that can be converted to `String`
pub trait ToString {
    /// Convert the type to strings
    fn to_string(&self) -> String;
}

impl ToString for &'static str {
    /// Convert the type to `String`
    fn to_string(&self) -> String {
        String::from_str(self)
    }
}

/// An iterator over unicode characters
pub struct Chars<'a> {
    /// The string iterating over
    string: &'a String,
    /// The offset of the iterator
    offset: usize,
}

impl <'a> Iterator for Chars<'a> {
    type Item = char;

    fn next(&mut self) -> Option<Self::Item> {
        if self.offset < self.string.len() {
            let ret = Some(self.string[self.offset]);
            self.offset += 1;
            ret
        } else {
            None
        }
    }
}

/// A split
pub struct Split<'a> {
    /// The string being split
    string: &'a String,
    /// The offset of the split
    offset: usize,
    /// The string seperator
    seperator: String,
}

impl <'a> Iterator for Split<'a> {
    type Item = String;
    fn next(&mut self) -> Option<Self::Item> {
        if self.offset < self.string.len() {
            let start = self.offset;
            let mut len = 0;
            for i in start..self.string.len() {
                if self.seperator == self.string.substr(i, self.seperator.len()) {
                    self.offset += self.seperator.len();
                    break;
                } else {
                    self.offset += 1;
                    len += 1;
                }
            }
            Some(self.string.substr(start, len))
        } else {
            None
        }
    }
}

/// A set of lines
pub struct Lines<'a> {
    /// The string being split into lines
    string: &'a String,
    /// The underlying split
    split: Split<'a>
}

impl <'a> Iterator for Lines<'a> {
    type Item = String;
    fn next(&mut self) -> Option<Self::Item> {
        match self.split.next() {
            Some(string) => if string.ends_with("\r".to_string()) {
                Some(string.substr(0, string.len() - 1))
            } else {
                Some(string)
            },
            None => None
        }
    }
}

/// A heap allocated, owned string.
pub struct String {
    /// The vector of the chars
    pub vec: Vec<char>,
}

impl String {
    /// Create a new empty `String`
    pub fn new() -> Self {
        String { vec: Vec::new() }
    }

    // TODO FromStr trait
    /// Convert a string literal to a `String`
    pub fn from_str(s: &str) -> Self {
        let mut vec: Vec<char> = Vec::new();

        for c in s.chars() {
            vec.push(c);
        }

        String { vec: vec }
    }

    /// Convert a c-style string slice to a String
    pub fn from_c_slice(s: &[u8]) -> Self {
        let mut vec: Vec<char> = Vec::new();

        for b in s {
            let c = *b as char;
            if c == '\0' {
                break;
            }
            vec.push(c);
        }

        String { vec: vec }
    }

    /// Convert a utf8 vector to a string
    // Why &Vec?
    pub fn from_utf8(utf_vec: &Vec<u8>) -> Self {
        let mut vec: Vec<char> = Vec::new();

        //TODO: better UTF support
        for b in utf_vec.iter() {
            let c = *b as char;
            if c == '\0' {
                break;
            }
            vec.push(c);
        }

        String { vec: vec }
    }

    /// Convert a C-style string literal to a `String`
    pub unsafe fn from_c_str(s: *const u8) -> Self {
        let mut vec: Vec<char> = Vec::new();

        let mut i = 0;
        loop {
            let c = ptr::read(s.offset(i)) as char;
            if c == '\0' {
                break;
            }
            vec.push(c);
            i += 1;
        }

        String { vec: vec }
    }

    /// Convert an integer to a String using a given radix
    pub fn from_num_radix(num: usize, radix: usize) -> Self {
        if radix == 0 {
            return String::new();
        }

        let mut vec: Vec<char> = Vec::new();

        let mut digit_num = num;
        loop {
            let mut digit = (digit_num % radix) as u8;
            if digit > 9 {
                digit += 'A' as u8 - 10;
            } else {
                digit += '0' as u8;
            }

            vec.insert(0, digit as char);

            if digit_num < radix {
                break;
            }

            digit_num /= radix;
        }

        String { vec: vec }
    }

    /// Convert a signed integer to a String
    // TODO: Consider using `int` instead of `num`
    pub fn from_num_radix_signed(num: isize, radix: usize) -> Self {
        if num >= 0 {
            String::from_num_radix(num as usize, radix)
        } else {
            "-".to_string() + String::from_num_radix((-num) as usize, radix)
        }
    }

    /// Convert a `char` to a string
    pub fn from_char(c: char) -> Self {
        if c == '\0' {
            return String::new();
        }

        let mut vec: Vec<char> = Vec::new();
        vec.push(c);

        String { vec: vec }
    }

    /// Convert an unsigned integer to a `String` in base 10
    pub fn from_num(num: usize) -> Self {
        String::from_num_radix(num, 10)
    }

    /// Convert a signed int to a `String` in base 10
    pub fn from_num_signed(num: isize) -> Self {
        String::from_num_radix_signed(num, 10)
    }

    /// Get a substring
    // TODO: Consider to use a string slice
    pub fn substr(&self, start: usize, len: usize) -> Self {
        let mut i = start;
        if i > self.len() {
            i = self.len();
        }

        let mut j = i + len;
        if j > self.len() {
            j = self.len();
        }

        let mut vec: Vec<char> = Vec::new();

        for k in i..j {
            vec.push(self[k]);
        }

        String { vec: vec }
    }

    /// Find the index of a substring in a string
    pub fn find(&self, other: Self) -> Option<usize> {
        if self.len() >= other.len() {
            for i in 0..self.len() + 1 - other.len() {
                if self.substr(i, other.len()) == other {
                    return Some(i);
                }
            }
        }
        None
    }

    /// Check if the string starts with a given string
    pub fn starts_with(&self, other: Self) -> bool {
        if self.len() >= other.len() {
            // FIXME: This is inefficient
            self.substr(0, other.len()) == other
        } else {
            false
        }
    }

    /// Check if a string ends with another string
    pub fn ends_with(&self, other: Self) -> bool {
        if self.len() >= other.len() {
            // FIXME: Inefficient
            self.substr(self.len() - other.len(), other.len()) == other
        } else {
            false
        }
    }

    /// Get the length of the string
    pub fn len(&self) -> usize {
        self.vec.len()
    }

    /// Get a iterator over the chars of the string
    pub fn chars(&self) -> Chars {
        Chars {
            string: &self,
            offset: 0,
        }
    }

    /// Get a iterator of the splits of the string (by a seperator)
    pub fn split(&self, seperator: Self) -> Split {
        Split {
            string: &self,
            offset: 0,
            seperator: seperator,
        }
    }

    /// Convert the string to UTF-8
    pub fn to_utf8(&self) -> Vec<u8> {
        let mut vec: Vec<u8> = Vec::new();

        for c in self.chars() {
            let u = c as usize;
            if u < 0x80 {
                vec.push(u as u8);
            } else if u < 0x800 {
                vec.push(0b11000000 | ((u >> 6) as u8 & 0b00011111));
                vec.push(0b10000000 | (u as u8 & 0b00111111));
            } else if u < 0x10000 {
                vec.push(0b11100000 | ((u >> 12) as u8 & 0b00001111));
                vec.push(0b10000000 | ((u >> 6) as u8 & 0b00111111));
                vec.push(0b10000000 | (u as u8 & 0b00111111));
            } else {
                d("Unhandled to_utf8 code ");
                dh(u);
                dl();
                unsafe {
                    dh(self.vec.as_ptr() as usize);
                }
                d(" ");
                dd(self.vec.len());
                d(" to ");
                unsafe {
                    dh(vec.as_ptr() as usize);
                }
                d(" ");
                dd(vec.len());
                dl();
                break;
            }
        }

        vec
    }

    /// Convert the string to a C-style string
    pub unsafe fn to_c_str(&self) -> *const u8 {
        let length = self.len() + 1;

        let data = alloc(length) as *mut u8;

        for i in 0..self.len() {
            ptr::write(data.offset(i as isize), self[i] as u8);
        }
        ptr::write(data.offset(self.len() as isize), 0);

        data
    }

    /// Parse the string to a integer using a given radix
    pub fn to_num_radix(&self, radix: usize) -> usize {
        if radix == 0 {
            return 0;
        }

        let mut num = 0;
        for c in self.chars() {
            let digit;
            if c >= '0' && c <= '9' {
                digit = c as usize - '0' as usize
            } else if c >= 'A' && c <= 'Z' {
                digit = c as usize - 'A' as usize + 10
            } else if c >= 'a' && c <= 'z' {
                digit = c as usize - 'a' as usize + 10
            } else {
                break;
            }

            if digit >= radix {
                break;
            }

            num *= radix;
            num += digit;
        }

        num
    }

    /// Parse the string as a signed integer using a given radix
    pub fn to_num_radix_signed(&self, radix: usize) -> isize {
        if self[0] == '-' {
            -(self.substr(1, self.len() - 1).to_num_radix(radix) as isize)
        } else {
            self.to_num_radix(radix) as isize
        }
    }

    /// Parse it as a unsigned integer in base 10
    pub fn to_num(&self) -> usize {
        self.to_num_radix(10)
    }

    /// Parse it as a signed integer in base 10
    pub fn to_num_signed(&self) -> isize {
        self.to_num_radix_signed(10)
    }

    /// Debug
    pub fn d(&self) {
        for c in self.chars() {
            dc(c);
        }
    }
}

static NULL_CHAR: char = '\0';

impl Index<usize> for String {
    type Output = char;
    fn index<'a>(&'a self, i: usize) -> &'a Self::Output {
        match self.vec.get(i) {
            Some(c) => c,
            None => &NULL_CHAR,
        }
    }
}

impl PartialEq for String {
    fn eq(&self, other: &Self) -> bool {
        if self.len() == other.len() {
            for i in 0..self.len() {
                if self[i] != other[i] {
                    return false;
                }
            }

            true
        } else {
            false
        }
    }
}

impl Clone for String {
    fn clone(&self) -> Self {
        self.substr(0, self.len())
    }
}

impl<'a> Add<&'a String> for String {
    type Output = String;
    fn add(mut self, other: &'a Self) -> Self {
        self.vec.push_all(&other.vec);
        self
    }
}

impl<'a> Add<&'a mut String> for String {
    type Output = String;
    fn add(mut self, other: &'a mut Self) -> Self {
        self.vec.push_all(&other.vec);
        self
    }
}

impl Add for String {
    type Output = String;
    fn add(mut self, other: Self) -> Self {
        self.vec.push_all(&other.vec);
        self
    }
}

impl<'a> Add<&'a str> for String {
    type Output = String;
    fn add(self, other: &'a str) -> Self {
        self + String::from_str(other)
    }
}

impl Add<char> for String {
    type Output = String;
    fn add(mut self, other: char) -> Self {
        self.vec.push(other);
        self
    }
}

impl Add<usize> for String {
    type Output = String;
    fn add(self, other: usize) -> Self {
        self + String::from_num(other)
    }
}

impl Add<isize> for String {
    type Output = String;
    fn add(self, other: isize) -> Self {
        self + String::from_num_signed(other)
    }
}

// Slightly modified version of the impl_eq found in the std collections String
// Ideally, we'd compare these as arrays. However, we'd need to flesh out String a bit more
macro_rules! impl_chars_eq {
    ($lhs:ty, $rhs: ty) => {
        impl<'a> PartialEq<$rhs> for $lhs {
            #[inline]
            fn eq(&self, other: &$rhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
            #[inline]
            fn ne(&self, other: &$rhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
        }

        impl<'a> PartialEq<$lhs> for $rhs {
            #[inline]
            fn eq(&self, other: &$lhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
            #[inline]
            fn ne(&self, other: &$lhs) -> bool { self.chars().zip(other.chars()).all(|(a,b)| a == b) }
        }

    }
}

impl_chars_eq! { String, str }
impl_chars_eq! { String, &'a str }
<|endoftext|>


<commit_before><commit_msg>Add docs for constants.<commit_after><|endoftext|>


<commit_before><commit_msg>depot_tools work<commit_after><|endoftext|>


<commit_before><commit_msg>New way of reading the color palette.<commit_after><|endoftext|>


<commit_before><commit_msg>Cleanup; abstraction<commit_after><|endoftext|>


<commit_before><commit_msg>Upgraded to latest piston-event<commit_after><|endoftext|>


<commit_before><commit_msg>Remove code from branches() test<commit_after><|endoftext|>


<commit_before><commit_msg>A model by Cho and Moreno<commit_after>% Woodford(2003) model as presented in Seonghoon Cho and Antonio Moreno (2011):
% "The forward method as a solution refinement in rational expectations Models"
% Journal of Economics Dynamics and Control 35 (2011) 257-272

endogenous PAI, Y, R, I

exogenous EPS

parameters delta kappa mu, beta, phi, rho, lambda

model
	PAI = delta*PAI{+1}+kappa*Y;

	Y = mu*Y{+1}+(1-mu)*Y{-1}-phi*(I-PAI{+1}-R);

	I = beta*PAI{+1}+lambda*Y;

	R = rho*R{-1} + EPS;

parameterization
	delta, 0.99;
	kappa,0.3;
	mu, .55;
	@# if multiple
		beta,0.95;
	@# else
		beta,1.5;
	@# end
	phi, 1;
	rho,.8;
	lambda,.1;<|endoftext|>


<commit_before><commit_msg>Add comment to globals.rs<commit_after><|endoftext|>


<commit_before><commit_msg>[Auto] bin/core/todo: Fix Clippy warnings<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor imag-todo to fit new store iterator interface<commit_after><|endoftext|>


<commit_before><commit_msg>Add SessionState::handle_handler_response, update docs.<commit_after><|endoftext|>


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

//! A standard, garbage-collected linked list.

use std::container::Container;

#[deriving(Clone, Eq)]
#[allow(missing_doc)]
pub enum List<T> {
    Cons(T, @List<T>),
    Nil,
}

pub struct Items<'a, T> {
    priv head: &'a List<T>,
    priv next: Option<&'a @List<T>>
}

impl<'a, T> Iterator<&'a T> for Items<'a, T> {
    fn next(&mut self) -> Option<&'a T> {
        match self.next {
            None => match *self.head {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            },
            Some(next) => match **next {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            }
        }
    }
}

impl<T> List<T> {
    /// Returns a forward iterator
    pub fn iter<'a>(&'a self) -> Items<'a, T> {
        Items {
            head: self,
            next: None
        }
    }
}

impl<T> Container for List<T> {
    /// Returns the length of a list
    fn len(&self) -> uint { self.iter().len() }

    /// Returns true if the list is empty
    fn is_empty(&self) -> bool { match *self { Nil => true, _ => false } }
}

/// Returns true if a list contains an element with the given value
pub fn has<T:Eq>(list: @List<T>, element: T) -> bool {
    let mut found = false;
    each(list, |e| {
        if *e == element { found = true; false } else { true }
    });
    return found;
}

/// Returns all but the first element of a list
pub fn tail<T>(list: @List<T>) -> @List<T> {
    match *list {
        Cons(_, tail) => return tail,
        Nil => fail!("list empty")
    }
}

/// Returns the first element of a list
pub fn head<T:Clone>(list: @List<T>) -> T {
    match *list {
      Cons(ref head, _) => (*head).clone(),
      // makes me sad
      _ => fail!("head invoked on empty list")
    }
}

/// Appends one list to another
pub fn append<T:Clone + 'static>(list: @List<T>, other: @List<T>) -> @List<T> {
    match *list {
      Nil => return other,
      Cons(ref head, tail) => {
        let rest = append(tail, other);
        return @Cons((*head).clone(), rest);
      }
    }
}

impl<T:'static + Clone> List<T> {
    /// Create a list from a vector
    pub fn from_vec(v: &[T]) -> List<T> {
        match v.len() {
            0 => Nil,
            _ => v.rev_iter().fold(Nil, |tail, value: &T| Cons(value.clone(), @tail))
        }
    }
}

/*
/// Push one element into the front of a list, returning a new list
/// THIS VERSION DOESN'T ACTUALLY WORK
fn push<T:Clone>(ll: &mut @list<T>, vv: T) {
    ll = &mut @cons(vv, *ll)
}
*/

/// Iterate over a list
pub fn iter<T>(list: @List<T>, f: |&T|) {
    let mut cur = list;
    loop {
        cur = match *cur {
          Cons(ref head, tail) => {
            f(head);
            tail
          }
          Nil => break
        }
    }
}

/// Iterate over a list
pub fn each<T>(list: @List<T>, f: |&T| -> bool) -> bool {
    let mut cur = list;
    loop {
        cur = match *cur {
          Cons(ref head, tail) => {
            if !f(head) { return false; }
            tail
          }
          Nil => { return true; }
        }
    }
}

#[cfg(test)]
mod tests {
    use list::{List, Nil, head, tail};
    use list;

    #[test]
    fn test_iter() {
        let list = List::from_vec([0, 1, 2]);
        let mut iter = list.iter();
        assert_eq!(&0, iter.next().unwrap());
        assert_eq!(&1, iter.next().unwrap());
        assert_eq!(&2, iter.next().unwrap());
        assert_eq!(None, iter.next());
    }

    #[test]
    fn test_is_empty() {
        let empty : list::List<int> = List::from_vec([]);
        let full1 = List::from_vec([1]);
        let full2 = List::from_vec(['r', 'u']);

        assert!(empty.is_empty());
        assert!(!full1.is_empty());
        assert!(!full2.is_empty());
    }

    #[test]
    fn test_from_vec() {
        let list = @List::from_vec([0, 1, 2]);

        assert_eq!(head(list), 0);

        let tail_l = tail(list);
        assert_eq!(head(tail_l), 1);

        let tail_tail_l = tail(tail_l);
        assert_eq!(head(tail_tail_l), 2);
    }

    #[test]
    fn test_from_vec_empty() {
        let empty : list::List<int> = List::from_vec([]);
        assert_eq!(empty, Nil::<int>);
    }

    #[test]
    fn test_fold() {
        fn add_(a: uint, b: &uint) -> uint { a + *b }
        fn subtract_(a: uint, b: &uint) -> uint { a - *b }

        let empty = Nil::<uint>;
        assert_eq!(empty.iter().fold(0u, add_), 0u);
        assert_eq!(empty.iter().fold(10u, subtract_), 10u);

        let list = List::from_vec([0u, 1u, 2u, 3u, 4u]);
        assert_eq!(list.iter().fold(0u, add_), 10u);
        assert_eq!(list.iter().fold(10u, subtract_), 0u);
    }

    #[test]
    fn test_find_success() {
        fn match_(i: & &int) -> bool { **i == 2 }

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_).unwrap(), &2);
    }

    #[test]
    fn test_find_fail() {
        fn match_(_i: & &int) -> bool { false }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().find(match_), None);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_), None);
    }

    #[test]
    fn test_any() {
        fn match_(i: &int) -> bool { *i == 2 }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().any(match_), false);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().any(match_), true);
    }

    #[test]
    fn test_has() {
        let list = @List::from_vec([5, 8, 6]);
        let empty = @list::Nil::<int>;
        assert!((list::has(list, 5)));
        assert!((!list::has(list, 7)));
        assert!((list::has(list, 8)));
        assert!((!list::has(empty, 5)));
    }

    #[test]
    fn test_len() {
        let empty = Nil::<int>;
        assert_eq!(empty.len(), 0u);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.len(), 3u);
    }

    #[test]
    fn test_append() {
        assert!(@List::from_vec([1,2,3,4])
            == list::append(@List::from_vec([1,2]), @List::from_vec([3,4])));
    }
}
<commit_msg>Removed deprecated list::{iter,each}() functions<commit_after>// Copyright 2012 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.

//! A standard, garbage-collected linked list.

use std::container::Container;

#[deriving(Clone, Eq)]
#[allow(missing_doc)]
pub enum List<T> {
    Cons(T, @List<T>),
    Nil,
}

pub struct Items<'a, T> {
    priv head: &'a List<T>,
    priv next: Option<&'a @List<T>>
}

impl<'a, T> Iterator<&'a T> for Items<'a, T> {
    fn next(&mut self) -> Option<&'a T> {
        match self.next {
            None => match *self.head {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            },
            Some(next) => match **next {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            }
        }
    }
}

impl<T> List<T> {
    /// Returns a forward iterator
    pub fn iter<'a>(&'a self) -> Items<'a, T> {
        Items {
            head: self,
            next: None
        }
    }
}

impl<T> Container for List<T> {
    /// Returns the length of a list
    fn len(&self) -> uint { self.iter().len() }

    /// Returns true if the list is empty
    fn is_empty(&self) -> bool { match *self { Nil => true, _ => false } }
}

/// Returns true if a list contains an element with the given value
pub fn has<T:Eq>(list: @List<T>, element: T) -> bool {
    let mut found = false;
    each(list, |e| {
        if *e == element { found = true; false } else { true }
    });
    return found;
}

/// Returns all but the first element of a list
pub fn tail<T>(list: @List<T>) -> @List<T> {
    match *list {
        Cons(_, tail) => return tail,
        Nil => fail!("list empty")
    }
}

/// Returns the first element of a list
pub fn head<T:Clone>(list: @List<T>) -> T {
    match *list {
      Cons(ref head, _) => (*head).clone(),
      // makes me sad
      _ => fail!("head invoked on empty list")
    }
}

/// Appends one list to another
pub fn append<T:Clone + 'static>(list: @List<T>, other: @List<T>) -> @List<T> {
    match *list {
      Nil => return other,
      Cons(ref head, tail) => {
        let rest = append(tail, other);
        return @Cons((*head).clone(), rest);
      }
    }
}

impl<T:'static + Clone> List<T> {
    /// Create a list from a vector
    pub fn from_vec(v: &[T]) -> List<T> {
        match v.len() {
            0 => Nil,
            _ => v.rev_iter().fold(Nil, |tail, value: &T| Cons(value.clone(), @tail))
        }
    }
}

/*
/// Push one element into the front of a list, returning a new list
/// THIS VERSION DOESN'T ACTUALLY WORK
fn push<T:Clone>(ll: &mut @list<T>, vv: T) {
    ll = &mut @cons(vv, *ll)
}
*/

#[cfg(test)]
mod tests {
    use list::{List, Nil, head, tail};
    use list;

    #[test]
    fn test_iter() {
        let list = List::from_vec([0, 1, 2]);
        let mut iter = list.iter();
        assert_eq!(&0, iter.next().unwrap());
        assert_eq!(&1, iter.next().unwrap());
        assert_eq!(&2, iter.next().unwrap());
        assert_eq!(None, iter.next());
    }

    #[test]
    fn test_is_empty() {
        let empty : list::List<int> = List::from_vec([]);
        let full1 = List::from_vec([1]);
        let full2 = List::from_vec(['r', 'u']);

        assert!(empty.is_empty());
        assert!(!full1.is_empty());
        assert!(!full2.is_empty());
    }

    #[test]
    fn test_from_vec() {
        let list = @List::from_vec([0, 1, 2]);

        assert_eq!(head(list), 0);

        let tail_l = tail(list);
        assert_eq!(head(tail_l), 1);

        let tail_tail_l = tail(tail_l);
        assert_eq!(head(tail_tail_l), 2);
    }

    #[test]
    fn test_from_vec_empty() {
        let empty : list::List<int> = List::from_vec([]);
        assert_eq!(empty, Nil::<int>);
    }

    #[test]
    fn test_fold() {
        fn add_(a: uint, b: &uint) -> uint { a + *b }
        fn subtract_(a: uint, b: &uint) -> uint { a - *b }

        let empty = Nil::<uint>;
        assert_eq!(empty.iter().fold(0u, add_), 0u);
        assert_eq!(empty.iter().fold(10u, subtract_), 10u);

        let list = List::from_vec([0u, 1u, 2u, 3u, 4u]);
        assert_eq!(list.iter().fold(0u, add_), 10u);
        assert_eq!(list.iter().fold(10u, subtract_), 0u);
    }

    #[test]
    fn test_find_success() {
        fn match_(i: & &int) -> bool { **i == 2 }

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_).unwrap(), &2);
    }

    #[test]
    fn test_find_fail() {
        fn match_(_i: & &int) -> bool { false }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().find(match_), None);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_), None);
    }

    #[test]
    fn test_any() {
        fn match_(i: &int) -> bool { *i == 2 }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().any(match_), false);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().any(match_), true);
    }

    #[test]
    fn test_has() {
        let list = @List::from_vec([5, 8, 6]);
        let empty = @list::Nil::<int>;
        assert!((list::has(list, 5)));
        assert!((!list::has(list, 7)));
        assert!((list::has(list, 8)));
        assert!((!list::has(empty, 5)));
    }

    #[test]
    fn test_len() {
        let empty = Nil::<int>;
        assert_eq!(empty.len(), 0u);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.len(), 3u);
    }

    #[test]
    fn test_append() {
        assert!(@List::from_vec([1,2,3,4])
            == list::append(@List::from_vec([1,2]), @List::from_vec([3,4])));
    }
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #5898 - glennw:corrupt-gz, r=jdm<commit_after><|endoftext|>


<commit_before><commit_msg>Missed lifetime for default path constant. Added 'static.<commit_after><|endoftext|>


<commit_before>use gl;
use glutin;
use native::NativeTaskBuilder;
use std::sync::atomic::{AtomicUint, Relaxed};
use std::sync::{Arc, Mutex};
use std::task::TaskBuilder;
use GliumCreationError;

enum Message {
    EndFrame,
    Execute(proc(CommandContext):Send),
}

pub struct Context {
    commands: Mutex<Sender<Message>>,
    events: Mutex<Receiver<glutin::Event>>,

    /// Dimensions of the frame buffer.
    dimensions: Arc<(AtomicUint, AtomicUint)>,
}

pub struct CommandContext<'a, 'b> {
    pub gl: &'a gl::Gl,
    pub state: &'b mut GLState,
    pub version: &'a GlVersion,
    pub extensions: &'a ExtensionsList,
    pub opengl_es: bool,
    pub capabilities: &'a Capabilities,
}

/// Represents the current OpenGL ctxt.state.
/// The current state is passed to each function and can be freely updated.
pub struct GLState {
    /// Whether GL_BLEND is enabled
    pub enabled_blend: bool,

    /// Whether GL_CULL_FACE is enabled
    pub enabled_cull_face: bool,

    /// Whether GL_DEBUG_OUTPUT is enabled. None means "unknown".
    pub enabled_debug_output: Option<bool>,

    /// Whether GL_DEBUG_OUTPUT_SYNCHRONOUS is enabled
    pub enabled_debug_output_synchronous: bool,

    /// Whether GL_DEPTH_TEST is enabled
    pub enabled_depth_test: bool,

    /// Whether GL_DITHER is enabled
    pub enabled_dither: bool,

    /// Whether GL_POLYGON_OFFSET_FILL is enabled
    pub enabled_polygon_offset_fill: bool,

    /// Whether GL_SAMPLE_ALPHA_TO_COVERAGE is enabled
    pub enabled_sample_alpha_to_coverage: bool,

    /// Whether GL_SAMPLE_COVERAGE is enabled
    pub enabled_sample_coverage: bool,

    /// Whether GL_SCISSOR_TEST is enabled
    pub enabled_scissor_test: bool,

    /// Whether GL_STENCIL_TEST is enabled
    pub enabled_stencil_test: bool,

    // The latest value passed to `glUseProgram`.
    pub program: gl::types::GLuint,

    // The latest value passed to `glBindVertexArray`.
    pub vertex_array: gl::types::GLuint,

    // The latest value passed to `glClearColor`.
    pub clear_color: (gl::types::GLclampf, gl::types::GLclampf,
                      gl::types::GLclampf, gl::types::GLclampf),

    // The latest value passed to `glClearDepthf`.
    pub clear_depth: gl::types::GLclampf,

    // The latest value passed to `glClearStencil`.
    pub clear_stencil: gl::types::GLint,

    /// The latest buffer bound to `GL_ARRAY_BUFFER`.
    pub array_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_ELEMENT_ARRAY_BUFFER`.
    pub element_array_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_PIXEL_PACK_BUFFER`.
    pub pixel_pack_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_PIXEL_UNPACK_BUFFER`.
    pub pixel_unpack_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_READ_FRAMEBUFFER`.
    pub read_framebuffer: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_DRAW_FRAMEBUFFER`.
    pub draw_framebuffer: Option<gl::types::GLuint>,

    /// The latest render buffer bound with `glBindRenderbuffer`.
    pub renderbuffer: Option<gl::types::GLuint>,

    /// The latest values passed to `glBlendFunc`.
    pub blend_func: (gl::types::GLenum, gl::types::GLenum),

    /// The latest value passed to `glDepthFunc`.
    pub depth_func: gl::types::GLenum,

    /// The latest values passed to `glViewport`.
    pub viewport: (gl::types::GLint, gl::types::GLint, gl::types::GLsizei, gl::types::GLsizei),

    /// The latest value passed to `glLineWidth`.
    pub line_width: gl::types::GLfloat,

    /// The latest value passed to `glCullFace`.
    pub cull_face: gl::types::GLenum,

    /// The latest value passed to `glPolygonMode`.
    pub polygon_mode: gl::types::GLenum,
}

impl GLState {
    /// Builds the `GLState` corresponding to the default GL values.
    fn new_defaults(viewport: (gl::types::GLint, gl::types::GLint, gl::types::GLsizei,
        gl::types::GLsizei)) -> GLState
    {
        GLState {
            enabled_blend: false,
            enabled_cull_face: false,
            enabled_debug_output: None,
            enabled_debug_output_synchronous: false,
            enabled_depth_test: false,
            enabled_dither: false,
            enabled_polygon_offset_fill: false,
            enabled_sample_alpha_to_coverage: false,
            enabled_sample_coverage: false,
            enabled_scissor_test: false,
            enabled_stencil_test: false,

            program: 0,
            vertex_array: 0,
            clear_color: (0.0, 0.0, 0.0, 0.0),
            clear_depth: 1.0,
            clear_stencil: 0,
            array_buffer_binding: None,
            element_array_buffer_binding: None,
            pixel_pack_buffer_binding: None,
            pixel_unpack_buffer_binding: None,
            read_framebuffer: None,
            draw_framebuffer: None,
            renderbuffer: None,
            depth_func: gl::LESS,
            blend_func: (0, 0),     // no default specified
            viewport: viewport,
            line_width: 1.0,
            cull_face: gl::BACK,
            polygon_mode: gl::FILL,
        }
    }
}

/// Describes an OpenGL ctxt.version.
#[deriving(Show, Clone, PartialEq, Eq)]
pub struct GlVersion(pub u8, pub u8);

impl PartialOrd for GlVersion {
    fn partial_cmp(&self, other: &GlVersion) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for GlVersion {
    fn cmp(&self, other: &GlVersion) -> Ordering {
        match self.0.cmp(&other.0) {
            Equal => self.1.cmp(&other.1),
            a => a
        }
    }
}

/// Contains data about the list of extensions
pub struct ExtensionsList {
    /// GL_EXT_direct_state_access
    pub gl_ext_direct_state_access: bool,
    /// GL_EXT_framebuffer_object
    pub gl_ext_framebuffer_object: bool,
    /// GL_EXT_geometry_shader4
    pub gl_ext_geometry_shader4: bool,
    /// GL_EXT_framebuffer_blit
    pub gl_ext_framebuffer_blit: bool,
    /// GL_KHR_debug
    pub gl_khr_debug: bool,
    /// GL_NVX_gpu_memory_info
    pub gl_nvx_gpu_memory_info: bool,
    /// GL_ATI_meminfo
    pub gl_ati_meminfo: bool,
}

/// Represents the capabilities of the context.
pub struct Capabilities {
    /// True if the context supports left and right buffers.
    pub stereo: bool,
}

impl Context {
    pub fn new_from_window(window: glutin::WindowBuilder) -> Result<Context, GliumCreationError> {
        let (tx_events, rx_events) = channel();
        let (tx_commands, rx_commands) = channel();

        let dimensions = Arc::new((AtomicUint::new(800), AtomicUint::new(600)));

        let context = Context {
            commands: Mutex::new(tx_commands),
            events: Mutex::new(rx_events),
            dimensions: dimensions.clone(),
        };

        let (tx_success, rx_success) = channel();

        TaskBuilder::new().native().spawn(proc() {
            let window = match window.build() {
                Ok(w) => w,
                Err(e) => {
                    tx_success.send(Err(e));
                    return;
                }
            };

            unsafe { window.make_current(); }
            tx_success.send(Ok(()));

            let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol));

            // building the GLState and modifying to GL state to match it
            let mut gl_state = {
                let viewport = {
                    let dim = window.get_inner_size().unwrap();
                    dimensions.0.store(dim.0, Relaxed);
                    dimensions.1.store(dim.1, Relaxed);
                    (0, 0, dim.0 as gl::types::GLsizei, dim.1 as gl::types::GLsizei)
                };

                GLState::new_defaults(viewport)
            };

            // getting the GL version and extensions
            let opengl_es = false;
            let version = get_gl_version(&gl);
            let capabilities = get_capabilities(&gl, opengl_es);
            let extensions = get_extensions(&gl);

            // main loop
            'main: loop {
                // processing commands
                loop {
                    match rx_commands.recv_opt() {
                        Ok(Message::EndFrame) => break,
                        Ok(Message::Execute(cmd)) => cmd(CommandContext {
                            gl:&gl, state: &mut gl_state, version: &version, extensions: &extensions,
                            opengl_es: opengl_es, capabilities: &capabilities,
                        }),
                        Err(_) => break 'main
                    }
                }

                // this is necessary on Windows 8, or nothing is being displayed
                unsafe { gl.Flush(); }

                // swapping
                window.swap_buffers();

                // getting events
                for event in window.poll_events() {
                    // calling `glViewport` if the window has been resized
                    if let &glutin::Event::Resized(width, height) = &event {
                        dimensions.0.store(width, Relaxed);
                        dimensions.1.store(height, Relaxed);

                        if gl_state.viewport != (0, 0, width as gl::types::GLsizei,
                                                 height as gl::types::GLsizei)
                        {
                            unsafe {
                                gl.Viewport(0, 0, width as gl::types::GLsizei,
                                    height as gl::types::GLsizei);
                                gl_state.viewport = (0, 0, width as gl::types::GLsizei,
                                    height as gl::types::GLsizei);
                            }
                        }
                    }

                    // sending the event outside
                    if tx_events.send_opt(event.clone()).is_err() {
                        break 'main;
                    }
                }
            }
        });

        try!(rx_success.recv());
        Ok(context)
    }

    pub fn new_from_headless(window: glutin::HeadlessRendererBuilder)
        -> Result<Context, GliumCreationError>
    {
        let (_, rx_events) = channel();
        let (tx_commands, rx_commands) = channel();

        // TODO: fixme
        let dimensions = Arc::new((AtomicUint::new(800), AtomicUint::new(600)));

        let context = Context {
            commands: Mutex::new(tx_commands),
            events: Mutex::new(rx_events),
            dimensions: dimensions,
        };

        let (tx_success, rx_success) = channel();

        TaskBuilder::new().native().spawn(proc() {
            let window = match window.build() {
                Ok(w) => w,
                Err(e) => {
                    tx_success.send(Err(e));
                    return;
                }
            };
            unsafe { window.make_current(); }
            tx_success.send(Ok(()));

            let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol));

            // building the GLState, version, and extensions
            let mut gl_state = GLState::new_defaults((0, 0, 0, 0));    // FIXME:
            let opengl_es = false;
            let version = get_gl_version(&gl);
            let extensions = get_extensions(&gl);
            let capabilities = get_capabilities(&gl, opengl_es);

            loop {
                match rx_commands.recv_opt() {
                    Ok(Message::Execute(cmd)) => cmd(CommandContext {
                        gl:&gl, state: &mut gl_state, version: &version, extensions: &extensions,
                        opengl_es: opengl_es, capabilities: &capabilities,
                    }),
                    Ok(Message::EndFrame) => (),     // ignoring buffer swapping
                    Err(_) => break
                }
            }
        });

        try!(rx_success.recv());
        Ok(context)
    }

    pub fn get_framebuffer_dimensions(&self) -> (uint, uint) {
        (
            self.dimensions.0.load(Relaxed),
            self.dimensions.1.load(Relaxed),
        )
    }

    pub fn exec(&self, f: proc(CommandContext): Send) {
        self.commands.lock().send(Message::Execute(f));
    }

    pub fn swap_buffers(&self) {
        self.commands.lock().send(Message::EndFrame);
    }

    pub fn recv(&self) -> Vec<glutin::Event> {
        let events = self.events.lock();

        let mut result = Vec::new();
        loop {
            match events.try_recv() {
                Ok(ev) => result.push(ev),
                Err(_) => break
            }
        }
        result
    }
}

fn get_gl_version(gl: &gl::Gl) -> GlVersion {
    use std::c_str::CString;

    unsafe {
        let version = gl.GetString(gl::VERSION);
        let version = CString::new(version as *const i8, false);
        let version = version.as_str().expect("OpenGL version contains non-utf8 characters");

        let version = version.words().next().expect("glGetString(GL_VERSION) returned an empty \
                                                     string");

        let mut iter = version.split(|c: char| c == '.');
        let major = iter.next().unwrap();
        let minor = iter.next().expect("glGetString(GL_VERSION) did not return a correct version");

        GlVersion(
            from_str(major).expect("failed to parse GL major version"),
            from_str(minor).expect("failed to parse GL minor version"),
        )
    }
}

fn get_extensions_strings(gl: &gl::Gl) -> Vec<String> {
    use std::c_str::CString;

    unsafe {
        let list = gl.GetString(gl::EXTENSIONS);

        if list.is_null() {
            let mut num_extensions = 0;
            gl.GetIntegerv(gl::NUM_EXTENSIONS, &mut num_extensions);

            range(0, num_extensions).map(|num| {
                let ext = gl.GetStringi(gl::EXTENSIONS, num as gl::types::GLuint);
                let ext = CString::new(ext as *const i8, false);
                ext.as_str().expect("OpenGL extension contains non-utf8 characters").to_string()
            }).collect()

        } else {
            let list = CString::new(list as *const i8, false);
            let list = list.as_str()
                           .expect("List of OpenGL extensions contains non-utf8 characters");
            list.words().map(|e| e.to_string()).collect()
        }
    }
}

fn get_extensions(gl: &gl::Gl) -> ExtensionsList {
    let strings = get_extensions_strings(gl);

    let mut extensions = ExtensionsList {
        gl_ext_direct_state_access: false,
        gl_ext_framebuffer_object: false,
        gl_ext_geometry_shader4: false,
        gl_ext_framebuffer_blit: false,
        gl_khr_debug: false,
        gl_nvx_gpu_memory_info: false,
        gl_ati_meminfo: false,
    };

    for extension in strings.into_iter() {
        match extension.as_slice() {
            "GL_EXT_direct_state_access" => extensions.gl_ext_direct_state_access = true,
            "GL_EXT_framebuffer_object" => extensions.gl_ext_framebuffer_object = true,
            "GL_EXT_geometry_shader4" => extensions.gl_ext_geometry_shader4 = true,
            "GL_EXT_framebuffer_blit" => extensions.gl_ext_framebuffer_blit = true,
            "GL_KHR_debug" => extensions.gl_khr_debug = true,
            "GL_NVX_gpu_memory_info" => extensions.gl_nvx_gpu_memory_info = true,
            "GL_ATI_meminfo" => extensions.gl_ati_meminfo = true,
            _ => ()
        }
    }

    extensions
}

fn get_capabilities(gl: &gl::Gl, gl_es: bool) -> Capabilities {
    Capabilities {
        stereo: unsafe {
            if gl_es {
                false
            } else {
                use std::mem;
                let mut val: gl::types::GLboolean = mem::uninitialized();
                gl.GetBooleanv(gl::STEREO, &mut val);
                val != 0
            }
        }
    }
}
<commit_msg>Calling glViewport at initialization<commit_after>use gl;
use glutin;
use native::NativeTaskBuilder;
use std::sync::atomic::{AtomicUint, Relaxed};
use std::sync::{Arc, Mutex};
use std::task::TaskBuilder;
use GliumCreationError;

enum Message {
    EndFrame,
    Execute(proc(CommandContext):Send),
}

pub struct Context {
    commands: Mutex<Sender<Message>>,
    events: Mutex<Receiver<glutin::Event>>,

    /// Dimensions of the frame buffer.
    dimensions: Arc<(AtomicUint, AtomicUint)>,
}

pub struct CommandContext<'a, 'b> {
    pub gl: &'a gl::Gl,
    pub state: &'b mut GLState,
    pub version: &'a GlVersion,
    pub extensions: &'a ExtensionsList,
    pub opengl_es: bool,
    pub capabilities: &'a Capabilities,
}

/// Represents the current OpenGL ctxt.state.
/// The current state is passed to each function and can be freely updated.
pub struct GLState {
    /// Whether GL_BLEND is enabled
    pub enabled_blend: bool,

    /// Whether GL_CULL_FACE is enabled
    pub enabled_cull_face: bool,

    /// Whether GL_DEBUG_OUTPUT is enabled. None means "unknown".
    pub enabled_debug_output: Option<bool>,

    /// Whether GL_DEBUG_OUTPUT_SYNCHRONOUS is enabled
    pub enabled_debug_output_synchronous: bool,

    /// Whether GL_DEPTH_TEST is enabled
    pub enabled_depth_test: bool,

    /// Whether GL_DITHER is enabled
    pub enabled_dither: bool,

    /// Whether GL_POLYGON_OFFSET_FILL is enabled
    pub enabled_polygon_offset_fill: bool,

    /// Whether GL_SAMPLE_ALPHA_TO_COVERAGE is enabled
    pub enabled_sample_alpha_to_coverage: bool,

    /// Whether GL_SAMPLE_COVERAGE is enabled
    pub enabled_sample_coverage: bool,

    /// Whether GL_SCISSOR_TEST is enabled
    pub enabled_scissor_test: bool,

    /// Whether GL_STENCIL_TEST is enabled
    pub enabled_stencil_test: bool,

    // The latest value passed to `glUseProgram`.
    pub program: gl::types::GLuint,

    // The latest value passed to `glBindVertexArray`.
    pub vertex_array: gl::types::GLuint,

    // The latest value passed to `glClearColor`.
    pub clear_color: (gl::types::GLclampf, gl::types::GLclampf,
                      gl::types::GLclampf, gl::types::GLclampf),

    // The latest value passed to `glClearDepthf`.
    pub clear_depth: gl::types::GLclampf,

    // The latest value passed to `glClearStencil`.
    pub clear_stencil: gl::types::GLint,

    /// The latest buffer bound to `GL_ARRAY_BUFFER`.
    pub array_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_ELEMENT_ARRAY_BUFFER`.
    pub element_array_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_PIXEL_PACK_BUFFER`.
    pub pixel_pack_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_PIXEL_UNPACK_BUFFER`.
    pub pixel_unpack_buffer_binding: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_READ_FRAMEBUFFER`.
    pub read_framebuffer: Option<gl::types::GLuint>,

    /// The latest buffer bound to `GL_DRAW_FRAMEBUFFER`.
    pub draw_framebuffer: Option<gl::types::GLuint>,

    /// The latest render buffer bound with `glBindRenderbuffer`.
    pub renderbuffer: Option<gl::types::GLuint>,

    /// The latest values passed to `glBlendFunc`.
    pub blend_func: (gl::types::GLenum, gl::types::GLenum),

    /// The latest value passed to `glDepthFunc`.
    pub depth_func: gl::types::GLenum,

    /// The latest values passed to `glViewport`.
    pub viewport: (gl::types::GLint, gl::types::GLint, gl::types::GLsizei, gl::types::GLsizei),

    /// The latest value passed to `glLineWidth`.
    pub line_width: gl::types::GLfloat,

    /// The latest value passed to `glCullFace`.
    pub cull_face: gl::types::GLenum,

    /// The latest value passed to `glPolygonMode`.
    pub polygon_mode: gl::types::GLenum,
}

impl GLState {
    /// Builds the `GLState` corresponding to the default GL values.
    fn new_defaults(viewport: (gl::types::GLint, gl::types::GLint, gl::types::GLsizei,
        gl::types::GLsizei)) -> GLState
    {
        GLState {
            enabled_blend: false,
            enabled_cull_face: false,
            enabled_debug_output: None,
            enabled_debug_output_synchronous: false,
            enabled_depth_test: false,
            enabled_dither: false,
            enabled_polygon_offset_fill: false,
            enabled_sample_alpha_to_coverage: false,
            enabled_sample_coverage: false,
            enabled_scissor_test: false,
            enabled_stencil_test: false,

            program: 0,
            vertex_array: 0,
            clear_color: (0.0, 0.0, 0.0, 0.0),
            clear_depth: 1.0,
            clear_stencil: 0,
            array_buffer_binding: None,
            element_array_buffer_binding: None,
            pixel_pack_buffer_binding: None,
            pixel_unpack_buffer_binding: None,
            read_framebuffer: None,
            draw_framebuffer: None,
            renderbuffer: None,
            depth_func: gl::LESS,
            blend_func: (0, 0),     // no default specified
            viewport: viewport,
            line_width: 1.0,
            cull_face: gl::BACK,
            polygon_mode: gl::FILL,
        }
    }
}

/// Describes an OpenGL ctxt.version.
#[deriving(Show, Clone, PartialEq, Eq)]
pub struct GlVersion(pub u8, pub u8);

impl PartialOrd for GlVersion {
    fn partial_cmp(&self, other: &GlVersion) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for GlVersion {
    fn cmp(&self, other: &GlVersion) -> Ordering {
        match self.0.cmp(&other.0) {
            Equal => self.1.cmp(&other.1),
            a => a
        }
    }
}

/// Contains data about the list of extensions
pub struct ExtensionsList {
    /// GL_EXT_direct_state_access
    pub gl_ext_direct_state_access: bool,
    /// GL_EXT_framebuffer_object
    pub gl_ext_framebuffer_object: bool,
    /// GL_EXT_geometry_shader4
    pub gl_ext_geometry_shader4: bool,
    /// GL_EXT_framebuffer_blit
    pub gl_ext_framebuffer_blit: bool,
    /// GL_KHR_debug
    pub gl_khr_debug: bool,
    /// GL_NVX_gpu_memory_info
    pub gl_nvx_gpu_memory_info: bool,
    /// GL_ATI_meminfo
    pub gl_ati_meminfo: bool,
}

/// Represents the capabilities of the context.
pub struct Capabilities {
    /// True if the context supports left and right buffers.
    pub stereo: bool,
}

impl Context {
    pub fn new_from_window(window: glutin::WindowBuilder) -> Result<Context, GliumCreationError> {
        let (tx_events, rx_events) = channel();
        let (tx_commands, rx_commands) = channel();

        let dimensions = Arc::new((AtomicUint::new(800), AtomicUint::new(600)));

        let context = Context {
            commands: Mutex::new(tx_commands),
            events: Mutex::new(rx_events),
            dimensions: dimensions.clone(),
        };

        let (tx_success, rx_success) = channel();

        TaskBuilder::new().native().spawn(proc() {
            let window = match window.build() {
                Ok(w) => w,
                Err(e) => {
                    tx_success.send(Err(e));
                    return;
                }
            };

            unsafe { window.make_current(); }
            tx_success.send(Ok(()));

            let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol));

            // building the GLState and modifying to GL state to match it
            let mut gl_state = {
                let viewport = {
                    let dim = window.get_inner_size().unwrap();
                    dimensions.0.store(dim.0, Relaxed);
                    dimensions.1.store(dim.1, Relaxed);
                    (0, 0, dim.0 as gl::types::GLsizei, dim.1 as gl::types::GLsizei)
                };

                unsafe { gl.Viewport(viewport.0, viewport.1, viewport.2, viewport.3) };
                GLState::new_defaults(viewport)
            };

            // getting the GL version and extensions
            let opengl_es = false;
            let version = get_gl_version(&gl);
            let capabilities = get_capabilities(&gl, opengl_es);
            let extensions = get_extensions(&gl);

            // main loop
            'main: loop {
                // processing commands
                loop {
                    match rx_commands.recv_opt() {
                        Ok(Message::EndFrame) => break,
                        Ok(Message::Execute(cmd)) => cmd(CommandContext {
                            gl:&gl, state: &mut gl_state, version: &version, extensions: &extensions,
                            opengl_es: opengl_es, capabilities: &capabilities,
                        }),
                        Err(_) => break 'main
                    }
                }

                // this is necessary on Windows 8, or nothing is being displayed
                unsafe { gl.Flush(); }

                // swapping
                window.swap_buffers();

                // getting events
                for event in window.poll_events() {
                    // calling `glViewport` if the window has been resized
                    if let &glutin::Event::Resized(width, height) = &event {
                        dimensions.0.store(width, Relaxed);
                        dimensions.1.store(height, Relaxed);

                        if gl_state.viewport != (0, 0, width as gl::types::GLsizei,
                                                 height as gl::types::GLsizei)
                        {
                            unsafe {
                                gl.Viewport(0, 0, width as gl::types::GLsizei,
                                    height as gl::types::GLsizei);
                                gl_state.viewport = (0, 0, width as gl::types::GLsizei,
                                    height as gl::types::GLsizei);
                            }
                        }
                    }

                    // sending the event outside
                    if tx_events.send_opt(event.clone()).is_err() {
                        break 'main;
                    }
                }
            }
        });

        try!(rx_success.recv());
        Ok(context)
    }

    pub fn new_from_headless(window: glutin::HeadlessRendererBuilder)
        -> Result<Context, GliumCreationError>
    {
        let (_, rx_events) = channel();
        let (tx_commands, rx_commands) = channel();

        // TODO: fixme
        let dimensions = Arc::new((AtomicUint::new(800), AtomicUint::new(600)));

        let context = Context {
            commands: Mutex::new(tx_commands),
            events: Mutex::new(rx_events),
            dimensions: dimensions,
        };

        let (tx_success, rx_success) = channel();

        TaskBuilder::new().native().spawn(proc() {
            let window = match window.build() {
                Ok(w) => w,
                Err(e) => {
                    tx_success.send(Err(e));
                    return;
                }
            };
            unsafe { window.make_current(); }
            tx_success.send(Ok(()));

            let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol));
            // TODO: call glViewport

            // building the GLState, version, and extensions
            let mut gl_state = GLState::new_defaults((0, 0, 0, 0));    // FIXME:
            let opengl_es = false;
            let version = get_gl_version(&gl);
            let extensions = get_extensions(&gl);
            let capabilities = get_capabilities(&gl, opengl_es);

            loop {
                match rx_commands.recv_opt() {
                    Ok(Message::Execute(cmd)) => cmd(CommandContext {
                        gl:&gl, state: &mut gl_state, version: &version, extensions: &extensions,
                        opengl_es: opengl_es, capabilities: &capabilities,
                    }),
                    Ok(Message::EndFrame) => (),     // ignoring buffer swapping
                    Err(_) => break
                }
            }
        });

        try!(rx_success.recv());
        Ok(context)
    }

    pub fn get_framebuffer_dimensions(&self) -> (uint, uint) {
        (
            self.dimensions.0.load(Relaxed),
            self.dimensions.1.load(Relaxed),
        )
    }

    pub fn exec(&self, f: proc(CommandContext): Send) {
        self.commands.lock().send(Message::Execute(f));
    }

    pub fn swap_buffers(&self) {
        self.commands.lock().send(Message::EndFrame);
    }

    pub fn recv(&self) -> Vec<glutin::Event> {
        let events = self.events.lock();

        let mut result = Vec::new();
        loop {
            match events.try_recv() {
                Ok(ev) => result.push(ev),
                Err(_) => break
            }
        }
        result
    }
}

fn get_gl_version(gl: &gl::Gl) -> GlVersion {
    use std::c_str::CString;

    unsafe {
        let version = gl.GetString(gl::VERSION);
        let version = CString::new(version as *const i8, false);
        let version = version.as_str().expect("OpenGL version contains non-utf8 characters");

        let version = version.words().next().expect("glGetString(GL_VERSION) returned an empty \
                                                     string");

        let mut iter = version.split(|c: char| c == '.');
        let major = iter.next().unwrap();
        let minor = iter.next().expect("glGetString(GL_VERSION) did not return a correct version");

        GlVersion(
            from_str(major).expect("failed to parse GL major version"),
            from_str(minor).expect("failed to parse GL minor version"),
        )
    }
}

fn get_extensions_strings(gl: &gl::Gl) -> Vec<String> {
    use std::c_str::CString;

    unsafe {
        let list = gl.GetString(gl::EXTENSIONS);

        if list.is_null() {
            let mut num_extensions = 0;
            gl.GetIntegerv(gl::NUM_EXTENSIONS, &mut num_extensions);

            range(0, num_extensions).map(|num| {
                let ext = gl.GetStringi(gl::EXTENSIONS, num as gl::types::GLuint);
                let ext = CString::new(ext as *const i8, false);
                ext.as_str().expect("OpenGL extension contains non-utf8 characters").to_string()
            }).collect()

        } else {
            let list = CString::new(list as *const i8, false);
            let list = list.as_str()
                           .expect("List of OpenGL extensions contains non-utf8 characters");
            list.words().map(|e| e.to_string()).collect()
        }
    }
}

fn get_extensions(gl: &gl::Gl) -> ExtensionsList {
    let strings = get_extensions_strings(gl);

    let mut extensions = ExtensionsList {
        gl_ext_direct_state_access: false,
        gl_ext_framebuffer_object: false,
        gl_ext_geometry_shader4: false,
        gl_ext_framebuffer_blit: false,
        gl_khr_debug: false,
        gl_nvx_gpu_memory_info: false,
        gl_ati_meminfo: false,
    };

    for extension in strings.into_iter() {
        match extension.as_slice() {
            "GL_EXT_direct_state_access" => extensions.gl_ext_direct_state_access = true,
            "GL_EXT_framebuffer_object" => extensions.gl_ext_framebuffer_object = true,
            "GL_EXT_geometry_shader4" => extensions.gl_ext_geometry_shader4 = true,
            "GL_EXT_framebuffer_blit" => extensions.gl_ext_framebuffer_blit = true,
            "GL_KHR_debug" => extensions.gl_khr_debug = true,
            "GL_NVX_gpu_memory_info" => extensions.gl_nvx_gpu_memory_info = true,
            "GL_ATI_meminfo" => extensions.gl_ati_meminfo = true,
            _ => ()
        }
    }

    extensions
}

fn get_capabilities(gl: &gl::Gl, gl_es: bool) -> Capabilities {
    Capabilities {
        stereo: unsafe {
            if gl_es {
                false
            } else {
                use std::mem;
                let mut val: gl::types::GLboolean = mem::uninitialized();
                gl.GetBooleanv(gl::STEREO, &mut val);
                val != 0
            }
        }
    }
}
<|endoftext|>


<commit_before>// This is a regression test that the metadata for the
// name_pool::methods impl in the other crate is reachable from this
// crate.

// aux-build:crate-method-reexport-grrrrrrr2.rs

use crate_method_reexport_grrrrrrr2;

fn main() {
    import crate_method_reexport_grrrrrrr2::rust::methods;
    let x = @();
    x.cx();
    let y = ();
    y.add("hi");
}<commit_msg>add xfail-fast directive<commit_after>// This is a regression test that the metadata for the
// name_pool::methods impl in the other crate is reachable from this
// crate.

// xfail-fast
// aux-build:crate-method-reexport-grrrrrrr2.rs

use crate_method_reexport_grrrrrrr2;

fn main() {
    import crate_method_reexport_grrrrrrr2::rust::methods;
    let x = @();
    x.cx();
    let y = ();
    y.add("hi");
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for issue #16791<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Test that unboxed closures in contexts with free type parameters
// monomorphize correctly (issue #16791)

#![feature(unboxed_closures)]

fn main(){
    fn bar<'a, T:'a> (t: T) -> Box<FnOnce<(),T> + 'a> {
        box move |:| t
    }

    let f = bar(42u);
    assert_eq!(f.call_once(()), 42);

    let f = bar("forty-two");
    assert_eq!(f.call_once(()), "forty-two");

    let x = 42u;
    let f = bar(&x);
    assert_eq!(f.call_once(()), &x);

    #[deriving(Show, PartialEq)]
    struct Foo(uint, &'static str);
    let x = Foo(42, "forty-two");
    let f = bar(x);
    assert_eq!(f.call_once(()), x);
}
<|endoftext|>


<commit_before><commit_msg>Change isr handler to print exception number<commit_after><|endoftext|>


<commit_before><commit_msg>Overloaded_calls is included with unboxed_closures<commit_after><|endoftext|>


<commit_before><commit_msg>Added support for integer division and multiplication<commit_after><|endoftext|>


<commit_before><commit_msg>Fix node splitting and add additional test<commit_after><|endoftext|>


<commit_before><commit_msg>Re-export error::Result<commit_after><|endoftext|>


<commit_before><commit_msg>Added bottom_up_iter to Expression and tweaked Ruleset a bit.<commit_after><|endoftext|>


<commit_before><commit_msg>treemap -> btreemap<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed missing docs warning<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor query building<commit_after><|endoftext|>


<commit_before><commit_msg>comment formatting<commit_after><|endoftext|>


<commit_before><commit_msg>Updated API doc<commit_after><|endoftext|>


<commit_before><commit_msg>Add more cookie match tests, fix discovered logic bug.<commit_after><|endoftext|>


<commit_before><commit_msg>add tests for email confirmation<commit_after><|endoftext|>


<commit_before><commit_msg>`eth_accounts` returned account from client, should return local keyfiles Added functionality to parse keystore directory. `eth_accounts` return local keystore files<commit_after><|endoftext|>


<commit_before><commit_msg>Little change<commit_after><|endoftext|>


<commit_before><commit_msg>Sync Redox and Unix sys modules<commit_after><|endoftext|>


<commit_before><commit_msg>Inline pixel drawing routines<commit_after><|endoftext|>


<commit_before><commit_msg>workers<commit_after>use std::{time, thread};
use std::sync::mpsc;
use fabric::FabricMsg;
use rand::{thread_rng, Rng};

pub enum WorkerMsg {
    Fabric(FabricMsg),
    Tick(time::SystemTime),
    Request,
    Done,
}

pub struct WorkerManager {
    ticker_interval: time::Duration,
    ticker_thread: Option<thread::JoinHandle<()>>,
    ticker_chan: mpsc::Sender<()>,
    threads: Vec<Option<thread::JoinHandle<()>>>,
    channels: Vec<mpsc::Sender<WorkerMsg>>,
}

impl WorkerManager {
    pub fn new<F>(thread_count: usize, fun: F, ticker_interval: time::Duration) -> Self
        where F: FnOnce(mpsc::Receiver<WorkerMsg>) + Clone + Send + 'static
    {
        assert!(thread_count > 0);
        let mut threads = Vec::new();
        let mut channels = Vec::new();
        for _ in 0..thread_count {
            let fun_cloned = fun.clone();
            let (tx, rx) = mpsc::channel();
            threads.push(Some(thread::spawn(move || fun_cloned(rx))));
            channels.push(tx);
        }
        let channels_cloned = channels.clone();
        let (ticker_tx, ticker_rx) = mpsc::channel();
        let ticker_thread = thread::spawn(move || {
            loop {
                thread::sleep(ticker_interval);
                if ticker_rx.try_recv().is_ok() {
                    break;
                }
                let now = time::SystemTime::now();
                for chan in &channels {
                    chan.send(WorkerMsg::Tick(now)).unwrap();
                }
            }
        });
        WorkerManager {
            ticker_interval: ticker_interval,
            ticker_thread: Some(ticker_thread),
            ticker_chan: ticker_tx,
            threads: threads,
            channels: channels_cloned,
        }
    }

    pub fn send(&self, msg: WorkerMsg) {
        thread_rng().choose(&self.channels).unwrap().send(msg).unwrap();
    }
}

impl Drop for WorkerManager {
    fn drop(&mut self) {
        self.ticker_chan.send(()).unwrap();
        for chan in &self.channels {
            chan.send(WorkerMsg::Done).unwrap();
        }
        self.ticker_thread.take().map(|t| t.join());
        for to in &mut self.threads {
            to.take().map(|t| t.join());
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>remove unused import, vars shouldn't be mutable if not explicitly needed<commit_after><|endoftext|>


<commit_before><commit_msg>fix typo<commit_after><|endoftext|>