<commit_before>// TODO: drop all panic!

use std::any::Any;
use std::any::TypeId;
use std::default::Default;
use std::fmt;
use std::io::Read;
use std::io::Write;

use clear::Clear;
use reflect::MessageDescriptor;
use reflect::EnumDescriptor;
use reflect::EnumValueDescriptor;
use unknown::UnknownFields;
use stream::WithCodedInputStream;
use stream::WithCodedOutputStream;
use stream::CodedInputStream;
use stream::CodedOutputStream;
use stream::with_coded_output_stream_to_bytes;
use error::ProtobufError;
use error::ProtobufResult;

pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
    // All generated Message types also implement MessageStatic.
    // However, rust doesn't allow these types to be extended by
    // Message.

    fn descriptor(&self) -> &'static MessageDescriptor;

    // all required fields set
    fn is_initialized(&self) -> bool;
    fn merge_from(&mut self, is: &mut CodedInputStream) -> ProtobufResult<()>;

    // sizes of this messages (and nested messages) must be cached
    // by calling `compute_size` prior to this call
    fn write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>;

    // compute and cache size of this message and all nested messages
    fn compute_size(&self) -> u32;

    // get size previously computed by `compute_size`
    fn get_cached_size(&self) -> u32;

    fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
        self.check_initialized()?;

        // cache sizes
        self.compute_size();
        self.write_to_with_cached_sizes(os)?;

        // TODO: assert we've written same number of bytes as computed

        Ok(())
    }

    fn write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
        let size = self.compute_size();
        os.write_raw_varint32(size)?;
        self.write_to_with_cached_sizes(os)?;

        // TODO: assert we've written same number of bytes as computed

        Ok(())
    }

    fn merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
        let mut is = CodedInputStream::from_bytes(bytes);
        self.merge_from(&mut is)
    }

    fn check_initialized(&self) -> ProtobufResult<()> {
        if !self.is_initialized() {
            Err((ProtobufError::message_not_initialized(self.descriptor().name())))
        } else {
            Ok(())
        }
    }

    fn write_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
        w.with_coded_output_stream(|os| {
            self.write_to(os)
        })
    }

    fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
        v.with_coded_output_stream(|os| {
            self.write_to(os)
        })
    }

    fn write_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
        self.check_initialized()?;

        let size = self.compute_size() as usize;
        let mut v = Vec::with_capacity(size);
        // skip zerofill
        unsafe { v.set_len(size); }
        {
            let mut os = CodedOutputStream::bytes(&mut v);
            self.write_to_with_cached_sizes(&mut os)?;
            os.check_eof();
        }
        Ok(v)
        }

    fn write_length_delimited_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
        w.with_coded_output_stream(|os| {
            self.write_length_delimited_to(os)
        })
    }

    fn write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
        with_coded_output_stream_to_bytes(|os| {
            self.write_length_delimited_to(os)
        })
    }

    fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
    fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;

    fn type_id(&self) -> TypeId {
        TypeId::of::<Self>()
    }

    fn as_any(&self) -> &Any;

    fn as_any_mut(&mut self) -> &mut Any {
        panic!()
    }

    fn into_any(self: Box<Self>) -> Box<Any> {
        panic!()
    }

    // Rust does not allow implementation of trait for trait:
    // impl<M : Message> fmt::Debug for M {
    // ...
    // }
}

// For some reason Rust doesn't allow conversion of &Foo to &Message it
// Message contains static functions. So static functions must be placed
// into separate place.
//
// See https://github.com/rust-lang/rust/commit/cd31e6ff for details.
pub trait MessageStatic : Message + Clone + Default + PartialEq /* + ProtobufValue */ {
    fn new() -> Self;

    // http://stackoverflow.com/q/20342436/15018
    fn descriptor_static(_: Option<Self>) -> &'static MessageDescriptor {
        panic!("descriptor_static is not implemented for message, \
            LITE_RUNTIME must be used");
    }
}

pub fn message_down_cast<'a, M : Message + 'a>(m: &'a Message) -> &'a M {
    m.as_any().downcast_ref::<M>().unwrap()
}

pub trait ProtobufEnum : Eq + Sized + Copy + 'static /* + ProtobufValue */ {
    fn value(&self) -> i32;

    fn from_i32(v: i32) -> Option<Self>;

    fn values() -> &'static [Self] {
        panic!();
    }

    fn descriptor(&self) -> &'static EnumValueDescriptor {
        self.enum_descriptor().value_by_number(self.value())
    }

    fn enum_descriptor(&self) -> &'static EnumDescriptor {
        ProtobufEnum::enum_descriptor_static(None::<Self>)
    }

    // http://stackoverflow.com/q/20342436/15018
    fn enum_descriptor_static(_: Option<Self>) -> &'static EnumDescriptor {
        panic!();
    }
}

pub fn parse_from<M : Message + MessageStatic>(is: &mut CodedInputStream) -> ProtobufResult<M> {
    let mut r: M = MessageStatic::new();
    r.merge_from(is)?;
    r.check_initialized()?;
    Ok(r)
}

pub fn parse_from_reader<M : Message + MessageStatic>(reader: &mut Read) -> ProtobufResult<M> {
    reader.with_coded_input_stream(|is| {
        parse_from::<M>(is)
    })
}

pub fn parse_from_bytes<M : Message + MessageStatic>(bytes: &[u8]) -> ProtobufResult<M> {
    bytes.with_coded_input_stream(|is| {
        parse_from::<M>(is)
    })
}

pub fn parse_length_delimited_from<M : Message + MessageStatic>(is: &mut CodedInputStream)
        -> ProtobufResult<M>
{
    is.read_message::<M>()
}

pub fn parse_length_delimited_from_reader<M : Message + MessageStatic>(r: &mut Read) -> ProtobufResult<M> {
    // TODO: wrong: we may read length first, and then read exact number of bytes needed
    r.with_coded_input_stream(|is| {
        is.read_message::<M>()
    })
}

pub fn parse_length_delimited_from_bytes<M : Message + MessageStatic>(bytes: &[u8]) -> ProtobufResult<M> {
    bytes.with_coded_input_stream(|is| {
        is.read_message::<M>()
    })
}

<commit_msg>fix style<commit_after>// TODO: drop all panic!

use std::any::Any;
use std::any::TypeId;
use std::default::Default;
use std::fmt;
use std::io::Read;
use std::io::Write;

use clear::Clear;
use reflect::MessageDescriptor;
use reflect::EnumDescriptor;
use reflect::EnumValueDescriptor;
use unknown::UnknownFields;
use stream::WithCodedInputStream;
use stream::WithCodedOutputStream;
use stream::CodedInputStream;
use stream::CodedOutputStream;
use stream::with_coded_output_stream_to_bytes;
use error::ProtobufError;
use error::ProtobufResult;

pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
    // All generated Message types also implement MessageStatic.
    // However, rust doesn't allow these types to be extended by
    // Message.

    fn descriptor(&self) -> &'static MessageDescriptor;

    // all required fields set
    fn is_initialized(&self) -> bool;
    fn merge_from(&mut self, is: &mut CodedInputStream) -> ProtobufResult<()>;

    // sizes of this messages (and nested messages) must be cached
    // by calling `compute_size` prior to this call
    fn write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>;

    // compute and cache size of this message and all nested messages
    fn compute_size(&self) -> u32;

    // get size previously computed by `compute_size`
    fn get_cached_size(&self) -> u32;

    fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
        self.check_initialized()?;

        // cache sizes
        self.compute_size();
        self.write_to_with_cached_sizes(os)?;

        // TODO: assert we've written same number of bytes as computed

        Ok(())
    }

    fn write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
        let size = self.compute_size();
        os.write_raw_varint32(size)?;
        self.write_to_with_cached_sizes(os)?;

        // TODO: assert we've written same number of bytes as computed

        Ok(())
    }

    fn merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
        let mut is = CodedInputStream::from_bytes(bytes);
        self.merge_from(&mut is)
    }

    fn check_initialized(&self) -> ProtobufResult<()> {
        if !self.is_initialized() {
            Err((ProtobufError::message_not_initialized(self.descriptor().name())))
        } else {
            Ok(())
        }
    }

    fn write_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
        w.with_coded_output_stream(|os| {
            self.write_to(os)
        })
    }

    fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
        v.with_coded_output_stream(|os| {
            self.write_to(os)
        })
    }

    fn write_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
        self.check_initialized()?;

        let size = self.compute_size() as usize;
        let mut v = Vec::with_capacity(size);
        // skip zerofill
        unsafe { v.set_len(size); }
        {
            let mut os = CodedOutputStream::bytes(&mut v);
            self.write_to_with_cached_sizes(&mut os)?;
            os.check_eof();
        }
        Ok(v)
    }

    fn write_length_delimited_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
        w.with_coded_output_stream(|os| {
            self.write_length_delimited_to(os)
        })
    }

    fn write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
        with_coded_output_stream_to_bytes(|os| {
            self.write_length_delimited_to(os)
        })
    }

    fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
    fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;

    fn type_id(&self) -> TypeId {
        TypeId::of::<Self>()
    }

    fn as_any(&self) -> &Any;

    fn as_any_mut(&mut self) -> &mut Any {
        panic!()
    }

    fn into_any(self: Box<Self>) -> Box<Any> {
        panic!()
    }

    // Rust does not allow implementation of trait for trait:
    // impl<M : Message> fmt::Debug for M {
    // ...
    // }
}

// For some reason Rust doesn't allow conversion of &Foo to &Message it
// Message contains static functions. So static functions must be placed
// into separate place.
//
// See https://github.com/rust-lang/rust/commit/cd31e6ff for details.
pub trait MessageStatic : Message + Clone + Default + PartialEq /* + ProtobufValue */ {
    fn new() -> Self;

    // http://stackoverflow.com/q/20342436/15018
    fn descriptor_static(_: Option<Self>) -> &'static MessageDescriptor {
        panic!("descriptor_static is not implemented for message, \
            LITE_RUNTIME must be used");
    }
}

pub fn message_down_cast<'a, M : Message + 'a>(m: &'a Message) -> &'a M {
    m.as_any().downcast_ref::<M>().unwrap()
}

pub trait ProtobufEnum : Eq + Sized + Copy + 'static /* + ProtobufValue */ {
    fn value(&self) -> i32;

    fn from_i32(v: i32) -> Option<Self>;

    fn values() -> &'static [Self] {
        panic!();
    }

    fn descriptor(&self) -> &'static EnumValueDescriptor {
        self.enum_descriptor().value_by_number(self.value())
    }

    fn enum_descriptor(&self) -> &'static EnumDescriptor {
        ProtobufEnum::enum_descriptor_static(None::<Self>)
    }

    // http://stackoverflow.com/q/20342436/15018
    fn enum_descriptor_static(_: Option<Self>) -> &'static EnumDescriptor {
        panic!();
    }
}

pub fn parse_from<M : Message + MessageStatic>(is: &mut CodedInputStream) -> ProtobufResult<M> {
    let mut r: M = MessageStatic::new();
    r.merge_from(is)?;
    r.check_initialized()?;
    Ok(r)
}

pub fn parse_from_reader<M : Message + MessageStatic>(reader: &mut Read) -> ProtobufResult<M> {
    reader.with_coded_input_stream(|is| {
        parse_from::<M>(is)
    })
}

pub fn parse_from_bytes<M : Message + MessageStatic>(bytes: &[u8]) -> ProtobufResult<M> {
    bytes.with_coded_input_stream(|is| {
        parse_from::<M>(is)
    })
}

pub fn parse_length_delimited_from<M : Message + MessageStatic>(is: &mut CodedInputStream)
        -> ProtobufResult<M>
{
    is.read_message::<M>()
}

pub fn parse_length_delimited_from_reader<M : Message + MessageStatic>(r: &mut Read) -> ProtobufResult<M> {
    // TODO: wrong: we may read length first, and then read exact number of bytes needed
    r.with_coded_input_stream(|is| {
        is.read_message::<M>()
    })
}

pub fn parse_length_delimited_from_bytes<M : Message + MessageStatic>(bytes: &[u8]) -> ProtobufResult<M> {
    bytes.with_coded_input_stream(|is| {
        is.read_message::<M>()
    })
}

<|endoftext|>


<commit_before>/* Module: math */

export consts;
export min, max;

export f32, f64;

// Currently this module supports from -lmath
// C95 - frexp - ldexp - fmod - modf + log2 + log1p

export
    acos, asin, atan, atan2, ceil, cos, cosh, exp, abs, floor,
    ln, ln1p, log10, log2, pow, sin, sinh, sqrt, tan, tanh;

// These two must match in width according to architecture

import ctypes::c_float;
import c_float = f64;

#[link_name = "m"]
#[abi = "cdecl"]
native mod f64 {

    // Alpabetically sorted by link_name

    fn acos(n: f64) -> f64;
    fn asin(n: f64) -> f64;
    fn atan(n: f64) -> f64;
    fn atan2(a: f64, b: f64) -> f64;
    fn ceil(n: f64) -> f64;
    fn cos(n: f64) -> f64;
    fn cosh(n: f64) -> f64;
    fn exp(n: f64) -> f64;
    #[link_name="fabs"] fn abs(n: f64) -> f64;
    fn floor(n: f64) -> f64;
    #[link_name="log"] fn ln(n: f64) -> f64;
    #[link_name="log1p"] fn ln1p(n: f64) -> f64;
    fn log10(n: f64) -> f64;
    fn log2(n: f64) -> f64;
    fn pow(n: f64, e: f64) -> f64;
    fn sin(n: f64) -> f64;
    fn sinh(n: f64) -> f64;
    fn sqrt(n: f64) -> f64;
    fn tan(n: f64) -> f64;
    fn tanh(n: f64) -> f64;
}

#[link_name = "m"]
#[abi = "cdecl"]
native mod f32 {

    // Alpabetically sorted by link_name

    #[link_name="acosf"] fn acos(n: f32) -> f32;
    #[link_name="asinf"] fn asin(n: f32) -> f32;
    #[link_name="atanf"] fn atan(n: f32) -> f32;
    #[link_name="atan2f"] fn atan2(a: f32, b: f32) -> f32;
    #[link_name="ceilf"] fn ceil(n: f32) -> f32;
    #[link_name="cosf"] fn cos(n: f32) -> f32;
    #[link_name="coshf"] fn cosh(n: f32) -> f32;
    #[link_name="expf"] fn exp(n: f32) -> f32;
    #[link_name="fabsf"] fn abs(n: f32) -> f32;
    #[link_name="floorf"] fn floor(n: f32) -> f32;
    #[link_name="powf"] fn pow(n: f32, e: f32) -> f32;
    #[link_name="sinf"] fn sin(n: f32) -> f32;
    #[link_name="sinhf"] fn sinh(n: f32) -> f32;
    #[link_name="sqrtf"] fn sqrt(n: f32) -> f32;
    #[link_name="tanf"] fn tan(n: f32) -> f32;
    #[link_name="tanhf"] fn tanh(n: f32) -> f32;
    #[link_name="logf"] fn ln(n: f32) -> f32;
    #[link_name="log1p"] fn ln1p(n: f64) -> f64;
    #[link_name="log2f"] fn log2(n: f32) -> f32;
    #[link_name="log10f"] fn log10(n: f32) -> f32;
}

mod consts {
    /*
    Const: pi

    Archimedes' constant
    */
    const pi: float = 3.14159265358979323846264338327950288;

    /*
    Const: frac_pi_2

    pi/2.0
    */
    const frac_pi_2: float = 1.57079632679489661923132169163975144;

    /*
    Const: frac_pi_4

    pi/4.0
    */
    const frac_pi_4: float = 0.785398163397448309615660845819875721;

    /*
    Const: frac_1_pi

    1.0/pi
    */
    const frac_1_pi: float = 0.318309886183790671537767526745028724;

    /*
    Const: frac_2_pi

    2.0/pi
    */
    const frac_2_pi: float = 0.636619772367581343075535053490057448;

    /*
    Const: frac_2_sqrtpi

    2.0/sqrt(pi)
    */
    const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;

    /*
    Const: sqrt2

    sqrt(2.0)
    */
    const sqrt2: float = 1.41421356237309504880168872420969808;

    /*
    Const: frac_1_sqrt2

    1.0/sqrt(2.0)
    */
    const frac_1_sqrt2: float = 0.707106781186547524400844362104849039;

    /*
    Const: e

    Euler's number
    */
    const e: float = 2.71828182845904523536028747135266250;

    /*
    Const: log2_e

    log2(e)
    */
    const log2_e: float = 1.44269504088896340735992468100189214;

    /*
    Const: log10_e

    log10(e)
    */
    const log10_e: float = 0.434294481903251827651128918916605082;

    /*
    Const: ln_2

    ln(2.0)
    */
    const ln_2: float = 0.693147180559945309417232121458176568;

    /*
    Const: ln_10

    ln(10.0)
    */
    const ln_10: float = 2.30258509299404568401799145468436421;

}

/*
Function: min

Returns the minimum of two values
*/
pure fn min<copy T>(x: T, y: T) -> T { x < y ? x : y }

/*
Function: max

Returns the maximum of two values
*/
pure fn max<copy T>(x: T, y: T) -> T { x < y ? y : x }

/*
Function: acos

Returns the arccosine of an angle (measured in rad)
*/
pure fn acos(x: float) -> float
    { unsafe { c_float::acos(x as c_float) as float } }

/*
Function: asin

Returns the arcsine of an angle (measured in rad)
*/
pure fn asin(x: float) -> float
    { unsafe { c_float::asin(x as c_float) as float } }

/*
Function: atan

Returns the arctangents of an angle (measured in rad)
*/
pure fn atan(x: float) -> float
    { unsafe { c_float::atan(x as c_float) as float } }

/*
Function: atan2

Returns the arctangent of an angle (measured in rad)
*/
pure fn atan2(y: float, x: float) -> float
    { unsafe { c_float::atan2(y as c_float, x as c_float) as float } }

/*
Function: ceil

Returns:

The smallest integral value less than or equal to `n`
*/
pure fn ceil(n: float) -> float
    { unsafe { c_float::ceil(n as c_float) as float } }

/*
Function: cos

Returns the cosine of an angle `x` (measured in rad)
*/
pure fn cos(x: float) -> float
    { unsafe { c_float::cos(x as c_float) as float } }

/*
Function: cosh

Returns the hyperbolic cosine of `x`

*/
pure fn cosh(x: float) -> float
    { unsafe { c_float::cosh(x as c_float) as float } }

/*
Function: exp

Returns:

e to the power of `n*
*/
pure fn exp(n: float) -> float
    { unsafe { c_float::exp(n as c_float) as float } }

/*
Function: abs

Returns:

The absolute value of  `n`

*/
pure fn abs(n: float) -> float
    { unsafe { c_float::abs(n as c_float) as float } }

/*
Function: floor

Returns:

The largest integral value less than or equal to `n`
*/
pure fn floor(n: float) -> float
    { unsafe { c_float::floor(n as c_float) as float } }

/*
Function: ln

Returns the natural logaritm of `n`
*/
pure fn ln(n: float) -> float
    { unsafe { c_float::ln(n as c_float) as float } }

/*
Function: ln1p

Returns the natural logarithm of `1+n` accurately,
even for very small values of `n`
*/
pure fn ln1p(n: float) -> float
    { unsafe { c_float::ln1p(n as c_float) as float } }

/*
Function: log10

Returns the logarithm to base 10 of `n`
*/
pure fn log10(n: float) -> float
    { unsafe { c_float::log10(n as c_float) as float } }

/*
Function: log2

Returns the logarithm to base 2 of `n`
*/
pure fn log2(n: float) -> float
    { unsafe { c_float::log2(n as c_float) as float } }

/*
Function: pow
*/
pure fn pow(v: float, e: float) -> float
    { unsafe { c_float::pow(v as c_float, e as c_float) as float } }

/*
Function: sin

Returns the sine of an angle `x` (measured in rad)
*/
pure fn sin(x: float) -> float
    { unsafe { c_float::sin(x as c_float) as float } }

/*
Function: sinh

Returns the hyperbolic sine of an angle `x` (measured in rad)
*/
pure fn sinh(x: float) -> float
    { unsafe { c_float::sinh(x as c_float) as float } }

/*
Function: sqrt

Returns the square root of `x`
*/
pure fn sqrt(x: float) -> float
    { unsafe { c_float::sqrt(x as c_float) as float } }

/*
Function: tan

Returns the tangent of an angle `x` (measured in rad)

*/
pure fn tan(x: float) -> float
    { unsafe { c_float::tan(x as c_float) as float } }

/*
Function: tanh

Returns the hyperbolic tangent of an angle `x` (measured in rad)

*/
pure fn tanh(x: float) -> float
    { unsafe { c_float::tanh(x as c_float) as float } }

<commit_msg>std: math now declares libm dependencies as pure<commit_after>/* Module: math */

export consts;
export min, max;

export f32, f64;

// Currently this module supports from -lmath
// C95 - frexp - ldexp - fmod - modf + log2 + log1p

export
    acos, asin, atan, atan2, ceil, cos, cosh, exp, abs, floor,
    ln, ln1p, log10, log2, pow, sin, sinh, sqrt, tan, tanh;

// These two must match in width according to architecture

import ctypes::c_float;
import c_float = f64;

#[link_name = "m"]
#[abi = "cdecl"]
native mod f64 {

    // Alpabetically sorted by link_name

    pure fn acos(n: f64) -> f64;
    pure fn asin(n: f64) -> f64;
    pure fn atan(n: f64) -> f64;
    pure fn atan2(a: f64, b: f64) -> f64;
    pure fn ceil(n: f64) -> f64;
    pure fn cos(n: f64) -> f64;
    pure fn cosh(n: f64) -> f64;
    pure fn exp(n: f64) -> f64;
    #[link_name="fabs"] pure fn abs(n: f64) -> f64;
    pure fn floor(n: f64) -> f64;
    #[link_name="log"] pure fn ln(n: f64) -> f64;
    #[link_name="log1p"] pure fn ln1p(n: f64) -> f64;
    pure fn log10(n: f64) -> f64;
    pure fn log2(n: f64) -> f64;
    pure fn pow(n: f64, e: f64) -> f64;
    pure fn sin(n: f64) -> f64;
    pure fn sinh(n: f64) -> f64;
    pure fn sqrt(n: f64) -> f64;
    pure fn tan(n: f64) -> f64;
    pure fn tanh(n: f64) -> f64;
}

#[link_name = "m"]
#[abi = "cdecl"]
native mod f32 {

    // Alpabetically sorted by link_name

    #[link_name="acosf"] pure fn acos(n: f32) -> f32;
    #[link_name="asinf"] pure fn asin(n: f32) -> f32;
    #[link_name="atanf"] pure fn atan(n: f32) -> f32;
    #[link_name="atan2f"] pure fn atan2(a: f32, b: f32) -> f32;
    #[link_name="ceilf"] pure fn ceil(n: f32) -> f32;
    #[link_name="cosf"] pure fn cos(n: f32) -> f32;
    #[link_name="coshf"] pure fn cosh(n: f32) -> f32;
    #[link_name="expf"] pure fn exp(n: f32) -> f32;
    #[link_name="fabsf"] pure fn abs(n: f32) -> f32;
    #[link_name="floorf"] pure fn floor(n: f32) -> f32;
    #[link_name="powf"] pure fn pow(n: f32, e: f32) -> f32;
    #[link_name="sinf"] pure fn sin(n: f32) -> f32;
    #[link_name="sinhf"] pure fn sinh(n: f32) -> f32;
    #[link_name="sqrtf"] pure fn sqrt(n: f32) -> f32;
    #[link_name="tanf"] pure fn tan(n: f32) -> f32;
    #[link_name="tanhf"] pure fn tanh(n: f32) -> f32;
    #[link_name="logf"] pure fn ln(n: f32) -> f32;
    #[link_name="log1p"] pure fn ln1p(n: f64) -> f64;
    #[link_name="log2f"] pure fn log2(n: f32) -> f32;
    #[link_name="log10f"] pure fn log10(n: f32) -> f32;
}

mod consts {
    /*
    Const: pi

    Archimedes' constant
    */
    const pi: float = 3.14159265358979323846264338327950288;

    /*
    Const: frac_pi_2

    pi/2.0
    */
    const frac_pi_2: float = 1.57079632679489661923132169163975144;

    /*
    Const: frac_pi_4

    pi/4.0
    */
    const frac_pi_4: float = 0.785398163397448309615660845819875721;

    /*
    Const: frac_1_pi

    1.0/pi
    */
    const frac_1_pi: float = 0.318309886183790671537767526745028724;

    /*
    Const: frac_2_pi

    2.0/pi
    */
    const frac_2_pi: float = 0.636619772367581343075535053490057448;

    /*
    Const: frac_2_sqrtpi

    2.0/sqrt(pi)
    */
    const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;

    /*
    Const: sqrt2

    sqrt(2.0)
    */
    const sqrt2: float = 1.41421356237309504880168872420969808;

    /*
    Const: frac_1_sqrt2

    1.0/sqrt(2.0)
    */
    const frac_1_sqrt2: float = 0.707106781186547524400844362104849039;

    /*
    Const: e

    Euler's number
    */
    const e: float = 2.71828182845904523536028747135266250;

    /*
    Const: log2_e

    log2(e)
    */
    const log2_e: float = 1.44269504088896340735992468100189214;

    /*
    Const: log10_e

    log10(e)
    */
    const log10_e: float = 0.434294481903251827651128918916605082;

    /*
    Const: ln_2

    ln(2.0)
    */
    const ln_2: float = 0.693147180559945309417232121458176568;

    /*
    Const: ln_10

    ln(10.0)
    */
    const ln_10: float = 2.30258509299404568401799145468436421;

}

/*
Function: min

Returns the minimum of two values
*/
pure fn min<copy T>(x: T, y: T) -> T { x < y ? x : y }

/*
Function: max

Returns the maximum of two values
*/
pure fn max<copy T>(x: T, y: T) -> T { x < y ? y : x }

/*
Function: acos

Returns the arccosine of an angle (measured in rad)
*/
pure fn acos(x: float) -> float
    { c_float::acos(x as c_float) as float }

/*
Function: asin

Returns the arcsine of an angle (measured in rad)
*/
pure fn asin(x: float) -> float
    { c_float::asin(x as c_float) as float }

/*
Function: atan

Returns the arctangents of an angle (measured in rad)
*/
pure fn atan(x: float) -> float
    { c_float::atan(x as c_float) as float }

/*
Function: atan2

Returns the arctangent of an angle (measured in rad)
*/
pure fn atan2(y: float, x: float) -> float
    { c_float::atan2(y as c_float, x as c_float) as float }

/*
Function: ceil

Returns:

The smallest integral value less than or equal to `n`
*/
pure fn ceil(n: float) -> float
    { c_float::ceil(n as c_float) as float }

/*
Function: cos

Returns the cosine of an angle `x` (measured in rad)
*/
pure fn cos(x: float) -> float
    { c_float::cos(x as c_float) as float }

/*
Function: cosh

Returns the hyperbolic cosine of `x`

*/
pure fn cosh(x: float) -> float
    { c_float::cosh(x as c_float) as float }

/*
Function: exp

Returns:

e to the power of `n*
*/
pure fn exp(n: float) -> float
    { c_float::exp(n as c_float) as float }

/*
Function: abs

Returns:

The absolute value of  `n`

*/
pure fn abs(n: float) -> float
    { c_float::abs(n as c_float) as float }

/*
Function: floor

Returns:

The largest integral value less than or equal to `n`
*/
pure fn floor(n: float) -> float
    { c_float::floor(n as c_float) as float }

/*
Function: ln

Returns the natural logaritm of `n`
*/
pure fn ln(n: float) -> float
    { c_float::ln(n as c_float) as float }

/*
Function: ln1p

Returns the natural logarithm of `1+n` accurately,
even for very small values of `n`
*/
pure fn ln1p(n: float) -> float
    { c_float::ln1p(n as c_float) as float }

/*
Function: log10

Returns the logarithm to base 10 of `n`
*/
pure fn log10(n: float) -> float
    { c_float::log10(n as c_float) as float }

/*
Function: log2

Returns the logarithm to base 2 of `n`
*/
pure fn log2(n: float) -> float
    { c_float::log2(n as c_float) as float }

/*
Function: pow
*/
pure fn pow(v: float, e: float) -> float
    { c_float::pow(v as c_float, e as c_float) as float }

/*
Function: sin

Returns the sine of an angle `x` (measured in rad)
*/
pure fn sin(x: float) -> float
    { c_float::sin(x as c_float) as float }

/*
Function: sinh

Returns the hyperbolic sine of an angle `x` (measured in rad)
*/
pure fn sinh(x: float) -> float
    { c_float::sinh(x as c_float) as float }

/*
Function: sqrt

Returns the square root of `x`
*/
pure fn sqrt(x: float) -> float
    { c_float::sqrt(x as c_float) as float }

/*
Function: tan

Returns the tangent of an angle `x` (measured in rad)

*/
pure fn tan(x: float) -> float
    { c_float::tan(x as c_float) as float }

/*
Function: tanh

Returns the hyperbolic tangent of an angle `x` (measured in rad)

*/
pure fn tanh(x: float) -> float
    { c_float::tanh(x as c_float) as float }

<|endoftext|>


<commit_before>use std::num::{Zero, One};
use vec::Vec3;
use mat::{Mat1, Mat2, Mat3, Inv, Row};

// some specializations:
impl<N: Num + Clone>
Inv for Mat1<N> {
    #[inline]
    fn inverse(&self) -> Option<Mat1<N>> {
        let mut res : Mat1<N> = self.clone();

        if res.inplace_inverse() {
            Some(res)
        }
        else {
            None
        }
    }

    #[inline]
    fn inplace_inverse(&mut self) -> bool {
        if self.m11.is_zero() {
            false
        }
        else {
            let _1: N = One::one();
            self.m11 = _1 / self.m11;
            true
        }
    }
}

impl<N: Num + Clone>
Inv for Mat2<N> {
    #[inline]
    fn inverse(&self) -> Option<Mat2<N>> {
        let mut res : Mat2<N> = self.clone();

        if res.inplace_inverse() {
            Some(res)
        }
        else {
            None
        }
    }

    #[inline]
    fn inplace_inverse(&mut self) -> bool {
        let det = self.m11 * self.m22 - self.m21 * self.m12;

        if det.is_zero() {
            false
        }
        else {
            *self = Mat2::new(
                self.m22 / det , -self.m12 / det,
                -self.m21 / det, self.m11 / det);

            true
        }
    }
}

impl<N: Num + Clone>
Inv for Mat3<N> {
    #[inline]
    fn inverse(&self) -> Option<Mat3<N>> {
        let mut res = self.clone();

        if res.inplace_inverse() {
            Some(res)
        }
        else {
            None
        }
    }

    #[inline]
    fn inplace_inverse(&mut self) -> bool {
        let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
        let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
        let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;

        let det = self.m11 * minor_m12_m23
                  - self.m12 * minor_m11_m23
                  + self.m13 * minor_m11_m22;

        if det.is_zero() {
            false
        }
        else {
            *self = Mat3::new(
                (minor_m12_m23 / det),
                ((self.m13 * self.m32 - self.m33 * self.m12) / det),
                ((self.m12 * self.m23 - self.m22 * self.m13) / det),

                (-minor_m11_m23 / det),
                ((self.m11 * self.m33 - self.m31 * self.m13) / det),
                ((self.m13 * self.m21 - self.m23 * self.m11) / det),

                (minor_m11_m22  / det),
                ((self.m12 * self.m31 - self.m32 * self.m11) / det),
                ((self.m11 * self.m22 - self.m21 * self.m12) / det)
                );

            true
        }
    }
}

impl<N: Clone> Row<Vec3<N>> for Mat3<N> {
    #[inline]
    fn row(&self, i: uint) -> Vec3<N> {
        match i {
            0 => Vec3::new(self.m11.clone(), self.m12.clone(), self.m13.clone()),
            1 => Vec3::new(self.m21.clone(), self.m22.clone(), self.m23.clone()),
            2 => Vec3::new(self.m31.clone(), self.m32.clone(), self.m33.clone()),
            _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.")
        }
    }

    #[inline]
    fn set_row(&mut self, i: uint, r: Vec3<N>) {
        match i {
            0 => {
                self.m11 = r.x.clone();
                self.m12 = r.y.clone();
                self.m13 = r.z;
            },
            1 => {
                self.m21 = r.x.clone();
                self.m22 = r.y.clone();
                self.m23 = r.z;
            },
            2 => {
                self.m31 = r.x.clone();
                self.m32 = r.y.clone();
                self.m33 = r.z;
            },
            _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.")

        }
    }
}
<commit_msg>Add function to create a projection matrix.<commit_after>use std::num::{Zero, One};
use vec::Vec3;
use mat::{Mat1, Mat2, Mat3, Inv, Row};
use mat;

// some specializations:
impl<N: Num + Clone>
Inv for Mat1<N> {
    #[inline]
    fn inverse(&self) -> Option<Mat1<N>> {
        let mut res : Mat1<N> = self.clone();

        if res.inplace_inverse() {
            Some(res)
        }
        else {
            None
        }
    }

    #[inline]
    fn inplace_inverse(&mut self) -> bool {
        if self.m11.is_zero() {
            false
        }
        else {
            let _1: N = One::one();
            self.m11 = _1 / self.m11;
            true
        }
    }
}

impl<N: Num + Clone>
Inv for Mat2<N> {
    #[inline]
    fn inverse(&self) -> Option<Mat2<N>> {
        let mut res : Mat2<N> = self.clone();

        if res.inplace_inverse() {
            Some(res)
        }
        else {
            None
        }
    }

    #[inline]
    fn inplace_inverse(&mut self) -> bool {
        let det = self.m11 * self.m22 - self.m21 * self.m12;

        if det.is_zero() {
            false
        }
        else {
            *self = Mat2::new(
                self.m22 / det , -self.m12 / det,
                -self.m21 / det, self.m11 / det);

            true
        }
    }
}

impl<N: Num + Clone>
Inv for Mat3<N> {
    #[inline]
    fn inverse(&self) -> Option<Mat3<N>> {
        let mut res = self.clone();

        if res.inplace_inverse() {
            Some(res)
        }
        else {
            None
        }
    }

    #[inline]
    fn inplace_inverse(&mut self) -> bool {
        let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
        let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
        let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;

        let det = self.m11 * minor_m12_m23
                  - self.m12 * minor_m11_m23
                  + self.m13 * minor_m11_m22;

        if det.is_zero() {
            false
        }
        else {
            *self = Mat3::new(
                (minor_m12_m23 / det),
                ((self.m13 * self.m32 - self.m33 * self.m12) / det),
                ((self.m12 * self.m23 - self.m22 * self.m13) / det),

                (-minor_m11_m23 / det),
                ((self.m11 * self.m33 - self.m31 * self.m13) / det),
                ((self.m13 * self.m21 - self.m23 * self.m11) / det),

                (minor_m11_m22  / det),
                ((self.m12 * self.m31 - self.m32 * self.m11) / det),
                ((self.m11 * self.m22 - self.m21 * self.m12) / det)
                );

            true
        }
    }
}

impl<N: Clone> Row<Vec3<N>> for Mat3<N> {
    #[inline]
    fn row(&self, i: uint) -> Vec3<N> {
        match i {
            0 => Vec3::new(self.m11.clone(), self.m12.clone(), self.m13.clone()),
            1 => Vec3::new(self.m21.clone(), self.m22.clone(), self.m23.clone()),
            2 => Vec3::new(self.m31.clone(), self.m32.clone(), self.m33.clone()),
            _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.")
        }
    }

    #[inline]
    fn set_row(&mut self, i: uint, r: Vec3<N>) {
        match i {
            0 => {
                self.m11 = r.x.clone();
                self.m12 = r.y.clone();
                self.m13 = r.z;
            },
            1 => {
                self.m21 = r.x.clone();
                self.m22 = r.y.clone();
                self.m23 = r.z;
            },
            2 => {
                self.m31 = r.x.clone();
                self.m32 = r.y.clone();
                self.m33 = r.z;
            },
            _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.")

        }
    }
}

// FIXME: move this to another file?
impl<N: Real + NumCast + Zero + One> mat::Mat4<N> {
    /// Computes a projection matrix given the frustrum near plane width, height, the field of
    /// view, and the distance to the clipping planes (`znear` and `zfar`).
    pub fn projection(width: N, height: N, fov: N, znear: N, zfar: N) -> mat::Mat4<N> {
        let aspect = width / height;

        let _1: N = One::one();
        let sy    = _1 / (fov * NumCast::from(0.5)).tan();
        let sx    = -sy / aspect;
        let sz    = -(zfar + znear) / (znear - zfar);
        let tz    = zfar * znear * NumCast::from(2.0) / (znear - zfar);

        mat::Mat4::new(
            sx,           Zero::zero(), Zero::zero(), Zero::zero(),
            Zero::zero(), sy,           Zero::zero(), Zero::zero(),
            Zero::zero(), Zero::zero(), sz,           tz,
            Zero::zero(), Zero::zero(), One::one(),   Zero::zero()
            )
    }
}
<|endoftext|>


<commit_before>use std::io;

use colour;
use network;
use request::Frame;
use request::FrameAddress;
use request::Header;
use request::Payload;
use request::ProtocolHeader;
use request::Request;
use request::RequestBin;

/// Finds devices on the network.
pub fn get_service() -> Result<network::Device, io::Error> {
    let msg =
        Request::new(
            Header::new(
                Frame::new(0, true, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, false, false, 156),
                ProtocolHeader::new(0, 2, 0)),
            Payload(vec![]));

    let msg_bin = RequestBin::from(msg);

    match network::Network::send_discover_devices(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

/// Gets the power state of the specified device.
pub fn get_device_power_state(device: network::Device) -> Result<network::Device, io::Error> {
    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, false, false, 156),
                ProtocolHeader::new(0, 20, 0)),
            Payload(vec![]));

    let msg_bin = RequestBin::from(msg);

    match device.send_get_device_power_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

pub fn set_device_on(device: &network::Device) -> Result<network::Device, io::Error> {
    set_device_power_state(device, 65535)
}

pub fn set_device_off(device: &network::Device) -> Result<network::Device, io::Error> {
    set_device_power_state(device, 0)
}

/// Sets the power state of the specified device.
fn set_device_power_state(device: &network::Device,
                        power_level: u16)
                        -> Result<network::Device, io::Error> {

    //! # Sample payload:
    //! ```
    //! vec![0x00, 0x00];
    //! ```

    let reserved = vec![0x00];
    let p = RequestBin::u16_to_u8_array(power_level).to_vec();

    let payload_bytes = vec![
        &reserved[..],
        &p[..],
    ].concat();

    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, true, false, 156),
                ProtocolHeader::new(0, 21, 0)),
            Payload(payload_bytes));

    let msg_bin = RequestBin::from(msg);

    match device.send_set_device_power_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

/// Gets the state of the specified device.
pub fn get_device_state(device: &network::Device) -> Result<network::Device, io::Error> {
    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, false, false, 156),
                ProtocolHeader::new(0, 101, 0)),
            Payload(vec![]));

    let msg_bin = RequestBin::from(msg);

    match device.send_get_device_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

/// Sets the state of the specified device.
pub fn set_device_state(device: &network::Device,
                        hsb: &colour::HSB,
                        kelvin: u16,
                        duration: u32)
                        -> Result<network::Device, io::Error> {

    //! # Sample payload:
    //! ```
    //! vec![0x00, 0xF7, 0x77, 0xFF, 0x0F, 0x4F, 0xFF, 0xA0, 0xAA, 0x00, 0x00, 0x03, 0xe8];
    //! ```

    let reserved = vec![0x00];
    let hue = colour::hue_degrees_to_word(hsb.hue).to_vec();
    let sat = colour::saturation_percent_to_word(hsb.saturation).to_vec();
    let bri = colour::brightness_percent_to_word(hsb.brightness).to_vec();
    let kel = RequestBin::u16_to_u8_array(kelvin).to_vec();
    let dur = RequestBin::u32_to_u8_array(duration).to_vec();

    let payload_bytes = vec![
        &reserved[..],
        &hue[..],
        &sat[..],
        &bri[..],
        &kel[..],
        &dur[..],
    ].concat();

    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, true, false, 156),
                ProtocolHeader::new(0, 102, 0)),
            Payload(payload_bytes));

    let msg_bin = RequestBin::from(msg);

    match device.send_set_device_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}
<commit_msg>Change get_device_power_state param to borrow.<commit_after>use std::io;

use colour;
use network;
use request::Frame;
use request::FrameAddress;
use request::Header;
use request::Payload;
use request::ProtocolHeader;
use request::Request;
use request::RequestBin;

/// Finds devices on the network.
pub fn get_service() -> Result<network::Device, io::Error> {
    let msg =
        Request::new(
            Header::new(
                Frame::new(0, true, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, false, false, 156),
                ProtocolHeader::new(0, 2, 0)),
            Payload(vec![]));

    let msg_bin = RequestBin::from(msg);

    match network::Network::send_discover_devices(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

/// Gets the power state of the specified device.
pub fn get_device_power_state(device: &network::Device) -> Result<network::Device, io::Error> {
    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, false, false, 156),
                ProtocolHeader::new(0, 20, 0)),
            Payload(vec![]));

    let msg_bin = RequestBin::from(msg);

    match device.send_get_device_power_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

pub fn set_device_on(device: &network::Device) -> Result<network::Device, io::Error> {
    set_device_power_state(device, 65535)
}

pub fn set_device_off(device: &network::Device) -> Result<network::Device, io::Error> {
    set_device_power_state(device, 0)
}

/// Sets the power state of the specified device.
fn set_device_power_state(device: &network::Device,
                        power_level: u16)
                        -> Result<network::Device, io::Error> {

    //! # Sample payload:
    //! ```
    //! vec![0x00, 0x00];
    //! ```

    let reserved = vec![0x00];
    let p = RequestBin::u16_to_u8_array(power_level).to_vec();

    let payload_bytes = vec![
        &reserved[..],
        &p[..],
    ].concat();

    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, true, false, 156),
                ProtocolHeader::new(0, 21, 0)),
            Payload(payload_bytes));

    let msg_bin = RequestBin::from(msg);

    match device.send_set_device_power_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

/// Gets the state of the specified device.
pub fn get_device_state(device: &network::Device) -> Result<network::Device, io::Error> {
    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, false, false, 156),
                ProtocolHeader::new(0, 101, 0)),
            Payload(vec![]));

    let msg_bin = RequestBin::from(msg);

    match device.send_get_device_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}

/// Sets the state of the specified device.
pub fn set_device_state(device: &network::Device,
                        hsb: &colour::HSB,
                        kelvin: u16,
                        duration: u32)
                        -> Result<network::Device, io::Error> {

    //! # Sample payload:
    //! ```
    //! vec![0x00, 0xF7, 0x77, 0xFF, 0x0F, 0x4F, 0xFF, 0xA0, 0xAA, 0x00, 0x00, 0x03, 0xe8];
    //! ```

    let reserved = vec![0x00];
    let hue = colour::hue_degrees_to_word(hsb.hue).to_vec();
    let sat = colour::saturation_percent_to_word(hsb.saturation).to_vec();
    let bri = colour::brightness_percent_to_word(hsb.brightness).to_vec();
    let kel = RequestBin::u16_to_u8_array(kelvin).to_vec();
    let dur = RequestBin::u32_to_u8_array(duration).to_vec();

    let payload_bytes = vec![
        &reserved[..],
        &hue[..],
        &sat[..],
        &bri[..],
        &kel[..],
        &dur[..],
    ].concat();

    let msg =
        Request::new(
            Header::new(
                Frame::new(0, false, true, 1024, 321),
                FrameAddress::new([0; 8], [0; 6], 0, true, false, 156),
                ProtocolHeader::new(0, 102, 0)),
            Payload(payload_bytes));

    let msg_bin = RequestBin::from(msg);

    match device.send_set_device_state(msg_bin) {
        Ok(r) => {
            network::print_debug("good send");
            Ok(r)
        }
        Err(e) => {
            network::print_debug(&format!("bad send: {}", e));
            Err(e)
        }
    }
}
<|endoftext|>


<commit_before>use super::utils::types::{ Sha256Digest, Address, U256 };
use super::utils::bls::PublicKey;
use super::rlp::{ RlpStream, Encodable };

pub struct ValidatorRecord {
    pub pubkey: PublicKey,
    pub withdrawal_shard: u16,
    pub withdrawal_address: Address,
    pub randao_commitment: Sha256Digest,
    pub balance: U256,
    pub switch_dynasty: u64
}

impl ValidatorRecord {
    pub fn new(pubkey: PublicKey,
               withdrawal_shard: u16,
               withdrawal_address: Address,
               randao_commitment: Sha256Digest,
               balance: U256,
               switch_dynasty: u64)
        -> Self
    {
        Self {
            pubkey,
            withdrawal_shard,
            withdrawal_address,
            randao_commitment,
            balance,
            switch_dynasty
        }
    }
}

/*
 * RLP Encoding
 */
impl Encodable for ValidatorRecord {
    fn rlp_append(&self, s: &mut RlpStream) {
        // s.append(&self.pubkey);      // TODO: serialize this
        s.append(&self.withdrawal_shard);
        s.append(&self.withdrawal_address);
        s.append(&self.randao_commitment);
        s.append(&self.balance);
        s.append(&self.switch_dynasty);
    }
}

#[cfg(test)]
mod tests {
    use super::super::rlp;
    extern crate rand;

    use super::*;
    use super::super::
        utils::test_helpers::get_dangerous_test_keypair;

    #[test]
    fn test_new() {
        let keypair = get_dangerous_test_keypair();;
        let withdrawal_shard = 1;
        let withdrawal_address = Address::random();
        let randao_commitment = Sha256Digest::random();
        let balance = U256::from(100);
        let switch_dynasty = 10;

        let v = ValidatorRecord::new(
            keypair.public,
            withdrawal_shard,
            withdrawal_address,
            randao_commitment,
            balance,
            switch_dynasty);
        // TODO: figure out how to compare keys
        // assert_eq!(v.pubkey, keypair.public);
        assert_eq!(v.withdrawal_shard, withdrawal_shard);
        assert_eq!(v.withdrawal_address, withdrawal_address);
        assert_eq!(v.randao_commitment, randao_commitment);
        assert_eq!(v.balance, balance);
        assert_eq!(v.switch_dynasty, switch_dynasty);
    }

    #[test]
    fn test_rlp_serialization() {
        let keypair = get_dangerous_test_keypair();
        let v = ValidatorRecord {
            pubkey: keypair.public,
            withdrawal_shard: 100,
            withdrawal_address: Address::zero(),
            randao_commitment: Sha256Digest::zero(),
            balance: U256::from(120),
            switch_dynasty: 30
        };
        let e = rlp::encode(&v);
        assert_eq!(e.len(), 57);    // TODO: fix when pubkey is serialized
        // TODO: test for serialized pubkey
        assert_eq!(e[0], 100);
        assert_eq!(e[1], 148);
        assert_eq!(e[2..22], [0; 20]);
        assert_eq!(e[22], 160);
        assert_eq!(e[23..55], [0; 32]);
        assert_eq!(e[55], 120);
        assert_eq!(e[56], 30);
    }
}
<commit_msg>Add zero method to ValidatorRecord<commit_after>extern crate rand;

use super::utils::types::{ Sha256Digest, Address, U256 };
use super::utils::bls::{ PublicKey, Keypair };
use super::rlp::{ RlpStream, Encodable };

use self::rand::thread_rng;

pub struct ValidatorRecord {
    pub pubkey: PublicKey,
    pub withdrawal_shard: u16,
    pub withdrawal_address: Address,
    pub randao_commitment: Sha256Digest,
    pub balance: U256,
    pub switch_dynasty: u64
}

impl ValidatorRecord {
    pub fn new(pubkey: PublicKey,
               withdrawal_shard: u16,
               withdrawal_address: Address,
               randao_commitment: Sha256Digest,
               balance: U256,
               switch_dynasty: u64)
        -> Self
    {
        Self {
            pubkey,
            withdrawal_shard,
            withdrawal_address,
            randao_commitment,
            balance,
            switch_dynasty
        }
    }

    pub fn zero_with_thread_rand_pub_key() -> Self {
        let mut rng = thread_rng();
        let keypair = Keypair::generate(&mut rng);
        Self {
            pubkey: keypair.public,
            withdrawal_shard: 0,
            withdrawal_address: Address::zero(),
            randao_commitment: Sha256Digest::zero(),
            balance: U256::zero(),
            switch_dynasty: 0
        }
    }
}

/*
 * RLP Encoding
 */
impl Encodable for ValidatorRecord {
    fn rlp_append(&self, s: &mut RlpStream) {
        // s.append(&self.pubkey);      // TODO: serialize this
        s.append(&self.withdrawal_shard);
        s.append(&self.withdrawal_address);
        s.append(&self.randao_commitment);
        s.append(&self.balance);
        s.append(&self.switch_dynasty);
    }
}

#[cfg(test)]
mod tests {
    use super::super::rlp;
    extern crate rand;

    use super::*;
    use super::super::
        utils::test_helpers::get_dangerous_test_keypair;

    #[test]
    fn test_new() {
        let keypair = get_dangerous_test_keypair();;
        let withdrawal_shard = 1;
        let withdrawal_address = Address::random();
        let randao_commitment = Sha256Digest::random();
        let balance = U256::from(100);
        let switch_dynasty = 10;

        let v = ValidatorRecord::new(
            keypair.public,
            withdrawal_shard,
            withdrawal_address,
            randao_commitment,
            balance,
            switch_dynasty);
        // TODO: figure out how to compare keys
        // assert_eq!(v.pubkey, keypair.public);
        assert_eq!(v.withdrawal_shard, withdrawal_shard);
        assert_eq!(v.withdrawal_address, withdrawal_address);
        assert_eq!(v.randao_commitment, randao_commitment);
        assert_eq!(v.balance, balance);
        assert_eq!(v.switch_dynasty, switch_dynasty);
    }

    #[test]
    fn test_rlp_serialization() {
        let keypair = get_dangerous_test_keypair();
        let v = ValidatorRecord {
            pubkey: keypair.public,
            withdrawal_shard: 100,
            withdrawal_address: Address::zero(),
            randao_commitment: Sha256Digest::zero(),
            balance: U256::from(120),
            switch_dynasty: 30
        };
        let e = rlp::encode(&v);
        assert_eq!(e.len(), 57);    // TODO: fix when pubkey is serialized
        // TODO: test for serialized pubkey
        assert_eq!(e[0], 100);
        assert_eq!(e[1], 148);
        assert_eq!(e[2..22], [0; 20]);
        assert_eq!(e[22], 160);
        assert_eq!(e[23..55], [0; 32]);
        assert_eq!(e[55], 120);
        assert_eq!(e[56], 30);
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::sync::Arc;
use bytes::{Bytes, BytesMut};

/// Represents various types of http message body.
#[derive(Debug)]
pub enum Body {
    /// Empty response. `Content-Length` header is set to `0`
    Empty,
    /// Specific response body.
    Binary(BinaryBody),
    /// Streaming response body with specified length.
    Length(u64),
    /// Unspecified streaming response. Developer is responsible for setting
    /// right `Content-Length` or `Transfer-Encoding` headers.
    Streaming,
    /// Upgrade connection.
    Upgrade,
}

/// Represents various types of binary body.
/// `Content-Length` header is set to length of the body.
#[derive(Debug)]
pub enum BinaryBody {
    /// Bytes body
    Bytes(Bytes),
    /// Static slice
    Slice(&'static [u8]),
    /// Shared bytes body
    SharedBytes(Rc<Bytes>),
    /// Shared stirng body
    SharedString(Rc<String>),
    /// Shared bytes body
    #[doc(hidden)]
    ArcSharedBytes(Arc<Bytes>),
    /// Shared string body
    #[doc(hidden)]
    ArcSharedString(Arc<String>),
}

impl Body {
    /// Does this body have payload.
    pub fn has_body(&self) -> bool {
        match *self {
            Body::Length(_) | Body::Streaming => true,
            _ => false
        }
    }

    /// Create body from slice (copy)
    pub fn from_slice<'a>(s: &'a [u8]) -> Body {
        Body::Binary(BinaryBody::Bytes(Bytes::from(s)))
    }
}

impl<T> From<T> for Body where T: Into<BinaryBody>{
    fn from(b: T) -> Body {
        Body::Binary(b.into())
    }
}

impl BinaryBody {
    pub fn len(&self) -> usize {
        match self {
            &BinaryBody::Bytes(ref bytes) => bytes.len(),
            &BinaryBody::Slice(slice) => slice.len(),
            &BinaryBody::SharedBytes(ref bytes) => bytes.len(),
            &BinaryBody::ArcSharedBytes(ref bytes) => bytes.len(),
            &BinaryBody::SharedString(ref s) => s.len(),
            &BinaryBody::ArcSharedString(ref s) => s.len(),
        }
    }

    /// Create binary body from slice
    pub fn from_slice<'a>(s: &'a [u8]) -> BinaryBody {
        BinaryBody::Bytes(Bytes::from(s))
    }
}

impl From<&'static str> for BinaryBody {
    fn from(s: &'static str) -> BinaryBody {
        BinaryBody::Slice(s.as_ref())
    }
}

impl From<&'static [u8]> for BinaryBody {
    fn from(s: &'static [u8]) -> BinaryBody {
        BinaryBody::Slice(s)
    }
}

impl From<Vec<u8>> for BinaryBody {
    fn from(vec: Vec<u8>) -> BinaryBody {
        BinaryBody::Bytes(Bytes::from(vec))
    }
}

impl From<String> for BinaryBody {
    fn from(s: String) -> BinaryBody {
        BinaryBody::Bytes(Bytes::from(s))
    }
}

impl From<Bytes> for BinaryBody {
    fn from(s: Bytes) -> BinaryBody {
        BinaryBody::Bytes(s)
    }
}

impl From<BytesMut> for BinaryBody {
    fn from(s: BytesMut) -> BinaryBody {
        BinaryBody::Bytes(s.freeze())
    }
}

impl From<Rc<Bytes>> for BinaryBody {
    fn from(body: Rc<Bytes>) -> BinaryBody {
        BinaryBody::SharedBytes(body)
    }
}

impl<'a> From<&'a Rc<Bytes>> for BinaryBody {
    fn from(body: &'a Rc<Bytes>) -> BinaryBody {
        BinaryBody::SharedBytes(Rc::clone(body))
    }
}

impl From<Arc<Bytes>> for BinaryBody {
    fn from(body: Arc<Bytes>) -> BinaryBody {
        BinaryBody::ArcSharedBytes(body)
    }
}

impl<'a> From<&'a Arc<Bytes>> for BinaryBody {
    fn from(body: &'a Arc<Bytes>) -> BinaryBody {
        BinaryBody::ArcSharedBytes(Arc::clone(body))
    }
}

impl From<Rc<String>> for BinaryBody {
    fn from(body: Rc<String>) -> BinaryBody {
        BinaryBody::SharedString(body)
    }
}

impl<'a> From<&'a Rc<String>> for BinaryBody {
    fn from(body: &'a Rc<String>) -> BinaryBody {
        BinaryBody::SharedString(Rc::clone(body))
    }
}

impl From<Arc<String>> for BinaryBody {
    fn from(body: Arc<String>) -> BinaryBody {
        BinaryBody::ArcSharedString(body)
    }
}

impl<'a> From<&'a Arc<String>> for BinaryBody {
    fn from(body: &'a Arc<String>) -> BinaryBody {
        BinaryBody::ArcSharedString(Arc::clone(body))
    }
}

impl AsRef<[u8]> for BinaryBody {
    fn as_ref(&self) -> &[u8] {
        match self {
            &BinaryBody::Bytes(ref bytes) => bytes.as_ref(),
            &BinaryBody::Slice(slice) => slice,
            &BinaryBody::SharedBytes(ref bytes) => bytes.as_ref(),
            &BinaryBody::ArcSharedBytes(ref bytes) => bytes.as_ref(),
            &BinaryBody::SharedString(ref s) => s.as_bytes(),
            &BinaryBody::ArcSharedString(ref s) => s.as_bytes(),
        }
    }
}
<commit_msg>body tests<commit_after>use std::rc::Rc;
use std::sync::Arc;
use bytes::{Bytes, BytesMut};

/// Represents various types of http message body.
#[derive(Debug)]
pub enum Body {
    /// Empty response. `Content-Length` header is set to `0`
    Empty,
    /// Specific response body.
    Binary(BinaryBody),
    /// Streaming response body with specified length.
    Length(u64),
    /// Unspecified streaming response. Developer is responsible for setting
    /// right `Content-Length` or `Transfer-Encoding` headers.
    Streaming,
    /// Upgrade connection.
    Upgrade,
}

/// Represents various types of binary body.
/// `Content-Length` header is set to length of the body.
#[derive(Debug)]
pub enum BinaryBody {
    /// Bytes body
    Bytes(Bytes),
    /// Static slice
    Slice(&'static [u8]),
    /// Shared bytes body
    SharedBytes(Rc<Bytes>),
    /// Shared stirng body
    SharedString(Rc<String>),
    /// Shared bytes body
    #[doc(hidden)]
    ArcSharedBytes(Arc<Bytes>),
    /// Shared string body
    #[doc(hidden)]
    ArcSharedString(Arc<String>),
}

impl Body {
    /// Does this body have payload.
    pub fn has_body(&self) -> bool {
        match *self {
            Body::Length(_) | Body::Streaming => true,
            _ => false
        }
    }

    /// Create body from slice (copy)
    pub fn from_slice<'a>(s: &'a [u8]) -> Body {
        Body::Binary(BinaryBody::Bytes(Bytes::from(s)))
    }
}

impl<T> From<T> for Body where T: Into<BinaryBody>{
    fn from(b: T) -> Body {
        Body::Binary(b.into())
    }
}

impl BinaryBody {
    pub fn len(&self) -> usize {
        match self {
            &BinaryBody::Bytes(ref bytes) => bytes.len(),
            &BinaryBody::Slice(slice) => slice.len(),
            &BinaryBody::SharedBytes(ref bytes) => bytes.len(),
            &BinaryBody::ArcSharedBytes(ref bytes) => bytes.len(),
            &BinaryBody::SharedString(ref s) => s.len(),
            &BinaryBody::ArcSharedString(ref s) => s.len(),
        }
    }

    /// Create binary body from slice
    pub fn from_slice<'a>(s: &'a [u8]) -> BinaryBody {
        BinaryBody::Bytes(Bytes::from(s))
    }
}

impl From<&'static str> for BinaryBody {
    fn from(s: &'static str) -> BinaryBody {
        BinaryBody::Slice(s.as_ref())
    }
}

impl From<&'static [u8]> for BinaryBody {
    fn from(s: &'static [u8]) -> BinaryBody {
        BinaryBody::Slice(s)
    }
}

impl From<Vec<u8>> for BinaryBody {
    fn from(vec: Vec<u8>) -> BinaryBody {
        BinaryBody::Bytes(Bytes::from(vec))
    }
}

impl From<String> for BinaryBody {
    fn from(s: String) -> BinaryBody {
        BinaryBody::Bytes(Bytes::from(s))
    }
}

impl From<Bytes> for BinaryBody {
    fn from(s: Bytes) -> BinaryBody {
        BinaryBody::Bytes(s)
    }
}

impl From<BytesMut> for BinaryBody {
    fn from(s: BytesMut) -> BinaryBody {
        BinaryBody::Bytes(s.freeze())
    }
}

impl From<Rc<Bytes>> for BinaryBody {
    fn from(body: Rc<Bytes>) -> BinaryBody {
        BinaryBody::SharedBytes(body)
    }
}

impl<'a> From<&'a Rc<Bytes>> for BinaryBody {
    fn from(body: &'a Rc<Bytes>) -> BinaryBody {
        BinaryBody::SharedBytes(Rc::clone(body))
    }
}

impl From<Arc<Bytes>> for BinaryBody {
    fn from(body: Arc<Bytes>) -> BinaryBody {
        BinaryBody::ArcSharedBytes(body)
    }
}

impl<'a> From<&'a Arc<Bytes>> for BinaryBody {
    fn from(body: &'a Arc<Bytes>) -> BinaryBody {
        BinaryBody::ArcSharedBytes(Arc::clone(body))
    }
}

impl From<Rc<String>> for BinaryBody {
    fn from(body: Rc<String>) -> BinaryBody {
        BinaryBody::SharedString(body)
    }
}

impl<'a> From<&'a Rc<String>> for BinaryBody {
    fn from(body: &'a Rc<String>) -> BinaryBody {
        BinaryBody::SharedString(Rc::clone(body))
    }
}

impl From<Arc<String>> for BinaryBody {
    fn from(body: Arc<String>) -> BinaryBody {
        BinaryBody::ArcSharedString(body)
    }
}

impl<'a> From<&'a Arc<String>> for BinaryBody {
    fn from(body: &'a Arc<String>) -> BinaryBody {
        BinaryBody::ArcSharedString(Arc::clone(body))
    }
}

impl AsRef<[u8]> for BinaryBody {
    fn as_ref(&self) -> &[u8] {
        match self {
            &BinaryBody::Bytes(ref bytes) => bytes.as_ref(),
            &BinaryBody::Slice(slice) => slice,
            &BinaryBody::SharedBytes(ref bytes) => bytes.as_ref(),
            &BinaryBody::ArcSharedBytes(ref bytes) => bytes.as_ref(),
            &BinaryBody::SharedString(ref s) => s.as_bytes(),
            &BinaryBody::ArcSharedString(ref s) => s.as_bytes(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_static_str() {
        assert_eq!(BinaryBody::from("test").len(), 4);
        assert_eq!(BinaryBody::from("test").as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_static_bytes() {
        assert_eq!(BinaryBody::from(b"test".as_ref()).len(), 4);
        assert_eq!(BinaryBody::from(b"test".as_ref()).as_ref(), "test".as_bytes());
        assert_eq!(BinaryBody::from_slice(b"test".as_ref()).len(), 4);
        assert_eq!(BinaryBody::from_slice(b"test".as_ref()).as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_vec() {
        assert_eq!(BinaryBody::from(Vec::from("test")).len(), 4);
        assert_eq!(BinaryBody::from(Vec::from("test")).as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_bytes() {
        assert_eq!(BinaryBody::from(Bytes::from("test")).len(), 4);
        assert_eq!(BinaryBody::from(Bytes::from("test")).as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_rc_bytes() {
        let b = Rc::new(Bytes::from("test"));
        assert_eq!(BinaryBody::from(b.clone()).len(), 4);
        assert_eq!(BinaryBody::from(b.clone()).as_ref(), "test".as_bytes());
        assert_eq!(BinaryBody::from(&b).len(), 4);
        assert_eq!(BinaryBody::from(&b).as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_rc_string() {
        let b = Rc::new("test".to_owned());
        assert_eq!(BinaryBody::from(b.clone()).len(), 4);
        assert_eq!(BinaryBody::from(b.clone()).as_ref(), "test".as_bytes());
        assert_eq!(BinaryBody::from(&b).len(), 4);
        assert_eq!(BinaryBody::from(&b).as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_arc_bytes() {
        let b = Arc::new(Bytes::from("test"));
        assert_eq!(BinaryBody::from(b.clone()).len(), 4);
        assert_eq!(BinaryBody::from(b.clone()).as_ref(), "test".as_bytes());
        assert_eq!(BinaryBody::from(&b).len(), 4);
        assert_eq!(BinaryBody::from(&b).as_ref(), "test".as_bytes());
    }

    #[test]
    fn test_arc_string() {
        let b = Arc::new("test".to_owned());
        assert_eq!(BinaryBody::from(b.clone()).len(), 4);
        assert_eq!(BinaryBody::from(b.clone()).as_ref(), "test".as_bytes());
        assert_eq!(BinaryBody::from(&b).len(), 4);
        assert_eq!(BinaryBody::from(&b).as_ref(), "test".as_bytes());
    }
}
<|endoftext|>


<commit_before>pub trait Level {
    fn size(&self) -> (usize, usize);
    fn is_solved(&self) -> bool;
    fn make_move<'a>(&'a mut self, x: usize, y: usize) -> &'a mut Level;
    fn get(&self, x: usize, y: usize) -> Option<usize>;
    fn set(&mut self, x: usize, y: usize, v: usize) -> bool;
}

#[derive(Debug)]
pub struct StructLevel {
    sx: usize,
    sy: usize,
    level: Vec<Vec<usize>>,
}

impl StructLevel {
    pub fn new(sx: usize, sy: usize) -> StructLevel {
        let v = vec![vec![0usize; sx]; sy];
        StructLevel {
            sx: sx,
            sy: sy,
            level: v,
        }
    }
}

impl Level for StructLevel {
    fn size(&self) -> (usize, usize) {
        (self.sx, self.sy)
    }

    fn get(&self, x: usize, y: usize) -> Option<usize> {
        if x < self.sx && y < self.sy {
            Some(self.level[y][x])
        } else {
            None
        }
    }

    fn set(&mut self, x: usize, y: usize, v: usize) -> bool {
        if x < self.sx && y < self.sy {
            match v {
                0...1 => {
                    *self.level.get_mut(y).unwrap().get_mut(x).unwrap() = v;
                    true
                }
                _ => false,
            }
        } else {
            false
        }
    }

    fn is_solved(&self) -> bool {
        for v in self.level.iter() {
            for e in v.iter() {
                if *e != 1 {
                    return false;
                }
            }
        }
        true
    }

    fn make_move<'a>(&'a mut self, x: usize, y: usize) -> &'a mut Level {
        if x >= self.sx || y >= self.sy {
            return self;
        }
        fn switch(this: &mut StructLevel, x: usize, y: usize) {
            match this.get(x, y) {
                Some(1) => this.set(x, y, 0),
                Some(0) => this.set(x, y, 1),
                _ => false,
            };
        }
        if y > 0 {
            switch(self, x, y - 1);
        }
        if x > 0 {
            switch(self, x - 1, y);
        }
        switch(self, x, y);
        switch(self, x + 1, y);
        switch(self, x, y + 1);
        self
    }
}

pub fn solve(level: &StructLevel) -> Option<Vec<(usize, usize)>> {
    let (sx, sy) = level.size();
    let mut mat = vec![vec![0usize; sy*sx]; sy*sx];
    let mut blank = StructLevel::new(sx, sy);
    let mut expected = vec![0, sx * sy];
    for y in 0..sy {
        for x in 0..sx {
            let row = y * sx + x;
            blank.make_move(x, y);
            for by in 0..sy {
                for bx in 0..sx {
                    let col = by * sx + bx;
                    *mat.get_mut(row).unwrap().get_mut(col).unwrap() = blank.get(bx, by).unwrap();
                }
            }
            blank.make_move(x, y);
            *expected.get_mut(row).unwrap() = level.get(x, y).unwrap() + 1 % 2;
        }
    }
    let sol = gauss_jordan_zf2(mat, expected);
    match sol {
        Some(s) => {
            let mut ret = Vec::with_capacity(s.len());
            for i in 0..s.len() {
                if s[i] != 0 {
                    let x = i % sx;
                    let y = i / sx;
                    ret.push((x, y));
                }
            }
            Some(ret)
        }
        None => None,
    }
}

fn gauss_jordan_zf2(mat: Vec<Vec<usize>>, expected: Vec<usize>) -> Option<Vec<usize>> {
    let mut m = mat.clone();
    let mut bs = expected.clone();
    let rows = m.len();
    if rows == 0 {
        return None;
    }
    let cols = m[0].len();
    if cols == 0 {
        return None;
    }

    fn swap(m: &mut Vec<Vec<usize>>, bs: &mut Vec<usize>, i: usize, j: usize) {
        if i == j {
            return;
        }
        // XXX is cloning optimal here?
        let tmpi = m.get(i).unwrap().clone();
        let tmpj = m.get(j).unwrap().clone();
        *m.get_mut(i).unwrap() = tmpj;
        *m.get_mut(j).unwrap() = tmpi;

        let tmp = *bs.get(i).unwrap();
        *bs.get_mut(i).unwrap() = *bs.get(j).unwrap();
        *bs.get_mut(j).unwrap() = tmp;
    };

    fn add(m: &mut Vec<Vec<usize>>, bs: &mut Vec<usize>, i: usize, j: usize) {
        if i == j {
            panic!("trying to add row to itself");
        }
        for x in 0..m.get(i).unwrap().len() {
            *m.get_mut(i).unwrap().get_mut(x).unwrap() += *m.get(j).unwrap().get(x).unwrap();
            *m.get_mut(i).unwrap().get_mut(x).unwrap() %= 2;
        }
        *bs.get_mut(i).unwrap() += *bs.get(j).unwrap();
        *bs.get_mut(i).unwrap() %= 2;
    };

    for pivot in 0..rows {
        // 1. find pivot row
        for i in pivot..rows {
            if m[i][pivot] != 0 {
                swap(&mut m, &mut bs, i, pivot);
                break;
            }
        }
        if m[pivot][pivot] == 0 && bs[pivot] != 0 {
            return None;
        }

        // 2. add pivot to all rows that have 1 in this column
        for i in 0..rows {
            if i == pivot {
                continue;
            }
            if m[i][pivot] != 0 {
                add(&mut m, &mut bs, i, pivot);
            }
        }
    }
    Some(bs)
}
<commit_msg>fix bug in AI<commit_after>pub trait Level {
    fn size(&self) -> (usize, usize);
    fn is_solved(&self) -> bool;
    fn make_move<'a>(&'a mut self, x: usize, y: usize) -> &'a mut Level;
    fn get(&self, x: usize, y: usize) -> Option<usize>;
    fn set(&mut self, x: usize, y: usize, v: usize) -> bool;
}

#[derive(Debug)]
pub struct StructLevel {
    sx: usize,
    sy: usize,
    level: Vec<Vec<usize>>,
}

impl StructLevel {
    pub fn new(sx: usize, sy: usize) -> StructLevel {
        let v = vec![vec![0usize; sx]; sy];
        StructLevel {
            sx: sx,
            sy: sy,
            level: v,
        }
    }
}

impl Level for StructLevel {
    fn size(&self) -> (usize, usize) {
        (self.sx, self.sy)
    }

    fn get(&self, x: usize, y: usize) -> Option<usize> {
        if x < self.sx && y < self.sy {
            Some(self.level[y][x])
        } else {
            None
        }
    }

    fn set(&mut self, x: usize, y: usize, v: usize) -> bool {
        if x < self.sx && y < self.sy {
            match v {
                0...1 => {
                    *self.level.get_mut(y).unwrap().get_mut(x).unwrap() = v;
                    true
                }
                _ => false,
            }
        } else {
            false
        }
    }

    fn is_solved(&self) -> bool {
        for v in self.level.iter() {
            for e in v.iter() {
                if *e != 1 {
                    return false;
                }
            }
        }
        true
    }

    fn make_move<'a>(&'a mut self, x: usize, y: usize) -> &'a mut Level {
        if x >= self.sx || y >= self.sy {
            return self;
        }
        fn switch(this: &mut StructLevel, x: usize, y: usize) {
            match this.get(x, y) {
                Some(1) => this.set(x, y, 0),
                Some(0) => this.set(x, y, 1),
                _ => false,
            };
        }
        if y > 0 {
            switch(self, x, y - 1);
        }
        if x > 0 {
            switch(self, x - 1, y);
        }
        switch(self, x, y);
        switch(self, x + 1, y);
        switch(self, x, y + 1);
        self
    }
}

pub fn solve(level: &StructLevel) -> Option<Vec<(usize, usize)>> {
    let (sx, sy) = level.size();
    let mut mat = vec![vec![0usize; sy*sx]; sy*sx];
    let mut blank = StructLevel::new(sx, sy);
    let mut expected = vec![0; sx * sy];
    for y in 0..sy {
        for x in 0..sx {
            let row = y * sx + x;
            blank.make_move(x, y);
            for by in 0..sy {
                for bx in 0..sx {
                    let col = by * sx + bx;
                    println!("{} {}", row, col);
                    println!("{:?} {:?} <- {:?}",
                             mat.get(row),
                             mat.get(row).unwrap().get(col),
                             blank.get(bx, by));
                    *mat.get_mut(row).unwrap().get_mut(col).unwrap() = blank.get(bx, by).unwrap();
                }
            }
            blank.make_move(x, y);
            *expected.get_mut(row).unwrap() = level.get(x, y).unwrap() + 1 % 2;
        }
    }
    let sol = gauss_jordan_zf2(mat, expected);
    match sol {
        Some(s) => {
            let mut ret = Vec::with_capacity(s.len());
            for i in 0..s.len() {
                if s[i] != 0 {
                    let x = i % sx;
                    let y = i / sx;
                    ret.push((x, y));
                }
            }
            Some(ret)
        }
        None => None,
    }
}

fn gauss_jordan_zf2(mat: Vec<Vec<usize>>, expected: Vec<usize>) -> Option<Vec<usize>> {
    let mut m = mat.clone();
    let mut bs = expected.clone();
    let rows = m.len();
    if rows == 0 {
        return None;
    }
    let cols = m[0].len();
    if cols == 0 {
        return None;
    }

    fn swap(m: &mut Vec<Vec<usize>>, bs: &mut Vec<usize>, i: usize, j: usize) {
        if i == j {
            return;
        }
        // XXX is cloning optimal here?
        let tmpi = m.get(i).unwrap().clone();
        let tmpj = m.get(j).unwrap().clone();
        *m.get_mut(i).unwrap() = tmpj;
        *m.get_mut(j).unwrap() = tmpi;

        let tmp = *bs.get(i).unwrap();
        *bs.get_mut(i).unwrap() = *bs.get(j).unwrap();
        *bs.get_mut(j).unwrap() = tmp;
    };

    fn add(m: &mut Vec<Vec<usize>>, bs: &mut Vec<usize>, i: usize, j: usize) {
        if i == j {
            panic!("trying to add row to itself");
        }
        for x in 0..m.get(i).unwrap().len() {
            *m.get_mut(i).unwrap().get_mut(x).unwrap() += *m.get(j).unwrap().get(x).unwrap();
            *m.get_mut(i).unwrap().get_mut(x).unwrap() %= 2;
        }
        *bs.get_mut(i).unwrap() += *bs.get(j).unwrap();
        *bs.get_mut(i).unwrap() %= 2;
    };

    for pivot in 0..rows {
        // 1. find pivot row
        for i in pivot..rows {
            if m[i][pivot] != 0 {
                swap(&mut m, &mut bs, i, pivot);
                break;
            }
        }
        if m[pivot][pivot] == 0 && bs[pivot] != 0 {
            return None;
        }

        // 2. add pivot to all rows that have 1 in this column
        for i in 0..rows {
            if i == pivot {
                continue;
            }
            if m[i][pivot] != 0 {
                add(&mut m, &mut bs, i, pivot);
            }
        }
    }
    Some(bs)
}
<|endoftext|>


<commit_before>use std::cmp;
use std::fmt;
use std::io::{self, Write};
use std::ptr;

use futures::{Async, Poll};
use tokio_io::{AsyncRead, AsyncWrite};

use super::{Http1Transaction, MessageHead};
use bytes::{BytesMut, Bytes};

const INIT_BUFFER_SIZE: usize = 8192;
pub const MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;

pub struct Buffered<T> {
    flush_pipeline: bool,
    io: T,
    read_blocked: bool,
    read_buf: BytesMut,
    write_buf: WriteBuf,
}

impl<T> fmt::Debug for Buffered<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Buffered")
            .field("read_buf", &self.read_buf)
            .field("write_buf", &self.write_buf)
            .finish()
    }
}

impl<T: AsyncRead + AsyncWrite> Buffered<T> {
    pub fn new(io: T) -> Buffered<T> {
        Buffered {
            flush_pipeline: false,
            io: io,
            read_buf: BytesMut::with_capacity(0),
            write_buf: WriteBuf::new(),
            read_blocked: false,
        }
    }

    pub fn set_flush_pipeline(&mut self, enabled: bool) {
        self.flush_pipeline = enabled;
    }

    pub fn read_buf(&self) -> &[u8] {
        self.read_buf.as_ref()
    }

    pub fn write_buf_mut(&mut self) -> &mut Vec<u8> {
        self.write_buf.maybe_reset();
        self.write_buf.maybe_reserve(0);
        &mut self.write_buf.0.bytes
    }

    pub fn consume_leading_lines(&mut self) {
        if !self.read_buf.is_empty() {
            let mut i = 0;
            while i < self.read_buf.len() {
                match self.read_buf[i] {
                    b'\r' | b'\n' => i += 1,
                    _ => break,
                }
            }
            self.read_buf.split_to(i);
        }
    }

    pub fn parse<S: Http1Transaction>(&mut self) -> Poll<MessageHead<S::Incoming>, ::Error> {
        loop {
            match try!(S::parse(&mut self.read_buf)) {
                Some(head) => {
                    //trace!("parsed {} bytes out of {}", len, self.read_buf.len());
                    return Ok(Async::Ready(head.0))
                },
                None => {
                    if self.read_buf.capacity() >= MAX_BUFFER_SIZE {
                        debug!("MAX_BUFFER_SIZE reached, closing");
                        return Err(::Error::TooLarge);
                    }
                },
            }
            match try_ready!(self.read_from_io()) {
                0 => {
                    trace!("parse eof");
                    //TODO: With Rust 1.14, this can be Error::from(ErrorKind)
                    return Err(io::Error::new(io::ErrorKind::UnexpectedEof, ParseEof).into());
                }
                _ => {},
            }
        }
    }

    pub fn read_from_io(&mut self) -> Poll<usize, io::Error> {
        use bytes::BufMut;
        self.read_blocked = false;
        //TODO: use io.read_buf(), so we don't have to zero memory
        //Reason this doesn't use it yet is because benchmarks show the
        //slightest **decrease** in performance. Switching should be done
        //when it doesn't cost anything.
        if self.read_buf.remaining_mut() < INIT_BUFFER_SIZE {
            self.read_buf.reserve(INIT_BUFFER_SIZE);
            unsafe { // Zero out unused memory
                let buf = self.read_buf.bytes_mut();
                let len = buf.len();
                ptr::write_bytes(buf.as_mut_ptr(), 0, len);
            }
        }
        unsafe {
            let n = match self.io.read(self.read_buf.bytes_mut()) {
                Ok(n) => n,
                Err(e) => {
                    if e.kind() == io::ErrorKind::WouldBlock {
                        self.read_blocked = true;
                        return Ok(Async::NotReady);
                    }
                    return Err(e)
                }
            };
            self.read_buf.advance_mut(n);
            Ok(Async::Ready(n))
        }
    }

    pub fn buffer<B: AsRef<[u8]>>(&mut self, buf: B) -> usize {
        self.write_buf.buffer(buf.as_ref())
    }

    pub fn io_mut(&mut self) -> &mut T {
        &mut self.io
    }

    pub fn is_read_blocked(&self) -> bool {
        self.read_blocked
    }
}

impl<T: Write> Write for Buffered<T> {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let n = self.write_buf.buffer(data);
        if n == 0 {
            Err(io::ErrorKind::WouldBlock.into())
        } else {
            Ok(n)
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        if self.flush_pipeline && self.read_buf.is_empty() {
            Ok(())
        } else if self.write_buf.remaining() == 0 {
            self.io.flush()
        } else {
            loop {
                let n = try!(self.write_buf.write_into(&mut self.io));
                trace!("flushed {} bytes", n);
                if self.write_buf.remaining() == 0 {
                    break;
                }
            }
            self.io.flush()
        }
    }
}

pub trait MemRead {
    fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error>;
}

impl<T: AsyncRead + AsyncWrite> MemRead for Buffered<T> {
    fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> {
        trace!("Buffered.read_mem read_buf={}, wanted={}", self.read_buf.len(), len);
        if !self.read_buf.is_empty() {
            let n = ::std::cmp::min(len, self.read_buf.len());
            trace!("Buffered.read_mem read_buf is not empty, slicing {}", n);
            Ok(Async::Ready(self.read_buf.split_to(n).freeze()))
        } else {
            let n = try_ready!(self.read_from_io());
            Ok(Async::Ready(self.read_buf.split_to(::std::cmp::min(len, n)).freeze()))
        }
    }
}

#[derive(Clone)]
pub struct Cursor<T> {
    bytes: T,
    pos: usize,
}

impl<T: AsRef<[u8]>> Cursor<T> {
    pub fn new(bytes: T) -> Cursor<T> {
        Cursor {
            bytes: bytes,
            pos: 0,
        }
    }

    pub fn has_started(&self) -> bool {
        self.pos != 0
    }

    pub fn is_written(&self) -> bool {
        trace!("Cursor::is_written pos = {}, len = {}", self.pos, self.bytes.as_ref().len());
        self.pos >= self.bytes.as_ref().len()
    }

    pub fn write_to<W: Write>(&mut self, dst: &mut W) -> io::Result<usize> {
        if self.remaining() == 0 {
            Ok(0)
        } else {
            dst.write(&self.bytes.as_ref()[self.pos..]).map(|n| {
                self.pos += n;
                n
            })
        }
    }

    fn remaining(&self) -> usize {
        self.bytes.as_ref().len() - self.pos
    }

    #[inline]
    pub fn buf(&self) -> &[u8] {
        &self.bytes.as_ref()[self.pos..]
    }

    #[inline]
    pub fn consume(&mut self, num: usize) {
        trace!("Cursor::consume({})", num);
        self.pos = ::std::cmp::min(self.bytes.as_ref().len(), self.pos + num);
    }
}

impl<T: AsRef<[u8]>> fmt::Debug for Cursor<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Cursor")
            .field("pos", &self.pos)
            .field("len", &self.bytes.as_ref().len())
            .finish()
    }
}

pub trait AtomicWrite {
    fn write_atomic(&mut self, data: &[&[u8]]) -> io::Result<usize>;
}

/*
#[cfg(not(windows))]
impl<T: Write + ::vecio::Writev> AtomicWrite for T {

    fn write_atomic(&mut self, bufs: &[&[u8]]) -> io::Result<usize> {
        self.writev(bufs)
    }

}

#[cfg(windows)]
*/
impl<T: Write> AtomicWrite for T {
    fn write_atomic(&mut self, bufs: &[&[u8]]) -> io::Result<usize> {
        if bufs.len() == 1 {
            self.write(bufs[0])
        } else {
            let vec = bufs.concat();
            self.write(&vec)
        }
    }
}
//}

// an internal buffer to collect writes before flushes
#[derive(Debug)]
struct WriteBuf(Cursor<Vec<u8>>);

impl WriteBuf {
    fn new() -> WriteBuf {
        WriteBuf(Cursor::new(Vec::new()))
    }

    fn write_into<W: Write>(&mut self, w: &mut W) -> io::Result<usize> {
        self.0.write_to(w)
    }

    fn buffer(&mut self, data: &[u8]) -> usize {
        trace!("WriteBuf::buffer() len = {:?}", data.len());
        self.maybe_reset();
        self.maybe_reserve(data.len());
        let vec = &mut self.0.bytes;
        let len = cmp::min(vec.capacity() - vec.len(), data.len());
        assert!(vec.capacity() - vec.len() >= len);
        unsafe {
            // in rust 1.9, we could use slice::copy_from_slice
            ptr::copy(
                data.as_ptr(),
                vec.as_mut_ptr().offset(vec.len() as isize),
                len
            );
            let new_len = vec.len() + len;
            vec.set_len(new_len);
        }
        len
    }

    fn remaining(&self) -> usize {
        self.0.remaining()
    }

    #[inline]
    fn maybe_reserve(&mut self, needed: usize) {
        let vec = &mut self.0.bytes;
        let cap = vec.capacity();
        if cap == 0 {
            let init = cmp::min(MAX_BUFFER_SIZE, cmp::max(INIT_BUFFER_SIZE, needed));
            trace!("WriteBuf reserving initial {}", init);
            vec.reserve(init);
        } else if cap < MAX_BUFFER_SIZE {
            vec.reserve(cmp::min(needed, MAX_BUFFER_SIZE - cap));
            trace!("WriteBuf reserved {}", vec.capacity() - cap);
        }
    }

    fn maybe_reset(&mut self) {
        if self.0.pos != 0 && self.0.remaining() == 0 {
            self.0.pos = 0;
            unsafe {
                self.0.bytes.set_len(0);
            }
        }
    }
}

#[derive(Debug)]
struct ParseEof;

impl fmt::Display for ParseEof {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("parse eof")
    }
}

impl ::std::error::Error for ParseEof {
    fn description(&self) -> &str {
        "parse eof"
    }
}

// TODO: Move tests to their own mod
#[cfg(test)]
use std::io::Read;

#[cfg(test)]
impl<T: Read> MemRead for ::mock::AsyncIo<T> {
    fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> {
        let mut v = vec![0; len];
        let n = try_nb!(self.read(v.as_mut_slice()));
        Ok(Async::Ready(BytesMut::from(&v[..n]).freeze()))
    }
}

#[test]
fn test_iobuf_write_empty_slice() {
    use mock::{AsyncIo, Buf as MockBuf};

    let mut mock = AsyncIo::new(MockBuf::new(), 256);
    mock.error(io::Error::new(io::ErrorKind::Other, "logic error"));

    let mut io_buf = Buffered::new(mock);

    // underlying io will return the logic error upon write,
    // so we are testing that the io_buf does not trigger a write
    // when there is nothing to flush
    io_buf.flush().expect("should short-circuit flush");
}

#[test]
fn test_parse_reads_until_blocked() {
    use mock::{AsyncIo, Buf as MockBuf};
    // missing last line ending
    let raw = "HTTP/1.1 200 OK\r\n";

    let mock = AsyncIo::new(MockBuf::wrap(raw.into()), raw.len());
    let mut buffered = Buffered::new(mock);
    assert_eq!(buffered.parse::<super::ClientTransaction>().unwrap(), Async::NotReady);
    assert!(buffered.io.blocked());
}
<commit_msg>fix(server): fix experimental pipeline flushing<commit_after>use std::cmp;
use std::fmt;
use std::io::{self, Write};
use std::ptr;

use futures::{Async, Poll};
use tokio_io::{AsyncRead, AsyncWrite};

use super::{Http1Transaction, MessageHead};
use bytes::{BytesMut, Bytes};

const INIT_BUFFER_SIZE: usize = 8192;
pub const MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;

pub struct Buffered<T> {
    flush_pipeline: bool,
    io: T,
    read_blocked: bool,
    read_buf: BytesMut,
    write_buf: WriteBuf,
}

impl<T> fmt::Debug for Buffered<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Buffered")
            .field("read_buf", &self.read_buf)
            .field("write_buf", &self.write_buf)
            .finish()
    }
}

impl<T: AsyncRead + AsyncWrite> Buffered<T> {
    pub fn new(io: T) -> Buffered<T> {
        Buffered {
            flush_pipeline: false,
            io: io,
            read_buf: BytesMut::with_capacity(0),
            write_buf: WriteBuf::new(),
            read_blocked: false,
        }
    }

    pub fn set_flush_pipeline(&mut self, enabled: bool) {
        self.flush_pipeline = enabled;
    }

    pub fn read_buf(&self) -> &[u8] {
        self.read_buf.as_ref()
    }

    pub fn write_buf_mut(&mut self) -> &mut Vec<u8> {
        self.write_buf.maybe_reset();
        self.write_buf.maybe_reserve(0);
        &mut self.write_buf.0.bytes
    }

    pub fn consume_leading_lines(&mut self) {
        if !self.read_buf.is_empty() {
            let mut i = 0;
            while i < self.read_buf.len() {
                match self.read_buf[i] {
                    b'\r' | b'\n' => i += 1,
                    _ => break,
                }
            }
            self.read_buf.split_to(i);
        }
    }

    pub fn parse<S: Http1Transaction>(&mut self) -> Poll<MessageHead<S::Incoming>, ::Error> {
        loop {
            match try!(S::parse(&mut self.read_buf)) {
                Some(head) => {
                    //trace!("parsed {} bytes out of {}", len, self.read_buf.len());
                    return Ok(Async::Ready(head.0))
                },
                None => {
                    if self.read_buf.capacity() >= MAX_BUFFER_SIZE {
                        debug!("MAX_BUFFER_SIZE reached, closing");
                        return Err(::Error::TooLarge);
                    }
                },
            }
            match try_ready!(self.read_from_io()) {
                0 => {
                    trace!("parse eof");
                    //TODO: With Rust 1.14, this can be Error::from(ErrorKind)
                    return Err(io::Error::new(io::ErrorKind::UnexpectedEof, ParseEof).into());
                }
                _ => {},
            }
        }
    }

    pub fn read_from_io(&mut self) -> Poll<usize, io::Error> {
        use bytes::BufMut;
        self.read_blocked = false;
        //TODO: use io.read_buf(), so we don't have to zero memory
        //Reason this doesn't use it yet is because benchmarks show the
        //slightest **decrease** in performance. Switching should be done
        //when it doesn't cost anything.
        if self.read_buf.remaining_mut() < INIT_BUFFER_SIZE {
            self.read_buf.reserve(INIT_BUFFER_SIZE);
            unsafe { // Zero out unused memory
                let buf = self.read_buf.bytes_mut();
                let len = buf.len();
                ptr::write_bytes(buf.as_mut_ptr(), 0, len);
            }
        }
        unsafe {
            let n = match self.io.read(self.read_buf.bytes_mut()) {
                Ok(n) => n,
                Err(e) => {
                    if e.kind() == io::ErrorKind::WouldBlock {
                        self.read_blocked = true;
                        return Ok(Async::NotReady);
                    }
                    return Err(e)
                }
            };
            self.read_buf.advance_mut(n);
            Ok(Async::Ready(n))
        }
    }

    pub fn buffer<B: AsRef<[u8]>>(&mut self, buf: B) -> usize {
        self.write_buf.buffer(buf.as_ref())
    }

    pub fn io_mut(&mut self) -> &mut T {
        &mut self.io
    }

    pub fn is_read_blocked(&self) -> bool {
        self.read_blocked
    }
}

impl<T: Write> Write for Buffered<T> {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let n = self.write_buf.buffer(data);
        if n == 0 {
            Err(io::ErrorKind::WouldBlock.into())
        } else {
            Ok(n)
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        if self.flush_pipeline && !self.read_buf.is_empty() {
            Ok(())
        } else if self.write_buf.remaining() == 0 {
            self.io.flush()
        } else {
            loop {
                let n = try!(self.write_buf.write_into(&mut self.io));
                trace!("flushed {} bytes", n);
                if self.write_buf.remaining() == 0 {
                    break;
                }
            }
            self.io.flush()
        }
    }
}

pub trait MemRead {
    fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error>;
}

impl<T: AsyncRead + AsyncWrite> MemRead for Buffered<T> {
    fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> {
        trace!("Buffered.read_mem read_buf={}, wanted={}", self.read_buf.len(), len);
        if !self.read_buf.is_empty() {
            let n = ::std::cmp::min(len, self.read_buf.len());
            trace!("Buffered.read_mem read_buf is not empty, slicing {}", n);
            Ok(Async::Ready(self.read_buf.split_to(n).freeze()))
        } else {
            let n = try_ready!(self.read_from_io());
            Ok(Async::Ready(self.read_buf.split_to(::std::cmp::min(len, n)).freeze()))
        }
    }
}

#[derive(Clone)]
pub struct Cursor<T> {
    bytes: T,
    pos: usize,
}

impl<T: AsRef<[u8]>> Cursor<T> {
    pub fn new(bytes: T) -> Cursor<T> {
        Cursor {
            bytes: bytes,
            pos: 0,
        }
    }

    pub fn has_started(&self) -> bool {
        self.pos != 0
    }

    pub fn is_written(&self) -> bool {
        trace!("Cursor::is_written pos = {}, len = {}", self.pos, self.bytes.as_ref().len());
        self.pos >= self.bytes.as_ref().len()
    }

    pub fn write_to<W: Write>(&mut self, dst: &mut W) -> io::Result<usize> {
        if self.remaining() == 0 {
            Ok(0)
        } else {
            dst.write(&self.bytes.as_ref()[self.pos..]).map(|n| {
                self.pos += n;
                n
            })
        }
    }

    fn remaining(&self) -> usize {
        self.bytes.as_ref().len() - self.pos
    }

    #[inline]
    pub fn buf(&self) -> &[u8] {
        &self.bytes.as_ref()[self.pos..]
    }

    #[inline]
    pub fn consume(&mut self, num: usize) {
        trace!("Cursor::consume({})", num);
        self.pos = ::std::cmp::min(self.bytes.as_ref().len(), self.pos + num);
    }
}

impl<T: AsRef<[u8]>> fmt::Debug for Cursor<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Cursor")
            .field("pos", &self.pos)
            .field("len", &self.bytes.as_ref().len())
            .finish()
    }
}

pub trait AtomicWrite {
    fn write_atomic(&mut self, data: &[&[u8]]) -> io::Result<usize>;
}

/*
#[cfg(not(windows))]
impl<T: Write + ::vecio::Writev> AtomicWrite for T {

    fn write_atomic(&mut self, bufs: &[&[u8]]) -> io::Result<usize> {
        self.writev(bufs)
    }

}

#[cfg(windows)]
*/
impl<T: Write> AtomicWrite for T {
    fn write_atomic(&mut self, bufs: &[&[u8]]) -> io::Result<usize> {
        if bufs.len() == 1 {
            self.write(bufs[0])
        } else {
            let vec = bufs.concat();
            self.write(&vec)
        }
    }
}
//}

// an internal buffer to collect writes before flushes
#[derive(Debug)]
struct WriteBuf(Cursor<Vec<u8>>);

impl WriteBuf {
    fn new() -> WriteBuf {
        WriteBuf(Cursor::new(Vec::new()))
    }

    fn write_into<W: Write>(&mut self, w: &mut W) -> io::Result<usize> {
        self.0.write_to(w)
    }

    fn buffer(&mut self, data: &[u8]) -> usize {
        trace!("WriteBuf::buffer() len = {:?}", data.len());
        self.maybe_reset();
        self.maybe_reserve(data.len());
        let vec = &mut self.0.bytes;
        let len = cmp::min(vec.capacity() - vec.len(), data.len());
        assert!(vec.capacity() - vec.len() >= len);
        unsafe {
            // in rust 1.9, we could use slice::copy_from_slice
            ptr::copy(
                data.as_ptr(),
                vec.as_mut_ptr().offset(vec.len() as isize),
                len
            );
            let new_len = vec.len() + len;
            vec.set_len(new_len);
        }
        len
    }

    fn remaining(&self) -> usize {
        self.0.remaining()
    }

    #[inline]
    fn maybe_reserve(&mut self, needed: usize) {
        let vec = &mut self.0.bytes;
        let cap = vec.capacity();
        if cap == 0 {
            let init = cmp::min(MAX_BUFFER_SIZE, cmp::max(INIT_BUFFER_SIZE, needed));
            trace!("WriteBuf reserving initial {}", init);
            vec.reserve(init);
        } else if cap < MAX_BUFFER_SIZE {
            vec.reserve(cmp::min(needed, MAX_BUFFER_SIZE - cap));
            trace!("WriteBuf reserved {}", vec.capacity() - cap);
        }
    }

    fn maybe_reset(&mut self) {
        if self.0.pos != 0 && self.0.remaining() == 0 {
            self.0.pos = 0;
            unsafe {
                self.0.bytes.set_len(0);
            }
        }
    }
}

#[derive(Debug)]
struct ParseEof;

impl fmt::Display for ParseEof {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("parse eof")
    }
}

impl ::std::error::Error for ParseEof {
    fn description(&self) -> &str {
        "parse eof"
    }
}

// TODO: Move tests to their own mod
#[cfg(test)]
use std::io::Read;

#[cfg(test)]
impl<T: Read> MemRead for ::mock::AsyncIo<T> {
    fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> {
        let mut v = vec![0; len];
        let n = try_nb!(self.read(v.as_mut_slice()));
        Ok(Async::Ready(BytesMut::from(&v[..n]).freeze()))
    }
}

#[test]
fn test_iobuf_write_empty_slice() {
    use mock::{AsyncIo, Buf as MockBuf};

    let mut mock = AsyncIo::new(MockBuf::new(), 256);
    mock.error(io::Error::new(io::ErrorKind::Other, "logic error"));

    let mut io_buf = Buffered::new(mock);

    // underlying io will return the logic error upon write,
    // so we are testing that the io_buf does not trigger a write
    // when there is nothing to flush
    io_buf.flush().expect("should short-circuit flush");
}

#[test]
fn test_parse_reads_until_blocked() {
    use mock::{AsyncIo, Buf as MockBuf};
    // missing last line ending
    let raw = "HTTP/1.1 200 OK\r\n";

    let mock = AsyncIo::new(MockBuf::wrap(raw.into()), raw.len());
    let mut buffered = Buffered::new(mock);
    assert_eq!(buffered.parse::<super::ClientTransaction>().unwrap(), Async::NotReady);
    assert!(buffered.io.blocked());
}
<|endoftext|>