<commit_before>use gl;
use gl::types::*;
use gl_context::{GLContext, GLContextExistence};
use std::default::Default;
use std::kinds::marker::ContravariantLifetime;
use vertex_buffer::GLBuffer;

// TODO(cgaebel): Handle texture creation from an SDL surface.

#[deriving(Copy, Clone)]
pub struct TextureUnit {
  pub glsl_id: GLuint,
}

impl TextureUnit {
  // TODO: consider making this part of the struct to avoid recalculating;
  // is that fetch cheaper than the addition of a constant?
  pub fn gl_id(&self) -> GLuint {
    gl::TEXTURE0 + self.glsl_id
  }
}

impl Default for TextureUnit {
  fn default() -> TextureUnit {
    TextureUnit {
      glsl_id: 0,
    }
  }
}

impl Add<u32, TextureUnit> for TextureUnit {
  fn add(&self, rhs: &u32) -> TextureUnit {
    TextureUnit {
      glsl_id: self.glsl_id + *rhs,
    }
  }
}

/// A GPU-allocated texture.
pub struct TextureHandle<'a> {
  pub gl_id: GLuint,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> TextureHandle<'a> {
  pub fn new(_gl: &'a GLContextExistence) -> TextureHandle<'a> {
    let mut handle = 0;
    unsafe {
      gl::GenTextures(1, &mut handle);
    }
    TextureHandle {
      gl_id: handle,
      lifetime: ContravariantLifetime,
    }
  }
}

#[unsafe_destructor]
impl<'a> Drop for TextureHandle<'a> {
  fn drop(&mut self) {
    unsafe {
      gl::DeleteTextures(1, &self.gl_id);
    }
  }
}

/// A GPU-allocated texture.
pub struct Texture2D<'a> {
  pub handle: TextureHandle<'a>,
}

impl<'a> Texture2D<'a> {
  pub fn new(gl: &'a GLContextExistence) -> Texture2D<'a> {
    Texture2D {
      handle: TextureHandle::new(gl),
    }
  }
}

/// See the OpenGL docs on buffer textures.
pub struct BufferTexture<'a, T> {
  pub handle: TextureHandle<'a>,
  pub buffer: GLBuffer<'a, T>,
}

impl<'a, T> BufferTexture<'a, T> {
  pub fn new(
    gl: &'a GLContextExistence,
    gl_context: &mut GLContext,
    format: GLenum,
    capacity: uint,
  ) -> BufferTexture<'a, T> {
    // TODO: enforce that `format` matches T.

    let buffer = GLBuffer::new(gl, gl_context, capacity);
    let handle = TextureHandle::new(gl);

    unsafe {
      gl::BindTexture(gl::TEXTURE_BUFFER, handle.gl_id);
      gl::TexBuffer(gl::TEXTURE_BUFFER, format, buffer.byte_buffer.handle.gl_id);
    }

    BufferTexture {
      handle: handle,
      buffer: buffer,
    }
  }
}
<commit_msg>rustup<commit_after>use gl;
use gl::types::*;
use gl_context::{GLContext, GLContextExistence};
use std::default::Default;
use std::kinds::marker::ContravariantLifetime;
use vertex_buffer::GLBuffer;

// TODO(cgaebel): Handle texture creation from an SDL surface.

#[deriving(Copy, Clone)]
pub struct TextureUnit {
  pub glsl_id: GLuint,
}

impl TextureUnit {
  // TODO: consider making this part of the struct to avoid recalculating;
  // is that fetch cheaper than the addition of a constant?
  pub fn gl_id(&self) -> GLuint {
    gl::TEXTURE0 + self.glsl_id
  }
}

impl Default for TextureUnit {
  fn default() -> TextureUnit {
    TextureUnit {
      glsl_id: 0,
    }
  }
}

impl Add<u32, TextureUnit> for TextureUnit {
  fn add(self, rhs: u32) -> TextureUnit {
    TextureUnit {
      glsl_id: self.glsl_id + rhs,
    }
  }
}

/// A GPU-allocated texture.
pub struct TextureHandle<'a> {
  pub gl_id: GLuint,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> TextureHandle<'a> {
  pub fn new(_gl: &'a GLContextExistence) -> TextureHandle<'a> {
    let mut handle = 0;
    unsafe {
      gl::GenTextures(1, &mut handle);
    }
    TextureHandle {
      gl_id: handle,
      lifetime: ContravariantLifetime,
    }
  }
}

#[unsafe_destructor]
impl<'a> Drop for TextureHandle<'a> {
  fn drop(&mut self) {
    unsafe {
      gl::DeleteTextures(1, &self.gl_id);
    }
  }
}

/// A GPU-allocated texture.
pub struct Texture2D<'a> {
  pub handle: TextureHandle<'a>,
}

impl<'a> Texture2D<'a> {
  pub fn new(gl: &'a GLContextExistence) -> Texture2D<'a> {
    Texture2D {
      handle: TextureHandle::new(gl),
    }
  }
}

/// See the OpenGL docs on buffer textures.
pub struct BufferTexture<'a, T> {
  pub handle: TextureHandle<'a>,
  pub buffer: GLBuffer<'a, T>,
}

impl<'a, T> BufferTexture<'a, T> {
  pub fn new(
    gl: &'a GLContextExistence,
    gl_context: &mut GLContext,
    format: GLenum,
    capacity: uint,
  ) -> BufferTexture<'a, T> {
    // TODO: enforce that `format` matches T.

    let buffer = GLBuffer::new(gl, gl_context, capacity);
    let handle = TextureHandle::new(gl);

    unsafe {
      gl::BindTexture(gl::TEXTURE_BUFFER, handle.gl_id);
      gl::TexBuffer(gl::TEXTURE_BUFFER, format, buffer.byte_buffer.handle.gl_id);
    }

    BufferTexture {
      handle: handle,
      buffer: buffer,
    }
  }
}
<|endoftext|>


<commit_before>use indoc::indoc;
use serde_json::{json, Number, Value};

#[test]
fn number() {
    assert_eq!(format!("{:?}", Number::from(1)), "Number(1)");
    assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)");
    assert_eq!(
        format!("{:?}", Number::from_f64(1.0).unwrap()),
        "Number(1.0)"
    );
}

#[test]
fn value_null() {
    assert_eq!(format!("{:?}", json!(null)), "Null");
}

#[test]
fn value_bool() {
    assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
    assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
}

#[test]
fn value_number() {
    assert_eq!(format!("{:?}", json!(1)), "Number(1)");
    assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
    assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
}

#[test]
fn value_string() {
    assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
}

#[test]
fn value_array() {
    assert_eq!(format!("{:?}", json!([])), "Array([])");
}

#[test]
fn value_object() {
    assert_eq!(format!("{:?}", json!({})), "Object({})");
}

#[test]
fn error() {
    let err = serde_json::from_str::<Value>("{0}").unwrap_err();
    let expected = "Error(\"key must be a string\", line: 1, column: 2)";
    assert_eq!(format!("{:?}", err), expected);
}

#[test]
fn indented() {
    let j = json!({
        "Null": null,
        "Bool": true,
        "Number": 1,
        "String": "...",
        "Array": [true],
        "EmptyArray": [],
        "EmptyObject": {}
    });
    let expected = indoc! {r#"
        Object({
            "Array": Array([
                Bool(
                    true,
                ),
            ]),
            "Bool": Bool(
                true,
            ),
            "EmptyArray": Array([]),
            "EmptyObject": Object({}),
            "Null": Null,
            "Number": Number(
                1,
            ),
            "String": String(
                "...",
            ),
        })"#
    };
    assert_eq!(format!("{:#?}", j), expected);
}
<commit_msg>Make Debug test compatible with preserve_order<commit_after>use indoc::indoc;
use serde_json::{json, Number, Value};

#[test]
fn number() {
    assert_eq!(format!("{:?}", Number::from(1)), "Number(1)");
    assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)");
    assert_eq!(
        format!("{:?}", Number::from_f64(1.0).unwrap()),
        "Number(1.0)"
    );
}

#[test]
fn value_null() {
    assert_eq!(format!("{:?}", json!(null)), "Null");
}

#[test]
fn value_bool() {
    assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
    assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
}

#[test]
fn value_number() {
    assert_eq!(format!("{:?}", json!(1)), "Number(1)");
    assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
    assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
}

#[test]
fn value_string() {
    assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
}

#[test]
fn value_array() {
    assert_eq!(format!("{:?}", json!([])), "Array([])");
}

#[test]
fn value_object() {
    assert_eq!(format!("{:?}", json!({})), "Object({})");
}

#[test]
fn error() {
    let err = serde_json::from_str::<Value>("{0}").unwrap_err();
    let expected = "Error(\"key must be a string\", line: 1, column: 2)";
    assert_eq!(format!("{:?}", err), expected);
}

#[test]
fn indented() {
    let j = json!({
        "Array": [true],
        "Bool": true,
        "EmptyArray": [],
        "EmptyObject": {},
        "Null": null,
        "Number": 1,
        "String": "...",
    });
    let expected = indoc! {r#"
        Object({
            "Array": Array([
                Bool(
                    true,
                ),
            ]),
            "Bool": Bool(
                true,
            ),
            "EmptyArray": Array([]),
            "EmptyObject": Object({}),
            "Null": Null,
            "Number": Number(
                1,
            ),
            "String": String(
                "...",
            ),
        })"#
    };
    assert_eq!(format!("{:#?}", j), expected);
}
<|endoftext|>


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

use std::fmt;
use std::io;

use std::cell::RefCell;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::io::{Read, Write};
use std::pin::Pin;

use futures::future::Future;
use futures::task::{Context, Poll, Waker};

use openssl::error::ErrorStack as SslErrorStack;
use openssl::ssl::Error as SslError;
use openssl::ssl::{HandshakeError, SslConnector, SslStream};

use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tokio::net::{TcpStream, ToSocketAddrs};

/// TLS error.
#[derive(Debug, Clone)]
pub struct TlsError {
    msg: String,
}

impl TlsError {
    /// Create a new error with a given message.
    pub fn new<T>(msg: T) -> Self
    where
        T: ToString,
    {
        Self {
            msg: msg.to_string(),
        }
    }
}

impl Error for TlsError {}

impl Display for TlsError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        f.write_str(&self.msg)
    }
}

impl From<io::Error> for TlsError {
    fn from(err: io::Error) -> Self {
        Self::new(err)
    }
}

impl From<SslError> for TlsError {
    fn from(err: SslError) -> Self {
        Self::new(err)
    }
}

impl From<SslErrorStack> for TlsError {
    fn from(err: SslErrorStack) -> Self {
        Self::new(err)
    }
}

thread_local! {
    /// An async context set when entering an async function to be later used
    /// by the IO methods within the `InnerSslStream`.
    static ASYNC_CONTEXT: RefCell<Option<Waker>> = RefCell::new(None);
}

/// A struct that will remove the async context when dropped.
struct DropAsyncContext;

impl Drop for DropAsyncContext {
    fn drop(&mut self) {
        ASYNC_CONTEXT.with(|v| {
            *v.borrow_mut() = None;
        })
    }
}

/// Set the async context.
fn set_async_context(cx: &Context) -> DropAsyncContext {
    ASYNC_CONTEXT.with(|v| {
        *v.borrow_mut() = Some(cx.waker().clone());
    });

    DropAsyncContext
}

/// Get the stored async context.
fn with_async_context<F, R>(f: F) -> R
where
    F: FnOnce(&mut Context) -> R,
{
    ASYNC_CONTEXT.with(|v| {
        let cell = v.borrow();
        let waker = cell.as_ref().expect("no async context set");

        let mut context = Context::from_waker(waker);

        f(&mut context)
    })
}

/// Helper struct.
struct InnerSslStream<S> {
    inner: S,
}

impl<S> InnerSslStream<S> {
    /// Create a new inner stream.
    fn new(stream: S) -> Self {
        Self { inner: stream }
    }
}

impl<S> Read for InnerSslStream<S>
where
    S: AsyncRead + Unpin,
{
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
        with_async_context(|cx| {
            let inner = Pin::new(&mut self.inner);

            let mut buf = ReadBuf::new(buf);

            let data = match inner.poll_read(cx, &mut buf) {
                Poll::Ready(Ok(())) => buf.filled(),
                Poll::Ready(Err(err)) => return Err(err),
                Poll::Pending => return Err(io::Error::from(io::ErrorKind::WouldBlock)),
            };

            Ok(data.len())
        })
    }
}

impl<S> Write for InnerSslStream<S>
where
    S: AsyncWrite + Unpin,
{
    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
        with_async_context(|cx| {
            let inner = Pin::new(&mut self.inner);

            if let Poll::Ready(res) = inner.poll_write(cx, buf) {
                res
            } else {
                Err(io::Error::from(io::ErrorKind::WouldBlock))
            }
        })
    }

    fn flush(&mut self) -> Result<(), io::Error> {
        with_async_context(|cx| {
            let inner = Pin::new(&mut self.inner);

            if let Poll::Ready(res) = inner.poll_flush(cx) {
                res
            } else {
                Err(io::Error::from(io::ErrorKind::WouldBlock))
            }
        })
    }
}

/// Asynchronous TLS stream.
pub struct TlsStream<S> {
    inner: SslStream<InnerSslStream<S>>,
}

impl<S> AsyncRead for TlsStream<S>
where
    S: AsyncRead + AsyncWrite + Unpin,
{
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    ) -> Poll<Result<(), io::Error>> {
        let _drop_context = set_async_context(cx);

        match self.inner.read(buf.initialize_unfilled()) {
            Ok(len) => buf.advance(len),
            Err(err) => match err.kind() {
                io::ErrorKind::WouldBlock => return Poll::Pending,
                _ => return Poll::Ready(Err(err)),
            },
        }

        Poll::Ready(Ok(()))
    }
}

impl<S> AsyncWrite for TlsStream<S>
where
    S: AsyncRead + AsyncWrite + Unpin,
{
    fn poll_write(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
        buf: &[u8],
    ) -> Poll<Result<usize, io::Error>> {
        let _drop_context = set_async_context(cx);

        match self.inner.write(buf) {
            Ok(len) => Poll::Ready(Ok(len)),
            Err(err) => match err.kind() {
                io::ErrorKind::WouldBlock => Poll::Pending,
                _ => Poll::Ready(Err(err)),
            },
        }
    }

    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
        let _drop_context = set_async_context(cx);

        match self.inner.flush() {
            Ok(()) => Poll::Ready(Ok(())),
            Err(err) => match err.kind() {
                io::ErrorKind::WouldBlock => Poll::Pending,
                _ => Poll::Ready(Err(err)),
            },
        }
    }

    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
        let _drop_context = set_async_context(cx);

        if let Err(err) = self.inner.shutdown() {
            match err.into_io_error() {
                Ok(err) => match err.kind() {
                    io::ErrorKind::WouldBlock => return Poll::Pending,
                    _ => return Poll::Ready(Err(err)),
                },
                Err(err) => {
                    return Poll::Ready(Err(io::Error::new(
                        io::ErrorKind::Other,
                        format!("TLS shutdown error: {}", err),
                    )));
                }
            }
        }

        let inner_stream = self.inner.get_mut();

        let inner = Pin::new(&mut inner_stream.inner);

        inner.poll_shutdown(cx)
    }
}

impl<S> From<SslStream<InnerSslStream<S>>> for TlsStream<S> {
    fn from(stream: SslStream<InnerSslStream<S>>) -> TlsStream<S> {
        TlsStream { inner: stream }
    }
}

/// Type alias.
type HandshakeResult<S> = Result<SslStream<InnerSslStream<S>>, HandshakeError<InnerSslStream<S>>>;

/// A pending TLS connection.
struct TlsConnect<S> {
    handshake: Option<HandshakeResult<S>>,
}

impl<S> Future for TlsConnect<S>
where
    S: AsyncRead + AsyncWrite + Unpin,
{
    type Output = Result<TlsStream<S>, TlsError>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        let _drop_context = set_async_context(cx);

        match self
            .handshake
            .take()
            .expect("the future has been already resolved")
        {
            Ok(stream) => Poll::Ready(Ok(stream.into())),
            Err(HandshakeError::SetupFailure(err)) => Poll::Ready(Err(TlsError::from(err))),
            Err(HandshakeError::Failure(m)) => Poll::Ready(Err(TlsError::from(m.into_error()))),
            Err(HandshakeError::WouldBlock(m)) => match m.handshake() {
                Ok(stream) => Poll::Ready(Ok(stream.into())),
                Err(HandshakeError::SetupFailure(err)) => Poll::Ready(Err(TlsError::from(err))),
                Err(HandshakeError::Failure(m)) => Poll::Ready(Err(TlsError::from(m.into_error()))),
                Err(HandshakeError::WouldBlock(m)) => {
                    self.handshake = Some(Err(HandshakeError::WouldBlock(m)));

                    Poll::Pending
                }
            },
        }
    }
}

/// Asynchronous TLS connector.
#[derive(Clone)]
pub struct TlsConnector {
    inner: SslConnector,
}

impl TlsConnector {
    /// Take a given asynchronous stream and perform a TLS handshake.
    pub async fn connect<T>(&self, addr: T) -> Result<TlsStream<TcpStream>, TlsError>
    where
        T: ToSocketAddrs,
    {
        let stream = TcpStream::connect(addr);
        let stream = stream.await?;
        let stream = InnerSslStream::new(stream);

        let configuration = self.inner.configure()?;

        let handshake = futures::future::lazy(move |cx| {
            let _drop_context = set_async_context(cx);

            // NOTE: We do not need to validate the server name because we use only one root
            // certificate. It's a self signed certificate issued directly by Angelcam and used
            // only for Arrow.
            configuration
                .verify_hostname(false)
                .connect("hostname", stream)
        });

        let handshake = handshake.await;

        let connect = TlsConnect {
            handshake: Some(handshake),
        };

        connect.await
    }
}

impl From<SslConnector> for TlsConnector {
    fn from(connector: SslConnector) -> Self {
        Self { inner: connector }
    }
}
<commit_msg>Fix potential connection error if either IPv4 or IPv6 is unavailable<commit_after>// Copyright 2018 click2stream, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;
use std::io;

use std::cell::RefCell;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::io::{Read, Write};
use std::pin::Pin;
use std::time::Duration;

use futures::future::Future;
use futures::stream::StreamExt;
use futures::task::{Context, Poll, Waker};

use openssl::error::ErrorStack as SslErrorStack;
use openssl::ssl::Error as SslError;
use openssl::ssl::{HandshakeError, SslConnector, SslStream};

use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tokio::net::{TcpStream, ToSocketAddrs};

/// TLS error.
#[derive(Debug, Clone)]
pub struct TlsError {
    msg: String,
}

impl TlsError {
    /// Create a new error with a given message.
    pub fn new<T>(msg: T) -> Self
    where
        T: ToString,
    {
        Self {
            msg: msg.to_string(),
        }
    }
}

impl Error for TlsError {}

impl Display for TlsError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        f.write_str(&self.msg)
    }
}

impl From<io::Error> for TlsError {
    fn from(err: io::Error) -> Self {
        Self::new(err)
    }
}

impl From<SslError> for TlsError {
    fn from(err: SslError) -> Self {
        Self::new(err)
    }
}

impl From<SslErrorStack> for TlsError {
    fn from(err: SslErrorStack) -> Self {
        Self::new(err)
    }
}

thread_local! {
    /// An async context set when entering an async function to be later used
    /// by the IO methods within the `InnerSslStream`.
    static ASYNC_CONTEXT: RefCell<Option<Waker>> = RefCell::new(None);
}

/// A struct that will remove the async context when dropped.
struct DropAsyncContext;

impl Drop for DropAsyncContext {
    fn drop(&mut self) {
        ASYNC_CONTEXT.with(|v| {
            *v.borrow_mut() = None;
        })
    }
}

/// Set the async context.
fn set_async_context(cx: &Context) -> DropAsyncContext {
    ASYNC_CONTEXT.with(|v| {
        *v.borrow_mut() = Some(cx.waker().clone());
    });

    DropAsyncContext
}

/// Get the stored async context.
fn with_async_context<F, R>(f: F) -> R
where
    F: FnOnce(&mut Context) -> R,
{
    ASYNC_CONTEXT.with(|v| {
        let cell = v.borrow();
        let waker = cell.as_ref().expect("no async context set");

        let mut context = Context::from_waker(waker);

        f(&mut context)
    })
}

/// Helper struct.
struct InnerSslStream<S> {
    inner: S,
}

impl<S> InnerSslStream<S> {
    /// Create a new inner stream.
    fn new(stream: S) -> Self {
        Self { inner: stream }
    }
}

impl<S> Read for InnerSslStream<S>
where
    S: AsyncRead + Unpin,
{
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
        with_async_context(|cx| {
            let inner = Pin::new(&mut self.inner);

            let mut buf = ReadBuf::new(buf);

            let data = match inner.poll_read(cx, &mut buf) {
                Poll::Ready(Ok(())) => buf.filled(),
                Poll::Ready(Err(err)) => return Err(err),
                Poll::Pending => return Err(io::Error::from(io::ErrorKind::WouldBlock)),
            };

            Ok(data.len())
        })
    }
}

impl<S> Write for InnerSslStream<S>
where
    S: AsyncWrite + Unpin,
{
    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
        with_async_context(|cx| {
            let inner = Pin::new(&mut self.inner);

            if let Poll::Ready(res) = inner.poll_write(cx, buf) {
                res
            } else {
                Err(io::Error::from(io::ErrorKind::WouldBlock))
            }
        })
    }

    fn flush(&mut self) -> Result<(), io::Error> {
        with_async_context(|cx| {
            let inner = Pin::new(&mut self.inner);

            if let Poll::Ready(res) = inner.poll_flush(cx) {
                res
            } else {
                Err(io::Error::from(io::ErrorKind::WouldBlock))
            }
        })
    }
}

/// Asynchronous TLS stream.
pub struct TlsStream<S> {
    inner: SslStream<InnerSslStream<S>>,
}

impl<S> AsyncRead for TlsStream<S>
where
    S: AsyncRead + AsyncWrite + Unpin,
{
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    ) -> Poll<Result<(), io::Error>> {
        let _drop_context = set_async_context(cx);

        match self.inner.read(buf.initialize_unfilled()) {
            Ok(len) => buf.advance(len),
            Err(err) => match err.kind() {
                io::ErrorKind::WouldBlock => return Poll::Pending,
                _ => return Poll::Ready(Err(err)),
            },
        }

        Poll::Ready(Ok(()))
    }
}

impl<S> AsyncWrite for TlsStream<S>
where
    S: AsyncRead + AsyncWrite + Unpin,
{
    fn poll_write(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
        buf: &[u8],
    ) -> Poll<Result<usize, io::Error>> {
        let _drop_context = set_async_context(cx);

        match self.inner.write(buf) {
            Ok(len) => Poll::Ready(Ok(len)),
            Err(err) => match err.kind() {
                io::ErrorKind::WouldBlock => Poll::Pending,
                _ => Poll::Ready(Err(err)),
            },
        }
    }

    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
        let _drop_context = set_async_context(cx);

        match self.inner.flush() {
            Ok(()) => Poll::Ready(Ok(())),
            Err(err) => match err.kind() {
                io::ErrorKind::WouldBlock => Poll::Pending,
                _ => Poll::Ready(Err(err)),
            },
        }
    }

    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
        let _drop_context = set_async_context(cx);

        if let Err(err) = self.inner.shutdown() {
            match err.into_io_error() {
                Ok(err) => match err.kind() {
                    io::ErrorKind::WouldBlock => return Poll::Pending,
                    _ => return Poll::Ready(Err(err)),
                },
                Err(err) => {
                    return Poll::Ready(Err(io::Error::new(
                        io::ErrorKind::Other,
                        format!("TLS shutdown error: {}", err),
                    )));
                }
            }
        }

        let inner_stream = self.inner.get_mut();

        let inner = Pin::new(&mut inner_stream.inner);

        inner.poll_shutdown(cx)
    }
}

impl<S> From<SslStream<InnerSslStream<S>>> for TlsStream<S> {
    fn from(stream: SslStream<InnerSslStream<S>>) -> TlsStream<S> {
        TlsStream { inner: stream }
    }
}

/// Type alias.
type HandshakeResult<S> = Result<SslStream<InnerSslStream<S>>, HandshakeError<InnerSslStream<S>>>;

/// A pending TLS connection.
struct TlsConnect<S> {
    handshake: Option<HandshakeResult<S>>,
}

impl<S> Future for TlsConnect<S>
where
    S: AsyncRead + AsyncWrite + Unpin,
{
    type Output = Result<TlsStream<S>, TlsError>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        let _drop_context = set_async_context(cx);

        match self
            .handshake
            .take()
            .expect("the future has been already resolved")
        {
            Ok(stream) => Poll::Ready(Ok(stream.into())),
            Err(HandshakeError::SetupFailure(err)) => Poll::Ready(Err(TlsError::from(err))),
            Err(HandshakeError::Failure(m)) => Poll::Ready(Err(TlsError::from(m.into_error()))),
            Err(HandshakeError::WouldBlock(m)) => match m.handshake() {
                Ok(stream) => Poll::Ready(Ok(stream.into())),
                Err(HandshakeError::SetupFailure(err)) => Poll::Ready(Err(TlsError::from(err))),
                Err(HandshakeError::Failure(m)) => Poll::Ready(Err(TlsError::from(m.into_error()))),
                Err(HandshakeError::WouldBlock(m)) => {
                    self.handshake = Some(Err(HandshakeError::WouldBlock(m)));

                    Poll::Pending
                }
            },
        }
    }
}

/// Asynchronous TLS connector.
#[derive(Clone)]
pub struct TlsConnector {
    inner: SslConnector,
}

impl TlsConnector {
    /// Take a given asynchronous stream and perform a TLS handshake.
    pub async fn connect<T>(&self, addr: T) -> Result<TlsStream<TcpStream>, TlsError>
    where
        T: ToSocketAddrs,
    {
        let addrs = tokio::net::lookup_host(addr).await?.enumerate();

        let sockets = futures::stream::iter(addrs)
            .then(|(idx, addr)| async move {
                // wait 1s before we try to connect to the next address from
                // the list
                if idx > 0 {
                    tokio::time::sleep(Duration::from_secs(1)).await;
                }

                addr
            })
            .map(TcpStream::connect)
            .buffered(4)
            .filter_map(|res| futures::future::ready(res.ok()));

        futures::pin_mut!(sockets);

        let socket = sockets
            .next()
            .await
            .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "the server is unreachable"))?;

        let stream = InnerSslStream::new(socket);

        let configuration = self.inner.configure()?;

        let handshake = futures::future::lazy(move |cx| {
            let _drop_context = set_async_context(cx);

            // NOTE: We do not need to validate the server name because we use only one root
            // certificate. It's a self signed certificate issued directly by Angelcam and used
            // only for Arrow.
            configuration
                .verify_hostname(false)
                .connect("hostname", stream)
        });

        let handshake = handshake.await;

        let connect = TlsConnect {
            handshake: Some(handshake),
        };

        connect.await
    }
}

impl From<SslConnector> for TlsConnector {
    fn from(connector: SslConnector) -> Self {
        Self { inner: connector }
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ffi::{CString, CStr};
use std::mem;
use libc;

pub struct DiskStat {
    pub capacity: u64,
    pub available: u64,
}

// Get the disk stats for path belongs.
// TODO: define own Error type instead of string.
pub fn get_disk_stat(path: &str) -> Result<DiskStat, String> {
    let cpath = CString::new(path).unwrap();
    unsafe {
        let mut stat: libc::statfs = mem::zeroed();
        let ret = libc::statfs(cpath.as_ptr(), &mut stat);
        if ret != 0 {
            return Err(format!("get stats for {} failed {}",
                               path,
                               CStr::from_ptr(libc::strerror(ret)).to_str().unwrap()));
        }

        Ok(DiskStat {
            capacity: (stat.f_bsize as u64 * stat.f_blocks) as u64,
            available: (stat.f_bsize as u64 * stat.f_bfree) as u64,
        })
    }
}

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Write;

    use tempdir::TempDir;

    use super::*;

    fn create_size_file(dir: &str, name: &str, size: usize) {
        let mut f = File::create(&format!("{}/{}", dir, name)).unwrap();
        let data = vec![0;size];
        f.write_all(&data).unwrap();
    }

    #[test]
    fn test_get_disk_stat() {
        let temp_dir = TempDir::new("var").unwrap();
        let dir = temp_dir.path().to_str().unwrap();

        let s1 = get_disk_stat(dir).unwrap();

        create_size_file(dir, "1.log", 1000);
        let s2 = get_disk_stat(dir).unwrap();

        assert_eq!(s2.capacity, s1.capacity);
        assert!(s2.available < s1.available);
    }
}
<commit_msg>test: only check disk stats change instead (#684)<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ffi::{CString, CStr};
use std::mem;
use libc;

pub struct DiskStat {
    pub capacity: u64,
    pub available: u64,
}

// Get the disk stats for path belongs.
// TODO: define own Error type instead of string.
pub fn get_disk_stat(path: &str) -> Result<DiskStat, String> {
    let cpath = CString::new(path).unwrap();
    unsafe {
        let mut stat: libc::statfs = mem::zeroed();
        let ret = libc::statfs(cpath.as_ptr(), &mut stat);
        if ret != 0 {
            return Err(format!("get stats for {} failed {}",
                               path,
                               CStr::from_ptr(libc::strerror(ret)).to_str().unwrap()));
        }

        Ok(DiskStat {
            capacity: (stat.f_bsize as u64 * stat.f_blocks) as u64,
            available: (stat.f_bsize as u64 * stat.f_bfree) as u64,
        })
    }
}

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Write;

    use tempdir::TempDir;

    use super::*;

    fn create_size_file(dir: &str, name: &str, size: usize) {
        let mut f = File::create(&format!("{}/{}", dir, name)).unwrap();
        let data = vec![0;size];
        f.write_all(&data).unwrap();
    }

    #[test]
    fn test_get_disk_stat() {
        let temp_dir = TempDir::new("var").unwrap();
        let dir = temp_dir.path().to_str().unwrap();

        let s1 = get_disk_stat(dir).unwrap();

        let cnt = 100;
        for i in 0..cnt {
            create_size_file(dir, &format!("{}.log", i), 1000);
            let s2 = get_disk_stat(dir).unwrap();
            assert_eq!(s2.capacity, s1.capacity);

            if s2.available != s1.available {
                return;
            }
        }

        panic!("available not changed after {} tries.", cnt);
    }
}
<|endoftext|>


<commit_before>extern crate xmltree;

use xmltree::Element;
use xmltree::ParseError;
use std::fs::File;
use std::io::Cursor;

#[test]
fn test_01() {
    let e: Element = Element::parse(File::open("tests/data/01.xml").unwrap()).unwrap();
    println!("E:=======\n{:#?}", e);
    assert_eq!(e.name, "project");
    let e2: &Element = e.get_child("libraries").expect("Missing libraries child element");
    assert_eq!(e2.name, "libraries");

    assert!(e.get_child("doesnotexist").is_none());

    let mut buf = Vec::new();
    e.write(&mut buf);

    let e2 = Element::parse(Cursor::new(buf)).unwrap();
    println!("E2:======\n{:#?}", e2);

    assert_eq!(e, e2);
}

#[test]
fn test_02() {
    let e: Element = Element::parse(File::open("tests/data/02.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_03() {
    let e: Element = Element::parse(File::open("tests/data/03.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_04() {
    let e: Element = Element::parse(File::open("tests/data/04.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_rw() {

    let e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();

    let mut buf = Vec::new();
    e.write(&mut buf);

    let e2 = Element::parse(Cursor::new(buf)).unwrap();

    assert_eq!(e, e2);
}

#[test]
fn test_mut() {

    let mut e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();
    {
        let name = e.get_mut_child("name").unwrap();
        name.attributes.insert("suffix".to_owned(), "mr".to_owned());
    }
}

#[test]
fn test_mal_01() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones />
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_02() {
    // some tests for error handling

    let data = r##"
            this is not even close
            to XML
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_03() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></badtag>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_new() {
    let e = Element::new("foo");
    assert_eq!(e.name.as_str(), "foo");
    assert_eq!(e.attributes.len(), 0);
    assert_eq!(e.children.len(), 0);
    assert_eq!(e.text, None);
}

#[test]
fn test_take() {
    let data_xml_1 = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></name>
            <name first="elizabeth" last="smith" />
            <remove_me key="value">
                <child />
            </remove_me>
        </names>
    "##;

    let data_xml_2 = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></name>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let mut data_1 = Element::parse(data_xml_1.as_bytes()).unwrap();
    let data_2 = Element::parse(data_xml_2.as_bytes()).unwrap();

    if let Some(removed) = data_1.take_child("remove_me") {
        assert_eq!(removed.children.len(), 1);

    } else {
        panic!("take_child failed");
    }

    assert_eq!(data_1, data_2);
}

#[test]
fn test_ns_rw() {
    {
        let e: Element = Element::parse(File::open("tests/data/ns1.xml").unwrap()).unwrap();

        let mut buf = Vec::new();
        e.write(&mut buf);

        let e2 = Element::parse(Cursor::new(buf)).unwrap();

        assert_eq!(e, e2);
    }
    {
        let e: Element = Element::parse(File::open("tests/data/ns2.xml").unwrap()).unwrap();

        let mut buf = Vec::new();
        e.write(&mut buf);

        let e2 = Element::parse(Cursor::new(buf)).unwrap();

        assert_eq!(e, e2);
    }
}
<commit_msg>New very basic test for write_with_config<commit_after>extern crate xmltree;

use xmltree::*;
use std::fs::File;
use std::io::Cursor;

#[test]
fn test_01() {
    let e: Element = Element::parse(File::open("tests/data/01.xml").unwrap()).unwrap();
    println!("E:=======\n{:#?}", e);
    assert_eq!(e.name, "project");
    let e2: &Element = e.get_child("libraries").expect("Missing libraries child element");
    assert_eq!(e2.name, "libraries");

    assert!(e.get_child("doesnotexist").is_none());

    let mut buf = Vec::new();
    e.write(&mut buf);

    let e2 = Element::parse(Cursor::new(buf)).unwrap();
    println!("E2:======\n{:#?}", e2);

    assert_eq!(e, e2);
}

#[test]
fn test_02() {
    let e: Element = Element::parse(File::open("tests/data/02.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_03() {
    let e: Element = Element::parse(File::open("tests/data/03.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_04() {
    let e: Element = Element::parse(File::open("tests/data/04.xml").unwrap()).unwrap();
    println!("{:#?}", e);
}

#[test]
fn test_rw() {

    let e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();

    let mut buf = Vec::new();
    e.write(&mut buf);

    let e2 = Element::parse(Cursor::new(buf)).unwrap();

    assert_eq!(e, e2);
}

#[test]
fn test_mut() {

    let mut e: Element = Element::parse(File::open("tests/data/rw.xml").unwrap()).unwrap();
    {
        let name = e.get_mut_child("name").unwrap();
        name.attributes.insert("suffix".to_owned(), "mr".to_owned());
    }
}

#[test]
fn test_mal_01() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones />
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_02() {
    // some tests for error handling

    let data = r##"
            this is not even close
            to XML
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_mal_03() {
    // some tests for error handling

    let data = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></badtag>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let names_element = Element::parse(data.as_bytes());
    if let Err(ParseError::MalformedXml(..)) = names_element {
        // OK
    } else {
        panic!("unexpected parse result");
    }
    println!("{:?}", names_element);

}

#[test]
fn test_new() {
    let e = Element::new("foo");
    assert_eq!(e.name.as_str(), "foo");
    assert_eq!(e.attributes.len(), 0);
    assert_eq!(e.children.len(), 0);
    assert_eq!(e.text, None);
}

#[test]
fn test_take() {
    let data_xml_1 = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></name>
            <name first="elizabeth" last="smith" />
            <remove_me key="value">
                <child />
            </remove_me>
        </names>
    "##;

    let data_xml_2 = r##"
        <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <names>
            <name first="bob" last="jones"></name>
            <name first="elizabeth" last="smith" />
        </names>
    "##;

    let mut data_1 = Element::parse(data_xml_1.as_bytes()).unwrap();
    let data_2 = Element::parse(data_xml_2.as_bytes()).unwrap();

    if let Some(removed) = data_1.take_child("remove_me") {
        assert_eq!(removed.children.len(), 1);

    } else {
        panic!("take_child failed");
    }

    assert_eq!(data_1, data_2);
}

#[test]
fn test_ns_rw() {
    {
        let e: Element = Element::parse(File::open("tests/data/ns1.xml").unwrap()).unwrap();

        let mut buf = Vec::new();
        e.write(&mut buf);

        let e2 = Element::parse(Cursor::new(buf)).unwrap();

        assert_eq!(e, e2);
    }
    {
        let e: Element = Element::parse(File::open("tests/data/ns2.xml").unwrap()).unwrap();

        let mut buf = Vec::new();
        e.write(&mut buf);

        let e2 = Element::parse(Cursor::new(buf)).unwrap();

        assert_eq!(e, e2);
    }
}

#[test]
fn test_write_with_config() {
    let e: Element = Element::parse(File::open("tests/data/01.xml").unwrap()).unwrap();

    let cfg = EmitterConfig {
        perform_indent: true,
        .. EmitterConfig::default()
    };

    let mut buf = Vec::new();
    e.write_with_config(&mut buf, cfg);

    let s = String::from_utf8(buf).unwrap();
    println!("{}", s);

}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::ffi::CStr;
use gl;

/// Describes a version.
///
/// A version can only be compared to another version if they belong to the same API.
/// For example, both `Version(Gl, 3, 0) >= Version(GlEs, 3, 0)` and `Version(GlEs, 3, 0) >=
/// Version(Gl, 3, 0)` return `false`.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Version(pub Api, pub u8, pub u8);

/// Describes an OpenGL-related API.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Api {
    /// Regular OpenGL.
    Gl,
    /// OpenGL embedded system.
    GlEs,
}

impl PartialOrd for Version {
    #[inline]
    fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
        if self.0 != other.0 {
            return None;
        }

        match self.1.cmp(&other.1) {
            Ordering::Equal => Some(self.2.cmp(&other.2)),
            a => Some(a)
        }
    }
}

/// Obtains the OpenGL version of the current context using the loaded functions.
///
/// # Unsafe
///
/// You must ensure that the functions belong to the current context, otherwise you will get
/// an undefined behavior.
pub unsafe fn get_gl_version(gl: &gl::Gl) -> Version {
    let version = gl.GetString(gl::VERSION) as *const i8;
    let version = String::from_utf8(CStr::from_ptr(version).to_bytes().to_vec()).unwrap();

    let (version, api) = if version.starts_with("OpenGL ES ") {
        (&version[10..], Api::GlEs)
    } else if version.starts_with("OpenGL ES-") {
        (&version[13..], Api::GlEs)
    } else {
        (&version[..], Api::Gl)
    };

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

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

    Version(
        api,
        major.parse().ok().expect("failed to parse GL major version"),
        minor.parse().ok().expect("failed to parse GL minor version"),
    )
}

/// Given an API version, this function returns the GLSL version that the implementation is
/// required to support.
///
/// # Panic
///
/// Panics if the version is invalid or is not supposed to support a GLSL version.
pub fn get_supported_glsl_version(gl_version: &Version) -> Version {
    match gl_version.0 {
        Api::Gl => {
            // since OpenGL 3.3: glsl versions match gl version, just return a copy
            if *gl_version >= Version(gl_version.0, 3, 3) {
                return *gl_version;
            }

            // match to detect invalid versions
            match *gl_version {
                Version(a, 2, 0) => Version(a, 1, 1),
                Version(a, 2, 1) => Version(a, 1, 2),
                Version(a, 3, 0) => Version(a, 1, 3),
                Version(a, 3, 1) => Version(a, 1, 4),
                Version(a, 3, 2) => Version(a, 1, 5),
                _ => panic!("no corresponding glsl version exists")
            }
        },
        Api::GlEs => {
            // since OpenGL ES 3.0: glsl versions match gl version, just return a copy
            if *gl_version >= Version(gl_version.0, 3, 0) {
                return *gl_version;
            }

            // only other valid GLES version is 2.0
            if *gl_version == Version(gl_version.0, 2, 0){
                return Version(Api::GlEs, 1, 0);
            } else {
                panic!("no corresponding glsl version exists")
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Version, Api, get_supported_glsl_version};

    macro_rules! assert_versions {
        ( $api:path, $gl_major:expr, $gl_minor:expr => $glsl_major:expr, $glsl_minor:expr) => {
            assert_eq!(
                get_supported_glsl_version(&Version($api, $gl_major, $gl_minor)),
                Version($api, $glsl_major, $glsl_minor)
                    );
        }
    }

    #[test]
    fn valid_gl_versions() {
        // irregular versions
        assert_versions!(Api::Gl, 2, 0 => 1, 1);
        assert_versions!(Api::Gl, 2, 1 => 1, 2);
        assert_versions!(Api::Gl, 3, 0 => 1, 3);
        assert_versions!(Api::Gl, 3, 1 => 1, 4);
        assert_versions!(Api::Gl, 3, 2 => 1, 5);

        // test a few regular versions
        assert_versions!(Api::Gl, 3, 3 => 3, 3);
        assert_versions!(Api::Gl, 4, 0 => 4, 0);
        assert_versions!(Api::Gl, 4, 5 => 4, 5);
    }

    #[test]
    fn valid_gles_versions() {
        // only irregular version
        assert_versions!(Api::GlEs, 2, 0 => 1, 0);

        // some regular versions
        assert_versions!(Api::GlEs, 3, 0 => 3, 0);
        assert_versions!(Api::GlEs, 3, 1 => 3, 1);
    }

    #[test]
    #[should_panic]
    fn invalid_gl_version() {
        get_supported_glsl_version(&Version(Api::Gl, 1, 0));
    }

    #[test]
    #[should_panic]
    fn invalid_gles_version() {
        get_supported_glsl_version(&Version(Api::GlEs, 1, 0));
    }
}
<commit_msg>Mock WebGL as OpenGL ES 2.0<commit_after>use std::cmp::Ordering;
use std::ffi::CStr;
use gl;

/// Describes a version.
///
/// A version can only be compared to another version if they belong to the same API.
/// For example, both `Version(Gl, 3, 0) >= Version(GlEs, 3, 0)` and `Version(GlEs, 3, 0) >=
/// Version(Gl, 3, 0)` return `false`.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Version(pub Api, pub u8, pub u8);

/// Describes an OpenGL-related API.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Api {
    /// Regular OpenGL.
    Gl,
    /// OpenGL embedded system.
    GlEs,
}

impl PartialOrd for Version {
    #[inline]
    fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
        if self.0 != other.0 {
            return None;
        }

        match self.1.cmp(&other.1) {
            Ordering::Equal => Some(self.2.cmp(&other.2)),
            a => Some(a)
        }
    }
}

/// Obtains the OpenGL version of the current context using the loaded functions.
///
/// # Unsafe
///
/// You must ensure that the functions belong to the current context, otherwise you will get
/// an undefined behavior.
pub unsafe fn get_gl_version(gl: &gl::Gl) -> Version {
    let version = gl.GetString(gl::VERSION) as *const i8;
    let version = String::from_utf8(CStr::from_ptr(version).to_bytes().to_vec()).unwrap();

    // for the moment we mock WebGL as OpenGL ES 2.0
    // TODO: handle the differences between WebGL and OpenGL ES
    if version.starts_with("WebGL ") {
        return Version(Api::GlEs, 2, 0);
    }

    let (version, api) = if version.starts_with("OpenGL ES ") {
        (&version[10..], Api::GlEs)
    } else if version.starts_with("OpenGL ES-") {
        (&version[13..], Api::GlEs)
    } else {
        (&version[..], Api::Gl)
    };

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

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

    Version(
        api,
        major.parse().ok().expect("failed to parse GL major version"),
        minor.parse().ok().expect("failed to parse GL minor version"),
    )
}

/// Given an API version, this function returns the GLSL version that the implementation is
/// required to support.
///
/// # Panic
///
/// Panics if the version is invalid or is not supposed to support a GLSL version.
pub fn get_supported_glsl_version(gl_version: &Version) -> Version {
    match gl_version.0 {
        Api::Gl => {
            // since OpenGL 3.3: glsl versions match gl version, just return a copy
            if *gl_version >= Version(gl_version.0, 3, 3) {
                return *gl_version;
            }

            // match to detect invalid versions
            match *gl_version {
                Version(a, 2, 0) => Version(a, 1, 1),
                Version(a, 2, 1) => Version(a, 1, 2),
                Version(a, 3, 0) => Version(a, 1, 3),
                Version(a, 3, 1) => Version(a, 1, 4),
                Version(a, 3, 2) => Version(a, 1, 5),
                _ => panic!("no corresponding glsl version exists")
            }
        },
        Api::GlEs => {
            // since OpenGL ES 3.0: glsl versions match gl version, just return a copy
            if *gl_version >= Version(gl_version.0, 3, 0) {
                return *gl_version;
            }

            // only other valid GLES version is 2.0
            if *gl_version == Version(gl_version.0, 2, 0){
                return Version(Api::GlEs, 1, 0);
            } else {
                panic!("no corresponding glsl version exists")
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Version, Api, get_supported_glsl_version};

    macro_rules! assert_versions {
        ( $api:path, $gl_major:expr, $gl_minor:expr => $glsl_major:expr, $glsl_minor:expr) => {
            assert_eq!(
                get_supported_glsl_version(&Version($api, $gl_major, $gl_minor)),
                Version($api, $glsl_major, $glsl_minor)
                    );
        }
    }

    #[test]
    fn valid_gl_versions() {
        // irregular versions
        assert_versions!(Api::Gl, 2, 0 => 1, 1);
        assert_versions!(Api::Gl, 2, 1 => 1, 2);
        assert_versions!(Api::Gl, 3, 0 => 1, 3);
        assert_versions!(Api::Gl, 3, 1 => 1, 4);
        assert_versions!(Api::Gl, 3, 2 => 1, 5);

        // test a few regular versions
        assert_versions!(Api::Gl, 3, 3 => 3, 3);
        assert_versions!(Api::Gl, 4, 0 => 4, 0);
        assert_versions!(Api::Gl, 4, 5 => 4, 5);
    }

    #[test]
    fn valid_gles_versions() {
        // only irregular version
        assert_versions!(Api::GlEs, 2, 0 => 1, 0);

        // some regular versions
        assert_versions!(Api::GlEs, 3, 0 => 3, 0);
        assert_versions!(Api::GlEs, 3, 1 => 3, 1);
    }

    #[test]
    #[should_panic]
    fn invalid_gl_version() {
        get_supported_glsl_version(&Version(Api::Gl, 1, 0));
    }

    #[test]
    #[should_panic]
    fn invalid_gles_version() {
        get_supported_glsl_version(&Version(Api::GlEs, 1, 0));
    }
}
<|endoftext|>


<commit_before>#![crate_name = "uu_yes"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: yes (GNU coreutils) 8.13 */

extern crate getopts;

#[macro_use]
extern crate uucore;

use getopts::Options;
use std::io::Write;

static NAME: &'static str = "yes";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = Options::new();

    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "output version information and exit");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => crash!(1, "invalid options\n{}", f)
    };
    if matches.opt_present("help") {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [STRING]... [OPTION]...", NAME);
        println!("");
        print!("{}", opts.usage("Repeatedly output a line with all specified STRING(s), or 'y'."));
        return 0;
    }
    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }
    let string = if matches.free.is_empty() {
        "y".to_owned()
    } else {
        matches.free.join(" ")
    };

    exec(&string[..]);

    0
}

pub fn exec(string: &str) {
    while pipe_println!("{}", string) { }
}
<commit_msg>Make 'yes' 1000 times faster.<commit_after>#![crate_name = "uu_yes"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: yes (GNU coreutils) 8.13 */

extern crate getopts;

#[macro_use]
extern crate uucore;

use getopts::Options;
use std::io::Write;

static NAME: &'static str = "yes";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");

const BUF_SIZE: usize = 8192;

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = Options::new();

    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "output version information and exit");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => crash!(1, "invalid options\n{}", f)
    };
    if matches.opt_present("help") {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [STRING]... [OPTION]...", NAME);
        println!("");
        print!("{}", opts.usage("Repeatedly output a line with all specified STRING(s), or 'y'."));
        return 0;
    }
    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }
    let string = if matches.free.is_empty() {
        "y".to_owned()
    } else {
        matches.free.join(" ")
    };

    let mut multistring = string.clone();
    while multistring.len() < BUF_SIZE - string.len() - 1 {
        multistring.push_str("\n");
        multistring.push_str(&string);
    }

    exec(&multistring[..]);

    0
}

pub fn exec(string: &str) {
    while pipe_println!("{}", string) { }
}
<|endoftext|>


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

use std::default::Default;
use time;
use coordinates::LLA;

use ::ffipredict;
use ::tle;
use ::sat::Sat;
use ::julian_time::{julian_timestamp, julian_to_unix};

pub type Location = LLA;

#[derive(Debug)]
pub struct Predict {
    pub sat: Sat,

    p_sat: ffipredict::sat_t,
    p_qth: ffipredict::qth_t,
}

impl Predict {

    pub fn new<T: Into<LLA>>(tle: &tle::Tle, location: T) -> Predict {
        let tle_t = tle::create_tle_t(tle).unwrap();
        let location_lla: LLA = location.into();

        let sgps: ffipredict::sgpsdp_static_t = Default::default();
        let dps: ffipredict::deep_static_t = Default::default();
        let deep_arg: ffipredict::deep_arg_t = Default::default();
        let pos: ffipredict::vector_t = Default::default();
        let vel: ffipredict::vector_t = Default::default();

        let mut sat_t = ffipredict::sat_t{
            name: b"placeholder\0".as_ptr() as *const i8,
            nickname: b"placeholder\0".as_ptr() as *const i8,
            website: b"placeholder\0".as_ptr() as *const i8,
            tle: tle_t,
            flags: 0,
            sgps: sgps,
            dps: dps,
            deep_arg: deep_arg,
            pos: pos,
            vel: vel,

            jul_epoch: 0.0,
            jul_utc: 0.0,
            tsince: 0.0,
            aos: 0.0,
            los: 0.0,
            az: 0.0,
            el: 0.0,
            range: 0.0,
            range_rate: 0.0,
            ra: 0.0,
            dec: 0.0,
            ssplat: 0.0,
            ssplon: 0.0,
            alt: 0.0,
            velo: 0.0,
            ma: 0.0,
            footprint: 0.0,
            phase: 0.0,
            meanmo: 0.0,
            orbit: 0,
            otype: ffipredict::orbit_type_t::ORBIT_TYPE_UNKNOWN,
        };

        let sat: Sat = Default::default();
        let mut qth = ffipredict::qth_t {
            name: b"placeholder\0".as_ptr() as *const i8,
            loc: b"placeholder\0".as_ptr() as *const i8,
            desc: b"placeholder\0".as_ptr() as *const i8,
            lat: location_lla.lat_deg,
            lon: location_lla.lon_deg,
            alt: location_lla.alt_m as i32,
            qra: b"placeholder\0".as_ptr() as *const i8,
            wx: b"placeholder\0".as_ptr() as *const i8,
        };

        unsafe {ffipredict::select_ephemeris(&mut sat_t)};
        unsafe {ffipredict::gtk_sat_data_init_sat(&mut sat_t, &mut qth)};

        Predict{sat: sat, p_sat: sat_t, p_qth: qth}
    }

    pub fn update(&mut self, timeoption: Option<time::Tm>) {
        let juliantime = match timeoption {
            Some(t) => julian_timestamp(t),
            None => unsafe {ffipredict::get_current_daynum()}
        };

        // we do not have AOS with some satellites, therefore option is used
        let aos = match unsafe {ffipredict::find_aos(&mut self.p_sat, &mut self.p_qth, juliantime, 1.0)} {
            0.0 => None,
            aos => Some(julian_to_unix(aos)),
        };
        let los = match unsafe {ffipredict::find_los(&mut self.p_sat, &mut self.p_qth, juliantime, 1.0)} {
            0.0 => None,
            los => Some(julian_to_unix(los)),
        };

        unsafe {ffipredict::predict_calc(&mut self.p_sat, &mut self.p_qth, juliantime)};

        self.sat.aos                = aos;
        self.sat.los                = los;
        self.sat.az_deg             = self.p_sat.az;
        self.sat.el_deg             = self.p_sat.el;
        self.sat.range_km           = self.p_sat.range;
        self.sat.range_rate_km_sec  = self.p_sat.range_rate;
        self.sat.lat_deg            = self.p_sat.ssplat;
        self.sat.lon_deg            = self.p_sat.ssplon;
        self.sat.alt_km             = self.p_sat.alt;
        self.sat.vel_km_s           = self.p_sat.velo;
        self.sat.orbit_nr           = self.p_sat.orbit;
    }
}

#[test]
fn predict_location_formats() {
    use coordinates::ECEF;
    let tle = tle::Tle {
        name: "GRIFEX".to_string(),
        line1: "1 40379U 15003D   15243.42702278  .00003367  00000-0  17130-3 0  9993".to_string(),
        line2: "2 40379  99.1124 290.6779 0157088   8.9691 351.4280 15.07659299 31889".to_string()
    };
    let lla = LLA { lat_deg: 0.,
                    lon_deg: 0.,
                    alt_m:   0., };
    let ecef = ECEF { x: 0.,
                      y: 0.,
                      z: 0., };

    Predict::new(&tle, &lla);
    Predict::new(&tle, lla);
    Predict::new(&tle, &ecef);
    Predict::new(&tle, ecef);
}
<commit_msg>fix build for 32 bit machines<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Andres Vahter (andres.vahter@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

use std::default::Default;
use time;
use coordinates::LLA;

use ::ffipredict;
use ::tle;
use ::sat::Sat;
use ::julian_time::{julian_timestamp, julian_to_unix};

pub type Location = LLA;

#[derive(Debug)]
pub struct Predict {
    pub sat: Sat,

    p_sat: ffipredict::sat_t,
    p_qth: ffipredict::qth_t,
}

impl Predict {

    pub fn new<T: Into<LLA>>(tle: &tle::Tle, location: T) -> Predict {
        let tle_t = tle::create_tle_t(tle).unwrap();
        let location_lla: LLA = location.into();

        let sgps: ffipredict::sgpsdp_static_t = Default::default();
        let dps: ffipredict::deep_static_t = Default::default();
        let deep_arg: ffipredict::deep_arg_t = Default::default();
        let pos: ffipredict::vector_t = Default::default();
        let vel: ffipredict::vector_t = Default::default();

        let mut sat_t = ffipredict::sat_t{
            name: b"placeholder\0".as_ptr() as *const i8,
            nickname: b"placeholder\0".as_ptr() as *const i8,
            website: b"placeholder\0".as_ptr() as *const i8,
            tle: tle_t,
            flags: 0,
            sgps: sgps,
            dps: dps,
            deep_arg: deep_arg,
            pos: pos,
            vel: vel,

            jul_epoch: 0.0,
            jul_utc: 0.0,
            tsince: 0.0,
            aos: 0.0,
            los: 0.0,
            az: 0.0,
            el: 0.0,
            range: 0.0,
            range_rate: 0.0,
            ra: 0.0,
            dec: 0.0,
            ssplat: 0.0,
            ssplon: 0.0,
            alt: 0.0,
            velo: 0.0,
            ma: 0.0,
            footprint: 0.0,
            phase: 0.0,
            meanmo: 0.0,
            orbit: 0,
            otype: ffipredict::orbit_type_t::ORBIT_TYPE_UNKNOWN,
        };

        let sat: Sat = Default::default();
        let mut qth = ffipredict::qth_t {
            name: b"placeholder\0".as_ptr() as *const i8,
            loc: b"placeholder\0".as_ptr() as *const i8,
            desc: b"placeholder\0".as_ptr() as *const i8,
            lat: location_lla.lat_deg,
            lon: location_lla.lon_deg,
            alt: location_lla.alt_m as i32,
            qra: b"placeholder\0".as_ptr() as *const i8,
            wx: b"placeholder\0".as_ptr() as *const i8,
        };

        unsafe {ffipredict::select_ephemeris(&mut sat_t)};
        unsafe {ffipredict::gtk_sat_data_init_sat(&mut sat_t, &mut qth)};

        Predict{sat: sat, p_sat: sat_t, p_qth: qth}
    }

    pub fn update(&mut self, timeoption: Option<time::Tm>) {
        let juliantime = match timeoption {
            Some(t) => julian_timestamp(t),
            None => unsafe {ffipredict::get_current_daynum()}
        };

        // we do not have AOS with some satellites, therefore option is used
        let aos = match unsafe {ffipredict::find_aos(&mut self.p_sat, &mut self.p_qth, juliantime, 1.0)} {
            0.0 => None,
            aos => Some(julian_to_unix(aos)),
        };
        let los = match unsafe {ffipredict::find_los(&mut self.p_sat, &mut self.p_qth, juliantime, 1.0)} {
            0.0 => None,
            los => Some(julian_to_unix(los)),
        };

        unsafe {ffipredict::predict_calc(&mut self.p_sat, &mut self.p_qth, juliantime)};

        self.sat.aos                = aos;
        self.sat.los                = los;
        self.sat.az_deg             = self.p_sat.az;
        self.sat.el_deg             = self.p_sat.el;
        self.sat.range_km           = self.p_sat.range;
        self.sat.range_rate_km_sec  = self.p_sat.range_rate;
        self.sat.lat_deg            = self.p_sat.ssplat;
        self.sat.lon_deg            = self.p_sat.ssplon;
        self.sat.alt_km             = self.p_sat.alt;
        self.sat.vel_km_s           = self.p_sat.velo;
        self.sat.orbit_nr           = self.p_sat.orbit as u64;
    }
}

#[test]
fn predict_location_formats() {
    use coordinates::ECEF;
    let tle = tle::Tle {
        name: "GRIFEX".to_string(),
        line1: "1 40379U 15003D   15243.42702278  .00003367  00000-0  17130-3 0  9993".to_string(),
        line2: "2 40379  99.1124 290.6779 0157088   8.9691 351.4280 15.07659299 31889".to_string()
    };
    let lla = LLA { lat_deg: 0.,
                    lon_deg: 0.,
                    alt_m:   0., };
    let ecef = ECEF { x: 0.,
                      y: 0.,
                      z: 0., };

    Predict::new(&tle, &lla);
    Predict::new(&tle, lla);
    Predict::new(&tle, &ecef);
    Predict::new(&tle, ecef);
}
<|endoftext|>


<commit_before>use libc;

extern {
    #[cfg(test)]
    fn highbd_dc_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_dc_left_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_dc_top_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    #[cfg(test)]
    fn highbd_h_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);

    #[cfg(test)]
    fn highbd_v_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
        bh: libc::c_int, above: *const u16,
        left: *const u16, bd: libc::c_int);
}

pub fn pred_dc_128(output: &mut [u16], stride: usize) {
    for y in 0..4 {
        for x in 0..4 {
            output[y*stride+x] = 128;
        }
    }
}

pub fn pred_dc_left_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_dc_left_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

pub fn pred_dc_top_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_dc_top_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

pub fn pred_dc(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    let edges = left.iter().chain(above.iter());
    let bw = above.len();
    let bh = left.len();
    let len = (bw + bh) as u32;
    let avg = (edges.fold(0, |acc, &v| acc + v as u32) + (len >> 1)) / len;

    for line in output.chunks_mut(stride).take(bh) {
        for v in &mut line[..bw] {
            *v = avg as u16;
        }
    }
}

pub trait Dim {
    const W : usize;
    const H : usize;
}

pub struct Block4x4;

impl Dim for Block4x4 {
    const W : usize = 4;
    const H : usize = 4;
}

pub fn pred_dc_trait<D: Dim>(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    let edges = left.iter().chain(above.iter());
    let bw = D::W;
    let bh = D::H;
    let len = (bw + bh) as u32;
    let avg = (edges.fold(0, |acc, &v| acc + v as u32) + (len >> 1)) / len;

    for line in output.chunks_mut(stride).take(bh) {
        for v in &mut line[..bw] {
            *v = avg as u16;
        }
    }
}

pub fn pred_h(output: &mut [u16], stride: usize, left: &[u16], bw: usize) {
  for (line, l) in output.chunks_mut(stride).zip(left) {
    for v in &mut line[..bw] {
      *v = *l;
    }
  }
}

pub fn pred_v(output: &mut [u16], stride: usize, above: &[u16], bh: usize) {
    let bw = above.len();
    for line in output.chunks_mut(stride).take(bh) {
        line[..bw].clone_from_slice(above)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rand::{ChaChaRng, Rng};
    use test::Bencher;

    const MAX_ITER: usize = 50000;

    fn setup_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>, Vec<u16>, Vec<u16>) {
        let output = vec![0u16; 32 * 32];
        let above: Vec<u16> = (0..32).map(|_| ra.gen()).collect();
        let left: Vec<u16> = (0..32).map(|_| ra.gen()).collect();

        let o1 = output.clone();
        let o2 = output.clone();

        (above, left, o1, o2)
    }

    fn pred_dc_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
        unsafe {
            highbd_dc_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
        }
    }

    pub fn pred_h_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
        unsafe {
            highbd_h_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
        }
    }

    pub fn pred_v_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
        unsafe {
            highbd_v_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
        }
    }

    fn do_dc_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>) {
        let (above, left, mut o1, mut o2) = setup_pred(ra);

        pred_dc_4x4(&mut o1, 32, &above[..4], &left[..4]);
        pred_dc(&mut o2, 32, &above[..4], &left[..4]);

        (o1, o2)
    }

    fn do_h_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>) {
        let (above, left, mut o1, mut o2) = setup_pred(ra);

        pred_h_4x4(&mut o1, 32, &above[..4], &left[..4]);
        pred_h(&mut o2, 32, &left[..4], 4);

        (o1, o2)
    }

    fn do_v_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>) {
        let (above, left, mut o1, mut o2) = setup_pred(ra);

        pred_v_4x4(&mut o1, 32, &above[..4], &left[..4]);
        pred_v(&mut o2, 32, &above[..4], 4);

        (o1, o2)
    }

    fn assert_same(o2: Vec<u16>) {
        for l in o2.chunks(32).take(4) {
            for v in l[..4].windows(2) {
                assert_eq!(v[0], v[1]);
            }
        }
    }

    #[test]
    fn pred_matches() {
        let mut ra = ChaChaRng::new_unseeded();
        for _ in 0..MAX_ITER {
            let (o1, o2) = do_dc_pred(&mut ra);
            assert_eq!(o1, o2);

            let (o1, o2) = do_h_pred(&mut ra);
            assert_eq!(o1, o2);

            let (o1, o2) = do_v_pred(&mut ra);
            assert_eq!(o1, o2);
        }
    }

    #[test]
    fn pred_same() {
        let mut ra = ChaChaRng::new_unseeded();
        for _ in 0..MAX_ITER {
            let (_, o2) = do_dc_pred(&mut ra);

            assert_same(o2)
        }
    }

    #[test]
    fn pred_max() {
        let max12bit = 4096 - 1;
        let above = [max12bit; 32];
        let left = [max12bit; 32];

        let mut o = vec![0u16; 32 * 32];

        pred_dc(&mut o, 32, &above[..4], &left[..4]);

        for l in o.chunks(32).take(4) {
            for v in l[..4].iter() {
                assert_eq!(*v, max12bit);
            }
        }

        pred_h(&mut o, 32, &left[..4], 4);

        for l in o.chunks(32).take(4) {
          for v in l[..4].iter() {
            assert_eq!(*v, max12bit);
          }
        }

        pred_v(&mut o, 32, &above[..4], 4);

        for l in o.chunks(32).take(4) {
          for v in l[..4].iter() {
            assert_eq!(*v, max12bit);
          }
        }
    }

    #[bench]
    fn native(b: &mut Bencher) {
        let mut ra = ChaChaRng::new_unseeded();
        let (above, left, _, mut o2) = setup_pred(&mut ra);

        b.iter(|| {
            for _ in 0..MAX_ITER {
                pred_dc(&mut o2, 32, &above[..4], &left[..4]);
            }
        })
    }

    #[bench]
    fn native_trait(b: &mut Bencher) {
        let mut ra = ChaChaRng::new_unseeded();
        let (above, left, _, mut o2) = setup_pred(&mut ra);

        b.iter(|| {
            for _ in 0..MAX_ITER {
                pred_dc_trait::<Block4x4>(&mut o2, 32, &above[..4], &left[..4]);
            }
        })
    }

    #[bench]
    fn aom(b: &mut Bencher) {
        let mut ra = ChaChaRng::new_unseeded();
        let (above, left, _, mut o2) = setup_pred(&mut ra);

        b.iter(|| {
            for _ in 0..MAX_ITER {
                pred_dc_4x4(&mut o2, 32, &above[..4], &left[..4]);
            }
        })
    }
}
<commit_msg>test the block-specific version<commit_after>use libc;

extern {
    #[cfg(test)]
    fn highbd_dc_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_dc_left_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_dc_top_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    #[cfg(test)]
    fn highbd_h_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);

    #[cfg(test)]
    fn highbd_v_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
        bh: libc::c_int, above: *const u16,
        left: *const u16, bd: libc::c_int);
}

pub fn pred_dc_128(output: &mut [u16], stride: usize) {
    for y in 0..4 {
        for x in 0..4 {
            output[y*stride+x] = 128;
        }
    }
}

pub fn pred_dc_left_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_dc_left_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

pub fn pred_dc_top_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_dc_top_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

pub fn pred_dc(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    let edges = left.iter().chain(above.iter());
    let bw = above.len();
    let bh = left.len();
    let len = (bw + bh) as u32;
    let avg = (edges.fold(0, |acc, &v| acc + v as u32) + (len >> 1)) / len;

    for line in output.chunks_mut(stride).take(bh) {
        for v in &mut line[..bw] {
            *v = avg as u16;
        }
    }
}

pub trait Dim {
    const W : usize;
    const H : usize;
}

pub struct Block4x4;

impl Dim for Block4x4 {
    const W : usize = 4;
    const H : usize = 4;
}

pub fn pred_dc_trait<D: Dim>(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    let edges = left.iter().chain(above.iter());
    let bw = D::W;
    let bh = D::H;
    let len = (bw + bh) as u32;
    let avg = (edges.fold(0, |acc, &v| acc + v as u32) + (len >> 1)) / len;

    for line in output.chunks_mut(stride).take(bh) {
        for v in &mut line[..bw] {
            *v = avg as u16;
        }
    }
}

pub fn pred_h(output: &mut [u16], stride: usize, left: &[u16], bw: usize) {
  for (line, l) in output.chunks_mut(stride).zip(left) {
    for v in &mut line[..bw] {
      *v = *l;
    }
  }
}

pub fn pred_v(output: &mut [u16], stride: usize, above: &[u16], bh: usize) {
    let bw = above.len();
    for line in output.chunks_mut(stride).take(bh) {
        line[..bw].clone_from_slice(above)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rand::{ChaChaRng, Rng};
    use test::Bencher;

    const MAX_ITER: usize = 50000;

    fn setup_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>, Vec<u16>, Vec<u16>) {
        let output = vec![0u16; 32 * 32];
        let above: Vec<u16> = (0..32).map(|_| ra.gen()).collect();
        let left: Vec<u16> = (0..32).map(|_| ra.gen()).collect();

        let o1 = output.clone();
        let o2 = output.clone();

        (above, left, o1, o2)
    }

    fn pred_dc_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
        unsafe {
            highbd_dc_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
        }
    }

    pub fn pred_h_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
        unsafe {
            highbd_h_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
        }
    }

    pub fn pred_v_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
        unsafe {
            highbd_v_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
        }
    }

    fn do_dc_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>) {
        let (above, left, mut o1, mut o2) = setup_pred(ra);

        pred_dc_4x4(&mut o1, 32, &above[..4], &left[..4]);
        pred_dc_trait::<Block4x4>(&mut o2, 32, &above[..4], &left[..4]);

        (o1, o2)
    }

    fn do_h_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>) {
        let (above, left, mut o1, mut o2) = setup_pred(ra);

        pred_h_4x4(&mut o1, 32, &above[..4], &left[..4]);
        pred_h(&mut o2, 32, &left[..4], 4);

        (o1, o2)
    }

    fn do_v_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>) {
        let (above, left, mut o1, mut o2) = setup_pred(ra);

        pred_v_4x4(&mut o1, 32, &above[..4], &left[..4]);
        pred_v(&mut o2, 32, &above[..4], 4);

        (o1, o2)
    }

    fn assert_same(o2: Vec<u16>) {
        for l in o2.chunks(32).take(4) {
            for v in l[..4].windows(2) {
                assert_eq!(v[0], v[1]);
            }
        }
    }

    #[test]
    fn pred_matches() {
        let mut ra = ChaChaRng::new_unseeded();
        for _ in 0..MAX_ITER {
            let (o1, o2) = do_dc_pred(&mut ra);
            assert_eq!(o1, o2);

            let (o1, o2) = do_h_pred(&mut ra);
            assert_eq!(o1, o2);

            let (o1, o2) = do_v_pred(&mut ra);
            assert_eq!(o1, o2);
        }
    }

    #[test]
    fn pred_same() {
        let mut ra = ChaChaRng::new_unseeded();
        for _ in 0..MAX_ITER {
            let (_, o2) = do_dc_pred(&mut ra);

            assert_same(o2)
        }
    }

    #[test]
    fn pred_max() {
        let max12bit = 4096 - 1;
        let above = [max12bit; 32];
        let left = [max12bit; 32];

        let mut o = vec![0u16; 32 * 32];

        pred_dc(&mut o, 32, &above[..4], &left[..4]);

        for l in o.chunks(32).take(4) {
            for v in l[..4].iter() {
                assert_eq!(*v, max12bit);
            }
        }

        pred_h(&mut o, 32, &left[..4], 4);

        for l in o.chunks(32).take(4) {
          for v in l[..4].iter() {
            assert_eq!(*v, max12bit);
          }
        }

        pred_v(&mut o, 32, &above[..4], 4);

        for l in o.chunks(32).take(4) {
          for v in l[..4].iter() {
            assert_eq!(*v, max12bit);
          }
        }
    }

    #[bench]
    fn native(b: &mut Bencher) {
        let mut ra = ChaChaRng::new_unseeded();
        let (above, left, _, mut o2) = setup_pred(&mut ra);

        b.iter(|| {
            for _ in 0..MAX_ITER {
                pred_dc(&mut o2, 32, &above[..4], &left[..4]);
            }
        })
    }

    #[bench]
    fn native_trait(b: &mut Bencher) {
        let mut ra = ChaChaRng::new_unseeded();
        let (above, left, _, mut o2) = setup_pred(&mut ra);

        b.iter(|| {
            for _ in 0..MAX_ITER {
                pred_dc_trait::<Block4x4>(&mut o2, 32, &above[..4], &left[..4]);
            }
        })
    }

    #[bench]
    fn aom(b: &mut Bencher) {
        let mut ra = ChaChaRng::new_unseeded();
        let (above, left, _, mut o2) = setup_pred(&mut ra);

        b.iter(|| {
            for _ in 0..MAX_ITER {
                pred_dc_4x4(&mut o2, 32, &above[..4], &left[..4]);
            }
        })
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::process::Command;
use std::path::PathBuf;

fn get_bin_dir() -> PathBuf {
    env::current_exe()
        .expect("test bin's directory")
        .parent()
        .expect("test bin's parent directory")
        .parent()
        .expect("executable's directory")
        .to_path_buf()
}

fn cmd_aux2bib() -> Command {
    let path;
    if cfg!(not(windows)) {
        path = get_bin_dir().join("aux2bib");
    } else {
        path = get_bin_dir().join("aux2bib.exe");
    }
    if !path.is_file() {
        panic!("aux2bib binary {:?} was not found", path);
    }
    println!("{:?}", path);
    let mut cmd = Command::new(path);
    cmd.env_clear();

    cmd
}

fn cmd_blg2bib() -> Command {
    let path;
    if cfg!(not(windows)) {
        path = get_bin_dir().join("blg2bib");
    } else {
        path = get_bin_dir().join("blg2bib.exe");
    }
    if !path.is_file() {
        panic!("blg2bib binary {:?} was not found", path);
    }
    let mut cmd = Command::new(path);
    cmd.env_clear();

    cmd
}

#[test]
fn aux2bib_runs() {
    let mut cmd = cmd_aux2bib().arg("--help").spawn().expect(
        "Failed to execute aux2bib",
    );

    let error_code = cmd.wait().expect("Failed to wait on aux2bib");

    assert!(error_code.success());

}

#[test]
fn blg2bib_runs() {
    let mut cmd = cmd_blg2bib().arg("--help").spawn().expect(
        "Failed to execute blg2bib",
    );

    let error_code = cmd.wait().expect("Failed to wait on blg2bib");

    assert!(error_code.success());

}
<commit_msg>test: Don't test binaries on windows<commit_after>use std::env;
use std::process::Command;
use std::path::PathBuf;

fn get_bin_dir() -> PathBuf {
    env::current_exe()
        .expect("test bin's directory")
        .parent()
        .expect("test bin's parent directory")
        .parent()
        .expect("executable's directory")
        .to_path_buf()
}

fn cmd_aux2bib() -> Command {
    let path;
    if cfg!(not(windows)) {
        path = get_bin_dir().join("aux2bib");
    } else {
        path = get_bin_dir().join("aux2bib.exe");
    }
    if !path.is_file() {
        panic!("aux2bib binary {:?} was not found", path);
    }
    println!("{:?}", path);
    let mut cmd = Command::new(path);
    cmd.env_clear();

    cmd
}

fn cmd_blg2bib() -> Command {
    let path;
    if cfg!(not(windows)) {
        path = get_bin_dir().join("blg2bib");
    } else {
        path = get_bin_dir().join("blg2bib.exe");
    }
    if !path.is_file() {
        panic!("blg2bib binary {:?} was not found", path);
    }
    let mut cmd = Command::new(path);
    cmd.env_clear();

    cmd
}

#[cfg(not(windows))]
#[test]
fn aux2bib_runs() {
    let mut cmd = cmd_aux2bib().arg("--help").spawn().expect(
        "Failed to execute aux2bib",
    );

    let error_code = cmd.wait().expect("Failed to wait on aux2bib");

    assert!(error_code.success());

}

#[cfg(not(windows))]
#[test]
fn blg2bib_runs() {
    let mut cmd = cmd_blg2bib().arg("--help").spawn().expect(
        "Failed to execute blg2bib",
    );

    let error_code = cmd.wait().expect("Failed to wait on blg2bib");

    assert!(error_code.success());

}
<|endoftext|>