<commit_before>use errors::crypto::CryptoError;
use services::crypto::anoncreds::constants::{
    LARGE_PRIME,
    LARGE_VPRIME_PRIME
};
use services::crypto::anoncreds::types::{
    Attribute,
    ByteOrder,
    PublicKey,
    Schema,
    SecretKey
};
use services::crypto::helpers::{
    random_qr,
    bitwise_or_big_int
};
use services::crypto::wrappers::bn::BigNumber;

use std::collections::HashMap;

pub struct Issuer {

}

impl Issuer {
    pub fn new() -> Issuer {
        Issuer {}
    }
    pub fn generate_keys(&self, schema: &Schema) -> Result<((PublicKey, SecretKey)), CryptoError> {
        //(Issuer::_generate_keys(&schema));
        unimplemented!();
    }

    pub fn create_claim() {

    }

    fn _generate_keys(schema: &Schema) -> Result<(PublicKey, SecretKey), CryptoError> {
        let bn = try!(BigNumber::new());
        let p = try!(bn.generate_safe_prime(LARGE_PRIME));
        let q = try!(bn.generate_safe_prime(LARGE_PRIME));

        let mut p_prime = try!(p.sub(&try!(BigNumber::from_u32(1))));
        try!(p_prime.div_word(2));

        let mut q_prime = try!(q.sub(&try!(BigNumber::from_u32(1))));
        try!(q_prime.div_word(2));

        let n = try!(p.mul(&q, None));
        let s = try!(random_qr(&n));
        let xz = try!(Issuer::_gen_x(&p_prime, &q_prime));
        let mut r: HashMap<String, BigNumber> = HashMap::new();

        for attribute in &schema.attribute_names {
            let random = try!(Issuer::_gen_x(&p_prime, &q_prime));
            r.insert(attribute.to_string(), try!(s.mod_exp(&random, &n, None)));
        }

        let z = try!(s.mod_exp(&xz, &n, None));

        let rms = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        let rctxt = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        Ok((
            PublicKey {
                n: n,
                rms: rms,
                rctxt: rctxt,
                r: r,
                s: s,
                z: z
            },
            SecretKey {
                p: p_prime,
                q: q_prime
            }
        ))
    }

    fn _generate_revocation_keys() {

    }

    fn _issuer_primary_claim(&self) {

    }

    fn _encode_attribute(attribute: &str, byte_order: ByteOrder) -> Result<String, CryptoError> {
        let mut result = try!(BigNumber::hash(&attribute.as_bytes()));
        let index = result.iter().position(|&value| value == 0);
        if let Some(position) = index {
            result.truncate(position);
        }
        if let ByteOrder::Little = byte_order {
            result.reverse();
        }
        let encoded_attribute = try!(BigNumber::from_bytes(&result));
        Ok(try!(encoded_attribute.to_dec()).to_string())
    }

    fn _encode_attributes(attributes: &Vec<Attribute>) -> Result<HashMap<String, String>, CryptoError> {
        let mut encoded_attributes: HashMap<String, String> = HashMap::new();
        for i in attributes {
            if i.encode {
                encoded_attributes.insert(i.name.clone(), try!(Issuer::_encode_attribute(&i.value, ByteOrder::Big)));
            }
                else {
                    encoded_attributes.insert(i.name.clone(), i.value.clone());
                }
        }
        Ok(encoded_attributes)
    }

//    fn issue_primary_claim(attributes: &Vec<AttributeType>, u: &BigNum, accumulator_id: &str, user_id: &str) {
//        let mut ctx = BigNumContext::new().unwrap();
//        let vprimeprime = AnoncredsService::generate_vprimeprime();
//        let (mut e_start, mut e_end) = (BigNum::new().unwrap(), BigNum::new().unwrap());
//        e_start.exp(&BigNum::from_u32(2).unwrap(), &BigNum::from_u32(LARGE_E_START as u32).unwrap(), &mut ctx);
//        e_end.exp(&BigNum::from_u32(2).unwrap(), &BigNum::from_u32(LARGE_E_END_RANGE as u32).unwrap(), &mut ctx);
//        e_end = &e_start + &e_end;
//        let e = AnoncredsService::generate_prime_in_range(&e_start, &e_end).unwrap();
//        let encoded_attributes = AnoncredsService::encode_attributes(attributes);
//        let m2 = AnoncredsService::generate_context(accumulator_id, user_id);
//    }

    fn _gen_x(p: &BigNumber, q: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut value = try!(p.mul(&q, None));
        try!(value.sub_word(3));

        let mut result = try!(value.rand_range());
        try!(result.add_word(2));
        Ok(result)
    }

    fn _generate_v_prime_prime() -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNumber::new());
        let a = try!(bn.rand(LARGE_VPRIME_PRIME));
        let mut b = try!(BigNumber::from_u32(2));
        b = try!(b.exp(&try!(BigNumber::from_u32((LARGE_VPRIME_PRIME - 1) as u32)), None));
        let v_prime_prime = try!(bitwise_or_big_int(&a, &b));
        Ok(v_prime_prime)
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn encode_attribute_works() {
        let test_str_one = "Alexer5435";
        let test_str_two = "Alexer";
        let test_answer_one = "62794";
        let test_answer_two = "93838255634171043313693932530283701522875554780708470423762684802192372035729";
        assert_eq!(test_answer_one, Issuer::_encode_attribute(test_str_one, ByteOrder::Big).unwrap());
        assert_eq!(test_answer_two, Issuer::_encode_attribute(test_str_two, ByteOrder::Big).unwrap());
    }

    #[test]
    fn encode_attributes_works() {
        assert_eq!(mocks::get_encoded_attributes(), Issuer::_encode_attributes(&mocks::get_attributes()).unwrap());
    }
}

mod mocks {
    use super::*;

    pub fn get_attributes() -> Vec<Attribute> {
        let attributes: Vec<Attribute> = vec![
            Attribute {
                name: "name".to_string(),
                value: "Alex".to_string(),
                encode: true
            },
            Attribute {
                name: "age".to_string(),
                value: "28".to_string(),
                encode: false
            },
            Attribute {
                name: "sex".to_string(),
                value: "male".to_string(),
                encode: true
            },
            Attribute {
                name: "height".to_string(),
                value: "175".to_string(),
                encode: false
            }
        ];
        attributes
    }

    pub fn get_encoded_attributes() -> HashMap<String, String> {
        let mut encoded_attributes: HashMap<String, String> = HashMap::new();
        encoded_attributes.insert("name".to_string(),
                                  "1139481716457488690172217916278103335".to_string());
        encoded_attributes.insert("age".to_string(), "28".to_string());
        encoded_attributes.insert(
            "sex".to_string(),
            "5944657099558967239210949258394887428692050081607692519917050011144233115103".to_string());
        encoded_attributes.insert("height".to_string(), "175".to_string());
        encoded_attributes
    }
}<commit_msg>added generate_context_attribute function<commit_after>use errors::crypto::CryptoError;
use services::crypto::anoncreds::constants::{
    LARGE_MASTER_SECRET,
    LARGE_PRIME,
    LARGE_VPRIME_PRIME
};
use services::crypto::anoncreds::types::{
    Attribute,
    ByteOrder,
    PublicKey,
    Schema,
    SecretKey
};
use services::crypto::helpers::{
    random_qr,
    bitwise_or_big_int,
    get_hash_as_int
};
use services::crypto::wrappers::bn::BigNumber;

use std::collections::HashMap;

pub struct Issuer {

}

impl Issuer {
    pub fn new() -> Issuer {
        Issuer {}
    }
    pub fn generate_keys(&self, schema: &Schema) -> Result<((PublicKey, SecretKey)), CryptoError> {
        //(Issuer::_generate_keys(&schema));
        unimplemented!();
    }

    pub fn create_claim() {

    }

    fn _generate_keys(schema: &Schema) -> Result<(PublicKey, SecretKey), CryptoError> {
        let bn = try!(BigNumber::new());
        let p = try!(bn.generate_safe_prime(LARGE_PRIME));
        let q = try!(bn.generate_safe_prime(LARGE_PRIME));

        let mut p_prime = try!(p.sub(&try!(BigNumber::from_u32(1))));
        try!(p_prime.div_word(2));

        let mut q_prime = try!(q.sub(&try!(BigNumber::from_u32(1))));
        try!(q_prime.div_word(2));

        let n = try!(p.mul(&q, None));
        let s = try!(random_qr(&n));
        let xz = try!(Issuer::_gen_x(&p_prime, &q_prime));
        let mut r: HashMap<String, BigNumber> = HashMap::new();

        for attribute in &schema.attribute_names {
            let random = try!(Issuer::_gen_x(&p_prime, &q_prime));
            r.insert(attribute.to_string(), try!(s.mod_exp(&random, &n, None)));
        }

        let z = try!(s.mod_exp(&xz, &n, None));

        let rms = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        let rctxt = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        Ok((
            PublicKey {
                n: n,
                rms: rms,
                rctxt: rctxt,
                r: r,
                s: s,
                z: z
            },
            SecretKey {
                p: p_prime,
                q: q_prime
            }
        ))
    }

    fn _generate_revocation_keys() {

    }

    fn _issuer_primary_claim(&self) {

    }

    //    fn issue_primary_claim(attributes: &Vec<AttributeType>, u: &BigNum, accumulator_id: &str, user_id: &str) {
    //        let mut ctx = BigNumContext::new().unwrap();
    //        let vprimeprime = AnoncredsService::generate_vprimeprime();
    //        let (mut e_start, mut e_end) = (BigNum::new().unwrap(), BigNum::new().unwrap());
    //        e_start.exp(&BigNum::from_u32(2).unwrap(), &BigNum::from_u32(LARGE_E_START as u32).unwrap(), &mut ctx);
    //        e_end.exp(&BigNum::from_u32(2).unwrap(), &BigNum::from_u32(LARGE_E_END_RANGE as u32).unwrap(), &mut ctx);
    //        e_end = &e_start + &e_end;
    //        let e = AnoncredsService::generate_prime_in_range(&e_start, &e_end).unwrap();
    //        let encoded_attributes = AnoncredsService::encode_attributes(attributes);
    //        let m2 = AnoncredsService::generate_context(accumulator_id, user_id);
    //    }

    fn _generate_context_attribute(accumulator_id: &String, user_id: &String) -> Result<BigNumber, CryptoError> {
        let accumulator_id_encoded = try!(Issuer::_encode_attribute(&accumulator_id, ByteOrder::Little));
        let user_id_encoded = try!(Issuer::_encode_attribute(&user_id, ByteOrder::Little));
        let mut s = vec![try!(bitwise_or_big_int(
            &try!(BigNumber::from_dec(&accumulator_id_encoded)),
            &try!(BigNumber::from_dec(&user_id_encoded))
        ))];
        let mut h = try!(get_hash_as_int(&mut s));
        let mut pow_2 = try!(BigNumber::from_u32(2));
        pow_2 = try!(pow_2.exp(&try!(BigNumber::from_u32(LARGE_MASTER_SECRET as u32)), None));
        h = try!(h.modulus(&pow_2, None));
        Ok(h)
    }

    fn _sign() {
        unimplemented!()
    }

    fn _encode_attribute(attribute: &str, byte_order: ByteOrder) -> Result<String, CryptoError> {
        let mut result = try!(BigNumber::hash(&attribute.as_bytes()));
        let index = result.iter().position(|&value| value == 0);
        if let Some(position) = index {
            result.truncate(position);
        }
        if let ByteOrder::Little = byte_order {
            result.reverse();
        }
        let encoded_attribute = try!(BigNumber::from_bytes(&result));
        Ok(try!(encoded_attribute.to_dec()).to_string())
    }

    fn _encode_attributes(attributes: &Vec<Attribute>) -> Result<HashMap<String, String>, CryptoError> {
        let mut encoded_attributes: HashMap<String, String> = HashMap::new();
        for i in attributes {
            if i.encode {
                encoded_attributes.insert(i.name.clone(), try!(Issuer::_encode_attribute(&i.value, ByteOrder::Big)));
            }
                else {
                    encoded_attributes.insert(i.name.clone(), i.value.clone());
                }
        }
        Ok(encoded_attributes)
    }

    fn _gen_x(p: &BigNumber, q: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut value = try!(p.mul(&q, None));
        try!(value.sub_word(3));

        let mut result = try!(value.rand_range());
        try!(result.add_word(2));
        Ok(result)
    }

    fn _generate_v_prime_prime() -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNumber::new());
        let a = try!(bn.rand(LARGE_VPRIME_PRIME));
        let mut b = try!(BigNumber::from_u32(2));
        b = try!(b.exp(&try!(BigNumber::from_u32((LARGE_VPRIME_PRIME - 1) as u32)), None));
        let v_prime_prime = try!(bitwise_or_big_int(&a, &b));
        Ok(v_prime_prime)
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn encode_attribute_works_short_hash() {
        let test_str = "Alexer5435";
        let test_answer = "62794";
        assert_eq!(test_answer, Issuer::_encode_attribute(test_str, ByteOrder::Big).unwrap());
    }

    #[test]
    fn encode_attribute_works_long_hash() {
        let test_str = "Alexer";
        let test_answer = "93838255634171043313693932530283701522875554780708470423762684802192372035729";
        assert_eq!(test_answer, Issuer::_encode_attribute(test_str, ByteOrder::Big).unwrap());
    }

    #[test]
    fn encode_attributes_works() {
        assert_eq!(mocks::get_encoded_attributes(), Issuer::_encode_attributes(&mocks::get_attributes()).unwrap());
    }

    #[test]
    fn generate_context_attribute_works() {
        let accumulator_id = "110".to_string();
        let user_id = "111".to_string();
        let answer = BigNumber::from_dec("59059690488564137142247698318091397258460906844819605876079330034815387295451").unwrap();
        let result = Issuer::_generate_context_attribute(&accumulator_id, &user_id).unwrap();
        assert_eq!(result, answer);
    }
}

mod mocks {
    use super::*;

    pub fn get_attributes() -> Vec<Attribute> {
        let attributes: Vec<Attribute> = vec![
            Attribute {
                name: "name".to_string(),
                value: "Alex".to_string(),
                encode: true
            },
            Attribute {
                name: "age".to_string(),
                value: "28".to_string(),
                encode: false
            },
            Attribute {
                name: "sex".to_string(),
                value: "male".to_string(),
                encode: true
            },
            Attribute {
                name: "height".to_string(),
                value: "175".to_string(),
                encode: false
            }
        ];
        attributes
    }

    pub fn get_encoded_attributes() -> HashMap<String, String> {
        let mut encoded_attributes: HashMap<String, String> = HashMap::new();
        encoded_attributes.insert("name".to_string(),
                                  "1139481716457488690172217916278103335".to_string());
        encoded_attributes.insert("age".to_string(), "28".to_string());
        encoded_attributes.insert(
            "sex".to_string(),
            "5944657099558967239210949258394887428692050081607692519917050011144233115103".to_string());
        encoded_attributes.insert("height".to_string(), "175".to_string());
        encoded_attributes
    }
}<|endoftext|>


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

#![warn(overflowing_literals)]
#![warn(const_err)]
// compile-pass

#[allow(unused_variables)]

fn main() {
    let x2: i8 = --128; //~ warn: literal out of range for i8

    let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32
    let x =  3.40282357e+38_f32; //~ warn: literal out of range for f32
    let x = -1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
    let x =  1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
}
<commit_msg>work around deviation in diagnostic output for opt-level=0 by forcing `-O`.<commit_after>// Copyright 2013 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.

// compile-flags: -O
#![warn(overflowing_literals)]
#![warn(const_err)]
// compile-pass

#[allow(unused_variables)]

fn main() {
    let x2: i8 = --128; //~ warn: literal out of range for i8

    let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32
    let x =  3.40282357e+38_f32; //~ warn: literal out of range for f32
    let x = -1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
    let x =  1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
}
<|endoftext|>


<commit_before>use std::io;

use error::Error;
use token::Sentence;

/// A trait for objects that can write CoNLL-X `Sentence`s.
pub trait WriteSentence {
    /// Write a `Sentence` into this object.
    ///
    /// # Errors
    ///
    /// A call to `write_sentence` may generate an error to indicate that
    /// the operation could not be completed.
    fn write_sentence(&mut self, sentence: &Sentence) -> Result<(), Error>;
}

/// A writer for CoNLL-X sentences. This writer will write sentences
/// to the embedded writer in CoNLL-X tabular format.
pub struct Writer<W> {
    write: W,
    first: bool,
}

impl<W: io::Write> Writer<W> {
    /// Construct a new writer from an object that implements the `io::Write`
    /// trait.
    pub fn new(write: W) -> Writer<W> {
        Writer {
            write: write,
            first: true,
        }
    }

    /// Borrow the embedded writer. Getting the underlying writer is often
    /// useful when the writer writes to a memory object.
    ///
    /// # Examples
    ///
    /// ```
    /// use conllx::{Sentence, Token, WriteSentence, Writer};
    /// use std::str;
    ///
    /// let output = Vec::new();
    /// let mut writer = Writer::new(output);
    /// let sent = Sentence::new(vec![
    ///   Token::new(),
    ///   Token::new(),
    /// ]);
    ///
    /// writer.write_sentence(&sent).unwrap();
    ///
    /// println!("Output:\n{}", str::from_utf8(writer.get_ref()).unwrap());
    /// ```
    pub fn get_ref(&self) -> &W {
        &self.write
    }
}

impl<W: io::Write> WriteSentence for Writer<W> {
    fn write_sentence(&mut self, sentence: &Sentence) -> Result<(), Error> {
        if self.first {
            self.first = false;
            try!(write!(self.write, "{}", sentence))
        } else {
            try!(write!(self.write, "\n\n{}", sentence))
        }

        Ok(())
    }
}

/// A writer for CoNLL-X sentences that partitions incoming objects
/// among multiple writers.
///
/// For example, suppose that a `PartitioningWriter` is wraps writers
/// *w1*, *w2*, and sentences s_[1-5]$ are written. The sentences are then
/// written as follows:
///
/// * s1 -> w1
/// * s2 -> w2
/// * s3 -> w1
/// * s4 -> w2
/// * s5 -> w1
pub struct PartitioningWriter<W>
    where W: WriteSentence
{
    writers: Vec<W>,
    fold: usize,
}

impl<W> PartitioningWriter<W> where W: WriteSentence
{
    pub fn new(writers: Vec<W>) -> PartitioningWriter<W> {
        PartitioningWriter {
            writers: writers,
            fold: 0,
        }
    }
}

impl<W> WriteSentence for PartitioningWriter<W> where W: WriteSentence
{
    fn write_sentence(&mut self, sentence: &Sentence) -> Result<(), Error> {
        if self.fold == self.writers.len() {
            self.fold = 0
        }

        try!(self.writers[self.fold].write_sentence(sentence));
        self.fold += 1;

        Ok(())
    }
}
<commit_msg>cargo fmt<commit_after>use std::io;

use error::Error;
use token::Sentence;

/// A trait for objects that can write CoNLL-X `Sentence`s.
pub trait WriteSentence {
    /// Write a `Sentence` into this object.
    ///
    /// # Errors
    ///
    /// A call to `write_sentence` may generate an error to indicate that
    /// the operation could not be completed.
    fn write_sentence(&mut self, sentence: &Sentence) -> Result<(), Error>;
}

/// A writer for CoNLL-X sentences. This writer will write sentences
/// to the embedded writer in CoNLL-X tabular format.
pub struct Writer<W> {
    write: W,
    first: bool,
}

impl<W: io::Write> Writer<W> {
    /// Construct a new writer from an object that implements the `io::Write`
    /// trait.
    pub fn new(write: W) -> Writer<W> {
        Writer {
            write: write,
            first: true,
        }
    }

    /// Borrow the embedded writer. Getting the underlying writer is often
    /// useful when the writer writes to a memory object.
    ///
    /// # Examples
    ///
    /// ```
    /// use conllx::{Sentence, Token, WriteSentence, Writer};
    /// use std::str;
    ///
    /// let output = Vec::new();
    /// let mut writer = Writer::new(output);
    /// let sent = Sentence::new(vec![
    ///   Token::new(),
    ///   Token::new(),
    /// ]);
    ///
    /// writer.write_sentence(&sent).unwrap();
    ///
    /// println!("Output:\n{}", str::from_utf8(writer.get_ref()).unwrap());
    /// ```
    pub fn get_ref(&self) -> &W {
        &self.write
    }
}

impl<W: io::Write> WriteSentence for Writer<W> {
    fn write_sentence(&mut self, sentence: &Sentence) -> Result<(), Error> {
        if self.first {
            self.first = false;
            try!(write!(self.write, "{}", sentence))
        } else {
            try!(write!(self.write, "\n\n{}", sentence))
        }

        Ok(())
    }
}

/// A writer for CoNLL-X sentences that partitions incoming objects
/// among multiple writers.
///
/// For example, suppose that a `PartitioningWriter` is wraps writers
/// *w1*, *w2*, and sentences s_[1-5]$ are written. The sentences are then
/// written as follows:
///
/// * s1 -> w1
/// * s2 -> w2
/// * s3 -> w1
/// * s4 -> w2
/// * s5 -> w1
pub struct PartitioningWriter<W>
    where W: WriteSentence
{
    writers: Vec<W>,
    fold: usize,
}

impl<W> PartitioningWriter<W>
    where W: WriteSentence
{
    pub fn new(writers: Vec<W>) -> PartitioningWriter<W> {
        PartitioningWriter {
            writers: writers,
            fold: 0,
        }
    }
}

impl<W> WriteSentence for PartitioningWriter<W>
    where W: WriteSentence
{
    fn write_sentence(&mut self, sentence: &Sentence) -> Result<(), Error> {
        if self.fold == self.writers.len() {
            self.fold = 0
        }

        try!(self.writers[self.fold].write_sentence(sentence));
        self.fold += 1;

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::ptr;
use std::sync::Arc;

use buffer::AbstractBuffer;
use descriptor_set::layout_def::Layout;
use descriptor_set::layout_def::SetLayout;
use descriptor_set::layout_def::SetLayoutWrite;
use descriptor_set::layout_def::SetLayoutInit;
use descriptor_set::layout_def::DescriptorWrite;
use descriptor_set::layout_def::DescriptorBind;
use descriptor_set::pool::DescriptorPool;
use device::Device;
use image::AbstractImageView;
use sampler::Sampler;

use OomError;
use SynchronizedVulkanObject;
use VulkanObject;
use VulkanPointers;
use check_errors;
use vk;

/// An actual descriptor set with the resources that are binded to it.
pub struct DescriptorSet<S> {
    set: vk::DescriptorSet,
    pool: Arc<DescriptorPool>,
    layout: Arc<DescriptorSetLayout<S>>,

    // Here we store the resources used by the descriptor set.
    // TODO: for the moment even when a resource is overwritten it stays in these lists
    resources_samplers: Vec<Arc<Sampler>>,
    resources_image_views: Vec<Arc<AbstractImageView>>,
    resources_buffers: Vec<Arc<AbstractBuffer>>,
}

impl<S> DescriptorSet<S> where S: SetLayout {
    ///
    /// # Panic
    ///
    /// - Panicks if the pool and the layout were not created from the same `Device`.
    ///
    pub fn new<I>(pool: &Arc<DescriptorPool>, layout: &Arc<DescriptorSetLayout<S>>, init: I)
                  -> Result<Arc<DescriptorSet<S>>, OomError>
        where S: SetLayoutInit<I>
    {
        unsafe {
            let mut set = try!(DescriptorSet::uninitialized(pool, layout));
            Arc::get_mut(&mut set).unwrap().unchecked_write(layout.layout().decode(init));
            Ok(set)
        }
    }

    ///
    /// # Panic
    ///
    /// - Panicks if the pool and the layout were not created from the same `Device`.
    ///
    // FIXME: this has to check whether there's still enough room in the pool
    pub unsafe fn uninitialized(pool: &Arc<DescriptorPool>, layout: &Arc<DescriptorSetLayout<S>>)
                                -> Result<Arc<DescriptorSet<S>>, OomError>
    {
        assert_eq!(&**pool.device() as *const Device, &*layout.device as *const Device);

        let vk = pool.device().pointers();

        let set = {
            let pool_obj = pool.internal_object_guard();

            let infos = vk::DescriptorSetAllocateInfo {
                sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
                pNext: ptr::null(),
                descriptorPool: *pool_obj,
                descriptorSetCount: 1,
                pSetLayouts: &layout.layout,
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.AllocateDescriptorSets(pool.device().internal_object(), &infos,
                                                        &mut output)));
            output
        };

        Ok(Arc::new(DescriptorSet {
            set: set,
            pool: pool.clone(),
            layout: layout.clone(),

            resources_samplers: Vec::new(),
            resources_image_views: Vec::new(),
            resources_buffers: Vec::new(),
        }))
    }

    /// Modifies a descriptor set.
    ///
    /// The parameter depends on your implementation of `SetLayout`.
    ///
    /// This function trusts the implementation of `SetLayout` when it comes to making sure
    /// that the correct resource type is written to the correct descriptor.
    pub fn write<W>(&mut self, write: W)
        where S: SetLayoutWrite<W>
    {
        let write = self.layout.layout().decode(write);
        unsafe { self.unchecked_write(write); }
    }

    /// Modifies a descriptor set without checking that the writes are correct.
    pub unsafe fn unchecked_write(&mut self, write: Vec<DescriptorWrite>) {
        let vk = self.pool.device().pointers();

        // TODO: how do we remove the existing resources that are overwritten?

        // This function uses multiple closures which all borrow `self`. In order to satisfy the
        // borrow checker, we extract references to the members here.
        let ref mut self_resources_buffers = self.resources_buffers;
        let ref mut self_resources_samplers = self.resources_samplers;
        let ref mut self_resources_image_views = self.resources_image_views;
        let self_set = self.set;

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let buffer_descriptors = write.iter().filter_map(|write| {
            match write.content {
                DescriptorBind::UniformBuffer { ref buffer, offset, size } |
                DescriptorBind::DynamicUniformBuffer { ref buffer, offset, size } => {
                    assert!(buffer.usage_uniform_buffer());
                    self_resources_buffers.push(buffer.clone());
                    Some(vk::DescriptorBufferInfo {
                        buffer: buffer.internal_object(),
                        offset: offset as u64,
                        range: size as u64,
                    })
                },
                DescriptorBind::StorageBuffer { ref buffer, offset, size } |
                DescriptorBind::DynamicStorageBuffer { ref buffer, offset, size } => {
                    assert!(buffer.usage_storage_buffer());
                    self_resources_buffers.push(buffer.clone());
                    Some(vk::DescriptorBufferInfo {
                        buffer: buffer.internal_object(),
                        offset: offset as u64,
                        range: size as u64,
                    })
                },
                _ => None
            }
        }).collect::<Vec<_>>();

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let image_descriptors = write.iter().filter_map(|write| {
            match write.content {
                DescriptorBind::Sampler(ref sampler) => {
                    self_resources_samplers.push(sampler.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: sampler.internal_object(),
                        imageView: 0,
                        imageLayout: 0,
                    })
                },
                DescriptorBind::CombinedImageSampler(ref sampler, ref image, layout) => {
                    assert!(image.usage_sampled());
                    self_resources_samplers.push(sampler.clone());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: sampler.internal_object(),
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                DescriptorBind::StorageImage(ref image, layout) => {
                    assert!(image.usage_storage());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: 0,
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                DescriptorBind::SampledImage(ref image, layout) => {
                    assert!(image.usage_sampled());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: 0,
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                DescriptorBind::InputAttachment(ref image, layout) => {
                    assert!(image.usage_input_attachment());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: 0,
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                _ => None
            }
        }).collect::<Vec<_>>();

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let mut next_buffer_desc = 0;
        let mut next_image_desc = 0;

        let vk_writes = write.iter().map(|write| {
            let (buffer_info, image_info) = match write.content {
                DescriptorBind::Sampler(_) | DescriptorBind::CombinedImageSampler(_, _ ,_) |
                DescriptorBind::SampledImage(_, _) | DescriptorBind::StorageImage(_, _) |
                DescriptorBind::InputAttachment(_, _) => {
                    let img = image_descriptors.as_ptr().offset(next_image_desc as isize);
                    next_image_desc += 1;
                    (ptr::null(), img)
                },
                //DescriptorBind::UniformTexelBuffer(_) | DescriptorBind::StorageTexelBuffer(_) =>
                DescriptorBind::UniformBuffer { .. } | DescriptorBind::StorageBuffer { .. } |
                DescriptorBind::DynamicUniformBuffer { .. } |
                DescriptorBind::DynamicStorageBuffer { .. } => {
                    let buf = buffer_descriptors.as_ptr().offset(next_buffer_desc as isize);
                    next_buffer_desc += 1;
                    (buf, ptr::null())
                },
            };

            // FIXME: the descriptor set must be synchronized
            vk::WriteDescriptorSet {
                sType: vk::STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                pNext: ptr::null(),
                dstSet: self_set,
                dstBinding: write.binding,
                dstArrayElement: write.array_element,
                descriptorCount: 1,
                descriptorType: write.content.ty() as u32,
                pImageInfo: image_info,
                pBufferInfo: buffer_info,
                pTexelBufferView: ptr::null(),      // TODO:
            }
        }).collect::<Vec<_>>();

        debug_assert_eq!(next_buffer_desc, buffer_descriptors.len());
        debug_assert_eq!(next_image_desc, image_descriptors.len());

        if !vk_writes.is_empty() {
            vk.UpdateDescriptorSets(self.pool.device().internal_object(),
                                    vk_writes.len() as u32, vk_writes.as_ptr(), 0, ptr::null());
        }
    }
}

unsafe impl<S> VulkanObject for DescriptorSet<S> {
    type Object = vk::DescriptorSet;

    #[inline]
    fn internal_object(&self) -> vk::DescriptorSet {
        self.set
    }
}

impl<S> Drop for DescriptorSet<S> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.pool.device().pointers();
            vk.FreeDescriptorSets(self.pool.device().internal_object(),
                                  *self.pool.internal_object_guard(), 1, &self.set);
        }
    }
}

/// Implemented on all `DescriptorSet` objects. Hides the template parameters.
pub unsafe trait AbstractDescriptorSet: ::VulkanObjectU64 {}
unsafe impl<S> AbstractDescriptorSet for DescriptorSet<S> {}

/// Describes the layout of all descriptors within a descriptor set.
pub struct DescriptorSetLayout<S> {
    layout: vk::DescriptorSetLayout,
    device: Arc<Device>,
    description: S,
}

impl<S> DescriptorSetLayout<S> where S: SetLayout {
    pub fn new(device: &Arc<Device>, description: S)
               -> Result<Arc<DescriptorSetLayout<S>>, OomError>
    {
        let vk = device.pointers();

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let bindings = description.descriptors().into_iter().map(|desc| {
            vk::DescriptorSetLayoutBinding {
                binding: desc.binding,
                descriptorType: desc.ty.vk_enum(),
                descriptorCount: desc.array_count,
                stageFlags: desc.stages.into(),
                pImmutableSamplers: ptr::null(),        // FIXME: not yet implemented
            }
        }).collect::<Vec<_>>();

        let layout = unsafe {
            let infos = vk::DescriptorSetLayoutCreateInfo {
                sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                bindingCount: bindings.len() as u32,
                pBindings: bindings.as_ptr(),
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateDescriptorSetLayout(device.internal_object(), &infos,
                                                           ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(DescriptorSetLayout {
            layout: layout,
            device: device.clone(),
            description: description,
        }))
    }

    #[inline]
    pub fn layout(&self) -> &S {
        &self.description
    }
}

unsafe impl<S> VulkanObject for DescriptorSetLayout<S> {
    type Object = vk::DescriptorSetLayout;

    #[inline]
    fn internal_object(&self) -> vk::DescriptorSetLayout {
        self.layout
    }
}

impl<S> Drop for DescriptorSetLayout<S> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroyDescriptorSetLayout(self.device.internal_object(), self.layout, ptr::null());
        }
    }
}

/// Implemented on all `DescriptorSetLayout` objects. Hides the template parameters.
pub unsafe trait AbstractDescriptorSetLayout: ::VulkanObjectU64 {}
unsafe impl<S> AbstractDescriptorSetLayout for DescriptorSetLayout<S> {}

/// A collection of `DescriptorSetLayout` structs.
// TODO: push constants.
pub struct PipelineLayout<P> {
    device: Arc<Device>,
    layout: vk::PipelineLayout,
    description: P,
    layouts: Vec<Arc<AbstractDescriptorSetLayout>>,     // TODO: is it necessary to keep the layouts alive? check the specs
}

impl<P> PipelineLayout<P> where P: Layout {
    /// Creates a new `PipelineLayout`.
    pub fn new(device: &Arc<Device>, description: P, layouts: P::DescriptorSetLayouts)
               -> Result<Arc<PipelineLayout<P>>, OomError>
    {
        let vk = device.pointers();

        let layouts = description.decode_descriptor_set_layouts(layouts);
        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let layouts_ids = layouts.iter().map(|l| {
            // FIXME: check that they belong to the same device
            ::VulkanObjectU64::internal_object(&**l)
        }).collect::<Vec<_>>();

        let layout = unsafe {
            let infos = vk::PipelineLayoutCreateInfo {
                sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                setLayoutCount: layouts_ids.len() as u32,
                pSetLayouts: layouts_ids.as_ptr(),
                pushConstantRangeCount: 0,      // TODO: unimplemented
                pPushConstantRanges: ptr::null(),    // TODO: unimplemented
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
                                                      ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(PipelineLayout {
            device: device.clone(),
            layout: layout,
            description: description,
            layouts: layouts,
        }))
    }

    #[inline]
    pub fn layout(&self) -> &P {
        &self.description
    }
}

unsafe impl<P> VulkanObject for PipelineLayout<P> {
    type Object = vk::PipelineLayout;

    #[inline]
    fn internal_object(&self) -> vk::PipelineLayout {
        self.layout
    }
}

impl<P> Drop for PipelineLayout<P> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroyDescriptorSetLayout(self.device.internal_object(), self.layout, ptr::null());
        }
    }
}
<commit_msg>Fix vkDestroyDescriptorSetLayout being used instead of vkDestroyPipelineLayout<commit_after>use std::mem;
use std::ptr;
use std::sync::Arc;

use buffer::AbstractBuffer;
use descriptor_set::layout_def::Layout;
use descriptor_set::layout_def::SetLayout;
use descriptor_set::layout_def::SetLayoutWrite;
use descriptor_set::layout_def::SetLayoutInit;
use descriptor_set::layout_def::DescriptorWrite;
use descriptor_set::layout_def::DescriptorBind;
use descriptor_set::pool::DescriptorPool;
use device::Device;
use image::AbstractImageView;
use sampler::Sampler;

use OomError;
use SynchronizedVulkanObject;
use VulkanObject;
use VulkanPointers;
use check_errors;
use vk;

/// An actual descriptor set with the resources that are binded to it.
pub struct DescriptorSet<S> {
    set: vk::DescriptorSet,
    pool: Arc<DescriptorPool>,
    layout: Arc<DescriptorSetLayout<S>>,

    // Here we store the resources used by the descriptor set.
    // TODO: for the moment even when a resource is overwritten it stays in these lists
    resources_samplers: Vec<Arc<Sampler>>,
    resources_image_views: Vec<Arc<AbstractImageView>>,
    resources_buffers: Vec<Arc<AbstractBuffer>>,
}

impl<S> DescriptorSet<S> where S: SetLayout {
    ///
    /// # Panic
    ///
    /// - Panicks if the pool and the layout were not created from the same `Device`.
    ///
    pub fn new<I>(pool: &Arc<DescriptorPool>, layout: &Arc<DescriptorSetLayout<S>>, init: I)
                  -> Result<Arc<DescriptorSet<S>>, OomError>
        where S: SetLayoutInit<I>
    {
        unsafe {
            let mut set = try!(DescriptorSet::uninitialized(pool, layout));
            Arc::get_mut(&mut set).unwrap().unchecked_write(layout.layout().decode(init));
            Ok(set)
        }
    }

    ///
    /// # Panic
    ///
    /// - Panicks if the pool and the layout were not created from the same `Device`.
    ///
    // FIXME: this has to check whether there's still enough room in the pool
    pub unsafe fn uninitialized(pool: &Arc<DescriptorPool>, layout: &Arc<DescriptorSetLayout<S>>)
                                -> Result<Arc<DescriptorSet<S>>, OomError>
    {
        assert_eq!(&**pool.device() as *const Device, &*layout.device as *const Device);

        let vk = pool.device().pointers();

        let set = {
            let pool_obj = pool.internal_object_guard();

            let infos = vk::DescriptorSetAllocateInfo {
                sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
                pNext: ptr::null(),
                descriptorPool: *pool_obj,
                descriptorSetCount: 1,
                pSetLayouts: &layout.layout,
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.AllocateDescriptorSets(pool.device().internal_object(), &infos,
                                                        &mut output)));
            output
        };

        Ok(Arc::new(DescriptorSet {
            set: set,
            pool: pool.clone(),
            layout: layout.clone(),

            resources_samplers: Vec::new(),
            resources_image_views: Vec::new(),
            resources_buffers: Vec::new(),
        }))
    }

    /// Modifies a descriptor set.
    ///
    /// The parameter depends on your implementation of `SetLayout`.
    ///
    /// This function trusts the implementation of `SetLayout` when it comes to making sure
    /// that the correct resource type is written to the correct descriptor.
    pub fn write<W>(&mut self, write: W)
        where S: SetLayoutWrite<W>
    {
        let write = self.layout.layout().decode(write);
        unsafe { self.unchecked_write(write); }
    }

    /// Modifies a descriptor set without checking that the writes are correct.
    pub unsafe fn unchecked_write(&mut self, write: Vec<DescriptorWrite>) {
        let vk = self.pool.device().pointers();

        // TODO: how do we remove the existing resources that are overwritten?

        // This function uses multiple closures which all borrow `self`. In order to satisfy the
        // borrow checker, we extract references to the members here.
        let ref mut self_resources_buffers = self.resources_buffers;
        let ref mut self_resources_samplers = self.resources_samplers;
        let ref mut self_resources_image_views = self.resources_image_views;
        let self_set = self.set;

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let buffer_descriptors = write.iter().filter_map(|write| {
            match write.content {
                DescriptorBind::UniformBuffer { ref buffer, offset, size } |
                DescriptorBind::DynamicUniformBuffer { ref buffer, offset, size } => {
                    assert!(buffer.usage_uniform_buffer());
                    self_resources_buffers.push(buffer.clone());
                    Some(vk::DescriptorBufferInfo {
                        buffer: buffer.internal_object(),
                        offset: offset as u64,
                        range: size as u64,
                    })
                },
                DescriptorBind::StorageBuffer { ref buffer, offset, size } |
                DescriptorBind::DynamicStorageBuffer { ref buffer, offset, size } => {
                    assert!(buffer.usage_storage_buffer());
                    self_resources_buffers.push(buffer.clone());
                    Some(vk::DescriptorBufferInfo {
                        buffer: buffer.internal_object(),
                        offset: offset as u64,
                        range: size as u64,
                    })
                },
                _ => None
            }
        }).collect::<Vec<_>>();

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let image_descriptors = write.iter().filter_map(|write| {
            match write.content {
                DescriptorBind::Sampler(ref sampler) => {
                    self_resources_samplers.push(sampler.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: sampler.internal_object(),
                        imageView: 0,
                        imageLayout: 0,
                    })
                },
                DescriptorBind::CombinedImageSampler(ref sampler, ref image, layout) => {
                    assert!(image.usage_sampled());
                    self_resources_samplers.push(sampler.clone());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: sampler.internal_object(),
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                DescriptorBind::StorageImage(ref image, layout) => {
                    assert!(image.usage_storage());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: 0,
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                DescriptorBind::SampledImage(ref image, layout) => {
                    assert!(image.usage_sampled());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: 0,
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                DescriptorBind::InputAttachment(ref image, layout) => {
                    assert!(image.usage_input_attachment());
                    self_resources_image_views.push(image.clone());
                    Some(vk::DescriptorImageInfo {
                        sampler: 0,
                        imageView: image.internal_object(),
                        imageLayout: layout as u32,
                    })
                },
                _ => None
            }
        }).collect::<Vec<_>>();

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let mut next_buffer_desc = 0;
        let mut next_image_desc = 0;

        let vk_writes = write.iter().map(|write| {
            let (buffer_info, image_info) = match write.content {
                DescriptorBind::Sampler(_) | DescriptorBind::CombinedImageSampler(_, _ ,_) |
                DescriptorBind::SampledImage(_, _) | DescriptorBind::StorageImage(_, _) |
                DescriptorBind::InputAttachment(_, _) => {
                    let img = image_descriptors.as_ptr().offset(next_image_desc as isize);
                    next_image_desc += 1;
                    (ptr::null(), img)
                },
                //DescriptorBind::UniformTexelBuffer(_) | DescriptorBind::StorageTexelBuffer(_) =>
                DescriptorBind::UniformBuffer { .. } | DescriptorBind::StorageBuffer { .. } |
                DescriptorBind::DynamicUniformBuffer { .. } |
                DescriptorBind::DynamicStorageBuffer { .. } => {
                    let buf = buffer_descriptors.as_ptr().offset(next_buffer_desc as isize);
                    next_buffer_desc += 1;
                    (buf, ptr::null())
                },
            };

            // FIXME: the descriptor set must be synchronized
            vk::WriteDescriptorSet {
                sType: vk::STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                pNext: ptr::null(),
                dstSet: self_set,
                dstBinding: write.binding,
                dstArrayElement: write.array_element,
                descriptorCount: 1,
                descriptorType: write.content.ty() as u32,
                pImageInfo: image_info,
                pBufferInfo: buffer_info,
                pTexelBufferView: ptr::null(),      // TODO:
            }
        }).collect::<Vec<_>>();

        debug_assert_eq!(next_buffer_desc, buffer_descriptors.len());
        debug_assert_eq!(next_image_desc, image_descriptors.len());

        if !vk_writes.is_empty() {
            vk.UpdateDescriptorSets(self.pool.device().internal_object(),
                                    vk_writes.len() as u32, vk_writes.as_ptr(), 0, ptr::null());
        }
    }
}

unsafe impl<S> VulkanObject for DescriptorSet<S> {
    type Object = vk::DescriptorSet;

    #[inline]
    fn internal_object(&self) -> vk::DescriptorSet {
        self.set
    }
}

impl<S> Drop for DescriptorSet<S> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.pool.device().pointers();
            vk.FreeDescriptorSets(self.pool.device().internal_object(),
                                  *self.pool.internal_object_guard(), 1, &self.set);
        }
    }
}

/// Implemented on all `DescriptorSet` objects. Hides the template parameters.
pub unsafe trait AbstractDescriptorSet: ::VulkanObjectU64 {}
unsafe impl<S> AbstractDescriptorSet for DescriptorSet<S> {}

/// Describes the layout of all descriptors within a descriptor set.
pub struct DescriptorSetLayout<S> {
    layout: vk::DescriptorSetLayout,
    device: Arc<Device>,
    description: S,
}

impl<S> DescriptorSetLayout<S> where S: SetLayout {
    pub fn new(device: &Arc<Device>, description: S)
               -> Result<Arc<DescriptorSetLayout<S>>, OomError>
    {
        let vk = device.pointers();

        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let bindings = description.descriptors().into_iter().map(|desc| {
            vk::DescriptorSetLayoutBinding {
                binding: desc.binding,
                descriptorType: desc.ty.vk_enum(),
                descriptorCount: desc.array_count,
                stageFlags: desc.stages.into(),
                pImmutableSamplers: ptr::null(),        // FIXME: not yet implemented
            }
        }).collect::<Vec<_>>();

        let layout = unsafe {
            let infos = vk::DescriptorSetLayoutCreateInfo {
                sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                bindingCount: bindings.len() as u32,
                pBindings: bindings.as_ptr(),
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateDescriptorSetLayout(device.internal_object(), &infos,
                                                           ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(DescriptorSetLayout {
            layout: layout,
            device: device.clone(),
            description: description,
        }))
    }

    #[inline]
    pub fn layout(&self) -> &S {
        &self.description
    }
}

unsafe impl<S> VulkanObject for DescriptorSetLayout<S> {
    type Object = vk::DescriptorSetLayout;

    #[inline]
    fn internal_object(&self) -> vk::DescriptorSetLayout {
        self.layout
    }
}

impl<S> Drop for DescriptorSetLayout<S> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroyDescriptorSetLayout(self.device.internal_object(), self.layout, ptr::null());
        }
    }
}

/// Implemented on all `DescriptorSetLayout` objects. Hides the template parameters.
pub unsafe trait AbstractDescriptorSetLayout: ::VulkanObjectU64 {}
unsafe impl<S> AbstractDescriptorSetLayout for DescriptorSetLayout<S> {}

/// A collection of `DescriptorSetLayout` structs.
// TODO: push constants.
pub struct PipelineLayout<P> {
    device: Arc<Device>,
    layout: vk::PipelineLayout,
    description: P,
    layouts: Vec<Arc<AbstractDescriptorSetLayout>>,     // TODO: is it necessary to keep the layouts alive? check the specs
}

impl<P> PipelineLayout<P> where P: Layout {
    /// Creates a new `PipelineLayout`.
    pub fn new(device: &Arc<Device>, description: P, layouts: P::DescriptorSetLayouts)
               -> Result<Arc<PipelineLayout<P>>, OomError>
    {
        let vk = device.pointers();

        let layouts = description.decode_descriptor_set_layouts(layouts);
        // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
        let layouts_ids = layouts.iter().map(|l| {
            // FIXME: check that they belong to the same device
            ::VulkanObjectU64::internal_object(&**l)
        }).collect::<Vec<_>>();

        let layout = unsafe {
            let infos = vk::PipelineLayoutCreateInfo {
                sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                setLayoutCount: layouts_ids.len() as u32,
                pSetLayouts: layouts_ids.as_ptr(),
                pushConstantRangeCount: 0,      // TODO: unimplemented
                pPushConstantRanges: ptr::null(),    // TODO: unimplemented
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
                                                      ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(PipelineLayout {
            device: device.clone(),
            layout: layout,
            description: description,
            layouts: layouts,
        }))
    }

    #[inline]
    pub fn layout(&self) -> &P {
        &self.description
    }
}

unsafe impl<P> VulkanObject for PipelineLayout<P> {
    type Object = vk::PipelineLayout;

    #[inline]
    fn internal_object(&self) -> vk::PipelineLayout {
        self.layout
    }
}

impl<P> Drop for PipelineLayout<P> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroyPipelineLayout(self.device.internal_object(), self.layout, ptr::null());
        }
    }
}
<|endoftext|>


<commit_before>
#![feature(globs)]
#![feature(macro_rules)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_variable)]
#![allow(non_snake_case)]

extern crate num;
extern crate native;
extern crate libc;

extern crate glfw;
extern crate gl;
extern crate nanovg;

use glfw::Context;
use std::cell::Cell; // for glfw error count
use nanovg::Ctx;

/// evaluate the expression, then check for GL error.
macro_rules! glcheck(
    ($e: expr) => (
        {
            $e;
            assert_eq!(gl::GetError(), 0);
        }
    )
)

mod perf;
mod demo;

#[start]
fn start(argc: int, argv: *const *const u8) -> int {
    native::start(argc, argv, main)
}

/// give GLFW a way to report errors, and count them.
fn error_callback(_: glfw::Error, description: String, error_count: &Cell<uint>) {
    println!("GLFW error {}: {}", error_count.get(), description);
    error_count.set(error_count.get() + 1);
}

fn init_gl() {
    glcheck!(gl::FrontFace(gl::CCW));
    glcheck!(gl::Enable(gl::DEPTH_TEST));
    glcheck!(gl::Enable(gl::SCISSOR_TEST));
    glcheck!(gl::DepthFunc(gl::LEQUAL));
    glcheck!(gl::FrontFace(gl::CCW));
    glcheck!(gl::Enable(gl::CULL_FACE));
    glcheck!(gl::CullFace(gl::BACK));
}

static mut blowup: bool = false;
static mut screenshot: bool = false;
static mut premult: bool = false;

fn main()
{
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

	// set up GLFW error callback, with an error-counter
	glfw.set_error_callback(Some(
	    glfw::Callback {
	        f: error_callback,
	        data: Cell::new(0),
	    }
	));

	glfw.window_hint(glfw::ContextVersion(3, 2));
 	glfw.window_hint(glfw::OpenglForwardCompat(true));
 	glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));
 	glfw.window_hint(glfw::OpenglDebugContext(true));

    let (window, events) = glfw.create_window(1100, 800, "NanoVG GL3 Rust demo", glfw::Windowed)
        .expect("Failed to create GLFW window.");

	// window.set_key_callback(key);
    window.set_key_polling(true);

    window.make_current();

    // use glfw to load GL function pointers
    glcheck!(gl::load_with(|name| glfw.get_proc_address(name)));
    init_gl();

   	let vg: nanovg::Ctx = nanovg::Ctx::create_gl3(nanovg::ANTIALIAS | nanovg::STENCIL_STROKES);
   	//assert!(!vg.ptr.is_null());

    let data = demo::DemoData::load(&vg, "../../res");

//    return test_linebreaks(vg);

	glfw.set_swap_interval(0);

	glfw.set_time(0.0);
	let mut prevt = glfw.get_time();

	let mut fps = perf::PerfGraph::init(perf::FPS, "Frame Time");

    while !window.should_close()
    {
    	let t: f64 = glfw.get_time();
    	let dt: f64 = t - prevt;
    	prevt = t;
    	fps.update(dt);

        let (mx, my) = window.get_cursor_pos(); // (f64,f64)
        let (winWidth, winHeight) = window.get_size();  // (i32,i32)
        let (fbWidth, fbHeight) = window.get_framebuffer_size();
        // Calculate pixel ration for hi-dpi devices.
        let pxRatio = fbWidth as f32 / winWidth as f32;

        // Update and render
        glcheck!(gl::Viewport(0, 0, fbWidth, fbHeight));
        unsafe {
            if premult {
                glcheck!(gl::ClearColor(0.0, 0.0, 0.0, 0.0));
            } else {
                glcheck!(gl::ClearColor(0.3, 0.3, 0.32, 1.0));
            }
        }
        glcheck!(gl::Clear(gl::COLOR_BUFFER_BIT|gl::DEPTH_BUFFER_BIT|gl::STENCIL_BUFFER_BIT));

        glcheck!(gl::Enable(gl::BLEND));
        glcheck!(gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA));
        glcheck!(gl::Enable(gl::CULL_FACE));
        glcheck!(gl::Disable(gl::DEPTH_TEST));

        vg.begin_frame(winWidth, winHeight, pxRatio as f32);

        unsafe { demo::render_demo(&vg, mx as f32,my as f32, winWidth as f32,winHeight as f32, t as f32, blowup, &data); }
        fps.render(&vg, 5.0, 5.0);

        vg.end_frame();

        gl::Enable(gl::DEPTH_TEST);

        unsafe {
	        if screenshot {
	        	screenshot = false;
	        	demo::save_screenshot(fbWidth as u32, fbHeight as u32, premult, "dump.png");
	        }
        }

    	window.swap_buffers();

        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&window, event);
        }
    }
}

fn handle_window_event(window: &glfw::Window, event: glfw::WindowEvent) {
    match event {
        glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) => {
            window.set_should_close(true)
        }
        glfw::KeyEvent(glfw::KeySpace, _, glfw::Press, _) => {
            unsafe {blowup = !blowup};
        }
        glfw::KeyEvent(glfw::KeyS, _, glfw::Press, _) => {
            unsafe {screenshot = true};
        }
        glfw::KeyEvent(glfw::KeyP, _, glfw::Press, _) => {
            unsafe {premult = !premult};
        }
        _ => {}
    }
}

//// think linebreaks api needs some love
//fn test_linebreaks(vg:Ctx) {
//    let x=0.0; let y=0.0;
//    let width = 120.0;
//
//    let text = "This is longer chunk of text.\n  \n  Would have used lorem ipsum but she    was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party.";
//    //let text = "01234 6789 1234 6789 1234 6789 123456789012345678901234567890123456789012345678901234567890123456789";
//
//
//    // The text break API can be used to fill a large buffer of rows,
//    // or to iterate over the text just few lines (or just one) at a time.
//    // The "next" variable of the last returned item tells where to continue.
//    let mut start: uint = 0;    // byte pos in utf8 'text' str
//    let end: uint = text.len(); // exclusive
//    'chunks: loop {
//        let text = text.slice(start, end);
//
//println!("{}", text);
//
//        let rows = vg.text_break_lines(text, width, 3);
//        let nrows = rows.len();
//        if nrows == 0 { break 'chunks; }
//        for i in range(0, nrows) {
//            let row = &rows[i];
//            let line = text.slice(row.start_index(), row.end_index());
//
//println!("i: {}  st: {}, en: {}  \t {} \tnext: {}", i, row.start_index(), row.end_index(), line, row.next_index());
//
//        }
//        // Keep going...
//        start += rows[nrows-1].next_index();
//    }
//}<commit_msg>fix a warning from glfw api change<commit_after>
#![feature(globs)]
#![feature(macro_rules)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_variable)]
#![allow(non_snake_case)]

extern crate num;
extern crate native;
extern crate libc;

extern crate glfw;
extern crate gl;
extern crate nanovg;

use glfw::Context;
use std::cell::Cell; // for glfw error count
use nanovg::Ctx;

/// evaluate the expression, then check for GL error.
macro_rules! glcheck(
    ($e: expr) => (
        {
            $e;
            assert_eq!(gl::GetError(), 0);
        }
    )
)

mod perf;
mod demo;

#[start]
fn start(argc: int, argv: *const *const u8) -> int {
    native::start(argc, argv, main)
}

/// give GLFW a way to report errors, and count them.
fn error_callback(_: glfw::Error, description: String, error_count: &Cell<uint>) {
    println!("GLFW error {}: {}", error_count.get(), description);
    error_count.set(error_count.get() + 1);
}

fn init_gl() {
    glcheck!(gl::FrontFace(gl::CCW));
    glcheck!(gl::Enable(gl::DEPTH_TEST));
    glcheck!(gl::Enable(gl::SCISSOR_TEST));
    glcheck!(gl::DepthFunc(gl::LEQUAL));
    glcheck!(gl::FrontFace(gl::CCW));
    glcheck!(gl::Enable(gl::CULL_FACE));
    glcheck!(gl::CullFace(gl::BACK));
}

static mut blowup: bool = false;
static mut screenshot: bool = false;
static mut premult: bool = false;

fn main()
{
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

	// set up GLFW error callback, with an error-counter
	glfw.set_error_callback(Some(
	    glfw::Callback {
	        f: error_callback,
	        data: Cell::new(0),
	    }
	));

	glfw.window_hint(glfw::ContextVersion(3, 2));
 	glfw.window_hint(glfw::OpenglForwardCompat(true));
 	glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));
 	glfw.window_hint(glfw::OpenglDebugContext(true));

    let (window, events) = glfw.create_window(1100, 800, "NanoVG GL3 Rust demo", glfw::Windowed)
        .expect("Failed to create GLFW window.");

	// window.set_key_callback(key);
    window.set_key_polling(true);

    window.make_current();

    // use glfw to load GL function pointers
    glcheck!(gl::load_with(|name| window.get_proc_address(name)));
    init_gl();

   	let vg: nanovg::Ctx = nanovg::Ctx::create_gl3(nanovg::ANTIALIAS | nanovg::STENCIL_STROKES);
   	//assert!(!vg.ptr.is_null());

    let data = demo::DemoData::load(&vg, "../../res");

//    return test_linebreaks(vg);

	glfw.set_swap_interval(0);

	glfw.set_time(0.0);
	let mut prevt = glfw.get_time();

	let mut fps = perf::PerfGraph::init(perf::FPS, "Frame Time");

    while !window.should_close()
    {
    	let t: f64 = glfw.get_time();
    	let dt: f64 = t - prevt;
    	prevt = t;
    	fps.update(dt);

        let (mx, my) = window.get_cursor_pos(); // (f64,f64)
        let (winWidth, winHeight) = window.get_size();  // (i32,i32)
        let (fbWidth, fbHeight) = window.get_framebuffer_size();
        // Calculate pixel ration for hi-dpi devices.
        let pxRatio = fbWidth as f32 / winWidth as f32;

        // Update and render
        glcheck!(gl::Viewport(0, 0, fbWidth, fbHeight));
        unsafe {
            if premult {
                glcheck!(gl::ClearColor(0.0, 0.0, 0.0, 0.0));
            } else {
                glcheck!(gl::ClearColor(0.3, 0.3, 0.32, 1.0));
            }
        }
        glcheck!(gl::Clear(gl::COLOR_BUFFER_BIT|gl::DEPTH_BUFFER_BIT|gl::STENCIL_BUFFER_BIT));

        glcheck!(gl::Enable(gl::BLEND));
        glcheck!(gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA));
        glcheck!(gl::Enable(gl::CULL_FACE));
        glcheck!(gl::Disable(gl::DEPTH_TEST));

        vg.begin_frame(winWidth, winHeight, pxRatio as f32);

        unsafe { demo::render_demo(&vg, mx as f32,my as f32, winWidth as f32,winHeight as f32, t as f32, blowup, &data); }
        fps.render(&vg, 5.0, 5.0);

        vg.end_frame();

        gl::Enable(gl::DEPTH_TEST);

        unsafe {
	        if screenshot {
	        	screenshot = false;
	        	demo::save_screenshot(fbWidth as u32, fbHeight as u32, premult, "dump.png");
	        }
        }

    	window.swap_buffers();

        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&window, event);
        }
    }
}

fn handle_window_event(window: &glfw::Window, event: glfw::WindowEvent) {
    match event {
        glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) => {
            window.set_should_close(true)
        }
        glfw::KeyEvent(glfw::KeySpace, _, glfw::Press, _) => {
            unsafe {blowup = !blowup};
        }
        glfw::KeyEvent(glfw::KeyS, _, glfw::Press, _) => {
            unsafe {screenshot = true};
        }
        glfw::KeyEvent(glfw::KeyP, _, glfw::Press, _) => {
            unsafe {premult = !premult};
        }
        _ => {}
    }
}

//// think linebreaks api needs some love
//fn test_linebreaks(vg:Ctx) {
//    let x=0.0; let y=0.0;
//    let width = 120.0;
//
//    let text = "This is longer chunk of text.\n  \n  Would have used lorem ipsum but she    was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party.";
//    //let text = "01234 6789 1234 6789 1234 6789 123456789012345678901234567890123456789012345678901234567890123456789";
//
//
//    // The text break API can be used to fill a large buffer of rows,
//    // or to iterate over the text just few lines (or just one) at a time.
//    // The "next" variable of the last returned item tells where to continue.
//    let mut start: uint = 0;    // byte pos in utf8 'text' str
//    let end: uint = text.len(); // exclusive
//    'chunks: loop {
//        let text = text.slice(start, end);
//
//println!("{}", text);
//
//        let rows = vg.text_break_lines(text, width, 3);
//        let nrows = rows.len();
//        if nrows == 0 { break 'chunks; }
//        for i in range(0, nrows) {
//            let row = &rows[i];
//            let line = text.slice(row.start_index(), row.end_index());
//
//println!("i: {}  st: {}, en: {}  \t {} \tnext: {}", i, row.start_index(), row.end_index(), line, row.next_index());
//
//        }
//        // Keep going...
//        start += rows[nrows-1].next_index();
//    }
//}<|endoftext|>


<commit_before>
extern crate gitlab_api as gitlab;

use std::env;
use gitlab::GitLab;
use gitlab::Pagination;

fn main() {
    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_) => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.",
                     default);
            default
        }
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_) => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from \
                    http://{}/profile/account",
                   hostname);
        }
    };

    let mut gl = GitLab::new_https(&hostname, &token);
    // for i in 1..82 {
    //     gl.set_pagination(Pagination{page: i, per_page: 1});
    //     println!("projects: {:?}", gl.projects().unwrap());
    // }
    gl.set_pagination(Pagination {
        page: 1,
        per_page: 100,
    });
    // let _projects = gl.projects().unwrap();
    // FIXME: Project's members are private
    // for project in projects {
    //     println!("{:?}", project.path_with_namespace);
    // }
}
<commit_msg>Dont set pagination<commit_after>
extern crate gitlab_api as gitlab;

use std::env;
use gitlab::GitLab;
use gitlab::Pagination;

fn main() {
    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_) => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.",
                     default);
            default
        }
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_) => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from \
                    http://{}/profile/account",
                   hostname);
        }
    };

    let mut gl = GitLab::new_https(&hostname, &token);
    // for i in 1..82 {
    //     gl.set_pagination(Pagination{page: i, per_page: 1});
    //     println!("projects: {:?}", gl.projects().unwrap());
    // }
    // gl.set_pagination(Pagination {
    //     page: 1,
    //     per_page: 100,
    // });
    // let _projects = gl.projects().unwrap();
    // FIXME: Project's members are private
    // for project in projects {
    //     println!("{:?}", project.path_with_namespace);
    // }
}
<|endoftext|>


<commit_before>use byteorder::{LittleEndian, WriteBytesExt};
use cfb::CompoundFile;
use std::io::{Cursor, Read, Seek, SeekFrom, Write};

/// Regression test for https://github.com/mdsteele/rust-cfb/issues/16.
#[test]
#[should_panic(
    expected = "Found reference to mini sector 123456789, but MiniFAT has \
                only 2 entries"
)]
fn invalid_mini_sector_issue_16() {
    // Create a CFB file with a mini stream.
    let cursor = Cursor::new(Vec::new());
    let mut comp = CompoundFile::create(cursor).unwrap();
    let version = comp.version();
    comp.create_stream("foo").unwrap().write_all(&[0u8; 80]).unwrap();
    let mut cursor = comp.into_inner();

    // Corrupt the starting mini sector ID of the stream.  Due to how we
    // constructed the CFB file, this will be at byte 116 of the second
    // 128-byte directory entry in the third sector of the CFB file.
    let offset = 116 + 128 * 1 + (version.sector_len() as u64) * 2;
    cursor.seek(SeekFrom::Start(offset)).unwrap();
    cursor.write_u32::<LittleEndian>(123456789).unwrap();

    // Re-open the CFB file and try to read the mini stream.
    let mut comp = CompoundFile::open(cursor).unwrap();
    let mut data = Vec::new();
    comp.open_stream("foo").unwrap().read_to_end(&mut data).unwrap();
}
<commit_msg>added check for infinite loops in problematic fuzzed files<commit_after>use byteorder::{LittleEndian, WriteBytesExt};
use cfb::CompoundFile;
use std::{
    fs::read_dir,
    io::{Cursor, Read, Seek, SeekFrom, Write},
    path::Path,
    sync::mpsc,
    thread,
    time::Duration,
};

// Run function on another thread, panic if it takes too long
fn panic_after<T, F>(d: Duration, f: F) -> T
where
    T: Send + 'static,
    F: FnOnce() -> T,
    F: Send + 'static,
{
    let (done_tx, done_rx) = mpsc::channel();
    let handle = thread::spawn(move || {
        let val = f();
        done_tx.send(()).expect("Unable to send completion signal");
        val
    });

    match done_rx.recv_timeout(d) {
        Ok(_) => handle.join().expect("Thread panicked"),
        Err(_) => panic!("Thread took too long"),
    }
}

// Checks to see if a file can be walked over and read properly, or fail if it can not be read
fn can_read(path: &Path) {
    let data = std::fs::read(&path).unwrap();

    let cursor = Cursor::new(data);
    let mut cfb = match CompoundFile::open(cursor) {
        Ok(cfb) => cfb,
        Err(_) => return,
    };

    #[allow(clippy::needless_collect)]
    let stream_paths = cfb
        .walk()
        .filter(|e| e.is_stream())
        .map(|e| e.path().to_path_buf())
        .collect::<Vec<_>>();

    let _unused = stream_paths
        .into_iter()
        .map(|s| -> Result<Vec<u8>, std::io::Error> {
            let mut data = Vec::new();
            cfb.open_stream(&s)?.read_to_end(&mut data)?;
            Ok(data)
        })
        .collect::<Vec<_>>();
}

/// Regression test for https://github.com/mdsteele/rust-cfb/issues/16.
#[test]
#[should_panic(
    expected = "Found reference to mini sector 123456789, but MiniFAT has \
                only 2 entries"
)]
fn invalid_mini_sector_issue_16() {
    // Create a CFB file with a mini stream.
    let cursor = Cursor::new(Vec::new());
    let mut comp = CompoundFile::create(cursor).unwrap();
    let version = comp.version();
    comp.create_stream("foo").unwrap().write_all(&[0u8; 80]).unwrap();
    let mut cursor = comp.into_inner();

    // Corrupt the starting mini sector ID of the stream.  Due to how we
    // constructed the CFB file, this will be at byte 116 of the second
    // 128-byte directory entry in the third sector of the CFB file.
    let offset = 116 + 128 * 1 + (version.sector_len() as u64) * 2;
    cursor.seek(SeekFrom::Start(offset)).unwrap();
    cursor.write_u32::<LittleEndian>(123456789).unwrap();

    // Re-open the CFB file and try to read the mini stream.
    let mut comp = CompoundFile::open(cursor).unwrap();
    let mut data = Vec::new();
    comp.open_stream("foo").unwrap().read_to_end(&mut data).unwrap();
}

#[test]
fn check_for_infinite_loops() {
    // Loop through the provided files
    for entry in read_dir("tests/infinite_loops_fuzzed").unwrap() {
        let entry = entry.unwrap();
        let path = entry.path();

        // Test will panic if it takes more than 1 second to load the file ie. stuck in a loop
        panic_after(Duration::from_secs(1), move || can_read(&path))
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
// Copyright © 2014-2018 Miguel Peláez <kernelfreeze@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use core::resource_manager::resource::Resource;
use core::resource_manager::shader_manager::ShaderManager;
use core::resource_manager::texture_manager::TextureManager;

use core::settings::Settings;

use gfx::shapes::Shapes;

use glium::Display;

use conrod::text::Font;
use smallvec::SmallVec;

use std::error::Error;
use std::sync::Mutex;
use std::time::Instant;

pub mod resource;
pub mod resource_type;
pub mod shader_manager;
pub mod texture_manager;

lazy_static! {
    /// Time since client start
    static ref STARTED: Instant = Instant::now();

    /// Enabled resource packs
    static ref RESOURCE_PACKS: Mutex<SmallVec<[String; 4]>> = Mutex::new(SmallVec::new());
}

/// Assets and resources manager
pub struct ResourceManager {
    texture_manager: TextureManager,
    shader_manager: ShaderManager,
    shapes: Shapes,
}

impl ResourceManager {
    /// Create Litecraft's resource manager
    pub fn new(display: &Display, settings: &Settings) -> ResourceManager {
        let mut resourcepacks = RESOURCE_PACKS
            .lock()
            .expect("Failed to lock resourcepacks manager!");

        *resourcepacks = SmallVec::from_vec(settings.resourcepacks().clone());

        ResourceManager {
            shapes: Shapes::new(display),
            texture_manager: TextureManager::new(),
            shader_manager: ShaderManager::new(),
        }
    }

    /// Get time since application start
    pub fn time() -> f32 {
        let dur = STARTED.elapsed();
        dur.as_secs() as f32 + dur.subsec_nanos() as f32 / 1_000_000_000.0
    }

    /// Get enabled resourcepacks
    pub fn resourcepacks() -> SmallVec<[String; 4]> {
        RESOURCE_PACKS
            .lock()
            .expect("Failed to lock resourcepacks manager!")
            .clone()
    }

    /// Get and load a font file
    pub fn font(resource: &Resource) -> Result<Font, Box<Error>> {
        use std::io::{Error, ErrorKind};
        use conrod::text::FontCollection;

        info!("Loading font file '{}'", resource);

        let data = resource.load_binary();
        let collection = FontCollection::from_bytes(data)?;

        collection.into_font().or_else(|_| {
            Err(From::from(Error::new(
                ErrorKind::Other,
                "Failed to decode font file",
            )))
        })
    }

    /// Tick all resource managers
    pub fn tick(&mut self, display: &Display) { self.texture_manager.tick(display); }

    /// Get VAOs and VBOs
    pub fn shapes(&self) -> &Shapes { &self.shapes }

    /// Get texture manager
    pub fn textures(&self) -> &TextureManager { &self.texture_manager }

    /// Get shader manager
    pub fn shaders(&self) -> &ShaderManager { &self.shader_manager }

    /// Get texture manager
    pub fn textures_mut(&mut self) -> &mut TextureManager { &mut self.texture_manager }

    /// Get shader manager
    pub fn shaders_mut(&mut self) -> &mut ShaderManager { &mut self.shader_manager }

    /// Check if resource manager is loaded
    pub fn loaded(&self) -> bool { self.texture_manager.loaded() }
}
<commit_msg>Reformat code<commit_after>// The MIT License (MIT)
// Copyright © 2014-2018 Miguel Peláez <kernelfreeze@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use core::resource_manager::resource::Resource;
use core::resource_manager::shader_manager::ShaderManager;
use core::resource_manager::texture_manager::TextureManager;

use core::settings::Settings;

use gfx::shapes::Shapes;

use glium::Display;

use conrod::text::Font;
use smallvec::SmallVec;

use std::error::Error;
use std::sync::Mutex;
use std::time::Instant;

pub mod resource;
pub mod resource_type;
pub mod shader_manager;
pub mod texture_manager;

lazy_static! {
    /// Time since client start
    static ref STARTED: Instant = Instant::now();

    /// Enabled resource packs
    static ref RESOURCE_PACKS: Mutex<SmallVec<[String; 4]>> = Mutex::new(SmallVec::new());
}

/// Assets and resources manager
pub struct ResourceManager {
    texture_manager: TextureManager,
    shader_manager: ShaderManager,
    shapes: Shapes,
}

impl ResourceManager {
    /// Create Litecraft's resource manager
    pub fn new(display: &Display, settings: &Settings) -> ResourceManager {
        let mut resourcepacks = RESOURCE_PACKS
            .lock()
            .expect("Failed to lock resourcepacks manager!");

        *resourcepacks = SmallVec::from_vec(settings.resourcepacks().clone());

        ResourceManager {
            shapes: Shapes::new(display),
            texture_manager: TextureManager::new(),
            shader_manager: ShaderManager::new(),
        }
    }

    /// Get time since application start
    pub fn time() -> f32 {
        let dur = STARTED.elapsed();
        dur.as_secs() as f32 + dur.subsec_nanos() as f32 / 1_000_000_000.0
    }

    /// Get enabled resourcepacks
    pub fn resourcepacks() -> SmallVec<[String; 4]> {
        RESOURCE_PACKS
            .lock()
            .expect("Failed to lock resourcepacks manager!")
            .clone()
    }

    /// Get and load a font file
    pub fn font(resource: &Resource) -> Result<Font, Box<Error>> {
        use conrod::text::FontCollection;
        use std::io::{Error, ErrorKind};

        info!("Loading font file '{}'", resource);

        let data = resource.load_binary();
        let collection = FontCollection::from_bytes(data)?;

        collection.into_font().or_else(|_| {
            Err(From::from(Error::new(
                ErrorKind::Other,
                "Failed to decode font file",
            )))
        })
    }

    /// Tick all resource managers
    pub fn tick(&mut self, display: &Display) { self.texture_manager.tick(display); }

    /// Get VAOs and VBOs
    pub fn shapes(&self) -> &Shapes { &self.shapes }

    /// Get texture manager
    pub fn textures(&self) -> &TextureManager { &self.texture_manager }

    /// Get shader manager
    pub fn shaders(&self) -> &ShaderManager { &self.shader_manager }

    /// Get texture manager
    pub fn textures_mut(&mut self) -> &mut TextureManager { &mut self.texture_manager }

    /// Get shader manager
    pub fn shaders_mut(&mut self) -> &mut ShaderManager { &mut self.shader_manager }

    /// Check if resource manager is loaded
    pub fn loaded(&self) -> bool { self.texture_manager.loaded() }
}
<|endoftext|>


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

//! Generic types for CSS values related to backgrounds.

use crate::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrAuto};

fn width_and_height_are_auto<L>(
    width: &LengthPercentageOrAuto<L>,
    height: &LengthPercentageOrAuto<L>,
) -> bool {
    width.is_auto() && height.is_auto()
}

/// A generic value for the `background-size` property.
#[derive(
    Animate,
    Clone,
    ComputeSquaredDistance,
    Copy,
    Debug,
    MallocSizeOf,
    PartialEq,
    SpecifiedValueInfo,
    ToAnimatedValue,
    ToAnimatedZero,
    ToComputedValue,
    ToCss,
    ToResolvedValue,
    ToShmem,
)]
#[repr(C, u8)]
pub enum GenericBackgroundSize<LengthPercent> {
    /// `<width> <height>`
    ExplicitSize {
        /// Explicit width.
        width: GenericLengthPercentageOrAuto<LengthPercent>,
        /// Explicit height.
        /// NOTE(emilio): We should probably simplify all these in case `width`
        /// and `height` are the same, but all other browsers agree on only
        /// special-casing `auto`.
        #[css(contextual_skip_if = "width_and_height_are_auto")]
        height: GenericLengthPercentageOrAuto<LengthPercent>,
    },
    /// `cover`
    #[animation(error)]
    Cover,
    /// `contain`
    #[animation(error)]
    Contain,
}

pub use self::GenericBackgroundSize as BackgroundSize;

impl<LengthPercentage> BackgroundSize<LengthPercentage> {
    /// Returns `auto auto`.
    pub fn auto() -> Self {
        GenericBackgroundSize::ExplicitSize {
            width: LengthPercentageOrAuto::Auto,
            height: LengthPercentageOrAuto::Auto,
        }
    }
}
<commit_msg>style: Fix the serialization of the computed value of background-size.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

//! Generic types for CSS values related to backgrounds.

use crate::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrAuto};

/// A generic value for the `background-size` property.
#[derive(
    Animate,
    Clone,
    ComputeSquaredDistance,
    Copy,
    Debug,
    MallocSizeOf,
    PartialEq,
    SpecifiedValueInfo,
    ToAnimatedValue,
    ToAnimatedZero,
    ToComputedValue,
    ToCss,
    ToResolvedValue,
    ToShmem,
)]
#[repr(C, u8)]
pub enum GenericBackgroundSize<LengthPercent> {
    /// `<width> <height>`
    ExplicitSize {
        /// Explicit width.
        width: GenericLengthPercentageOrAuto<LengthPercent>,
        /// Explicit height.
        #[css(skip_if = "GenericLengthPercentageOrAuto::is_auto")]
        height: GenericLengthPercentageOrAuto<LengthPercent>,
    },
    /// `cover`
    #[animation(error)]
    Cover,
    /// `contain`
    #[animation(error)]
    Contain,
}

pub use self::GenericBackgroundSize as BackgroundSize;

impl<LengthPercentage> BackgroundSize<LengthPercentage> {
    /// Returns `auto auto`.
    pub fn auto() -> Self {
        GenericBackgroundSize::ExplicitSize {
            width: LengthPercentageOrAuto::Auto,
            height: LengthPercentageOrAuto::Auto,
        }
    }
}
<|endoftext|>


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

#![allow(missing_docs)]

use std::marker::PhantomData;

macro_rules! impl_surface_type {
    { $($name:ident,)* } => {
        #[derive(Copy, Clone)]
        #[allow(non_camel_case_types)]
        #[repr(u8)]
        pub enum SurfaceType {
            $( $name, )*
        }
        $(
            pub enum $name {}
            impl SurfaceTyped for $name {
                fn get_surface_type() -> SurfaceType {
                    SurfaceType::$name
                }
            }
        )*
    }
}

impl_surface_type! {
    R8_G8_B8_A8,
    R16_G16_B16_A16,
    D24_S8,
}

macro_rules! impl_channel_type {
    { $($name:ident,)* } => {
        #[derive(Copy, Clone)]
        #[repr(u8)]
        pub enum ChannelType {
            $( $name, )*
        }
        $(
            pub enum $name {}
            impl ChannelTyped for $name {
                fn get_channel_type() -> ChannelType {
                    ChannelType::$name
                }
            }
        )*
    }
}

impl_channel_type! {
    Int,
    Uint,
    IntScaled,
    UintScaled,
    IntNormalized,
    UintNormalized,
    Float,
}

#[derive(Copy, Clone)]
#[repr(u8)]
pub enum Channel {
    Zero,
    One,
    X,
    Y,
    Z,
    W,
}

#[derive(Copy, Clone)]
pub struct Swizzle(pub Channel, pub Channel, pub Channel, pub Channel);

pub const NO_SWIZZLE: Swizzle = Swizzle(Channel::X, Channel::Y, Channel::Z, Channel::W);

#[derive(Copy, Clone)]
pub struct RuntimeFormat(pub SurfaceType, pub ChannelType, pub Swizzle);

// compile-time specification

pub trait SurfaceTyped {
    fn get_surface_type() -> SurfaceType;
}

pub trait ChannelTyped {
    fn get_channel_type() -> ChannelType;
}

pub trait Formatted {
    fn get_format() -> RuntimeFormat;
}

pub struct CompileFormat<S, C>(PhantomData<(S,C)>);

impl<S: SurfaceTyped, C: ChannelTyped> Formatted for CompileFormat<S, C> {
    fn get_format() -> RuntimeFormat {
        RuntimeFormat(S::get_surface_type(), C::get_channel_type(), NO_SWIZZLE)
    }
}

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

#![allow(missing_docs)]

use std::marker::PhantomData;

macro_rules! impl_surface_type {
    { $($name:ident $(=$tr:ident)* ,)* } => {
        #[derive(Copy, Clone)]
        #[allow(non_camel_case_types)]
        #[repr(u8)]
        pub enum SurfaceType {
            $( $name, )*
        }
        $(
            #[allow(non_camel_case_types)]
            pub enum $name {}
            impl SurfaceTyped for $name {
                fn get_surface_type() -> SurfaceType {
                    SurfaceType::$name
                }
            }
            $(
                impl $tr for $name {}
            )*
        )*
    }
}

impl_surface_type! {
    R8_G8_B8_A8     = BufferSurface = TextureSurface = RenderSurface,
    R16_G16_B16_A16 = BufferSurface = TextureSurface = RenderSurface,
    R32_G32_B32_A32 = BufferSurface = TextureSurface = RenderSurface,
    D24_S8          = TextureSurface = DepthStencilSurface,
}

macro_rules! impl_channel_type {
    { $($name:ident $(=$tr:ident)* ,)* } => {
        #[derive(Copy, Clone)]
        #[repr(u8)]
        pub enum ChannelType {
            $( $name, )*
        }
        $(
            pub enum $name {}
            impl ChannelTyped for $name {
                fn get_channel_type() -> ChannelType {
                    ChannelType::$name
                }
            }
            $(
                impl $tr for $name {}
            )*
        )*
    }
}

impl_channel_type! {
    Int             = TextureChannel = RenderChannel,
    Uint            = TextureChannel = RenderChannel,
    IntScaled       = TextureChannel,
    UintScaled      = TextureChannel,
    IntNormalized   = TextureChannel = RenderChannel = BlendChannel,
    UintNormalized  = TextureChannel = RenderChannel = BlendChannel,
    Float           = TextureChannel = RenderChannel = BlendChannel,
    Srgb            = TextureChannel = RenderChannel = BlendChannel,
}

#[derive(Copy, Clone)]
#[repr(u8)]
pub enum Channel {
    Zero,
    One,
    X,
    Y,
    Z,
    W,
}

#[derive(Copy, Clone)]
pub struct Swizzle(pub Channel, pub Channel, pub Channel, pub Channel);

pub const NO_SWIZZLE: Swizzle = Swizzle(Channel::X, Channel::Y, Channel::Z, Channel::W);

#[derive(Copy, Clone)]
pub struct RuntimeFormat(pub SurfaceType, pub ChannelType, pub Swizzle);

// compile-time specification

pub trait SurfaceTyped {
    fn get_surface_type() -> SurfaceType;
}
pub trait BufferSurface: SurfaceTyped {}
pub trait TextureSurface: SurfaceTyped {}
pub trait RenderSurface: SurfaceTyped {}
pub trait DepthStencilSurface: SurfaceTyped {}

pub trait ChannelTyped {
    fn get_channel_type() -> ChannelType;
}
pub trait TextureChannel: ChannelTyped {}
pub trait RenderChannel: ChannelTyped {}
pub trait BlendChannel: RenderChannel {}

pub trait Formatted {
    fn get_format() -> RuntimeFormat;
}
pub trait BufferFormat: Formatted {}
pub trait DepthStencilFormat: Formatted {}
pub trait TextureFormat: Formatted {}
pub trait RenderFormat: Formatted {}
pub trait BlendFormat: RenderFormat {}

impl ChannelTyped for () {
    fn get_channel_type() -> ChannelType {
        ChannelType::Float
    }
}

pub struct CompileFormat<S, C>(PhantomData<(S,C)>);

impl<S: SurfaceTyped, C: ChannelTyped> Formatted for CompileFormat<S, C> {
    fn get_format() -> RuntimeFormat {
        RuntimeFormat(S::get_surface_type(), C::get_channel_type(), NO_SWIZZLE)
    }
}

impl<S: BufferSurface> BufferFormat                         for CompileFormat<S, ()> {}
impl<S: DepthStencilSurface> DepthStencilFormat             for CompileFormat<S, ()> {}
impl<S: TextureSurface, C: TextureChannel> TextureFormat    for CompileFormat<S, C> {}
impl<S: RenderSurface, C: RenderChannel> RenderFormat       for CompileFormat<S, C> {}
impl<S: RenderSurface, C: BlendChannel> BlendFormat         for CompileFormat<S, C> {}

pub type Rgba8 = CompileFormat<R8_G8_B8_A8, UintNormalized>;
pub type Rgba16F = CompileFormat<R16_G16_B16_A16, Float>;
pub type Rgba32F = CompileFormat<R32_G32_B32_A32, Float>;
pub type DepthStencil = CompileFormat<D24_S8, UintNormalized>;
<|endoftext|>