<commit_before>#[cfg(feature = "curl-easy")]
pub use easy::CurlEasyClient;

#[cfg(feature = "curl-easy")]
mod easy {
    use super::super::{
        Request,
        SetupRequest,
    };
    use curl::easy::{
        Easy,
        List,
        Transfer,
    };
    use http_types::{
        header::HeaderValue,
        Method,
    };

    fn headermap_to_curl_list(headermap: &http_types::HeaderMap<HeaderValue>) -> List {
        let mut list = List::new();
        headermap.iter().for_each(|(k, v)| {
                            // this will scan for printable US-ASCII only bytes
                            let header = v.to_str()
                                          .map(|hval| [k.as_str(), ": ", hval].concat())
                                          .expect("found header value without a displayable US-ASCII string");
                            list.append(header.as_str())
                                .expect("failed to allocate node for curl list of headers");
                        });
        list
    }

    #[derive(Debug)]
    pub enum CurlEasyClient<'easy, 'data> {
        Easy(&'easy Easy),
        Transfer(Transfer<'easy, 'data>),
    }

    impl<'easy, 'data> From<Transfer<'easy, 'data>> for CurlEasyClient<'easy, 'data> {
        fn from(t: Transfer<'easy, 'data>) -> Self {
            Self::Transfer(t)
        }
    }

    impl<'easy> From<&'easy Easy> for CurlEasyClient<'easy, '_> {
        fn from(e: &'easy Easy) -> Self {
            Self::Easy(e)
        }
    }

    impl<'easy, 'data> CurlEasyClient<'easy, 'data> {
        pub fn new(easy: &'easy Easy) -> Self {
            Self::Easy(easy)
        }

        pub fn perform(&self) -> Result<(), curl::Error> {
            match self {
                Self::Easy(e) => e.perform(),
                Self::Transfer(t) => t.perform(),
            }
        }

        pub fn into_transfer(self) -> Option<Transfer<'easy, 'data>> {
            match self {
                Self::Transfer(t) => Some(t),
                Self::Easy(_) => None,
            }
        }

        pub fn easy(&self) -> Option<&'easy Easy> {
            if let Self::Easy(e) = self {
                Some(e)
            } else {
                None
            }
        }
    }

    impl<'easy, 'data, URI: ToString> SetupRequest<'easy, URI, CurlEasyClient<'easy, 'data>> for Easy {
        fn setup_request(&'easy mut self, r: Request, params: URI) -> CurlEasyClient<'easy, 'data> {
            let (uri, body) = r.parameters.uri_and_body(r.path);
            let uri_base = params;
            let uri = uri_base.to_string() + uri.as_ref();

            match r.method {
                Method::GET => self.get(true),
                Method::POST => self.post(true),
                Method::PUT => self.put(true),
                // any other verb needs to use custom_request()
                m => self.custom_request(m.as_str()),
            }.expect("failed to set up the request's method");

            self.url(uri.as_str()).expect("error setting up url for curl");
            let mut headerlist = headermap_to_curl_list(&r.headers);
            // libcurl by default adds "Expect: 100-continue" to send bodies, which would break us
            headerlist.append("Expect:")
                      .expect("failed to allocate node for curl list of headers");
            // don't specify Content-Type for this request (similar to other clients)
            headerlist.append("Content-Type:")
                      .expect("failed to allocate node for curl list of headers");
            self.http_headers(headerlist)
                .expect("error setting up headers for curl");

            match body {
                Some(_) => {
                    use std::io::Read;

                    let body = r.parameters.into_inner();
                    // this sets the Content-Length - some servers will misbehave without this
                    self.post_field_size(body.len() as u64)
                        .expect("failed to set post size");
                    let mut transfer = self.transfer();

                    let mut count = 0usize;
                    transfer.read_function(move |buf| {
                                let mut bytes = &body.as_bytes()[count..];
                                let newcount =
                                    bytes.read(buf).expect("error while copying body data to buffer");
                                count += newcount;
                                Ok(newcount)
                            })
                            .expect("failed to set up read function for curl");

                    transfer.into()
                }
                None => (self as &Easy).into(),
            }
        }
    }
}
<commit_msg>request/curl: extract common fns for curl clients<commit_after>use curl::easy::List;
use http_types::header::HeaderValue;

// Common functions for curl clients
fn headermap_to_curl_list(headermap: &http_types::HeaderMap<HeaderValue>) -> List {
    let mut list = List::new();
    headermap.iter().for_each(|(k, v)| {
                        // this will scan for printable US-ASCII only bytes
                        let header = v.to_str()
                                      .map(|hval| [k.as_str(), ": ", hval].concat())
                                      .expect("found header value without a displayable US-ASCII string");
                        list.append(header.as_str())
                            .expect("failed to allocate node for curl list of headers");
                    });
    list
}

pub fn copy_data(offset: &mut usize, source: &[u8], dst: &mut [u8]) -> usize {
    use std::io::Read;

    let mut bytes = &source[*offset..];
    let newcount = bytes.read(dst).expect("error while copying body data to buffer");
    *offset += newcount;
    newcount
}

#[cfg(feature = "curl-easy")]
pub use easy::CurlEasyClient;

#[cfg(feature = "curl-easy")]
mod easy {
    use super::super::{
        Request,
        SetupRequest,
    };
    use curl::easy::{
        Easy,
        Transfer,
    };
    use http_types::Method;

    #[derive(Debug)]
    pub enum CurlEasyClient<'easy, 'data> {
        Easy(&'easy Easy),
        Transfer(Transfer<'easy, 'data>),
    }

    impl<'easy, 'data> From<Transfer<'easy, 'data>> for CurlEasyClient<'easy, 'data> {
        fn from(t: Transfer<'easy, 'data>) -> Self {
            Self::Transfer(t)
        }
    }

    impl<'easy> From<&'easy Easy> for CurlEasyClient<'easy, '_> {
        fn from(e: &'easy Easy) -> Self {
            Self::Easy(e)
        }
    }

    impl<'easy, 'data> CurlEasyClient<'easy, 'data> {
        pub fn new(easy: &'easy Easy) -> Self {
            Self::Easy(easy)
        }

        pub fn perform(&self) -> Result<(), curl::Error> {
            match self {
                Self::Easy(e) => e.perform(),
                Self::Transfer(t) => t.perform(),
            }
        }

        pub fn into_transfer(self) -> Option<Transfer<'easy, 'data>> {
            match self {
                Self::Transfer(t) => Some(t),
                Self::Easy(_) => None,
            }
        }

        pub fn easy(&self) -> Option<&'easy Easy> {
            if let Self::Easy(e) = self {
                Some(e)
            } else {
                None
            }
        }
    }

    impl<'easy, 'data, URI: ToString> SetupRequest<'easy, URI, CurlEasyClient<'easy, 'data>> for Easy {
        fn setup_request(&'easy mut self, r: Request, params: URI) -> CurlEasyClient<'easy, 'data> {
            let (uri, body) = r.parameters.uri_and_body(r.path);
            let uri_base = params;
            let uri = uri_base.to_string() + uri.as_ref();

            match r.method {
                Method::GET => self.get(true),
                Method::POST => self.post(true),
                Method::PUT => self.put(true),
                // any other verb needs to use custom_request()
                m => self.custom_request(m.as_str()),
            }.expect("failed to set up the request's method");

            self.url(uri.as_str()).expect("error setting up url for curl");
            let mut headerlist = super::headermap_to_curl_list(&r.headers);
            // libcurl by default adds "Expect: 100-continue" to send bodies, which would break us
            headerlist.append("Expect:")
                      .expect("failed to allocate node for curl list of headers");
            // don't specify Content-Type for this request (similar to other clients)
            headerlist.append("Content-Type:")
                      .expect("failed to allocate node for curl list of headers");
            self.http_headers(headerlist)
                .expect("error setting up headers for curl");

            match body {
                Some(_) => {
                    let body = r.parameters.into_inner();
                    // this sets the Content-Length - some servers will misbehave without this
                    self.post_field_size(body.len() as u64)
                        .expect("failed to set post size");
                    let mut transfer = self.transfer();

                    let mut count = 0usize;
                    transfer.read_function(move |buf| {
                                Ok(super::copy_data(&mut count, &body.as_bytes(), buf))
                            })
                            .expect("failed to set up read function for curl");

                    transfer.into()
                }
                None => (self as &Easy).into(),
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::Mode;
use super::KeyMap;
use super::Key;
use super::Command;
use super::KeyMapState;
use super::Direction;
use super::WordEdgeMatch;
use super::OverlayType;

use command;

/// NormalMode mimics Vi's Normal mode.
pub struct NormalMode {
    keymap: KeyMap<Command>,
    builder: command::Builder,
}

impl NormalMode {

    /// Create a new instance of NormalMode
    pub fn new() -> NormalMode {
        NormalMode {
            keymap: NormalMode::key_defaults(),
            builder: command::Builder::new(),
        }
    }

    /// Creates a KeyMap with default NormalMode key bindings
    fn key_defaults() -> KeyMap<Command> {
        let mut keymap = KeyMap::new();

        // movement
        keymap.bind_key(Key::Char('W'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('B'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('w'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('b'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('G'), Command::MoveCursor(Direction::LastLine, 0));
        keymap.bind_keys(&[Key::Char('g'), Key::Char('g')], Command::MoveCursor(Direction::FirstLine, 0));

        // editing
        keymap.bind_keys(&[Key::Char('d'), Key::Char('W')], Command::Delete(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('B')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('w')], Command::Delete(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('b')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('x'), Command::Delete(Direction::Right, 1));
        keymap.bind_key(Key::Char('X'), Command::Delete(Direction::Left, 1));
        keymap.bind_key(Key::Char('u'), Command::Undo);
        keymap.bind_key(Key::Ctrl('r'), Command::Redo);

        keymap
    }

}

impl Mode for NormalMode {
    /// Given a key, pass it through the NormalMode KeyMap and return the associated Command, if any.
    fn handle_key_event(&mut self, key: Key) -> command::BuilderEvent {
        self.builder.check_key(key)
    }
}
<commit_msg>Added undo/redo to normal mode<commit_after>use super::Mode;
use super::KeyMap;
use super::Key;
use super::Command;
use super::KeyMapState;
use super::Direction;
use super::WordEdgeMatch;
use super::OverlayType;

use command;

/// NormalMode mimics Vi's Normal mode.
pub struct NormalMode {
    keymap: KeyMap<Command>,
    builder: command::Builder,
}

impl NormalMode {

    /// Create a new instance of NormalMode
    pub fn new() -> NormalMode {
        NormalMode {
            keymap: NormalMode::key_defaults(),
            builder: command::Builder::new(),
        }
    }

    /// Creates a KeyMap with default NormalMode key bindings
    fn key_defaults() -> KeyMap<Command> {
        let mut keymap = KeyMap::new();

        // movement
        keymap.bind_key(Key::Char('W'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('B'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('w'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('b'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('G'), Command::MoveCursor(Direction::LastLine, 0));
        keymap.bind_keys(&[Key::Char('g'), Key::Char('g')], Command::MoveCursor(Direction::FirstLine, 0));

        // editing
        keymap.bind_keys(&[Key::Char('d'), Key::Char('W')], Command::Delete(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('B')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('w')], Command::Delete(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('b')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('x'), Command::Delete(Direction::Right, 1));
        keymap.bind_key(Key::Char('X'), Command::Delete(Direction::Left, 1));

        keymap.bind_key(Key::Char('u'), Command {
            number: 1,
            action: Action::Operation(Operation::Undo),
            object: None
        });
        keymap.bind_key(Key::Ctrl('r'), Command {
            number: 1,
            action: Action::Operation(Operation::Redo),
            object: None
        });

        keymap
    }

}

impl Mode for NormalMode {
    /// Given a key, pass it through the NormalMode KeyMap and return the associated Command, if any.
    fn handle_key_event(&mut self, key: Key) -> command::BuilderEvent {
        self.builder.check_key(key)
    }
}
<|endoftext|>


<commit_before>// helper for transmutation, shown below.
type RustClosure = (int,int);

struct Condition {
    key: task::local_data::LocalDataKey<Handler>
}

struct Handler {
    // Handler should link to previous handler and
    // reinstall it when popped.
    handle: RustClosure
}

struct ProtectBlock {
    cond: &Condition,
    inner: RustClosure
}

struct PopHandler {
    cond: &Condition,
    drop {
        unsafe {
            task::local_data::local_data_pop(self.cond.key);
        }
    }
}

struct HandleBlock {
    pb: &ProtectBlock,
    handler: @Handler,
    drop {
        unsafe {
            task::local_data::local_data_set(self.pb.cond.key,
                                             self.handler);
            let _pop = PopHandler { cond: self.pb.cond };
            // transmutation to avoid copying non-copyable, should
            // be fixable by tracking closure pointees in regionck.
            let f : &fn() = ::cast::transmute(self.pb.inner);
            f();
        }
    }
}

impl ProtectBlock {
    fn handle<T, U: Copy>(&self, h: &self/fn(&T) ->U) -> HandleBlock/&self {
        unsafe {
            let p : *RustClosure = ::cast::transmute(&h);
            HandleBlock { pb: self,
                          handler: @Handler{handle: *p} }
        }
    }
}

impl Condition {

    fn protect(&self, inner: &self/fn()) -> ProtectBlock/&self {
        unsafe {
            // transmutation to avoid copying non-copyable, should
            // be fixable by tracking closure pointees in regionck.
            let p : *RustClosure = ::cast::transmute(&inner);
            ProtectBlock { cond: self,
                           inner: *p } }
    }

    fn raise<T, U: Copy>(t:&T) -> U {
        unsafe {
            match task::local_data::local_data_get(self.key) {
                None => fail,
                Some(handler) => {
                    io::println("got handler");
                    let f : &fn(&T) -> U = ::cast::transmute(handler.handle);
                    f(t)
                }
            }
        }
    }
}

#[test]
fn happiness_key(_x: @Handler) { }

#[test]
fn sadness_key(_x: @Handler) { }

#[test]
fn trouble(i: int) {
    // Condition should work as a const, just limitations in consts.
    let sadness_condition : Condition = Condition { key: sadness_key };
    io::println("raising");
    let j = sadness_condition.raise(&i);
    io::println(fmt!("handler recovered with %d", j));
}

#[test]
fn test() {

    let sadness_condition : Condition = Condition { key: sadness_key };

    let mut i = 10;

    let b = do sadness_condition.protect {
        io::println("in protected block");
        trouble(1);
        trouble(2);
        trouble(3);
    };

    do b.handle |j| {
        i += *j;
        i
    };

    assert i == 16;
}<commit_msg>core: add previous-handler save and restore for proper nesting.<commit_after>// helper for transmutation, shown below.
type RustClosure = (int,int);

struct Condition {
    key: task::local_data::LocalDataKey<Handler>
}

struct Handler {
    handle: RustClosure,
    prev: Option<@Handler>
}

struct ProtectBlock {
    cond: &Condition,
    inner: RustClosure
}

struct PopHandler {
    cond: &Condition,
    drop {
        unsafe {
            debug!("PopHandler: popping handler from TLS");
            match task::local_data::local_data_pop(self.cond.key) {
                None => (),
                Some(h) => {
                    match h.prev {
                        None => (),
                        Some(p) =>
                        task::local_data::local_data_set(self.cond.key, p)
                    }
                }
            }
        }
    }
}

struct HandleBlock {
    pb: &ProtectBlock,
    handler: @Handler,
    drop {
        unsafe {
            debug!("HandleBlock: pushing handler to TLS");
            task::local_data::local_data_set(self.pb.cond.key,
                                             self.handler);
            let _pop = PopHandler { cond: self.pb.cond };
            // transmutation to avoid copying non-copyable, should
            // be fixable by tracking closure pointees in regionck.
            let f : &fn() = ::cast::transmute(self.pb.inner);
            debug!("HandleBlock: invoking protected code");
            f();
            debug!("HandleBlock: returned from protected code");
        }
    }
}

impl ProtectBlock {
    fn handle<T, U: Copy>(&self, h: &self/fn(&T) ->U) -> HandleBlock/&self {
        unsafe {
            debug!("ProtectBlock.handle: setting up handler block");
            let p : *RustClosure = ::cast::transmute(&h);
            let prev = task::local_data::local_data_get(self.cond.key);
            HandleBlock { pb: self,
                          handler: @Handler{handle: *p, prev: prev} }
        }
    }
}

impl Condition {

    fn protect(&self, inner: &self/fn()) -> ProtectBlock/&self {
        unsafe {
            // transmutation to avoid copying non-copyable, should
            // be fixable by tracking closure pointees in regionck.
            debug!("Condition.protect: setting up protected block");
            let p : *RustClosure = ::cast::transmute(&inner);
            ProtectBlock { cond: self,
                           inner: *p }
        }
    }

    fn raise<T, U: Copy>(t:&T) -> U {
        unsafe {
            match task::local_data::local_data_get(self.key) {
                None => {
                    debug!("Condition.raise: found no handler");
                    fail
                }

                Some(handler) => {
                    debug!("Condition.raise: found handler");
                    let f : &fn(&T) -> U = ::cast::transmute(handler.handle);
                    f(t)
                }
            }
        }
    }
}

#[cfg(test)]
fn happiness_key(_x: @Handler) { }

#[cfg(test)]
fn sadness_key(_x: @Handler) { }

#[cfg(test)]
fn trouble(i: int) {
    // Condition should work as a const, just limitations in consts.
    let sadness_condition : Condition = Condition { key: sadness_key };
    debug!("trouble: raising conition");
    let j = sadness_condition.raise(&i);
    debug!("trouble: handler recovered with %d", j);
}

#[test]
fn test1() {

    let sadness_condition : Condition = Condition { key: sadness_key };

    let mut i = 10;

    let b = do sadness_condition.protect {
        debug!("test1: in protected block");
        trouble(1);
        trouble(2);
        trouble(3);
    };

    do b.handle |j| {
        debug!("test1: in handler");
        i += *j;
        i
    };

    assert i == 16;
}
#[cfg(test)]
fn nested_test_inner() {
    let sadness_condition : Condition = Condition { key: sadness_key };

    let mut inner_trapped = false;

    let b = do sadness_condition.protect {
        debug!("nested_test_inner: in protected block");
        trouble(1);
    };

    do b.handle |_j:&int| {
        debug!("nested_test_inner: in handler");
        inner_trapped = true;
        0
    };

    assert inner_trapped;
}

#[test]
fn nested_test_outer() {

    let sadness_condition : Condition = Condition { key: sadness_key };

    let mut outer_trapped = false;

    let b = do sadness_condition.protect {
        debug!("nested_test_outer: in protected block");
        nested_test_inner();
        trouble(1);
    };

    do b.handle |_j:&int| {
        debug!("nested_test_outer: in handler");
        outer_trapped = true;
        0
    };

    assert outer_trapped;
}
<|endoftext|>


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

use std::fmt;

/// CrateIds identify crates and include the crate name and optionally a path
/// and version. In the full form, they look like relative URLs. Example:
/// `github.com/mozilla/rust#std:1.0` would be a package ID with a path of
/// `gitub.com/mozilla/rust` and a crate name of `std` with a version of
/// `1.0`. If no crate name is given after the hash, the name is inferred to
/// be the last component of the path. If no version is given, it is inferred
/// to be `0.0`.

use std::from_str::FromStr;

#[deriving(Clone, PartialEq)]
pub struct CrateId {
    /// A path which represents the codes origin. By convention this is the
    /// URL, without `http://` or `https://` prefix, to the crate's repository
    pub path: String,
    /// The name of the crate.
    pub name: String,
    /// The version of the crate.
    pub version: Option<String>,
}

impl fmt::Show for CrateId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "{}", self.path));
        let version = match self.version {
            None => "0.0",
            Some(ref version) => version.as_slice(),
        };
        if self.path == self.name ||
                self.path
                    .as_slice()
                    .ends_with(format!("/{}", self.name).as_slice()) {
            write!(f, "\\#{}", version)
        } else {
            write!(f, "\\#{}:{}", self.name, version)
        }
    }
}

impl FromStr for CrateId {
    fn from_str(s: &str) -> Option<CrateId> {
        let pieces: Vec<&str> = s.splitn('#', 1).collect();
        let path = pieces.get(0).to_string();

        if path.as_slice().starts_with("/") || path.as_slice().ends_with("/") ||
            path.as_slice().starts_with(".") || path.is_empty() {
            return None;
        }

        let path_pieces: Vec<&str> = path.as_slice()
                                         .rsplitn('/', 1)
                                         .collect();
        let inferred_name = *path_pieces.get(0);

        let (name, version) = if pieces.len() == 1 {
            (inferred_name.to_string(), None)
        } else {
            let hash_pieces: Vec<&str> = pieces.get(1)
                                               .splitn(':', 1)
                                               .collect();
            let (hash_name, hash_version) = if hash_pieces.len() == 1 {
                ("", *hash_pieces.get(0))
            } else {
                (*hash_pieces.get(0), *hash_pieces.get(1))
            };

            let name = if !hash_name.is_empty() {
                hash_name.to_string()
            } else {
                inferred_name.to_string()
            };

            let version = if !hash_version.is_empty() {
                if hash_version == "0.0" {
                    None
                } else {
                    Some(hash_version.to_string())
                }
            } else {
                None
            };

            (name, version)
        };

        Some(CrateId {
            path: path.to_string(),
            name: name,
            version: version,
        })
    }
}

impl CrateId {
    pub fn version_or_default<'a>(&'a self) -> &'a str {
        match self.version {
            None => "0.0",
            Some(ref version) => version.as_slice(),
        }
    }

    pub fn short_name_with_version(&self) -> String {
        (format!("{}-{}", self.name, self.version_or_default())).to_string()
    }

    pub fn matches(&self, other: &CrateId) -> bool {
        // FIXME: why does this not match on `path`?
        if self.name != other.name { return false }
        match (&self.version, &other.version) {
            (&Some(ref v1), &Some(ref v2)) => v1 == v2,
            _ => true,
        }
    }
}

#[test]
fn bare_name() {
    let crateid: CrateId = from_str("foo").expect("valid crateid");
    assert_eq!(crateid.name, "foo".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "foo".to_string());
}

#[test]
fn bare_name_single_char() {
    let crateid: CrateId = from_str("f").expect("valid crateid");
    assert_eq!(crateid.name, "f".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "f".to_string());
}

#[test]
fn empty_crateid() {
    let crateid: Option<CrateId> = from_str("");
    assert!(crateid.is_none());
}

#[test]
fn simple_path() {
    let crateid: CrateId = from_str("example.com/foo/bar").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "example.com/foo/bar".to_string());
}

#[test]
fn simple_version() {
    let crateid: CrateId = from_str("foo#1.0").expect("valid crateid");
    assert_eq!(crateid.name, "foo".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "foo".to_string());
}

#[test]
fn absolute_path() {
    let crateid: Option<CrateId> = from_str("/foo/bar");
    assert!(crateid.is_none());
}

#[test]
fn path_ends_with_slash() {
    let crateid: Option<CrateId> = from_str("foo/bar/");
    assert!(crateid.is_none());
}

#[test]
fn path_and_version() {
    let crateid: CrateId = from_str("example.com/foo/bar#1.0").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "example.com/foo/bar".to_string());
}

#[test]
fn single_chars() {
    let crateid: CrateId = from_str("a/b#1").expect("valid crateid");
    assert_eq!(crateid.name, "b".to_string());
    assert_eq!(crateid.version, Some("1".to_string()));
    assert_eq!(crateid.path, "a/b".to_string());
}

#[test]
fn missing_version() {
    let crateid: CrateId = from_str("foo#").expect("valid crateid");
    assert_eq!(crateid.name, "foo".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "foo".to_string());
}

#[test]
fn path_and_name() {
    let crateid: CrateId = from_str("foo/rust-bar#bar:1.0").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "foo/rust-bar".to_string());
}

#[test]
fn empty_name() {
    let crateid: CrateId = from_str("foo/bar#:1.0").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "foo/bar".to_string());
}
<commit_msg>Fix typo "gihub" in libsyntax/crateid.<commit_after>// Copyright 2013-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.

use std::fmt;

/// CrateIds identify crates and include the crate name and optionally a path
/// and version. In the full form, they look like relative URLs. Example:
/// `github.com/mozilla/rust#std:1.0` would be a package ID with a path of
/// `github.com/mozilla/rust` and a crate name of `std` with a version of
/// `1.0`. If no crate name is given after the hash, the name is inferred to
/// be the last component of the path. If no version is given, it is inferred
/// to be `0.0`.

use std::from_str::FromStr;

#[deriving(Clone, PartialEq)]
pub struct CrateId {
    /// A path which represents the codes origin. By convention this is the
    /// URL, without `http://` or `https://` prefix, to the crate's repository
    pub path: String,
    /// The name of the crate.
    pub name: String,
    /// The version of the crate.
    pub version: Option<String>,
}

impl fmt::Show for CrateId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "{}", self.path));
        let version = match self.version {
            None => "0.0",
            Some(ref version) => version.as_slice(),
        };
        if self.path == self.name ||
                self.path
                    .as_slice()
                    .ends_with(format!("/{}", self.name).as_slice()) {
            write!(f, "\\#{}", version)
        } else {
            write!(f, "\\#{}:{}", self.name, version)
        }
    }
}

impl FromStr for CrateId {
    fn from_str(s: &str) -> Option<CrateId> {
        let pieces: Vec<&str> = s.splitn('#', 1).collect();
        let path = pieces.get(0).to_string();

        if path.as_slice().starts_with("/") || path.as_slice().ends_with("/") ||
            path.as_slice().starts_with(".") || path.is_empty() {
            return None;
        }

        let path_pieces: Vec<&str> = path.as_slice()
                                         .rsplitn('/', 1)
                                         .collect();
        let inferred_name = *path_pieces.get(0);

        let (name, version) = if pieces.len() == 1 {
            (inferred_name.to_string(), None)
        } else {
            let hash_pieces: Vec<&str> = pieces.get(1)
                                               .splitn(':', 1)
                                               .collect();
            let (hash_name, hash_version) = if hash_pieces.len() == 1 {
                ("", *hash_pieces.get(0))
            } else {
                (*hash_pieces.get(0), *hash_pieces.get(1))
            };

            let name = if !hash_name.is_empty() {
                hash_name.to_string()
            } else {
                inferred_name.to_string()
            };

            let version = if !hash_version.is_empty() {
                if hash_version == "0.0" {
                    None
                } else {
                    Some(hash_version.to_string())
                }
            } else {
                None
            };

            (name, version)
        };

        Some(CrateId {
            path: path.to_string(),
            name: name,
            version: version,
        })
    }
}

impl CrateId {
    pub fn version_or_default<'a>(&'a self) -> &'a str {
        match self.version {
            None => "0.0",
            Some(ref version) => version.as_slice(),
        }
    }

    pub fn short_name_with_version(&self) -> String {
        (format!("{}-{}", self.name, self.version_or_default())).to_string()
    }

    pub fn matches(&self, other: &CrateId) -> bool {
        // FIXME: why does this not match on `path`?
        if self.name != other.name { return false }
        match (&self.version, &other.version) {
            (&Some(ref v1), &Some(ref v2)) => v1 == v2,
            _ => true,
        }
    }
}

#[test]
fn bare_name() {
    let crateid: CrateId = from_str("foo").expect("valid crateid");
    assert_eq!(crateid.name, "foo".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "foo".to_string());
}

#[test]
fn bare_name_single_char() {
    let crateid: CrateId = from_str("f").expect("valid crateid");
    assert_eq!(crateid.name, "f".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "f".to_string());
}

#[test]
fn empty_crateid() {
    let crateid: Option<CrateId> = from_str("");
    assert!(crateid.is_none());
}

#[test]
fn simple_path() {
    let crateid: CrateId = from_str("example.com/foo/bar").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "example.com/foo/bar".to_string());
}

#[test]
fn simple_version() {
    let crateid: CrateId = from_str("foo#1.0").expect("valid crateid");
    assert_eq!(crateid.name, "foo".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "foo".to_string());
}

#[test]
fn absolute_path() {
    let crateid: Option<CrateId> = from_str("/foo/bar");
    assert!(crateid.is_none());
}

#[test]
fn path_ends_with_slash() {
    let crateid: Option<CrateId> = from_str("foo/bar/");
    assert!(crateid.is_none());
}

#[test]
fn path_and_version() {
    let crateid: CrateId = from_str("example.com/foo/bar#1.0").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "example.com/foo/bar".to_string());
}

#[test]
fn single_chars() {
    let crateid: CrateId = from_str("a/b#1").expect("valid crateid");
    assert_eq!(crateid.name, "b".to_string());
    assert_eq!(crateid.version, Some("1".to_string()));
    assert_eq!(crateid.path, "a/b".to_string());
}

#[test]
fn missing_version() {
    let crateid: CrateId = from_str("foo#").expect("valid crateid");
    assert_eq!(crateid.name, "foo".to_string());
    assert_eq!(crateid.version, None);
    assert_eq!(crateid.path, "foo".to_string());
}

#[test]
fn path_and_name() {
    let crateid: CrateId = from_str("foo/rust-bar#bar:1.0").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "foo/rust-bar".to_string());
}

#[test]
fn empty_name() {
    let crateid: CrateId = from_str("foo/bar#:1.0").expect("valid crateid");
    assert_eq!(crateid.name, "bar".to_string());
    assert_eq!(crateid.version, Some("1.0".to_string()));
    assert_eq!(crateid.path, "foo/bar".to_string());
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
use std::io;
use std::convert::AsRef;
use super::imagemagick_commands;
use super::op_types::{ImageMagickOpType};
use image_tools::image_ops::{ElementaryPageOperations, Pixels, Direction};
use image_tools::image_ops::ImageResolution;
use image_tools::image_ops::RunOperation;
use image_tools::image_ops::OperationResults;
use image_tools::image_ops::{FileName, FilePath};
use std::string::{String};

type ImageMagickArg = String;

#[derive(Clone, Debug)]
struct ImageMagickArgs {
    file_path: FilePath,
    file_name: FileName,
    img_args:  Vec<ImageMagickArg>,
}

impl ImageMagickArgs {
    fn new(file_path: FilePath, file_name: FileName, img_args: &Vec<ImageMagickArg>) -> ImageMagickArgs {
        ImageMagickArgs {
            file_path: file_path,
            file_name: file_name,
            img_args:  img_args.clone(),
        }
    }
}

#[derive(Clone, Debug)]
pub struct ElementaryImageMagickOperation {
    op:   ImageMagickOpType,
    args: ImageMagickArgs,
}

impl ElementaryImageMagickOperation {
    fn new(op: ImageMagickOpType, args: ImageMagickArgs) -> ElementaryImageMagickOperation {
        ElementaryImageMagickOperation {
            op:   op,
            args: args,
        }
    }

    fn arg(&mut self, arg: ImageMagickArg) {
        self.args.img_args.push(arg);
    }

    fn args(&mut self, args: &[ImageMagickArg]) {
        for arg in args {
            self.args.img_args.push(arg.clone());
        }
    }

    fn run_operation(&self) -> io::Result<String> {
        match self.op {
            ImageMagickOpType::Identify        => {
                imagemagick_commands::imagemagick_identify_default(&self.args.file_path)
            }
            ImageMagickOpType::IdentifyVerbose => {
                imagemagick_commands::imagemagick_identify_verbose(&self.args.file_path)
            }
            ImageMagickOpType::Convert         => {
                imagemagick_commands::imagemagick_convert(&self.args.file_path, &self.args.img_args)
            }
            ImageMagickOpType::Mogrify         => {
                imagemagick_commands::imagemagick_mogrify(&self.args.file_path, &self.args.img_args)
            }
            ImageMagickOpType::NoOperation     => {
                imagemagick_commands::imagemagick_no_operation()
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct ImageMagickOperation {
    ops: Vec<ElementaryImageMagickOperation>,
}

impl ImageMagickOperation {
    fn new() -> ImageMagickOperation {
        ImageMagickOperation {
            ops: Vec::new(),
        }
    }

    fn add_op(&mut self, op: ElementaryImageMagickOperation)  {
        self.ops.push(op);
    }

    fn add_ops(&mut self, ops: &[ElementaryImageMagickOperation]) {
        for op in ops.iter() {
            self.ops.push(op.clone());
        }
    }

}

// This implementation will be the generator for the sequence of
// ImageMagick commands for each operation.
impl ElementaryPageOperations for ImageMagickOperation {

    fn identify(file_name: FileName, file_path: FilePath) -> ImageMagickOperation {
        // Identify presesntly generates an identify command without the -verbose flag.
        // This may change in the future where we use verbose as the default.
        let args = ImageMagickArgs::new(file_name, file_path, &Vec::new());
        let elem_op = ElementaryImageMagickOperation::new(ImageMagickOpType::Identify, args);
        let mut op = ImageMagickOperation::new();
        op.add_op(elem_op);

        op

    }

    fn rescale(amount: Pixels, dir: Direction) -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_left_edge(amount: Pixels)        -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_right_edge(amount: Pixels)       -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_top_edge(amount: Pixels)         -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_bottom_edge(amount: Pixels)      -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_left_edge(amount: Pixels)          -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_right_edge(amount: Pixels)         -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_top_edge(amount: Pixels)           -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_bottom_edge(amount: Pixels)        -> ImageMagickOperation {
        unimplemented!();
    }

    fn set_resolution(res: ImageResolution)    -> ImageMagickOperation {
        unimplemented!();
    }

    fn no_operation()                          -> ImageMagickOperation {
        let mut op = ImageMagickOperation::new();
        let args = ImageMagickArgs::new(String::from(""), String::from(""), &Vec::new());
        let elem_op = ElementaryImageMagickOperation::new(ImageMagickOpType::NoOperation, args);
        op.add_op(elem_op);

        op
    }
}

impl AsRef<[ElementaryImageMagickOperation]> for ImageMagickOperation {
    fn as_ref(&self) -> &[ElementaryImageMagickOperation] {
        self.ops.as_ref()
    }
}

impl RunOperation for ImageMagickOperation {
    fn run_operation(op: ImageMagickOperation) -> OperationResults {
        let mut results = OperationResults::new();

        for action in op.ops {
            let mut result = Vec::new();
            result.push(action.run_operation());
            results.append(&mut OperationResults::from(&mut result));
        }

        results
    }
}

<commit_msg>Cleanup.<commit_after>#![allow(dead_code)]
use super::imagemagick_commands;
use super::op_types::{ImageMagickOpType};
use image_tools::image_ops::{ElementaryPageOperations, Pixels, Direction};
use image_tools::image_ops::ImageResolution;
use image_tools::image_ops::RunOperation;
use image_tools::image_ops::OperationResults;
use image_tools::image_ops::{FileName, FilePath};
use std::string::{String};
use std::io;
use std::convert::AsRef;

type ImageMagickArg = String;

#[derive(Clone, Debug)]
struct ImageMagickArgs {
    file_path: FilePath,
    file_name: FileName,
    img_args:  Vec<ImageMagickArg>,
}

impl ImageMagickArgs {
    fn new(file_path: FilePath, file_name: FileName, img_args: &Vec<ImageMagickArg>) -> ImageMagickArgs {
        ImageMagickArgs {
            file_path: file_path,
            file_name: file_name,
            img_args:  img_args.clone(),
        }
    }
}

#[derive(Clone, Debug)]
pub struct ElementaryImageMagickOperation {
    op:   ImageMagickOpType,
    args: ImageMagickArgs,
}

impl ElementaryImageMagickOperation {
    fn new(op: ImageMagickOpType, args: ImageMagickArgs) -> ElementaryImageMagickOperation {
        ElementaryImageMagickOperation {
            op:   op,
            args: args,
        }
    }

    fn arg(&mut self, arg: ImageMagickArg) {
        self.args.img_args.push(arg);
    }

    fn args(&mut self, args: &[ImageMagickArg]) {
        for arg in args {
            self.args.img_args.push(arg.clone());
        }
    }

    fn run_operation(&self) -> io::Result<String> {
        match self.op {
            ImageMagickOpType::Identify        => {
                imagemagick_commands::imagemagick_identify_default(&self.args.file_path)
            }
            ImageMagickOpType::IdentifyVerbose => {
                imagemagick_commands::imagemagick_identify_verbose(&self.args.file_path)
            }
            ImageMagickOpType::Convert         => {
                imagemagick_commands::imagemagick_convert(&self.args.file_path, &self.args.img_args)
            }
            ImageMagickOpType::Mogrify         => {
                imagemagick_commands::imagemagick_mogrify(&self.args.file_path, &self.args.img_args)
            }
            ImageMagickOpType::NoOperation     => {
                imagemagick_commands::imagemagick_no_operation()
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct ImageMagickOperation {
    ops: Vec<ElementaryImageMagickOperation>,
}

impl ImageMagickOperation {
    fn new() -> ImageMagickOperation {
        ImageMagickOperation {
            ops: Vec::new(),
        }
    }

    fn add_op(&mut self, op: ElementaryImageMagickOperation)  {
        self.ops.push(op);
    }

    fn add_ops(&mut self, ops: &[ElementaryImageMagickOperation]) {
        for op in ops.iter() {
            self.ops.push(op.clone());
        }
    }

}

// This implementation will be the generator for the sequence of
// ImageMagick commands for each operation.
impl ElementaryPageOperations for ImageMagickOperation {

    fn identify(file_name: FileName, file_path: FilePath) -> ImageMagickOperation {
        // Identify presesntly generates an identify command without the -verbose flag.
        // This may change in the future where we use verbose as the default.
        let args = ImageMagickArgs::new(file_name, file_path, &Vec::new());
        let elem_op = ElementaryImageMagickOperation::new(ImageMagickOpType::Identify, args);
        let mut op = ImageMagickOperation::new();
        op.add_op(elem_op);

        op

    }

    fn rescale(amount: Pixels, dir: Direction) -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_left_edge(amount: Pixels)        -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_right_edge(amount: Pixels)       -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_top_edge(amount: Pixels)         -> ImageMagickOperation {
        unimplemented!();
    }

    fn expand_bottom_edge(amount: Pixels)      -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_left_edge(amount: Pixels)          -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_right_edge(amount: Pixels)         -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_top_edge(amount: Pixels)           -> ImageMagickOperation {
        unimplemented!();
    }

    fn trim_bottom_edge(amount: Pixels)        -> ImageMagickOperation {
        unimplemented!();
    }

    fn set_resolution(res: ImageResolution)    -> ImageMagickOperation {
        unimplemented!();
    }

    fn no_operation()                          -> ImageMagickOperation {
        let mut op = ImageMagickOperation::new();
        let args = ImageMagickArgs::new(String::from(""), String::from(""), &Vec::new());
        let elem_op = ElementaryImageMagickOperation::new(ImageMagickOpType::NoOperation, args);
        op.add_op(elem_op);

        op
    }
}

impl AsRef<[ElementaryImageMagickOperation]> for ImageMagickOperation {
    fn as_ref(&self) -> &[ElementaryImageMagickOperation] {
        self.ops.as_ref()
    }
}

impl RunOperation for ImageMagickOperation {
    fn run_operation(op: ImageMagickOperation) -> OperationResults {
        let mut results = OperationResults::new();

        for action in op.ops {
            let mut result = Vec::new();
            result.push(action.run_operation());
            results.append(&mut OperationResults::from(&mut result));
        }

        results
    }
}

<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::string;

use serde::de::{self, DeserializeSeed, Visitor, SeqAccess, MapAccess};

use super::MaxMindDBError;
use super::MaxMindDBError::DecodingError;

pub type DbArray = Vec<DataRecord>;
pub type DbMap = BTreeMap<string::String, DataRecord>;

#[derive(Clone, Debug, PartialEq)]
pub enum DataRecord {
    String(string::String),
    Double(f64),
    Byte(u8),
    Uint16(u16),
    Uint32(u32),
    Map(Box<DbMap>),
    Int32(i32),
    Uint64(u64),
    Boolean(bool),
    Array(DbArray),
    Float(f32),
    Null,
}

use self::DataRecord::{Array, Boolean, Byte, Double, Float, Int32, Map, Null, String, Uint16,
                       Uint32, Uint64};

macro_rules! expect(
    ($e:expr, $t:ident) => ({
        match $e {
            $t(v) => Ok(v),
            other => Err(DecodingError(format!("Error decoding {:?} as {:?}",
                         other, stringify!($t))))
        }
    })
);

#[derive(Debug)]
pub struct Decoder {
    stack: Vec<DataRecord>,
}

impl Decoder {
    /// Creates a new decoder instance for decoding the specified JSON value.
    pub fn new(record: DataRecord) -> Decoder {
        Decoder { stack: vec![record] }
    }
}

impl Decoder {
    fn pop(&mut self) -> DataRecord {
        self.stack.pop().unwrap()
    }

    fn peek(&self) -> Option<&DataRecord> {
        self.stack.get(self.stack.len() - 1)
    }
}

pub type DecodeResult<T> = Result<T, MaxMindDBError>;

// Much of this code was borrowed from the Rust JSON library, Serde Deserializer example
impl<'de, 'a> de::Deserializer<'de> for &'a mut Decoder {
    type Error = MaxMindDBError;

    fn deserialize_any<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("deserialize_any");
        match self.peek() {
            Some(&String(_)) => self.deserialize_str(visitor),
            Some(&Double(_)) => self.deserialize_f64(visitor),
            Some(&Byte(_)) => self.deserialize_u8(visitor),
            Some(&Uint16(_)) => self.deserialize_u16(visitor),
            Some(&Uint32(_)) => self.deserialize_u32(visitor),
            Some(&Map(_)) => self.deserialize_map(visitor),
            Some(&Int32(_)) => self.deserialize_i32(visitor),
            Some(&Uint64(_)) => self.deserialize_u64(visitor),
            Some(&Boolean(_)) => self.deserialize_bool(visitor),
            Some(&Array(_)) => self.deserialize_seq(visitor),
            Some(&Float(_)) => self.deserialize_f32(visitor),
            Some(&Null) => self.deserialize_unit(visitor),
            None => Err(DecodingError("nothing left to deserialize".to_owned())),
        }
    }

    // Like `deserialize_any` but indicates to the `Deserializer` that it makes
    // no difference which `Visitor` method is called because the data is
    // ignored.
    //
    // Some deserializers are able to implement this more efficiently than
    // `deserialize_any`, for example by rapidly skipping over matched
    // delimiters without paying close attention to the data in between.
    //
    // Some formats are not able to implement this at all. Formats that can
    // implement `deserialize_any` and `deserialize_ignored_any` are known as
    // self-describing.
    fn deserialize_ignored_any<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_any(visitor)
    }

    fn deserialize_u64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u64");
        visitor.visit_u64(expect!(self.pop(), Uint64)?)
    }

    fn deserialize_u32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u32");
        visitor.visit_u32(expect!(self.pop(), Uint32)?)
    }

    fn deserialize_u16<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u16");
        visitor.visit_u16(expect!(self.pop(), Uint16)?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u8");
        visitor.visit_u8(expect!(self.pop(), Byte)?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i64");
        self.deserialize_i32(visitor)
    }

    fn deserialize_i32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i32");
        visitor.visit_i32(expect!(self.pop(), Int32)?)
    }

    fn deserialize_i16<V>(self, _visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        unimplemented!()
    }

    fn deserialize_i8<V>(self, _visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        unimplemented!()
    }

    fn deserialize_bool<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_bool");
        visitor.visit_bool(expect!(self.pop(), Boolean)?)
    }

    fn deserialize_f64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f64");
        visitor.visit_f64(expect!(self.pop(), Double)?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f32");
        visitor.visit_f32(expect!(self.pop(), Float)?)
    }

    fn deserialize_char<V>(self, _visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        unimplemented!()
    }

    fn deserialize_str<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        let string = expect!(self.pop(), String)?;
        debug!("read_str: {}", string);
        visitor.visit_str(&string)
    }

    fn deserialize_string<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_string");
        self.deserialize_str(visitor)
    }

    fn deserialize_bytes<V>(self, _visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        unimplemented!()
    }

    fn deserialize_byte_buf<V>(self, _visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        unimplemented!()
    }

    fn deserialize_enum<V>(
        self,
        _name: &'static str,
        _variants: &'static [&'static str],
        _visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        unimplemented!()
    }

    // Structs look just like maps in JSON.
    //
    // Notice the `fields` parameter - a "struct" in the Serde data model means
    // that the `Deserialize` implementation is required to know what the fields
    // are before even looking at the input data. Any key-value pairing in which
    // the fields cannot be known ahead of time is probably a map.
    fn deserialize_struct<V>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    // Tuples look just like sequences in JSON. Some formats may be able to
    // represent tuples more efficiently.
    //
    // As indicated by the length parameter, the `Deserialize` implementation
    // for a tuple in the Serde data model is required to know the length of the
    // tuple before even looking at the input data.
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    // Tuple structs look just like sequences in JSON.
    fn deserialize_tuple_struct<V>(
        self,
        _name: &'static str,
        _len: usize,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    fn deserialize_option<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_option()");
        match self.pop() {
            Null => visitor.visit_none(),
            value => {
                self.stack.push(value);
                visitor.visit_some(self)
            }
        }
    }

    // In Serde, unit means an anonymous value containing no data.
    fn deserialize_unit<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_nil");
        match self.pop() {
            Null => visitor.visit_unit(),
            other => Err(DecodingError(format!("Error decoding Null as {:?}", other))),
        }
    }

    // Unit struct means a named value containing no data.
    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_unit(visitor)
    }

    // As is done here, serializers are encouraged to treat newtype structs as
    // insignificant wrappers around the data they contain. That means not
    // parsing anything other than the contained value.
    fn deserialize_newtype_struct<V>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    // An identifier in Serde is the type that identifies a field of a struct or
    // the variant of an enum.
    fn deserialize_identifier<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_str(visitor)
    }

    fn deserialize_seq<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_seq()");
        let list = expect!(self.pop(), Array)?;
        let len = list.len();

        for v in list.into_iter().rev() {
            self.stack.push(v);
        }

        let value = visitor.visit_seq(ArrayAccess::new(&mut self, len))?;
        Ok(value)
    }

    // Much like `deserialize_seq` but calls the visitors `visit_map` method
    // with a `MapAccess` implementation, rather than the visitor's `visit_seq`
    // method with a `SeqAccess` implementation.
    fn deserialize_map<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_map()");
        let obj = expect!(self.pop(), Map)?;
        let len = obj.len();
        for (key, value) in obj.into_iter() {
            self.stack.push(value);
            self.stack.push(String(key));
        }

        let value = visitor.visit_map(MapAccessor::new(&mut self, len * 2))?;
        Ok(value)
    }
}

struct ArrayAccess<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> ArrayAccess<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        ArrayAccess {
            de: de,
            count: count,
        }
    }
}

// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
// through elements of the sequence.
impl<'de, 'a> SeqAccess<'de> for ArrayAccess<'a> {
    type Error = MaxMindDBError;

    fn next_element_seed<T>(&mut self, seed: T) -> DecodeResult<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        // Check if there are no more elements.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize an array element.
        seed.deserialize(&mut *self.de).map(Some)
    }
}

struct MapAccessor<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> MapAccessor<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        MapAccessor {
            de: de,
            count: count,
        }
    }
}

// `MapAccess` is provided to the `Visitor` to give it the ability to iterate
// through entries of the map.
impl<'de, 'a> MapAccess<'de> for MapAccessor<'a> {
    type Error = MaxMindDBError;

    fn next_key_seed<K>(&mut self, seed: K) -> DecodeResult<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize a map key.
        seed.deserialize(&mut *self.de).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> DecodeResult<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Err(DecodingError("no more entries".to_owned()));
        }
        self.count -= 1;

        // Deserialize a map value.
        seed.deserialize(&mut *self.de)
    }
}
<commit_msg>Forward more methods to deserialize_any<commit_after>use std::collections::BTreeMap;
use std::string;

use serde::de::{self, DeserializeSeed, Visitor, SeqAccess, MapAccess};

use super::MaxMindDBError;
use super::MaxMindDBError::DecodingError;

pub type DbArray = Vec<DataRecord>;
pub type DbMap = BTreeMap<string::String, DataRecord>;

#[derive(Clone, Debug, PartialEq)]
pub enum DataRecord {
    String(string::String),
    Double(f64),
    Byte(u8),
    Uint16(u16),
    Uint32(u32),
    Map(Box<DbMap>),
    Int32(i32),
    Uint64(u64),
    Boolean(bool),
    Array(DbArray),
    Float(f32),
    Null,
}

use self::DataRecord::{Array, Boolean, Byte, Double, Float, Int32, Map, Null, String, Uint16,
                       Uint32, Uint64};

macro_rules! expect(
    ($e:expr, $t:ident) => ({
        match $e {
            $t(v) => Ok(v),
            other => Err(DecodingError(format!("Error decoding {:?} as {:?}",
                         other, stringify!($t))))
        }
    })
);

#[derive(Debug)]
pub struct Decoder {
    stack: Vec<DataRecord>,
}

impl Decoder {
    /// Creates a new decoder instance for decoding the specified JSON value.
    pub fn new(record: DataRecord) -> Decoder {
        Decoder { stack: vec![record] }
    }
}

impl Decoder {
    fn pop(&mut self) -> DataRecord {
        self.stack.pop().unwrap()
    }

    fn peek(&self) -> Option<&DataRecord> {
        self.stack.get(self.stack.len() - 1)
    }
}

pub type DecodeResult<T> = Result<T, MaxMindDBError>;

// Much of this code was borrowed from the Rust JSON library, Serde Deserializer example
impl<'de, 'a> de::Deserializer<'de> for &'a mut Decoder {
    type Error = MaxMindDBError;

    #[inline]
    fn deserialize_any<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("deserialize_any");
        match self.peek() {
            Some(&String(_)) => self.deserialize_str(visitor),
            Some(&Double(_)) => self.deserialize_f64(visitor),
            Some(&Byte(_)) => self.deserialize_u8(visitor),
            Some(&Uint16(_)) => self.deserialize_u16(visitor),
            Some(&Uint32(_)) => self.deserialize_u32(visitor),
            Some(&Map(_)) => self.deserialize_map(visitor),
            Some(&Int32(_)) => self.deserialize_i32(visitor),
            Some(&Uint64(_)) => self.deserialize_u64(visitor),
            Some(&Boolean(_)) => self.deserialize_bool(visitor),
            Some(&Array(_)) => self.deserialize_seq(visitor),
            Some(&Float(_)) => self.deserialize_f32(visitor),
            Some(&Null) => self.deserialize_unit(visitor),
            None => Err(DecodingError("nothing left to deserialize".to_owned())),
        }
    }

    fn deserialize_u64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u64");
        visitor.visit_u64(expect!(self.pop(), Uint64)?)
    }

    fn deserialize_u32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u32");
        visitor.visit_u32(expect!(self.pop(), Uint32)?)
    }

    fn deserialize_u16<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u16");
        visitor.visit_u16(expect!(self.pop(), Uint16)?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u8");
        visitor.visit_u8(expect!(self.pop(), Byte)?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i64");
        self.deserialize_i32(visitor)
    }

    fn deserialize_i32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i32");
        visitor.visit_i32(expect!(self.pop(), Int32)?)
    }

    fn deserialize_bool<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_bool");
        visitor.visit_bool(expect!(self.pop(), Boolean)?)
    }

    fn deserialize_f64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f64");
        visitor.visit_f64(expect!(self.pop(), Double)?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f32");
        visitor.visit_f32(expect!(self.pop(), Float)?)
    }

    fn deserialize_str<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        let string = expect!(self.pop(), String)?;
        debug!("read_str: {}", string);
        visitor.visit_str(&string)
    }

    fn deserialize_string<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_string");
        self.deserialize_str(visitor)
    }

    // Structs look just like maps in JSON.
    //
    // Notice the `fields` parameter - a "struct" in the Serde data model means
    // that the `Deserialize` implementation is required to know what the fields
    // are before even looking at the input data. Any key-value pairing in which
    // the fields cannot be known ahead of time is probably a map.
    fn deserialize_struct<V>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    // Tuples look just like sequences in JSON. Some formats may be able to
    // represent tuples more efficiently.
    //
    // As indicated by the length parameter, the `Deserialize` implementation
    // for a tuple in the Serde data model is required to know the length of the
    // tuple before even looking at the input data.
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    // Tuple structs look just like sequences in JSON.
    fn deserialize_tuple_struct<V>(
        self,
        _name: &'static str,
        _len: usize,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    fn deserialize_option<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_option()");
        match self.pop() {
            Null => visitor.visit_none(),
            value => {
                self.stack.push(value);
                visitor.visit_some(self)
            }
        }
    }

    // In Serde, unit means an anonymous value containing no data.
    fn deserialize_unit<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_nil");
        match self.pop() {
            Null => visitor.visit_unit(),
            other => Err(DecodingError(format!("Error decoding Null as {:?}", other))),
        }
    }

    // Unit struct means a named value containing no data.
    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_unit(visitor)
    }

    // As is done here, serializers are encouraged to treat newtype structs as
    // insignificant wrappers around the data they contain. That means not
    // parsing anything other than the contained value.
    fn deserialize_newtype_struct<V>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    // An identifier in Serde is the type that identifies a field of a struct or
    // the variant of an enum.
    fn deserialize_identifier<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_str(visitor)
    }

    fn deserialize_seq<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_seq()");
        let list = expect!(self.pop(), Array)?;
        let len = list.len();

        for v in list.into_iter().rev() {
            self.stack.push(v);
        }

        let value = visitor.visit_seq(ArrayAccess::new(&mut self, len))?;
        Ok(value)
    }

    // Much like `deserialize_seq` but calls the visitors `visit_map` method
    // with a `MapAccess` implementation, rather than the visitor's `visit_seq`
    // method with a `SeqAccess` implementation.
    fn deserialize_map<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_map()");
        let obj = expect!(self.pop(), Map)?;
        let len = obj.len();
        for (key, value) in obj.into_iter() {
            self.stack.push(value);
            self.stack.push(String(key));
        }

        let value = visitor.visit_map(MapAccessor::new(&mut self, len * 2))?;
        Ok(value)
    }

    forward_to_deserialize_any! {
        bytes byte_buf char enum i8 i16 ignored_any
    }
}

struct ArrayAccess<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> ArrayAccess<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        ArrayAccess {
            de: de,
            count: count,
        }
    }
}

// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
// through elements of the sequence.
impl<'de, 'a> SeqAccess<'de> for ArrayAccess<'a> {
    type Error = MaxMindDBError;

    fn next_element_seed<T>(&mut self, seed: T) -> DecodeResult<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        // Check if there are no more elements.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize an array element.
        seed.deserialize(&mut *self.de).map(Some)
    }
}

struct MapAccessor<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> MapAccessor<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        MapAccessor {
            de: de,
            count: count,
        }
    }
}

// `MapAccess` is provided to the `Visitor` to give it the ability to iterate
// through entries of the map.
impl<'de, 'a> MapAccess<'de> for MapAccessor<'a> {
    type Error = MaxMindDBError;

    fn next_key_seed<K>(&mut self, seed: K) -> DecodeResult<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize a map key.
        seed.deserialize(&mut *self.de).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> DecodeResult<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Err(DecodingError("no more entries".to_owned()));
        }
        self.count -= 1;

        // Deserialize a map value.
        seed.deserialize(&mut *self.de)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Philipp Oppermann. See the README.md
// file at the top-level directory of this distribution.
//
// 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.

pub use self::entry::*;
use memory::{PAGE_SIZE, Frame, FrameAllocator};
use self::table::{Table, Level4};
use self::temporary_page::TemporaryPage;
pub use self::mapper::Mapper;
use core::ops::{Deref, DerefMut};
use core::ptr::Unique;
use multiboot2::BootInformation;

mod entry;
mod table;
mod temporary_page;
mod mapper;

const ENTRY_COUNT: usize = 512;

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

#[derive(Debug, Clone, Copy)]
pub struct Page {
    number: usize,
}

impl Page {
    pub fn containing_address(address: VirtualAddress) -> Page {
        assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
                "invalid address: 0x{:x}",
                address);
        Page { number: address / PAGE_SIZE }
    }

    fn start_address(&self) -> usize {
        self.number * PAGE_SIZE
    }

    fn p4_index(&self) -> usize {
        (self.number >> 27) & 0o777
    }
    fn p3_index(&self) -> usize {
        (self.number >> 18) & 0o777
    }
    fn p2_index(&self) -> usize {
        (self.number >> 9) & 0o777
    }
    fn p1_index(&self) -> usize {
        (self.number >> 0) & 0o777
    }
}

pub struct ActivePageTable {
    mapper: Mapper,
}

impl Deref for ActivePageTable {
    type Target = Mapper;

    fn deref(&self) -> &Mapper {
        &self.mapper
    }
}

impl DerefMut for ActivePageTable {
    fn deref_mut(&mut self) -> &mut Mapper {
        &mut self.mapper
    }
}

impl ActivePageTable {
    unsafe fn new() -> ActivePageTable {
        ActivePageTable { mapper: Mapper::new() }
    }

    pub fn with<F>(&mut self,
                   table: &mut InactivePageTable,
                   temporary_page: &mut temporary_page::TemporaryPage, // new
                   f: F)
        where F: FnOnce(&mut Mapper)
    {
        use x86::{controlregs, tlb};
        let flush_tlb = || unsafe { tlb::flush_all() };

        {
            let backup = Frame::containing_address(unsafe { controlregs::cr3() } as usize);

            // map temporary_page to current p4 table
            let p4_table = temporary_page.map_table_frame(backup.clone(), self);

            // overwrite recursive mapping
            self.p4_mut()[511].set(table.p4_frame.clone(), PRESENT | WRITABLE);
            flush_tlb();

            // execute f in the new context
            f(self);

            // restore recursive mapping to original p4 table
            p4_table[511].set(backup, PRESENT | WRITABLE);
            flush_tlb();
        }

        temporary_page.unmap(self);
    }

    pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
        use x86::controlregs;

        let old_table = InactivePageTable {
            p4_frame: Frame::containing_address(unsafe { controlregs::cr3() } as usize),
        };
        unsafe {
            controlregs::cr3_write(new_table.p4_frame.start_address() as u64);
        }
        old_table
    }
}

pub struct InactivePageTable {
    p4_frame: Frame,
}

impl InactivePageTable {
    pub fn new(frame: Frame,
               active_table: &mut ActivePageTable,
               temporary_page: &mut TemporaryPage)
               -> InactivePageTable {
        {
            let table = temporary_page.map_table_frame(frame.clone(), active_table);
            table.zero();
            table[511].set(frame.clone(), PRESENT | WRITABLE);
        }
        temporary_page.unmap(active_table);

        InactivePageTable { p4_frame: frame }
    }
}

pub fn test_paging<A>(allocator: &mut A)
    where A: FrameAllocator
{
    let mut page_table = unsafe { ActivePageTable::new() };

    // test translate
    println!("Some = {:?}", page_table.translate(0));
    println!("Some = {:?}", page_table.translate(4096)); // second P1 entry
    println!("Some = {:?}", page_table.translate(512 * 4096)); // second P2 entry
    println!("Some = {:?}", page_table.translate(300 * 512 * 4096)); // 300th P2 entry
    println!("None = {:?}", page_table.translate(512 * 512 * 4096)); // second P3 entry
    println!("Some = {:?}", page_table.translate(512 * 512 * 4096 - 1)); // last mapped byte

    // test map_to
    let addr = 42 * 512 * 512 * 4096; // 42th P3 entry
    let page = Page::containing_address(addr);
    let frame = allocator.allocate_frame().expect("no more frames");
    println!("None = {:?}, map to {:?}",
             page_table.translate(addr),
             frame);
    page_table.map_to(page, frame, EntryFlags::empty(), allocator);
    println!("Some = {:?}", page_table.translate(addr));
    println!("next free frame: {:?}", allocator.allocate_frame());

    // test unmap
    println!("{:#x}",
             unsafe { *(Page::containing_address(addr).start_address() as *const u64) });
    page_table.unmap(Page::containing_address(addr), allocator);
    println!("None = {:?}", page_table.translate(addr));
}

pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
    where A: FrameAllocator
{
    use core::ops::Range;

    let mut temporary_page = TemporaryPage::new(Page { number: 0xcafebabe }, allocator);

    let mut active_table = unsafe { ActivePageTable::new() };
    let mut new_table = {
        let frame = allocator.allocate_frame().expect("no more frames");
        InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
    };

    active_table.with(&mut new_table, &mut temporary_page, |mapper| {
        let elf_sections_tag = boot_info.elf_sections_tag()
                                        .expect("Memory map tag required");

        for section in elf_sections_tag.sections() {
            use multiboot2::ELF_SECTION_ALLOCATED;
            use self::entry::WRITABLE;

            if !section.flags().contains(ELF_SECTION_ALLOCATED) {
                // section is not loaded to memory
                continue;
            }

            println!("mapping section at addr: {:#x}, size: {:#x}",
                     section.addr,
                     section.size);

            let flags = WRITABLE; // TODO use real section flags

            let range = Range {
                start: section.addr as usize,
                end: (section.addr + section.size) as usize,
            };
            for address in range.step_by(PAGE_SIZE) {
                assert!(address % PAGE_SIZE == 0, "sections need to be page aligned");
                let frame = Frame::containing_address(address);
                mapper.identity_map(frame, flags, allocator);
            }
        }
    });

    let old_table = active_table.switch(new_table);
    println!("NEW TABLE!!!");
}
<commit_msg>Identity map the vga text buffer<commit_after>// Copyright 2015 Philipp Oppermann. See the README.md
// file at the top-level directory of this distribution.
//
// 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.

pub use self::entry::*;
use memory::{PAGE_SIZE, Frame, FrameAllocator};
use self::table::{Table, Level4};
use self::temporary_page::TemporaryPage;
pub use self::mapper::Mapper;
use core::ops::{Deref, DerefMut};
use core::ptr::Unique;
use multiboot2::BootInformation;

mod entry;
mod table;
mod temporary_page;
mod mapper;

const ENTRY_COUNT: usize = 512;

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

#[derive(Debug, Clone, Copy)]
pub struct Page {
    number: usize,
}

impl Page {
    pub fn containing_address(address: VirtualAddress) -> Page {
        assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
                "invalid address: 0x{:x}",
                address);
        Page { number: address / PAGE_SIZE }
    }

    fn start_address(&self) -> usize {
        self.number * PAGE_SIZE
    }

    fn p4_index(&self) -> usize {
        (self.number >> 27) & 0o777
    }
    fn p3_index(&self) -> usize {
        (self.number >> 18) & 0o777
    }
    fn p2_index(&self) -> usize {
        (self.number >> 9) & 0o777
    }
    fn p1_index(&self) -> usize {
        (self.number >> 0) & 0o777
    }
}

pub struct ActivePageTable {
    mapper: Mapper,
}

impl Deref for ActivePageTable {
    type Target = Mapper;

    fn deref(&self) -> &Mapper {
        &self.mapper
    }
}

impl DerefMut for ActivePageTable {
    fn deref_mut(&mut self) -> &mut Mapper {
        &mut self.mapper
    }
}

impl ActivePageTable {
    unsafe fn new() -> ActivePageTable {
        ActivePageTable { mapper: Mapper::new() }
    }

    pub fn with<F>(&mut self,
                   table: &mut InactivePageTable,
                   temporary_page: &mut temporary_page::TemporaryPage, // new
                   f: F)
        where F: FnOnce(&mut Mapper)
    {
        use x86::{controlregs, tlb};
        let flush_tlb = || unsafe { tlb::flush_all() };

        {
            let backup = Frame::containing_address(unsafe { controlregs::cr3() } as usize);

            // map temporary_page to current p4 table
            let p4_table = temporary_page.map_table_frame(backup.clone(), self);

            // overwrite recursive mapping
            self.p4_mut()[511].set(table.p4_frame.clone(), PRESENT | WRITABLE);
            flush_tlb();

            // execute f in the new context
            f(self);

            // restore recursive mapping to original p4 table
            p4_table[511].set(backup, PRESENT | WRITABLE);
            flush_tlb();
        }

        temporary_page.unmap(self);
    }

    pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
        use x86::controlregs;

        let old_table = InactivePageTable {
            p4_frame: Frame::containing_address(unsafe { controlregs::cr3() } as usize),
        };
        unsafe {
            controlregs::cr3_write(new_table.p4_frame.start_address() as u64);
        }
        old_table
    }
}

pub struct InactivePageTable {
    p4_frame: Frame,
}

impl InactivePageTable {
    pub fn new(frame: Frame,
               active_table: &mut ActivePageTable,
               temporary_page: &mut TemporaryPage)
               -> InactivePageTable {
        {
            let table = temporary_page.map_table_frame(frame.clone(), active_table);
            table.zero();
            table[511].set(frame.clone(), PRESENT | WRITABLE);
        }
        temporary_page.unmap(active_table);

        InactivePageTable { p4_frame: frame }
    }
}

pub fn test_paging<A>(allocator: &mut A)
    where A: FrameAllocator
{
    let mut page_table = unsafe { ActivePageTable::new() };

    // test translate
    println!("Some = {:?}", page_table.translate(0));
    println!("Some = {:?}", page_table.translate(4096)); // second P1 entry
    println!("Some = {:?}", page_table.translate(512 * 4096)); // second P2 entry
    println!("Some = {:?}", page_table.translate(300 * 512 * 4096)); // 300th P2 entry
    println!("None = {:?}", page_table.translate(512 * 512 * 4096)); // second P3 entry
    println!("Some = {:?}", page_table.translate(512 * 512 * 4096 - 1)); // last mapped byte

    // test map_to
    let addr = 42 * 512 * 512 * 4096; // 42th P3 entry
    let page = Page::containing_address(addr);
    let frame = allocator.allocate_frame().expect("no more frames");
    println!("None = {:?}, map to {:?}",
             page_table.translate(addr),
             frame);
    page_table.map_to(page, frame, EntryFlags::empty(), allocator);
    println!("Some = {:?}", page_table.translate(addr));
    println!("next free frame: {:?}", allocator.allocate_frame());

    // test unmap
    println!("{:#x}",
             unsafe { *(Page::containing_address(addr).start_address() as *const u64) });
    page_table.unmap(Page::containing_address(addr), allocator);
    println!("None = {:?}", page_table.translate(addr));
}

pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
    where A: FrameAllocator
{
    use core::ops::Range;

    let mut temporary_page = TemporaryPage::new(Page { number: 0xcafebabe }, allocator);

    let mut active_table = unsafe { ActivePageTable::new() };
    let mut new_table = {
        let frame = allocator.allocate_frame().expect("no more frames");
        InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
    };

    active_table.with(&mut new_table, &mut temporary_page, |mapper| {
        let elf_sections_tag = boot_info.elf_sections_tag()
                                        .expect("Memory map tag required");

        for section in elf_sections_tag.sections() {
            use multiboot2::ELF_SECTION_ALLOCATED;
            use self::entry::WRITABLE;

            if !section.flags().contains(ELF_SECTION_ALLOCATED) {
                // section is not loaded to memory
                continue;
            }

            println!("mapping section at addr: {:#x}, size: {:#x}",
                     section.addr,
                     section.size);

            let flags = WRITABLE; // TODO use real section flags

            let range = Range {
                start: section.addr as usize,
                end: (section.addr + section.size) as usize,
            };
            for address in range.step_by(PAGE_SIZE) {
                assert!(address % PAGE_SIZE == 0, "sections need to be page aligned");
                let frame = Frame::containing_address(address);
                mapper.identity_map(frame, flags, allocator);
            }
        }

        let vga_buffer_frame = Frame::containing_address(0xb8000);
        mapper.identity_map(vga_buffer_frame, WRITABLE, allocator);
    });

    let old_table = active_table.switch(new_table);
    println!("NEW TABLE!!!");
}
<|endoftext|>


<commit_before>use nn::{Module, InitModuleStruct, GetFieldStruct, ModDelegate, ModIntf, Parameter};
use autograd::Variable;
use nn::_functions::Conv2dFArgs;
use std::marker::PhantomData;
use nn::functional as F;
use tensor::NumLimits;

#[builder(pattern="owned")]
#[derive(Builder)]
pub struct Conv2dArgs<T: NumLimits> {
    in_features: usize,
    out_features: usize,
    kernel_size: (i32, i32),
    #[builder(default="vec![1, 1]")]
    pub stride: Vec<i32>,
    #[builder(default="vec![0, 0]")]
    pub padding: Vec<i32>,
    #[builder(default="vec![1, 1]")]
    pub dilation: Vec<i32>,
    #[builder(default="1")]
    groups: u32,
    #[builder(default="true")]
    bias: bool,
    #[builder(default="PhantomData")]
    phantom: PhantomData<T>,
}

impl<T: NumLimits> Conv2dArgsBuilder<T> {
    pub fn done(self) -> Conv2d<T> {
        let args = self.build().unwrap();
        Conv2d::new(args)
    }
}

#[derive(ModParse)]
pub struct Conv2d<T: NumLimits> {
    delegate: Module<T>,
    weight: Parameter<T>,
    bias: Option<Parameter<T>>,
    #[ignore]
    args: Conv2dFArgs,
}

impl<T: NumLimits> Conv2d<T> {
    pub fn build(in_features: usize,
                 out_features: usize,
                 kernel_size: (i32, i32))
                 -> Conv2dArgsBuilder<T> {
        Conv2dArgsBuilder::default()
            .in_features(in_features)
            .out_features(out_features)
            .kernel_size(kernel_size)
    }
    fn reset_parameters(mut self) -> Self {
        let mut n = self.args.in_features as i32;
        for k in &self.args.kernel_size {
            n *= *k;
        }
        let stdv: f64 = 1. / (n as f64).sqrt();
        self.weight.v.data().uniform_((-stdv, stdv));
        if let Some(ref mut bias) = self.bias {
            bias.v.data().uniform_((-stdv, stdv));
        }
        self
    }
    pub fn new(args: Conv2dArgs<T>) -> Conv2d<T> {
        let bias = if args.bias {
            Some(Parameter::new((args.out_features)))
        } else {
            None
        };
        let fargs = Conv2dFArgs {
            in_features: args.in_features,
            out_features: args.out_features,
            kernel_size: vec![args.kernel_size.0, args.kernel_size.1],
            stride: args.stride.clone(),
            padding: args.padding.clone(),
            dilation: args.dilation.clone(),
            groups: args.groups,
        };
        Conv2d {
                delegate: Module::new(),
                weight: Parameter::new([args.out_features / args.groups as usize, args.in_features,
                    args.kernel_size.0 as usize, args.kernel_size.1 as usize]),
                bias: bias,
                args: fargs,
            }
            .init_module()
            .reset_parameters()
    }
}
impl_mod_delegate!(Conv2d);

impl<T: NumLimits> ModIntf<T> for Conv2d<T> {
    fn forward(&mut self, input: &mut Variable<T>) -> Variable<T> {
        let bias = if let Some(ref mut biasp) = self.bias {
            Some(&mut biasp.v)
        } else {
            None
        };
        F::conv2d(input, &mut self.weight.v, bias, &mut self.args)
    }
}
<commit_msg>rustfmt<commit_after>use nn::{Module, InitModuleStruct, GetFieldStruct, ModDelegate, ModIntf, Parameter};
use autograd::Variable;
use nn::_functions::Conv2dFArgs;
use std::marker::PhantomData;
use nn::functional as F;
use tensor::NumLimits;

#[builder(pattern="owned")]
#[derive(Builder)]
pub struct Conv2dArgs<T: NumLimits> {
    in_features: usize,
    out_features: usize,
    kernel_size: (i32, i32),
    #[builder(default="vec![1, 1]")]
    pub stride: Vec<i32>,
    #[builder(default="vec![0, 0]")]
    pub padding: Vec<i32>,
    #[builder(default="vec![1, 1]")]
    pub dilation: Vec<i32>,
    #[builder(default="1")]
    groups: u32,
    #[builder(default="true")]
    bias: bool,
    #[builder(default="PhantomData")]
    phantom: PhantomData<T>,
}

impl<T: NumLimits> Conv2dArgsBuilder<T> {
    pub fn done(self) -> Conv2d<T> {
        let args = self.build().unwrap();
        Conv2d::new(args)
    }
}

#[derive(ModParse)]
pub struct Conv2d<T: NumLimits> {
    delegate: Module<T>,
    weight: Parameter<T>,
    bias: Option<Parameter<T>>,
    #[ignore]
    args: Conv2dFArgs,
}

impl<T: NumLimits> Conv2d<T> {
    pub fn build(in_features: usize,
                 out_features: usize,
                 kernel_size: (i32, i32))
                 -> Conv2dArgsBuilder<T> {
        Conv2dArgsBuilder::default()
            .in_features(in_features)
            .out_features(out_features)
            .kernel_size(kernel_size)
    }
    fn reset_parameters(mut self) -> Self {
        let mut n = self.args.in_features as i32;
        for k in &self.args.kernel_size {
            n *= *k;
        }
        let stdv: f64 = 1. / (n as f64).sqrt();
        self.weight.v.data().uniform_((-stdv, stdv));
        if let Some(ref mut bias) = self.bias {
            bias.v.data().uniform_((-stdv, stdv));
        }
        self
    }
    pub fn new(args: Conv2dArgs<T>) -> Conv2d<T> {
        let bias = if args.bias {
            Some(Parameter::new((args.out_features)))
        } else {
            None
        };
        let fargs = Conv2dFArgs {
            in_features: args.in_features,
            out_features: args.out_features,
            kernel_size: vec![args.kernel_size.0, args.kernel_size.1],
            stride: args.stride.clone(),
            padding: args.padding.clone(),
            dilation: args.dilation.clone(),
            groups: args.groups,
        };
        Conv2d {
                delegate: Module::new(),
                weight: Parameter::new([args.out_features / args.groups as usize,
                                        args.in_features,
                                        args.kernel_size.0 as usize,
                                        args.kernel_size.1 as usize]),
                bias: bias,
                args: fargs,
            }
            .init_module()
            .reset_parameters()
    }
}
impl_mod_delegate!(Conv2d);

impl<T: NumLimits> ModIntf<T> for Conv2d<T> {
    fn forward(&mut self, input: &mut Variable<T>) -> Variable<T> {
        let bias = if let Some(ref mut biasp) = self.bias {
            Some(&mut biasp.v)
        } else {
            None
        };
        F::conv2d(input, &mut self.weight.v, bias, &mut self.args)
    }
}
<|endoftext|>