<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/. */

use app_units::Au;
use device::TextureFilter;
use euclid::{TypedPoint2D, UnknownUnit};
use fnv::FnvHasher;
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits};
use profiler::BackendProfileCounters;
use std::collections::{HashMap, HashSet};
use std::f32;
use std::hash::BuildHasherDefault;
use std::{i32, usize};
use std::path::PathBuf;
use std::sync::Arc;
use tiling;
use webrender_traits::{Epoch, ColorF, PipelineId, DeviceIntSize};
use webrender_traits::{ImageFormat, MixBlendMode, NativeFontHandle};
use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand};

// An ID for a texture that is owned by the
// texture cache module. This can include atlases
// or standalone textures allocated via the
// texture cache (e.g. if an image is too large
// to be added to an atlas). The texture cache
// manages the allocation and freeing of these
// IDs, and the rendering thread maintains a
// map from cache texture ID to native texture.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct CacheTextureId(pub usize);

// Represents the source for a texture.
// These are passed from throughout the
// pipeline until they reach the rendering
// thread, where they are resolved to a
// native texture ID.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum SourceTexture {
    Invalid,
    TextureCache(CacheTextureId),
    WebGL(u32),                         // Is actually a gl::GLuint
    External(ExternalImageId),
}

pub enum GLContextHandleWrapper {
    Native(NativeGLContextHandle),
    OSMesa(OSMesaContextHandle),
}

impl GLContextHandleWrapper {
    pub fn current_native_handle() -> Option<GLContextHandleWrapper> {
        NativeGLContext::current_handle().map(GLContextHandleWrapper::Native)
    }

    pub fn current_osmesa_handle() -> Option<GLContextHandleWrapper> {
        OSMesaContext::current_handle().map(GLContextHandleWrapper::OSMesa)
    }

    pub fn new_context(&self,
                       size: DeviceIntSize,
                       attributes: GLContextAttributes,
                       dispatcher: Option<Box<GLContextDispatcher>>) -> Result<GLContextWrapper, &'static str> {
        match *self {
            GLContextHandleWrapper::Native(ref handle) => {
                let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size.to_untyped(),
                                                                                attributes,
                                                                                ColorAttachmentType::Texture,
                                                                                Some(handle),
                                                                                dispatcher);
                ctx.map(GLContextWrapper::Native)
            }
            GLContextHandleWrapper::OSMesa(ref handle) => {
                let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
                                                                                attributes,
                                                                                ColorAttachmentType::Texture,
                                                                                Some(handle),
                                                                                dispatcher);
                ctx.map(GLContextWrapper::OSMesa)
            }
        }
    }
}

pub enum GLContextWrapper {
    Native(GLContext<NativeGLContext>),
    OSMesa(GLContext<OSMesaContext>),
}

impl GLContextWrapper {
    pub fn make_current(&self) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                ctx.make_current().unwrap();
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                ctx.make_current().unwrap();
            }
        }
    }

    pub fn unbind(&self) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                ctx.unbind().unwrap();
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                ctx.unbind().unwrap();
            }
        }
    }

    pub fn apply_command(&self, cmd: WebGLCommand) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                cmd.apply(ctx);
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                cmd.apply(ctx);
            }
        }
    }

    pub fn get_info(&self) -> (DeviceIntSize, u32, GLLimits) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                let (real_size, texture_id) = {
                    let draw_buffer = ctx.borrow_draw_buffer().unwrap();
                    (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap())
                };

                let limits = ctx.borrow_limits().clone();

                (DeviceIntSize::from_untyped(&real_size), texture_id, limits)
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                let (real_size, texture_id) = {
                    let draw_buffer = ctx.borrow_draw_buffer().unwrap();
                    (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap())
                };

                let limits = ctx.borrow_limits().clone();

                (DeviceIntSize::from_untyped(&real_size), texture_id, limits)
            }
        }
    }

    pub fn resize(&mut self, size: &DeviceIntSize) -> Result<(), &'static str> {
        match *self {
            GLContextWrapper::Native(ref mut ctx) => {
                ctx.resize(size.to_untyped())
            }
            GLContextWrapper::OSMesa(ref mut ctx) => {
                ctx.resize(size.to_untyped())
            }
        }
    }
}

const COLOR_FLOAT_TO_FIXED: f32 = 255.0;
pub const ANGLE_FLOAT_TO_FIXED: f32 = 65535.0;

pub const ORTHO_NEAR_PLANE: f32 = -1000000.0;
pub const ORTHO_FAR_PLANE: f32 = 1000000.0;

#[derive(Clone)]
pub enum FontTemplate {
    Raw(Arc<Vec<u8>>),
    Native(NativeFontHandle),
}

#[derive(Debug, PartialEq, Eq)]
pub enum TextureSampler {
    Color0,
    Color1,
    Color2,
    Mask,
    Cache,
    Data16,
    Data32,
    Data64,
    Data128,
    Layers,
    RenderTasks,
    Geometry,
    ResourceRects,
}

impl TextureSampler {
    pub fn color(n: usize) -> TextureSampler {
        match n {
            0 => TextureSampler::Color0,
            1 => TextureSampler::Color1,
            2 => TextureSampler::Color2,
            _ => {
                panic!("There are only 3 color samplers.");
            }
        }
    }
}

/// Optional textures that can be used as a source in the shaders.
/// Textures that are not used by the batch are equal to TextureId::invalid().
#[derive(Copy, Clone, Debug)]
pub struct BatchTextures {
    pub colors: [SourceTexture; 3],
}

impl BatchTextures {
    pub fn no_texture() -> Self {
        BatchTextures {
            colors: [SourceTexture::Invalid; 3],
        }
    }
}

// In some places we need to temporarily bind a texture to any slot.
pub const DEFAULT_TEXTURE: TextureSampler = TextureSampler::Color0;

#[derive(Clone, Copy, Debug)]
pub enum VertexAttribute {
    // vertex-frequency basic attributes
    Position,
    Color,
    ColorTexCoord,
    // instance-frequency primitive attributes
    GlobalPrimId,
    PrimitiveAddress,
    TaskIndex,
    ClipTaskIndex,
    LayerIndex,
    ElementIndex,
    UserData,
}

#[derive(Clone, Copy, Debug)]
pub enum ClearAttribute {
    // vertex frequency
    Position,
    // instance frequency
    Rectangle,
}

#[derive(Clone, Copy, Debug)]
pub enum BlurAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    SourceTaskIndex,
    Direction,
}

#[derive(Clone, Copy, Debug)]
pub enum ClipAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    LayerIndex,
    DataIndex,
    BaseTaskIndex,
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedColor {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl PackedColor {
    pub fn from_color(color: &ColorF) -> PackedColor {
        PackedColor {
            r: (0.5 + color.r * COLOR_FLOAT_TO_FIXED).floor() as u8,
            g: (0.5 + color.g * COLOR_FLOAT_TO_FIXED).floor() as u8,
            b: (0.5 + color.b * COLOR_FLOAT_TO_FIXED).floor() as u8,
            a: (0.5 + color.a * COLOR_FLOAT_TO_FIXED).floor() as u8,
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedVertex {
    pub pos: [f32; 2],
}

#[derive(Debug)]
pub struct DebugFontVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
    pub u: f32,
    pub v: f32,
}

impl DebugFontVertex {
    pub fn new(x: f32, y: f32, u: f32, v: f32, color: PackedColor) -> DebugFontVertex {
        DebugFontVertex {
            x: x,
            y: y,
            color: color,
            u: u,
            v: v,
        }
    }
}

pub struct DebugColorVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
}

impl DebugColorVertex {
    pub fn new(x: f32, y: f32, color: PackedColor) -> DebugColorVertex {
        DebugColorVertex {
            x: x,
            y: y,
            color: color,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum RenderTargetMode {
    None,
    SimpleRenderTarget,
    LayerRenderTarget(i32),      // Number of texture layers
}

pub enum TextureUpdateOp {
    Create(u32, u32, ImageFormat, TextureFilter, RenderTargetMode, Option<Arc<Vec<u8>>>),
    Update(u32, u32, u32, u32, Arc<Vec<u8>>, Option<u32>),
    Grow(u32, u32, ImageFormat, TextureFilter, RenderTargetMode),
}

pub struct TextureUpdate {
    pub id: CacheTextureId,
    pub op: TextureUpdateOp,
}

pub struct TextureUpdateList {
    pub updates: Vec<TextureUpdate>,
}

impl TextureUpdateList {
    pub fn new() -> TextureUpdateList {
        TextureUpdateList {
            updates: Vec::new(),
        }
    }

    #[inline]
    pub fn push(&mut self, update: TextureUpdate) {
        self.updates.push(update);
    }
}

/// Mostly wraps a tiling::Frame, adding a bit of extra information.
pub struct RendererFrame {
    /// The last rendered epoch for each pipeline present in the frame.
    /// This information is used to know if a certain transformation on the layout has
    /// been rendered, which is necessary for reftests.
    pub pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
    /// The layers that are currently affected by the over-scrolling animation.
    pub layers_bouncing_back: HashSet<ScrollLayerId, BuildHasherDefault<FnvHasher>>,

    pub frame: Option<tiling::Frame>,
}

impl RendererFrame {
    pub fn new(pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
               layers_bouncing_back: HashSet<ScrollLayerId, BuildHasherDefault<FnvHasher>>,
               frame: Option<tiling::Frame>)
               -> RendererFrame {
        RendererFrame {
            pipeline_epoch_map: pipeline_epoch_map,
            layers_bouncing_back: layers_bouncing_back,
            frame: frame,
        }
    }
}

pub enum ResultMsg {
    UpdateTextureCache(TextureUpdateList),
    RefreshShader(PathBuf),
    NewFrame(RendererFrame, BackendProfileCounters),
}

#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AxisDirection {
    Horizontal,
    Vertical,
}

#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
pub struct StackingContextIndex(pub usize);

#[derive(Clone, Copy, Debug)]
pub struct RectUv<T, U = UnknownUnit> {
    pub top_left: TypedPoint2D<T, U>,
    pub top_right: TypedPoint2D<T, U>,
    pub bottom_left: TypedPoint2D<T, U>,
    pub bottom_right: TypedPoint2D<T, U>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum LowLevelFilterOp {
    Blur(Au, AxisDirection),
    Brightness(Au),
    Contrast(Au),
    Grayscale(Au),
    /// Fixed-point in `ANGLE_FLOAT_TO_FIXED` units.
    HueRotate(i32),
    Invert(Au),
    Opacity(Au),
    Saturate(Au),
    Sepia(Au),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum CompositionOp {
    MixBlend(MixBlendMode),
    Filter(LowLevelFilterOp),
}<commit_msg>Auto merge of #664 - glennw:fix-debug-profiler, r=larsbergstrom<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/. */

use app_units::Au;
use device::TextureFilter;
use euclid::{TypedPoint2D, UnknownUnit};
use fnv::FnvHasher;
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits};
use profiler::BackendProfileCounters;
use std::collections::{HashMap, HashSet};
use std::f32;
use std::hash::BuildHasherDefault;
use std::{i32, usize};
use std::path::PathBuf;
use std::sync::Arc;
use tiling;
use webrender_traits::{Epoch, ColorF, PipelineId, DeviceIntSize};
use webrender_traits::{ImageFormat, MixBlendMode, NativeFontHandle};
use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand};

// An ID for a texture that is owned by the
// texture cache module. This can include atlases
// or standalone textures allocated via the
// texture cache (e.g. if an image is too large
// to be added to an atlas). The texture cache
// manages the allocation and freeing of these
// IDs, and the rendering thread maintains a
// map from cache texture ID to native texture.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct CacheTextureId(pub usize);

// Represents the source for a texture.
// These are passed from throughout the
// pipeline until they reach the rendering
// thread, where they are resolved to a
// native texture ID.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum SourceTexture {
    Invalid,
    TextureCache(CacheTextureId),
    WebGL(u32),                         // Is actually a gl::GLuint
    External(ExternalImageId),
}

pub enum GLContextHandleWrapper {
    Native(NativeGLContextHandle),
    OSMesa(OSMesaContextHandle),
}

impl GLContextHandleWrapper {
    pub fn current_native_handle() -> Option<GLContextHandleWrapper> {
        NativeGLContext::current_handle().map(GLContextHandleWrapper::Native)
    }

    pub fn current_osmesa_handle() -> Option<GLContextHandleWrapper> {
        OSMesaContext::current_handle().map(GLContextHandleWrapper::OSMesa)
    }

    pub fn new_context(&self,
                       size: DeviceIntSize,
                       attributes: GLContextAttributes,
                       dispatcher: Option<Box<GLContextDispatcher>>) -> Result<GLContextWrapper, &'static str> {
        match *self {
            GLContextHandleWrapper::Native(ref handle) => {
                let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size.to_untyped(),
                                                                                attributes,
                                                                                ColorAttachmentType::Texture,
                                                                                Some(handle),
                                                                                dispatcher);
                ctx.map(GLContextWrapper::Native)
            }
            GLContextHandleWrapper::OSMesa(ref handle) => {
                let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
                                                                                attributes,
                                                                                ColorAttachmentType::Texture,
                                                                                Some(handle),
                                                                                dispatcher);
                ctx.map(GLContextWrapper::OSMesa)
            }
        }
    }
}

pub enum GLContextWrapper {
    Native(GLContext<NativeGLContext>),
    OSMesa(GLContext<OSMesaContext>),
}

impl GLContextWrapper {
    pub fn make_current(&self) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                ctx.make_current().unwrap();
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                ctx.make_current().unwrap();
            }
        }
    }

    pub fn unbind(&self) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                ctx.unbind().unwrap();
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                ctx.unbind().unwrap();
            }
        }
    }

    pub fn apply_command(&self, cmd: WebGLCommand) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                cmd.apply(ctx);
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                cmd.apply(ctx);
            }
        }
    }

    pub fn get_info(&self) -> (DeviceIntSize, u32, GLLimits) {
        match *self {
            GLContextWrapper::Native(ref ctx) => {
                let (real_size, texture_id) = {
                    let draw_buffer = ctx.borrow_draw_buffer().unwrap();
                    (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap())
                };

                let limits = ctx.borrow_limits().clone();

                (DeviceIntSize::from_untyped(&real_size), texture_id, limits)
            }
            GLContextWrapper::OSMesa(ref ctx) => {
                let (real_size, texture_id) = {
                    let draw_buffer = ctx.borrow_draw_buffer().unwrap();
                    (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap())
                };

                let limits = ctx.borrow_limits().clone();

                (DeviceIntSize::from_untyped(&real_size), texture_id, limits)
            }
        }
    }

    pub fn resize(&mut self, size: &DeviceIntSize) -> Result<(), &'static str> {
        match *self {
            GLContextWrapper::Native(ref mut ctx) => {
                ctx.resize(size.to_untyped())
            }
            GLContextWrapper::OSMesa(ref mut ctx) => {
                ctx.resize(size.to_untyped())
            }
        }
    }
}

const COLOR_FLOAT_TO_FIXED: f32 = 255.0;
pub const ANGLE_FLOAT_TO_FIXED: f32 = 65535.0;

pub const ORTHO_NEAR_PLANE: f32 = -1000000.0;
pub const ORTHO_FAR_PLANE: f32 = 1000000.0;

#[derive(Clone)]
pub enum FontTemplate {
    Raw(Arc<Vec<u8>>),
    Native(NativeFontHandle),
}

#[derive(Debug, PartialEq, Eq)]
pub enum TextureSampler {
    Color0,
    Color1,
    Color2,
    Mask,
    Cache,
    Data16,
    Data32,
    Data64,
    Data128,
    Layers,
    RenderTasks,
    Geometry,
    ResourceRects,
}

impl TextureSampler {
    pub fn color(n: usize) -> TextureSampler {
        match n {
            0 => TextureSampler::Color0,
            1 => TextureSampler::Color1,
            2 => TextureSampler::Color2,
            _ => {
                panic!("There are only 3 color samplers.");
            }
        }
    }
}

/// Optional textures that can be used as a source in the shaders.
/// Textures that are not used by the batch are equal to TextureId::invalid().
#[derive(Copy, Clone, Debug)]
pub struct BatchTextures {
    pub colors: [SourceTexture; 3],
}

impl BatchTextures {
    pub fn no_texture() -> Self {
        BatchTextures {
            colors: [SourceTexture::Invalid; 3],
        }
    }
}

// In some places we need to temporarily bind a texture to any slot.
pub const DEFAULT_TEXTURE: TextureSampler = TextureSampler::Color0;

#[derive(Clone, Copy, Debug)]
pub enum VertexAttribute {
    // vertex-frequency basic attributes
    Position,
    Color,
    ColorTexCoord,
    // instance-frequency primitive attributes
    GlobalPrimId,
    PrimitiveAddress,
    TaskIndex,
    ClipTaskIndex,
    LayerIndex,
    ElementIndex,
    UserData,
}

#[derive(Clone, Copy, Debug)]
pub enum ClearAttribute {
    // vertex frequency
    Position,
    // instance frequency
    Rectangle,
}

#[derive(Clone, Copy, Debug)]
pub enum BlurAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    SourceTaskIndex,
    Direction,
}

#[derive(Clone, Copy, Debug)]
pub enum ClipAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    LayerIndex,
    DataIndex,
    BaseTaskIndex,
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedColor {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl PackedColor {
    pub fn from_color(color: &ColorF) -> PackedColor {
        PackedColor {
            r: (0.5 + color.r * COLOR_FLOAT_TO_FIXED).floor() as u8,
            g: (0.5 + color.g * COLOR_FLOAT_TO_FIXED).floor() as u8,
            b: (0.5 + color.b * COLOR_FLOAT_TO_FIXED).floor() as u8,
            a: (0.5 + color.a * COLOR_FLOAT_TO_FIXED).floor() as u8,
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedVertex {
    pub pos: [f32; 2],
}

#[derive(Debug)]
#[repr(C)]
pub struct DebugFontVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
    pub u: f32,
    pub v: f32,
}

impl DebugFontVertex {
    pub fn new(x: f32, y: f32, u: f32, v: f32, color: PackedColor) -> DebugFontVertex {
        DebugFontVertex {
            x: x,
            y: y,
            color: color,
            u: u,
            v: v,
        }
    }
}

#[repr(C)]
pub struct DebugColorVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
}

impl DebugColorVertex {
    pub fn new(x: f32, y: f32, color: PackedColor) -> DebugColorVertex {
        DebugColorVertex {
            x: x,
            y: y,
            color: color,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum RenderTargetMode {
    None,
    SimpleRenderTarget,
    LayerRenderTarget(i32),      // Number of texture layers
}

pub enum TextureUpdateOp {
    Create(u32, u32, ImageFormat, TextureFilter, RenderTargetMode, Option<Arc<Vec<u8>>>),
    Update(u32, u32, u32, u32, Arc<Vec<u8>>, Option<u32>),
    Grow(u32, u32, ImageFormat, TextureFilter, RenderTargetMode),
}

pub struct TextureUpdate {
    pub id: CacheTextureId,
    pub op: TextureUpdateOp,
}

pub struct TextureUpdateList {
    pub updates: Vec<TextureUpdate>,
}

impl TextureUpdateList {
    pub fn new() -> TextureUpdateList {
        TextureUpdateList {
            updates: Vec::new(),
        }
    }

    #[inline]
    pub fn push(&mut self, update: TextureUpdate) {
        self.updates.push(update);
    }
}

/// Mostly wraps a tiling::Frame, adding a bit of extra information.
pub struct RendererFrame {
    /// The last rendered epoch for each pipeline present in the frame.
    /// This information is used to know if a certain transformation on the layout has
    /// been rendered, which is necessary for reftests.
    pub pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
    /// The layers that are currently affected by the over-scrolling animation.
    pub layers_bouncing_back: HashSet<ScrollLayerId, BuildHasherDefault<FnvHasher>>,

    pub frame: Option<tiling::Frame>,
}

impl RendererFrame {
    pub fn new(pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
               layers_bouncing_back: HashSet<ScrollLayerId, BuildHasherDefault<FnvHasher>>,
               frame: Option<tiling::Frame>)
               -> RendererFrame {
        RendererFrame {
            pipeline_epoch_map: pipeline_epoch_map,
            layers_bouncing_back: layers_bouncing_back,
            frame: frame,
        }
    }
}

pub enum ResultMsg {
    UpdateTextureCache(TextureUpdateList),
    RefreshShader(PathBuf),
    NewFrame(RendererFrame, BackendProfileCounters),
}

#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AxisDirection {
    Horizontal,
    Vertical,
}

#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
pub struct StackingContextIndex(pub usize);

#[derive(Clone, Copy, Debug)]
pub struct RectUv<T, U = UnknownUnit> {
    pub top_left: TypedPoint2D<T, U>,
    pub top_right: TypedPoint2D<T, U>,
    pub bottom_left: TypedPoint2D<T, U>,
    pub bottom_right: TypedPoint2D<T, U>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum LowLevelFilterOp {
    Blur(Au, AxisDirection),
    Brightness(Au),
    Contrast(Au),
    Grayscale(Au),
    /// Fixed-point in `ANGLE_FLOAT_TO_FIXED` units.
    HueRotate(i32),
    Invert(Au),
    Opacity(Au),
    Saturate(Au),
    Sepia(Au),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum CompositionOp {
    MixBlend(MixBlendMode),
    Filter(LowLevelFilterOp),
}<|endoftext|>


<commit_before>// Copyright (c) 2014 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]

extern crate libc;

pub const AF_LINK: libc::c_int = 18;

const IF_NAMESIZE: uint = 16;
const IFNAMSIZ: uint = IF_NAMESIZE;
const IOC_IN: libc::c_ulong = 0x80000000;
const IOC_OUT: libc::c_ulong = 0x40000000;
const IOC_INOUT: libc::c_ulong = IOC_IN | IOC_OUT;
const IOCPARM_SHIFT: libc::c_ulong = 13;
const IOCPARM_MASK: libc::c_ulong = (1 << (IOCPARM_SHIFT as uint)) - 1;

const SIZEOF_IFREQ: libc::c_ulong = 32;
const SIZEOF_C_UINT: libc::c_ulong = 4;
#[cfg(target_os = "freebsd")]
const SIZEOF_C_LONG: libc::c_int = 8;

pub const BIOCSETIF: libc::c_ulong = IOC_IN |
                                      ((SIZEOF_IFREQ & IOCPARM_MASK) << 16u) |
                                      ('B' as libc::c_ulong << 8u) |
                                      108;
pub const BIOCIMMEDIATE: libc::c_ulong = IOC_IN |
                                          ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                          ('B' as libc::c_ulong << 8) |
                                          112;
pub const BIOCGBLEN: libc::c_ulong = IOC_OUT |
                                      ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                      ('B' as libc::c_ulong << 8) |
                                      102;
pub const BIOCGDLT: libc::c_ulong = IOC_OUT |
                                      ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                      ('B' as libc::c_ulong << 8) |
                                      106;

pub const BIOCSBLEN: libc::c_ulong = IOC_INOUT |
                                      ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                      ('B' as libc::c_ulong << 8) |
                                      102;
pub const BIOCSHDRCMPLT: libc::c_ulong = IOC_IN |
                                          ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                          ('B' as libc::c_ulong << 8) |
                                          117;

#[cfg(target_os = "freebsd")]
pub const BIOCFEEDBACK: libc::c_ulong = IOC_IN |
                                          ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                          ('B' as libc::c_ulong << 8) |
                                          124;
// NOTE Could use BIOCSSEESENT on OS X, though set to 1 by default anyway

pub const DLT_NULL: libc::c_uint = 0;

#[cfg(target_os = "freebsd")]
const BPF_ALIGNMENT: libc::c_int = SIZEOF_C_LONG;
#[cfg(target_os = "macos")]
#[cfg(windows)]
const BPF_ALIGNMENT: libc::c_int = 4;

pub fn BPF_WORDALIGN<T : Int + ToPrimitive + FromPrimitive>(x: T) -> T {
    use std::num::{from_i32};
    let bpf_alignment: T = from_i32(BPF_ALIGNMENT).unwrap();
    let one: T = from_i32(1).unwrap();

    (x + (bpf_alignment - one)) & !(bpf_alignment - one)
}

// See /usr/include/net/if.h
pub struct ifreq {
    pub ifr_name: [libc::c_char, ..IFNAMSIZ],
    pub ifru_addr: libc::sockaddr, // NOTE Should be a union
}

// See /usr/include/net/if_dl.h
#[cfg(target_os = "freebsd")]
pub struct sockaddr_dl {
    pub sdl_len: libc::c_uchar,
    pub sdl_family: libc::c_uchar,
    pub sdl_index: libc::c_ushort,
    pub sdl_type: libc::c_uchar,
    pub sdl_nlen: libc::c_uchar,
    pub sdl_alen: libc::c_uchar,
    pub sdl_slen: libc::c_uchar,
    pub sdl_data: [libc::c_char, ..46],
}

#[cfg(target_os = "macos")]
pub struct sockaddr_dl {
    pub sdl_len: libc::c_uchar,
    pub sdl_family: libc::c_uchar,
    pub sdl_index: libc::c_ushort,
    pub sdl_type: libc::c_uchar,
    pub sdl_nlen: libc::c_uchar,
    pub sdl_alen: libc::c_uchar,
    pub sdl_slen: libc::c_uchar,
    pub sdl_data: [libc::c_char, ..12],
    pub sdl_rcf: libc::c_ushort,
    pub sdl_route: [libc::c_ushort, ..16],
}

// See man 4 bpf or /usr/include/net/bpf.h [windows: or Common/Packet32.h]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "macos", target_word_size = "32")]
#[cfg(windows)]
pub struct bpf_hdr {
    pub bh_tstamp: libc::timeval,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

pub struct timeval32 {
    pub tv_sec: i32,
    pub tv_usec: i32,
}

#[cfg(target_os = "macos", target_word_size = "64")]
pub struct bpf_hdr {
    pub bh_tstamp: timeval32,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

#[cfg(not(windows))]
extern {
    pub fn ioctl(d: libc::c_int, request: libc::c_ulong, ...) -> libc::c_int;
}

<commit_msg>Fix compiler errors for cfg attributes with latest nightly rustc.<commit_after>// Copyright (c) 2014 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]

extern crate libc;

pub const AF_LINK: libc::c_int = 18;

const IF_NAMESIZE: uint = 16;
const IFNAMSIZ: uint = IF_NAMESIZE;
const IOC_IN: libc::c_ulong = 0x80000000;
const IOC_OUT: libc::c_ulong = 0x40000000;
const IOC_INOUT: libc::c_ulong = IOC_IN | IOC_OUT;
const IOCPARM_SHIFT: libc::c_ulong = 13;
const IOCPARM_MASK: libc::c_ulong = (1 << (IOCPARM_SHIFT as uint)) - 1;

const SIZEOF_IFREQ: libc::c_ulong = 32;
const SIZEOF_C_UINT: libc::c_ulong = 4;
#[cfg(target_os = "freebsd")]
const SIZEOF_C_LONG: libc::c_int = 8;

pub const BIOCSETIF: libc::c_ulong = IOC_IN |
                                      ((SIZEOF_IFREQ & IOCPARM_MASK) << 16u) |
                                      ('B' as libc::c_ulong << 8u) |
                                      108;
pub const BIOCIMMEDIATE: libc::c_ulong = IOC_IN |
                                          ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                          ('B' as libc::c_ulong << 8) |
                                          112;
pub const BIOCGBLEN: libc::c_ulong = IOC_OUT |
                                      ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                      ('B' as libc::c_ulong << 8) |
                                      102;
pub const BIOCGDLT: libc::c_ulong = IOC_OUT |
                                      ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                      ('B' as libc::c_ulong << 8) |
                                      106;

pub const BIOCSBLEN: libc::c_ulong = IOC_INOUT |
                                      ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                      ('B' as libc::c_ulong << 8) |
                                      102;
pub const BIOCSHDRCMPLT: libc::c_ulong = IOC_IN |
                                          ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                          ('B' as libc::c_ulong << 8) |
                                          117;

#[cfg(target_os = "freebsd")]
pub const BIOCFEEDBACK: libc::c_ulong = IOC_IN |
                                          ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) |
                                          ('B' as libc::c_ulong << 8) |
                                          124;
// NOTE Could use BIOCSSEESENT on OS X, though set to 1 by default anyway

pub const DLT_NULL: libc::c_uint = 0;

#[cfg(target_os = "freebsd")]
const BPF_ALIGNMENT: libc::c_int = SIZEOF_C_LONG;
#[cfg(any(target_os = "macos", windows))]
const BPF_ALIGNMENT: libc::c_int = 4;

pub fn BPF_WORDALIGN<T : Int + ToPrimitive + FromPrimitive>(x: T) -> T {
    use std::num::{from_i32};
    let bpf_alignment: T = from_i32(BPF_ALIGNMENT).unwrap();
    let one: T = from_i32(1).unwrap();

    (x + (bpf_alignment - one)) & !(bpf_alignment - one)
}

// See /usr/include/net/if.h
pub struct ifreq {
    pub ifr_name: [libc::c_char, ..IFNAMSIZ],
    pub ifru_addr: libc::sockaddr, // NOTE Should be a union
}

// See /usr/include/net/if_dl.h
#[cfg(target_os = "freebsd")]
pub struct sockaddr_dl {
    pub sdl_len: libc::c_uchar,
    pub sdl_family: libc::c_uchar,
    pub sdl_index: libc::c_ushort,
    pub sdl_type: libc::c_uchar,
    pub sdl_nlen: libc::c_uchar,
    pub sdl_alen: libc::c_uchar,
    pub sdl_slen: libc::c_uchar,
    pub sdl_data: [libc::c_char, ..46],
}

#[cfg(target_os = "macos")]
pub struct sockaddr_dl {
    pub sdl_len: libc::c_uchar,
    pub sdl_family: libc::c_uchar,
    pub sdl_index: libc::c_ushort,
    pub sdl_type: libc::c_uchar,
    pub sdl_nlen: libc::c_uchar,
    pub sdl_alen: libc::c_uchar,
    pub sdl_slen: libc::c_uchar,
    pub sdl_data: [libc::c_char, ..12],
    pub sdl_rcf: libc::c_ushort,
    pub sdl_route: [libc::c_ushort, ..16],
}

// See man 4 bpf or /usr/include/net/bpf.h [windows: or Common/Packet32.h]
#[cfg(any(target_os = "freebsd", all(target_os = "macos", target_word_size = "32"), windows))]
pub struct bpf_hdr {
    pub bh_tstamp: libc::timeval,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

pub struct timeval32 {
    pub tv_sec: i32,
    pub tv_usec: i32,
}

#[cfg(all(target_os = "macos", target_word_size = "64"))]
pub struct bpf_hdr {
    pub bh_tstamp: timeval32,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

#[cfg(not(windows))]
extern {
    pub fn ioctl(d: libc::c_int, request: libc::c_ulong, ...) -> libc::c_int;
}

<|endoftext|>


<commit_before>use notty_encoding::cmds::{SetBufferMode, SetEchoMode};

use command::prelude::*;
<commit_msg>Remove echo command module.<commit_after><|endoftext|>


<commit_before>extern crate tempdir;

use std::io::prelude::*;
use std::fs::File;
use std::process::Command;
use std::env;

use tempdir::TempDir;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

fn cargo_sysroot() -> Command {
    let mut me = t!(env::current_exe());
    me.pop();
    me.push("cargo-sysroot");
    let mut cmd = Command::new(me);
    cmd.arg("sysroot");
    return cmd
}

#[test]
fn supported_triple() {
    let triple = "arm-unknown-linux-gnueabihf";
    let td = t!(TempDir::new("cargo-sysroot"));

    run(cargo_sysroot().arg("--target")
                       .arg(triple)
                       .arg(td.path())
                       .arg("--verbose"));

    assert!(td.path().join(format!("debug/lib/rustlib/{}/lib/libcore.rlib", triple))
                     .is_file());

    run(cargo_sysroot().arg("--target")
                       .arg(triple)
                       .arg(td.path())
                       .arg("--verbose")
                       .arg("--release"));

    assert!(td.path().join(format!("debug/lib/rustlib/{}/lib/libcore.rlib", triple))
                     .is_file());
    assert!(td.path().join(format!("release/lib/rustlib/{}/lib/libcore.rlib", triple))
                     .is_file());
}

#[test]
fn custom_target() {
    let spec = r#"
        {
          "arch": "arm",
          "llvm-target": "thumbv7m-none-eabi",
          "os": "none",
          "target-endian": "little",
          "target-pointer-width": "32",
          "archive-format": "gnu"
        }
    "#;
    let td = t!(TempDir::new("cargo-sysroot"));
    t!(t!(File::create(td.path().join("custom.json"))).write_all(spec.as_bytes()));

    // test --target triple
    run(cargo_sysroot().arg("--target=custom")
                       .arg(td.path().join("target"))
                       .arg("--verbose")
                       .current_dir(td.path()));

    assert!(td.path().join("target/debug/lib/rustlib/custom/lib/libcore.rlib")
                     .is_file());

    // test /path/to/target.json
    run(cargo_sysroot().arg("--target")
                       .arg(td.path().join("custom.json"))
                       .arg(td.path().join("other"))
                       .arg("--verbose"));

    assert!(td.path().join("other/debug/lib/rustlib/custom/lib/libcore.rlib")
                     .is_file());

    // make sure the original spec is there but the copied version is gone
    assert!(td.path().join("custom.json").is_file());
    assert!(!td.path().join("other/src/libcore/custom.json").is_file());
}

fn run(cmd: &mut Command) {
    println!("running: {:?}", cmd);
    let output = t!(cmd.output());
    if !output.status.success() {
        println!("--- stdout:\n{}", String::from_utf8_lossy(&output.stdout));
        println!("--- stderr:\n{}", String::from_utf8_lossy(&output.stderr));
        panic!("expected success, got: {}", output.status);
    }
}
<commit_msg>fix tests<commit_after>extern crate tempdir;

use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
use std::{env, fs};

use tempdir::TempDir;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

fn cargo_sysroot() -> Command {
    let mut me = t!(env::current_exe());
    me.pop();
    me.push("cargo-sysroot");
    let mut cmd = Command::new(me);
    cmd.arg("sysroot");
    return cmd
}

fn exists_rlib(krate: &str, profile: &str, target: &str, sysroot: &Path) -> bool {
    for entry in t!(fs::read_dir(sysroot.join(format!("{}/lib/rustlib/{}/lib", profile, target)))) {
        let path = t!(entry).path();
        let filename = path.file_stem().unwrap().to_str().unwrap();
        let extension = path.extension().unwrap().to_str().unwrap();

        if filename.starts_with(&format!("lib{}", krate)) && extension == "rlib" && path.is_file() {
            return true;
        }
    }

    false
}

#[test]
fn supported_triple() {
    let triple = "arm-unknown-linux-gnueabihf";
    let td = t!(TempDir::new("cargo-sysroot"));

    run(cargo_sysroot().arg("--target")
                       .arg(triple)
                       .arg(td.path())
                       .arg("--verbose"));

    assert!(exists_rlib("core", "debug", triple, td.path()));

    run(cargo_sysroot().arg("--target")
                       .arg(triple)
                       .arg(td.path())
                       .arg("--verbose")
                       .arg("--release"));

    assert!(exists_rlib("core", "debug", triple, td.path()));
    assert!(exists_rlib("core", "release", triple, td.path()));
}

#[test]
fn custom_target() {
    let spec = r#"
        {
          "arch": "arm",
          "llvm-target": "thumbv7m-none-eabi",
          "os": "none",
          "target-endian": "little",
          "target-pointer-width": "32",
          "archive-format": "gnu"
        }
    "#;
    let td = t!(TempDir::new("cargo-sysroot"));
    t!(t!(File::create(td.path().join("custom.json"))).write_all(spec.as_bytes()));

    // test --target triple
    run(cargo_sysroot().arg("--target=custom")
                       .arg(td.path().join("target"))
                       .arg("--verbose")
                       .current_dir(td.path()));

    assert!(exists_rlib("core", "debug", "custom", &td.path().join("target")));

    // test /path/to/target.json
    run(cargo_sysroot().arg("--target")
                       .arg(td.path().join("custom.json"))
                       .arg(td.path().join("other"))
                       .arg("--verbose"));

    assert!(exists_rlib("core", "debug", "custom", &td.path().join("other")));

    // make sure the original spec is there but the copied version is gone
    assert!(td.path().join("custom.json").is_file());
    assert!(!td.path().join("other/src/libcore/custom.json").is_file());
}

fn run(cmd: &mut Command) {
    println!("running: {:?}", cmd);
    let output = t!(cmd.output());
    if !output.status.success() {
        println!("--- stdout:\n{}", String::from_utf8_lossy(&output.stdout));
        println!("--- stderr:\n{}", String::from_utf8_lossy(&output.stderr));
        panic!("expected success, got: {}", output.status);
    }
}
<|endoftext|>


<commit_before>// Binary Indexed Tree (BIT) is an array structure
// implemented as a tree that looks like:
//
//      [                       8                     ] _ ..
//      [          4          ] _______________________ [ ..
//      [    2    ] ___________ [    6    ] ___________ [ ..
//      [ 1 ] _____ [ 3 ] _____ [ 5 ] _____ [ 7 ] _____ [ ..
//                                                        ..
//      < 0 > < 1 > < 2 > < 3 > < 4 > < 5 > < 6 > < 7 > < ..
//
// where each ``[ i ]`` is i-th node
// and each ``< i >`` is i-th element of the structure.

// Invariant: each node holds the sum of values of elements that covers. e.g.
//      [1] = <0>,
//      [6] = <4> + <5>,
//      [2^N] = <0> + .. + <2^N - 1>.

// Technique: for i (> 1), node [i]'s parent is [i + (i & -i)].

// 1-indexed. [0] is unused.
type BIT = Vec<i64>;

pub fn bit_new(len: usize) -> BIT {
    vec![0; len + 1]
}

pub fn bit_len(bit: &BIT) -> usize {
    bit.len() - 1
}

/// Increments an element.
pub fn bit_add(bit: &mut BIT, index: usize, value: i64) {
    let mut j = index + 1;
    while j < bit_len(bit) {
        bit[j] += value;
        j += rightmost_bit(j);
    }
}

/// Gets sum of items in range 0..right.
pub fn bit_acc(bit: &BIT, right: usize) -> i64 {
    let mut acc = 0;
    let mut j = right;
    while 0 < j && j < bit_len(bit) {
        acc += bit[j];
        j -= rightmost_bit(j);
    }
    acc
}

/// Gets sum of items in range left..right.
pub fn bit_sum(bit: &BIT, left: usize, right: usize) -> i64 {
    let mut acc = bit_acc(bit, right);
    acc -= bit_acc(bit, left);
    acc
}

fn rightmost_bit(n: usize) -> usize {
    let s = n as isize;
    (s & -s) as usize
}

#[cfg(test)]
#[allow(unused_imports)]
mod tests {
    use super::*;

    #[test]
    fn test() {
        let mut bit = bit_new(6);
        for (i, &x) in [3, 1, 4, 1, 5, 9].into_iter().enumerate() {
            bit_add(&mut bit, i, x);
        }

        assert_eq!(1 + 4 + 1, bit_sum(&bit, 1, 4));
    }
}
<commit_msg>Fix binary_indexed_tree<commit_after>// Binary Indexed Tree (BIT) is an array structure
// implemented as a tree that looks like:
//
//      [                       8                     ] _ ..
//      [          4          ] _______________________ [ ..
//      [    2    ] ___________ [    6    ] ___________ [ ..
//      [ 1 ] _____ [ 3 ] _____ [ 5 ] _____ [ 7 ] _____ [ ..
//                                                        ..
//      < 0 > < 1 > < 2 > < 3 > < 4 > < 5 > < 6 > < 7 > < ..
//
// where each ``[ i ]`` is i-th node
// and each ``< i >`` is i-th element of the structure.

// Invariant: each node holds the sum of values of elements that covers. e.g.
//      [1] = <0>,
//      [6] = <4> + <5>,
//      [2^N] = <0> + .. + <2^N - 1>.

// Technique: for i (> 1), node [i]'s parent is [i + (i & -i)].

use std::cmp::min;

// 1-indexed. [0] is unused.
type BIT = Vec<i64>;

pub fn bit_new(len: usize) -> BIT {
    vec![0; len + 1]
}

pub fn bit_len(bit: &BIT) -> usize {
    bit.len() - 1
}

/// Increments an element.
pub fn bit_add(bit: &mut BIT, index: usize, value: i64) {
    let mut j = index + 1;
    while j <= bit_len(bit) {
        bit[j] += value;
        j += rightmost_bit(j);
    }
}

/// Gets sum of items in range 0..right.
pub fn bit_acc(bit: &BIT, right: usize) -> i64 {
    let mut acc = 0;
    let mut j = min(right, bit_len(bit));
    while j > 0 {
        acc += bit[j];
        j -= rightmost_bit(j);
    }
    acc
}

/// Gets sum of items in range left..right.
pub fn bit_sum(bit: &BIT, left: usize, right: usize) -> i64 {
    bit_acc(bit, right) - bit_acc(bit, min(left, right))
}

fn rightmost_bit(n: usize) -> usize {
    let s = n as isize;
    (s & -s) as usize
}

#[cfg(test)]
#[allow(unused_imports)]
mod tests {
    use super::*;
    use std::cmp::min;

    #[test]
    fn test() {
        let a = vec![3, 1, 4, 1, 5, 9];
        let n = a.len();

        let mut bit = bit_new(n);
        for (i, &x) in a.iter().enumerate() {
            bit_add(&mut bit, i, x);
        }

        assert_eq!(3 + 1 + 4, bit_acc(&bit, 3));
        assert_eq!(3 + 1 + 4 + 1 + 5 + 9, bit_acc(&bit, 6));

        assert_eq!(1 + 4 + 1, bit_sum(&bit, 1, 4));

        for l in 0..n {
            for r in 0..n {
                let actual = a[min(l, r)..r].iter().sum::<i64>();
                let expected = bit_sum(&bit, l, r);
                assert_eq!(actual, expected, "l={} r={}", l, r);
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate ruyi;

use std::time::{Instant, Duration};
use futures::Future;

use ruyi::reactor;

#[test]
#[ignore]
fn sleep() {
    const TIMEOUT: u64 = 10;
    let start = Instant::now();
    let sleep = reactor::sleep(Duration::from_secs(TIMEOUT)).then(|_| {
        let elapsed = Instant::now() - start;
        if elapsed.as_secs() < TIMEOUT - 1 {
            Err(format!("Expect elapsed({:?}) >= {}s", elapsed, TIMEOUT - 1))
        } else if elapsed.as_secs() > TIMEOUT + 1 {
            Err(format!("Expect elapsed({:?}) <= {}s", elapsed, TIMEOUT + 1))
        } else {
            Ok(())
        }
    });
    reactor::run(sleep).unwrap();
}
<commit_msg>Add test for BinaryHeap based timer<commit_after>extern crate futures;
extern crate ruyi;

use std::time::{Instant, Duration};
use futures::Future;

use ruyi::reactor::{self, Timer};

fn into_millis(dur: Duration) -> u64 {
    const NANOS_PER_MILLI: u32 = 1_000_000;
    const MILLIS_PER_SEC: u64 = 1_000;

    let millis = (dur.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
    dur.as_secs()
        .wrapping_mul(MILLIS_PER_SEC)
        .wrapping_add(millis as u64)
}

#[test]
#[ignore]
fn sleep() {
    const TIMEOUT: u64 = 10;
    let start = Instant::now();
    let sleep = reactor::sleep(TIMEOUT).then(|e| {
        assert_eq!(e.is_ok(), true);
        let elapsed = Instant::now() - start;
        if elapsed.as_secs() < TIMEOUT - 1 {
            Err(format!("Expect elapsed({:?}) >= {}s", elapsed, TIMEOUT - 1))
        } else if elapsed.as_secs() > TIMEOUT + 1 {
            Err(format!("Expect elapsed({:?}) <= {}s", elapsed, TIMEOUT + 1))
        } else {
            Ok(())
        }
    });
    reactor::run(sleep).unwrap();
}

#[test]
#[ignore]
fn timer() {
    const TIMEOUT: u64 = 100;
    let start = Instant::now();
    let sleep = Timer::new(Duration::from_millis(TIMEOUT)).then(|res| {
        assert_eq!(res.is_ok(), true);
        let elapsed = Instant::now() - start;
        if into_millis(elapsed) < TIMEOUT - 1 {
            Err(format!("Expect elapsed({:?}) >= {}ms", elapsed, TIMEOUT - 1))
        } else if into_millis(elapsed) > TIMEOUT + 1 {
            Err(format!("Expect elapsed({:?}) <= {}ms", elapsed, TIMEOUT + 1))
        } else {
            Ok(())
        }
    });
    reactor::run(sleep).unwrap();
}
<|endoftext|>


<commit_before>use quote::{Tokens, Ident};
use syn::Visibility;
use structs::Struct;

pub fn derive(input: &Struct) -> Tokens {
    let name = &input.name;
    let visibility = &input.visibility;
    let detail_mod = Ident::from(format!("__detail_iter_{}", name.as_ref().to_lowercase()));
    let vec_name = &input.vec_name();
    let slice_name = &input.slice_name();
    let slice_mut_name = &input.slice_mut_name();
    let ref_name = &input.ref_name();
    let ref_mut_name = &input.ref_mut_name();

    let ref_doc_url = format!("[`{0}`](struct.{0}.html)", ref_name);
    let ref_mut_doc_url = format!("[`{0}`](struct.{0}.html)", ref_mut_name);

    let fields_names = &input.fields.iter()
                                    .map(|field| field.ident.clone().unwrap())
                                    .collect::<Vec<_>>();
    let first_field = &fields_names[0];

    let fields_types = &input.fields.iter()
                                    .map(|field| &field.ty)
                                    .collect::<Vec<_>>();
    let first_field_type = &fields_types[0];

    let mut iter_type = quote!{
        slice::Iter<'a, #first_field_type>
    };
    let mut iter_pat = quote!{
        #first_field
    };
    let mut create_iter = quote!{
        self.#first_field.iter()
    };

    let mut iter_mut_type = quote!{
        slice::IterMut<'a, #first_field_type>
    };
    let mut create_iter_mut = quote!{
        self.#first_field.iter_mut()
    };

    if fields_types.len() > 1 {
        for field in &input.fields[1..] {
            let field_name = &field.ident;
            let field_type = &field.ty;

            iter_pat = quote!{
                (#iter_pat, #field_name)
            };

            iter_type = quote!{
                iter::Zip<#iter_type, slice::Iter<'a, #field_type>>
            };

            create_iter = quote!{
                #create_iter.zip(self.#field_name.iter())
            };

            iter_mut_type = quote!{
                iter::Zip<#iter_mut_type, slice::IterMut<'a, #field_type>>
            };

            create_iter_mut = quote!{
                #create_iter_mut.zip(self.#field_name.iter_mut())
            };
        }
    }

    let mut generated = quote! {
        #[allow(non_snake_case, dead_code)]
        mod #detail_mod {
            use super::*;
            use std::slice;
            #[allow(unused_imports)]
            use std::iter;

            #visibility struct Iter<'a>(pub(super) #iter_type);

            impl<'a> Iterator for Iter<'a> {
                type Item = #ref_name<'a>;
                fn next(&mut self) -> Option<#ref_name<'a>> {
                    self.0.next().and_then(|#iter_pat|
                        Some(#ref_name{
                            #(#fields_names,)*
                        })
                    )
                }
            }

            impl #vec_name {
                /// Get an iterator over the
                #[doc = #ref_doc_url]
                /// in this vector
                #visibility fn iter(&self) -> Iter {
                    Iter(#create_iter)
                }
            }

            impl<'a> #slice_name<'a> {
                /// Get an iterator over the
                #[doc = #ref_doc_url]
                /// in this slice.
                #visibility fn iter(&self) -> Iter {
                    Iter(#create_iter)
                }
            }

            #visibility struct IterMut<'a>(pub(super) #iter_mut_type);

            impl<'a> Iterator for IterMut<'a> {
                type Item = #ref_mut_name<'a>;
                fn next(&mut self) -> Option<#ref_mut_name<'a>> {
                    self.0.next().and_then(|#iter_pat|
                        Some(#ref_mut_name{
                            #(#fields_names,)*
                        })
                    )
                }
            }

            impl #vec_name {
                /// Get a mutable iterator over the
                #[doc = #ref_mut_doc_url]
                /// in this vector
                #visibility fn iter_mut(&mut self) -> IterMut {
                    IterMut(#create_iter_mut)
                }
            }

            impl<'a> #slice_mut_name<'a> {
                /// Get an iterator over the
                #[doc = #ref_doc_url]
                /// in this vector
                #visibility fn iter(&mut self) -> Iter {
                    Iter(#create_iter)
                }

                /// Get a mutable iterator over the
                #[doc = #ref_mut_doc_url]
                /// in this vector
                #visibility fn iter_mut(&mut self) -> IterMut {
                    IterMut(#create_iter_mut)
                }
            }
        }
    };

    if let Visibility::Public = *visibility {
        generated.append(quote!{
            impl<'a> IntoIterator for #slice_name<'a> {
                type Item = #ref_name<'a>;
                type IntoIter = #detail_mod::Iter<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::Iter(#create_iter)
                }
            }

            impl<'a,'b> IntoIterator for &'a #slice_name<'b> {
                type Item = #ref_name<'a>;
                type IntoIter = #detail_mod::Iter<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::Iter(#create_iter)
                }
            }

            impl<'a> IntoIterator for &'a #vec_name {
                type Item = #ref_name<'a>;
                type IntoIter = #detail_mod::Iter<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::Iter(#create_iter)
                }
            }

            impl<'a> IntoIterator for #slice_mut_name<'a> {
                type Item = #ref_mut_name<'a>;
                type IntoIter = #detail_mod::IterMut<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::IterMut(#create_iter_mut)
                }
            }

            impl<'a> IntoIterator for &'a mut #vec_name {
                type Item = #ref_mut_name<'a>;
                type IntoIter = #detail_mod::IterMut<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::IterMut(#create_iter_mut)
                }
            }
        });
    }

    return generated;
}
<commit_msg>Add implementation of DoubleEndedIterator<commit_after>use quote::{Tokens, Ident};
use syn::Visibility;
use structs::Struct;

pub fn derive(input: &Struct) -> Tokens {
    let name = &input.name;
    let visibility = &input.visibility;
    let detail_mod = Ident::from(format!("__detail_iter_{}", name.as_ref().to_lowercase()));
    let vec_name = &input.vec_name();
    let slice_name = &input.slice_name();
    let slice_mut_name = &input.slice_mut_name();
    let ref_name = &input.ref_name();
    let ref_mut_name = &input.ref_mut_name();

    let ref_doc_url = format!("[`{0}`](struct.{0}.html)", ref_name);
    let ref_mut_doc_url = format!("[`{0}`](struct.{0}.html)", ref_mut_name);

    let fields_names = &input.fields.iter()
                                    .map(|field| field.ident.clone().unwrap())
                                    .collect::<Vec<_>>();
    let first_field = &fields_names[0];

    let fields_types = &input.fields.iter()
                                    .map(|field| &field.ty)
                                    .collect::<Vec<_>>();
    let first_field_type = &fields_types[0];

    let mut iter_type = quote!{
        slice::Iter<'a, #first_field_type>
    };
    let mut iter_pat = quote!{
        #first_field
    };
    let mut create_iter = quote!{
        self.#first_field.iter()
    };

    let mut iter_mut_type = quote!{
        slice::IterMut<'a, #first_field_type>
    };
    let mut create_iter_mut = quote!{
        self.#first_field.iter_mut()
    };

    if fields_types.len() > 1 {
        for field in &input.fields[1..] {
            let field_name = &field.ident;
            let field_type = &field.ty;

            iter_pat = quote!{
                (#iter_pat, #field_name)
            };

            iter_type = quote!{
                iter::Zip<#iter_type, slice::Iter<'a, #field_type>>
            };

            create_iter = quote!{
                #create_iter.zip(self.#field_name.iter())
            };

            iter_mut_type = quote!{
                iter::Zip<#iter_mut_type, slice::IterMut<'a, #field_type>>
            };

            create_iter_mut = quote!{
                #create_iter_mut.zip(self.#field_name.iter_mut())
            };
        }
    }

    let mut generated = quote! {
        #[allow(non_snake_case, dead_code)]
        mod #detail_mod {
            use super::*;
            use std::slice;
            #[allow(unused_imports)]
            use std::iter;

            #visibility struct Iter<'a>(pub(super) #iter_type);

            impl<'a> Iterator for Iter<'a> {
                type Item = #ref_name<'a>;
                fn next(&mut self) -> Option<#ref_name<'a>> {
                    self.0.next().and_then(|#iter_pat|
                        Some(#ref_name{
                            #(#fields_names,)*
                        })
                    )
                }
            }

            impl<'a> DoubleEndedIterator for Iter<'a> {
                fn next_back(&mut self) -> Option<#ref_name<'a>> {
                    self.0.next_back().and_then(|#iter_pat|
                        Some(#ref_name{
                            #(#fields_names,)*
                        })
                    )
                }
            }

            impl #vec_name {
                /// Get an iterator over the
                #[doc = #ref_doc_url]
                /// in this vector
                #visibility fn iter(&self) -> Iter {
                    Iter(#create_iter)
                }
            }

            impl<'a> #slice_name<'a> {
                /// Get an iterator over the
                #[doc = #ref_doc_url]
                /// in this slice.
                #visibility fn iter(&self) -> Iter {
                    Iter(#create_iter)
                }
            }

            #visibility struct IterMut<'a>(pub(super) #iter_mut_type);

            impl<'a> Iterator for IterMut<'a> {
                type Item = #ref_mut_name<'a>;
                fn next(&mut self) -> Option<#ref_mut_name<'a>> {
                    self.0.next().and_then(|#iter_pat|
                        Some(#ref_mut_name{
                            #(#fields_names,)*
                        })
                    )
                }
            }

            impl<'a> DoubleEndedIterator for IterMut<'a> {
                fn next_back(&mut self) -> Option<#ref_mut_name<'a>> {
                    self.0.next_back().and_then(|#iter_pat|
                        Some(#ref_mut_name{
                            #(#fields_names,)*
                        })
                    )
                }
            }

            impl #vec_name {
                /// Get a mutable iterator over the
                #[doc = #ref_mut_doc_url]
                /// in this vector
                #visibility fn iter_mut(&mut self) -> IterMut {
                    IterMut(#create_iter_mut)
                }
            }

            impl<'a> #slice_mut_name<'a> {
                /// Get an iterator over the
                #[doc = #ref_doc_url]
                /// in this vector
                #visibility fn iter(&mut self) -> Iter {
                    Iter(#create_iter)
                }

                /// Get a mutable iterator over the
                #[doc = #ref_mut_doc_url]
                /// in this vector
                #visibility fn iter_mut(&mut self) -> IterMut {
                    IterMut(#create_iter_mut)
                }
            }
        }
    };

    if let Visibility::Public = *visibility {
        generated.append(quote!{
            impl<'a> IntoIterator for #slice_name<'a> {
                type Item = #ref_name<'a>;
                type IntoIter = #detail_mod::Iter<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::Iter(#create_iter)
                }
            }

            impl<'a,'b> IntoIterator for &'a #slice_name<'b> {
                type Item = #ref_name<'a>;
                type IntoIter = #detail_mod::Iter<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::Iter(#create_iter)
                }
            }

            impl<'a> IntoIterator for &'a #vec_name {
                type Item = #ref_name<'a>;
                type IntoIter = #detail_mod::Iter<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::Iter(#create_iter)
                }
            }

            impl<'a> IntoIterator for #slice_mut_name<'a> {
                type Item = #ref_mut_name<'a>;
                type IntoIter = #detail_mod::IterMut<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::IterMut(#create_iter_mut)
                }
            }

            impl<'a> IntoIterator for &'a mut #vec_name {
                type Item = #ref_mut_name<'a>;
                type IntoIter = #detail_mod::IterMut<'a>;

                fn into_iter(self) -> Self::IntoIter {
                    #detail_mod::IterMut(#create_iter_mut)
                }
            }
        });
    }

    return generated;
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2016 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

//! Support for sending and receiving data link layer packets

use sockets;
use std::io;
use std::option::Option;
use std::time::Duration;
use util::MacAddr;

use ipnetwork::IpNetwork;

#[cfg(windows)]
#[path = "winpcap.rs"]
mod backend;

#[cfg(windows)]
pub mod winpcap;

#[cfg(all(not(feature = "netmap"),
          target_os = "linux"
          )
      )]
#[path = "linux.rs"]
mod backend;

#[cfg(target_os = "linux")]
pub mod linux;

#[cfg(all(not(feature = "netmap"),
          any(target_os = "freebsd",
              target_os = "macos")
             )
     )]
#[path = "bpf.rs"]
mod backend;

#[cfg(any(target_os = "freebsd", target_os = "macos"))]
pub mod bpf;

#[cfg(feature = "netmap")]
#[path = "netmap.rs"]
mod backend;

#[cfg(feature = "netmap")]
pub mod netmap;

#[cfg(feature = "pcap")]
pub mod pcap;

pub mod dummy;

/// Type alias for an EtherType.
pub type EtherType = u16;

/// Type of data link channel to present (Linux only)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ChannelType {
    /// Send and receive layer 2 packets directly, including headers
    Layer2,
    /// Send and receive "cooked" packets - send and receive network layer packets
    Layer3(EtherType),
}

/// A channel for sending and receiving at the data link layer
///
/// NOTE: It is important to always include a catch-all variant in match statements using this
/// enum, since new variants may be added. For example:
///
/// ```ignore
/// match some_channel {
///     Ethernet(tx, rx) => { /* Handle Ethernet packets */ },
///     _ => panic!("Unhandled channel type")
/// }
/// ```
pub enum Channel {
    /// A datalink channel which sends and receives Ethernet packets
    Ethernet(Box<DataLinkSender>, Box<DataLinkReceiver>),

    /// This variant should never be used
    ///
    /// Including it allows new variants to be added to `Channel` without breaking existing code.
    PleaseIncludeACatchAllVariantWhenMatchingOnThisEnum,
}

/// A generic configuration type, encapsulating all options supported by each backend
///
/// Each option should be treated as a hint - each backend is free to ignore any and all
/// options which don't apply to it.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Config {
    /// The size of buffer to use when writing packets. Defaults to 4096
    pub write_buffer_size: usize,

    /// The size of buffer to use when reading packets. Defaults to 4096
    pub read_buffer_size: usize,

    /// Linux/BPF/Netmap only: The read timeout. Defaults to None.
    pub read_timeout: Option<Duration>,

    /// Linux/BPF/Netmap only: The write timeout. Defaults to None.
    pub write_timeout: Option<Duration>,

    /// Linux only: Specifies whether to read packets at the datalink layer or network layer.
    /// Defaults to Layer2
    pub channel_type: ChannelType,

    /// BPF/OS X only: The number of /dev/bpf* file descriptors to attempt before failing. Defaults
    /// to: 1000
    pub bpf_fd_attempts: usize,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            write_buffer_size: 4096,
            read_buffer_size: 4096,
            channel_type: ChannelType::Layer2,
            bpf_fd_attempts: 1000,
            read_timeout: None,
            write_timeout: None,
        }
    }
}

/// Create a new datalink channel for sending and receiving data
///
/// This allows for sending and receiving packets at the data link layer.
///
/// A list of network interfaces can be retrieved using datalink::interfaces().
///
/// The configuration serves as a hint to the backend - some or all of it may be used or ignored,
/// depending on which backend is used.
///
/// When matching on the returned channel, make sure to include a catch-all so that code doesn't
/// break when new channel types are added.
#[inline]
pub fn channel(network_interface: &NetworkInterface, configuration: Config) -> io::Result<Channel> {
    backend::channel(network_interface, (&configuration).into())
}

/// Trait to enable sending $packet packets
pub trait DataLinkSender: Send {
    /// Create and send a number of packets
    ///
    /// This will call `func` `num_packets` times. The function will be provided with a
    /// mutable packet to manipulate, which will then be sent. This allows packets to be
    /// built in-place, avoiding the copy required for `send`. If there is not sufficient
    /// capacity in the buffer, None will be returned.
    #[inline]
    fn build_and_send(&mut self,
                      num_packets: usize,
                      packet_size: usize,
                      func: &mut FnMut(&mut [u8]))
    -> Option<io::Result<()>>;

    /// Send a packet
    ///
    /// This may require an additional copy compared to `build_and_send`, depending on the
    /// operating system being used. The second parameter is currently ignored, however
    /// `None` should be passed.
    #[inline]
    fn send_to(&mut self,
                packet: &[u8],
                dst: Option<NetworkInterface>)
        -> Option<io::Result<()>>;
}

/// Structure for receiving packets at the data link layer. Should be constructed using
/// datalink_channel().
pub trait DataLinkReceiver: Send {
    /// Returns an iterator over Ethernet frames.
    ///
    /// This will likely be removed once other layer two types are supported.
    #[inline]
    fn iter<'a>(&'a mut self) -> Box<DataLinkChannelIterator + 'a>;
}

/// An iterator over data link layer packets
pub trait DataLinkChannelIterator<'a> {
    /// Get the next Ethernet frame in the channel
    #[inline]
    fn next(&mut self) -> io::Result<&[u8]>;
}

/// Represents a network interface and its associated addresses
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct NetworkInterface {
    /// The name of the interface
    pub name: String,
    /// The interface index (operating system specific)
    pub index: u32,
    /// A MAC address for the interface
    pub mac: Option<MacAddr>,
    /// IP addresses and netmasks for the interface
    pub ips: Vec<IpNetwork>,
    /// Operating system specific flags for the interface
    pub flags: u32,
}

impl NetworkInterface {
    /// Retrieve the MAC address associated with the interface
    pub fn mac_address(&self) -> MacAddr {
        self.mac.unwrap()
    }

    /// Is the interface a loopback interface?
    pub fn is_loopback(&self) -> bool {
        self.flags & (sockets::IFF_LOOPBACK as u32) != 0
    }
}

/// Get a list of available network interfaces for the current machine.
pub fn interfaces() -> Vec<NetworkInterface> {
    backend::interfaces()
}
<commit_msg>Get rid of DataLinkChannelIterator<commit_after>// Copyright (c) 2014-2016 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

//! Support for sending and receiving data link layer packets

use sockets;
use std::io;
use std::option::Option;
use std::time::Duration;
use util::MacAddr;

use ipnetwork::IpNetwork;

#[cfg(windows)]
#[path = "winpcap.rs"]
mod backend;

#[cfg(windows)]
pub mod winpcap;

#[cfg(all(not(feature = "netmap"),
          target_os = "linux"
          )
      )]
#[path = "linux.rs"]
mod backend;

#[cfg(target_os = "linux")]
pub mod linux;

#[cfg(all(not(feature = "netmap"),
          any(target_os = "freebsd",
              target_os = "macos")
             )
     )]
#[path = "bpf.rs"]
mod backend;

#[cfg(any(target_os = "freebsd", target_os = "macos"))]
pub mod bpf;

#[cfg(feature = "netmap")]
#[path = "netmap.rs"]
mod backend;

#[cfg(feature = "netmap")]
pub mod netmap;

#[cfg(feature = "pcap")]
pub mod pcap;

pub mod dummy;

/// Type alias for an EtherType.
pub type EtherType = u16;

/// Type of data link channel to present (Linux only)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ChannelType {
    /// Send and receive layer 2 packets directly, including headers
    Layer2,
    /// Send and receive "cooked" packets - send and receive network layer packets
    Layer3(EtherType),
}

/// A channel for sending and receiving at the data link layer
///
/// NOTE: It is important to always include a catch-all variant in match statements using this
/// enum, since new variants may be added. For example:
///
/// ```ignore
/// match some_channel {
///     Ethernet(tx, rx) => { /* Handle Ethernet packets */ },
///     _ => panic!("Unhandled channel type")
/// }
/// ```
pub enum Channel {
    /// A datalink channel which sends and receives Ethernet packets
    Ethernet(Box<DataLinkSender>, Box<DataLinkReceiver>),

    /// This variant should never be used
    ///
    /// Including it allows new variants to be added to `Channel` without breaking existing code.
    PleaseIncludeACatchAllVariantWhenMatchingOnThisEnum,
}

/// A generic configuration type, encapsulating all options supported by each backend
///
/// Each option should be treated as a hint - each backend is free to ignore any and all
/// options which don't apply to it.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Config {
    /// The size of buffer to use when writing packets. Defaults to 4096
    pub write_buffer_size: usize,

    /// The size of buffer to use when reading packets. Defaults to 4096
    pub read_buffer_size: usize,

    /// Linux/BPF/Netmap only: The read timeout. Defaults to None.
    pub read_timeout: Option<Duration>,

    /// Linux/BPF/Netmap only: The write timeout. Defaults to None.
    pub write_timeout: Option<Duration>,

    /// Linux only: Specifies whether to read packets at the datalink layer or network layer.
    /// Defaults to Layer2
    pub channel_type: ChannelType,

    /// BPF/OS X only: The number of /dev/bpf* file descriptors to attempt before failing. Defaults
    /// to: 1000
    pub bpf_fd_attempts: usize,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            write_buffer_size: 4096,
            read_buffer_size: 4096,
            channel_type: ChannelType::Layer2,
            bpf_fd_attempts: 1000,
            read_timeout: None,
            write_timeout: None,
        }
    }
}

/// Create a new datalink channel for sending and receiving data
///
/// This allows for sending and receiving packets at the data link layer.
///
/// A list of network interfaces can be retrieved using datalink::interfaces().
///
/// The configuration serves as a hint to the backend - some or all of it may be used or ignored,
/// depending on which backend is used.
///
/// When matching on the returned channel, make sure to include a catch-all so that code doesn't
/// break when new channel types are added.
#[inline]
pub fn channel(network_interface: &NetworkInterface, configuration: Config) -> io::Result<Channel> {
    backend::channel(network_interface, (&configuration).into())
}

/// Trait to enable sending $packet packets
pub trait DataLinkSender: Send {
    /// Create and send a number of packets
    ///
    /// This will call `func` `num_packets` times. The function will be provided with a
    /// mutable packet to manipulate, which will then be sent. This allows packets to be
    /// built in-place, avoiding the copy required for `send`. If there is not sufficient
    /// capacity in the buffer, None will be returned.
    #[inline]
    fn build_and_send(&mut self,
                      num_packets: usize,
                      packet_size: usize,
                      func: &mut FnMut(&mut [u8]))
    -> Option<io::Result<()>>;

    /// Send a packet
    ///
    /// This may require an additional copy compared to `build_and_send`, depending on the
    /// operating system being used. The second parameter is currently ignored, however
    /// `None` should be passed.
    #[inline]
    fn send_to(&mut self,
                packet: &[u8],
                dst: Option<NetworkInterface>)
        -> Option<io::Result<()>>;
}

/// Structure for receiving packets at the data link layer. Should be constructed using
/// datalink_channel().
pub trait DataLinkReceiver: Send {
    #[inline]
    /// Get the next Ethernet frame in the channel
    fn next(&mut self) -> io::Result<&[u8]>;
}

/// Represents a network interface and its associated addresses
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct NetworkInterface {
    /// The name of the interface
    pub name: String,
    /// The interface index (operating system specific)
    pub index: u32,
    /// A MAC address for the interface
    pub mac: Option<MacAddr>,
    /// IP addresses and netmasks for the interface
    pub ips: Vec<IpNetwork>,
    /// Operating system specific flags for the interface
    pub flags: u32,
}

impl NetworkInterface {
    /// Retrieve the MAC address associated with the interface
    pub fn mac_address(&self) -> MacAddr {
        self.mac.unwrap()
    }

    /// Is the interface a loopback interface?
    pub fn is_loopback(&self) -> bool {
        self.flags & (sockets::IFF_LOOPBACK as u32) != 0
    }
}

/// Get a list of available network interfaces for the current machine.
pub fn interfaces() -> Vec<NetworkInterface> {
    backend::interfaces()
}
<|endoftext|>


<commit_before>struct S {}

trait T<'a> {
    type A;
}

impl T<'_> for S {
    type A = u32;
}

fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
//~^ ERROR binding for associated type `Output` references an anonymous lifetime

fn main() {}
<commit_msg>Include the note in the test.<commit_after>struct S {}

trait T<'a> {
    type A;
}

impl T<'_> for S {
    type A = u32;
}

fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
//~^ ERROR binding for associated type `Output` references an anonymous lifetime
//~^^ NOTE lifetimes appearing in an associated type are not considered constrained

fn main() {}
<|endoftext|>


<commit_before>use decoders::tiff::*;
use std::fmt;

/// Representation of the color filter array pattern in raw cameras
///
/// # Example
/// ```
/// use rawloader::CFA;
/// let cfa = CFA::new("RGGB");
/// assert_eq!(cfa.color_at(0,0), 0);
/// assert_eq!(cfa.color_at(0,1), 1);
/// assert_eq!(cfa.color_at(1,0), 1);
/// assert_eq!(cfa.color_at(1,1), 2);
/// ```
///
/// You will almost always get your CFA struct from a RawImage decode, already fully
/// initialized and ready to be used in processing. The color_at() implementation is
/// designed to be fast so it can be called inside the inner loop of demosaic or other
/// color-aware algorithms that work on pre-demosaic data
pub struct CFA {
  /// CFA pattern as a String
  pub name: String,
  /// Width of the repeating pattern
  pub width: usize,
  /// Height of the repeating pattern
  pub height: usize,

  pattern: [[usize;48];48],
}

impl CFA {
  #[doc(hidden)] pub fn new_from_tag(pat: &TiffEntry) -> CFA {
    let mut patname = String::new();
    for i in 0..pat.count() {
      patname.push(match pat.get_u32(i as usize) {
        0 => 'R',
        1 => 'G',
        2 => 'B',
        _ => 'U',
      });
    }
    CFA::new(&patname)
  }

  /// Create a new CFA from a string describing it. For simplicity the pattern is specified
  /// as each pixel being one of R/G/B/E representing the 0/1/2/3 colors in a 4 color image.
  /// The pattern is specified as the colors in each row concatenated so RGGB means that
  /// the first row is RG and the second row GB. Row size is determined by pattern size
  /// (e.g., the xtrans pattern is 6x6 and thus 36 characters long). In theory this could
  /// lead to confusion between different pattern sizes but in practice there are only
  /// a few oddball cameras no one cares about that do anything but 2x2 and 6x6 (and those
  /// work fine with this as well).
  pub fn new(patname: &str) -> CFA {
    let (width, height) = match patname.len() {
      0 => (0,0),
      4 => (2,2),
      36 => (6,6),
      16 => (2,8),
      144 => (12,12),
      _ => panic!("Unknown CFA size \"{}\"", patname),
    };
    let mut pattern: [[usize;48];48] = [[0;48];48];

    if width > 0 {
      // copy the pattern into the top left
      for (i,c) in patname.bytes().enumerate() {
        pattern[i/width][i%width] = match c {
          b'R' => 0,
          b'G' => 1,
          b'B' => 2,
          b'E' => 3,
          b'M' => 1,
          b'Y' => 3,
          _    => {
              let unknown_char = patname[i..].chars().next().unwrap();
              panic!("Unknown CFA color \"{}\" in pattern \"{}\"", unknown_char, patname)
          },
        };
      }

      // extend the pattern into the full matrix
      for row in 0..48 {
        for col in 0..48 {
          pattern[row][col] = pattern[row%height][col%width];
        }
      }
    }

    CFA {
      name: patname.to_string(),
      pattern: pattern,
      width: width,
      height: height,
    }
  }

  /// Get the color index at the given position. Designed to be fast so it can be called
  /// from inner loops without performance issues.
  pub fn color_at(&self, row: usize, col: usize) -> usize {
    self.pattern[(row+48) % 48][(col+48) % 48]
  }

  /// Shift the pattern left and/or down. This is useful when cropping the image to get
  /// the equivalent pattern of the crop when it's not a multiple of the pattern size.
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.color_at(0,0), 0);
  /// assert_eq!(cfa.color_at(0,1), 1);
  /// assert_eq!(cfa.color_at(1,0), 1);
  /// assert_eq!(cfa.color_at(1,1), 2);
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.color_at(0,0), 2);
  /// assert_eq!(shifted.color_at(0,1), 1);
  /// assert_eq!(shifted.color_at(1,0), 1);
  /// assert_eq!(shifted.color_at(1,1), 0);
  /// ```
  pub fn shift(&self, x: usize, y: usize) -> CFA {
    let mut pattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        pattern[row][col] = self.color_at(row+y,col+x);
      }
    }

    let mut name = "".to_string();
    for row in 0..self.height {
      for col in 0..self.width {
        name.push_str(match pattern[row][col] {
          0 => "R",
          1 => "G",
          2 => "B",
          3 => "E",
          x => panic!("Unknown CFA color \"{}\"", x),
        });
      }
    }

    CFA {
      name: name,
      pattern: pattern,
      width: self.width,
      height: self.height,
    }
  }

  /// Test if this is actually a valid CFA pattern
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert!(cfa.is_valid());
  ///
  /// let cfa = CFA::new("");
  /// assert!(!cfa.is_valid());
  /// ```
  pub fn is_valid(&self) -> bool {
    self.width != 0 && self.height != 0
  }

  /// Convert the CFA back into a pattern string
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.to_string(), "RGGB");
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.to_string(), "BGGR");
  /// ```
  pub fn to_string(&self) -> String {
    self.name.clone()
  }
}

impl fmt::Debug for CFA {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "CFA {{ {} }}", self.name)
  }
}

impl Clone for CFA {
  fn clone(&self) -> CFA {
    let mut cpattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        cpattern[row][col] = self.pattern[row][col];
      }
    }
    CFA {
      name: self.name.clone(),
      pattern: cpattern,
      width: self.width,
      height: self.height,
    }
  }
}
<commit_msg>Replace Clone in CFA with a derive<commit_after>use decoders::tiff::*;
use std::fmt;

/// Representation of the color filter array pattern in raw cameras
///
/// # Example
/// ```
/// use rawloader::CFA;
/// let cfa = CFA::new("RGGB");
/// assert_eq!(cfa.color_at(0,0), 0);
/// assert_eq!(cfa.color_at(0,1), 1);
/// assert_eq!(cfa.color_at(1,0), 1);
/// assert_eq!(cfa.color_at(1,1), 2);
/// ```
///
/// You will almost always get your CFA struct from a RawImage decode, already fully
/// initialized and ready to be used in processing. The color_at() implementation is
/// designed to be fast so it can be called inside the inner loop of demosaic or other
/// color-aware algorithms that work on pre-demosaic data
#[derive(Clone)]
pub struct CFA {
  /// CFA pattern as a String
  pub name: String,
  /// Width of the repeating pattern
  pub width: usize,
  /// Height of the repeating pattern
  pub height: usize,

  pattern: [[usize;48];48],
}

impl CFA {
  #[doc(hidden)] pub fn new_from_tag(pat: &TiffEntry) -> CFA {
    let mut patname = String::new();
    for i in 0..pat.count() {
      patname.push(match pat.get_u32(i as usize) {
        0 => 'R',
        1 => 'G',
        2 => 'B',
        _ => 'U',
      });
    }
    CFA::new(&patname)
  }

  /// Create a new CFA from a string describing it. For simplicity the pattern is specified
  /// as each pixel being one of R/G/B/E representing the 0/1/2/3 colors in a 4 color image.
  /// The pattern is specified as the colors in each row concatenated so RGGB means that
  /// the first row is RG and the second row GB. Row size is determined by pattern size
  /// (e.g., the xtrans pattern is 6x6 and thus 36 characters long). In theory this could
  /// lead to confusion between different pattern sizes but in practice there are only
  /// a few oddball cameras no one cares about that do anything but 2x2 and 6x6 (and those
  /// work fine with this as well).
  pub fn new(patname: &str) -> CFA {
    let (width, height) = match patname.len() {
      0 => (0,0),
      4 => (2,2),
      36 => (6,6),
      16 => (2,8),
      144 => (12,12),
      _ => panic!("Unknown CFA size \"{}\"", patname),
    };
    let mut pattern: [[usize;48];48] = [[0;48];48];

    if width > 0 {
      // copy the pattern into the top left
      for (i,c) in patname.bytes().enumerate() {
        pattern[i/width][i%width] = match c {
          b'R' => 0,
          b'G' => 1,
          b'B' => 2,
          b'E' => 3,
          b'M' => 1,
          b'Y' => 3,
          _    => {
              let unknown_char = patname[i..].chars().next().unwrap();
              panic!("Unknown CFA color \"{}\" in pattern \"{}\"", unknown_char, patname)
          },
        };
      }

      // extend the pattern into the full matrix
      for row in 0..48 {
        for col in 0..48 {
          pattern[row][col] = pattern[row%height][col%width];
        }
      }
    }

    CFA {
      name: patname.to_string(),
      pattern: pattern,
      width: width,
      height: height,
    }
  }

  /// Get the color index at the given position. Designed to be fast so it can be called
  /// from inner loops without performance issues.
  pub fn color_at(&self, row: usize, col: usize) -> usize {
    self.pattern[(row+48) % 48][(col+48) % 48]
  }

  /// Shift the pattern left and/or down. This is useful when cropping the image to get
  /// the equivalent pattern of the crop when it's not a multiple of the pattern size.
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.color_at(0,0), 0);
  /// assert_eq!(cfa.color_at(0,1), 1);
  /// assert_eq!(cfa.color_at(1,0), 1);
  /// assert_eq!(cfa.color_at(1,1), 2);
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.color_at(0,0), 2);
  /// assert_eq!(shifted.color_at(0,1), 1);
  /// assert_eq!(shifted.color_at(1,0), 1);
  /// assert_eq!(shifted.color_at(1,1), 0);
  /// ```
  pub fn shift(&self, x: usize, y: usize) -> CFA {
    let mut pattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        pattern[row][col] = self.color_at(row+y,col+x);
      }
    }

    let mut name = "".to_string();
    for row in 0..self.height {
      for col in 0..self.width {
        name.push_str(match pattern[row][col] {
          0 => "R",
          1 => "G",
          2 => "B",
          3 => "E",
          x => panic!("Unknown CFA color \"{}\"", x),
        });
      }
    }

    CFA {
      name: name,
      pattern: pattern,
      width: self.width,
      height: self.height,
    }
  }

  /// Test if this is actually a valid CFA pattern
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert!(cfa.is_valid());
  ///
  /// let cfa = CFA::new("");
  /// assert!(!cfa.is_valid());
  /// ```
  pub fn is_valid(&self) -> bool {
    self.width != 0 && self.height != 0
  }

  /// Convert the CFA back into a pattern string
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.to_string(), "RGGB");
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.to_string(), "BGGR");
  /// ```
  pub fn to_string(&self) -> String {
    self.name.clone()
  }
}

impl fmt::Debug for CFA {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "CFA {{ {} }}", self.name)
  }
}
<|endoftext|>


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

use libc::{
    c_char,
    c_int,
};

use types::{
    CLPK_complex,
    CLPK_doublecomplex,
    CLPK_doublereal,
    CLPK_integer,
    CLPK_real,
};

#[link(name = "lapack")]
extern "C" {
    pub fn ssyev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer, a: *mut CLPK_real,
            lda: *const CLPK_integer, w: CLPK_real, work: CLPK_real,
            lwork: CLPK_integer,
            info: *mut CLPK_integer) -> c_int;
    pub fn dsyev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            a: *mut CLPK_doublereal, lda: *const CLPK_integer, w: CLPK_doublereal,
            work: CLPK_doublereal, lwork: CLPK_integer,
            info: *mut CLPK_integer) -> c_int;

    pub fn cheev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer, a: *mut CLPK_complex,
            lda: *const CLPK_integer, w: CLPK_real, work: CLPK_complex,
            lwork: CLPK_integer, rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zheev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            a: *mut CLPK_doublecomplex, lda: *const CLPK_integer,
            w: CLPK_doublereal, work: CLPK_doublecomplex,
            lwork: CLPK_integer, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn sspev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer, ap: CLPK_real,
            w: CLPK_real, z: CLPK_real, ldz: CLPK_integer,
            work: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn dspev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            ap: CLPK_doublereal, w: CLPK_doublereal,
            z: CLPK_doublereal, ldz: CLPK_integer,
            work: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn chpev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            ap: CLPK_complex, w: CLPK_real, z: CLPK_complex,
            ldz: CLPK_integer, work: CLPK_complex, rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zhpev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            ap: CLPK_doublecomplex, w: CLPK_doublereal,
            z: CLPK_doublecomplex, ldz: CLPK_integer,
            work: CLPK_doublecomplex, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn ssbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_real, ldab: CLPK_integer,
            w: CLPK_real, z: CLPK_real, ldz: CLPK_integer,
            work: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn dsbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_doublereal, ldab: CLPK_integer,
            w: CLPK_doublereal, z: CLPK_doublereal, ldz: CLPK_integer,
            work: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn chbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_complex, ldab: CLPK_integer,
            w: CLPK_real, z: CLPK_complex, ldz: CLPK_integer,
            work: CLPK_complex, rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zhbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_doublecomplex,
            ldab: CLPK_integer, w: CLPK_doublereal,
            z: CLPK_doublecomplex, ldz: CLPK_integer,
            work: CLPK_doublecomplex, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn sstev_(jobz: c_char, n: *const CLPK_integer, d: CLPK_real,
            e: CLPK_real, z: CLPK_real, ldz: CLPK_integer,
            work: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn dstev_(jobz: c_char, n: *const CLPK_integer, d: CLPK_doublereal,
            e: CLPK_doublereal, z: CLPK_doublereal, ldz: CLPK_integer,
            work: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;
}
<commit_msg>Add Geev trait<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use libc::{
    c_char,
    c_int,
};

use types::{
    CLPK_complex,
    CLPK_doublecomplex,
    CLPK_doublereal,
    CLPK_integer,
    CLPK_real,
};

#[link(name = "lapack")]
extern "C" {
    pub fn ssyev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer, a: *mut CLPK_real,
            lda: *const CLPK_integer, w: CLPK_real, work: CLPK_real,
            lwork: CLPK_integer,
            info: *mut CLPK_integer) -> c_int;
    pub fn dsyev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            a: *mut CLPK_doublereal, lda: *const CLPK_integer, w: CLPK_doublereal,
            work: CLPK_doublereal, lwork: CLPK_integer,
            info: *mut CLPK_integer) -> c_int;

    pub fn cheev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer, a: *mut CLPK_complex,
            lda: *const CLPK_integer, w: CLPK_real, work: CLPK_complex,
            lwork: CLPK_integer, rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zheev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            a: *mut CLPK_doublecomplex, lda: *const CLPK_integer,
            w: CLPK_doublereal, work: CLPK_doublecomplex,
            lwork: CLPK_integer, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn sspev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer, ap: CLPK_real,
            w: CLPK_real, z: CLPK_real, ldz: CLPK_integer,
            work: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn dspev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            ap: CLPK_doublereal, w: CLPK_doublereal,
            z: CLPK_doublereal, ldz: CLPK_integer,
            work: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn chpev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            ap: CLPK_complex, w: CLPK_real, z: CLPK_complex,
            ldz: CLPK_integer, work: CLPK_complex, rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zhpev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            ap: CLPK_doublecomplex, w: CLPK_doublereal,
            z: CLPK_doublecomplex, ldz: CLPK_integer,
            work: CLPK_doublecomplex, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn ssbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_real, ldab: CLPK_integer,
            w: CLPK_real, z: CLPK_real, ldz: CLPK_integer,
            work: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn dsbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_doublereal, ldab: CLPK_integer,
            w: CLPK_doublereal, z: CLPK_doublereal, ldz: CLPK_integer,
            work: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn chbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_complex, ldab: CLPK_integer,
            w: CLPK_real, z: CLPK_complex, ldz: CLPK_integer,
            work: CLPK_complex, rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zhbev_(jobz: c_char, uplo: c_char, n: *const CLPK_integer,
            kd: CLPK_integer, ab: CLPK_doublecomplex,
            ldab: CLPK_integer, w: CLPK_doublereal,
            z: CLPK_doublecomplex, ldz: CLPK_integer,
            work: CLPK_doublecomplex, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn sstev_(jobz: c_char, n: *const CLPK_integer, d: CLPK_real,
            e: CLPK_real, z: CLPK_real, ldz: CLPK_integer,
            work: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn dstev_(jobz: c_char, n: *const CLPK_integer, d: CLPK_doublereal,
            e: CLPK_doublereal, z: CLPK_doublereal, ldz: CLPK_integer,
            work: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;

    pub fn sgeev_(jobvl: c_char, jobvr: c_char, n: *const CLPK_integer, a: *mut CLPK_real,
            lda: *const CLPK_integer, wr: CLPK_real, wi: CLPK_real,
            vl: CLPK_real, ldvl: CLPK_integer, vr: CLPK_real,
            ldvr: CLPK_integer, work: CLPK_real, lwork: CLPK_integer,
            info: *mut CLPK_integer) -> c_int;
    pub fn dgeev_(jobvl: c_char, jobvr: c_char, n: *const CLPK_integer,
            a: *mut CLPK_doublereal, lda: *const CLPK_integer, wr: CLPK_doublereal,
            wi: CLPK_doublereal, vl: CLPK_doublereal,
            ldvl: CLPK_integer, vr: CLPK_doublereal, ldvr: CLPK_integer,
            work: CLPK_doublereal, lwork: CLPK_integer,
            info: *mut CLPK_integer) -> c_int;
    pub fn cgeev_(jobvl: c_char, jobvr: c_char, n: *const CLPK_integer,
            a: *mut CLPK_complex, lda: *const CLPK_integer, w: CLPK_complex,
            vl: CLPK_complex, ldvl: CLPK_integer, vr: CLPK_complex,
            ldvr: CLPK_integer, work: CLPK_complex, lwork: CLPK_integer,
            rwork: CLPK_real,
            info: *mut CLPK_integer) -> c_int;
    pub fn zgeev_(jobvl: c_char, jobvr: c_char, n: *const CLPK_integer,
            a: *mut CLPK_doublecomplex, lda: *const CLPK_integer,
            w: CLPK_doublecomplex, vl: CLPK_doublecomplex,
            ldvl: CLPK_integer, vr: CLPK_doublecomplex,
            ldvr: CLPK_integer, work: CLPK_doublecomplex,
            lwork: CLPK_integer, rwork: CLPK_doublereal,
            info: *mut CLPK_integer) -> c_int;
}
<|endoftext|>