<commit_before>//! A singly-linked list.
//!
//! Using this data structure only makes sense under very specific
//! circumstances:
//!
//! - If you have a list that rarely stores more than one element, then this
//!   data-structure can store the element without allocating and only uses as
//!   much space as a `Option<(T, usize)>`. If T can double as the `Option`
//!   discriminant, it will even only be as large as `T, usize`.
//!
//! If you expect to store more than 1 element in the common case, steer clear
//! and use a `Vec<T>`, `Box<[T]>`, or a `SmallVec<T>`.

#[cfg(test)]
mod tests;

#[derive(Clone)]
pub struct TinyList<T: PartialEq> {
    head: Option<Element<T>>
}

impl<T: PartialEq> TinyList<T> {
    #[inline]
    pub fn new() -> TinyList<T> {
        TinyList {
            head: None
        }
    }

    #[inline]
    pub fn new_single(data: T) -> TinyList<T> {
        TinyList {
            head: Some(Element {
                data,
                next: None,
            })
        }
    }

    #[inline]
    pub fn insert(&mut self, data: T) {
        self.head = Some(Element {
            data,
            next: self.head.take().map(Box::new)
        });
    }

    #[inline]
    pub fn remove(&mut self, data: &T) -> bool {
        self.head = match self.head {
            Some(ref mut head) if head.data == *data => {
                head.next.take().map(|x| *x)
            }
            Some(ref mut head) => return head.remove_next(data),
            None => return false,
        };
        true
    }

    #[inline]
    pub fn contains(&self, data: &T) -> bool {
        let mut elem = self.head.as_ref();
        while let Some(ref e) = elem {
            if &e.data == data {
                return true;
            }
            elem = e.next.as_ref().map(|e| &**e);
        }
        false
    }

    #[inline]
    pub fn len(&self) -> usize {
        let (mut elem, mut count) = (self.head.as_ref(), 0);
        while let Some(ref e) = elem {
            count += 1;
            elem = e.next.as_ref().map(|e| &**e);
        }
        count
    }
}

#[derive(Clone)]
struct Element<T: PartialEq> {
    data: T,
    next: Option<Box<Element<T>>>,
}

impl<T: PartialEq> Element<T> {
    fn remove_next(&mut self, data: &T) -> bool {
        let new_next = match self.next {
            Some(ref mut next) if next.data == *data => next.next.take(),
            Some(ref mut next) => return next.remove_next(data),
            None => return false,
        };
        self.next = new_next;
        true
    }
}
<commit_msg>Rollup merge of #67239 - llogiq:tiny-list-iterative-remove, r=Mark-Simulacrum<commit_after>//! A singly-linked list.
//!
//! Using this data structure only makes sense under very specific
//! circumstances:
//!
//! - If you have a list that rarely stores more than one element, then this
//!   data-structure can store the element without allocating and only uses as
//!   much space as a `Option<(T, usize)>`. If T can double as the `Option`
//!   discriminant, it will even only be as large as `T, usize`.
//!
//! If you expect to store more than 1 element in the common case, steer clear
//! and use a `Vec<T>`, `Box<[T]>`, or a `SmallVec<T>`.

#[cfg(test)]
mod tests;

#[derive(Clone)]
pub struct TinyList<T: PartialEq> {
    head: Option<Element<T>>,
}

impl<T: PartialEq> TinyList<T> {
    #[inline]
    pub fn new() -> TinyList<T> {
        TinyList { head: None }
    }

    #[inline]
    pub fn new_single(data: T) -> TinyList<T> {
        TinyList { head: Some(Element { data, next: None }) }
    }

    #[inline]
    pub fn insert(&mut self, data: T) {
        self.head = Some(Element { data, next: self.head.take().map(Box::new) });
    }

    #[inline]
    pub fn remove(&mut self, data: &T) -> bool {
        self.head = match self.head {
            Some(ref mut head) if head.data == *data => head.next.take().map(|x| *x),
            Some(ref mut head) => return head.remove_next(data),
            None => return false,
        };
        true
    }

    #[inline]
    pub fn contains(&self, data: &T) -> bool {
        let mut elem = self.head.as_ref();
        while let Some(ref e) = elem {
            if &e.data == data {
                return true;
            }
            elem = e.next.as_ref().map(|e| &**e);
        }
        false
    }

    #[inline]
    pub fn len(&self) -> usize {
        let (mut elem, mut count) = (self.head.as_ref(), 0);
        while let Some(ref e) = elem {
            count += 1;
            elem = e.next.as_ref().map(|e| &**e);
        }
        count
    }
}

#[derive(Clone)]
struct Element<T: PartialEq> {
    data: T,
    next: Option<Box<Element<T>>>,
}

impl<T: PartialEq> Element<T> {
    fn remove_next(&mut self, data: &T) -> bool {
        let mut n = self;
        loop {
            match n.next {
                Some(ref mut next) if next.data == *data => {
                    n.next = next.next.take();
                    return true;
                }
                Some(ref mut next) => n = next,
                None => return false,
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #11985 - Veykril:config-valid, r=Veykril<commit_after><|endoftext|>


<commit_before><commit_msg>ac97: Mark pci::ac97_bus_master::test::start_playback ignored<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2014-2016 Robert Clipsham <robert@octarineparrot.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Support for sending and receiving data link layer packets using the WinPcap library

extern crate libc;
extern crate winapi;

use bindings::{bpf, winpcap};
use {DataLinkReceiver, DataLinkSender, MacAddr, NetworkInterface};

use ipnetwork::{ip_mask_to_prefix, IpNetwork};

use std::cmp;
use std::collections::VecDeque;
use std::ffi::{CStr, CString};
use std::io;
use std::mem;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::Arc;

struct WinPcapAdapter {
    adapter: winpcap::LPADAPTER,
}

impl Drop for WinPcapAdapter {
    fn drop(&mut self) {
        unsafe {
            winpcap::PacketCloseAdapter(self.adapter);
        }
    }
}

struct WinPcapPacket {
    packet: winpcap::LPPACKET,
}

impl Drop for WinPcapPacket {
    fn drop(&mut self) {
        unsafe {
            winpcap::PacketFreePacket(self.packet);
        }
    }
}

/// WinPcap specific configuration
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Config {
    /// The size of buffer to use when writing packets. Defaults to 4096
    pub write_buffer_size: usize,

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

impl<'a> From<&'a super::Config> for Config {
    fn from(config: &super::Config) -> Config {
        Config {
            write_buffer_size: config.write_buffer_size,
            read_buffer_size: config.read_buffer_size,
        }
    }
}

impl Default for Config {
    fn default() -> Config {
        Config {
            write_buffer_size: 4096,
            read_buffer_size: 4096,
        }
    }
}

/// Create a datalink channel using the WinPcap library
#[inline]
pub fn channel(network_interface: &NetworkInterface,
               config: Config)
    -> io::Result<super::Channel> {
    let mut read_buffer = Vec::new();
    read_buffer.resize(config.read_buffer_size, 0u8);

    let mut write_buffer = Vec::new();
    write_buffer.resize(config.write_buffer_size, 0u8);

    let adapter = unsafe {
        let net_if_str = CString::new(network_interface.name.as_bytes()).unwrap();
        winpcap::PacketOpenAdapter(net_if_str.as_ptr() as *mut libc::c_char)
    };
    if adapter.is_null() {
        return Err(io::Error::last_os_error());
    }

    let ret = unsafe { winpcap::PacketSetHwFilter(adapter, winpcap::NDIS_PACKET_TYPE_PROMISCUOUS) };
    if ret == 0 {
        return Err(io::Error::last_os_error());
    }

    // Set kernel buffer size
    let ret = unsafe { winpcap::PacketSetBuff(adapter, config.read_buffer_size as libc::c_int) };
    if ret == 0 {
        return Err(io::Error::last_os_error());
    }

    // Immediate mode
    let ret = unsafe { winpcap::PacketSetMinToCopy(adapter, 1) };
    if ret == 0 {
        return Err(io::Error::last_os_error());
    }

    let read_packet = unsafe { winpcap::PacketAllocatePacket() };
    if read_packet.is_null() {
        unsafe {
            winpcap::PacketCloseAdapter(adapter);
        }
        return Err(io::Error::last_os_error());
    }

    unsafe {
        winpcap::PacketInitPacket(read_packet,
                                  read_buffer.as_mut_ptr() as winpcap::PVOID,
                                  config.read_buffer_size as winpcap::UINT)
    }

    let write_packet = unsafe { winpcap::PacketAllocatePacket() };
    if write_packet.is_null() {
        unsafe {
            winpcap::PacketFreePacket(read_packet);
            winpcap::PacketCloseAdapter(adapter);
        }
        return Err(io::Error::last_os_error());
    }

    unsafe {
        winpcap::PacketInitPacket(write_packet,
                                  write_buffer.as_mut_ptr() as winpcap::PVOID,
                                  config.write_buffer_size as winpcap::UINT)
    }

    let adapter = Arc::new(WinPcapAdapter { adapter: adapter });
    let sender = Box::new(DataLinkSenderImpl {
        adapter: adapter.clone(),
        _write_buffer: write_buffer,
        packet: WinPcapPacket { packet: write_packet },
    });
    let receiver = Box::new(DataLinkReceiverImpl {
        adapter: adapter,
        _read_buffer: read_buffer,
        packet: WinPcapPacket { packet: read_packet },
        // Enough room for minimally sized packets without reallocating
        packets: VecDeque::with_capacity(unsafe { (*read_packet).Length } as usize / 64),
    });
    Ok(super::Channel::Ethernet(sender, receiver))
}

struct DataLinkSenderImpl {
    adapter: Arc<WinPcapAdapter>,
    _write_buffer: Vec<u8>,
    packet: WinPcapPacket,
}

impl DataLinkSender for DataLinkSenderImpl {
    #[inline]
    fn build_and_send(&mut self,
                      num_packets: usize,
                      packet_size: usize,
                      func: &mut FnMut(&mut [u8]))
        -> Option<io::Result<()>> {
        let len = num_packets * packet_size;
        if len >= unsafe { (*self.packet.packet).Length } as usize {
            None
        } else {
            let min = unsafe { cmp::min((*self.packet.packet).Length as usize, len) };
            let slice: &mut [u8] =
                unsafe { slice::from_raw_parts_mut((*self.packet.packet).Buffer as *mut u8, min) };
            for chunk in slice.chunks_mut(packet_size) {
                func(chunk);

                // Make sure the right length of packet is sent
                let old_len = unsafe { (*self.packet.packet).Length };
                unsafe {
                    (*self.packet.packet).Length = packet_size as u32;
                }

                let ret = unsafe {
                    winpcap::PacketSendPacket(self.adapter.adapter, self.packet.packet, 0)
                };

                unsafe {
                    (*self.packet.packet).Length = old_len;
                }

                if ret == 0 {
                    return Some(Err(io::Error::last_os_error()));
                }
            }
            Some(Ok(()))
        }
    }

    #[inline]
    fn send_to(&mut self,
               packet: &[u8],
               _dst: Option<NetworkInterface>)
        -> Option<io::Result<()>> {
        self.build_and_send(1,
                            packet.len(),
                            &mut |eh: &mut [u8]| {
                                eh.copy_from_slice(packet);
                            })
    }
}

unsafe impl Send for DataLinkSenderImpl {}
unsafe impl Sync for DataLinkSenderImpl {}

struct DataLinkReceiverImpl {
    adapter: Arc<WinPcapAdapter>,
    _read_buffer: Vec<u8>,
    packet: WinPcapPacket,
    packets: VecDeque<(usize, usize)>,
}

unsafe impl Send for DataLinkReceiverImpl {}
unsafe impl Sync for DataLinkReceiverImpl {}

impl DataLinkReceiver for DataLinkReceiverImpl {
    fn next(&mut self) -> io::Result<&[u8]> {
        // NOTE Most of the logic here is identical to FreeBSD/OS X
        while self.packets.is_empty() {
            let ret = unsafe {
                winpcap::PacketReceivePacket(self.adapter.adapter, self.packet.packet, 0)
            };
            let buflen = match ret {
                0 => return Err(io::Error::last_os_error()),
                _ => unsafe { (*self.packet.packet).ulBytesReceived as isize },
            };
            let mut ptr = unsafe { (*self.packet.packet).Buffer };
            let end = unsafe { (*self.packet.packet).Buffer.offset(buflen) };
            while ptr < end {
                unsafe {
                    let packet: *const bpf::bpf_hdr = mem::transmute(ptr);
                    let start = ptr as isize + (*packet).bh_hdrlen as isize -
                                (*self.packet.packet).Buffer as isize;
                    self.packets.push_back((start as usize, (*packet).bh_caplen as usize));
                    let offset = (*packet).bh_hdrlen as isize + (*packet).bh_caplen as isize;
                    ptr = ptr.offset(bpf::BPF_WORDALIGN(offset));
                }
            }
        }
        let (start, len) = self.packets.pop_front().unwrap();
        let slice = unsafe {
            let data = (*self.packet.packet).Buffer as usize + start;
            slice::from_raw_parts(data as *const u8, len)
        };
        Ok(slice)
    }
}

/// Get a list of available network interfaces for the current machine.
pub fn interfaces() -> Vec<NetworkInterface> {
    use bindings::winpcap;

    let mut adapters_size = 0u32;

    unsafe {
        let mut tmp: winpcap::IP_ADAPTER_INFO = mem::zeroed();
        // FIXME [windows] This only gets IPv4 addresses - should use
        // GetAdaptersAddresses
        winpcap::GetAdaptersInfo(&mut tmp, &mut adapters_size);
    }

    let vec_size = adapters_size / mem::size_of::<winpcap::IP_ADAPTER_INFO>() as u32;

    if adapters_size % mem::size_of::<winpcap::IP_ADAPTER_INFO>() as u32 != 0 {
        vec_size += 1;
    }

    let mut adapters = Vec::with_capacity(vec_size as usize);

    // FIXME [windows] Check return code
    unsafe {
        winpcap::GetAdaptersInfo(adapters.as_mut_ptr(), &mut adapters_size);
    }

    // Create a complete list of NetworkInterfaces for the machine
    let mut cursor = adapters.as_mut_ptr();
    let mut all_ifaces = Vec::with_capacity(vec_size as usize);
    while !cursor.is_null() {
        let mac = unsafe {
            MacAddr((*cursor).Address[0],
                    (*cursor).Address[1],
                    (*cursor).Address[2],
                    (*cursor).Address[3],
                    (*cursor).Address[4],
                    (*cursor).Address[5])
        };
        let mut ip_cursor = unsafe { &mut (*cursor).IpAddressList as winpcap::PIP_ADDR_STRING };
        let mut ips = Vec::new();
        while !ip_cursor.is_null() {
            if let Ok(ip_network) = parse_ip_network(ip_cursor) {
                ips.push(ip_network);
            }
            ip_cursor = unsafe { (*ip_cursor).Next };
        }

        unsafe {
            let name_str_ptr = (*cursor).AdapterName.as_ptr() as *const i8;

            let bytes = CStr::from_ptr(name_str_ptr).to_bytes();
            let name_str = from_utf8_unchecked(bytes).to_owned();

            all_ifaces.push(NetworkInterface {
                name: name_str,
                index: (*cursor).Index,
                mac: Some(mac),
                ips: ips,
                // flags: (*cursor).Type, // FIXME [windows]
                flags: 0,
            });

            cursor = (*cursor).Next;
        }
    }

    let mut buf = vec![0u8; 4096];
    let mut buflen = buf.len() as u32;

    if unsafe { winpcap::PacketGetAdapterNames(buf.as_mut_ptr() as *mut i8, &mut buflen) } == 0 {
        buf.resize(buflen as usize, 0);

        // Second call should now work with the correct buffer size. If not, this may be
        // due to some privilege or other unforseen issue.
        if unsafe { winpcap::PacketGetAdapterNames(buf.as_mut_ptr() as *mut i8, &mut buflen) } == 0 {
            panic!("Unable to get interface list despite increasing buffer size");
        }
    }

    let buf_str = unsafe { from_utf8_unchecked(&buf) };
    let iface_names = buf_str.split("\0\0").next();
    let mut vec = Vec::new();

    // Return only supported adapters
    match iface_names {
        Some(iface_names) => {
            for iface in iface_names.split('\0') {
                let name = iface.to_owned();
                let next = all_ifaces.iter().filter(|x| name[..].ends_with(&x.name[..])).next();
                if next.is_some() {
                    let mut iface = next.unwrap().clone();
                    iface.name = name;
                    vec.push(iface);
                }
            }
        }
        None => (),
    };

    vec
}

fn parse_ip_network(ip_cursor: winpcap::PIP_ADDR_STRING) -> Result<IpNetwork, ()> {
    let ip_str_ptr = unsafe { &(*ip_cursor) }.IpAddress.String.as_ptr() as *const i8;
    let ip_bytes = unsafe { CStr::from_ptr(ip_str_ptr).to_bytes() };
    let ip_str = unsafe { from_utf8_unchecked(ip_bytes).to_owned() };
    let ip = ip_str.parse().map_err(|_| ())?;

    let mask_str_ptr = unsafe { &(*ip_cursor) }.IpMask.String.as_ptr() as *const i8;
    let mask_bytes = unsafe { CStr::from_ptr(mask_str_ptr).to_bytes() };
    let mask_str = unsafe { from_utf8_unchecked(mask_bytes).to_owned() };
    let mask = mask_str.parse().map_err(|_| ())?;

    let prefix = ip_mask_to_prefix(mask).map_err(|_| ())?;
    IpNetwork::new(ip, prefix).map_err(|_| ())
}
<commit_msg>call GetAdaptersInfo will crash<commit_after>// Copyright (c) 2014-2016 Robert Clipsham <robert@octarineparrot.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Support for sending and receiving data link layer packets using the WinPcap library

extern crate libc;
extern crate winapi;

use bindings::{bpf, winpcap};
use {DataLinkReceiver, DataLinkSender, MacAddr, NetworkInterface};

use ipnetwork::{ip_mask_to_prefix, IpNetwork};

use std::cmp;
use std::collections::VecDeque;
use std::ffi::{CStr, CString};
use std::io;
use std::mem;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::Arc;

struct WinPcapAdapter {
    adapter: winpcap::LPADAPTER,
}

impl Drop for WinPcapAdapter {
    fn drop(&mut self) {
        unsafe {
            winpcap::PacketCloseAdapter(self.adapter);
        }
    }
}

struct WinPcapPacket {
    packet: winpcap::LPPACKET,
}

impl Drop for WinPcapPacket {
    fn drop(&mut self) {
        unsafe {
            winpcap::PacketFreePacket(self.packet);
        }
    }
}

/// WinPcap specific configuration
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Config {
    /// The size of buffer to use when writing packets. Defaults to 4096
    pub write_buffer_size: usize,

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

impl<'a> From<&'a super::Config> for Config {
    fn from(config: &super::Config) -> Config {
        Config {
            write_buffer_size: config.write_buffer_size,
            read_buffer_size: config.read_buffer_size,
        }
    }
}

impl Default for Config {
    fn default() -> Config {
        Config {
            write_buffer_size: 4096,
            read_buffer_size: 4096,
        }
    }
}

/// Create a datalink channel using the WinPcap library
#[inline]
pub fn channel(network_interface: &NetworkInterface,
               config: Config)
    -> io::Result<super::Channel> {
    let mut read_buffer = Vec::new();
    read_buffer.resize(config.read_buffer_size, 0u8);

    let mut write_buffer = Vec::new();
    write_buffer.resize(config.write_buffer_size, 0u8);

    let adapter = unsafe {
        let net_if_str = CString::new(network_interface.name.as_bytes()).unwrap();
        winpcap::PacketOpenAdapter(net_if_str.as_ptr() as *mut libc::c_char)
    };
    if adapter.is_null() {
        return Err(io::Error::last_os_error());
    }

    let ret = unsafe { winpcap::PacketSetHwFilter(adapter, winpcap::NDIS_PACKET_TYPE_PROMISCUOUS) };
    if ret == 0 {
        return Err(io::Error::last_os_error());
    }

    // Set kernel buffer size
    let ret = unsafe { winpcap::PacketSetBuff(adapter, config.read_buffer_size as libc::c_int) };
    if ret == 0 {
        return Err(io::Error::last_os_error());
    }

    // Immediate mode
    let ret = unsafe { winpcap::PacketSetMinToCopy(adapter, 1) };
    if ret == 0 {
        return Err(io::Error::last_os_error());
    }

    let read_packet = unsafe { winpcap::PacketAllocatePacket() };
    if read_packet.is_null() {
        unsafe {
            winpcap::PacketCloseAdapter(adapter);
        }
        return Err(io::Error::last_os_error());
    }

    unsafe {
        winpcap::PacketInitPacket(read_packet,
                                  read_buffer.as_mut_ptr() as winpcap::PVOID,
                                  config.read_buffer_size as winpcap::UINT)
    }

    let write_packet = unsafe { winpcap::PacketAllocatePacket() };
    if write_packet.is_null() {
        unsafe {
            winpcap::PacketFreePacket(read_packet);
            winpcap::PacketCloseAdapter(adapter);
        }
        return Err(io::Error::last_os_error());
    }

    unsafe {
        winpcap::PacketInitPacket(write_packet,
                                  write_buffer.as_mut_ptr() as winpcap::PVOID,
                                  config.write_buffer_size as winpcap::UINT)
    }

    let adapter = Arc::new(WinPcapAdapter { adapter: adapter });
    let sender = Box::new(DataLinkSenderImpl {
        adapter: adapter.clone(),
        _write_buffer: write_buffer,
        packet: WinPcapPacket { packet: write_packet },
    });
    let receiver = Box::new(DataLinkReceiverImpl {
        adapter: adapter,
        _read_buffer: read_buffer,
        packet: WinPcapPacket { packet: read_packet },
        // Enough room for minimally sized packets without reallocating
        packets: VecDeque::with_capacity(unsafe { (*read_packet).Length } as usize / 64),
    });
    Ok(super::Channel::Ethernet(sender, receiver))
}

struct DataLinkSenderImpl {
    adapter: Arc<WinPcapAdapter>,
    _write_buffer: Vec<u8>,
    packet: WinPcapPacket,
}

impl DataLinkSender for DataLinkSenderImpl {
    #[inline]
    fn build_and_send(&mut self,
                      num_packets: usize,
                      packet_size: usize,
                      func: &mut FnMut(&mut [u8]))
        -> Option<io::Result<()>> {
        let len = num_packets * packet_size;
        if len >= unsafe { (*self.packet.packet).Length } as usize {
            None
        } else {
            let min = unsafe { cmp::min((*self.packet.packet).Length as usize, len) };
            let slice: &mut [u8] =
                unsafe { slice::from_raw_parts_mut((*self.packet.packet).Buffer as *mut u8, min) };
            for chunk in slice.chunks_mut(packet_size) {
                func(chunk);

                // Make sure the right length of packet is sent
                let old_len = unsafe { (*self.packet.packet).Length };
                unsafe {
                    (*self.packet.packet).Length = packet_size as u32;
                }

                let ret = unsafe {
                    winpcap::PacketSendPacket(self.adapter.adapter, self.packet.packet, 0)
                };

                unsafe {
                    (*self.packet.packet).Length = old_len;
                }

                if ret == 0 {
                    return Some(Err(io::Error::last_os_error()));
                }
            }
            Some(Ok(()))
        }
    }

    #[inline]
    fn send_to(&mut self,
               packet: &[u8],
               _dst: Option<NetworkInterface>)
        -> Option<io::Result<()>> {
        self.build_and_send(1,
                            packet.len(),
                            &mut |eh: &mut [u8]| {
                                eh.copy_from_slice(packet);
                            })
    }
}

unsafe impl Send for DataLinkSenderImpl {}
unsafe impl Sync for DataLinkSenderImpl {}

struct DataLinkReceiverImpl {
    adapter: Arc<WinPcapAdapter>,
    _read_buffer: Vec<u8>,
    packet: WinPcapPacket,
    packets: VecDeque<(usize, usize)>,
}

unsafe impl Send for DataLinkReceiverImpl {}
unsafe impl Sync for DataLinkReceiverImpl {}

impl DataLinkReceiver for DataLinkReceiverImpl {
    fn next(&mut self) -> io::Result<&[u8]> {
        // NOTE Most of the logic here is identical to FreeBSD/OS X
        while self.packets.is_empty() {
            let ret = unsafe {
                winpcap::PacketReceivePacket(self.adapter.adapter, self.packet.packet, 0)
            };
            let buflen = match ret {
                0 => return Err(io::Error::last_os_error()),
                _ => unsafe { (*self.packet.packet).ulBytesReceived as isize },
            };
            let mut ptr = unsafe { (*self.packet.packet).Buffer };
            let end = unsafe { (*self.packet.packet).Buffer.offset(buflen) };
            while ptr < end {
                unsafe {
                    let packet: *const bpf::bpf_hdr = mem::transmute(ptr);
                    let start = ptr as isize + (*packet).bh_hdrlen as isize -
                                (*self.packet.packet).Buffer as isize;
                    self.packets.push_back((start as usize, (*packet).bh_caplen as usize));
                    let offset = (*packet).bh_hdrlen as isize + (*packet).bh_caplen as isize;
                    ptr = ptr.offset(bpf::BPF_WORDALIGN(offset));
                }
            }
        }
        let (start, len) = self.packets.pop_front().unwrap();
        let slice = unsafe {
            let data = (*self.packet.packet).Buffer as usize + start;
            slice::from_raw_parts(data as *const u8, len)
        };
        Ok(slice)
    }
}

/// Get a list of available network interfaces for the current machine.
pub fn interfaces() -> Vec<NetworkInterface> {
    use bindings::winpcap;

    let mut adapters_size = 0u32;

    unsafe {
        let mut tmp: winpcap::IP_ADAPTER_INFO = mem::zeroed();
        // FIXME [windows] This only gets IPv4 addresses - should use
        // GetAdaptersAddresses
        winpcap::GetAdaptersInfo(&mut tmp, &mut adapters_size);
    }

    let mut vec_size = adapters_size / mem::size_of::<winpcap::IP_ADAPTER_INFO>() as u32;
    if adapters_size % mem::size_of::<winpcap::IP_ADAPTER_INFO>() as u32 != 0 {
        vec_size += 1;
    }
    let mut adapters = Vec::with_capacity(vec_size as usize);

    // FIXME [windows] Check return code
    unsafe {
        winpcap::GetAdaptersInfo(adapters.as_mut_ptr(), &mut adapters_size);
    }

    // Create a complete list of NetworkInterfaces for the machine
    let mut cursor = adapters.as_mut_ptr();
    let mut all_ifaces = Vec::with_capacity(vec_size as usize);
    while !cursor.is_null() {
        let mac = unsafe {
            MacAddr((*cursor).Address[0],
                    (*cursor).Address[1],
                    (*cursor).Address[2],
                    (*cursor).Address[3],
                    (*cursor).Address[4],
                    (*cursor).Address[5])
        };
        let mut ip_cursor = unsafe { &mut (*cursor).IpAddressList as winpcap::PIP_ADDR_STRING };
        let mut ips = Vec::new();
        while !ip_cursor.is_null() {
            if let Ok(ip_network) = parse_ip_network(ip_cursor) {
                ips.push(ip_network);
            }
            ip_cursor = unsafe { (*ip_cursor).Next };
        }

        unsafe {
            let name_str_ptr = (*cursor).AdapterName.as_ptr() as *const i8;

            let bytes = CStr::from_ptr(name_str_ptr).to_bytes();
            let name_str = from_utf8_unchecked(bytes).to_owned();

            all_ifaces.push(NetworkInterface {
                name: name_str,
                index: (*cursor).Index,
                mac: Some(mac),
                ips: ips,
                // flags: (*cursor).Type, // FIXME [windows]
                flags: 0,
            });

            cursor = (*cursor).Next;
        }
    }

    let mut buf = vec![0u8; 4096];
    let mut buflen = buf.len() as u32;

    if unsafe { winpcap::PacketGetAdapterNames(buf.as_mut_ptr() as *mut i8, &mut buflen) } == 0 {
        buf.resize(buflen as usize, 0);

        // Second call should now work with the correct buffer size. If not, this may be
        // due to some privilege or other unforseen issue.
        if unsafe { winpcap::PacketGetAdapterNames(buf.as_mut_ptr() as *mut i8, &mut buflen) } == 0 {
            panic!("Unable to get interface list despite increasing buffer size");
        }
    }

    let buf_str = unsafe { from_utf8_unchecked(&buf) };
    let iface_names = buf_str.split("\0\0").next();
    let mut vec = Vec::new();

    // Return only supported adapters
    match iface_names {
        Some(iface_names) => {
            for iface in iface_names.split('\0') {
                let name = iface.to_owned();
                let next = all_ifaces.iter().filter(|x| name[..].ends_with(&x.name[..])).next();
                if next.is_some() {
                    let mut iface = next.unwrap().clone();
                    iface.name = name;
                    vec.push(iface);
                }
            }
        }
        None => (),
    };

    vec
}

fn parse_ip_network(ip_cursor: winpcap::PIP_ADDR_STRING) -> Result<IpNetwork, ()> {
    let ip_str_ptr = unsafe { &(*ip_cursor) }.IpAddress.String.as_ptr() as *const i8;
    let ip_bytes = unsafe { CStr::from_ptr(ip_str_ptr).to_bytes() };
    let ip_str = unsafe { from_utf8_unchecked(ip_bytes).to_owned() };
    let ip = ip_str.parse().map_err(|_| ())?;

    let mask_str_ptr = unsafe { &(*ip_cursor) }.IpMask.String.as_ptr() as *const i8;
    let mask_bytes = unsafe { CStr::from_ptr(mask_str_ptr).to_bytes() };
    let mask_str = unsafe { from_utf8_unchecked(mask_bytes).to_owned() };
    let mask = mask_str.parse().map_err(|_| ())?;

    let prefix = ip_mask_to_prefix(mask).map_err(|_| ())?;
    IpNetwork::new(ip, prefix).map_err(|_| ())
}
<|endoftext|>


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

#![no_std]
#![feature(profiler_runtime)]
#![profiler_runtime]
#![unstable(feature = "profiler_runtime_lib",
            reason = "internal implementation detail of rustc right now",
            issue = "0")]
#![allow(unused_features)]
#![feature(staged_api)]
<commit_msg>[nll] libprofiler_builtins: enable feature(nll) for bootstrap<commit_after>// Copyright 2017 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.

#![no_std]
#![feature(profiler_runtime)]
#![profiler_runtime]
#![unstable(feature = "profiler_runtime_lib",
            reason = "internal implementation detail of rustc right now",
            issue = "0")]
#![allow(unused_features)]
#![cfg_attr(not(stage0), feature(nll))]
#![feature(staged_api)]
<|endoftext|>


<commit_before><commit_msg>Use `Context::load` to jump out of finished coroutine.<commit_after><|endoftext|>


<commit_before><commit_msg>More refactoring<commit_after><|endoftext|>


<commit_before><commit_msg>Adding content-type to all requests. Adding unit tests to ensure the unit test is correct. This required me to make a utility function that just spit out a ContentType header as I felt it's important enough that this can be tested.<commit_after><|endoftext|>


<commit_before><commit_msg>implement status_thing()<commit_after><|endoftext|>


<commit_before>#![feature(unboxed_closures, macro_rules, globs)]

extern crate shader_version;
extern crate event;
extern crate event_loop;
extern crate conrod;
extern crate graphics;
extern crate window;
extern crate opengl_graphics;
extern crate current;

use conrod::*;

use current::Set;

use event::Event;
use event_loop::{Events, Ups, MaxFps};

use opengl_graphics::Gl;
use opengl_graphics::glyph_cache::GlyphCache as Font;

use shader_version::opengl::OpenGL;

use window::{Window, WindowSettings};

use std::comm::TryRecvError;

use std::default::Default;

use std::io::fs::{mod, PathExtensions};
use std::io::IoResult;

use std::os;

use std::cell::RefCell;

pub struct FileDialog {
    title: String,
    dimen: [u32, ..2],
    samples: u8,
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: Font,
    filter_hidden: bool,
}

macro_rules! setter(
    ($field:ident: $ty:ty -> $ret:ident) => (
        fn $field(mut self, $field: $ty) -> $ret {
            self.$field = $field;
            self
        }
    );
)

impl FileDialog {
    pub fn new<S: StrAllocating>(title: S, font: Font) -> FileDialog {
        FileDialog {
            title: title.into_string(),
            dimen: [640, 480],
            samples: 4,
            background: Color::new(0.9, 0.9, 0.9, 1.0), // Should be a nice light-grey
            select: SelectType::File,
            // Possible panic! here, but unlikely.
            starting_path: os::homedir().unwrap_or_else(|| os::getcwd().unwrap()),
            font: font,
            filter_hidden: true,
        }
    }

    pub fn width(mut self, width: u32) -> FileDialog {
        self.dimen[0] = width;
        self
    }

    pub fn height(mut self, height: u32) -> FileDialog {
        self.dimen[1] = height;
        self
    }

    pub fn dimensions(mut self, width: u32, height: u32) -> FileDialog {
        self.dimen = [width, height];
        self
    }

    setter!(samples: u8 -> FileDialog)

    setter!(background: Color -> FileDialog)

    setter!(select: SelectType -> FileDialog)

    setter!(starting_path: Path -> FileDialog)

    setter!(filter_hidden: bool -> FileDialog)

    // How should we format the trait bounds here?
    /// Show the dialog
    pub fn show<W: Window, F: FnOnce(OpenGL, WindowSettings) -> W + Send>
    (self, win_fn: F, gl: OpenGL) -> FilePromise {
        let (promise, tx) = FilePromise::new();
        let (dialog, window) = self.explode(tx);

        spawn(proc() render_file_dialog(dialog, window, gl, win_fn));

        promise
    }

    fn explode(self, tx: Sender<Path>) -> (DialogSettings, WindowSettings) {
        (
            DialogSettings {
                background: self.background,
                select: self.select,
                starting_path: self.starting_path,
                font: self.font,
                tx: tx,
                filter_hidden: self.filter_hidden,
            },
            WindowSettings {
                title: self.title,
                size: self.dimen,
                samples: self.samples,
                fullscreen: false,
                exit_on_esc: true,
            }
        )
    }
}

/// An enum describing the file selection behavior.
pub enum SelectType {
    /// User must select an existing file on the filesystem.
    File,
    /// User must select an existing folder on the filesystem, or create a new one.
    Folder,
    /// User must select the location to save a file, and the filename.
    /// The contained `Option<String>` is the default filename, if any.
    SaveFile(Option<String>),
}

impl SelectType {
    fn show_files(&self) -> bool {
        match *self {
            SelectType::File | SelectType::SaveFile(_) => true,
            _ => false,
        }
    }
}

struct DialogSettings {
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: Font,
    tx: Sender<Path>,
    filter_hidden: bool,
}

impl DialogSettings {
    fn into_state(self) -> (DialogState, Font) {
        (
            DialogState {
                dir: self.starting_path,
                selected: None,
                paths: Vec::new(),
                background: self.background,
                select: self.select,
                dir_changed: false,
                pages: 0,
                tx: self.tx,
                sent: false,
                filter_hidden: self.filter_hidden,
            },
            self.font,
        )
    }
}

fn render_file_dialog<W: Window, F: FnOnce(OpenGL, WindowSettings) -> W>
(dialog: DialogSettings, window: WindowSettings, gl: OpenGL, win_fn: F) {
    let (mut state, font) = dialog.into_state();
    state.update_paths();

    let ref mut state = state;

    let window = win_fn(gl, window);
    let mut event_loop = Events::new(window).set(Ups(120)).set(MaxFps(60));
    let mut gl = Gl::new(gl);

    let ref mut uic = UiContext::new(font, Theme::default());
    let ref mut buf = Default::default();

    for event in event_loop {
        if state.sent { return; }

        uic.handle_event(&event);
        match event {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |_, gl| {
                    draw_dialog_ui(gl, uic, state, buf);
                });
            },
            _ => {}
        }
    }
}

#[deriving(Default)]
struct Buffers {
    dir: String,
}

struct DialogState {
    dir: Path,
    selected: Option<uint>,
    paths: Vec<Path>,
    background: Color,
    select: SelectType,
    dir_changed: bool,
    pages: uint,
    tx: Sender<Path>,
    sent: bool,
    filter_hidden: bool,
}

impl DialogState {
    fn update_dir(&mut self, new_dir: Path) {
        self.dir_changed = if new_dir.is_dir() {
            self.dir = new_dir;
            self.update_paths();
            true
        } else {
            false
        }
    }

    fn update_paths(&mut self) {
        self.selected = None;
        self.paths = entries(&self.dir, self.select.show_files(), self.filter_hidden).unwrap();

        let count = self.paths.len();
        let per_page = COLS * ROWS;
        self.pages = count / per_page;

        if count % per_page != 0 { self.pages += 1; }
    }

    fn up_dir(&mut self) {
        self.dir_changed = self.dir.pop();
        self.update_paths();
    }

    fn select(&mut self, num: uint) {
        // Double-clicked
        if self.selected == Some(num) {
            let path = self.paths.remove(num).unwrap();

            if self.select.show_files() && !path.is_dir() {
                self.tx.send(path);
                self.sent = true;
            } else {
                self.update_dir(path);
            }
        } else {
            self.selected = Some(num);
        }
    }
}

const COLS: uint = 5;
const ROWS: uint = 10;

fn draw_dialog_ui(gl: &mut Gl, uic: &mut UiContext, state: &mut DialogState, buf: &mut Buffers) {
    uic.background().color(state.background).draw(gl);

    if state.dir_changed {
        buf.dir.clear();
    }

    if buf.dir.is_empty() {
        state.dir.as_str().map(|s| buf.dir.push_str(s));
    }

    let text_id = 42u64;

    const BUTTON_ID: u64 = 78;

    uic.button(BUTTON_ID)
        .dimensions(30.0, 30.0)
        .position(605.0, 5.0)
        .label("Up")
        .callback(|| state.up_dir())
        .draw(gl);

    uic.label(&*buf.dir)
        .position(5.0, 5.0)
        .size(24)
        .draw(gl);

    let base_id = 96u64;

    uic.widget_matrix(COLS, ROWS)
        .position(5.0, 35.0)
        .dimensions(635.0, 440.0)
        .cell_padding(5.0, 5.0)
        .each_widget(|uic, num, _, _, pt, dimen| {
            if num >= state.paths.len() { return; }

            let label = state.paths[num].filename_str().unwrap().into_string();

            let button = uic.button(base_id + num as u64)
                .point(pt)
                .dimensions(dimen[0], dimen[1])
                .label(&*label).label_font_size(20);

                if state.selected == Some(num) {
                    button.color(Color::new(0.5, 0.9, 0.5, 1.0))
                } else { button }
                .callback(|| state.select(num))
                .draw(gl);
        });
}

fn entries(path: &Path, keep_files: bool, filter_hidden: bool) -> IoResult<Vec<Path>> {
    let mut entries = try!(fs::readdir(path));
    entries.retain(|file|
        (filter_hidden && !file.filename_str().unwrap().starts_with(".")) &&
        (keep_files || file.is_dir())
    );
    entries.sort();

    Ok(entries)
}

pub struct FilePromise {
    opt: Option<Path>,
    rx: Receiver<Path>,
}

impl FilePromise {
    pub fn new() -> (FilePromise, Sender<Path>) {
        let (tx, rx) = channel();

        (
            FilePromise {
                opt: None,
                rx: rx,
            },
            tx,
        )
    }

    pub fn poll(&mut self) -> Option<&Path> {
        match self.rx.try_recv() {
            Ok(val) => self.opt = Some(val),
            Err(TryRecvError::Empty) => return None,
            Err(TryRecvError::Disconnected) if self.opt.is_none() =>
                panic!("Promised value never received; processing task ended prematurely!"),
            _ => (),
        }

        self.opt.as_ref()
    }

    pub fn unwrap(mut self) -> Path {
        while self.poll().is_none() {}

        self.opt.unwrap()
    }
}
<commit_msg>Pagination<commit_after>#![feature(unboxed_closures, macro_rules, globs)]

extern crate shader_version;
extern crate event;
extern crate event_loop;
extern crate conrod;
extern crate graphics;
extern crate window;
extern crate opengl_graphics;
extern crate current;

use conrod::*;

use current::Set;

use event::Event;
use event_loop::{Events, Ups, MaxFps};

use opengl_graphics::Gl;
use opengl_graphics::glyph_cache::GlyphCache as Font;

use shader_version::opengl::OpenGL;

use window::{Window, WindowSettings};

use std::comm::TryRecvError;

use std::default::Default;

use std::io::fs::{mod, PathExtensions};
use std::io::IoResult;

use std::os;

use std::cell::Cell;

pub struct FileDialog {
    title: String,
    dimen: [u32, ..2],
    samples: u8,
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: Font,
    filter_hidden: bool,
}

macro_rules! setter(
    ($field:ident: $ty:ty -> $ret:ident) => (
        fn $field(mut self, $field: $ty) -> $ret {
            self.$field = $field;
            self
        }
    );
)

impl FileDialog {
    pub fn new<S: StrAllocating>(title: S, font: Font) -> FileDialog {
        FileDialog {
            title: title.into_string(),
            dimen: [640, 480],
            samples: 4,
            background: Color::new(0.9, 0.9, 0.9, 1.0), // Should be a nice light-grey
            select: SelectType::File,
            // Possible panic! here, but unlikely.
            starting_path: os::homedir().unwrap_or_else(|| os::getcwd().unwrap()),
            font: font,
            filter_hidden: true,
        }
    }

    pub fn width(mut self, width: u32) -> FileDialog {
        self.dimen[0] = width;
        self
    }

    pub fn height(mut self, height: u32) -> FileDialog {
        self.dimen[1] = height;
        self
    }

    pub fn dimensions(mut self, width: u32, height: u32) -> FileDialog {
        self.dimen = [width, height];
        self
    }

    setter!(samples: u8 -> FileDialog)

    setter!(background: Color -> FileDialog)

    setter!(select: SelectType -> FileDialog)

    setter!(starting_path: Path -> FileDialog)

    setter!(filter_hidden: bool -> FileDialog)

    // How should we format the trait bounds here?
    /// Show the dialog
    pub fn show<W: Window, F: FnOnce(OpenGL, WindowSettings) -> W + Send>
    (self, win_fn: F, gl: OpenGL) -> FilePromise {
        let (promise, tx) = FilePromise::new();
        let (dialog, window) = self.explode(tx);

        spawn(proc() render_file_dialog(dialog, window, gl, win_fn));

        promise
    }

    fn explode(self, tx: Sender<Path>) -> (DialogSettings, WindowSettings) {
        (
            DialogSettings {
                background: self.background,
                select: self.select,
                starting_path: self.starting_path,
                font: self.font,
                tx: tx,
                filter_hidden: self.filter_hidden,
            },
            WindowSettings {
                title: self.title,
                size: self.dimen,
                samples: self.samples,
                fullscreen: false,
                exit_on_esc: true,
            }
        )
    }
}

/// An enum describing the file selection behavior.
pub enum SelectType {
    /// User must select an existing file on the filesystem.
    File,
    /// User must select an existing folder on the filesystem, or create a new one.
    Folder,
    /// User must select the location to save a file, and the filename.
    /// The contained `Option<String>` is the default filename, if any.
    SaveFile(Option<String>),
}

impl SelectType {
    fn show_files(&self) -> bool {
        match *self {
            SelectType::File | SelectType::SaveFile(_) => true,
            _ => false,
        }
    }
}

struct DialogSettings {
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: Font,
    tx: Sender<Path>,
    filter_hidden: bool,
}

impl DialogSettings {
    fn into_state(self) -> (DialogState, Font) {
        (
            DialogState {
                dir: self.starting_path,
                selected: None,
                paths: Vec::new(),
                background: self.background,
                select: self.select,
                dir_changed: false,
                pages: 0,
                cur_page: 0,
                tx: self.tx,
                exit: false,
                filter_hidden: self.filter_hidden,
            },
            self.font,
        )
    }
}

fn render_file_dialog<W: Window, F: FnOnce(OpenGL, WindowSettings) -> W>
(dialog: DialogSettings, window: WindowSettings, gl: OpenGL, win_fn: F) {
    let (mut state, font) = dialog.into_state();
    state.update_paths();

    let ref mut state = state;

    let window = win_fn(gl, window);
    let mut event_loop = Events::new(window).set(Ups(120)).set(MaxFps(60));
    let mut gl = Gl::new(gl);

    let ref mut uic = UiContext::new(font, Theme::default());
    let ref mut buf = Default::default();

    for event in event_loop {
        if state.exit { break; }

        uic.handle_event(&event);
        match event {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |_, gl| {
                    draw_dialog_ui(gl, uic, state, buf);
                });
            },
            _ => {}
        }
    }
}

#[deriving(Default)]
struct Buffers {
    dir: String,
    page: String,
}

impl Buffers {
    fn set_page(&mut self, page: uint, total: uint) {
        self.page = format!("Page: {} Total: {}", page, total);
    }
}

struct DialogState {
    dir: Path,
    selected: Option<uint>,
    paths: Vec<Path>,
    background: Color,
    select: SelectType,
    dir_changed: bool,
    pages: uint,
    cur_page: uint,
    tx: Sender<Path>,
    exit: bool,
    filter_hidden: bool,
}

impl DialogState {
    fn update_dir(&mut self, new_dir: Path) {
        self.dir_changed = if new_dir.is_dir() {
            self.dir = new_dir;
            self.update_paths();
            true
        } else {
            false
        }
    }

    fn update_paths(&mut self) {
        self.selected = None;
        self.paths = entries(&self.dir, self.select.show_files(), self.filter_hidden).unwrap();

        let count = self.paths.len();
        self.pages = count / PER_PAGE;

        if count % PER_PAGE != 0 { self.pages += 1; }
    }

    fn up_dir(&mut self) {
        self.dir_changed = self.dir.pop();
        self.update_paths();
    }

    fn select(&mut self, num: uint) {
        // Double-clicked
        if self.selected == Some(num) {
            let path = self.paths.remove(num).unwrap();

            if self.select.show_files() && !path.is_dir() {
                self.tx.send(path);
                self.exit = true;
            } else {
                self.update_dir(path);
            }
        } else {
            self.selected = Some(num);
        }
    }
}

const COLS: uint = 5;
const ROWS: uint = 8;
const PER_PAGE: uint = COLS * ROWS;

fn draw_dialog_ui(gl: &mut Gl, uic: &mut UiContext, state: &mut DialogState, buf: &mut Buffers) {
    uic.background().color(state.background).draw(gl);

    if state.dir_changed {
        buf.dir.clear();
    }

    if buf.dir.is_empty() {
        state.dir.as_str().map(|s| buf.dir.push_str(s));
    }

    thread_local!(static CUR_PAGE: Cell<uint> = Cell::new(1))

    CUR_PAGE.with(|cur_page| {
        let page = cur_page.get();
        if page != state.cur_page {
            state.cur_page = page;
            buf.set_page(page, state.pages);
        }
    });

    const BUTTON_ID: u64 = 78;

    uic.button(BUTTON_ID)
        .position(605.0, 5.0)
        .dimensions(30.0, 30.0)
        .label("Up")
        .callback(|| state.up_dir())
        .draw(gl);

    uic.label(&*buf.dir)
        .position(5.0, 5.0)
        .size(24)
        .draw(gl);

    const PREV_PAGE: u64 = 199;

    uic.button(PREV_PAGE)
        .position(30.0, 445.0)
        .dimensions(90.0, 30.0)
        .label("Previous")
        .callback(|| CUR_PAGE.with(|cur_page| {
            let page = cur_page.get();
            if page > 1 { cur_page.set(page - 1); }
        }))
        .draw(gl);

    uic.button(PREV_PAGE + 1)
        .right_from(PREV_PAGE, 125.0)
        .dimensions(90.0, 30.0)
        .label("Next")
        .callback(|| CUR_PAGE.with(|cur_page| {
            let page = cur_page.get();
            if page < state.pages { cur_page.set(page + 1); }
        }))
        .draw(gl);

    uic.label(&*buf.page)
        .right_from(PREV_PAGE, 30.0)
        .size(24)
        .draw(gl);

    const FILE_START_ID: u64 = 365;
    uic.widget_matrix(COLS, ROWS)
        .position(5.0, 35.0)
        .dimensions(600.0, 400.0)
        .cell_padding(5.0, 5.0)
        .each_widget(|uic, num, _, _, pt, dimen| {
            let idx = (state.cur_page - 1) * PER_PAGE + num;

            if idx >= state.paths.len() { return; }

            let label = state.paths[idx].filename_str().unwrap().into_string();

            let button = uic.button(FILE_START_ID + num as u64)
                .point(pt)
                .dimensions(dimen[0], dimen[1])
                .label(&*label).label_font_size(18);

                if state.selected == Some(num) {
                    button.color(Color::new(0.5, 0.9, 0.5, 1.0))
                } else { button }
                .callback(|| state.select(num))
                .draw(gl);
        });
}

fn entries(path: &Path, keep_files: bool, filter_hidden: bool) -> IoResult<Vec<Path>> {
    let mut entries = try!(fs::readdir(path));
    entries.retain(|file|
        (filter_hidden && !file.filename_str().unwrap().starts_with(".")) &&
        (keep_files || file.is_dir())
    );
    entries.sort();

    Ok(entries)
}

pub struct FilePromise {
    opt: Option<Path>,
    rx: Receiver<Path>,
}

impl FilePromise {
    pub fn new() -> (FilePromise, Sender<Path>) {
        let (tx, rx) = channel();

        (
            FilePromise {
                opt: None,
                rx: rx,
            },
            tx,
        )
    }

    pub fn poll(&mut self) -> Option<&Path> {
        match self.rx.try_recv() {
            Ok(val) => self.opt = Some(val),
            Err(TryRecvError::Empty) => return None,
            Err(TryRecvError::Disconnected) if self.opt.is_none() =>
                panic!("Promised value never received; processing task ended prematurely!"),
            _ => (),
        }

        self.opt.as_ref()
    }

    pub fn unwrap(mut self) -> Path {
        while self.poll().is_none() {}

        self.opt.unwrap()
    }
}
<|endoftext|>


<commit_before>#![doc(html_root_url = "https://docs.rs/twitter-stream/0.10.0-alpha.5")]

/*!
# Twitter Stream

A library for listening on Twitter Streaming API.

## Usage

Add `twitter-stream` to your dependencies in your project's `Cargo.toml`:

```toml
[dependencies]
futures = "0.3"
tokio = { version = "0.2", features = ["macros"] }
twitter-stream = "=0.10.0-alpha.5"
```

## Overview

Here is a basic example that prints public mentions to @Twitter in JSON format:

```rust,no_run
use futures::prelude::*;
use twitter_stream::Token;

# #[tokio::main]
# async fn main() {
let token = Token::new("consumer_key", "consumer_secret", "access_key", "access_secret");

twitter_stream::Builder::filter(token)
    .track("@Twitter")
    .listen()
    .try_flatten_stream()
    .try_for_each(|json| {
        println!("{}", json);
        future::ok(())
    })
    .await
    .unwrap();
# }
```
*/

#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(intra_doc_link_resolution_failure)]

#[macro_use]
mod util;

pub mod builder;
pub mod error;
#[cfg(feature = "hyper")]
#[cfg_attr(docsrs, doc(cfg(feature = "hyper")))]
pub mod hyper;
pub mod service;

mod gzip;
mod token;

pub use oauth::Credentials;

pub use crate::builder::Builder;
pub use crate::error::Error;
pub use crate::token::Token;

use std::borrow::Borrow;
use std::future::Future;
use std::pin::Pin;
use std::str;
use std::task::{Context, Poll};

use bytes::Bytes;
use futures_core::Stream;
use futures_util::ready;
use http::header::CONTENT_ENCODING;
use http::response::Parts;
use http::Response;
use http::StatusCode;
use http_body::Body;
use pin_project_lite::pin_project;

use crate::gzip::MaybeGzip;
use crate::util::{HttpBodyAsStream, Lines};

pin_project! {
    /// A future returned by constructor methods
    /// which resolves to a `TwitterStream`.
    pub struct FutureTwitterStream<F> {
        #[pin]
        response: F,
    }
}

pin_project! {
    /// A listener for Twitter Streaming API.
    /// It yields JSON strings returned from the API.
    pub struct TwitterStream<B: Body> {
        #[pin]
        inner: Lines<MaybeGzip<HttpBodyAsStream<B>>>,
    }
}

#[cfg(feature = "hyper")]
impl<B: Body> TwitterStream<B> {
    /// A shorthand for `Builder::filter().listen()`.
    ///
    /// # Panics
    ///
    /// This will panic if the underlying HTTPS connector failed to initialize.
    pub fn filter<C, A>(token: Token<C, A>) -> crate::hyper::FutureTwitterStream
    where
        C: Borrow<str>,
        A: Borrow<str>,
    {
        Builder::filter(token).listen()
    }

    /// A shorthand for `Builder::sample().listen()`.
    ///
    /// # Panics
    ///
    /// This will panic if the underlying HTTPS connector failed to initialize.
    pub fn sample<C, A>(token: Token<C, A>) -> crate::hyper::FutureTwitterStream
    where
        C: Borrow<str>,
        A: Borrow<str>,
    {
        Builder::sample(token).listen()
    }
}

impl<F, B, E> Future for FutureTwitterStream<F>
where
    F: Future<Output = Result<Response<B>, E>>,
    B: Body,
{
    type Output = Result<TwitterStream<B>, Error<E>>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let res = match ready!(self.project().response.poll(cx)) {
            Ok(res) => res,
            Err(e) => return Poll::Ready(Err(Error::Service(e))),
        };
        let (parts, body) = res.into_parts();
        let Parts {
            status, headers, ..
        } = parts;

        if StatusCode::OK != status {
            return Poll::Ready(Err(Error::Http(status)));
        }

        let use_gzip = headers
            .get_all(CONTENT_ENCODING)
            .iter()
            .any(|e| e == "gzip");
        let inner = if use_gzip {
            Lines::new(gzip::gzip(HttpBodyAsStream::new(body)))
        } else {
            Lines::new(gzip::identity(HttpBodyAsStream::new(body)))
        };

        Poll::Ready(Ok(TwitterStream { inner }))
    }
}

impl<B> Stream for TwitterStream<B>
where
    B: Body,
{
    type Item = Result<string::String<Bytes>, Error<B::Error>>;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut this = self.project();

        loop {
            let line = match ready!(this.inner.as_mut().poll_next(cx)?) {
                Some(t) => t,
                None => return std::task::Poll::Ready(None),
            };

            if line.iter().all(|&c| is_json_whitespace(c)) {
                continue;
            }

            str::from_utf8(&line).map_err(Error::Utf8)?;
            let line = unsafe {
                // Safety:
                // - We have checked above that `line` is valid as UTF-8.
                // - `Bytes` satisfies the requirements of `string::StableAsRef` trait
                // (https://github.com/carllerche/string/pull/17)
                string::String::<Bytes>::from_utf8_unchecked(line)
            };
            return Poll::Ready(Some(Ok(line)));
        }
    }
}

fn is_json_whitespace(c: u8) -> bool {
    // RFC7159 §2
    b" \t\n\r".contains(&c)
}
<commit_msg>Fix `unused_imports` warning when compiling without `hyper` feature<commit_after>#![doc(html_root_url = "https://docs.rs/twitter-stream/0.10.0-alpha.5")]

/*!
# Twitter Stream

A library for listening on Twitter Streaming API.

## Usage

Add `twitter-stream` to your dependencies in your project's `Cargo.toml`:

```toml
[dependencies]
futures = "0.3"
tokio = { version = "0.2", features = ["macros"] }
twitter-stream = "=0.10.0-alpha.5"
```

## Overview

Here is a basic example that prints public mentions to @Twitter in JSON format:

```rust,no_run
use futures::prelude::*;
use twitter_stream::Token;

# #[tokio::main]
# async fn main() {
let token = Token::new("consumer_key", "consumer_secret", "access_key", "access_secret");

twitter_stream::Builder::filter(token)
    .track("@Twitter")
    .listen()
    .try_flatten_stream()
    .try_for_each(|json| {
        println!("{}", json);
        future::ok(())
    })
    .await
    .unwrap();
# }
```
*/

#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(intra_doc_link_resolution_failure)]

#[macro_use]
mod util;

pub mod builder;
pub mod error;
#[cfg(feature = "hyper")]
#[cfg_attr(docsrs, doc(cfg(feature = "hyper")))]
pub mod hyper;
pub mod service;

mod gzip;
mod token;

pub use oauth::Credentials;

pub use crate::builder::Builder;
pub use crate::error::Error;
pub use crate::token::Token;

use std::future::Future;
use std::pin::Pin;
use std::str;
use std::task::{Context, Poll};

use bytes::Bytes;
use futures_core::Stream;
use futures_util::ready;
use http::header::CONTENT_ENCODING;
use http::response::Parts;
use http::Response;
use http::StatusCode;
use http_body::Body;
use pin_project_lite::pin_project;

use crate::gzip::MaybeGzip;
use crate::util::{HttpBodyAsStream, Lines};

pin_project! {
    /// A future returned by constructor methods
    /// which resolves to a `TwitterStream`.
    pub struct FutureTwitterStream<F> {
        #[pin]
        response: F,
    }
}

pin_project! {
    /// A listener for Twitter Streaming API.
    /// It yields JSON strings returned from the API.
    pub struct TwitterStream<B: Body> {
        #[pin]
        inner: Lines<MaybeGzip<HttpBodyAsStream<B>>>,
    }
}

#[cfg(feature = "hyper")]
impl<B: Body> TwitterStream<B> {
    /// A shorthand for `Builder::filter().listen()`.
    ///
    /// # Panics
    ///
    /// This will panic if the underlying HTTPS connector failed to initialize.
    pub fn filter<C, A>(token: Token<C, A>) -> crate::hyper::FutureTwitterStream
    where
        C: std::borrow::Borrow<str>,
        A: std::borrow::Borrow<str>,
    {
        Builder::filter(token).listen()
    }

    /// A shorthand for `Builder::sample().listen()`.
    ///
    /// # Panics
    ///
    /// This will panic if the underlying HTTPS connector failed to initialize.
    pub fn sample<C, A>(token: Token<C, A>) -> crate::hyper::FutureTwitterStream
    where
        C: std::borrow::Borrow<str>,
        A: std::borrow::Borrow<str>,
    {
        Builder::sample(token).listen()
    }
}

impl<F, B, E> Future for FutureTwitterStream<F>
where
    F: Future<Output = Result<Response<B>, E>>,
    B: Body,
{
    type Output = Result<TwitterStream<B>, Error<E>>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let res = match ready!(self.project().response.poll(cx)) {
            Ok(res) => res,
            Err(e) => return Poll::Ready(Err(Error::Service(e))),
        };
        let (parts, body) = res.into_parts();
        let Parts {
            status, headers, ..
        } = parts;

        if StatusCode::OK != status {
            return Poll::Ready(Err(Error::Http(status)));
        }

        let use_gzip = headers
            .get_all(CONTENT_ENCODING)
            .iter()
            .any(|e| e == "gzip");
        let inner = if use_gzip {
            Lines::new(gzip::gzip(HttpBodyAsStream::new(body)))
        } else {
            Lines::new(gzip::identity(HttpBodyAsStream::new(body)))
        };

        Poll::Ready(Ok(TwitterStream { inner }))
    }
}

impl<B> Stream for TwitterStream<B>
where
    B: Body,
{
    type Item = Result<string::String<Bytes>, Error<B::Error>>;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut this = self.project();

        loop {
            let line = match ready!(this.inner.as_mut().poll_next(cx)?) {
                Some(t) => t,
                None => return std::task::Poll::Ready(None),
            };

            if line.iter().all(|&c| is_json_whitespace(c)) {
                continue;
            }

            str::from_utf8(&line).map_err(Error::Utf8)?;
            let line = unsafe {
                // Safety:
                // - We have checked above that `line` is valid as UTF-8.
                // - `Bytes` satisfies the requirements of `string::StableAsRef` trait
                // (https://github.com/carllerche/string/pull/17)
                string::String::<Bytes>::from_utf8_unchecked(line)
            };
            return Poll::Ready(Some(Ok(line)));
        }
    }
}

fn is_json_whitespace(c: u8) -> bool {
    // RFC7159 §2
    b" \t\n\r".contains(&c)
}
<|endoftext|>


<commit_before>#![cfg(any(target_os = "macos", target_os = "ios"))]

#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]

extern crate core_foundation_sys;

use core_foundation_sys::string::*;
use core_foundation_sys::data::*;
use core_foundation_sys::dictionary::*;
use core_foundation_sys::propertylist::*;

use std::ptr;

include!("generated.rs");

#[inline]
pub unsafe fn MIDIPacketNext(pkt: *const MIDIPacket) -> *const MIDIPacket {
    // Get pointer to potentially unaligned data without triggering undefined behavior
    // addr_of does not require creating an intermediate reference to unaligned data.
    let ptr = ptr::addr_of!((*pkt).data) as *const u8;
    let offset = (*pkt).length as isize;
    if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
        // MIDIPacket must be 4-byte aligned on ARM
        ((ptr.offset(offset + 3) as usize) & !(3usize)) as *const MIDIPacket
    } else {
        ptr.offset(offset) as *const MIDIPacket
    }
}

#[allow(dead_code)]
mod static_test {
    /// Statically assert the correct size of `MIDIPacket` and `MIDIPacketList`,
    /// which require non-default alignment.
    unsafe fn assert_sizes() {
        use super::{MIDIPacket, MIDIPacketList};
        use std::mem::{transmute, zeroed};

        let p: MIDIPacket = zeroed();
        transmute::<_, [u8; 268]>(p);

        let p: MIDIPacketList = zeroed();
        transmute::<_, [u8; 272]>(p);
    }
}
<commit_msg>included regression test<commit_after>#![cfg(any(target_os = "macos", target_os = "ios"))]

#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]

extern crate core_foundation_sys;

use core_foundation_sys::string::*;
use core_foundation_sys::data::*;
use core_foundation_sys::dictionary::*;
use core_foundation_sys::propertylist::*;

use std::ptr;

include!("generated.rs");

#[inline]
pub unsafe fn MIDIPacketNext(pkt: *const MIDIPacket) -> *const MIDIPacket {
    // Get pointer to potentially unaligned data without triggering undefined behavior
    // addr_of does not require creating an intermediate reference to unaligned data.
    let ptr = ptr::addr_of!((*pkt).data) as *const u8;
    let offset = (*pkt).length as isize;
    if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
        // MIDIPacket must be 4-byte aligned on ARM
        ((ptr.offset(offset + 3) as usize) & !(3usize)) as *const MIDIPacket
    } else {
        ptr.offset(offset) as *const MIDIPacket
    }
}

#[allow(dead_code)]
mod static_test {
    /// Statically assert the correct size of `MIDIPacket` and `MIDIPacketList`,
    /// which require non-default alignment.
    unsafe fn assert_sizes() {
        use super::{MIDIPacket, MIDIPacketList};
        use std::mem::{transmute, zeroed};

        let p: MIDIPacket = zeroed();
        transmute::<_, [u8; 268]>(p);

        let p: MIDIPacketList = zeroed();
        transmute::<_, [u8; 272]>(p);
    }
}

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

    #[test]
    fn midi_packet_next() {
        const BUFFER_SIZE: usize = 65536;
        let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
        let pkt_list_ptr = buffer.as_mut_ptr() as *mut MIDIPacketList;

        let packets = vec![
            (1, vec![0x90, 0x40, 0x7f]),
            (2, vec![0x90, 0x41, 0x7f]),
        ];

        unsafe {
            let mut pkt_ptr = MIDIPacketListInit(pkt_list_ptr);
            for pkt in &packets {
                pkt_ptr = MIDIPacketListAdd(
                    pkt_list_ptr,
                    BUFFER_SIZE as u64,
                    pkt_ptr,
                    pkt.0,
                    pkt.1.len() as u64,
                    pkt.1.as_ptr(),
                );
                assert!(!pkt_ptr.is_null());
            }
        }

        unsafe {
            let pkt_ptr = &(*pkt_list_ptr).packet as *const MIDIPacket;
            let len = (*pkt_ptr).length as usize;
            assert_eq!(
                &(*pkt_ptr).data[0..len],
                &[0x90, 0x40, 0x7f]
            );

            let pkt_ptr = MIDIPacketNext(pkt_ptr);
            let len = (*pkt_ptr).length as usize;
            assert_eq!(
                &(*pkt_ptr).data[0..len],
                &[0x90, 0x41, 0x7f]
            );
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "bindgen")]
extern crate bindgen;

extern crate gcc;
extern crate glob;

use std::{env, fs};
use std::path::PathBuf;

#[cfg(feature = "bindgen")]
fn generate_bindings() {
    use std::env;
    use std::path::PathBuf;

    let bindings = bindgen::Builder::default()
        .header("zstd.h")
        .blacklist_type("max_align_t")
        .use_core()
        .ctypes_prefix("::libc")
        .clang_arg("-Izstd/lib")
        .clang_arg("-DZSTD_STATIC_LINKING_ONLY")
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Could not write bindings");

}

#[cfg(not(feature = "bindgen"))]
fn generate_bindings() {}

#[cfg(not(feature = "legacy"))]
fn set_legacy(_config: &mut gcc::Build) {}

#[cfg(feature = "legacy")]
fn set_legacy(config: &mut gcc::Build) {
    config.define("ZSTD_LEGACY_SUPPORT", Some("1"));
}

#[cfg(feature = "zstdmt")]
fn set_pthread(config: &mut gcc::Build) {
    config.flag("-pthread");
}

#[cfg(not(feature = "zstdmt"))]
fn set_pthread(_config: &mut gcc::Build) {}

fn compile_zstd() {
    let mut config = gcc::Build::new();

    let globs = &[
        "zstd/lib/common/*.c",
        "zstd/lib/compress/*.c",
        "zstd/lib/decompress/*.c",
        "zstd/lib/legacy/*.c",
        "zstd/lib/deprecated/*.c",
        "zstd/lib/dictBuilder/*.c",
    ];

    for pattern in globs {
        for path in glob::glob(pattern).unwrap() {
            let path = path.unwrap();
            config.file(path);
        }
    }

    // Some extra parameters
    config.opt_level(3);
    config.include("zstd/lib/");
    config.include("zstd/lib/common");
    config.include("zstd/lib/legacy");
    config.warnings(false);

    set_pthread(&mut config);
    set_legacy(&mut config);

    // Compile!
    config.compile("libzstd.a");

    let src = env::current_dir().unwrap().join("zstd").join("lib");
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let include = dst.join("include");
    fs::create_dir_all(&include).unwrap();
    fs::copy(src.join("zstd.h"), include.join("zstd.h")).unwrap();
    fs::copy(src.join("dictBuilder").join("zdict.h"), include.join("zdict.h")).unwrap();
    println!("cargo:root={}", dst.display());
}

fn main() {
    // println!("cargo:rustc-link-lib=zstd");

    compile_zstd();
    generate_bindings();
}
<commit_msg>Do not build ZSTD deprecated features<commit_after>#[cfg(feature = "bindgen")]
extern crate bindgen;

extern crate gcc;
extern crate glob;

use std::{env, fs};
use std::path::PathBuf;

#[cfg(feature = "bindgen")]
fn generate_bindings() {
    use std::env;
    use std::path::PathBuf;

    let bindings = bindgen::Builder::default()
        .header("zstd.h")
        .blacklist_type("max_align_t")
        .use_core()
        .ctypes_prefix("::libc")
        .clang_arg("-Izstd/lib")
        .clang_arg("-DZSTD_STATIC_LINKING_ONLY")
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Could not write bindings");

}

#[cfg(not(feature = "bindgen"))]
fn generate_bindings() {}

#[cfg(not(feature = "legacy"))]
fn set_legacy(_config: &mut gcc::Build) {}

#[cfg(feature = "legacy")]
fn set_legacy(config: &mut gcc::Build) {
    config.define("ZSTD_LEGACY_SUPPORT", Some("1"));
}

#[cfg(feature = "zstdmt")]
fn set_pthread(config: &mut gcc::Build) {
    config.flag("-pthread");
}

#[cfg(not(feature = "zstdmt"))]
fn set_pthread(_config: &mut gcc::Build) {}

fn compile_zstd() {
    let mut config = gcc::Build::new();

    let globs = &[
        "zstd/lib/common/*.c",
        "zstd/lib/compress/*.c",
        "zstd/lib/decompress/*.c",
        "zstd/lib/legacy/*.c",
        "zstd/lib/dictBuilder/*.c",
    ];

    for pattern in globs {
        for path in glob::glob(pattern).unwrap() {
            let path = path.unwrap();
            config.file(path);
        }
    }

    // Some extra parameters
    config.opt_level(3);
    config.include("zstd/lib/");
    config.include("zstd/lib/common");
    config.include("zstd/lib/legacy");
    config.warnings(false);

    config.define("ZSTD_LIB_DEPRECATED", Some("0"));
    set_pthread(&mut config);
    set_legacy(&mut config);

    // Compile!
    config.compile("libzstd.a");

    let src = env::current_dir().unwrap().join("zstd").join("lib");
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let include = dst.join("include");
    fs::create_dir_all(&include).unwrap();
    fs::copy(src.join("zstd.h"), include.join("zstd.h")).unwrap();
    fs::copy(src.join("dictBuilder").join("zdict.h"), include.join("zdict.h")).unwrap();
    println!("cargo:root={}", dst.display());
}

fn main() {
    // println!("cargo:rustc-link-lib=zstd");

    compile_zstd();
    generate_bindings();
}
<|endoftext|>


<commit_before>extern crate libc;

use x11::xlib;
use x11::xlib::{ Window, Display };

use std::boxed::Box;
use std::collections::HashMap;
use super::layout;
use super::WindowManager;

pub struct Workspace {
    root: Window,
    windows: Vec<Window>,
    layout: Box<layout::Layout>
}

impl Workspace {
    pub fn new() -> Workspace {
        Workspace {
            root: 0,
            windows: Vec::new(),
            layout: Box::new(layout::TilingLayout::new(layout::Direction::Horizontal))
        }
    }

    pub fn p(&self) {
        for w in self.windows.iter() {
            println!("{}", w);
        }
    }
    pub fn add(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => {}
            None => { self.windows.push(window) ;}
        }
    }

    pub fn remove(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => { self.windows.remove(i); }
            None => {}
        };
    }

    pub fn get(&self, index: usize) -> Window{
        self.windows[index]
    }

    pub fn size(&self) -> usize {
        self.windows.len()
    }

    pub fn hide(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            libx::unmap_window(display, *w);
        }
    }

    pub fn show(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            libx::map_window(display, *w);
        }
    }

    pub fn contain(&self, window: Window) -> Option<usize>{
        self.windows.iter().position(|x| *x == window)
    }

    pub fn change_layout(&mut self, layout_type: layout::Type) {
        let t = self.layout.get_type();
        if t == layout_type {
            self.layout.toggle();
        }
        else{
            match layout_type {
                layout::Type::Tiling => {
                    let tmp = layout::TilingLayout::new(layout::Direction::Horizontal);
                    self.layout = Box::new(tmp);
                }
            }
        }
    }

    pub fn config(&self, display: *mut xlib::Display, screen_num: libc::c_int) {
        debug!("size {}", self.windows.len());
        self.layout.configure(&self.windows, display, screen_num);
    }
}

pub struct Workspaces {
    current: char,
    pub spaces: HashMap<char, Workspace>,
}

impl Workspaces {
    pub fn new() -> Workspaces {
        Workspaces {
            current: '1',
            spaces: HashMap::new()
        }
    }

    pub fn contain(&mut self, key: char) -> bool{
        self.spaces.contains_key(&key)
    }

    pub fn create(&mut self, key: char) {
        let space = Workspace::new();
        self.spaces.insert(key, space);
    }

    pub fn delete(&mut self, key: char) {
        self.spaces.remove(&key);
    }

    pub fn get(&mut self, key: char) -> Option<&mut Workspace>{
        self.spaces.get_mut(&key)
    }

    pub fn current(&mut self) -> &mut Workspace {
        self.spaces.get_mut(&self.current).unwrap()
    }

    pub fn current_name(&self) -> char {
        self.current
    }

    pub fn switch_current(&mut self, new: char, display: *mut Display){
        if new != self.current {
            if !self.contain(new) {
                self.create(new);
            }
            let old = self.current;
            self.current = new;

            match self.get(old) {
                Some(v) => {
                    v.hide(display);
                }
                None => {}
            }

            match self.get(new) {
                Some(v) => {
                    v.show(display);
                }
                None => {}
            }
        }
    }

    pub fn move_window(&mut self, window: Window, from: char, to: char){
        if self.get(to).is_none(){
            self.create(to);
        }

        if from != to {
            match self.get(from) {
                Some(w) => { w.remove(window); }
                None => {}
            }
            match self.get(to) {
                Some(w) => { w.add(window); }
                None => {}
            }
        }
    }
}
<commit_msg>use libx<commit_after>extern crate libc;

use x11::xlib::{ Window, Display };

use std::boxed::Box;
use std::collections::HashMap;
use super::layout;
use super::WindowManager;
use super::super::libx;

pub struct Workspace {
    root: Window,
    focus: Window,
    windows: Vec<Window>,
    layout: Box<layout::Layout>
}

impl Workspace {
    pub fn new() -> Workspace {
        Workspace {
            root: 0,
            focus: 0,
            windows: Vec::new(),
            layout: Box::new(layout::TilingLayout::new(layout::Direction::Horizontal))
        }
    }

    pub fn p(&self) {
        for w in self.windows.iter() {
            println!("{}", w);
        }
    }

    pub fn add(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => {}
            None => { self.windows.push(window) ;}
        }
    }

    pub fn remove(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => { self.windows.remove(i); }
            None => {}
        };
    }

    pub fn get(&self, index: usize) -> Window{
        self.windows[index]
    }

    pub fn size(&self) -> usize {
        self.windows.len()
    }

    pub fn hide(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            libx::unmap_window(display, *w);
        }
    }

    pub fn show(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            libx::map_window(display, *w);
        }
    }

    pub fn contain(&self, window: Window) -> Option<usize>{
        self.windows.iter().position(|x| *x == window)
    }

    pub fn change_layout(&mut self, layout_type: layout::Type) {
        let t = self.layout.get_type();
        if t == layout_type {
            self.layout.toggle();
        }
        else{
            match layout_type {
                layout::Type::Tiling => {
                    let tmp = layout::TilingLayout::new(layout::Direction::Horizontal);
                    self.layout = Box::new(tmp);
                }
            }
        }
    }

    pub fn config(&self, display: *mut Display, screen_num: libc::c_int) {
        debug!("size {}", self.windows.len());
        self.layout.configure(&self.windows, display, screen_num);
    }
}

pub struct Workspaces {
    current: char,
    pub spaces: HashMap<char, Workspace>,
}

impl Workspaces {
    pub fn new() -> Workspaces {
        Workspaces {
            current: '1',
            spaces: HashMap::new()
        }
    }

    pub fn contain(&mut self, key: char) -> bool{
        self.spaces.contains_key(&key)
    }

    pub fn create(&mut self, key: char) {
        let space = Workspace::new();
        self.spaces.insert(key, space);
    }

    pub fn delete(&mut self, key: char) {
        self.spaces.remove(&key);
    }

    pub fn get(&mut self, key: char) -> Option<&mut Workspace>{
        self.spaces.get_mut(&key)
    }

    pub fn current(&mut self) -> &mut Workspace {
        self.spaces.get_mut(&self.current).unwrap()
    }

    pub fn current_name(&self) -> char {
        self.current
    }

    pub fn switch_current(&mut self, new: char, display: *mut Display){
        if new != self.current {
            if !self.contain(new) {
                self.create(new);
            }
            let old = self.current;
            self.current = new;

            match self.get(old) {
                Some(v) => {
                    v.hide(display);
                }
                None => {}
            }

            match self.get(new) {
                Some(v) => {
                    v.show(display);
                }
                None => {}
            }
        }
    }

    pub fn move_window(&mut self, window: Window, from: char, to: char){
        if self.get(to).is_none(){
            self.create(to);
        }

        if from != to {
            match self.get(from) {
                Some(w) => { w.remove(window); }
                None => {}
            }
            match self.get(to) {
                Some(w) => { w.add(window); }
                None => {}
            }
        }
    }
}
<|endoftext|>


<commit_before>extern mod extra;

use std::io;
use extra::net;
use extra::uv;

struct Client {
    writer: @io::WriterUtil,
    reader: @io::ReaderUtil
}

impl Client {
    fn flush(&self) {
        self.writer.write_str("flush_all\r\n");
    }
}

fn main() {
    let socket = get_connection().get();
    let writer = @socket as @io::WriterUtil;
    let reader = @socket as @io::ReaderUtil;

    let client = Client{writer: writer, reader: reader};

    client.flush();

}

fn get_connection() -> Result<net::tcp::TcpSocketBuf, ()> {
    match net::tcp::connect(net::ip::v4::parse_addr("127.0.0.1"), 11211, &uv::global_loop::get()) {
        Err(err) => {
            match err {
                net::tcp::GenericConnectErr(name,msg) => io::println(fmt!("Connection error %s: %s", name, msg)),
                net::tcp::ConnectionRefused => io::println("Connection refused")
            }
            return Err(());
        },
        Ok(socket) => {
            let socket_buf = net::tcp::socket_buf(socket);
            return Ok(socket_buf);
        }
    }

}
<commit_msg>delete old files<commit_after><|endoftext|>


<commit_before>
#![feature(test)]

extern crate test;
extern crate rle_vec;

use std::iter::FromIterator;
use std::iter::repeat;
use test::Bencher;
use rle_vec::RleVec;
use std::io::{Cursor, Read};

#[bench]
fn rle_read_100000_u8(b: &mut Bencher) {
    let zeros = repeat(0u8).take(10);
    let ones = repeat(1u8).take(10);
    let iter = repeat(zeros.chain(ones)).flat_map(|x| x).take(100_000);

    let rle = RleVec::from_iter(iter);

    let mut buf = vec![0; 1024];
    b.iter(|| {
        let mut rle = rle.clone();
        loop {
            match rle.read(&mut buf) {
                Ok(n) if n == 0 => break,
                Ok(_) => {},
                Err(e) => panic!(e)
            }
        }
    });
}

#[bench]
fn cursor_vec_read_100000_u8(b: &mut Bencher) {
    let zeros = repeat(0u8).take(10);
    let ones = repeat(1u8).take(10);
    let iter = repeat(zeros.chain(ones)).flat_map(|x| x).take(100_000);

    let vec = Vec::from_iter(iter);

    let mut buf = vec![0; 1024];
    b.iter(|| {
        let mut cur = Cursor::new(vec.clone());
        loop {
            match cur.read(&mut buf) {
                Ok(n) if n == 0 => break,
                Ok(_) => {},
                Err(e) => panic!(e)
            }
        }
    });
}

<commit_msg>test read with 2 buffersizes<commit_after>
#![feature(test)]

extern crate test;
extern crate rle_vec;

use std::iter::FromIterator;
use std::iter::repeat;
use test::Bencher;
use rle_vec::RleVec;
use std::io::{Cursor, Read};

#[bench]
fn rle_read_smallbuf_100000_u8(b: &mut Bencher) {
    let zeros = repeat(0u8).take(10);
    let ones = repeat(1u8).take(10);
    let iter = repeat(zeros.chain(ones)).flat_map(|x| x).take(100_000);

    let rle = RleVec::from_iter(iter);

    let mut buf = vec![0; 1024];
    b.iter(|| {
        let mut rle = rle.clone();
        loop {
            match rle.read(&mut buf) {
                Ok(n) if n == 0 => break,
                Ok(_) => {},
                Err(e) => panic!(e)
            }
        }
    });
}

#[bench]
fn rle_read_largebuf_100000_u8(b: &mut Bencher) {
    let zeros = repeat(0u8).take(10);
    let ones = repeat(1u8).take(10);
    let iter = repeat(zeros.chain(ones)).flat_map(|x| x).take(100_000);

    let rle = RleVec::from_iter(iter);

    let mut buf = vec![0; 10000];
    b.iter(|| {
        let mut rle = rle.clone();
        loop {
            match rle.read(&mut buf) {
                Ok(n) if n == 0 => break,
                Ok(_) => {},
                Err(e) => panic!(e)
            }
        }
    });
}

#[bench]
fn cursor_vec_read_100000_u8(b: &mut Bencher) {
    let zeros = repeat(0u8).take(10);
    let ones = repeat(1u8).take(10);
    let iter = repeat(zeros.chain(ones)).flat_map(|x| x).take(100_000);

    let vec = Vec::from_iter(iter);

    let mut buf = vec![0; 1024];
    b.iter(|| {
        let mut cur = Cursor::new(vec.clone());
        loop {
            match cur.read(&mut buf) {
                Ok(n) if n == 0 => break,
                Ok(_) => {},
                Err(e) => panic!(e)
            }
        }
    });
}

<|endoftext|>


<commit_before>// $ cargo bench --features full --bench rust

#![recursion_limit = "256"]
#![feature(rustc_private)]

extern crate rustc_data_structures;
extern crate syntax;
extern crate syntax_pos;

#[macro_use]
#[path = "../tests/macros/mod.rs"]
mod macros;

#[path = "../tests/common/mod.rs"]
mod common;

use proc_macro2::TokenStream;
use rustc_data_structures::sync::Lrc;
use std::fs;
use std::str::FromStr;
use std::time::{Duration, Instant};
use syntax::edition::Edition;
use syntax::errors::{emitter::Emitter, DiagnosticBuilder, Handler};
use syntax::parse::ParseSess;
use syntax::source_map::{FilePathMapping, SourceMap};
use syntax_pos::FileName;

fn tokenstream_parse(content: &str) -> Result<(), ()> {
    TokenStream::from_str(content).map(drop).map_err(drop)
}

fn syn_parse(content: &str) -> Result<(), ()> {
    syn::parse_file(content).map(drop).map_err(drop)
}

fn libsyntax_parse(content: &str) -> Result<(), ()> {
    struct SilentEmitter;

    impl Emitter for SilentEmitter {
        fn emit_diagnostic(&mut self, _db: &DiagnosticBuilder) {}
    }

    syntax::with_globals(Edition::Edition2018, || {
        let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
        let emitter = Box::new(SilentEmitter);
        let handler = Handler::with_emitter(false, None, emitter);
        let sess = ParseSess::with_span_handler(handler, cm);
        if let Err(mut diagnostic) = syntax::parse::parse_crate_from_source_str(
            FileName::Custom("bench".to_owned()),
            content.to_owned(),
            &sess,
        ) {
            diagnostic.cancel();
            return Err(());
        };
        Ok(())
    })
}

fn exec(codepath: fn(&str) -> Result<(), ()>) -> Duration {
    let begin = Instant::now();
    let mut success = 0;
    let mut total = 0;

    walkdir::WalkDir::new("tests/rust/src")
        .into_iter()
        .filter_entry(common::base_dir_filter)
        .for_each(|entry| {
            let entry = entry.unwrap();
            let path = entry.path();
            if path.is_dir() {
                return;
            }
            let content = fs::read_to_string(path).unwrap();
            let ok = codepath(&content).is_ok();
            success += ok as usize;
            total += 1;
            if !ok {
                eprintln!("FAIL {}", path.display());
            }
        });

    assert_eq!(success, total);
    begin.elapsed()
}

fn main() {
    common::clone_rust();

    macro_rules! testcases {
        ($($name:ident),*) => {
            vec![
                $(
                    (stringify!($name), $name as fn(&str) -> Result<(), ()>),
                )*
            ]
        };
    }

    eprintln!();
    for (name, f) in testcases!(tokenstream_parse, syn_parse, libsyntax_parse) {
        eprint!("{:20}", format!("{}:", name));
        let elapsed = exec(f);
        eprintln!(
            "elapsed={}.{:03}s",
            elapsed.as_secs(),
            elapsed.subsec_millis(),
        );
    }
    eprintln!();
}
<commit_msg>Print lines of code in rust repo benchmark<commit_after>// $ cargo bench --features full --bench rust

#![recursion_limit = "256"]
#![feature(rustc_private)]

extern crate rustc_data_structures;
extern crate syntax;
extern crate syntax_pos;

#[macro_use]
#[path = "../tests/macros/mod.rs"]
mod macros;

#[path = "../tests/common/mod.rs"]
mod common;

use proc_macro2::TokenStream;
use rustc_data_structures::sync::Lrc;
use std::fs;
use std::str::FromStr;
use std::time::{Duration, Instant};
use syntax::edition::Edition;
use syntax::errors::{emitter::Emitter, DiagnosticBuilder, Handler};
use syntax::parse::ParseSess;
use syntax::source_map::{FilePathMapping, SourceMap};
use syntax_pos::FileName;

fn tokenstream_parse(content: &str) -> Result<(), ()> {
    TokenStream::from_str(content).map(drop).map_err(drop)
}

fn syn_parse(content: &str) -> Result<(), ()> {
    syn::parse_file(content).map(drop).map_err(drop)
}

fn libsyntax_parse(content: &str) -> Result<(), ()> {
    struct SilentEmitter;

    impl Emitter for SilentEmitter {
        fn emit_diagnostic(&mut self, _db: &DiagnosticBuilder) {}
    }

    syntax::with_globals(Edition::Edition2018, || {
        let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
        let emitter = Box::new(SilentEmitter);
        let handler = Handler::with_emitter(false, None, emitter);
        let sess = ParseSess::with_span_handler(handler, cm);
        if let Err(mut diagnostic) = syntax::parse::parse_crate_from_source_str(
            FileName::Custom("bench".to_owned()),
            content.to_owned(),
            &sess,
        ) {
            diagnostic.cancel();
            return Err(());
        };
        Ok(())
    })
}

fn exec(mut codepath: impl FnMut(&str) -> Result<(), ()>) -> Duration {
    let begin = Instant::now();
    let mut success = 0;
    let mut total = 0;

    walkdir::WalkDir::new("tests/rust/src")
        .into_iter()
        .filter_entry(common::base_dir_filter)
        .for_each(|entry| {
            let entry = entry.unwrap();
            let path = entry.path();
            if path.is_dir() {
                return;
            }
            let content = fs::read_to_string(path).unwrap();
            let ok = codepath(&content).is_ok();
            success += ok as usize;
            total += 1;
            if !ok {
                eprintln!("FAIL {}", path.display());
            }
        });

    assert_eq!(success, total);
    begin.elapsed()
}

fn main() {
    common::clone_rust();

    macro_rules! testcases {
        ($($name:ident),*) => {
            vec![
                $(
                    (stringify!($name), $name as fn(&str) -> Result<(), ()>),
                )*
            ]
        };
    }

    let mut lines = 0;
    exec(|content| {
        lines += content.lines().count();
        Ok(())
    });
    eprintln!("\n{} lines", lines);

    for (name, f) in testcases!(tokenstream_parse, syn_parse, libsyntax_parse) {
        eprint!("{:20}", format!("{}:", name));
        let elapsed = exec(f);
        eprintln!(
            "elapsed={}.{:03}s",
            elapsed.as_secs(),
            elapsed.subsec_millis(),
        );
    }
    eprintln!();
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate mio;
extern crate term_input;

use mio::Events;
use mio::Poll;
use mio::PollOpt;
use mio::Ready;
use mio::Token;
use mio::unix::EventedFd;

use std::io;
use std::io::Write;

use term_input::{Event, Key, Input};

fn main() {
    // put the terminal in non-buffering, no-enchoing mode
    let mut old_term : libc::termios = unsafe { std::mem::zeroed() };
    unsafe { libc::tcgetattr(libc::STDIN_FILENO, &mut old_term); }

    let mut new_term : libc::termios = old_term.clone();
    new_term.c_iflag &= !(libc::IGNBRK | libc::BRKINT | libc::PARMRK | libc::ISTRIP | libc::INLCR |
                          libc::IGNCR | libc::ICRNL | libc::IXON);
    new_term.c_lflag &= !(libc::ICANON | libc::ECHO | libc::ISIG | libc::IEXTEN);
    unsafe { libc::tcsetattr(libc::STDIN_FILENO, libc::TCSAFLUSH, &new_term) };

    // enable focus events
    {
        let stdout = io::stdout();
        stdout.lock().write_all(b"\x1b[?1004h").unwrap();
        stdout.lock().flush().unwrap();
    }

    let poll = Poll::new().unwrap();
    poll.register(
        &EventedFd(&libc::STDIN_FILENO),
        Token(libc::STDIN_FILENO as usize),
        Ready::readable(),
        PollOpt::level()).unwrap();

    let mut input = Input::new();
    let mut evs = Vec::new();
    let mut events = Events::with_capacity(10);
    'mainloop:
    loop {
        match poll.poll(&mut events, None) {
            Err(_) => {}
            Ok(_) => {
                input.read_input_events(&mut evs);
                println!("{:?}", evs);
                for ev in evs.iter() {
                    if ev == &Event::Key(Key::Esc) {
                        break 'mainloop;
                    }
                }
            }
        }
    }

    // restore the old settings
    unsafe { libc::tcsetattr(libc::STDIN_FILENO, libc::TCSANOW, &old_term) };

    // disable focus events
    {
        let stdout = io::stdout();
        stdout.lock().write_all(b"\x1b[?1004l").unwrap();
    }
}
<commit_msg>Update term_input example for better resize handling<commit_after>extern crate libc;
extern crate mio;
extern crate term_input;

use mio::Events;
use mio::Poll;
use mio::PollOpt;
use mio::Ready;
use mio::Token;
use mio::unix::EventedFd;

use std::io;
use std::io::Write;

use term_input::{Event, Key, Input};

fn main() {
    // put the terminal in non-buffering, no-enchoing mode
    let mut old_term : libc::termios = unsafe { std::mem::zeroed() };
    unsafe { libc::tcgetattr(libc::STDIN_FILENO, &mut old_term); }

    let mut new_term : libc::termios = old_term.clone();
    new_term.c_iflag &= !(libc::IGNBRK | libc::BRKINT | libc::PARMRK | libc::ISTRIP | libc::INLCR |
                          libc::IGNCR | libc::ICRNL | libc::IXON);
    new_term.c_lflag &= !(libc::ICANON | libc::ECHO | libc::ISIG | libc::IEXTEN);
    unsafe { libc::tcsetattr(libc::STDIN_FILENO, libc::TCSAFLUSH, &new_term) };

    // enable focus events
    {
        let stdout = io::stdout();
        stdout.lock().write_all(b"\x1b[?1004h").unwrap();
        stdout.lock().flush().unwrap();
    }

    let poll = Poll::new().unwrap();
    poll.register(
        &EventedFd(&libc::STDIN_FILENO),
        Token(libc::STDIN_FILENO as usize),
        Ready::readable(),
        PollOpt::level()).unwrap();

    let mut input = Input::new();
    let mut evs = Vec::new();
    let mut events = Events::with_capacity(10);
    'mainloop:
    loop {
        let _poll_ret = poll.poll(&mut events, None);
        // println!("poll ret: {:?}", _poll_ret);

        // Err: probably SIGWINCH
        // Ok: stdin available
        //
        // there are events to handle either way
        input.read_input_events(&mut evs);
        println!("{:?}", evs);
        for ev in evs.iter() {
            if ev == &Event::Key(Key::Esc) {
                break 'mainloop;
            }
        }
    }

    // restore the old settings
    unsafe { libc::tcsetattr(libc::STDIN_FILENO, libc::TCSANOW, &old_term) };

    // disable focus events
    {
        let stdout = io::stdout();
        stdout.lock().write_all(b"\x1b[?1004l").unwrap();
    }
}
<|endoftext|>


<commit_before>use std::num::{Num,Zero};
use std::vec;

// types and type aliases

pub type R = f64;

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Deg(u8);

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Dim(uint);

// constants

pub static DEFAULT_INTEGRATION_REL_ERR: R = 1e-12;
pub static DEFAULT_INTEGRATION_ABS_ERR: R = 1e-12;

#[inline]
pub fn pow(radix: R, exp: uint) -> R {
  if exp == 0u { return 1 as R; }
  if radix == 0. { return 0 as R; }
  let mut prod = 1 as R;
  let mut _exp = exp;
  let mut multiplier = radix;
  while (_exp > 0u) {
    if _exp % 2u == 1u {
      prod *= multiplier;
    }
    _exp /= 2u;
    multiplier *= multiplier;
  }
 prod
}

#[inline(always)]
pub fn sq<T:Mul<T,T>>(x: T) -> T {
  x.mul(&x)
}

pub fn cumulative_sums_prev_elems<T:Num+Clone>(xs: &[T]) -> ~[T] {
  let mut cum_sums = vec::with_capacity(xs.len());
  let mut sum: T =  Zero::zero();
  for x in xs.iter() {
    cum_sums.push(sum.clone());
    sum = sum.add(x);
  }
  cum_sums
}

#[test]
fn test_pow() {
  assert_eq!(pow(2.,2), 4.);
  assert_eq!(pow(2.,3), 8.);
  assert_eq!(pow(0.,3), 0.);
  assert_eq!(pow(1.,3), 1.);
  assert_eq!(pow(0.,0), 1.); // In context of integral exponents and continuous radix, this def is most appropriate.
}

#[test]
fn test_sq() {
  assert_eq!(sq(0.), 0.);
  assert_eq!(sq(1.), 1.);
  assert_eq!(sq(2.), 4.);
  assert_eq!(sq(2.2), 2.2*2.2);
}

#[test]
fn test_cum_sums_prev() {
  let xs =  ~[1u, 2u, 3u];
  assert_eq!(cumulative_sums_prev_elems(xs), ~[0u, 1u, 3u]);
}
<commit_msg>Add R_NaN.<commit_after>use std::num::{Num,Zero};
use std::vec;
use std::f64;

// types and type aliases

pub type R = f64;
pub static R_NaN: R = f64::NaN;

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Deg(u8);

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Dim(uint);

// constants

pub static DEFAULT_INTEGRATION_REL_ERR: R = 1e-12;
pub static DEFAULT_INTEGRATION_ABS_ERR: R = 1e-12;

#[inline]
pub fn pow(radix: R, exp: uint) -> R {
  if exp == 0u { return 1 as R; }
  if radix == 0. { return 0 as R; }
  let mut prod = 1 as R;
  let mut _exp = exp;
  let mut multiplier = radix;
  while (_exp > 0u) {
    if _exp % 2u == 1u {
      prod *= multiplier;
    }
    _exp /= 2u;
    multiplier *= multiplier;
  }
 prod
}

#[inline(always)]
pub fn sq<T:Mul<T,T>>(x: T) -> T {
  x.mul(&x)
}

pub fn cumulative_sums_prev_elems<T:Num+Clone>(xs: &[T]) -> ~[T] {
  let mut cum_sums = vec::with_capacity(xs.len());
  let mut sum: T =  Zero::zero();
  for x in xs.iter() {
    cum_sums.push(sum.clone());
    sum = sum.add(x);
  }
  cum_sums
}

#[test]
fn test_pow() {
  assert_eq!(pow(2.,2), 4.);
  assert_eq!(pow(2.,3), 8.);
  assert_eq!(pow(0.,3), 0.);
  assert_eq!(pow(1.,3), 1.);
  assert_eq!(pow(0.,0), 1.); // In context of integral exponents and continuous radix, this def is most appropriate.
}

#[test]
fn test_sq() {
  assert_eq!(sq(0.), 0.);
  assert_eq!(sq(1.), 1.);
  assert_eq!(sq(2.), 4.);
  assert_eq!(sq(2.2), 2.2*2.2);
}

#[test]
fn test_cum_sums_prev() {
  let xs =  ~[1u, 2u, 3u];
  assert_eq!(cumulative_sums_prev_elems(xs), ~[0u, 1u, 3u]);
}
<|endoftext|>