<commit_before>extern crate byteorder;

use std;
use std::io::Write;
use self::byteorder::NativeEndian;
use self::byteorder::WriteBytesExt;

/// Represents a value in the scalar set.
/// The values must be able to store booking information
/// for managing the contents of the set. These requirements
/// are captured in this trait.
pub trait Value
{
    /// Gets the index of the bucket for this value.
    fn get_bucket_index(
        &self,
        buckets: &Self,
    ) -> usize;

    /// Gets a zero.
    fn zero() -> Self;

    /// Gets the integer value as a size.
    fn as_index( &self ) -> usize;

    /// Converts the number of buckets into the value type.i
    fn from_bucket_count( bucket_count: &usize ) -> Self;

    /// Converts the number of set members into the value type.
    fn from_member_count( member_count: usize ) -> Self;

    /// Converts the given index into the value type.
    fn from_index( index: usize ) -> Self;

    /// Decrements the value by one.
    fn decrement( &self ) -> Self;

    /// Provides total ordering for elements.
    fn cmp(
        &self,
        other: &Self,
    ) -> std::cmp::Ordering;

    /// Serializes the value.
    fn serialize(
        &self,
        &mut Write,
    ) -> Result<(), std::io::Error>;
}

/// Implements Value trait for i32
impl Value for i32
{
    /// Gets the index of the bucket for this value.
    fn get_bucket_index(
        &self,
        buckets: &i32,
    ) -> usize
    {
        return ( self.clone() as usize ) % ( buckets.clone() as usize );
    }

    /// Gets a zero.
    fn zero() -> i32
    {
        return 0;
    }

    /// Gets the integer value as a size.
    fn as_index( &self ) -> usize
    {
        return self.clone() as usize;
    }

    /// Converts the specified value to a value that can be stored in the container.
    fn from_bucket_count( bucket_count: &usize ) -> i32
    {
        return bucket_count.clone() as i32;
    }

    /// Converts the number of set members into the value type.
    fn from_member_count( member_count: usize ) -> i32
    {
        return member_count as i32;
    }

    /// Converts the given value to index.
    fn from_index( index: usize ) -> i32
    {
        return index as i32;
    }

    /// Decrements the value by one.
    fn decrement( &self ) -> i32
    {
        return self - 1;
    }

    /// Provides total ordering for elements.
    fn cmp(
        &self,
        other: &i32,
    ) -> std::cmp::Ordering
    {
        std::cmp::Ord::cmp( self, other )
    }

    /// Serializes the value.
    fn serialize(
        &self,
        writer: &mut Write,
    ) -> Result<(), std::io::Error>
    {
        writer.write_i32::<NativeEndian>( *self )?;
        Ok( () )
    }
}

/// Implements Value trait for f32
/// * The largest permissible value is 2^24.
/// * Mainly implemented to provide an easy to use interface for sending the structure to GPU.
#[cfg(any(feature = "floats", test))]
impl Value for f32
{
    /// Gets the index of the bucket for this value.
    fn get_bucket_index(
        &self,
        buckets: &f32,
    ) -> usize
    {
        return ( self.clone() as usize ) % ( buckets.clone() as usize );
    }

    /// Gets a zero.
    fn zero() -> f32
    {
        return 0.0;
    }

    /// Gets the integer value as a size.
    fn as_index( &self ) -> usize
    {
        return self.clone() as usize;
    }

    /// Converts the specified value to a value that can be stored in the container.
    fn from_bucket_count( bucket_count: &usize ) -> f32
    {
        return bucket_count.clone() as f32;
    }

    /// Converts the number of set members into the value type.
    fn from_member_count( member_count: usize ) -> f32
    {
        return member_count as f32;
    }

    /// Converts the given value to index.
    fn from_index( index: usize ) -> f32
    {
        return index as f32;
    }

    /// Decrements the value by one.
    fn decrement( &self ) -> f32
    {
        return self - 1.0;
    }

    /// Provides total ordering for Value elements.
    fn cmp(
        &self,
        other: &f32,
    ) -> std::cmp::Ordering
    {
        let me = self.clone() as i32;
        let other = other.clone() as i32;
        std::cmp::Ord::cmp( &me, &other )
    }

    /// Serializes the value.
    fn serialize(
        &self,
        writer: &mut Write,
    ) -> Result<(), std::io::Error>
    {
        writer.write_f32::<NativeEndian>( *self )?;
        Ok( () )
    }
}

/// The index or position in the array that holds the number of members in the set.
const SIZE_INDEX: usize = 1;

/// The index or position in the array that holds the index to the first value of the first bucket.
const FIRST_BUCKET_INDEX: usize = 2;

/// Defines how the data is stored in the scalar set.
enum Storage<'a, TA, TB>
where
    TB: 'a,
{
    /// The data is stored as a vector.
    Vector
    { data: Vec<TA> },

    /// The data is stored in a slice. Not owned by the scalar set.
    Slice
    { data: &'a [TB] },
}

/// Scalar set cabable of storing values with Value trait.
pub struct RoScalarSet<'a, T>
where
    T: std::clone::Clone + Value + 'a,
{
    _storage: Storage<'a, T, T>,
}

impl<'a, T> Clone for RoScalarSet<'a, T>
where
    T: std::clone::Clone + Value + 'a,
{
    /// Returns a copy of the set.
    fn clone( &self ) -> Self
    {
        RoScalarSet::new( self.borrow_values() )
    }

    /// Copies the content from the given set.alloc
    fn clone_from(
        &mut self,
        source: &Self,
    )
    {
        let storage = RoScalarSet::create_storage( source.borrow_values() );
        self._storage = storage;
    }
}

impl<'a, T> RoScalarSet<'a, T>
where
    T: std::clone::Clone + Value + 'a,
{
    /// Returns a new integer hash set holding the specified values.
    ///
    /// # ArgumentRoScalarSets
    ///
    /// * 'values' Holds the values stored in the hash set.
    pub fn new<'b, 'c>( values: &'c [T] ) -> RoScalarSet<'b, T>
    {
        let storage = RoScalarSet::create_storage( values );
        return RoScalarSet { _storage: storage };
    }

    /// Attaches an integer hash set to a slice holding the values.
    ///
    /// # ArgumentRoScalarSets
    ///
    /// * 'values' Slice that holds the values stored in the hash set.
    pub fn attach<'b>( buffer: &'b [T] ) -> Result<( RoScalarSet<'b, T>, &'b [T] ), &str>
    {
        // Determine the length of this scalar set.
        if buffer.len() < 4
        {
            return Err( "The buffer is to small" );
        }
        let buckets = buffer[0].as_index();
        let values = buffer[SIZE_INDEX].as_index();
        let total_size = FIRST_BUCKET_INDEX + ( buckets + 1 ) + values;

        // Attach.
        let ( set, remainder ) = buffer.split_at( total_size );
        let storage: Storage<T, T> = Storage::Slice { data: set };
        return Ok( ( RoScalarSet { _storage: storage }, remainder ) );
    }

    /// Checks if any the sets have anything in common.
    pub fn any(
        &self,
        other: &RoScalarSet<T>,
    ) -> bool
    {
        // Determine the smaller set.
        let small;
        let large;
        if other.size() < self.size()
        {
            small = other;
            large = self;
        }
        else
        {
            small = self;
            large = other;
        }

        // For better performance we iterate the smaller set.
        for s in small.borrow_values()
        {
            if large.contains( s )
            {
                return true;
            }
        }

        // Values was not found.
        return false;
    }

    /// Checks whether the given value exists in the set or not.
    pub fn contains(
        &self,
        value: &T,
    ) -> bool
    {
        // Get the bucket associated with the value.
        let bucket = self.get_bucket( &value );

        // Locate the value.
        match bucket.binary_search_by( |probe| probe.cmp( &value ) )
        {
            Ok( _ ) => return true,
            Err( _ ) => return false,
        }
    }

    /// Gets the number of members in the set.
    pub fn size( &self ) -> usize
    {
        let storage = self.borrow_storage();
        return storage[SIZE_INDEX].as_index();
    }

    /// Gets the number of buckets.
    pub fn bucket_count( &self ) -> usize
    {
        let storage = self.borrow_storage();
        return storage[0].as_index();
    }

    /// Serializes the scalar set into the given writer.
    pub fn serialize<W>(
        &self,
        writer: &mut W,
    ) -> Result<(), std::io::Error>
    where
        W: Write,
    {
        // Write our intern
        let storage = self.borrow_storage();
        for v in storage
        {
            v.serialize( writer )?;
        }
        Ok( () )
    }

    /// Gets a read-only slice containing the values of a bucket that holdes the given value.
    fn get_bucket(
        &self,
        value: &T,
    ) -> &[T]
    {
        // Determine the bucket.
        let storage = self.borrow_storage();
        let bucket_id: usize = value.get_bucket_index( &storage[0] );
        let bucket_index = bucket_id + FIRST_BUCKET_INDEX;
        let begin: usize = storage[bucket_index].as_index();
        let end: usize = storage[( bucket_index + 1 )].as_index();
        let ( _, remainder ) = storage.split_at( begin );
        let ( bucket, _ ) = remainder.split_at( end - begin );
        return bucket;
    }

    /// Borrows the values of the set.
    fn borrow_values( &'a self ) -> &'a [T]
    {
        // Split the value part from the storage.
        let start = FIRST_BUCKET_INDEX + self.bucket_count() + 1;
        let ( _, values ) = self.borrow_storage().split_at( start );
        return values;
    }

    /// Borrows the storage for accessing the values.
    fn borrow_storage( &'a self ) -> &'a [T]
    {
        let s: &'a [T] = match &self._storage
        {
            &Storage::Vector { ref data } => data.as_slice(),
            &Storage::Slice { ref data } => data,
        };
        return s;
    }

    /// Creates a new storage buffer from the given values.
    fn create_storage( values: &[T] ) -> Storage<'a, T, T>
    {
        // Determine the number of buckets. We introduce a 5% overhead.
        let bucket_count: usize = ( values.len() as f64 * 0.05 ).ceil() as usize;
        let mut storage: Vec<T> = vec![T::zero(); ( FIRST_BUCKET_INDEX + bucket_count + 1 + values.len() )];

        // Store the number of buckets.
        let buckets = T::from_bucket_count( &bucket_count );
        storage[0] = buckets.clone();

        // Store the number of members.
        storage[SIZE_INDEX] = T::from_member_count( values.len() );

        // Count the values required for each bucket.
        let mut values_in_buckets: Vec<i32> = vec![0; bucket_count];
        for v in values
        {
            let bucket = v.get_bucket_index( &buckets );
            values_in_buckets[bucket] += 1;
        }

        // Set bucket pointers to point the end of each bucket.
        // This way we can use the bucket pointers to track the next empty position when
        // distributing the values into the buckets.
        let first_bucket: usize = FIRST_BUCKET_INDEX;
        let data_start: usize = FIRST_BUCKET_INDEX + bucket_count + 1;
        let mut previous_bucket_end = data_start;
        for b in 0..bucket_count
        {
            // The end of the previous bucket is the start of the previous bucket.
            let index = previous_bucket_end + values_in_buckets[b].as_index();
            storage[b + first_bucket] = T::from_index( index );
            previous_bucket_end = index;
        }

        // Fix the end of the last bucket.
        storage[first_bucket + bucket_count] = T::from_index( storage.len() );

        // Put values into buckets.
        for v in values
        {
            // Determine bucket for the value.
            let bucket_id = v.get_bucket_index( &buckets );

            // Make room for the new value.
            storage[bucket_id + first_bucket] = storage[bucket_id + first_bucket].decrement();
            let value_index: usize = storage[bucket_id + first_bucket].as_index();

            // And finally store the value.
            storage[value_index] = v.clone();
        }

        // Sort each bucket to enable binary search.
        for b in 0..bucket_count
        {
            // Determine the location of the bucket.
            let begin: usize = storage[b + first_bucket].as_index();
            let end: usize = storage[b + first_bucket + 1].as_index();
            if end < begin
            {
                panic!( "Invalid bucket: {}", b );
            }

            // Get a splice that represents the bucket and sort it.
            let ( _, remainder ) = storage.split_at_mut( begin );
            let ( bucket, _ ) = remainder.split_at_mut( end - begin );
            bucket.sort_by( |a, b| a.cmp( b ) );
        }

        let storage: Storage<'a, T, T> = Storage::Vector { data: storage };
        storage
    }
}
<commit_msg>Fixed a warning<commit_after>extern crate byteorder;

use std;
use std::io::Write;
use self::byteorder::NativeEndian;
use self::byteorder::WriteBytesExt;

/// Represents a value in the scalar set.
/// The values must be able to store booking information
/// for managing the contents of the set. These requirements
/// are captured in this trait.
pub trait Value
{
    /// Gets the index of the bucket for this value.
    fn get_bucket_index(
        &self,
        buckets: &Self,
    ) -> usize;

    /// Gets a zero.
    fn zero() -> Self;

    /// Gets the integer value as a size.
    fn as_index( &self ) -> usize;

    /// Converts the number of buckets into the value type.i
    fn from_bucket_count( bucket_count: &usize ) -> Self;

    /// Converts the number of set members into the value type.
    fn from_member_count( member_count: usize ) -> Self;

    /// Converts the given index into the value type.
    fn from_index( index: usize ) -> Self;

    /// Decrements the value by one.
    fn decrement( &self ) -> Self;

    /// Provides total ordering for elements.
    fn cmp(
        &self,
        other: &Self,
    ) -> std::cmp::Ordering;

    /// Serializes the value.
    fn serialize(
        &self,
        &mut Write,
    ) -> Result<(), std::io::Error>;
}

/// Implements Value trait for i32
impl Value for i32
{
    /// Gets the index of the bucket for this value.
    fn get_bucket_index(
        &self,
        buckets: &i32,
    ) -> usize
    {
        return ( self.clone() as usize ) % ( buckets.clone() as usize );
    }

    /// Gets a zero.
    fn zero() -> i32
    {
        return 0;
    }

    /// Gets the integer value as a size.
    fn as_index( &self ) -> usize
    {
        return self.clone() as usize;
    }

    /// Converts the specified value to a value that can be stored in the container.
    fn from_bucket_count( bucket_count: &usize ) -> i32
    {
        return bucket_count.clone() as i32;
    }

    /// Converts the number of set members into the value type.
    fn from_member_count( member_count: usize ) -> i32
    {
        return member_count as i32;
    }

    /// Converts the given value to index.
    fn from_index( index: usize ) -> i32
    {
        return index as i32;
    }

    /// Decrements the value by one.
    fn decrement( &self ) -> i32
    {
        return self - 1;
    }

    /// Provides total ordering for elements.
    fn cmp(
        &self,
        other: &i32,
    ) -> std::cmp::Ordering
    {
        std::cmp::Ord::cmp( self, other )
    }

    /// Serializes the value.
    fn serialize(
        &self,
        writer: &mut Write,
    ) -> Result<(), std::io::Error>
    {
        writer.write_i32::<NativeEndian>( *self )?;
        Ok( () )
    }
}

/// Implements Value trait for f32
/// * The largest permissible value is 2^24.
/// * Mainly implemented to provide an easy to use interface for sending the structure to GPU.
#[cfg(any(feature = "floats", test))]
impl Value for f32
{
    /// Gets the index of the bucket for this value.
    fn get_bucket_index(
        &self,
        buckets: &f32,
    ) -> usize
    {
        return ( self.clone() as usize ) % ( buckets.clone() as usize );
    }

    /// Gets a zero.
    fn zero() -> f32
    {
        return 0.0;
    }

    /// Gets the integer value as a size.
    fn as_index( &self ) -> usize
    {
        return self.clone() as usize;
    }

    /// Converts the specified value to a value that can be stored in the container.
    fn from_bucket_count( bucket_count: &usize ) -> f32
    {
        return bucket_count.clone() as f32;
    }

    /// Converts the number of set members into the value type.
    fn from_member_count( member_count: usize ) -> f32
    {
        return member_count as f32;
    }

    /// Converts the given value to index.
    fn from_index( index: usize ) -> f32
    {
        return index as f32;
    }

    /// Decrements the value by one.
    fn decrement( &self ) -> f32
    {
        return self - 1.0;
    }

    /// Provides total ordering for Value elements.
    fn cmp(
        &self,
        other: &f32,
    ) -> std::cmp::Ordering
    {
        let me = self.clone() as i32;
        let other = other.clone() as i32;
        std::cmp::Ord::cmp( &me, &other )
    }

    /// Serializes the value.
    fn serialize(
        &self,
        writer: &mut Write,
    ) -> Result<(), std::io::Error>
    {
        writer.write_f32::<NativeEndian>( *self )?;
        Ok( () )
    }
}

/// The index or position in the array that holds the number of members in the set.
const SIZE_INDEX: usize = 1;

/// The index or position in the array that holds the index to the first value of the first bucket.
const FIRST_BUCKET_INDEX: usize = 2;

/// Defines how the data is stored in the scalar set.
enum Storage<'a, TA, TB>
where
    TB: 'a,
{
    /// The data is stored as a vector.
    Vector
    { data: Vec<TA> },

    /// The data is stored in a slice. Not owned by the scalar set.
    Slice
    { data: &'a [TB] },
}

/// Scalar set cabable of storing values with Value trait.
pub struct RoScalarSet<'a, T>
where
    T: std::clone::Clone + Value + 'a,
{
    _storage: Storage<'a, T, T>,
}

impl<'a, T> Clone for RoScalarSet<'a, T>
where
    T: std::clone::Clone + Value + 'a,
{
    /// Returns a copy of the set.
    fn clone( &self ) -> Self
    {
        RoScalarSet::new( self.borrow_values() )
    }

    /// Copies the content from the given set.alloc
    fn clone_from(
        &mut self,
        source: &Self,
    )
    {
        let storage = RoScalarSet::create_storage( source.borrow_values() );
        self._storage = storage;
    }
}

impl<'a, T> RoScalarSet<'a, T>
where
    T: std::clone::Clone + Value + 'a,
{
    /// Returns a new integer hash set holding the specified values.
    ///
    /// # ArgumentRoScalarSets
    ///
    /// * 'values' Holds the values stored in the hash set.
    pub fn new<'b, 'c>( values: &'c [T] ) -> RoScalarSet<'b, T>
    {
        let storage = RoScalarSet::create_storage( values );
        return RoScalarSet { _storage: storage };
    }

    /// Attaches an integer hash set to a slice holding the values.
    ///
    /// # ArgumentRoScalarSets
    ///
    /// * 'values' Slice that holds the values stored in the hash set.
    pub fn attach<'b>( buffer: &'b [T] ) -> Result<( RoScalarSet<'b, T>, &'b [T] ), &str>
    {
        // Determine the length of this scalar set.
        if buffer.len() < 4
        {
            return Err( "The buffer is to small" );
        }
        let buckets = buffer[0].as_index();
        let values = buffer[SIZE_INDEX].as_index();
        let total_size = FIRST_BUCKET_INDEX + ( buckets + 1 ) + values;

        // Attach.
        let ( set, remainder ) = buffer.split_at( total_size );
        let storage: Storage<T, T> = Storage::Slice { data: set };
        return Ok( ( RoScalarSet { _storage: storage }, remainder ) );
    }

    /// Checks if any the sets have anything in common.
    pub fn any(
        &self,
        other: &RoScalarSet<T>,
    ) -> bool
    {
        // Determine the smaller set.
        let small;
        let large;
        if other.size() < self.size()
        {
            small = other;
            large = self;
        }
        else
        {
            small = self;
            large = other;
        }

        // For better performance we iterate the smaller set.
        for s in small.borrow_values()
        {
            if large.contains( s )
            {
                return true;
            }
        }

        // Values was not found.
        return false;
    }

    /// Checks whether the given value exists in the set or not.
    pub fn contains(
        &self,
        value: &T,
    ) -> bool
    {
        // Get the bucket associated with the value.
        let bucket = self.get_bucket( &value );

        // Locate the value.
        match bucket.binary_search_by( |probe| probe.cmp( &value ) )
        {
            Ok( _ ) => return true,
            Err( _ ) => return false,
        }
    }

    /// Gets the number of members in the set.
    pub fn size( &self ) -> usize
    {
        let storage = self.borrow_storage();
        return storage[SIZE_INDEX].as_index();
    }

    /// Gets the number of buckets.
    pub fn bucket_count( &self ) -> usize
    {
        let storage = self.borrow_storage();
        return storage[0].as_index();
    }

    /// Serializes the scalar set into the given writer.
    pub fn serialize<W>(
        &self,
        writer: &mut W,
    ) -> Result<(), std::io::Error>
    where
        W: Write,
    {
        // Write our intern
        let storage = self.borrow_storage();
        for v in storage
        {
            v.serialize( writer )?;
        }
        Ok( () )
    }

    /// Gets a read-only slice containing the values of a bucket that holdes the given value.
    fn get_bucket(
        &self,
        value: &T,
    ) -> &[T]
    {
        // Determine the bucket.
        let storage = self.borrow_storage();
        let bucket_id: usize = value.get_bucket_index( &storage[0] );
        let bucket_index = bucket_id + FIRST_BUCKET_INDEX;
        let begin: usize = storage[bucket_index].as_index();
        let end: usize = storage[( bucket_index + 1 )].as_index();
        let ( _, remainder ) = storage.split_at( begin );
        let ( bucket, _ ) = remainder.split_at( end - begin );
        return bucket;
    }

    /// Borrows the values of the set.
    fn borrow_values( &'a self ) -> &'a [T]
    {
        // Split the value part from the storage.
        let start = FIRST_BUCKET_INDEX + self.bucket_count() + 1;
        let ( _, values ) = self.borrow_storage().split_at( start );
        return values;
    }

    /// Borrows the storage for accessing the values.
    fn borrow_storage( &'a self ) -> &'a [T]
    {
        let s: &'a [T] = match &self._storage
        {
            &Storage::Vector { ref data } => data.as_slice(),
            &Storage::Slice { ref data } => data,
        };
        return s;
    }

    /// Creates a new storage buffer from the given values.
    fn create_storage( values: &[T] ) -> Storage<'a, T, T>
    {
        // Determine the number of buckets. We introduce a 5% overhead.
        let bucket_count: usize = ( values.len() as f64 * 0.05 ).ceil() as usize;
        let mut storage: Vec<T> = vec![T::zero(); FIRST_BUCKET_INDEX + bucket_count + 1 + values.len()];

        // Store the number of buckets.
        let buckets = T::from_bucket_count( &bucket_count );
        storage[0] = buckets.clone();

        // Store the number of members.
        storage[SIZE_INDEX] = T::from_member_count( values.len() );

        // Count the values required for each bucket.
        let mut values_in_buckets: Vec<i32> = vec![0; bucket_count];
        for v in values
        {
            let bucket = v.get_bucket_index( &buckets );
            values_in_buckets[bucket] += 1;
        }

        // Set bucket pointers to point the end of each bucket.
        // This way we can use the bucket pointers to track the next empty position when
        // distributing the values into the buckets.
        let first_bucket: usize = FIRST_BUCKET_INDEX;
        let data_start: usize = FIRST_BUCKET_INDEX + bucket_count + 1;
        let mut previous_bucket_end = data_start;
        for b in 0..bucket_count
        {
            // The end of the previous bucket is the start of the previous bucket.
            let index = previous_bucket_end + values_in_buckets[b].as_index();
            storage[b + first_bucket] = T::from_index( index );
            previous_bucket_end = index;
        }

        // Fix the end of the last bucket.
        storage[first_bucket + bucket_count] = T::from_index( storage.len() );

        // Put values into buckets.
        for v in values
        {
            // Determine bucket for the value.
            let bucket_id = v.get_bucket_index( &buckets );

            // Make room for the new value.
            storage[bucket_id + first_bucket] = storage[bucket_id + first_bucket].decrement();
            let value_index: usize = storage[bucket_id + first_bucket].as_index();

            // And finally store the value.
            storage[value_index] = v.clone();
        }

        // Sort each bucket to enable binary search.
        for b in 0..bucket_count
        {
            // Determine the location of the bucket.
            let begin: usize = storage[b + first_bucket].as_index();
            let end: usize = storage[b + first_bucket + 1].as_index();
            if end < begin
            {
                panic!( "Invalid bucket: {}", b );
            }

            // Get a splice that represents the bucket and sort it.
            let ( _, remainder ) = storage.split_at_mut( begin );
            let ( bucket, _ ) = remainder.split_at_mut( end - begin );
            bucket.sort_by( |a, b| a.cmp( b ) );
        }

        let storage: Storage<'a, T, T> = Storage::Vector { data: storage };
        storage
    }
}
<|endoftext|>


<commit_before>use byteorder::{LittleEndian, WriteBytesExt};
use rustc_serialize::{Decodable, Encodable};
use std::collections::HashMap;
use std;
use super::{Decoder, Encoder};
use super::error::Error;

pub fn decode<T: std::io::Read>(data: &mut T) -> Result<HashMap<String, String>, Error> {
    let mut decoder = Decoder::new(data);
    let length = decoder.pop_length()? as usize;
    let mut result = HashMap::<String, String>::new();
    let mut size_count = 0;
    while length > size_count {
        let point = String::decode(&mut decoder)?;
        size_count += point.len() + 4;
        let mut point = point.splitn(2, '=');
        let key = point.next().ok_or(Error::UnsupportedData)?;
        let value = point.next().ok_or(Error::UnsupportedData)?;
        result.insert(String::from(key), String::from(value));
    }
    Ok(result)
}

pub fn encode<T: std::io::Write>(data: HashMap<String, String>,
                                 buffer: &mut T)
                                 -> Result<(), Error> {
    let mut encoder = Encoder::new();
    for (key, value) in data {
        [key, value].join("=").encode(&mut encoder)?;
    }
    buffer.write_u32::<LittleEndian>(encoder.len() as u32)?;
    encoder.write_to(buffer).map_err(|v| Error::Io(v))
}
<commit_msg>Add tests for TCPROS header<commit_after>use byteorder::{LittleEndian, WriteBytesExt};
use rustc_serialize::{Decodable, Encodable};
use std::collections::HashMap;
use std;
use super::{Decoder, Encoder};
use super::error::Error;

pub fn decode<T: std::io::Read>(data: &mut T) -> Result<HashMap<String, String>, Error> {
    let mut decoder = Decoder::new(data);
    let length = decoder.pop_length()? as usize;
    let mut result = HashMap::<String, String>::new();
    let mut size_count = 0;
    while length > size_count {
        let point = String::decode(&mut decoder)?;
        size_count += point.len() + 4;
        let mut point = point.splitn(2, '=');
        let key = point.next().ok_or(Error::UnsupportedData)?;
        let value = point.next().ok_or(Error::UnsupportedData)?;
        result.insert(String::from(key), String::from(value));
    }
    Ok(result)
}

pub fn encode<T: std::io::Write>(data: HashMap<String, String>,
                                 buffer: &mut T)
                                 -> Result<(), Error> {
    let mut encoder = Encoder::new();
    for (key, value) in data {
        [key, value].join("=").encode(&mut encoder)?;
    }
    buffer.write_u32::<LittleEndian>(encoder.len() as u32)?;
    encoder.write_to(buffer).map_err(|v| Error::Io(v))
}

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

    #[test]
    fn writes_empty_map() {
        let mut cursor = std::io::Cursor::new(Vec::new());
        let data = HashMap::<String, String>::new();
        encode(data, &mut cursor).unwrap();
        assert_eq!(vec![0, 0, 0, 0], cursor.into_inner());
    }

    #[test]
    fn writes_single_item() {
        let mut cursor = std::io::Cursor::new(Vec::new());
        let mut data = HashMap::<String, String>::new();
        data.insert(String::from("abc"), String::from("123"));
        encode(data, &mut cursor).unwrap();
        assert_eq!(vec![11, 0, 0, 0, 7, 0, 0, 0, 97, 98, 99, 61, 49, 50, 51],
                   cursor.into_inner());
    }

    #[test]
    fn reads_empty_map() {
        let input = vec![0, 0, 0, 0];
        let data = decode(&mut std::io::Cursor::new(input)).unwrap();
        assert_eq!(0, data.len());
    }

    #[test]
    fn reads_single_element() {
        let input = vec![11, 0, 0, 0, 7, 0, 0, 0, 97, 98, 99, 61, 49, 50, 51];
        let data = decode(&mut std::io::Cursor::new(input)).unwrap();
        assert_eq!(1, data.len());
        assert_eq!(Some(&String::from("123")), data.get("abc"));
    }

    #[test]
    fn reads_typical_header() {
        let input = vec![0xb0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x6d, 0x65, 0x73, 0x73,
                         0x61, 0x67, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69,
                         0x6f, 0x6e, 0x3d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x61,
                         0x74, 0x61, 0x0a, 0x0a, 0x25, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6c, 0x6c,
                         0x65, 0x72, 0x69, 0x64, 0x3d, 0x2f, 0x72, 0x6f, 0x73, 0x74, 0x6f, 0x70,
                         0x69, 0x63, 0x5f, 0x34, 0x37, 0x36, 0x37, 0x5f, 0x31, 0x33, 0x31, 0x36,
                         0x39, 0x31, 0x32, 0x37, 0x34, 0x31, 0x35, 0x35, 0x37, 0x0a, 0x00, 0x00,
                         0x00, 0x6c, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x3d, 0x31, 0x27,
                         0x00, 0x00, 0x00, 0x6d, 0x64, 0x35, 0x73, 0x75, 0x6d, 0x3d, 0x39, 0x39,
                         0x32, 0x63, 0x65, 0x38, 0x61, 0x31, 0x36, 0x38, 0x37, 0x63, 0x65, 0x63,
                         0x38, 0x63, 0x38, 0x62, 0x64, 0x38, 0x38, 0x33, 0x65, 0x63, 0x37, 0x33,
                         0x63, 0x61, 0x34, 0x31, 0x64, 0x31, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x6f,
                         0x70, 0x69, 0x63, 0x3d, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x74, 0x65, 0x72,
                         0x14, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x73, 0x74, 0x64,
                         0x5f, 0x6d, 0x73, 0x67, 0x73, 0x2f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67];
        let data = decode(&mut std::io::Cursor::new(input)).unwrap();
        assert_eq!(6, data.len());
        assert_eq!(Some(&String::from("string data\n\n")),
                   data.get("message_definition"));
        assert_eq!(Some(&String::from("/rostopic_4767_1316912741557")),
                   data.get("callerid"));
        assert_eq!(Some(&String::from("1")), data.get("latching"));
        assert_eq!(Some(&String::from("992ce8a1687cec8c8bd883ec73ca41d1")),
                   data.get("md5sum"));
        assert_eq!(Some(&String::from("/chatter")), data.get("topic"));
        assert_eq!(Some(&String::from("std_msgs/String")), data.get("type"));
    }
}
<|endoftext|>


<commit_before>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;
use std::cmp;

use super::StreamProducer;

#[derive(Debug)]
pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  Continue,
  EndOfInput,
  Unknown,
}

// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  // Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  // Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  // Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          let consumed = self.len() - i.len();

          self.offset += consumed;

          Err(ErrorKind::Consumed(consumed))
        } else {
          Err(ErrorKind::Unknown)
        }
      }
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  // Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => self.needed = needed,
          ErrorKind::Consumed(consumed) => buffer.consume(consumed),
          _                             => (),
        }

        Err(kind)
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::be_u32;

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<commit_msg>Return `ErrorKind::Continue` when appropriate<commit_after>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;
use std::cmp;

use super::StreamProducer;

#[derive(Debug)]
pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  Continue,
  EndOfInput,
  Unknown,
}

// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  // Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  // Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  // Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          let consumed = self.len() - i.len();

          self.offset += consumed;

          Err(ErrorKind::Consumed(consumed))
        } else {
          Err(ErrorKind::Unknown)
        }
      }
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  // Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => {
            self.needed = needed;

            Err(ErrorKind::Continue)
          }
          ErrorKind::Consumed(consumed) => {
            buffer.consume(consumed);

            Err(ErrorKind::Continue)
          }
          _                             => Err(kind),
        }
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::be_u32;

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<|endoftext|>


<commit_before>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;
use std::cmp;

#[derive(Debug)]
pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  EndOfInput,
  Unknown,
}

pub trait StreamProducer {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T>;
}

pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          self.offset += self.len() - i.len();
        }

        Err(ErrorKind::Unknown)
      }
    }
  }
}

pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => self.needed = needed,
          ErrorKind::Consumed(consumed) => buffer.consume(consumed),
          _                             => (),
        }

        Err(kind)
      }
    }
  }
}

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

  #[test]
  fn test_buffer() {
    let buffer = Buffer::new();

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);
  }
}
<commit_msg>Add test for `Buffer::fill`<commit_after>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;
use std::cmp;

#[derive(Debug)]
pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  EndOfInput,
  Unknown,
}

pub trait StreamProducer {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T>;
}

pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          self.offset += self.len() - i.len();
        }

        Err(ErrorKind::Unknown)
      }
    }
  }
}

pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => self.needed = needed,
          ErrorKind::Consumed(consumed) => buffer.consume(consumed),
          _                             => (),
        }

        Err(kind)
      }
    }
  }
}

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

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);
  }
}
<|endoftext|>


<commit_before>extern crate glium;

use rand::{thread_rng, Rng};
use std::rc::Rc;
use std::convert::Into;
use std::convert::From;

use draw::Vertex;
use glium::backend::Facade;
use draw::display_object::{Frame,Drawable,HasFrame};
use draw::shaders::ShaderManager;
use glium::program::Program;
use glium::{VertexBuffer,IndexBuffer,Surface};
use na::{Mat4};
use glium::uniforms::AsUniformValue;

#[derive(Debug, Copy, Clone)]
pub enum TerrainType {
	Water,
	Grass,
	TallGrass,
	Sand,
	Snow,
	Tundra
}

#[derive(Debug)]
pub struct Tile {
	typ:TerrainType,
	height:f32,
}

pub struct Terrain {
	data:Vec<Tile>,
	frame:Frame<f32>,
	shader:Rc<Program>,
	vertex_buffer:VertexBuffer<Vertex>,
	index_buffer:IndexBuffer<u16>,
}

impl Terrain {
	pub fn new<F>(display: &F, shader_manager: &mut ShaderManager, size:u16) -> Terrain where F: Facade + Clone {
		// load the shader
		let shader = shader_manager.load(display,"identity.vert","identity.frag").unwrap();

		// fill up the terrain with random tiles
		let choices = [
			TerrainType::Water,
			TerrainType::Grass,
			TerrainType::TallGrass,
			TerrainType::Sand,
			TerrainType::Snow,
			TerrainType::Tundra,
		];
		let mut rng = thread_rng();
		let mut terrain_data = Vec::with_capacity((size*size) as usize);
		for n in 0..(size*size) {
			terrain_data.push(Tile { typ:*rng.choose(&choices).unwrap(), height:0f32 });
		}

		// generate the geometry

		// create the vertices
		let mut vertices = Vec::new();
		let size_f = size as f32;
		for index in 0..(size*size) {
			let index_f = index as f32;
			let row = index / size;
			let column = index % size;
			// TODO: generate the actual normals
			vertices.push(Vertex { position:[column as f32, row as f32, terrain_data[index as usize].height], texcoords:[column as f32/size_f,row as f32/size_f], normal:[0f32,0f32,1f32] });
		}

		// create the vertex buffer
		let vertex_buffer = glium::VertexBuffer::new(display,&vertices).unwrap();

		// create the indices
		let mut indices = Vec::new();
		let columnsize = size - 1;
		for index in 0..(columnsize*columnsize){
			let row = index / columnsize;
			let column = index % columnsize;
			// build the 2 triangles for this square
			let baseindex = row*size+column;
			indices.push(baseindex as u16);
			indices.push(baseindex+size as u16);
			indices.push(baseindex+size+1 as u16 );
			indices.push(baseindex as u16);
			indices.push(baseindex+size+1 as u16);
			indices.push(baseindex+1 as u16 );
		}

		// create the index buffer
		let index_buffer = glium::IndexBuffer::new(display, glium::index::PrimitiveType::TrianglesList, &indices).unwrap();

		// create the terrain data
		let mut terrain = Terrain {
			data:terrain_data,
			frame:Frame::<f32>::new(),
			shader:shader,
			vertex_buffer:vertex_buffer,
			index_buffer:index_buffer,
		};

		println!("{:?}", terrain.frame);

		terrain
	}
}

impl Drawable for Terrain {
	fn draw(&self, target:&mut glium::Frame, params:&glium::DrawParameters, mvp_matrix:&Mat4<f32>) {
		/*Into::<[[f32; 4]; 4]>::into(matrix)*/
		target.draw(&self.vertex_buffer,&self.index_buffer,self.shader.as_ref(),&uniform! { mvpMatrix:[[f32; 4]; 4].from(mvp_matrix) },params);
		//target.draw(&vertex_buffer,&indices,&program,&glium::uniforms::EmptyUniforms,&params).unwrap();
	}
}

impl HasFrame<f32> for Terrain {
	fn get_frame(&self) -> &Frame<f32> {
		&self.frame
	}
}<commit_msg>Succesfully converted it to a f32 matrix<commit_after>extern crate glium;

use rand::{thread_rng, Rng};
use std::rc::Rc;

use draw::Vertex;
use glium::backend::Facade;
use draw::display_object::{Frame,Drawable,HasFrame};
use draw::shaders::ShaderManager;
use glium::program::Program;
use glium::{VertexBuffer,IndexBuffer,Surface};
use na::{Mat4};
use glium::uniforms::AsUniformValue;

#[derive(Debug, Copy, Clone)]
pub enum TerrainType {
	Water,
	Grass,
	TallGrass,
	Sand,
	Snow,
	Tundra
}

#[derive(Debug)]
pub struct Tile {
	typ:TerrainType,
	height:f32,
}

pub struct Terrain {
	data:Vec<Tile>,
	frame:Frame<f32>,
	shader:Rc<Program>,
	vertex_buffer:VertexBuffer<Vertex>,
	index_buffer:IndexBuffer<u16>,
}

impl Terrain {
	pub fn new<F>(display: &F, shader_manager: &mut ShaderManager, size:u16) -> Terrain where F: Facade + Clone {
		// load the shader
		let shader = shader_manager.load(display,"identity.vert","identity.frag").unwrap();

		// fill up the terrain with random tiles
		let choices = [
			TerrainType::Water,
			TerrainType::Grass,
			TerrainType::TallGrass,
			TerrainType::Sand,
			TerrainType::Snow,
			TerrainType::Tundra,
		];
		let mut rng = thread_rng();
		let mut terrain_data = Vec::with_capacity((size*size) as usize);
		for n in 0..(size*size) {
			terrain_data.push(Tile { typ:*rng.choose(&choices).unwrap(), height:0f32 });
		}

		// generate the geometry

		// create the vertices
		let mut vertices = Vec::new();
		let size_f = size as f32;
		for index in 0..(size*size) {
			let index_f = index as f32;
			let row = index / size;
			let column = index % size;
			// TODO: generate the actual normals
			vertices.push(Vertex { position:[column as f32, row as f32, terrain_data[index as usize].height], texcoords:[column as f32/size_f,row as f32/size_f], normal:[0f32,0f32,1f32] });
		}

		// create the vertex buffer
		let vertex_buffer = glium::VertexBuffer::new(display,&vertices).unwrap();

		// create the indices
		let mut indices = Vec::new();
		let columnsize = size - 1;
		for index in 0..(columnsize*columnsize){
			let row = index / columnsize;
			let column = index % columnsize;
			// build the 2 triangles for this square
			let baseindex = row*size+column;
			indices.push(baseindex as u16);
			indices.push(baseindex+size as u16);
			indices.push(baseindex+size+1 as u16 );
			indices.push(baseindex as u16);
			indices.push(baseindex+size+1 as u16);
			indices.push(baseindex+1 as u16 );
		}

		// create the index buffer
		let index_buffer = glium::IndexBuffer::new(display, glium::index::PrimitiveType::TrianglesList, &indices).unwrap();

		// create the terrain data
		let mut terrain = Terrain {
			data:terrain_data,
			frame:Frame::<f32>::new(),
			shader:shader,
			vertex_buffer:vertex_buffer,
			index_buffer:index_buffer,
		};

		println!("{:?}", terrain.frame);

		terrain
	}
}

impl Drawable for Terrain {
	fn draw(&self, target:&mut glium::Frame, params:&glium::DrawParameters, mvp_matrix:&Mat4<f32>) {
		/*Into::<[[f32; 4]; 4]>::into(matrix)*/
		target.draw(&self.vertex_buffer,&self.index_buffer,self.shader.as_ref(),&uniform! { mvpMatrix:*mvp_matrix.as_ref() },params);
		//target.draw(&vertex_buffer,&indices,&program,&glium::uniforms::EmptyUniforms,&params).unwrap();
	}
}

impl HasFrame<f32> for Terrain {
	fn get_frame(&self) -> &Frame<f32> {
		&self.frame
	}
}<|endoftext|>


<commit_before>#[doc="Creates CSS boxes from a DOM."]

import dom::base::{element, es_div, es_img, nk_element, nk_text, node};
import dom::rcu::reader_methods;
import gfx::geom;
import /*layout::*/base::{bk_block, bk_inline, bk_intrinsic, bk_text, box};
import /*layout::*/base::{box_kind, btree, node_methods, ntree, rd_tree_ops};
import /*layout::*/base::wr_tree_ops;
import /*layout::*/style::style::{di_block, di_inline, style_methods};
import /*layout::*/text::text_box;
import util::tree;

export box_builder_methods;

enum ctxt = {
    // The parent node that we're scanning.
    parent_node: node,
    // The parent box that these boxes will be added to.
    parent_box: @box,

    // The current anonymous box that we're currently appending inline nodes
    // to.
    //
    // See CSS2 9.2.1.1.
    mut anon_box: option<@box>
};

fn new_box(n: node, kind: box_kind) -> @box {
    @box({tree: tree::empty(),
          node: n,
          mut bounds: geom::zero_rect_au(),
          kind: kind })
}

fn create_context(parent_node: node, parent_box: @box) -> ctxt {
    ret ctxt({
        parent_node: parent_node,
        parent_box: parent_box,
        mut anon_box: none
    });
}

impl methods for ctxt {
    #[doc="
        Constructs boxes for the parent's children, when the parent's 'display'
        attribute is 'block'.
    "]
    fn construct_boxes_for_block_children() {
        for ntree.each_child(self.parent_node) {
            |kid|

            // Create boxes for the child. Get its primary box.
            let kid_box = kid.construct_boxes();

            // Determine the child's display.
            let disp = kid.get_computed_style().display;
            if disp != di_inline {
                self.finish_anonymous_box_if_necessary();
            }

            // Add the child's box to the current enclosing box or the current
            // anonymous box.
            alt kid.get_computed_style().display {
                di_block { btree.add_child(self.parent_box, kid_box); }
                di_inline {
                    let anon_box = alt self.anon_box {
                        none {
                            let b = new_box(kid, bk_inline);
                            self.anon_box = some(b);
                            b
                        }
                        some(b) { b }
                    };
                    btree.add_child(anon_box, kid_box);
                }
            }
        }
    }

    #[doc="
        Constructs boxes for the parent's children, when the parent's 'display'
        attribute is 'inline'.
    "]
    fn construct_boxes_for_inline_children() {
        // TODO
    }

    #[doc="Constructs boxes for the parent's children."]
    fn construct_boxes_for_children() {
        #debug("parent node:");
        self.parent_node.dump();

        alt self.parent_node.get_computed_style().display {
            di_block { self.construct_boxes_for_block_children(); }
            di_inline { self.construct_boxes_for_inline_children(); }
        }

        self.finish_anonymous_box_if_necessary();
        assert self.anon_box.is_none();
    }

    #[doc="
        Flushes the anonymous box we're creating if it exists. This appends the
        anonymous box to the block.
    "]
    fn finish_anonymous_box_if_necessary() {
        alt self.anon_box {
            none { /* Nothing to do. */ }
            some(b) { btree.add_child(self.parent_box, b); }
        }
        self.anon_box = none;
    }
}

impl box_builder_priv for node {
    #[doc="
        Determines the kind of box that this node needs. Also, for images,
        computes the intrinsic size.
    "]
    fn determine_box_kind() -> box_kind {
        alt self.rd({ |n| n.kind }) {
            ~nk_text(string) { bk_text(@text_box(string)) }
            ~nk_element(element) {
                alt *element.subclass {
                    es_div       { bk_block            }
                    es_img(size) { bk_intrinsic(@size) }
                    es_unknown   { bk_inline           }
                }
            }
        }
    }
}

impl box_builder_methods for node {
    #[doc="Creates boxes for this node. This is the entry point."]
    fn construct_boxes() -> @box {
        let box_kind = self.determine_box_kind();
        let my_box = new_box(self, box_kind);
        if box_kind == bk_block {
            let cx = create_context(self, my_box);
            cx.construct_boxes_for_children();
        }
        ret my_box;
    }
}

<commit_msg>Incomplete box construction for inline children<commit_after>#[doc="Creates CSS boxes from a DOM."]

import dom::base::{element, es_div, es_img, nk_element, nk_text, node};
import dom::rcu::reader_methods;
import gfx::geom;
import /*layout::*/base::{bk_block, bk_inline, bk_intrinsic, bk_text, box};
import /*layout::*/base::{box_kind, btree, node_methods, ntree, rd_tree_ops};
import /*layout::*/base::wr_tree_ops;
import /*layout::*/style::style::{di_block, di_inline, style_methods};
import /*layout::*/text::text_box;
import util::tree;

export box_builder_methods;

enum ctxt = {
    // The parent node that we're scanning.
    parent_node: node,
    // The parent box that these boxes will be added to.
    parent_box: @box,

    // The current anonymous box that we're currently appending inline nodes
    // to.
    //
    // See CSS2 9.2.1.1.
    mut anon_box: option<@box>
};

fn new_box(n: node, kind: box_kind) -> @box {
    @box({tree: tree::empty(),
          node: n,
          mut bounds: geom::zero_rect_au(),
          kind: kind })
}

fn create_context(parent_node: node, parent_box: @box) -> ctxt {
    ret ctxt({
        parent_node: parent_node,
        parent_box: parent_box,
        mut anon_box: none
    });
}

impl methods for ctxt {
    #[doc="
        Constructs boxes for the parent's children, when the parent's 'display'
        attribute is 'block'.
    "]
    fn construct_boxes_for_block_children() {
        for ntree.each_child(self.parent_node) {
            |kid|

            // Create boxes for the child. Get its primary box.
            let kid_box = kid.construct_boxes();

            // Determine the child's display.
            let disp = kid.get_computed_style().display;
            if disp != di_inline {
                self.finish_anonymous_box_if_necessary();
            }

            // Add the child's box to the current enclosing box or the current
            // anonymous box.
            alt kid.get_computed_style().display {
                di_block { btree.add_child(self.parent_box, kid_box); }
                di_inline {
                    let anon_box = alt self.anon_box {
                        none {
                            let b = new_box(kid, bk_inline);
                            self.anon_box = some(b);
                            b
                        }
                        some(b) { b }
                    };
                    btree.add_child(anon_box, kid_box);
                }
            }
        }
    }

    #[doc="
        Constructs boxes for the parent's children, when the parent's 'display'
        attribute is 'inline'.
    "]
    fn construct_boxes_for_inline_children() {
        for ntree.each_child(self.parent_node) {
            |kid|

            // Construct boxes for the child. Get its primary box.
            let kid_box = kid.construct_boxes();

            // Determine the child's display.
            let disp = kid.get_computed_style().display;
            if disp != di_inline {
                // TODO
            }

            // Add the child's box to the current enclosing box.
            alt kid.get_computed_style().display {
                di_block {
                    // TODO
                    #warn("TODO: non-inline display found inside inline box");
                    btree.add_child(self.parent_box, kid_box);
                }
                di_inline {
                    btree.add_child(self.parent_box, kid_box);
                }
            }
        }
    }

    #[doc="Constructs boxes for the parent's children."]
    fn construct_boxes_for_children() {
        #debug("parent node:");
        self.parent_node.dump();

        alt self.parent_node.get_computed_style().display {
            di_block { self.construct_boxes_for_block_children(); }
            di_inline { self.construct_boxes_for_inline_children(); }
        }

        self.finish_anonymous_box_if_necessary();
        assert self.anon_box.is_none();
    }

    #[doc="
        Flushes the anonymous box we're creating if it exists. This appends the
        anonymous box to the block.
    "]
    fn finish_anonymous_box_if_necessary() {
        alt self.anon_box {
            none { /* Nothing to do. */ }
            some(b) { btree.add_child(self.parent_box, b); }
        }
        self.anon_box = none;
    }
}

impl box_builder_priv for node {
    #[doc="
        Determines the kind of box that this node needs. Also, for images,
        computes the intrinsic size.
    "]
    fn determine_box_kind() -> box_kind {
        alt self.rd({ |n| n.kind }) {
            ~nk_text(string) { bk_text(@text_box(string)) }
            ~nk_element(element) {
                alt *element.subclass {
                    es_div       { bk_block            }
                    es_img(size) { bk_intrinsic(@size) }
                    es_unknown   { bk_inline           }
                }
            }
        }
    }
}

impl box_builder_methods for node {
    #[doc="Creates boxes for this node. This is the entry point."]
    fn construct_boxes() -> @box {
        let box_kind = self.determine_box_kind();
        let my_box = new_box(self, box_kind);
        alt box_kind {
            bk_block | bk_inline {
                let cx = create_context(self, my_box);
                cx.construct_boxes_for_children();
            }
            _ {
                // Nothing to do.
            }
        }
        ret my_box;
    }
}

<|endoftext|>


<commit_before>//! general purpose combinators

#![allow(unused_imports)]

#[cfg(feature = "alloc")]
use lib::std::boxed::Box;

#[cfg(feature = "std")]
use lib::std::fmt::Debug;
use internal::*;
use error::ParseError;
use traits::{AsChar, InputIter, InputLength, InputTakeAtPosition};
use traits::{need_more, need_more_err, AtEof, ParseTo};
use lib::std::ops::{Range, RangeFrom, RangeTo};
use traits::{Compare, CompareResult, Offset, Slice};
use error::ErrorKind;
use lib::std::mem::transmute;

#[macro_use]
mod macros;

#[cfg(feature = "alloc")]
#[inline]
pub fn tag_cl<'a, 'b>(rec: &'a [u8]) -> Box<Fn(&'b [u8]) -> IResult<&'b [u8], &'b [u8]> + 'a> {
  Box::new(move |i: &'b [u8]| -> IResult<&'b [u8], &'b [u8]> {
    if i.len() >= rec.len() && &i[0..rec.len()] == rec {
      Ok((&i[rec.len()..], &i[0..rec.len()]))
    } else {
      let e: ErrorKind = ErrorKind::TagClosure;
      Err(Err::Error(error_position!(i, e)))
    }
  })
}

#[cfg(feature = "std")]
#[inline]
pub fn print<T: Debug>(input: T) -> IResult<T, ()> {
  println!("{:?}", input);
  Ok((input, ()))
}

#[inline]
pub fn begin(input: &[u8]) -> IResult<(), &[u8]> {
  Ok(((), input))
}

pub fn sized_buffer<'a, E: ParseError<&'a[u8]>>(input: &'a[u8]) -> IResult<&'a[u8], &'a[u8], E> {
  if input.is_empty() {
    return need_more(input, Needed::Unknown);
  }

  let len = input[0] as usize;

  if input.len() >= len + 1 {
    Ok((&input[len + 1..], &input[1..len + 1]))
  } else {
    need_more(input, Needed::Size(1 + len))
  }
}

/// Recognizes non empty buffers
#[inline]
pub fn non_empty<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
where
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
  T: InputLength + AtEof,
{
  if input.input_len() == 0 {
    return need_more_err(input, Needed::Unknown, ErrorKind::NonEmpty);
  } else {
    Ok((input.slice(input.input_len()..), input))
  }
}

/// Return the remaining input.
#[inline]
pub fn rest<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
where
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
  T: InputLength,
{
  Ok((input.slice(input.input_len()..), input))
}

/// Return the length of the remaining input.
#[inline]
pub fn rest_len<T, E: ParseError<T>>(input: T) -> IResult<T, usize, E>
where
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
  T: InputLength,
{
  let len = input.input_len();
  Ok((input, len))
}

/// Return the remaining input, for strings.
#[inline]
pub fn rest_s<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> {
  Ok((&input[input.len()..], input))
}

pub fn map<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(O1) -> O2,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    Ok((input, second(o1)))
  }
}

pub fn map_res<I: Clone, O1, O2, E: ParseError<I>, E2, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(O1) -> Result<O2, E2>,
{
  move |input: I| {
    let i = input.clone();
    let (input, o1) = first(input)?;
    match second(o1) {
      Ok(o2) => Ok((input, o2)),
      Err(_) => Err(Err::Error(E::from_error_kind(i, ErrorKind::MapRes))),
    }
  }
}

pub fn opt<I:Clone, O, E: ParseError<I>, F>(f: F) -> impl Fn(I) -> IResult<I, Option<O>, E>
where
  F: Fn(I) -> IResult<I, O, E>,
{
  move |input: I| {
    let i = input.clone();
    match f(input) {
      Ok((i, o)) => Ok((i, Some(o))),
      Err(Err::Error(_)) => Ok((i, None)),
      Err(e) => Err(e),
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use internal::{Err, IResult, Needed};
  use error::ParseError;

  macro_rules! assert_parse(
    ($left: expr, $right: expr) => {
      let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
      assert_eq!(res, $right);
    };
  );

  #[test]
  #[cfg(feature = "alloc")]
  fn tag_closure() {
    let x = tag_cl(&b"abcd"[..]);
    let r = x(&b"abcdabcdefgh"[..]);
    assert_eq!(r, Ok((&b"abcdefgh"[..], &b"abcd"[..])));

    let r2 = x(&b"abcefgh"[..]);
    assert_eq!(
      r2,
      Err(Err::Error(error_position!(
        &b"abcefgh"[..],
        ErrorKind::TagClosure
      ),))
    );
  }

  #[test]
  #[cfg(feature = "alloc")]
  fn buffer_with_size() {
    use lib::std::vec::Vec;
    let i: Vec<u8> = vec![7, 8];
    let o: Vec<u8> = vec![4, 5, 6];
    //let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let arr: [u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let res = sized_buffer::<(_, ErrorKind)>(&arr[..]);
    assert_eq!(res, Ok((&i[..], &o[..])))
  }

  /*#[test]
  fn t1() {
    let v1:Vec<u8> = vec![1,2,3];
    let v2:Vec<u8> = vec![4,5,6];
    let d = Ok((&v1[..], &v2[..]));
    let res = d.flat_map(print);
    assert_eq!(res, Ok((&v2[..], ())));
  }*/

  /*
    #[test]
    fn end_of_input() {
        let not_over = &b"Hello, world!"[..];
        let is_over = &b""[..];
        named!(eof_test, eof!());

        let res_not_over = eof_test(not_over);
        assert_eq!(res_not_over, Err(Err::Error(error_position!(not_over, ErrorKind::Eof))));

        let res_over = eof_test(is_over);
        assert_eq!(res_over, Ok((is_over, is_over)));
    }
    */

  #[test]
  fn rest_on_slices() {
    let input: &[u8] = &b"Hello, world!"[..];
    let empty: &[u8] = &b""[..];
    assert_parse!(rest(input), Ok((empty, input)));
  }

  #[test]
  fn rest_on_strs() {
    let input: &str = "Hello, world!";
    let empty: &str = "";
    assert_parse!(rest(input), Ok((empty, input)));
  }

  #[test]
  fn rest_len_on_slices() {
    let input: &[u8] = &b"Hello, world!"[..];
    assert_parse!(rest_len(input), Ok((input, input.len())));
  }

  use lib::std::convert::From;
  impl From<u32> for CustomError {
    fn from(_: u32) -> Self {
      CustomError
    }
  }

  impl<I> ParseError<I> for CustomError {
    fn from_error_kind(_: I, _: ErrorKind) -> Self {
      CustomError
    }

    fn append(_: I, _: ErrorKind, _: CustomError) -> Self {
      CustomError
    }
  }

  struct CustomError;
  #[allow(dead_code)]
  fn custom_error(input: &[u8]) -> IResult<&[u8], &[u8], CustomError> {
    //fix_error!(input, CustomError, alphanumeric)
    ::character::streaming::alphanumeric(input)
  }

}
<commit_msg>add flat_map combinator<commit_after>//! general purpose combinators

#![allow(unused_imports)]

#[cfg(feature = "alloc")]
use lib::std::boxed::Box;

#[cfg(feature = "std")]
use lib::std::fmt::Debug;
use internal::*;
use error::ParseError;
use traits::{AsChar, InputIter, InputLength, InputTakeAtPosition};
use traits::{need_more, need_more_err, AtEof, ParseTo};
use lib::std::ops::{Range, RangeFrom, RangeTo};
use traits::{Compare, CompareResult, Offset, Slice};
use error::ErrorKind;
use lib::std::mem::transmute;

#[macro_use]
mod macros;

#[cfg(feature = "alloc")]
#[inline]
pub fn tag_cl<'a, 'b>(rec: &'a [u8]) -> Box<Fn(&'b [u8]) -> IResult<&'b [u8], &'b [u8]> + 'a> {
  Box::new(move |i: &'b [u8]| -> IResult<&'b [u8], &'b [u8]> {
    if i.len() >= rec.len() && &i[0..rec.len()] == rec {
      Ok((&i[rec.len()..], &i[0..rec.len()]))
    } else {
      let e: ErrorKind = ErrorKind::TagClosure;
      Err(Err::Error(error_position!(i, e)))
    }
  })
}

#[cfg(feature = "std")]
#[inline]
pub fn print<T: Debug>(input: T) -> IResult<T, ()> {
  println!("{:?}", input);
  Ok((input, ()))
}

#[inline]
pub fn begin(input: &[u8]) -> IResult<(), &[u8]> {
  Ok(((), input))
}

pub fn sized_buffer<'a, E: ParseError<&'a[u8]>>(input: &'a[u8]) -> IResult<&'a[u8], &'a[u8], E> {
  if input.is_empty() {
    return need_more(input, Needed::Unknown);
  }

  let len = input[0] as usize;

  if input.len() >= len + 1 {
    Ok((&input[len + 1..], &input[1..len + 1]))
  } else {
    need_more(input, Needed::Size(1 + len))
  }
}

/// Recognizes non empty buffers
#[inline]
pub fn non_empty<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
where
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
  T: InputLength + AtEof,
{
  if input.input_len() == 0 {
    return need_more_err(input, Needed::Unknown, ErrorKind::NonEmpty);
  } else {
    Ok((input.slice(input.input_len()..), input))
  }
}

/// Return the remaining input.
#[inline]
pub fn rest<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
where
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
  T: InputLength,
{
  Ok((input.slice(input.input_len()..), input))
}

/// Return the length of the remaining input.
#[inline]
pub fn rest_len<T, E: ParseError<T>>(input: T) -> IResult<T, usize, E>
where
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
  T: InputLength,
{
  let len = input.input_len();
  Ok((input, len))
}

/// Return the remaining input, for strings.
#[inline]
pub fn rest_s<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> {
  Ok((&input[input.len()..], input))
}

pub fn map<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(O1) -> O2,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    Ok((input, second(o1)))
  }
}

pub fn map_res<I: Clone, O1, O2, E: ParseError<I>, E2, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(O1) -> Result<O2, E2>,
{
  move |input: I| {
    let i = input.clone();
    let (input, o1) = first(input)?;
    match second(o1) {
      Ok(o2) => Ok((input, o2)),
      Err(_) => Err(Err::Error(E::from_error_kind(i, ErrorKind::MapRes))),
    }
  }
}

pub fn flat_map<I, O1, O2, E: ParseError<I>, F, G, H>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(O1) -> H,
  H: Fn(I) -> IResult<I, O2, E>
{
  move |input: I| {
    let (input, o1) = first(input)?;
    second(o1)(input)
  }
}

pub fn opt<I:Clone, O, E: ParseError<I>, F>(f: F) -> impl Fn(I) -> IResult<I, Option<O>, E>
where
  F: Fn(I) -> IResult<I, O, E>,
{
  move |input: I| {
    let i = input.clone();
    match f(input) {
      Ok((i, o)) => Ok((i, Some(o))),
      Err(Err::Error(_)) => Ok((i, None)),
      Err(e) => Err(e),
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use internal::{Err, IResult, Needed};
  use error::ParseError;

  macro_rules! assert_parse(
    ($left: expr, $right: expr) => {
      let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
      assert_eq!(res, $right);
    };
  );

  #[test]
  #[cfg(feature = "alloc")]
  fn tag_closure() {
    let x = tag_cl(&b"abcd"[..]);
    let r = x(&b"abcdabcdefgh"[..]);
    assert_eq!(r, Ok((&b"abcdefgh"[..], &b"abcd"[..])));

    let r2 = x(&b"abcefgh"[..]);
    assert_eq!(
      r2,
      Err(Err::Error(error_position!(
        &b"abcefgh"[..],
        ErrorKind::TagClosure
      ),))
    );
  }

  #[test]
  #[cfg(feature = "alloc")]
  fn buffer_with_size() {
    use lib::std::vec::Vec;
    let i: Vec<u8> = vec![7, 8];
    let o: Vec<u8> = vec![4, 5, 6];
    //let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let arr: [u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let res = sized_buffer::<(_, ErrorKind)>(&arr[..]);
    assert_eq!(res, Ok((&i[..], &o[..])))
  }

  /*#[test]
  fn t1() {
    let v1:Vec<u8> = vec![1,2,3];
    let v2:Vec<u8> = vec![4,5,6];
    let d = Ok((&v1[..], &v2[..]));
    let res = d.flat_map(print);
    assert_eq!(res, Ok((&v2[..], ())));
  }*/

  /*
    #[test]
    fn end_of_input() {
        let not_over = &b"Hello, world!"[..];
        let is_over = &b""[..];
        named!(eof_test, eof!());

        let res_not_over = eof_test(not_over);
        assert_eq!(res_not_over, Err(Err::Error(error_position!(not_over, ErrorKind::Eof))));

        let res_over = eof_test(is_over);
        assert_eq!(res_over, Ok((is_over, is_over)));
    }
    */

  #[test]
  fn rest_on_slices() {
    let input: &[u8] = &b"Hello, world!"[..];
    let empty: &[u8] = &b""[..];
    assert_parse!(rest(input), Ok((empty, input)));
  }

  #[test]
  fn rest_on_strs() {
    let input: &str = "Hello, world!";
    let empty: &str = "";
    assert_parse!(rest(input), Ok((empty, input)));
  }

  #[test]
  fn rest_len_on_slices() {
    let input: &[u8] = &b"Hello, world!"[..];
    assert_parse!(rest_len(input), Ok((input, input.len())));
  }

  use lib::std::convert::From;
  impl From<u32> for CustomError {
    fn from(_: u32) -> Self {
      CustomError
    }
  }

  impl<I> ParseError<I> for CustomError {
    fn from_error_kind(_: I, _: ErrorKind) -> Self {
      CustomError
    }

    fn append(_: I, _: ErrorKind, _: CustomError) -> Self {
      CustomError
    }
  }

  struct CustomError;
  #[allow(dead_code)]
  fn custom_error(input: &[u8]) -> IResult<&[u8], &[u8], CustomError> {
    //fix_error!(input, CustomError, alphanumeric)
    ::character::streaming::alphanumeric(input)
  }

}
<|endoftext|>