<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/. */

//! This module contains shared types and messages for use by devtools/script.
//! The traits are here instead of in script so that the devtools crate can be
//! modified independently of the rest of Servo.

#![crate_name = "devtools_traits"]
#![crate_type = "rlib"]

#![feature(net)]

#![allow(non_snake_case)]

extern crate msg;
extern crate "rustc-serialize" as rustc_serialize;
extern crate url;
extern crate util;
extern crate time;

use rustc_serialize::{Decodable, Decoder};
use msg::constellation_msg::{PipelineId, WorkerId};
use util::str::DOMString;
use url::Url;

use std::net::TcpStream;
use std::sync::mpsc::{Sender, Receiver};

pub type DevtoolsControlChan = Sender<DevtoolsControlMsg>;
pub type DevtoolsControlPort = Receiver<DevtoolScriptControlMsg>;

// Information would be attached to NewGlobal to be received and show in devtools.
// Extend these fields if we need more information.
pub struct DevtoolsPageInfo {
    pub title: DOMString,
    pub url: Url
}

/// Messages to the instruct the devtools server to update its known actors/state
/// according to changes in the browser.
pub enum DevtoolsControlMsg {
    AddClient(TcpStream),
    NewGlobal((PipelineId, Option<WorkerId>), Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo),
    SendConsoleMessage(PipelineId, ConsoleMessage),
    ServerExitMsg
}

/// Serialized JS return values
/// TODO: generalize this beyond the EvaluateJS message?
pub enum EvaluateJSReply {
    VoidValue,
    NullValue,
    BooleanValue(bool),
    NumberValue(f64),
    StringValue(String),
    ActorValue(String),
}

pub struct AttrInfo {
    pub namespace: String,
    pub name: String,
    pub value: String,
}

pub struct NodeInfo {
    pub uniqueId: String,
    pub baseURI: String,
    pub parent: String,
    pub nodeType: u16,
    pub namespaceURI: String,
    pub nodeName: String,
    pub numChildren: usize,

    pub name: String,
    pub publicId: String,
    pub systemId: String,

    pub attrs: Vec<AttrInfo>,

    pub isDocumentElement: bool,

    pub shortValue: String,
    pub incompleteValue: bool,
}

#[derive(PartialEq, Eq)]
pub enum TracingMetadata {
    Default,
    IntervalStart,
    IntervalEnd,
    Event,
    EventBacktrace,
}

pub struct TimelineMarker {
    pub name: String,
    pub metadata: TracingMetadata,
    pub time: time::PreciseTime,
    pub stack: Option<Vec<()>>,
}

#[derive(PartialEq, Eq, Hash, Clone)]
pub enum TimelineMarkerType {
    Reflow,
    DOMEvent,
}

/// Messages to process in a particular script task, as instructed by a devtools client.
pub enum DevtoolScriptControlMsg {
    EvaluateJS(PipelineId, String, Sender<EvaluateJSReply>),
    GetRootNode(PipelineId, Sender<NodeInfo>),
    GetDocumentElement(PipelineId, Sender<NodeInfo>),
    GetChildren(PipelineId, String, Sender<Vec<NodeInfo>>),
    GetLayout(PipelineId, String, Sender<(f32, f32)>),
    ModifyAttribute(PipelineId, String, Vec<Modification>),
    WantsLiveNotifications(PipelineId, bool),
    SetTimelineMarkers(PipelineId, Vec<TimelineMarkerType>, Sender<TimelineMarker>),
    DropTimelineMarkers(PipelineId, Vec<TimelineMarkerType>),
}

/// Messages to instruct devtools server to update its state relating to a particular
/// tab.
pub enum ScriptDevtoolControlMsg {
    /// Report a new JS error message
    ReportConsoleMsg(String),
}

#[derive(RustcEncodable)]
pub struct Modification{
    pub attributeName: String,
    pub newValue: Option<String>,
}

impl Decodable for Modification {
    fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> {
        d.read_struct("Modification", 2, |d|
            Ok(Modification {
                attributeName: try!(d.read_struct_field("attributeName", 0, |d| Decodable::decode(d))),
                newValue: match d.read_struct_field("newValue", 1, |d| Decodable::decode(d)) {
                    Ok(opt) => opt,
                    Err(_) => None
                }
            })
        )
    }
}

//TODO: Include options for Warn, Debug, Info, Error messages from Console
#[derive(Clone)]
pub enum ConsoleMessage {
    // Log: message, filename, line number, column number
    LogMessage(String, String, u32, u32),
    //WarnMessage(String),
}

impl TimelineMarker {
    pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
        TimelineMarker {
            name: name,
            metadata: metadata,
            time: time::PreciseTime::now(),
            stack: None,
        }
    }
}
<commit_msg>Remove unused ScriptDevtoolControlMsg enum<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/. */

//! This module contains shared types and messages for use by devtools/script.
//! The traits are here instead of in script so that the devtools crate can be
//! modified independently of the rest of Servo.

#![crate_name = "devtools_traits"]
#![crate_type = "rlib"]

#![feature(net)]

#![allow(non_snake_case)]

extern crate msg;
extern crate "rustc-serialize" as rustc_serialize;
extern crate url;
extern crate util;
extern crate time;

use rustc_serialize::{Decodable, Decoder};
use msg::constellation_msg::{PipelineId, WorkerId};
use util::str::DOMString;
use url::Url;

use std::net::TcpStream;
use std::sync::mpsc::{Sender, Receiver};

pub type DevtoolsControlChan = Sender<DevtoolsControlMsg>;
pub type DevtoolsControlPort = Receiver<DevtoolScriptControlMsg>;

// Information would be attached to NewGlobal to be received and show in devtools.
// Extend these fields if we need more information.
pub struct DevtoolsPageInfo {
    pub title: DOMString,
    pub url: Url
}

/// Messages to the instruct the devtools server to update its known actors/state
/// according to changes in the browser.
pub enum DevtoolsControlMsg {
    AddClient(TcpStream),
    NewGlobal((PipelineId, Option<WorkerId>), Sender<DevtoolScriptControlMsg>, DevtoolsPageInfo),
    SendConsoleMessage(PipelineId, ConsoleMessage),
    ServerExitMsg
}

/// Serialized JS return values
/// TODO: generalize this beyond the EvaluateJS message?
pub enum EvaluateJSReply {
    VoidValue,
    NullValue,
    BooleanValue(bool),
    NumberValue(f64),
    StringValue(String),
    ActorValue(String),
}

pub struct AttrInfo {
    pub namespace: String,
    pub name: String,
    pub value: String,
}

pub struct NodeInfo {
    pub uniqueId: String,
    pub baseURI: String,
    pub parent: String,
    pub nodeType: u16,
    pub namespaceURI: String,
    pub nodeName: String,
    pub numChildren: usize,

    pub name: String,
    pub publicId: String,
    pub systemId: String,

    pub attrs: Vec<AttrInfo>,

    pub isDocumentElement: bool,

    pub shortValue: String,
    pub incompleteValue: bool,
}

#[derive(PartialEq, Eq)]
pub enum TracingMetadata {
    Default,
    IntervalStart,
    IntervalEnd,
    Event,
    EventBacktrace,
}

pub struct TimelineMarker {
    pub name: String,
    pub metadata: TracingMetadata,
    pub time: time::PreciseTime,
    pub stack: Option<Vec<()>>,
}

#[derive(PartialEq, Eq, Hash, Clone)]
pub enum TimelineMarkerType {
    Reflow,
    DOMEvent,
}

/// Messages to process in a particular script task, as instructed by a devtools client.
pub enum DevtoolScriptControlMsg {
    EvaluateJS(PipelineId, String, Sender<EvaluateJSReply>),
    GetRootNode(PipelineId, Sender<NodeInfo>),
    GetDocumentElement(PipelineId, Sender<NodeInfo>),
    GetChildren(PipelineId, String, Sender<Vec<NodeInfo>>),
    GetLayout(PipelineId, String, Sender<(f32, f32)>),
    ModifyAttribute(PipelineId, String, Vec<Modification>),
    WantsLiveNotifications(PipelineId, bool),
    SetTimelineMarkers(PipelineId, Vec<TimelineMarkerType>, Sender<TimelineMarker>),
    DropTimelineMarkers(PipelineId, Vec<TimelineMarkerType>),
}

#[derive(RustcEncodable)]
pub struct Modification{
    pub attributeName: String,
    pub newValue: Option<String>,
}

impl Decodable for Modification {
    fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> {
        d.read_struct("Modification", 2, |d|
            Ok(Modification {
                attributeName: try!(d.read_struct_field("attributeName", 0, |d| Decodable::decode(d))),
                newValue: match d.read_struct_field("newValue", 1, |d| Decodable::decode(d)) {
                    Ok(opt) => opt,
                    Err(_) => None
                }
            })
        )
    }
}

//TODO: Include options for Warn, Debug, Info, Error messages from Console
#[derive(Clone)]
pub enum ConsoleMessage {
    // Log: message, filename, line number, column number
    LogMessage(String, String, u32, u32),
    //WarnMessage(String),
}

impl TimelineMarker {
    pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
        TimelineMarker {
            name: name,
            metadata: metadata,
            time: time::PreciseTime::now(),
            stack: None,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>svlog: ast: Change mod/intf/pkg indefinite naming<commit_after><|endoftext|>


<commit_before>use {Enum, EnumMap};

use core::iter::Enumerate;
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ptr;
use core::slice;

/// Immutable enum map iterator
///
/// This struct is created by `iter` method or `into_iter` on a reference
/// to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     assert_eq!(map[Example::A], 3);
///     for (key, &value) in &map {
///         assert_eq!(value, match key {
///             Example::A => 3,
///             _ => 0,
///         });
///     }
/// }
/// ```
#[derive(Debug)]
pub struct Iter<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::Iter<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for Iter<'a, K, V> {
    type Item = (K, &'a V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a EnumMap<K, V> {
    type Item = (K, &'a V);
    type IntoIter = Iter<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        Iter {
            _phantom: PhantomData,
            iterator: self.as_slice().iter().enumerate(),
        }
    }
}

/// Mutable map iterator
///
/// This struct is created by `iter_mut` method or `into_iter` on a mutable
/// reference to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     for (_, value) in &mut map {
///         *value += 1;
///     }
///     assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
/// }
/// ```
#[derive(Debug)]
pub struct IterMut<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::IterMut<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for IterMut<'a, K, V> {
    type Item = (K, &'a mut V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
    type Item = (K, &'a mut V);
    type IntoIter = IterMut<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IterMut {
            _phantom: PhantomData,
            iterator: self.as_mut_slice().iter_mut().enumerate(),
        }
    }
}

/// A map iterator that moves out of map.
///
/// This struct is created by `into_iter` on `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
/// }
///
/// fn main() {
///     let map = enum_map! { Example::A | Example::B => String::from("123") };
///     for (_, value) in map {
///         assert_eq!(value + "4", "1234");
///     }
/// }
/// ```
pub struct IntoIter<K: Enum<V>, V> {
    map: ManuallyDrop<EnumMap<K, V>>,
    position: usize,
}

impl<K: Enum<V>, V> Iterator for IntoIter<K, V> {
    type Item = (K, V);
    fn next(&mut self) -> Option<(K, V)> {
        let slice = self.map.as_slice();
        if self.position < slice.len() {
            let key = K::from_usize(self.position);
            let result = Some((key, unsafe { ptr::read(&slice[self.position]) }));
            self.position += 1;
            result
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let slice = self.map.as_slice();
        let diff = slice.len() - self.position;
        (diff, Some(diff))
    }
}

impl<K: Enum<V>, V> ExactSizeIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> Drop for IntoIter<K, V> {
    fn drop(&mut self) {
        for _item in self {}
    }
}

impl<K: Enum<V>, V> IntoIterator for EnumMap<K, V> {
    type Item = (K, V);
    type IntoIter = IntoIter<K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IntoIter {
            map: ManuallyDrop::new(self),
            position: 0,
        }
    }
}

impl<K: Enum<V>, V> EnumMap<K, V> {
    /// An iterator visiting all values. The iterator type is `&V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let map = enum_map! { false => 3, true => 4 };
    ///     let mut values = map.values();
    ///     assert_eq!(values.next(), Some(&3));
    ///     assert_eq!(values.next(), Some(&4));
    ///     assert_eq!(values.next(), None);
    /// }
    /// ```
    pub fn values(&self) -> Values<V> {
        Values(self.as_slice().iter())
    }

    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 2 };
    ///     for value in map.values_mut() {
    ///         *value += 2;
    ///     }
    ///     assert_eq!(map[false], 4);
    ///     assert_eq!(map[true], 4);
    /// }
    /// ```
    pub fn values_mut(&mut self) -> ValuesMut<V> {
        ValuesMut(self.as_mut_slice().iter_mut())
    }
}

/// An iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values` method of `EnumMap`.
/// See its documentation for more.
pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);

impl<'a, V: 'a> Iterator for Values<'a, V> {
    type Item = &'a V;
    fn next(&mut self) -> Option<&'a V> {
        self.0.next()
    }
}

/// A mutable iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values_mut` method of `EnumMap`.
/// See its documentation for more.
pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);

impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
    type Item = &'a mut V;
    fn next(&mut self) -> Option<&'a mut V> {
        self.0.next()
    }
}
<commit_msg>Revert "Revert "Implement FusedIterator for enum map iterators""<commit_after>use {Enum, EnumMap};

use core::iter::{Enumerate, FusedIterator};
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ptr;
use core::slice;

/// Immutable enum map iterator
///
/// This struct is created by `iter` method or `into_iter` on a reference
/// to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     assert_eq!(map[Example::A], 3);
///     for (key, &value) in &map {
///         assert_eq!(value, match key {
///             Example::A => 3,
///             _ => 0,
///         });
///     }
/// }
/// ```
#[derive(Debug)]
pub struct Iter<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::Iter<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for Iter<'a, K, V> {
    type Item = (K, &'a V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> FusedIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a EnumMap<K, V> {
    type Item = (K, &'a V);
    type IntoIter = Iter<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        Iter {
            _phantom: PhantomData,
            iterator: self.as_slice().iter().enumerate(),
        }
    }
}

/// Mutable map iterator
///
/// This struct is created by `iter_mut` method or `into_iter` on a mutable
/// reference to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     for (_, value) in &mut map {
///         *value += 1;
///     }
///     assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
/// }
/// ```
#[derive(Debug)]
pub struct IterMut<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::IterMut<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for IterMut<'a, K, V> {
    type Item = (K, &'a mut V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> FusedIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
    type Item = (K, &'a mut V);
    type IntoIter = IterMut<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IterMut {
            _phantom: PhantomData,
            iterator: self.as_mut_slice().iter_mut().enumerate(),
        }
    }
}

/// A map iterator that moves out of map.
///
/// This struct is created by `into_iter` on `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
/// }
///
/// fn main() {
///     let map = enum_map! { Example::A | Example::B => String::from("123") };
///     for (_, value) in map {
///         assert_eq!(value + "4", "1234");
///     }
/// }
/// ```
pub struct IntoIter<K: Enum<V>, V> {
    map: ManuallyDrop<EnumMap<K, V>>,
    position: usize,
}

impl<K: Enum<V>, V> Iterator for IntoIter<K, V> {
    type Item = (K, V);
    fn next(&mut self) -> Option<(K, V)> {
        let slice = self.map.as_slice();
        if self.position < slice.len() {
            let key = K::from_usize(self.position);
            let result = Some((key, unsafe { ptr::read(&slice[self.position]) }));
            self.position += 1;
            result
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let slice = self.map.as_slice();
        let diff = slice.len() - self.position;
        (diff, Some(diff))
    }
}

impl<K: Enum<V>, V> ExactSizeIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> FusedIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> Drop for IntoIter<K, V> {
    fn drop(&mut self) {
        for _item in self {}
    }
}

impl<K: Enum<V>, V> IntoIterator for EnumMap<K, V> {
    type Item = (K, V);
    type IntoIter = IntoIter<K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IntoIter {
            map: ManuallyDrop::new(self),
            position: 0,
        }
    }
}

impl<K: Enum<V>, V> EnumMap<K, V> {
    /// An iterator visiting all values. The iterator type is `&V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let map = enum_map! { false => 3, true => 4 };
    ///     let mut values = map.values();
    ///     assert_eq!(values.next(), Some(&3));
    ///     assert_eq!(values.next(), Some(&4));
    ///     assert_eq!(values.next(), None);
    /// }
    /// ```
    pub fn values(&self) -> Values<V> {
        Values(self.as_slice().iter())
    }

    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 2 };
    ///     for value in map.values_mut() {
    ///         *value += 2;
    ///     }
    ///     assert_eq!(map[false], 4);
    ///     assert_eq!(map[true], 4);
    /// }
    /// ```
    pub fn values_mut(&mut self) -> ValuesMut<V> {
        ValuesMut(self.as_mut_slice().iter_mut())
    }
}

/// An iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values` method of `EnumMap`.
/// See its documentation for more.
pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);

impl<'a, V: 'a> Iterator for Values<'a, V> {
    type Item = &'a V;
    fn next(&mut self) -> Option<&'a V> {
        self.0.next()
    }
}

/// A mutable iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values_mut` method of `EnumMap`.
/// See its documentation for more.
pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);

impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
    type Item = &'a mut V;
    fn next(&mut self) -> Option<&'a mut V> {
        self.0.next()
    }
}
<|endoftext|>


<commit_before>use crate::runtime;
use crate::task::JoinHandle;

use std::future::Future;

doc_rt_core! {
    /// Spawns a new asynchronous task, returning a
    /// [`JoinHandle`](super::JoinHandle) for it.
    ///
    /// Spawning a task enables the task to execute concurrently to other tasks. The
    /// spawned task may execute on the current thread, or it may be sent to a
    /// different thread to be executed. The specifics depend on the current
    /// [`Runtime`](crate::runtime::Runtime) configuration.
    ///
    /// There is no guarantee that a spawned task will execute to completion.
    /// When a runtime is shutdown, all outstanding tasks are dropped,
    /// regardless of the lifecycle of that task.
    ///
    /// # Examples
    ///
    /// In this example, a server is started and `spawn` is used to start a new task
    /// that processes each received connection.
    ///
    /// ```no_run
    /// use tokio::net::{TcpListener, TcpStream};
    ///
    /// use std::io;
    ///
    /// async fn process(socket: TcpStream) {
    ///     // ...
    /// # drop(socket);
    /// }
    ///
    /// #[tokio::main]
    /// async fn main() -> io::Result<()> {
    ///     let mut listener = TcpListener::bind("127.0.0.1:8080").await?;
    ///
    ///     loop {
    ///         let (socket, _) = listener.accept().await?;
    ///
    ///         tokio::spawn(async move {
    ///             // Process each socket concurrently.
    ///             process(socket).await
    ///         });
    ///     }
    /// }
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if called from **outside** of the Tokio runtime.
    ///
    /// # Using `!Send` values from a task
    ///
    /// The task supplied to `spawn` must implement `!Send`. However, it is
    /// possible to **use** `!Send` values from the task as long as they only
    /// exist between calls to `.await`.
    ///
    /// For example, this will work:
    ///
    /// ```
    /// use tokio::task;
    ///
    /// use std::rc::Rc;
    ///
    /// fn use_rc(rc: Rc<()>) {
    ///     // Do stuff w/ rc
    /// # drop(rc);
    /// }
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     tokio::spawn(async {
    ///         // Force the `Rc` to stay in a scope with no `.await`
    ///         {
    ///             let rc = Rc::new(());
    ///             use_rc(rc.clone());
    ///         }
    ///
    ///         task::yield_now().await;
    ///     }).await.unwrap();
    /// }
    /// ```
    ///
    /// This will **not** work:
    ///
    /// ```compile_fail
    /// use tokio::task;
    ///
    /// use std::rc::Rc;
    ///
    /// fn use_rc(rc: Rc<()>) {
    ///     // Do stuff w/ rc
    /// # drop(rc);
    /// }
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     tokio::spawn(async {
    ///         let rc = Rc::new(());
    ///
    ///         task::yield_now().await;
    ///
    ///         use_rc(rc.clone());
    ///     }).await.unwrap();
    /// }
    /// ```
    ///
    /// Holding on to a `!Send` value across calls to `.await` will result in
    /// an unfriendly compile error message similar to:
    ///
    /// ```text
    /// `[... some type ...]` cannot be sent between threads safely
    /// ```
    ///
    /// or:
    ///
    /// ```text
    /// error[E0391]: cycle detected when processing `main`
    /// ```
    pub fn spawn<T>(task: T) -> JoinHandle<T::Output>
    where
        T: Future + Send + 'static,
        T::Output: Send + 'static,
    {
        runtime::spawn(task)
    }
}
<commit_msg>fix spawn function documentation (#1940)<commit_after>use crate::runtime;
use crate::task::JoinHandle;

use std::future::Future;

doc_rt_core! {
    /// Spawns a new asynchronous task, returning a
    /// [`JoinHandle`](super::JoinHandle) for it.
    ///
    /// Spawning a task enables the task to execute concurrently to other tasks. The
    /// spawned task may execute on the current thread, or it may be sent to a
    /// different thread to be executed. The specifics depend on the current
    /// [`Runtime`](crate::runtime::Runtime) configuration.
    ///
    /// There is no guarantee that a spawned task will execute to completion.
    /// When a runtime is shutdown, all outstanding tasks are dropped,
    /// regardless of the lifecycle of that task.
    ///
    /// # Examples
    ///
    /// In this example, a server is started and `spawn` is used to start a new task
    /// that processes each received connection.
    ///
    /// ```no_run
    /// use tokio::net::{TcpListener, TcpStream};
    ///
    /// use std::io;
    ///
    /// async fn process(socket: TcpStream) {
    ///     // ...
    /// # drop(socket);
    /// }
    ///
    /// #[tokio::main]
    /// async fn main() -> io::Result<()> {
    ///     let mut listener = TcpListener::bind("127.0.0.1:8080").await?;
    ///
    ///     loop {
    ///         let (socket, _) = listener.accept().await?;
    ///
    ///         tokio::spawn(async move {
    ///             // Process each socket concurrently.
    ///             process(socket).await
    ///         });
    ///     }
    /// }
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if called from **outside** of the Tokio runtime.
    ///
    /// # Using `!Send` values from a task
    ///
    /// The task supplied to `spawn` must implement `Send`. However, it is
    /// possible to **use** `!Send` values from the task as long as they only
    /// exist between calls to `.await`.
    ///
    /// For example, this will work:
    ///
    /// ```
    /// use tokio::task;
    ///
    /// use std::rc::Rc;
    ///
    /// fn use_rc(rc: Rc<()>) {
    ///     // Do stuff w/ rc
    /// # drop(rc);
    /// }
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     tokio::spawn(async {
    ///         // Force the `Rc` to stay in a scope with no `.await`
    ///         {
    ///             let rc = Rc::new(());
    ///             use_rc(rc.clone());
    ///         }
    ///
    ///         task::yield_now().await;
    ///     }).await.unwrap();
    /// }
    /// ```
    ///
    /// This will **not** work:
    ///
    /// ```compile_fail
    /// use tokio::task;
    ///
    /// use std::rc::Rc;
    ///
    /// fn use_rc(rc: Rc<()>) {
    ///     // Do stuff w/ rc
    /// # drop(rc);
    /// }
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     tokio::spawn(async {
    ///         let rc = Rc::new(());
    ///
    ///         task::yield_now().await;
    ///
    ///         use_rc(rc.clone());
    ///     }).await.unwrap();
    /// }
    /// ```
    ///
    /// Holding on to a `!Send` value across calls to `.await` will result in
    /// an unfriendly compile error message similar to:
    ///
    /// ```text
    /// `[... some type ...]` cannot be sent between threads safely
    /// ```
    ///
    /// or:
    ///
    /// ```text
    /// error[E0391]: cycle detected when processing `main`
    /// ```
    pub fn spawn<T>(task: T) -> JoinHandle<T::Output>
    where
        T: Future + Send + 'static,
        T::Output: Send + 'static,
    {
        runtime::spawn(task)
    }
}
<|endoftext|>


<commit_before>extern crate nom;
extern crate wasm;
extern crate wasm_spec;

use nom::{IResult,Err};
use std::str;

fn panic_from(test_name: &str, mut err: Err<&[u8]>) {
    loop {
        match err {
            Err::Code(kind) => panic!("Parse error in {}, (kind {:?}).", test_name, kind),
            Err::Node(_,rest) => { err = *rest }
            Err::Position(kind,pos) => panic!("Parse error in {}, (kind {:?}, pos {}...).", test_name, kind, str::from_utf8(&pos[..128]).unwrap()),
            Err::NodePosition(_,_,rest) => { err = *rest }
        }
    }
}

#[test]
fn spec_tests() {
    for (test_name, test_wast) in wasm_spec::tests() {
        match wasm::parser::text::top_level(test_wast.as_bytes()) {
            IResult::Done(_,_) => (),
            IResult::Error(err) => panic_from(test_name, err),
            IResult::Incomplete(need) => panic!("Incomplete parse in {}, {:?}.", test_name, need),
        }
    }
}
<commit_msg>Commented out tests for now.<commit_after>// extern crate nom;
// extern crate wasm;
// extern crate wasm_spec;

// use nom::{IResult,Err};
// use std::str;

// fn print(mut err: Err<&[u8]>) {
//     loop {
//         match err {
//             Err::Code(kind) => { println!("Kind {:?}.", kind); return; }
//             Err::Node(kind, rest) => { println!("Nested kind {:?}" , kind); err = *rest }
//             Err::Position(kind,pos) => { println!("Kind {:?} at {}...", kind, str::from_utf8(&pos[..32]).unwrap()); return; }
//             Err::NodePosition(kind, pos, rest) => { println!("Nested kind {:?} at {}...", kind, str::from_utf8(&pos[..32]).unwrap()); err = *rest }
//         }
//     }
// }

// #[test]
// fn spec_tests() {
//     for (test_name, test_wast) in wasm_spec::tests() {
//         match wasm::parser::text::top_level(test_wast.as_bytes()) {
//             IResult::Done(_,_) => (),
//             IResult::Error(err) => { print(err); panic!("Parse error in {}", test_name) },
//             IResult::Incomplete(need) => panic!("Incomplete parse in {}, {:?}.", test_name, need),
//         }
//     }
// }
<|endoftext|>


<commit_before>pub mod error;
pub mod ops;
pub mod vm;

#[test]
fn it_works() {
}
<commit_msg>Silence some warnings for `chip8_vm`<commit_after>// Silence 'core' feature warnings
// for `error:Error` and such
#![feature(core)]
// Silence 'io' feature warnings
// for `BufWriter` and such
#![feature(io)]

pub mod error;
pub mod ops;
pub mod vm;

#[test]
fn it_works() {
}
<|endoftext|>


<commit_before>use cairo;
use cairo_sys;
use glib::translate::*;
use glib_sys;
use libc;
use pango;
use pango_sys;

use color::*;
use error::*;
use node::NodeType;
use node::RsvgNode;
use opacity::*;
use path_builder::RsvgPathBuilder;
use state::RsvgState;

pub enum RsvgDrawingCtx {}

extern "C" {
    fn rsvg_drawing_ctx_get_dpi(
        draw_ctx: *const RsvgDrawingCtx,
        out_dpi_x: *mut f64,
        out_dpi_y: *mut f64,
    );

    fn rsvg_drawing_ctx_get_normalized_font_size(draw_ctx: *const RsvgDrawingCtx) -> f64;

    fn rsvg_drawing_ctx_get_view_box_size(
        draw_ctx: *const RsvgDrawingCtx,
        out_x: *mut f64,
        out_y: *mut f64,
    );

    fn rsvg_drawing_ctx_push_view_box(draw_ctx: *const RsvgDrawingCtx, width: f64, height: f64);

    fn rsvg_drawing_ctx_pop_view_box(draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_drawing_ctx_acquire_node(
        draw_ctx: *const RsvgDrawingCtx,
        url: *const libc::c_char,
    ) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_acquire_node_of_type(
        draw_ctx: *const RsvgDrawingCtx,
        url: *const libc::c_char,
        node_type: NodeType,
    ) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_release_node(draw_ctx: *const RsvgDrawingCtx, node: *mut RsvgNode);

    fn rsvg_drawing_ctx_get_current_state_affine(draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix;

    fn rsvg_drawing_ctx_set_current_state_affine(
        draw_ctx: *const RsvgDrawingCtx,
        affine: *const cairo::Matrix,
    );

    fn rsvg_drawing_ctx_get_pango_context(
        draw_ctx: *const RsvgDrawingCtx,
    ) -> *mut pango_sys::PangoContext;

    fn rsvg_drawing_ctx_add_clipping_rect(
        draw_ctx: *const RsvgDrawingCtx,
        x: f64,
        y: f64,
        w: f64,
        h: f64,
    );

    fn rsvg_drawing_ctx_draw_node_from_stack(
        draw_ctx: *const RsvgDrawingCtx,
        node: *const RsvgNode,
        dominate: i32,
    );

    fn rsvg_current_state(draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState;
    fn rsvg_state_new() -> *mut RsvgState;
    fn rsvg_state_free(state: *mut RsvgState);
    fn rsvg_state_reinit(state: *mut RsvgState);
    fn rsvg_state_reconstruct(state: *mut RsvgState, node: *const RsvgNode);
    fn rsvg_state_is_overflow(state: *const RsvgState) -> glib_sys::gboolean;
    fn rsvg_state_has_overflow(state: *const RsvgState) -> glib_sys::gboolean;
    fn rsvg_state_get_cond_true(state: *const RsvgState) -> glib_sys::gboolean;
    fn rsvg_state_set_cond_true(state: *const RsvgState, cond_true: glib_sys::gboolean);
    fn rsvg_state_get_stop_color(state: *const RsvgState) -> *const ColorSpec;
    fn rsvg_state_get_stop_opacity(state: *const RsvgState) -> *const OpacitySpec;
    fn rsvg_state_get_current_color(state: *const RsvgState) -> u32;

    fn rsvg_state_push(draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_state_pop(draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_state_reinherit_top(
        draw_ctx: *const RsvgDrawingCtx,
        state: *mut RsvgState,
        dominate: libc::c_int,
    );

    fn rsvg_push_discrete_layer(draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_pop_discrete_layer(draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_drawing_ctx_render_path_builder(
        draw_ctx: *const RsvgDrawingCtx,
        builder: *const RsvgPathBuilder,
    );
    fn rsvg_drawing_ctx_render_surface(
        draw_ctx: *const RsvgDrawingCtx,
        surface: *const cairo_sys::cairo_surface_t,
        x: f64,
        y: f64,
        w: f64,
        h: f64,
    );

    fn rsvg_cairo_get_cairo_context(draw_ctx: *const RsvgDrawingCtx) -> *mut cairo_sys::cairo_t;
    fn rsvg_cairo_set_cairo_context(draw_ctx: *const RsvgDrawingCtx, cr: *const cairo_sys::cairo_t);
}

pub fn get_dpi(draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut dpi_x: f64 = 0.0;
    let mut dpi_y: f64 = 0.0;

    unsafe {
        rsvg_drawing_ctx_get_dpi(draw_ctx, &mut dpi_x, &mut dpi_y);
    }

    (dpi_x, dpi_y)
}

pub fn get_normalized_font_size(draw_ctx: *const RsvgDrawingCtx) -> f64 {
    unsafe { rsvg_drawing_ctx_get_normalized_font_size(draw_ctx) }
}

pub fn get_view_box_size(draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut w: f64 = 0.0;
    let mut h: f64 = 0.0;

    unsafe {
        rsvg_drawing_ctx_get_view_box_size(draw_ctx, &mut w, &mut h);
    }

    (w, h)
}

pub fn push_view_box(draw_ctx: *const RsvgDrawingCtx, width: f64, height: f64) {
    unsafe {
        rsvg_drawing_ctx_push_view_box(draw_ctx, width, height);
    }
}

pub fn pop_view_box(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_drawing_ctx_pop_view_box(draw_ctx);
    }
}

pub fn get_acquired_node(draw_ctx: *const RsvgDrawingCtx, url: &str) -> Option<AcquiredNode> {
    let raw_node = unsafe { rsvg_drawing_ctx_acquire_node(draw_ctx, str::to_glib_none(url).0) };

    if raw_node.is_null() {
        None
    } else {
        Some(AcquiredNode(draw_ctx, raw_node))
    }
}

pub fn get_acquired_node_of_type(
    draw_ctx: *const RsvgDrawingCtx,
    url: &str,
    node_type: NodeType,
) -> Option<AcquiredNode> {
    let raw_node = unsafe {
        rsvg_drawing_ctx_acquire_node_of_type(draw_ctx, str::to_glib_none(url).0, node_type)
    };

    if raw_node.is_null() {
        None
    } else {
        Some(AcquiredNode(draw_ctx, raw_node))
    }
}

pub fn state_reinherit_top(draw_ctx: *const RsvgDrawingCtx, state: *mut RsvgState, dominate: i32) {
    unsafe {
        rsvg_state_reinherit_top(draw_ctx, state, dominate);
    }
}

pub fn push_discrete_layer(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_push_discrete_layer(draw_ctx);
    }
}

pub fn pop_discrete_layer(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_pop_discrete_layer(draw_ctx);
    }
}

pub fn render_path_builder(draw_ctx: *const RsvgDrawingCtx, builder: &RsvgPathBuilder) {
    unsafe {
        rsvg_drawing_ctx_render_path_builder(draw_ctx, builder);
    }
}

pub fn render_surface(
    draw_ctx: *const RsvgDrawingCtx,
    surface: &cairo::ImageSurface,
    x: f64,
    y: f64,
    w: f64,
    h: f64,
) {
    unsafe {
        rsvg_drawing_ctx_render_surface(draw_ctx, surface.to_raw_none(), x, y, w, h);
    }
}

pub fn get_cairo_context(draw_ctx: *const RsvgDrawingCtx) -> cairo::Context {
    unsafe {
        let raw_cr = rsvg_cairo_get_cairo_context(draw_ctx);

        cairo::Context::from_glib_none(raw_cr)
    }
}

pub fn set_cairo_context(draw_ctx: *const RsvgDrawingCtx, cr: &cairo::Context) {
    unsafe {
        let raw_cr = cr.to_glib_none().0;

        rsvg_cairo_set_cairo_context(draw_ctx, raw_cr);
    }
}

pub fn get_current_state_affine(draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix {
    unsafe { rsvg_drawing_ctx_get_current_state_affine(draw_ctx) }
}

pub fn set_current_state_affine(draw_ctx: *const RsvgDrawingCtx, affine: cairo::Matrix) {
    unsafe {
        rsvg_drawing_ctx_set_current_state_affine(draw_ctx, &affine);
    }
}

pub fn get_pango_context(draw_ctx: *const RsvgDrawingCtx) -> pango::Context {
    unsafe { from_glib_full(rsvg_drawing_ctx_get_pango_context(draw_ctx)) }
}

pub fn add_clipping_rect(draw_ctx: *const RsvgDrawingCtx, x: f64, y: f64, w: f64, h: f64) {
    unsafe {
        rsvg_drawing_ctx_add_clipping_rect(draw_ctx, x, y, w, h);
    }
}

pub fn draw_node_from_stack(draw_ctx: *const RsvgDrawingCtx, node: *const RsvgNode, dominate: i32) {
    unsafe {
        rsvg_drawing_ctx_draw_node_from_stack(draw_ctx, node, dominate);
    }
}

pub fn get_current_state(draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState {
    unsafe { rsvg_current_state(draw_ctx) }
}

pub fn state_new() -> *mut RsvgState {
    unsafe { rsvg_state_new() }
}

pub fn state_free(state: *mut RsvgState) {
    unsafe {
        rsvg_state_free(state);
    }
}

pub fn state_reinit(state: *mut RsvgState) {
    unsafe {
        rsvg_state_reinit(state);
    }
}

pub fn state_reconstruct(state: *mut RsvgState, node: *const RsvgNode) {
    unsafe {
        rsvg_state_reconstruct(state, node);
    }
}

pub fn state_is_overflow(state: *const RsvgState) -> bool {
    unsafe { from_glib(rsvg_state_is_overflow(state)) }
}

pub fn state_has_overflow(state: *const RsvgState) -> bool {
    unsafe { from_glib(rsvg_state_has_overflow(state)) }
}

pub fn state_get_cond_true(state: *const RsvgState) -> bool {
    unsafe { from_glib(rsvg_state_get_cond_true(state)) }
}

pub fn state_set_cond_true(state: *const RsvgState, cond_true: bool) {
    unsafe {
        rsvg_state_set_cond_true(state, cond_true.to_glib());
    }
}

pub fn state_push(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_push(draw_ctx);
    }
}

pub fn state_pop(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_pop(draw_ctx);
    }
}

pub fn state_get_stop_color(state: *const RsvgState) -> Result<Option<Color>, AttributeError> {
    unsafe {
        let spec_ptr = rsvg_state_get_stop_color(state);

        if spec_ptr.is_null() {
            Ok(None)
        } else {
            Color::from_color_spec(&*spec_ptr).map(Some)
        }
    }
}

pub fn state_get_stop_opacity(state: *const RsvgState) -> Result<Option<Opacity>, AttributeError> {
    unsafe {
        let opacity_ptr = rsvg_state_get_stop_opacity(state);

        if opacity_ptr.is_null() {
            Ok(None)
        } else {
            Opacity::from_opacity_spec(&*opacity_ptr).map(Some)
        }
    }
}

pub fn state_get_current_color(state: *const RsvgState) -> Color {
    let argb = unsafe { rsvg_state_get_current_color(state) };

    Color::from(argb)
}

pub struct AcquiredNode(*const RsvgDrawingCtx, *mut RsvgNode);

impl Drop for AcquiredNode {
    fn drop(&mut self) {
        unsafe {
            rsvg_drawing_ctx_release_node(self.0, self.1);
        }
    }
}

impl AcquiredNode {
    pub fn get(&self) -> RsvgNode {
        unsafe { (*self.1).clone() }
    }
}
<commit_msg>drawing_ctx::set_affine_on_cr(): Bind to Rust<commit_after>use cairo;
use cairo_sys;
use glib::translate::*;
use glib_sys;
use libc;
use pango;
use pango_sys;

use color::*;
use error::*;
use node::NodeType;
use node::RsvgNode;
use opacity::*;
use path_builder::RsvgPathBuilder;
use state::RsvgState;

pub enum RsvgDrawingCtx {}

extern "C" {
    fn rsvg_drawing_ctx_get_dpi(
        draw_ctx: *const RsvgDrawingCtx,
        out_dpi_x: *mut f64,
        out_dpi_y: *mut f64,
    );

    fn rsvg_drawing_ctx_get_normalized_font_size(draw_ctx: *const RsvgDrawingCtx) -> f64;

    fn rsvg_drawing_ctx_get_view_box_size(
        draw_ctx: *const RsvgDrawingCtx,
        out_x: *mut f64,
        out_y: *mut f64,
    );

    fn rsvg_drawing_ctx_push_view_box(draw_ctx: *const RsvgDrawingCtx, width: f64, height: f64);

    fn rsvg_drawing_ctx_pop_view_box(draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_drawing_ctx_acquire_node(
        draw_ctx: *const RsvgDrawingCtx,
        url: *const libc::c_char,
    ) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_acquire_node_of_type(
        draw_ctx: *const RsvgDrawingCtx,
        url: *const libc::c_char,
        node_type: NodeType,
    ) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_release_node(draw_ctx: *const RsvgDrawingCtx, node: *mut RsvgNode);

    fn rsvg_drawing_ctx_get_current_state_affine(draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix;

    fn rsvg_drawing_ctx_set_current_state_affine(
        draw_ctx: *const RsvgDrawingCtx,
        affine: *const cairo::Matrix,
    );

    fn rsvg_drawing_ctx_set_affine_on_cr(
        draw_ctx: *const RsvgDrawingCtx,
        cr: *mut cairo_sys::cairo_t,
        affine: *const cairo::Matrix,
    );

    fn rsvg_drawing_ctx_get_pango_context(
        draw_ctx: *const RsvgDrawingCtx,
    ) -> *mut pango_sys::PangoContext;

    fn rsvg_drawing_ctx_add_clipping_rect(
        draw_ctx: *const RsvgDrawingCtx,
        x: f64,
        y: f64,
        w: f64,
        h: f64,
    );

    fn rsvg_drawing_ctx_draw_node_from_stack(
        draw_ctx: *const RsvgDrawingCtx,
        node: *const RsvgNode,
        dominate: i32,
    );

    fn rsvg_current_state(draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState;
    fn rsvg_state_new() -> *mut RsvgState;
    fn rsvg_state_free(state: *mut RsvgState);
    fn rsvg_state_reinit(state: *mut RsvgState);
    fn rsvg_state_reconstruct(state: *mut RsvgState, node: *const RsvgNode);
    fn rsvg_state_is_overflow(state: *const RsvgState) -> glib_sys::gboolean;
    fn rsvg_state_has_overflow(state: *const RsvgState) -> glib_sys::gboolean;
    fn rsvg_state_get_cond_true(state: *const RsvgState) -> glib_sys::gboolean;
    fn rsvg_state_set_cond_true(state: *const RsvgState, cond_true: glib_sys::gboolean);
    fn rsvg_state_get_stop_color(state: *const RsvgState) -> *const ColorSpec;
    fn rsvg_state_get_stop_opacity(state: *const RsvgState) -> *const OpacitySpec;
    fn rsvg_state_get_current_color(state: *const RsvgState) -> u32;

    fn rsvg_state_push(draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_state_pop(draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_state_reinherit_top(
        draw_ctx: *const RsvgDrawingCtx,
        state: *mut RsvgState,
        dominate: libc::c_int,
    );

    fn rsvg_push_discrete_layer(draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_pop_discrete_layer(draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_drawing_ctx_render_path_builder(
        draw_ctx: *const RsvgDrawingCtx,
        builder: *const RsvgPathBuilder,
    );
    fn rsvg_drawing_ctx_render_surface(
        draw_ctx: *const RsvgDrawingCtx,
        surface: *const cairo_sys::cairo_surface_t,
        x: f64,
        y: f64,
        w: f64,
        h: f64,
    );

    fn rsvg_cairo_get_cairo_context(draw_ctx: *const RsvgDrawingCtx) -> *mut cairo_sys::cairo_t;
    fn rsvg_cairo_set_cairo_context(draw_ctx: *const RsvgDrawingCtx, cr: *const cairo_sys::cairo_t);
}

pub fn get_dpi(draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut dpi_x: f64 = 0.0;
    let mut dpi_y: f64 = 0.0;

    unsafe {
        rsvg_drawing_ctx_get_dpi(draw_ctx, &mut dpi_x, &mut dpi_y);
    }

    (dpi_x, dpi_y)
}

pub fn get_normalized_font_size(draw_ctx: *const RsvgDrawingCtx) -> f64 {
    unsafe { rsvg_drawing_ctx_get_normalized_font_size(draw_ctx) }
}

pub fn get_view_box_size(draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut w: f64 = 0.0;
    let mut h: f64 = 0.0;

    unsafe {
        rsvg_drawing_ctx_get_view_box_size(draw_ctx, &mut w, &mut h);
    }

    (w, h)
}

pub fn push_view_box(draw_ctx: *const RsvgDrawingCtx, width: f64, height: f64) {
    unsafe {
        rsvg_drawing_ctx_push_view_box(draw_ctx, width, height);
    }
}

pub fn pop_view_box(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_drawing_ctx_pop_view_box(draw_ctx);
    }
}

pub fn get_acquired_node(draw_ctx: *const RsvgDrawingCtx, url: &str) -> Option<AcquiredNode> {
    let raw_node = unsafe { rsvg_drawing_ctx_acquire_node(draw_ctx, str::to_glib_none(url).0) };

    if raw_node.is_null() {
        None
    } else {
        Some(AcquiredNode(draw_ctx, raw_node))
    }
}

pub fn get_acquired_node_of_type(
    draw_ctx: *const RsvgDrawingCtx,
    url: &str,
    node_type: NodeType,
) -> Option<AcquiredNode> {
    let raw_node = unsafe {
        rsvg_drawing_ctx_acquire_node_of_type(draw_ctx, str::to_glib_none(url).0, node_type)
    };

    if raw_node.is_null() {
        None
    } else {
        Some(AcquiredNode(draw_ctx, raw_node))
    }
}

pub fn state_reinherit_top(draw_ctx: *const RsvgDrawingCtx, state: *mut RsvgState, dominate: i32) {
    unsafe {
        rsvg_state_reinherit_top(draw_ctx, state, dominate);
    }
}

pub fn push_discrete_layer(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_push_discrete_layer(draw_ctx);
    }
}

pub fn pop_discrete_layer(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_pop_discrete_layer(draw_ctx);
    }
}

pub fn render_path_builder(draw_ctx: *const RsvgDrawingCtx, builder: &RsvgPathBuilder) {
    unsafe {
        rsvg_drawing_ctx_render_path_builder(draw_ctx, builder);
    }
}

pub fn render_surface(
    draw_ctx: *const RsvgDrawingCtx,
    surface: &cairo::ImageSurface,
    x: f64,
    y: f64,
    w: f64,
    h: f64,
) {
    unsafe {
        rsvg_drawing_ctx_render_surface(draw_ctx, surface.to_raw_none(), x, y, w, h);
    }
}

pub fn get_cairo_context(draw_ctx: *const RsvgDrawingCtx) -> cairo::Context {
    unsafe {
        let raw_cr = rsvg_cairo_get_cairo_context(draw_ctx);

        cairo::Context::from_glib_none(raw_cr)
    }
}

pub fn set_cairo_context(draw_ctx: *const RsvgDrawingCtx, cr: &cairo::Context) {
    unsafe {
        let raw_cr = cr.to_glib_none().0;

        rsvg_cairo_set_cairo_context(draw_ctx, raw_cr);
    }
}

pub fn get_current_state_affine(draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix {
    unsafe { rsvg_drawing_ctx_get_current_state_affine(draw_ctx) }
}

pub fn set_current_state_affine(draw_ctx: *const RsvgDrawingCtx, affine: cairo::Matrix) {
    unsafe {
        rsvg_drawing_ctx_set_current_state_affine(draw_ctx, &affine);
    }
}

pub fn set_affine_on_cr(
    draw_ctx: *const RsvgDrawingCtx,
    cr: &cairo::Context,
    affine: &cairo::Matrix,
) {
    unsafe {
        rsvg_drawing_ctx_set_affine_on_cr(
            draw_ctx,
            cr.to_glib_none().0,
            affine as *const cairo::Matrix,
        );
    }
}

pub fn get_pango_context(draw_ctx: *const RsvgDrawingCtx) -> pango::Context {
    unsafe { from_glib_full(rsvg_drawing_ctx_get_pango_context(draw_ctx)) }
}

pub fn add_clipping_rect(draw_ctx: *const RsvgDrawingCtx, x: f64, y: f64, w: f64, h: f64) {
    unsafe {
        rsvg_drawing_ctx_add_clipping_rect(draw_ctx, x, y, w, h);
    }
}

pub fn draw_node_from_stack(draw_ctx: *const RsvgDrawingCtx, node: *const RsvgNode, dominate: i32) {
    unsafe {
        rsvg_drawing_ctx_draw_node_from_stack(draw_ctx, node, dominate);
    }
}

pub fn get_current_state(draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState {
    unsafe { rsvg_current_state(draw_ctx) }
}

pub fn state_new() -> *mut RsvgState {
    unsafe { rsvg_state_new() }
}

pub fn state_free(state: *mut RsvgState) {
    unsafe {
        rsvg_state_free(state);
    }
}

pub fn state_reinit(state: *mut RsvgState) {
    unsafe {
        rsvg_state_reinit(state);
    }
}

pub fn state_reconstruct(state: *mut RsvgState, node: *const RsvgNode) {
    unsafe {
        rsvg_state_reconstruct(state, node);
    }
}

pub fn state_is_overflow(state: *const RsvgState) -> bool {
    unsafe { from_glib(rsvg_state_is_overflow(state)) }
}

pub fn state_has_overflow(state: *const RsvgState) -> bool {
    unsafe { from_glib(rsvg_state_has_overflow(state)) }
}

pub fn state_get_cond_true(state: *const RsvgState) -> bool {
    unsafe { from_glib(rsvg_state_get_cond_true(state)) }
}

pub fn state_set_cond_true(state: *const RsvgState, cond_true: bool) {
    unsafe {
        rsvg_state_set_cond_true(state, cond_true.to_glib());
    }
}

pub fn state_push(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_push(draw_ctx);
    }
}

pub fn state_pop(draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_pop(draw_ctx);
    }
}

pub fn state_get_stop_color(state: *const RsvgState) -> Result<Option<Color>, AttributeError> {
    unsafe {
        let spec_ptr = rsvg_state_get_stop_color(state);

        if spec_ptr.is_null() {
            Ok(None)
        } else {
            Color::from_color_spec(&*spec_ptr).map(Some)
        }
    }
}

pub fn state_get_stop_opacity(state: *const RsvgState) -> Result<Option<Opacity>, AttributeError> {
    unsafe {
        let opacity_ptr = rsvg_state_get_stop_opacity(state);

        if opacity_ptr.is_null() {
            Ok(None)
        } else {
            Opacity::from_opacity_spec(&*opacity_ptr).map(Some)
        }
    }
}

pub fn state_get_current_color(state: *const RsvgState) -> Color {
    let argb = unsafe { rsvg_state_get_current_color(state) };

    Color::from(argb)
}

pub struct AcquiredNode(*const RsvgDrawingCtx, *mut RsvgNode);

impl Drop for AcquiredNode {
    fn drop(&mut self) {
        unsafe {
            rsvg_drawing_ctx_release_node(self.0, self.1);
        }
    }
}

impl AcquiredNode {
    pub fn get(&self) -> RsvgNode {
        unsafe { (*self.1).clone() }
    }
}
<|endoftext|>


<commit_before>extern crate curl;

#[cfg(feature = "pi")]
extern crate wiringpi;

use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::io::prelude::*;
use std::io::stdout;
use std::{thread, time};
use std::str;

use curl::easy::Easy;

static CONFIG_FILE_NAME: &'static str = "doorstate.config";

struct API {
    url: String,
    rate_ms: i64,
    pre_shared_key: String
}

struct GPIO {
    pin: i8
}

fn config() -> (API, GPIO)
{
    let path = Path::new(CONFIG_FILE_NAME);
    let path_display = path.display();

    let mut file = match File::open(&path) {
        Err(why) => panic!(
            "Couldn't open {}: {}",
            path_display,
            why.description()),
        Ok(file) => file,
    };

    let mut config = String::new();

    match file.read_to_string(&mut config) {
        Err(why) => panic!(
            "Couldn't read {}: {}",
            path_display,
            why.description()),
        //Ok(_) => print!("{} contains:\n{}", path_display, config),
        Ok(_) => {},
    };

    let mut api = API {
        url: String::new(),
        pre_shared_key: String::new(),
        rate_ms: -1
    };

    let mut gpio = GPIO {
        pin: -1
    };

    for line in config.lines() {
        // Ignore comments (lines starting with '#')
        if !line.trim().starts_with("#") {
            //println!("{}", line);
            let tokens: Vec<&str> = line.splitn(2, "=").collect();

            let key = tokens[0].trim();
            let value = tokens[1].trim();

            match key {
                "api.url" => api.url = value.to_string(),
                "api.rate-ms" => api.rate_ms = value.parse::<i64>().unwrap(),
                "api.pre-shared-key" => api.pre_shared_key = value.to_string(),
                "gpio.pin" => gpio.pin = value.parse::<i8>().unwrap(),
                _ => {},
            }
        }
    }

    (api, gpio)
}

#[cfg(feature = "pi")]
fn read_doorstate() {
}

fn send_doorstate(url: String, data: String) {
    let mut easy = Easy::new();
    let mut dst = Vec::new();

    easy.url(&url).unwrap();
    let mut transfer = easy.transfer();
    transfer.write_function(|data| {
        dst.extend_from_slice(data);
        Ok(data.len())
    }).unwrap();
    transfer.perform().unwrap();
    let mut clone = &dst.clone();
    let result = str::from_utf8(&clone).unwrap();

    println!("{}", result);
}

#[cfg(feature = "pi")]
fn setup_gpio(pin: i8) -> WiringPi {
    let pi = wiringpi::setup();
    let pin = pi.input_pin(pin);

    pi
}

#[allow(unused_variables)]
fn setup_gpio(pin: i8) {
}

fn main() {
    let (api, gpio) = config();
    let duration;

    let pi = setup_gpio(gpio.pin);

    if api.rate_ms > -1 {
        duration = time::Duration::from_millis(api.rate_ms as u64);
    } else {
        duration = time::Duration::from_millis(0);
    }

    send_doorstate(api.url, "".to_string());

    /*
    loop {
        println!("Test");

        if pi != () {
            println!("pi is not equal to unit type");
        }

        if duration > time::Duration::from_millis(0) {
            thread::sleep(duration);
        }
    }
    */
}
<commit_msg>Fix issue with storing the result<commit_after>extern crate curl;

#[cfg(feature = "pi")]
extern crate wiringpi;

use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::io::prelude::*;
use std::io::stdout;
use std::{thread, time};
use std::str;

use curl::easy::Easy;

static CONFIG_FILE_NAME: &'static str = "doorstate.config";

struct API {
    url: String,
    rate_ms: i64,
    pre_shared_key: String
}

struct GPIO {
    pin: i8
}

fn config() -> (API, GPIO)
{
    let path = Path::new(CONFIG_FILE_NAME);
    let path_display = path.display();

    let mut file = match File::open(&path) {
        Err(why) => panic!(
            "Couldn't open {}: {}",
            path_display,
            why.description()),
        Ok(file) => file,
    };

    let mut config = String::new();

    match file.read_to_string(&mut config) {
        Err(why) => panic!(
            "Couldn't read {}: {}",
            path_display,
            why.description()),
        //Ok(_) => print!("{} contains:\n{}", path_display, config),
        Ok(_) => {},
    };

    let mut api = API {
        url: String::new(),
        pre_shared_key: String::new(),
        rate_ms: -1
    };

    let mut gpio = GPIO {
        pin: -1
    };

    for line in config.lines() {
        // Ignore comments (lines starting with '#')
        if !line.trim().starts_with("#") {
            //println!("{}", line);
            let tokens: Vec<&str> = line.splitn(2, "=").collect();

            let key = tokens[0].trim();
            let value = tokens[1].trim();

            match key {
                "api.url" => api.url = value.to_string(),
                "api.rate-ms" => api.rate_ms = value.parse::<i64>().unwrap(),
                "api.pre-shared-key" => api.pre_shared_key = value.to_string(),
                "gpio.pin" => gpio.pin = value.parse::<i8>().unwrap(),
                _ => {},
            }
        }
    }

    (api, gpio)
}

#[cfg(feature = "pi")]
fn read_doorstate() {
}

fn send_doorstate(url: String, data: String) {
    let mut easy = Easy::new();
    let mut dst = Vec::new();

    easy.url(&url).unwrap();

    // This scope is required to end the borrow of dst
    {
        let mut transfer = easy.transfer();
        transfer.write_function(|data| {
            dst.extend_from_slice(data);
            Ok(data.len())
        }).unwrap();
        transfer.perform().unwrap();
    }

    let mut clone = &dst.clone();
    let challenge = str::from_utf8(&clone).unwrap();

    println!("{}", challenge);
}

#[cfg(feature = "pi")]
fn setup_gpio(pin: i8) -> WiringPi {
    let pi = wiringpi::setup();
    let pin = pi.input_pin(pin);

    pi
}

#[allow(unused_variables)]
fn setup_gpio(pin: i8) {
}

fn main() {
    let (api, gpio) = config();
    let duration;

    let pi = setup_gpio(gpio.pin);

    if api.rate_ms > -1 {
        duration = time::Duration::from_millis(api.rate_ms as u64);
    } else {
        duration = time::Duration::from_millis(0);
    }

    send_doorstate(api.url, "".to_string());

    /*
    loop {
        println!("Test");

        if pi != () {
            println!("pi is not equal to unit type");
        }

        if duration > time::Duration::from_millis(0) {
            thread::sleep(duration);
        }
    }
    */
}
<|endoftext|>


<commit_before>// from: https://github.com/Maktm/FLIRTDB/blob/1f5763535e02d7cccf2f90a96a8ebaa36e9b2495/cmt/windows/libcmt_15_msvc_x86.pat#L355
//
//    3B0D........F27502F2C3F2E9...................................... 00 0000 0011 :0000 @__security_check_cookie@4 :000B@ $failure$4 ^0002 ___security_cookie ^000D ___report_gsfailure
//    ^^^^        ^^^^^^^^^^^^^^   bytes
//        ^^^^^^^^                 relocations
//
//                                                                     00 0000 0011
//                                                                     ^^ number of bytes crc16'd
//                                                                        ^^^^ crc16
//                                                                             ^^^^ size of fn
//
//                                                                                :0000 @__security_check_cookie@4
//                                                                                ^^^^^ offset of match
//                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^ name
//
//                                                                                :000B@ $failure$4
//                                                                                ^^^^^^ local offset
//                                                                                ^^^^^^^^^^ local name
//
//                                                                                ^0002 ___security_cookie
//                                                                                ^^^^^ reference offset
//                                                                                ^^^^^^^^^^^^^^^^^^ reference name

use log::{trace};
use nom::IResult;
use nom::multi::many0;
use nom::multi::many1;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_till1;
use nom::bytes::complete::take_while;
use nom::bytes::complete::take_while_m_n;
use nom::branch::alt;
use nom::sequence::pair;
use nom::combinator::map;
use nom::combinator::map_res;
use nom::combinator::peek;
use nom::combinator::opt;
use failure::{Error, Fail};

use super::{SigElement, ByteSignature, Offset, Name, Symbol, FlirtSignature};

#[derive(Debug, Fail)]
pub enum PatError {
    #[fail(display = "The pattern is not supported")]
    NotSupported,
    #[fail(display = "The .pat file is corrupt (or unsupported)")]
    CorruptPatFile,
}

fn whitespace(input: &str) -> IResult<&str, &str> {
    take_while(|c| c == ' ')(input)
}

fn is_hex_digit(c: char) -> bool {
  c.is_digit(16)
}

fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> {
  u8::from_str_radix(input, 16)
}

/// parse a single hex byte, like `AB`
fn hex(input: &str) -> IResult<&str, u8> {
    map_res(
        take_while_m_n(2, 2, is_hex_digit),
        from_hex
    )(input)
}

fn hex_byte(input: &str) -> IResult<&str, u8> {
    let (input, v) = hex(input)?;
    Ok((input, v))
}

fn hex_word(input: &str) -> IResult<&str, u16> {
    let (input, v1) = hex(input)?;
    let (input, v2) = hex(input)?;
    let v: u16 = ((v1 as u16) << 2) | (v2 as u16);
    Ok((input, v))
}

/// parse a single byte signature element, which is either a hex byte or a wildcard.
fn sig_element(input: &str) -> IResult<&str, SigElement> {
    alt((
        map(hex, |v| SigElement::Byte(v)),
        map(tag(".."), |_| SigElement::Wildcard)
    ))(input)
}

/// parse byte signature elements, hex or wildcard.
fn byte_signature(input: &str) -> IResult<&str, ByteSignature> {
    let (input, elems) = many1(sig_element)(input)?;
    Ok((input, ByteSignature(elems)))
}

/// parse a hex-encoded offset, like `0000`
/// max is 0x8000.
/// TODO: this can be negative.
fn hex_offset(input: &str) -> IResult<&str, u16> {
    hex_word(input)
}

/// parse a public offset, like `:0000`
fn public_offset(input: &str) -> IResult<&str, u16> {
    let (input, _) = tag(":")(input)?;
    let (input, offset) = hex_offset(input)?;
    let (input, _) = peek(tag(" "))(input)?;

    Ok((input, offset))
}

/// parse a local offset, like `:000B@`
fn local_offset(input: &str) -> IResult<&str, u16> {
    let (input, _) = tag(":")(input)?;
    let (input, offset) = hex_offset(input)?;
    let (input, _) = tag("@")(input)?;

    Ok((input, offset))
}

/// parse an external reference, like `^0002`
fn reference_offset(input: &str) -> IResult<&str, u16> {
    let (input, _) = tag("^")(input)?;
    let (input, offset) = hex_offset(input)?;

    Ok((input, offset))
}

fn offset(input: &str) -> IResult<&str, Offset> {
    alt((
        // this must go first, because it has trailing `@`,
        // otherwise, the same as public.
        map(local_offset, |v| Offset::Local(v)),
        map(public_offset, |v| Offset::Public(v)),
        map(reference_offset, |v| Offset::Reference(v))
    ))(input)
}

fn symbol_name(input: &str) -> IResult<&str, &str> {
    take_till1(|c| c == ' ' || c == '\n')(input)
}

/// parse a (offset, symbol) pair.
///
/// note: this also consumes trailing spaces so that a sequence of these can be easily parsed.
fn symbol(input: &str) -> IResult<&str, Symbol> {
    let (input, offset) = offset(input)?;
    let (input, _) = whitespace(input)?;
    let (input, name) = symbol_name(input)?;
    let (input, _) = opt(whitespace)(input)?;
    match offset {
        Offset::Public(v) => {
            Ok((input, Symbol::Public(Name {name: name.to_string(), offset: v})))
        },
        Offset::Local(v) => {
            Ok((input, Symbol::Local(Name {name: name.to_string(), offset: v})))
        },
        Offset::Reference(v) => {
            Ok((input, Symbol::Reference(Name {name: name.to_string(), offset: v})))
        },
    }
}

fn symbols(input: &str) -> IResult<&str, Vec<Symbol>> {
    many1(symbol)(input)
}

fn pat_signature(input: &str) -> IResult<&str, FlirtSignature> {
    let (input, byte_sig) = byte_signature(input)?;
    let (input, _) = whitespace(input)?;
    trace!("sig: {:?}", byte_sig);

    let (input, size_of_bytes_crc16) = hex_byte(input)?;
    let (input, _) = whitespace(input)?;
    trace!("crc16 len: {:02x}", size_of_bytes_crc16);

    let (input, crc16) = hex_word(input)?;
    let (input, _) = whitespace(input)?;
    trace!("crc16: {:04x}", crc16);

    let (input, size_of_function) = hex_word(input)?;
    let (input, _) = whitespace(input)?;
    trace!("function size: {:04x}", size_of_function);

    let (input, names) = symbols(input)?;
    trace!("names: {:?}", names);

    let (input, footer) = opt(byte_signature)(input)?;
    trace!("footer: {:?}", footer);

    Ok((input, FlirtSignature {
        byte_sig,
        size_of_bytes_crc16,
        crc16,
        size_of_function,
        names,
        footer,
    }))
}

/// parse a .pat file into FLIRT signatures.
fn pat(input: &str) -> IResult<&str, Vec<FlirtSignature>> {
    // each signature is newline separated.
    // drop the newline after we've parsed it.
    let pat_sig_line = map(pair(pat_signature, tag("\n")), |p| p.0);
    let (input, sigs) = many0(pat_sig_line)(input)?;

    // the file ends with `---`.
    let (input, _) = tag("---")(input)?;

    // TODO: assert there is nothing left in the file

    Ok((input, sigs))
}

/// ```
/// use flirt::pat;
/// let pat_buf = "3B0D........F27502F2C3F2E9...................................... 00 0000 0011 :0000 @__security_check_cookie@4 :000B@ $failure$4 ^0002 ___security_cookie ^000D ___report_gsfailure\n---";
/// assert_eq!(pat::parse(pat_buf).unwrap().len(), 1);
/// ```
pub fn parse(buf: &str) -> Result<Vec<FlirtSignature>, Error> {
    if let Ok((_, sigs)) = pat(buf) {
        Ok(sigs)
    } else {
        Err(PatError::CorruptPatFile.into())
    }
}

<commit_msg>flirt: pat: fix parsing of hex word field<commit_after>// from: https://github.com/Maktm/FLIRTDB/blob/1f5763535e02d7cccf2f90a96a8ebaa36e9b2495/cmt/windows/libcmt_15_msvc_x86.pat#L355
//
//    3B0D........F27502F2C3F2E9...................................... 00 0000 0011 :0000 @__security_check_cookie@4 :000B@ $failure$4 ^0002 ___security_cookie ^000D ___report_gsfailure
//    ^^^^        ^^^^^^^^^^^^^^   bytes
//        ^^^^^^^^                 relocations
//
//                                                                     00 0000 0011
//                                                                     ^^ number of bytes crc16'd
//                                                                        ^^^^ crc16
//                                                                             ^^^^ size of fn
//
//                                                                                :0000 @__security_check_cookie@4
//                                                                                ^^^^^ offset of match
//                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^ name
//
//                                                                                :000B@ $failure$4
//                                                                                ^^^^^^ local offset
//                                                                                ^^^^^^^^^^ local name
//
//                                                                                ^0002 ___security_cookie
//                                                                                ^^^^^ reference offset
//                                                                                ^^^^^^^^^^^^^^^^^^ reference name

use log::{trace};
use nom::IResult;
use nom::multi::many0;
use nom::multi::many1;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_till1;
use nom::bytes::complete::take_while;
use nom::bytes::complete::take_while_m_n;
use nom::branch::alt;
use nom::sequence::pair;
use nom::combinator::map;
use nom::combinator::map_res;
use nom::combinator::peek;
use nom::combinator::opt;
use failure::{Error, Fail};

use super::{SigElement, ByteSignature, Offset, Name, Symbol, FlirtSignature};

#[derive(Debug, Fail)]
pub enum PatError {
    #[fail(display = "The pattern is not supported")]
    NotSupported,
    #[fail(display = "The .pat file is corrupt (or unsupported)")]
    CorruptPatFile,
}

fn whitespace(input: &str) -> IResult<&str, &str> {
    take_while(|c| c == ' ')(input)
}

fn is_hex_digit(c: char) -> bool {
  c.is_digit(16)
}

fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> {
  u8::from_str_radix(input, 16)
}

/// parse a single hex byte, like `AB`
fn hex(input: &str) -> IResult<&str, u8> {
    map_res(
        take_while_m_n(2, 2, is_hex_digit),
        from_hex
    )(input)
}

fn hex_byte(input: &str) -> IResult<&str, u8> {
    let (input, v) = hex(input)?;
    Ok((input, v))
}

fn hex_word(input: &str) -> IResult<&str, u16> {
    let (input, v1) = hex(input)?;
    let (input, v2) = hex(input)?;
    let v: u16 = ((v1 as u16) << 8) | (v2 as u16);
    Ok((input, v))
}

/// parse a single byte signature element, which is either a hex byte or a wildcard.
fn sig_element(input: &str) -> IResult<&str, SigElement> {
    alt((
        map(hex, |v| SigElement::Byte(v)),
        map(tag(".."), |_| SigElement::Wildcard)
    ))(input)
}

/// parse byte signature elements, hex or wildcard.
fn byte_signature(input: &str) -> IResult<&str, ByteSignature> {
    let (input, elems) = many1(sig_element)(input)?;
    Ok((input, ByteSignature(elems)))
}

/// parse a hex-encoded offset, like `0000`
/// max is 0x8000.
/// TODO: this can be negative.
fn hex_offset(input: &str) -> IResult<&str, u16> {
    hex_word(input)
}

/// parse a public offset, like `:0000`
fn public_offset(input: &str) -> IResult<&str, u16> {
    let (input, _) = tag(":")(input)?;
    let (input, offset) = hex_offset(input)?;
    let (input, _) = peek(tag(" "))(input)?;

    Ok((input, offset))
}

/// parse a local offset, like `:000B@`
fn local_offset(input: &str) -> IResult<&str, u16> {
    let (input, _) = tag(":")(input)?;
    let (input, offset) = hex_offset(input)?;
    let (input, _) = tag("@")(input)?;

    Ok((input, offset))
}

/// parse an external reference, like `^0002`
fn reference_offset(input: &str) -> IResult<&str, u16> {
    let (input, _) = tag("^")(input)?;
    let (input, offset) = hex_offset(input)?;

    Ok((input, offset))
}

fn offset(input: &str) -> IResult<&str, Offset> {
    alt((
        // this must go first, because it has trailing `@`,
        // otherwise, the same as public.
        map(local_offset, |v| Offset::Local(v)),
        map(public_offset, |v| Offset::Public(v)),
        map(reference_offset, |v| Offset::Reference(v))
    ))(input)
}

fn symbol_name(input: &str) -> IResult<&str, &str> {
    take_till1(|c| c == ' ' || c == '\n')(input)
}

/// parse a (offset, symbol) pair.
///
/// note: this also consumes trailing spaces so that a sequence of these can be easily parsed.
fn symbol(input: &str) -> IResult<&str, Symbol> {
    let (input, offset) = offset(input)?;
    let (input, _) = whitespace(input)?;
    let (input, name) = symbol_name(input)?;
    let (input, _) = opt(whitespace)(input)?;
    match offset {
        Offset::Public(v) => {
            Ok((input, Symbol::Public(Name {name: name.to_string(), offset: v})))
        },
        Offset::Local(v) => {
            Ok((input, Symbol::Local(Name {name: name.to_string(), offset: v})))
        },
        Offset::Reference(v) => {
            Ok((input, Symbol::Reference(Name {name: name.to_string(), offset: v})))
        },
    }
}

fn symbols(input: &str) -> IResult<&str, Vec<Symbol>> {
    many1(symbol)(input)
}

fn pat_signature(input: &str) -> IResult<&str, FlirtSignature> {
    let (input, byte_sig) = byte_signature(input)?;
    let (input, _) = whitespace(input)?;
    trace!("sig: {:?}", byte_sig);

    let (input, size_of_bytes_crc16) = hex_byte(input)?;
    let (input, _) = whitespace(input)?;
    trace!("crc16 len: {:02x}", size_of_bytes_crc16);

    let (input, crc16) = hex_word(input)?;
    let (input, _) = whitespace(input)?;
    trace!("crc16: {:04x}", crc16);

    let (input, size_of_function) = hex_word(input)?;
    let (input, _) = whitespace(input)?;
    trace!("function size: {:04x}", size_of_function);

    let (input, names) = symbols(input)?;
    trace!("names: {:?}", names);

    let (input, footer) = opt(byte_signature)(input)?;
    trace!("footer: {:?}", footer);

    Ok((input, FlirtSignature {
        byte_sig,
        size_of_bytes_crc16,
        crc16,
        size_of_function,
        names,
        footer,
    }))
}

/// parse a .pat file into FLIRT signatures.
fn pat(input: &str) -> IResult<&str, Vec<FlirtSignature>> {
    // each signature is newline separated.
    // drop the newline after we've parsed it.
    let pat_sig_line = map(pair(pat_signature, tag("\n")), |p| p.0);
    let (input, sigs) = many0(pat_sig_line)(input)?;

    // the file ends with `---`.
    let (input, _) = tag("---")(input)?;

    // TODO: assert there is nothing left in the file

    Ok((input, sigs))
}

/// ```
/// use flirt::pat;
/// let pat_buf = "3B0D........F27502F2C3F2E9...................................... 00 0000 0011 :0000 @__security_check_cookie@4 :000B@ $failure$4 ^0002 ___security_cookie ^000D ___report_gsfailure\n---";
/// assert_eq!(pat::parse(pat_buf).unwrap().len(), 1);
/// ```
pub fn parse(buf: &str) -> Result<Vec<FlirtSignature>, Error> {
    if let Ok((_, sigs)) = pat(buf) {
        Ok(sigs)
    } else {
        Err(PatError::CorruptPatFile.into())
    }
}

<|endoftext|>


<commit_before>use piston::input::Button;
use piston::input::Button::Keyboard;
use piston::input::Key;
use piston::input::{RenderArgs, UpdateArgs};

use entity::Entity;
use std::collections::HashMap;

use player::Player;

pub struct App {
    /// next unique id
    last_entity_id: u32,
    entities: HashMap<u32, Box<Entity>>,
}

//fn insert(&mut self, k: K, v: V) -> Option<V>

impl App {
    pub fn new() -> App {
        let mut hm : HashMap<u32, Box<Entity>> = HashMap::new();
        hm.insert(0, Box::new(Player::new()));

        App {
            last_entity_id: 1,
            entities: hm,
        }
    }

    pub fn key_press(&mut self, args: Button) {
        if args == Keyboard(Key::Space) {
            println!("was");
        }
    }
/*
    pub fn add_entity(&mut self, e: Box<Entity>) {
        self.entities.push(e);
    }*/

    pub fn update(&mut self, args: UpdateArgs) {
        for (id, e) in &mut self.entities {
            e.update(args);
        }
    }

    pub fn render(&mut self, args: RenderArgs) {
        for (id, e) in &mut self.entities {
            e.render(args);
        }
    }
}
<commit_msg>Added player property to App.<commit_after>use piston::input::Button;
use piston::input::Button::Keyboard;
use piston::input::Key;
use piston::input::{RenderArgs, UpdateArgs};

use std::cell::RefCell;
use std::cell::Ref;
use std::rc::Rc;
use entity::Entity;
use std::collections::HashMap;

use player::Player;

pub struct App {
    /// next unique id
    player : Rc<RefCell<Player>>,
    last_entity_id: u32,
    entities: HashMap<u32, Rc<RefCell<Entity>>>,
}

//fn insert(&mut self, k: K, v: V) -> Option<V>

impl App {
    pub fn new() -> App {
        let mut hm : HashMap<u32, Rc<RefCell<Entity>>> = HashMap::new();
        let mut player = Rc::new(RefCell::new(Player::new()));
        hm.insert(0, player.clone());
        let mut app = App {
            last_entity_id: 1,
            entities: hm,
            player : player.clone()
        };

        return app;
    }

    pub fn key_press(&mut self, args: Button) {
        if args == Keyboard(Key::Space) {
            println!("was");
        }
    }
/*
    pub fn add_entity(&mut self, e: Box<Entity>) {
        self.entities.push(e);
    }*/

    pub fn update(&mut self, args: UpdateArgs) {
        for (id, e) in &mut self.entities {
            e.borrow_mut().update(args);
        }
    }

    pub fn render(&mut self, args: RenderArgs) {
        for (id, e) in &mut self.entities {
            e.borrow_mut().render(args);
        }
    }
}
<|endoftext|>