<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::borrow::ToOwned;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::sync::mpsc::{channel, Receiver, Sender};
use url::Url;

use net_traits::storage_task::{StorageTask, StorageTaskMsg, StorageType};
use util::str::DOMString;
use util::task::spawn_named;

pub trait StorageTaskFactory {
    fn new() -> Self;
}

impl StorageTaskFactory for StorageTask {
    /// Create a StorageTask
    fn new() -> StorageTask {
        let (chan, port) = channel();
        spawn_named("StorageManager".to_owned(), move || {
            StorageManager::new(port).start();
        });
        chan
    }
}

struct StorageManager {
    port: Receiver<StorageTaskMsg>,
    session_data: HashMap<String, BTreeMap<DOMString, DOMString>>,
    local_data: HashMap<String, BTreeMap<DOMString, DOMString>>,
}

impl StorageManager {
    fn new(port: Receiver<StorageTaskMsg>) -> StorageManager {
        StorageManager {
            port: port,
            session_data: HashMap::new(),
            local_data: HashMap::new(),
        }
    }
}

impl StorageManager {
    fn start(&mut self) {
        loop {
            match self.port.recv().unwrap() {
                StorageTaskMsg::Length(sender, url, storage_type) => {
                    self.length(sender, url, storage_type)
                }
                StorageTaskMsg::Key(sender, url, storage_type, index) => {
                    self.key(sender, url, storage_type, index)
                }
                StorageTaskMsg::SetItem(sender, url, storage_type, name, value) => {
                    self.set_item(sender, url, storage_type, name, value)
                }
                StorageTaskMsg::GetItem(sender, url, storage_type, name) => {
                    self.get_item(sender, url, storage_type, name)
                }
                StorageTaskMsg::RemoveItem(sender, url, storage_type, name) => {
                    self.remove_item(sender, url, storage_type, name)
                }
                StorageTaskMsg::Clear(sender, url, storage_type) => {
                    self.clear(sender, url, storage_type)
                }
                StorageTaskMsg::Exit => {
                    break
                }
            }
        }
    }

    fn select_data(& self, storage_type: StorageType) -> &HashMap<String, BTreeMap<DOMString, DOMString>> {
        match storage_type {
            StorageType::Session => &self.session_data,
            StorageType::Local => &self.local_data
        }
    }

    fn select_data_mut(&mut self, storage_type: StorageType) -> &mut HashMap<String, BTreeMap<DOMString, DOMString>> {
        match storage_type {
            StorageType::Session => &mut self.session_data,
            StorageType::Local => &mut self.local_data
        }
    }

    fn length(&self, sender: Sender<u32>, url: Url, storage_type: StorageType) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data(storage_type);
        sender.send(data.get(&origin).map_or(0u, |entry| entry.len()) as u32).unwrap();
    }

    fn key(&self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, index: u32) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data(storage_type);
        sender.send(data.get(&origin)
                    .and_then(|entry| entry.keys().nth(index as uint))
                    .map(|key| key.clone())).unwrap();
    }

    /// Sends Some(old_value) in case there was a previous value with the same key name but with different
    /// value name, otherwise sends None
    fn set_item(&mut self, sender: Sender<(bool, Option<DOMString>)>, url: Url, storage_type: StorageType, name: DOMString, value: DOMString) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data_mut(storage_type);
        if !data.contains_key(&origin) {
            data.insert(origin.clone(), BTreeMap::new());
        }

        let (changed, old_value) = data.get_mut(&origin).map(|entry| {
            entry.insert(name, value.clone()).map_or(
                (true, None),
                |old| if old == value {
                    (false, None)
                } else {
                    (true, Some(old))
                })
        }).unwrap();
        sender.send((changed, old_value)).unwrap();
    }

    fn get_item(&self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, name: DOMString) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data(storage_type);
        sender.send(data.get(&origin)
                    .and_then(|entry| entry.get(&name))
                    .map(|value| value.to_string())).unwrap();
    }

    /// Sends Some(old_value) in case there was a previous value with the key name, otherwise sends None
    fn remove_item(&mut self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, name: DOMString) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data_mut(storage_type);
        let old_value = data.get_mut(&origin).map(|entry| {
            entry.remove(&name)
        }).unwrap();
        sender.send(old_value).unwrap();
    }

    fn clear(&mut self, sender: Sender<bool>, url: Url, storage_type: StorageType) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data_mut(storage_type);
        sender.send(data.get_mut(&origin)
                    .map_or(false, |entry| {
                        if !entry.is_empty() {
                            entry.clear();
                            true
                        } else {
                            false
                        }})).unwrap();
    }

    fn get_origin_as_string(&self, url: Url) -> String {
        let mut origin = "".to_string();
        origin.push_str(&url.scheme);
        origin.push_str("://");
        url.domain().map(|domain| origin.push_str(&domain));
        url.port().map(|port| {
            origin.push_str(":");
            origin.push_str(&port.to_string());
        });
        origin.push_str("/");
        origin
    }
}
<commit_msg>net/storage_task.rs: Fix remove_item<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::borrow::ToOwned;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::sync::mpsc::{channel, Receiver, Sender};
use url::Url;

use net_traits::storage_task::{StorageTask, StorageTaskMsg, StorageType};
use util::str::DOMString;
use util::task::spawn_named;

pub trait StorageTaskFactory {
    fn new() -> Self;
}

impl StorageTaskFactory for StorageTask {
    /// Create a StorageTask
    fn new() -> StorageTask {
        let (chan, port) = channel();
        spawn_named("StorageManager".to_owned(), move || {
            StorageManager::new(port).start();
        });
        chan
    }
}

struct StorageManager {
    port: Receiver<StorageTaskMsg>,
    session_data: HashMap<String, BTreeMap<DOMString, DOMString>>,
    local_data: HashMap<String, BTreeMap<DOMString, DOMString>>,
}

impl StorageManager {
    fn new(port: Receiver<StorageTaskMsg>) -> StorageManager {
        StorageManager {
            port: port,
            session_data: HashMap::new(),
            local_data: HashMap::new(),
        }
    }
}

impl StorageManager {
    fn start(&mut self) {
        loop {
            match self.port.recv().unwrap() {
                StorageTaskMsg::Length(sender, url, storage_type) => {
                    self.length(sender, url, storage_type)
                }
                StorageTaskMsg::Key(sender, url, storage_type, index) => {
                    self.key(sender, url, storage_type, index)
                }
                StorageTaskMsg::SetItem(sender, url, storage_type, name, value) => {
                    self.set_item(sender, url, storage_type, name, value)
                }
                StorageTaskMsg::GetItem(sender, url, storage_type, name) => {
                    self.get_item(sender, url, storage_type, name)
                }
                StorageTaskMsg::RemoveItem(sender, url, storage_type, name) => {
                    self.remove_item(sender, url, storage_type, name)
                }
                StorageTaskMsg::Clear(sender, url, storage_type) => {
                    self.clear(sender, url, storage_type)
                }
                StorageTaskMsg::Exit => {
                    break
                }
            }
        }
    }

    fn select_data(& self, storage_type: StorageType) -> &HashMap<String, BTreeMap<DOMString, DOMString>> {
        match storage_type {
            StorageType::Session => &self.session_data,
            StorageType::Local => &self.local_data
        }
    }

    fn select_data_mut(&mut self, storage_type: StorageType) -> &mut HashMap<String, BTreeMap<DOMString, DOMString>> {
        match storage_type {
            StorageType::Session => &mut self.session_data,
            StorageType::Local => &mut self.local_data
        }
    }

    fn length(&self, sender: Sender<u32>, url: Url, storage_type: StorageType) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data(storage_type);
        sender.send(data.get(&origin).map_or(0u, |entry| entry.len()) as u32).unwrap();
    }

    fn key(&self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, index: u32) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data(storage_type);
        sender.send(data.get(&origin)
                    .and_then(|entry| entry.keys().nth(index as uint))
                    .map(|key| key.clone())).unwrap();
    }

    /// Sends Some(old_value) in case there was a previous value with the same key name but with different
    /// value name, otherwise sends None
    fn set_item(&mut self, sender: Sender<(bool, Option<DOMString>)>, url: Url, storage_type: StorageType, name: DOMString, value: DOMString) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data_mut(storage_type);
        if !data.contains_key(&origin) {
            data.insert(origin.clone(), BTreeMap::new());
        }

        let (changed, old_value) = data.get_mut(&origin).map(|entry| {
            entry.insert(name, value.clone()).map_or(
                (true, None),
                |old| if old == value {
                    (false, None)
                } else {
                    (true, Some(old))
                })
        }).unwrap();
        sender.send((changed, old_value)).unwrap();
    }

    fn get_item(&self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, name: DOMString) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data(storage_type);
        sender.send(data.get(&origin)
                    .and_then(|entry| entry.get(&name))
                    .map(|value| value.to_string())).unwrap();
    }

    /// Sends Some(old_value) in case there was a previous value with the key name, otherwise sends None
    fn remove_item(&mut self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, name: DOMString) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data_mut(storage_type);
        let old_value = data.get_mut(&origin).and_then(|entry| {
            entry.remove(&name)
        });
        sender.send(old_value).unwrap();
    }

    fn clear(&mut self, sender: Sender<bool>, url: Url, storage_type: StorageType) {
        let origin = self.get_origin_as_string(url);
        let data = self.select_data_mut(storage_type);
        sender.send(data.get_mut(&origin)
                    .map_or(false, |entry| {
                        if !entry.is_empty() {
                            entry.clear();
                            true
                        } else {
                            false
                        }})).unwrap();
    }

    fn get_origin_as_string(&self, url: Url) -> String {
        let mut origin = "".to_string();
        origin.push_str(&url.scheme);
        origin.push_str("://");
        url.domain().map(|domain| origin.push_str(&domain));
        url.port().map(|port| {
            origin.push_str(":");
            origin.push_str(&port.to_string());
        });
        origin.push_str("/");
        origin
    }
}
<|endoftext|>


<commit_before><commit_msg>Add cli validators for date and datetime<commit_after><|endoftext|>


<commit_before><commit_msg>Move thread handle in function<commit_after><|endoftext|>


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


<commit_before><commit_msg>add collections::Vec::set_length<commit_after><|endoftext|>


<commit_before><commit_msg>parser: use the hashmap instead of creating our AST<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor: remove warnings<commit_after><|endoftext|>


<commit_before><commit_msg>add test file<commit_after>extern crate gamma_lut;

fn main() {
    let contrast = 0.0;
    let gamma = 0.0;

    let table = gamma_lut::gamma_lut::new(contrast, gamma, gamma);
    table.print_values();
}
<|endoftext|>


<commit_before><commit_msg>"hello world" source<commit_after>fn main() {
    println!("Hello, world!");
}
<|endoftext|>


<commit_before><commit_msg>A first attempt at interpreting brainfuck programs<commit_after><|endoftext|>


<commit_before><commit_msg>Change from match to if let.<commit_after><|endoftext|>


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

fn main() {
    let stdout = &io::stdout() as &io::WriterUtil;
    stdout.write_line("Hello!");
}
<|endoftext|>


<commit_before><commit_msg>Allow "dup" modifiers<commit_after><|endoftext|>


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

// Check that when a `let`-binding occurs in a loop, its associated
// drop-flag is reinitialized (to indicate "needs-drop" at the end of
// the owning variable's scope).

struct A<'a>(&'a mut i32);

impl<'a> Drop for A<'a> {
    fn drop(&mut self) {
        *self.0 += 1;
    }
}

fn main() {
    let mut cnt = 0;
    for i in 0..2 {
        let a = A(&mut cnt);
        if i == 1 { // Note that
            break;  //  both this break
        }           //   and also
        drop(a);    //    this move of `a`
        // are necessary to expose the bug
    }
    assert_eq!(cnt, 2);
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>Starting to play with a bitmap font impl.<commit_after>
use std::collections::HashMap;
use ggez;

/// Describes the layout of characters in your
/// bitmap font.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct TextMap {
    map: HashMap<char, ggez::Rect>,
}

impl TextMap {
    /// Creates a new `TextMap` from a uniform grid of
    /// sprites.  Takes the number of sprites wide and
    /// tall that the bitmap should be, and a string
    /// describing the characters in the map... in order,
    /// left to right, top to bottom.
    ///
    /// The characters do not necessarily need to fill
    /// the entire image.  ie, if your image is 16x16 glyphs
    /// for 256 total, and you only use the first 150 of them,
    /// that's fine.
    ///
    /// The floating point math involved should always be
    /// exact for `Image`'s and sprites with a resolution
    /// that is a power of two, I think.
    fn from_grid(mapping: &str, width: usize, height: usize) -> Self {
        // Assert the given width and height can fit the listed characters.
        let num_chars = mapping.chars.count();
        assert!(num_chars <= width * height);
        let rect_width = 1.0 / (width as f32);
        let rect_height = 1.0 / (height as f32);
        let mut map = HashMap::with_capacity(num_chars);
        let mut current_x = 0;
        let mut current_y = 0;
        for c in mapping.chars() {
            let x_offset = current_x as f32 * rect_width;
            let y_offset = current_y as f32 * rect_height;
            let char_rect = ggez::Rect {
                x: x_offset,
                y: y_offset,
                w: rect_width,
                h: rect_height;
            };
            map.insert(c, char_rect);
            current_x = (current_x + 1) % width;
            if current_x == 0 {
                current_y += 1;
            }
        }

        Self {
            map,
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BitmapFont {
    bitmap: ggez::graphics::Image,
    batch: ggez::graphics::SpriteBatch,
    map: TextMap,
}

impl BitmapFont {

}<|endoftext|>


<commit_before><commit_msg>Add TODO about improving builder finalize error.<commit_after><|endoftext|>


<commit_before><commit_msg>add list api specification<commit_after>#![allow(dead_code)]
#![allow(unused)]
#![warn(missing_docs)]

use ApiResponse;
use chrono;
use error;
use error::api;
use prelude::*;
use Proxer;
use request;
use request::info::*;
use reqwest;
use reqwest::IntoUrl;
use response::info;
use serde_derive;
use serde_json;
use serde_json::Value;
use std;
use std::collections::HashMap;
use std::ops::Deref;
use std::process::exit;
use std::rc::Rc;
use std::thread;
use std::time;

pub struct List<'a> {
    pub proxer: Proxer<'a>
}

impl<'a> List<'a> {
    fn get_entry_list(self) -> request::list::GetEntryList<'a> {
        request::list::GetEntryList
    }
}
<|endoftext|>


<commit_before><commit_msg>Add tests for expr.<commit_after><|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

pub const DBUS_TIMEOUT: i32 = 20000; // millieconds

pub const STRATIS_VERSION: &'static str = "1";
pub const MANAGER_NAME: &'static str = "/Manager";
pub const STRATIS_BASE_PATH: &'static str = "/org/storage/stratis1";
pub const STRATIS_BASE_SERVICE: &'static str = "org.storage.stratis1";
pub const STRATIS_BASE_MANAGER: &'static str = "/org/storage/stratis1/Manager";
pub const STRATIS_MANAGER_INTERFACE: &'static str = "org.storage.stratis1.Manager";
pub const STRATIS_POOL_BASE_INTERFACE: &'static str = "org.storage.stratis1.pool";
pub const STRATIS_FILESYSTEM_BASE_INTERFACE: &'static str = "org.storage.stratis1.filesystem";
pub const STRATIS_DEV_BASE_INTERFACE: &'static str = "org.storage.stratis1.dev";
pub const STRATIS_CACHE_BASE_INTERFACE: &'static str = "org.storage.stratis1.cache";
pub const STRATIS_POOL_BASE_PATH: &'static str = "/org/storage/stratis/pool";

pub const DEFAULT_OBJECT_PATH: &'static str = "/";

// Manager Methods
pub const LIST_POOLS: &'static str = "ListPools";
pub const CREATE_POOL: &'static str = "CreatePool";
pub const DESTROY_POOL: &'static str = "DestroyPool";
pub const GET_POOL_OBJECT_PATH: &'static str = "GetPoolObjectPath";
pub const GET_FILESYSTEM_OBJECT_PATH: &'static str = "GetFilesystemObjectPath";
pub const GET_DEV_OBJECT_PATH: &'static str = "GetDevObjectPath";
pub const GET_CACHE_OBJECT_PATH: &'static str = "GetCacheObjectPath";
pub const GET_ERROR_CODES: &'static str = "GetErrorCodes";
pub const GET_RAID_LEVELS: &'static str = "GetRaidLevels";
pub const GET_DEV_TYPES: &'static str = "GetDevTypes";
pub const CONFIGURE_SIMULATOR: &'static str = "ConfigureSimulator";

// Pool Methods
pub const CREATE_FILESYSTEMS: &'static str = "CreateFilesystems";
pub const DESTROY_FILESYSTEMS: &'static str = "DestroyFilesystems";
pub const LIST_FILESYSTEMS: &'static str = "ListFilesystems";
pub const LIST_DEVS: &'static str = "ListDevs";
pub const LIST_CACHE_DEVS: &'static str = "ListCacheDevs";
pub const ADD_CACHE_DEVS: &'static str = "AddCacheDevs";
pub const REMOVE_CACHE_DEVS: &'static str = "RemoveCacheDevs";
pub const ADD_DEVS: &'static str = "AddDevs";
pub const REMOVE_DEVS: &'static str = "RemoveDevs";
pub const RENAME_POOL: &'static str = "Rename";

// Filesystem Methods
pub const CREATE_SNAPSHOT: &'static str = "CreateSnapshot";
pub const RENAME_FILESYSTEM: &'static str = "Rename";
pub const SET_MOUNTPOINT: &'static str = "SetMountpoint";
pub const SET_QUOTA: &'static str = "SetQuota";

pub trait HasCodes {
    /// Indicates that this enum can be converted to an int or described
    /// with a string.
    fn get_error_int(&self) -> u16;
    fn get_error_string(&self) -> &str;
}

custom_derive! {
    #[derive(Copy, Clone, EnumDisplay,
             IterVariants(StratisDBusErrorVariants),
             IterVariantNames(StratisDBusErrorVariantNames))]
    #[allow(non_camel_case_types)]
    pub enum ErrorEnum {
        OK,
        ERROR,

        ALREADY_EXISTS,
        BAD_PARAM,
        BUSY,
        CACHE_NOTFOUND,
        DEV_NOTFOUND,
        FILESYSTEM_NOTFOUND,
        IO_ERROR,
        LIST_FAILURE,
        INTERNAL_ERROR,
        NIX_ERROR,
        NO_POOLS,
        NOTFOUND,
        NULL,
        NULL_NAME,
        POOL_NOTFOUND,
    }
}

impl HasCodes for ErrorEnum {
    fn get_error_int(&self) -> u16 {
        *self as u16
    }

    fn get_error_string(&self) -> &str {
        match *self {
            ErrorEnum::OK => "Ok",
            ErrorEnum::ERROR => "A general error happened",
            ErrorEnum::NULL => "Null parameter was supplied",
            ErrorEnum::NOTFOUND => "Not found",
            ErrorEnum::POOL_NOTFOUND => "Pool not found",
            ErrorEnum::FILESYSTEM_NOTFOUND => "Filesystem not found",
            ErrorEnum::CACHE_NOTFOUND => "Cache not found",
            ErrorEnum::BAD_PARAM => "Bad parameter",
            ErrorEnum::DEV_NOTFOUND => "Dev not found",
            ErrorEnum::ALREADY_EXISTS => "Already exists",
            ErrorEnum::NULL_NAME => "Null name supplied",
            ErrorEnum::NO_POOLS => "No pools",
            ErrorEnum::LIST_FAILURE => "List operation failure.",
            ErrorEnum::INTERNAL_ERROR => "Internal error",
            ErrorEnum::IO_ERROR => "IO error during operation.",
            ErrorEnum::NIX_ERROR => "System error during operation.",
            ErrorEnum::BUSY => "Operation can not be performed at this time",
        }
    }
}

custom_derive! {
    #[derive(Copy, Clone, EnumDisplay,
             IterVariants(StratisDBusRaidTypeVariants),
             IterVariantNames(StratisDBusRaidTypeVariantNames))]
    #[allow(non_camel_case_types)]
    pub enum RaidType {
        RAID_TYPE_UNKNOWN,
        RAID_TYPE_SINGLE,
        RAID_TYPE_RAID1,
        RAID_TYPE_RAID5,
        RAID_TYPE_RAID6,
    }
}

impl HasCodes for RaidType {
    fn get_error_int(&self) -> u16 {
        *self as u16
    }

    fn get_error_string(&self) -> &str {
        match *self {
            RaidType::RAID_TYPE_UNKNOWN => "Unknown",
            RaidType::RAID_TYPE_SINGLE => "Single",
            RaidType::RAID_TYPE_RAID1 => "Mirrored",
            RaidType::RAID_TYPE_RAID5 => "Block-level striping with distributed parity",
            RaidType::RAID_TYPE_RAID6 => "Block-level striping with two distributed parities",
        }
    }
}
<commit_msg>Remove unused constants.<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

pub const STRATIS_BASE_PATH: &'static str = "/org/storage/stratis1";
pub const STRATIS_BASE_SERVICE: &'static str = "org.storage.stratis1";
pub const STRATIS_MANAGER_INTERFACE: &'static str = "org.storage.stratis1.Manager";
pub const STRATIS_POOL_BASE_INTERFACE: &'static str = "org.storage.stratis1.pool";
pub const STRATIS_FILESYSTEM_BASE_INTERFACE: &'static str = "org.storage.stratis1.filesystem";

pub const DEFAULT_OBJECT_PATH: &'static str = "/";

// Manager Methods
pub const LIST_POOLS: &'static str = "ListPools";
pub const CREATE_POOL: &'static str = "CreatePool";
pub const DESTROY_POOL: &'static str = "DestroyPool";
pub const GET_POOL_OBJECT_PATH: &'static str = "GetPoolObjectPath";
pub const GET_FILESYSTEM_OBJECT_PATH: &'static str = "GetFilesystemObjectPath";
pub const GET_DEV_OBJECT_PATH: &'static str = "GetDevObjectPath";
pub const GET_CACHE_OBJECT_PATH: &'static str = "GetCacheObjectPath";
pub const GET_ERROR_CODES: &'static str = "GetErrorCodes";
pub const GET_RAID_LEVELS: &'static str = "GetRaidLevels";
pub const GET_DEV_TYPES: &'static str = "GetDevTypes";
pub const CONFIGURE_SIMULATOR: &'static str = "ConfigureSimulator";

// Pool Methods
pub const CREATE_FILESYSTEMS: &'static str = "CreateFilesystems";
pub const DESTROY_FILESYSTEMS: &'static str = "DestroyFilesystems";
pub const LIST_FILESYSTEMS: &'static str = "ListFilesystems";
pub const LIST_DEVS: &'static str = "ListDevs";
pub const LIST_CACHE_DEVS: &'static str = "ListCacheDevs";
pub const ADD_CACHE_DEVS: &'static str = "AddCacheDevs";
pub const REMOVE_CACHE_DEVS: &'static str = "RemoveCacheDevs";
pub const ADD_DEVS: &'static str = "AddDevs";
pub const REMOVE_DEVS: &'static str = "RemoveDevs";
pub const RENAME_POOL: &'static str = "Rename";

// Filesystem Methods
pub const CREATE_SNAPSHOT: &'static str = "CreateSnapshot";
pub const RENAME_FILESYSTEM: &'static str = "Rename";
pub const SET_MOUNTPOINT: &'static str = "SetMountpoint";
pub const SET_QUOTA: &'static str = "SetQuota";

pub trait HasCodes {
    /// Indicates that this enum can be converted to an int or described
    /// with a string.
    fn get_error_int(&self) -> u16;
    fn get_error_string(&self) -> &str;
}

custom_derive! {
    #[derive(Copy, Clone, EnumDisplay,
             IterVariants(StratisDBusErrorVariants),
             IterVariantNames(StratisDBusErrorVariantNames))]
    #[allow(non_camel_case_types)]
    pub enum ErrorEnum {
        OK,
        ERROR,

        ALREADY_EXISTS,
        BAD_PARAM,
        BUSY,
        CACHE_NOTFOUND,
        DEV_NOTFOUND,
        FILESYSTEM_NOTFOUND,
        IO_ERROR,
        LIST_FAILURE,
        INTERNAL_ERROR,
        NIX_ERROR,
        NO_POOLS,
        NOTFOUND,
        NULL,
        NULL_NAME,
        POOL_NOTFOUND,
    }
}

impl HasCodes for ErrorEnum {
    fn get_error_int(&self) -> u16 {
        *self as u16
    }

    fn get_error_string(&self) -> &str {
        match *self {
            ErrorEnum::OK => "Ok",
            ErrorEnum::ERROR => "A general error happened",
            ErrorEnum::NULL => "Null parameter was supplied",
            ErrorEnum::NOTFOUND => "Not found",
            ErrorEnum::POOL_NOTFOUND => "Pool not found",
            ErrorEnum::FILESYSTEM_NOTFOUND => "Filesystem not found",
            ErrorEnum::CACHE_NOTFOUND => "Cache not found",
            ErrorEnum::BAD_PARAM => "Bad parameter",
            ErrorEnum::DEV_NOTFOUND => "Dev not found",
            ErrorEnum::ALREADY_EXISTS => "Already exists",
            ErrorEnum::NULL_NAME => "Null name supplied",
            ErrorEnum::NO_POOLS => "No pools",
            ErrorEnum::LIST_FAILURE => "List operation failure.",
            ErrorEnum::INTERNAL_ERROR => "Internal error",
            ErrorEnum::IO_ERROR => "IO error during operation.",
            ErrorEnum::NIX_ERROR => "System error during operation.",
            ErrorEnum::BUSY => "Operation can not be performed at this time",
        }
    }
}

custom_derive! {
    #[derive(Copy, Clone, EnumDisplay,
             IterVariants(StratisDBusRaidTypeVariants),
             IterVariantNames(StratisDBusRaidTypeVariantNames))]
    #[allow(non_camel_case_types)]
    pub enum RaidType {
        RAID_TYPE_UNKNOWN,
        RAID_TYPE_SINGLE,
        RAID_TYPE_RAID1,
        RAID_TYPE_RAID5,
        RAID_TYPE_RAID6,
    }
}

impl HasCodes for RaidType {
    fn get_error_int(&self) -> u16 {
        *self as u16
    }

    fn get_error_string(&self) -> &str {
        match *self {
            RaidType::RAID_TYPE_UNKNOWN => "Unknown",
            RaidType::RAID_TYPE_SINGLE => "Single",
            RaidType::RAID_TYPE_RAID1 => "Mirrored",
            RaidType::RAID_TYPE_RAID5 => "Block-level striping with distributed parity",
            RaidType::RAID_TYPE_RAID6 => "Block-level striping with two distributed parities",
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a struct representing the chosen device and interface options<commit_after>use std::fmt;

static DEFAULTDEVICE: &'static str = "/dev/net/tun";
static DEFAULTINTERFACE: &'static str = "tap0";

pub enum CloneDevice {
    DefaultDevice,
    UserDefinedDevice(String)
}

impl fmt::Show for CloneDevice {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            DefaultDevice => write!(f, "{}", DEFAULTDEVICE),
            UserDefinedDevice(ref d) => write!(f, "{}", d),
        }
    }
}

pub enum InterfaceName {
    DefaultInterface,
    UserDefinedName(String)
}

impl fmt::Show for InterfaceName {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            DefaultInterface => write!(f, "{}", DEFAULTINTERFACE),
            UserDefinedName(ref i) => write!(f, "{}", i),
        }
    }
}

pub struct DeviceInfo {
    clone_device: CloneDevice,
    interface: InterfaceName
}

impl DeviceInfo {
    pub fn new(d: CloneDevice, i: InterfaceName) -> DeviceInfo {
        DeviceInfo {clone_device: d, interface: i}
    }

    pub fn get_clone_device_name(&self) -> String {
        format!("{}", self.clone_device)
    }

    pub fn get_interface_name(&self) -> String {
        format!("{}", self.interface)
    }
}

impl fmt::Show for DeviceInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "clone device: {}, interface name: {}", self.clone_device, self.interface)
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a parser for metadata block headers<commit_after>use nom::be_u8;

use utility::to_u32;

named!(header <&[u8], (u8, bool, u32)>,
  chain!(
    block_byte: be_u8 ~
    length: map!(take!(3), to_u32),
    || {
      let is_last    = (block_byte >> 7) == 1;
      let block_type = block_byte & 0b01111111;

      (block_type, is_last, length)
    }
  )
);
<|endoftext|>


<commit_before>use std::{cmp, fmt, ptr};
use std::os::raw::c_int;
use std::os::unix::io::RawFd;
use std::collections::HashMap;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::Duration;

use libc::{self, time_t};

use {io, Ready, PollOpt, Token};
use event::{self, Event};
use sys::unix::cvt;
use sys::unix::io::set_cloexec;

/// Each Selector has a globally unique(ish) ID associated with it. This ID
/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
/// registered with the `Selector`. If a type that is previously associated with
/// a `Selector` attempts to register itself with a different `Selector`, the
/// operation will return with an error. This matches windows behavior.
static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

macro_rules! kevent {
    ($id: expr, $filter: expr, $flags: expr, $data: expr) => {
        libc::kevent {
            ident: $id as ::libc::uintptr_t,
            filter: $filter,
            flags: $flags,
            fflags: 0,
            data: 0,
            udata: $data as *mut _,
        }
    }
}

pub struct Selector {
    id: usize,
    kq: RawFd,
}

impl Selector {
    pub fn new() -> io::Result<Selector> {
        // offset by 1 to avoid choosing 0 as the id of a selector
        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
        let kq = unsafe { try!(cvt(libc::kqueue())) };
        drop(set_cloexec(kq));

        Ok(Selector {
            id: id,
            kq: kq,
        })
    }

    pub fn id(&self) -> usize {
        self.id
    }

    pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> {
        let timeout = timeout.map(|to| {
            libc::timespec {
                tv_sec: cmp::min(to.as_secs(), time_t::max_value() as u64) as time_t,
                tv_nsec: to.subsec_nanos() as libc::c_long,
            }
        });
        let timeout = timeout.as_ref().map(|s| s as *const _).unwrap_or(ptr::null_mut());

        unsafe {
            let cnt = try!(cvt(libc::kevent(self.kq,
                                            ptr::null(),
                                            0,
                                            evts.sys_events.0.as_mut_ptr(),
            // FIXME: needs a saturating cast here.
                                            evts.sys_events.0.capacity() as c_int,
                                            timeout)));
            evts.sys_events.0.set_len(cnt as usize);
            Ok(evts.coalesce(awakener))
        }
    }

    pub fn register(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        trace!("registering; token={:?}; interests={:?}", token, interests);

        let flags = if opts.contains(PollOpt::edge()) { libc::EV_CLEAR } else { 0 } |
                    if opts.contains(PollOpt::oneshot()) { libc::EV_ONESHOT } else { 0 } |
                    libc::EV_RECEIPT;

        unsafe {
            let r = if interests.contains(Ready::readable()) { libc::EV_ADD } else { libc::EV_DELETE };
            let w = if interests.contains(Ready::writable()) { libc::EV_ADD } else { libc::EV_DELETE };
            let mut changes = [
                kevent!(fd, libc::EVFILT_READ, flags | r, usize::from(token)),
                kevent!(fd, libc::EVFILT_WRITE, flags | w, usize::from(token)),
            ];
            try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
                                           changes.as_mut_ptr(), changes.len() as c_int,
                                           ::std::ptr::null())));
            for change in changes.iter() {
                debug_assert_eq!(change.flags & libc::EV_ERROR, libc::EV_ERROR);
                if change.data != 0 {
                    // there’s some error, but we want to ignore ENOENT error for EV_DELETE
                    let orig_flags = if change.filter == libc::EVFILT_READ { r } else { w };
                    if !(change.data as i32 == libc::ENOENT && orig_flags & libc::EV_DELETE != 0) {
                        return Err(::std::io::Error::from_raw_os_error(change.data as i32));
                    }
                }
            }
            Ok(())
        }
    }

    pub fn reregister(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        // Just need to call register here since EV_ADD is a mod if already
        // registered
        self.register(fd, token, interests, opts)
    }

    pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
        unsafe {
            // EV_RECEIPT is a nice way to apply changes and get back per-event results while not
            // draining the actual changes.
            let filter = libc::EV_DELETE | libc::EV_RECEIPT;
            let mut changes = [
                kevent!(fd, libc::EVFILT_READ, filter, ptr::null_mut()),
                kevent!(fd, libc::EVFILT_WRITE, filter, ptr::null_mut()),
            ];
            try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
                                           changes.as_mut_ptr(), changes.len() as c_int,
                                           ::std::ptr::null())).map(|_| ()));
            if changes[0].data as i32 == libc::ENOENT && changes[1].data as i32 == libc::ENOENT {
                return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
            }
            for change in changes.iter() {
                debug_assert_eq!(libc::EV_ERROR & change.flags, libc::EV_ERROR);
                if change.data != 0 && change.data as i32 != libc::ENOENT {
                    return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
                }
            }
            Ok(())
        }
    }
}

impl fmt::Debug for Selector {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Selector")
            .field("id", &self.id)
            .field("kq", &self.kq)
            .finish()
    }
}

impl Drop for Selector {
    fn drop(&mut self) {
        unsafe {
            let _ = libc::close(self.kq);
        }
    }
}

pub struct Events {
    sys_events: KeventList,
    events: Vec<Event>,
    event_map: HashMap<Token, usize>,
}

struct KeventList(Vec<libc::kevent>);

unsafe impl Send for KeventList {}
unsafe impl Sync for KeventList {}

impl Events {
    pub fn with_capacity(cap: usize) -> Events {
        Events {
            sys_events: KeventList(Vec::with_capacity(cap)),
            events: Vec::with_capacity(cap),
            event_map: HashMap::with_capacity(cap)
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.events.len()
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.events.is_empty()
    }

    pub fn get(&self, idx: usize) -> Option<Event> {
        self.events.get(idx).map(|e| *e)
    }

    fn coalesce(&mut self, awakener: Token) -> bool {
        let mut ret = false;
        self.events.clear();
        self.event_map.clear();

        for e in self.sys_events.0.iter() {
            let token = Token(e.udata as usize);
            let len = self.events.len();

            if token == awakener {
                // TODO: Should this return an error if event is an error. It
                // is not critical as spurious wakeups are permitted.
                ret = true;
                continue;
            }

            let idx = *self.event_map.entry(token)
                .or_insert(len);

            if idx == len {
                // New entry, insert the default
                self.events.push(Event::new(Ready::none(), token));

            }

            if e.flags & libc::EV_ERROR != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::error());
            }

            if e.filter == libc::EVFILT_READ {
                event::kind_mut(&mut self.events[idx]).insert(Ready::readable());
            } else if e.filter == libc::EVFILT_WRITE {
                event::kind_mut(&mut self.events[idx]).insert(Ready::writable());
            }

            if e.flags & libc::EV_EOF != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::hup());

                // When the read end of the socket is closed, EV_EOF is set on
                // flags, and fflags contains the error if there is one.
                if e.fflags != 0 {
                    event::kind_mut(&mut self.events[idx]).insert(Ready::error());
                }
            }
        }

        ret
    }

    pub fn push_event(&mut self, event: Event) {
        self.events.push(event);
    }
}

impl fmt::Debug for Events {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "Events {{ len: {} }}", self.sys_events.0.len())
    }
}

#[test]
fn does_not_register_rw() {
    use ::deprecated::{EventLoopBuilder, Handler};
    use ::unix::EventedFd;
    struct Nop;
    impl Handler for Nop {
        type Timeout = ();
        type Message = ();
    }

    // registering kqueue fd will fail if write is requested
    let kq = unsafe { libc::kqueue() };
    let kqf = EventedFd(&kq);
    let mut evtloop = EventLoopBuilder::new().build::<Nop>().expect("evt loop builds");
    evtloop.register(&kqf, Token(1234), Ready::readable() | Ready::writable(),
                     PollOpt::edge() | PollOpt::oneshot()).unwrap_err();
    evtloop.deregister(&kqf).unwrap();
    evtloop.register(&kqf, Token(1234), Ready::readable(),
                     PollOpt::edge() | PollOpt::oneshot()).unwrap();
}
<commit_msg>Remove the check testing assumptions<commit_after>use std::{cmp, fmt, ptr};
use std::os::raw::c_int;
use std::os::unix::io::RawFd;
use std::collections::HashMap;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::Duration;

use libc::{self, time_t};

use {io, Ready, PollOpt, Token};
use event::{self, Event};
use sys::unix::cvt;
use sys::unix::io::set_cloexec;

/// Each Selector has a globally unique(ish) ID associated with it. This ID
/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
/// registered with the `Selector`. If a type that is previously associated with
/// a `Selector` attempts to register itself with a different `Selector`, the
/// operation will return with an error. This matches windows behavior.
static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

macro_rules! kevent {
    ($id: expr, $filter: expr, $flags: expr, $data: expr) => {
        libc::kevent {
            ident: $id as ::libc::uintptr_t,
            filter: $filter,
            flags: $flags,
            fflags: 0,
            data: 0,
            udata: $data as *mut _,
        }
    }
}

pub struct Selector {
    id: usize,
    kq: RawFd,
}

impl Selector {
    pub fn new() -> io::Result<Selector> {
        // offset by 1 to avoid choosing 0 as the id of a selector
        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
        let kq = unsafe { try!(cvt(libc::kqueue())) };
        drop(set_cloexec(kq));

        Ok(Selector {
            id: id,
            kq: kq,
        })
    }

    pub fn id(&self) -> usize {
        self.id
    }

    pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> {
        let timeout = timeout.map(|to| {
            libc::timespec {
                tv_sec: cmp::min(to.as_secs(), time_t::max_value() as u64) as time_t,
                tv_nsec: to.subsec_nanos() as libc::c_long,
            }
        });
        let timeout = timeout.as_ref().map(|s| s as *const _).unwrap_or(ptr::null_mut());

        unsafe {
            let cnt = try!(cvt(libc::kevent(self.kq,
                                            ptr::null(),
                                            0,
                                            evts.sys_events.0.as_mut_ptr(),
            // FIXME: needs a saturating cast here.
                                            evts.sys_events.0.capacity() as c_int,
                                            timeout)));
            evts.sys_events.0.set_len(cnt as usize);
            Ok(evts.coalesce(awakener))
        }
    }

    pub fn register(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        trace!("registering; token={:?}; interests={:?}", token, interests);

        let flags = if opts.contains(PollOpt::edge()) { libc::EV_CLEAR } else { 0 } |
                    if opts.contains(PollOpt::oneshot()) { libc::EV_ONESHOT } else { 0 } |
                    libc::EV_RECEIPT;

        unsafe {
            let r = if interests.contains(Ready::readable()) { libc::EV_ADD } else { libc::EV_DELETE };
            let w = if interests.contains(Ready::writable()) { libc::EV_ADD } else { libc::EV_DELETE };
            let mut changes = [
                kevent!(fd, libc::EVFILT_READ, flags | r, usize::from(token)),
                kevent!(fd, libc::EVFILT_WRITE, flags | w, usize::from(token)),
            ];
            try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
                                           changes.as_mut_ptr(), changes.len() as c_int,
                                           ::std::ptr::null())));
            for change in changes.iter() {
                debug_assert_eq!(change.flags & libc::EV_ERROR, libc::EV_ERROR);
                if change.data != 0 {
                    // there’s some error, but we want to ignore ENOENT error for EV_DELETE
                    let orig_flags = if change.filter == libc::EVFILT_READ { r } else { w };
                    if !(change.data as i32 == libc::ENOENT && orig_flags & libc::EV_DELETE != 0) {
                        return Err(::std::io::Error::from_raw_os_error(change.data as i32));
                    }
                }
            }
            Ok(())
        }
    }

    pub fn reregister(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        // Just need to call register here since EV_ADD is a mod if already
        // registered
        self.register(fd, token, interests, opts)
    }

    pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
        unsafe {
            // EV_RECEIPT is a nice way to apply changes and get back per-event results while not
            // draining the actual changes.
            let filter = libc::EV_DELETE | libc::EV_RECEIPT;
            let mut changes = [
                kevent!(fd, libc::EVFILT_READ, filter, ptr::null_mut()),
                kevent!(fd, libc::EVFILT_WRITE, filter, ptr::null_mut()),
            ];
            try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
                                           changes.as_mut_ptr(), changes.len() as c_int,
                                           ::std::ptr::null())).map(|_| ()));
            if changes[0].data as i32 == libc::ENOENT && changes[1].data as i32 == libc::ENOENT {
                return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
            }
            for change in changes.iter() {
                debug_assert_eq!(libc::EV_ERROR & change.flags, libc::EV_ERROR);
                if change.data != 0 && change.data as i32 != libc::ENOENT {
                    return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
                }
            }
            Ok(())
        }
    }
}

impl fmt::Debug for Selector {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Selector")
            .field("id", &self.id)
            .field("kq", &self.kq)
            .finish()
    }
}

impl Drop for Selector {
    fn drop(&mut self) {
        unsafe {
            let _ = libc::close(self.kq);
        }
    }
}

pub struct Events {
    sys_events: KeventList,
    events: Vec<Event>,
    event_map: HashMap<Token, usize>,
}

struct KeventList(Vec<libc::kevent>);

unsafe impl Send for KeventList {}
unsafe impl Sync for KeventList {}

impl Events {
    pub fn with_capacity(cap: usize) -> Events {
        Events {
            sys_events: KeventList(Vec::with_capacity(cap)),
            events: Vec::with_capacity(cap),
            event_map: HashMap::with_capacity(cap)
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.events.len()
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.events.is_empty()
    }

    pub fn get(&self, idx: usize) -> Option<Event> {
        self.events.get(idx).map(|e| *e)
    }

    fn coalesce(&mut self, awakener: Token) -> bool {
        let mut ret = false;
        self.events.clear();
        self.event_map.clear();

        for e in self.sys_events.0.iter() {
            let token = Token(e.udata as usize);
            let len = self.events.len();

            if token == awakener {
                // TODO: Should this return an error if event is an error. It
                // is not critical as spurious wakeups are permitted.
                ret = true;
                continue;
            }

            let idx = *self.event_map.entry(token)
                .or_insert(len);

            if idx == len {
                // New entry, insert the default
                self.events.push(Event::new(Ready::none(), token));

            }

            if e.flags & libc::EV_ERROR != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::error());
            }

            if e.filter == libc::EVFILT_READ {
                event::kind_mut(&mut self.events[idx]).insert(Ready::readable());
            } else if e.filter == libc::EVFILT_WRITE {
                event::kind_mut(&mut self.events[idx]).insert(Ready::writable());
            }

            if e.flags & libc::EV_EOF != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::hup());

                // When the read end of the socket is closed, EV_EOF is set on
                // flags, and fflags contains the error if there is one.
                if e.fflags != 0 {
                    event::kind_mut(&mut self.events[idx]).insert(Ready::error());
                }
            }
        }

        ret
    }

    pub fn push_event(&mut self, event: Event) {
        self.events.push(event);
    }
}

impl fmt::Debug for Events {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "Events {{ len: {} }}", self.sys_events.0.len())
    }
}

#[test]
fn does_not_register_rw() {
    use ::deprecated::{EventLoopBuilder, Handler};
    use ::unix::EventedFd;
    struct Nop;
    impl Handler for Nop {
        type Timeout = ();
        type Message = ();
    }

    // registering kqueue fd will fail if write is requested (On anything but some versions of OS
    // X)
    let kq = unsafe { libc::kqueue() };
    let kqf = EventedFd(&kq);
    let mut evtloop = EventLoopBuilder::new().build::<Nop>().expect("evt loop builds");
    evtloop.register(&kqf, Token(1234), Ready::readable(),
                     PollOpt::edge() | PollOpt::oneshot()).unwrap();
}
<|endoftext|>


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

/*!

The `Ord` and `Eq` comparison traits

This module contains the definition of both `Ord` and `Eq` which define
the common interfaces for doing comparison. Both are language items
that the compiler uses to implement the comparison operators. Rust code
may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
and `Eq` to overload the `==` and `!=` operators.

*/

/**
* Trait for values that can be compared for equality
* and inequality.
*
* Eventually this may be simplified to only require
* an `eq` method, with the other generated from
* a default implementation. However it should
* remain possible to implement `ne` separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="eq"]
pub trait Eq {
    pure fn eq(&self, other: &Self) -> bool;
    pure fn ne(&self, other: &Self) -> bool;
}

#[deriving_eq]
pub enum Ordering { Less, Equal, Greater }

/// Trait for types that form a total order
pub trait TotalOrd {
    pure fn cmp(&self, other: &Self) -> Ordering;
}

pure fn icmp<T: Ord>(a: &T, b: &T) -> Ordering {
    if *a < *b { Less }
    else if *a > *b { Greater }
    else { Equal }
}

impl TotalOrd for u8 {
    #[inline(always)]
    pure fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u16 {
    #[inline(always)]
    pure fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u32 {
    #[inline(always)]
    pure fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u64 {
    #[inline(always)]
    pure fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i8 {
    #[inline(always)]
    pure fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i16 {
    #[inline(always)]
    pure fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i32 {
    #[inline(always)]
    pure fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i64 {
    #[inline(always)]
    pure fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) }
}

impl TotalOrd for int {
    #[inline(always)]
    pure fn cmp(&self, other: &int) -> Ordering { icmp(self, other) }
}

impl TotalOrd for uint {
    #[inline(always)]
    pure fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) }
}

/**
* Trait for values that can be compared for a sort-order.
*
* Eventually this may be simplified to only require
* an `le` method, with the others generated from
* default implementations. However it should remain
* possible to implement the others separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord {
    pure fn lt(&self, other: &Self) -> bool;
    pure fn le(&self, other: &Self) -> bool;
    pure fn ge(&self, other: &Self) -> bool;
    pure fn gt(&self, other: &Self) -> bool;
}

#[inline(always)]
pub pure fn lt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).lt(v2)
}

#[inline(always)]
pub pure fn le<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).le(v2)
}

#[inline(always)]
pub pure fn eq<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).eq(v2)
}

#[inline(always)]
pub pure fn ne<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).ne(v2)
}

#[inline(always)]
pub pure fn ge<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).ge(v2)
}

#[inline(always)]
pub pure fn gt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).gt(v2)
}

#[inline(always)]
pub pure fn min<T:Ord>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

#[inline(always)]
pub pure fn max<T:Ord>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_int() {
        assert 5.cmp(&10) == Less;
        assert 10.cmp(&5) == Greater;
        assert 5.cmp(&5) == Equal;
        assert (-5).cmp(&12) == Less;
        assert 12.cmp(-5) == Greater;
    }
}
<commit_msg>inline the implementation of TotalOrd for integers<commit_after>// Copyright 2012 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.

/*!

The `Ord` and `Eq` comparison traits

This module contains the definition of both `Ord` and `Eq` which define
the common interfaces for doing comparison. Both are language items
that the compiler uses to implement the comparison operators. Rust code
may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
and `Eq` to overload the `==` and `!=` operators.

*/

/**
* Trait for values that can be compared for equality
* and inequality.
*
* Eventually this may be simplified to only require
* an `eq` method, with the other generated from
* a default implementation. However it should
* remain possible to implement `ne` separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="eq"]
pub trait Eq {
    pure fn eq(&self, other: &Self) -> bool;
    pure fn ne(&self, other: &Self) -> bool;
}

#[deriving_eq]
pub enum Ordering { Less, Equal, Greater }

/// Trait for types that form a total order
pub trait TotalOrd {
    pure fn cmp(&self, other: &Self) -> Ordering;
}

#[inline(always)]
pure fn icmp<T: Ord>(a: &T, b: &T) -> Ordering {
    if *a < *b { Less }
    else if *a > *b { Greater }
    else { Equal }
}

impl TotalOrd for u8 {
    #[inline(always)]
    pure fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u16 {
    #[inline(always)]
    pure fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u32 {
    #[inline(always)]
    pure fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u64 {
    #[inline(always)]
    pure fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i8 {
    #[inline(always)]
    pure fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i16 {
    #[inline(always)]
    pure fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i32 {
    #[inline(always)]
    pure fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i64 {
    #[inline(always)]
    pure fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) }
}

impl TotalOrd for int {
    #[inline(always)]
    pure fn cmp(&self, other: &int) -> Ordering { icmp(self, other) }
}

impl TotalOrd for uint {
    #[inline(always)]
    pure fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) }
}

/**
* Trait for values that can be compared for a sort-order.
*
* Eventually this may be simplified to only require
* an `le` method, with the others generated from
* default implementations. However it should remain
* possible to implement the others separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord {
    pure fn lt(&self, other: &Self) -> bool;
    pure fn le(&self, other: &Self) -> bool;
    pure fn ge(&self, other: &Self) -> bool;
    pure fn gt(&self, other: &Self) -> bool;
}

#[inline(always)]
pub pure fn lt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).lt(v2)
}

#[inline(always)]
pub pure fn le<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).le(v2)
}

#[inline(always)]
pub pure fn eq<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).eq(v2)
}

#[inline(always)]
pub pure fn ne<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).ne(v2)
}

#[inline(always)]
pub pure fn ge<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).ge(v2)
}

#[inline(always)]
pub pure fn gt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).gt(v2)
}

#[inline(always)]
pub pure fn min<T:Ord>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

#[inline(always)]
pub pure fn max<T:Ord>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_int() {
        assert 5.cmp(&10) == Less;
        assert 10.cmp(&5) == Greater;
        assert 5.cmp(&5) == Equal;
        assert (-5).cmp(&12) == Less;
        assert 12.cmp(-5) == Greater;
    }
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

pub struct InstructionIterator<'a, I: 'a> {
    pub editor: &'a Editor,
    pub iter: &'a mut I,
}

impl<'a, I: Iterator<Item = EventOption>> Iterator for InstructionIterator<'a, I> {
    type Item = Inst;

    fn next(&mut self) -> Option<Inst> {
        let mut n = 0;

        let mut last = '\0';
        for c in self.iter {
            match self.editor.cursors[self.editor.current_cursor as usize].mode {
                Mode::Primitive(_) => {
                    Inst(0, c);
                },
                Mode::Command(_) => {
                    n = match c {
                        '0' if n != 0 => n * 10,
                        '1'           => n * 10 + 1,
                        '2'           => n * 10 + 2,
                        '3'           => n * 10 + 3,
                        '4'           => n * 10 + 4,
                        '5'           => n * 10 + 5,
                        '6'           => n * 10 + 6,
                        '7'           => n * 10 + 7,
                        '8'           => n * 10 + 8,
                        '9'           => n * 10 + 9,
                        _             => {
                            last = c;
                            break;
                        },
                    }

                }
            }
        }

        Some(Inst(if n == 0 { 1 } else { n }, last))
    }
}

trait ToInstructionIterator {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self>;
}

impl ToInstructionIterator for Iterator<Item = EventOption> {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self> {
        InstructionIterator {
            editor: self,
            iter: self,
        }
    }
}
impl Editor {
    /// Execute a instruction
    pub fn exec(&mut self, inst: Inst) {

    }

}
<commit_msg>Fix some type errors<commit_after>use super::*;
use redox::*;

pub struct InstructionIterator<'a, I: 'a> {
    pub editor: &'a Editor,
    pub iter: &'a mut I,
}

impl<'a, I: Iterator<Item = EventOption>> Iterator for InstructionIterator<'a, I> {
    type Item = Inst;

    fn next(&mut self) -> Option<Inst> {
        let mut n = 0;

        let mut last = '\0';
        for e in self.iter {
            match e {
                EventOption::Key(k) if k.pressed => {
                    let c = k.character;
                    match self.editor.cursors[self.editor.current_cursor as usize].mode {
                        Mode::Primitive(_) => {
                            Inst(0, c);
                        },
                        Mode::Command(_) => {
                            n = match c {
                                '0' if n != 0 => n * 10,
                                '1'           => n * 10 + 1,
                                '2'           => n * 10 + 2,
                                '3'           => n * 10 + 3,
                                '4'           => n * 10 + 4,
                                '5'           => n * 10 + 5,
                                '6'           => n * 10 + 6,
                                '7'           => n * 10 + 7,
                                '8'           => n * 10 + 8,
                                '9'           => n * 10 + 9,
                                _             => {
                                    last = c;
                                    break;
                                },
                            }

                        }
                    }
        }

        Some(Inst(if n == 0 { 1 } else { n }, last))
    }
}

trait ToInstructionIterator {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self>;
}

impl ToInstructionIterator for Iterator<Item = EventOption> {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self> {
        InstructionIterator {
            editor: self,
            iter: self,
        }
    }
}
impl Editor {
    /// Execute a instruction
    pub fn exec(&mut self, inst: Inst) {

    }

}
<|endoftext|>


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

// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory

//! Operations on unsafe pointers, `*const T`, and `*mut T`.
//!
//! Working with unsafe pointers in Rust is uncommon,
//! typically limited to a few patterns.
//!
//! Use the [`null` function](fn.null.html) to create null pointers,
//! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
//! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
//! work everywhere. The `RawPtr` also defines the `offset` method,
//! for pointer math.
//!
//! # Common ways to create unsafe pointers
//!
//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
//!
//! ```
//! let my_num: int = 10;
//! let my_num_ptr: *const int = &my_num;
//! let mut my_speed: int = 88;
//! let my_speed_ptr: *mut int = &mut my_speed;
//! ```
//!
//! This does not take ownership of the original allocation
//! and requires no resource management later,
//! but you must not use the pointer after its lifetime.
//!
//! ## 2. Transmute an owned box (`Box<T>`).
//!
//! The `transmute` function takes, by value, whatever it's given
//! and returns it as whatever type is requested, as long as the
//! types are the same size. Because `Box<T>` and `*mut T` have the same
//! representation they can be trivially,
//! though unsafely, transformed from one type to the other.
//!
//! ```
//! use std::mem;
//!
//! unsafe {
//!     let my_num: Box<int> = box 10;
//!     let my_num: *const int = mem::transmute(my_num);
//!     let my_speed: Box<int> = box 88;
//!     let my_speed: *mut int = mem::transmute(my_speed);
//!
//!     // By taking ownership of the original `Box<T>` though
//!     // we are obligated to transmute it back later to be destroyed.
//!     drop(mem::transmute::<_, Box<int>>(my_speed));
//!     drop(mem::transmute::<_, Box<int>>(my_num));
//! }
//! ```
//!
//! Note that here the call to `drop` is for clarity - it indicates
//! that we are done with the given value and it should be destroyed.
//!
//! ## 3. Get it from C.
//!
//! ```
//! extern crate libc;
//!
//! use std::mem;
//!
//! fn main() {
//!     unsafe {
//!         let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
//!         if my_num.is_null() {
//!             panic!("failed to allocate memory");
//!         }
//!         libc::free(my_num as *mut libc::c_void);
//!     }
//! }
//! ```
//!
//! Usually you wouldn't literally use `malloc` and `free` from Rust,
//! but C APIs hand out a lot of pointers generally, so are a common source
//! of unsafe pointers in Rust.

use mem;
use clone::Clone;
use intrinsics;
use option::Option;
use option::Option::{Some, None};

use cmp::{PartialEq, Eq, PartialOrd, Equiv};
use cmp::Ordering;
use cmp::Ordering::{Less, Equal, Greater};

pub use intrinsics::copy_memory;
pub use intrinsics::copy_nonoverlapping_memory;
pub use intrinsics::set_memory;

/// Create a null pointer.
///
/// # Example
///
/// ```
/// use std::ptr;
///
/// let p: *const int = ptr::null();
/// assert!(p.is_null());
/// ```
#[inline]
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn null<T>() -> *const T { 0 as *const T }

/// Create an unsafe mutable null pointer.
///
/// # Example
///
/// ```
/// use std::ptr;
///
/// let p: *mut int = ptr::null_mut();
/// assert!(p.is_null());
/// ```
#[inline]
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn null_mut<T>() -> *mut T { 0 as *mut T }

/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
#[inline]
#[experimental = "uncertain about naming and semantics"]
#[allow(experimental)]
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
    set_memory(dst, 0, count);
}

/// Swap the values at two mutable locations of the same type, without
/// deinitialising either. They may overlap.
#[inline]
#[unstable]
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
    // Give ourselves some scratch space to work with
    let mut tmp: T = mem::uninitialized();
    let t: *mut T = &mut tmp;

    // Perform the swap
    copy_nonoverlapping_memory(t, &*x, 1);
    copy_memory(x, &*y, 1); // `x` and `y` may overlap
    copy_nonoverlapping_memory(y, &*t, 1);

    // y and t now point to the same thing, but we need to completely forget `tmp`
    // because it's no longer relevant.
    mem::forget(tmp);
}

/// Replace the value at a mutable location with a new one, returning the old
/// value, without deinitialising either.
#[inline]
#[unstable]
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
    mem::swap(mem::transmute(dest), &mut src); // cannot overlap
    src
}

/// Reads the value from `*src` and returns it.
#[inline(always)]
#[unstable]
pub unsafe fn read<T>(src: *const T) -> T {
    let mut tmp: T = mem::uninitialized();
    copy_nonoverlapping_memory(&mut tmp, src, 1);
    tmp
}

/// Reads the value from `*src` and nulls it out.
/// This currently prevents destructors from executing.
#[inline(always)]
#[experimental]
#[allow(experimental)]
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
    // Copy the data out from `dest`:
    let tmp = read(&*dest);

    // Now zero out `dest`:
    zero_memory(dest, 1);

    tmp
}

/// Unsafely overwrite a memory location with the given value without destroying
/// the old value.
///
/// This operation is unsafe because it does not destroy the previous value
/// contained at the location `dst`. This could leak allocations or resources,
/// so care must be taken to previously deallocate the value at `dst`.
#[inline]
#[unstable]
pub unsafe fn write<T>(dst: *mut T, src: T) {
    intrinsics::move_val_init(&mut *dst, src)
}

/// Methods on raw pointers
pub trait RawPtr<T> {
    /// Returns the null pointer.
    fn null() -> Self;

    /// Returns true if the pointer is equal to the null pointer.
    fn is_null(&self) -> bool;

    /// Returns true if the pointer is not equal to the null pointer.
    fn is_not_null(&self) -> bool { !self.is_null() }

    /// Returns the value of this pointer (ie, the address it points to)
    fn to_uint(&self) -> uint;

    /// Returns `None` if the pointer is null, or else returns a reference to the
    /// value wrapped in `Some`.
    ///
    /// # Safety Notes
    ///
    /// While this method and its mutable counterpart are useful for null-safety,
    /// it is important to note that this is still an unsafe operation because
    /// the returned value could be pointing to invalid memory.
    unsafe fn as_ref<'a>(&self) -> Option<&'a T>;

    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
    /// the object, or one-byte-past-the-end.  `count` is in units of T; e.g. a
    /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
    unsafe fn offset(self, count: int) -> Self;
}

/// Methods on mutable raw pointers
pub trait RawMutPtr<T>{
    /// Returns `None` if the pointer is null, or else returns a mutable reference
    /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
    /// it cannot verify the validity of the returned pointer.
    unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
}

impl<T> RawPtr<T> for *const T {
    #[inline]
    fn null() -> *const T { null() }

    #[inline]
    fn is_null(&self) -> bool { *self == RawPtr::null() }

    #[inline]
    fn to_uint(&self) -> uint { *self as uint }

    #[inline]
    unsafe fn offset(self, count: int) -> *const T {
        intrinsics::offset(self, count)
    }

    #[inline]
    unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        if self.is_null() {
            None
        } else {
            Some(&**self)
        }
    }
}

impl<T> RawPtr<T> for *mut T {
    #[inline]
    fn null() -> *mut T { null_mut() }

    #[inline]
    fn is_null(&self) -> bool { *self == RawPtr::null() }

    #[inline]
    fn to_uint(&self) -> uint { *self as uint }

    #[inline]
    unsafe fn offset(self, count: int) -> *mut T {
        intrinsics::offset(self as *const T, count) as *mut T
    }

    #[inline]
    unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        if self.is_null() {
            None
        } else {
            Some(&**self)
        }
    }
}

impl<T> RawMutPtr<T> for *mut T {
    #[inline]
    unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
        if self.is_null() {
            None
        } else {
            Some(&mut **self)
        }
    }
}

// Equality for pointers
impl<T> PartialEq for *const T {
    #[inline]
    fn eq(&self, other: &*const T) -> bool {
        *self == *other
    }
    #[inline]
    fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
}

impl<T> Eq for *const T {}

impl<T> PartialEq for *mut T {
    #[inline]
    fn eq(&self, other: &*mut T) -> bool {
        *self == *other
    }
    #[inline]
    fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}

impl<T> Eq for *mut T {}

// Equivalence for pointers
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*mut T> for *const T {
    fn equiv(&self, other: &*mut T) -> bool {
        self.to_uint() == other.to_uint()
    }
}

#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*const T> for *mut T {
    fn equiv(&self, other: &*const T) -> bool {
        self.to_uint() == other.to_uint()
    }
}

impl<T> Clone for *const T {
    #[inline]
    fn clone(&self) -> *const T {
        *self
    }
}

impl<T> Clone for *mut T {
    #[inline]
    fn clone(&self) -> *mut T {
        *self
    }
}

// Equality for extern "C" fn pointers
mod externfnpointers {
    use mem;
    use cmp::PartialEq;

    impl<_R> PartialEq for extern "C" fn() -> _R {
        #[inline]
        fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
            let self_: *const () = unsafe { mem::transmute(*self) };
            let other_: *const () = unsafe { mem::transmute(*other) };
            self_ == other_
        }
    }
    macro_rules! fnptreq(
        ($($p:ident),*) => {
            impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
                #[inline]
                fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
                    let self_: *const () = unsafe { mem::transmute(*self) };

                    let other_: *const () = unsafe { mem::transmute(*other) };
                    self_ == other_
                }
            }
        }
    )
    fnptreq!(A)
    fnptreq!(A,B)
    fnptreq!(A,B,C)
    fnptreq!(A,B,C,D)
    fnptreq!(A,B,C,D,E)
}

// Comparison for pointers
impl<T> PartialOrd for *const T {
    #[inline]
    fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
        if self < other {
            Some(Less)
        } else if self == other {
            Some(Equal)
        } else {
            Some(Greater)
        }
    }

    #[inline]
    fn lt(&self, other: &*const T) -> bool { *self < *other }

    #[inline]
    fn le(&self, other: &*const T) -> bool { *self <= *other }

    #[inline]
    fn gt(&self, other: &*const T) -> bool { *self > *other }

    #[inline]
    fn ge(&self, other: &*const T) -> bool { *self >= *other }
}

impl<T> PartialOrd for *mut T {
    #[inline]
    fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
        if self < other {
            Some(Less)
        } else if self == other {
            Some(Equal)
        } else {
            Some(Greater)
        }
    }

    #[inline]
    fn lt(&self, other: &*mut T) -> bool { *self < *other }

    #[inline]
    fn le(&self, other: &*mut T) -> bool { *self <= *other }

    #[inline]
    fn gt(&self, other: &*mut T) -> bool { *self > *other }

    #[inline]
    fn ge(&self, other: &*mut T) -> bool { *self >= *other }
}

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

// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory

//! Operations on unsafe pointers, `*const T`, and `*mut T`.
//!
//! Working with unsafe pointers in Rust is uncommon,
//! typically limited to a few patterns.
//!
//! Use the [`null` function](fn.null.html) to create null pointers,
//! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
//! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
//! work everywhere. The `RawPtr` also defines the `offset` method,
//! for pointer math.
//!
//! # Common ways to create unsafe pointers
//!
//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
//!
//! ```
//! let my_num: int = 10;
//! let my_num_ptr: *const int = &my_num;
//! let mut my_speed: int = 88;
//! let my_speed_ptr: *mut int = &mut my_speed;
//! ```
//!
//! This does not take ownership of the original allocation
//! and requires no resource management later,
//! but you must not use the pointer after its lifetime.
//!
//! ## 2. Transmute an owned box (`Box<T>`).
//!
//! The `transmute` function takes, by value, whatever it's given
//! and returns it as whatever type is requested, as long as the
//! types are the same size. Because `Box<T>` and `*mut T` have the same
//! representation they can be trivially,
//! though unsafely, transformed from one type to the other.
//!
//! ```
//! use std::mem;
//!
//! unsafe {
//!     let my_num: Box<int> = box 10;
//!     let my_num: *const int = mem::transmute(my_num);
//!     let my_speed: Box<int> = box 88;
//!     let my_speed: *mut int = mem::transmute(my_speed);
//!
//!     // By taking ownership of the original `Box<T>` though
//!     // we are obligated to transmute it back later to be destroyed.
//!     drop(mem::transmute::<_, Box<int>>(my_speed));
//!     drop(mem::transmute::<_, Box<int>>(my_num));
//! }
//! ```
//!
//! Note that here the call to `drop` is for clarity - it indicates
//! that we are done with the given value and it should be destroyed.
//!
//! ## 3. Get it from C.
//!
//! ```
//! extern crate libc;
//!
//! use std::mem;
//!
//! fn main() {
//!     unsafe {
//!         let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
//!         if my_num.is_null() {
//!             panic!("failed to allocate memory");
//!         }
//!         libc::free(my_num as *mut libc::c_void);
//!     }
//! }
//! ```
//!
//! Usually you wouldn't literally use `malloc` and `free` from Rust,
//! but C APIs hand out a lot of pointers generally, so are a common source
//! of unsafe pointers in Rust.

use mem;
use clone::Clone;
use intrinsics;
use option::Option;
use option::Option::{Some, None};

use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv};
use cmp::Ordering;
use cmp::Ordering::{Less, Equal, Greater};

pub use intrinsics::copy_memory;
pub use intrinsics::copy_nonoverlapping_memory;
pub use intrinsics::set_memory;

/// Create a null pointer.
///
/// # Example
///
/// ```
/// use std::ptr;
///
/// let p: *const int = ptr::null();
/// assert!(p.is_null());
/// ```
#[inline]
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn null<T>() -> *const T { 0 as *const T }

/// Create an unsafe mutable null pointer.
///
/// # Example
///
/// ```
/// use std::ptr;
///
/// let p: *mut int = ptr::null_mut();
/// assert!(p.is_null());
/// ```
#[inline]
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn null_mut<T>() -> *mut T { 0 as *mut T }

/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
#[inline]
#[experimental = "uncertain about naming and semantics"]
#[allow(experimental)]
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
    set_memory(dst, 0, count);
}

/// Swap the values at two mutable locations of the same type, without
/// deinitialising either. They may overlap.
#[inline]
#[unstable]
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
    // Give ourselves some scratch space to work with
    let mut tmp: T = mem::uninitialized();
    let t: *mut T = &mut tmp;

    // Perform the swap
    copy_nonoverlapping_memory(t, &*x, 1);
    copy_memory(x, &*y, 1); // `x` and `y` may overlap
    copy_nonoverlapping_memory(y, &*t, 1);

    // y and t now point to the same thing, but we need to completely forget `tmp`
    // because it's no longer relevant.
    mem::forget(tmp);
}

/// Replace the value at a mutable location with a new one, returning the old
/// value, without deinitialising either.
#[inline]
#[unstable]
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
    mem::swap(mem::transmute(dest), &mut src); // cannot overlap
    src
}

/// Reads the value from `*src` and returns it.
#[inline(always)]
#[unstable]
pub unsafe fn read<T>(src: *const T) -> T {
    let mut tmp: T = mem::uninitialized();
    copy_nonoverlapping_memory(&mut tmp, src, 1);
    tmp
}

/// Reads the value from `*src` and nulls it out.
/// This currently prevents destructors from executing.
#[inline(always)]
#[experimental]
#[allow(experimental)]
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
    // Copy the data out from `dest`:
    let tmp = read(&*dest);

    // Now zero out `dest`:
    zero_memory(dest, 1);

    tmp
}

/// Unsafely overwrite a memory location with the given value without destroying
/// the old value.
///
/// This operation is unsafe because it does not destroy the previous value
/// contained at the location `dst`. This could leak allocations or resources,
/// so care must be taken to previously deallocate the value at `dst`.
#[inline]
#[unstable]
pub unsafe fn write<T>(dst: *mut T, src: T) {
    intrinsics::move_val_init(&mut *dst, src)
}

/// Methods on raw pointers
pub trait RawPtr<T> {
    /// Returns the null pointer.
    fn null() -> Self;

    /// Returns true if the pointer is equal to the null pointer.
    fn is_null(&self) -> bool;

    /// Returns true if the pointer is not equal to the null pointer.
    fn is_not_null(&self) -> bool { !self.is_null() }

    /// Returns the value of this pointer (ie, the address it points to)
    fn to_uint(&self) -> uint;

    /// Returns `None` if the pointer is null, or else returns a reference to the
    /// value wrapped in `Some`.
    ///
    /// # Safety Notes
    ///
    /// While this method and its mutable counterpart are useful for null-safety,
    /// it is important to note that this is still an unsafe operation because
    /// the returned value could be pointing to invalid memory.
    unsafe fn as_ref<'a>(&self) -> Option<&'a T>;

    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
    /// the object, or one-byte-past-the-end.  `count` is in units of T; e.g. a
    /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
    unsafe fn offset(self, count: int) -> Self;
}

/// Methods on mutable raw pointers
pub trait RawMutPtr<T>{
    /// Returns `None` if the pointer is null, or else returns a mutable reference
    /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
    /// it cannot verify the validity of the returned pointer.
    unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
}

impl<T> RawPtr<T> for *const T {
    #[inline]
    fn null() -> *const T { null() }

    #[inline]
    fn is_null(&self) -> bool { *self == RawPtr::null() }

    #[inline]
    fn to_uint(&self) -> uint { *self as uint }

    #[inline]
    unsafe fn offset(self, count: int) -> *const T {
        intrinsics::offset(self, count)
    }

    #[inline]
    unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        if self.is_null() {
            None
        } else {
            Some(&**self)
        }
    }
}

impl<T> RawPtr<T> for *mut T {
    #[inline]
    fn null() -> *mut T { null_mut() }

    #[inline]
    fn is_null(&self) -> bool { *self == RawPtr::null() }

    #[inline]
    fn to_uint(&self) -> uint { *self as uint }

    #[inline]
    unsafe fn offset(self, count: int) -> *mut T {
        intrinsics::offset(self as *const T, count) as *mut T
    }

    #[inline]
    unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        if self.is_null() {
            None
        } else {
            Some(&**self)
        }
    }
}

impl<T> RawMutPtr<T> for *mut T {
    #[inline]
    unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
        if self.is_null() {
            None
        } else {
            Some(&mut **self)
        }
    }
}

// Equality for pointers
impl<T> PartialEq for *const T {
    #[inline]
    fn eq(&self, other: &*const T) -> bool {
        *self == *other
    }
    #[inline]
    fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
}

impl<T> Eq for *const T {}

impl<T> PartialEq for *mut T {
    #[inline]
    fn eq(&self, other: &*mut T) -> bool {
        *self == *other
    }
    #[inline]
    fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}

impl<T> Eq for *mut T {}

// Equivalence for pointers
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*mut T> for *const T {
    fn equiv(&self, other: &*mut T) -> bool {
        self.to_uint() == other.to_uint()
    }
}

#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*const T> for *mut T {
    fn equiv(&self, other: &*const T) -> bool {
        self.to_uint() == other.to_uint()
    }
}

impl<T> Clone for *const T {
    #[inline]
    fn clone(&self) -> *const T {
        *self
    }
}

impl<T> Clone for *mut T {
    #[inline]
    fn clone(&self) -> *mut T {
        *self
    }
}

// Equality for extern "C" fn pointers
mod externfnpointers {
    use mem;
    use cmp::PartialEq;

    impl<_R> PartialEq for extern "C" fn() -> _R {
        #[inline]
        fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
            let self_: *const () = unsafe { mem::transmute(*self) };
            let other_: *const () = unsafe { mem::transmute(*other) };
            self_ == other_
        }
    }
    macro_rules! fnptreq(
        ($($p:ident),*) => {
            impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
                #[inline]
                fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
                    let self_: *const () = unsafe { mem::transmute(*self) };

                    let other_: *const () = unsafe { mem::transmute(*other) };
                    self_ == other_
                }
            }
        }
    )
    fnptreq!(A)
    fnptreq!(A,B)
    fnptreq!(A,B,C)
    fnptreq!(A,B,C,D)
    fnptreq!(A,B,C,D,E)
}

// Comparison for pointers
impl<T> Ord for *const T {
    #[inline]
    fn cmp(&self, other: &*const T) -> Ordering {
        if self < other {
            Less
        } else if self == other {
            Equal
        } else {
            Greater
        }
    }
}

impl<T> PartialOrd for *const T {
    #[inline]
    fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
        Some(self.cmp(other))
    }

    #[inline]
    fn lt(&self, other: &*const T) -> bool { *self < *other }

    #[inline]
    fn le(&self, other: &*const T) -> bool { *self <= *other }

    #[inline]
    fn gt(&self, other: &*const T) -> bool { *self > *other }

    #[inline]
    fn ge(&self, other: &*const T) -> bool { *self >= *other }
}

impl<T> Ord for *mut T {
    #[inline]
    fn cmp(&self, other: &*mut T) -> Ordering {
        if self < other {
            Less
        } else if self == other {
            Equal
        } else {
            Greater
        }
    }
}

impl<T> PartialOrd for *mut T {
    #[inline]
    fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
        Some(self.cmp(other))
    }

    #[inline]
    fn lt(&self, other: &*mut T) -> bool { *self < *other }

    #[inline]
    fn le(&self, other: &*mut T) -> bool { *self <= *other }

    #[inline]
    fn gt(&self, other: &*mut T) -> bool { *self > *other }

    #[inline]
    fn ge(&self, other: &*mut T) -> bool { *self >= *other }
}

<|endoftext|>