<commit_before>// Copyright 2016 Serde YAML Developers
//
// 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.

//! YAML Deserialization
//!
//! This module provides YAML deserialization with the type `Deserializer`.

use std::io;
use std::iter;
use std::str;

use yaml_rust::{Yaml, YamlLoader};
use yaml_rust::yaml;

use serde::de::{self, Deserialize, DeserializeSeed};

use super::error::{Error, Result};

pub struct Deserializer {
    doc: Yaml,
}

impl Deserializer {
    pub fn new(doc: Yaml) -> Self {
        Deserializer {
            doc: doc,
        }
    }
}

struct SeqVisitor {
    /// Iterator over the YAML array being visited.
    iter: <yaml::Array as iter::IntoIterator>::IntoIter,
}

impl SeqVisitor {
    fn new(seq: yaml::Array) -> Self {
        SeqVisitor {
            iter: seq.into_iter(),
        }
    }
}

impl de::SeqVisitor for SeqVisitor {
    type Error = Error;

    fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
        where T: DeserializeSeed
    {
        match self.iter.next() {
            None => Ok(None),
            Some(t) => seed.deserialize(Deserializer::new(t)).map(Some),
        }
    }
}

struct MapVisitor {
    /// Iterator over the YAML hash being visited.
    iter: <yaml::Hash as iter::IntoIterator>::IntoIter,
    /// Value associated with the most recently visited key.
    v: Option<Yaml>,
}

impl MapVisitor {
    fn new(hash: yaml::Hash) -> Self {
        MapVisitor {
            iter: hash.into_iter(),
            v: None,
        }
    }
}

impl de::MapVisitor for MapVisitor {
    type Error = Error;

    fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
        where K: DeserializeSeed
    {
        match self.iter.next() {
            None => Ok(None),
            Some((k, v)) => {
                self.v = Some(v);
                seed.deserialize(Deserializer::new(k)).map(Some)
            }
        }
    }

    fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
        where V: DeserializeSeed
    {
        match self.v.take() {
            Some(v) => seed.deserialize(Deserializer::new(v)),
            None => panic!("visit_value called before visit_key"),
        }
    }
}

struct EnumVisitor {
    variant: Yaml,
    content: Yaml,
}

impl EnumVisitor {
    fn new(variant: Yaml, content: Yaml) -> Self {
        EnumVisitor {
            variant: variant,
            content: content,
        }
    }
}

impl de::EnumVisitor for EnumVisitor {
    type Error = Error;
    type Variant = VariantVisitor;

    fn visit_variant_seed<V>(
        self,
        seed: V,
    ) -> Result<(V::Value, VariantVisitor)>
        where V: DeserializeSeed
    {
        let variant = try!(seed.deserialize(Deserializer::new(self.variant)));
        Ok((variant, VariantVisitor::new(self.content)))
    }
}

struct VariantVisitor {
    content: Yaml,
}

impl VariantVisitor {
    fn new(content: Yaml) -> Self {
        VariantVisitor {
            content: content,
        }
    }
}

impl de::VariantVisitor for VariantVisitor {
    type Error = Error;

    fn visit_unit(self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value>
        where T: DeserializeSeed
    {
        seed.deserialize(Deserializer::new(self.content))
    }

    fn visit_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        de::Deserializer::deserialize(Deserializer::new(self.content), visitor)
    }

    fn visit_struct<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor
    {
        de::Deserializer::deserialize(Deserializer::new(self.content), visitor)
    }
}

impl de::Deserializer for Deserializer {
    type Error = Error;

    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.doc {
            Yaml::Real(ref s) => {
                match s.parse() {
                    Ok(f) => visitor.visit_f64(f),
                    Err(_) => visitor.visit_str(s),
                }
            }
            Yaml::Integer(i) => visitor.visit_i64(i),
            Yaml::String(s) => visitor.visit_string(s),
            Yaml::Boolean(b) => visitor.visit_bool(b),
            Yaml::Array(seq) => visitor.visit_seq(SeqVisitor::new(seq)),
            Yaml::Hash(hash) => visitor.visit_map(MapVisitor::new(hash)),
            Yaml::Alias(_) => Err(Error::AliasUnsupported),
            Yaml::Null => visitor.visit_unit(),
            Yaml::BadValue => {
                // The yaml-rust library produces BadValue when a nonexistent
                // node is accessed by the Index trait, and when a type
                // conversion is invalid. Both of these are unexpected in our
                // usage.
                panic!("bad value")
            }
        }
    }

    /// Parses `null` as None and any other values as `Some(...)`.
    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.doc {
            Yaml::Null => visitor.visit_none(),
            _ => visitor.visit_some(self),
        }
    }

    /// Parses a newtype struct as the underlying value.
    fn deserialize_newtype_struct<V>(
        self,
        _name: &str,
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_newtype_struct(self)
    }

    /// Parses an enum as a single key:value pair where the key identifies the
    /// variant and the value gives the content. A String will also parse correctly
    /// to a unit enum value.
    fn deserialize_enum<V>(
        self,
        name: &str,
        _variants: &'static [&'static str],
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.doc {
            Yaml::Hash(hash) => {
                let len = hash.len();
                let mut iter = hash.into_iter();
                if let (Some(entry), None) = (iter.next(), iter.next()) {
                    let (variant, content) = entry;
                    visitor.visit_enum(EnumVisitor::new(variant, content))
                } else {
                    Err(Error::VariantMapWrongSize(String::from(name), len))
                }
            }
            ystr @ Yaml::String(_) => {
                visitor.visit_enum(EnumVisitor::new(ystr, Yaml::Null))
            }
            _ => Err(Error::VariantNotAMapOrString(String::from(name))),
        }
    }

    forward_to_deserialize!{
        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
        seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct
        struct_field tuple ignored_any
    }
}

/// Decodes a YAML value from a `&str`.
pub fn from_str<T>(s: &str) -> Result<T>
    where T: Deserialize
{
    let docs = try!(YamlLoader::load_from_str(s));
    match docs.len() {
        0 => Err(Error::EndOfStream),
        1 => {
            let doc = docs.into_iter().next().unwrap();
            Deserialize::deserialize(Deserializer::new(doc))
        }
        n => Err(Error::TooManyDocuments(n)),
    }
}

pub fn from_iter<I, T>(iter: I) -> Result<T>
    where I: Iterator<Item = io::Result<u8>>,
          T: Deserialize
{
    let bytes: Vec<u8> = try!(iter.collect());
    from_str(try!(str::from_utf8(&bytes)))
}

pub fn from_reader<R, T>(rdr: R) -> Result<T>
    where R: io::Read,
          T: Deserialize
{
    from_iter(rdr.bytes())
}

pub fn from_slice<T>(v: &[u8]) -> Result<T>
    where T: Deserialize
{
    from_iter(v.iter().map(|byte| Ok(*byte)))
}
<commit_msg>Loader to capture yaml events<commit_after>// Copyright 2016 Serde YAML Developers
//
// 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.

//! YAML Deserialization
//!
//! This module provides YAML deserialization with the type `Deserializer`.

use std::io;
use std::iter;
use std::str;

use yaml_rust::{yaml, Yaml, YamlLoader};
use yaml_rust::parser::{Parser, MarkedEventReceiver, Event};
use yaml_rust::scanner::{Marker, TokenType, TScalarStyle};

use serde::de::{self, Deserialize, DeserializeSeed};

use super::error::{Error, Result};

pub struct Loader {
    events: Vec<(Event, Marker)>,
}

impl MarkedEventReceiver for Loader {
    fn on_event(&mut self, event: &Event, marker: Marker) {
        match *event {
            Event::Nothing
                | Event::StreamStart
                | Event::StreamEnd
                | Event::DocumentStart
                | Event::DocumentEnd => {}

            Event::Alias(_)
                | Event::Scalar(_, _, _, _)
                | Event::SequenceStart(_)
                | Event::SequenceEnd
                | Event::MappingStart(_)
                | Event::MappingEnd => self.events.push((event.clone(), marker)),
        }
    }
}

pub struct Deserializer {
    doc: Yaml,
}

impl Deserializer {
    pub fn new(doc: Yaml) -> Self {
        Deserializer {
            doc: doc,
        }
    }
}

struct SeqVisitor {
    /// Iterator over the YAML array being visited.
    iter: <yaml::Array as iter::IntoIterator>::IntoIter,
}

impl SeqVisitor {
    fn new(seq: yaml::Array) -> Self {
        SeqVisitor {
            iter: seq.into_iter(),
        }
    }
}

impl de::SeqVisitor for SeqVisitor {
    type Error = Error;

    fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
        where T: DeserializeSeed
    {
        match self.iter.next() {
            None => Ok(None),
            Some(t) => seed.deserialize(Deserializer::new(t)).map(Some),
        }
    }
}

struct MapVisitor {
    /// Iterator over the YAML hash being visited.
    iter: <yaml::Hash as iter::IntoIterator>::IntoIter,
    /// Value associated with the most recently visited key.
    v: Option<Yaml>,
}

impl MapVisitor {
    fn new(hash: yaml::Hash) -> Self {
        MapVisitor {
            iter: hash.into_iter(),
            v: None,
        }
    }
}

impl de::MapVisitor for MapVisitor {
    type Error = Error;

    fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
        where K: DeserializeSeed
    {
        match self.iter.next() {
            None => Ok(None),
            Some((k, v)) => {
                self.v = Some(v);
                seed.deserialize(Deserializer::new(k)).map(Some)
            }
        }
    }

    fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
        where V: DeserializeSeed
    {
        match self.v.take() {
            Some(v) => seed.deserialize(Deserializer::new(v)),
            None => panic!("visit_value called before visit_key"),
        }
    }
}

struct EnumVisitor {
    variant: Yaml,
    content: Yaml,
}

impl EnumVisitor {
    fn new(variant: Yaml, content: Yaml) -> Self {
        EnumVisitor {
            variant: variant,
            content: content,
        }
    }
}

impl de::EnumVisitor for EnumVisitor {
    type Error = Error;
    type Variant = VariantVisitor;

    fn visit_variant_seed<V>(
        self,
        seed: V,
    ) -> Result<(V::Value, VariantVisitor)>
        where V: DeserializeSeed
    {
        let variant = try!(seed.deserialize(Deserializer::new(self.variant)));
        Ok((variant, VariantVisitor::new(self.content)))
    }
}

struct VariantVisitor {
    content: Yaml,
}

impl VariantVisitor {
    fn new(content: Yaml) -> Self {
        VariantVisitor {
            content: content,
        }
    }
}

impl de::VariantVisitor for VariantVisitor {
    type Error = Error;

    fn visit_unit(self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value>
        where T: DeserializeSeed
    {
        seed.deserialize(Deserializer::new(self.content))
    }

    fn visit_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        de::Deserializer::deserialize(Deserializer::new(self.content), visitor)
    }

    fn visit_struct<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor
    {
        de::Deserializer::deserialize(Deserializer::new(self.content), visitor)
    }
}

impl de::Deserializer for Deserializer {
    type Error = Error;

    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.doc {
            Yaml::Real(ref s) => {
                match s.parse() {
                    Ok(f) => visitor.visit_f64(f),
                    Err(_) => visitor.visit_str(s),
                }
            }
            Yaml::Integer(i) => visitor.visit_i64(i),
            Yaml::String(s) => visitor.visit_string(s),
            Yaml::Boolean(b) => visitor.visit_bool(b),
            Yaml::Array(seq) => visitor.visit_seq(SeqVisitor::new(seq)),
            Yaml::Hash(hash) => visitor.visit_map(MapVisitor::new(hash)),
            Yaml::Alias(_) => Err(Error::AliasUnsupported),
            Yaml::Null => visitor.visit_unit(),
            Yaml::BadValue => {
                // The yaml-rust library produces BadValue when a nonexistent
                // node is accessed by the Index trait, and when a type
                // conversion is invalid. Both of these are unexpected in our
                // usage.
                panic!("bad value")
            }
        }
    }

    /// Parses `null` as None and any other values as `Some(...)`.
    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.doc {
            Yaml::Null => visitor.visit_none(),
            _ => visitor.visit_some(self),
        }
    }

    /// Parses a newtype struct as the underlying value.
    fn deserialize_newtype_struct<V>(
        self,
        _name: &str,
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_newtype_struct(self)
    }

    /// Parses an enum as a single key:value pair where the key identifies the
    /// variant and the value gives the content. A String will also parse correctly
    /// to a unit enum value.
    fn deserialize_enum<V>(
        self,
        name: &str,
        _variants: &'static [&'static str],
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.doc {
            Yaml::Hash(hash) => {
                let len = hash.len();
                let mut iter = hash.into_iter();
                if let (Some(entry), None) = (iter.next(), iter.next()) {
                    let (variant, content) = entry;
                    visitor.visit_enum(EnumVisitor::new(variant, content))
                } else {
                    Err(Error::VariantMapWrongSize(String::from(name), len))
                }
            }
            ystr @ Yaml::String(_) => {
                visitor.visit_enum(EnumVisitor::new(ystr, Yaml::Null))
            }
            _ => Err(Error::VariantNotAMapOrString(String::from(name))),
        }
    }

    forward_to_deserialize!{
        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
        seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct
        struct_field tuple ignored_any
    }
}

/// Decodes a YAML value from a `&str`.
pub fn from_str<T>(s: &str) -> Result<T>
    where T: Deserialize
{
    let docs = try!(YamlLoader::load_from_str(s));
    match docs.len() {
        0 => Err(Error::EndOfStream),
        1 => {
            let doc = docs.into_iter().next().unwrap();
            Deserialize::deserialize(Deserializer::new(doc))
        }
        n => Err(Error::TooManyDocuments(n)),
    }
}

pub fn from_iter<I, T>(iter: I) -> Result<T>
    where I: Iterator<Item = io::Result<u8>>,
          T: Deserialize
{
    let bytes: Vec<u8> = try!(iter.collect());
    from_str(try!(str::from_utf8(&bytes)))
}

pub fn from_reader<R, T>(rdr: R) -> Result<T>
    where R: io::Read,
          T: Deserialize
{
    from_iter(rdr.bytes())
}

pub fn from_slice<T>(v: &[u8]) -> Result<T>
    where T: Deserialize
{
    from_iter(v.iter().map(|byte| Ok(*byte)))
}
<|endoftext|>


<commit_before>use wad::{LightEffectKind, LightInfo};

pub struct Lights {
    lights: Vec<LightInfo>,
}

impl Lights {
    pub fn new() -> Self {
        Self {
            lights: Vec::with_capacity(256),
        }
    }

    pub fn push(&mut self, light_info: &LightInfo) -> u8 {
        self.lights
            .iter()
            .position(|x| x == light_info)
            .unwrap_or_else(|| {
                // TODO(cristicbz): Remove this restriction.
                assert!(self.lights.len() < 255);
                self.lights.push(light_info.clone());
                self.lights.len() - 1_usize
            }) as u8
    }

    pub fn fill_buffer_at(&mut self, time: f32, buffer: &mut [u8]) {
        for (value, info) in buffer.iter_mut().zip(self.lights.iter()) {
            *value = (clamp(light_level_at(info, time)) * 255.0) as u8;
        }
    }
}

fn light_level_at(info: &LightInfo, time: f32) -> f32 {
    let effect = if let Some(ref effect) = info.effect {
        effect
    } else {
        return info.level;
    };
    match effect.kind {
        LightEffectKind::Glow => {
            let scale = info.level - effect.alt_level;
            let phase = time * effect.speed / scale;
            (0.5 - fract(phase)).abs() * 2.0 * scale + effect.alt_level
        }
        LightEffectKind::Random => {
            if noise(effect.sync, (time * effect.speed).floor()) < effect.duration {
                effect.alt_level
            } else {
                info.level
            }
        }
        LightEffectKind::Alternate => {
            if fract(time * effect.speed + effect.sync * 3.5435) < effect.duration {
                effect.alt_level
            } else {
                info.level
            }
        }
    }
}

fn noise(sync: f32, time: f32) -> f32 {
    fract(1.0 + ((sync + time / 1000.0) * 12.9898 + sync * 78.233).sin() * 43758.547)
}

fn fract(x: f32) -> f32 {
    x - x.floor()
}

fn clamp(x: f32) -> f32 {
    if x < 0.0 {
        0.0
    } else if x > 1.0 {
        1.0
    } else {
        x
    }
}
<commit_msg>linters: fix; game::lights, removed usize suffix<commit_after>use wad::{LightEffectKind, LightInfo};

pub struct Lights {
    lights: Vec<LightInfo>,
}

impl Lights {
    pub fn new() -> Self {
        Self {
            lights: Vec::with_capacity(256),
        }
    }

    pub fn push(&mut self, light_info: &LightInfo) -> u8 {
        self.lights
            .iter()
            .position(|x| x == light_info)
            .unwrap_or_else(|| {
                // TODO(cristicbz): Remove this restriction.
                assert!(self.lights.len() < 255);
                self.lights.push(light_info.clone());
                self.lights.len() - 1
            }) as u8
    }

    pub fn fill_buffer_at(&mut self, time: f32, buffer: &mut [u8]) {
        for (value, info) in buffer.iter_mut().zip(self.lights.iter()) {
            *value = (clamp(light_level_at(info, time)) * 255.0) as u8;
        }
    }
}

fn light_level_at(info: &LightInfo, time: f32) -> f32 {
    let effect = if let Some(ref effect) = info.effect {
        effect
    } else {
        return info.level;
    };
    match effect.kind {
        LightEffectKind::Glow => {
            let scale = info.level - effect.alt_level;
            let phase = time * effect.speed / scale;
            (0.5 - fract(phase)).abs() * 2.0 * scale + effect.alt_level
        }
        LightEffectKind::Random => {
            if noise(effect.sync, (time * effect.speed).floor()) < effect.duration {
                effect.alt_level
            } else {
                info.level
            }
        }
        LightEffectKind::Alternate => {
            if fract(time * effect.speed + effect.sync * 3.5435) < effect.duration {
                effect.alt_level
            } else {
                info.level
            }
        }
    }
}

fn noise(sync: f32, time: f32) -> f32 {
    fract(1.0 + ((sync + time / 1000.0) * 12.9898 + sync * 78.233).sin() * 43758.547)
}

fn fract(x: f32) -> f32 {
    x - x.floor()
}

fn clamp(x: f32) -> f32 {
    if x < 0.0 {
        0.0
    } else if x > 1.0 {
        1.0
    } else {
        x
    }
}
<|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 eutil::slice_to_str;
use libc::{self, size_t, c_int, c_ushort, c_void};
use libc::types::os::arch::c95::wchar_t;
use std::char;
use std::cmp::Ordering;
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
    unsafe {
        libc::free(str as *mut c_void)
    }
}

#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn string_utf8_dtor(str: *mut u8) {
    unsafe {
        libc::free(str as *mut c_void)
    }
}

#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
    unsafe {
        libc::free(str as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
    cef_string_wide_clear(cs);
    unsafe {
        libc::free(cs as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
    unsafe {
        cef_string_utf8_clear(cs);
        libc::free(cs as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: cef_string_userfree_utf16_t) {
    unsafe {
        cef_string_utf16_clear(cs);
        libc::free(cs as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[inline(never)]
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    unsafe {
        libc::calloc(1, mem::size_of::<cef_string_utf8_t>() as u64) as *mut cef_string_utf8_t
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = libc::calloc(1, src_len + 1) as *mut u8;
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy(src, (*output).str, src_len as usize);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf8_dtor as extern "C" fn(*mut u8));
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int {
    unsafe {
        let astr = (*a).str as *const u8;
        let bstr = (*b).str as *const u8;
        let astr = slice::from_raw_parts(astr, (*a).length as usize);
        let bstr = slice::from_raw_parts(bstr, (*b).length as usize);
        match astr.cmp(bstr) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    slice_to_str(src, src_len as usize, |result| {
        let conv = result.utf16_units().collect::<Vec<u16>>();
        cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
        1
    })
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
        let ustr = slice::from_raw_parts(src, src_len as usize);
        match string::String::from_utf16(ustr) {
            Ok(str) => {
                cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                1 as c_int
            },
            _ =>  0 as c_int
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[inline(never)]
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    unsafe {
        libc::calloc(1, mem::size_of::<cef_string_utf16_t>() as u64) as *mut cef_string_utf16_t
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = libc::calloc(1, (src_len + 1) * mem::size_of::<c_ushort>() as u64) as
                 *mut u16;
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy(src, (*output).str, src_len as usize);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf16_dtor as extern "C" fn(*mut c_ushort));
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int {
    unsafe {
        let astr = (*a).str as *const _;
        let bstr = (*b).str as *const _;
        let astr: &[u16] = slice::from_raw_parts(astr, (*a).length as usize);
        let bstr: &[u16] = slice::from_raw_parts(bstr, (*b).length as usize);
        match astr.cmp(bstr) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[inline(never)]
#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    unsafe {
        libc::calloc(1, mem::size_of::<cef_string_wide_t>() as u64) as *mut cef_string_wide_t
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = libc::calloc(1, (src_len + 1) * mem::size_of::<wchar_t>() as u64) as
                 *mut wchar_t;
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy(src, (*output).str, src_len as usize);
             (*output).length = src_len;
             (*output).dtor = Some(string_wide_dtor as extern "C" fn(*mut wchar_t));
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_cmp(a: *const cef_string_wide_t, b: *const cef_string_wide_t) -> c_int {
    unsafe {
        let astr = (*a).str as *const wchar_t;
        let bstr = (*b).str as *const wchar_t;
        let astr = slice::from_raw_parts(astr, (*a).length as usize);
        let bstr = slice::from_raw_parts(bstr, (*b).length as usize);
        match astr.cmp(bstr) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_wide(src: *const u8, src_len: size_t, output: *mut cef_string_wide_t) -> c_int {
    if mem::size_of::<wchar_t>() == mem::size_of::<u16>() {
         return cef_string_utf8_to_utf16(src, src_len, output as *mut cef_string_utf16_t);
    }
    slice_to_str(src, src_len as usize, |result| {
        let conv = result.chars().map(|c| c as u32).collect::<Vec<u32>>();
        cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1)
    })
}

#[no_mangle]
pub extern "C" fn cef_string_wide_to_utf8(src: *const wchar_t, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    if mem::size_of::<wchar_t>() == mem::size_of::<u16>() {
         return cef_string_utf16_to_utf8(src as *const u16, src_len, output);
    }
    unsafe {
        let ustr = slice::from_raw_parts(src, src_len as usize);
        let conv = ustr.iter().map(|&c| char::from_u32(c as u32).unwrap_or('\u{FFFD}')).collect::<String>();
        cef_string_utf8_set(conv.as_bytes().as_ptr(), conv.len() as size_t, output, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_ascii_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    slice_to_str(src, src_len as usize, |result| {
        let conv = result.utf16_units().collect::<Vec<u16>>();
        cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1)
    })
}

#[no_mangle]
pub extern "C" fn cef_string_ascii_to_wide(src: *const u8, src_len: size_t, output: *mut cef_string_wide_t) -> c_int {
    unsafe {
        let ustr = slice::from_raw_parts(src, src_len as usize);
        let conv = ustr.iter().map(|&c| c as u8).collect::<Vec<u8>>();
        cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1)
    }
}

pub fn empty_utf16_string() -> cef_string_utf16_t {
    cef_string_utf16_t {
        str: ptr::null_mut(),
        length: 0,
        dtor: None,
    }
}

pub fn string_to_userfree_string(string: cef_string_utf16_t) -> cef_string_userfree_utf16_t {
    unsafe {
        let allocation: cef_string_userfree_utf16_t =
            mem::transmute(libc::malloc(mem::size_of::<cef_string_utf16_t>() as size_t));
        ptr::write(allocation, string);
        allocation
    }
}

pub fn empty_utf16_userfree_string() -> cef_string_userfree_utf16_t {
    string_to_userfree_string(empty_utf16_string())
}

<commit_msg>Assign None into CEF string drop fields rather than transmuting a null pointer.<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 eutil::slice_to_str;
use libc::{self, size_t, c_int, c_ushort, c_void};
use libc::types::os::arch::c95::wchar_t;
use std::char;
use std::cmp::Ordering;
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
    unsafe {
        libc::free(str as *mut c_void)
    }
}

#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn string_utf8_dtor(str: *mut u8) {
    unsafe {
        libc::free(str as *mut c_void)
    }
}

#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
    unsafe {
        libc::free(str as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
    cef_string_wide_clear(cs);
    unsafe {
        libc::free(cs as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
    unsafe {
        cef_string_utf8_clear(cs);
        libc::free(cs as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: cef_string_userfree_utf16_t) {
    unsafe {
        cef_string_utf16_clear(cs);
        libc::free(cs as *mut c_void)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = None;
    }
}

#[inline(never)]
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    unsafe {
        libc::calloc(1, mem::size_of::<cef_string_utf8_t>() as u64) as *mut cef_string_utf8_t
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = libc::calloc(1, src_len + 1) as *mut u8;
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy(src, (*output).str, src_len as usize);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf8_dtor as extern "C" fn(*mut u8));
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = None;
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int {
    unsafe {
        let astr = (*a).str as *const u8;
        let bstr = (*b).str as *const u8;
        let astr = slice::from_raw_parts(astr, (*a).length as usize);
        let bstr = slice::from_raw_parts(bstr, (*b).length as usize);
        match astr.cmp(bstr) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    slice_to_str(src, src_len as usize, |result| {
        let conv = result.utf16_units().collect::<Vec<u16>>();
        cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
        1
    })
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
        let ustr = slice::from_raw_parts(src, src_len as usize);
        match string::String::from_utf16(ustr) {
            Ok(str) => {
                cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                1 as c_int
            },
            _ =>  0 as c_int
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = None;
    }
}

#[inline(never)]
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    unsafe {
        libc::calloc(1, mem::size_of::<cef_string_utf16_t>() as u64) as *mut cef_string_utf16_t
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = libc::calloc(1, (src_len + 1) * mem::size_of::<c_ushort>() as u64) as
                 *mut u16;
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy(src, (*output).str, src_len as usize);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf16_dtor as extern "C" fn(*mut c_ushort));
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = None;
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int {
    unsafe {
        let astr = (*a).str as *const _;
        let bstr = (*b).str as *const _;
        let astr: &[u16] = slice::from_raw_parts(astr, (*a).length as usize);
        let bstr: &[u16] = slice::from_raw_parts(bstr, (*b).length as usize);
        match astr.cmp(bstr) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = None;
    }
}

#[inline(never)]
#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    unsafe {
        libc::calloc(1, mem::size_of::<cef_string_wide_t>() as u64) as *mut cef_string_wide_t
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = libc::calloc(1, (src_len + 1) * mem::size_of::<wchar_t>() as u64) as
                 *mut wchar_t;
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy(src, (*output).str, src_len as usize);
             (*output).length = src_len;
             (*output).dtor = Some(string_wide_dtor as extern "C" fn(*mut wchar_t));
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = None;
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_cmp(a: *const cef_string_wide_t, b: *const cef_string_wide_t) -> c_int {
    unsafe {
        let astr = (*a).str as *const wchar_t;
        let bstr = (*b).str as *const wchar_t;
        let astr = slice::from_raw_parts(astr, (*a).length as usize);
        let bstr = slice::from_raw_parts(bstr, (*b).length as usize);
        match astr.cmp(bstr) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1
        }
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_wide(src: *const u8, src_len: size_t, output: *mut cef_string_wide_t) -> c_int {
    if mem::size_of::<wchar_t>() == mem::size_of::<u16>() {
         return cef_string_utf8_to_utf16(src, src_len, output as *mut cef_string_utf16_t);
    }
    slice_to_str(src, src_len as usize, |result| {
        let conv = result.chars().map(|c| c as u32).collect::<Vec<u32>>();
        cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1)
    })
}

#[no_mangle]
pub extern "C" fn cef_string_wide_to_utf8(src: *const wchar_t, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    if mem::size_of::<wchar_t>() == mem::size_of::<u16>() {
         return cef_string_utf16_to_utf8(src as *const u16, src_len, output);
    }
    unsafe {
        let ustr = slice::from_raw_parts(src, src_len as usize);
        let conv = ustr.iter().map(|&c| char::from_u32(c as u32).unwrap_or('\u{FFFD}')).collect::<String>();
        cef_string_utf8_set(conv.as_bytes().as_ptr(), conv.len() as size_t, output, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_ascii_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    slice_to_str(src, src_len as usize, |result| {
        let conv = result.utf16_units().collect::<Vec<u16>>();
        cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1)
    })
}

#[no_mangle]
pub extern "C" fn cef_string_ascii_to_wide(src: *const u8, src_len: size_t, output: *mut cef_string_wide_t) -> c_int {
    unsafe {
        let ustr = slice::from_raw_parts(src, src_len as usize);
        let conv = ustr.iter().map(|&c| c as u8).collect::<Vec<u8>>();
        cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1)
    }
}

pub fn empty_utf16_string() -> cef_string_utf16_t {
    cef_string_utf16_t {
        str: ptr::null_mut(),
        length: 0,
        dtor: None,
    }
}

pub fn string_to_userfree_string(string: cef_string_utf16_t) -> cef_string_userfree_utf16_t {
    unsafe {
        let allocation: cef_string_userfree_utf16_t =
            mem::transmute(libc::malloc(mem::size_of::<cef_string_utf16_t>() as size_t));
        ptr::write(allocation, string);
        allocation
    }
}

pub fn empty_utf16_userfree_string() -> cef_string_userfree_utf16_t {
    string_to_userfree_string(empty_utf16_string())
}

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

//! Generic types for counters-related CSS values.

#[cfg(feature = "servo")]
use computed_values::list_style_type::T as ListStyleType;
use std::ops::Deref;
use values::CustomIdent;
#[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone;
#[cfg(feature = "gecko")]
use values::specified::Attr;

/// A name / value pair for counters.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct CounterPair<Integer> {
    /// The name of the counter.
    pub name: CustomIdent,
    /// The value of the counter / increment / etc.
    pub value: Integer,
}

/// A generic value for the `counter-increment` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct CounterIncrement<I>(Counters<I>);

impl<I> CounterIncrement<I> {
    /// Returns a new value for `counter-increment`.
    #[inline]
    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
        CounterIncrement(Counters(counters.into_boxed_slice()))
    }
}

impl<I> Deref for CounterIncrement<I> {
    type Target = [CounterPair<I>];

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

/// A generic value for the `counter-reset` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct CounterReset<I>(Counters<I>);

impl<I> CounterReset<I> {
    /// Returns a new value for `counter-reset`.
    #[inline]
    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
        CounterReset(Counters(counters.into_boxed_slice()))
    }
}

impl<I> Deref for CounterReset<I> {
    type Target = [CounterPair<I>];

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

/// A generic value for lists of counters.
///
/// Keyword `none` is represented by an empty vector.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);

impl<I> Default for Counters<I> {
    #[inline]
    fn default() -> Self {
        Counters(vec![].into_boxed_slice())
    }
}

#[cfg(feature = "servo")]
type CounterStyleType = ListStyleType;

#[cfg(feature = "gecko")]
type CounterStyleType = CounterStyleOrNone;

#[cfg(feature = "servo")]
#[inline]
fn is_decimal(counter_type: &CounterStyleType) -> bool {
    *counter_type == ListStyleType::Decimal
}

#[cfg(feature = "gecko")]
#[inline]
fn is_decimal(counter_type: &CounterStyleType) -> bool {
    *counter_type == CounterStyleOrNone::decimal()
}

/// The specified value for the `content` property.
///
/// https://drafts.csswg.org/css-content/#propdef-content
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub enum Content<ImageUrl> {
    /// `normal` reserved keyword.
    Normal,
    /// `none` reserved keyword.
    None,
    /// `-moz-alt-content`.
    #[cfg(feature = "gecko")]
    MozAltContent,
    /// Content items.
    Items(#[css(iterable)] Box<[ContentItem<ImageUrl>]>),
}

impl<ImageUrl> Content<ImageUrl> {
    /// Set `content` property to `normal`.
    #[inline]
    pub fn normal() -> Self {
        Content::Normal
    }

}

/// Items for the `content` property.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub enum ContentItem<ImageUrl> {
    /// Literal string content.
    String(Box<str>),
    /// `counter(name, style)`.
    #[css(comma, function)]
    Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
    /// `counters(name, separator, style)`.
    #[css(comma, function)]
    Counters(
        CustomIdent,
        Box<str>,
        #[css(skip_if = "is_decimal")] CounterStyleType,
    ),
    /// `open-quote`.
    OpenQuote,
    /// `close-quote`.
    CloseQuote,
    /// `no-open-quote`.
    NoOpenQuote,
    /// `no-close-quote`.
    NoCloseQuote,
    /// `attr([namespace? `|`]? ident)`
    #[cfg(feature = "gecko")]
    Attr(Attr),
    /// `url(url)`
    Url(ImageUrl),
}
<commit_msg>style: Remove stray newline.<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/. */

//! Generic types for counters-related CSS values.

#[cfg(feature = "servo")]
use computed_values::list_style_type::T as ListStyleType;
use std::ops::Deref;
use values::CustomIdent;
#[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone;
#[cfg(feature = "gecko")]
use values::specified::Attr;

/// A name / value pair for counters.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct CounterPair<Integer> {
    /// The name of the counter.
    pub name: CustomIdent,
    /// The value of the counter / increment / etc.
    pub value: Integer,
}

/// A generic value for the `counter-increment` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct CounterIncrement<I>(Counters<I>);

impl<I> CounterIncrement<I> {
    /// Returns a new value for `counter-increment`.
    #[inline]
    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
        CounterIncrement(Counters(counters.into_boxed_slice()))
    }
}

impl<I> Deref for CounterIncrement<I> {
    type Target = [CounterPair<I>];

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

/// A generic value for the `counter-reset` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct CounterReset<I>(Counters<I>);

impl<I> CounterReset<I> {
    /// Returns a new value for `counter-reset`.
    #[inline]
    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
        CounterReset(Counters(counters.into_boxed_slice()))
    }
}

impl<I> Deref for CounterReset<I> {
    type Target = [CounterPair<I>];

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

/// A generic value for lists of counters.
///
/// Keyword `none` is represented by an empty vector.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);

impl<I> Default for Counters<I> {
    #[inline]
    fn default() -> Self {
        Counters(vec![].into_boxed_slice())
    }
}

#[cfg(feature = "servo")]
type CounterStyleType = ListStyleType;

#[cfg(feature = "gecko")]
type CounterStyleType = CounterStyleOrNone;

#[cfg(feature = "servo")]
#[inline]
fn is_decimal(counter_type: &CounterStyleType) -> bool {
    *counter_type == ListStyleType::Decimal
}

#[cfg(feature = "gecko")]
#[inline]
fn is_decimal(counter_type: &CounterStyleType) -> bool {
    *counter_type == CounterStyleOrNone::decimal()
}

/// The specified value for the `content` property.
///
/// https://drafts.csswg.org/css-content/#propdef-content
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub enum Content<ImageUrl> {
    /// `normal` reserved keyword.
    Normal,
    /// `none` reserved keyword.
    None,
    /// `-moz-alt-content`.
    #[cfg(feature = "gecko")]
    MozAltContent,
    /// Content items.
    Items(#[css(iterable)] Box<[ContentItem<ImageUrl>]>),
}

impl<ImageUrl> Content<ImageUrl> {
    /// Set `content` property to `normal`.
    #[inline]
    pub fn normal() -> Self {
        Content::Normal
    }
}

/// Items for the `content` property.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
         ToComputedValue, ToCss)]
pub enum ContentItem<ImageUrl> {
    /// Literal string content.
    String(Box<str>),
    /// `counter(name, style)`.
    #[css(comma, function)]
    Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
    /// `counters(name, separator, style)`.
    #[css(comma, function)]
    Counters(
        CustomIdent,
        Box<str>,
        #[css(skip_if = "is_decimal")] CounterStyleType,
    ),
    /// `open-quote`.
    OpenQuote,
    /// `close-quote`.
    CloseQuote,
    /// `no-open-quote`.
    NoOpenQuote,
    /// `no-close-quote`.
    NoCloseQuote,
    /// `attr([namespace? `|`]? ident)`
    #[cfg(feature = "gecko")]
    Attr(Attr),
    /// `url(url)`
    Url(ImageUrl),
}
<|endoftext|>


<commit_before>use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::sync::mpsc::{Sender};
use std::collections::HashMap;
use consts::{WatchedEventType, ZkError, ZkState};
use proto::WatchedEvent;
use zookeeper::{ZkResult, ZooKeeper};
use zookeeper_ext::ZooKeeperExt;
use listeners::{Subscription};

pub type ChildData = Arc<Vec<u8>>;
pub type Data = HashMap<String, ChildData>;

#[derive(Debug)]
pub enum PathChildrenCacheEvent {
    Initialized,
    ConnectionSuspended,
    ConnectionLost,
    ConnectionReconnected,
    ChildRemoved(String),
    ChildAdded(String, ChildData),
    ChildUpdated(String, ChildData),
}

#[derive(Debug)]
pub enum RefreshMode {
    Standard,
    ForceGetDataAndStat,
}

#[derive(Debug)]
pub enum Operation {
    Shutdown,
    Refresh(RefreshMode),
    Event(PathChildrenCacheEvent),
    GetData(String /* path */),
}

pub struct PathChildrenCache {
    path: Arc<String>,
    zk: Arc<ZooKeeper>,
    data: Arc<Mutex<Data>>,
    worker_thread: Option<thread::JoinHandle<()>>,
    channel: Option<Sender<Operation>>,
    listener_subscription: Option<Subscription>,
}

impl PathChildrenCache {

    fn get_children(zk: Arc<ZooKeeper>, path: &str, data: Arc<Mutex<Data>>, ops_chan: Sender<Operation>) -> ZkResult<()> {
        let ops_chan1 = ops_chan.clone();

        let watcher = move |event: &WatchedEvent| {
            match event.event_type {
                WatchedEventType::NodeChildrenChanged => {
                    let _path = event.path.as_ref().expect("Path absent");

                    // Subscribe to new changes recursively
                    match ops_chan1.send(Operation::Refresh(RefreshMode::Standard)) {
                        Err(err) => {
                            warn!("error sending Refresh operation to ops channel: {:?}", err);
                        },
                        _ => {}
                    };
                },
                _ => error!("Unexpected: {:?}", event)
            };
        };

        let children = try!(zk.get_children_w(&path, watcher));

        let mut data_locked = data.lock().unwrap();

        for child in children.iter() {
            let child_path = join_path(path, child);

            if !data_locked.contains_key(&child_path) {

                let child_data = try!(Self::get_data(zk.clone(), &child_path, data.clone(), ops_chan.clone()));

                let child_data = Arc::new(child_data);

                data_locked.insert(child_path.clone(), child_data.clone());

                try!(ops_chan.send(Operation::Event(PathChildrenCacheEvent::ChildAdded(child_path, child_data))).map_err(|err| {
                    info!("error sending ChildAdded event: {:?}", err);
                    ZkError::APIError
                }));
            }
        }

        debug!("New data: {:?}", *data_locked);

        Ok(())
    }

    fn get_data(zk: Arc<ZooKeeper>, path: &str, data: Arc<Mutex<Data>>, ops_chan: Sender<Operation>) -> ZkResult<Vec<u8>> {
        let path1 = path.to_owned();

        let data_watcher = move |event: &WatchedEvent| {
            let mut data_locked = data.lock().unwrap();
            match event.event_type {
                WatchedEventType::NodeDeleted => {
                    data_locked.remove(&path1);

                    match ops_chan.send(Operation::Event(PathChildrenCacheEvent::ChildRemoved(path1.clone()))) {
                        Err(err) => {
                            warn!("error sending ChildRemoved event: {:?}", err);
                        },
                        _ => {}
                    }
                },
                WatchedEventType::NodeDataChanged => {
                    // Subscribe to new changes recursively
                    match ops_chan.send(Operation::GetData(path1)) {
                        Err(err) => {
                            warn!("error sending GetData to op channel: {:?}", err);
                        },
                        _ => {}
                    }
                },
                _ => error!("Unexpected: {:?}", event)
            };

            debug!("New data: {:?}", *data_locked);
        };

        zk.get_data_w(path, data_watcher).map(|stuff| { stuff.0 })
    }

    fn update_data(zk: Arc<ZooKeeper>, path: &str, data: Arc<Mutex<Data>>, ops_chan_tx: Sender<Operation>) -> ZkResult<()> {
        let mut data_locked = data.lock().unwrap();

        let path = path.to_owned();

        let result = Self::get_data(zk.clone(), &path, data.clone(), ops_chan_tx.clone());

        match result {
            Ok(child_data) => {
                info!("got data {:?}", child_data);

                let child_data = Arc::new(child_data);

                data_locked.insert(path.clone(), child_data.clone());

                ops_chan_tx.send(Operation::Event(PathChildrenCacheEvent::ChildUpdated(path, child_data))).map_err(|err| {
                    warn!("error sending ChildUpdated event: {:?}", err);
                    ZkError::APIError
                })
            },
            Err(err) => {
                warn!("error getting child data: {:?}", err);
                Err(ZkError::APIError)
            }
        }
    }

    pub fn new(zk: Arc<ZooKeeper>, path: &str) -> ZkResult<PathChildrenCache> {

        let data = Arc::new(Mutex::new(HashMap::new()));

        try!(zk.ensure_path(path));

        Ok(PathChildrenCache{
            path: Arc::new(path.to_string()),
            zk: zk,
            data: data,
            worker_thread: None,
            channel: None,
            listener_subscription: None,
        })
    }

    pub fn get_current_data(&self) -> Data {
        self.data.lock().unwrap().clone()
    }

    pub fn clear(&self) {
        self.data.lock().unwrap().clear()
    }

    fn handle_state_change(state: ZkState, ops_chan_tx: Sender<Operation>) -> bool {
        let mut done = false;

        info!("zk state change {:?}", state);
        match state {
            ZkState::Connected => {
                match ops_chan_tx.send(Operation::Refresh(RefreshMode::ForceGetDataAndStat)) {
                    Err(err) => {
                        warn!("error sending Refresh to op channel: {:?}", err);
                        done = true;
                    },
                    _ => {}
                }
            },
            _ => {
            }
        }

        done
    }

    fn handle_operation(op: Operation, zk: Arc<ZooKeeper>, path: Arc<String>, data: Arc<Mutex<Data>>, ops_chan_tx: Sender<Operation>) -> bool {
        let mut done = false;

        debug!("handling op {:?}", op);
        match op {
            Operation::Shutdown => {
                info!("shutting down worker thread");
                done = true;
            },
            Operation::Refresh(_mode) => {
                debug!("getting children");
                let result = Self::get_children(zk.clone(), &*path, data.clone(), ops_chan_tx.clone());
                info!("got children {:?}", result);
            },
            Operation::GetData(path) => {
                debug!("getting data");
                let result = Self::update_data(zk.clone(), &*path, data.clone(), ops_chan_tx.clone());
                match result {
                    Err(err) => {
                        warn!("error getting child data: {:?}", err);
                    },
                    _ => {}
                }
            },
            Operation::Event(event) => {
                info!("received event {:?}", event);
            },
        }

        done
    }

    pub fn start(&mut self) -> ZkResult<()> {
        let (ops_chan_tx, ops_chan_rx) = mpsc::channel();
        let (listener_chan_tx, listener_chan_rx) = mpsc::channel();

        let sub = self.zk.add_listener(listener_chan_tx.clone());
        self.listener_subscription = Some(sub);

        let zk = self.zk.clone();
        let path = self.path.clone();
        let data = self.data.clone();
        self.channel = Some(ops_chan_tx.clone());

        self.worker_thread = Some(thread::spawn(move || {
            let mut done = false;

            while !done {
                select! (
                    state_result = listener_chan_rx.recv() => {
                        match state_result {
                            Ok(state) => {
                                done = Self::handle_state_change(state, ops_chan_tx.clone());
                            },
                            Err(err) => {
                                info!("zk state chan err. shutting down. {:?}", err);
                                done = true;
                            }
                        }
                    },
                    op_result = ops_chan_rx.recv() => {
                        match op_result {
                            Ok(operation) => {
                                done = Self::handle_operation(operation, zk.clone(), path.clone(), data.clone(), ops_chan_tx.clone());
                            },
                            Err(err) => {
                                info!("error receiving from operations channel ({:?}). shutting down worker thread", err);
                                done = true;
                            }
                        }
                    });
            }
        }));

        self.offer_operation(Operation::Refresh(RefreshMode::ForceGetDataAndStat))
    }

    fn offer_operation(&self, op: Operation) -> ZkResult<()> {
        match self.channel {
            Some(ref chan) => {
                chan.send(op).map_err(|err| {
                    warn!("error submitting op to channel: {:?}", err);
                    ZkError::APIError
                })
            },
            None => Err(ZkError::APIError)
        }
    }

}

pub fn join_path(dir: &str, child: &str) -> String {
    let dir_bytes = dir.as_bytes();
    let mut result = dir.to_string();
    if dir_bytes[dir_bytes.len() - 1] != ('/' as u8) {
        result.push_str("/");
    }
    result.push_str(child);
    result
}
<commit_msg>notify event listeners<commit_after>use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver};
use std::collections::HashMap;
use consts::{WatchedEventType, ZkError, ZkState};
use proto::WatchedEvent;
use zookeeper::{ZkResult, ZooKeeper};
use zookeeper_ext::ZooKeeperExt;
use listeners::{ListenerSet, Subscription};

pub type ChildData = Arc<Vec<u8>>;
pub type Data = HashMap<String, ChildData>;

#[derive(Debug,Clone)]
pub enum PathChildrenCacheEvent {
    Initialized,
    ConnectionSuspended,
    ConnectionLost,
    ConnectionReconnected,
    ChildRemoved(String),
    ChildAdded(String, ChildData),
    ChildUpdated(String, ChildData),
}

#[derive(Debug)]
pub enum RefreshMode {
    Standard,
    ForceGetDataAndStat,
}

#[derive(Debug)]
pub enum Operation {
    Shutdown,
    Refresh(RefreshMode),
    Event(PathChildrenCacheEvent),
    GetData(String /* path */),
}

pub struct PathChildrenCache {
    path: Arc<String>,
    zk: Arc<ZooKeeper>,
    data: Arc<Mutex<Data>>,
    worker_thread: Option<thread::JoinHandle<()>>,
    channel: Option<Sender<Operation>>,
    listener_subscription: Option<Subscription>,
    event_listeners: ListenerSet<PathChildrenCacheEvent>,
}

impl PathChildrenCache {

    fn get_children(zk: Arc<ZooKeeper>, path: &str, data: Arc<Mutex<Data>>, ops_chan: Sender<Operation>) -> ZkResult<()> {
        let ops_chan1 = ops_chan.clone();

        let watcher = move |event: &WatchedEvent| {
            match event.event_type {
                WatchedEventType::NodeChildrenChanged => {
                    let _path = event.path.as_ref().expect("Path absent");

                    // Subscribe to new changes recursively
                    match ops_chan1.send(Operation::Refresh(RefreshMode::Standard)) {
                        Err(err) => {
                            warn!("error sending Refresh operation to ops channel: {:?}", err);
                        },
                        _ => {}
                    };
                },
                _ => error!("Unexpected: {:?}", event)
            };
        };

        let children = try!(zk.get_children_w(&path, watcher));

        let mut data_locked = data.lock().unwrap();

        for child in children.iter() {
            let child_path = join_path(path, child);

            if !data_locked.contains_key(&child_path) {

                let child_data = try!(Self::get_data(zk.clone(), &child_path, data.clone(), ops_chan.clone()));

                let child_data = Arc::new(child_data);

                data_locked.insert(child_path.clone(), child_data.clone());

                try!(ops_chan.send(Operation::Event(PathChildrenCacheEvent::ChildAdded(child_path, child_data))).map_err(|err| {
                    info!("error sending ChildAdded event: {:?}", err);
                    ZkError::APIError
                }));
            }
        }

        debug!("New data: {:?}", *data_locked);

        Ok(())
    }

    fn get_data(zk: Arc<ZooKeeper>, path: &str, data: Arc<Mutex<Data>>, ops_chan: Sender<Operation>) -> ZkResult<Vec<u8>> {
        let path1 = path.to_owned();

        let data_watcher = move |event: &WatchedEvent| {
            let mut data_locked = data.lock().unwrap();
            match event.event_type {
                WatchedEventType::NodeDeleted => {
                    data_locked.remove(&path1);

                    match ops_chan.send(Operation::Event(PathChildrenCacheEvent::ChildRemoved(path1.clone()))) {
                        Err(err) => {
                            warn!("error sending ChildRemoved event: {:?}", err);
                        },
                        _ => {}
                    }
                },
                WatchedEventType::NodeDataChanged => {
                    // Subscribe to new changes recursively
                    match ops_chan.send(Operation::GetData(path1)) {
                        Err(err) => {
                            warn!("error sending GetData to op channel: {:?}", err);
                        },
                        _ => {}
                    }
                },
                _ => error!("Unexpected: {:?}", event)
            };

            debug!("New data: {:?}", *data_locked);
        };

        zk.get_data_w(path, data_watcher).map(|stuff| { stuff.0 })
    }

    fn update_data(zk: Arc<ZooKeeper>, path: &str, data: Arc<Mutex<Data>>, ops_chan_tx: Sender<Operation>) -> ZkResult<()> {
        let mut data_locked = data.lock().unwrap();

        let path = path.to_owned();

        let result = Self::get_data(zk.clone(), &path, data.clone(), ops_chan_tx.clone());

        match result {
            Ok(child_data) => {
                info!("got data {:?}", child_data);

                let child_data = Arc::new(child_data);

                data_locked.insert(path.clone(), child_data.clone());

                ops_chan_tx.send(Operation::Event(PathChildrenCacheEvent::ChildUpdated(path, child_data))).map_err(|err| {
                    warn!("error sending ChildUpdated event: {:?}", err);
                    ZkError::APIError
                })
            },
            Err(err) => {
                warn!("error getting child data: {:?}", err);
                Err(ZkError::APIError)
            }
        }
    }

    pub fn new(zk: Arc<ZooKeeper>, path: &str) -> ZkResult<PathChildrenCache> {

        let data = Arc::new(Mutex::new(HashMap::new()));

        try!(zk.ensure_path(path));

        Ok(PathChildrenCache{
            path: Arc::new(path.to_string()),
            zk: zk,
            data: data,
            worker_thread: None,
            channel: None,
            listener_subscription: None,
            event_listeners: ListenerSet::new(),
        })
    }

    pub fn get_current_data(&self) -> Data {
        self.data.lock().unwrap().clone()
    }

    pub fn clear(&self) {
        self.data.lock().unwrap().clear()
    }

    fn handle_state_change(state: ZkState, ops_chan_tx: Sender<Operation>) -> bool {
        let mut done = false;

        info!("zk state change {:?}", state);
        match state {
            ZkState::Connected => {
                match ops_chan_tx.send(Operation::Refresh(RefreshMode::ForceGetDataAndStat)) {
                    Err(err) => {
                        warn!("error sending Refresh to op channel: {:?}", err);
                        done = true;
                    },
                    _ => {}
                }
            },
            _ => {
            }
        }

        done
    }

    fn handle_operation(op: Operation, zk: Arc<ZooKeeper>, path: Arc<String>, data: Arc<Mutex<Data>>, event_listeners: ListenerSet<PathChildrenCacheEvent>, ops_chan_tx: Sender<Operation>) -> bool {
        let mut done = false;

        debug!("handling op {:?}", op);
        match op {
            Operation::Shutdown => {
                info!("shutting down worker thread");
                done = true;
            },
            Operation::Refresh(_mode) => {
                debug!("getting children");
                let result = Self::get_children(zk.clone(), &*path, data.clone(), ops_chan_tx.clone());
                info!("got children {:?}", result);
            },
            Operation::GetData(path) => {
                debug!("getting data");
                let result = Self::update_data(zk.clone(), &*path, data.clone(), ops_chan_tx.clone());
                match result {
                    Err(err) => {
                        warn!("error getting child data: {:?}", err);
                    },
                    _ => {}
                }
            },
            Operation::Event(event) => {
                info!("received event {:?}", event);
                event_listeners.notify(&event);
            },
        }

        done
    }

    pub fn start(&mut self) -> ZkResult<()> {
        let (ops_chan_tx, ops_chan_rx) = mpsc::channel();
        let (listener_chan_tx, listener_chan_rx) = mpsc::channel();

        let sub = self.zk.add_listener(listener_chan_tx.clone());
        self.listener_subscription = Some(sub);

        let zk = self.zk.clone();
        let path = self.path.clone();
        let data = self.data.clone();
        let event_listeners = self.event_listeners.clone();
        self.channel = Some(ops_chan_tx.clone());

        self.worker_thread = Some(thread::spawn(move || {
            let mut done = false;

            while !done {
                select! (
                    state_result = listener_chan_rx.recv() => {
                        match state_result {
                            Ok(state) => {
                                done = Self::handle_state_change(state, ops_chan_tx.clone());
                            },
                            Err(err) => {
                                info!("zk state chan err. shutting down. {:?}", err);
                                done = true;
                            }
                        }
                    },
                    op_result = ops_chan_rx.recv() => {
                        match op_result {
                            Ok(operation) => {
                                done = Self::handle_operation(operation, zk.clone(), path.clone(), data.clone(), event_listeners.clone(), ops_chan_tx.clone());
                            },
                            Err(err) => {
                                info!("error receiving from operations channel ({:?}). shutting down worker thread", err);
                                done = true;
                            }
                        }
                    });
            }
        }));

        self.offer_operation(Operation::Refresh(RefreshMode::ForceGetDataAndStat))
    }

    pub fn add_listener(&self, subscriber: Sender<PathChildrenCacheEvent>) -> Subscription {
        self.event_listeners.subscribe(subscriber)
    }

    pub fn remove_listener(&self, sub: Subscription) -> () {
        self.event_listeners.unsubscribe(sub)
    }

    fn offer_operation(&self, op: Operation) -> ZkResult<()> {
        match self.channel {
            Some(ref chan) => {
                chan.send(op).map_err(|err| {
                    warn!("error submitting op to channel: {:?}", err);
                    ZkError::APIError
                })
            },
            None => Err(ZkError::APIError)
        }
    }

}

pub fn join_path(dir: &str, child: &str) -> String {
    let dir_bytes = dir.as_bytes();
    let mut result = dir.to_string();
    if dir_bytes[dir_bytes.len() - 1] != ('/' as u8) {
        result.push_str("/");
    }
    result.push_str(child);
    result
}
<|endoftext|>


<commit_before>use linalg::matrix::Matrix;
use linalg::vector::Vector;
use learning::SupModel;
use rand::{Rng, thread_rng};

/// Neural Network struct
///
/// Requires the number of neurons in each layer to be specified.
pub struct NeuralNet<'a> {
    layer_sizes: &'a [usize],
    weights: Vec<f64>,
}

impl<'a> NeuralNet<'a> {

	/// Create a new neural network with the specified layer sizes.
	///
	/// The layer sizes slice should include the input, hidden layers, and output layer sizes.
	///
	/// # Examples
	///
	/// ```
	/// use rusty_machine::learning::nnet::NeuralNet;
	///
	/// // Create a neural net with 4 layers, 3 neurons in each.
	/// let layers = &[3; 4];
	/// let mut a = NeuralNet::new(layers);
	/// ```
    pub fn new(layer_sizes: &[usize]) -> NeuralNet {
        NeuralNet {
            layer_sizes: layer_sizes,
            weights: NeuralNet::create_weights(layer_sizes),
        }
    }

    /// Creates initial weights for all neurons in the network.
    fn create_weights(layer_sizes: &[usize]) -> Vec<f64> {
        let total_layers = layer_sizes.len();

        let mut capacity = 0usize;

        for l in 0..total_layers - 1 {
            capacity += (layer_sizes[l]+1) * layer_sizes[l + 1]
        }

        let mut layers = Vec::with_capacity(capacity);

        for l in 0..total_layers - 1 {
            layers.append(&mut NeuralNet::initialize_weights(layer_sizes[l]+1, layer_sizes[l + 1]));
        }

        layers
    }

    /// Initializes the weights for a single layer in the network.
    fn initialize_weights(rows: usize, cols: usize) -> Vec<f64> {
        let mut weights = Vec::with_capacity(rows * cols);
        let eps_init = (6f64).sqrt() / ((rows + cols) as f64).sqrt();

        let mut rng = thread_rng();

        for _i in 0..rows * cols {
            let w = (rng.gen_range(0f64, 1f64) * 2f64 * eps_init) - eps_init;
            weights.push(w);
        }

        weights
    }

    /// Gets matrix of weights between specified layer and forward layer.
	///
	/// # Examples
	///
	/// ```
	/// use rusty_machine::learning::nnet::NeuralNet;
	///
	/// // Create a neural net with 4 layers, 3 neurons in each.
	/// let layers = &[3; 4];
	/// let mut a = NeuralNet::new(layers);
	///
	/// let w = &a.get_layer_weights(2);
	/// assert_eq!(w.rows(), 4);
	/// assert_eq!(w.cols(), 3);
	/// ```
    pub fn get_layer_weights(&self, idx: usize) -> Matrix<f64> {
    	assert!(idx < self.layer_sizes.len()-1);

    	let mut start = 0usize;

        for l in 0..idx {
            start += (self.layer_sizes[l]+1) * self.layer_sizes[l + 1]
        }

        let capacity = (self.layer_sizes[idx]+1) * self.layer_sizes[idx + 1];

        let mut weights = Vec::with_capacity((self.layer_sizes[idx]+1) * self.layer_sizes[idx + 1]);
        unsafe {
	        for i in start..start+capacity {
	        	weights.push(*self.weights.get_unchecked(i));
	        }
    	}

        Matrix::new(self.layer_sizes[idx]+1, self.layer_sizes[idx + 1], weights)

    }

    fn compute_cost_grad(&self, data: &Matrix<f64>, outputs: &Matrix<f64>) {
    	assert_eq!(data.cols(), self.layer_sizes[0]);

    	let mut forward_weights = Vec::with_capacity(self.layer_sizes.len()-1);
    	let mut activations = Vec::with_capacity(self.layer_sizes.len());

    	activations.push(data.clone());

    	// Forward propagation
    	{
	    	let mut a = self.get_layer_weights(0) * data;
	    	activations.push(a.clone());

	    	for l in 1..self.layer_sizes.len()-1 {
	    		let z = self.get_layer_weights(l) * a.clone();
	    		forward_weights.push(z.clone());

	    		activations.push(z.apply(&sigmoid));
	    	}

	    }

	    // Backward propagation
	    {
	    	let mut delta = &activations[self.layer_sizes.len()-1] - outputs;

	    }
    }

}

impl<'a> SupModel<Matrix<f64>, Vector<usize>> for NeuralNet<'a> {
    fn predict(&self, data: Matrix<f64>) -> Vector<usize> {
        unimplemented!()
    }

    fn train(&mut self, data: Matrix<f64>, values: Vector<usize>) {
        unimplemented!()
    }
}

/// Sigmoid function.
///
/// Returns 1 / ( 1 + e^-t).
fn sigmoid(t: f64) -> f64 {
	1.0 / (1.0 + (-t).exp() )
}

/// Gradient of sigmoid function.
///
/// Evaluates to (1 - e^-t) / (1 + e^-t)^2
fn sigmoid_grad(t: f64) -> f64 {
	sigmoid(t) * (1f64-sigmoid(t))
}<commit_msg>First pass at back propagation.<commit_after>use linalg::matrix::Matrix;
use linalg::vector::Vector;
use learning::SupModel;
use rand::{Rng, thread_rng};

/// Neural Network struct
///
/// Requires the number of neurons in each layer to be specified.
pub struct NeuralNet<'a> {
    layer_sizes: &'a [usize],
    weights: Vec<f64>,
}

impl<'a> NeuralNet<'a> {

	/// Create a new neural network with the specified layer sizes.
	///
	/// The layer sizes slice should include the input, hidden layers, and output layer sizes.
	///
	/// # Examples
	///
	/// ```
	/// use rusty_machine::learning::nnet::NeuralNet;
	///
	/// // Create a neural net with 4 layers, 3 neurons in each.
	/// let layers = &[3; 4];
	/// let mut a = NeuralNet::new(layers);
	/// ```
    pub fn new(layer_sizes: &[usize]) -> NeuralNet {
        NeuralNet {
            layer_sizes: layer_sizes,
            weights: NeuralNet::create_weights(layer_sizes),
        }
    }

    /// Creates initial weights for all neurons in the network.
    fn create_weights(layer_sizes: &[usize]) -> Vec<f64> {
        let total_layers = layer_sizes.len();

        let mut capacity = 0usize;

        for l in 0..total_layers - 1 {
            capacity += (layer_sizes[l]+1) * layer_sizes[l + 1]
        }

        let mut layers = Vec::with_capacity(capacity);

        for l in 0..total_layers - 1 {
            layers.append(&mut NeuralNet::initialize_weights(layer_sizes[l]+1, layer_sizes[l + 1]));
        }

        layers
    }

    /// Initializes the weights for a single layer in the network.
    fn initialize_weights(rows: usize, cols: usize) -> Vec<f64> {
        let mut weights = Vec::with_capacity(rows * cols);
        let eps_init = (6f64).sqrt() / ((rows + cols) as f64).sqrt();

        let mut rng = thread_rng();

        for _i in 0..rows * cols {
            let w = (rng.gen_range(0f64, 1f64) * 2f64 * eps_init) - eps_init;
            weights.push(w);
        }

        weights
    }

    /// Gets matrix of weights between specified layer and forward layer.
	///
	/// # Examples
	///
	/// ```
	/// use rusty_machine::learning::nnet::NeuralNet;
	///
	/// // Create a neural net with 4 layers, 3 neurons in each.
	/// let layers = &[3; 4];
	/// let mut a = NeuralNet::new(layers);
	///
	/// let w = &a.get_layer_weights(2);
	/// assert_eq!(w.rows(), 4);
	/// assert_eq!(w.cols(), 3);
	/// ```
    pub fn get_layer_weights(&self, idx: usize) -> Matrix<f64> {
    	assert!(idx < self.layer_sizes.len()-1);

    	let mut start = 0usize;

        for l in 0..idx {
            start += (self.layer_sizes[l]+1) * self.layer_sizes[l + 1]
        }

        let capacity = (self.layer_sizes[idx]+1) * self.layer_sizes[idx + 1];

        let mut weights = Vec::with_capacity((self.layer_sizes[idx]+1) * self.layer_sizes[idx + 1]);
        unsafe {
	        for i in start..start+capacity {
	        	weights.push(*self.weights.get_unchecked(i));
	        }
    	}

        Matrix::new(self.layer_sizes[idx]+1, self.layer_sizes[idx + 1], weights)

    }

    fn compute_cost_grad(&self, data: &Matrix<f64>, outputs: &Matrix<f64>) {
    	assert_eq!(data.cols(), self.layer_sizes[0]);

    	let mut forward_weights = Vec::with_capacity(self.layer_sizes.len()-1);
    	let mut activations = Vec::with_capacity(self.layer_sizes.len());

    	activations.push(data.clone());

    	// Forward propagation
    	{
	    	let mut a = self.get_layer_weights(0) * data;
	    	activations.push(a.clone());

	    	for l in 1..self.layer_sizes.len()-1 {
	    		let z = self.get_layer_weights(l) * a.clone();
	    		forward_weights.push(z.clone());

	    		activations.push(z.apply(&sigmoid));
	    	}

	    }

	    let mut deltas = Vec::with_capacity(self.layer_sizes.len()-1);
	    // Backward propagation
	    {
	    	let mut delta = &activations[self.layer_sizes.len()-1] - outputs;
	    	deltas.push(delta.clone());

	    	for l in (0..self.layer_sizes.len()-1).rev() {
	    		let g = forward_weights[l].clone().apply(&sigmoid_grad);
	    		delta = (self.get_layer_weights(l).transpose() * delta.clone()).elemul(&g);
	    		deltas.push(delta.clone());
	    	}
	    }

	    let mut grad = Vec::with_capacity(self.layer_sizes.len()-1);
	   	for l in 0..self.layer_sizes.len()-1 {
	   		// Probably need to remove the first column on the deltas.
	   		let g = deltas[l].clone() * activations[l].clone().transpose();
	   		grad.push(g / (data.rows() as f64))
	   	}
    }

}

impl<'a> SupModel<Matrix<f64>, Vector<usize>> for NeuralNet<'a> {
    fn predict(&self, data: Matrix<f64>) -> Vector<usize> {
        unimplemented!()
    }

    fn train(&mut self, data: Matrix<f64>, values: Vector<usize>) {
        unimplemented!()
    }
}

/// Sigmoid function.
///
/// Returns 1 / ( 1 + e^-t).
fn sigmoid(t: f64) -> f64 {
	1.0 / (1.0 + (-t).exp() )
}

/// Gradient of sigmoid function.
///
/// Evaluates to (1 - e^-t) / (1 + e^-t)^2
fn sigmoid_grad(t: f64) -> f64 {
	sigmoid(t) * (1f64-sigmoid(t))
}<|endoftext|>


<commit_before>//! Allow user to define custom functions to be called from libsass.
//! https://github.com/sass/libsass/wiki/Custom-Functions-internal

use sass_value::SassValue;
use sass_sys;
use std::ffi;
use std::mem;

/// Type of the function to be defined by the user.
pub type SassFunction = fn(& SassValue)->SassValue;

/// Dispatcher function called from libsass (C interface).
/// The cookie argument is setup in SassFunctionCallback::from_sig_fn.
/// Note that the SassFunctionCallback is not used directly in the dispatch.
extern "C" fn dispatch(arg1: *const sass_sys::Union_Sass_Value,
                       cookie: *mut ::libc::c_void) -> *mut sass_sys::Union_Sass_Value {
    let _fn :SassFunction = unsafe {mem::transmute(cookie)};
    let result = _fn(&SassValue::from_raw(arg1)).as_raw();
    match result {
        Some(raw) => raw,
        None => SassValue::sass_error("bad call").as_raw().unwrap()
    }

}

/// Associate the signature with the C callback.$one,$two
pub struct SassFunctionCallback {
    pub signature: String,
    pub c_callback:sass_sys::Sass_C_Function_Callback
}

impl SassFunctionCallback {
    pub fn from_sig_fn(signature:String,_fn:SassFunction) -> SassFunctionCallback {
        let c_sig = ffi::CString::new(signature.as_slice()).unwrap();
        let _fn_c = unsafe {sass_sys::sass_make_function(c_sig.as_ptr(), Some(dispatch), mem::transmute(_fn))};
        SassFunctionCallback {
            signature: signature,
            c_callback: _fn_c
        }
    }

}
<commit_msg>Derive debug in Sass Callbacks<commit_after>//! Allow user to define custom functions to be called from libsass.
//! https://github.com/sass/libsass/wiki/Custom-Functions-internal

use sass_value::SassValue;
use sass_sys;
use std::ffi;
use std::mem;

/// Type of the function to be defined by the user.
pub type SassFunction = fn(& SassValue)->SassValue;

/// Dispatcher function called from libsass (C interface).
/// The cookie argument is setup in SassFunctionCallback::from_sig_fn.
/// Note that the SassFunctionCallback is not used directly in the dispatch.
extern "C" fn dispatch(arg1: *const sass_sys::Union_Sass_Value,
                       cookie: *mut ::libc::c_void) -> *mut sass_sys::Union_Sass_Value {
    let _fn :SassFunction = unsafe {mem::transmute(cookie)};
    let result = _fn(&SassValue::from_raw(arg1)).as_raw();
    match result {
        Some(raw) => raw,
        None => SassValue::sass_error("bad call").as_raw().unwrap()
    }

}

/// Associate the signature with the C callback.$one,$two
#[derive(Debug)]
pub struct SassFunctionCallback {
    pub signature: String,
    pub c_callback:sass_sys::Sass_C_Function_Callback
}

impl SassFunctionCallback {
    pub fn from_sig_fn(signature:String,_fn:SassFunction) -> SassFunctionCallback {
        let c_sig = ffi::CString::new(signature.as_slice()).unwrap();
        let _fn_c = unsafe {sass_sys::sass_make_function(c_sig.as_ptr(), Some(dispatch), mem::transmute(_fn))};
        SassFunctionCallback {
            signature: signature,
            c_callback: _fn_c
        }
    }

}
<|endoftext|>


<commit_before>extern crate sdl;

use std::rand::Rng;

#[main]
pub fn main() {
    sdl::init([sdl::InitVideo]);
    sdl::wm::set_caption("rust-sdl demo - video", "rust-sdl");

    let mut rng = std::rand::task_rng();
    let screen = match sdl::video::set_video_mode(800, 600, 32, [sdl::video::HWSurface],
                                                                [sdl::video::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => fail!("failed to set video mode: {}", err)
    };

    // Note: You'll want to put this and the flip call inside the main loop
    // but we don't as to not startle epileptics
    for i in range(0, 10) {
        for j in range(0, 10) {
            screen.fill_rect(Some(sdl::Rect {
                x: (i as i16) * 800 / 10,
                y: (j as i16) * 600 / 10,
                w: 800 / 10,
                h: 600 / 10
            }), rng.gen::<sdl::video::Color>());
        }
    }

    screen.flip();

    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                sdl::event::QuitEvent => break 'main,
                sdl::event::NoEvent => break 'event,
                sdl::event::KeyEvent(k, _, _, _)
                    if k == sdl::event::EscapeKey
                        => break 'main,
                _ => {}
            }
        }
    }

    sdl::quit();
}
<commit_msg>Integer types are no longer inferred as int<commit_after>extern crate sdl;

use std::rand::Rng;

#[main]
pub fn main() {
    sdl::init([sdl::InitVideo]);
    sdl::wm::set_caption("rust-sdl demo - video", "rust-sdl");

    let mut rng = std::rand::task_rng();
    let screen = match sdl::video::set_video_mode(800, 600, 32, [sdl::video::HWSurface],
                                                                [sdl::video::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => fail!("failed to set video mode: {}", err)
    };

    // Note: You'll want to put this and the flip call inside the main loop
    // but we don't as to not startle epileptics
    for i in range(0u, 10) {
        for j in range(0u, 10) {
            screen.fill_rect(Some(sdl::Rect {
                x: (i as i16) * 800 / 10,
                y: (j as i16) * 600 / 10,
                w: 800 / 10,
                h: 600 / 10
            }), rng.gen::<sdl::video::Color>());
        }
    }

    screen.flip();

    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                sdl::event::QuitEvent => break 'main,
                sdl::event::NoEvent => break 'event,
                sdl::event::KeyEvent(k, _, _, _)
                    if k == sdl::event::EscapeKey
                        => break 'main,
                _ => {}
            }
        }
    }

    sdl::quit();
}
<|endoftext|>


<commit_before>use std::io::net::tcp::TcpStream;

use super::splice;
pub use splice::proto::{NegotiateError, ProtocolOutdated, AuthenticationFailed};
pub use splice::proto::StreamHeader;
pub use splice::proto::verify_header;

pub static MAGIC_BYTES: &'static [u8] = bytes!("SPLICEPROTO");
pub static PROTO_VER_MAJOR: i32 = 0;
pub static PROTO_VER_MINOR: i32 = 1;

#[deriving(Clone)]
pub enum AuthMethod {
    FileSecret(Path), // Unimplemented
}

pub fn negotiate(stream: &mut TcpStream, auth: &Option<AuthMethod>) -> Result<(), NegotiateError> {
    let StreamHeader {
        magic: magic,
        major_ver: major_ver,
        minor_ver: minor_ver,
    } = try!(verify_header(stream, StreamHeader {
        magic: Vec::from_slice(MAGIC_BYTES),
        major_ver: PROTO_VER_MAJOR,
        minor_ver: PROTO_VER_MINOR,
    }));
    if major_ver < PROTO_VER_MAJOR {
        return Err(ProtocolOutdated)
    }
    match *auth {
        Some(FileSecret(ref p)) => {
            stream.write_be_i32(splice::proto::FileSecret as i32);
            auth_file_secret(p)
        },
        None => {
            stream.write_be_i32(splice::proto::NoAuth as i32);
            Ok(())
        },
    }
}

// TODO: Implement file based secret authentication method
fn auth_file_secret(path: &Path) -> Result<(), NegotiateError> {
    Err(AuthenticationFailed)
}
<commit_msg>Correct definition of auth_file_secret<commit_after>use std::io::net::tcp::TcpStream;

use super::splice;
pub use splice::proto::{NegotiateError, ProtocolOutdated, AuthenticationFailed};
pub use splice::proto::StreamHeader;
pub use splice::proto::verify_header;

pub static MAGIC_BYTES: &'static [u8] = bytes!("SPLICEPROTO");
pub static PROTO_VER_MAJOR: i32 = 0;
pub static PROTO_VER_MINOR: i32 = 1;

#[deriving(Clone)]
pub enum AuthMethod {
    FileSecret(Path), // Unimplemented
}

pub fn negotiate(stream: &mut TcpStream, auth: &Option<AuthMethod>) -> Result<(), NegotiateError> {
    let StreamHeader {
        magic: magic,
        major_ver: major_ver,
        minor_ver: minor_ver,
    } = try!(verify_header(stream, StreamHeader {
        magic: Vec::from_slice(MAGIC_BYTES),
        major_ver: PROTO_VER_MAJOR,
        minor_ver: PROTO_VER_MINOR,
    }));
    if major_ver < PROTO_VER_MAJOR {
        return Err(ProtocolOutdated)
    }
    match *auth {
        Some(FileSecret(ref p)) => {
            stream.write_be_i32(splice::proto::FileSecret as i32);
            auth_file_secret(stream, p)
        },
        None => {
            stream.write_be_i32(splice::proto::NoAuth as i32);
            Ok(())
        },
    }
}

// TODO: Implement file based secret authentication method
fn auth_file_secret(stream: &mut TcpStream, path: &Path) -> Result<(), NegotiateError> {
    Err(AuthenticationFailed)
}
<|endoftext|>