<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 container::Container;
use comm::{Sender, Receiver};
use io;
use option::{None, Option, Some};
use result::{Ok, Err};
use super::{Reader, Writer, IoResult};
use str::StrSlice;
use slice::{bytes, CloneableVector, MutableVector, ImmutableVector};

/// 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<~[u8]>,  // A buffer of bytes received but not consumed.
    pos: uint,           // How many of the buffered bytes have already be consumed.
    rx: Receiver<~[u8]>,   // The rx to pull data from.
    closed: bool,        // Whether the pipe this rx connects to has been closed.
}

impl ChanReader {
    /// Wraps a `Port` in a `ChanReader` structure
    pub fn new(rx: Receiver<~[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_slice_from(num_read);
                    let src = prev.slice_from(self.pos);
                    let count = cmp::min(dst.len(), src.len());
                    bytes::copy_memory(dst, src.slice_to(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<~[u8]>,
}

impl ChanWriter {
    /// Wraps a channel in a `ChanWriter` structure
    pub fn new(tx: Sender<~[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_owned()).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(box [1u8, 2u8]);
          tx.send(box []);
          tx.send(box [3u8, 4u8]);
          tx.send(box [5u8, 6u8]);
          tx.send(box [7u8, 8u8]);
        });

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

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

        assert_eq!(Ok(3), reader.read(buf));
        assert_eq!(box [1,2,3], buf);

        assert_eq!(Ok(3), reader.read(buf));
        assert_eq!(box [4,5,6], buf);

        assert_eq!(Ok(2), reader.read(buf));
        assert_eq!(box [7,8,6], buf);

        match reader.read(buf) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(box [7,8,6], buf);

        // Ensure it continues to fail in the same way.
        match reader.read(buf) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(box [7,8,6], buf);
    }

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

        let wanted = box [0u8, 0u8, 0u8, 42u8];
        let got = task::try(proc() { rx.recv() }).unwrap();
        assert_eq!(wanted, got);

        match writer.write_u8(1) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::BrokenPipe),
        }
    }
}
<commit_msg>auto merge of #14765 : 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 container::Container;
use comm::{Sender, Receiver};
use io;
use option::{None, Option, Some};
use result::{Ok, Err};
use super::{Reader, Writer, IoResult};
use str::StrSlice;
use slice::{bytes, MutableVector, ImmutableVector};
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_slice_from(num_read);
                    let src = prev.slice_from(self.pos);
                    let count = cmp::min(dst.len(), src.len());
                    bytes::copy_memory(dst, src.slice_to(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(Vec::from_slice(buf)).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));
        assert_eq!(&[1,2,3], buf.as_slice());

        assert_eq!(Ok(3), reader.read(buf));
        assert_eq!(&[4,5,6], buf.as_slice());

        assert_eq!(Ok(2), reader.read(buf));
        assert_eq!(&[7,8,6], buf.as_slice());

        match reader.read(buf) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(&[7,8,6], buf.as_slice());

        // Ensure it continues to fail in the same way.
        match reader.read(buf) {
            Ok(..) => fail!(),
            Err(e) => assert_eq!(e.kind, io::EndOfFile),
        }
        assert_eq!(&[7,8,6], 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 = task::try(proc() { rx.recv() }).unwrap();
        assert_eq!(wanted, got);

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


<commit_before>//! Implementation of mio for Windows using IOCP
//!
//! This module uses I/O Completion Ports (IOCP) on Windows to implement mio's
//! Unix epoll-like interface. Unfortunately these two I/O models are
//! fundamentally incompatible:
//!
//! * IOCP is a completion-based model where work is submitted to the kernel and
//!   a program is notified later when the work finished.
//! * epoll is a readiness-based model where the kernel is queried as to what
//!   work can be done, and afterwards the work is done.
//!
//! As a result, this implementation for Windows is much less "low level" than
//! the Unix implementation of mio. This design decision was intentional,
//! however.
//!
//! ## What is IOCP?
//!
//! The [official docs][docs] have a comprehensive explanation of what IOCP is,
//! but at a high level it requires the following operations to be executed to
//! perform some I/O:
//!
//! 1. A completion port is created
//! 2. An I/O handle and a token is registered with this completion port
//! 3. Some I/O is issued on the handle. This generally means that an API was
//!    invoked with a zeroed `OVERLAPPED` structure. The API will immediately
//!    return.
//! 4. After some time, the application queries the I/O port for completed
//!    events. The port will returned a pointer to the `OVERLAPPED` along with
//!    the token presented at registration time.
//!
//! Many I/O operations can be fired off before waiting on a port, and the port
//! will block execution of the calling thread until an I/O event has completed
//! (or a timeout has elapsed).
//!
//! Currently all of these low-level operations are housed in a separate `miow`
//! crate to provide a 0-cost abstraction over IOCP. This crate uses that to
//! implement all fiddly bits so there's very few actual Windows API calls or
//! `unsafe` blocks as a result.
//!
//! [docs]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx
//!
//! ## Safety of IOCP
//!
//! Unfortunately for us, IOCP is pretty unsafe in terms of Rust lifetimes and
//! such. When an I/O operation is submitted to the kernel, it involves handing
//! the kernel a few pointers like a buffer to read/write, an `OVERLAPPED`
//! structure pointer, and perhaps some other buffers such as for socket
//! addresses. These pointers all have to remain valid **for the entire I/O
//! operation's duration**.
//!
//! There's 0-cost way to define a safe lifetime for these pointers/buffers over
//! the span of an I/O operation, so we're forced to add a layer of abstraction
//! (not 0-cost) to make these APIs safe. Currently this implementation
//! basically just boxes everything up on the heap to give it a stable address
//! and then keys of that most of the time.
//!
//! ## From completion to readiness
//!
//! Translating a completion-based model to a readiness-based model is also no
//! easy task, and a significant portion of this implementation is managing this
//! translation. The basic idea behind this implementation is to issue I/O
//! operations preemptively and then translate their completions to a "I'm
//! ready" event.
//!
//! For example, in the case of reading a `TcpSocket`, as soon as a socket is
//! connected (or registered after an accept) a read operation is executed.
//! While the read is in progress calls to `read` will return `WouldBlock`, and
//! once the read is completed we translate the completion notification into a
//! `readable` event. Once the internal buffer is drained (e.g. all data from it
//! has been read) a read operation is re-issued.
//!
//! Write operations are a little different from reads, and the current
//! implementation is to just schedule a write as soon as `write` is first
//! called. While that write operation is in progress all future calls to
//! `write` will return `WouldBlock`. Completion of the write then translates to
//! a `writable` event. Note that this will probably want to add some layer of
//! internal buffering in the future.
//!
//! ## Buffer Management
//!
//! As there's lots of I/O operations in flight at any one point in time,
//! there's lots of live buffers that need to be juggled around (e.g. this
//! implementaiton's own internal buffers).
//!
//! Currently all buffers are created for the I/O operation at hand and are then
//! discarded when it completes (this is listed as future work below).
//!
//! ## Callback Management
//!
//! When the main event loop receives a notification that an I/O operation has
//! completed, some work needs to be done to translate that to a set of events
//! or perhaps some more I/O needs to be scheduled. For example after a
//! `TcpStream` is connected it generates a writable event and also schedules a
//! read.
//!
//! To manage all this the `Selector` uses the `OVERLAPPED` pointer from the
//! completion status. The selector assumes that all `OVERLAPPED` pointers are
//! actually pointers to the interior of a `selector::Overlapped` which means
//! that right after the `OVERLAPPED` itself there's a function pointer. This
//! function pointer is given the completion status as well as another callback
//! to push events onto the selector.
//!
//! The callback for each I/O operation doesn't have any environment, so it
//! relies on memory layout and unsafe casting to translate an `OVERLAPPED`
//! pointer (or in this case a `selector::Overlapped` pointer) to a type of
//! `FromRawArc<T>` (see module docs the for why this type exists).
//!
//! ## Thread Safety
//!
//! Currently all of the I/O primitives make liberal use of `Arc` and `Mutex`
//! as an implementation detail. The main reason for this is to ensure that the
//! types are `Send` and `Sync`, but the implementations have not been stressed
//! in multithreaded situations yet. As a result, there are bound to be
//! functional surprises in using these concurrently.
//!
//! ## Future Work
//!
//! First up, let's take a look at unimplemented portions of this module:
//!
//! * The `PollOpt::level()` option is currently entirely unimplemented.
//! * Each `EventLoop` currently owns its completion port, but this prevents an
//!   I/O handle from being added to multiple event loops (something that can be
//!   done on Unix). Additionally, it hinders event loops moving across threads.
//!   This should be solved by likely having a global `Selector` which all
//!   others then communicate with.
//! * Although Unix sockets don't exist on Windows, there are named pipes and
//!   those should likely be bound here in a similar fashion to `TcpStream`.
//!
//! Next up, there are a few performance improvements and optimizations that can
//! still be implemented
//!
//! * Buffer management right now is pretty bad, they're all just allocated
//!   right before an I/O operation and discarded right after. There should at
//!   least be some form of buffering buffers.
//! * No calls to `write` are internally buffered before being scheduled, which
//!   means that writing performance is abysmal compared to Unix. There should
//!   be some level of buffering of writes probably.

use std::io;
use std::os::windows::prelude::*;

use kernel32;
use winapi;

mod awakener;
#[macro_use]
mod selector;
mod tcp;
mod udp;
mod from_raw_arc;
mod buffer_pool;
mod iovec;

pub use self::awakener::Awakener;
pub use self::selector::{Events, Selector, Overlapped, Binding};
pub use self::tcp::{TcpStream, TcpListener};
pub use self::udp::UdpSocket;
pub use self::iovec::IoVec;

#[derive(Copy, Clone)]
enum Family {
    V4, V6,
}

fn wouldblock() -> io::Error {
    io::Error::new(io::ErrorKind::WouldBlock, "operation would block")
}

unsafe fn cancel(socket: &AsRawSocket,
                 overlapped: &Overlapped) -> io::Result<()> {
    let handle = socket.as_raw_socket() as winapi::HANDLE;
    let ret = kernel32::CancelIoEx(handle, overlapped.as_mut_ptr());
    if ret == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}
<commit_msg>Several typo fixes for sys/windows/mod.rs<commit_after>//! Implementation of mio for Windows using IOCP
//!
//! This module uses I/O Completion Ports (IOCP) on Windows to implement mio's
//! Unix epoll-like interface. Unfortunately these two I/O models are
//! fundamentally incompatible:
//!
//! * IOCP is a completion-based model where work is submitted to the kernel and
//!   a program is notified later when the work finished.
//! * epoll is a readiness-based model where the kernel is queried as to what
//!   work can be done, and afterwards the work is done.
//!
//! As a result, this implementation for Windows is much less "low level" than
//! the Unix implementation of mio. This design decision was intentional,
//! however.
//!
//! ## What is IOCP?
//!
//! The [official docs][docs] have a comprehensive explanation of what IOCP is,
//! but at a high level it requires the following operations to be executed to
//! perform some I/O:
//!
//! 1. A completion port is created
//! 2. An I/O handle and a token is registered with this completion port
//! 3. Some I/O is issued on the handle. This generally means that an API was
//!    invoked with a zeroed `OVERLAPPED` structure. The API will immediately
//!    return.
//! 4. After some time, the application queries the I/O port for completed
//!    events. The port will returned a pointer to the `OVERLAPPED` along with
//!    the token presented at registration time.
//!
//! Many I/O operations can be fired off before waiting on a port, and the port
//! will block execution of the calling thread until an I/O event has completed
//! (or a timeout has elapsed).
//!
//! Currently all of these low-level operations are housed in a separate `miow`
//! crate to provide a 0-cost abstraction over IOCP. This crate uses that to
//! implement all fiddly bits so there's very few actual Windows API calls or
//! `unsafe` blocks as a result.
//!
//! [docs]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx
//!
//! ## Safety of IOCP
//!
//! Unfortunately for us, IOCP is pretty unsafe in terms of Rust lifetimes and
//! such. When an I/O operation is submitted to the kernel, it involves handing
//! the kernel a few pointers like a buffer to read/write, an `OVERLAPPED`
//! structure pointer, and perhaps some other buffers such as for socket
//! addresses. These pointers all have to remain valid **for the entire I/O
//! operation's duration**.
//!
//! There's no way to define a safe lifetime for these pointers/buffers over
//! the span of an I/O operation, so we're forced to add a layer of abstraction
//! (not 0-cost) to make these APIs safe. Currently this implementation
//! basically just boxes everything up on the heap to give it a stable address
//! and then keys off that most of the time.
//!
//! ## From completion to readiness
//!
//! Translating a completion-based model to a readiness-based model is also no
//! easy task, and a significant portion of this implementation is managing this
//! translation. The basic idea behind this implementation is to issue I/O
//! operations preemptively and then translate their completions to a "I'm
//! ready" event.
//!
//! For example, in the case of reading a `TcpSocket`, as soon as a socket is
//! connected (or registered after an accept) a read operation is executed.
//! While the read is in progress calls to `read` will return `WouldBlock`, and
//! once the read is completed we translate the completion notification into a
//! `readable` event. Once the internal buffer is drained (e.g. all data from it
//! has been read) a read operation is re-issued.
//!
//! Write operations are a little different from reads, and the current
//! implementation is to just schedule a write as soon as `write` is first
//! called. While that write operation is in progress all future calls to
//! `write` will return `WouldBlock`. Completion of the write then translates to
//! a `writable` event. Note that this will probably want to add some layer of
//! internal buffering in the future.
//!
//! ## Buffer Management
//!
//! As there's lots of I/O operations in flight at any one point in time,
//! there's lots of live buffers that need to be juggled around (e.g. this
//! implementation's own internal buffers).
//!
//! Currently all buffers are created for the I/O operation at hand and are then
//! discarded when it completes (this is listed as future work below).
//!
//! ## Callback Management
//!
//! When the main event loop receives a notification that an I/O operation has
//! completed, some work needs to be done to translate that to a set of events
//! or perhaps some more I/O needs to be scheduled. For example after a
//! `TcpStream` is connected it generates a writable event and also schedules a
//! read.
//!
//! To manage all this the `Selector` uses the `OVERLAPPED` pointer from the
//! completion status. The selector assumes that all `OVERLAPPED` pointers are
//! actually pointers to the interior of a `selector::Overlapped` which means
//! that right after the `OVERLAPPED` itself there's a function pointer. This
//! function pointer is given the completion status as well as another callback
//! to push events onto the selector.
//!
//! The callback for each I/O operation doesn't have any environment, so it
//! relies on memory layout and unsafe casting to translate an `OVERLAPPED`
//! pointer (or in this case a `selector::Overlapped` pointer) to a type of
//! `FromRawArc<T>` (see module docs for why this type exists).
//!
//! ## Thread Safety
//!
//! Currently all of the I/O primitives make liberal use of `Arc` and `Mutex`
//! as an implementation detail. The main reason for this is to ensure that the
//! types are `Send` and `Sync`, but the implementations have not been stressed
//! in multithreaded situations yet. As a result, there are bound to be
//! functional surprises in using these concurrently.
//!
//! ## Future Work
//!
//! First up, let's take a look at unimplemented portions of this module:
//!
//! * The `PollOpt::level()` option is currently entirely unimplemented.
//! * Each `EventLoop` currently owns its completion port, but this prevents an
//!   I/O handle from being added to multiple event loops (something that can be
//!   done on Unix). Additionally, it hinders event loops moving across threads.
//!   This should be solved by likely having a global `Selector` which all
//!   others then communicate with.
//! * Although Unix sockets don't exist on Windows, there are named pipes and
//!   those should likely be bound here in a similar fashion to `TcpStream`.
//!
//! Next up, there are a few performance improvements and optimizations that can
//! still be implemented
//!
//! * Buffer management right now is pretty bad, they're all just allocated
//!   right before an I/O operation and discarded right after. There should at
//!   least be some form of buffering buffers.
//! * No calls to `write` are internally buffered before being scheduled, which
//!   means that writing performance is abysmal compared to Unix. There should
//!   be some level of buffering of writes probably.

use std::io;
use std::os::windows::prelude::*;

use kernel32;
use winapi;

mod awakener;
#[macro_use]
mod selector;
mod tcp;
mod udp;
mod from_raw_arc;
mod buffer_pool;
mod iovec;

pub use self::awakener::Awakener;
pub use self::selector::{Events, Selector, Overlapped, Binding};
pub use self::tcp::{TcpStream, TcpListener};
pub use self::udp::UdpSocket;
pub use self::iovec::IoVec;

#[derive(Copy, Clone)]
enum Family {
    V4, V6,
}

fn wouldblock() -> io::Error {
    io::Error::new(io::ErrorKind::WouldBlock, "operation would block")
}

unsafe fn cancel(socket: &AsRawSocket,
                 overlapped: &Overlapped) -> io::Result<()> {
    let handle = socket.as_raw_socket() as winapi::HANDLE;
    let ret = kernel32::CancelIoEx(handle, overlapped.as_mut_ptr());
    if ret == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>stat rust version<commit_after>use std::io::{Error, ErrorKind};
use std::result::Result;

fn range_vec<T>(nl: &Vec<T>, i: usize, j: usize) -> Result<Vec<T>, Error>
where
    T: Copy + Clone,
{
    if i >= nl.len() {
        return Err(Error::new(
            ErrorKind::Other,
            "first index larger than length",
        ));
    }

    let mut jj;

    if j > nl.len() {
        jj = nl.len() - 1;
    } else {
        jj = j - 1;
    }

    let mut ind = 0;
    let mut result: Vec<T> = vec![];

    for this in nl {
        if ind >= i && ind <= jj {
            result.push(*this);
        }
        ind += 1;
    }

    Result::Ok(result)
}

fn main() {
    let a = vec![1, 2, 3, 4, 5, 6];
    println!("{:?}", range_vec(&a, 0, 1));
    println!("{:?}", range_vec(&a, 2, 6));
    println!("{:?}", range_vec(&a, 6, 6));
    println!("{:?}", range_vec(&a, 5, 6));
}
<|endoftext|>


<commit_before><commit_msg>Fix: List ids sorted<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests based on issue #70372 comments<commit_after>// check-pass

#![deny(unreachable_patterns)]

#![feature(or_patterns)]
fn main() {
    match (3,42) {
        (a,_) | (_,a) if a > 10 => {println!("{}", a)}
        _ => ()
    }

    match Some((3,42)) {
        Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)}
        _ => ()

    }

    match Some((3,42)) {
        Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)}
        _ => ()
    }
}
<|endoftext|>


<commit_before>fn even(&&e: int) -> bool {
    e % 2 == 0
}

fn log_if<T>(c: fn(T)->bool, e: T) {
    if c(e) { log e; }
}

fn main() {
    (bind log_if(even, _))(2);
}
<commit_msg>Revert "Add a test case for #898. Closes #898."<commit_after><|endoftext|>


<commit_before><commit_msg>Add test<commit_after>#![deny(unused_mut)]

fn main() {
    let mut x; //~ ERROR: variable does not need to be mutable
    x = 0;
    dbg!(0);
}
<|endoftext|>


<commit_before><commit_msg>qcow: Add vec_cache<commit_after>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::collections::hash_map::IterMut;
use std::collections::HashMap;
use std::io;
use std::ops::{Index, IndexMut};

/// Trait that allows for checking if an implementor is dirty. Useful for types that are cached so
/// it can be checked if they need to be committed to disk.
pub trait Cacheable {
    /// Used to check if the item needs to be written out or if it can be discarded.
    fn dirty(&self) -> bool;
}

#[derive(Debug)]
/// Represents a vector that implements the `Cacheable` trait so it can be held in a cache.
pub struct VecCache<T: 'static + Copy + Default> {
    vec: Box<[T]>,
    dirty: bool,
}

impl<T: 'static + Copy + Default> VecCache<T> {
    /// Creates a `VecCache` that can hold `count` elements.
    pub fn new(count: usize) -> VecCache<T> {
        VecCache {
            vec: vec![Default::default(); count].into_boxed_slice(),
            dirty: true,
        }
    }

    /// Creates a `VecCache` from the passed in `vec`.
    pub fn from_vec(vec: Vec<T>) -> VecCache<T> {
        VecCache {
            vec: vec.into_boxed_slice(),
            dirty: false,
        }
    }

    /// Gets a reference to the underlying vector.
    pub fn get_values(&self) -> &[T] {
        &self.vec
    }

    /// Mark this cache element as clean.
    pub fn mark_clean(&mut self) {
        self.dirty = false;
    }
}

impl<T: 'static + Copy + Default> Cacheable for VecCache<T> {
    fn dirty(&self) -> bool {
        self.dirty
    }
}

impl<T: 'static + Copy + Default> Index<usize> for VecCache<T> {
    type Output = T;

    fn index(&self, index: usize) -> &T {
        self.vec.index(index)
    }
}

impl<T: 'static + Copy + Default> IndexMut<usize> for VecCache<T> {
    fn index_mut(&mut self, index: usize) -> &mut T {
        self.dirty = true;
        self.vec.index_mut(index)
    }
}

#[derive(Debug)]
pub struct CacheMap<T: Cacheable> {
    capacity: usize,
    map: HashMap<usize, T>,
}

impl<T: Cacheable> CacheMap<T> {
    pub fn new(capacity: usize) -> Self {
        CacheMap {
            capacity,
            map: HashMap::with_capacity(capacity),
        }
    }

    pub fn contains_key(&self, key: &usize) -> bool {
        self.map.contains_key(key)
    }

    pub fn get(&self, index: &usize) -> Option<&T> {
        self.map.get(index)
    }

    pub fn get_mut(&mut self, index: &usize) -> Option<&mut T> {
        self.map.get_mut(index)
    }

    pub fn iter_mut(&mut self) -> IterMut<usize, T> {
        self.map.iter_mut()
    }

    // Check if the refblock cache is full and we need to evict.
    pub fn insert<F>(&mut self, index: usize, block: T, write_callback: F) -> io::Result<()>
    where
        F: FnOnce(usize, T) -> io::Result<()>,
    {
        if self.map.len() == self.capacity {
            // TODO(dgreid) - smarter eviction strategy.
            let to_evict = *self.map.iter().nth(0).unwrap().0;
            if let Some(evicted) = self.map.remove(&to_evict) {
                if evicted.dirty() {
                    write_callback(to_evict, evicted)?;
                }
            }
        }
        self.map.insert(index, block);
        Ok(())
    }
}

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

    struct NumCache(pub u64);
    impl Cacheable for NumCache {
        fn dirty(&self) -> bool {
            true
        }
    }

    #[test]
    fn evicts_when_full() {
        let mut cache = CacheMap::<NumCache>::new(3);
        let mut evicted = None;
        cache
            .insert(0, NumCache(5), |index, _| {
                evicted = Some(index);
                Ok(())
            })
            .unwrap();
        assert_eq!(evicted, None);
        cache
            .insert(1, NumCache(6), |index, _| {
                evicted = Some(index);
                Ok(())
            })
            .unwrap();
        assert_eq!(evicted, None);
        cache
            .insert(2, NumCache(7), |index, _| {
                evicted = Some(index);
                Ok(())
            })
            .unwrap();
        assert_eq!(evicted, None);
        cache
            .insert(3, NumCache(8), |index, _| {
                evicted = Some(index);
                Ok(())
            })
            .unwrap();
        assert!(evicted.is_some());

        // Check that three of the four items inserted are still there and that the most recently
        // inserted is one of them.
        let num_items = (0..=3).filter(|k| cache.contains_key(&k)).count();
        assert_eq!(num_items, 3);
        assert!(cache.contains_key(&3));
    }
}
<|endoftext|>


<commit_before><commit_msg>Generate one descriptor set layout per canonical set, and bind at the canonical set index<commit_after><|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.

// ignore-macos #16872 spurious deadlock

#![feature(phase)]

#[phase(plugin)]
extern crate green;
extern crate native;

use std::io::{TcpListener, Listener, Acceptor, EndOfFile, TcpStream};
use std::sync::{atomic, Arc};
use std::task::TaskBuilder;
use native::NativeTaskBuilder;

static N: uint = 8;
static M: uint = 100;

green_start!(main)

fn main() {
    test();

    let (tx, rx) = channel();
    TaskBuilder::new().native().spawn(proc() {
        tx.send(test());
    });
    rx.recv();
}

fn test() {
    let mut l = TcpListener::bind("127.0.0.1", 0).unwrap();
    let addr = l.socket_name().unwrap();
    let mut a = l.listen().unwrap();
    let cnt = Arc::new(atomic::AtomicUint::new(0));

    let (tx, rx) = channel();
    for _ in range(0, N) {
        let a = a.clone();
        let cnt = cnt.clone();
        let tx = tx.clone();
        spawn(proc() {
            let mut a = a;
            let mut mycnt = 0u;
            loop {
                match a.accept() {
                    Ok(..) => {
                        mycnt += 1;
                        if cnt.fetch_add(1, atomic::SeqCst) == N * M - 1 {
                            break
                        }
                    }
                    Err(ref e) if e.kind == EndOfFile => break,
                    Err(e) => fail!("{}", e),
                }
            }
            assert!(mycnt > 0);
            tx.send(());
        });
    }

    for _ in range(0, N) {
        let tx = tx.clone();
        spawn(proc() {
            for _ in range(0, M) {
                let _s = TcpStream::connect(addr.ip.to_string().as_slice(),
                                            addr.port).unwrap();
            }
            tx.send(());
        });
    }

    // wait for senders
    assert_eq!(rx.iter().take(N).count(), N);

    // wait for one acceptor to die
    let _ = rx.recv();

    // Notify other receivers should die
    a.close_accept().unwrap();

    // wait for receivers
    assert_eq!(rx.iter().take(N - 1).count(), N - 1);

    // Everything should have been accepted.
    assert_eq!(cnt.load(atomic::SeqCst), N * M);
}

<commit_msg>test: Fix the tcp-accept-stress test<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.

#![feature(phase)]

#[phase(plugin)]
extern crate green;
extern crate native;

use std::io::{TcpListener, Listener, Acceptor, EndOfFile, TcpStream};
use std::sync::{atomic, Arc};
use std::task::TaskBuilder;
use native::NativeTaskBuilder;

static N: uint = 8;
static M: uint = 100;

green_start!(main)

fn main() {
    test();

    let (tx, rx) = channel();
    TaskBuilder::new().native().spawn(proc() {
        tx.send(test());
    });
    rx.recv();
}

fn test() {
    let mut l = TcpListener::bind("127.0.0.1", 0).unwrap();
    let addr = l.socket_name().unwrap();
    let mut a = l.listen().unwrap();
    let cnt = Arc::new(atomic::AtomicUint::new(0));

    let (tx, rx) = channel();
    for _ in range(0, N) {
        let a = a.clone();
        let cnt = cnt.clone();
        let tx = tx.clone();
        spawn(proc() {
            let mut a = a;
            loop {
                match a.accept() {
                    Ok(..) => {
                        if cnt.fetch_add(1, atomic::SeqCst) == N * M - 1 {
                            break
                        }
                    }
                    Err(ref e) if e.kind == EndOfFile => break,
                    Err(e) => fail!("{}", e),
                }
            }
            tx.send(());
        });
    }

    for _ in range(0, N) {
        let tx = tx.clone();
        spawn(proc() {
            for _ in range(0, M) {
                let _s = TcpStream::connect(addr.ip.to_string().as_slice(),
                                            addr.port).unwrap();
            }
            tx.send(());
        });
    }
    drop(tx);

    // wait for senders
    assert_eq!(rx.iter().take(N).count(), N);

    // wait for one acceptor to die
    let _ = rx.recv();

    // Notify other receivers should die
    a.close_accept().unwrap();

    // wait for receivers
    assert_eq!(rx.iter().take(N - 1).count(), N - 1);

    // Everything should have been accepted.
    assert_eq!(cnt.load(atomic::SeqCst), N * M);
}

<|endoftext|>


<commit_before><commit_msg>Added while let example<commit_after>fn main() {
    // Make `optional` of type `Option<i32>`
    let mut optional = Some(0);

    // Repeatedly try this test.
    loop {
        match optional {
            // If `optional` destructures, evaluate the block.
            Some(i) => {
                if i > 9 {
                    println!("Greater than 9, quit!");
                    optional = None;
                } else {
                    println!("`i` is `{:?}`. Try again.", i);
                    optional = Some(i + 1);
                }
                // ^ Requires 3 indentations!
            },
            // Quit when the destructure fails, meaning `break`.
            _ => { break; }
            // ^ Why should this be required? Seems superfluous.
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>solved 0010 with Rust<commit_after>use std::io::prelude::*;
use std::str::FromStr;

fn ans(i:Vec<f64>) -> (f64,f64,f64) {
    let x1 = i[0];
    let y1 = i[1];
    let x2 = i[2];
    let y2 = i[3];
    let x3 = i[4];
    let y3 = i[5];

    let a2 = x1.powf(2.0) - x2.powf(2.0);
    let b2 = 2.0 * (x1-x2);
    let c2 = y1.powf(2.0) - y2.powf(2.0);
    let d2 = 2.0 * (y1-y2);
    let a3 = x1.powf(2.0) - x3.powf(2.0);
    let b3 = 2.0 * (x1-x3);
    let c3 = y1.powf(2.0) - y3.powf(2.0);
    let d3 = 2.0 * (y1-y3);

    let xp = (a2*d3 + c2*d3 - a3*d2 - c3*d2) / (b2*d3 - b3*d2);
    let yp = if d2 != 0.0 {
                (a2+c2 - b2*xp) / d2
             } else {
                 (a3+c3-b3*xp) / d3
             };
    let r = ( (x1-xp).powf(2.0) + (y1-yp).powf(2.0) ).sqrt();
    (xp, yp, r)
}

fn main() {
    let stdin = std::io::stdin();

    let l = stdin.lock().lines().next().unwrap().unwrap();
    let n = i32::from_str(&l).unwrap();

    for _ in 0..n {
        let s = stdin.lock().lines().next().unwrap().unwrap();
        let d : Vec<f64> = s.split_whitespace().map(|x| f64::from_str(x).unwrap()).collect();
        let (x,y,r) = ans(d);
        println!("{:.3} {:.3} {:.3}",x,y,r);
    }
}
<|endoftext|>


<commit_before><commit_msg>added lists<commit_after><|endoftext|>


<commit_before><commit_msg>Add support for compiler flags in executable<commit_after><|endoftext|>


<commit_before><commit_msg>squash<commit_after><|endoftext|>


<commit_before>use alloc::boxed::*;

use core::ptr;

use common::memory::*;
use common::paging::*;
use common::scheduler::*;
use common::vec::*;

use syscall::call::sys_exit;

pub const CONTEXT_STACK_SIZE: usize = 1024*1024;

pub static mut contexts_ptr: *mut Box<Vec<Context>> = 0 as *mut Box<Vec<Context>>;
pub static mut context_i: usize = 0;

pub unsafe extern "cdecl" fn context_box(box_fn_ptr: usize){
    let box_fn = ptr::read(box_fn_ptr as *mut Box<FnBox()>);
    unalloc(box_fn_ptr);
    box_fn();
}

pub unsafe extern "cdecl" fn context_exit() -> !{
    loop {
        sys_exit();
    }
}

pub struct Context {
    pub stack: usize,
    pub stack_ptr: u32,
    pub fx: usize,
    pub physical_address: usize,
    pub virtual_address: usize,
    pub virtual_size: usize

}

impl Context {
    pub unsafe fn root() -> Context {
        let ret = Context {
            stack: 0,
            stack_ptr: 0,
            fx: alloc(512),
            physical_address: 0,
            virtual_address: 0,
            virtual_size: 0
        };

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub unsafe fn new(call: usize, args: &Vec<usize>) -> Context {
        let stack = alloc(CONTEXT_STACK_SIZE);

        let mut ret = Context {
            stack: stack,
            stack_ptr: (stack + CONTEXT_STACK_SIZE) as u32,
            fx: alloc(512),
            physical_address: 0,
            virtual_address: 0,
            virtual_size: 0
        };

        let ebp = ret.stack_ptr;

        for arg in args.iter() {
            ret.push(*arg as u32);
        }

        ret.push(context_exit as u32); //If the function call returns, we will exit
        ret.push(call as u32); //We will ret into this function call

        ret.push(0); //ESI is a param used in the switch function

        ret.push(1 << 9); //Flags

        let esp = ret.stack_ptr;

        ret.push(0); //EAX
        ret.push(0); //ECX
        ret.push(0); //EDX
        ret.push(0); //EBX
        ret.push(esp); //ESP (ignored)
        ret.push(ebp); //EBP
        ret.push(0); //ESI
        ret.push(0); //EDI

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub fn spawn(box_fn: Box<FnBox()>) {
        unsafe{
            let box_fn_ptr: *mut Box<FnBox()> = alloc_type();
            ptr::write(box_fn_ptr, box_fn);

            let mut context_box_args: Vec<usize> = Vec::new();
            context_box_args.push(box_fn_ptr as usize);

            let reenable = start_no_ints();
            if contexts_ptr as usize > 0 {
                (*contexts_ptr).push(Context::new(context_box as usize, &context_box_args));
            }
            end_no_ints(reenable);
        }
    }

    pub unsafe fn push(&mut self, data: u32){
        self.stack_ptr -= 4;
        *(self.stack_ptr as *mut u32) = data;
    }

    pub unsafe fn map(&mut self){
        for i in 0..(self.virtual_size + 4095)/4096 {
            set_page(self.virtual_address + i*4096, self.physical_address + i*4096);
        }
    }

    pub unsafe fn unmap(&mut self){
        for i in 0..(self.virtual_size + 4095)/4096 {
            identity_page(self.virtual_address + i*4096);
        }
    }

    pub unsafe fn remap(&mut self, other: &mut Context){
        self.unmap();
        other.map();
    }

    //Warning: This function MUST be inspected in disassembly for correct push/pop
    //It should have exactly one extra push/pop of ESI
    #[cold]
    #[inline(never)]
    pub unsafe fn switch(&mut self, other: &mut Context){
        asm!("pushfd
            pushad
            mov [esi], esp"
            :
            : "{esi}"(&mut self.stack_ptr)
            : "memory"
            : "intel", "volatile");
        /*
        asm!("fxsave [esi]"
            :
            : "{esi}"(self.fx)
            : "memory"
            : "intel", "volatile");
        asm!("fxrstor [esi]"
            :
            : "{esi}"(other.fx)
            : "memory"
            : "intel", "volatile");
        */
        asm!("mov esp, [esi]
            popad
            popfd"
            :
            : "{esi}"(&mut other.stack_ptr)
            : "memory"
            : "intel", "volatile");
    }
}

impl Drop for Context {
    fn drop(&mut self){
        if self.stack > 0 {
            unsafe {
                unalloc(self.stack);
            }
        }

        if self.fx > 0 {
            unsafe {
                unalloc(self.fx);
            }
        }
    }
}
<commit_msg>FXsave/FXrstor<commit_after>use alloc::boxed::*;

use core::ptr;

use common::memory::*;
use common::paging::*;
use common::scheduler::*;
use common::vec::*;

use syscall::call::sys_exit;

pub const CONTEXT_STACK_SIZE: usize = 1024*1024;

pub static mut contexts_ptr: *mut Box<Vec<Context>> = 0 as *mut Box<Vec<Context>>;
pub static mut context_i: usize = 0;

pub unsafe extern "cdecl" fn context_box(box_fn_ptr: usize){
    let box_fn = ptr::read(box_fn_ptr as *mut Box<FnBox()>);
    unalloc(box_fn_ptr);
    box_fn();
}

pub unsafe extern "cdecl" fn context_exit() -> !{
    loop {
        sys_exit();
    }
}

pub struct Context {
    pub stack: usize,
    pub stack_ptr: u32,
    pub fx: usize,
    pub physical_address: usize,
    pub virtual_address: usize,
    pub virtual_size: usize

}

impl Context {
    pub unsafe fn root() -> Context {
        let ret = Context {
            stack: 0,
            stack_ptr: 0,
            fx: alloc(512),
            physical_address: 0,
            virtual_address: 0,
            virtual_size: 0
        };

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub unsafe fn new(call: usize, args: &Vec<usize>) -> Context {
        let stack = alloc(CONTEXT_STACK_SIZE);

        let mut ret = Context {
            stack: stack,
            stack_ptr: (stack + CONTEXT_STACK_SIZE) as u32,
            fx: alloc(512),
            physical_address: 0,
            virtual_address: 0,
            virtual_size: 0
        };

        let ebp = ret.stack_ptr;

        for arg in args.iter() {
            ret.push(*arg as u32);
        }

        ret.push(context_exit as u32); //If the function call returns, we will exit
        ret.push(call as u32); //We will ret into this function call

        ret.push(0); //ESI is a param used in the switch function

        ret.push(1 << 9); //Flags

        let esp = ret.stack_ptr;

        ret.push(0); //EAX
        ret.push(0); //ECX
        ret.push(0); //EDX
        ret.push(0); //EBX
        ret.push(esp); //ESP (ignored)
        ret.push(ebp); //EBP
        ret.push(0); //ESI
        ret.push(0); //EDI

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub fn spawn(box_fn: Box<FnBox()>) {
        unsafe{
            let box_fn_ptr: *mut Box<FnBox()> = alloc_type();
            ptr::write(box_fn_ptr, box_fn);

            let mut context_box_args: Vec<usize> = Vec::new();
            context_box_args.push(box_fn_ptr as usize);

            let reenable = start_no_ints();
            if contexts_ptr as usize > 0 {
                (*contexts_ptr).push(Context::new(context_box as usize, &context_box_args));
            }
            end_no_ints(reenable);
        }
    }

    pub unsafe fn push(&mut self, data: u32){
        self.stack_ptr -= 4;
        *(self.stack_ptr as *mut u32) = data;
    }

    pub unsafe fn map(&mut self){
        for i in 0..(self.virtual_size + 4095)/4096 {
            set_page(self.virtual_address + i*4096, self.physical_address + i*4096);
        }
    }

    pub unsafe fn unmap(&mut self){
        for i in 0..(self.virtual_size + 4095)/4096 {
            identity_page(self.virtual_address + i*4096);
        }
    }

    pub unsafe fn remap(&mut self, other: &mut Context){
        self.unmap();
        other.map();
    }

    //Warning: This function MUST be inspected in disassembly for correct push/pop
    //It should have exactly one extra push/pop of ESI
    #[cold]
    #[inline(never)]
    pub unsafe fn switch(&mut self, other: &mut Context){
        asm!("pushfd
            pushad
            mov [esi], esp"
            :
            : "{esi}"(&mut self.stack_ptr)
            : "memory"
            : "intel", "volatile");

        asm!("fxsave [esi]"
            :
            : "{esi}"(self.fx)
            : "memory"
            : "intel", "volatile");

        asm!("fxrstor [esi]"
            :
            : "{esi}"(other.fx)
            : "memory"
            : "intel", "volatile");

        asm!("mov esp, [esi]
            popad
            popfd"
            :
            : "{esi}"(&mut other.stack_ptr)
            : "memory"
            : "intel", "volatile");
    }
}

impl Drop for Context {
    fn drop(&mut self){
        if self.stack > 0 {
            unsafe {
                unalloc(self.stack);
            }
        }

        if self.fx > 0 {
            unsafe {
                unalloc(self.fx);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add unit test for the new and the changed errors<commit_after>// Copyright 2015 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.

const X: usize = 42 && 39; //~ ERROR: can't do this op on unsigned integrals
const ARR: [i32; X] = [99; 34]; //~ NOTE: for array length here

const X1: usize = 42 || 39; //~ ERROR: can't do this op on unsigned integrals
const ARR1: [i32; X1] = [99; 47]; //~ NOTE: for array length here

// FIXME: the error should be `on signed integrals`
const X2: usize = -42 || -39; //~ ERROR: can't do this op on unsigned integrals
const ARR2: [i32; X2] = [99; 18446744073709551607]; //~ NOTE: for array length here

// FIXME: the error should be `on signed integrals`
const X3: usize = -42 && -39; //~ ERROR: can't do this op on unsigned integrals
const ARR3: [i32; X3] = [99; 6]; //~ NOTE: for array length here

const Y: usize = 42.0 == 42.0;
const ARRR: [i32; Y] = [99; 1]; //~ ERROR: expected constant integer expression for array length
const Y1: usize = 42.0 >= 42.0;
const ARRR1: [i32; Y] = [99; 1]; //~ ERROR: expected constant integer expression for array length
const Y2: usize = 42.0 <= 42.0;
const ARRR2: [i32; Y] = [99; 1]; //~ ERROR: expected constant integer expression for array length
const Y3: usize = 42.0 > 42.0;
const ARRR3: [i32; Y] = [99; 0]; //~ ERROR: expected constant integer expression for array length
const Y4: usize = 42.0 < 42.0;
const ARRR4: [i32; Y] = [99; 0]; //~ ERROR: expected constant integer expression for array length
const Y5: usize = 42.0 != 42.0;
const ARRR5: [i32; Y] = [99; 0]; //~ ERROR: expected constant integer expression for array length

fn main() {
    let _ = ARR;
    let _ = ARRR;
    let _ = ARRR1;
    let _ = ARRR2;
    let _ = ARRR3;
    let _ = ARRR4;
    let _ = ARRR5;
}
<|endoftext|>


<commit_before><commit_msg>Added type inference to partial application.<commit_after><|endoftext|>


<commit_before><commit_msg>Elaborate on TODO<commit_after><|endoftext|>


<commit_before><commit_msg>Add an example at `examples/basic.rs`.<commit_after>#![feature(plugin)]
#![plugin(speculate)]

pub mod math {
    pub fn add(a: i32, b: i32) -> i32 {
        a + b
    }

    pub fn sub(a: i32, b: i32) -> i32 {
        a - b
    }
}

speculate! {
    describe "math" {
        before {
            let zero = 0;
            let one = 1;
        }

        it "can add stuff" {
            assert_eq!(one, ::math::add(zero, one));
        }

        it "can subtract stuff" {
            assert_eq!(zero, ::math::sub(one, one));
        }
    }
}

fn main() {
}
<|endoftext|>


<commit_before><commit_msg>Add Unit Tests For peer::Handshake<commit_after><|endoftext|>


<commit_before>use std::io;

use crate::backend::Backend;
use crate::buffer::Cell;
use crate::layout::Rect;
use crate::style::{Color, Modifier, Style};
use crate::symbols::{bar, block};
#[cfg(unix)]
use crate::symbols::{line, DOT};
#[cfg(unix)]
use pancurses::ToChtype;
use unicode_segmentation::UnicodeSegmentation;

pub struct CursesBackend {
    curses: easycurses::EasyCurses,
}

impl CursesBackend {
    pub fn new() -> Option<CursesBackend> {
        let curses = easycurses::EasyCurses::initialize_system()?;
        Some(CursesBackend { curses })
    }

    pub fn with_curses(curses: easycurses::EasyCurses) -> CursesBackend {
        CursesBackend { curses }
    }

    pub fn get_curses(&self) -> &easycurses::EasyCurses {
        &self.curses
    }

    pub fn get_curses_mut(&mut self) -> &mut easycurses::EasyCurses {
        &mut self.curses
    }
}

impl Backend for CursesBackend {
    fn draw<'a, I>(&mut self, content: I) -> io::Result<()>
    where
        I: Iterator<Item = (u16, u16, &'a Cell)>,
    {
        let mut last_col = 0;
        let mut last_row = 0;
        let mut style = Style {
            fg: Color::Reset,
            bg: Color::Reset,
            modifier: Modifier::Reset,
        };
        let mut curses_style = CursesStyle {
            fg: easycurses::Color::White,
            bg: easycurses::Color::Black,
            attribute: pancurses::Attribute::Normal,
        };
        let mut update_color = false;
        for (col, row, cell) in content {
            // eprintln!("{:?}", cell);
            if row != last_row || col != last_col + 1 {
                self.curses.move_rc(row as i32, col as i32);
            }
            last_col = col;
            last_row = row;
            if cell.style.modifier != style.modifier {
                if curses_style.attribute != pancurses::Attribute::Normal {
                    self.curses.win.attroff(curses_style.attribute);
                }
                let attribute: pancurses::Attribute = cell.style.modifier.into();
                self.curses.win.attron(attribute);
                curses_style.attribute = attribute;
                style.modifier = cell.style.modifier;
            };
            if cell.style.fg != style.fg {
                update_color = true;
                if let Some(ccolor) = cell.style.fg.into() {
                    style.fg = cell.style.fg;
                    curses_style.fg = ccolor;
                } else {
                    style.fg = Color::White;
                    curses_style.fg = easycurses::Color::White;
                }
            };
            if cell.style.bg != style.bg {
                update_color = true;
                if let Some(ccolor) = cell.style.bg.into() {
                    style.bg = cell.style.bg;
                    curses_style.bg = ccolor;
                } else {
                    style.bg = Color::Black;
                    curses_style.bg = easycurses::Color::Black;
                }
            };
            if update_color {
                self.curses
                    .set_color_pair(easycurses::ColorPair::new(curses_style.fg, curses_style.bg));
            };
            update_color = false;
            draw(&mut self.curses, cell.symbol.as_str());
        }
        self.curses.win.attrset(pancurses::Attribute::Normal);
        self.curses.set_color_pair(easycurses::ColorPair::new(
            easycurses::Color::White,
            easycurses::Color::Black,
        ));
        Ok(())
    }
    fn hide_cursor(&mut self) -> io::Result<()> {
        self.curses
            .set_cursor_visibility(easycurses::CursorVisibility::Invisible);
        Ok(())
    }
    fn show_cursor(&mut self) -> io::Result<()> {
        self.curses
            .set_cursor_visibility(easycurses::CursorVisibility::Visible);
        Ok(())
    }
    fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
        let (x, y) = self.curses.get_cursor_rc();
        Ok((x as u16, y as u16))
    }
    fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {
        self.curses.move_rc(x as i32, y as i32);
        Ok(())
    }
    fn clear(&mut self) -> io::Result<()> {
        self.curses.clear();
        // self.curses.refresh();
        Ok(())
    }
    fn size(&self) -> Result<Rect, io::Error> {
        let (nrows, ncols) = self.curses.get_row_col_count();
        Ok(Rect::new(0, 0, ncols as u16, nrows as u16))
    }
    fn flush(&mut self) -> io::Result<()> {
        self.curses.refresh();
        Ok(())
    }
}

struct CursesStyle {
    fg: easycurses::Color,
    bg: easycurses::Color,
    attribute: pancurses::Attribute,
}

#[cfg(unix)]
/// Deals with lack of unicode support for ncurses on unix
fn draw(curses: &mut easycurses::EasyCurses, symbol: &str) {
    for grapheme in symbol.graphemes(true) {
        let ch = match grapheme {
            line::TOP_RIGHT => pancurses::ACS_URCORNER(),
            line::VERTICAL => pancurses::ACS_VLINE(),
            line::HORIZONTAL => pancurses::ACS_HLINE(),
            line::TOP_LEFT => pancurses::ACS_ULCORNER(),
            line::BOTTOM_RIGHT => pancurses::ACS_LRCORNER(),
            line::BOTTOM_LEFT => pancurses::ACS_LLCORNER(),
            line::VERTICAL_LEFT => pancurses::ACS_RTEE(),
            line::VERTICAL_RIGHT => pancurses::ACS_LTEE(),
            line::HORIZONTAL_DOWN => pancurses::ACS_TTEE(),
            line::HORIZONTAL_UP => pancurses::ACS_BTEE(),
            block::FULL => pancurses::ACS_BLOCK(),
            block::SEVEN_EIGHTHS => pancurses::ACS_BLOCK(),
            block::THREE_QUATERS => pancurses::ACS_BLOCK(),
            block::FIVE_EIGHTHS => pancurses::ACS_BLOCK(),
            block::HALF => pancurses::ACS_BLOCK(),
            block::THREE_EIGHTHS => ' ' as u32,
            block::ONE_QUATER => ' ' as u32,
            block::ONE_EIGHTH => ' ' as u32,
            bar::SEVEN_EIGHTHS => pancurses::ACS_BLOCK(),
            bar::THREE_QUATERS => pancurses::ACS_BLOCK(),
            bar::FIVE_EIGHTHS => pancurses::ACS_BLOCK(),
            bar::HALF => pancurses::ACS_BLOCK(),
            bar::THREE_EIGHTHS => pancurses::ACS_S9(),
            bar::ONE_QUATER => pancurses::ACS_S9(),
            bar::ONE_EIGHTH => pancurses::ACS_S9(),
            DOT => pancurses::ACS_BULLET(),
            unicode_char => {
                if unicode_char.is_ascii() {
                    let mut chars = unicode_char.chars();
                    if let Some(ch) = chars.next() {
                        ch.to_chtype()
                    } else {
                        pancurses::ACS_BLOCK()
                    }
                } else {
                    pancurses::ACS_BLOCK()
                }
            }
        };
        curses.win.addch(ch);
    }
}

#[cfg(windows)]
fn draw(curses: &mut easycurses::EasyCurses, symbol: &str) {
    for grapheme in symbol.graphemes(true) {
        let ch = match grapheme {
            block::SEVEN_EIGHTHS => block::FULL,
            block::THREE_QUATERS => block::FULL,
            block::FIVE_EIGHTHS => block::HALF,
            block::THREE_EIGHTHS => block::HALF,
            block::ONE_QUATER => block::HALF,
            block::ONE_EIGHTH => " ",
            bar::SEVEN_EIGHTHS => bar::FULL,
            bar::THREE_QUATERS => bar::FULL,
            bar::FIVE_EIGHTHS => bar::HALF,
            bar::THREE_EIGHTHS => bar::HALF,
            bar::ONE_QUATER => bar::HALF,
            bar::ONE_EIGHTH => " ",
            ch => ch,
        };
        // curses.win.addch(ch);
        curses.print(ch);
    }
}

impl From<Color> for Option<easycurses::Color> {
    fn from(color: Color) -> Option<easycurses::Color> {
        match color {
            Color::Reset => None,
            Color::Black => Some(easycurses::Color::Black),
            Color::Red | Color::LightRed => Some(easycurses::Color::Red),
            Color::Green | Color::LightGreen => Some(easycurses::Color::Green),
            Color::Yellow | Color::LightYellow => Some(easycurses::Color::Yellow),
            Color::Magenta | Color::LightMagenta => Some(easycurses::Color::Magenta),
            Color::Cyan | Color::LightCyan => Some(easycurses::Color::Cyan),
            Color::White | Color::Gray | Color::DarkGray => Some(easycurses::Color::White),
            Color::Blue | Color::LightBlue => Some(easycurses::Color::Blue),
            Color::Rgb(_, _, _) => None,
        }
    }
}

impl From<Modifier> for pancurses::Attribute {
    fn from(modifier: Modifier) -> pancurses::Attribute {
        match modifier {
            Modifier::Blink => pancurses::Attribute::Blink,
            Modifier::Bold => pancurses::Attribute::Bold,
            Modifier::CrossedOut => pancurses::Attribute::Strikeout,
            Modifier::Faint => pancurses::Attribute::Dim,
            Modifier::Invert => pancurses::Attribute::Reverse,
            Modifier::Italic => pancurses::Attribute::Italic,
            Modifier::Underline => pancurses::Attribute::Underline,
            _ => pancurses::Attribute::Normal,
        }
    }
}
<commit_msg>fix(backend/curses): avoid platform specific conversion of graphemes<commit_after>use std::io;

use crate::backend::Backend;
use crate::buffer::Cell;
use crate::layout::Rect;
use crate::style::{Color, Modifier, Style};
use crate::symbols::{bar, block};
#[cfg(unix)]
use crate::symbols::{line, DOT};
#[cfg(unix)]
use pancurses::ToChtype;
use unicode_segmentation::UnicodeSegmentation;

pub struct CursesBackend {
    curses: easycurses::EasyCurses,
}

impl CursesBackend {
    pub fn new() -> Option<CursesBackend> {
        let curses = easycurses::EasyCurses::initialize_system()?;
        Some(CursesBackend { curses })
    }

    pub fn with_curses(curses: easycurses::EasyCurses) -> CursesBackend {
        CursesBackend { curses }
    }

    pub fn get_curses(&self) -> &easycurses::EasyCurses {
        &self.curses
    }

    pub fn get_curses_mut(&mut self) -> &mut easycurses::EasyCurses {
        &mut self.curses
    }
}

impl Backend for CursesBackend {
    fn draw<'a, I>(&mut self, content: I) -> io::Result<()>
    where
        I: Iterator<Item = (u16, u16, &'a Cell)>,
    {
        let mut last_col = 0;
        let mut last_row = 0;
        let mut style = Style {
            fg: Color::Reset,
            bg: Color::Reset,
            modifier: Modifier::Reset,
        };
        let mut curses_style = CursesStyle {
            fg: easycurses::Color::White,
            bg: easycurses::Color::Black,
            attribute: pancurses::Attribute::Normal,
        };
        let mut update_color = false;
        for (col, row, cell) in content {
            // eprintln!("{:?}", cell);
            if row != last_row || col != last_col + 1 {
                self.curses.move_rc(row as i32, col as i32);
            }
            last_col = col;
            last_row = row;
            if cell.style.modifier != style.modifier {
                if curses_style.attribute != pancurses::Attribute::Normal {
                    self.curses.win.attroff(curses_style.attribute);
                }
                let attribute: pancurses::Attribute = cell.style.modifier.into();
                self.curses.win.attron(attribute);
                curses_style.attribute = attribute;
                style.modifier = cell.style.modifier;
            };
            if cell.style.fg != style.fg {
                update_color = true;
                if let Some(ccolor) = cell.style.fg.into() {
                    style.fg = cell.style.fg;
                    curses_style.fg = ccolor;
                } else {
                    style.fg = Color::White;
                    curses_style.fg = easycurses::Color::White;
                }
            };
            if cell.style.bg != style.bg {
                update_color = true;
                if let Some(ccolor) = cell.style.bg.into() {
                    style.bg = cell.style.bg;
                    curses_style.bg = ccolor;
                } else {
                    style.bg = Color::Black;
                    curses_style.bg = easycurses::Color::Black;
                }
            };
            if update_color {
                self.curses
                    .set_color_pair(easycurses::ColorPair::new(curses_style.fg, curses_style.bg));
            };
            update_color = false;
            draw(&mut self.curses, cell.symbol.as_str());
        }
        self.curses.win.attrset(pancurses::Attribute::Normal);
        self.curses.set_color_pair(easycurses::ColorPair::new(
            easycurses::Color::White,
            easycurses::Color::Black,
        ));
        Ok(())
    }
    fn hide_cursor(&mut self) -> io::Result<()> {
        self.curses
            .set_cursor_visibility(easycurses::CursorVisibility::Invisible);
        Ok(())
    }
    fn show_cursor(&mut self) -> io::Result<()> {
        self.curses
            .set_cursor_visibility(easycurses::CursorVisibility::Visible);
        Ok(())
    }
    fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
        let (x, y) = self.curses.get_cursor_rc();
        Ok((x as u16, y as u16))
    }
    fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {
        self.curses.move_rc(x as i32, y as i32);
        Ok(())
    }
    fn clear(&mut self) -> io::Result<()> {
        self.curses.clear();
        // self.curses.refresh();
        Ok(())
    }
    fn size(&self) -> Result<Rect, io::Error> {
        let (nrows, ncols) = self.curses.get_row_col_count();
        Ok(Rect::new(0, 0, ncols as u16, nrows as u16))
    }
    fn flush(&mut self) -> io::Result<()> {
        self.curses.refresh();
        Ok(())
    }
}

struct CursesStyle {
    fg: easycurses::Color,
    bg: easycurses::Color,
    attribute: pancurses::Attribute,
}

#[cfg(unix)]
/// Deals with lack of unicode support for ncurses on unix
fn draw(curses: &mut easycurses::EasyCurses, symbol: &str) {
    for grapheme in symbol.graphemes(true) {
        let ch = match grapheme {
            line::TOP_RIGHT => pancurses::ACS_URCORNER(),
            line::VERTICAL => pancurses::ACS_VLINE(),
            line::HORIZONTAL => pancurses::ACS_HLINE(),
            line::TOP_LEFT => pancurses::ACS_ULCORNER(),
            line::BOTTOM_RIGHT => pancurses::ACS_LRCORNER(),
            line::BOTTOM_LEFT => pancurses::ACS_LLCORNER(),
            line::VERTICAL_LEFT => pancurses::ACS_RTEE(),
            line::VERTICAL_RIGHT => pancurses::ACS_LTEE(),
            line::HORIZONTAL_DOWN => pancurses::ACS_TTEE(),
            line::HORIZONTAL_UP => pancurses::ACS_BTEE(),
            block::FULL => pancurses::ACS_BLOCK(),
            block::SEVEN_EIGHTHS => pancurses::ACS_BLOCK(),
            block::THREE_QUATERS => pancurses::ACS_BLOCK(),
            block::FIVE_EIGHTHS => pancurses::ACS_BLOCK(),
            block::HALF => pancurses::ACS_BLOCK(),
            block::THREE_EIGHTHS => ' '.into(),
            block::ONE_QUATER => ' '.into(),
            block::ONE_EIGHTH => ' '.into(),
            bar::SEVEN_EIGHTHS => pancurses::ACS_BLOCK(),
            bar::THREE_QUATERS => pancurses::ACS_BLOCK(),
            bar::FIVE_EIGHTHS => pancurses::ACS_BLOCK(),
            bar::HALF => pancurses::ACS_BLOCK(),
            bar::THREE_EIGHTHS => pancurses::ACS_S9(),
            bar::ONE_QUATER => pancurses::ACS_S9(),
            bar::ONE_EIGHTH => pancurses::ACS_S9(),
            DOT => pancurses::ACS_BULLET(),
            unicode_char => {
                if unicode_char.is_ascii() {
                    let mut chars = unicode_char.chars();
                    if let Some(ch) = chars.next() {
                        ch.to_chtype()
                    } else {
                        pancurses::ACS_BLOCK()
                    }
                } else {
                    pancurses::ACS_BLOCK()
                }
            }
        };
        curses.win.addch(ch);
    }
}

#[cfg(windows)]
fn draw(curses: &mut easycurses::EasyCurses, symbol: &str) {
    for grapheme in symbol.graphemes(true) {
        let ch = match grapheme {
            block::SEVEN_EIGHTHS => block::FULL,
            block::THREE_QUATERS => block::FULL,
            block::FIVE_EIGHTHS => block::HALF,
            block::THREE_EIGHTHS => block::HALF,
            block::ONE_QUATER => block::HALF,
            block::ONE_EIGHTH => " ",
            bar::SEVEN_EIGHTHS => bar::FULL,
            bar::THREE_QUATERS => bar::FULL,
            bar::FIVE_EIGHTHS => bar::HALF,
            bar::THREE_EIGHTHS => bar::HALF,
            bar::ONE_QUATER => bar::HALF,
            bar::ONE_EIGHTH => " ",
            ch => ch,
        };
        // curses.win.addch(ch);
        curses.print(ch);
    }
}

impl From<Color> for Option<easycurses::Color> {
    fn from(color: Color) -> Option<easycurses::Color> {
        match color {
            Color::Reset => None,
            Color::Black => Some(easycurses::Color::Black),
            Color::Red | Color::LightRed => Some(easycurses::Color::Red),
            Color::Green | Color::LightGreen => Some(easycurses::Color::Green),
            Color::Yellow | Color::LightYellow => Some(easycurses::Color::Yellow),
            Color::Magenta | Color::LightMagenta => Some(easycurses::Color::Magenta),
            Color::Cyan | Color::LightCyan => Some(easycurses::Color::Cyan),
            Color::White | Color::Gray | Color::DarkGray => Some(easycurses::Color::White),
            Color::Blue | Color::LightBlue => Some(easycurses::Color::Blue),
            Color::Rgb(_, _, _) => None,
        }
    }
}

impl From<Modifier> for pancurses::Attribute {
    fn from(modifier: Modifier) -> pancurses::Attribute {
        match modifier {
            Modifier::Blink => pancurses::Attribute::Blink,
            Modifier::Bold => pancurses::Attribute::Bold,
            Modifier::CrossedOut => pancurses::Attribute::Strikeout,
            Modifier::Faint => pancurses::Attribute::Dim,
            Modifier::Invert => pancurses::Attribute::Reverse,
            Modifier::Italic => pancurses::Attribute::Italic,
            Modifier::Underline => pancurses::Attribute::Underline,
            _ => pancurses::Attribute::Normal,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>More solutions<commit_after>// https://leetcode.com/problems/min-stack/

struct MinStack {
    stack: Vec<i32>,
    min_stack: Vec<i32>,
}

/**
 * `&self` means the method takes an immutable reference.
 * If you need a mutable reference, change it to `&mut self` instead.
 */
impl MinStack {
    fn new() -> Self {
        MinStack {
            stack: Vec::new(),
            min_stack: Vec::new(),
        }
    }

    fn push(&mut self, val: i32) {
        self.stack.push(val);
        if self.min_stack.len() == 0 {
            self.min_stack.push(val);
        } else {
            self.min_stack
                .push(val.min(*self.min_stack.last().unwrap()));
        }
    }

    fn pop(&mut self) {
        self.stack.pop();
        self.min_stack.pop();
    }

    fn top(&self) -> i32 {
        *self.stack.last().unwrap()
    }

    fn get_min(&self) -> i32 {
        *self.min_stack.last().unwrap()
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * let obj = MinStack::new();
 * obj.push(val);
 * obj.pop();
 * let ret_3: i32 = obj.top();
 * let ret_4: i32 = obj.get_min();
 */

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

    #[test]
    fn test_1() {
        todo!("Need some extra effort to make use of the provided test cases");
    }
}
<|endoftext|>


<commit_before><commit_msg>Alternative, more advanced design<commit_after>use core::marker::PhantomData;

pub const fn P4(page: &Page) -> Table<Level4> {
    Table {
        table_page: Page { number: 0o_777_777_777_777 },
        target_page_number: page.number,
        _phantom: PhantomData,
    }
}

pub fn translate(virtual_address: usize) -> Option<PhysicalAddress> {
    let page = Page::containing_address(virtual_address);
    let offset = virtual_address % PAGE_SIZE;

    let frame_number = {
        let p3 = match P4(&page).next_table() {
            None => return None,
            Some(t) => t,
        };

        if p3.entry().flags().contains(PRESENT | HUGE_PAGE) {
            // 1GiB page (address must be 1GiB aligned)
            let start_frame_number = p3.entry().pointed_frame().number;
            assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
            start_frame_number + Table::<Level2>::index_of(&page) * ENTRY_COUNT +
            Table::<Level1>::index_of(&page)
        } else {
            // 2MiB or 4KiB page
            let p2 = match p3.next_table() {
                None => return None,
                Some(t) => t,
            };

            if p2.entry().flags().contains(PRESENT | HUGE_PAGE) {
                // 2MiB page (address must be 2MiB aligned)
                let start_frame_number = p2.entry().pointed_frame().number;
                assert!(start_frame_number % ENTRY_COUNT == 0);
                start_frame_number + Table::<Level2>::index_of(&page)
            } else {
                // standard 4KiB page
                let p1 = match p2.next_table() {
                    None => return None,
                    Some(t) => t,
                };
                p1.entry().pointed_frame().number
            }
        }
    };
    Some(frame_number * PAGE_SIZE + offset)
}

pub fn map_to<A>(page: &Page, frame: Frame, flags: TableEntryFlags, allocator: &mut A)
    where A: FrameAllocator
{
    let mut p3 = P4(page).next_table_create(allocator);
    let mut p2 = p3.next_table_create(allocator);
    let mut p1 = p2.next_table_create(allocator);

    assert!(!p1.entry().flags().contains(PRESENT));
    p1.set_entry(TableEntry::new(frame, flags));
}

trait TableLevel{
    fn level_number() -> usize;
}
pub enum Level1 {}
pub enum Level2 {}
pub enum Level3 {}
pub enum Level4 {}

impl TableLevel for Level4 {
    fn level_number() -> usize {
        4
    }
}
impl TableLevel for Level3 {
    fn level_number() -> usize {
        3
    }
}
impl TableLevel for Level2 {
    fn level_number() -> usize {
        2
    }
}
impl TableLevel for Level1 {
    fn level_number() -> usize {
        1
    }
}

trait HierachicalLevel: TableLevel {
    type NextLevel: TableLevel;
}

impl HierachicalLevel for Level4 {
    type NextLevel = Level3;
}

impl HierachicalLevel for Level3 {
    type NextLevel = Level2;
}

impl HierachicalLevel for Level2 {
    type NextLevel = Level1;
}

impl<L> Table<L> where L: TableLevel
{
    pub fn index_of(page: &Page) -> usize {
        Self::index_of_page_number(page.number)
    }

    fn index_of_page_number(page_number: usize) -> usize {
        let s = (L::level_number() - 1) * 9;
        (page_number >> s) & 0o777
    }

    fn index(&self) -> usize {
        Self::index_of_page_number(self.target_page_number)
    }
}

use memory::{Frame, FrameAllocator};

pub const PAGE_SIZE: usize = 4096;
const ENTRY_SIZE: usize = 8;
const ENTRY_COUNT: usize = 512;

pub type PhysicalAddress = usize;
pub type VirtualAddress = usize;

pub struct Page {
    number: usize,
}

impl Page {
    fn containing_address(address: VirtualAddress) -> Page {
        match address {
            addr if addr < 0o_400_000_000_000_0000 => Page { number: addr / PAGE_SIZE },
            addr if addr >= 0o177777_400_000_000_000_0000 => {
                Page { number: (address / PAGE_SIZE) & 0o_777_777_777_777 }
            }
            _ => panic!("invalid address: 0x{:x}", address),
        }
    }

    pub fn start_address(&self) -> VirtualAddress {
        if self.number >= 0x800000000 {
            // sign extension necessary
            (self.number << 12) | 0xffff_000000000000
        } else {
            self.number << 12
        }
    }
}

pub struct Table<Level> {
    table_page: Page,
    target_page_number: usize,
    _phantom: PhantomData<Level>,
}

impl<L> Table<L> where L: TableLevel
{
    fn entry(&self) -> TableEntry {
        let entry_address = self.table_page.start_address() + self.index() * ENTRY_SIZE;
        unsafe { *(entry_address as *const _) }
    }

    fn set_entry(&mut self, value: TableEntry) {
        let entry_address = self.table_page.start_address() + self.index() * ENTRY_SIZE;
        unsafe { *(entry_address as *mut _) = value }
    }

    fn zero(&mut self) {
        let page = self.table_page.start_address() as *mut [TableEntry; ENTRY_COUNT];
        unsafe { *page = [TableEntry::unused(); ENTRY_COUNT] };
    }
}

impl<L> Table<L> where L: HierachicalLevel
{
    fn next_table_internal(&self) -> Table<L::NextLevel> {
        Table {
            table_page: Page {
                number: ((self.target_page_number << 9) & 0o_777_777_777_777) | self.index(),
            },
            target_page_number: self.target_page_number,
            _phantom: PhantomData,
        }
    }

    fn next_table(&self) -> Option<Table<L::NextLevel>> {
        if self.entry().flags().contains(PRESENT) {
            Some(self.next_table_internal())
        } else {
            None
        }
    }

    fn next_table_create<A>(&mut self, allocator: &mut A) -> Table<L::NextLevel>
        where A: FrameAllocator
    {
        match self.next_table() {
            Some(table) => table,
            None => {
                let frame = allocator.allocate_frame().expect("no frames available");
                self.set_entry(TableEntry::new(frame, PRESENT | WRITABLE));
                let mut next_table = self.next_table_internal();
                next_table.zero();
                next_table
            }
        }
    }
}

#[derive(Debug, Clone, Copy)]
struct TableEntry(u64);

impl TableEntry {
    const fn unused() -> TableEntry {
        TableEntry(0)
    }

    fn new(frame: Frame, flags: TableEntryFlags) -> TableEntry {
        let frame_addr = (frame.number << 12) & 0x000fffff_fffff000;
        TableEntry((frame_addr as u64) | flags.bits())
    }

    fn flags(&self) -> TableEntryFlags {
        TableEntryFlags::from_bits_truncate(self.0)
    }

    fn pointed_frame(&self) -> Frame {
        Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize }
    }
}

bitflags! {
    flags TableEntryFlags: u64 {
        const PRESENT =         1 << 0,
        const WRITABLE =        1 << 1,
        const USER_ACCESSIBLE = 1 << 2,
        const WRITE_THROUGH =   1 << 3,
        const NO_CACHE =        1 << 4,
        const ACCESSED =        1 << 5,
        const DIRTY =           1 << 6,
        const HUGE_PAGE =       1 << 7,
        const GLOBAL =          1 << 8,
        const NO_EXECUTE =      1 << 63,
    }
}
<|endoftext|>


<commit_before><commit_msg>copy and mutable closure<commit_after><|endoftext|>


<commit_before><commit_msg>Add addition example<commit_after>extern crate llvm;
use llvm::*;
use llvm::Attribute::*;
fn main() {
    let ctx = Context::new();
    let module = Module::new("add", &ctx);
    let func = module.add_function("add", Type::get::<fn(f64, f64) -> f64>(&ctx));
    func.add_attributes(&[NoUnwind, ReadNone]);
    let entry = func.append("entry");
    let builder = Builder::new(&ctx);
    builder.position_at_end(entry);
    let a = &func[0];
    let b = &func[1];
    let value = builder.build_add(a, b);
    builder.build_ret(value);
    module.verify().unwrap();
    let ee = JitEngine::new(&module, JitOptions {opt_level: 3}).unwrap();
    ee.with_function(func, |add:extern fn((f64, f64)) -> f64| {
        println!("{} + {} = {}", 1., 2., add((1., 2.)));
    });
}
<|endoftext|>


<commit_before><commit_msg>add direct3d matrix<commit_after><|endoftext|>


<commit_before><commit_msg>Implement Into trait for packets that included with define_packet_set!<commit_after><|endoftext|>


<commit_before>//! AWS Regions and helper functions
//!
//! Mostly used for translating the Region enum to a string AWS accepts.
//!
//! EG: UsEast1 to "us-east-1"

/// AWS Region
#[derive(Debug)]
pub enum Region {
    UsEast1,
    UsWest1,
    UsWest2,
    EuWest1,
    EuCentral1,
    ApSoutheast1,
    ApNortheast1,
    ApSoutheast2,
    SaEast1,
}

/// Translates region enum into AWS format.  EG: us-east-1
pub fn region_in_aws_format(region: &Region) -> String {
    match region {
        &Region::UsEast1 => "us-east-1".to_string(),
        &Region::UsWest1 => "us-west-1".to_string(),
        &Region::UsWest2 => "us-west-2".to_string(),
        &Region::EuWest1 => "eu-west-1".to_string(),
        &Region::EuCentral1 => "eu-central-1".to_string(),
        &Region::ApSoutheast1 => "ap-southeast-1".to_string(),
        &Region::ApNortheast1 => "ap-northeast-1".to_string(),
        &Region::ApSoutheast2 => "ap-southeast-2".to_string(),
        &Region::SaEast1 => "sa-east-1".to_string(),
    }
}

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

	#[test]
	fn regions_correctly_map_to_aws_strings() {
        let mut region = Region::UsEast1;
        if region_in_aws_format(&region) != "us-east-1" {
            panic!("Couldn't map us-east-1 enum right.");
        }
        region = Region::UsWest1;
        if region_in_aws_format(&region) != "us-west-1" {
            panic!("Couldn't map us-west-1 enum right.");
        }
        region = Region::UsWest2;
        if region_in_aws_format(&region) != "us-west-2" {
            panic!("Couldn't map us-west-2 enum right.");
        }
        region = Region::EuWest1;
        if region_in_aws_format(&region) != "eu-west-1" {
            panic!("Couldn't map eu-west-1 enum right.");
        }
        region = Region::EuCentral1;
        if region_in_aws_format(&region) != "eu-central-1" {
            panic!("Couldn't map eu-central-1 enum right.");
        }
        region = Region::ApSoutheast1;
        if region_in_aws_format(&region) != "ap-southeast-1" {
            panic!("Couldn't map ap-southeast-1 enum right.");
        }
        region = Region::ApNortheast1;
        if region_in_aws_format(&region) != "ap-northeast-1" {
            panic!("Couldn't map ap-northeast-1 enum right.");
        }
        region = Region::ApSoutheast2;
        if region_in_aws_format(&region) != "ap-southeast-2" {
            panic!("Couldn't map ap-southeast-2 enum right.");
        }
        region = Region::SaEast1;
        if region_in_aws_format(&region) != "sa-east-1" {
            panic!("Couldn't map sa-east-1 enum right.");
        }
    }
}
<commit_msg>Use FromStr trait to parse region strs<commit_after>//! AWS Regions and helper functions
//!
//! Mostly used for translating the Region enum to a string AWS accepts.
//!
//! EG: UsEast1 to "us-east-1"

use std::str::FromStr;

/// AWS Region
#[derive(Debug,PartialEq)]
pub enum Region {
    UsEast1,
    UsWest1,
    UsWest2,
    EuWest1,
    EuCentral1,
    ApSoutheast1,
    ApNortheast1,
    ApSoutheast2,
    SaEast1,
}

#[derive(Debug,PartialEq)]
pub struct ParseRegionError;

impl FromStr for Region {
    type Err = ParseRegionError;

    fn from_str(s: &str) -> Result<Region, ParseRegionError> {
        match s {
            "us-east-1" => Ok(Region::UsEast1),
            "us-west-1" => Ok(Region::UsWest1),
            "us-west-2" => Ok(Region::UsWest2),
            "eu-west-1" => Ok(Region::EuWest1),
            "eu-central-1" => Ok(Region::EuCentral1),
            "ap-southeast-1" => Ok(Region::ApSoutheast1),
            "ap-northeast-1" => Ok(Region::ApNortheast1),
            "ap-southeast-2" => Ok(Region::ApSoutheast2),
            "sa-east-1" => Ok(Region::SaEast1),
            _ => Err(ParseRegionError)
        }
    }
}

/// Translates region enum into AWS format.  EG: us-east-1
pub fn region_in_aws_format(region: &Region) -> String {
    match region {
        &Region::UsEast1 => "us-east-1".to_string(),
        &Region::UsWest1 => "us-west-1".to_string(),
        &Region::UsWest2 => "us-west-2".to_string(),
        &Region::EuWest1 => "eu-west-1".to_string(),
        &Region::EuCentral1 => "eu-central-1".to_string(),
        &Region::ApSoutheast1 => "ap-southeast-1".to_string(),
        &Region::ApNortheast1 => "ap-northeast-1".to_string(),
        &Region::ApSoutheast2 => "ap-southeast-2".to_string(),
        &Region::SaEast1 => "sa-east-1".to_string(),
    }
}

#[cfg(test)]
mod tests {
	use super::*;
    use std::str::FromStr;

    #[test]
    fn from_str_for_region() {
        assert_eq!(FromStr::from_str("us-east-1"), Ok(Region::UsEast1));
        assert_eq!(FromStr::from_str("us-west-1"), Ok(Region::UsWest1));
        assert_eq!(FromStr::from_str("us-west-2"), Ok(Region::UsWest2));
        assert_eq!(FromStr::from_str("eu-west-1"), Ok(Region::EuWest1));
        assert_eq!(FromStr::from_str("eu-central-1"), Ok(Region::EuCentral1));
    }

	#[test]
	fn regions_correctly_map_to_aws_strings() {
        let mut region = Region::UsEast1;
        if region_in_aws_format(&region) != "us-east-1" {
            panic!("Couldn't map us-east-1 enum right.");
        }
        region = Region::UsWest1;
        if region_in_aws_format(&region) != "us-west-1" {
            panic!("Couldn't map us-west-1 enum right.");
        }
        region = Region::UsWest2;
        if region_in_aws_format(&region) != "us-west-2" {
            panic!("Couldn't map us-west-2 enum right.");
        }
        region = Region::EuWest1;
        if region_in_aws_format(&region) != "eu-west-1" {
            panic!("Couldn't map eu-west-1 enum right.");
        }
        region = Region::EuCentral1;
        if region_in_aws_format(&region) != "eu-central-1" {
            panic!("Couldn't map eu-central-1 enum right.");
        }
        region = Region::ApSoutheast1;
        if region_in_aws_format(&region) != "ap-southeast-1" {
            panic!("Couldn't map ap-southeast-1 enum right.");
        }
        region = Region::ApNortheast1;
        if region_in_aws_format(&region) != "ap-northeast-1" {
            panic!("Couldn't map ap-northeast-1 enum right.");
        }
        region = Region::ApSoutheast2;
        if region_in_aws_format(&region) != "ap-southeast-2" {
            panic!("Couldn't map ap-southeast-2 enum right.");
        }
        region = Region::SaEast1;
        if region_in_aws_format(&region) != "sa-east-1" {
            panic!("Couldn't map sa-east-1 enum right.");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>coap work<commit_after><|endoftext|>