<commit_before><commit_msg>Add Reed-Solomon encoding and decoding<commit_after>//! Encoding and decoding of the (24, 12, 13) short, (24, 16, 9) medium, and (36, 20, 17)
//! long Reed-Solomon codes described by P25.
//!
//! These algorithms are sourced from \[1].
//!
//! \[1]: "Coding Theory and Cryptography: The Essentials", 2nd ed, Hankerson, Hoffman, et
//! al, 2000

use std;

use bits::Hexbit;
use bmcf;
use galois::{P25Codeword, Polynomial, PolynomialCoefs};
use util::CollectSlice;

/// Encoding and decoding of the (24, 12, 13) code.
pub mod short {
    use bits::Hexbit;

    /// Transpose of G_LC.
    const GEN: [[u8; 12]; 12] = [
        [0o62, 0o11, 0o03, 0o21, 0o30, 0o01, 0o61, 0o24, 0o72, 0o72, 0o73, 0o71],
        [0o44, 0o12, 0o01, 0o70, 0o22, 0o41, 0o76, 0o22, 0o42, 0o14, 0o65, 0o05],
        [0o03, 0o11, 0o05, 0o27, 0o03, 0o27, 0o21, 0o71, 0o05, 0o65, 0o36, 0o55],
        [0o25, 0o11, 0o75, 0o45, 0o75, 0o56, 0o55, 0o56, 0o20, 0o54, 0o61, 0o03],
        [0o14, 0o16, 0o14, 0o16, 0o15, 0o76, 0o76, 0o21, 0o43, 0o35, 0o42, 0o71],
        [0o16, 0o64, 0o06, 0o67, 0o15, 0o64, 0o01, 0o35, 0o47, 0o25, 0o22, 0o34],
        [0o27, 0o67, 0o20, 0o23, 0o33, 0o21, 0o63, 0o73, 0o33, 0o41, 0o17, 0o60],
        [0o03, 0o55, 0o44, 0o64, 0o15, 0o53, 0o35, 0o42, 0o56, 0o16, 0o04, 0o11],
        [0o53, 0o01, 0o66, 0o73, 0o51, 0o04, 0o30, 0o57, 0o01, 0o15, 0o44, 0o74],
        [0o04, 0o76, 0o06, 0o33, 0o03, 0o25, 0o13, 0o74, 0o16, 0o40, 0o20, 0o02],
        [0o36, 0o26, 0o70, 0o44, 0o53, 0o01, 0o64, 0o43, 0o13, 0o71, 0o25, 0o41],
        [0o47, 0o73, 0o66, 0o21, 0o50, 0o12, 0o70, 0o76, 0o76, 0o26, 0o05, 0o50],
    ];

    /// Calculate the 12 parity hexbits for the 12 data hexbits.
    pub fn encode(buf: &mut [Hexbit; 24]) {
        let (data, parity) = buf.split_at_mut(12);
        super::encode(data, parity, GEN.iter().map(|r| &r[..]));
    }

    /// Try to decode the 24-hexbit word to the nearest codeword, correcting up to 6
    /// errors. Return `Some((data, err))`, where `data` are the 12 data hexbits and `err`
    /// is the number of errors corrected, on success and `None` on an unrecoverable
    /// error.
    pub fn decode(buf: &mut [Hexbit; 24]) -> Option<(&[Hexbit], usize)> {
        let (poly, err) = match super::decode::<super::ShortCoefs>(buf) {
            Some(x) => x,
            None => return None,
        };

        Some((super::copy_data(poly, &mut buf[..12]), err))
    }
}

/// Encoding and decoding of the (24, 16, 9) code.
pub mod medium {
    use bits::Hexbit;

    /// Transpose of G_ES.
    const GEN: [[u8; 16]; 8] = [
        [0o51, 0o57, 0o05, 0o73, 0o75, 0o20, 0o02, 0o24, 0o42, 0o32, 0o65, 0o64, 0o62, 0o55, 0o24, 0o67],
        [0o45, 0o25, 0o01, 0o07, 0o15, 0o32, 0o75, 0o74, 0o64, 0o32, 0o36, 0o06, 0o63, 0o43, 0o23, 0o75],
        [0o67, 0o63, 0o31, 0o47, 0o51, 0o14, 0o43, 0o15, 0o07, 0o55, 0o25, 0o54, 0o74, 0o34, 0o23, 0o45],
        [0o15, 0o73, 0o04, 0o14, 0o51, 0o42, 0o05, 0o72, 0o22, 0o41, 0o07, 0o32, 0o70, 0o71, 0o05, 0o60],
        [0o64, 0o71, 0o16, 0o41, 0o17, 0o75, 0o01, 0o24, 0o61, 0o57, 0o50, 0o76, 0o05, 0o57, 0o50, 0o57],
        [0o67, 0o22, 0o54, 0o77, 0o67, 0o42, 0o40, 0o26, 0o20, 0o66, 0o16, 0o46, 0o27, 0o76, 0o70, 0o24],
        [0o52, 0o40, 0o25, 0o47, 0o17, 0o70, 0o12, 0o74, 0o40, 0o21, 0o40, 0o14, 0o37, 0o50, 0o42, 0o06],
        [0o12, 0o15, 0o76, 0o11, 0o57, 0o54, 0o64, 0o61, 0o65, 0o77, 0o51, 0o36, 0o46, 0o64, 0o23, 0o26],
    ];

    /// Calculate the 8 parity hexbits for the 16 data hexbits.
    pub fn encode(buf: &mut [Hexbit; 24]) {
        let (data, parity) = buf.split_at_mut(16);
        super::encode(data, parity, GEN.iter().map(|r| &r[..]));
    }

    /// Try to decode the 24-hexbit word to the nearest codeword, correcting up to 4
    /// errors. Return `Some((data, err))`, where `data` are the 16 data hexbits and `err`
    /// is the number of errors corrected, on success and `None` on an unrecoverable
    /// error.
    pub fn decode(buf: &mut [Hexbit; 24]) -> Option<(&[Hexbit], usize)> {
        let (poly, err) = match super::decode::<super::MedCoefs>(buf) {
            Some(x) => x,
            None => return None,
        };

        Some((super::copy_data(poly, &mut buf[..16]), err))
    }
}

/// Encoding and decoding of the (36, 20, 17) code.
pub mod long {
    use bits::Hexbit;

    /// Transpose of P_HDR.
    const GEN: [[u8; 20]; 16] = [
        [0o74, 0o04, 0o07, 0o26, 0o23, 0o24, 0o52, 0o55, 0o54, 0o74, 0o54, 0o51, 0o01, 0o11, 0o06, 0o34, 0o63, 0o71, 0o02, 0o34],
        [0o37, 0o17, 0o23, 0o05, 0o73, 0o51, 0o33, 0o62, 0o51, 0o41, 0o70, 0o07, 0o65, 0o70, 0o02, 0o31, 0o43, 0o21, 0o01, 0o35],
        [0o34, 0o50, 0o37, 0o07, 0o73, 0o25, 0o14, 0o56, 0o32, 0o30, 0o11, 0o72, 0o32, 0o05, 0o65, 0o01, 0o25, 0o70, 0o53, 0o02],
        [0o06, 0o24, 0o46, 0o63, 0o41, 0o23, 0o02, 0o25, 0o65, 0o41, 0o03, 0o30, 0o70, 0o10, 0o11, 0o15, 0o44, 0o44, 0o74, 0o23],
        [0o02, 0o11, 0o56, 0o63, 0o72, 0o22, 0o20, 0o73, 0o77, 0o43, 0o13, 0o65, 0o13, 0o65, 0o41, 0o44, 0o77, 0o56, 0o02, 0o21],
        [0o07, 0o05, 0o75, 0o27, 0o34, 0o41, 0o06, 0o60, 0o12, 0o22, 0o22, 0o54, 0o44, 0o24, 0o20, 0o64, 0o63, 0o04, 0o14, 0o27],
        [0o44, 0o30, 0o43, 0o63, 0o21, 0o74, 0o14, 0o15, 0o54, 0o51, 0o16, 0o06, 0o73, 0o15, 0o45, 0o16, 0o17, 0o30, 0o52, 0o22],
        [0o64, 0o57, 0o45, 0o40, 0o51, 0o66, 0o25, 0o30, 0o13, 0o06, 0o57, 0o21, 0o24, 0o77, 0o42, 0o24, 0o17, 0o74, 0o74, 0o33],
        [0o26, 0o33, 0o55, 0o06, 0o67, 0o74, 0o52, 0o13, 0o35, 0o64, 0o03, 0o36, 0o12, 0o22, 0o46, 0o52, 0o64, 0o04, 0o12, 0o64],
        [0o14, 0o03, 0o21, 0o04, 0o16, 0o65, 0o23, 0o17, 0o32, 0o33, 0o45, 0o63, 0o52, 0o24, 0o54, 0o16, 0o14, 0o23, 0o57, 0o42],
        [0o26, 0o02, 0o50, 0o40, 0o31, 0o70, 0o35, 0o20, 0o56, 0o03, 0o72, 0o50, 0o21, 0o24, 0o35, 0o06, 0o40, 0o71, 0o24, 0o05],
        [0o44, 0o02, 0o31, 0o45, 0o74, 0o36, 0o74, 0o02, 0o12, 0o47, 0o31, 0o61, 0o55, 0o74, 0o12, 0o62, 0o74, 0o70, 0o63, 0o73],
        [0o54, 0o15, 0o45, 0o47, 0o11, 0o67, 0o75, 0o70, 0o75, 0o27, 0o30, 0o64, 0o12, 0o07, 0o40, 0o20, 0o31, 0o63, 0o15, 0o51],
        [0o13, 0o16, 0o27, 0o30, 0o21, 0o45, 0o75, 0o55, 0o01, 0o12, 0o56, 0o52, 0o35, 0o44, 0o64, 0o13, 0o72, 0o45, 0o42, 0o46],
        [0o77, 0o25, 0o71, 0o75, 0o12, 0o64, 0o43, 0o14, 0o72, 0o55, 0o35, 0o01, 0o14, 0o07, 0o65, 0o55, 0o54, 0o56, 0o52, 0o73],
        [0o05, 0o26, 0o62, 0o07, 0o21, 0o01, 0o27, 0o47, 0o63, 0o47, 0o22, 0o60, 0o72, 0o46, 0o33, 0o57, 0o06, 0o43, 0o33, 0o60],
    ];

    /// Calculate the 16 parity hexbits for the 20 data hexbits.
    pub fn encode(buf: &mut [Hexbit; 36]) {
        let (data, parity) = buf.split_at_mut(20);
        super::encode(data, parity, GEN.iter().map(|r| &r[..]))
    }

    /// Try to decode the 36-hexbit word to the nearest codeword, correcting up to 8
    /// errors. Return `Some((data, err))`, where `data` are the 20 data hexbits and `err`
    /// is the number of errors corrected, on success and `None` on an unrecoverable
    /// error.
    pub fn decode(buf: &mut [Hexbit; 36]) -> Option<(&[Hexbit], usize)> {
        let (poly, err) = match super::decode::<super::LongCoefs>(buf) {
            Some(x) => x,
            None => return None,
        };

        Some((super::copy_data(poly, &mut buf[..20]), err))
    }
}

/// Encode the given data with the given generator matrix and place the resulting parity
/// symbols in the given destination.
fn encode<'g, G>(data: &[Hexbit], parity: &mut [Hexbit], gen: G) where
    G: Iterator<Item = &'g [u8]>
{
    for (p, row) in parity.iter_mut().zip(gen) {
        *p = Hexbit::new(
            row.iter()
                .zip(data.iter())
                .fold(P25Codeword::default(), |s, (&col, &d)| {
                    s + P25Codeword::new(d.bits()) * P25Codeword::new(col)
                }).bits()
        );
    }
}

/// Try to fix any errors in the given word.
fn decode<P: PolynomialCoefs>(word: &[Hexbit]) -> Option<(Polynomial<P>, usize)> {
    // In a received hexbit word, the least most significant hexbit symbol (the first data
    // symbol) maps to the highest degree.
    let mut poly = Polynomial::<P>::new(word.iter().rev().map(|&b| {
        P25Codeword::new(b.bits())
    }));

    let syn = syndromes(&poly);
    let dec = bmcf::BerlMasseyDecoder::new(syn).decode();
    let errors = dec.degree().expect("invalid error polynomial");

    let fixed = bmcf::Errors::new(dec, syn)
        .take(errors)
        .fold(0, |count, (loc, val)| {
            poly[loc] = poly[loc] + val;
            count + 1
        });

    if fixed == errors {
        Some((poly, fixed))
    } else {
        None
    }
}

/// Calculate the syndrome polynomial for the given word.
fn syndromes<P: PolynomialCoefs>(word: &Polynomial<P>) -> Polynomial<P> {
    Polynomial::new(std::iter::once(P25Codeword::for_power(0))
        .chain((1..P::distance()).map(|pow| {
            word.eval(P25Codeword::for_power(pow))
        }))
    )
}

/// Copy the data symbols in the given polynomial to the destination as bytes.
fn copy_data<P: PolynomialCoefs>(poly: Polynomial<P>, data: &mut [Hexbit]) -> &[Hexbit] {
    poly.iter().rev().map(|coef| Hexbit::new(coef.bits())).collect_slice(data);
    data
}

/// Polynomial coefficients for the short code.
#[derive(Copy, Clone, Debug, Default)]
struct ShortCoefs([P25Codeword; 24]);

impl PolynomialCoefs for ShortCoefs {
    fn distance() -> usize { 13 }
}

impl std::ops::Deref for ShortCoefs {
    type Target = [P25Codeword];
    fn deref(&self) -> &Self::Target { &self.0[..] }
}

impl std::ops::DerefMut for ShortCoefs {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0[..] }
}

/// Polynomial coefficients for the medium code.
#[derive(Copy, Clone, Debug, Default)]
struct MedCoefs([P25Codeword; 24]);

impl PolynomialCoefs for MedCoefs {
    fn distance() -> usize { 9 }
}

impl std::ops::Deref for MedCoefs {
    type Target = [P25Codeword];
    fn deref(&self) -> &Self::Target { &self.0[..] }
}

impl std::ops::DerefMut for MedCoefs {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0[..] }
}

/// Polynomial coefficients for the long code.
#[derive(Copy)]
struct LongCoefs([P25Codeword; 36]);

impl PolynomialCoefs for LongCoefs {
    fn distance() -> usize { 17 }
}

impl std::fmt::Debug for LongCoefs {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(fmt, "{:?}", &self.0[..])
    }
}

impl Clone for LongCoefs {
    fn clone(&self) -> Self {
        let mut coefs = [P25Codeword::default(); 36];
        self.0.iter().cloned().collect_slice(&mut coefs[..]);
        LongCoefs(coefs)
    }
}

impl Default for LongCoefs {
    fn default() -> LongCoefs { LongCoefs([P25Codeword::default(); 36]) }
}

impl std::ops::Deref for LongCoefs {
    type Target = [P25Codeword];
    fn deref(&self) -> &Self::Target { &self.0[..] }
}

impl std::ops::DerefMut for LongCoefs {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0[..] }
}

#[cfg(test)]
mod test {
    use super::*;
    use super::{MedCoefs, ShortCoefs, LongCoefs};
    use galois::{PolynomialCoefs};
    use bits::Hexbit;
    use util::CollectSlice;

    #[test]
    fn validate_coefs() {
        ShortCoefs::default().validate();
        MedCoefs::default().validate();
        LongCoefs::default().validate();
    }

    #[test]
    fn test_decode_short() {
        let mut buf = [Hexbit::default(); 24];
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].iter()
             .map(|&b| Hexbit::new(b)).collect_slice(&mut buf[..]);

        short::encode(&mut buf);

        buf[0] = Hexbit::new(0o00);
        buf[2] = Hexbit::new(0o60);
        buf[7] = Hexbit::new(0o42);
        buf[13] = Hexbit::new(0o14);
        buf[18] = Hexbit::new(0o56);
        buf[23] = Hexbit::new(0o72);

        let dec = short::decode(&mut buf);
        let exp = [
           Hexbit::new(1),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
        ];

        assert_eq!(dec, Some((&exp[..], 6)));
    }

    #[test]
    fn test_decode_med() {
        let mut buf = [Hexbit::default(); 24];
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].iter()
             .map(|&b| Hexbit::new(b)).collect_slice(&mut buf[..]);

        medium::encode(&mut buf);

        buf[0] = Hexbit::new(0o00);
        buf[10] = Hexbit::new(0o60);
        buf[16] = Hexbit::new(0o42);
        buf[23] = Hexbit::new(0o14);

        let dec = medium::decode(&mut buf);
        let exp = [
           Hexbit::new(1),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
        ];

        assert_eq!(dec, Some((&exp[..], 4)));
    }

    #[test]
    fn test_decode_long() {
        let mut buf = [Hexbit::default(); 36];
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].iter()
            .map(|&b| Hexbit::new(b)).collect_slice(&mut buf[..]);

        long::encode(&mut buf);

        buf[0] = Hexbit::new(0o00);
        buf[2] = Hexbit::new(0o43);
        buf[5] = Hexbit::new(0o21);
        buf[10] = Hexbit::new(0o11);
        buf[18] = Hexbit::new(0o67);
        buf[22] = Hexbit::new(0o04);
        buf[27] = Hexbit::new(0o12);
        buf[30] = Hexbit::new(0o32);

        let dec = long::decode(&mut buf);
        let exp = [
           Hexbit::new(1),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
           Hexbit::new(0),
        ];

        assert_eq!(dec, Some((&exp[..], 8)));
    }
}
<|endoftext|>


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

//! Slices
//!
//! See `Slice`-structure documentation for more information on this module.

use core::{handle, buffer};
use core::{Primitive, Resources, VertexCount};
use core::command::InstanceParams;
use core::factory::Factory;
use core::memory::Bind;
use format::Format;
use pso;

/// A `Slice` dictates in which and in what order vertices get processed. It is required for
/// processing a PSO.
///
/// # Overview
/// A `Slice` object in essence dictates in what order the vertices in a `VertexBuffer` get
/// processed. To do this, it contains an internal index-buffer. This `Buffer` is a list of
/// indices into this `VertexBuffer` (vertex-index). A vertex-index of 0 represents the first
/// vertex in the `VertexBuffer`, a vertex-index of 1 represents the second, 2 represents the
/// third, and so on. The vertex-indices in the index-buffer are read in order; every vertex-index
/// tells the pipeline which vertex to process next.
///
/// Because the same index can re-appear multiple times, duplicate-vertices can be avoided. For
/// instance, if you want to draw a square, you need two triangles, and thus six vertices. Because
/// the same index can reappear multiple times, this means we can instead use 4 vertices, and 6
/// vertex-indices.
///
/// This index-buffer has a few variants. See the `IndexBuffer` documentation for a detailed
/// description.
///
/// The `start` and `end` fields say where in the index-buffer to start and stop reading.
/// Setting `start` to 0, and `end` to the length of the index-buffer, will cause the entire
/// index-buffer to be processed. The `base_vertex` dictates the index of the first vertex
/// in the `VertexBuffer`. This essentially moves the the start of the `VertexBuffer`, to the
/// vertex with this index.
///
/// # Constuction & Handling
/// The `Slice` structure can be constructed automatically when using a `Factory` to create a
/// vertex buffer. If needed, it can also be created manually.
///
/// A `Slice` is required to process a PSO, as it contains the needed information on in what order
/// to draw which vertices. As such, every `draw` call on an `Encoder` requires a `Slice`.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Slice<R: Resources> {
    /// The start index of the index-buffer. Processing will start at this location in the
    /// index-buffer.
    pub start: VertexCount,
    /// The end index in the index-buffer. Processing will stop at this location (exclusive) in
    /// the index buffer.
    pub end: VertexCount,
    /// This is the index of the first vertex in the `VertexBuffer`. This value will be added to
    /// every index in the index-buffer, effectively moving the start of the `VertexBuffer` to this
    /// base-vertex.
    pub base_vertex: VertexCount,
    /// Instancing configuration.
    pub instances: Option<InstanceParams>,
    /// Represents the type of index-buffer used.
    pub buffer: IndexBuffer<R>,
}

impl<R: Resources> Slice<R> {
    /// Creates a new `Slice` to match the supplied vertex buffer, from start to end, in order.
    pub fn new_match_vertex_buffer<V>(vbuf: &handle::Buffer<R, V>) -> Self
                                      where V: pso::buffer::Structure<Format> {
        Slice {
            start: 0,
            end: vbuf.len() as u32,
            base_vertex: 0,
            instances: None,
            buffer: IndexBuffer::Auto,
        }
    }

    /// Calculates the number of primitives of the specified type in this `Slice`.
    pub fn get_prim_count(&self, prim: Primitive) -> u32 {
        use core::Primitive as p;
        let nv = (self.end - self.start) as u32;
        match prim {
            p::PointList => nv,
            p::LineList => nv / 2,
            p::LineStrip => (nv-1),
            p::TriangleList => nv / 3,
            p::TriangleStrip => (nv-2) / 3,
            p::LineListAdjacency => nv / 4,
            p::LineStripAdjacency => (nv-3),
            p::TriangleListAdjacency => nv / 6,
            p::TriangleStripAdjacency => (nv-4) / 2,
            p::PatchList(num) => nv / (num as u32),
        }
    }

    /// Divides one slice into two at an index.
    ///
    /// The first will contain the range in the index-buffer [self.start, mid) (excluding the index mid itself) and the
    /// second will contain the range [mid, self.end).
    pub fn split_at(&self, mid: VertexCount) -> (Self, Self) {
        let mut first = self.clone();
        let mut second = self.clone();
        first.end = mid;
        second.start = mid;

        (first, second)
    }
}

/// Type of index-buffer used in a Slice.
///
/// The `Auto` variant represents a hypothetical index-buffer from 0 to infinity. In other words,
/// all vertices get processed in order. Do note that the `Slice`' `start` and `end` restrictions
/// still apply for this variant. To render every vertex in the `VertexBuffer`, you would set
/// `start` to 0, and `end` to the `VertexBuffer`'s length.
///
/// The `Index*` variants represent an actual `Buffer` with a list of vertex-indices. The numeric
/// suffix specifies the amount of bits to use per index. Each of these also contains a
/// base-vertex. This is the index of the first vertex in the `VertexBuffer`. This value will be
/// added to every index in the index-buffer, effectively moving the start of the `VertexBuffer` to
/// this base-vertex.
///
/// # Construction & Handling
/// A `IndexBuffer` can be constructed using the `IntoIndexBuffer` trait, from either a slice or a
/// `Buffer` of integers, using a factory.
///
/// An `IndexBuffer` is exclusively used to create `Slice`s.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum IndexBuffer<R: Resources> {
    /// Represents a hypothetical index-buffer from 0 to infinity. In other words, all vertices
    /// get processed in order.
    Auto,
    /// An index-buffer with unsigned 16 bit indices.
    Index16(handle::Buffer<R, u16>),
    /// An index-buffer with unsigned 32 bit indices.
    Index32(handle::Buffer<R, u32>),
}

impl<R: Resources> Default for IndexBuffer<R> {
    fn default() -> Self {
        IndexBuffer::Auto
    }
}
/// A helper trait to create `IndexBuffers` from different kinds of data.
pub trait IntoIndexBuffer<R: Resources> {
    /// Turns self into an `IndexBuffer`.
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R>;
}

impl<R: Resources> IntoIndexBuffer<R> for IndexBuffer<R> {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        self
    }
}

impl<R: Resources> IntoIndexBuffer<R> for () {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        IndexBuffer::Auto
    }
}

macro_rules! impl_index_buffer {
    ($prim_ty:ty, $buf_ty:ident) => (
        impl<R: Resources> IntoIndexBuffer<R> for handle::Buffer<R, $prim_ty> {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
                IndexBuffer::$buf_ty(self)
            }
        }

        impl<'s, R: Resources> IntoIndexBuffer<R> for &'s [$prim_ty] {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R> {
                factory.create_buffer_immutable(self, buffer::Role::Index, Bind::empty())
                       .unwrap()
                       .into_index_buffer(factory)
            }
        }
    )
}

impl_index_buffer!(u16, Index16);
impl_index_buffer!(u32, Index32);
<commit_msg>Auto merge of #1284 - ucarion:ucarion-fix-index-buffer-typo, r=kvark<commit_after>// Copyright 2014 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.

//! Slices
//!
//! See `Slice`-structure documentation for more information on this module.

use core::{handle, buffer};
use core::{Primitive, Resources, VertexCount};
use core::command::InstanceParams;
use core::factory::Factory;
use core::memory::Bind;
use format::Format;
use pso;

/// A `Slice` dictates in which and in what order vertices get processed. It is required for
/// processing a PSO.
///
/// # Overview
/// A `Slice` object in essence dictates in what order the vertices in a `VertexBuffer` get
/// processed. To do this, it contains an internal index-buffer. This `Buffer` is a list of
/// indices into this `VertexBuffer` (vertex-index). A vertex-index of 0 represents the first
/// vertex in the `VertexBuffer`, a vertex-index of 1 represents the second, 2 represents the
/// third, and so on. The vertex-indices in the index-buffer are read in order; every vertex-index
/// tells the pipeline which vertex to process next.
///
/// Because the same index can re-appear multiple times, duplicate-vertices can be avoided. For
/// instance, if you want to draw a square, you need two triangles, and thus six vertices. Because
/// the same index can reappear multiple times, this means we can instead use 4 vertices, and 6
/// vertex-indices.
///
/// This index-buffer has a few variants. See the `IndexBuffer` documentation for a detailed
/// description.
///
/// The `start` and `end` fields say where in the index-buffer to start and stop reading.
/// Setting `start` to 0, and `end` to the length of the index-buffer, will cause the entire
/// index-buffer to be processed. The `base_vertex` dictates the index of the first vertex
/// in the `VertexBuffer`. This essentially moves the the start of the `VertexBuffer`, to the
/// vertex with this index.
///
/// # Constuction & Handling
/// The `Slice` structure can be constructed automatically when using a `Factory` to create a
/// vertex buffer. If needed, it can also be created manually.
///
/// A `Slice` is required to process a PSO, as it contains the needed information on in what order
/// to draw which vertices. As such, every `draw` call on an `Encoder` requires a `Slice`.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Slice<R: Resources> {
    /// The start index of the index-buffer. Processing will start at this location in the
    /// index-buffer.
    pub start: VertexCount,
    /// The end index in the index-buffer. Processing will stop at this location (exclusive) in
    /// the index buffer.
    pub end: VertexCount,
    /// This is the index of the first vertex in the `VertexBuffer`. This value will be added to
    /// every index in the index-buffer, effectively moving the start of the `VertexBuffer` to this
    /// base-vertex.
    pub base_vertex: VertexCount,
    /// Instancing configuration.
    pub instances: Option<InstanceParams>,
    /// Represents the type of index-buffer used.
    pub buffer: IndexBuffer<R>,
}

impl<R: Resources> Slice<R> {
    /// Creates a new `Slice` to match the supplied vertex buffer, from start to end, in order.
    pub fn new_match_vertex_buffer<V>(vbuf: &handle::Buffer<R, V>) -> Self
                                      where V: pso::buffer::Structure<Format> {
        Slice {
            start: 0,
            end: vbuf.len() as u32,
            base_vertex: 0,
            instances: None,
            buffer: IndexBuffer::Auto,
        }
    }

    /// Calculates the number of primitives of the specified type in this `Slice`.
    pub fn get_prim_count(&self, prim: Primitive) -> u32 {
        use core::Primitive as p;
        let nv = (self.end - self.start) as u32;
        match prim {
            p::PointList => nv,
            p::LineList => nv / 2,
            p::LineStrip => (nv-1),
            p::TriangleList => nv / 3,
            p::TriangleStrip => (nv-2) / 3,
            p::LineListAdjacency => nv / 4,
            p::LineStripAdjacency => (nv-3),
            p::TriangleListAdjacency => nv / 6,
            p::TriangleStripAdjacency => (nv-4) / 2,
            p::PatchList(num) => nv / (num as u32),
        }
    }

    /// Divides one slice into two at an index.
    ///
    /// The first will contain the range in the index-buffer [self.start, mid) (excluding the index mid itself) and the
    /// second will contain the range [mid, self.end).
    pub fn split_at(&self, mid: VertexCount) -> (Self, Self) {
        let mut first = self.clone();
        let mut second = self.clone();
        first.end = mid;
        second.start = mid;

        (first, second)
    }
}

/// Type of index-buffer used in a Slice.
///
/// The `Auto` variant represents a hypothetical index-buffer from 0 to infinity. In other words,
/// all vertices get processed in order. Do note that the `Slice`'s `start` and `end` restrictions
/// still apply for this variant. To render every vertex in the `VertexBuffer`, you would set
/// `start` to 0, and `end` to the `VertexBuffer`'s length.
///
/// The `Index*` variants represent an actual `Buffer` with a list of vertex-indices. The numeric
/// suffix specifies the amount of bits to use per index. Each of these also contains a
/// base-vertex. This is the index of the first vertex in the `VertexBuffer`. This value will be
/// added to every index in the index-buffer, effectively moving the start of the `VertexBuffer` to
/// this base-vertex.
///
/// # Construction & Handling
/// A `IndexBuffer` can be constructed using the `IntoIndexBuffer` trait, from either a slice or a
/// `Buffer` of integers, using a factory.
///
/// An `IndexBuffer` is exclusively used to create `Slice`s.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum IndexBuffer<R: Resources> {
    /// Represents a hypothetical index-buffer from 0 to infinity. In other words, all vertices
    /// get processed in order.
    Auto,
    /// An index-buffer with unsigned 16 bit indices.
    Index16(handle::Buffer<R, u16>),
    /// An index-buffer with unsigned 32 bit indices.
    Index32(handle::Buffer<R, u32>),
}

impl<R: Resources> Default for IndexBuffer<R> {
    fn default() -> Self {
        IndexBuffer::Auto
    }
}
/// A helper trait to create `IndexBuffers` from different kinds of data.
pub trait IntoIndexBuffer<R: Resources> {
    /// Turns self into an `IndexBuffer`.
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R>;
}

impl<R: Resources> IntoIndexBuffer<R> for IndexBuffer<R> {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        self
    }
}

impl<R: Resources> IntoIndexBuffer<R> for () {
    fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
        IndexBuffer::Auto
    }
}

macro_rules! impl_index_buffer {
    ($prim_ty:ty, $buf_ty:ident) => (
        impl<R: Resources> IntoIndexBuffer<R> for handle::Buffer<R, $prim_ty> {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
                IndexBuffer::$buf_ty(self)
            }
        }

        impl<'s, R: Resources> IntoIndexBuffer<R> for &'s [$prim_ty] {
            fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R> {
                factory.create_buffer_immutable(self, buffer::Role::Index, Bind::empty())
                       .unwrap()
                       .into_index_buffer(factory)
            }
        }
    )
}

impl_index_buffer!(u16, Index16);
impl_index_buffer!(u32, Index32);
<|endoftext|>


<commit_before>use std::io::{self, ErrorKind};
use std::sync::Arc;
use std::net::{self, SocketAddr};

use futures::stream::Stream;
use futures::{Future, IntoFuture, failed};
use mio;

use {IoFuture, IoStream, ReadinessPair, ReadinessStream, LoopHandle};

/// An I/O object representing a TCP socket listening for incoming connections.
///
/// This object can be converted into a stream of incoming connections for
/// various forms of processing.
pub struct TcpListener {
    loop_handle: LoopHandle,
    inner: ReadinessPair<mio::tcp::TcpListener>,
}

impl TcpListener {
    fn new(listener: mio::tcp::TcpListener,
           handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        ReadinessPair::new(handle.clone(), listener).map(|p| {
            TcpListener { loop_handle: handle, inner: p }
        }).boxed()
    }

    /// Create a new TCP listener from the standard library's TCP listener.
    ///
    /// This method can be used when the `LoopHandle::tcp_listen` method isn't
    /// sufficient because perhaps some more configuration is needed in terms of
    /// before the calls to `bind` and `listen`.
    ///
    /// This API is typically paired with the `net2` crate and the `TcpBuilder`
    /// type to build up and customize a listener before it's shipped off to the
    /// backing event loop. This allows configuration of options like
    /// `SO_REUSEPORT`, binding to multiple addresses, etc.
    ///
    /// The `addr` argument here is one of the addresses that `listener` is
    /// bound to and the listener will only be guaranteed to accept connections
    /// of the same address type currently.
    ///
    /// Finally, the `handle` argument is the event loop that this listener will
    /// be bound to.
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and connections
    ///   can be accepted as normal
    ///
    /// * On Windows, the address is stored internally and all future accepts
    ///   will only be for the same IP version as `addr` specified. That is, if
    ///   `addr` is an IPv4 address then all sockets accepted will be IPv4 as
    ///   well (same for IPv6).
    pub fn from_listener(listener: net::TcpListener,
                         addr: &SocketAddr,
                         handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        mio::tcp::TcpListener::from_listener(listener, addr)
            .into_future()
            .and_then(|l| TcpListener::new(l, handle))
            .boxed()
    }

    /// Returns the local address that this listener is bound to.
    ///
    /// This can be useful, for example, when binding to port 0 to figure out
    /// which port was actually bound.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.inner.source.local_addr()
    }

    /// Consumes this listener, returning a stream of the sockets this listener
    /// accepts.
    ///
    /// This method returns an implementation of the `Stream` trait which
    /// resolves to the sockets the are accepted on this listener.
    pub fn incoming(self) -> Box<IoStream<(TcpStream, SocketAddr)>> {
        let TcpListener { loop_handle, inner } = self;
        let source = inner.source;

        inner.ready_read
            .and_then(move |()| source.accept())
            .filter_map(|i| i) // discard spurious notifications
            .and_then(move |(tcp, addr)| {
                ReadinessPair::new(loop_handle.clone(), tcp).map(move |pair| {
                    let stream = TcpStream {
                        source: pair.source,
                        ready_read: pair.ready_read,
                        ready_write: pair.ready_write,
                    };
                    (stream, addr)
                })
            }).boxed()
    }
}

/// An I/O object representing a TCP stream connected to a remote endpoint.
///
/// A TCP stream can either be created by connecting to an endpoint or by
/// accepting a connection from a listener. Inside the stream is access to the
/// raw underlying I/O object as well as streams for the read/write
/// notifications on the stream itself.
#[allow(missing_docs)]
pub struct TcpStream {
    pub source: Arc<mio::tcp::TcpStream>,
    pub ready_read: ReadinessStream,
    pub ready_write: ReadinessStream,
}

impl TcpStream {
    fn new(connected_stream: mio::tcp::TcpStream,
           handle: LoopHandle)
           -> Box<IoFuture<TcpStream>> {
        // Once we've connected, wait for the stream to be writable as that's
        // when the actual connection has been initiated. Once we're writable we
        // check for `take_socket_error` to see if the connect actually hit an
        // error or not.
        //
        // If all that succeeded then we ship everything on up.
        ReadinessPair::new(handle, connected_stream).and_then(|pair| {
            let ReadinessPair { source, ready_read, ready_write } = pair;
            let source_for_skip = source.clone(); // TODO: find a better way to do this
            let connected = ready_write.skip_while(move |&()| {
                match source_for_skip.take_socket_error() {
                    Ok(()) => Ok(false),
                    Err(ref e) if e.kind() == ErrorKind::WouldBlock => Ok(true),
                    Err(e) => Err(e),
                }
            });
            let connected = connected.into_future();
            connected.map(move |(_, stream)| {
                TcpStream {
                    source: source,
                    ready_read: ready_read,
                    ready_write: stream.into_inner()
                }
            }).map_err(|(e, _)| e)
        }).boxed()
    }

    /// Creates a new `TcpStream` from the pending socket inside the given
    /// `std::net::TcpStream`, connecting it to the address specified.
    ///
    /// This constructor allows configuring the socket before it's actually
    /// connected, and this function will transfer ownership to the returned
    /// `TcpStream` if successful. An unconnected `TcpStream` can be created
    /// with the `net2::TcpBuilder` type (and also configured via that route).
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and then a
    ///   `connect` call is issued.
    ///
    /// * On Windows, the address is stored internally and the connect operation
    ///   is issued when the returned `TcpStream` is registered with an event
    ///   loop. Note that on Windows you must `bind` a socket before it can be
    ///   connected, so if a custom `TcpBuilder` is used it should be bound
    ///   (perhaps to `INADDR_ANY`) before this method is called.
    pub fn connect_stream(stream: net::TcpStream,
                          addr: &SocketAddr,
                          handle: LoopHandle) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect_stream(stream, addr) {
            Ok(tcp) => TcpStream::new(tcp, handle),
            Err(e) => failed(e).boxed(),
        }
    }
}

impl LoopHandle {
    /// Create a new TCP listener associated with this event loop.
    ///
    /// The TCP listener will bind to the provided `addr` address, if available,
    /// and will be returned as a future. The returned future, if resolved
    /// successfully, can then be used to accept incoming connections.
    pub fn tcp_listen(self, addr: &SocketAddr) -> Box<IoFuture<TcpListener>> {
        match mio::tcp::TcpListener::bind(addr) {
            Ok(l) => TcpListener::new(l, self),
            Err(e) => failed(e).boxed(),
        }
    }

    /// Create a new TCP stream connected to the specified address.
    ///
    /// This function will create a new TCP socket and attempt to connect it to
    /// the `addr` provided. The returned future will be resolved once the
    /// stream has successfully connected. If an error happens during the
    /// connection or during the socket creation, that error will be returned to
    /// the future instead.
    pub fn tcp_connect(self, addr: &SocketAddr) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect(addr) {
            Ok(tcp) => TcpStream::new(tcp, self),
            Err(e) => failed(e).boxed(),
        }
    }
}
<commit_msg>Accept as many connections as possible<commit_after>use std::io::{self, ErrorKind};
use std::sync::Arc;
use std::net::{self, SocketAddr};

use futures::stream::{self, Stream};
use futures::{Future, IntoFuture, failed};
use mio;

use {IoFuture, IoStream, ReadinessPair, ReadinessStream, LoopHandle};

/// An I/O object representing a TCP socket listening for incoming connections.
///
/// This object can be converted into a stream of incoming connections for
/// various forms of processing.
pub struct TcpListener {
    loop_handle: LoopHandle,
    inner: ReadinessPair<mio::tcp::TcpListener>,
}

impl TcpListener {
    fn new(listener: mio::tcp::TcpListener,
           handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        ReadinessPair::new(handle.clone(), listener).map(|p| {
            TcpListener { loop_handle: handle, inner: p }
        }).boxed()
    }

    /// Create a new TCP listener from the standard library's TCP listener.
    ///
    /// This method can be used when the `LoopHandle::tcp_listen` method isn't
    /// sufficient because perhaps some more configuration is needed in terms of
    /// before the calls to `bind` and `listen`.
    ///
    /// This API is typically paired with the `net2` crate and the `TcpBuilder`
    /// type to build up and customize a listener before it's shipped off to the
    /// backing event loop. This allows configuration of options like
    /// `SO_REUSEPORT`, binding to multiple addresses, etc.
    ///
    /// The `addr` argument here is one of the addresses that `listener` is
    /// bound to and the listener will only be guaranteed to accept connections
    /// of the same address type currently.
    ///
    /// Finally, the `handle` argument is the event loop that this listener will
    /// be bound to.
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and connections
    ///   can be accepted as normal
    ///
    /// * On Windows, the address is stored internally and all future accepts
    ///   will only be for the same IP version as `addr` specified. That is, if
    ///   `addr` is an IPv4 address then all sockets accepted will be IPv4 as
    ///   well (same for IPv6).
    pub fn from_listener(listener: net::TcpListener,
                         addr: &SocketAddr,
                         handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        mio::tcp::TcpListener::from_listener(listener, addr)
            .into_future()
            .and_then(|l| TcpListener::new(l, handle))
            .boxed()
    }

    /// Returns the local address that this listener is bound to.
    ///
    /// This can be useful, for example, when binding to port 0 to figure out
    /// which port was actually bound.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.inner.source.local_addr()
    }

    /// Consumes this listener, returning a stream of the sockets this listener
    /// accepts.
    ///
    /// This method returns an implementation of the `Stream` trait which
    /// resolves to the sockets the are accepted on this listener.
    pub fn incoming(self) -> Box<IoStream<(TcpStream, SocketAddr)>> {
        let TcpListener { loop_handle, inner } = self;
        let source = inner.source;

        inner.ready_read
            .map(move |()| {
                stream::iter(NonblockingIter {
                    source: source.clone()
                }.fuse()).and_then(|e| e)
            })
            .flatten()
            .and_then(move |(tcp, addr)| {
                ReadinessPair::new(loop_handle.clone(), tcp).map(move |pair| {
                    let stream = TcpStream {
                        source: pair.source,
                        ready_read: pair.ready_read,
                        ready_write: pair.ready_write,
                    };
                    (stream, addr)
                })
            }).boxed()
    }
}

struct NonblockingIter {
    source: Arc<mio::tcp::TcpListener>,
}

impl Iterator for NonblockingIter {
    type Item = io::Result<(mio::tcp::TcpStream, SocketAddr)>;

    fn next(&mut self) -> Option<io::Result<(mio::tcp::TcpStream, SocketAddr)>> {
        match self.source.accept() {
            Ok(Some(e)) => Some(Ok(e)),
            Ok(None) => None,
            Err(e) => Some(Err(e)),
        }
    }
}

/// An I/O object representing a TCP stream connected to a remote endpoint.
///
/// A TCP stream can either be created by connecting to an endpoint or by
/// accepting a connection from a listener. Inside the stream is access to the
/// raw underlying I/O object as well as streams for the read/write
/// notifications on the stream itself.
#[allow(missing_docs)]
pub struct TcpStream {
    pub source: Arc<mio::tcp::TcpStream>,
    pub ready_read: ReadinessStream,
    pub ready_write: ReadinessStream,
}

impl TcpStream {
    fn new(connected_stream: mio::tcp::TcpStream,
           handle: LoopHandle)
           -> Box<IoFuture<TcpStream>> {
        // Once we've connected, wait for the stream to be writable as that's
        // when the actual connection has been initiated. Once we're writable we
        // check for `take_socket_error` to see if the connect actually hit an
        // error or not.
        //
        // If all that succeeded then we ship everything on up.
        ReadinessPair::new(handle, connected_stream).and_then(|pair| {
            let ReadinessPair { source, ready_read, ready_write } = pair;
            let source_for_skip = source.clone(); // TODO: find a better way to do this
            let connected = ready_write.skip_while(move |&()| {
                match source_for_skip.take_socket_error() {
                    Ok(()) => Ok(false),
                    Err(ref e) if e.kind() == ErrorKind::WouldBlock => Ok(true),
                    Err(e) => Err(e),
                }
            });
            let connected = connected.into_future();
            connected.map(move |(_, stream)| {
                TcpStream {
                    source: source,
                    ready_read: ready_read,
                    ready_write: stream.into_inner()
                }
            }).map_err(|(e, _)| e)
        }).boxed()
    }

    /// Creates a new `TcpStream` from the pending socket inside the given
    /// `std::net::TcpStream`, connecting it to the address specified.
    ///
    /// This constructor allows configuring the socket before it's actually
    /// connected, and this function will transfer ownership to the returned
    /// `TcpStream` if successful. An unconnected `TcpStream` can be created
    /// with the `net2::TcpBuilder` type (and also configured via that route).
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and then a
    ///   `connect` call is issued.
    ///
    /// * On Windows, the address is stored internally and the connect operation
    ///   is issued when the returned `TcpStream` is registered with an event
    ///   loop. Note that on Windows you must `bind` a socket before it can be
    ///   connected, so if a custom `TcpBuilder` is used it should be bound
    ///   (perhaps to `INADDR_ANY`) before this method is called.
    pub fn connect_stream(stream: net::TcpStream,
                          addr: &SocketAddr,
                          handle: LoopHandle) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect_stream(stream, addr) {
            Ok(tcp) => TcpStream::new(tcp, handle),
            Err(e) => failed(e).boxed(),
        }
    }
}

impl LoopHandle {
    /// Create a new TCP listener associated with this event loop.
    ///
    /// The TCP listener will bind to the provided `addr` address, if available,
    /// and will be returned as a future. The returned future, if resolved
    /// successfully, can then be used to accept incoming connections.
    pub fn tcp_listen(self, addr: &SocketAddr) -> Box<IoFuture<TcpListener>> {
        match mio::tcp::TcpListener::bind(addr) {
            Ok(l) => TcpListener::new(l, self),
            Err(e) => failed(e).boxed(),
        }
    }

    /// Create a new TCP stream connected to the specified address.
    ///
    /// This function will create a new TCP socket and attempt to connect it to
    /// the `addr` provided. The returned future will be resolved once the
    /// stream has successfully connected. If an error happens during the
    /// connection or during the socket creation, that error will be returned to
    /// the future instead.
    pub fn tcp_connect(self, addr: &SocketAddr) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect(addr) {
            Ok(tcp) => TcpStream::new(tcp, self),
            Err(e) => failed(e).boxed(),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>:art: Add serde options<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests for get_slice()<commit_after>#[test]
fn get_slice_array_test() {
    let array = [1, 2, 3, 4, 5];
    assert_eq!(array.get_slice(2, None), array[2..]);
    assert_eq!(array.get_slice(2, array.len()), array[2..array.len()]);
    assert_eq!(array.get_slice(None, 2), array[..2]);
    assert_eq!(array.get_slice(0, 2), array[0..2]);
    assert_eq!(array.get_slice(1, array.len()), array[1..array.len()]);
    assert_eq!(array.get_slice(1, array.len() + 1), array[1..array.len()]);
    assert_eq!(array.get_slice(array.len(), array.len()), array[array.len()..array.len()]);
    assert_eq!(array.get_slice(array.len() + 2, array.len() + 2), array[array.len()..array.len()]);
}
<|endoftext|>


<commit_before><commit_msg>Add Rust solutin for balanced brackets<commit_after>use std::collections::HashMap;

fn balanced_brackets(s: &str) -> bool {
  // Use a vector as a stack
  let mut stack = Vec::new();

  let mut matches = HashMap::new();
  matches.insert(')', '(');
  matches.insert(']', '[');
  matches.insert('}', '{');

  for c in s.chars() {
    match c {
      '(' | '[' | '{' => stack.push(c),
      ')' | ']' | '}' => {
        let prev = stack.pop();
        match matches.get(&c) {
          Some(prev) => (),
          _ => unreachable!()
        }
      }
      _ => return false, // Not a bracket
    }
  }
  true
}

fn main() {
    assert_eq!(true, balanced_brackets("{([][[[][]({})]])}"));
}
<|endoftext|>


<commit_before>// This whole file is strongly inspired by: https://github.com/jeaye/q3/blob/master/src/client/ui/ttf/glyph.rs
// available under the BSD-3 licence.
// It has been modified to work with gl-rs, nalgebra, and rust-freetype

use na::Vec2;

#[repr(packed)]
/// A ttf glyph.
pub struct Glyph {
    #[doc(hidden)]
    pub tex:        Vec2<f32>,
    #[doc(hidden)]
    pub advance:    Vec2<f32>,
    #[doc(hidden)]
    pub dimensions: Vec2<f32>,
    #[doc(hidden)]
    pub offset:     Vec2<f32>,
    #[doc(hidden)]
    pub buffer:     Vec<u8>
}

impl Glyph {
    /// Creates a new empty glyph.
    pub fn new(tex:        Vec2<f32>,
               advance:    Vec2<f32>,
               dimensions: Vec2<f32>,
               offset:     Vec2<f32>,
               buffer:     Vec<u8>)
               -> Glyph {
        Glyph {
            tex:        tex,
            advance:    advance,
            dimensions: dimensions,
            offset:     offset,
            buffer:     buffer
        }
    }
}
<commit_msg>Remove unnecessary use of `#[repr(packed)]`.<commit_after>// This whole file is strongly inspired by: https://github.com/jeaye/q3/blob/master/src/client/ui/ttf/glyph.rs
// available under the BSD-3 licence.
// It has been modified to work with gl-rs, nalgebra, and rust-freetype

use na::Vec2;

/// A ttf glyph.
pub struct Glyph {
    #[doc(hidden)]
    pub tex:        Vec2<f32>,
    #[doc(hidden)]
    pub advance:    Vec2<f32>,
    #[doc(hidden)]
    pub dimensions: Vec2<f32>,
    #[doc(hidden)]
    pub offset:     Vec2<f32>,
    #[doc(hidden)]
    pub buffer:     Vec<u8>
}

impl Glyph {
    /// Creates a new empty glyph.
    pub fn new(tex:        Vec2<f32>,
               advance:    Vec2<f32>,
               dimensions: Vec2<f32>,
               offset:     Vec2<f32>,
               buffer:     Vec<u8>)
               -> Glyph {
        Glyph {
            tex:        tex,
            advance:    advance,
            dimensions: dimensions,
            offset:     offset,
            buffer:     buffer
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added fibbonacci.rs with a functional and a mutable approach.<commit_after>fn fibbonacci(num :u64) {
    let mut _curr:u64 = 1;
    let mut prev:u64 = 0;
    let mut _cont:u64 = 0;
    while _curr < num {
        println!("{}, ", prev);
        _cont = _curr;
        _curr = _curr + prev;
        prev = _cont;
    }
}

fn fibbonacci_func_caller(num :u64) {
    fibbonacci_func(num, 0, 1);
}

fn fibbonacci_func(num :u64, prev :u64, curr :u64) {
    println!("{}, ", prev);
    if prev >= num {
        return;
    }
    fibbonacci_func(num, curr, (prev+curr));
}

fn main() {
    fibbonacci_func_caller(10000000000000000000);
}<|endoftext|>


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

//! High-level bindings to Azure.

use azure::{AzRect, AzFloat, AzIntSize, AzColor, AzColorPatternRef};
use azure::{AzStrokeOptions, AzDrawOptions, AzSurfaceFormat, AzFilter, AzDrawSurfaceOptions};
use azure::{AzBackendType, AzDrawTargetRef, AzSourceSurfaceRef, AzDataSourceSurfaceRef};
use azure::{struct__AzColor};
use azure::{struct__AzDrawOptions, struct__AzDrawSurfaceOptions, struct__AzIntSize};
use azure::{struct__AzRect, struct__AzStrokeOptions};
use azure::bindgen::{AzCreateColorPattern, AzCreateDrawTarget, AzCreateDrawTargetForData};
use azure::bindgen::{AzDataSourceSurfaceGetData, AzDataSourceSurfaceGetStride};
use azure::bindgen::{AzDrawTargetClearRect};
use azure::bindgen::{AzDrawTargetCreateSourceSurfaceFromData};
use azure::bindgen::{AzDrawTargetDrawSurface, AzDrawTargetFillRect, AzDrawTargetFlush};
use azure::bindgen::{AzDrawTargetGetSnapshot, AzDrawTargetSetTransform, AzDrawTargetStrokeRect};
use azure::bindgen::{AzReleaseColorPattern, AzReleaseDrawTarget};
use azure::bindgen::{AzReleaseSourceSurface, AzRetainDrawTarget};
use azure::bindgen::{AzSourceSurfaceGetDataSurface, AzSourceSurfaceGetFormat};
use azure::bindgen::{AzSourceSurfaceGetSize};

use core::libc::types::common::c99::uint16_t;
use core::cast::transmute;
use core::ptr::{null, to_unsafe_ptr};
use geom::matrix2d::Matrix2D;
use geom::rect::Rect;
use geom::size::Size2D;
use std::arc::ARC;
use std::arc;

pub trait AsAzureRect {
    fn as_azure_rect(&self) -> AzRect;
}

impl AsAzureRect for Rect<AzFloat> {
    fn as_azure_rect(&self) -> AzRect {
        struct__AzRect {
            x: self.origin.x,
            y: self.origin.y,
            width: self.size.width,
            height: self.size.height
        }
    }
}

pub trait AsAzureIntSize {
    fn as_azure_int_size(&self) -> AzIntSize;
}

impl AsAzureIntSize for Size2D<i32> {
    fn as_azure_int_size(&self) -> AzIntSize {
        struct__AzIntSize {
            width: self.width,
            height: self.height
        }
    }
}

pub struct Color {
    r: AzFloat,
    g: AzFloat,
    b: AzFloat,
    a: AzFloat,
}

impl Color {
    fn as_azure_color(&self) -> AzColor {
        struct__AzColor { r: self.r, g: self.g, b: self.b, a: self.a }
    }
}

pub fn Color(r: AzFloat, g: AzFloat, b: AzFloat, a: AzFloat) -> Color {
    Color { r: r, g: g, b: b, a: a }
}

// FIXME: Should have a class hierarchy here starting with Pattern.
pub struct ColorPattern {
    azure_color_pattern: AzColorPatternRef,
}

impl Drop for ColorPattern {
    fn finalize(&self) {
        unsafe {
            AzReleaseColorPattern(self.azure_color_pattern);
        }
    }
}

pub fn ColorPattern(color: Color) -> ColorPattern {
    unsafe {
        ColorPattern {
            azure_color_pattern: AzCreateColorPattern(&color.as_azure_color())
        }
    }
}

pub struct StrokeOptions {
    line_width: AzFloat,
    miter_limit: AzFloat,
    fields: uint16_t,
}

impl StrokeOptions {
    fn as_azure_stroke_options(&self) -> AzStrokeOptions {
        struct__AzStrokeOptions {
            mLineWidth: self.line_width,
            mMiterLimit: self.miter_limit,
            mDashPattern: null(),
            mDashLength: 0,
            mDashOffset: 0.0f as AzFloat,
            fields: self.fields
        }
    }
}

pub fn StrokeOptions(line_width: AzFloat,
                  miter_limit: AzFloat,
                  fields: uint16_t) -> StrokeOptions {
    StrokeOptions {
        line_width: line_width,
        miter_limit: miter_limit,
        fields: fields
    }
}

pub struct DrawOptions {
    alpha: AzFloat,
    fields: uint16_t,
}

impl DrawOptions {
    fn as_azure_draw_options(&self) -> AzDrawOptions {
        struct__AzDrawOptions {
            mAlpha: self.alpha,
            fields: self.fields
        }
    }
}

pub fn DrawOptions(alpha: AzFloat, fields: uint16_t) -> DrawOptions {
    DrawOptions {
        alpha : alpha,
        fields : fields,
    }
}

pub enum SurfaceFormat {
    B8G8R8A8,
    B8G8R8X8,
    R5G6B5,
    A8
}

impl SurfaceFormat {
    fn as_azure_surface_format(self) -> AzSurfaceFormat {
        self as AzSurfaceFormat
    }

    pub fn new(azure_surface_format: AzSurfaceFormat) -> SurfaceFormat {
        match azure_surface_format {
            0 => B8G8R8A8,
            1 => B8G8R8X8,
            2 => R5G6B5,
            3 => A8,
            _ => fail!(~"SurfaceFormat::new(): unknown Azure surface format")
        }
    }
}

pub enum Filter {
    Linear,
    Point
}

impl Filter {
    fn as_azure_filter(self) -> AzFilter {
        self as AzFilter
    }
}

pub struct DrawSurfaceOptions {
    filter: Filter,
    sampling_bounds: bool,
}

impl DrawSurfaceOptions {
    fn as_azure_draw_surface_options(&self) -> AzDrawSurfaceOptions {
        struct__AzDrawSurfaceOptions {
            fields: ((self.filter as int) | (if self.sampling_bounds { 8 } else { 0 })) as u32
        }
    }
}

pub fn DrawSurfaceOptions(filter: Filter, sampling_bounds: bool) -> DrawSurfaceOptions {
    DrawSurfaceOptions {
        filter: filter,
        sampling_bounds: sampling_bounds,
    }
}

pub enum BackendType {
    NoBackend,
    Direct2DBackend,
    CoreGraphicsBackend,
    CoreGraphicsAcceleratedBackend,
    CairoBackend,
    SkiaBackend,
    RecordingBackend
}

impl BackendType {
    pub fn as_azure_backend_type(self) -> AzBackendType {
        match self {
            NoBackend                      => 0,
            Direct2DBackend                => 1,
            CoreGraphicsBackend            => 2,
            CoreGraphicsAcceleratedBackend => 3,
            CairoBackend                   => 4,
            SkiaBackend                    => 5,
            RecordingBackend               => 6,
        }
    }
}

pub struct DrawTarget {
    azure_draw_target: AzDrawTargetRef,
    data: Option<ARC<~[u8]>>,
}

impl Drop for DrawTarget {
    fn finalize(&self) {
        unsafe {
            AzReleaseDrawTarget(self.azure_draw_target);
        }
    }
}

pub impl DrawTarget {
    pub fn new(backend: BackendType, size: Size2D<i32>, format: SurfaceFormat)
                   -> DrawTarget {
        unsafe {
            let azure_draw_target = AzCreateDrawTarget(backend.as_azure_backend_type(),
                                                       to_unsafe_ptr(&size.as_azure_int_size()),
                                                       format.as_azure_surface_format());
            if azure_draw_target == ptr::null() { fail!(~"null azure draw target"); }
            DrawTarget { azure_draw_target: azure_draw_target, data: None }
        }
    }

    pub fn new_with_data(backend: BackendType,
                         data: ~[u8],
                         offset: uint,
                         size: Size2D<i32>,
                         stride: i32,
                         format: SurfaceFormat) -> DrawTarget {
        unsafe {
            assert!((data.len() - offset) as i32 >= stride * size.height);
            let azure_draw_target =
                AzCreateDrawTargetForData(backend.as_azure_backend_type(),
                                          to_unsafe_ptr(&data[offset]),
                                          to_unsafe_ptr(&size.as_azure_int_size()),
                                          stride,
                                          format.as_azure_surface_format());
            if azure_draw_target == ptr::null() { fail!(~"null azure draw target"); }
            DrawTarget {
                azure_draw_target: azure_draw_target,
                data: Some(ARC(data))
            }
        }
    }

    fn clone(&const self) -> DrawTarget {
        unsafe {
            AzRetainDrawTarget(self.azure_draw_target);
            DrawTarget {
                azure_draw_target: self.azure_draw_target,
                data: match self.data {
                    None => None,
                    Some(ref arc) => {
                        // FIXME: Workaround for the fact that arc::clone doesn't
                        // take const.
                        Some(arc::clone(cast::transmute(arc)))
                    }
                }
            }
        }
    }

    fn flush(&self) {
        unsafe {
            AzDrawTargetFlush(self.azure_draw_target);
        }
    }

    fn clear_rect(&self, rect: &Rect<AzFloat>) {
        unsafe {
            AzDrawTargetClearRect(self.azure_draw_target, &rect.as_azure_rect());
        }
    }

    fn fill_rect(&self, rect: &Rect<AzFloat>, pattern: &ColorPattern) {
        unsafe {
            AzDrawTargetFillRect(self.azure_draw_target,
                                 to_unsafe_ptr(&rect.as_azure_rect()),
                                 pattern.azure_color_pattern);
        }
    }

    fn stroke_rect(&self,
                   rect: &Rect<AzFloat>,
                   pattern: &ColorPattern,
                   stroke_options: &StrokeOptions,
                   draw_options: &DrawOptions) {
        unsafe {
            AzDrawTargetStrokeRect(self.azure_draw_target,
                                   &rect.as_azure_rect(),
                                   pattern.azure_color_pattern,
                                   &stroke_options.as_azure_stroke_options(),
                                   &draw_options.as_azure_draw_options());
        }
    }

    fn draw_surface(&self,
                    surface: SourceSurface,
                    dest: Rect<AzFloat>,
                    source: Rect<AzFloat>,
                    surf_options: DrawSurfaceOptions,
                    options: DrawOptions) {
        unsafe {
            AzDrawTargetDrawSurface(self.azure_draw_target,
                                    surface.azure_source_surface,
                                    to_unsafe_ptr(&dest.as_azure_rect()),
                                    to_unsafe_ptr(&source.as_azure_rect()),
                                    to_unsafe_ptr(&surf_options.as_azure_draw_surface_options()),
                                    to_unsafe_ptr(&options.as_azure_draw_options()));
        }
    }

    fn snapshot(&const self) -> SourceSurface {
        unsafe {
            let azure_surface = AzDrawTargetGetSnapshot(self.azure_draw_target);
            SourceSurface(azure_surface)
        }
    }

    fn create_source_surface_from_data(&self,
                                       data: &[u8],
                                       size: Size2D<i32>,
                                       stride: i32,
                                       format: SurfaceFormat)
                                    -> SourceSurface {
        assert!(data.len() as i32 == stride * size.height);
        unsafe {
            let azure_surface = AzDrawTargetCreateSourceSurfaceFromData(
                self.azure_draw_target,
                &data[0],
                &size.as_azure_int_size(),
                stride,
                format.as_azure_surface_format());
            SourceSurface(azure_surface)
        }
    }

    fn set_transform(&self, matrix: &Matrix2D<AzFloat>) {
        unsafe {
            AzDrawTargetSetTransform(self.azure_draw_target, transmute(matrix));
        }
    }
}

// Ugly workaround for the lack of explicit self.
pub fn clone_mutable_draw_target(draw_target: &mut DrawTarget) -> DrawTarget {
    return draw_target.clone();
}

pub fn new_draw_target_from_azure_draw_target(azure_draw_target: AzDrawTargetRef) -> DrawTarget {
    unsafe {
        AzRetainDrawTarget(azure_draw_target);
        DrawTarget {
            azure_draw_target: azure_draw_target,
            data: None
        }
    }
}

pub struct SourceSurface {
    priv azure_source_surface: AzSourceSurfaceRef,
}

impl Drop for SourceSurface {
    fn finalize(&self) {
        unsafe {
            AzReleaseSourceSurface(self.azure_source_surface);
        }
    }
}

pub fn SourceSurface(azure_source_surface: AzSourceSurfaceRef) -> SourceSurface {
    SourceSurface {
        azure_source_surface: azure_source_surface
    }
}

pub trait SourceSurfaceMethods {
    fn get_azure_source_surface(&const self) -> AzSourceSurfaceRef;

    fn size(&const self) -> Size2D<i32> {
        unsafe {
            let size = AzSourceSurfaceGetSize(self.get_azure_source_surface());
            Size2D { width: size.width, height: size.height }
        }
    }

    fn format(&const self) -> SurfaceFormat {
        unsafe {
            SurfaceFormat::new(AzSourceSurfaceGetFormat(self.get_azure_source_surface()))
        }
    }
}

impl SourceSurface {
    pub fn get_data_surface(&const self) -> DataSourceSurface {
        unsafe {
            let data_source_surface = AzSourceSurfaceGetDataSurface(
                self.azure_source_surface);
            DataSourceSurface {
                azure_data_source_surface: data_source_surface
            }
        }
    }
}

impl SourceSurfaceMethods for SourceSurface {
    fn get_azure_source_surface(&const self) -> AzSourceSurfaceRef { self.azure_source_surface }
}

pub struct DataSourceSurface {
    priv azure_data_source_surface: AzDataSourceSurfaceRef,
}

impl Drop for DataSourceSurface {
    fn finalize(&self) {
        unsafe {
            AzReleaseSourceSurface(self.azure_data_source_surface);
        }
    }
}

impl DataSourceSurface {
    pub fn with_data(&const self, f: &fn(&[u8])) {
        unsafe {
            let buf = AzDataSourceSurfaceGetData(self.azure_data_source_surface);
            let len = self.stride() * self.size().height;
            vec::raw::buf_as_slice(buf, len as uint, f);
        }
    }

    pub fn stride(&const self) -> i32 {
        unsafe {
            AzDataSourceSurfaceGetStride(self.azure_data_source_surface)
        }
    }

    // FIXME: Workaround for lack of working cross-crate default methods.
    pub fn get_size(&const self) -> Size2D<i32> {
        self.size()
    }
}

impl SourceSurfaceMethods for DataSourceSurface {
    fn get_azure_source_surface(&const self) -> AzSourceSurfaceRef {
        self.azure_data_source_surface
    }
}

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

//! High-level bindings to Azure.

use azure::{AzRect, AzFloat, AzIntSize, AzColor, AzColorPatternRef};
use azure::{AzStrokeOptions, AzDrawOptions, AzSurfaceFormat, AzFilter, AzDrawSurfaceOptions};
use azure::{AzBackendType, AzDrawTargetRef, AzSourceSurfaceRef, AzDataSourceSurfaceRef};
use azure::{struct__AzColor};
use azure::{struct__AzDrawOptions, struct__AzDrawSurfaceOptions, struct__AzIntSize};
use azure::{struct__AzRect, struct__AzStrokeOptions};
use azure::bindgen::{AzCreateColorPattern, AzCreateDrawTarget, AzCreateDrawTargetForData};
use azure::bindgen::{AzDataSourceSurfaceGetData, AzDataSourceSurfaceGetStride};
use azure::bindgen::{AzDrawTargetClearRect};
use azure::bindgen::{AzDrawTargetCreateSourceSurfaceFromData};
use azure::bindgen::{AzDrawTargetDrawSurface, AzDrawTargetFillRect, AzDrawTargetFlush};
use azure::bindgen::{AzDrawTargetGetSnapshot, AzDrawTargetSetTransform, AzDrawTargetStrokeRect};
use azure::bindgen::{AzReleaseColorPattern, AzReleaseDrawTarget};
use azure::bindgen::{AzReleaseSourceSurface, AzRetainDrawTarget};
use azure::bindgen::{AzSourceSurfaceGetDataSurface, AzSourceSurfaceGetFormat};
use azure::bindgen::{AzSourceSurfaceGetSize};

use core::libc::types::common::c99::uint16_t;
use core::cast::transmute;
use core::ptr::{null, to_unsafe_ptr};
use geom::matrix2d::Matrix2D;
use geom::rect::Rect;
use geom::size::Size2D;
use std::arc::ARC;
use std::arc;

pub trait AsAzureRect {
    fn as_azure_rect(&self) -> AzRect;
}

impl AsAzureRect for Rect<AzFloat> {
    fn as_azure_rect(&self) -> AzRect {
        struct__AzRect {
            x: self.origin.x,
            y: self.origin.y,
            width: self.size.width,
            height: self.size.height
        }
    }
}

pub trait AsAzureIntSize {
    fn as_azure_int_size(&self) -> AzIntSize;
}

impl AsAzureIntSize for Size2D<i32> {
    fn as_azure_int_size(&self) -> AzIntSize {
        struct__AzIntSize {
            width: self.width,
            height: self.height
        }
    }
}

pub struct Color {
    r: AzFloat,
    g: AzFloat,
    b: AzFloat,
    a: AzFloat,
}

impl Color {
    fn as_azure_color(&self) -> AzColor {
        struct__AzColor { r: self.r, g: self.g, b: self.b, a: self.a }
    }
}

pub fn Color(r: AzFloat, g: AzFloat, b: AzFloat, a: AzFloat) -> Color {
    Color { r: r, g: g, b: b, a: a }
}

// FIXME: Should have a class hierarchy here starting with Pattern.
pub struct ColorPattern {
    azure_color_pattern: AzColorPatternRef,
}

impl Drop for ColorPattern {
    fn finalize(&self) {
        unsafe {
            AzReleaseColorPattern(self.azure_color_pattern);
        }
    }
}

pub fn ColorPattern(color: Color) -> ColorPattern {
    unsafe {
        ColorPattern {
            azure_color_pattern: AzCreateColorPattern(&color.as_azure_color())
        }
    }
}

pub struct StrokeOptions {
    line_width: AzFloat,
    miter_limit: AzFloat,
    fields: uint16_t,
}

impl StrokeOptions {
    fn as_azure_stroke_options(&self) -> AzStrokeOptions {
        struct__AzStrokeOptions {
            mLineWidth: self.line_width,
            mMiterLimit: self.miter_limit,
            mDashPattern: null(),
            mDashLength: 0,
            mDashOffset: 0.0f as AzFloat,
            fields: self.fields
        }
    }
}

pub fn StrokeOptions(line_width: AzFloat,
                  miter_limit: AzFloat,
                  fields: uint16_t) -> StrokeOptions {
    StrokeOptions {
        line_width: line_width,
        miter_limit: miter_limit,
        fields: fields
    }
}

pub struct DrawOptions {
    alpha: AzFloat,
    fields: uint16_t,
}

impl DrawOptions {
    fn as_azure_draw_options(&self) -> AzDrawOptions {
        struct__AzDrawOptions {
            mAlpha: self.alpha,
            fields: self.fields
        }
    }
}

pub fn DrawOptions(alpha: AzFloat, fields: uint16_t) -> DrawOptions {
    DrawOptions {
        alpha : alpha,
        fields : fields,
    }
}

pub enum SurfaceFormat {
    B8G8R8A8,
    B8G8R8X8,
    R5G6B5,
    A8
}

impl SurfaceFormat {
    fn as_azure_surface_format(self) -> AzSurfaceFormat {
        self as AzSurfaceFormat
    }

    pub fn new(azure_surface_format: AzSurfaceFormat) -> SurfaceFormat {
        match azure_surface_format {
            0 => B8G8R8A8,
            1 => B8G8R8X8,
            2 => R5G6B5,
            3 => A8,
            _ => fail!(~"SurfaceFormat::new(): unknown Azure surface format")
        }
    }
}

pub enum Filter {
    Linear,
    Point
}

impl Filter {
    fn as_azure_filter(self) -> AzFilter {
        self as AzFilter
    }
}

pub struct DrawSurfaceOptions {
    filter: Filter,
    sampling_bounds: bool,
}

impl DrawSurfaceOptions {
    fn as_azure_draw_surface_options(&self) -> AzDrawSurfaceOptions {
        struct__AzDrawSurfaceOptions {
            fields: ((self.filter as int) | (if self.sampling_bounds { 8 } else { 0 })) as u32
        }
    }
}

pub fn DrawSurfaceOptions(filter: Filter, sampling_bounds: bool) -> DrawSurfaceOptions {
    DrawSurfaceOptions {
        filter: filter,
        sampling_bounds: sampling_bounds,
    }
}

pub enum BackendType {
    NoBackend,
    Direct2DBackend,
    CoreGraphicsBackend,
    CoreGraphicsAcceleratedBackend,
    CairoBackend,
    SkiaBackend,
    RecordingBackend
}

impl BackendType {
    pub fn as_azure_backend_type(self) -> AzBackendType {
        match self {
            NoBackend                      => 0,
            Direct2DBackend                => 1,
            CoreGraphicsBackend            => 2,
            CoreGraphicsAcceleratedBackend => 3,
            CairoBackend                   => 4,
            SkiaBackend                    => 5,
            RecordingBackend               => 6,
        }
    }
}

pub struct DrawTarget {
    azure_draw_target: AzDrawTargetRef,
    data: Option<ARC<~[u8]>>,
}

impl Drop for DrawTarget {
    fn finalize(&self) {
        unsafe {
            AzReleaseDrawTarget(self.azure_draw_target);
        }
    }
}

pub impl DrawTarget {
    pub fn new(backend: BackendType, size: Size2D<i32>, format: SurfaceFormat)
                   -> DrawTarget {
        unsafe {
            let azure_draw_target = AzCreateDrawTarget(backend.as_azure_backend_type(),
                                                       to_unsafe_ptr(&size.as_azure_int_size()),
                                                       format.as_azure_surface_format());
            if azure_draw_target == ptr::null() { fail!(~"null azure draw target"); }
            DrawTarget { azure_draw_target: azure_draw_target, data: None }
        }
    }

    pub fn new_with_data(backend: BackendType,
                         data: ~[u8],
                         offset: uint,
                         size: Size2D<i32>,
                         stride: i32,
                         format: SurfaceFormat) -> DrawTarget {
        unsafe {
            assert!((data.len() - offset) as i32 >= stride * size.height);
            let azure_draw_target =
                AzCreateDrawTargetForData(backend.as_azure_backend_type(),
                                          to_unsafe_ptr(&data[offset]),
                                          to_unsafe_ptr(&size.as_azure_int_size()),
                                          stride,
                                          format.as_azure_surface_format());
            if azure_draw_target == ptr::null() { fail!(~"null azure draw target"); }
            DrawTarget {
                azure_draw_target: azure_draw_target,
                data: Some(ARC(data))
            }
        }
    }

    fn clone(&self) -> DrawTarget {
        unsafe {
            AzRetainDrawTarget(self.azure_draw_target);
            DrawTarget {
                azure_draw_target: self.azure_draw_target,
                data: match self.data {
                    None => None,
                    Some(ref arc) => {
                        // FIXME: Workaround for the fact that arc::clone doesn't
                        // take const.
                        Some(arc::clone(cast::transmute(arc)))
                    }
                }
            }
        }
    }

    fn flush(&self) {
        unsafe {
            AzDrawTargetFlush(self.azure_draw_target);
        }
    }

    fn clear_rect(&self, rect: &Rect<AzFloat>) {
        unsafe {
            AzDrawTargetClearRect(self.azure_draw_target, &rect.as_azure_rect());
        }
    }

    fn fill_rect(&self, rect: &Rect<AzFloat>, pattern: &ColorPattern) {
        unsafe {
            AzDrawTargetFillRect(self.azure_draw_target,
                                 to_unsafe_ptr(&rect.as_azure_rect()),
                                 pattern.azure_color_pattern);
        }
    }

    fn stroke_rect(&self,
                   rect: &Rect<AzFloat>,
                   pattern: &ColorPattern,
                   stroke_options: &StrokeOptions,
                   draw_options: &DrawOptions) {
        unsafe {
            AzDrawTargetStrokeRect(self.azure_draw_target,
                                   &rect.as_azure_rect(),
                                   pattern.azure_color_pattern,
                                   &stroke_options.as_azure_stroke_options(),
                                   &draw_options.as_azure_draw_options());
        }
    }

    fn draw_surface(&self,
                    surface: SourceSurface,
                    dest: Rect<AzFloat>,
                    source: Rect<AzFloat>,
                    surf_options: DrawSurfaceOptions,
                    options: DrawOptions) {
        unsafe {
            AzDrawTargetDrawSurface(self.azure_draw_target,
                                    surface.azure_source_surface,
                                    to_unsafe_ptr(&dest.as_azure_rect()),
                                    to_unsafe_ptr(&source.as_azure_rect()),
                                    to_unsafe_ptr(&surf_options.as_azure_draw_surface_options()),
                                    to_unsafe_ptr(&options.as_azure_draw_options()));
        }
    }

    fn snapshot(&self) -> SourceSurface {
        unsafe {
            let azure_surface = AzDrawTargetGetSnapshot(self.azure_draw_target);
            SourceSurface(azure_surface)
        }
    }

    fn create_source_surface_from_data(&self,
                                       data: &[u8],
                                       size: Size2D<i32>,
                                       stride: i32,
                                       format: SurfaceFormat)
                                    -> SourceSurface {
        assert!(data.len() as i32 == stride * size.height);
        unsafe {
            let azure_surface = AzDrawTargetCreateSourceSurfaceFromData(
                self.azure_draw_target,
                &data[0],
                &size.as_azure_int_size(),
                stride,
                format.as_azure_surface_format());
            SourceSurface(azure_surface)
        }
    }

    fn set_transform(&self, matrix: &Matrix2D<AzFloat>) {
        unsafe {
            AzDrawTargetSetTransform(self.azure_draw_target, transmute(matrix));
        }
    }
}

// Ugly workaround for the lack of explicit self.
pub fn clone_mutable_draw_target(draw_target: &mut DrawTarget) -> DrawTarget {
    return draw_target.clone();
}

pub fn new_draw_target_from_azure_draw_target(azure_draw_target: AzDrawTargetRef) -> DrawTarget {
    unsafe {
        AzRetainDrawTarget(azure_draw_target);
        DrawTarget {
            azure_draw_target: azure_draw_target,
            data: None
        }
    }
}

pub struct SourceSurface {
    priv azure_source_surface: AzSourceSurfaceRef,
}

impl Drop for SourceSurface {
    fn finalize(&self) {
        unsafe {
            AzReleaseSourceSurface(self.azure_source_surface);
        }
    }
}

pub fn SourceSurface(azure_source_surface: AzSourceSurfaceRef) -> SourceSurface {
    SourceSurface {
        azure_source_surface: azure_source_surface
    }
}

pub trait SourceSurfaceMethods {
    fn get_azure_source_surface(&self) -> AzSourceSurfaceRef;

    fn size(&self) -> Size2D<i32> {
        unsafe {
            let size = AzSourceSurfaceGetSize(self.get_azure_source_surface());
            Size2D { width: size.width, height: size.height }
        }
    }

    fn format(&self) -> SurfaceFormat {
        unsafe {
            SurfaceFormat::new(AzSourceSurfaceGetFormat(self.get_azure_source_surface()))
        }
    }
}

impl SourceSurface {
    pub fn get_data_surface(&self) -> DataSourceSurface {
        unsafe {
            let data_source_surface = AzSourceSurfaceGetDataSurface(
                self.azure_source_surface);
            DataSourceSurface {
                azure_data_source_surface: data_source_surface
            }
        }
    }
}

impl SourceSurfaceMethods for SourceSurface {
    fn get_azure_source_surface(&self) -> AzSourceSurfaceRef { self.azure_source_surface }
}

pub struct DataSourceSurface {
    priv azure_data_source_surface: AzDataSourceSurfaceRef,
}

impl Drop for DataSourceSurface {
    fn finalize(&self) {
        unsafe {
            AzReleaseSourceSurface(self.azure_data_source_surface);
        }
    }
}

impl DataSourceSurface {
    pub fn with_data(&self, f: &fn(&[u8])) {
        unsafe {
            let buf = AzDataSourceSurfaceGetData(self.azure_data_source_surface);
            let len = self.stride() * self.size().height;
            vec::raw::buf_as_slice(buf, len as uint, f);
        }
    }

    pub fn stride(&self) -> i32 {
        unsafe {
            AzDataSourceSurfaceGetStride(self.azure_data_source_surface)
        }
    }

    // FIXME: Workaround for lack of working cross-crate default methods.
    pub fn get_size(&self) -> Size2D<i32> {
        self.size()
    }
}

impl SourceSurfaceMethods for DataSourceSurface {
    fn get_azure_source_surface(&self) -> AzSourceSurfaceRef {
        self.azure_data_source_surface
    }
}

<|endoftext|>


<commit_before><commit_msg>Revert "Allow dead_code in main.rs"<commit_after><|endoftext|>


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

// Test that multibyte characters don't crash the compiler
fn main() {
    io::println("마이너스 사인이 없으면");
}
<|endoftext|>


<commit_before><commit_msg>const param in async<commit_after>// edition:2018
// check-pass
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]

async fn foo<const N: usize>(arg: [u8; N]) -> usize { arg.len() }

async fn bar<const N: usize>() -> [u8; N] {
    [0; N]
}

trait Trait<const N: usize> {
    fn fynn(&self) -> usize;
}
impl<const N: usize> Trait<N> for [u8; N] {
    fn fynn(&self) -> usize {
        N
    }
}
async fn baz<const N: usize>() -> impl Trait<N> {
    [0; N]
}

async fn biz<const N: usize>(v: impl Trait<N>) -> usize {
    v.fynn()
}

async fn user<const N: usize>() {
    let _ = foo::<N>(bar().await).await;
    let _ = biz(baz::<N>().await).await;
}

fn main() { }
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #79177 - fanzier:drop-order-test, r=RalfJung<commit_after>// run-pass

//! Test that let bindings and destructuring assignments have consistent drop orders

#![feature(destructuring_assignment)]
#![allow(unused_variables, unused_assignments)]

use std::cell::RefCell;

thread_local! {
    static DROP_ORDER: RefCell<Vec<usize>> = RefCell::new(Vec::new());
}

struct DropRecorder(usize);
impl Drop for DropRecorder {
    fn drop(&mut self) {
        DROP_ORDER.with(|d| d.borrow_mut().push(self.0));
    }
}

fn main() {
    let expected_drop_order = vec![1, 4, 5, 3, 2];
    // Check the drop order for let bindings:
    {
        let _ = DropRecorder(1);
        let _val = DropRecorder(2);
        let (x, _) = (DropRecorder(3), DropRecorder(4));
        drop(DropRecorder(5));
    }
    DROP_ORDER.with(|d| {
        assert_eq!(&*d.borrow(), &expected_drop_order);
        d.borrow_mut().clear();
    });
    // Check that the drop order for destructuring assignment is the same:
    {
        let _val;
        let x;
        _ = DropRecorder(1);
        _val = DropRecorder(2);
        (x, _) = (DropRecorder(3), DropRecorder(4));
        drop(DropRecorder(5));
    }
    DROP_ORDER.with(|d| assert_eq!(&*d.borrow(), &expected_drop_order));
}
<|endoftext|>


<commit_before><commit_msg>add regression test for #48071<commit_after>// Copyright 2018 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.

// Regression test for #48071. This test used to ICE because -- in
// the leak-check -- it would pass since we knew that the return type
// was `'static`, and hence `'static: 'a` was legal even for a
// placeholder region, but in NLL land it would fail because we had
// rewritten `'static` to a region variable.
//
// compile-pass

#![allow(warnings)]
#![feature(dyn_trait)]
#![feature(nll)]

trait Foo {
    fn foo(&self) { }
}

impl Foo for () {
}

type MakeFooFn = for<'a> fn(&'a u8) -> Box<dyn Foo + 'a>;

fn make_foo(x: &u8) -> Box<dyn Foo + 'static> {
    Box::new(())
}

fn main() {
    let x: MakeFooFn = make_foo as MakeFooFn;
}
<|endoftext|>


<commit_before><commit_msg>[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks<commit_after><|endoftext|>


<commit_before><commit_msg>Problem: inject_nonce is not being used<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for if without else cannot return result<commit_after>// error-pattern:`if` without `else` can not produce a result

fn main() {
    let a = if true { true };
    log a;
}<|endoftext|>


<commit_before><commit_msg>practice<commit_after>fn main() {
    let x: i32 = 17;
    {
        let y: i32 = 3;
        println!("The value of x is {} and value of y is {}", x, y);
    }
}
<|endoftext|>


<commit_before><commit_msg>iterate over string enumerations<commit_after><|endoftext|>