<commit_before>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Animations — Animated images.

use std::mem;
use std::ptr;
use glib::{Error, GlibContainer, TimeVal};
use glib::object::Upcast;
use glib::translate::*;
use gdk_pixbuf_ffi as ffi;
use super::Pixbuf;

glib_wrapper! {
    pub struct PixbufAnimationIter(Object<ffi::GdkPixbufAnimationIter>);

    match fn {
        get_type => || ffi::gdk_pixbuf_animation_iter_get_type(),
    }
}

impl PixbufAnimationIter {
    pub fn advance(&self, start_time: &TimeVal) -> bool {
        unsafe {
            from_glib(ffi::gdk_pixbuf_animation_iter_advance(self.to_glib_none().0,
                mem::transmute(start_time)))
        }
    }

    pub fn get_pixbuf(&self) -> Pixbuf {
        unsafe { from_glib_none(ffi::gdk_pixbuf_animation_iter_get_pixbuf(self.to_glib_none().0)) }
    }

    pub fn get_delay_time(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_animation_iter_get_delay_time(self.to_glib_none().0) }
    }

    pub fn on_currently_loading_frame(&self) -> bool {
        unsafe {
            from_glib(
                ffi::gdk_pixbuf_animation_iter_on_currently_loading_frame(self.to_glib_none().0))
        }
    }
}

glib_wrapper! {
    pub struct PixbufAnimation(Object<ffi::GdkPixbufAnimation>);

    match fn {
        get_type => || ffi::gdk_pixbuf_animation_get_type(),
    }
}

impl PixbufAnimation {
    pub fn new_from_file(file: &str) -> Result<PixbufAnimation, Error> {
        #[cfg(windows)]
        use gdk_pixbuf_ffi::gdk_pixbuf_animation_new_from_file_utf8
            as gdk_pixbuf_animation_new_from_file;
        #[cfg(not(windows))]
        use gdk_pixbuf_ffi::gdk_pixbuf_animation_new_from_file;

        unsafe {
            let mut error = ptr::null_mut();
            let ptr = gdk_pixbuf_animation_new_from_file(file.to_glib_none().0, &mut error);
            if error.is_null() {
                Ok(from_glib_full(ptr))
            } else {
                Err(Error::wrap(error))
            }
        }
    }

    #[cfg(gdk_3_8)] // gdk-pixbuf 2.28
    pub fn new_from_resource(resource_path: &str) -> Result<PixbufAnimation, Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ptr = ffi::gdk_pixbuf_animation_new_from_resource(resource_path.to_glib_none().0,
                                                                  &mut error);
            if error.is_null() {
                Ok(from_glib_full(ptr))
            } else {
                Err(Error::wrap(error))
            }
        }
    }
}

pub trait PixbufAnimationExt {
    fn get_width(&self) -> i32;
    fn get_height(&self) -> i32;
    fn get_iter(&self, start_time: &TimeVal) -> PixbufAnimationIter;
    fn is_static_image(&self) -> bool;
    fn get_static_image(&self) -> Option<Pixbuf>;
}

impl<T: Upcast<PixbufAnimation>> PixbufAnimationExt for T {
    fn get_width(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_animation_get_width(self.upcast().to_glib_none().0) }
    }

    fn get_height(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_animation_get_height(self.upcast().to_glib_none().0) }
    }

    fn get_iter(&self, start_time: &TimeVal) -> PixbufAnimationIter {
        unsafe {
            from_glib_full(
                ffi::gdk_pixbuf_animation_get_iter(self.upcast().to_glib_none().0,
                                                   mem::transmute(start_time)))
        }
    }

    fn is_static_image(&self) -> bool {
        unsafe {
            from_glib(ffi::gdk_pixbuf_animation_is_static_image(self.upcast().to_glib_none().0))
        }
    }

    fn get_static_image(&self) -> Option<Pixbuf> {
        unsafe {
            from_glib_none(ffi::gdk_pixbuf_animation_get_static_image(
                self.upcast().to_glib_none().0))
        }
    }
}

glib_wrapper! {
    pub struct PixbufSimpleAnim(Object<ffi::GdkPixbufSimpleAnim>): PixbufAnimation;

    match fn {
        get_type => || ffi::gdk_pixbuf_simple_anim_get_type(),
    }
}

impl PixbufSimpleAnim {
    pub fn new(width: i32, height: i32, rate: f32) -> PixbufSimpleAnim {
        unsafe { from_glib_full(ffi::gdk_pixbuf_simple_anim_new(width, height, rate)) }
    }

    pub fn add_frame(&self, pixbuf: &Pixbuf) {
        unsafe {
            ffi::gdk_pixbuf_simple_anim_add_frame(self.to_glib_none().0, pixbuf.to_glib_none().0)
        }
    }

    pub fn set_loop(&self, loop_: bool) {
        unsafe { ffi::gdk_pixbuf_simple_anim_set_loop(self.to_glib_none().0, loop_.to_glib()) }
    }

    pub fn get_loop(&self) -> bool {
        unsafe { from_glib(ffi::gdk_pixbuf_simple_anim_get_loop(self.to_glib_none().0)) }
    }
}
<commit_msg>Remove calls to upcast<commit_after>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Animations — Animated images.

use std::mem;
use std::ptr;
use glib::{Error, GlibContainer, TimeVal};
use glib::object::Upcast;
use glib::translate::*;
use gdk_pixbuf_ffi as ffi;
use super::Pixbuf;

glib_wrapper! {
    pub struct PixbufAnimationIter(Object<ffi::GdkPixbufAnimationIter>);

    match fn {
        get_type => || ffi::gdk_pixbuf_animation_iter_get_type(),
    }
}

impl PixbufAnimationIter {
    pub fn advance(&self, start_time: &TimeVal) -> bool {
        unsafe {
            from_glib(ffi::gdk_pixbuf_animation_iter_advance(self.to_glib_none().0,
                mem::transmute(start_time)))
        }
    }

    pub fn get_pixbuf(&self) -> Pixbuf {
        unsafe { from_glib_none(ffi::gdk_pixbuf_animation_iter_get_pixbuf(self.to_glib_none().0)) }
    }

    pub fn get_delay_time(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_animation_iter_get_delay_time(self.to_glib_none().0) }
    }

    pub fn on_currently_loading_frame(&self) -> bool {
        unsafe {
            from_glib(
                ffi::gdk_pixbuf_animation_iter_on_currently_loading_frame(self.to_glib_none().0))
        }
    }
}

glib_wrapper! {
    pub struct PixbufAnimation(Object<ffi::GdkPixbufAnimation>);

    match fn {
        get_type => || ffi::gdk_pixbuf_animation_get_type(),
    }
}

impl PixbufAnimation {
    pub fn new_from_file(file: &str) -> Result<PixbufAnimation, Error> {
        #[cfg(windows)]
        use gdk_pixbuf_ffi::gdk_pixbuf_animation_new_from_file_utf8
            as gdk_pixbuf_animation_new_from_file;
        #[cfg(not(windows))]
        use gdk_pixbuf_ffi::gdk_pixbuf_animation_new_from_file;

        unsafe {
            let mut error = ptr::null_mut();
            let ptr = gdk_pixbuf_animation_new_from_file(file.to_glib_none().0, &mut error);
            if error.is_null() {
                Ok(from_glib_full(ptr))
            } else {
                Err(Error::wrap(error))
            }
        }
    }

    #[cfg(gdk_3_8)] // gdk-pixbuf 2.28
    pub fn new_from_resource(resource_path: &str) -> Result<PixbufAnimation, Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ptr = ffi::gdk_pixbuf_animation_new_from_resource(resource_path.to_glib_none().0,
                                                                  &mut error);
            if error.is_null() {
                Ok(from_glib_full(ptr))
            } else {
                Err(Error::wrap(error))
            }
        }
    }
}

pub trait PixbufAnimationExt {
    fn get_width(&self) -> i32;
    fn get_height(&self) -> i32;
    fn get_iter(&self, start_time: &TimeVal) -> PixbufAnimationIter;
    fn is_static_image(&self) -> bool;
    fn get_static_image(&self) -> Option<Pixbuf>;
}

impl<T: Upcast<PixbufAnimation>> PixbufAnimationExt for T {
    fn get_width(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_animation_get_width(self.to_glib_none().0) }
    }

    fn get_height(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_animation_get_height(self.to_glib_none().0) }
    }

    fn get_iter(&self, start_time: &TimeVal) -> PixbufAnimationIter {
        unsafe {
            from_glib_full(
                ffi::gdk_pixbuf_animation_get_iter(self.to_glib_none().0,
                                                   mem::transmute(start_time)))
        }
    }

    fn is_static_image(&self) -> bool {
        unsafe {
            from_glib(ffi::gdk_pixbuf_animation_is_static_image(self.to_glib_none().0))
        }
    }

    fn get_static_image(&self) -> Option<Pixbuf> {
        unsafe {
            from_glib_none(ffi::gdk_pixbuf_animation_get_static_image(
                self.to_glib_none().0))
        }
    }
}

glib_wrapper! {
    pub struct PixbufSimpleAnim(Object<ffi::GdkPixbufSimpleAnim>): PixbufAnimation;

    match fn {
        get_type => || ffi::gdk_pixbuf_simple_anim_get_type(),
    }
}

impl PixbufSimpleAnim {
    pub fn new(width: i32, height: i32, rate: f32) -> PixbufSimpleAnim {
        unsafe { from_glib_full(ffi::gdk_pixbuf_simple_anim_new(width, height, rate)) }
    }

    pub fn add_frame(&self, pixbuf: &Pixbuf) {
        unsafe {
            ffi::gdk_pixbuf_simple_anim_add_frame(self.to_glib_none().0, pixbuf.to_glib_none().0)
        }
    }

    pub fn set_loop(&self, loop_: bool) {
        unsafe { ffi::gdk_pixbuf_simple_anim_set_loop(self.to_glib_none().0, loop_.to_glib()) }
    }

    pub fn get_loop(&self) -> bool {
        unsafe { from_glib(ffi::gdk_pixbuf_simple_anim_get_loop(self.to_glib_none().0)) }
    }
}
<|endoftext|>


<commit_before>use std::io;

use byteorder::{NetworkEndian, WriteBytesExt};

use super::Extras;
use ::protocol::{Magic, Command, DataType};

/// Memcached request instance. In case if you need to construct request manually.
pub struct Request {
    opcode: Command,
    key_length: u16,
    extras_length: u8,
    data_type: DataType,
    vbucket_id: u16,
    body_length: u32,
    opaque: u32,
    cas: u64,

    // body
    extras: Option<Vec<u8>>,
    key: Option<Vec<u8>>,
    value: Option<Vec<u8>>,
}

impl Request {

    /// Create new Request with all fields blank.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let mut request = Request::new(Command::Get);
    /// ```
    pub fn new(command: Command) -> Request {
        Request {
            opcode: command,
            key_length: 0,
            extras_length: 0,
            data_type: DataType::RawBytes,
            vbucket_id: 0x00,
            body_length: 0,
            opaque: 0,
            cas: 0,
            extras: None,
            key: None,
            value: None,
        }
    }

    /// Provide key field.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let mut request = Request::new(Command::Get);
    /// request.set_key(b"Hello");
    /// ```
    pub fn set_key(&mut self, key: &[u8]) {
        self.key_length = key.len() as u16; // TODO: Possible cast failure
        self.key = Some(key.to_owned()); // TODO: must use `key` directly and remove additional allocation
        self.body_length += self.key_length as u32;
    }

    /// Provide value field.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let mut request = Request::new(Command::Set);
    /// request.set_key(b"Hello");
    /// request.set_value(b"World");
    /// ```
    pub fn set_value(&mut self, value: &[u8]) {
        self.body_length += value.len() as u32; // TODO: Possible cast failure
        self.value = Some(value.to_owned()); // TODO: Must use `value` directly and remove additional allocation
    }

    pub fn set_extras<T: Extras>(&mut self, extras: T) {
        let mut buf: Vec<u8> = vec![];
        extras.write(&mut buf).expect("Failed to set extras");

        self.extras_length = buf.len() as u8; // TODO: Possible cast failure
        self.extras = Some(buf);
        self.body_length += self.extras_length as u32;
    }

    /// Write serialized request as a bytes into `T`
    ///
    /// # Errors
    ///
    /// Returns an [`std::io::Error`][Error] if write had failed somehow.
    ///
    /// [Error]: ../../std/io/struct.Error.html
    pub fn write<T: io::Write>(&self, out: &mut T) -> io::Result<()> {
        out.write_u8(Magic::Request as u8)?;
        out.write_u8(self.opcode as u8)?;
        out.write_u16::<NetworkEndian>(self.key_length)?;
        out.write_u8(self.extras_length)?;
        out.write_u8(self.data_type as u8)?;
        out.write_u16::<NetworkEndian>(self.vbucket_id)?;
        out.write_u32::<NetworkEndian>(self.body_length)?;
        out.write_u32::<NetworkEndian>(self.opaque)?;
        out.write_u64::<NetworkEndian>(self.cas)?;

        if let Some(ref extras) = self.extras {
            out.write_all(extras)?;
        }

        if let Some(ref key) = self.key {
            out.write_all(key)?;
        }

        if let Some(ref value) = self.value {
            out.write_all(value)?;
        }

        Ok(())
    }
}

<commit_msg>Partially unifying set_key() and set_value() methods for Request<commit_after>use std::io;
use std::convert::AsRef;

use byteorder::{NetworkEndian, WriteBytesExt};

use super::Extras;
use ::protocol::{Magic, Command, DataType};

/// Memcached request instance. In case if you need to construct request manually.
pub struct Request {
    opcode: Command,
    key_length: u16,
    extras_length: u8,
    data_type: DataType,
    vbucket_id: u16,
    body_length: u32,
    opaque: u32,
    cas: u64,

    // body
    extras: Option<Vec<u8>>,
    key: Option<Vec<u8>>,
    value: Option<Vec<u8>>,
}

impl Request {

    /// Create new Request with all fields blank.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let mut request = Request::new(Command::Get);
    /// ```
    pub fn new(command: Command) -> Request {
        Request {
            opcode: command,
            key_length: 0,
            extras_length: 0,
            data_type: DataType::RawBytes,
            vbucket_id: 0x00,
            body_length: 0,
            opaque: 0,
            cas: 0,
            extras: None,
            key: None,
            value: None,
        }
    }

    /// Provide key field.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let mut request = Request::new(Command::Get);
    /// request.set_key(b"Hello");
    /// ```
    pub fn set_key<T: AsRef<[u8]>>(&mut self, key: T) {
        self.key_length = key.as_ref().len() as u16; // TODO: Possible cast failure
        self.key = Some(key.as_ref().to_owned());
        self.body_length += self.key_length as u32;
    }

    /// Provide value field.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let mut request = Request::new(Command::Set);
    /// request.set_key(b"Hello");
    /// request.set_value(b"World");
    /// ```
    pub fn set_value<T: AsRef<[u8]>>(&mut self, value: T) {
        self.body_length += value.as_ref().len() as u32; // TODO: Possible cast failure
        self.value = Some(value.as_ref().to_owned());
    }

    pub fn set_extras<T: Extras>(&mut self, extras: T) {
        let mut buf: Vec<u8> = vec![];
        extras.write(&mut buf).expect("Failed to set extras");

        self.extras_length = buf.len() as u8; // TODO: Possible cast failure
        self.extras = Some(buf);
        self.body_length += self.extras_length as u32;
    }

    /// Write serialized request as a bytes into `T`
    ///
    /// # Errors
    ///
    /// Returns an [`std::io::Error`][Error] if write had failed somehow.
    ///
    /// [Error]: ../../std/io/struct.Error.html
    pub fn write<T: io::Write>(&self, out: &mut T) -> io::Result<()> {
        out.write_u8(Magic::Request as u8)?;
        out.write_u8(self.opcode as u8)?;
        out.write_u16::<NetworkEndian>(self.key_length)?;
        out.write_u8(self.extras_length)?;
        out.write_u8(self.data_type as u8)?;
        out.write_u16::<NetworkEndian>(self.vbucket_id)?;
        out.write_u32::<NetworkEndian>(self.body_length)?;
        out.write_u32::<NetworkEndian>(self.opaque)?;
        out.write_u64::<NetworkEndian>(self.cas)?;

        if let Some(ref extras) = self.extras {
            out.write_all(extras)?;
        }

        if let Some(ref key) = self.key {
            out.write_all(key)?;
        }

        if let Some(ref value) = self.value {
            out.write_all(value)?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>//! A reader that manages namespace declarations found in the input and able
//! to resolve [qualified names] to [expanded names].
//!
//! [qualified names]: https://www.w3.org/TR/xml-names11/#dt-qualname
//! [expanded names]: https://www.w3.org/TR/xml-names11/#dt-expname

use std::io::BufRead;
use std::ops::{Deref, DerefMut};

use crate::errors::Result;
use crate::events::Event;
use crate::name::{LocalName, NamespaceResolver, QName, ResolveResult};
use crate::reader::Reader;

/// A low level encoding-agnostic XML event reader that performs namespace resolution.
///
/// Consumes a [`BufRead`] and streams XML `Event`s.
pub struct NsReader<R> {
    /// An XML reader
    reader: Reader<R>,
    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
    /// and an `=`) and namespace values.
    buffer: Vec<u8>,
    /// A buffer to manage namespaces
    ns_resolver: NamespaceResolver,
    /// We cannot pop data from the namespace stack until returned `Empty` or `End`
    /// event will be processed by the user, so we only mark that we should that
    /// in the next [`Self::read_namespaced_event()`] call.
    pending_pop: bool,
}

impl<R> NsReader<R> {
    #[inline]
    fn new(reader: Reader<R>) -> Self {
        Self {
            reader,
            buffer: Vec::new(),
            ns_resolver: NamespaceResolver::default(),
            pending_pop: false,
        }
    }
}

/// Getters
impl<R> NsReader<R> {
    /// Resolves a potentially qualified **event name** into (namespace name, local name).
    ///
    /// *Qualified* attribute names have the form `prefix:local-name` where the`prefix` is defined
    /// on any containing XML element via `xmlns:prefix="the:namespace:uri"`. The namespace prefix
    /// can be defined on the same element as the attribute in question.
    ///
    /// *Unqualified* event inherits the current *default namespace*.
    ///
    /// # Lifetimes
    ///
    /// - `'n`: lifetime of an element name
    #[inline]
    pub fn event_namespace<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
        self.ns_resolver.resolve(name, &self.buffer, true)
    }

    /// Resolves a potentially qualified **attribute name** into (namespace name, local name).
    ///
    /// *Qualified* attribute names have the form `prefix:local-name` where the`prefix` is defined
    /// on any containing XML element via `xmlns:prefix="the:namespace:uri"`. The namespace prefix
    /// can be defined on the same element as the attribute in question.
    ///
    /// *Unqualified* attribute names do *not* inherit the current *default namespace*.
    ///
    /// # Lifetimes
    ///
    /// - `'n`: lifetime of an attribute
    #[inline]
    pub fn attribute_namespace<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
        self.ns_resolver.resolve(name, &self.buffer, false)
    }
}

impl<R: BufRead> NsReader<R> {
    /// Reads the next event and resolves its namespace (if applicable).
    ///
    /// # Examples
    ///
    /// ```
    /// use std::str::from_utf8;
    /// use quick_xml::NsReader;
    /// use quick_xml::events::Event;
    /// use quick_xml::name::ResolveResult::*;
    ///
    /// let xml = r#"<x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
    ///                 <y:tag2><!--Test comment-->Test</y:tag2>
    ///                 <y:tag2>Test 2</y:tag2>
    ///             </x:tag1>"#;
    /// let mut reader = NsReader::from_str(xml);
    /// reader.trim_text(true);
    /// let mut count = 0;
    /// let mut buf = Vec::new();
    /// let mut txt = Vec::new();
    /// loop {
    ///     match reader.read_namespaced_event(&mut buf) {
    ///         Ok((Bound(ns), Event::Start(e))) => {
    ///             count += 1;
    ///             match (ns.as_ref(), e.local_name().as_ref()) {
    ///                 (b"www.xxxx", b"tag1") => (),
    ///                 (b"www.yyyy", b"tag2") => (),
    ///                 (ns, n) => panic!("Namespace and local name mismatch"),
    ///             }
    ///             println!("Resolved namespace: {:?}", ns);
    ///         }
    ///         Ok((Unbound, Event::Start(_))) => {
    ///             panic!("Element not in any namespace")
    ///         },
    ///         Ok((Unknown(p), Event::Start(_))) => {
    ///             panic!("Undeclared namespace prefix {:?}", String::from_utf8(p))
    ///         }
    ///         Ok((_, Event::Text(e))) => {
    ///             txt.push(e.decode_and_unescape(&reader).unwrap().into_owned())
    ///         },
    ///         Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
    ///         Ok((_, Event::Eof)) => break,
    ///         _ => (),
    ///     }
    ///     buf.clear();
    /// }
    /// println!("Found {} start events", count);
    /// println!("Text events: {:?}", txt);
    /// ```
    pub fn read_namespaced_event<'b>(
        &mut self,
        buf: &'b mut Vec<u8>,
    ) -> Result<(ResolveResult, Event<'b>)> {
        if self.pending_pop {
            self.ns_resolver.pop(&mut self.buffer);
        }
        self.pending_pop = false;
        match self.reader.read_event_into(buf) {
            Ok(Event::Eof) => Ok((ResolveResult::Unbound, Event::Eof)),
            Ok(Event::Start(e)) => {
                self.ns_resolver.push(&e, &mut self.buffer);
                Ok((
                    self.ns_resolver.find(e.name(), &mut self.buffer),
                    Event::Start(e),
                ))
            }
            Ok(Event::Empty(e)) => {
                // For empty elements we need to 'artificially' keep the namespace scope on the
                // stack until the next `next()` call occurs.
                // Otherwise the caller has no chance to use `resolve` in the context of the
                // namespace declarations that are 'in scope' for the empty element alone.
                // Ex: <img rdf:nodeID="abc" xmlns:rdf="urn:the-rdf-uri" />
                self.ns_resolver.push(&e, &mut self.buffer);
                // notify next `read_namespaced_event()` invocation that it needs to pop this
                // namespace scope
                self.pending_pop = true;
                Ok((
                    self.ns_resolver.find(e.name(), &mut self.buffer),
                    Event::Empty(e),
                ))
            }
            Ok(Event::End(e)) => {
                // notify next `read_namespaced_event()` invocation that it needs to pop this
                // namespace scope
                self.pending_pop = true;
                Ok((
                    self.ns_resolver.find(e.name(), &mut self.buffer),
                    Event::End(e),
                ))
            }
            Ok(e) => Ok((ResolveResult::Unbound, e)),
            Err(e) => Err(e),
        }
    }
}

impl<'i> NsReader<&'i [u8]> {
    /// Creates an XML reader from a string slice.
    #[inline]
    pub fn from_str(s: &'i str) -> Self {
        Self::new(Reader::from_str(s))
    }

    /// Creates an XML reader from a slice of bytes.
    #[inline]
    pub fn from_bytes(bytes: &'i [u8]) -> Self {
        Self::new(Reader::from_bytes(bytes))
    }
}

impl<R> Deref for NsReader<R> {
    type Target = Reader<R>;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.reader
    }
}

impl<R> DerefMut for NsReader<R> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.reader
    }
}
<commit_msg>ns: Make namespace reading independent from buffer<commit_after>//! A reader that manages namespace declarations found in the input and able
//! to resolve [qualified names] to [expanded names].
//!
//! [qualified names]: https://www.w3.org/TR/xml-names11/#dt-qualname
//! [expanded names]: https://www.w3.org/TR/xml-names11/#dt-expname

use std::io::BufRead;
use std::ops::{Deref, DerefMut};

use crate::errors::Result;
use crate::events::Event;
use crate::name::{LocalName, NamespaceResolver, QName, ResolveResult};
use crate::reader::{Reader, XmlSource};

/// A low level encoding-agnostic XML event reader that performs namespace resolution.
///
/// Consumes a [`BufRead`] and streams XML `Event`s.
pub struct NsReader<R> {
    /// An XML reader
    reader: Reader<R>,
    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
    /// and an `=`) and namespace values.
    buffer: Vec<u8>,
    /// A buffer to manage namespaces
    ns_resolver: NamespaceResolver,
    /// We cannot pop data from the namespace stack until returned `Empty` or `End`
    /// event will be processed by the user, so we only mark that we should that
    /// in the next [`Self::read_event_impl()`] call.
    pending_pop: bool,
}

impl<R> NsReader<R> {
    #[inline]
    fn new(reader: Reader<R>) -> Self {
        Self {
            reader,
            buffer: Vec::new(),
            ns_resolver: NamespaceResolver::default(),
            pending_pop: false,
        }
    }
}

/// Getters
impl<R> NsReader<R> {
    /// Resolves a potentially qualified **event name** into (namespace name, local name).
    ///
    /// *Qualified* attribute names have the form `prefix:local-name` where the`prefix` is defined
    /// on any containing XML element via `xmlns:prefix="the:namespace:uri"`. The namespace prefix
    /// can be defined on the same element as the attribute in question.
    ///
    /// *Unqualified* event inherits the current *default namespace*.
    ///
    /// # Lifetimes
    ///
    /// - `'n`: lifetime of an element name
    #[inline]
    pub fn event_namespace<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
        self.ns_resolver.resolve(name, &self.buffer, true)
    }

    /// Resolves a potentially qualified **attribute name** into (namespace name, local name).
    ///
    /// *Qualified* attribute names have the form `prefix:local-name` where the`prefix` is defined
    /// on any containing XML element via `xmlns:prefix="the:namespace:uri"`. The namespace prefix
    /// can be defined on the same element as the attribute in question.
    ///
    /// *Unqualified* attribute names do *not* inherit the current *default namespace*.
    ///
    /// # Lifetimes
    ///
    /// - `'n`: lifetime of an attribute
    #[inline]
    pub fn attribute_namespace<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
        self.ns_resolver.resolve(name, &self.buffer, false)
    }
}

impl<R: BufRead> NsReader<R> {
    /// Reads the next event and resolves its namespace (if applicable).
    ///
    /// # Examples
    ///
    /// ```
    /// use std::str::from_utf8;
    /// use quick_xml::NsReader;
    /// use quick_xml::events::Event;
    /// use quick_xml::name::ResolveResult::*;
    ///
    /// let xml = r#"<x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
    ///                 <y:tag2><!--Test comment-->Test</y:tag2>
    ///                 <y:tag2>Test 2</y:tag2>
    ///             </x:tag1>"#;
    /// let mut reader = NsReader::from_str(xml);
    /// reader.trim_text(true);
    /// let mut count = 0;
    /// let mut buf = Vec::new();
    /// let mut txt = Vec::new();
    /// loop {
    ///     match reader.read_namespaced_event(&mut buf) {
    ///         Ok((Bound(ns), Event::Start(e))) => {
    ///             count += 1;
    ///             match (ns.as_ref(), e.local_name().as_ref()) {
    ///                 (b"www.xxxx", b"tag1") => (),
    ///                 (b"www.yyyy", b"tag2") => (),
    ///                 (ns, n) => panic!("Namespace and local name mismatch"),
    ///             }
    ///             println!("Resolved namespace: {:?}", ns);
    ///         }
    ///         Ok((Unbound, Event::Start(_))) => {
    ///             panic!("Element not in any namespace")
    ///         },
    ///         Ok((Unknown(p), Event::Start(_))) => {
    ///             panic!("Undeclared namespace prefix {:?}", String::from_utf8(p))
    ///         }
    ///         Ok((_, Event::Text(e))) => {
    ///             txt.push(e.decode_and_unescape(&reader).unwrap().into_owned())
    ///         },
    ///         Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
    ///         Ok((_, Event::Eof)) => break,
    ///         _ => (),
    ///     }
    ///     buf.clear();
    /// }
    /// println!("Found {} start events", count);
    /// println!("Text events: {:?}", txt);
    /// ```
    pub fn read_namespaced_event<'b>(
        &mut self,
        buf: &'b mut Vec<u8>,
    ) -> Result<(ResolveResult, Event<'b>)> {
        self.read_event_impl(buf)
    }
}

/// Private methods
impl<R> NsReader<R> {
    fn read_event_impl<'i, B>(&mut self, buf: B) -> Result<(ResolveResult, Event<'i>)>
    where
        R: XmlSource<'i, B>,
    {
        if self.pending_pop {
            self.ns_resolver.pop(&mut self.buffer);
            self.pending_pop = false;
        }
        match self.reader.read_event_impl(buf) {
            Ok(Event::Start(e)) => {
                self.ns_resolver.push(&e, &mut self.buffer);
                Ok((
                    self.ns_resolver.find(e.name(), &mut self.buffer),
                    Event::Start(e),
                ))
            }
            Ok(Event::Empty(e)) => {
                self.ns_resolver.push(&e, &mut self.buffer);
                // notify next `read_event_impl()` invocation that it needs to pop this
                // namespace scope
                self.pending_pop = true;
                Ok((
                    self.ns_resolver.find(e.name(), &mut self.buffer),
                    Event::Empty(e),
                ))
            }
            Ok(Event::End(e)) => {
                // notify next `read_event_impl()` invocation that it needs to pop this
                // namespace scope
                self.pending_pop = true;
                Ok((
                    self.ns_resolver.find(e.name(), &mut self.buffer),
                    Event::End(e),
                ))
            }
            Ok(e) => Ok((ResolveResult::Unbound, e)),
            Err(e) => Err(e),
        }
    }
}

impl<'i> NsReader<&'i [u8]> {
    /// Creates an XML reader from a string slice.
    #[inline]
    pub fn from_str(s: &'i str) -> Self {
        Self::new(Reader::from_str(s))
    }

    /// Creates an XML reader from a slice of bytes.
    #[inline]
    pub fn from_bytes(bytes: &'i [u8]) -> Self {
        Self::new(Reader::from_bytes(bytes))
    }
}

impl<R> Deref for NsReader<R> {
    type Target = Reader<R>;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.reader
    }
}

impl<R> DerefMut for NsReader<R> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.reader
    }
}
<|endoftext|>


<commit_before>use std::time::{SystemTime, UNIX_EPOCH};
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::io::Cursor;
use std::collections::HashSet;
use quick_xml::Writer;
use quick_xml::events::{Event, BytesEnd, BytesStart, BytesDecl};
use quick_xml::Result;
use traces::{TraceMap, CoverageStat};
use config::Config;

fn write_header<T:Write>(writer: &mut Writer<T>, config: &Config) -> Result<usize> {

    writer.write_event(Event::Start(BytesStart::borrowed(b"sources", b"sources".len())))?;
    writer.write_event(Event::Start(BytesStart::borrowed(b"source", b"source".len())))?;

    let parent_folder = match config.manifest.parent() {
        Some(s) => s.to_str().unwrap_or_default(),
        None => "",
    };
    writer.write(parent_folder.as_bytes()).unwrap();
    writer.write_event(Event::End(BytesEnd::borrowed(b"source")))?;
    writer.write_event(Event::End(BytesEnd::borrowed(b"sources")))
}

/// Input only from single source file
fn write_class<T:Write>(writer: &mut Writer<T>,
                        manifest_path: &Path,
                        filename: &Path,
                        coverage: &TraceMap) ->Result<usize> {
    if !coverage.is_empty() {
        let covered = coverage.covered_in_path(filename);
        let covered = (covered as f32)/(coverage.coverable_in_path(filename) as f32);

        let tidy_filename = match filename.strip_prefix(manifest_path) {
            Ok(p) => p,
            _ => filename,
        };
        let name = filename.file_stem().unwrap_or_default().to_str().unwrap_or_default();

        let mut class = BytesStart::owned(b"class".to_vec(), b"class".len());
        class.push_attribute(("name", name));
        class.push_attribute(("filename", tidy_filename.to_str().unwrap_or_default()));
        class.push_attribute(("line-rate", covered.to_string().as_ref()));
        class.push_attribute(("branch-rate", "1.0"));
        class.push_attribute(("complexity", "0.0"));
        writer.write_event(Event::Start(class))?;
        writer.write_event(Event::Empty(BytesStart::owned(b"methods".to_vec(), b"methods".len())))?;
        writer.write_event(Event::Start(BytesStart::borrowed(b"lines", b"lines".len())))?;
        for trace in coverage.get_child_traces(filename) {
            let mut line = BytesStart::owned(b"line".to_vec(), b"line".len());
            line.push_attribute(("number", trace.line.to_string().as_ref()));
            match trace.stats {
                CoverageStat::Line(hit) => {
                    line.push_attribute(("hits", hit.to_string().as_ref()));
                },
                _ => {
                    println!("Coverage statistic currently not implemented for cobertura");
                },
            }
            writer.write_event(Event::Empty(line))?;
        }
        writer.write_event(Event::End(BytesEnd::borrowed(b"lines")))?;
        writer.write_event(Event::End(BytesEnd::borrowed(b"class")))
    } else {
        Ok(0)
    }
}

/// Input only tracer data from a single source folder
fn write_package<T:Write>(mut writer: &mut Writer<T>,
                          package: &Path,
                          package_name: &str,
                          coverage: &TraceMap) -> Result<usize> {
    let covered = coverage.covered_in_path(package);
    let covered = (covered as f32)/(coverage.coverable_in_path(package) as f32);

    let mut pack = BytesStart::owned(b"package".to_vec(), b"package".len());
    pack.push_attribute(("name", package_name));
    pack.push_attribute(("line-rate", covered.to_string().as_ref()));
    pack.push_attribute(("branch-rate", "1.0"));
    pack.push_attribute(("complexity", "0.0"));
    writer.write_event(Event::Start(pack))?;
    writer.write_event(Event::Start(BytesStart::borrowed(b"classes", b"classes".len())))?;

    for file in &coverage.files() {
        if file.parent() == Some(package) {
            write_class(&mut writer, package, file, coverage)?;
        }
    }

    writer.write_event(Event::End(BytesEnd::borrowed(b"classes")))?;
    writer.write_event(Event::End(BytesEnd::borrowed(b"package")))
}

pub fn export(coverage_data: &TraceMap, config: &Config) {
    let mut file = File::create("cobertura.xml").unwrap();
    let mut writer = Writer::new(Cursor::new(Vec::new()));
    writer.write_event(Event::Decl(BytesDecl::new(b"1.0", None, None))).unwrap();
    // Construct cobertura xml
    let line_rate = coverage_data.coverage_percentage();
    let mut cov = BytesStart::owned(b"coverage".to_vec(), b"coverage".len());
    cov.push_attribute(("line-rate", line_rate.to_string().as_ref()));
    cov.push_attribute(("branch-rate", "1.0"));
    cov.push_attribute(("version", "1.9"));

    if let Ok(s) = SystemTime::now().duration_since(UNIX_EPOCH) {
        cov.push_attribute(("timestamp", s.as_secs().to_string().as_ref()));
    } else {
        cov.push_attribute(("timestamp", "0"));
    }

    writer.write_event(Event::Start(cov)).unwrap();
    let _ = write_header(&mut writer, &config);
    // other data
    writer.write_event(Event::Start(BytesStart::borrowed(b"packages", b"packages".len()))).unwrap();

    let mut folder_set: HashSet<&Path> = HashSet::new();
    for t in &coverage_data.files() {
        let parent = match t.parent() {
            Some(x) => x,
            None => continue,
        };
        if !folder_set.contains(&parent) {
            folder_set.insert(parent);
            let manifest_path = config.manifest.parent().unwrap_or(&config.manifest);
            let package_name = match parent.strip_prefix(manifest_path) {
                Ok(p) => p,
                _ => manifest_path,
            };
            let package_name = package_name.to_str().unwrap_or_default();
            let _ = write_package(&mut writer, &parent, package_name, &coverage_data);
        }
    }

    writer.write_event(Event::End(BytesEnd::borrowed(b"packages"))).unwrap();
    writer.write_event(Event::End(BytesEnd::borrowed(b"coverage"))).unwrap();
    let result = writer.into_inner().into_inner();
    file.write_all(&result).unwrap();
}
<commit_msg>Use root-relative filepath in XML output<commit_after>use std::time::{SystemTime, UNIX_EPOCH};
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::io::Cursor;
use std::collections::HashSet;
use quick_xml::Writer;
use quick_xml::events::{Event, BytesEnd, BytesStart, BytesDecl};
use quick_xml::Result;
use traces::{TraceMap, CoverageStat};
use config::Config;

fn write_header<T:Write>(writer: &mut Writer<T>, config: &Config) -> Result<usize> {

    writer.write_event(Event::Start(BytesStart::borrowed(b"sources", b"sources".len())))?;
    writer.write_event(Event::Start(BytesStart::borrowed(b"source", b"source".len())))?;

    let parent_folder = match config.manifest.parent() {
        Some(s) => s.to_str().unwrap_or_default(),
        None => "",
    };
    writer.write(parent_folder.as_bytes()).unwrap();
    writer.write_event(Event::End(BytesEnd::borrowed(b"source")))?;
    writer.write_event(Event::End(BytesEnd::borrowed(b"sources")))
}

/// Input only from single source file
fn write_class<T:Write>(writer: &mut Writer<T>,
                        manifest_path: &Path,
                        filename: &Path,
                        coverage: &TraceMap) ->Result<usize> {
    if !coverage.is_empty() {
        let covered = coverage.covered_in_path(filename);
        let covered = (covered as f32)/(coverage.coverable_in_path(filename) as f32);

        let tidy_filename = match filename.strip_prefix(manifest_path) {
            Ok(p) => p,
            _ => filename,
        };
        let name = filename.file_stem().unwrap_or_default().to_str().unwrap_or_default();

        let mut class = BytesStart::owned(b"class".to_vec(), b"class".len());
        class.push_attribute(("name", name));
        class.push_attribute(("filename", tidy_filename.to_str().unwrap_or_default()));
        class.push_attribute(("line-rate", covered.to_string().as_ref()));
        class.push_attribute(("branch-rate", "1.0"));
        class.push_attribute(("complexity", "0.0"));
        writer.write_event(Event::Start(class))?;
        writer.write_event(Event::Empty(BytesStart::owned(b"methods".to_vec(), b"methods".len())))?;
        writer.write_event(Event::Start(BytesStart::borrowed(b"lines", b"lines".len())))?;
        for trace in coverage.get_child_traces(filename) {
            let mut line = BytesStart::owned(b"line".to_vec(), b"line".len());
            line.push_attribute(("number", trace.line.to_string().as_ref()));
            match trace.stats {
                CoverageStat::Line(hit) => {
                    line.push_attribute(("hits", hit.to_string().as_ref()));
                },
                _ => {
                    println!("Coverage statistic currently not implemented for cobertura");
                },
            }
            writer.write_event(Event::Empty(line))?;
        }
        writer.write_event(Event::End(BytesEnd::borrowed(b"lines")))?;
        writer.write_event(Event::End(BytesEnd::borrowed(b"class")))
    } else {
        Ok(0)
    }
}

/// Input only tracer data from a single source folder
fn write_package<T:Write>(mut writer: &mut Writer<T>,
                          package: &Path,
                          manifest_path: &Path,
                          package_name: &str,
                          coverage: &TraceMap) -> Result<usize> {
    let covered = coverage.covered_in_path(package);
    let covered = (covered as f32)/(coverage.coverable_in_path(package) as f32);

    let mut pack = BytesStart::owned(b"package".to_vec(), b"package".len());
    pack.push_attribute(("name", package_name));
    pack.push_attribute(("line-rate", covered.to_string().as_ref()));
    pack.push_attribute(("branch-rate", "1.0"));
    pack.push_attribute(("complexity", "0.0"));
    writer.write_event(Event::Start(pack))?;
    writer.write_event(Event::Start(BytesStart::borrowed(b"classes", b"classes".len())))?;

    for file in &coverage.files() {
        if file.parent() == Some(package) {
            write_class(&mut writer, manifest_path, file, coverage)?;
        }
    }

    writer.write_event(Event::End(BytesEnd::borrowed(b"classes")))?;
    writer.write_event(Event::End(BytesEnd::borrowed(b"package")))
}

pub fn export(coverage_data: &TraceMap, config: &Config) {
    let mut file = File::create("cobertura.xml").unwrap();
    let mut writer = Writer::new(Cursor::new(Vec::new()));
    writer.write_event(Event::Decl(BytesDecl::new(b"1.0", None, None))).unwrap();
    // Construct cobertura xml
    let line_rate = coverage_data.coverage_percentage();
    let mut cov = BytesStart::owned(b"coverage".to_vec(), b"coverage".len());
    cov.push_attribute(("line-rate", line_rate.to_string().as_ref()));
    cov.push_attribute(("branch-rate", "1.0"));
    cov.push_attribute(("version", "1.9"));

    if let Ok(s) = SystemTime::now().duration_since(UNIX_EPOCH) {
        cov.push_attribute(("timestamp", s.as_secs().to_string().as_ref()));
    } else {
        cov.push_attribute(("timestamp", "0"));
    }

    writer.write_event(Event::Start(cov)).unwrap();
    let _ = write_header(&mut writer, &config);
    // other data
    writer.write_event(Event::Start(BytesStart::borrowed(b"packages", b"packages".len()))).unwrap();

    let mut folder_set: HashSet<&Path> = HashSet::new();
    for t in &coverage_data.files() {
        let parent = match t.parent() {
            Some(x) => x,
            None => continue,
        };
        if !folder_set.contains(&parent) {
            folder_set.insert(parent);
            let manifest_path = config.manifest.parent().unwrap_or(&config.manifest);
            let package_name = match parent.strip_prefix(manifest_path) {
                Ok(p) => p,
                _ => manifest_path,
            };
            let package_name = package_name.to_str().unwrap_or_default();
            let _ = write_package(&mut writer, &parent, &manifest_path, package_name, &coverage_data);
        }
    }

    writer.write_event(Event::End(BytesEnd::borrowed(b"packages"))).unwrap();
    writer.write_event(Event::End(BytesEnd::borrowed(b"coverage"))).unwrap();
    let result = writer.into_inner().into_inner();
    file.write_all(&result).unwrap();
}
<|endoftext|>


<commit_before>extern "C" {
    #[no_mangle]
    fn mmap_read8(addr: u32) -> i32;
    #[no_mangle]
    fn mmap_read16(addr: u32) -> i32;
    #[no_mangle]
    fn mmap_read32(addr: u32) -> i32;

    #[no_mangle]
    fn mmap_write8(addr: u32, value: i32);
    #[no_mangle]
    fn mmap_write16(addr: u32, value: i32);
    #[no_mangle]
    fn mmap_write32(addr: u32, value: i32);
    #[no_mangle]
    fn mmap_write128(addr: u32, v0: i32, v1: i32, v2: i32, v3: i32);
}

use cpu2::cpu::*;
use cpu2::global_pointers::*;
use page::Page;

const USE_A20: bool = false;

#[no_mangle]
pub unsafe fn in_mapped_range(addr: u32) -> bool {
    return addr >= 0xA0000 && addr < 0xC0000 || addr >= *memory_size;
}

#[no_mangle]
pub unsafe fn read8(mut addr: u32) -> i32 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read8(addr);
    }
    else {
        return *mem8.offset(addr as isize) as i32;
    };
}
#[no_mangle]
pub unsafe fn read16(mut addr: u32) -> i32 {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read16(addr);
    }
    else {
        return *(mem8.offset(addr as isize) as *mut u16) as i32;
    };
}
#[no_mangle]
pub unsafe fn read_aligned16(mut addr: u32) -> i32 {
    dbg_assert!(addr < 0x80000000);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK16 as u32
    }
    if in_mapped_range(addr << 1) {
        return mmap_read16(addr << 1);
    }
    else {
        return *mem16.offset(addr as isize) as i32;
    };
}
#[no_mangle]
pub unsafe fn read32s(mut addr: u32) -> i32 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read32(addr);
    }
    else {
        return *(mem8.offset(addr as isize) as *mut i32);
    };
}
#[no_mangle]
pub unsafe fn read64s(mut addr: u32) -> i64 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read32(addr) as i64 | (mmap_read32(addr.wrapping_add(4 as u32)) as i64) << 32;
    }
    else {
        return *(mem8.offset(addr as isize) as *mut i64);
    };
}
#[no_mangle]
pub unsafe fn read_aligned32(mut addr: u32) -> i32 {
    dbg_assert!(addr < 0x40000000 as u32);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK32 as u32
    }
    if in_mapped_range(addr << 2) {
        return mmap_read32(addr << 2);
    }
    else {
        return *mem32s.offset(addr as isize);
    };
}
#[no_mangle]
pub unsafe fn read128(mut addr: u32) -> reg128 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    let mut value: reg128 = reg128 {
        i8_0: [0 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    };
    if in_mapped_range(addr) {
        value.i32_0[0] = mmap_read32(addr);
        value.i32_0[1] = mmap_read32(addr.wrapping_add(4 as u32));
        value.i32_0[2] = mmap_read32(addr.wrapping_add(8 as u32));
        value.i32_0[3] = mmap_read32(addr.wrapping_add(12 as u32))
    }
    else {
        value.i64_0[0] = *(mem8.offset(addr as isize) as *mut i64);
        value.i64_0[1] = *(mem8.offset(addr as isize).offset(8) as *mut i64)
    }
    return value;
}

#[no_mangle]
pub unsafe fn write8(mut addr: u32, value: i32) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write8(addr, value);
    }
    else {
        ::c_api::jit_dirty_page(Page::page_of(addr));
        *mem8.offset(addr as isize) = value as u8
    };
}

pub unsafe fn write8_no_mmap_or_dirty_check(addr: u32, value: i32) {
    *mem8.offset(addr as isize) = value as u8
}

#[no_mangle]
pub unsafe fn write16(mut addr: u32, value: i32) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write16(addr, value);
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(2 as u32));
        *(mem8.offset(addr as isize) as *mut u16) = value as u16
    };
}
#[no_mangle]
pub unsafe fn write_aligned16(mut addr: u32, value: u32) {
    dbg_assert!(addr < 0x80000000);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK16 as u32
    }
    let phys_addr: u32 = addr << 1;
    if in_mapped_range(phys_addr) {
        mmap_write16(phys_addr, value as i32);
    }
    else {
        ::c_api::jit_dirty_cache_small(phys_addr, phys_addr.wrapping_add(2 as u32));
        *mem16.offset(addr as isize) = value as u16
    };
}
#[no_mangle]
pub unsafe fn write32(mut addr: u32, value: i32) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write32(addr, value);
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(4 as u32));
        *(mem8.offset(addr as isize) as *mut i32) = value
    };
}

pub unsafe fn write_aligned32_no_mmap_or_dirty_check(addr: u32, value: i32) {
    *mem32s.offset(addr as isize) = value
}

#[no_mangle]
pub unsafe fn write_aligned32(mut addr: u32, value: i32) {
    dbg_assert!(addr < 0x40000000 as u32);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK32 as u32
    }
    let phys_addr: u32 = addr << 2;
    if in_mapped_range(phys_addr) {
        mmap_write32(phys_addr, value);
    }
    else {
        ::c_api::jit_dirty_cache_small(phys_addr, phys_addr.wrapping_add(4 as u32));
        *mem32s.offset(addr as isize) = value
    };
}
#[no_mangle]
pub unsafe fn write64(mut addr: u32, value: i64) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write32(
            addr.wrapping_add(0 as u32),
            (value & 0xFFFFFFFF as i64) as i32,
        );
        mmap_write32(addr.wrapping_add(4 as u32), (value >> 32) as i32);
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(8 as u32));
        *(mem8.offset(addr as isize) as *mut i64) = value
    };
}
#[no_mangle]
pub unsafe fn write128(mut addr: u32, value: reg128) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write128(
            addr,
            value.i32_0[0],
            value.i32_0[1],
            value.i32_0[2],
            value.i32_0[3],
        );
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(16 as u32));
        *(mem8.offset(addr as isize) as *mut i64) = value.i64_0[0];
        *(mem8.offset(addr as isize).offset(8) as *mut i64) = value.i64_0[1]
    };
}
<commit_msg>Simplify<commit_after>extern "C" {
    #[no_mangle]
    fn mmap_read8(addr: u32) -> i32;
    #[no_mangle]
    fn mmap_read16(addr: u32) -> i32;
    #[no_mangle]
    fn mmap_read32(addr: u32) -> i32;

    #[no_mangle]
    fn mmap_write8(addr: u32, value: i32);
    #[no_mangle]
    fn mmap_write16(addr: u32, value: i32);
    #[no_mangle]
    fn mmap_write32(addr: u32, value: i32);
    #[no_mangle]
    fn mmap_write128(addr: u32, v0: i32, v1: i32, v2: i32, v3: i32);
}

use cpu2::cpu::*;
use cpu2::global_pointers::*;
use page::Page;

const USE_A20: bool = false;

#[no_mangle]
pub unsafe fn in_mapped_range(addr: u32) -> bool {
    return addr >= 0xA0000 && addr < 0xC0000 || addr >= *memory_size;
}

#[no_mangle]
pub unsafe fn read8(mut addr: u32) -> i32 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read8(addr);
    }
    else {
        return *mem8.offset(addr as isize) as i32;
    };
}
#[no_mangle]
pub unsafe fn read16(mut addr: u32) -> i32 {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read16(addr);
    }
    else {
        return *(mem8.offset(addr as isize) as *mut u16) as i32;
    };
}
#[no_mangle]
pub unsafe fn read_aligned16(mut addr: u32) -> i32 {
    dbg_assert!(addr < 0x80000000);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK16 as u32
    }
    if in_mapped_range(addr << 1) {
        return mmap_read16(addr << 1);
    }
    else {
        return *mem16.offset(addr as isize) as i32;
    };
}
#[no_mangle]
pub unsafe fn read32s(mut addr: u32) -> i32 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read32(addr);
    }
    else {
        return *(mem8.offset(addr as isize) as *mut i32);
    };
}
#[no_mangle]
pub unsafe fn read64s(mut addr: u32) -> i64 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        return mmap_read32(addr) as i64 | (mmap_read32(addr.wrapping_add(4 as u32)) as i64) << 32;
    }
    else {
        return *(mem8.offset(addr as isize) as *mut i64);
    };
}
#[no_mangle]
pub unsafe fn read_aligned32(mut addr: u32) -> i32 {
    dbg_assert!(addr < 0x40000000 as u32);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK32 as u32
    }
    if in_mapped_range(addr << 2) {
        return mmap_read32(addr << 2);
    }
    else {
        return *mem32s.offset(addr as isize);
    };
}
#[no_mangle]
pub unsafe fn read128(mut addr: u32) -> reg128 {
    if 0 != USE_A20 as i32 && 0 != *a20_enabled as i32 {
        addr &= A20_MASK as u32
    }
    let mut value: reg128 = reg128 {
        i8_0: [0 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    };
    if in_mapped_range(addr) {
        value.i32_0[0] = mmap_read32(addr);
        value.i32_0[1] = mmap_read32(addr.wrapping_add(4 as u32));
        value.i32_0[2] = mmap_read32(addr.wrapping_add(8 as u32));
        value.i32_0[3] = mmap_read32(addr.wrapping_add(12 as u32))
    }
    else {
        value.i64_0[0] = *(mem8.offset(addr as isize) as *mut i64);
        value.i64_0[1] = *(mem8.offset(addr as isize).offset(8) as *mut i64)
    }
    return value;
}

#[no_mangle]
pub unsafe fn write8(mut addr: u32, value: i32) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write8(addr, value);
    }
    else {
        ::c_api::jit_dirty_page(Page::page_of(addr));
        write8_no_mmap_or_dirty_check(addr, value);
    };
}

pub unsafe fn write8_no_mmap_or_dirty_check(addr: u32, value: i32) {
    *mem8.offset(addr as isize) = value as u8
}

#[no_mangle]
pub unsafe fn write16(mut addr: u32, value: i32) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write16(addr, value);
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(2 as u32));
        *(mem8.offset(addr as isize) as *mut u16) = value as u16
    };
}
#[no_mangle]
pub unsafe fn write_aligned16(mut addr: u32, value: u32) {
    dbg_assert!(addr < 0x80000000);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK16 as u32
    }
    let phys_addr: u32 = addr << 1;
    if in_mapped_range(phys_addr) {
        mmap_write16(phys_addr, value as i32);
    }
    else {
        ::c_api::jit_dirty_cache_small(phys_addr, phys_addr.wrapping_add(2 as u32));
        *mem16.offset(addr as isize) = value as u16
    };
}
#[no_mangle]
pub unsafe fn write32(mut addr: u32, value: i32) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write32(addr, value);
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(4 as u32));
        *(mem8.offset(addr as isize) as *mut i32) = value
    };
}

pub unsafe fn write_aligned32_no_mmap_or_dirty_check(addr: u32, value: i32) {
    *mem32s.offset(addr as isize) = value
}

#[no_mangle]
pub unsafe fn write_aligned32(mut addr: u32, value: i32) {
    dbg_assert!(addr < 0x40000000 as u32);
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK32 as u32
    }
    let phys_addr: u32 = addr << 2;
    if in_mapped_range(phys_addr) {
        mmap_write32(phys_addr, value);
    }
    else {
        ::c_api::jit_dirty_cache_small(phys_addr, phys_addr.wrapping_add(4 as u32));
        write_aligned32_no_mmap_or_dirty_check(addr, value);
    };
}
#[no_mangle]
pub unsafe fn write64(mut addr: u32, value: i64) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write32(
            addr.wrapping_add(0 as u32),
            (value & 0xFFFFFFFF as i64) as i32,
        );
        mmap_write32(addr.wrapping_add(4 as u32), (value >> 32) as i32);
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(8 as u32));
        *(mem8.offset(addr as isize) as *mut i64) = value
    };
}
#[no_mangle]
pub unsafe fn write128(mut addr: u32, value: reg128) {
    if 0 != USE_A20 as i32 && !*a20_enabled {
        addr &= A20_MASK as u32
    }
    if in_mapped_range(addr) {
        mmap_write128(
            addr,
            value.i32_0[0],
            value.i32_0[1],
            value.i32_0[2],
            value.i32_0[3],
        );
    }
    else {
        ::c_api::jit_dirty_cache_small(addr, addr.wrapping_add(16 as u32));
        *(mem8.offset(addr as isize) as *mut i64) = value.i64_0[0];
        *(mem8.offset(addr as isize).offset(8) as *mut i64) = value.i64_0[1]
    };
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use schema::Value;

/// Internal representation of a document used for JSON
/// serialization.
///
/// A `NamedFieldDocument` is a simple representation of a document
/// as a `BTreeMap<String, Vec<Value>>`.
///
#[derive(Serialize)]
pub struct NamedFieldDocument(pub BTreeMap<String, Vec<Value>>);

// TODO: Remove
/*
impl Encodable for NamedFieldDocument {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_struct("named_field_document", self.0.len(), |s| {
            for (i, (name, vals)) in self.0.iter().enumerate() {
                s.emit_struct_field(name, i, |s| {
                    for (j, val) in vals.iter().enumerate() {
                        s.emit_seq(vals.len(), |s| {
                            s.emit_seq_elt(j, |s| {
                                match *val {
                                    Value::Str(ref text) => {
                                        s.emit_str(text)
                                    },
                                    Value::U64(ref val) => {
                                        s.emit_u64(*val)
                                    }
                                    Value::I64(ref val) => {
                                        s.emit_i64(*val)
                                    }
                                }
                            })
                        })?;
                    }
                    Ok(())

                })?;
            }
            Ok(())
        })
    }
}
*/
<commit_msg>Remove old serialization code<commit_after>use std::collections::BTreeMap;
use schema::Value;

/// Internal representation of a document used for JSON
/// serialization.
///
/// A `NamedFieldDocument` is a simple representation of a document
/// as a `BTreeMap<String, Vec<Value>>`.
///
#[derive(Serialize)]
pub struct NamedFieldDocument(pub BTreeMap<String, Vec<Value>>);
<|endoftext|>


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

// compile-flags: --cfg fooA --cfg fooB

#[cfg(fooA, not(bar))] // fooA AND !bar
fn foo1() -> int { 1 }

#[cfg(not(fooA, bar))] // !fooA AND !bar
fn foo2() -> int { 2 }

#[cfg(fooC)]
#[cfg(fooB, not(bar))] // fooB AND !bar
fn foo2() -> int { 3 } // fooC OR (fooB AND !bar)

fn main() {
    fail_unless!(1 == foo1());
    fail_unless!(3 == foo2());
}
<commit_msg>Fix pretty printing for cfg test.<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: --cfg fooA --cfg fooB

// fooA AND !bar
#[cfg(fooA, not(bar))]
fn foo1() -> int { 1 }

// !fooA AND !bar
#[cfg(not(fooA, bar))]
fn foo2() -> int { 2 }

// fooC OR (fooB AND !bar)
#[cfg(fooC)]
#[cfg(fooB, not(bar))]
fn foo2() -> int { 3 }

fn main() {
    fail_unless!(1 == foo1());
    fail_unless!(3 == foo2());
}
<|endoftext|>


<commit_before>// Copyright 2018 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is a basic balance service. The only available operation is a wallet balance update.
//! Regression test for transactions processing is built on a base of this service.
extern crate bodyparser;
#[macro_use]
extern crate exonum;
extern crate futures;
extern crate iron;
extern crate router;
extern crate serde;
extern crate serde_json;

pub mod schema {
    use exonum::storage::{Entry, Fork, Snapshot};

    pub struct BalanceSchema<T> {
        view: T,
    }

    impl<T: AsRef<Snapshot>> BalanceSchema<T> {
        pub fn new(view: T) -> Self {
            Self { view }
        }

        pub fn balance(&self) -> Entry<&Snapshot, u64> {
            Entry::new("balance", self.view.as_ref())
        }
    }

    impl<'a> BalanceSchema<&'a mut Fork> {
        pub fn balance_mut(&mut self) -> Entry<&mut Fork, u64> {
            Entry::new("balance", self.view)
        }
    }
}

pub mod transactions {
    use service::SERVICE_ID;

    transactions! {
        pub BalanceTransactions {
            const SERVICE_ID = SERVICE_ID;

            struct TxAddBalance {
                amount: u64,
                seed: u64
            }
        }
    }
}

pub mod contracts {
    use exonum::blockchain::{ExecutionResult, Transaction};
    use exonum::storage::Fork;

    use schema::BalanceSchema;
    use transactions::TxAddBalance;

    impl Transaction for TxAddBalance {
        fn verify(&self) -> bool {
            true
        }

        fn execute(&self, view: &mut Fork) -> ExecutionResult {
            let mut schema = BalanceSchema::new(view);
            let new_balance = schema.balance().get().unwrap() + self.amount();
            schema.balance_mut().set(new_balance);

            Ok(())
        }
    }
}

pub mod service {
    use exonum::blockchain::{Service, Transaction, TransactionSet};
    use exonum::crypto::{gen_keypair, Hash};
    use exonum::helpers;
    use exonum::node::{ExternalMessage, Node, TransactionSend};
    use exonum::storage::{Database, Fork, MemoryDB, Snapshot};
    use exonum::{encoding, messages::RawTransaction};
    use serde_json::Value;

    use schema::BalanceSchema;
    use transactions::{BalanceTransactions, TxAddBalance};

    use std::sync::Arc;
    use std::thread;
    use std::time;

    pub const SERVICE_ID: u16 = 1;

    pub struct BalanceService();

    impl Service for BalanceService {
        fn service_id(&self) -> u16 {
            SERVICE_ID
        }

        fn service_name(&self) -> &str {
            "balance"
        }

        fn state_hash(&self, _: &Snapshot) -> Vec<Hash> {
            vec![]
        }

        fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
            let tx = BalanceTransactions::tx_from_raw(raw)?;
            Ok(tx.into())
        }

        fn initialize(&self, fork: &mut Fork) -> Value {
            let mut schema = BalanceSchema::new(fork);
            schema.balance_mut().set(0);
            Value::Null
        }
    }

    #[test]
    fn test_duplicated_transaction() {
        let (_, private_key) = gen_keypair();

        let db = Arc::from(Box::new(MemoryDB::new()) as Box<Database>) as Arc<Database>;
        let mut node_cfg = helpers::generate_testnet_config(1, 16_500)[0].clone();

        // Override timeouts to little values, so we won't have to wait for consensus too long.
        node_cfg.genesis.consensus.min_propose_timeout = 0;
        node_cfg.genesis.consensus.max_propose_timeout = 0;
        node_cfg.genesis.consensus.propose_timeout_threshold = 0;
        node_cfg.genesis.consensus.round_timeout = 40;

        let service = Box::new(BalanceService());
        let node = Node::new(db.clone(), vec![service], node_cfg.clone());
        let api_tx = node.channel();

        let node_thread = thread::spawn(move || {
            node.run().unwrap();
        });

        let tx_orig = Box::new(TxAddBalance::new(10, 0, &private_key));
        let tx_copy = tx_orig.clone();

        // Send two identical transactions.
        api_tx.send(tx_orig).unwrap();

        api_tx.send(tx_copy).unwrap();

        // Wait to be sure that transaction was processed.
        thread::sleep(time::Duration::from_millis(200));

        // Shut down the node
        api_tx
            .send_external_message(ExternalMessage::Shutdown)
            .unwrap();

        node_thread.join().unwrap();

        // Check that only one transaction was accepted.
        let schema = BalanceSchema::new(db.snapshot());
        let balance = schema.balance().get().unwrap();

        assert_eq!(balance, 10);
    }
}
<commit_msg>Ignore test_duplicated_transaction (#713)<commit_after>// Copyright 2018 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is a basic balance service. The only available operation is a wallet balance update.
//! Regression test for transactions processing is built on a base of this service.
extern crate bodyparser;
#[macro_use]
extern crate exonum;
extern crate futures;
extern crate iron;
extern crate router;
extern crate serde;
extern crate serde_json;

pub mod schema {
    use exonum::storage::{Entry, Fork, Snapshot};

    pub struct BalanceSchema<T> {
        view: T,
    }

    impl<T: AsRef<Snapshot>> BalanceSchema<T> {
        pub fn new(view: T) -> Self {
            Self { view }
        }

        pub fn balance(&self) -> Entry<&Snapshot, u64> {
            Entry::new("balance", self.view.as_ref())
        }
    }

    impl<'a> BalanceSchema<&'a mut Fork> {
        pub fn balance_mut(&mut self) -> Entry<&mut Fork, u64> {
            Entry::new("balance", self.view)
        }
    }
}

pub mod transactions {
    use service::SERVICE_ID;

    transactions! {
        pub BalanceTransactions {
            const SERVICE_ID = SERVICE_ID;

            struct TxAddBalance {
                amount: u64,
                seed: u64
            }
        }
    }
}

pub mod contracts {
    use exonum::blockchain::{ExecutionResult, Transaction};
    use exonum::storage::Fork;

    use schema::BalanceSchema;
    use transactions::TxAddBalance;

    impl Transaction for TxAddBalance {
        fn verify(&self) -> bool {
            true
        }

        fn execute(&self, view: &mut Fork) -> ExecutionResult {
            let mut schema = BalanceSchema::new(view);
            let new_balance = schema.balance().get().unwrap() + self.amount();
            schema.balance_mut().set(new_balance);

            Ok(())
        }
    }
}

pub mod service {
    use exonum::blockchain::{Service, Transaction, TransactionSet};
    use exonum::crypto::{gen_keypair, Hash};
    use exonum::helpers;
    use exonum::node::{ExternalMessage, Node, TransactionSend};
    use exonum::storage::{Database, Fork, MemoryDB, Snapshot};
    use exonum::{encoding, messages::RawTransaction};
    use serde_json::Value;

    use schema::BalanceSchema;
    use transactions::{BalanceTransactions, TxAddBalance};

    use std::sync::Arc;
    use std::thread;
    use std::time;

    pub const SERVICE_ID: u16 = 1;

    pub struct BalanceService();

    impl Service for BalanceService {
        fn service_id(&self) -> u16 {
            SERVICE_ID
        }

        fn service_name(&self) -> &str {
            "balance"
        }

        fn state_hash(&self, _: &Snapshot) -> Vec<Hash> {
            vec![]
        }

        fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
            let tx = BalanceTransactions::tx_from_raw(raw)?;
            Ok(tx.into())
        }

        fn initialize(&self, fork: &mut Fork) -> Value {
            let mut schema = BalanceSchema::new(fork);
            schema.balance_mut().set(0);
            Value::Null
        }
    }

    #[test]
    #[ignore] // FIXME: Test fails at random condition [ECR-1410]
    fn test_duplicated_transaction() {
        let (_, private_key) = gen_keypair();

        let db = Arc::from(Box::new(MemoryDB::new()) as Box<Database>) as Arc<Database>;
        let mut node_cfg = helpers::generate_testnet_config(1, 16_500)[0].clone();

        // Override timeouts to little values, so we won't have to wait for consensus too long.
        node_cfg.genesis.consensus.min_propose_timeout = 0;
        node_cfg.genesis.consensus.max_propose_timeout = 0;
        node_cfg.genesis.consensus.propose_timeout_threshold = 0;
        node_cfg.genesis.consensus.round_timeout = 40;

        let service = Box::new(BalanceService());
        let node = Node::new(db.clone(), vec![service], node_cfg.clone());
        let api_tx = node.channel();

        let node_thread = thread::spawn(move || {
            node.run().unwrap();
        });

        let tx_orig = Box::new(TxAddBalance::new(10, 0, &private_key));
        let tx_copy = tx_orig.clone();

        // Send two identical transactions.
        api_tx.send(tx_orig).unwrap();

        api_tx.send(tx_copy).unwrap();

        // Wait to be sure that transaction was processed.
        thread::sleep(time::Duration::from_millis(200));

        // Shut down the node
        api_tx
            .send_external_message(ExternalMessage::Shutdown)
            .unwrap();

        node_thread.join().unwrap();

        // Check that only one transaction was accepted.
        let schema = BalanceSchema::new(db.snapshot());
        let balance = schema.balance().get().unwrap();

        assert_eq!(balance, 10);
    }
}
<|endoftext|>


<commit_before>use std::default::Default;
use std::path::Path;

use collada;
use gfx;
use gfx::Typed;
use gfx::traits::*;
use gfx_texture;

use math::*;
use skeleton::Skeleton;
use transform::Transform;

const MAX_JOINTS: usize = 64;

pub struct SkinnedRenderBatch<R: gfx::Resources, T: Transform> {
    skinning_transforms_buffer: gfx::handle::Buffer<R, T>,
    slice: gfx::Slice<R>,
    vertex_buffer: gfx::handle::Buffer<R, SkinnedVertex>,
    pso: gfx::PipelineState<R, pipe::Meta>,
    texture: (gfx::handle::ShaderResourceView<R, [f32; 4]>, gfx::handle::Sampler<R>),
}

pub struct SkinnedRenderer<R: gfx::Resources, T: Transform> {
    skeleton: Skeleton, // TODO Should this be a ref? Should this just be the joints?
    render_batches: Vec<SkinnedRenderBatch<R, T>>,
}

pub trait HasShaderSources<'a> {
    fn vertex_shader_source() -> &'a [u8];
    fn fragment_shader_source() -> &'a [u8];
}

impl<'a> HasShaderSources<'a> for Matrix4<f32> {
    fn vertex_shader_source() -> &'a [u8] {
        include_bytes!("lbs_skinning_150.glslv")
    }
    fn fragment_shader_source() -> &'a [u8] {
        include_bytes!("skinning_150.glslf")
    }
}

impl<'a> HasShaderSources<'a> for DualQuaternion<f32> {
    fn vertex_shader_source() -> &'a [u8] {
        include_bytes!("dlb_skinning_150.glslv")
    }
    fn fragment_shader_source() -> &'a [u8] {
        include_bytes!("skinning_150.glslf")
    }
}

impl<'a, R: gfx::Resources, T: Transform + HasShaderSources<'a>> SkinnedRenderer<R, T> {

    pub fn from_collada<F: gfx::Factory<R>>(
        factory: &mut F,
        collada_document: collada::document::ColladaDocument,
        texture_paths: Vec<&str>, // TODO - read from the COLLADA document (if available)
    ) -> Result<SkinnedRenderer<R, T>, gfx::shade::ProgramError> {
        use gfx::format::Formatted;

        let program = {
            let vs = T::vertex_shader_source();
            let fs = T::fragment_shader_source();
            match factory.link_program(vs, fs) {
                Ok(program_handle) => program_handle,
                Err(e) => return Err(e),
            }
        };

        let obj_set = collada_document.get_obj_set().unwrap();

        let skeleton_set = collada_document.get_skeletons().unwrap();
        let skeleton = Skeleton::from_collada(&skeleton_set[0]);

        let mut render_batches = Vec::new();

        for (i, object) in obj_set.objects.iter().enumerate().take(6) {

            let mut vertex_data: Vec<SkinnedVertex> = Vec::new();
            let mut index_data: Vec<u32> = Vec::new();

            get_vertex_index_data(&object, &mut vertex_data, &mut index_data);

            let (vbuf, slice) = factory.create_vertex_buffer_with_slice
                (&vertex_data, &index_data[..]);

            // let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

            /*
            let slice = factory
                .create_buffer_const::<u32>(&index_data[..], gfx::BufferRole::Index)
                .unwrap()
                .to_slice(gfx::PrimitiveType::TriangleList);
            */

            let skinning_transforms_buffer = factory.create_buffer_dynamic::<T>(
                MAX_JOINTS, gfx::BufferRole::Uniform, gfx::Bind::empty()).unwrap();

            let texture = gfx_texture::Texture::from_path(
                factory,
                &Path::new(&texture_paths[i]),
                gfx_texture::Flip::None,
                &gfx_texture::TextureSettings::new()
            ).unwrap();

            let sampler = factory.create_sampler(
                gfx::tex::SamplerInfo::new(
                    gfx::tex::FilterMethod::Trilinear,
                    gfx::tex::WrapMode::Clamp
                )
            );

            /*
            let mut batch = gfx::batch::Full::new(mesh, program.clone(), shader_params).unwrap();
            batch.slice = slice;
            batch.state = state;
            */

            // TODO: Pass in format as parameter.
            let format = gfx::format::Srgba8::get_format();
            let init = pipe::Init {
                vertex: (),
                u_model_view_proj: "u_model_view_proj",
                u_model_view: "u_model_view",
                u_skinning_transforms: "u_skinning_transforms",
                u_texture: "u_texture",
                out_color: ("out_color", format, gfx::state::MASK_ALL, Some(gfx::preset::blend::ALPHA)),
                out_depth: gfx::preset::depth::LESS_EQUAL_WRITE,
            };
            let pso = factory.create_pipeline_from_program(
                &program,
                gfx::Primitive::LineList,
                gfx::state::Rasterizer::new_fill(),
                init
            ).unwrap();

            render_batches.push(SkinnedRenderBatch {
                pso: pso,
                slice: slice,
                vertex_buffer: vbuf,
                skinning_transforms_buffer: skinning_transforms_buffer,
                texture: (texture.view.clone(), sampler),
            });
        }

        Ok(SkinnedRenderer {
            render_batches: render_batches,
            skeleton: skeleton.clone(),
        })
    }

    pub fn render<C: gfx::CommandBuffer<R>, Rf: gfx::format::RenderFormat> (
        &mut self,
        encoder: &mut gfx::Encoder<R, C>,
        out_color: &gfx::handle::RenderTargetView<R, Rf>,
        out_depth: &gfx::handle::DepthStencilView<R, gfx::format::DepthStencil>,
        view: [[f32; 4]; 4],
        projection: [[f32; 4]; 4],
        joint_poses: &[T]
    ) {

        let skinning_transforms = self.calculate_skinning_transforms(&joint_poses);

        for material in self.render_batches.iter_mut() {
            // FIXME -- should all be able to share the same buffer
            encoder.update_buffer(&material.skinning_transforms_buffer, &skinning_transforms[..], 0).unwrap();

            let data = pipe::Data {
                vertex: material.vertex_buffer.clone(),
                u_model_view_proj: projection,
                u_model_view: view,
                u_skinning_transforms: material.skinning_transforms_buffer.raw().clone(),
                u_texture: material.texture.clone(),
                out_color: out_color.raw().clone(),
                out_depth: out_depth.clone(),
            };

            encoder.draw(&material.slice, &material.pso, &data);
        }
    }

    ///
    /// TODO - don't allocate a new vector
    ///
    pub fn calculate_skinning_transforms(&self, global_poses: &[T]) -> Vec<T> {
        self.skeleton.joints.iter().enumerate().map(|(i, joint)| {
            // TODO avoid conversion...
            global_poses[i].concat(T::from_matrix(joint.inverse_bind_pose))
        }).collect()
    }
}

gfx_pipeline_base!( pipe {
    vertex: gfx::VertexBuffer<SkinnedVertex>,
    u_model_view_proj: gfx::Global<[[f32; 4]; 4]>,
    u_model_view: gfx::Global<[[f32; 4]; 4]>,
    u_skinning_transforms: gfx::RawConstantBuffer,
    u_texture: gfx::TextureSampler<[f32; 4]>,
    out_color: gfx::RawRenderTarget,
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil>,
});

/*
gfx_pipeline!( pipe {
    u_model_view_proj: gfx::Global<[[f32; 4]; 4]> = "u_model_view_proj",
    u_model_view: gfx::Global<[[f32; 4]; 4]> = "u_model_view",
    u_skinning_transforms: gfx::RawVertexBuffer = &[],
    u_texture: gfx::TextureSampler<[f32; 4]> = "u_texture",
    // out_color: gfx::RenderTarget<gfx::format::Srgba8> = "o_Color",
    out_color: gfx::RawRenderTarget = "o_Color",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> =
        gfx::preset::depth::LESS_EQUAL_WRITE,
});
*/

gfx_vertex_struct!(SkinnedVertex {
    pos: [f32; 3] = "pos",
    normal: [f32; 3] = "normal",
    uv: [f32; 2] = "uv",
    joint_indices: [i32; 4] = "joint_indices",
    joint_weights: [f32; 4] = "joint_weights", // TODO last weight is redundant
});

impl Default for SkinnedVertex {
    fn default() -> SkinnedVertex {
        SkinnedVertex {
            pos: [0.0; 3],
            normal: [0.0; 3],
            uv: [0.0; 2],
            joint_indices: [0; 4],
            joint_weights: [0.0; 4],
        }
    }
}

fn vtn_to_vertex(a: collada::VTNIndex, obj: &collada::Object) -> SkinnedVertex
{
    let mut vertex: SkinnedVertex = Default::default();
    let position = obj.vertices[a.0];

    vertex.pos = [position.x as f32, position.y as f32, position.z as f32];

    if obj.joint_weights.len() == obj.vertices.len() {
        let weights = obj.joint_weights[a.0];
        vertex.joint_weights = weights.weights;
        vertex.joint_indices = [
            weights.joints[0] as i32,
            weights.joints[1] as i32,
            weights.joints[2] as i32,
            weights.joints[3] as i32,
        ];
    }

    if let Some(uv) = a.1 {
        let uv = obj.tex_vertices[uv];
        vertex.uv = [uv.x as f32, uv.y as f32];
    }

    if let Some(normal) = a.2 {
        let normal = obj.normals[normal];
        vertex.normal = [normal.x as f32, normal.y as f32, normal.z as f32];
    }

    vertex
}

fn get_vertex_index_data(obj: &collada::Object, vertex_data: &mut Vec<SkinnedVertex>, index_data: &mut Vec<u32>) {
    for geom in obj.geometry.iter() {
        let mut i = vertex_data.len() as u32;
        let mut uvs: u32 = 0;
        let mut normals: u32 = 0;
        {
            let mut add = |a: collada::VTNIndex| {
                if let Some(_) = a.1 { uvs += 1; }
                if let Some(_) = a.2 { normals += 1; }
                vertex_data.push(vtn_to_vertex(a, obj));
                index_data.push(i);
                i += 1;
            };
            for shape in geom.shapes.iter() {
                match shape {
                    &collada::Shape::Triangle(a, b, c) => {
                        add(a);
                        add(b);
                        add(c);
                    }
                    _ => {}
                }
            }
        }
    }
}
<commit_msg>Moved PSO out of the render batch<commit_after>use std::default::Default;
use std::path::Path;

use collada;
use gfx;
use gfx::Typed;
use gfx::traits::*;
use gfx_texture;

use math::*;
use skeleton::Skeleton;
use transform::Transform;

const MAX_JOINTS: usize = 64;

pub struct SkinnedRenderBatch<R: gfx::Resources, T: Transform> {
    skinning_transforms_buffer: gfx::handle::Buffer<R, T>,
    slice: gfx::Slice<R>,
    vertex_buffer: gfx::handle::Buffer<R, SkinnedVertex>,
    texture: (gfx::handle::ShaderResourceView<R, [f32; 4]>, gfx::handle::Sampler<R>),
}

pub struct SkinnedRenderer<R: gfx::Resources, T: Transform> {
    pso: gfx::PipelineState<R, pipe::Meta>,
    skeleton: Skeleton, // TODO Should this be a ref? Should this just be the joints?
    render_batches: Vec<SkinnedRenderBatch<R, T>>,
}

pub trait HasShaderSources<'a> {
    fn vertex_shader_source() -> &'a [u8];
    fn fragment_shader_source() -> &'a [u8];
}

impl<'a> HasShaderSources<'a> for Matrix4<f32> {
    fn vertex_shader_source() -> &'a [u8] {
        include_bytes!("lbs_skinning_150.glslv")
    }
    fn fragment_shader_source() -> &'a [u8] {
        include_bytes!("skinning_150.glslf")
    }
}

impl<'a> HasShaderSources<'a> for DualQuaternion<f32> {
    fn vertex_shader_source() -> &'a [u8] {
        include_bytes!("dlb_skinning_150.glslv")
    }
    fn fragment_shader_source() -> &'a [u8] {
        include_bytes!("skinning_150.glslf")
    }
}

impl<'a, R: gfx::Resources, T: Transform + HasShaderSources<'a>> SkinnedRenderer<R, T> {

    pub fn from_collada<F: gfx::Factory<R>>(
        factory: &mut F,
        collada_document: collada::document::ColladaDocument,
        texture_paths: Vec<&str>, // TODO - read from the COLLADA document (if available)
    ) -> Result<SkinnedRenderer<R, T>, gfx::shade::ProgramError> {
        use gfx::format::Formatted;

        let program = {
            let vs = T::vertex_shader_source();
            let fs = T::fragment_shader_source();
            match factory.link_program(vs, fs) {
                Ok(program_handle) => program_handle,
                Err(e) => return Err(e),
            }
        };

        // TODO: Pass in format as parameter.
        let format = gfx::format::Srgba8::get_format();
        let init = pipe::Init {
            vertex: (),
            u_model_view_proj: "u_model_view_proj",
            u_model_view: "u_model_view",
            u_skinning_transforms: "u_skinning_transforms",
            u_texture: "u_texture",
            out_color: ("out_color", format, gfx::state::MASK_ALL, Some(gfx::preset::blend::ALPHA)),
            out_depth: gfx::preset::depth::LESS_EQUAL_WRITE,
        };
        let pso = factory.create_pipeline_from_program(
            &program,
            gfx::Primitive::LineList,
            gfx::state::Rasterizer::new_fill(),
            init
        ).unwrap();

        let sampler = factory.create_sampler(
            gfx::tex::SamplerInfo::new(
                gfx::tex::FilterMethod::Trilinear,
                gfx::tex::WrapMode::Clamp
            )
        );

        let obj_set = collada_document.get_obj_set().unwrap();

        let skeleton_set = collada_document.get_skeletons().unwrap();
        let skeleton = Skeleton::from_collada(&skeleton_set[0]);

        let mut render_batches = Vec::new();

        for (i, object) in obj_set.objects.iter().enumerate().take(6) {

            let mut vertex_data: Vec<SkinnedVertex> = Vec::new();
            let mut index_data: Vec<u32> = Vec::new();

            get_vertex_index_data(&object, &mut vertex_data, &mut index_data);

            let (vbuf, slice) = factory.create_vertex_buffer_with_slice
                (&vertex_data, &index_data[..]);

            let skinning_transforms_buffer = factory.create_buffer_dynamic::<T>(
                MAX_JOINTS, gfx::BufferRole::Uniform, gfx::Bind::empty()).unwrap();

            let texture = gfx_texture::Texture::from_path(
                factory,
                &Path::new(&texture_paths[i]),
                gfx_texture::Flip::None,
                &gfx_texture::TextureSettings::new()
            ).unwrap();

            render_batches.push(SkinnedRenderBatch {
                slice: slice,
                vertex_buffer: vbuf,
                skinning_transforms_buffer: skinning_transforms_buffer,
                texture: (texture.view.clone(), sampler.clone()),
            });
        }

        Ok(SkinnedRenderer {
            pso: pso,
            render_batches: render_batches,
            skeleton: skeleton.clone(),
        })
    }

    pub fn render<C: gfx::CommandBuffer<R>, Rf: gfx::format::RenderFormat> (
        &mut self,
        encoder: &mut gfx::Encoder<R, C>,
        out_color: &gfx::handle::RenderTargetView<R, Rf>,
        out_depth: &gfx::handle::DepthStencilView<R, gfx::format::DepthStencil>,
        view: [[f32; 4]; 4],
        projection: [[f32; 4]; 4],
        joint_poses: &[T]
    ) {

        let skinning_transforms = self.calculate_skinning_transforms(&joint_poses);

        for material in self.render_batches.iter_mut() {
            // FIXME -- should all be able to share the same buffer
            encoder.update_buffer(&material.skinning_transforms_buffer, &skinning_transforms[..], 0).unwrap();

            let data = pipe::Data {
                vertex: material.vertex_buffer.clone(),
                u_model_view_proj: projection,
                u_model_view: view,
                u_skinning_transforms: material.skinning_transforms_buffer.raw().clone(),
                u_texture: material.texture.clone(),
                out_color: out_color.raw().clone(),
                out_depth: out_depth.clone(),
            };

            encoder.draw(&material.slice, &self.pso, &data);
        }
    }

    ///
    /// TODO - don't allocate a new vector
    ///
    pub fn calculate_skinning_transforms(&self, global_poses: &[T]) -> Vec<T> {
        self.skeleton.joints.iter().enumerate().map(|(i, joint)| {
            // TODO avoid conversion...
            global_poses[i].concat(T::from_matrix(joint.inverse_bind_pose))
        }).collect()
    }
}

gfx_pipeline_base!( pipe {
    vertex: gfx::VertexBuffer<SkinnedVertex>,
    u_model_view_proj: gfx::Global<[[f32; 4]; 4]>,
    u_model_view: gfx::Global<[[f32; 4]; 4]>,
    u_skinning_transforms: gfx::RawConstantBuffer,
    u_texture: gfx::TextureSampler<[f32; 4]>,
    out_color: gfx::RawRenderTarget,
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil>,
});

/*
gfx_pipeline!( pipe {
    u_model_view_proj: gfx::Global<[[f32; 4]; 4]> = "u_model_view_proj",
    u_model_view: gfx::Global<[[f32; 4]; 4]> = "u_model_view",
    u_skinning_transforms: gfx::RawVertexBuffer = &[],
    u_texture: gfx::TextureSampler<[f32; 4]> = "u_texture",
    // out_color: gfx::RenderTarget<gfx::format::Srgba8> = "o_Color",
    out_color: gfx::RawRenderTarget = "o_Color",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> =
        gfx::preset::depth::LESS_EQUAL_WRITE,
});
*/

gfx_vertex_struct!(SkinnedVertex {
    pos: [f32; 3] = "pos",
    normal: [f32; 3] = "normal",
    uv: [f32; 2] = "uv",
    joint_indices: [i32; 4] = "joint_indices",
    joint_weights: [f32; 4] = "joint_weights", // TODO last weight is redundant
});

impl Default for SkinnedVertex {
    fn default() -> SkinnedVertex {
        SkinnedVertex {
            pos: [0.0; 3],
            normal: [0.0; 3],
            uv: [0.0; 2],
            joint_indices: [0; 4],
            joint_weights: [0.0; 4],
        }
    }
}

fn vtn_to_vertex(a: collada::VTNIndex, obj: &collada::Object) -> SkinnedVertex
{
    let mut vertex: SkinnedVertex = Default::default();
    let position = obj.vertices[a.0];

    vertex.pos = [position.x as f32, position.y as f32, position.z as f32];

    if obj.joint_weights.len() == obj.vertices.len() {
        let weights = obj.joint_weights[a.0];
        vertex.joint_weights = weights.weights;
        vertex.joint_indices = [
            weights.joints[0] as i32,
            weights.joints[1] as i32,
            weights.joints[2] as i32,
            weights.joints[3] as i32,
        ];
    }

    if let Some(uv) = a.1 {
        let uv = obj.tex_vertices[uv];
        vertex.uv = [uv.x as f32, uv.y as f32];
    }

    if let Some(normal) = a.2 {
        let normal = obj.normals[normal];
        vertex.normal = [normal.x as f32, normal.y as f32, normal.z as f32];
    }

    vertex
}

fn get_vertex_index_data(obj: &collada::Object, vertex_data: &mut Vec<SkinnedVertex>, index_data: &mut Vec<u32>) {
    for geom in obj.geometry.iter() {
        let mut i = vertex_data.len() as u32;
        let mut uvs: u32 = 0;
        let mut normals: u32 = 0;
        {
            let mut add = |a: collada::VTNIndex| {
                if let Some(_) = a.1 { uvs += 1; }
                if let Some(_) = a.2 { normals += 1; }
                vertex_data.push(vtn_to_vertex(a, obj));
                index_data.push(i);
                i += 1;
            };
            for shape in geom.shapes.iter() {
                match shape {
                    &collada::Shape::Triangle(a, b, c) => {
                        add(a);
                        add(b);
                        add(c);
                    }
                    _ => {}
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>#![crate_type = "proc-macro"]
#![recursion_limit = "192"]
#![feature(trace_macros)]
#![feature(log_syntax)]

extern crate syn;
extern crate proc_macro;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;

#[proc_macro_derive(ModParse, attributes(module))]
pub fn parse(input: TokenStream) -> TokenStream {
    let source = input.to_string();
    let mut ast = syn::parse_derive_input(&source).expect("failed to parse rust syntax");
    let gen = impl_parse(&mut ast);
    gen.parse().expect("failed to serialize into rust syntax")
}

fn impl_parse(ast: &mut syn::DeriveInput) -> quote::Tokens {
    use syn::{Body, VariantData};

    let ref mut variants = match ast.body {
        Body::Struct(VariantData::Struct(ref vars)) => vars,
        _ => panic!("#[derive(Parse)] is only defined for braced structs"),
    };

    let name = &ast.ident;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let atmatch = variants.iter()
        .filter_map(|field| {
        	let field_name = field.ident.as_ref().clone();

        	let ret = if field.attrs.iter().any(|attr| attr.name() == "param") {
        		Some( quote! { self.delegate._params.push(stringify!(#field_name) ) } )
        	} else if field.attrs.iter().any(|attr| attr.name() == "module") {
//        		Some ( quote! { self.delegate._modules.insert(stringify!(#field_name).to_owned(), self. #field_name .delegate()) } )
        		Some ( quote! {
        			self.delegate.add_module(&mut self. #field_name );
        		 } )
        	} else { None };
        	//field.attrs.retain(|ref attr| !names.contains(&attr.name()) );
    		ret
        });
    let foo = quote! {
        impl #impl_generics ModuleStruct<'a> for #name  #ty_generics  #where_clause {
            fn init_module(&mut self) {
            	self.delegate._name = stringify!(#name);
				#(#atmatch);*
				;
            }
        }
    };
    println!("parse is {}", foo);
    foo
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>GC dead code<commit_after>#![crate_type = "proc-macro"]
#![recursion_limit = "192"]
#![feature(trace_macros)]
#![feature(log_syntax)]

extern crate syn;
extern crate proc_macro;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;

#[proc_macro_derive(ModParse, attributes(module))]
pub fn parse(input: TokenStream) -> TokenStream {
    let source = input.to_string();
    let mut ast = syn::parse_derive_input(&source).expect("failed to parse rust syntax");
    let gen = impl_parse(&mut ast);
    gen.parse().expect("failed to serialize into rust syntax")
}

fn impl_parse(ast: &mut syn::DeriveInput) -> quote::Tokens {
    use syn::{Body, VariantData};

    let ref mut variants = match ast.body {
        Body::Struct(VariantData::Struct(ref vars)) => vars,
        _ => panic!("#[derive(Parse)] is only defined for braced structs"),
    };

    let name = &ast.ident;
    let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
    let atmatch = variants.iter()
        .filter_map(|field| {
        	let field_name = field.ident.as_ref().clone();

        	let ret = if field.attrs.iter().any(|attr| attr.name() == "param") {
        		Some( quote! { self.delegate._params.push(stringify!(#field_name) ) } )
        	} else if field.attrs.iter().any(|attr| attr.name() == "module") {
//        		Some ( quote! { self.delegate._modules.insert(stringify!(#field_name).to_owned(), self. #field_name .delegate()) } )
        		Some ( quote! {
        			self.delegate.add_module(&mut self. #field_name );
        		 } )
        	} else { None };
    		ret
        });
    let foo = quote! {
        impl #impl_generics ModuleStruct<'a> for #name  #ty_generics  #where_clause {
            fn init_module(&mut self) {
            	self.delegate._name = stringify!(#name);
				#(#atmatch);*
				;
            }
        }
    };
    println!("parse is {}", foo);
    foo
}

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


<commit_before>/* AES ECB/CBC mode oracle
 *
 * Dmitry Vasiliev <dima@hlabs.org>
 */

extern crate aes_lib;

use std::rand::{random, task_rng, Rng};

use aes_lib::{AES_BLOCK_SIZE, encrypt_aes_ecb, encrypt_aes_cbc};

fn random_bytes(len: uint) -> Vec<u8> {
    Vec::from_fn(len, |_| random::<u8>())
}

fn random_uint(low: uint, high: uint) -> uint {
    task_rng().gen_range(low, high)
}

fn random_bool() -> bool {
    random::<bool>()
}

fn aes_encrypt() -> (Vec<u8>, bool) {
    let key = random_bytes(AES_BLOCK_SIZE);
    let data = random_bytes(AES_BLOCK_SIZE * random_uint(30, 80)
                            + random_uint(0, AES_BLOCK_SIZE));
    let use_ecb = random_bool();
    let encrypted = if use_ecb {
        encrypt_aes_ecb(data.as_slice(), key.as_slice())
    } else {
        let iv = random_bytes(AES_BLOCK_SIZE);
        encrypt_aes_cbc(data.as_slice(), key.as_slice(), iv.as_slice())
    };
    (encrypted, use_ecb)
}

fn main() {
    let (encrypted, use_ecb) = aes_encrypt();
    let mode = if use_ecb {"ECB"} else {"CBC"};
    println!("Mode: {} Enc: {}", mode, encrypted);
}
<commit_msg>Add enum for AES modes<commit_after>/* AES ECB/CBC mode oracle
 *
 * Dmitry Vasiliev <dima@hlabs.org>
 */

extern crate aes_lib;

use std::rand::{random, task_rng, Rng, Rand};
use std::fmt::{Show, Formatter, FormatError};

use aes_lib::{AES_BLOCK_SIZE, encrypt_aes_ecb, encrypt_aes_cbc};

enum Mode {
    ECB,
    CBC
}

impl Rand for Mode {
    fn rand<R: Rng>(rng: &mut R) -> Mode {
        match rng.gen() {
            true => ECB,
            false => CBC
        }
    }
}

impl Show for Mode {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        match *self {
            ECB => f.pad("ECB"),
            CBC => f.pad("CBC")
        }
    }
}

fn random_bytes(len: uint) -> Vec<u8> {
    Vec::from_fn(len, |_| random::<u8>())
}

fn random_uint(low: uint, high: uint) -> uint {
    task_rng().gen_range(low, high)
}

fn aes_encrypt() -> (Vec<u8>, Mode) {
    let key = random_bytes(AES_BLOCK_SIZE);
    let data = random_bytes(AES_BLOCK_SIZE * random_uint(30, 80)
                            + random_uint(0, AES_BLOCK_SIZE));
    match random::<Mode>() {
        ECB => (encrypt_aes_ecb(data.as_slice(), key.as_slice()), ECB),
        CBC => {
            let iv = random_bytes(AES_BLOCK_SIZE);
            (encrypt_aes_cbc(data.as_slice(), key.as_slice(),
                             iv.as_slice()), CBC)
        }
    }
}

fn main() {
    let (encrypted, mode) = aes_encrypt();
    println!("Mode: {}", mode);
}
<|endoftext|>