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

use clone::Clone;
use cmp;
use collections::Collection;
use comm::{Sender, Receiver};
use io;
use option::{None, Option, Some};
use result::{Ok, Err};
use slice::{bytes, CloneableVector};
use super::{Reader, Writer, IoResult};
use vec::Vec;

/// Allows reading from a rx.
///
/// # Example
///
/// ```
/// use std::io::ChanReader;
///
/// let (tx, rx) = channel();
/// # drop(tx);
/// let mut reader = ChanReader::new(rx);
///
/// let mut buf = [0u8, ..100];
/// match reader.read(buf) {
///     Ok(nread) => println!("Read {} bytes", nread),
///     Err(e) => println!("read error: {}", e),
/// }
/// ```
pub struct ChanReader {
    buf: Option<Vec<u8>>,  // A buffer of bytes received but not consumed.
    pos: uint,             // How many of the buffered bytes have already be consumed.
    rx: Receiver<Vec<u8>>, // The Receiver to pull data from.
    closed: bool,          // Whether the channel this Receiver connects to has been closed.
}

impl ChanReader {
    /// Wraps a `Port` in a `ChanReader` structure
    pub fn new(rx: Receiver<Vec<u8>>) -> ChanReader {
        ChanReader {
            buf: None,
            pos: 0,
            rx: rx,
            closed: false,
        }
    }
}

impl Reader for ChanReader {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        let mut num_read = 0;
        loop {
            match self.buf {
                Some(ref prev) => {
                    let dst = buf[mut num_read..];
                    let src = prev[self.pos..];
                    let count = cmp::min(dst.len(), src.len());
                    bytes::copy_memory(dst, src[..count]);
                    num_read += count;
                    self.pos += count;
                },
                None => (),
            };
            if num_read == buf.len() || self.closed {
                break;
            }
            self.pos = 0;
            self.buf = self.rx.recv_opt().ok();
            self.closed = self.buf.is_none();
        }
        if self.closed && num_read == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(num_read)
        }
    }
}

/// Allows writing to a tx.
///
/// # Example
///
/// ```
/// # #![allow(unused_must_use)]
/// use std::io::ChanWriter;
///
/// let (tx, rx) = channel();
/// # drop(rx);
/// let mut writer = ChanWriter::new(tx);
/// writer.write("hello, world".as_bytes());
/// ```
pub struct ChanWriter {
    tx: Sender<Vec<u8>>,
}

impl ChanWriter {
    /// Wraps a channel in a `ChanWriter` structure
    pub fn new(tx: Sender<Vec<u8>>) -> ChanWriter {
        ChanWriter { tx: tx }
    }
}

impl Clone for ChanWriter {
    fn clone(&self) -> ChanWriter {
        ChanWriter { tx: self.tx.clone() }
    }
}

impl Writer for ChanWriter {
    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
        self.tx.send_opt(buf.to_vec()).map_err(|_| {
            io::IoError {
                kind: io::BrokenPipe,
                desc: "Pipe closed",
                detail: None
            }
        })
    }
}

#[cfg(test)]
mod test {
    use prelude::*;
    use super::*;
    use io;
    use task;

    #[test]
    fn test_rx_reader() {
        let (tx, rx) = channel();
        task::spawn(proc() {
          tx.send(vec![1u8, 2u8]);
          tx.send(vec![]);
          tx.send(vec![3u8, 4u8]);
          tx.send(vec![5u8, 6u8]);
          tx.send(vec![7u8, 8u8]);
        });

        let mut reader = ChanReader::new(rx);
        let mut buf = [0u8, ..3];

        assert_eq!(Ok(0), reader.read([]));

        assert_eq!(Ok(3), reader.read(buf));
        let a: &[u8] = &[1,2,3];
        assert_eq!(a, buf.as_slice());

        assert_eq!(Ok(3), reader.read(buf));
        let a: &[u8] = &[4,5,6];
        assert_eq!(a, buf.as_slice());

        assert_eq!(Ok(2), reader.read(buf));
        let a: &[u8] = &[7,8,6];
        assert_eq!(a, buf.as_slice());

        match reader.read(buf.as_mut_slice()) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(a, buf.as_slice());

        // Ensure it continues to fail in the same way.
        match reader.read(buf.as_mut_slice()) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(a, buf.as_slice());
    }

    #[test]
    fn test_chan_writer() {
        let (tx, rx) = channel();
        let mut writer = ChanWriter::new(tx);
        writer.write_be_u32(42).unwrap();

        let wanted = vec![0u8, 0u8, 0u8, 42u8];
        let got = match task::try(proc() { rx.recv() }) {
            Ok(got) => got,
            Err(_) => fail!(),
        };
        assert_eq!(wanted, got);

        match writer.write_u8(1) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::BrokenPipe),
        }
    }
}
<commit_msg>auto merge of #17998 : rapha/rust/master, r=alexcrichton<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use clone::Clone;
use cmp;
use collections::Collection;
use comm::{Sender, Receiver};
use io;
use option::{None, Some};
use result::{Ok, Err};
use slice::{bytes, CloneableVector};
use super::{Buffer, Reader, Writer, IoResult};
use vec::Vec;

/// Allows reading from a rx.
///
/// # Example
///
/// ```
/// use std::io::ChanReader;
///
/// let (tx, rx) = channel();
/// # drop(tx);
/// let mut reader = ChanReader::new(rx);
///
/// let mut buf = [0u8, ..100];
/// match reader.read(buf) {
///     Ok(nread) => println!("Read {} bytes", nread),
///     Err(e) => println!("read error: {}", e),
/// }
/// ```
pub struct ChanReader {
    buf: Vec<u8>,          // A buffer of bytes received but not consumed.
    pos: uint,             // How many of the buffered bytes have already be consumed.
    rx: Receiver<Vec<u8>>, // The Receiver to pull data from.
    closed: bool,          // Whether the channel this Receiver connects to has been closed.
}

impl ChanReader {
    /// Wraps a `Port` in a `ChanReader` structure
    pub fn new(rx: Receiver<Vec<u8>>) -> ChanReader {
        ChanReader {
            buf: Vec::new(),
            pos: 0,
            rx: rx,
            closed: false,
        }
    }
}

impl Buffer for ChanReader {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        if self.pos >= self.buf.len() {
            self.pos = 0;
            match self.rx.recv_opt() {
                Ok(bytes) => {
                    self.buf = bytes;
                },
                Err(()) => {
                    self.closed = true;
                    self.buf = Vec::new();
                }
            }
        }
        if self.closed {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(self.buf.slice_from(self.pos))
        }
    }

    fn consume(&mut self, amt: uint) {
        self.pos += amt;
        assert!(self.pos <= self.buf.len());
    }
}

impl Reader for ChanReader {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        let mut num_read = 0;
        loop {
            let count = match self.fill_buf().ok() {
                Some(src) => {
                    let dst = buf[mut num_read..];
                    let count = cmp::min(src.len(), dst.len());
                    bytes::copy_memory(dst, src[..count]);
                    count
                },
                None => 0,
            };
            self.consume(count);
            num_read += count;
            if num_read == buf.len() || self.closed {
                break;
            }
        }
        if self.closed && num_read == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(num_read)
        }
    }
}

/// Allows writing to a tx.
///
/// # Example
///
/// ```
/// # #![allow(unused_must_use)]
/// use std::io::ChanWriter;
///
/// let (tx, rx) = channel();
/// # drop(rx);
/// let mut writer = ChanWriter::new(tx);
/// writer.write("hello, world".as_bytes());
/// ```
pub struct ChanWriter {
    tx: Sender<Vec<u8>>,
}

impl ChanWriter {
    /// Wraps a channel in a `ChanWriter` structure
    pub fn new(tx: Sender<Vec<u8>>) -> ChanWriter {
        ChanWriter { tx: tx }
    }
}

impl Clone for ChanWriter {
    fn clone(&self) -> ChanWriter {
        ChanWriter { tx: self.tx.clone() }
    }
}

impl Writer for ChanWriter {
    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
        self.tx.send_opt(buf.to_vec()).map_err(|_| {
            io::IoError {
                kind: io::BrokenPipe,
                desc: "Pipe closed",
                detail: None
            }
        })
    }
}

#[cfg(test)]
mod test {
    use prelude::*;
    use super::*;
    use io;
    use task;

    #[test]
    fn test_rx_reader() {
        let (tx, rx) = channel();
        task::spawn(proc() {
          tx.send(vec![1u8, 2u8]);
          tx.send(vec![]);
          tx.send(vec![3u8, 4u8]);
          tx.send(vec![5u8, 6u8]);
          tx.send(vec![7u8, 8u8]);
        });

        let mut reader = ChanReader::new(rx);
        let mut buf = [0u8, ..3];

        assert_eq!(Ok(0), reader.read([]));

        assert_eq!(Ok(3), reader.read(buf));
        let a: &[u8] = &[1,2,3];
        assert_eq!(a, buf.as_slice());

        assert_eq!(Ok(3), reader.read(buf));
        let a: &[u8] = &[4,5,6];
        assert_eq!(a, buf.as_slice());

        assert_eq!(Ok(2), reader.read(buf));
        let a: &[u8] = &[7,8,6];
        assert_eq!(a, buf.as_slice());

        match reader.read(buf.as_mut_slice()) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(a, buf.as_slice());

        // Ensure it continues to fail in the same way.
        match reader.read(buf.as_mut_slice()) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(a, buf.as_slice());
    }

    #[test]
    fn test_rx_buffer() {
        let (tx, rx) = channel();
        task::spawn(proc() {
          tx.send(b"he".to_vec());
          tx.send(b"llo wo".to_vec());
          tx.send(b"".to_vec());
          tx.send(b"rld\nhow ".to_vec());
          tx.send(b"are you?".to_vec());
          tx.send(b"".to_vec());
        });

        let mut reader = ChanReader::new(rx);

        assert_eq!(Ok("hello world\n".to_string()), reader.read_line());
        assert_eq!(Ok("how are you?".to_string()), reader.read_line());
        match reader.read_line() {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
    }

    #[test]
    fn test_chan_writer() {
        let (tx, rx) = channel();
        let mut writer = ChanWriter::new(tx);
        writer.write_be_u32(42).unwrap();

        let wanted = vec![0u8, 0u8, 0u8, 42u8];
        let got = match task::try(proc() { rx.recv() }) {
            Ok(got) => got,
            Err(_) => fail!(),
        };
        assert_eq!(wanted, got);

        match writer.write_u8(1) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::BrokenPipe),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>[compiler][causality] Solve the causality models generated, and add errors E0032 and E0033 when a causality error occurs.<commit_after>// Copyright 2018 Pierre Talbot (IRCAM)

// 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 session::*;
use context::*;
use middle::causality::causal_model::*;
use pcp::search::*;
use pcp::kernel::*;

pub fn solve_causal_model(session: Session, c: (Context, Vec<CausalModel>)) -> Env<Context> {
  let solver = Solver::new(session, c.0, c.1);
  solver.solve_all()
}

pub struct Solver {
  session: Session,
  context: Context,
  models: Vec<CausalModel>,
}

impl Solver {
  pub fn new(session: Session, context: Context, models: Vec<CausalModel>) -> Self {
    Solver { session, context, models }
  }

  pub fn solve_all(mut self) -> Env<Context> {
    for model in self.models.clone() {
      if let Some(model) = self.prepare_model(model) {
        if !self.solve_model(model) {
          break;
        }
      }
    }
    if self.session.has_errors() {
      Env::fake(self.session, self.context)
    } else {
      Env::value(self.session, self.context)
    }
  }

  fn solve_model(&mut self, model: CausalModel) -> bool {
    // Search step.
    let space = model.clone().space;
    let mut search = one_solution_engine();
    search.start(&space);
    let (frozen_space, status) = search.enter(space);
    let _space = frozen_space.unfreeze();

    // Print result.
    match status {
      Status::Satisfiable => true,
      Status::Unsatisfiable => {
        self.err_unsatisfiable_model();
        false
      }
      Status::EndOfSearch
    | Status::Unknown(_) => unreachable!(
        "After the search step, the problem instance should be either satisfiable or unsatisfiable.")
    }
  }

  fn err_unsatisfiable_model(&self) {
    self.session.struct_span_err_with_code(DUMMY_SP,
      &format!("causality error: a write access happens after a read access on the same variable."),
      "E0033")
      .help(&"Unfortunately, we just report that the program is not causal but not the reason (see issue #4).")
      .emit();
  }

  /// Returns `None` if the model is statically unsatisfiable (an error has already been registered).
  fn prepare_model(&mut self, mut model: CausalModel) -> Option<CausalModel> {
    let mut unsatisfiable = false;
    let n = model.num_ops();
    for op1 in 0..n {
      for op2 in (op1+1)..n {
        let v1 = model.params.var_of_op[op1].clone();
        let v2 = model.params.var_of_op[op2].clone();
        if v1 == v2 && model.params.activated[op1] && model.params.activated[op2]
        {
          let err_msg = "every variable access must have an explicit permission (should be done in `infer_permission.rs`).";
          let a1 = v1.permission.expect(err_msg);
          let a2 = v2.permission.expect(err_msg);
          // Enforce that every access read is done after readwrite, and in turn that every write is realized after a readwrite.
          if a1 > a2 {
            model.add_sequential_constraint(op1, op2);
          }
          else if a1 < a2 {
            model.add_sequential_constraint(op2, op1);
          }
          // Enforce that a variable is not accessed two times with readwrite.
          else if a1 == Permission::ReadWrite && a2 == Permission::ReadWrite {
            self.err_two_readwrite_accesses(v1, v2);
            unsatisfiable = true;
          }
        }
      }
    }
    if unsatisfiable { None }
    else { Some(model) }
  }

  fn err_two_readwrite_accesses(&self, v1: Variable, v2: Variable) {
    self.session.struct_span_err_with_code(v2.span,
      &format!("second readwrite access to this variable."),
      "E0032")
      .span_label(v1.span, &"previous readwrite access")
      .help(&"Rational: We forbid more than one readwrite on a variable to keep the computation deterministic.\n\
            Solution 1: Remove one readwrite.\n\
            Solution 2: Encapsulate both readwrite in a single host function.\n\
            Solution 3: Separate the readwrite accesses with a delay (such as `pause`).")
      .emit();
  }
}<|endoftext|>


<commit_before><commit_msg>update rss feed url<commit_after><|endoftext|>


<commit_before><commit_msg>rename ETC tests file, add create2 tests<commit_after>#![cfg_attr(feature = "bench", feature(test))]
#![allow(non_snake_case)]
#![allow(unused)]

#[macro_use]
extern crate jsontests_derive;
extern crate jsontests;

#[cfg(feature = "bench")]
extern crate test;

/// Shifting opcodes tests
#[derive(JsonTests)]
#[directory = "jsontests/res/files/SputnikVM/vmEIP215"]
#[test_with = "jsontests::util::run_test"]
#[cfg_attr(feature = "bench", bench_with = "jsontests::util::run_bench")]
struct EIP215;

/// EXTCODEHASH tests
#[derive(JsonTests)]
#[directory = "jsontests/res/files/SputnikVM/vmEIP215"]
#[test_with = "jsontests::util::run_test"]
#[cfg_attr(feature = "bench", bench_with = "jsontests::util::run_bench")]
struct EIP1052;

/// CREATE2 tests
#[derive(JsonTests)]
#[directory = "jsontests/res/files/eth/VMTests/vmEIP1014"]
#[test_with = "jsontests::util::run_test"]
#[cfg_attr(feature = "bench", bench_with = "jsontests::util::run_bench")]
struct EIP1014;
<|endoftext|>


<commit_before><commit_msg>Get things partially compiling.<commit_after>/*
Module: zmq
*/

#[cfg(target_os = "macos")];

use std;
import std::ctypes::*;
import std::option;
import std::option::{none, some};
import std::ptr;
import std::str;
import std::sys;
import std::unsafe;
import std::result;
import std::result::{ok, err};
import std::u64;

#[link_name = "zmq"]
#[link_args = "-L /opt/local/lib"]
native mod libzmq {
    type ctx_t;
    type socket_t;
    type msg_t;

    fn zmq_init(io_threads: c_int) -> *ctx_t;
    fn zmq_term(ctx: *ctx_t) -> c_int;

    fn zmq_errno() -> c_int;
    fn zmq_strerror(errnum: c_int) -> str::sbuf;

    fn zmq_socket(ctx: *ctx_t, typ: c_int) -> *socket_t;
    fn zmq_close(socket: *socket_t) -> c_int;

    fn zmq_getsockopt<T>(socket: *socket_t, option: c_int, optval: *T,
                         size: *size_t) -> c_int;
    fn zmq_setsockopt<T>(socket: *socket_t, option: c_int, optval: *T,
                         size: size_t) -> c_int;

    fn zmq_bind(socket: *socket_t, endpoint: str::sbuf) -> c_int;
    fn zmq_connect(socket: *socket_t, endpoint: str::sbuf) -> c_int;

/*
fn zmq_msg_init(msg: *msg_t) -> int;
fn zmq_msg_init_size(msg: *msg_t, size: size_t) -> int;
fn zmq_msg_init_data(msg: *msg_t, data: *u8, size: size_t,
free_cb: free_cb_t, hint: *void);

fn zmq_send(socket: *socket_t, msg: *msg_t, flags: int) -> int;
fn zmq_recv(socket: *socket_t, msg: *msg_t, flags: int) -> int;
*/
}

mod libzmq_constants {
    const ZMQ_PAIR : c_int = 0i32;
    const ZMQ_PUB : c_int = 1i32;
    const ZMQ_SUB : c_int = 2i32;
    const ZMQ_REQ : c_int = 3i32;
    const ZMQ_REP : c_int = 4i32;
    const ZMQ_DEALER : c_int = 5i32;
    const ZMQ_ROUTER : c_int = 6i32;
    const ZMQ_PULL : c_int = 7i32;
    const ZMQ_PUSH : c_int = 8i32;
    const ZMQ_XPUB : c_int = 9i32;
    const ZMQ_XSUB : c_int = 10i32;

    const ZMQ_HWM : c_int = 1i32;
    const ZMQ_SWAP : c_int = 3i32;
    const ZMQ_AFFINITY : c_int = 4i32;
    const ZMQ_IDENTITY : c_int = 5i32;
    const ZMQ_SUBSCRIBE : c_int = 6i32;
    const ZMQ_UNSUBSCRIBE : c_int = 7i32;
    const ZMQ_RATE : c_int = 8i32;
    const ZMQ_RECOVERY_IVL : c_int = 9i32;
    const ZMQ_MCAST_LOOP : c_int = 10i32;
    const ZMQ_SNDBUF : c_int = 11i32;
    const ZMQ_RCVBUF : c_int = 12i32;
    const ZMQ_RCVMORE : c_int = 13i32;
    const ZMQ_FD : c_int = 14i32;
    const ZMQ_EVENTS : c_int = 15i32;
    const ZMQ_TYPE : c_int = 16i32;
    const ZMQ_LINGER : c_int = 17i32;
    const ZMQ_RECONNECT_IVL : c_int = 18i32;
    const ZMQ_BACKLOG : c_int = 19i32;
    const ZMQ_RECOVERY_IVL_MSEC : c_int = 20i32;
    const ZMQ_RECONNECT_IVL_MAX : c_int = 21i32;

    const ZMQ_NOBLOCK : c_int = 1i32;
    const ZMQ_SNDMORE : c_int = 2i32;

    const ZMQ_POLLIN : c_int = 1i32;
    const ZMQ_POLLOUT : c_int = 2i32;
    const ZMQ_POLLERR : c_int = 4i32;

    const ZMQ_MAX_VSM_SIZE : c_int = 30i32;
    const ZMQ_DELIMITER : c_int = 31i32;
    const ZMQ_VSM : c_int = 32i32;

    const ZMQ_MSG_MORE : c_int = 1i32;
    const ZMQ_MSG_SHARED : c_int = 128i32;
    const ZMQ_MSG_MASK : c_int = 129i32;

    const ZMQ_HAUSNUMERO : c_int = 156384712i32;

    const ENOTSUP : c_int = 156384712i32 + 1i32; //ZMQ_HAUSNUMERO + 1i32;
    const EPROTONOSUPPORT : c_int = 156384712i32 + 2i32; //ZMQ_HAUSNUMERO + 2i32;
    const ENOBUFS : c_int = 156384712i32 + 3i32; //ZMQ_HAUSNUMERO + 3i32;
    const ENETDOWN : c_int = 156384712i32 + 4i32; //ZMQ_HAUSNUMERO + 4i32;
    const EADDRINUSE : c_int = 156384712i32 + 5i32; //ZMQ_HAUSNUMERO + 5i32;
    const EADDRNOTAVAIL : c_int = 156384712i32 + 6i32; //ZMQ_HAUSNUMERO + 6i32;
    const ECONNREFUSED : c_int = 156384712i32 + 7i32; //ZMQ_HAUSNUMERO + 7i32;
    const EINPROGRESS : c_int = 156384712i32 + 8i32; //ZMQ_HAUSNUMERO + 8i32;
    const ENOTSOCK : c_int = 156384712i32 + 9i32; //ZMQ_HAUSNUMERO + 9i32;

    const EFSM : c_int = 156384712i32 + 51i32; //ZMQ_HAUSNUMERO + 51i32;
    const ENOCOMPATPROTO : c_int = 156384712i32 + 52i32; //ZMQ_HAUSNUMERO + 52i32;
    const ETERM : c_int = 156384712i32 + 53i32; //ZMQ_HAUSNUMERO + 53i32;
    const EMTHREAD : c_int = 156384712i32 + 54i32; //ZMQ_HAUSNUMERO + 54i32;
}

mod zmq {
    type ctx_t = *libzmq::ctx_t;
    type socket_t = *libzmq::socket_t;

    tag socket_kind {
        PAIR;
        PUB;
        SUB;
        REQ;
        REP;
        DEALER;
        ROUTER;
        PULL;
        PUSH;
        XPUB;
        XSUB;
    }

    tag error_t {
        ENOTSUP;
        EPROTONOSUPPORT;
        ENOBUFS;
        ENETDOWN;
        EADDRINUSE;
        EADDRNOTAVAIL;
        ECONNREFUSED;
        EINPROGRESS;
        ENOTSOCK;
        EFSM;
        ENOCOMPATPROTO;
        ETERM;
        EMTHREAD;
        UNKNOWN(c_int);
    }

    fn init(io_threads: int) -> ctx_t { libzmq::zmq_init(io_threads as i32) }

    fn term(ctx: ctx_t) -> option::t<error_t> {
        let r = libzmq::zmq_term(ctx);
        if r == -1i32 { some(errno_to_error()) } else { none }
    }

    fn socket(ctx: ctx_t, kind: socket_kind) -> result::t<socket_t, error_t> unsafe {
        let s = libzmq::zmq_socket(ctx, socket_kind_to_i32(kind));
        ret if unsafe::reinterpret_cast(s) == 0 {
            err(errno_to_error())
        } else {
            ok(s)
        };
    }

    fn close(socket: socket_t) -> option::t<error_t> {
        let r = libzmq::zmq_close(socket);
        if r == -1i32 { some(errno_to_error()) } else { none }
    }

    fn bind(socket: socket_t, endpoint: str) -> option::t<error_t> {
        let r = str::as_buf(endpoint, { |buf| libzmq::zmq_bind(socket, buf) });

        if r == -1i32 { some(errno_to_error()) } else { none }
    }

    fn get_high_water_mark(socket: socket_t) -> result::t<u64, error_t> {
        let hwm = 0u64;
        let size = sys::size_of::<u64>();

        let r = libzmq::zmq_getsockopt(
            socket,
            libzmq_constants::ZMQ_HWM,
            ptr::addr_of(hwm),
            ptr::addr_of(size)
        );

        if r == -1i32 { err(errno_to_error()) } else { ok(hwm) }
    }

    fn set_high_water_mark(socket: socket_t, hwm: u64) -> option::t<error_t> {
        let r = libzmq::zmq_setsockopt(
            socket,
            libzmq_constants::ZMQ_HWM,
            ptr::addr_of(hwm),
            sys::size_of::<u64>()
        );

        if r == -1i32 { some(errno_to_error()) } else { none }
    }

    fn socket_kind_to_i32(k: socket_kind) -> c_int {
        alt k {
          PAIR. { libzmq_constants::ZMQ_PAIR }
          PUB. { libzmq_constants::ZMQ_PUB }
          SUB. { libzmq_constants::ZMQ_SUB }
          REQ. { libzmq_constants::ZMQ_REQ }
          REP. { libzmq_constants::ZMQ_REP }
          DEALER. { libzmq_constants::ZMQ_DEALER }
          ROUTER. { libzmq_constants::ZMQ_ROUTER }
          PULL. { libzmq_constants::ZMQ_PULL }
          PUSH. { libzmq_constants::ZMQ_PUSH }
          XPUB. { libzmq_constants::ZMQ_XPUB }
          XSUB. { libzmq_constants::ZMQ_XSUB }
        }
    }

    fn error_to_str(error: error_t) -> str unsafe {
        let s = libzmq::zmq_strerror(error_to_errno(error));
        ret if unsafe::reinterpret_cast(s) == -1 {
            let s = unsafe::reinterpret_cast(s);
            str::str_from_cstr(s)
        } else {
            ""
        }
    }

    fn errno_to_error() -> error_t {
        alt libzmq::zmq_errno() {
          e when e == libzmq_constants::ENOTSUP { ENOTSUP }
          e when e == libzmq_constants::EPROTONOSUPPORT { EPROTONOSUPPORT }
          e when e == libzmq_constants::ENOBUFS { ENOBUFS }
          e when e == libzmq_constants::ENETDOWN { ENETDOWN }
          e when e == libzmq_constants::EADDRINUSE { EADDRINUSE }
          e when e == libzmq_constants::EADDRNOTAVAIL { EADDRNOTAVAIL }
          e when e == libzmq_constants::ECONNREFUSED { ECONNREFUSED }
          e when e == libzmq_constants::EINPROGRESS { EINPROGRESS }
          e when e == libzmq_constants::ENOTSOCK { ENOTSOCK }
          e when e == libzmq_constants::EFSM { EFSM }
          e when e == libzmq_constants::ENOCOMPATPROTO { ENOCOMPATPROTO }
          e when e == libzmq_constants::ETERM { ETERM }
          e when e == libzmq_constants::EMTHREAD { EMTHREAD }
          e { UNKNOWN(e) }
        }
    }

    fn error_to_errno(error: error_t) -> c_int {
        alt error {
          ENOTSUP. { libzmq_constants::ENOTSUP }
          EPROTONOSUPPORT. { libzmq_constants::EPROTONOSUPPORT }
          ENOBUFS. { libzmq_constants::ENOBUFS }
          ENETDOWN. { libzmq_constants::ENETDOWN }
          EADDRINUSE. { libzmq_constants::EADDRINUSE }
          EADDRNOTAVAIL. { libzmq_constants::EADDRNOTAVAIL }
          ECONNREFUSED. { libzmq_constants::ECONNREFUSED }
          EINPROGRESS. { libzmq_constants::EINPROGRESS }
          ENOTSOCK. { libzmq_constants::ENOTSOCK }
          EFSM. { libzmq_constants::EFSM }
          ENOCOMPATPROTO. { libzmq_constants::ENOCOMPATPROTO }
          ETERM. { libzmq_constants::ETERM }
          EMTHREAD. { libzmq_constants::EMTHREAD }
          UNKNOWN(e) { e }
        }
    }
}

fn main() {
    let ctx = zmq::init(1);
    let socket = alt zmq::socket(ctx, zmq::REP) {
      ok(s) { s }
      err(e) { fail zmq::error_to_str(e) }
    };

    alt zmq::set_high_water_mark(socket, 10u64) {
      none. { log_err "no error"; }
      some(e) { zmq::error_to_str(e); }
    }

    alt zmq::bind(socket, "tcp://127.0.0.1:2345") {
      none. { log_err "no error"; }
      some(e) { zmq::error_to_str(e); }
    }

    zmq::close(socket);
    log_err "hello\n";
    zmq::term(ctx);
}
<|endoftext|>


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

//! An efficient hash map for node IDs

use collections::{HashMap, HashSet};
use std::hash::{Hasher, Hash};
use std::io;
use syntax::ast;

#[cfg(not(stage0))]
pub type NodeMap<T> = HashMap<ast::NodeId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdMap<T> = HashMap<ast::DefId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type NodeSet = HashSet<ast::NodeId, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdSet = HashSet<ast::DefId, FnvHasher>;

// Hacks to get good names
#[cfg(not(stage0))]
pub mod NodeMap {
    use collections::HashMap;
    pub fn new<T>() -> super::NodeMap<T> {
        HashMap::with_hasher(super::FnvHasher)
    }
}
#[cfg(not(stage0))]
pub mod NodeSet {
    use collections::HashSet;
    pub fn new() -> super::NodeSet {
        HashSet::with_hasher(super::FnvHasher)
    }
}
#[cfg(not(stage0))]
pub mod DefIdMap {
    use collections::HashMap;
    pub fn new<T>() -> super::DefIdMap<T> {
        HashMap::with_hasher(super::FnvHasher)
    }
}
#[cfg(not(stage0))]
pub mod DefIdSet {
    use collections::HashSet;
    pub fn new() -> super::DefIdSet {
        HashSet::with_hasher(super::FnvHasher)
    }
}

#[cfg(stage0)]
pub type NodeMap<T> = HashMap<ast::NodeId, T>;
#[cfg(stage0)]
pub type DefIdMap<T> = HashMap<ast::DefId, T>;
#[cfg(stage0)]
pub type NodeSet = HashSet<ast::NodeId>;
#[cfg(stage0)]
pub type DefIdSet = HashSet<ast::DefId>;

// Hacks to get good names
#[cfg(stage0)]
pub mod NodeMap {
    use collections::HashMap;
    pub fn new<T>() -> super::NodeMap<T> {
        HashMap::new()
    }
}
#[cfg(stage0)]
pub mod NodeSet {
    use collections::HashSet;
    pub fn new() -> super::NodeSet {
        HashSet::new()
    }
}
#[cfg(stage0)]
pub mod DefIdMap {
    use collections::HashMap;
    pub fn new<T>() -> super::DefIdMap<T> {
        HashMap::new()
    }
}
#[cfg(stage0)]
pub mod DefIdSet {
    use collections::HashSet;
    pub fn new() -> super::DefIdSet {
        HashSet::new()
    }
}

/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
/// want. In the compiler we're not really worried about DOS attempts, so we
/// just default to a non-cryptographic hash.
///
/// This uses FNV hashing, as described here:
/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
#[deriving(Clone)]
pub struct FnvHasher;

pub struct FnvState(u64);

impl Hasher<FnvState> for FnvHasher {
    fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 {
        let mut state = FnvState(0xcbf29ce484222325);
        t.hash(&mut state);
        let FnvState(ret) = state;
        return ret;
    }
}

impl Writer for FnvState {
    fn write(&mut self, bytes: &[u8]) -> io::IoResult<()> {
        let FnvState(mut hash) = *self;
        for byte in bytes.iter() {
            hash = hash * 0x100000001b3;
            hash = hash ^ (*byte as u64);
        }
        *self = FnvState(hash);
        Ok(())
    }
}
<commit_msg>change FVN hash function to the FVN-1a variant<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! An efficient hash map for node IDs

use collections::{HashMap, HashSet};
use std::hash::{Hasher, Hash};
use std::io;
use syntax::ast;

#[cfg(not(stage0))]
pub type NodeMap<T> = HashMap<ast::NodeId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdMap<T> = HashMap<ast::DefId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type NodeSet = HashSet<ast::NodeId, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdSet = HashSet<ast::DefId, FnvHasher>;

// Hacks to get good names
#[cfg(not(stage0))]
pub mod NodeMap {
    use collections::HashMap;
    pub fn new<T>() -> super::NodeMap<T> {
        HashMap::with_hasher(super::FnvHasher)
    }
}
#[cfg(not(stage0))]
pub mod NodeSet {
    use collections::HashSet;
    pub fn new() -> super::NodeSet {
        HashSet::with_hasher(super::FnvHasher)
    }
}
#[cfg(not(stage0))]
pub mod DefIdMap {
    use collections::HashMap;
    pub fn new<T>() -> super::DefIdMap<T> {
        HashMap::with_hasher(super::FnvHasher)
    }
}
#[cfg(not(stage0))]
pub mod DefIdSet {
    use collections::HashSet;
    pub fn new() -> super::DefIdSet {
        HashSet::with_hasher(super::FnvHasher)
    }
}

#[cfg(stage0)]
pub type NodeMap<T> = HashMap<ast::NodeId, T>;
#[cfg(stage0)]
pub type DefIdMap<T> = HashMap<ast::DefId, T>;
#[cfg(stage0)]
pub type NodeSet = HashSet<ast::NodeId>;
#[cfg(stage0)]
pub type DefIdSet = HashSet<ast::DefId>;

// Hacks to get good names
#[cfg(stage0)]
pub mod NodeMap {
    use collections::HashMap;
    pub fn new<T>() -> super::NodeMap<T> {
        HashMap::new()
    }
}
#[cfg(stage0)]
pub mod NodeSet {
    use collections::HashSet;
    pub fn new() -> super::NodeSet {
        HashSet::new()
    }
}
#[cfg(stage0)]
pub mod DefIdMap {
    use collections::HashMap;
    pub fn new<T>() -> super::DefIdMap<T> {
        HashMap::new()
    }
}
#[cfg(stage0)]
pub mod DefIdSet {
    use collections::HashSet;
    pub fn new() -> super::DefIdSet {
        HashSet::new()
    }
}

/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
/// want. In the compiler we're not really worried about DOS attempts, so we
/// just default to a non-cryptographic hash.
///
/// This uses FNV hashing, as described here:
/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
#[deriving(Clone)]
pub struct FnvHasher;

pub struct FnvState(u64);

impl Hasher<FnvState> for FnvHasher {
    fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 {
        let mut state = FnvState(0xcbf29ce484222325);
        t.hash(&mut state);
        let FnvState(ret) = state;
        return ret;
    }
}

impl Writer for FnvState {
    fn write(&mut self, bytes: &[u8]) -> io::IoResult<()> {
        let FnvState(mut hash) = *self;
        for byte in bytes.iter() {
            hash = hash ^ (*byte as u64);
            hash = hash * 0x100000001b3;
        }
        *self = FnvState(hash);
        Ok(())
    }
}
<|endoftext|>


<commit_before>//! Setting functionality - set cookie data

use url::{utf8_percent_encode, FORM_URLENCODED_ENCODE_SET};
use serialize::json::{Json, Number, String, Boolean, List, Object, Null};
use iron::Response;
use super::Cookie;
use time::Tm;
use std::collections::TreeMap;

/// Set cookies.
///
/// This trait is added as a mix-in to `Response`, allowing
/// simple cookie-setting.
pub trait SetCookie {
    /// Set a cookie.
    ///
    /// Set cookies directly on the response with `res.set_cookie("coo=kie;")`.
    /// Only one cookie may sent per response, with the given key/value.
    /// Doing otherwise will result in ***undefined behavior***.
    ///
    /// Keys/values may contain restricted characters, but they will be URI encoded in the cookie.
    ///
    /// They will be decoded when the cookie is returned to the server.
    ///
    /// Cookies ***must*** be set before the response body is sent.
    /// Headers are flushed as soon anything is sent in the response body.
    fn set_cookie(&mut self, &Cookie, (String, String), HeaderCollection);

    /// Set a cookie as JSON.
    ///
    /// Cookies set as JSON will be available under `cookie.json`.
    /// Otherwise, they behave exactly as normally serialized cookies.
    ///
    /// Note that restricted characters will still be URI encoded in your cookie.
    ///
    /// They will be decoded when the cookie is returned to the server.
    fn set_json_cookie(&mut self, &Cookie, (String, Json), HeaderCollection);
}

impl SetCookie for Response {
    fn set_cookie(&mut self,
                  signer: &Cookie,
                  (key, value): (String, String),
                  options: HeaderCollection) {

        self.headers.extensions.insert("Set-Cookie".to_string(),
            match signer.sign(&value) {
                Some(signature) => {
                    utf8_percent_encode(key.as_slice(), FORM_URLENCODED_ENCODE_SET)
                        .append("=")
                        .append("s:")
                        .append(utf8_percent_encode(value.as_slice(), FORM_URLENCODED_ENCODE_SET).as_slice())
                        .append(".")
                        .append(signature.as_slice())
                },
                None            => {
                    utf8_percent_encode(key.as_slice(), FORM_URLENCODED_ENCODE_SET)
                        .append("=")
                        .append(utf8_percent_encode(value.as_slice(), FORM_URLENCODED_ENCODE_SET).as_slice())
                }
            }.append(options.to_cookie_av().as_slice())
        );
    }

    fn set_json_cookie(&mut self,
                       signer: &Cookie,
                       (key, value): (String, Json),
                       options: HeaderCollection) {
        let json = "j:".to_string().append(stringify_json(&value).as_slice());
        self.set_cookie(signer, (key, json), options)
    }
}

fn stringify_json(json: &Json) -> String {
    match *json {
        Object(ref object) => {
            let obj: Vec<String> = object.iter().map(stringify_pair).collect();
            "{".to_string().append(obj.connect(",").as_slice()).append("}")
        },
        List(ref list)     => {
            let ary: Vec<String> = list.iter().map(stringify_json).collect();
            "[".to_string().append(ary.connect(",").as_slice()).append("]")
        },
        Number(number) => number.to_string(),
        String(ref string) => "\"".to_string().append(string.as_slice()).append("\""),
        Boolean(true)      => "true".to_string(),
        Boolean(false)     => "false".to_string(),
        Null               => "null".to_string()
    }
}

fn stringify_pair((key, val): (&String, &Json)) -> String {
    "\"".to_string().append(key.as_slice()).append("\":").append(stringify_json(val).as_slice())
}

/// The headers used to set a cookie.
///
/// These headers are defined by [RFC 6265](http://tools.ietf.org/html/rfc6265)
pub struct HeaderCollection {
    /// An absolute date/time at which this cookie should expire.
    pub expires:    Option<Tm>,
    /// A relative time (in seconds) at which this cookie should expire.
    pub max_age:    Option<u32>,
    /// The scope of the cookie.
    ///
    /// If set, the browser will send this cookie to the set domain and all subdomains.
    /// If not set, the browser will only send this cookie to the originating domain.
    ///
    /// This may only be set to the sending domain and its subdomains.
    pub domain:     Option<String>,
    /// The scope of the cookie.
    pub path:       Option<String>,
    /// A cookie with this flag should only be sent over secured/encrypted connections.
    ///
    /// This will be respected by the browser.
    pub secure:     bool,
    /// A cookie with this flag is only accessible through HTTP and HTTPS.
    ///
    /// This helps to prevent Javascript and, specifically, XSS attacks.
    pub http_only:  bool,
    /// Any additional headers.
    ///
    /// This may be any sequence of valid characters.
    ///
    /// Extensions will be separated with `;`.
    /// If a value is specified in the `Map`, the extension will be
    /// written as `[key]=[value]`.
    pub extensions: Option<TreeMap<String, Option<String>>>
}

impl HeaderCollection {
    #[doc(hidden)]
    pub fn to_cookie_av(self) -> String {
        let mut options = String::new()
            .append(head("Expires", self.expires, |v| v.rfc822()).as_slice())
            .append(head("Max-Age", self.max_age, |v| v.to_string()).as_slice())
            .append(head("Domain", self.domain, |v| v).as_slice())
            .append(head("Path", self.path, |v| v).as_slice());
        if self.secure { options.push_str("; Secure"); }
        if self.http_only { options.push_str("; Http-Only"); }
        match self.extensions {
            Some(map) => {
                for (header, value) in map.iter() {
                    options.push_str(extension(header, value.clone()).as_slice());
                }
            },
            None      => ()
        }
        options
    }
}

impl HeaderCollection {
    /// Convenience function for a set of empty cookie headers
    pub fn empty() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// that will expire the cookie in `seconds` seconds
    pub fn aged(seconds: u32) -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: Some(seconds),
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// declaring the cookie `Secure` and `HttpOnly`
    pub fn secured() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: true,
            http_only: true,
            extensions: None
        }
    }
}

fn head<V>(header: &str, value: Option<V>, mutator: |V| -> String) -> String {
    match value {
        Some(val) => {
            // Delimit from previous cookie/options
            "; ".to_string()
            // Add the header
                .append(header).append("=")
            // Add the mutated value
                .append(mutator(val).as_slice())
        },
        None      => String::new()
    }
}

fn extension(header: &String, value: Option<String>) -> String {
    match value {
        Some(val) => head(header.as_slice(), Some(val), |v| v),
        None      => "; ".to_string().append(header.as_slice())
    }
}

#[cfg(test)]
mod test {
    use std::mem::uninitialized;
    use std::collections::TreeMap;
    use http::server::response::ResponseWriter;
    use super::*;
    use super::super::cookie::*;
    use serialize::json::{Json, Object, String};
    use iron::Response;

    // Set a cookie and return its set value
    fn get_cookie<'a>(headers: HeaderCollection, secret: Option<String>, key: &str, value: &str) -> String {
        let mut http_res = unsafe { ResponseWriter::new(uninitialized()) };
        let mut res = Response::from_http(&mut http_res);
        let signer = Cookie::new(secret);
        let cookie = (key.to_string(), value.to_string());
        res.set_cookie(&signer, cookie, headers);
        res.headers.extensions.find(&"Set-Cookie".to_string()).unwrap().clone()
    }

    // Set a JSON cookie and return its set value
    fn get_json_cookie<'a>(headers: HeaderCollection, secret: Option<String>, key: &str, value: Json) -> String {
        let mut http_res = unsafe { ResponseWriter::new(uninitialized()) };
        let mut res = Response::from_http(&mut http_res);
        let signer = Cookie::new(secret);
        let cookie = (key.to_string(), value);
        res.set_json_cookie(&signer, cookie, headers);
        res.headers.extensions.find(&"Set-Cookie".to_string()).unwrap().clone()
    }

    #[test]
    fn check_stringify_json() {
        let mut obj_map = TreeMap::new();
        obj_map.insert("foo".to_string(), String("bar".to_string()));
        let json = Object(obj_map);
        assert_eq!("{\"foo\":\"bar\"}".to_string(), super::stringify_json(&json)) // FIXME
    }

    #[test]
    fn check_cookie() {
        let headers = HeaderCollection::empty();
        assert_eq!(get_cookie(headers, None, "thing", "thing"), "thing=thing".to_string());
    }

    #[test]
    fn check_escaping() {
        let headers = HeaderCollection::empty();
        assert_eq!(get_cookie(headers, None, "~`!@#$%^&*()_+-={}|[]\\:\";'<>?,./'", "~`!@#$%^&*()_+-={}|[]\\:\";'<>?,./'"),
            // Url component encoding should escape these characters
            "~%60%21%40%23%24%25%5E%26*%28%29_%2B-%3D%7B%7D%7C%5B%5D%5C%3A%22%3B%27%3C%3E%3F%2C.%2F%27=\
             ~%60%21%40%23%24%25%5E%26*%28%29_%2B-%3D%7B%7D%7C%5B%5D%5C%3A%22%3B%27%3C%3E%3F%2C.%2F%27".to_string());
    }

    #[test]
    fn check_headers() {
        // Mock the cookie headers
        let mut headers = HeaderCollection {
            expires:    None,
            max_age:    Some(42),
            domain:     Some("example.com".to_string()),
            path:       Some("/a/path".to_string()),
            secure:     true,
            http_only:  true,
            extensions: Some(TreeMap::<String, Option<String>>::new())
        };
        headers.extensions.as_mut().unwrap().insert("foo".to_string(), Some("bar".to_string()));
        headers.extensions.as_mut().unwrap().insert("@zzmp".to_string(), None);
        assert_eq!(get_cookie(headers, None, "thing", "thing"),
            "thing=thing; Max-Age=42; Domain=example.com; Path=/a/path; Secure; Http-Only; @zzmp; foo=bar".to_string());
    }

    #[test]
    fn check_signature() {
        let headers = HeaderCollection::empty();
        assert_eq!(get_cookie(headers, Some("@zzmp".to_string()), "thing", "thung"),
            // HMAC-SHA256 of key "@zzmp" and message "thung"
            "thing=s:thung.e99abddcf60cad18f8d4b993efae53e81410cf2b2855af0309f1ae46fa527fbb".to_string());
    }

    #[test]
    fn check_json() {
        let headers = HeaderCollection::empty();
        let mut obj_map = TreeMap::new();
        obj_map.insert("foo".to_string(), String("bar".to_string()));
        let json = Object(obj_map);
        assert_eq!(get_json_cookie(headers, None, "thing", json),
            // Url component encoded JSON: {"foo":"bar"}
            "thing=j%3A%7B%22foo%22%3A%22bar%22%7D".to_string());
    }
}
<commit_msg>(test) Eradicated uninitialized.<commit_after>//! Setting functionality - set cookie data

use url::{utf8_percent_encode, FORM_URLENCODED_ENCODE_SET};
use serialize::json::{Json, Number, String, Boolean, List, Object, Null};
use iron::Response;
use super::Cookie;
use time::Tm;
use std::collections::TreeMap;

/// Set cookies.
///
/// This trait is added as a mix-in to `Response`, allowing
/// simple cookie-setting.
pub trait SetCookie {
    /// Set a cookie.
    ///
    /// Set cookies directly on the response with `res.set_cookie("coo=kie;")`.
    /// Only one cookie may sent per response, with the given key/value.
    /// Doing otherwise will result in ***undefined behavior***.
    ///
    /// Keys/values may contain restricted characters, but they will be URI encoded in the cookie.
    ///
    /// They will be decoded when the cookie is returned to the server.
    ///
    /// Cookies ***must*** be set before the response body is sent.
    /// Headers are flushed as soon anything is sent in the response body.
    fn set_cookie(&mut self, &Cookie, (String, String), HeaderCollection);

    /// Set a cookie as JSON.
    ///
    /// Cookies set as JSON will be available under `cookie.json`.
    /// Otherwise, they behave exactly as normally serialized cookies.
    ///
    /// Note that restricted characters will still be URI encoded in your cookie.
    ///
    /// They will be decoded when the cookie is returned to the server.
    fn set_json_cookie(&mut self, &Cookie, (String, Json), HeaderCollection);
}

impl SetCookie for Response {
    fn set_cookie(&mut self,
                  signer: &Cookie,
                  (key, value): (String, String),
                  options: HeaderCollection) {

        self.headers.extensions.insert("Set-Cookie".to_string(),
            match signer.sign(&value) {
                Some(signature) => {
                    utf8_percent_encode(key.as_slice(), FORM_URLENCODED_ENCODE_SET)
                        .append("=")
                        .append("s:")
                        .append(utf8_percent_encode(value.as_slice(), FORM_URLENCODED_ENCODE_SET).as_slice())
                        .append(".")
                        .append(signature.as_slice())
                },
                None            => {
                    utf8_percent_encode(key.as_slice(), FORM_URLENCODED_ENCODE_SET)
                        .append("=")
                        .append(utf8_percent_encode(value.as_slice(), FORM_URLENCODED_ENCODE_SET).as_slice())
                }
            }.append(options.to_cookie_av().as_slice())
        );
    }

    fn set_json_cookie(&mut self,
                       signer: &Cookie,
                       (key, value): (String, Json),
                       options: HeaderCollection) {
        let json = "j:".to_string().append(stringify_json(&value).as_slice());
        self.set_cookie(signer, (key, json), options)
    }
}

fn stringify_json(json: &Json) -> String {
    match *json {
        Object(ref object) => {
            let obj: Vec<String> = object.iter().map(stringify_pair).collect();
            "{".to_string().append(obj.connect(",").as_slice()).append("}")
        },
        List(ref list)     => {
            let ary: Vec<String> = list.iter().map(stringify_json).collect();
            "[".to_string().append(ary.connect(",").as_slice()).append("]")
        },
        Number(number) => number.to_string(),
        String(ref string) => "\"".to_string().append(string.as_slice()).append("\""),
        Boolean(true)      => "true".to_string(),
        Boolean(false)     => "false".to_string(),
        Null               => "null".to_string()
    }
}

fn stringify_pair((key, val): (&String, &Json)) -> String {
    "\"".to_string().append(key.as_slice()).append("\":").append(stringify_json(val).as_slice())
}

/// The headers used to set a cookie.
///
/// These headers are defined by [RFC 6265](http://tools.ietf.org/html/rfc6265)
pub struct HeaderCollection {
    /// An absolute date/time at which this cookie should expire.
    pub expires:    Option<Tm>,
    /// A relative time (in seconds) at which this cookie should expire.
    pub max_age:    Option<u32>,
    /// The scope of the cookie.
    ///
    /// If set, the browser will send this cookie to the set domain and all subdomains.
    /// If not set, the browser will only send this cookie to the originating domain.
    ///
    /// This may only be set to the sending domain and its subdomains.
    pub domain:     Option<String>,
    /// The scope of the cookie.
    pub path:       Option<String>,
    /// A cookie with this flag should only be sent over secured/encrypted connections.
    ///
    /// This will be respected by the browser.
    pub secure:     bool,
    /// A cookie with this flag is only accessible through HTTP and HTTPS.
    ///
    /// This helps to prevent Javascript and, specifically, XSS attacks.
    pub http_only:  bool,
    /// Any additional headers.
    ///
    /// This may be any sequence of valid characters.
    ///
    /// Extensions will be separated with `;`.
    /// If a value is specified in the `Map`, the extension will be
    /// written as `[key]=[value]`.
    pub extensions: Option<TreeMap<String, Option<String>>>
}

impl HeaderCollection {
    #[doc(hidden)]
    pub fn to_cookie_av(self) -> String {
        let mut options = String::new()
            .append(head("Expires", self.expires, |v| v.rfc822()).as_slice())
            .append(head("Max-Age", self.max_age, |v| v.to_string()).as_slice())
            .append(head("Domain", self.domain, |v| v).as_slice())
            .append(head("Path", self.path, |v| v).as_slice());
        if self.secure { options.push_str("; Secure"); }
        if self.http_only { options.push_str("; Http-Only"); }
        match self.extensions {
            Some(map) => {
                for (header, value) in map.iter() {
                    options.push_str(extension(header, value.clone()).as_slice());
                }
            },
            None      => ()
        }
        options
    }
}

impl HeaderCollection {
    /// Convenience function for a set of empty cookie headers
    pub fn empty() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// that will expire the cookie in `seconds` seconds
    pub fn aged(seconds: u32) -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: Some(seconds),
            domain: None,
            path: None,
            secure: false,
            http_only: false,
            extensions: None
        }
    }

    /// Convenience function for a set of cookie headers
    /// declaring the cookie `Secure` and `HttpOnly`
    pub fn secured() -> HeaderCollection {
        HeaderCollection {
            expires: None,
            max_age: None,
            domain: None,
            path: None,
            secure: true,
            http_only: true,
            extensions: None
        }
    }
}

fn head<V>(header: &str, value: Option<V>, mutator: |V| -> String) -> String {
    match value {
        Some(val) => {
            // Delimit from previous cookie/options
            "; ".to_string()
            // Add the header
                .append(header).append("=")
            // Add the mutated value
                .append(mutator(val).as_slice())
        },
        None      => String::new()
    }
}

fn extension(header: &String, value: Option<String>) -> String {
    match value {
        Some(val) => head(header.as_slice(), Some(val), |v| v),
        None      => "; ".to_string().append(header.as_slice())
    }
}

#[cfg(test)]
mod test {
    use std::collections::TreeMap;
    use super::*;
    use super::super::cookie::*;
    use serialize::json::{Json, Object, String};
    use test::mock::response;

    // Set a cookie and return its set value
    fn get_cookie<'a>(headers: HeaderCollection, secret: Option<String>, key: &str, value: &str) -> String {
        let mut res = response::new();
        let signer = Cookie::new(secret);
        let cookie = (key.to_string(), value.to_string());
        res.set_cookie(&signer, cookie, headers);
        res.headers.extensions.find(&"Set-Cookie".to_string()).unwrap().clone()
    }

    // Set a JSON cookie and return its set value
    fn get_json_cookie<'a>(headers: HeaderCollection, secret: Option<String>, key: &str, value: Json) -> String {
        let mut res = response::new();
        let signer = Cookie::new(secret);
        let cookie = (key.to_string(), value);
        res.set_json_cookie(&signer, cookie, headers);
        res.headers.extensions.find(&"Set-Cookie".to_string()).unwrap().clone()
    }

    #[test]
    fn check_stringify_json() {
        let mut obj_map = TreeMap::new();
        obj_map.insert("foo".to_string(), String("bar".to_string()));
        let json = Object(obj_map);
        assert_eq!("{\"foo\":\"bar\"}".to_string(), super::stringify_json(&json)) // FIXME
    }

    #[test]
    fn check_cookie() {
        let headers = HeaderCollection::empty();
        assert_eq!(get_cookie(headers, None, "thing", "thing"), "thing=thing".to_string());
    }

    #[test]
    fn check_escaping() {
        let headers = HeaderCollection::empty();
        assert_eq!(get_cookie(headers, None, "~`!@#$%^&*()_+-={}|[]\\:\";'<>?,./'", "~`!@#$%^&*()_+-={}|[]\\:\";'<>?,./'"),
            // Url component encoding should escape these characters
            "~%60%21%40%23%24%25%5E%26*%28%29_%2B-%3D%7B%7D%7C%5B%5D%5C%3A%22%3B%27%3C%3E%3F%2C.%2F%27=\
             ~%60%21%40%23%24%25%5E%26*%28%29_%2B-%3D%7B%7D%7C%5B%5D%5C%3A%22%3B%27%3C%3E%3F%2C.%2F%27".to_string());
    }

    #[test]
    fn check_headers() {
        // Mock the cookie headers
        let mut headers = HeaderCollection {
            expires:    None,
            max_age:    Some(42),
            domain:     Some("example.com".to_string()),
            path:       Some("/a/path".to_string()),
            secure:     true,
            http_only:  true,
            extensions: Some(TreeMap::<String, Option<String>>::new())
        };
        headers.extensions.as_mut().unwrap().insert("foo".to_string(), Some("bar".to_string()));
        headers.extensions.as_mut().unwrap().insert("@zzmp".to_string(), None);
        assert_eq!(get_cookie(headers, None, "thing", "thing"),
            "thing=thing; Max-Age=42; Domain=example.com; Path=/a/path; Secure; Http-Only; @zzmp; foo=bar".to_string());
    }

    #[test]
    fn check_signature() {
        let headers = HeaderCollection::empty();
        assert_eq!(get_cookie(headers, Some("@zzmp".to_string()), "thing", "thung"),
            // HMAC-SHA256 of key "@zzmp" and message "thung"
            "thing=s:thung.e99abddcf60cad18f8d4b993efae53e81410cf2b2855af0309f1ae46fa527fbb".to_string());
    }

    #[test]
    fn check_json() {
        let headers = HeaderCollection::empty();
        let mut obj_map = TreeMap::new();
        obj_map.insert("foo".to_string(), String("bar".to_string()));
        let json = Object(obj_map);
        assert_eq!(get_json_cookie(headers, None, "thing", json),
            // Url component encoded JSON: {"foo":"bar"}
            "thing=j%3A%7B%22foo%22%3A%22bar%22%7D".to_string());
    }
}
<|endoftext|>


<commit_before><commit_msg>Add Clone derivation for all gradebook-related structs<commit_after><|endoftext|>


<commit_before><commit_msg>DNS-based get_host_by_name().<commit_after>use std::{io, mem};
use std::net::IpAddr;
use std::str::FromStr;
use domain::bits::DNameBuf;
use domain::resolv::Resolver;
use domain::resolv::lookup::host::{lookup_host, FoundHosts, LookupHost};
use futures::{Async, Future, Poll};
use tokio_core::reactor;

//============ Low-level API =================================================

//pub mod files;

//============ High-level API ================================================

pub fn get_host_by_name(name: &str) -> Result<HostEnt, io::Error> {
    let mut core = reactor::Core::new()?;
    let handle = core.handle();
    core.run(poll_host_by_name(name, &handle))
}

pub fn get_host_by_addr(addr: IpAddr) -> Result<HostEnt, io::Error> {
    let mut core = reactor::Core::new()?;
    let handle = core.handle();
    core.run(poll_host_by_addr(addr, &handle))
}

/// Returns host information for a given host name.
///
/// The name is either a hostname, an IPv4 or IPv6 address in its standard
/// text notation. In the latter two cases, no lookups are performed and a
/// `HostEnt` is returned with `name` as the canonical name, the parsed
/// address as the sole address, and no aliases.
///
/// Otherwise the name is interpreted as a host name and lookups according to
/// the system configuraition are performed.
///
/// The function returns a future that performes all necessary IO via the
/// tokio reactor given by `reactor`.
///
/// # Limitations
///
/// For this initial version of the crate, the lookup is a `files` lookup
/// first and only if that does not succeed, a DNS query for both A and AAAA
/// records. This initial version also does not yet fill the aliases list of
/// the returned `HostEnt`.
pub fn poll_host_by_name(name: &str, reactor: &reactor::Handle)
                         -> HostByNameFuture {
    HostByNameFuture::new(name, reactor)
}

pub fn poll_host_by_addr(addr: IpAddr, reactor: &reactor::Handle)
                         -> HostByAddrFuture {
    unimplemented!()
}

//------------ HostEnt -------------------------------------------------------

pub struct HostEnt {
    pub name: String,
    pub aliases: Vec<String>,
    pub addrs: Vec<IpAddr>,
}

impl From<FoundHosts> for HostEnt {
    fn from(found: FoundHosts) -> HostEnt {
        HostEnt {
            name: format!("{}", found.canonical_name()),
            aliases: Vec::new(),
            addrs: found.iter().collect(),
        }
    }
}

//------------ HostByNameFuture ----------------------------------------------

pub struct HostByNameFuture(ByNameInner);

enum ByNameInner {
    Dns(LookupHost),
    Error(io::Error),
    Done,
}

impl HostByNameFuture {
    pub fn new(name: &str, reactor: &reactor::Handle) -> Self {
        let name = match DNameBuf::from_str(name) {
            Ok(name) => name,
            Err(e) => {
                return HostByNameFuture(ByNameInner::Error(
                    io::Error::new(io::ErrorKind::Other, e)
                ))
            }
        };
        HostByNameFuture(ByNameInner::Dns(lookup_host(Resolver::new(reactor),
                                                      name)))
    }
}

impl Future for HostByNameFuture {
    type Item = HostEnt;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match self.0 {
            ByNameInner::Dns(ref mut lookup) => {
                let found = match lookup.poll() {
                    Ok(Async::NotReady) => return Ok(Async::NotReady),
                    Ok(Async::Ready(found)) => found,
                    Err(err) => {
                        return Err(io::Error::new(io::ErrorKind::Other, err))
                    }
                };
                return Ok(Async::Ready(found.into()))
            }
            _ => { }
        }
        match mem::replace(&mut self.0, ByNameInner::Done) {
            ByNameInner::Error(err) => Err(err),
            ByNameInner::Done => panic!("polling a resolved HostByNameFuture"),
            _ => panic!()
        }
    }
}

//------------ HostByAddrFuture ----------------------------------------------

pub struct HostByAddrFuture;

impl Future for HostByAddrFuture {
    type Item = HostEnt;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        unimplemented!()
    }
}

<|endoftext|>


<commit_before>use std::io;

macro_rules! readln {
    () => {
        {
            let mut line = String::new();
            match io::stdin().read_line(&mut line) {
                Ok(n) => Some(line.trim().to_string()),
                Err(e) => None
            }
        }
    };
}

fn console_title(title: &str){

}

#[no_mangle]
pub fn main() {
    console_title("Test");

    println!("Type help for a command list");
    while let Some(line) = readln!() {
        let mut args: Vec<String> = Vec::new();
        for arg in line.split(' ') {
            args.push(arg.to_string());
        }

        if let Some(command) = args.get(0) {
            println!("# {}", line);

            if command == "panic" {
                panic!("Test panic");
            } else {
                println!("Commands: panic");
            }
        }
    }
}
<commit_msg>Style<commit_after>use std::io;

macro_rules! readln {
    () => {
        {
            let mut line = String::new();
            match io::stdin().read_line(&mut line) {
                Ok(n) => Some(line.trim().to_string()),
                Err(e) => None
            }
        }
    };
}

fn console_title(title: &str) {

}

#[no_mangle]
pub fn main() {
    console_title("Test");

    println!("Type help for a command list");
    while let Some(line) = readln!() {
        let mut args: Vec<String> = Vec::new();
        for arg in line.split(' ') {
            args.push(arg.to_string());
        }

        if let Some(command) = args.get(0) {
            println!("# {}", line);

            if command == "panic" {
                panic!("Test panic");
            } else {
                println!("Commands: panic");
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example usage in docs<commit_after><|endoftext|>


<commit_before><commit_msg>The event_type is never used<commit_after><|endoftext|>


<commit_before><commit_msg>clear syntax<commit_after><|endoftext|>


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

// verify that an error is raised when trying to move out of a
// borrowed path.

fn main() {
    let a = ~~2;
    let b = &a;

    let z = *a; //~ ERROR: cannot move out of `*a` because it is borrowed
}
<|endoftext|>


<commit_before><commit_msg>Pass the path to the ui builder function when creating a mock application<commit_after><|endoftext|>


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

extern crate cgmath;
#[macro_use]
extern crate gfx;
extern crate gfx_core;
extern crate gfx_window_glfw;
extern crate glfw;
extern crate time;
extern crate gfx_gl as gl;
extern crate gfx_device_gl;

use time::precise_time_s;
use cgmath::{SquareMatrix, Matrix, Point3, Vector3, Matrix3, Matrix4};
use cgmath::{Transform, Vector4};
pub use gfx::format::{DepthStencil, Rgba8 as ColorBuffer};
use glfw::Context;
use gl::Gl;
use gl::types::*;
use std::mem;
use std::ptr;
use std::str;
use std::env;
use std::str::FromStr;
use std::iter::repeat;
use std::ffi::CString;
use gfx_device_gl::{Resources as R, CommandBuffer as CB};
use gfx_core::Device;

gfx_defines!{
    vertex Vertex {
        pos: [f32; 3] = "a_Pos",
    }

    pipeline pipe {
        vbuf: gfx::VertexBuffer<Vertex> = (),
        transform: gfx::Global<[[f32; 4]; 4]> = "u_Transform",
        out_color: gfx::RenderTarget<ColorBuffer> = "o_Color",
    }
}

static VERTEX_SRC: &'static [u8] = b"
    #version 150 core
    in vec3 a_Pos;
    uniform mat4 u_Transform;

    void main() {
        gl_Position = u_Transform * vec4(a_Pos, 1.0);
   }
";

static FRAGMENT_SRC: &'static [u8] = b"
    #version 150 core
    out vec4 o_Color;

    void main() {
        o_Color = vec4(1.0, 0.0, 0.0, 1.0);
    }
";

static VERTEX_DATA: &'static [Vertex] = &[
    Vertex { pos: [-1.0, 0.0, -1.0] },
    Vertex { pos: [ 1.0, 0.0, -1.0] },
    Vertex { pos: [-1.0, 0.0,  1.0] },
];

const CLEAR_COLOR: (f32, f32, f32, f32) = (0.3, 0.3, 0.3, 1.0);

//----------------------------------------

fn transform(x: i16, y: i16, proj_view: &Matrix4<f32>) -> Matrix4<f32> {
    let mut model = Matrix4::from(Matrix3::identity() * 0.05);
    model.w = Vector4::new(x as f32 * 0.10,
                           0f32,
                           y as f32 * 0.10,
                           1f32);
    proj_view * model
}

trait Renderer: Drop {
    fn render(&mut self, window: &mut glfw::Window, proj_view: &Matrix4<f32>);
}

struct GFX {
    device:gfx_device_gl::Device,
    encoder: gfx::Encoder<R,CB>,
    data: pipe::Data<R>,
    pso: gfx::PipelineState<R, pipe::Meta>,
    slice: gfx::Slice<R>,
    dimension: i16,
}

impl GFX {
    fn new(window: &mut glfw::Window, dimension: i16) -> Self {
        use gfx::traits::FactoryExt;

        let (device, mut factory, main_color, _) =
            gfx_window_glfw::init(window);
        let encoder: gfx::Encoder<_,_> = factory.create_command_buffer().into();

        let pso = factory.create_pipeline_simple(
            VERTEX_SRC, FRAGMENT_SRC,
            gfx::state::CullFace::Nothing,
            pipe::new()
        ).unwrap();

        let (vbuf, slice) = factory.create_vertex_buffer_with_slice(VERTEX_DATA,());

        let data = pipe::Data {
            vbuf: vbuf,
            transform: cgmath::Matrix4::identity().into(),
            out_color: main_color,
        };

        GFX {
            device: device,
            encoder: encoder,
            data: data,
            pso: pso,
            slice: slice,
            dimension: dimension,
        }
    }
}

impl Renderer for GFX {
    fn render(&mut self, window: &mut glfw::Window, proj_view:&Matrix4<f32>) {
        let start = precise_time_s() * 1000.;
        self.encoder.clear(&self.data.out_color, [CLEAR_COLOR.0,
                                                  CLEAR_COLOR.1,
                                                  CLEAR_COLOR.2,
                                                  CLEAR_COLOR.3]);

        for x in (-self.dimension) ..self.dimension {
            for y in (-self.dimension) ..self.dimension {
                self.data.transform = transform(x, y, proj_view).into();
                self.encoder.draw(&self.slice, &self.pso, &self.data);
            }
        }

        let pre_submit = precise_time_s() * 1000.;
        self.encoder.flush(&mut self.device);
        let post_submit = precise_time_s() * 1000.;
        window.swap_buffers();
        self.device.cleanup();
        let swap = precise_time_s() * 1000.;

        println!("total time:\t\t{0:4.2}ms", swap - start);
        println!("\tcreate list:\t{0:4.2}ms", pre_submit - start);
        println!("\tsubmit:\t\t{0:4.2}ms", post_submit - pre_submit);
        println!("\tgpu wait:\t{0:4.2}ms", swap - post_submit);
    }
}

impl Drop for GFX {
    fn drop(&mut self) {
    }
}

struct GL {
    gl:Gl,
    trans_uniform:GLint,
    vs:GLuint,
    fs:GLuint,
    program:GLuint,
    vbo:GLuint,
    vao:GLuint,
    dimension:i16,
}

impl GL {
    fn new(window: &mut glfw::Window, dimension: i16) -> Self {
        let gl = Gl::load_with(|s| window.get_proc_address(s) as *const _);

        fn compile_shader (gl:&Gl, src: &[u8], ty: GLenum) -> GLuint {
            unsafe {
                let shader = gl.CreateShader(ty);
                // Attempt to compile the shader
                gl.ShaderSource(shader, 1,
                                &(src.as_ptr() as *const i8),
                                &(src.len() as GLint));
                gl.CompileShader(shader);

                // Get the compile status
                let mut status = gl::FALSE as GLint;
                gl.GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

                // Fail on error
                if status != (gl::TRUE as GLint) {
                    let mut len: GLint = 0;
                    gl.GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
                    let mut buf: Vec<u8> = repeat(0u8).take((len as isize).saturating_sub(1) as usize).collect();     // subtract 1 to skip the trailing null character
                    gl.GetShaderInfoLog(shader, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
                    panic!("{}", str::from_utf8(&buf).ok().expect("ShaderInfoLog not valid utf8"));
                }
                shader
            }
        };

        // Create GLSL shaders
        let vs = compile_shader(&gl, VERTEX_SRC, gl::VERTEX_SHADER);
        let fs = compile_shader(&gl, FRAGMENT_SRC, gl::FRAGMENT_SHADER);

        // Link program
        let program;
        unsafe {
            program = gl.CreateProgram();
            gl.AttachShader(program, vs);
            gl.AttachShader(program, fs);
            gl.LinkProgram(program);
            // Get the link status
            let mut status = gl::FALSE as GLint;
            gl.GetProgramiv(program, gl::LINK_STATUS, &mut status);

            // Fail on error
            if status != (gl::TRUE as GLint) {
                let mut len: GLint = 0;
                gl.GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
                let mut buf: Vec<u8> = repeat(0u8).take((len as isize).saturating_sub(1) as usize).collect();     // subtract 1 to skip the trailing null character
                gl.GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
                panic!("{}", str::from_utf8(&buf).ok().expect("ProgramInfoLog not valid utf8"));
            }
        }

        let mut vao = 0;
        let mut vbo = 0;

        let trans_uniform;
        unsafe {
            // Create Vertex Array Object
            gl.GenVertexArrays(1, &mut vao);
            gl.BindVertexArray(vao);

            // Create a Vertex Buffer Object and copy the vertex data to it
            gl.GenBuffers(1, &mut vbo);
            gl.BindBuffer(gl::ARRAY_BUFFER, vbo);

            gl.BufferData(gl::ARRAY_BUFFER,
                          (VERTEX_DATA.len() * mem::size_of::<Vertex>()) as GLsizeiptr,
                          mem::transmute(&VERTEX_DATA[0]),
                          gl::STATIC_DRAW);

            // Use shader program
            gl.UseProgram(program);
            let o_color = CString::new("o_Color").unwrap();
            gl.BindFragDataLocation(program, 0, o_color.as_bytes_with_nul().as_ptr() as *const i8);

            // Specify the layout of the vertex data
            let a_pos = CString::new("a_Pos").unwrap();
            gl.BindFragDataLocation(program, 0, a_pos.as_bytes_with_nul().as_ptr() as *const i8);

            let pos_attr = gl.GetAttribLocation(program, a_pos.as_ptr());
            gl.EnableVertexAttribArray(pos_attr as GLuint);
            gl.VertexAttribPointer(pos_attr as GLuint, 3, gl::FLOAT,
                                   gl::FALSE as GLboolean, 0, ptr::null());

            let u_transform = CString::new("u_Transform").unwrap();
            trans_uniform = gl.GetUniformLocation(program, u_transform.as_bytes_with_nul().as_ptr() as *const i8)
        };

        GL {
            gl: gl,
            vs: vs,
            fs: fs,
            program: program,
            vbo: vbo,
            vao: vao,
            trans_uniform: trans_uniform,
            dimension: dimension,
        }
    }
}

impl Renderer for GL {
    fn render(&mut self, window: &mut glfw::Window, proj_view: &Matrix4<f32>) {
        let start = precise_time_s() * 1000.;

        // Clear the screen to black
        unsafe {
            self.gl.ClearColor(CLEAR_COLOR.0, CLEAR_COLOR.1, CLEAR_COLOR.2, CLEAR_COLOR.3);
            self.gl.Clear(gl::COLOR_BUFFER_BIT);
        }

        for x in (-self.dimension) ..self.dimension {
            for y in (-self.dimension) ..self.dimension {
                let mat:Matrix4<f32> = transform(x, y, proj_view).into();

                unsafe {
                    self.gl.UniformMatrix4fv(self.trans_uniform,
                                             1,
                                             gl::FALSE,
                                             mat.as_ptr());
                    self.gl.DrawArrays(gl::TRIANGLES, 0, 3);
                }

            }
        }

        let submit = precise_time_s() * 1000.;

        // Swap buffers
        window.swap_buffers();
        let swap = precise_time_s() * 1000.;

        println!("total time:\t\t{0:4.2}ms", swap - start);
        println!("\tsubmit:\t\t{0:4.2}ms", submit - start);
        println!("\tgpu wait:\t{0:4.2}ms", swap - submit)
    }
}

impl Drop for GL {
    fn drop(&mut self) {
        unsafe {
            self.gl.DeleteProgram(self.program);
            self.gl.DeleteShader(self.fs);
            self.gl.DeleteShader(self.vs);
            self.gl.DeleteBuffers(1, &self.vbo);
            self.gl.DeleteVertexArrays(1, &self.vao);
        }
    }
}

fn main() {
    let ref mut args = env::args();
    let args_count = env::args().count();
    if args_count == 1 {
        println!("gfx-perf [gl|gfx] <size>");
        return;
    }

    let mode = args.nth(1).unwrap();
    let count: i32 = if args_count == 3 {
        FromStr::from_str(&args.next().unwrap()).ok()
    } else {
        None
    }.unwrap_or(10000);

    let count = ((count as f64).sqrt() / 2.) as i16;

    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS)
        .ok().expect("Failed to initialize glfw-rs");

    glfw.window_hint(glfw::WindowHint::ContextVersion(3, 2));
    glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
    glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));

    let (mut window, events) = glfw
        .create_window(640, 480, "Performance example", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.make_current();
    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    let proj_view = {
        let view = Matrix4::look_at(
            Point3::new(0f32, 5.0, -5.0),
            Point3::new(0f32, 0.0, 0.0),
            Vector3::unit_z(),
        );

        let proj = {
            let aspect = {
                let (w, h) = window.get_framebuffer_size();
                w as f32 / h as f32
            };
            cgmath::perspective(cgmath::deg(45.0f32), aspect, 1.0, 10.0)
        };
        proj * view
    };

    let mut r: Box<Renderer>;
    match mode.as_ref() {
        "gfx" => r = Box::new(GFX::new(&mut window, count)),
        "gl" => r = Box::new(GL::new(&mut window, count)),
        x => {
            panic!("{} is not a known mode", x)
        }
    }

    println!("count is {}", count*count*4);

    while !window.should_close() {
        // Poll events
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _) =>
                    window.set_should_close(true),
                _ => {},
            }
        }
        r.render(&mut window, &proj_view);
    }
}
<commit_msg>Changed ColorBuffer to ColorFormat<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate cgmath;
#[macro_use]
extern crate gfx;
extern crate gfx_core;
extern crate gfx_window_glfw;
extern crate glfw;
extern crate time;
extern crate gfx_gl as gl;
extern crate gfx_device_gl;

use time::precise_time_s;
use cgmath::{SquareMatrix, Matrix, Point3, Vector3, Matrix3, Matrix4};
use cgmath::{Transform, Vector4};
pub use gfx::format::{DepthStencil, Rgba8 as ColorFormat};
use glfw::Context;
use gl::Gl;
use gl::types::*;
use std::mem;
use std::ptr;
use std::str;
use std::env;
use std::str::FromStr;
use std::iter::repeat;
use std::ffi::CString;
use gfx_device_gl::{Resources as R, CommandBuffer as CB};
use gfx_core::Device;

gfx_defines!{
    vertex Vertex {
        pos: [f32; 3] = "a_Pos",
    }

    pipeline pipe {
        vbuf: gfx::VertexBuffer<Vertex> = (),
        transform: gfx::Global<[[f32; 4]; 4]> = "u_Transform",
        out_color: gfx::RenderTarget<ColorFormat> = "o_Color",
    }
}

static VERTEX_SRC: &'static [u8] = b"
    #version 150 core
    in vec3 a_Pos;
    uniform mat4 u_Transform;

    void main() {
        gl_Position = u_Transform * vec4(a_Pos, 1.0);
   }
";

static FRAGMENT_SRC: &'static [u8] = b"
    #version 150 core
    out vec4 o_Color;

    void main() {
        o_Color = vec4(1.0, 0.0, 0.0, 1.0);
    }
";

static VERTEX_DATA: &'static [Vertex] = &[
    Vertex { pos: [-1.0, 0.0, -1.0] },
    Vertex { pos: [ 1.0, 0.0, -1.0] },
    Vertex { pos: [-1.0, 0.0,  1.0] },
];

const CLEAR_COLOR: (f32, f32, f32, f32) = (0.3, 0.3, 0.3, 1.0);

//----------------------------------------

fn transform(x: i16, y: i16, proj_view: &Matrix4<f32>) -> Matrix4<f32> {
    let mut model = Matrix4::from(Matrix3::identity() * 0.05);
    model.w = Vector4::new(x as f32 * 0.10,
                           0f32,
                           y as f32 * 0.10,
                           1f32);
    proj_view * model
}

trait Renderer: Drop {
    fn render(&mut self, window: &mut glfw::Window, proj_view: &Matrix4<f32>);
}

struct GFX {
    device:gfx_device_gl::Device,
    encoder: gfx::Encoder<R,CB>,
    data: pipe::Data<R>,
    pso: gfx::PipelineState<R, pipe::Meta>,
    slice: gfx::Slice<R>,
    dimension: i16,
}

impl GFX {
    fn new(window: &mut glfw::Window, dimension: i16) -> Self {
        use gfx::traits::FactoryExt;

        let (device, mut factory, main_color, _) =
            gfx_window_glfw::init(window);
        let encoder: gfx::Encoder<_,_> = factory.create_command_buffer().into();

        let pso = factory.create_pipeline_simple(
            VERTEX_SRC, FRAGMENT_SRC,
            gfx::state::CullFace::Nothing,
            pipe::new()
        ).unwrap();

        let (vbuf, slice) = factory.create_vertex_buffer_with_slice(VERTEX_DATA,());

        let data = pipe::Data {
            vbuf: vbuf,
            transform: cgmath::Matrix4::identity().into(),
            out_color: main_color,
        };

        GFX {
            device: device,
            encoder: encoder,
            data: data,
            pso: pso,
            slice: slice,
            dimension: dimension,
        }
    }
}

impl Renderer for GFX {
    fn render(&mut self, window: &mut glfw::Window, proj_view:&Matrix4<f32>) {
        let start = precise_time_s() * 1000.;
        self.encoder.clear(&self.data.out_color, [CLEAR_COLOR.0,
                                                  CLEAR_COLOR.1,
                                                  CLEAR_COLOR.2,
                                                  CLEAR_COLOR.3]);

        for x in (-self.dimension) ..self.dimension {
            for y in (-self.dimension) ..self.dimension {
                self.data.transform = transform(x, y, proj_view).into();
                self.encoder.draw(&self.slice, &self.pso, &self.data);
            }
        }

        let pre_submit = precise_time_s() * 1000.;
        self.encoder.flush(&mut self.device);
        let post_submit = precise_time_s() * 1000.;
        window.swap_buffers();
        self.device.cleanup();
        let swap = precise_time_s() * 1000.;

        println!("total time:\t\t{0:4.2}ms", swap - start);
        println!("\tcreate list:\t{0:4.2}ms", pre_submit - start);
        println!("\tsubmit:\t\t{0:4.2}ms", post_submit - pre_submit);
        println!("\tgpu wait:\t{0:4.2}ms", swap - post_submit);
    }
}

impl Drop for GFX {
    fn drop(&mut self) {
    }
}

struct GL {
    gl:Gl,
    trans_uniform:GLint,
    vs:GLuint,
    fs:GLuint,
    program:GLuint,
    vbo:GLuint,
    vao:GLuint,
    dimension:i16,
}

impl GL {
    fn new(window: &mut glfw::Window, dimension: i16) -> Self {
        let gl = Gl::load_with(|s| window.get_proc_address(s) as *const _);

        fn compile_shader (gl:&Gl, src: &[u8], ty: GLenum) -> GLuint {
            unsafe {
                let shader = gl.CreateShader(ty);
                // Attempt to compile the shader
                gl.ShaderSource(shader, 1,
                                &(src.as_ptr() as *const i8),
                                &(src.len() as GLint));
                gl.CompileShader(shader);

                // Get the compile status
                let mut status = gl::FALSE as GLint;
                gl.GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

                // Fail on error
                if status != (gl::TRUE as GLint) {
                    let mut len: GLint = 0;
                    gl.GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
                    let mut buf: Vec<u8> = repeat(0u8).take((len as isize).saturating_sub(1) as usize).collect();     // subtract 1 to skip the trailing null character
                    gl.GetShaderInfoLog(shader, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
                    panic!("{}", str::from_utf8(&buf).ok().expect("ShaderInfoLog not valid utf8"));
                }
                shader
            }
        };

        // Create GLSL shaders
        let vs = compile_shader(&gl, VERTEX_SRC, gl::VERTEX_SHADER);
        let fs = compile_shader(&gl, FRAGMENT_SRC, gl::FRAGMENT_SHADER);

        // Link program
        let program;
        unsafe {
            program = gl.CreateProgram();
            gl.AttachShader(program, vs);
            gl.AttachShader(program, fs);
            gl.LinkProgram(program);
            // Get the link status
            let mut status = gl::FALSE as GLint;
            gl.GetProgramiv(program, gl::LINK_STATUS, &mut status);

            // Fail on error
            if status != (gl::TRUE as GLint) {
                let mut len: GLint = 0;
                gl.GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
                let mut buf: Vec<u8> = repeat(0u8).take((len as isize).saturating_sub(1) as usize).collect();     // subtract 1 to skip the trailing null character
                gl.GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
                panic!("{}", str::from_utf8(&buf).ok().expect("ProgramInfoLog not valid utf8"));
            }
        }

        let mut vao = 0;
        let mut vbo = 0;

        let trans_uniform;
        unsafe {
            // Create Vertex Array Object
            gl.GenVertexArrays(1, &mut vao);
            gl.BindVertexArray(vao);

            // Create a Vertex Buffer Object and copy the vertex data to it
            gl.GenBuffers(1, &mut vbo);
            gl.BindBuffer(gl::ARRAY_BUFFER, vbo);

            gl.BufferData(gl::ARRAY_BUFFER,
                          (VERTEX_DATA.len() * mem::size_of::<Vertex>()) as GLsizeiptr,
                          mem::transmute(&VERTEX_DATA[0]),
                          gl::STATIC_DRAW);

            // Use shader program
            gl.UseProgram(program);
            let o_color = CString::new("o_Color").unwrap();
            gl.BindFragDataLocation(program, 0, o_color.as_bytes_with_nul().as_ptr() as *const i8);

            // Specify the layout of the vertex data
            let a_pos = CString::new("a_Pos").unwrap();
            gl.BindFragDataLocation(program, 0, a_pos.as_bytes_with_nul().as_ptr() as *const i8);

            let pos_attr = gl.GetAttribLocation(program, a_pos.as_ptr());
            gl.EnableVertexAttribArray(pos_attr as GLuint);
            gl.VertexAttribPointer(pos_attr as GLuint, 3, gl::FLOAT,
                                   gl::FALSE as GLboolean, 0, ptr::null());

            let u_transform = CString::new("u_Transform").unwrap();
            trans_uniform = gl.GetUniformLocation(program, u_transform.as_bytes_with_nul().as_ptr() as *const i8)
        };

        GL {
            gl: gl,
            vs: vs,
            fs: fs,
            program: program,
            vbo: vbo,
            vao: vao,
            trans_uniform: trans_uniform,
            dimension: dimension,
        }
    }
}

impl Renderer for GL {
    fn render(&mut self, window: &mut glfw::Window, proj_view: &Matrix4<f32>) {
        let start = precise_time_s() * 1000.;

        // Clear the screen to black
        unsafe {
            self.gl.ClearColor(CLEAR_COLOR.0, CLEAR_COLOR.1, CLEAR_COLOR.2, CLEAR_COLOR.3);
            self.gl.Clear(gl::COLOR_BUFFER_BIT);
        }

        for x in (-self.dimension) ..self.dimension {
            for y in (-self.dimension) ..self.dimension {
                let mat:Matrix4<f32> = transform(x, y, proj_view).into();

                unsafe {
                    self.gl.UniformMatrix4fv(self.trans_uniform,
                                             1,
                                             gl::FALSE,
                                             mat.as_ptr());
                    self.gl.DrawArrays(gl::TRIANGLES, 0, 3);
                }

            }
        }

        let submit = precise_time_s() * 1000.;

        // Swap buffers
        window.swap_buffers();
        let swap = precise_time_s() * 1000.;

        println!("total time:\t\t{0:4.2}ms", swap - start);
        println!("\tsubmit:\t\t{0:4.2}ms", submit - start);
        println!("\tgpu wait:\t{0:4.2}ms", swap - submit)
    }
}

impl Drop for GL {
    fn drop(&mut self) {
        unsafe {
            self.gl.DeleteProgram(self.program);
            self.gl.DeleteShader(self.fs);
            self.gl.DeleteShader(self.vs);
            self.gl.DeleteBuffers(1, &self.vbo);
            self.gl.DeleteVertexArrays(1, &self.vao);
        }
    }
}

fn main() {
    let ref mut args = env::args();
    let args_count = env::args().count();
    if args_count == 1 {
        println!("gfx-perf [gl|gfx] <size>");
        return;
    }

    let mode = args.nth(1).unwrap();
    let count: i32 = if args_count == 3 {
        FromStr::from_str(&args.next().unwrap()).ok()
    } else {
        None
    }.unwrap_or(10000);

    let count = ((count as f64).sqrt() / 2.) as i16;

    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS)
        .ok().expect("Failed to initialize glfw-rs");

    glfw.window_hint(glfw::WindowHint::ContextVersion(3, 2));
    glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
    glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));

    let (mut window, events) = glfw
        .create_window(640, 480, "Performance example", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.make_current();
    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    let proj_view = {
        let view = Matrix4::look_at(
            Point3::new(0f32, 5.0, -5.0),
            Point3::new(0f32, 0.0, 0.0),
            Vector3::unit_z(),
        );

        let proj = {
            let aspect = {
                let (w, h) = window.get_framebuffer_size();
                w as f32 / h as f32
            };
            cgmath::perspective(cgmath::deg(45.0f32), aspect, 1.0, 10.0)
        };
        proj * view
    };

    let mut r: Box<Renderer>;
    match mode.as_ref() {
        "gfx" => r = Box::new(GFX::new(&mut window, count)),
        "gl" => r = Box::new(GL::new(&mut window, count)),
        x => {
            panic!("{} is not a known mode", x)
        }
    }

    println!("count is {}", count*count*4);

    while !window.should_close() {
        // Poll events
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _) =>
                    window.set_should_close(true),
                _ => {},
            }
        }
        r.render(&mut window, &proj_view);
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove unused imports/code<commit_after><|endoftext|>


<commit_before><commit_msg>Add a regression test for issue-68951<commit_after>// check-pass

fn main() {
    let array = [0x42u8; 10];
    for b in &array {
        let lo = b & 0xf;
        let hi = (b >> 4) & 0xf;
    }
}
<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>