<commit_before>//! Return parsed property from a `Line`.

use std::iter::Iterator;
use std::io::BufRead;
use std::error::Error;
use std::fmt;

use ::line;

/// A parsed `Line`.
///
/// It's only split a raw line into the mains elements:
/// - name: Property name.
/// - params: Vector of key/value parameter.
/// - value: Property Value.
pub struct LineParsed {
    name: String,
    params: Option<Vec<(String, String)>>,
    value: String,
}

impl LineParsed {
    pub fn new() -> LineParsed {
        LineParsed {
            name: String::new(),
            params: None,
            value: String::new(),
        }
    }

    pub fn set_name(&mut self, name: &str) {
        self.name = name.to_uppercase();
    }

    pub fn set_value(&mut self, value: &str) {
        self.value = value.to_string();
    }

    pub fn set_parameters(&mut self, params: Option<Vec<(String, String)>>) {
        self.params = params;
    }

    pub fn add_parameter(&mut self, key: &str, value: &str) {
        let param = (key.to_uppercase(), value.to_string());

        match self.params {
            Some(ref mut list)  => list.push(param),
            None => self.params = Some(vec!(param)),
        };
    }
}

impl fmt::Display for LineParsed {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "name: {}\nparams: {:?}\nvalue: {}",
               self.name,
               self.params,
               self.value)
    }
}

/// A splitted `Line`.
pub struct LineParser<B> {
    line_reader: line::LineReader<B>,
}

impl<B: BufRead> LineParser<B> {
    pub fn new(line_reader: line::LineReader<B>) -> LineParser<B> {
        LineParser { line_reader: line_reader }
    }

    fn parse(&self, line: line::Line) -> Result<LineParsed, ParseError> {
        let mut property = LineParsed::new();

        // Parse name.
        let name = self.parse_name(line.as_str())
            .ok_or(ParseError::MissingName)?;
        property.set_name(name);

        // Parse value
        let value = self.parse_value(line.as_str())
            .ok_or(ParseError::MissingValue)?;
        property.set_value(value);

        // Parse parameters.
        let parameters = self.parse_parameters(line.as_str())?;
        property.set_parameters(parameters);
        Ok(property)

    }

    /// Return the name from the given `Line`.
    fn parse_name<'a>(&self, line: &'a str) -> Option<&'a str> {
        let end_name_index;

        let param_index = line.find(::PARAM_DELIMITER).unwrap_or(usize::max_value());
        let value_index = line.find(::VALUE_DELIMITER).unwrap_or(usize::max_value());

        if param_index < value_index {
            end_name_index = param_index;
        } else if value_index != usize::max_value() {
            end_name_index = value_index;
        } else {
            return None;
        }

        Some(line.split_at(end_name_index).0)
    }

    /// Return the value from the given `Line`.
    fn parse_value<'a>(&self, line: &'a str) -> Option<&'a str> {
        let value_index = match line.find(::VALUE_DELIMITER) {
            Some(val) => val + 1, // Jump the VALUE_DELIMITER
            None => return None,
        };

        if value_index < line.len() {
            Some(line.split_at(value_index).1)
        } else {
            None
        }
    }

    /// Return the parameters from the given `Line`.
    fn parse_parameters(&self, line: &str) -> Result<Option<Vec<(String, String)>>, ParseError> {
        let params_str;
        let mut param_list =  Vec::new();

        let end_param_index = line.find(::VALUE_DELIMITER)
            .ok_or(ParseError::MissingValueDelimiter)?;

        let start_param_index = match line.find(::PARAM_DELIMITER) {
            Some(val) => val + 1, // Jump the PARAM_DELIMITER sign.
            None => return Ok(None), // there is no params.
        };

        if start_param_index > line.len() {
            // There is not parameters after PARAM_DELIMITER.
            return Err(ParseError::InvalidParamFormat);
        }

        unsafe {
            params_str = line.slice_unchecked(start_param_index, end_param_index);
        }

        let key_value_list: Vec<&str> = params_str.split(::PARAM_DELIMITER).collect();

        for key_value in key_value_list {

            let mut elem_list = key_value.split(::PARAM_NAME_DELIMITER);

            let key = elem_list.next()
                .and_then(|key| Some(key.to_uppercase()))
                .ok_or(ParseError::InvalidParamFormat)?;

            let value = elem_list.next()
                .and_then(|value| Some(value.to_string()))
                .ok_or(ParseError::InvalidParamFormat)?;

            param_list.push((key, value));

        }
        Ok(Some((param_list)))
    }
}

impl<B: BufRead> Iterator for LineParser<B> {
    type Item = Result<LineParsed, ParseError>;

    fn next(&mut self) -> Option<Result<LineParsed, ParseError>> {
        let line = match self.line_reader.next() {
            Some(val) => val,
            None => return None,
        };

        Some(self.parse(line))
    }
}

#[derive(Debug)]
pub enum ParseError {
    MissingValueDelimiter,
    MissingName,
    MissingValue,
    InvalidParamFormat,
}

impl Error for ParseError {
    fn description(&self) -> &str {
        match *self {
            ParseError::MissingValueDelimiter => "Missing value delimiter.",
            ParseError::MissingName => "Missing name.",
            ParseError::MissingValue => "Missing value.",
            ParseError::InvalidParamFormat => "Invalid parameter format.",
        }
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}
<commit_msg>Update some comments.<commit_after>//! Return parsed property from a `Line`.

use std::iter::Iterator;
use std::io::BufRead;
use std::error::Error;
use std::fmt;

use ::line;

/// A parsed `Line`.
///
/// It's only split a raw line into the mains elements:
/// - name: Property name.
/// - params: Vector of (key,value) parameter.
/// - value: Property Value.
pub struct LineParsed {
    name: String,
    params: Option<Vec<(String, String)>>,
    value: String,
}

impl LineParsed {
    pub fn new() -> LineParsed {
        LineParsed {
            name: String::new(),
            params: None,
            value: String::new(),
        }
    }

    pub fn set_name(&mut self, name: &str) {
        self.name = name.to_uppercase();
    }

    pub fn set_value(&mut self, value: &str) {
        self.value = value.to_string();
    }

    pub fn set_parameters(&mut self, params: Option<Vec<(String, String)>>) {
        self.params = params;
    }

    pub fn add_parameter(&mut self, key: &str, value: &str) {
        let param = (key.to_uppercase(), value.to_string());

        match self.params {
            Some(ref mut list)  => list.push(param),
            None => self.params = Some(vec!(param)),
        };
    }
}

impl fmt::Display for LineParsed {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "name: {}\nparams: {:?}\nvalue: {}",
               self.name,
               self.params,
               self.value)
    }
}

/// A splitted `Line`.
pub struct LineParser<B> {
    line_reader: line::LineReader<B>,
}

impl<B: BufRead> LineParser<B> {
    pub fn new(line_reader: line::LineReader<B>) -> LineParser<B> {
        LineParser { line_reader: line_reader }
    }

    fn parse(&self, line: line::Line) -> Result<LineParsed, ParseError> {
        let mut property = LineParsed::new();

        // Parse name.
        let name = self.parse_name(line.as_str())
            .ok_or(ParseError::MissingName)?;
        property.set_name(name);

        // Parse value
        let value = self.parse_value(line.as_str())
            .ok_or(ParseError::MissingValue)?;
        property.set_value(value);

        // Parse parameters.
        let parameters = self.parse_parameters(line.as_str())?;
        property.set_parameters(parameters);
        Ok(property)

    }

    /// Return the name from the given `Line`.
    fn parse_name<'a>(&self, line: &'a str) -> Option<&'a str> {
        let end_name_index;

        let param_index = line.find(::PARAM_DELIMITER).unwrap_or(usize::max_value());
        let value_index = line.find(::VALUE_DELIMITER).unwrap_or(usize::max_value());

        if param_index < value_index {
            end_name_index = param_index;
        } else if value_index != usize::max_value() {
            end_name_index = value_index;
        } else {
            return None;
        }

        Some(line.split_at(end_name_index).0)
    }

    /// Return the value from the given `Line`.
    fn parse_value<'a>(&self, line: &'a str) -> Option<&'a str> {
        let value_index = match line.find(::VALUE_DELIMITER) {
            Some(val) => val + 1, // Jump the VALUE_DELIMITER
            None => return None,
        };

        if value_index < line.len() {
            Some(line.split_at(value_index).1)
        } else {
            None
        }
    }

    /// Return the parameters from the given `Line`.
    fn parse_parameters(&self, line: &str) -> Result<Option<Vec<(String, String)>>, ParseError> {
        let params_str;
        let mut param_list =  Vec::new();

        let end_param_index = line.find(::VALUE_DELIMITER)
            .ok_or(ParseError::MissingValueDelimiter)?;

        let start_param_index = match line.find(::PARAM_DELIMITER) {
            Some(val) => val + 1, // Jump the PARAM_DELIMITER sign.
            None => return Ok(None), // there is no params.
        };

        if start_param_index > line.len() {
            // There is not parameters after PARAM_DELIMITER.
            return Err(ParseError::InvalidParamFormat);
        }

        unsafe {
            params_str = line.slice_unchecked(start_param_index, end_param_index);
        }

        let key_value_list: Vec<&str> = params_str.split(::PARAM_DELIMITER).collect();

        for key_value in key_value_list {

            let mut elem_list = key_value.split(::PARAM_NAME_DELIMITER);

            let key = elem_list.next()
                .and_then(|key| Some(key.to_uppercase()))
                .ok_or(ParseError::InvalidParamFormat)?;

            let value = elem_list.next()
                .and_then(|value| Some(value.to_string()))
                .ok_or(ParseError::InvalidParamFormat)?;

            param_list.push((key, value));

        }
        Ok(Some((param_list)))
    }
}

impl<B: BufRead> Iterator for LineParser<B> {
    type Item = Result<LineParsed, ParseError>;

    fn next(&mut self) -> Option<Result<LineParsed, ParseError>> {
        let line = match self.line_reader.next() {
            Some(val) => val,
            None => return None,
        };

        Some(self.parse(line))
    }
}

#[derive(Debug)]
pub enum ParseError {
    MissingValueDelimiter,
    MissingName,
    MissingValue,
    InvalidParamFormat,
}

impl Error for ParseError {
    fn description(&self) -> &str {
        match *self {
            ParseError::MissingValueDelimiter => "Missing value delimiter.",
            ParseError::MissingName => "Missing name.",
            ParseError::MissingValue => "Missing value.",
            ParseError::InvalidParamFormat => "Invalid parameter format.",
        }
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}
<|endoftext|>


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

use std::num::Float;

use {gradient, math, Seed};

/// 2-dimensional perlin noise
pub fn perlin2<T: Float>(seed: &Seed, point: &math::Point2<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, whole: math::Point2<isize>, frac: math::Vector2<T>) -> T {
        math::dot2(frac, gradient::get2(seed.get2(whole)))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);

    let f00 = gradient(seed, [x0_whole, y0_whole], [x0_frac, y0_frac]);
    let f10 = gradient(seed, [x1_whole, y0_whole], [x1_frac, y0_frac]);
    let f01 = gradient(seed, [x0_whole, y1_whole], [x0_frac, y1_frac]);
    let f11 = gradient(seed, [x1_whole, y1_whole], [x1_frac, y1_frac]);

    math::bilerp(x_curve, y_curve, f00, f10, f01, f11)
}

/// 3-dimensional perlin noise
pub fn perlin3<T: Float>(seed: &Seed, point: &math::Point3<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, whole: math::Point3<isize>, frac: math::Vector3<T>) -> T {
        math::dot3(frac, gradient::get3(seed.get3(whole)))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);

    let f000 = gradient(seed, [x0_whole, y0_whole, z0_whole], [x0_frac, y0_frac, z0_frac]);
    let f100 = gradient(seed, [x1_whole, y0_whole, z0_whole], [x1_frac, y0_frac, z0_frac]);
    let f010 = gradient(seed, [x0_whole, y1_whole, z0_whole], [x0_frac, y1_frac, z0_frac]);
    let f110 = gradient(seed, [x1_whole, y1_whole, z0_whole], [x1_frac, y1_frac, z0_frac]);
    let f001 = gradient(seed, [x0_whole, y0_whole, z1_whole], [x0_frac, y0_frac, z1_frac]);
    let f101 = gradient(seed, [x1_whole, y0_whole, z1_whole], [x1_frac, y0_frac, z1_frac]);
    let f011 = gradient(seed, [x0_whole, y1_whole, z1_whole], [x0_frac, y1_frac, z1_frac]);
    let f111 = gradient(seed, [x1_whole, y1_whole, z1_whole], [x1_frac, y1_frac, z1_frac]);

    math::trilerp(x_curve, y_curve, z_curve, f000, f100, f010, f110, f001, f101, f011, f111)
}

/// 4-dimensional perlin noise
pub fn perlin4<T: Float>(seed: &Seed, point: &math::Point4<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, whole: math::Point4<isize>, frac: math::Vector4<T>) -> T {
        math::dot4(frac, gradient::get4(seed.get4(whole)))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();
    let wfloor = point[3].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);
    let w0_whole: isize = math::cast(wfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;
    let w1_whole = w0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;
    let w0_frac = point[2] - wfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;
    let w1_frac = w0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);
    let w_curve = math::scurve5(w0_frac);

    let f0000 = gradient(seed, [x0_whole, y0_whole, z0_whole, w0_whole], [x0_frac, y0_frac, z0_frac, w0_frac]);
    let f1000 = gradient(seed, [x1_whole, y0_whole, z0_whole, w0_whole], [x1_frac, y0_frac, z0_frac, w0_frac]);
    let f0001 = gradient(seed, [x0_whole, y1_whole, z0_whole, w0_whole], [x0_frac, y1_frac, z0_frac, w0_frac]);
    let f1001 = gradient(seed, [x1_whole, y1_whole, z0_whole, w0_whole], [x1_frac, y1_frac, z0_frac, w0_frac]);
    let f0010 = gradient(seed, [x0_whole, y0_whole, z1_whole, w0_whole], [x0_frac, y0_frac, z1_frac, w0_frac]);
    let f1010 = gradient(seed, [x1_whole, y0_whole, z1_whole, w0_whole], [x1_frac, y0_frac, z1_frac, w0_frac]);
    let f0011 = gradient(seed, [x0_whole, y1_whole, z1_whole, w0_whole], [x0_frac, y1_frac, z1_frac, w0_frac]);
    let f1011 = gradient(seed, [x1_whole, y1_whole, z1_whole, w0_whole], [x1_frac, y1_frac, z1_frac, w0_frac]);
    let f0100 = gradient(seed, [x0_whole, y0_whole, z0_whole, w1_whole], [x0_frac, y0_frac, z0_frac, w1_frac]);
    let f1100 = gradient(seed, [x1_whole, y0_whole, z0_whole, w1_whole], [x1_frac, y0_frac, z0_frac, w1_frac]);
    let f0101 = gradient(seed, [x0_whole, y1_whole, z0_whole, w1_whole], [x0_frac, y1_frac, z0_frac, w1_frac]);
    let f1101 = gradient(seed, [x1_whole, y1_whole, z0_whole, w1_whole], [x1_frac, y1_frac, z0_frac, w1_frac]);
    let f0110 = gradient(seed, [x0_whole, y0_whole, z1_whole, w1_whole], [x0_frac, y0_frac, z1_frac, w1_frac]);
    let f1110 = gradient(seed, [x1_whole, y0_whole, z1_whole, w1_whole], [x1_frac, y0_frac, z1_frac, w1_frac]);
    let f0111 = gradient(seed, [x0_whole, y1_whole, z1_whole, w1_whole], [x0_frac, y1_frac, z1_frac, w1_frac]);
    let f1111 = gradient(seed, [x1_whole, y1_whole, z1_whole, w1_whole], [x1_frac, y1_frac, z1_frac, w1_frac]);

    math::quadlerp(x_curve, y_curve, z_curve, w_curve, f0000, f1000, f0001, f1001, f0010, f1010, f0011, f1011, f0100, f1100, f0101, f1101, f0110, f1110, f0111, f1111)
}
<commit_msg>Cache permutation lookups for perlin<commit_after>// Copyright 2015 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::Float;

use {gradient, math, Seed};

/// 2-dimensional perlin noise
pub fn perlin2<T: Float>(seed: &Seed, point: &math::Point2<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: math::Point2<usize>, frac: math::Vector2<T>) -> T {
        math::dot2(frac, gradient::get2((seed[0] ^ seed[1]) as usize))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);

    let x0_cache = seed.get1(x0_whole);
    let y0_cache = seed.get1(y0_whole);
    let x1_cache = seed.get1(x1_whole);
    let y1_cache = seed.get1(y1_whole);

    let f00 = gradient([x0_cache, y0_cache], [x0_frac, y0_frac]);
    let f10 = gradient([x1_cache, y0_cache], [x1_frac, y0_frac]);
    let f01 = gradient([x0_cache, y1_cache], [x0_frac, y1_frac]);
    let f11 = gradient([x1_cache, y1_cache], [x1_frac, y1_frac]);

    math::bilerp(x_curve, y_curve, f00, f10, f01, f11)
}

/// 3-dimensional perlin noise
pub fn perlin3<T: Float>(seed: &Seed, point: &math::Point3<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: math::Point3<usize>, frac: math::Vector3<T>) -> T {
        math::dot3(frac, gradient::get3(seed[0] ^ seed[1] ^ seed[2]))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);

    let x0_cache = seed.get1(x0_whole);
    let y0_cache = seed.get1(y0_whole);
    let z0_cache = seed.get1(z0_whole);
    let x1_cache = seed.get1(x1_whole);
    let y1_cache = seed.get1(y1_whole);
    let z1_cache = seed.get1(z1_whole);

    let f000 = gradient([x0_cache, y0_cache, z0_cache], [x0_frac, y0_frac, z0_frac]);
    let f100 = gradient([x1_cache, y0_cache, z0_cache], [x1_frac, y0_frac, z0_frac]);
    let f010 = gradient([x0_cache, y1_cache, z0_cache], [x0_frac, y1_frac, z0_frac]);
    let f110 = gradient([x1_cache, y1_cache, z0_cache], [x1_frac, y1_frac, z0_frac]);
    let f001 = gradient([x0_cache, y0_cache, z1_cache], [x0_frac, y0_frac, z1_frac]);
    let f101 = gradient([x1_cache, y0_cache, z1_cache], [x1_frac, y0_frac, z1_frac]);
    let f011 = gradient([x0_cache, y1_cache, z1_cache], [x0_frac, y1_frac, z1_frac]);
    let f111 = gradient([x1_cache, y1_cache, z1_cache], [x1_frac, y1_frac, z1_frac]);

    math::trilerp(x_curve, y_curve, z_curve, f000, f100, f010, f110, f001, f101, f011, f111)
}

/// 4-dimensional perlin noise
pub fn perlin4<T: Float>(seed: &Seed, point: &math::Point4<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: math::Point4<usize>, frac: math::Vector4<T>) -> T {
        math::dot4(frac, gradient::get4(seed[0] ^ seed[1] ^ seed[2] ^ seed[3]))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();
    let wfloor = point[3].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);
    let w0_whole: isize = math::cast(wfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;
    let w1_whole = w0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;
    let w0_frac = point[2] - wfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;
    let w1_frac = w0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);
    let w_curve = math::scurve5(w0_frac);

    let x0_cache = seed.get1(x0_whole);
    let y0_cache = seed.get1(y0_whole);
    let z0_cache = seed.get1(z0_whole);
    let w0_cache = seed.get1(w0_whole);
    let x1_cache = seed.get1(x1_whole);
    let y1_cache = seed.get1(y1_whole);
    let z1_cache = seed.get1(z1_whole);
    let w1_cache = seed.get1(w1_whole);

    let f0000 = gradient([x0_cache, y0_cache, z0_cache, w0_cache], [x0_frac, y0_frac, z0_frac, w0_frac]);
    let f1000 = gradient([x1_cache, y0_cache, z0_cache, w0_cache], [x1_frac, y0_frac, z0_frac, w0_frac]);
    let f0001 = gradient([x0_cache, y1_cache, z0_cache, w0_cache], [x0_frac, y1_frac, z0_frac, w0_frac]);
    let f1001 = gradient([x1_cache, y1_cache, z0_cache, w0_cache], [x1_frac, y1_frac, z0_frac, w0_frac]);
    let f0010 = gradient([x0_cache, y0_cache, z1_cache, w0_cache], [x0_frac, y0_frac, z1_frac, w0_frac]);
    let f1010 = gradient([x1_cache, y0_cache, z1_cache, w0_cache], [x1_frac, y0_frac, z1_frac, w0_frac]);
    let f0011 = gradient([x0_cache, y1_cache, z1_cache, w0_cache], [x0_frac, y1_frac, z1_frac, w0_frac]);
    let f1011 = gradient([x1_cache, y1_cache, z1_cache, w0_cache], [x1_frac, y1_frac, z1_frac, w0_frac]);
    let f0100 = gradient([x0_cache, y0_cache, z0_cache, w1_cache], [x0_frac, y0_frac, z0_frac, w1_frac]);
    let f1100 = gradient([x1_cache, y0_cache, z0_cache, w1_cache], [x1_frac, y0_frac, z0_frac, w1_frac]);
    let f0101 = gradient([x0_cache, y1_cache, z0_cache, w1_cache], [x0_frac, y1_frac, z0_frac, w1_frac]);
    let f1101 = gradient([x1_cache, y1_cache, z0_cache, w1_cache], [x1_frac, y1_frac, z0_frac, w1_frac]);
    let f0110 = gradient([x0_cache, y0_cache, z1_cache, w1_cache], [x0_frac, y0_frac, z1_frac, w1_frac]);
    let f1110 = gradient([x1_cache, y0_cache, z1_cache, w1_cache], [x1_frac, y0_frac, z1_frac, w1_frac]);
    let f0111 = gradient([x0_cache, y1_cache, z1_cache, w1_cache], [x0_frac, y1_frac, z1_frac, w1_frac]);
    let f1111 = gradient([x1_cache, y1_cache, z1_cache, w1_cache], [x1_frac, y1_frac, z1_frac, w1_frac]);

    math::quadlerp(x_curve, y_curve, z_curve, w_curve, f0000, f1000, f0001, f1001, f0010, f1010, f0011, f1011, f0100, f1100, f0101, f1101, f0110, f1110, f0111, f1111)
}
<|endoftext|>


<commit_before>/*
    Copyright 2013 Jesse 'Jeaye' Wilkerson
    See licensing in LICENSE file, or at:
        http://www.opensource.org/licenses/BSD-3-Clause

    File: server/main.rs
    Author: Jesse 'Jeaye' Wilkerson
    Description:
      Main engine controller and entry point
      for the server.
*/

#[feature(globs)];

extern mod ui;

struct Server
{
  log: ~str,
  ui_driver: ~ui::Driver,
}

impl Server
{
  pub fn new() -> Server
  {
    let server = Server
    {
      log: ~"",
      ui_driver: ui::term::initialize().expect("Unable to create UI"),
    };

    server
  }
}

fn main()
{
  let _server = Server::new();
}

<commit_msg> #50 Added commandline options<commit_after>/*
    Copyright 2013 Jesse 'Jeaye' Wilkerson
    See licensing in LICENSE file, or at:
        http://www.opensource.org/licenses/BSD-3-Clause

    File: server/main.rs
    Author: Jesse 'Jeaye' Wilkerson
    Description:
      Main engine controller and entry point
      for the server.
*/

#[feature(globs)];

extern mod ui;

use std::os;

struct Server
{
  log: ~str,
  ui_driver: ~ui::Driver,
}

impl Server
{
  pub fn new() -> Server
  {
    let args = os::args();
    if args.contains(&~"--help")
    { Server::show_help(); }

    /* Determine the UI driver. */
    let driver =
    if args.contains(&~"--gui")
    { fail!("GUI mode is not yet implemented"); }
    else
    { ui::term::initialize().expect("Unable to create terminal UI") };

    let server = Server
    {
      log: ~"",
      ui_driver: driver,
    };

    server
  }

  fn show_help()
  {
    let args = os::args();

    println!("Q³ Server {}.{}", env!("VERSION"), env!("COMMIT"));
    println!("Usage:\n\t{} [options...]", args[0]);
    println!("");
    println!("Options:");
    println!("\t--help\tShows this help menu and exits");
    println!("\t--tui\tEnable textual user interface mode (default)");
    println!("\t--gui\tEnable graphical user interface mode");
    println!("");

    fail!("Exiting");
  }
}

fn main()
{
  let _server = Server::new();
}

<|endoftext|>


<commit_before>use std::env;
use std::default::Default;
use std::collections::BTreeMap;

use time::now_utc;
use rand::{Rng, thread_rng};
use rustc_serialize::json::{ToJson, Json};
use r2d2_redis::RedisConnectionManager;
use r2d2::{Config, Pool, PooledConnection};
use redis::{cmd, Commands, RedisResult, parse_redis_url};

pub type RedisPooledConnection = PooledConnection<RedisConnectionManager>;
pub type RedisPool = Pool<RedisConnectionManager>;

pub fn create_redis_pool() -> RedisPool {
    let config = Config::builder().build();
    let redis_url = &env::var("REDIS_URL").unwrap_or("redis://127.0.0.1/".to_owned());
    let url = parse_redis_url(redis_url).unwrap();
    let manager = RedisConnectionManager::new(url).unwrap();
    Pool::new(config, manager).unwrap()
}

#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct Job {
    pub class: String,
    pub args: String,
    pub retry: i64,
    pub queue: String,
    pub jid: String,
    pub created_at: i64,
    pub enqueued_at: i64,
}

impl Default for JobOpts {
    fn default() -> JobOpts {
        let now = now_utc().to_timespec().sec;
        let jid = thread_rng().gen_ascii_chars().take(24).collect::<String>();
        JobOpts {
            retry: 25,
            queue: "default".to_string(),
            jid: jid,
            created_at: now,
            enqueued_at: now,
        }
    }
}

pub struct JobOpts {
    pub retry: i64,
    pub queue: String,
    pub jid: String,
    pub created_at: i64,
    pub enqueued_at: i64,
}

impl Job {
    pub fn new(class: String, args: String, opts: JobOpts) -> Job {
        Job {
            class: class,
            args: args,
            retry: opts.retry,
            queue: opts.queue,
            jid: opts.jid,
            created_at: opts.created_at,
            enqueued_at: opts.enqueued_at,
        }
    }
}

impl ToJson for Job {
    fn to_json(&self) -> Json {
        let mut object = BTreeMap::new();
        object.insert("class".to_string(), self.class.to_json());
        // `args` are already serialized, creating Json struct from it.
        object.insert("args".to_string(), Json::from_str(&self.args).unwrap());
        object.insert("retry".to_string(), self.retry.to_json());
        object.insert("queue".to_string(), self.queue.to_json());
        object.insert("jid".to_string(), self.jid.to_json());
        object.insert("created_at".to_string(), self.created_at.to_json());
        object.insert("enqueued_at".to_string(), self.enqueued_at.to_json());
        Json::Object(object)
    }
}

pub struct ClientOpts {
    pub namespace: Option<String>,
}

impl Default for ClientOpts {
    fn default() -> ClientOpts {
        ClientOpts { namespace: None }
    }
}

pub struct Client {
    pub pool: RedisPool,
    pub namespace: Option<String>,
}

impl Client {
    pub fn new(pool: RedisPool, opts: ClientOpts) -> Client {
        Client {
            pool: pool,
            namespace: opts.namespace,
        }
    }

    fn get_connection(&self) -> RedisPooledConnection {
        self.pool.get().unwrap()
    }

    pub fn push(&self, job: Job) -> RedisResult<Job> {
        let conn = self.get_connection();
        let _: () = cmd("SADD")
                        .arg("queues")
                        .arg(job.queue.to_string())
                        .query(&*conn)
                        .unwrap();
        let _: () = cmd("LPUSH")
                        .arg(self.queue_name(&job.queue))
                        .arg(job.to_json())
                        .query(&*conn)
                        .unwrap();
        Ok(job)
    }

    fn queue_name(&self, queue: &str) -> String {
        if let Some(ref ns) = self.namespace {
            format!("{}:queue:{}", ns, queue)
        } else {
            format!("queue:{}", queue)
        }
    }
}
<commit_msg>Use multi pipe and move get connection to new<commit_after>use std::env;
use std::default::Default;
use std::collections::BTreeMap;

use time::now_utc;
use rand::{Rng, thread_rng};
use rustc_serialize::json::{ToJson, Json};
use r2d2_redis::RedisConnectionManager;
use r2d2::{Config, Pool, PooledConnection};
use redis::{pipe, RedisResult, parse_redis_url};

pub type RedisPooledConnection = PooledConnection<RedisConnectionManager>;
pub type RedisPool = Pool<RedisConnectionManager>;

pub fn create_redis_pool() -> RedisPool {
    let config = Config::builder().build();
    let redis_url = &env::var("REDIS_URL").unwrap_or("redis://127.0.0.1/".to_owned());
    let url = parse_redis_url(redis_url).unwrap();
    let manager = RedisConnectionManager::new(url).unwrap();
    Pool::new(config, manager).unwrap()
}

#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct Job {
    pub class: String,
    pub args: String,
    pub retry: i64,
    pub queue: String,
    pub jid: String,
    pub created_at: i64,
    pub enqueued_at: i64,
}

impl Default for JobOpts {
    fn default() -> JobOpts {
        let now = now_utc().to_timespec().sec;
        let jid = thread_rng().gen_ascii_chars().take(24).collect::<String>();
        JobOpts {
            retry: 25,
            queue: "default".to_string(),
            jid: jid,
            created_at: now,
            enqueued_at: now,
        }
    }
}

pub struct JobOpts {
    pub retry: i64,
    pub queue: String,
    pub jid: String,
    pub created_at: i64,
    pub enqueued_at: i64,
}

impl Job {
    pub fn new(class: String, args: String, opts: JobOpts) -> Job {
        Job {
            class: class,
            args: args,
            retry: opts.retry,
            queue: opts.queue,
            jid: opts.jid,
            created_at: opts.created_at,
            enqueued_at: opts.enqueued_at,
        }
    }
}

impl ToJson for Job {
    fn to_json(&self) -> Json {
        let mut object = BTreeMap::new();
        object.insert("class".to_string(), self.class.to_json());
        // `args` are already serialized, creating Json struct from it.
        object.insert("args".to_string(), Json::from_str(&self.args).unwrap());
        object.insert("retry".to_string(), self.retry.to_json());
        object.insert("queue".to_string(), self.queue.to_json());
        object.insert("jid".to_string(), self.jid.to_json());
        object.insert("created_at".to_string(), self.created_at.to_json());
        object.insert("enqueued_at".to_string(), self.enqueued_at.to_json());
        Json::Object(object)
    }
}

pub struct ClientOpts {
    pub namespace: Option<String>,
}

impl Default for ClientOpts {
    fn default() -> ClientOpts {
        ClientOpts { namespace: None }
    }
}

pub struct Client {
    pub connection: RedisPooledConnection,
    pub namespace: Option<String>,
}

impl Client {
    pub fn new(pool: RedisPool, opts: ClientOpts) -> Client {
        Client {
            connection: pool.get().unwrap(),
            namespace: opts.namespace,
        }
    }

    pub fn push(&self, job: Job) -> RedisResult<Job> {
        let _: () = try!(pipe()
            .atomic()
            .cmd("SADD")
            .arg("queues")
            .arg(job.queue.to_string()).ignore()
            .cmd("LPUSH")
            .arg(self.queue_name(&job.queue))
            .arg(job.to_json())
            .query(&*self.connection));
        Ok(job)
    }

    fn queue_name(&self, queue: &str) -> String {
        if let Some(ref ns) = self.namespace {
            format!("{}:queue:{}", ns, queue)
        } else {
            format!("queue:{}", queue)
        }
    }
}
<|endoftext|>


<commit_before>use std::io::Read;
use azure::core;
use azure::core::errors::{self, AzureError};
use azure::storage::client::Client;
use hyper::status::StatusCode;
use rustc_serialize::{Decodable, Encodable, json};

const TABLE_SUFFIX: &'static str = "table.core.windows.net";

pub struct TableClient {
    client: Client,
}

impl TableClient {
    pub fn new(client: Client) -> Self {
        TableClient { client: client }
    }

    pub fn list(&self) -> Result<Vec<String>, core::errors::AzureError> {
        Ok(self.query_range_entity("Tables", None)?
               .into_iter()
               .map(|x: TableEntry| x.TableName)
               .collect())
    }

    pub fn insert_entity<T: Encodable>(&self,
                                       table_name: &str,
                                       partition_key: &str,
                                       row_key: &str,
                                       entity: &T)
                                       -> Result<(), core::errors::AzureError> {
        let ref body = json::encode(entity).unwrap();
        if !body.starts_with("{") {
            return Err(AzureError::InputParametersError("body not valid.".to_owned()));
        };

        let ref post_body = format!(r#"{{"PartitionKey":"{}","RowKey":"{}",{}"#,
                                    partition_key,
                                    row_key,
                                    &body[1..]);

        try!(self.do_request(table_name,
                             core::HTTPMethod::Post,
                             Some(post_body),
                             StatusCode::Created));
        Ok(())
    }

    pub fn get_entity<T: Decodable>(&self,
                                    table_name: &str,
                                    partition_key: &str,
                                    row_key: &str)
                                    -> Result<Option<T>, core::errors::AzureError> {
        let ref path = format!("{}(PartitionKey='{}',RowKey='{}')",
                               table_name,
                               partition_key,
                               row_key);
        Ok(self.do_request(path,
                           core::HTTPMethod::Get,
                           None,
                           StatusCode::Ok)?
               .map(|x| json::decode(x.as_str()).unwrap()))
    }

    pub fn query_range_entity<T: Decodable>(&self,
                                           path: &str,
                                           query: Option<&str>)
                                           -> Result<Vec<T>, core::errors::AzureError> {
        let ref path = format!("{}?{}",
                               path,
                               match query {
                                   Some(clause) => clause,
                                   None => "",
                               });
        let result =
            self.do_request(path, core::HTTPMethod::Get, None, StatusCode::Ok).map(|x| x.unwrap());
        let ec: EntryCollection<T> = json::decode(result?.as_str()).unwrap();
        Ok(ec.value)
    }

    pub fn do_request(&self,
                      segment: &str,
                      method: core::HTTPMethod,
                      request_str: Option<&str>,
                      expected_status_code: StatusCode)
                      -> Result<Option<String>, core::errors::AzureError> {
        let client = &self.client;
        if let Some(ref body) = request_str {
            trace!("Request: {}", body);
        }

        let uri = format!("{}://{}.{}/{}",
                          client.auth_scheme(),
                          client.account(),
                          TABLE_SUFFIX,
                          segment);
        trace!("uri:{}", uri);
        let mut resp = try!(client.perform_table_request(&uri, method, request_str));
        if StatusCode::NotFound == resp.status {
            return Ok(None);
        }

        try!(errors::check_status(&mut resp, expected_status_code));
        let mut resp_s = String::new();
        try!(resp.read_to_string(&mut resp_s));

        trace!("Response: {}", resp_s);
        Ok(Some(resp_s))
    }
}

#[allow(non_snake_case)]
#[derive(RustcDecodable)]
struct TableEntry {
    TableName: String,
}

#[derive(RustcDecodable)]
struct EntryCollection<T> {
    value: Vec<T>,
}
<commit_msg>Show error log.<commit_after>use std::io::Read;
use azure::core;
use azure::core::errors::{self, AzureError};
use azure::storage::client::Client;
use hyper::status::StatusCode;
use rustc_serialize::{Decodable, Encodable, json};

const TABLE_SUFFIX: &'static str = "table.core.windows.net";

pub struct TableClient {
    client: Client,
}

impl TableClient {
    pub fn new(client: Client) -> Self {
        TableClient { client: client }
    }

    pub fn list(&self) -> Result<Vec<String>, core::errors::AzureError> {
        Ok(self.query_range_entity("Tables", None)?
               .into_iter()
               .map(|x: TableEntry| x.TableName)
               .collect())
    }

    pub fn insert_entity<T: Encodable>(&self,
                                       table_name: &str,
                                       partition_key: &str,
                                       row_key: &str,
                                       entity: &T)
                                       -> Result<(), core::errors::AzureError> {
        let ref body = json::encode(entity).unwrap();
        if !body.starts_with("{") {
            return Err(AzureError::InputParametersError("body not valid.".to_owned()));
        };

        let ref post_body = format!(r#"{{"PartitionKey":"{}","RowKey":"{}",{}"#,
                                    partition_key,
                                    row_key,
                                    &body[1..]);

        try!(self.do_request(table_name,
                             core::HTTPMethod::Post,
                             Some(post_body),
                             StatusCode::Created));
        Ok(())
    }

    pub fn get_entity<T: Decodable>(&self,
                                    table_name: &str,
                                    partition_key: &str,
                                    row_key: &str)
                                    -> Result<Option<T>, core::errors::AzureError> {
        let ref path = format!("{}(PartitionKey='{}',RowKey='{}')",
                               table_name,
                               partition_key,
                               row_key);
        Ok(self.do_request(path,
                           core::HTTPMethod::Get,
                           None,
                           StatusCode::Ok)?
               .map(|x| json::decode(x.as_str()).unwrap()))
    }

    pub fn query_range_entity<T: Decodable>(&self,
                                            path: &str,
                                            query: Option<&str>)
                                            -> Result<Vec<T>, core::errors::AzureError> {
        let ref path = format!("{}?{}",
                               path,
                               match query {
                                   Some(clause) => clause,
                                   None => "",
                               });
        let result =
            self.do_request(path, core::HTTPMethod::Get, None, StatusCode::Ok).map(|x| x.unwrap());
        let ec: EntryCollection<T> = json::decode(result?.as_str()).unwrap();
        Ok(ec.value)
    }

    pub fn do_request(&self,
                      segment: &str,
                      method: core::HTTPMethod,
                      request_str: Option<&str>,
                      expected_status_code: StatusCode)
                      -> Result<Option<String>, core::errors::AzureError> {
        let client = &self.client;
        if let Some(ref body) = request_str {
            trace!("Request: {}", body);
        }

        let uri = format!("{}://{}.{}/{}",
                          client.auth_scheme(),
                          client.account(),
                          TABLE_SUFFIX,
                          segment);
        trace!("uri:{}", uri);
        let mut resp = try!(client.perform_table_request(&uri, method, request_str));
        if StatusCode::NotFound == resp.status {
            return Ok(None);
        }

        let cs = errors::check_status(&mut resp, expected_status_code);
        if cs.is_err() {
            trace!("Err Response:{:?}", cs);
            try!(cs);
        }

        let mut resp_s = String::new();
        try!(resp.read_to_string(&mut resp_s));

        trace!("Response: {}", resp_s);
        Ok(Some(resp_s))
    }
}

#[allow(non_snake_case)]
#[derive(RustcDecodable)]
struct TableEntry {
    TableName: String,
}

#[derive(RustcDecodable)]
struct EntryCollection<T> {
    value: Vec<T>,
}
<|endoftext|>


<commit_before>// Copyright © 2018, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate csv;
extern crate failure;
extern crate geo;
extern crate mimir;
extern crate mimirsbrunn;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate slog;
#[macro_use]
extern crate slog_scope;
#[macro_use]
extern crate structopt;

use failure::ResultExt;
use mimir::rubber::Rubber;
use mimirsbrunn::admin_geofinder::AdminGeoFinder;
use std::cell::Cell;
use std::fs;
use std::path::PathBuf;

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub struct OpenAddresse {
    pub id: String,
    pub street: String,
    pub postcode: String,
    pub district: String,
    pub region: String,
    pub city: String,
    pub number: String,
    pub unit: String,
    pub lat: f64,
    pub lon: f64,
}

impl OpenAddresse {
    pub fn into_addr(self, admins_geofinder: &AdminGeoFinder) -> mimir::Addr {
        let street_name = format!("{} ({})", self.street, self.city);
        let addr_name = format!("{} {}", self.number, self.street);
        let addr_label = format!("{} ({})", addr_name, self.city);
        let street_id = format!("street:{}", self.id); // TODO check if thats ok
        let admins = admins_geofinder.get(&geo::Coordinate {
            x: self.lon,
            y: self.lat,
        });

        let weight = admins
            .iter()
            .find(|a| a.is_city())
            .map_or(0., |a| a.weight.get());

        let street = mimir::Street {
            id: street_id,
            street_name: self.street,
            label: street_name.to_string(),
            administrative_regions: admins,
            weight: weight,
            zip_codes: vec![self.postcode.clone()],
            coord: mimir::Coord::new(self.lon, self.lat),
        };
        mimir::Addr {
            id: format!("addr:{};{}", self.lon, self.lat),
            house_number: self.number,
            street: street,
            label: addr_label,
            coord: mimir::Coord::new(self.lon, self.lat),
            weight: weight,
            zip_codes: vec![self.postcode.clone()],
        }
    }
}

fn index_oa<I>(cnx_string: &str, dataset: &str, files: I) -> Result<(), mimirsbrunn::Error>
where
    I: Iterator<Item = std::path::PathBuf>,
{
    let mut rubber = Rubber::new(cnx_string);

    let admins = rubber
        .get_admins_from_dataset(dataset)
        .unwrap_or_else(|err| {
            info!(
                "Administratives regions not found in es db for dataset {}. (error: {})",
                dataset, err
            );
            vec![]
        });
    let admins_geofinder = admins.into_iter().collect();

    let addr_index = rubber
        .make_index(dataset)
        .with_context(|_| format!("error occureed when making index for {}", dataset))?;
    info!("Add data in elasticsearch db.");
    for f in files {
        info!("importing {:?}...", &f);
        let skipped_addresses = Cell::new(0);
        let mut rdr = csv::ReaderBuilder::new().has_headers(true).from_path(&f)?;
        let iter = rdr
            .deserialize()
            .filter_map(|r| {
                r.map_err(|e| info!("impossible to read line, error: {}", e))
                    .ok()
                    .map(|v: OpenAddresse| v.into_addr(&admins_geofinder))
            })
            .filter(|a| {
                !a.street.street_name.is_empty() || {
                    skipped_addresses.set(skipped_addresses.get() + 1);
                    false
                }
            });
        let nb = rubber
            .bulk_index(&addr_index, iter)
            .with_context(|_| format!("failed to bulk insert file {:?}", &f))?;
        info!(
            "importing {:?}: {} addresses added and {} addresses skipped.",
            &f,
            nb,
            skipped_addresses.get()
        );
    }
    rubber.publish_index(dataset, addr_index)
}

#[derive(StructOpt, Debug)]
struct Args {
    /// openaddresses files. Can be either a directory or a file.
    #[structopt(short = "i", long = "input", parse(from_os_str))]
    input: PathBuf,
    /// Elasticsearch parameters.
    #[structopt(
        short = "c", long = "connection-string", default_value = "http://localhost:9200/munin"
    )]
    connection_string: String,
    /// Name of the dataset.
    #[structopt(short = "d", long = "dataset", default_value = "fr")]
    dataset: String,
    /// Deprecated option.
    #[structopt(short = "C", long = "city-level")]
    city_level: Option<String>,
}

fn run(args: Args) -> Result<(), failure::Error> {
    info!("importing open addresses into Mimir");

    if args.city_level.is_some() {
        warn!("city-level option is deprecated, it now has no effect.");
    }

    if args.input.is_dir() {
        let paths: std::fs::ReadDir = fs::read_dir(&args.input)?;
        index_oa(
            &args.connection_string,
            &args.dataset,
            paths.map(|p| p.unwrap().path()),
        )
    } else {
        index_oa(
            &args.connection_string,
            &args.dataset,
            std::iter::once(args.input),
        )
    }
}

fn main() {
    mimirsbrunn::utils::launch_run(run);
}
<commit_msg>log open addresses<commit_after>// Copyright © 2018, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate csv;
extern crate failure;
extern crate geo;
extern crate mimir;
extern crate mimirsbrunn;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate slog;
#[macro_use]
extern crate slog_scope;
#[macro_use]
extern crate structopt;

use failure::ResultExt;
use mimir::rubber::Rubber;
use mimirsbrunn::admin_geofinder::AdminGeoFinder;
use std::cell::Cell;
use std::fs;
use std::path::PathBuf;

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub struct OpenAddresse {
    pub id: String,
    pub street: String,
    pub postcode: String,
    pub district: String,
    pub region: String,
    pub city: String,
    pub number: String,
    pub unit: String,
    pub lat: f64,
    pub lon: f64,
}

impl OpenAddresse {
    pub fn into_addr(self, admins_geofinder: &AdminGeoFinder) -> mimir::Addr {
        let street_name = format!("{} ({})", self.street, self.city);
        let addr_name = format!("{} {}", self.number, self.street);
        let addr_label = format!("{} ({})", addr_name, self.city);
        let street_id = format!("street:{}", self.id); // TODO check if thats ok
        let admins = admins_geofinder.get(&geo::Coordinate {
            x: self.lon,
            y: self.lat,
        });

        let weight = admins
            .iter()
            .find(|a| a.is_city())
            .map_or(0., |a| a.weight.get());

        let street = mimir::Street {
            id: street_id,
            street_name: self.street,
            label: street_name.to_string(),
            administrative_regions: admins,
            weight: weight,
            zip_codes: vec![self.postcode.clone()],
            coord: mimir::Coord::new(self.lon, self.lat),
        };
        mimir::Addr {
            id: format!("addr:{};{}", self.lon, self.lat),
            house_number: self.number,
            street: street,
            label: addr_label,
            coord: mimir::Coord::new(self.lon, self.lat),
            weight: weight,
            zip_codes: vec![self.postcode.clone()],
        }
    }
}

fn index_oa<I>(cnx_string: &str, dataset: &str, files: I) -> Result<(), mimirsbrunn::Error>
where
    I: Iterator<Item = std::path::PathBuf>,
{
    let mut rubber = Rubber::new(cnx_string);

    let admins = rubber
        .get_admins_from_dataset(dataset)
        .unwrap_or_else(|err| {
            info!(
                "Administratives regions not found in es db for dataset {}. (error: {})",
                dataset, err
            );
            vec![]
        });
    let admins_geofinder = admins.into_iter().collect();

    let addr_index = rubber
        .make_index(dataset)
        .with_context(|_| format!("error occureed when making index for {}", dataset))?;
    info!("Add data in elasticsearch db.");
    for f in files {
        info!("importing {:?}...", &f);
        let mut rdr = csv::ReaderBuilder::new().has_headers(true).from_path(&f)?;
        let iter = rdr
            .deserialize()
            .filter_map(|r| {
                r.map_err(|e| info!("impossible to read line, error: {}", e))
                    .ok()
                    .map(|v: OpenAddresse| v.into_addr(&admins_geofinder))
            })
            .filter(|a| {
                !a.street.street_name.is_empty() || {
                    info!(
                        "Address {}:{:?}:{:?} has no street name and has been ignored.",
                        a.id, a.coord, a.street
                    );
                    false
                }
            });
        let nb = rubber
            .bulk_index(&addr_index, iter)
            .with_context(|_| format!("failed to bulk insert file {:?}", &f))?;
        info!("importing {:?}: {} addresses", &f, nb);
    }
    rubber.publish_index(dataset, addr_index)
}

#[derive(StructOpt, Debug)]
struct Args {
    /// openaddresses files. Can be either a directory or a file.
    #[structopt(short = "i", long = "input", parse(from_os_str))]
    input: PathBuf,
    /// Elasticsearch parameters.
    #[structopt(
        short = "c", long = "connection-string", default_value = "http://localhost:9200/munin"
    )]
    connection_string: String,
    /// Name of the dataset.
    #[structopt(short = "d", long = "dataset", default_value = "fr")]
    dataset: String,
    /// Deprecated option.
    #[structopt(short = "C", long = "city-level")]
    city_level: Option<String>,
}

fn run(args: Args) -> Result<(), failure::Error> {
    info!("importing open addresses into Mimir");

    if args.city_level.is_some() {
        warn!("city-level option is deprecated, it now has no effect.");
    }

    if args.input.is_dir() {
        let paths: std::fs::ReadDir = fs::read_dir(&args.input)?;
        index_oa(
            &args.connection_string,
            &args.dataset,
            paths.map(|p| p.unwrap().path()),
        )
    } else {
        index_oa(
            &args.connection_string,
            &args.dataset,
            std::iter::once(args.input),
        )
    }
}

fn main() {
    mimirsbrunn::utils::launch_run(run);
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;

#[derive(Debug)]
struct Node {
    children: Vec<Node>,
    value: u64,
}

fn dfs_recursive(n: &Node) {
    println!("{}", n.value);

    for child in &n.children {
        dfs_recursive(child);
    }
}

fn dfs_recursive_postorder(n: &Node) {
    for child in &n.children {
        dfs_recursive(child);
    }

    println!("{}", n.value);
}

fn dfs_recursive_inorder_btree(n: &Node) {
    if n.children.len() == 2{
        dfs_recursive_inorder_btree(&n.children[1]);
        println!("{}", n.value);
        dfs_recursive_inorder_btree(&n.children[0]);
    } else if n.children.len() == 1 {
        dfs_recursive_inorder_btree(&n.children[0]);
        println!("{}", n.value);
    } else if n.children.len() == 0 {
        println!("{}", n.value);
    } else {
        println!("This is not a binary tree.");
    }
}

fn dfs_stack(n: &Node) {
    let mut stack = vec![n];

    while let Some(current) = stack.pop() {
        println!("{}", current.value);
        stack.extend(&current.children);
    }
}

fn bfs_queue(n: &Node){
    let mut queue = VecDeque::new();
    queue.push_back(n);

    while let Some(current) = queue.pop_front() {
        println!("{}", current.value);
        queue.extend(&current.children);
    }
}

fn create_tree(num_row: u64, num_child: u64) -> Node {
    if num_row == 0 {
        return Node { children: vec![], value: 0 };
    }

    let children = (0..num_child)
        .map(|_| create_tree(num_row - 1, num_child))
        .collect();

    Node { children, value: num_row }
}

fn main() {
    let root = create_tree(3,2);
    println!("Recursive DFS:");
    dfs_recursive(&root);
    println!("Stack DFS:");
    dfs_stack(&root);
    println!("Queue BFS:");
    bfs_queue(&root);
    println!("Recursive PostOrder DFS: ");
    dfs_recursive_postorder(&root);
    println!("Recursive DFS BTree:");
    dfs_recursive_inorder_btree(&root);
}
<commit_msg>Fix typo in Rust tree traversal.<commit_after>use std::collections::VecDeque;

#[derive(Debug)]
struct Node {
    children: Vec<Node>,
    value: u64,
}

fn dfs_recursive(n: &Node) {
    println!("{}", n.value);

    for child in &n.children {
        dfs_recursive(child);
    }
}

fn dfs_recursive_postorder(n: &Node) {
    for child in &n.children {
        dfs_recursive_postorder(child);
    }

    println!("{}", n.value);
}

fn dfs_recursive_inorder_btree(n: &Node) {
    if n.children.len() == 2{
        dfs_recursive_inorder_btree(&n.children[1]);
        println!("{}", n.value);
        dfs_recursive_inorder_btree(&n.children[0]);
    } else if n.children.len() == 1 {
        dfs_recursive_inorder_btree(&n.children[0]);
        println!("{}", n.value);
    } else if n.children.len() == 0 {
        println!("{}", n.value);
    } else {
        println!("This is not a binary tree.");
    }
}

fn dfs_stack(n: &Node) {
    let mut stack = vec![n];

    while let Some(current) = stack.pop() {
        println!("{}", current.value);
        stack.extend(&current.children);
    }
}

fn bfs_queue(n: &Node){
    let mut queue = VecDeque::new();
    queue.push_back(n);

    while let Some(current) = queue.pop_front() {
        println!("{}", current.value);
        queue.extend(&current.children);
    }
}

fn create_tree(num_row: u64, num_child: u64) -> Node {
    if num_row == 0 {
        return Node { children: vec![], value: 0 };
    }

    let children = (0..num_child)
        .map(|_| create_tree(num_row - 1, num_child))
        .collect();

    Node { children, value: num_row }
}

fn main() {
    let root = create_tree(2, 3);
    println!("Recursive DFS:");
    dfs_recursive(&root);
    println!("Stack DFS:");
    dfs_stack(&root);
    println!("Queue BFS:");
    bfs_queue(&root);
    println!("Recursive post-order DFS:");
    dfs_recursive_postorder(&root);
    println!("Recursive in-order DFS BTree:");
    let root_binary = create_tree(3, 2);
    dfs_recursive_inorder_btree(&root_binary);
}
<|endoftext|>


<commit_before>#![allow(clippy::many_single_char_names)]

use pyo3::prelude::*;

use std::collections::HashMap;

use crate::bragg;
use crate::parameters;
use statrs::function::gamma;

#[cfg(test)]
use crate::comparison;

#[pyfunction]
pub fn radial_grid_kk(num_points: usize) -> (Vec<f64>, Vec<f64>) {
    let n = num_points as i32;
    let rws: Vec<_> = (1..=n).map(|i| kk_r_w(i, n)).collect();
    rws.iter().cloned().unzip()
}

// https://doi.org/10.1063/1.475719, eqs. 9-13
fn kk_r_w(i: i32, n: i32) -> (f64, f64) {
    let pi = std::f64::consts::PI;

    let angle = ((i as f64) * pi) / ((n + 1) as f64);
    let s = angle.sin();
    let c = angle.cos();
    let t1 = ((n + 1 - 2 * i) as f64) / ((n + 1) as f64);
    let t2 = 2.0 / pi;
    let x = t1 + t2 * c * s * (1.0 + (2.0 / 3.0) * s * s);
    let f = 1.0 / 2.0_f64.ln();
    let r = f * (2.0 / (1.0 - x)).ln();
    let w = r * r * (f / (1.0 - x)) * (16.0 * s * s * s * s) / (3.0 * (n as f64) + 3.0);

    (r, w)
}

#[test]
fn test_radial_grid_kk() {
    let (rs, ws) = radial_grid_kk(99);
    assert!(comparison::floats_are_same(
        rs[0],
        27.520865062836048,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        rs[1],
        22.522899235303480,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        rs[98],
        7.4914976443367854e-9,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        ws[0],
        5462.4446669497620,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        ws[1],
        1828.2535433191961,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        ws[98],
        2.1018140707490095e-24,
        1.0e-15
    ));
}

#[pyfunction]
pub fn radial_grid(
    alpha_min: HashMap<usize, f64>,
    alpha_max: f64,
    radial_precision: f64,
    proton_charge: i32,
) -> (Vec<f64>, Vec<f64>) {
    // factor 2.0 to match DIRAC code
    let r_inner = get_r_inner(radial_precision, alpha_max * 2.0);

    let mut h = std::f64::MAX;
    let mut r_outer: f64 = 0.0;

    // we need alpha_min sorted by l
    // at this point not sure why ... need to check again the literature
    let mut v: Vec<_> = alpha_min.into_iter().collect();
    v.sort_by(|x, y| x.0.cmp(&y.0));

    for (l, a) in v {
        if a > 0.0 {
            r_outer = r_outer.max(get_r_outer(
                radial_precision,
                a,
                l,
                4.0 * bragg::get_bragg_angstrom(proton_charge),
            ));
            assert!(r_outer > r_inner);
            h = h.min(get_h(radial_precision, l, 0.1 * (r_outer - r_inner)));
        }
    }
    assert!(r_outer > h);

    let c = r_inner / (h.exp() - 1.0);
    let num_points = ((1.0 + (r_outer / c)).ln() / h) as usize;

    let mut rs = Vec::new();
    let mut ws = Vec::new();

    for i in 1..=num_points {
        let r = c * (((i as f64) * h).exp() - 1.0);
        rs.push(r);
        ws.push((r + c) * r * r * h);
    }

    (rs, ws)
}

// TCA 106, 178 (2001), eq. 25
// we evaluate r_inner for s functions
fn get_r_inner(max_error: f64, alpha_inner: f64) -> f64 {
    let d = 1.9;

    let mut r = d - (1.0 / max_error).ln();
    r *= 2.0 / 3.0;
    r = r.exp() / alpha_inner;
    r = r.sqrt();

    r
}

#[test]
fn test_get_r_inner() {
    assert!(comparison::floats_are_same(
        get_r_inner(1.0e-12, 2.344e4),
        0.0000012304794589759454,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_inner(1.0e-12, 2.602e1),
        0.000036931719276091795,
        1.0e-15
    ));
}

// TCA 106, 178 (2001), eq. 19
fn get_r_outer(max_error: f64, alpha_outer: f64, l: usize, guess: f64) -> f64 {
    let m = (2 * l) as f64;
    let mut r_old = std::f64::MAX;
    let mut step = 0.5;
    let mut sign = 1.0;
    let mut r = guess;

    while (r_old - r).abs() > parameters::SMALL {
        let c = gamma::gamma((m + 3.0) / 2.0);
        let a = (alpha_outer * r * r).powf((m + 1.0) / 2.0);
        let e = (-alpha_outer * r * r).exp();
        let f = c * a * e;

        let sign_old = sign;
        sign = if f > max_error { 1.0 } else { -1.0 };
        if r < 0.0 {
            sign = 1.0
        }
        if sign * sign_old < 0.0 {
            step *= 0.1;
        }

        r_old = r;
        r += sign * step;
    }

    r
}

#[test]
fn test_get_r_outer() {
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.3023, 0, 2.4),
        9.827704700468292,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.2753, 1, 2.4),
        10.97632862649149,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 1.1850, 2, 2.4),
        5.656909461147809,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.1220, 0, 1.4),
        15.470033591458682,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.7270, 1, 1.4),
        6.75449681779016,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.1220, 0, 1.4),
        15.470033591458682,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.7270, 1, 1.4),
        6.75449681779016,
        1.0e-15
    ));
}

// TCA 106, 178 (2001), eqs. 17 and 18
fn get_h(max_error: f64, l: usize, guess: f64) -> f64 {
    let m = (2 * l) as f64;
    let mut h_old = std::f64::MAX;
    let mut h = guess;
    let mut step = 0.1 * guess;
    let mut sign = -1.0;

    let pi = std::f64::consts::PI;

    while (h_old - h).abs() > parameters::SMALL {
        let c0 = 4.0 * (2.0 as f64).sqrt() * pi;
        let cm = gamma::gamma(3.0 / 2.0) / gamma::gamma((m + 3.0) / 2.0);
        let p0 = 1.0 / h;
        let e0 = (-pi * pi / (2.0 * h)).exp();
        let pm = (pi / h).powf(m / 2.0);
        let rd0 = c0 * p0 * e0;
        let f = cm * pm * rd0;

        let sign_old = sign;
        sign = if f > max_error { -1.0 } else { 1.0 };
        if h < 0.0 {
            sign = 1.0
        }
        if sign * sign_old < 0.0 {
            step *= 0.1;
        }

        h_old = h;
        h += sign * step;
    }

    h
}

#[test]
fn test_get_h() {
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 0, 0.9827703),
        0.1523549756417546,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 1, 1.0976330),
        0.1402889524647394,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 2, 1.0976330),
        0.13136472924710518,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 0, 1.5470000),
        0.15235497564177505,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 1, 1.5470000),
        0.14028895246475018,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 0, 1.5470000),
        0.15235497564177505,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 1, 1.5470000),
        0.14028895246475018,
        1.0e-15
    ));
}
<commit_msg>reverse the KK grid so that "inside" points come first<commit_after>#![allow(clippy::many_single_char_names)]

use pyo3::prelude::*;

use std::collections::HashMap;

use crate::bragg;
use crate::parameters;
use statrs::function::gamma;

#[cfg(test)]
use crate::comparison;

#[pyfunction]
pub fn radial_grid_kk(num_points: usize) -> (Vec<f64>, Vec<f64>) {
    let n = num_points as i32;
    let mut rws: Vec<_> = (1..=n).map(|i| kk_r_w(i, n)).collect();
    rws.reverse();
    rws.iter().cloned().unzip()
}

// https://doi.org/10.1063/1.475719, eqs. 9-13
fn kk_r_w(i: i32, n: i32) -> (f64, f64) {
    let pi = std::f64::consts::PI;

    let angle = ((i as f64) * pi) / ((n + 1) as f64);
    let s = angle.sin();
    let c = angle.cos();
    let t1 = ((n + 1 - 2 * i) as f64) / ((n + 1) as f64);
    let t2 = 2.0 / pi;
    let x = t1 + t2 * c * s * (1.0 + (2.0 / 3.0) * s * s);
    let f = 1.0 / 2.0_f64.ln();
    let r = f * (2.0 / (1.0 - x)).ln();
    let w = r * r * (f / (1.0 - x)) * (16.0 * s * s * s * s) / (3.0 * (n as f64) + 3.0);

    (r, w)
}

#[test]
fn test_radial_grid_kk() {
    let (rs, ws) = radial_grid_kk(99);
    assert!(comparison::floats_are_same(
        rs[98],
        27.520865062836048,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        rs[97],
        22.522899235303480,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        rs[0],
        7.4914976443367854e-9,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        ws[98],
        5462.4446669497620,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        ws[97],
        1828.2535433191961,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        ws[0],
        2.1018140707490095e-24,
        1.0e-15
    ));
}

#[pyfunction]
pub fn radial_grid(
    alpha_min: HashMap<usize, f64>,
    alpha_max: f64,
    radial_precision: f64,
    proton_charge: i32,
) -> (Vec<f64>, Vec<f64>) {
    // factor 2.0 to match DIRAC code
    let r_inner = get_r_inner(radial_precision, alpha_max * 2.0);

    let mut h = std::f64::MAX;
    let mut r_outer: f64 = 0.0;

    // we need alpha_min sorted by l
    // at this point not sure why ... need to check again the literature
    let mut v: Vec<_> = alpha_min.into_iter().collect();
    v.sort_by(|x, y| x.0.cmp(&y.0));

    for (l, a) in v {
        if a > 0.0 {
            r_outer = r_outer.max(get_r_outer(
                radial_precision,
                a,
                l,
                4.0 * bragg::get_bragg_angstrom(proton_charge),
            ));
            assert!(r_outer > r_inner);
            h = h.min(get_h(radial_precision, l, 0.1 * (r_outer - r_inner)));
        }
    }
    assert!(r_outer > h);

    let c = r_inner / (h.exp() - 1.0);
    let num_points = ((1.0 + (r_outer / c)).ln() / h) as usize;

    let mut rs = Vec::new();
    let mut ws = Vec::new();

    for i in 1..=num_points {
        let r = c * (((i as f64) * h).exp() - 1.0);
        rs.push(r);
        ws.push((r + c) * r * r * h);
    }

    (rs, ws)
}

// TCA 106, 178 (2001), eq. 25
// we evaluate r_inner for s functions
fn get_r_inner(max_error: f64, alpha_inner: f64) -> f64 {
    let d = 1.9;

    let mut r = d - (1.0 / max_error).ln();
    r *= 2.0 / 3.0;
    r = r.exp() / alpha_inner;
    r = r.sqrt();

    r
}

#[test]
fn test_get_r_inner() {
    assert!(comparison::floats_are_same(
        get_r_inner(1.0e-12, 2.344e4),
        0.0000012304794589759454,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_inner(1.0e-12, 2.602e1),
        0.000036931719276091795,
        1.0e-15
    ));
}

// TCA 106, 178 (2001), eq. 19
fn get_r_outer(max_error: f64, alpha_outer: f64, l: usize, guess: f64) -> f64 {
    let m = (2 * l) as f64;
    let mut r_old = std::f64::MAX;
    let mut step = 0.5;
    let mut sign = 1.0;
    let mut r = guess;

    while (r_old - r).abs() > parameters::SMALL {
        let c = gamma::gamma((m + 3.0) / 2.0);
        let a = (alpha_outer * r * r).powf((m + 1.0) / 2.0);
        let e = (-alpha_outer * r * r).exp();
        let f = c * a * e;

        let sign_old = sign;
        sign = if f > max_error { 1.0 } else { -1.0 };
        if r < 0.0 {
            sign = 1.0
        }
        if sign * sign_old < 0.0 {
            step *= 0.1;
        }

        r_old = r;
        r += sign * step;
    }

    r
}

#[test]
fn test_get_r_outer() {
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.3023, 0, 2.4),
        9.827704700468292,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.2753, 1, 2.4),
        10.97632862649149,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 1.1850, 2, 2.4),
        5.656909461147809,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.1220, 0, 1.4),
        15.470033591458682,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.7270, 1, 1.4),
        6.75449681779016,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.1220, 0, 1.4),
        15.470033591458682,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_r_outer(1.0e-12, 0.7270, 1, 1.4),
        6.75449681779016,
        1.0e-15
    ));
}

// TCA 106, 178 (2001), eqs. 17 and 18
fn get_h(max_error: f64, l: usize, guess: f64) -> f64 {
    let m = (2 * l) as f64;
    let mut h_old = std::f64::MAX;
    let mut h = guess;
    let mut step = 0.1 * guess;
    let mut sign = -1.0;

    let pi = std::f64::consts::PI;

    while (h_old - h).abs() > parameters::SMALL {
        let c0 = 4.0 * (2.0 as f64).sqrt() * pi;
        let cm = gamma::gamma(3.0 / 2.0) / gamma::gamma((m + 3.0) / 2.0);
        let p0 = 1.0 / h;
        let e0 = (-pi * pi / (2.0 * h)).exp();
        let pm = (pi / h).powf(m / 2.0);
        let rd0 = c0 * p0 * e0;
        let f = cm * pm * rd0;

        let sign_old = sign;
        sign = if f > max_error { -1.0 } else { 1.0 };
        if h < 0.0 {
            sign = 1.0
        }
        if sign * sign_old < 0.0 {
            step *= 0.1;
        }

        h_old = h;
        h += sign * step;
    }

    h
}

#[test]
fn test_get_h() {
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 0, 0.9827703),
        0.1523549756417546,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 1, 1.0976330),
        0.1402889524647394,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 2, 1.0976330),
        0.13136472924710518,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 0, 1.5470000),
        0.15235497564177505,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 1, 1.5470000),
        0.14028895246475018,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 0, 1.5470000),
        0.15235497564177505,
        1.0e-15
    ));
    assert!(comparison::floats_are_same(
        get_h(1.0e-12, 1, 1.5470000),
        0.14028895246475018,
        1.0e-15
    ));
}
<|endoftext|>


<commit_before>use log::{error, warn};
use std::cmp;
use std::convert::TryInto;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::sync::Mutex;

use rayon::prelude::*;

use super::parser;
use super::{Document, Object, ObjectId};
use crate::object_stream::ObjectStream;
use crate::xref::XrefEntry;
use crate::{Error, Result};
use crate::error::XrefError;

impl Document {
	/// Load a PDF document from a specified file path.
	#[inline]
	pub fn load<P: AsRef<Path>>(path: P) -> Result<Document> {
		let file = File::open(path)?;
		let buffer = Vec::with_capacity(file.metadata()?.len() as usize);
		Self::load_internal(file, buffer)
	}

	/// Load a PDF document from an arbitrary source.
	#[inline]
	pub fn load_from<R: Read>(source: R) -> Result<Document> {
		let buffer = Vec::<u8>::new();
		Self::load_internal(source, buffer)
	}

	fn load_internal<R: Read>(mut source: R, mut buffer: Vec<u8>) -> Result<Document> {
		source.read_to_end(&mut buffer)?;

		let mut reader = Reader {
			buffer: &buffer,
			document: Document::new(),
		};

		reader.read()?;
		Ok(reader.document)
	}

	/// Load a PDF document from a memory slice.
	pub fn load_mem(buffer: &[u8]) -> Result<Document> {
		buffer.try_into()
	}
}

impl TryInto<Document> for &[u8] {
	type Error = Error;

	fn try_into(self) -> Result<Document> {
		let mut reader = Reader {
			buffer: self,
			document: Document::new(),
		};
		reader.read()?;
		Ok(reader.document)
	}
}

pub struct Reader<'a> {
	buffer: &'a [u8],
	document: Document,
}

impl <'a> Reader<'a> {
	/// Read whole document.
	fn read(&mut self) -> Result<()> {
		// The document structure can be expressed in PEG as:
		//   document <- header indirect_object* xref trailer xref_start
		let version = parser::header(&self.buffer).ok_or(Error::Header)?;

		let xref_start = Self::get_xref_start(&self.buffer)?;
		if xref_start > self.buffer.len() {
			return Err(Error::Xref(XrefError::Start));
		}

		let (mut xref, mut trailer) = parser::xref_and_trailer(&self.buffer[xref_start..], self)?;

		// Read previous Xrefs of linearized or incremental updated document.
		let mut prev_xref_start = trailer.remove(b"Prev");
		while let Some(prev) = prev_xref_start.and_then(|offset| offset.as_i64().ok()) {
			let prev = prev as usize;
			if prev > self.buffer.len() {
				return Err(Error::Xref(XrefError::PrevStart));
			}
			let (prev_xref, mut prev_trailer) = parser::xref_and_trailer(&self.buffer[prev..], &self)?;
			xref.extend(prev_xref);

			// Read xref stream in hybrid-reference file
			let prev_xref_stream_start = trailer.remove(b"XRefStm");
			if let Some(prev) = prev_xref_stream_start.and_then(|offset| offset.as_i64().ok()) {
				let prev = prev as usize;
				if prev > self.buffer.len() {
					return Err(Error::Xref(XrefError::StreamStart));
				}
				let (prev_xref, _) = parser::xref_and_trailer(&self.buffer[prev..], &self)?;
				xref.extend(prev_xref);
			}

			prev_xref_start = prev_trailer.remove(b"Prev");
		}

		let xref_entry_count = xref.max_id() + 1;
		if xref.size != xref_entry_count {
			warn!("Size entry of trailer dictionary is {}, correct value is {}.", xref.size, xref_entry_count);
			xref.size = xref_entry_count;
		}

		self.document.version = version;
		self.document.max_id = xref.size - 1;
		self.document.trailer = trailer;
		self.document.reference_table = xref;

		let zero_length_streams = Mutex::new(vec![]);
		let object_streams = Mutex::new(vec![]);

		self.document.objects = self.document.reference_table.entries.par_iter().filter_map(|(_, entry)| {
			if let XrefEntry::Normal { offset, .. } = *entry {
				let (object_id, mut object) = self.read_object(offset as usize)
					.map_err(|e| error!("Object load error: {:?}", e)).ok()?;
				if let Ok(ref mut stream) = object.as_stream_mut() {
					if stream.dict.type_is(b"ObjStm") {
						let obj_stream = ObjectStream::new(stream).ok()?;
						let mut object_streams = object_streams.lock().unwrap();
						object_streams.extend(obj_stream.objects);
					} else if stream.content.is_empty() {
						let mut zero_length_streams = zero_length_streams.lock().unwrap();
						zero_length_streams.push(object_id);
					}
				}
				Some((object_id, object))
			} else {
				None
			}
		}).collect();

		self.document.objects.extend(object_streams.into_inner().unwrap());

		for object_id in zero_length_streams.into_inner().unwrap() {
			let _ = self.set_stream_content(object_id);
		}

		Ok(())
	}

	fn set_stream_content(&mut self, object_id: ObjectId) -> Result<()> {
		let length = self.get_stream_length(object_id)?;
		let stream = self.document.get_object_mut(object_id).and_then(Object::as_stream_mut)?;
		let start = stream.start_position.ok_or(Error::ObjectNotFound)?;

		let end = start + length as usize;
		stream.set_content(self.buffer[start..end].to_vec());
		Ok(())
	}

	fn get_stream_length(&self, object_id: ObjectId) -> Result<i64> {
		let object = self.document.get_object(object_id)?;
		let stream = object.as_stream()?;

		stream.dict.get(b"Length").and_then(|value| {
			if let Ok(id) = value.as_reference() {
				return self.document.get_object(id).and_then(Object::as_i64);
			}
			value.as_i64()
		})
	}

	/// Get object offset by object id.
	fn get_offset(&self, id: ObjectId) -> Result<u32> {
		let entry = self.document.reference_table.get(id.0).ok_or(Error::ObjectNotFound)?;
		match *entry {
			XrefEntry::Normal { offset, generation } => {
				if id.1 == generation {
					Ok(offset)
				} else {
					Err(Error::ObjectNotFound)
				}
			}
			_ => Err(Error::ObjectNotFound),
		}
	}

	pub fn get_object(&self, id: ObjectId) -> Result<Object> {
		let offset = self.get_offset(id)?;
		let (_, obj) = self.read_object(offset as usize)?;

		Ok(obj)
	}

	fn read_object(&self, offset: usize) -> Result<(ObjectId, Object)> {
		if offset > self.buffer.len() {
			return Err(Error::Offset(offset));
		}

		parser::indirect_object(&self.buffer, offset, self)
	}

	fn get_xref_start(buffer: &[u8]) -> Result<usize> {
		let seek_pos = buffer.len() - cmp::min(buffer.len(), 512);
		Self::search_substring(buffer, b"%%EOF", seek_pos)
			.and_then(|eof_pos| Self::search_substring(buffer, b"startxref", eof_pos - 25))
			.ok_or(Error::Xref(XrefError::Start))
			.and_then(|xref_pos| if xref_pos <= buffer.len() {
				match parser::xref_start(&buffer[xref_pos..]) {
					Some(startxref) => Ok(startxref as usize),
					None => Err(Error::Xref(XrefError::Start)),
				}
			} else {
				Err(Error::Xref(XrefError::Start))
			})
	}

	fn search_substring(buffer: &[u8], pattern: &[u8], start_pos: usize) -> Option<usize> {
		let mut seek_pos = start_pos;
		let mut index = 0;

		while seek_pos < buffer.len() && index < pattern.len() {
			if buffer[seek_pos] == pattern[index] {
				index += 1;
			} else if index > 0 {
				seek_pos -= index;
				index = 0;
			}
			seek_pos += 1;

			if index == pattern.len() {
				return Some(seek_pos - index);
			}
		}

		None
	}
}

#[test]
fn load_document() {
	let mut doc = Document::load("assets/example.pdf").unwrap();
	assert_eq!(doc.version, "1.5");
	doc.save("test_2_load.pdf").unwrap();
}
<commit_msg>Unify buffer creation.<commit_after>use log::{error, warn};
use std::cmp;
use std::convert::TryInto;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::sync::Mutex;

use rayon::prelude::*;

use super::parser;
use super::{Document, Object, ObjectId};
use crate::object_stream::ObjectStream;
use crate::xref::XrefEntry;
use crate::{Error, Result};
use crate::error::XrefError;

impl Document {
	/// Load a PDF document from a specified file path.
	#[inline]
	pub fn load<P: AsRef<Path>>(path: P) -> Result<Document> {
		let file = File::open(path)?;
		let capacity = Some(file.metadata()?.len() as usize);
		Self::load_internal(file, capacity)
	}

	/// Load a PDF document from an arbitrary source.
	#[inline]
	pub fn load_from<R: Read>(source: R) -> Result<Document> {
		Self::load_internal(source, None)
	}

	fn load_internal<R: Read>(mut source: R, capacity: Option<usize>) -> Result<Document> {
		let mut buffer = capacity.map(Vec::with_capacity).unwrap_or_else(Vec::new);
		source.read_to_end(&mut buffer)?;

		let mut reader = Reader {
			buffer: &buffer,
			document: Document::new(),
		};

		reader.read()?;
		Ok(reader.document)
	}

	/// Load a PDF document from a memory slice.
	pub fn load_mem(buffer: &[u8]) -> Result<Document> {
		buffer.try_into()
	}
}

impl TryInto<Document> for &[u8] {
	type Error = Error;

	fn try_into(self) -> Result<Document> {
		let mut reader = Reader {
			buffer: self,
			document: Document::new(),
		};
		reader.read()?;
		Ok(reader.document)
	}
}

pub struct Reader<'a> {
	buffer: &'a [u8],
	document: Document,
}

impl <'a> Reader<'a> {
	/// Read whole document.
	fn read(&mut self) -> Result<()> {
		// The document structure can be expressed in PEG as:
		//   document <- header indirect_object* xref trailer xref_start
		let version = parser::header(&self.buffer).ok_or(Error::Header)?;

		let xref_start = Self::get_xref_start(&self.buffer)?;
		if xref_start > self.buffer.len() {
			return Err(Error::Xref(XrefError::Start));
		}

		let (mut xref, mut trailer) = parser::xref_and_trailer(&self.buffer[xref_start..], self)?;

		// Read previous Xrefs of linearized or incremental updated document.
		let mut prev_xref_start = trailer.remove(b"Prev");
		while let Some(prev) = prev_xref_start.and_then(|offset| offset.as_i64().ok()) {
			let prev = prev as usize;
			if prev > self.buffer.len() {
				return Err(Error::Xref(XrefError::PrevStart));
			}
			let (prev_xref, mut prev_trailer) = parser::xref_and_trailer(&self.buffer[prev..], &self)?;
			xref.extend(prev_xref);

			// Read xref stream in hybrid-reference file
			let prev_xref_stream_start = trailer.remove(b"XRefStm");
			if let Some(prev) = prev_xref_stream_start.and_then(|offset| offset.as_i64().ok()) {
				let prev = prev as usize;
				if prev > self.buffer.len() {
					return Err(Error::Xref(XrefError::StreamStart));
				}
				let (prev_xref, _) = parser::xref_and_trailer(&self.buffer[prev..], &self)?;
				xref.extend(prev_xref);
			}

			prev_xref_start = prev_trailer.remove(b"Prev");
		}

		let xref_entry_count = xref.max_id() + 1;
		if xref.size != xref_entry_count {
			warn!("Size entry of trailer dictionary is {}, correct value is {}.", xref.size, xref_entry_count);
			xref.size = xref_entry_count;
		}

		self.document.version = version;
		self.document.max_id = xref.size - 1;
		self.document.trailer = trailer;
		self.document.reference_table = xref;

		let zero_length_streams = Mutex::new(vec![]);
		let object_streams = Mutex::new(vec![]);

		self.document.objects = self.document.reference_table.entries.par_iter().filter_map(|(_, entry)| {
			if let XrefEntry::Normal { offset, .. } = *entry {
				let (object_id, mut object) = self.read_object(offset as usize)
					.map_err(|e| error!("Object load error: {:?}", e)).ok()?;
				if let Ok(ref mut stream) = object.as_stream_mut() {
					if stream.dict.type_is(b"ObjStm") {
						let obj_stream = ObjectStream::new(stream).ok()?;
						let mut object_streams = object_streams.lock().unwrap();
						object_streams.extend(obj_stream.objects);
					} else if stream.content.is_empty() {
						let mut zero_length_streams = zero_length_streams.lock().unwrap();
						zero_length_streams.push(object_id);
					}
				}
				Some((object_id, object))
			} else {
				None
			}
		}).collect();

		self.document.objects.extend(object_streams.into_inner().unwrap());

		for object_id in zero_length_streams.into_inner().unwrap() {
			let _ = self.set_stream_content(object_id);
		}

		Ok(())
	}

	fn set_stream_content(&mut self, object_id: ObjectId) -> Result<()> {
		let length = self.get_stream_length(object_id)?;
		let stream = self.document.get_object_mut(object_id).and_then(Object::as_stream_mut)?;
		let start = stream.start_position.ok_or(Error::ObjectNotFound)?;

		let end = start + length as usize;
		stream.set_content(self.buffer[start..end].to_vec());
		Ok(())
	}

	fn get_stream_length(&self, object_id: ObjectId) -> Result<i64> {
		let object = self.document.get_object(object_id)?;
		let stream = object.as_stream()?;

		stream.dict.get(b"Length").and_then(|value| {
			if let Ok(id) = value.as_reference() {
				return self.document.get_object(id).and_then(Object::as_i64);
			}
			value.as_i64()
		})
	}

	/// Get object offset by object id.
	fn get_offset(&self, id: ObjectId) -> Result<u32> {
		let entry = self.document.reference_table.get(id.0).ok_or(Error::ObjectNotFound)?;
		match *entry {
			XrefEntry::Normal { offset, generation } => {
				if id.1 == generation {
					Ok(offset)
				} else {
					Err(Error::ObjectNotFound)
				}
			}
			_ => Err(Error::ObjectNotFound),
		}
	}

	pub fn get_object(&self, id: ObjectId) -> Result<Object> {
		let offset = self.get_offset(id)?;
		let (_, obj) = self.read_object(offset as usize)?;

		Ok(obj)
	}

	fn read_object(&self, offset: usize) -> Result<(ObjectId, Object)> {
		if offset > self.buffer.len() {
			return Err(Error::Offset(offset));
		}

		parser::indirect_object(&self.buffer, offset, self)
	}

	fn get_xref_start(buffer: &[u8]) -> Result<usize> {
		let seek_pos = buffer.len() - cmp::min(buffer.len(), 512);
		Self::search_substring(buffer, b"%%EOF", seek_pos)
			.and_then(|eof_pos| Self::search_substring(buffer, b"startxref", eof_pos - 25))
			.ok_or(Error::Xref(XrefError::Start))
			.and_then(|xref_pos| if xref_pos <= buffer.len() {
				match parser::xref_start(&buffer[xref_pos..]) {
					Some(startxref) => Ok(startxref as usize),
					None => Err(Error::Xref(XrefError::Start)),
				}
			} else {
				Err(Error::Xref(XrefError::Start))
			})
	}

	fn search_substring(buffer: &[u8], pattern: &[u8], start_pos: usize) -> Option<usize> {
		let mut seek_pos = start_pos;
		let mut index = 0;

		while seek_pos < buffer.len() && index < pattern.len() {
			if buffer[seek_pos] == pattern[index] {
				index += 1;
			} else if index > 0 {
				seek_pos -= index;
				index = 0;
			}
			seek_pos += 1;

			if index == pattern.len() {
				return Some(seek_pos - index);
			}
		}

		None
	}
}

#[test]
fn load_document() {
	let mut doc = Document::load("assets/example.pdf").unwrap();
	assert_eq!(doc.version, "1.5");
	doc.save("test_2_load.pdf").unwrap();
}
<|endoftext|>