<commit_before>use architecture::*;
use goblin;
use loader::*;
use memory::backing::Memory;
use memory::MemoryPermissions;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Read;
use std::path::Path;

/// Loader for a single ELf file.
#[derive(Debug)]
pub struct Elf {
    base_address: u64,
    bytes: Vec<u8>,
    user_function_entries: Vec<u64>,
    architecture: Box<Architecture>
}

impl Elf {
    /// Create a new Elf from the given bytes. This Elf will be rebased to the given
    /// base address.
    pub fn new(bytes: Vec<u8>, base_address: u64) -> Result<Elf> {
        let architecture = {
            let elf = goblin::elf::Elf::parse(&bytes)
                .map_err(|_| "Not a valid elf")?;

            let architecture =
                if elf.header.e_machine == goblin::elf::header::EM_386 {
                    Box::new(X86::new())
                }
                else if elf.header.e_machine == goblin::elf::header::EM_MIPS {
                    match elf.header.endianness()? {
                        goblin::container::Endian::Big =>
                            Box::new(Mips::new()) as Box<Architecture>,
                        goblin::container::Endian::Little =>
                            Box::new(Mipsel::new()) as Box<Architecture>,
                    }
                }
                else {
                    bail!("Unsupported Architecture");
                };

            architecture
        };

        Ok(Elf {
            base_address: base_address,
            bytes: bytes,
            user_function_entries: Vec::new(),
            architecture: architecture
        })
    }

    /// Get the base address of this Elf where it has been loaded into loader
    /// memory.
    pub fn base_address(&self) -> u64 {
        self.base_address
    }

    /// Load an Elf from a file and use the given base address.
    pub fn from_file_with_base_address(filename: &Path, base_address: u64)
        -> Result<Elf> {
        let mut file = match File::open(filename) {
            Ok(file) => file,
            Err(e) => return Err(format!(
                "Error opening {}: {}",
                filename.to_str().unwrap(),
                e).into())
        };
        let mut buf = Vec::new();
        file.read_to_end(&mut buf)?;
        Elf::new(buf, base_address)
    }

    /// Load an elf from a file and use the base address of 0.
    pub fn from_file(filename: &Path) -> Result<Elf> {
        Elf::from_file_with_base_address(filename, 0)
    }

    /// Allow the user to manually specify a function entry
    pub fn add_user_function(&mut self, address: u64) {
        self.user_function_entries.push(address);
    }

    /// Return the strings from the DT_NEEDED entries.
    pub fn dt_needed(&self) -> Result<Vec<String>> {
        let mut v = Vec::new();

        let elf = self.elf();
        if let Some(dynamic) = elf.dynamic {
            // We need that strtab, and we have to do this one manually.
            // Get the strtab address
            let mut strtab_address = None;
            for dyn in &dynamic.dyns {
                if dyn.d_tag == goblin::elf::dyn::DT_STRTAB {
                    strtab_address = Some(dyn.d_val);
                    break;
                }
            }
            if strtab_address.is_none() {
                return Ok(v);
            }
            let strtab_address = strtab_address.unwrap();
            // We're going to make a pretty safe assumption that strtab is all
            // in one section
            for section_header in &elf.section_headers {
                if    section_header.sh_addr > 0
                   && section_header.sh_addr <= strtab_address
                   && section_header.sh_addr + section_header.sh_size > strtab_address {
                    let start = section_header.sh_offset + (strtab_address - section_header.sh_addr);
                    let size = section_header.sh_size - (start - section_header.sh_offset);
                    let start = start as usize;
                    let size = size as usize;
                    let strtab_bytes = self.bytes.get(start..(start + size)).unwrap();
                    let strtab = goblin::strtab::Strtab::new(&strtab_bytes, 0);
                    for dyn in dynamic.dyns {
                        if dyn.d_tag == goblin::elf::dyn::DT_NEEDED {
                            let so_name = &strtab[dyn.d_val as usize];
                            v.push(so_name.to_string());
                        }
                    }
                    return Ok(v);
                }
            }
            // if we got here, we didn't return a vector (I think ;))
            panic!("Failed to get Dynamic strtab");
        }

        Ok(v)
    }

    /// Return the goblin::elf::Elf for this elf.
    pub(crate) fn elf(&self) -> goblin::elf::Elf {
        goblin::elf::Elf::parse(&self.bytes).unwrap()
    }

    /// Return all symbols exported from this Elf
    pub(crate) fn exported_symbols(&self) -> Vec<Symbol> {
        let mut v = Vec::new();
        let elf = self.elf();
        for sym in elf.dynsyms.iter() {
            if sym.st_value == 0 {
                continue;
            }
            if    sym.st_bind() == goblin::elf::sym::STB_GLOBAL
               || sym.st_bind() == goblin::elf::sym::STB_WEAK {
                v.push(Symbol::new(&elf.dynstrtab[sym.st_name], sym.st_value));
            }
        }

        v
    }
}

impl Loader for Elf {
    fn memory(&self) -> Result<Memory> {
        let elf = self.elf();
        let mut memory = Memory::new(self.architecture().endian());

        for ph in elf.program_headers {
            if ph.p_type == goblin::elf::program_header::PT_LOAD {
                let file_range = (ph.p_offset as usize)..((ph.p_offset + ph.p_filesz) as usize);
                let mut bytes = self.bytes
                                    .get(file_range)
                                    .ok_or("Malformed Elf")?
                                    .to_vec();

                if bytes.len() != ph.p_memsz as usize {
                    bytes.append(&mut vec![0; (ph.p_memsz - ph.p_filesz) as usize]);
                }

                let mut permissions = memory::MemoryPermissions::NONE;
                if ph.p_flags & goblin::elf::program_header::PF_R != 0 {
                    permissions |= MemoryPermissions::READ;
                }
                if ph.p_flags & goblin::elf::program_header::PF_W != 0 {
                    permissions |= MemoryPermissions::WRITE;
                }
                if ph.p_flags & goblin::elf::program_header::PF_X != 0 {
                    permissions |= MemoryPermissions::EXECUTE;
                }

                memory.set_memory(ph.p_vaddr + self.base_address,
                                  bytes,
                                  permissions);
            }
        }

        Ok(memory)
    }

    fn function_entries(&self) -> Result<Vec<FunctionEntry>> {
        let elf = self.elf();

        let mut function_entries = Vec::new();

        let mut functions_added: BTreeSet<u64> = BTreeSet::new();

        // dynamic symbols
        for sym in &elf.dynsyms {
            if sym.is_function() && sym.st_value != 0 {
                let name = &elf.dynstrtab[sym.st_name];
                function_entries.push(FunctionEntry::new(
                    sym.st_value + self.base_address,
                    Some(name.to_string())
                ));
                functions_added.insert(sym.st_value);
            }
        }

        // normal symbols
        for sym in &elf.syms {
            if sym.is_function() && sym.st_value != 0 {
                let name = &elf.strtab[sym.st_name];
                function_entries.push(FunctionEntry::new(
                    sym.st_value + self.base_address,
                    Some(name.to_string()))
                );
                functions_added.insert(sym.st_value);
            }
        }

        if !functions_added.contains(&elf.header.e_entry) {
            function_entries.push(FunctionEntry::new(
                elf.header.e_entry + self.base_address,
                None
            ));
        }

        for user_function_entry in &self.user_function_entries {
            if functions_added.get(&(user_function_entry + self.base_address)).is_some() {
                continue;
            }

            function_entries.push(FunctionEntry::new(
                user_function_entry + self.base_address,
                Some(format!("user_function_{:x}", user_function_entry))
            ));
        }

        Ok(function_entries)
    }

    fn program_entry(&self) -> u64 {
        self.elf().header.e_entry
    }

    fn architecture(&self) -> &Architecture {
        self.architecture.as_ref()
    }
}<commit_msg>don't export symbols with a section index of 0<commit_after>use architecture::*;
use goblin;
use loader::*;
use memory::backing::Memory;
use memory::MemoryPermissions;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Read;
use std::path::Path;

/// Loader for a single ELf file.
#[derive(Debug)]
pub struct Elf {
    base_address: u64,
    bytes: Vec<u8>,
    user_function_entries: Vec<u64>,
    architecture: Box<Architecture>
}

impl Elf {
    /// Create a new Elf from the given bytes. This Elf will be rebased to the given
    /// base address.
    pub fn new(bytes: Vec<u8>, base_address: u64) -> Result<Elf> {
        let architecture = {
            let elf = goblin::elf::Elf::parse(&bytes)
                .map_err(|_| "Not a valid elf")?;

            let architecture =
                if elf.header.e_machine == goblin::elf::header::EM_386 {
                    Box::new(X86::new())
                }
                else if elf.header.e_machine == goblin::elf::header::EM_MIPS {
                    match elf.header.endianness()? {
                        goblin::container::Endian::Big =>
                            Box::new(Mips::new()) as Box<Architecture>,
                        goblin::container::Endian::Little =>
                            Box::new(Mipsel::new()) as Box<Architecture>,
                    }
                }
                else {
                    bail!("Unsupported Architecture");
                };

            architecture
        };

        Ok(Elf {
            base_address: base_address,
            bytes: bytes,
            user_function_entries: Vec::new(),
            architecture: architecture
        })
    }

    /// Get the base address of this Elf where it has been loaded into loader
    /// memory.
    pub fn base_address(&self) -> u64 {
        self.base_address
    }

    /// Load an Elf from a file and use the given base address.
    pub fn from_file_with_base_address(filename: &Path, base_address: u64)
        -> Result<Elf> {
        let mut file = match File::open(filename) {
            Ok(file) => file,
            Err(e) => return Err(format!(
                "Error opening {}: {}",
                filename.to_str().unwrap(),
                e).into())
        };
        let mut buf = Vec::new();
        file.read_to_end(&mut buf)?;
        Elf::new(buf, base_address)
    }

    /// Load an elf from a file and use the base address of 0.
    pub fn from_file(filename: &Path) -> Result<Elf> {
        Elf::from_file_with_base_address(filename, 0)
    }

    /// Allow the user to manually specify a function entry
    pub fn add_user_function(&mut self, address: u64) {
        self.user_function_entries.push(address);
    }

    /// Return the strings from the DT_NEEDED entries.
    pub fn dt_needed(&self) -> Result<Vec<String>> {
        let mut v = Vec::new();

        let elf = self.elf();
        if let Some(dynamic) = elf.dynamic {
            // We need that strtab, and we have to do this one manually.
            // Get the strtab address
            let mut strtab_address = None;
            for dyn in &dynamic.dyns {
                if dyn.d_tag == goblin::elf::dyn::DT_STRTAB {
                    strtab_address = Some(dyn.d_val);
                    break;
                }
            }
            if strtab_address.is_none() {
                return Ok(v);
            }
            let strtab_address = strtab_address.unwrap();
            // We're going to make a pretty safe assumption that strtab is all
            // in one section
            for section_header in &elf.section_headers {
                if    section_header.sh_addr > 0
                   && section_header.sh_addr <= strtab_address
                   && section_header.sh_addr + section_header.sh_size > strtab_address {
                    let start = section_header.sh_offset + (strtab_address - section_header.sh_addr);
                    let size = section_header.sh_size - (start - section_header.sh_offset);
                    let start = start as usize;
                    let size = size as usize;
                    let strtab_bytes = self.bytes.get(start..(start + size)).unwrap();
                    let strtab = goblin::strtab::Strtab::new(&strtab_bytes, 0);
                    for dyn in dynamic.dyns {
                        if dyn.d_tag == goblin::elf::dyn::DT_NEEDED {
                            let so_name = &strtab[dyn.d_val as usize];
                            v.push(so_name.to_string());
                        }
                    }
                    return Ok(v);
                }
            }
            // if we got here, we didn't return a vector (I think ;))
            panic!("Failed to get Dynamic strtab");
        }

        Ok(v)
    }

    /// Return the goblin::elf::Elf for this elf.
    pub(crate) fn elf(&self) -> goblin::elf::Elf {
        goblin::elf::Elf::parse(&self.bytes).unwrap()
    }

    /// Return all symbols exported from this Elf
    pub(crate) fn exported_symbols(&self) -> Vec<Symbol> {
        let mut v = Vec::new();
        let elf = self.elf();
        for sym in elf.dynsyms.iter() {
            if sym.st_value == 0 || sym.st_shndx == 0 {
                continue;
            }
            if    sym.st_bind() == goblin::elf::sym::STB_GLOBAL
               || sym.st_bind() == goblin::elf::sym::STB_WEAK {
                v.push(Symbol::new(&elf.dynstrtab[sym.st_name], sym.st_value));
            }
        }

        v
    }
}

impl Loader for Elf {
    fn memory(&self) -> Result<Memory> {
        let elf = self.elf();
        let mut memory = Memory::new(self.architecture().endian());

        for ph in elf.program_headers {
            if ph.p_type == goblin::elf::program_header::PT_LOAD {
                let file_range = (ph.p_offset as usize)..((ph.p_offset + ph.p_filesz) as usize);
                let mut bytes = self.bytes
                                    .get(file_range)
                                    .ok_or("Malformed Elf")?
                                    .to_vec();

                if bytes.len() != ph.p_memsz as usize {
                    bytes.append(&mut vec![0; (ph.p_memsz - ph.p_filesz) as usize]);
                }

                let mut permissions = memory::MemoryPermissions::NONE;
                if ph.p_flags & goblin::elf::program_header::PF_R != 0 {
                    permissions |= MemoryPermissions::READ;
                }
                if ph.p_flags & goblin::elf::program_header::PF_W != 0 {
                    permissions |= MemoryPermissions::WRITE;
                }
                if ph.p_flags & goblin::elf::program_header::PF_X != 0 {
                    permissions |= MemoryPermissions::EXECUTE;
                }

                memory.set_memory(ph.p_vaddr + self.base_address,
                                  bytes,
                                  permissions);
            }
        }

        Ok(memory)
    }

    fn function_entries(&self) -> Result<Vec<FunctionEntry>> {
        let elf = self.elf();

        let mut function_entries = Vec::new();

        let mut functions_added: BTreeSet<u64> = BTreeSet::new();

        // dynamic symbols
        for sym in &elf.dynsyms {
            if sym.is_function() && sym.st_value != 0 {
                let name = &elf.dynstrtab[sym.st_name];
                function_entries.push(FunctionEntry::new(
                    sym.st_value + self.base_address,
                    Some(name.to_string())
                ));
                functions_added.insert(sym.st_value);
            }
        }

        // normal symbols
        for sym in &elf.syms {
            if sym.is_function() && sym.st_value != 0 {
                let name = &elf.strtab[sym.st_name];
                function_entries.push(FunctionEntry::new(
                    sym.st_value + self.base_address,
                    Some(name.to_string()))
                );
                functions_added.insert(sym.st_value);
            }
        }

        if !functions_added.contains(&elf.header.e_entry) {
            function_entries.push(FunctionEntry::new(
                elf.header.e_entry + self.base_address,
                None
            ));
        }

        for user_function_entry in &self.user_function_entries {
            if functions_added.get(&(user_function_entry + self.base_address)).is_some() {
                continue;
            }

            function_entries.push(FunctionEntry::new(
                user_function_entry + self.base_address,
                Some(format!("user_function_{:x}", user_function_entry))
            ));
        }

        Ok(function_entries)
    }

    fn program_entry(&self) -> u64 {
        self.elf().header.e_entry
    }

    fn architecture(&self) -> &Architecture {
        self.architecture.as_ref()
    }
}<|endoftext|>


<commit_before>use std::io;

fn to_interger(string :String) -> int {
    match from_str::<int>(string.trim()) {
        Some(0) => 0,
        Some(x) => x,
        _       => 0
    }
}

fn main() {
    println!("Enter width of the room:");
    let width = to_interger(io::stdin().read_line().unwrap());
    println!("Enter depth of the room:");
    let depth = to_interger(io::stdin().read_line().unwrap());
    println!("Enter price of sqrm of tiles:");
    let tile_price = to_interger(io::stdin().read_line().unwrap());

    let price = width * depth * tile_price;

    println!("The Price for the tiles would be: {}€", price);
}<commit_msg>Fixed build error and function for tile costcalc after rust update.g<commit_after>extern crate debug;

use std::io;

fn to_interger(string :String) -> int {
    match from_str::<int>(string.as_slice().trim()) {
        Some(0) => 0,
        Some(x) => x,
        _       => 0
    }
}

fn main() {
    println!("Enter width of the room:");
    let width = to_interger(io::stdin().read_line().unwrap());
    println!("Enter depth of the room:");
    let depth = to_interger(io::stdin().read_line().unwrap());
    println!("Enter price of sqrm of tiles:");
    let tile_price = to_interger(io::stdin().read_line().unwrap());

    let price = width * depth * tile_price;

    println!("The Price for the tiles would be: {}€", price);
}<|endoftext|>


<commit_before>//! Checks for useless borrowed references.
//!
//! This lint is **warn** by default

use crate::utils::{snippet_with_applicability, span_lint_and_then};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BindingAnnotation, Mutability, Node, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for useless borrowed references.
    ///
    /// **Why is this bad?** It is mostly useless and make the code look more
    /// complex than it
    /// actually is.
    ///
    /// **Known problems:** It seems that the `&ref` pattern is sometimes useful.
    /// For instance in the following snippet:
    /// ```rust,ignore
    /// enum Animal {
    ///     Cat(u64),
    ///     Dog(u64),
    /// }
    ///
    /// fn foo(a: &Animal, b: &Animal) {
    ///     match (a, b) {
    ///         (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime mismatch error
    ///         (&Animal::Dog(ref c), &Animal::Dog(_)) => ()
    ///     }
    /// }
    /// ```
    /// There is a lifetime mismatch error for `k` (indeed a and b have distinct
    /// lifetime).
    /// This can be fixed by using the `&ref` pattern.
    /// However, the code can also be fixed by much cleaner ways
    ///
    /// **Example:**
    /// ```rust
    /// let mut v = Vec::<String>::new();
    /// let _ = v.iter_mut().filter(|&ref a| a.is_empty());
    /// ```
    /// This closure takes a reference on something that has been matched as a
    /// reference and
    /// de-referenced.
    /// As such, it could just be |a| a.is_empty()
    pub NEEDLESS_BORROWED_REFERENCE,
    complexity,
    "taking a needless borrowed reference"
}

declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);

impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
        if pat.span.from_expansion() {
            // OK, simple enough, lints doesn't check in macro.
            return;
        }

        if_chain! {
            // Only lint immutable refs, because `&mut ref T` may be useful.
            if let PatKind::Ref(ref sub_pat, Mutability::Not) = pat.kind;

            // Check sub_pat got a `ref` keyword (excluding `ref mut`).
            if let PatKind::Binding(BindingAnnotation::Ref, .., spanned_name, _) = sub_pat.kind;
            let parent_id = cx.tcx.hir().get_parent_node(pat.hir_id);
            if let Some(parent_node) = cx.tcx.hir().find(parent_id);
            then {
                // do not recurse within patterns, as they may have other references
                // XXXManishearth we can relax this constraint if we only check patterns
                // with a single ref pattern inside them
                if let Node::Pat(_) = parent_node {
                    return;
                }
                let mut applicability = Applicability::MachineApplicable;
                span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, pat.span,
                                   "this pattern takes a reference on something that is being de-referenced",
                                   |diag| {
                                       let hint = snippet_with_applicability(cx, spanned_name.span, "..", &mut applicability).into_owned();
                                       diag.span_suggestion(
                                           pat.span,
                                           "try removing the `&ref` part and just keep",
                                           hint,
                                           applicability,
                                       );
                                   });
            }
        }
    }
}
<commit_msg>Auto merge of #6794 - camsteffen:needless-borrowed-ref, r=flip1995<commit_after>use crate::utils::{snippet_with_applicability, span_lint_and_then};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BindingAnnotation, Mutability, Node, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for bindings that destructure a reference and borrow the inner
    /// value with `&ref`.
    ///
    /// **Why is this bad?** This pattern has no effect in almost all cases.
    ///
    /// **Known problems:** In some cases, `&ref` is needed to avoid a lifetime mismatch error.
    /// Example:
    /// ```rust
    /// fn foo(a: &Option<String>, b: &Option<String>) {
    ///     match (a, b) {
    ///         (None, &ref c) | (&ref c, None) => (),
    ///         (&Some(ref c), _) => (),
    ///     };
    /// }
    /// ```
    ///
    /// **Example:**
    /// Bad:
    /// ```rust
    /// let mut v = Vec::<String>::new();
    /// let _ = v.iter_mut().filter(|&ref a| a.is_empty());
    /// ```
    ///
    /// Good:
    /// ```rust
    /// let mut v = Vec::<String>::new();
    /// let _ = v.iter_mut().filter(|a| a.is_empty());
    /// ```
    pub NEEDLESS_BORROWED_REFERENCE,
    complexity,
    "destructuring a reference and borrowing the inner value"
}

declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);

impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
        if pat.span.from_expansion() {
            // OK, simple enough, lints doesn't check in macro.
            return;
        }

        if_chain! {
            // Only lint immutable refs, because `&mut ref T` may be useful.
            if let PatKind::Ref(ref sub_pat, Mutability::Not) = pat.kind;

            // Check sub_pat got a `ref` keyword (excluding `ref mut`).
            if let PatKind::Binding(BindingAnnotation::Ref, .., spanned_name, _) = sub_pat.kind;
            let parent_id = cx.tcx.hir().get_parent_node(pat.hir_id);
            if let Some(parent_node) = cx.tcx.hir().find(parent_id);
            then {
                // do not recurse within patterns, as they may have other references
                // XXXManishearth we can relax this constraint if we only check patterns
                // with a single ref pattern inside them
                if let Node::Pat(_) = parent_node {
                    return;
                }
                let mut applicability = Applicability::MachineApplicable;
                span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, pat.span,
                                   "this pattern takes a reference on something that is being de-referenced",
                                   |diag| {
                                       let hint = snippet_with_applicability(cx, spanned_name.span, "..", &mut applicability).into_owned();
                                       diag.span_suggestion(
                                           pat.span,
                                           "try removing the `&ref` part and just keep",
                                           hint,
                                           applicability,
                                       );
                                   });
            }
        }
    }
}
<|endoftext|>


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

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![staged_api]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(libc)]
#![feature(no_std)]
#![feature(staged_api)]

extern crate libc;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    unsafe { imp::allocate(size, align) }
}

#[no_mangle]
pub extern fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
    unsafe { imp::deallocate(ptr, old_size, align) }
}

#[no_mangle]
pub extern fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize,
                                align: usize) -> *mut u8 {
    unsafe { imp::reallocate(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize,
                                        size: usize, align: usize) -> usize {
    unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern fn __rust_usable_size(size: usize, align: usize) -> usize {
    imp::usable_size(size, align)
}

#[cfg(unix)]
mod imp {
    use core::cmp;
    use core::ptr;
    use libc;
    use MIN_ALIGN;

    extern {
        // Apparently android doesn't have posix_memalign
        #[cfg(target_os = "android")]
        fn memalign(align: libc::size_t, size: libc::size_t) -> *mut libc::c_void;

        #[cfg(not(target_os = "android"))]
        fn posix_memalign(memptr: *mut *mut libc::c_void,
                          align: libc::size_t,
                          size: libc::size_t) -> libc::c_int;
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::malloc(size as libc::size_t) as *mut u8
        } else {
            #[cfg(target_os = "android")]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                memalign(align as libc::size_t, size as libc::size_t) as *mut u8
            }
            #[cfg(not(target_os = "android"))]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                let mut out = ptr::null_mut();
                let ret = posix_memalign(&mut out,
                                         align as libc::size_t,
                                         size as libc::size_t);
                if ret != 0 {
                    ptr::null_mut()
                } else {
                    out as *mut u8
                }
            }
            more_aligned_malloc(size, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize,
                             align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
        } else {
            let new_ptr = allocate(size, align);
            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
            deallocate(ptr, old_size, align);
            new_ptr
        }
    }

    pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: usize, _size: usize,
                                     _align: usize) -> usize {
        old_size
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
        libc::free(ptr as *mut libc::c_void)
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}

#[cfg(windows)]
mod imp {
    use libc::{BOOL, DWORD, HANDLE, LPVOID, SIZE_T};
    use MIN_ALIGN;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID,
                       dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize);
        *get_header(aligned) = Header(ptr);
        aligned
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
        } else {
            let ptr = HeapAlloc(GetProcessHeap(), 0,
                                (size + align) as SIZE_T) as *mut u8;
            if ptr.is_null() { return ptr }
            align_ptr(ptr, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize,
                             align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
        } else {
            let header = get_header(ptr);
            let new = HeapReAlloc(GetProcessHeap(), 0, header.0 as LPVOID,
                                  (size + align) as SIZE_T) as *mut u8;
            if new.is_null() { return new }
            align_ptr(new, align)
        }
    }

    pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
                                     align: usize) -> usize {
        if align <= MIN_ALIGN {
            let new = HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY,
                                  ptr as LPVOID, size as SIZE_T) as *mut u8;
            if new.is_null() { old_size } else { size }
        } else {
            old_size
        }
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
        if align <= MIN_ALIGN {
            let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
            debug_assert!(err != 0);
        } else {
            let header = get_header(ptr);
            let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
            debug_assert!(err != 0);
        }
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}
<commit_msg>Rollup merge of #28989 - ahmedcharles:liballoc_system, r=nrc<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![staged_api]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(libc)]
#![feature(no_std)]
#![feature(staged_api)]

extern crate libc;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    unsafe { imp::allocate(size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
    unsafe { imp::deallocate(ptr, old_size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    size: usize,
                                    align: usize)
                                    -> *mut u8 {
    unsafe { imp::reallocate(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
                                            old_size: usize,
                                            size: usize,
                                            align: usize)
                                            -> usize {
    unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
    imp::usable_size(size, align)
}

#[cfg(unix)]
mod imp {
    use core::cmp;
    use core::ptr;
    use libc;
    use MIN_ALIGN;

    extern {
        // Apparently android doesn't have posix_memalign
        #[cfg(target_os = "android")]
        fn memalign(align: libc::size_t, size: libc::size_t) -> *mut libc::c_void;

        #[cfg(not(target_os = "android"))]
        fn posix_memalign(memptr: *mut *mut libc::c_void,
                          align: libc::size_t,
                          size: libc::size_t)
                          -> libc::c_int;
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::malloc(size as libc::size_t) as *mut u8
        } else {
            #[cfg(target_os = "android")]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                memalign(align as libc::size_t, size as libc::size_t) as *mut u8
            }
            #[cfg(not(target_os = "android"))]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                let mut out = ptr::null_mut();
                let ret = posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
                if ret != 0 {
                    ptr::null_mut()
                } else {
                    out as *mut u8
                }
            }
            more_aligned_malloc(size, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
        } else {
            let new_ptr = allocate(size, align);
            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
            deallocate(ptr, old_size, align);
            new_ptr
        }
    }

    pub unsafe fn reallocate_inplace(_ptr: *mut u8,
                                     old_size: usize,
                                     _size: usize,
                                     _align: usize)
                                     -> usize {
        old_size
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
        libc::free(ptr as *mut libc::c_void)
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}

#[cfg(windows)]
mod imp {
    use libc::{BOOL, DWORD, HANDLE, LPVOID, SIZE_T};
    use MIN_ALIGN;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize);
        *get_header(aligned) = Header(ptr);
        aligned
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
        } else {
            let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8;
            if ptr.is_null() {
                return ptr
            }
            align_ptr(ptr, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
        } else {
            let header = get_header(ptr);
            let new = HeapReAlloc(GetProcessHeap(),
                                  0,
                                  header.0 as LPVOID,
                                  (size + align) as SIZE_T) as *mut u8;
            if new.is_null() {
                return new
            }
            align_ptr(new, align)
        }
    }

    pub unsafe fn reallocate_inplace(ptr: *mut u8,
                                     old_size: usize,
                                     size: usize,
                                     align: usize)
                                     -> usize {
        if align <= MIN_ALIGN {
            let new = HeapReAlloc(GetProcessHeap(),
                                  HEAP_REALLOC_IN_PLACE_ONLY,
                                  ptr as LPVOID,
                                  size as SIZE_T) as *mut u8;
            if new.is_null() {
                old_size
            } else {
                size
            }
        } else {
            old_size
        }
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
        if align <= MIN_ALIGN {
            let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
            debug_assert!(err != 0);
        } else {
            let header = get_header(ptr);
            let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
            debug_assert!(err != 0);
        }
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}
<|endoftext|>


<commit_before>//! # Functions and types used by generated protobuf code
//!
//! These are not considered to be public API of rust-protobuf,
//! so they can be changed any time (provided compatibility with
//! previously generated code is preserved).

pub use crate::cached_size::CachedSize;
use crate::coded_input_stream::CodedInputStream;
use crate::coded_output_stream::CodedOutputStream;
use crate::enums::Enum;
use crate::error::Result;
pub use crate::lazy::Lazy;
pub use crate::wire_format::WireType;
use crate::zigzag::*;
use crate::EnumOrUnknown;
use crate::Message;
use crate::MessageField;

pub(crate) mod map;
pub(crate) mod repeated;
pub(crate) mod unsorted;
pub use map::compute_map_size;
pub use map::read_map_into;
pub use map::write_map_with_cached_sizes;
pub use repeated::read_repeated_packed_enum_or_unknown_into;
pub use unsorted::read_unknown_or_skip_group;
pub use unsorted::unknown_fields_size;

use crate::varint::encode::encoded_varint64_len;

/// Given `u64` value compute varint encoded length.
pub fn compute_raw_varint64_size(value: u64) -> u64 {
    encoded_varint64_len(value) as u64
}

/// Given `u32` value compute varint encoded length.
pub(crate) fn compute_raw_varint32_size(value: u32) -> u64 {
    compute_raw_varint64_size(value as u64)
}

/// Size of encoded `sint32` value.
pub fn sint32_size_no_tag(value: i32) -> u64 {
    compute_raw_varint32_size(encode_zig_zag_32(value))
}

/// Size of encoded `sint64` value.
pub fn sint64_size_no_tag(value: i64) -> u64 {
    compute_raw_varint64_size(encode_zig_zag_64(value))
}

/// Fixed size integers.
pub trait ProtobufFixed {
    /// Size of this fixed type in bytes.
    const LEN: u32;
}

/// Helper trait implemented by integer types which could be encoded as varint.
pub trait ProtobufVarint {
    /// Size of self when encoded as varint.
    fn len_varint(&self) -> u64;
}

/// Helper trait implemented by integer types which could be encoded as zigzag varint.
pub trait ProtobufVarintZigzag {
    /// Size of self when encoded as zigzag varint.
    fn len_varint_zigzag(&self) -> u64;
}

impl ProtobufVarint for u64 {
    fn len_varint(&self) -> u64 {
        compute_raw_varint64_size(*self)
    }
}

impl ProtobufVarint for u32 {
    fn len_varint(&self) -> u64 {
        (*self as u64).len_varint()
    }
}

impl ProtobufVarint for i64 {
    fn len_varint(&self) -> u64 {
        // same as length of u64
        (*self as u64).len_varint()
    }
}

impl ProtobufVarintZigzag for i64 {
    fn len_varint_zigzag(&self) -> u64 {
        compute_raw_varint64_size(encode_zig_zag_64(*self))
    }
}

impl ProtobufVarint for i32 {
    fn len_varint(&self) -> u64 {
        // sign-extend and then compute
        (*self as i64).len_varint()
    }
}

impl ProtobufVarintZigzag for i32 {
    fn len_varint_zigzag(&self) -> u64 {
        compute_raw_varint32_size(encode_zig_zag_32(*self))
    }
}

impl ProtobufVarint for bool {
    fn len_varint(&self) -> u64 {
        1
    }
}

impl ProtobufFixed for u32 {
    const LEN: u32 = 4;
}

impl ProtobufFixed for i32 {
    const LEN: u32 = 4;
}

impl ProtobufFixed for u64 {
    const LEN: u32 = 8;
}

impl ProtobufFixed for i64 {
    const LEN: u32 = 8;
}

impl ProtobufFixed for f32 {
    const LEN: u32 = 4;
}

impl ProtobufFixed for f64 {
    const LEN: u32 = 8;
}

/// Technically `bool` is not fixed, but it can be considered as fixed
/// for the purpose of encoding.
impl ProtobufFixed for bool {
    const LEN: u32 = 1;
}

/// Size of serialized repeated packed field, excluding length and tag.
pub fn vec_packed_varint_data_size<T: ProtobufVarint>(vec: &[T]) -> u64 {
    vec.iter()
        .map(|v| v.len_varint() as u64)
        .fold(0, |a, i| a + i)
}

/// Size of serialized repeated packed field, excluding length and tag.
pub fn vec_packed_varint_zigzag_data_size<T: ProtobufVarintZigzag>(vec: &[T]) -> u64 {
    vec.iter()
        .map(|v| v.len_varint_zigzag())
        .fold(0, |a, i| a + i)
}

/// Size of serialized repeated packed enum field, excluding length and tag.
pub fn vec_packed_enum_or_unknown_data_size<E: Enum>(vec: &[EnumOrUnknown<E>]) -> u64 {
    vec.iter()
        .map(|e| compute_raw_varint32_size(e.value() as u32))
        .fold(0, |a, i| a + i)
}

/// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_size<T: ProtobufVarint>(field_number: u32, vec: &[T]) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_zigzag_size<T: ProtobufVarintZigzag>(field_number: u32, vec: &[T]) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_zigzag_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Size of serialized data with length prefix and tag
pub fn vec_packed_enum_or_unknown_size<E: Enum>(
    field_number: u32,
    vec: &[EnumOrUnknown<E>],
) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_enum_or_unknown_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Compute data size of fixed encoding of repeated field data.
pub(crate) fn vec_packed_fixed_data_size<V: ProtobufFixed>(vec: &[V]) -> u64 {
    (vec.len() as u64) * (V::LEN as u64)
}

/// Compute field size (data plus header) of fixed encoding of repeated field.
pub fn vec_packed_fixed_size<V: ProtobufFixed>(field_number: u32, vec: &[V]) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_fixed_data_size::<V>(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Compute tag size. Size of tag does not depend on wire type.
pub fn tag_size(field_number: u32) -> u64 {
    encoded_varint64_len((field_number as u64) << 3) as u64
}

/// Integer value size when encoded as specified wire type.
pub fn value_size_no_tag<T: ProtobufVarint>(value: T, wt: WireType) -> u64 {
    match wt {
        WireType::Fixed64 => 8,
        WireType::Fixed32 => 4,
        WireType::Varint => value.len_varint(),
        _ => panic!(),
    }
}

/// Size of encoded enum field value.
pub fn enum_or_unknown_size_no_tag<E: Enum>(value: EnumOrUnknown<E>) -> u64 {
    value.value().len_varint() as u64
}

/// Size of encoded enum field value.
pub fn enum_or_unknown_size<E: Enum>(field_number: u32, value: EnumOrUnknown<E>) -> u64 {
    tag_size(field_number) + enum_or_unknown_size_no_tag(value)
}

/// Size of encoded bytes field.
pub fn bytes_size_no_tag(bytes: &[u8]) -> u64 {
    compute_raw_varint64_size(bytes.len() as u64) + bytes.len() as u64
}

/// Size of encoded string field.
pub fn string_size_no_tag(s: &str) -> u64 {
    bytes_size_no_tag(s.as_bytes())
}

/// Read singular `message` field.
pub fn read_singular_message_into_field<M>(
    is: &mut CodedInputStream,
    target: &mut MessageField<M>,
) -> Result<()>
where
    M: Message,
{
    let mut m = M::new();
    is.merge_message(&mut m)?;
    *target = MessageField::some(m);
    Ok(())
}

/// Write message with field number and length to the stream.
pub fn write_message_field_with_cached_size<M>(
    field_number: u32,
    message: &M,
    os: &mut CodedOutputStream,
) -> Result<()>
where
    M: Message,
{
    os.write_tag(field_number, WireType::LengthDelimited)?;
    os.write_raw_varint32(message.cached_size())?;
    message.write_to_with_cached_sizes(os)
}
<commit_msg>Dead code<commit_after>//! # Functions and types used by generated protobuf code
//!
//! These are not considered to be public API of rust-protobuf,
//! so they can be changed any time (provided compatibility with
//! previously generated code is preserved).

pub use crate::cached_size::CachedSize;
use crate::coded_input_stream::CodedInputStream;
use crate::coded_output_stream::CodedOutputStream;
use crate::enums::Enum;
use crate::error::Result;
pub use crate::lazy::Lazy;
pub use crate::wire_format::WireType;
use crate::zigzag::*;
use crate::EnumOrUnknown;
use crate::Message;
use crate::MessageField;

pub(crate) mod map;
pub(crate) mod repeated;
pub(crate) mod unsorted;
pub use map::compute_map_size;
pub use map::read_map_into;
pub use map::write_map_with_cached_sizes;
pub use repeated::read_repeated_packed_enum_or_unknown_into;
pub use unsorted::read_unknown_or_skip_group;
pub use unsorted::unknown_fields_size;

use crate::varint::encode::encoded_varint64_len;

/// Given `u64` value compute varint encoded length.
pub fn compute_raw_varint64_size(value: u64) -> u64 {
    encoded_varint64_len(value) as u64
}

/// Given `u32` value compute varint encoded length.
pub(crate) fn compute_raw_varint32_size(value: u32) -> u64 {
    compute_raw_varint64_size(value as u64)
}

/// Size of encoded `sint32` value.
pub fn sint32_size_no_tag(value: i32) -> u64 {
    compute_raw_varint32_size(encode_zig_zag_32(value))
}

/// Size of encoded `sint64` value.
pub fn sint64_size_no_tag(value: i64) -> u64 {
    compute_raw_varint64_size(encode_zig_zag_64(value))
}

/// Fixed size integers.
pub trait ProtobufFixed {
    /// Size of this fixed type in bytes.
    const LEN: u32;
}

/// Helper trait implemented by integer types which could be encoded as varint.
pub trait ProtobufVarint {
    /// Size of self when encoded as varint.
    fn len_varint(&self) -> u64;
}

/// Helper trait implemented by integer types which could be encoded as zigzag varint.
pub trait ProtobufVarintZigzag {
    /// Size of self when encoded as zigzag varint.
    fn len_varint_zigzag(&self) -> u64;
}

impl ProtobufVarint for u64 {
    fn len_varint(&self) -> u64 {
        compute_raw_varint64_size(*self)
    }
}

impl ProtobufVarint for u32 {
    fn len_varint(&self) -> u64 {
        (*self as u64).len_varint()
    }
}

impl ProtobufVarint for i64 {
    fn len_varint(&self) -> u64 {
        // same as length of u64
        (*self as u64).len_varint()
    }
}

impl ProtobufVarintZigzag for i64 {
    fn len_varint_zigzag(&self) -> u64 {
        compute_raw_varint64_size(encode_zig_zag_64(*self))
    }
}

impl ProtobufVarint for i32 {
    fn len_varint(&self) -> u64 {
        // sign-extend and then compute
        (*self as i64).len_varint()
    }
}

impl ProtobufVarintZigzag for i32 {
    fn len_varint_zigzag(&self) -> u64 {
        compute_raw_varint32_size(encode_zig_zag_32(*self))
    }
}

impl ProtobufVarint for bool {
    fn len_varint(&self) -> u64 {
        1
    }
}

impl ProtobufFixed for u32 {
    const LEN: u32 = 4;
}

impl ProtobufFixed for i32 {
    const LEN: u32 = 4;
}

impl ProtobufFixed for u64 {
    const LEN: u32 = 8;
}

impl ProtobufFixed for i64 {
    const LEN: u32 = 8;
}

impl ProtobufFixed for f32 {
    const LEN: u32 = 4;
}

impl ProtobufFixed for f64 {
    const LEN: u32 = 8;
}

/// Technically `bool` is not fixed, but it can be considered as fixed
/// for the purpose of encoding.
impl ProtobufFixed for bool {
    const LEN: u32 = 1;
}

/// Size of serialized repeated packed field, excluding length and tag.
pub fn vec_packed_varint_data_size<T: ProtobufVarint>(vec: &[T]) -> u64 {
    vec.iter()
        .map(|v| v.len_varint() as u64)
        .fold(0, |a, i| a + i)
}

/// Size of serialized repeated packed field, excluding length and tag.
pub fn vec_packed_varint_zigzag_data_size<T: ProtobufVarintZigzag>(vec: &[T]) -> u64 {
    vec.iter()
        .map(|v| v.len_varint_zigzag())
        .fold(0, |a, i| a + i)
}

/// Size of serialized repeated packed enum field, excluding length and tag.
pub fn vec_packed_enum_or_unknown_data_size<E: Enum>(vec: &[EnumOrUnknown<E>]) -> u64 {
    vec.iter()
        .map(|e| compute_raw_varint32_size(e.value() as u32))
        .fold(0, |a, i| a + i)
}

/// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_size<T: ProtobufVarint>(field_number: u32, vec: &[T]) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Size of serialized data with length prefix and tag
pub fn vec_packed_varint_zigzag_size<T: ProtobufVarintZigzag>(field_number: u32, vec: &[T]) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_varint_zigzag_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Size of serialized data with length prefix and tag
pub fn vec_packed_enum_or_unknown_size<E: Enum>(
    field_number: u32,
    vec: &[EnumOrUnknown<E>],
) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_enum_or_unknown_data_size(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Compute data size of fixed encoding of repeated field data.
pub(crate) fn vec_packed_fixed_data_size<V: ProtobufFixed>(vec: &[V]) -> u64 {
    (vec.len() as u64) * (V::LEN as u64)
}

/// Compute field size (data plus header) of fixed encoding of repeated field.
pub fn vec_packed_fixed_size<V: ProtobufFixed>(field_number: u32, vec: &[V]) -> u64 {
    if vec.is_empty() {
        0
    } else {
        let data_size = vec_packed_fixed_data_size::<V>(vec);
        tag_size(field_number) + data_size.len_varint() + data_size
    }
}

/// Compute tag size. Size of tag does not depend on wire type.
pub fn tag_size(field_number: u32) -> u64 {
    encoded_varint64_len((field_number as u64) << 3) as u64
}

/// Integer value size when encoded as specified wire type.
pub fn value_size_no_tag<T: ProtobufVarint>(value: T, wt: WireType) -> u64 {
    match wt {
        WireType::Fixed64 => 8,
        WireType::Fixed32 => 4,
        WireType::Varint => value.len_varint(),
        _ => panic!(),
    }
}

/// Size of encoded enum field value.
pub fn enum_or_unknown_size_no_tag<E: Enum>(value: EnumOrUnknown<E>) -> u64 {
    value.value().len_varint() as u64
}

/// Size of encoded bytes field.
pub fn bytes_size_no_tag(bytes: &[u8]) -> u64 {
    compute_raw_varint64_size(bytes.len() as u64) + bytes.len() as u64
}

/// Size of encoded string field.
pub fn string_size_no_tag(s: &str) -> u64 {
    bytes_size_no_tag(s.as_bytes())
}

/// Read singular `message` field.
pub fn read_singular_message_into_field<M>(
    is: &mut CodedInputStream,
    target: &mut MessageField<M>,
) -> Result<()>
where
    M: Message,
{
    let mut m = M::new();
    is.merge_message(&mut m)?;
    *target = MessageField::some(m);
    Ok(())
}

/// Write message with field number and length to the stream.
pub fn write_message_field_with_cached_size<M>(
    field_number: u32,
    message: &M,
    os: &mut CodedOutputStream,
) -> Result<()>
where
    M: Message,
{
    os.write_tag(field_number, WireType::LengthDelimited)?;
    os.write_raw_varint32(message.cached_size())?;
    message.write_to_with_cached_sizes(os)
}
<|endoftext|>


<commit_before>extern crate time;

#[derive(Clone, Debug)]
enum Token {
    DOTTEDDATE, HYPHENDATE,
    HOURMIN,
    INT1DIGIT, INT2DIGIT, INT4DIGIT, INT58DIGIT,
    INT, FLOAT,
    NOW,
    AM, PM,
    NOON, MIDNIGHT, TEATIME,
    SUN, MON, TUE, WED, THU, FRI, SAT,
    TODAY, TOMORROW,
    NEXT,
    MINUTE, HOUR, DAY, WEEK, MONTH, YEAR,
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC,
    UTC,
    PLUS, MINUS
}

fn parse_timespec(tokens: Vec<Token>, current_time: time::Tm) -> time::Tm {
    let mut new_time = time::empty_tm();
    for token in tokens {
        match token {
            Token::NOW => {
                new_time = current_time;
            }
            Token::MIDNIGHT => {
                new_time.tm_hour = 0;
                new_time.tm_min = 0;
            }
            Token::NOON => {
                new_time.tm_hour = 12;
                new_time.tm_min = 0;
            }
            Token::TEATIME => {
                new_time.tm_hour = 16;
                new_time.tm_min = 0;
            }
            Token::SUN => {
                new_time.tm_wday = 0;
            }
            Token::MON => {
                new_time.tm_wday = 1;
            }
            Token::TUE => {
                new_time.tm_wday = 2;
            }
            Token::WED => {
                new_time.tm_wday = 3;
            }
            Token::THU => {
                new_time.tm_wday = 4;
            }
            Token::FRI => {
                new_time.tm_wday = 5;
            }
            Token::SAT => {
                new_time.tm_wday = 6;
            }
            Token::JAN => {
                new_time.tm_mon = 0;
            }
            Token::FEB => {
                new_time.tm_mon = 1;
            }
            Token::MAR => {
                new_time.tm_mon = 2;
            }
            Token::APR => {
                new_time.tm_mon = 3;
            }
            Token::MAY => {
                new_time.tm_mon = 4;
            }
            Token::JUN => {
                new_time.tm_mon = 5;
            }
            Token::JUL => {
                new_time.tm_mon = 6;
            }
            Token::AUG => {
                new_time.tm_mon = 7;
            }
            Token::SEP => {
                new_time.tm_mon = 8;
            }
            Token::OCT => {
                new_time.tm_mon = 9;
            }
            Token::NOV => {
                new_time.tm_mon = 10;
            }
            Token::DEC => {
                new_time.tm_mon = 11;
            }
            Token::PLUS => {
                new_time = current_time;
            }
            _ => println!("Unknown token: {:?}", token)
        }
    }
    return new_time;
}

fn increment_time(tokens: Vec<Token>) -> time::Tm {
    inc_dec_time(decrement_tm, tokens)
}

fn decrement_time(tokens: Vec<Token>) -> time::Tm {
    inc_dec_time(increment_tm, tokens)
}

fn inc_dec_time(inc_dec: fn(time::Tm, time::Duration) -> time::Tm, tokens:Vec<Token>) -> time::Tm {
    return time::now();
}

fn increment_tm(a: time::Tm, b: time::Duration) -> time::Tm {
    return a + b;
}

fn decrement_tm(a: time::Tm, b: time::Duration) -> time::Tm {
    return a - b;
}

fn tokenize (timespec: String) -> Vec<Token> {
    let mut tokens: Vec<Token> = vec![];
    let exprs = timespec.split(' ');
    for expr in exprs {
        match expr {
            "now" => {
                tokens.push(Token::NOW.clone());
            }
            "midnight" => {
                tokens.push(Token::MIDNIGHT.clone());
            }
            "noon" => {
                tokens.push(Token::NOON.clone());
            }
            "teatime" => {
                tokens.push(Token::TEATIME.clone());
            }
            "sun" | "sunday" => {
                tokens.push(Token::SUN.clone());
            }
            "mon" | "monday" => {
                tokens.push(Token::MON.clone());
            }
            "tue" | "tuesday" => {
                tokens.push(Token::TUE.clone());
            }
            "wed" | "wednesday" => {
                tokens.push(Token::WED.clone());
            }
            "thu" | "thursday" => {
                tokens.push(Token::TUE.clone());
            }
            "fri" | "friday" => {
                tokens.push(Token::FRI.clone());
            }
            "sat" | "saturday" => {
                tokens.push(Token::SAT.clone());
            }
            "jan" | "january" => {
                tokens.push(Token::JAN.clone());
            }
            "feb" | "february" => {
                tokens.push(Token::FEB.clone());
            }
            "mar" | "march" => {
                tokens.push(Token::MAR.clone());
            }
            "apr" | "april" => {
                tokens.push(Token::APR.clone());
            }
            "may" => {
                tokens.push(Token::MAY.clone());
            }
            "jun" | "june" => {
                tokens.push(Token::JUN.clone());
            }
            "jul" | "july" => {
                tokens.push(Token::JUL.clone());
            }
            "aug" | "august" => {
                tokens.push(Token::AUG.clone());
            }
            "sep" | "september" => {
                tokens.push(Token::SEP.clone());
            }
            "oct" | "october" => {
                tokens.push(Token::OCT.clone());
            }
            "nov" | "november" => {
                tokens.push(Token::NOV.clone());
            }
            "dec" | "december" => {
                tokens.push(Token::DEC.clone());
            }
            "+" => {
                tokens.push(Token::PLUS.clone());
            }
            _ => {
            }
        }
    }
    return tokens;
}

pub fn parsetime (timespec: String) -> time::Tm {
    let now = time::now();

    let tokens = tokenize(timespec);
    let time = parse_timespec(tokens, now);

    return time;
}
<commit_msg>Set time to 00:00:00 to begin<commit_after>extern crate time;

#[derive(Clone, Debug)]
enum Token {
    DOTTEDDATE, HYPHENDATE,
    HOURMIN,
    INT1DIGIT, INT2DIGIT, INT4DIGIT, INT58DIGIT,
    INT, FLOAT,
    NOW,
    AM, PM,
    NOON, MIDNIGHT, TEATIME,
    SUN, MON, TUE, WED, THU, FRI, SAT,
    TODAY, TOMORROW,
    NEXT,
    MINUTE, HOUR, DAY, WEEK, MONTH, YEAR,
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC,
    UTC,
    PLUS, MINUS
}

fn parse_timespec(tokens: Vec<Token>, current_time: time::Tm) -> time::Tm {
    let mut new_time = time::now();

    // Reset to zero for midnight/noon/teatime
    new_time.tm_hour = 0;
    new_time.tm_min = 0;
    new_time.tm_sec = 0;

    for token in tokens {
        match token {
            Token::NOW => {
                new_time = current_time;
            }
            Token::MIDNIGHT => {
                new_time.tm_hour = 0;
            }
            Token::NOON => {
                new_time.tm_hour = 12;
            }
            Token::TEATIME => {
                new_time.tm_hour = 16;
            }
            Token::SUN => {
                new_time.tm_wday = 0;
            }
            Token::MON => {
                new_time.tm_wday = 1;
            }
            Token::TUE => {
                new_time.tm_wday = 2;
            }
            Token::WED => {
                new_time.tm_wday = 3;
            }
            Token::THU => {
                new_time.tm_wday = 4;
            }
            Token::FRI => {
                new_time.tm_wday = 5;
            }
            Token::SAT => {
                new_time.tm_wday = 6;
            }
            Token::JAN => {
                new_time.tm_mon = 0;
            }
            Token::FEB => {
                new_time.tm_mon = 1;
            }
            Token::MAR => {
                new_time.tm_mon = 2;
            }
            Token::APR => {
                new_time.tm_mon = 3;
            }
            Token::MAY => {
                new_time.tm_mon = 4;
            }
            Token::JUN => {
                new_time.tm_mon = 5;
            }
            Token::JUL => {
                new_time.tm_mon = 6;
            }
            Token::AUG => {
                new_time.tm_mon = 7;
            }
            Token::SEP => {
                new_time.tm_mon = 8;
            }
            Token::OCT => {
                new_time.tm_mon = 9;
            }
            Token::NOV => {
                new_time.tm_mon = 10;
            }
            Token::DEC => {
                new_time.tm_mon = 11;
            }
            Token::PLUS => {
                new_time = current_time;
            }
            _ => println!("Unknown token: {:?}", token)
        }
    }
    return new_time;
}

fn increment_time(tokens: Vec<Token>) -> time::Tm {
    inc_dec_time(decrement_tm, tokens)
}

fn decrement_time(tokens: Vec<Token>) -> time::Tm {
    inc_dec_time(increment_tm, tokens)
}

fn inc_dec_time(inc_dec: fn(time::Tm, time::Duration) -> time::Tm, tokens:Vec<Token>) -> time::Tm {
    return time::now();
}

fn increment_tm(a: time::Tm, b: time::Duration) -> time::Tm {
    return a + b;
}

fn decrement_tm(a: time::Tm, b: time::Duration) -> time::Tm {
    return a - b;
}

fn tokenize (timespec: String) -> Vec<Token> {
    let mut tokens: Vec<Token> = vec![];
    let exprs = timespec.split(' ');
    for expr in exprs {
        match expr {
            "now" => {
                tokens.push(Token::NOW.clone());
            }
            "midnight" => {
                tokens.push(Token::MIDNIGHT.clone());
            }
            "noon" => {
                tokens.push(Token::NOON.clone());
            }
            "teatime" => {
                tokens.push(Token::TEATIME.clone());
            }
            "sun" | "sunday" => {
                tokens.push(Token::SUN.clone());
            }
            "mon" | "monday" => {
                tokens.push(Token::MON.clone());
            }
            "tue" | "tuesday" => {
                tokens.push(Token::TUE.clone());
            }
            "wed" | "wednesday" => {
                tokens.push(Token::WED.clone());
            }
            "thu" | "thursday" => {
                tokens.push(Token::TUE.clone());
            }
            "fri" | "friday" => {
                tokens.push(Token::FRI.clone());
            }
            "sat" | "saturday" => {
                tokens.push(Token::SAT.clone());
            }
            "jan" | "january" => {
                tokens.push(Token::JAN.clone());
            }
            "feb" | "february" => {
                tokens.push(Token::FEB.clone());
            }
            "mar" | "march" => {
                tokens.push(Token::MAR.clone());
            }
            "apr" | "april" => {
                tokens.push(Token::APR.clone());
            }
            "may" => {
                tokens.push(Token::MAY.clone());
            }
            "jun" | "june" => {
                tokens.push(Token::JUN.clone());
            }
            "jul" | "july" => {
                tokens.push(Token::JUL.clone());
            }
            "aug" | "august" => {
                tokens.push(Token::AUG.clone());
            }
            "sep" | "september" => {
                tokens.push(Token::SEP.clone());
            }
            "oct" | "october" => {
                tokens.push(Token::OCT.clone());
            }
            "nov" | "november" => {
                tokens.push(Token::NOV.clone());
            }
            "dec" | "december" => {
                tokens.push(Token::DEC.clone());
            }
            "+" => {
                tokens.push(Token::PLUS.clone());
            }
            _ => {
            }
        }
    }
    return tokens;
}

pub fn parsetime (timespec: String) -> time::Tm {
    let now = time::now();

    let tokens = tokenize(timespec);
    let time = parse_timespec(tokens, now);

    return time;
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::time::Duration;
use std::slice::{Iter, IterMut};
use comp::{Component, ComponentManager};
use entity::{Entity, EntityManager, EntityRef, EntityRefMut};
use world::World;
/// Processes components of entities
/// With each Processor running continuously as if it has a private internal thread,
/// performing global actions on every Entity that possesses a Component of the same
/// aspect as the Processor
pub trait Processor: 'static {
    /// Process a single entity with a delta in seconds
    fn run(&mut self, entity: EntityRefMut, delta:f64);

    /// Process entities with a delta in seconds
    fn run_all(&mut self, entities: &mut EntityManager, components: &mut ComponentManager, entity: &Vec<Entity>, delta:f64) {
        for &entity in entity.iter() {
            self.run(EntityRefMut {
                entity: entity,
                entities: entities,
                components: components
            }, delta);
        }
    }
}
impl<T, C> Processor for C where T:Component, C:FnMut(EntityRefMut, f64)+'static {
    fn run(&mut self, entity: EntityRefMut, delta:f64) {
        (*self)(entity, delta)
    }
}

/// A processor that runs every interval instead of every tick.
pub struct IntervalProcessor<S> {
    /// The interval, in seconds
    pub interval: f64,
    /// The number of seconds since the last update
    pub since_last: f64,
    /// The actual processor to run
    pub processor: S
}
impl<S> IntervalProcessor<S> where S:Processor {
    /// Makes a new interval processor from the given processor and interval
    pub fn new(processor: S, interval: Duration) -> IntervalProcessor<S> {
        IntervalProcessor {
            interval: interval.num_seconds() as f64 + 0.001 * interval.num_milliseconds() as f64,
            since_last: 0.0,
            processor: processor
        }
    }
}
impl<S> Processor for IntervalProcessor<S> where S:Processor {
    fn run(&mut self, entity: EntityRefMut, delta:f64) {
        self.processor.run(entity, delta)
    }

    fn run_all(&mut self, entities: &mut EntityManager, components: &mut ComponentManager, entity: &Vec<Entity>, delta:f64) {
        self.since_last += delta;
        if self.since_last > self.interval {
            self.since_last -= self.interval;
            let interval = self.interval;
            self.processor.run_all(entities, components, entity, interval);
        }
    }
}

/// Represents the processor and its aspect
pub struct MetaProcessor {
    /// The aspect to process
    pub aspect: RefCell<Box<Aspect>>,
    /// The processor
    pub processor: Box<Processor>,
    /// Relevant entities
    pub entities: RefCell<Vec<Entity>>
}
/// Encapsulates processors and their categories
pub struct ProcessorManager {
    processors: Vec<MetaProcessor>
}
impl ProcessorManager {
    /// Create a new processor manager
    pub fn new() -> ProcessorManager {
        ProcessorManager {
            processors : Vec::new()
        }
    }
    /// Update a processor
    pub fn update(&mut self, world: &World, index: uint) {
        let processor = &mut self.processors[index];
        let mut entities = processor.entities.borrow_mut();
        *entities = world.entities.iter().filter(|&entity| {
            let entity = EntityRef {
                entity: entity,
                entities: &world.entities,
                components: &world.components
            };
            entity.is_active() && processor.aspect.borrow_mut().check(entity)
        }).collect::<Vec<_>>();
    }
    /// Add a processor with an aspect into the world
    pub fn add(&mut self, processor: Box<Processor>, aspect: Box<Aspect>) {
        self.processors.push(MetaProcessor {
            processor: processor,
            aspect: RefCell::new(aspect),
            entities: RefCell::new(Vec::new())
        });
    }
    #[inline(always)]
    /// Iterate through the systems and their descriptors immutably
    pub fn iter(&self) -> Iter<MetaProcessor> {
        self.processors.iter()
    }
    #[inline(always)]
    /// Iterate through the systems and their descriptors mutably
    pub fn iter_mut(&mut self) -> IterMut<MetaProcessor> {
        self.processors.iter_mut()
    }
}

/// An Aspect is used by processors as a matcher against entities,
/// to check if a processor is interested in an entity
pub trait Aspect :'static {
    /// Check if the entity meets the criteria of the aspect
    fn check<'a>(&mut self, entity: EntityRef<'a>) -> bool;
}

impl Aspect for |EntityRef|:'static -> bool {
    fn check<'a>(&mut self, entity: EntityRef<'a>) -> bool {
        (*self)(entity)
    }
}<commit_msg>Update docs<commit_after>use std::cell::RefCell;
use std::time::Duration;
use std::slice::{Iter, IterMut};
use comp::{Component, ComponentManager};
use entity::{Entity, EntityManager, EntityRef, EntityRefMut};
use world::World;
/// Processes components of entities
/// With each Processor running continuously as if it has a private internal thread,
/// performing actions on every Entity that possesses a Component of a matching
/// aspect to the Processor
pub trait Processor: 'static {
    /// Process a single entity with a delta in seconds
    fn run(&mut self, entity: EntityRefMut, delta:f64);

    /// Process entities with a delta in seconds
    fn run_all(&mut self, entities: &mut EntityManager, components: &mut ComponentManager, entity: &Vec<Entity>, delta:f64) {
        for &entity in entity.iter() {
            self.run(EntityRefMut {
                entity: entity,
                entities: entities,
                components: components
            }, delta);
        }
    }
}
impl<T, C> Processor for C where T:Component, C:FnMut(EntityRefMut, f64)+'static {
    fn run(&mut self, entity: EntityRefMut, delta:f64) {
        (*self)(entity, delta)
    }
}

/// A processor that runs every interval instead of every tick.
pub struct IntervalProcessor<S> {
    /// The interval, in seconds
    pub interval: f64,
    /// The number of seconds since the last update
    pub since_last: f64,
    /// The actual processor to run
    pub processor: S
}
impl<S> IntervalProcessor<S> where S:Processor {
    /// Makes a new interval processor from the given processor and interval
    pub fn new(processor: S, interval: Duration) -> IntervalProcessor<S> {
        IntervalProcessor {
            interval: interval.num_seconds() as f64 + 0.001 * interval.num_milliseconds() as f64,
            since_last: 0.0,
            processor: processor
        }
    }
}
impl<S> Processor for IntervalProcessor<S> where S:Processor {
    fn run(&mut self, entity: EntityRefMut, delta:f64) {
        self.processor.run(entity, delta)
    }

    fn run_all(&mut self, entities: &mut EntityManager, components: &mut ComponentManager, entity: &Vec<Entity>, delta:f64) {
        self.since_last += delta;
        if self.since_last > self.interval {
            self.since_last -= self.interval;
            let interval = self.interval;
            self.processor.run_all(entities, components, entity, interval);
        }
    }
}

/// Represents the processor and its aspect
pub struct MetaProcessor {
    /// The aspect to process
    pub aspect: RefCell<Box<Aspect>>,
    /// The processor
    pub processor: Box<Processor>,
    /// Relevant entities
    pub entities: RefCell<Vec<Entity>>
}
/// Encapsulates processors and their categories
pub struct ProcessorManager {
    processors: Vec<MetaProcessor>
}
impl ProcessorManager {
    /// Create a new processor manager
    pub fn new() -> ProcessorManager {
        ProcessorManager {
            processors : Vec::new()
        }
    }
    /// Update a processor
    pub fn update(&mut self, world: &World, index: uint) {
        let processor = &mut self.processors[index];
        let mut entities = processor.entities.borrow_mut();
        *entities = world.entities.iter().filter(|&entity| {
            let entity = EntityRef {
                entity: entity,
                entities: &world.entities,
                components: &world.components
            };
            entity.is_active() && processor.aspect.borrow_mut().check(entity)
        }).collect::<Vec<_>>();
    }
    /// Add a processor with an aspect into the world
    pub fn add(&mut self, processor: Box<Processor>, aspect: Box<Aspect>) {
        self.processors.push(MetaProcessor {
            processor: processor,
            aspect: RefCell::new(aspect),
            entities: RefCell::new(Vec::new())
        });
    }
    #[inline(always)]
    /// Iterate through the systems and their descriptors immutably
    pub fn iter(&self) -> Iter<MetaProcessor> {
        self.processors.iter()
    }
    #[inline(always)]
    /// Iterate through the systems and their descriptors mutably
    pub fn iter_mut(&mut self) -> IterMut<MetaProcessor> {
        self.processors.iter_mut()
    }
}

/// An Aspect is used by processors as a matcher against entities,
/// to check if a processor is interested in an entity
pub trait Aspect :'static {
    /// Check if the entity meets the criteria of the aspect
    fn check<'a>(&mut self, entity: EntityRef<'a>) -> bool;
}

impl Aspect for |EntityRef|:'static -> bool {
    fn check<'a>(&mut self, entity: EntityRef<'a>) -> bool {
        (*self)(entity)
    }
}<|endoftext|>


<commit_before>const NUM_RUNS: usize = 10;

fn run_self(exe: &str) -> usize {
    use std::process::Command;
    let mut set = std::collections::HashSet::new();

    let mut cmd = Command::new(exe);
    cmd.arg("--report");
    (0..NUM_RUNS).for_each(|_| {
        set.insert(cmd.output().expect("failed to execute process").stdout);
    });
    set.len()
}

fn main() {
    let mut args = std::env::args();
    let arg0 = args.next().unwrap();
    match args.next() {
        Some(s) if s.eq("--report") => {
            println!("main = {:#?}", &main as *const _);
        }
        Some(s) if s.eq("--test-no-aslr") => {
            let cnt = run_self(&arg0);
            if cnt != 1 {
                eprintln!("FAIL: {} most likely ASLR", arg0);
                std::process::exit(1);
            }
            println!("PASS: {} does no ASLR", arg0);
        }
        Some(s) if s.eq("--test-aslr") => {
            let cnt = run_self(&arg0);
            if cnt != NUM_RUNS {
                eprintln!("FAIL: {} most likely no ASLR", arg0);
                std::process::exit(1);
            }
            println!("PASS: {} does ASLR", arg0);
        }
        Some(_) | None => {
            println!("Usage: {} --test-no-aslr | --test-aslr", arg0);
            std::process::exit(1);
        }
    }
}
<commit_msg>Fix src/test/run-make/static-pie/test-aslr.rs<commit_after>const NUM_RUNS: usize = 10;

fn run_self(exe: &str) -> usize {
    use std::process::Command;
    let mut set = std::collections::HashSet::new();

    let mut cmd = Command::new(exe);
    cmd.arg("--report");
    (0..NUM_RUNS).for_each(|_| {
        set.insert(cmd.output().expect("failed to execute process").stdout);
    });
    set.len()
}

fn main() {
    let mut args = std::env::args();
    let arg0 = args.next().unwrap();
    match args.next() {
        Some(s) if s.eq("--report") => {
            println!("main = {:#?}", &main as *const _);
        }
        Some(s) if s.eq("--test-no-aslr") => {
            let cnt = run_self(&arg0);
            if cnt != 1 {
                eprintln!("FAIL: {} most likely ASLR", arg0);
                std::process::exit(1);
            }
            println!("PASS: {} does no ASLR", arg0);
        }
        Some(s) if s.eq("--test-aslr") => {
            let cnt = run_self(&arg0);
            if cnt == 1 {
                eprintln!("FAIL: {} most likely no ASLR", arg0);
                std::process::exit(1);
            }
            println!("PASS: {} does ASLR", arg0);
        }
        Some(_) | None => {
            println!("Usage: {} --test-no-aslr | --test-aslr", arg0);
            std::process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>// use communication::{Message, Observer};
// use serialization::Serializable;
use drain::DrainExt;

use {Push, Data};
use dataflow::channels::Content;
use abomonation::Abomonation;

// an observer routing between multiple pushers
// TODO : Software write combining
pub struct Exchange<T, D, P: Push<(T, Content<D>)>, H: Fn(&D) -> u64> {
    pushers: Vec<P>,
    buffers: Vec<Vec<D>>,
    current: Option<T>,
    hash_func: H,
}

impl<T: Clone, D, P: Push<(T, Content<D>)>, H: Fn(&D)->u64>  Exchange<T, D, P, H> {
    pub fn new(pushers: Vec<P>, key: H) -> Exchange<T, D, P, H> {
        let mut buffers = vec![];
        for _ in 0..pushers.len() {
            buffers.push(Vec::with_capacity(Content::<D>::default_length()));
        }
        Exchange {
            pushers: pushers,
            hash_func: key,
            buffers: buffers,
            current: None,
        }
    }
    #[inline]
    fn flush(&mut self, index: usize) {
        if self.buffers[index].len() > 0 {
            if let Some(ref time) = self.current {
                Content::push_at(&mut self.buffers[index], time.clone(), &mut self.pushers[index]);
            }
        }
    }
}

impl<T: Eq+Clone+'static, D: Data+Abomonation, P: Push<(T, Content<D>)>, H: Fn(&D)->u64> Push<(T, Content<D>)> for Exchange<T, D, P, H> {
    #[inline]
    fn push(&mut self, message: &mut Option<(T, Content<D>)>) {
        // if only one pusher, no exchange
        if self.pushers.len() == 1 {
            self.pushers[0].push(message);
        }
        else {
            if let Some((ref time, ref mut data)) = *message {

                // if the time isn't right, flush everything.
                if self.current.as_ref().map(|x| x != time).unwrap_or(false) {
                    for index in 0..self.pushers.len() {
                        self.flush(index);
                    }
                }
                self.current = Some(time.clone());

                // if the number of pushers is a power of two, use a mask
                if (self.pushers.len() & (self.pushers.len() - 1)) == 0 {
                    let mask = (self.pushers.len() - 1) as u64;
                    for datum in data.drain_temp() {
                        let index = (((self.hash_func)(&datum)) & mask) as usize;
                        self.buffers[index].push(datum);
                        if self.buffers[index].len() == self.buffers[index].capacity() {
                            self.flush(index);
                        }
                    }
                }
                // as a last resort, use mod (%)
                else {
                    for datum in data.drain_temp() {
                        let index = (((self.hash_func)(&datum)) % self.pushers.len() as u64) as usize;
                        self.buffers[index].push(datum);
                        if self.buffers[index].len() == self.buffers[index].capacity() {
                            self.flush(index);
                        }
                    }
                }

            }
            else {
                // flush
                for index in 0..self.pushers.len() {
                    self.flush(index);
                    self.pushers[index].push(&mut None);
                }
            }
        }
    }
}
<commit_msg>added commented unsafe version of code<commit_after>// use communication::{Message, Observer};
// use serialization::Serializable;
use drain::DrainExt;

use {Push, Data};
use dataflow::channels::Content;
use abomonation::Abomonation;

// an observer routing between multiple pushers
// TODO : Software write combining
pub struct Exchange<T, D, P: Push<(T, Content<D>)>, H: Fn(&D) -> u64> {
    pushers: Vec<P>,
    buffers: Vec<Vec<D>>,
    current: Option<T>,
    hash_func: H,
}

impl<T: Clone, D, P: Push<(T, Content<D>)>, H: Fn(&D)->u64>  Exchange<T, D, P, H> {
    pub fn new(pushers: Vec<P>, key: H) -> Exchange<T, D, P, H> {
        let mut buffers = vec![];
        for _ in 0..pushers.len() {
            buffers.push(Vec::with_capacity(Content::<D>::default_length()));
        }
        Exchange {
            pushers: pushers,
            hash_func: key,
            buffers: buffers,
            current: None,
        }
    }
    #[inline]
    fn flush(&mut self, index: usize) {
        if self.buffers[index].len() > 0 {
            if let Some(ref time) = self.current {
                Content::push_at(&mut self.buffers[index], time.clone(), &mut self.pushers[index]);
            }
        }
    }
}

impl<T: Eq+Clone+'static, D: Data+Abomonation, P: Push<(T, Content<D>)>, H: Fn(&D)->u64> Push<(T, Content<D>)> for Exchange<T, D, P, H> {
    #[inline]
    fn push(&mut self, message: &mut Option<(T, Content<D>)>) {
        // if only one pusher, no exchange
        if self.pushers.len() == 1 {
            self.pushers[0].push(message);
        }
        else {
            if let Some((ref time, ref mut data)) = *message {

                // if the time isn't right, flush everything.
                if self.current.as_ref().map(|x| x != time).unwrap_or(false) {
                    for index in 0..self.pushers.len() {
                        self.flush(index);
                    }
                }
                self.current = Some(time.clone());

                // if the number of pushers is a power of two, use a mask
                if (self.pushers.len() & (self.pushers.len() - 1)) == 0 {
                    let mask = (self.pushers.len() - 1) as u64;
                    for datum in data.drain_temp() {
                        let index = (((self.hash_func)(&datum)) & mask) as usize;

                        self.buffers[index].push(datum);
                        if self.buffers[index].len() == self.buffers[index].capacity() {
                            self.flush(index);
                        }

                        // unsafe {
                        //     self.buffers.get_unchecked_mut(index).push(datum);
                        //     if self.buffers.get_unchecked(index).len() == self.buffers.get_unchecked(index).capacity() {
                        //         self.flush(index);
                        //     }
                        // }

                    }
                }
                // as a last resort, use mod (%)
                else {
                    for datum in data.drain_temp() {
                        let index = (((self.hash_func)(&datum)) % self.pushers.len() as u64) as usize;
                        self.buffers[index].push(datum);
                        if self.buffers[index].len() == self.buffers[index].capacity() {
                            self.flush(index);
                        }
                    }
                }

            }
            else {
                // flush
                for index in 0..self.pushers.len() {
                    self.flush(index);
                    self.pushers[index].push(&mut None);
                }
            }
        }
    }
}
<|endoftext|>


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

use js::jsapi::{JSVal, JSContext};
use js::{JSVAL_FALSE, JSVAL_TRUE};
use js::glue::{RUST_UINT_TO_JSVAL, RUST_JSVAL_TO_INT, RUST_DOUBLE_TO_JSVAL};
use js::glue::{RUST_JSVAL_TO_DOUBLE, RUST_JSVAL_IS_INT, RUST_JSVAL_IS_DOUBLE};
use js::glue::{RUST_JSVAL_IS_BOOLEAN, RUST_JSVAL_TO_BOOLEAN};

pub trait JSValConvertible {
    fn to_jsval(&self) -> JSVal;
    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<Self>;
}

impl JSValConvertible for i64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<i64> {
        unsafe {
            if RUST_JSVAL_IS_INT(val) != 0 {
                Some(RUST_JSVAL_TO_DOUBLE(val) as i64)
            } else {
                None
            }
        }
    }
}

impl JSValConvertible for u32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self)
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<u32> {
        unsafe {
            if RUST_JSVAL_IS_INT(val) != 0 {
                Some(RUST_JSVAL_TO_INT(val) as u32)
            } else {
                None
            }
        }
    }
}

impl JSValConvertible for i32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<i32> {
        unsafe {
            if RUST_JSVAL_IS_INT(val) != 0 {
                Some(RUST_JSVAL_TO_INT(val) as i32)
            } else {
                None
            }
        }
    }
}

impl JSValConvertible for u16 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<u16> {
        unsafe {
            if RUST_JSVAL_IS_INT(val) != 0 {
                Some(RUST_JSVAL_TO_INT(val) as u16)
            } else {
                None
            }
        }
    }
}

impl JSValConvertible for bool {
    fn to_jsval(&self) -> JSVal {
        if *self {
            JSVAL_TRUE
        } else {
            JSVAL_FALSE
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<bool> {
        unsafe {
            if RUST_JSVAL_IS_BOOLEAN(val) != 0 {
                Some(RUST_JSVAL_TO_BOOLEAN(val) != 0)
            } else {
                None
            }
        }
    }
}

impl JSValConvertible for f32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<f32> {
        unsafe {
            if RUST_JSVAL_IS_DOUBLE(val) != 0 {
                Some(RUST_JSVAL_TO_DOUBLE(val) as f32)
            } else {
                None
            }
        }
    }
}

impl JSValConvertible for f64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(_cx: *JSContext, val: JSVal) -> Option<f64> {
        unsafe {
            if RUST_JSVAL_IS_DOUBLE(val) != 0 {
                Some(RUST_JSVAL_TO_DOUBLE(val) as f64)
            } else {
                None
            }
        }
    }
}
<commit_msg>Reimplement conversion to primitive types for correctness in the face of non-primitive arguments.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use js::jsapi::{JSVal, JSBool, JSContext};
use js::jsapi::{JS_ValueToInt64, JS_ValueToECMAInt32, JS_ValueToECMAUint32};
use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean};
use js::{JSVAL_FALSE, JSVAL_TRUE};
use js::glue::{RUST_UINT_TO_JSVAL, RUST_DOUBLE_TO_JSVAL};

pub trait JSValConvertible {
    fn to_jsval(&self) -> JSVal;
    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<Self>;
}

unsafe fn convert_from_jsval<T: Default>(
    cx: *JSContext, value: JSVal,
    convert_fn: extern "C" unsafe fn(*JSContext, JSVal, *T) -> JSBool) -> Option<T> {
    let mut ret = Default::default();
    if convert_fn(cx, value, &mut ret as *mut T as *T) == 0 {
        None
    } else {
        Some(ret)
    }
}

impl JSValConvertible for i64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i64> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) }
    }
}

impl JSValConvertible for u32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u32> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) }
    }
}

impl JSValConvertible for i32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i32> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }
    }
}

impl JSValConvertible for u16 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u16> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) }
    }
}

impl JSValConvertible for bool {
    fn to_jsval(&self) -> JSVal {
        if *self {
            JSVAL_TRUE
        } else {
            JSVAL_FALSE
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<bool> {
        let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) };
        result.map(|b| b != 0)
    }
}

impl JSValConvertible for f32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f32> {
        let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) };
        result.map(|f| f as f32)
    }
}

impl JSValConvertible for f64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f64> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }
    }
}
<|endoftext|>