<commit_before>/* Copyright © 2001-2014, 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
*/

#include "raptor_solutions.h"
#include "raptor_path.h"
#include "raptor.h"
#include "raptor_path_defs.h"

namespace bt = boost::posix_time;
namespace navitia { namespace routing {

Solutions
get_solutions(const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
             const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations,
             bool clockwise, const type::AccessibiliteParams & accessibilite_params,
             bool disruption_active, const RAPTOR& raptor) {
      Solutions result;
      auto pareto_front = get_pareto_front(clockwise, departs, destinations,
              accessibilite_params, disruption_active, raptor);
      result.insert(pareto_front.begin(), pareto_front.end());

      if(!pareto_front.empty()) {
          auto walking_solutions = get_walking_solutions(clockwise, departs, destinations,
                  *pareto_front.rbegin(), disruption_active, accessibilite_params, raptor);
          if(!walking_solutions.empty()) {
            result.insert(walking_solutions.begin(), walking_solutions.end());
          }
      }
      return result;
}

Solutions
get_solutions(const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
              const DateTime &dep, bool clockwise, const type::Data & data, bool) {
    Solutions result;
    for(auto dep_dist : departs) {
        for(auto journey_pattern : data.pt_data->stop_points[dep_dist.first]->journey_pattern_point_list) {
            Solution d;
            d.count = 0;
            d.rpidx = journey_pattern->idx;
            d.walking_time = dep_dist.second;
            if(clockwise)
                d.arrival = dep + d.walking_time.total_seconds();
            else
                d.arrival = dep - d.walking_time.total_seconds();
            result.insert(d);
        }
    }
    return result;
}

// Does the current date improves compared to best_so_far – we must not forget to take the walking duration
bool improves(const DateTime & best_so_far, bool clockwise, const DateTime & current, int walking_duration) {
    if(clockwise) {
        return (current - walking_duration) > best_so_far;
    } else {
        return (current + walking_duration) < best_so_far;
    }
}

Solutions
get_pareto_front(bool clockwise, const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
               const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations,
               const type::AccessibiliteParams & accessibilite_params, bool disruption_active, const RAPTOR& raptor) {
    Solutions result;

    DateTime best_dt, best_dt_jpp;
    if(clockwise) {
        best_dt = DateTimeUtils::min;
        best_dt_jpp = DateTimeUtils::min;
    } else {
        best_dt = DateTimeUtils::inf;
        best_dt_jpp = DateTimeUtils::inf;
    }
    for(unsigned int round=1; round < raptor.labels.size(); ++round) {
        // For every round with look for the best journey pattern point that belongs to one of the destination stop points
        // We must not forget to walking duration
        type::idx_t best_jpp = type::invalid_idx;
        for(auto spid_dist : destinations) {
            for(auto journey_pattern_point : raptor.data.pt_data->stop_points[spid_dist.first]->journey_pattern_point_list) {
                type::idx_t jppidx = journey_pattern_point->idx;
                auto type = raptor.labels[round][journey_pattern_point->idx].type;
                auto& l = raptor.labels[round][jppidx];
                if((type == boarding_type::vj || type == boarding_type::connection_stay_in) &&
                   l.dt != DateTimeUtils::inf &&
                   l.dt != DateTimeUtils::min &&
                   improves(best_dt, clockwise, l.dt, spid_dist.second.total_seconds()) ) {
                    best_jpp = jppidx;
                    best_dt_jpp = l.dt;
                    // Dans le sens horaire : lors du calcul on gardé que l’heure de départ, mais on veut l’arrivée
                    // Il faut donc retrouver le stop_time qui nous intéresse avec best_stop_time
                    const type::StopTime* st;
                    DateTime dt = 0;

                    std::tie(st, dt) = best_stop_time(journey_pattern_point, l.dt, accessibilite_params.vehicle_properties,
                                                      !clockwise, disruption_active, raptor.data, true);
                    BOOST_ASSERT(st);
                    if(st != nullptr) {
                        if(clockwise) {
                            auto arrival_time = !st->is_frequency() ? st->arrival_time : st->f_arrival_time(DateTimeUtils::hour(dt));
                            DateTimeUtils::update(best_dt_jpp, arrival_time, !clockwise);
                        } else {
                            auto departure_time = !st->is_frequency() ? st->departure_time : st->f_departure_time(DateTimeUtils::hour(dt));
                            DateTimeUtils::update(best_dt_jpp, departure_time, !clockwise);
                        }
                    }
                    if(clockwise)
                        best_dt = l.dt - (spid_dist.second.total_seconds());
                    else
                        best_dt = l.dt + (spid_dist.second.total_seconds());
                }
            }
        }
        if(best_jpp != type::invalid_idx) {
            Solution s;
            s.rpidx = best_jpp;
            s.count = round;
            s.walking_time = getWalkingTime(round, best_jpp, departs, destinations, clockwise, disruption_active,
                                            accessibilite_params, raptor);
            s.arrival = best_dt_jpp;
            s.ratio = 0;
            type::idx_t final_rpidx;
            std::tie(final_rpidx, s.upper_bound) = get_final_jppidx_and_date(round, best_jpp, clockwise,
                                                                             disruption_active, accessibilite_params, raptor);
            for(auto spid_dep : departs) {
                if(raptor.data.pt_data->journey_pattern_points[final_rpidx]->stop_point->idx == spid_dep.first) {
                    if(clockwise) {
                        s.upper_bound = s.upper_bound + (spid_dep.second.total_seconds());
                    }else {
                        s.upper_bound = s.upper_bound - (spid_dep.second.total_seconds());
                    }
                }
            }
            result.insert(s);
        }
    }

    return result;
}

Solutions
get_walking_solutions(bool clockwise, const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
                      const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations, const Solution& best,
                      const bool disruption_active, const type::AccessibiliteParams &accessibilite_params,
                      const RAPTOR& raptor) {
    Solutions result;

    std::/*unordered_*/map<type::idx_t, Solution> tmp;

    for(uint32_t i=0; i<raptor.labels.size(); ++i) {
        for(auto spid_dist : destinations) {
            Solution best_departure;
            best_departure.ratio = 2;
            best_departure.rpidx = type::invalid_idx;
            for(auto journey_pattern_point : raptor.data.pt_data->stop_points[spid_dist.first]->journey_pattern_point_list) {
                type::idx_t jppidx = journey_pattern_point->idx;
                if(raptor.labels[i][journey_pattern_point->idx].type != boarding_type::uninitialized) {
                    navitia::time_duration walking_time = getWalkingTime(i, jppidx, departs, destinations, clockwise,
                                                                         disruption_active, accessibilite_params, raptor);
                    if(best.walking_time <= walking_time) {
                        continue;
                    }
                    float lost_time;
                    if(clockwise)
                        lost_time = raptor.labels[i][jppidx].dt - (spid_dist.second.total_seconds()) - best.arrival;
                    else
                        lost_time = raptor.labels[i][jppidx].dt + (spid_dist.second.total_seconds()) - best.arrival;

                    //Si je gagne 5 minutes de marche a pied, je suis pret à perdre jusqu'à 10 minutes.
                    int walking_time_diff_in_s = (best.walking_time - walking_time).total_seconds();
                    if (walking_time_diff_in_s > 0) {
                        float ratio = lost_time / walking_time_diff_in_s;
                        if( ratio < best_departure.ratio) {
                            Solution s;
                            s.rpidx = jppidx;
                            s.count = i;
                            s.ratio = ratio;
                            s.walking_time = walking_time;
                            s.arrival = raptor.labels[i][jppidx].dt;
                            type::idx_t final_rpidx;
                            DateTime last_time;
                            std::tie(final_rpidx, last_time) = get_final_jppidx_and_date(i, jppidx, clockwise,
                                                                                disruption_active, accessibilite_params, raptor);

                            if(clockwise) {
                                s.upper_bound = last_time;
                                for(auto spid_dep : departs) {
                                    if(raptor.data.pt_data->journey_pattern_points[final_rpidx]->stop_point->idx == spid_dep.first) {
                                        s.upper_bound = s.upper_bound + (spid_dep.second.total_seconds());
                                    }
                                }
                            } else {
                                s.upper_bound = last_time;
                                for(auto spid_dep : departs) {
                                    if(raptor.data.pt_data->journey_pattern_points[final_rpidx]->stop_point->idx == spid_dep.first) {
                                        s.upper_bound = s.upper_bound - (spid_dep.second.total_seconds());
                                    }
                                }
                            }

                            best_departure = s;
                        }
                    }
                }
            }
            if(best_departure.rpidx != type::invalid_idx) {
                type::idx_t journey_pattern = raptor.data.pt_data->journey_pattern_points[best_departure.rpidx]->journey_pattern->idx;
                if(tmp.find(journey_pattern) == tmp.end()) {
                    tmp.insert(std::make_pair(journey_pattern, best_departure));
                } else if(tmp[journey_pattern].ratio > best_departure.ratio) {
                    tmp[journey_pattern] = best_departure;
                }
            }

        }
    }

    std::vector<Solution> to_sort;
    for(auto p : tmp) {
        to_sort.push_back(p.second);
    }
    std::sort(to_sort.begin(), to_sort.end(),
            [](const Solution s1, const Solution s2) { return s1.ratio < s2.ratio;});

    if(to_sort.size() > 2)
        to_sort.resize(2);
    result.insert(to_sort.begin(), to_sort.end());

    return result;
}

struct VisitorFinalJppAndDate : public BasePathVisitor {
    type::idx_t current_jpp = type::invalid_idx;
    DateTime last_time = DateTimeUtils::inf;
    void final_step(const type::idx_t current_jpp, size_t count, const std::vector<label_vector_t> &labels) {
        this->current_jpp = current_jpp;
        last_time = labels[count][current_jpp].dt;
    }
};

// Reparcours l’itinéraire rapidement pour avoir le JPP et la date de départ (si on cherchait l’arrivée au plus tôt)
std::pair<type::idx_t, DateTime>
get_final_jppidx_and_date(int count, type::idx_t jpp_idx, bool clockwise, bool disruption_active,
                          const type::AccessibiliteParams & accessibilite_params, const RAPTOR& raptor) {
    VisitorFinalJppAndDate v;
    read_path(v, jpp_idx, count, !clockwise, disruption_active, accessibilite_params, raptor);
    return std::make_pair(v.current_jpp, v.last_time);
}

struct VisitorWalkingTime : public BasePathVisitor {
    navitia::time_duration walking_time = {};
    void connection(type::StopPoint* , type::StopPoint* ,
                boost::posix_time::ptime dep_time, boost::posix_time::ptime arr_time,
                type::StopPointConnection*) {

        walking_time += navitia::seconds((arr_time - dep_time).total_seconds());
    }
};

navitia::time_duration getWalkingTime(int count, type::idx_t jpp_idx, const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
                     const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations,
                     bool clockwise, bool disruption_active, const type::AccessibiliteParams & accessibilite_params,
                     const RAPTOR& raptor) {

    const type::JourneyPatternPoint* current_jpp = raptor.data.pt_data->journey_pattern_points[jpp_idx];
    navitia::time_duration walking_time = {};

    //Marche à la fin
    for(auto dest_dist : destinations) {
        if(dest_dist.first == current_jpp->stop_point->idx) {
            walking_time = dest_dist.second;
            break;
        }
    }

    VisitorWalkingTime v;
    read_path(v, current_jpp->idx, count, !clockwise, disruption_active, accessibilite_params, raptor);
    walking_time += v.walking_time;
    //Marche au départ
    for(auto dep_dist : departs) {
        if(dep_dist.first == current_jpp->stop_point->idx) {
            walking_time += dep_dist.second;
            break;
        }
    }

    return walking_time;
}

}}

<commit_msg>Kraken: only look for solutions ending by a vj or a connection_stay_in<commit_after>/* Copyright © 2001-2014, 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
*/

#include "raptor_solutions.h"
#include "raptor_path.h"
#include "raptor.h"
#include "raptor_path_defs.h"

namespace bt = boost::posix_time;
namespace navitia { namespace routing {

Solutions
get_solutions(const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
             const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations,
             bool clockwise, const type::AccessibiliteParams & accessibilite_params,
             bool disruption_active, const RAPTOR& raptor) {
      Solutions result;
      auto pareto_front = get_pareto_front(clockwise, departs, destinations,
              accessibilite_params, disruption_active, raptor);
      result.insert(pareto_front.begin(), pareto_front.end());

      if(!pareto_front.empty()) {
          auto walking_solutions = get_walking_solutions(clockwise, departs, destinations,
                  *pareto_front.rbegin(), disruption_active, accessibilite_params, raptor);
          if(!walking_solutions.empty()) {
            result.insert(walking_solutions.begin(), walking_solutions.end());
          }
      }
      return result;
}

Solutions
get_solutions(const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
              const DateTime &dep, bool clockwise, const type::Data & data, bool) {
    Solutions result;
    for(auto dep_dist : departs) {
        for(auto journey_pattern : data.pt_data->stop_points[dep_dist.first]->journey_pattern_point_list) {
            Solution d;
            d.count = 0;
            d.rpidx = journey_pattern->idx;
            d.walking_time = dep_dist.second;
            if(clockwise)
                d.arrival = dep + d.walking_time.total_seconds();
            else
                d.arrival = dep - d.walking_time.total_seconds();
            result.insert(d);
        }
    }
    return result;
}

// Does the current date improves compared to best_so_far – we must not forget to take the walking duration
bool improves(const DateTime & best_so_far, bool clockwise, const DateTime & current, int walking_duration) {
    if(clockwise) {
        return (current - walking_duration) > best_so_far;
    } else {
        return (current + walking_duration) < best_so_far;
    }
}

Solutions
get_pareto_front(bool clockwise, const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
               const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations,
               const type::AccessibiliteParams & accessibilite_params, bool disruption_active, const RAPTOR& raptor) {
    Solutions result;

    DateTime best_dt, best_dt_jpp;
    if(clockwise) {
        best_dt = DateTimeUtils::min;
        best_dt_jpp = DateTimeUtils::min;
    } else {
        best_dt = DateTimeUtils::inf;
        best_dt_jpp = DateTimeUtils::inf;
    }
    for(unsigned int round=1; round < raptor.labels.size(); ++round) {
        // For every round with look for the best journey pattern point that belongs to one of the destination stop points
        // We must not forget to walking duration
        type::idx_t best_jpp = type::invalid_idx;
        for(auto spid_dist : destinations) {
            for(auto journey_pattern_point : raptor.data.pt_data->stop_points[spid_dist.first]->journey_pattern_point_list) {
                type::idx_t jppidx = journey_pattern_point->idx;
                auto type = raptor.labels[round][journey_pattern_point->idx].type;
                auto& l = raptor.labels[round][jppidx];
                if((type == boarding_type::vj || type == boarding_type::connection_stay_in) &&
                   l.dt != DateTimeUtils::inf &&
                   l.dt != DateTimeUtils::min &&
                   improves(best_dt, clockwise, l.dt, spid_dist.second.total_seconds()) ) {
                    best_jpp = jppidx;
                    best_dt_jpp = l.dt;
                    // Dans le sens horaire : lors du calcul on gardé que l’heure de départ, mais on veut l’arrivée
                    // Il faut donc retrouver le stop_time qui nous intéresse avec best_stop_time
                    const type::StopTime* st;
                    DateTime dt = 0;

                    std::tie(st, dt) = best_stop_time(journey_pattern_point, l.dt, accessibilite_params.vehicle_properties,
                                                      !clockwise, disruption_active, raptor.data, true);
                    BOOST_ASSERT(st);
                    if(st != nullptr) {
                        if(clockwise) {
                            auto arrival_time = !st->is_frequency() ? st->arrival_time : st->f_arrival_time(DateTimeUtils::hour(dt));
                            DateTimeUtils::update(best_dt_jpp, arrival_time, !clockwise);
                        } else {
                            auto departure_time = !st->is_frequency() ? st->departure_time : st->f_departure_time(DateTimeUtils::hour(dt));
                            DateTimeUtils::update(best_dt_jpp, departure_time, !clockwise);
                        }
                    }
                    if(clockwise)
                        best_dt = l.dt - (spid_dist.second.total_seconds());
                    else
                        best_dt = l.dt + (spid_dist.second.total_seconds());
                }
            }
        }
        if(best_jpp != type::invalid_idx) {
            Solution s;
            s.rpidx = best_jpp;
            s.count = round;
            s.walking_time = getWalkingTime(round, best_jpp, departs, destinations, clockwise, disruption_active,
                                            accessibilite_params, raptor);
            s.arrival = best_dt_jpp;
            s.ratio = 0;
            type::idx_t final_rpidx;
            std::tie(final_rpidx, s.upper_bound) = get_final_jppidx_and_date(round, best_jpp, clockwise,
                                                                             disruption_active, accessibilite_params, raptor);
            for(auto spid_dep : departs) {
                if(raptor.data.pt_data->journey_pattern_points[final_rpidx]->stop_point->idx == spid_dep.first) {
                    if(clockwise) {
                        s.upper_bound = s.upper_bound + (spid_dep.second.total_seconds());
                    }else {
                        s.upper_bound = s.upper_bound - (spid_dep.second.total_seconds());
                    }
                }
            }
            result.insert(s);
        }
    }

    return result;
}

Solutions
get_walking_solutions(bool clockwise, const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
                      const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations, const Solution& best,
                      const bool disruption_active, const type::AccessibiliteParams &accessibilite_params,
                      const RAPTOR& raptor) {
    Solutions result;

    std::/*unordered_*/map<type::idx_t, Solution> tmp;

    for(uint32_t i=0; i<raptor.labels.size(); ++i) {
        for(auto spid_dist : destinations) {
            Solution best_departure;
            best_departure.ratio = 2;
            best_departure.rpidx = type::invalid_idx;
            for(auto journey_pattern_point : raptor.data.pt_data->stop_points[spid_dist.first]->journey_pattern_point_list) {
                type::idx_t jppidx = journey_pattern_point->idx;
                // We only want solution ending by a vehicle journey or a stay_in
                if(raptor.labels[i][journey_pattern_point->idx].type == boarding_type::vj &&
                   raptor.labels[i][journey_pattern_point->idx].type == boarding_type::connection_stay_in) {
                    navitia::time_duration walking_time = getWalkingTime(i, jppidx, departs, destinations, clockwise,
                                                                         disruption_active, accessibilite_params, raptor);
                    if(best.walking_time <= walking_time) {
                        continue;
                    }
                    float lost_time;
                    if(clockwise)
                        lost_time = raptor.labels[i][jppidx].dt - (spid_dist.second.total_seconds()) - best.arrival;
                    else
                        lost_time = raptor.labels[i][jppidx].dt + (spid_dist.second.total_seconds()) - best.arrival;

                    //Si je gagne 5 minutes de marche a pied, je suis pret à perdre jusqu'à 10 minutes.
                    int walking_time_diff_in_s = (best.walking_time - walking_time).total_seconds();
                    if (walking_time_diff_in_s > 0) {
                        float ratio = lost_time / walking_time_diff_in_s;
                        if( ratio >= best_departure.ratio) {
                            continue;
                        }
                        Solution s;
                        s.rpidx = jppidx;
                        s.count = i;
                        s.ratio = ratio;
                        s.walking_time = walking_time;
                        s.arrival = raptor.labels[i][jppidx].dt;
                        type::idx_t final_rpidx;
                        DateTime last_time;
                        std::tie(final_rpidx, last_time) = get_final_jppidx_and_date(i, jppidx, clockwise,
                                            disruption_active, accessibilite_params, raptor);

                        if(clockwise) {
                            s.upper_bound = last_time;
                            for(auto spid_dep : departs) {
                                if(raptor.data.pt_data->journey_pattern_points[final_rpidx]->stop_point->idx == spid_dep.first) {
                                    s.upper_bound = s.upper_bound + (spid_dep.second.total_seconds());
                                }
                            }
                        } else {
                            s.upper_bound = last_time;
                            for(auto spid_dep : departs) {
                                if(raptor.data.pt_data->journey_pattern_points[final_rpidx]->stop_point->idx == spid_dep.first) {
                                    s.upper_bound = s.upper_bound - (spid_dep.second.total_seconds());
                                }
                            }
                        }

                        best_departure = s;
                    }
                }
            }
            if(best_departure.rpidx != type::invalid_idx) {
                type::idx_t journey_pattern = raptor.data.pt_data->journey_pattern_points[best_departure.rpidx]->journey_pattern->idx;
                if(tmp.find(journey_pattern) == tmp.end()) {
                    tmp.insert(std::make_pair(journey_pattern, best_departure));
                } else if(tmp[journey_pattern].ratio > best_departure.ratio) {
                    tmp[journey_pattern] = best_departure;
                }
            }

        }
    }

    std::vector<Solution> to_sort;
    for(auto p : tmp) {
        to_sort.push_back(p.second);
    }
    std::sort(to_sort.begin(), to_sort.end(),
            [](const Solution s1, const Solution s2) { return s1.ratio < s2.ratio;});

    if(to_sort.size() > 2)
        to_sort.resize(2);
    result.insert(to_sort.begin(), to_sort.end());

    return result;
}

struct VisitorFinalJppAndDate : public BasePathVisitor {
    type::idx_t current_jpp = type::invalid_idx;
    DateTime last_time = DateTimeUtils::inf;
    void final_step(const type::idx_t current_jpp, size_t count, const std::vector<label_vector_t> &labels) {
        this->current_jpp = current_jpp;
        last_time = labels[count][current_jpp].dt;
    }
};

// Reparcours l’itinéraire rapidement pour avoir le JPP et la date de départ (si on cherchait l’arrivée au plus tôt)
std::pair<type::idx_t, DateTime>
get_final_jppidx_and_date(int count, type::idx_t jpp_idx, bool clockwise, bool disruption_active,
                          const type::AccessibiliteParams & accessibilite_params, const RAPTOR& raptor) {
    VisitorFinalJppAndDate v;
    read_path(v, jpp_idx, count, !clockwise, disruption_active, accessibilite_params, raptor);
    return std::make_pair(v.current_jpp, v.last_time);
}

struct VisitorWalkingTime : public BasePathVisitor {
    navitia::time_duration walking_time = {};
    void connection(type::StopPoint* , type::StopPoint* ,
                boost::posix_time::ptime dep_time, boost::posix_time::ptime arr_time,
                type::StopPointConnection*) {

        walking_time += navitia::seconds((arr_time - dep_time).total_seconds());
    }
};

navitia::time_duration getWalkingTime(int count, type::idx_t jpp_idx, const std::vector<std::pair<type::idx_t, navitia::time_duration> > &departs,
                     const std::vector<std::pair<type::idx_t, navitia::time_duration> > &destinations,
                     bool clockwise, bool disruption_active, const type::AccessibiliteParams & accessibilite_params,
                     const RAPTOR& raptor) {

    const type::JourneyPatternPoint* current_jpp = raptor.data.pt_data->journey_pattern_points[jpp_idx];
    navitia::time_duration walking_time = {};

    //Marche à la fin
    for(auto dest_dist : destinations) {
        if(dest_dist.first == current_jpp->stop_point->idx) {
            walking_time = dest_dist.second;
            break;
        }
    }

    VisitorWalkingTime v;
    read_path(v, current_jpp->idx, count, !clockwise, disruption_active, accessibilite_params, raptor);
    walking_time += v.walking_time;
    //Marche au départ
    for(auto dep_dist : departs) {
        if(dep_dist.first == current_jpp->stop_point->idx) {
            walking_time += dep_dist.second;
            break;
        }
    }

    return walking_time;
}

}}

<|endoftext|>


<commit_before>/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include "Config.h"
#include "version.h"

using namespace boost::program_options;

namespace i2p {
namespace config {
  options_description m_OptionsDesc;
  variables_map       m_Options;

  /* list of renamed options */
  std::map<std::string, std::string> remapped_options = {
    { "tunnelscfg",          "tunconf" },
    { "v6",                  "ipv6" },
    { "httpaddress",         "http.address" },
    { "httpport",            "http.port"    },
    { "httpproxyaddress",    "httpproxy.address"  },
    { "httpproxyport",       "httpproxy.port"     },
    { "socksproxyaddress",   "socksproxy.address" },
    { "socksproxyport",      "socksproxy.port"    },
    { "samaddress",          "sam.address" },
    { "samport",             "sam.port"    },
    { "bobaddress",          "bob.address" },
    { "bobport",             "bob.port"    },
    { "i2pcontroladdress",   "i2pcontrol.address" },
    { "i2pcontroladdress",   "i2pcontrol.port"    },
    { "proxykeys",           "httpproxy.keys" },
  };
  /* list of options, that loose their argument and become simple switch */
  std::set<std::string> boolean_options = {
    "daemon", "floodfill", "notransit", "service", "ipv6"
  };

  /* this function is a solid piece of shit, remove it after 2.6.0 */
  std::pair<std::string, std::string> old_syntax_parser(const std::string& s) {
    std::string name  = "";
    std::string value = "";
    std::size_t pos = 0;
    /* shortcuts -- -h */
    if (s.length() == 2 && s.at(0) == '-' && s.at(1) != '-')
      return make_pair(s.substr(1), "");
    /* old-style -- -log, /log, etc */
    if (s.at(0) == '/' || (s.at(0) == '-' && s.at(1) != '-')) {
      if ((pos = s.find_first_of("= ")) != std::string::npos) {
        name  = s.substr(1, pos - 1);
        value = s.substr(pos + 1);
      } else {
        name  = s.substr(1, pos);
        value = "";
      }
      if (boolean_options.count(name) > 0 && value != "")
        std::cerr << "args: don't give an argument to switch option: " << s << std::endl;
      if (m_OptionsDesc.find_nothrow(name, false)) {
        std::cerr << "args: option " << s << " style is DEPRECATED, use --" << name << " instead" << std::endl;
        return std::make_pair(name, value);
      }
      if (remapped_options.count(name) > 0) {
        name = remapped_options[name];
        std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl;
        return std::make_pair(name, value);
      } /* else */
    }
    /* long options -- --help */
    if (s.substr(0, 2) == "--") {
      if ((pos = s.find_first_of("= ")) != std::string::npos) {
        name  = s.substr(2, pos - 2);
        value = s.substr(pos + 1);
      } else {
        name  = s.substr(2, pos);
        value = "";
      }
      if (boolean_options.count(name) > 0 && value != "") {
        std::cerr << "args: don't give an argument to switch option: " << s << std::endl;
        value = "";
      }
      if (m_OptionsDesc.find_nothrow(name, false))
        return std::make_pair(name, value);
      if (remapped_options.count(name) > 0) {
        name = remapped_options[name];
        std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl;
        return std::make_pair(name, value);
      } /* else */
    }
    std::cerr << "args: unknown option -- " << s << std::endl;
    return std::make_pair("", "");
  }

  void Init() {
    options_description general("General options");
    general.add_options()
      ("help",     "Show this message")
      ("conf",      value<std::string>()->default_value(""),     "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
      ("tunconf",   value<std::string>()->default_value(""),     "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
      ("pidfile",   value<std::string>()->default_value(""),     "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
      ("log",       value<std::string>()->default_value(""),     "Logs destination: stdout, file, syslog (stdout if not set)")
      ("logfile",   value<std::string>()->default_value(""),     "Path to logfile (stdout if not set, autodetect if daemon)")
      ("loglevel",  value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)")
	  ("family",    value<std::string>()->default_value(""),     "Specify a family, router belongs to")
	  ("datadir",   value<std::string>()->default_value(""),     "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
      ("host",      value<std::string>()->default_value("0.0.0.0"),     "External IP")
      ("port",      value<uint16_t>()->default_value(0),                "Port to listen for incoming connections (default: auto)")
      ("ipv4",      value<bool>()->zero_tokens()->default_value(true),  "Enable communication through ipv4")
      ("ipv6",      value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
      ("daemon",    value<bool>()->zero_tokens()->default_value(false), "Router will go to background after start")
      ("service",   value<bool>()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'")
      ("notransit", value<bool>()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup")
      ("floodfill", value<bool>()->zero_tokens()->default_value(false), "Router will be floodfill")
      ("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in kbps or letters: L (32), O (256), P (2048), X (>9000)")
#ifdef _WIN32
      ("svcctl",    value<std::string>()->default_value(""),     "Windows service management ('install' or 'remove')")
      ("insomnia", value<bool>()->zero_tokens()->default_value(false), "Prevent system from sleeping")
      ("close", value<std::string>()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something
#endif
      ;

    options_description httpserver("HTTP Server options");
    httpserver.add_options()
      ("http.enabled",        value<bool>()->default_value(true),               "Enable or disable webconsole")
      ("http.address",        value<std::string>()->default_value("127.0.0.1"), "Webconsole listen address")
      ("http.port",           value<uint16_t>()->default_value(7070),           "Webconsole listen port")
      ;

    options_description httpproxy("HTTP Proxy options");
    httpproxy.add_options()
      ("httpproxy.enabled",   value<bool>()->default_value(true),                         "Enable or disable HTTP Proxy")
      ("httpproxy.address",   value<std::string>()->default_value("127.0.0.1"),           "HTTP Proxy listen address")
      ("httpproxy.port",      value<uint16_t>()->default_value(4444),                     "HTTP Proxy listen port")
      ("httpproxy.keys",      value<std::string>()->default_value(""),  "File to persist HTTP Proxy keys")
      ;

    options_description socksproxy("SOCKS Proxy options");
    socksproxy.add_options()
      ("socksproxy.enabled",  value<bool>()->default_value(true),                         "Enable or disable SOCKS Proxy")
      ("socksproxy.address",  value<std::string>()->default_value("127.0.0.1"),           "SOCKS Proxy listen address")
      ("socksproxy.port",     value<uint16_t>()->default_value(4447),                     "SOCKS Proxy listen port")
      ("socksproxy.keys",     value<std::string>()->default_value(""), "File to persist SOCKS Proxy keys")
      ("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
      ("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
      ;

    options_description sam("SAM bridge options");
    sam.add_options()
      ("sam.enabled",         value<bool>()->default_value(false),                        "Enable or disable SAM Application bridge")
      ("sam.address",         value<std::string>()->default_value("127.0.0.1"),           "SAM listen address")
      ("sam.port",            value<uint16_t>()->default_value(7656),                     "SAM listen port")
      ;

    options_description bob("BOB options");
    bob.add_options()
      ("bob.enabled",         value<bool>()->default_value(false),                        "Enable or disable BOB command channel")
      ("bob.address",         value<std::string>()->default_value("127.0.0.1"),           "BOB listen address")
      ("bob.port",            value<uint16_t>()->default_value(2827),                     "BOB listen port")
      ;

    options_description i2pcontrol("I2PControl options");
    i2pcontrol.add_options()
      ("i2pcontrol.enabled",  value<bool>()->default_value(false),                        "Enable or disable I2P Control Protocol")
      ("i2pcontrol.address",  value<std::string>()->default_value("127.0.0.1"),           "I2PCP listen address")
      ("i2pcontrol.port",     value<uint16_t>()->default_value(7650),                     "I2PCP listen port")
      ("i2pcontrol.password", value<std::string>()->default_value("itoopie"),             "I2PCP access password")
      ("i2pcontrol.cert",     value<std::string>()->default_value("i2pcontrol.crt.pem"),  "I2PCP connection cerificate")
      ("i2pcontrol.key",      value<std::string>()->default_value("i2pcontrol.key.pem"),  "I2PCP connection cerificate key")
      ;

	options_description precomputation("Precomputation options");
	precomputation.add_options()
	  ("precomputation.elgamal",
#if defined(__x86_64__)
	   value<bool>()->default_value(false),
#else
	   value<bool>()->default_value(true),
#endif
	   "Enable or disable elgamal precomputation table")
	  ;

    m_OptionsDesc
      .add(general)
      .add(httpserver)
      .add(httpproxy)
      .add(socksproxy)
      .add(sam)
      .add(bob)
      .add(i2pcontrol)
	  .add(precomputation)
      ;
  }

  void ParseCmdline(int argc, char* argv[]) {
    try {
      auto style = boost::program_options::command_line_style::unix_style
                 | boost::program_options::command_line_style::allow_long_disguise;
      style &=   ~ boost::program_options::command_line_style::allow_guessing;
      store(parse_command_line(argc, argv, m_OptionsDesc, style, old_syntax_parser), m_Options);
    } catch (boost::program_options::error& e) {
      std::cerr << "args: " << e.what() << std::endl;
      exit(EXIT_FAILURE);
    }

    if (m_Options.count("help") || m_Options.count("h")) {
      std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
      std::cout << m_OptionsDesc;
      exit(EXIT_SUCCESS);
    }
  }

  void ParseConfig(const std::string& path) {
    if (path == "") return;

    std::ifstream config(path, std::ios::in);

    if (!config.is_open())
	{
      std::cerr << "missing/unreadable config file: " << path << std::endl;
      exit(EXIT_FAILURE);
    }

    try
	{
		store(boost::program_options::parse_config_file(config, m_OptionsDesc), m_Options);
    }
	catch (boost::program_options::error& e)
	{
      std::cerr << e.what() << std::endl;
      exit(EXIT_FAILURE);
    };
  }

  void Finalize() {
    notify(m_Options);
  }

  bool IsDefault(const char *name) {
    if (!m_Options.count(name))
      throw "try to check non-existent option";

    if (m_Options[name].defaulted())
      return true;
    return false;
  }
} // namespace config
} // namespace i2p
<commit_msg>added some limits options<commit_after>/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include "Config.h"
#include "version.h"

using namespace boost::program_options;

namespace i2p {
namespace config {
  options_description m_OptionsDesc;
  variables_map       m_Options;

  /* list of renamed options */
  std::map<std::string, std::string> remapped_options = {
    { "tunnelscfg",          "tunconf" },
    { "v6",                  "ipv6" },
    { "httpaddress",         "http.address" },
    { "httpport",            "http.port"    },
    { "httpproxyaddress",    "httpproxy.address"  },
    { "httpproxyport",       "httpproxy.port"     },
    { "socksproxyaddress",   "socksproxy.address" },
    { "socksproxyport",      "socksproxy.port"    },
    { "samaddress",          "sam.address" },
    { "samport",             "sam.port"    },
    { "bobaddress",          "bob.address" },
    { "bobport",             "bob.port"    },
    { "i2pcontroladdress",   "i2pcontrol.address" },
    { "i2pcontroladdress",   "i2pcontrol.port"    },
    { "proxykeys",           "httpproxy.keys" },
  };
  /* list of options, that loose their argument and become simple switch */
  std::set<std::string> boolean_options = {
    "daemon", "floodfill", "notransit", "service", "ipv6"
  };

  /* this function is a solid piece of shit, remove it after 2.6.0 */
  std::pair<std::string, std::string> old_syntax_parser(const std::string& s) {
    std::string name  = "";
    std::string value = "";
    std::size_t pos = 0;
    /* shortcuts -- -h */
    if (s.length() == 2 && s.at(0) == '-' && s.at(1) != '-')
      return make_pair(s.substr(1), "");
    /* old-style -- -log, /log, etc */
    if (s.at(0) == '/' || (s.at(0) == '-' && s.at(1) != '-')) {
      if ((pos = s.find_first_of("= ")) != std::string::npos) {
        name  = s.substr(1, pos - 1);
        value = s.substr(pos + 1);
      } else {
        name  = s.substr(1, pos);
        value = "";
      }
      if (boolean_options.count(name) > 0 && value != "")
        std::cerr << "args: don't give an argument to switch option: " << s << std::endl;
      if (m_OptionsDesc.find_nothrow(name, false)) {
        std::cerr << "args: option " << s << " style is DEPRECATED, use --" << name << " instead" << std::endl;
        return std::make_pair(name, value);
      }
      if (remapped_options.count(name) > 0) {
        name = remapped_options[name];
        std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl;
        return std::make_pair(name, value);
      } /* else */
    }
    /* long options -- --help */
    if (s.substr(0, 2) == "--") {
      if ((pos = s.find_first_of("= ")) != std::string::npos) {
        name  = s.substr(2, pos - 2);
        value = s.substr(pos + 1);
      } else {
        name  = s.substr(2, pos);
        value = "";
      }
      if (boolean_options.count(name) > 0 && value != "") {
        std::cerr << "args: don't give an argument to switch option: " << s << std::endl;
        value = "";
      }
      if (m_OptionsDesc.find_nothrow(name, false))
        return std::make_pair(name, value);
      if (remapped_options.count(name) > 0) {
        name = remapped_options[name];
        std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl;
        return std::make_pair(name, value);
      } /* else */
    }
    std::cerr << "args: unknown option -- " << s << std::endl;
    return std::make_pair("", "");
  }

  void Init() {
    options_description general("General options");
    general.add_options()
      ("help",     "Show this message")
      ("conf",      value<std::string>()->default_value(""),     "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
      ("tunconf",   value<std::string>()->default_value(""),     "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
      ("pidfile",   value<std::string>()->default_value(""),     "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
      ("log",       value<std::string>()->default_value(""),     "Logs destination: stdout, file, syslog (stdout if not set)")
      ("logfile",   value<std::string>()->default_value(""),     "Path to logfile (stdout if not set, autodetect if daemon)")
      ("loglevel",  value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)")
	  ("family",    value<std::string>()->default_value(""),     "Specify a family, router belongs to")
	  ("datadir",   value<std::string>()->default_value(""),     "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
      ("host",      value<std::string>()->default_value("0.0.0.0"),     "External IP")
      ("port",      value<uint16_t>()->default_value(0),                "Port to listen for incoming connections (default: auto)")
      ("ipv4",      value<bool>()->zero_tokens()->default_value(true),  "Enable communication through ipv4")
      ("ipv6",      value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
      ("daemon",    value<bool>()->zero_tokens()->default_value(false), "Router will go to background after start")
      ("service",   value<bool>()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'")
      ("notransit", value<bool>()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup")
      ("floodfill", value<bool>()->zero_tokens()->default_value(false), "Router will be floodfill")
      ("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in kbps or letters: L (32), O (256), P (2048), X (>9000)")
#ifdef _WIN32
      ("svcctl",    value<std::string>()->default_value(""),     "Windows service management ('install' or 'remove')")
      ("insomnia", value<bool>()->zero_tokens()->default_value(false), "Prevent system from sleeping")
      ("close", value<std::string>()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something
#endif
      ;
    options_description limits("Limits options");
    limits.add_options()
      ("limits.transit",   value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
      ("limits.router",    value<uint16_t>()->default_value(4096), "Maximum active router sessions (default:4096)")
      ("limits.client",    value<uint16_t>()->default_value(1024), "Maximum active client sessions (default:1024)")
      ("limits.floodfill", value<uint16_t>()->default_value(1024), "Maximum active floodfill sessions (default:1024)")
      ;

    options_description httpserver("HTTP Server options");
    httpserver.add_options()
      ("http.enabled",        value<bool>()->default_value(true),               "Enable or disable webconsole")
      ("http.address",        value<std::string>()->default_value("127.0.0.1"), "Webconsole listen address")
      ("http.port",           value<uint16_t>()->default_value(7070),           "Webconsole listen port")
      ;

    options_description httpproxy("HTTP Proxy options");
    httpproxy.add_options()
      ("httpproxy.enabled",   value<bool>()->default_value(true),                         "Enable or disable HTTP Proxy")
      ("httpproxy.address",   value<std::string>()->default_value("127.0.0.1"),           "HTTP Proxy listen address")
      ("httpproxy.port",      value<uint16_t>()->default_value(4444),                     "HTTP Proxy listen port")
      ("httpproxy.keys",      value<std::string>()->default_value(""),  "File to persist HTTP Proxy keys")
      ;

    options_description socksproxy("SOCKS Proxy options");
    socksproxy.add_options()
      ("socksproxy.enabled",  value<bool>()->default_value(true),                         "Enable or disable SOCKS Proxy")
      ("socksproxy.address",  value<std::string>()->default_value("127.0.0.1"),           "SOCKS Proxy listen address")
      ("socksproxy.port",     value<uint16_t>()->default_value(4447),                     "SOCKS Proxy listen port")
      ("socksproxy.keys",     value<std::string>()->default_value(""), "File to persist SOCKS Proxy keys")
      ("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
      ("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
      ;

    options_description sam("SAM bridge options");
    sam.add_options()
      ("sam.enabled",         value<bool>()->default_value(false),                        "Enable or disable SAM Application bridge")
      ("sam.address",         value<std::string>()->default_value("127.0.0.1"),           "SAM listen address")
      ("sam.port",            value<uint16_t>()->default_value(7656),                     "SAM listen port")
      ;

    options_description bob("BOB options");
    bob.add_options()
      ("bob.enabled",         value<bool>()->default_value(false),                        "Enable or disable BOB command channel")
      ("bob.address",         value<std::string>()->default_value("127.0.0.1"),           "BOB listen address")
      ("bob.port",            value<uint16_t>()->default_value(2827),                     "BOB listen port")
      ;

    options_description i2pcontrol("I2PControl options");
    i2pcontrol.add_options()
      ("i2pcontrol.enabled",  value<bool>()->default_value(false),                        "Enable or disable I2P Control Protocol")
      ("i2pcontrol.address",  value<std::string>()->default_value("127.0.0.1"),           "I2PCP listen address")
      ("i2pcontrol.port",     value<uint16_t>()->default_value(7650),                     "I2PCP listen port")
      ("i2pcontrol.password", value<std::string>()->default_value("itoopie"),             "I2PCP access password")
      ("i2pcontrol.cert",     value<std::string>()->default_value("i2pcontrol.crt.pem"),  "I2PCP connection cerificate")
      ("i2pcontrol.key",      value<std::string>()->default_value("i2pcontrol.key.pem"),  "I2PCP connection cerificate key")
      ;

	options_description precomputation("Precomputation options");
	precomputation.add_options()
	  ("precomputation.elgamal",
#if defined(__x86_64__)
	   value<bool>()->default_value(false),
#else
	   value<bool>()->default_value(true),
#endif
	   "Enable or disable elgamal precomputation table")
	  ;

    m_OptionsDesc
      .add(general)
      .add(httpserver)
      .add(httpproxy)
      .add(socksproxy)
      .add(sam)
      .add(bob)
      .add(i2pcontrol)
	  .add(precomputation)
      ;
  }

  void ParseCmdline(int argc, char* argv[]) {
    try {
      auto style = boost::program_options::command_line_style::unix_style
                 | boost::program_options::command_line_style::allow_long_disguise;
      style &=   ~ boost::program_options::command_line_style::allow_guessing;
      store(parse_command_line(argc, argv, m_OptionsDesc, style, old_syntax_parser), m_Options);
    } catch (boost::program_options::error& e) {
      std::cerr << "args: " << e.what() << std::endl;
      exit(EXIT_FAILURE);
    }

    if (m_Options.count("help") || m_Options.count("h")) {
      std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
      std::cout << m_OptionsDesc;
      exit(EXIT_SUCCESS);
    }
  }

  void ParseConfig(const std::string& path) {
    if (path == "") return;

    std::ifstream config(path, std::ios::in);

    if (!config.is_open())
	{
      std::cerr << "missing/unreadable config file: " << path << std::endl;
      exit(EXIT_FAILURE);
    }

    try
	{
		store(boost::program_options::parse_config_file(config, m_OptionsDesc), m_Options);
    }
	catch (boost::program_options::error& e)
	{
      std::cerr << e.what() << std::endl;
      exit(EXIT_FAILURE);
    };
  }

  void Finalize() {
    notify(m_Options);
  }

  bool IsDefault(const char *name) {
    if (!m_Options.count(name))
      throw "try to check non-existent option";

    if (m_Options[name].defaulted())
      return true;
    return false;
  }
} // namespace config
} // namespace i2p
<|endoftext|>


<commit_before>/*!
 * Copyright (C) 2014 Nomovok Ltd. All rights reserved.
 * Contact: info@nomovok.com
 *
 * This file may be used under the terms of the GNU Lesser
 * General Public License version 2.1 as published by the Free Software
 * Foundation and appearing in the file LICENSE.LGPL included in the
 * packaging of this file.  Please review the following information to
 * ensure the GNU Lesser General Public License version 2.1 requirements
 * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 * In addition, as a special exception, copyright holders
 * give you certain additional rights.  These rights are described in
 * the Digia Qt LGPL Exception version 1.1, included in the file
 * LGPL_EXCEPTION.txt in this package.
 */

#include <QQmlEngine>
#include <QMap>

#include <QQmlComponent>

#include <private/qv4isel_moth_p.h>
#include <private/qobject_p.h>
#include <private/qqmlcompiler_p.h>
#include <private/qqmlcomponent_p.h>
#include <private/qv4compileddata_p.h>

#include "qmcloader.h"
#include "qmcfile.h"
#include "qmcunit.h"
#include "qmctypeunit.h"

static int DEPENDENCY_MAX_RECURSION_DEPTH = 10;

class QmcLoaderPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QmcLoader)
public:
    QmcLoaderPrivate(QQmlEngine *engine);
    virtual ~QmcLoaderPrivate();
    QQmlEngine *engine;
    QList<QQmlError> errors;
    QmcTypeUnit* unit;
    QMap<QString, QmcUnit *> dependencies;
    bool loadDependenciesAutomatically;
    int dependencyRecursionDepth;
};

QmcLoaderPrivate::QmcLoaderPrivate(QQmlEngine *engine)
    : engine(engine),
      unit(NULL),
      loadDependenciesAutomatically(true),
      dependencyRecursionDepth(0)
{
}

QmcLoaderPrivate::~QmcLoaderPrivate()
{
    if (unit)
        unit->release();

    foreach (QmcUnit *unit, dependencies) {
        unit->blob->release();
    }
    dependencies.clear();
}

QmcLoader::QmcLoader(QQmlEngine *engine, QObject *parent) :
    QObject(*(new QmcLoaderPrivate(engine)), parent)
{
}

QQmlComponent *QmcLoader::loadComponent(const QString &file)
{
    QFile f(file);
    if (!f.open(QFile::ReadOnly)) {
        QQmlError error;
        error.setDescription("Could not open file for reading");
        appendError(error);
        return NULL;
    }

    QDataStream in(&f);
    QQmlComponent *ret = loadComponent(in, createLoadedUrl(file));
    f.close();
    return ret;
}

QQmlComponent *QmcLoader::loadComponent(QDataStream &stream, const QUrl &loadedUrl)
{
    clearError();
    Q_D(QmcLoader);
    // TBD: check validity of all read values
    QmcUnit *unit = QmcUnit::loadUnit(stream, d->engine, this, loadedUrl);
    if (!unit) {
        QQmlError error;
        error.setDescription("Error parsing / loading");
        appendError(error);
        return NULL;
    }

    // replace with loaded url cause we aren't always loading from the same
    // directories as we compiled
    unit->url = loadedUrl;
    unit->urlString = loadedUrl.toString();

    if (unit->type != QMC_QML) {
        QQmlError error;
        error.setDescription("Cannot have Script unit as main unit");
        appendError(error);
        unit->blob->release();
        return NULL;
    }

    QmcTypeUnit *typeUnit = (QmcTypeUnit *)unit->blob;

    // add to engine
    if (!typeUnit->link()) {
        appendErrors(unit->errors);
        unit->blob->release();
        return NULL;
    }

    // create QQmlComponent and attach QQmlCompiledData into it
    QQmlComponent *component = typeUnit->createComponent();
    if (!component) {
        QQmlError error;
        error.setDescription("Error creating QQmlComponent");
        error.setUrl(unit->url);
        appendError(error);
        unit->blob->release();
        return NULL;
    }

    // TBD: where to put unit
    d->unit = typeUnit;
    d->unit->addref();

    return component;
}

void QmcLoader::setLoadDependenciesAutomatically(bool load)
{
    Q_D(QmcLoader);
    d->loadDependenciesAutomatically = load;
}

bool QmcLoader::isLoadDependenciesAutomatically() const
{
    const Q_D(QmcLoader);
    return d->loadDependenciesAutomatically;
}

QUrl QmcLoader::createLoadedUrl(const QString &file)
{
    QString urlStr;
    if (file.startsWith(":/"))
        urlStr = "qrc:";
    else
        urlStr = "file:";
    urlStr.append(file);
    return QUrl(urlStr);
}

QString QmcLoader::getBaseUrl(const QUrl &url)
{
    QString path = url.path();
    QUrl newUrl(url);
    int lastSlash = path.lastIndexOf('/');
    if (lastSlash != -1) {
        path = path.left(lastSlash + 1);
        newUrl.setPath(path);
    } else {
        newUrl.setPath("");
    }
    return newUrl.toString();
}

QmcUnit *QmcLoader::getUnit(const QString &url)
{
    Q_D(QmcLoader);
    QString precompiled = precompiledUrl(url);
    if (!d->dependencies.contains(precompiled)) {
        if (d->loadDependenciesAutomatically) {
            // try to load it
            if (d->dependencyRecursionDepth >= DEPENDENCY_MAX_RECURSION_DEPTH) {
                QQmlError error;
                error.setDescription("Could not load dependency, too deep recursion");
                error.setUrl(url);
                appendError(error);
                return NULL;
            }
            d->dependencyRecursionDepth++;
            QmcUnit *unit = doloadDependency(precompiled);
            d->dependencyRecursionDepth--;
            return unit;
        } else
        return NULL;
    }
    return d->dependencies[precompiled];
}

QString QmcLoader::precompiledUrl(const QString &url)
{
    QString urlString = url;
    if (url.endsWith(".js"))
        urlString.append("c");
    else if (url.endsWith(".qml"))
        urlString[urlString.length() - 1] = 'c';
    return urlString;
}

QmcScriptUnit *QmcLoader::getScript(const QString &url, const QUrl &loaderUrl)
{
    QString newUrl;
    if(url.startsWith("file:")){
        newUrl = url;
    }else{
        newUrl = getBaseUrl(loaderUrl);
        newUrl.append(url);
    }

    QmcUnit *unit = getUnit(newUrl);
    if (!unit)
        return NULL;
    if (unit->type != QMC_JS)
        return NULL;
    unit->blob->addref();
    return (QmcScriptUnit *)unit->blob;
}

QmcUnit *QmcLoader::getType(const QString &name, const QUrl &loaderUrl)
{
    qDebug() << "Getting type name = " << name << "loaderUrl =" << loaderUrl;

    QString newUrl;
    if(name.startsWith("file://")){
        newUrl = name;
        newUrl.append(".qml");
    }else{
        newUrl = getBaseUrl(loaderUrl);
        newUrl.append(name);
        newUrl.append(".qml");
    }

    QmcUnit *unit = getUnit(newUrl);
    if (!unit)
        return NULL;
    if (unit->type != QMC_QML)
        return NULL;
    unit->blob->addref();
    return unit;
}

bool QmcLoader::loadDependency(QDataStream &stream, const QUrl &loadedUrl)
{
    clearError();
    QmcUnit *unit = doloadDependency(stream, loadedUrl);
    unit->blob->release();
    return true;
}

bool QmcLoader::loadDependency(const QString &file)
{
    clearError();
    QFile f(file);
    if (!f.open(QFile::ReadOnly)) {
        QQmlError error;
        error.setDescription("Could not open file for reading");
        appendError(error);
        return NULL;
    }

    QDataStream in(&f);
    QmcUnit *unit = doloadDependency(in, createLoadedUrl(file));
    unit->blob->release();
    f.close();
    return true;
}

QmcUnit *QmcLoader::doloadDependency(const QString &url)
{
    QUrl u(url);
    QString file = u.toLocalFile();
    QFile f(file);
    if (!f.open(QFile::ReadOnly)) {
        QQmlError error;
        error.setDescription("Could not open file for reading: " + f.errorString());
        qWarning() << "Could not open file for reading" << file;
        error.setUrl(QUrl(file));
        qDebug() << "Cannot open" << file;
        appendError(error);
        return NULL;
    }

    QDataStream in(&f);
    const QUrl loadAs = createLoadedUrl(file);
    qDebug() << "Loading dependency" << url << "as" << loadAs;
    QmcUnit *unit = doloadDependency(in, loadAs);
    f.close();
    return unit;
}

QmcUnit *QmcLoader::doloadDependency(QDataStream &stream, const QUrl &loadedUrl)
{
    Q_D(QmcLoader);
    QmcUnit *unit = QmcUnit::loadUnit(stream, d->engine, this, loadedUrl);
    if (!unit) {
        QQmlError error;
        error.setDescription("Error loading");
        appendError(error);
        return NULL;
    }

    // add to dependencies
    d->dependencies[unit->loadedUrl.toString()] = unit;
    unit->blob->addref();
    return unit;
}

const QList<QQmlError>& QmcLoader::errors() const
{
    const Q_D(QmcLoader);
    return d->errors;
}

void QmcLoader::clearError() {
    Q_D(QmcLoader);
    d->errors.clear();
}

void QmcLoader::appendError(QQmlError error)
{
    Q_D(QmcLoader);
    d->errors.append(error);
}

void QmcLoader::appendErrors(const QList<QQmlError> &errors)
{
    Q_D(QmcLoader);
    d->errors.append(errors);
}
<commit_msg>Load under full path to fix assert.<commit_after>/*!
 * Copyright (C) 2014 Nomovok Ltd. All rights reserved.
 * Contact: info@nomovok.com
 *
 * This file may be used under the terms of the GNU Lesser
 * General Public License version 2.1 as published by the Free Software
 * Foundation and appearing in the file LICENSE.LGPL included in the
 * packaging of this file.  Please review the following information to
 * ensure the GNU Lesser General Public License version 2.1 requirements
 * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 * In addition, as a special exception, copyright holders
 * give you certain additional rights.  These rights are described in
 * the Digia Qt LGPL Exception version 1.1, included in the file
 * LGPL_EXCEPTION.txt in this package.
 */

#include <QQmlEngine>
#include <QMap>
#include <QDir>

#include <QQmlComponent>

#include <private/qv4isel_moth_p.h>
#include <private/qobject_p.h>
#include <private/qqmlcompiler_p.h>
#include <private/qqmlcomponent_p.h>
#include <private/qv4compileddata_p.h>

#include "qmcloader.h"
#include "qmcfile.h"
#include "qmcunit.h"
#include "qmctypeunit.h"

static int DEPENDENCY_MAX_RECURSION_DEPTH = 10;

class QmcLoaderPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QmcLoader)
public:
    QmcLoaderPrivate(QQmlEngine *engine);
    virtual ~QmcLoaderPrivate();
    QQmlEngine *engine;
    QList<QQmlError> errors;
    QmcTypeUnit* unit;
    QMap<QString, QmcUnit *> dependencies;
    bool loadDependenciesAutomatically;
    int dependencyRecursionDepth;
};

QmcLoaderPrivate::QmcLoaderPrivate(QQmlEngine *engine)
    : engine(engine),
      unit(NULL),
      loadDependenciesAutomatically(true),
      dependencyRecursionDepth(0)
{
}

QmcLoaderPrivate::~QmcLoaderPrivate()
{
    if (unit)
        unit->release();

    foreach (QmcUnit *unit, dependencies) {
        unit->blob->release();
    }
    dependencies.clear();
}

QmcLoader::QmcLoader(QQmlEngine *engine, QObject *parent) :
    QObject(*(new QmcLoaderPrivate(engine)), parent)
{
}

QQmlComponent *QmcLoader::loadComponent(const QString &file)
{
    QFile f(file);
    if (!f.open(QFile::ReadOnly)) {
        QQmlError error;
        error.setDescription("Could not open file for reading");
        appendError(error);
        return NULL;
    }

    QDataStream in(&f);
    QQmlComponent *ret = loadComponent(in, createLoadedUrl(file));
    f.close();
    return ret;
}

QQmlComponent *QmcLoader::loadComponent(QDataStream &stream, const QUrl &loadedUrl)
{
    clearError();
    Q_D(QmcLoader);
    // TBD: check validity of all read values
    QmcUnit *unit = QmcUnit::loadUnit(stream, d->engine, this, loadedUrl);
    if (!unit) {
        QQmlError error;
        error.setDescription("Error parsing / loading");
        appendError(error);
        return NULL;
    }

    // replace with loaded url cause we aren't always loading from the same
    // directories as we compiled
    unit->url = loadedUrl;
    unit->urlString = loadedUrl.toString();

    if (unit->type != QMC_QML) {
        QQmlError error;
        error.setDescription("Cannot have Script unit as main unit");
        appendError(error);
        unit->blob->release();
        return NULL;
    }

    QmcTypeUnit *typeUnit = (QmcTypeUnit *)unit->blob;

    // add to engine
    if (!typeUnit->link()) {
        appendErrors(unit->errors);
        unit->blob->release();
        return NULL;
    }

    // create QQmlComponent and attach QQmlCompiledData into it
    QQmlComponent *component = typeUnit->createComponent();
    if (!component) {
        QQmlError error;
        error.setDescription("Error creating QQmlComponent");
        error.setUrl(unit->url);
        appendError(error);
        unit->blob->release();
        return NULL;
    }

    // TBD: where to put unit
    d->unit = typeUnit;
    d->unit->addref();

    return component;
}

void QmcLoader::setLoadDependenciesAutomatically(bool load)
{
    Q_D(QmcLoader);
    d->loadDependenciesAutomatically = load;
}

bool QmcLoader::isLoadDependenciesAutomatically() const
{
    const Q_D(QmcLoader);
    return d->loadDependenciesAutomatically;
}

QUrl QmcLoader::createLoadedUrl(const QString &file)
{
    QString urlStr;
    if (file.startsWith(":/"))
        urlStr = "qrc:";
    else if(file.startsWith("/"))
        urlStr = "file://";
    else{
        QDir dd;
        urlStr = "file://" + dd.absolutePath() + "/";
    }
    urlStr.append(file);
    return QUrl(urlStr);
}

QString QmcLoader::getBaseUrl(const QUrl &url)
{
    QString path = url.path();
    QUrl newUrl(url);
    int lastSlash = path.lastIndexOf('/');
    if (lastSlash != -1) {
        path = path.left(lastSlash + 1);
        newUrl.setPath(path);
    } else {
        newUrl.setPath("");
    }
    return newUrl.toString();
}

QmcUnit *QmcLoader::getUnit(const QString &url)
{
    Q_D(QmcLoader);
    QString precompiled = precompiledUrl(url);
    if (!d->dependencies.contains(precompiled)) {
        if (d->loadDependenciesAutomatically) {
            // try to load it
            if (d->dependencyRecursionDepth >= DEPENDENCY_MAX_RECURSION_DEPTH) {
                QQmlError error;
                error.setDescription("Could not load dependency, too deep recursion");
                error.setUrl(url);
                appendError(error);
                return NULL;
            }
            d->dependencyRecursionDepth++;
            QmcUnit *unit = doloadDependency(precompiled);
            d->dependencyRecursionDepth--;
            return unit;
        } else
        return NULL;
    }
    return d->dependencies[precompiled];
}

QString QmcLoader::precompiledUrl(const QString &url)
{
    QString urlString = url;
    if (url.endsWith(".js"))
        urlString.append("c");
    else if (url.endsWith(".qml"))
        urlString[urlString.length() - 1] = 'c';
    return urlString;
}

QmcScriptUnit *QmcLoader::getScript(const QString &url, const QUrl &loaderUrl)
{
    QString newUrl;
    if(url.startsWith("file:")){
        newUrl = url;
    }else{
        newUrl = getBaseUrl(loaderUrl);
        newUrl.append(url);
    }

    QmcUnit *unit = getUnit(newUrl);
    if (!unit)
        return NULL;
    if (unit->type != QMC_JS)
        return NULL;
    unit->blob->addref();
    return (QmcScriptUnit *)unit->blob;
}

QmcUnit *QmcLoader::getType(const QString &name, const QUrl &loaderUrl)
{
    qDebug() << "Getting type name = " << name << "loaderUrl =" << loaderUrl;

    QString newUrl;
    if(name.startsWith("file://")){
        newUrl = name;
        newUrl.append(".qml");
    }else{
        newUrl = getBaseUrl(loaderUrl);
        newUrl.append(name);
        newUrl.append(".qml");
    }

    QmcUnit *unit = getUnit(newUrl);
    if (!unit)
        return NULL;
    if (unit->type != QMC_QML)
        return NULL;
    unit->blob->addref();
    return unit;
}

bool QmcLoader::loadDependency(QDataStream &stream, const QUrl &loadedUrl)
{
    clearError();
    QmcUnit *unit = doloadDependency(stream, loadedUrl);
    unit->blob->release();
    return true;
}

bool QmcLoader::loadDependency(const QString &file)
{
    clearError();
    QFile f(file);
    if (!f.open(QFile::ReadOnly)) {
        QQmlError error;
        error.setDescription("Could not open file for reading");
        appendError(error);
        return NULL;
    }

    QDataStream in(&f);
    QmcUnit *unit = doloadDependency(in, createLoadedUrl(file));
    unit->blob->release();
    f.close();
    return true;
}

QmcUnit *QmcLoader::doloadDependency(const QString &url)
{
    QUrl u(url);
    QString file = u.toLocalFile();
    QFile f(file);
    if (!f.open(QFile::ReadOnly)) {
        QQmlError error;
        error.setDescription("Could not open file for reading: " + f.errorString());
        qWarning() << "Could not open file for reading" << file;
        error.setUrl(QUrl(file));
        qDebug() << "Cannot open" << file;
        appendError(error);
        return NULL;
    }

    QDataStream in(&f);
    const QUrl loadAs = createLoadedUrl(file);
    qDebug() << "Loading dependency" << url << "as" << loadAs;
    QmcUnit *unit = doloadDependency(in, loadAs);
    f.close();
    return unit;
}

QmcUnit *QmcLoader::doloadDependency(QDataStream &stream, const QUrl &loadedUrl)
{
    Q_D(QmcLoader);
    QmcUnit *unit = QmcUnit::loadUnit(stream, d->engine, this, loadedUrl);
    if (!unit) {
        QQmlError error;
        error.setDescription("Error loading");
        appendError(error);
        return NULL;
    }

    // add to dependencies
    d->dependencies[unit->loadedUrl.toString()] = unit;
    unit->blob->addref();
    return unit;
}

const QList<QQmlError>& QmcLoader::errors() const
{
    const Q_D(QmcLoader);
    return d->errors;
}

void QmcLoader::clearError() {
    Q_D(QmcLoader);
    d->errors.clear();
}

void QmcLoader::appendError(QQmlError error)
{
    Q_D(QmcLoader);
    d->errors.append(error);
}

void QmcLoader::appendErrors(const QList<QQmlError> &errors)
{
    Q_D(QmcLoader);
    d->errors.append(errors);
}
<|endoftext|>


<commit_before>/**
 ** \file libport/timer.cc
 ** \brief Implementation for libport/timer.hh.
 */

#include <libport/config.h>
#include <iostream>
#include <iomanip>

#ifdef LIBPORT_HAVE_SYS_TIMES_H
# include <sys/times.h>
#else

# include "libport/utime.hh"
# include "libport/detect_win32.h"
struct tms
{
  libport::utime_t tms_utime;  /* user time */
  libport::utime_t tms_stime;  /* system time */
  libport::utime_t tms_cutime; /* user time of dead children */
  libport::utime_t tms_cstime; /* system time of dead children */
};

# ifdef WIN32
# include "libport/windows.hh"
static libport::utime_t times(struct tms& t)
{
 //unit: 100 nanoseconds
 FILETIME ctime, etime, kerneltime, usertime;
 GetProcessTimes(GetCurrentProcess(), &ctime, &etime, &kerneltime, &usertime);
 t.tms_cutime = t.tms_cstime = 0;
 t.tms_utime = usertime.dwLowDateTime + static_cast<libport::utime_t>(usertime.dwHighDateTime) << 32;
 t.tms_stime = kerneltime.dwLowDateTime + static_cast<libport::utime_t>(kernelTime.dwHighDateTime) << 32;
 return utime()*10LL;
}

/// FILETIME unit is 100 nanoseconds.
# define sysconf(i) 10000000LL
# endif

#endif

#include <unistd.h>

#include "libport/timer.hh"
#include "libport/contract.hh"

namespace libport
{

  /*-----------------.
  | timer::time_var.  |
  `-----------------*/

  timer::time_var::time_var ()
    : initial (true)
  { }

  void
  timer::time_var::start ()
  {
    struct tms t;

    begin.wall = times (&t);
    begin.user = t.tms_utime;
    begin.sys  = t.tms_stime;

    if (initial)
      {
	initial = false;
	first = begin;
      }
  }

  void
  timer::time_var::stop ()
  {
    struct tms t;

    last.wall = times (&t);
    last.user = t.tms_utime;
    last.sys = t.tms_stime;
    elapsed.wall += last.wall - begin.wall;
    elapsed.user += last.user - begin.user;
    elapsed.sys += last.sys - begin.sys;
  }

  bool
  timer::time_var::is_zero ()
  {
    return true
	    && elapsed.wall == 0
	    && elapsed.user == 0
	    && elapsed.sys  == 0;
  }

  /*--------.
  | timer.  |
  `--------*/

  timer::timer () :
    dump_stream (0)
  { }

  // Duplicate a timer. No tasks should be running.
  timer::timer (const timer& rhs) :
    intmap (rhs.intmap),
    total (rhs.total),
    dump_stream (rhs.dump_stream)
  {
    precondition (rhs.tasks.empty ());

    for (task_map_type::const_iterator i = rhs.tasksmap.begin ();
	 i != rhs.tasksmap.end (); ++i)
      if (tasksmap.find (i->first) == tasksmap.end ())
	tasksmap[i->first] = new time_var (*i->second);
  }

  timer::~timer ()
  {
    // If magic is asked on destruction, let it happen completely.
    if (dump_stream)
      {
	// Consider that if the tasks were not properly closed, then
	// stop was not invoked either.
	if (!tasks.empty ())
	  {
	    do
	      pop ();
	    while (!tasks.empty ())
	      ;
	    stop ();
	  }
	dump (*dump_stream);
      }

    // Deallocate all our time_var.
    for (task_map_type::iterator i = tasksmap.begin ();
	 i != tasksmap.end (); ++i)
      delete i->second;
  }

  void
  timer::name (int i, std::string task_name)
  {
    intmap[i] = task_name;
  }

  void
  timer::timeinfo (long time, long total_time, std::ostream& out)
  {
    out << setiosflags (std::ios::left);
    out << std::setw (6) << std::setprecision (6)
	<< (float) (time) / clocks_per_sec;
    out << resetiosflags (std::ios::left);
    out << " (";
    out << std::setw (5) << std::setprecision (3)
	<< (total_time ?
	    (float) time * 100 / total_time :
	    (float) time);
    out << "%) ";
  }

  void
  timer::dump (std::ostream& out = std::cerr)
  {
    out << "Execution times (seconds)" << std::endl;
    for (task_map_type::const_iterator i = tasksmap.begin ();
	 i != tasksmap.end (); ++i)
      {
	if (!(i->second->is_zero ()))
	  {
	    out << " " << i->first << std::setw (26 - i->first.length ());
	    out << ": ";
	    timeinfo (i->second->elapsed.user, total.elapsed.user, out);
	    out << "  ";
	    timeinfo (i->second->elapsed.sys, total.elapsed.sys, out);
	    out << "  ";
	    timeinfo (i->second->elapsed.wall, total.elapsed.wall, out);
	    out << std::endl;
	  }
      }
    out << std::endl;

    out << "Cumulated times (seconds)" << std::endl;
    for (task_map_type::const_iterator i = tasksmap.begin ();
	 i != tasksmap.end (); ++i)
      {
	if (0 != (i->second->last.wall - i->second->first.wall))
	  {
	    out << " " << i->first << std::setw (26 - i->first.length ());
	    out << ": ";
	    timeinfo (i->second->last.user - i->second->first.user,
		      total.elapsed.user, out);
	    out << "  ";
	    timeinfo (i->second->last.sys - i->second->first.sys,
		      total.elapsed.sys, out);
	    out << "  ";
	    timeinfo (i->second->last.wall - i->second->first.wall,
		      total.elapsed.wall, out);
	    out << std::endl;
	  }
      }
    out << std::endl;

    out << " TOTAL (seconds)"  << std::setw (11) << ": "

	<< setiosflags (std::ios::left) << std::setw (7)
	<< (float) total.elapsed.user / clocks_per_sec
	<< std::setw (11)
	<< "user,"

	<< std::setw (7)
	<< (float) total.elapsed.sys / clocks_per_sec
	<< std::setw (11)
	<< "system,"

	<< std::setw (7)
	<< (float) total.elapsed.wall / clocks_per_sec
	<< "wall"

	<< resetiosflags (std::ios::left) << std::endl;
  }

  void
  timer::push (const std::string& task_name)
  {
    time_var* current;

    // if stack isn't empty, we set elapsed time for the current task
    if (!tasks.empty ())
      tasks.top ()->stop ();

    if (tasksmap.find (task_name) == tasksmap.end ())
      tasksmap[task_name] = new time_var;

    current = tasksmap[task_name];
    tasks.push (current);
    current->start ();
  }

  void
  timer::pop ()
  {
    precondition (!tasks.empty ());

    // Set the Elapsed time for the task we are closing
    tasks.top ()->stop ();

    // Current task is removed of the stack
    tasks.pop ();

    // We set the start time of the previous task at current time
    if (!tasks.empty ())
      tasks.top ()->start ();
  }

  timer&
  timer::operator<< (const timer& rhs)
  {
    // No task should be running when merging timers.
    precondition (rhs.tasks.empty ());

    for (task_map_type::const_iterator i = rhs.tasksmap.begin ();
	 i != rhs.tasksmap.end (); ++i)
      {
	if (tasksmap.find (i->first) == tasksmap.end ())
	  tasksmap[i->first] = new time_var (*i->second);
      }

    intmap.insert (rhs.intmap.begin (), rhs.intmap.end ());
    return *this;
  }

  const long timer::clocks_per_sec = sysconf (_SC_CLK_TCK);

} // namespace libport
<commit_msg>Fix windows version of times.<commit_after>/**
 ** \file libport/timer.cc
 ** \brief Implementation for libport/timer.hh.
 */

#include <libport/config.h>
#include <iostream>
#include <iomanip>

#ifdef LIBPORT_HAVE_SYS_TIMES_H
# include <sys/times.h>
#else

# include "libport/utime.hh"
# include "libport/detect_win32.h"
struct tms
{
  libport::utime_t tms_utime;  /* user time */
  libport::utime_t tms_stime;  /* system time */
  libport::utime_t tms_cutime; /* user time of dead children */
  libport::utime_t tms_cstime; /* system time of dead children */
};

# ifdef WIN32
# include "libport/windows.hh"
static libport::utime_t times(struct tms* t)
{
 //unit: 100 nanoseconds
 FILETIME ctime, etime, kerneltime, usertime;
 GetProcessTimes(GetCurrentProcess(), &ctime, &etime, &kerneltime, &usertime);
 t->tms_cutime = t->tms_cstime = 0;
 t->tms_utime = usertime.dwLowDateTime + static_cast<libport::utime_t>(usertime.dwHighDateTime) << 32;
 t->tms_stime = kerneltime.dwLowDateTime + static_cast<libport::utime_t>(kerneltime.dwHighDateTime) << 32;
 return libport::utime()*10LL;
}

/// FILETIME unit is 100 nanoseconds.
# define sysconf(i) 10000000LL
# endif

#endif

#include <unistd.h>

#include "libport/timer.hh"
#include "libport/contract.hh"

namespace libport
{

  /*-----------------.
  | timer::time_var.  |
  `-----------------*/

  timer::time_var::time_var ()
    : initial (true)
  { }

  void
  timer::time_var::start ()
  {
    struct tms t;

    begin.wall = times (&t);
    begin.user = t.tms_utime;
    begin.sys  = t.tms_stime;

    if (initial)
      {
	initial = false;
	first = begin;
      }
  }

  void
  timer::time_var::stop ()
  {
    struct tms t;

    last.wall = times (&t);
    last.user = t.tms_utime;
    last.sys = t.tms_stime;
    elapsed.wall += last.wall - begin.wall;
    elapsed.user += last.user - begin.user;
    elapsed.sys += last.sys - begin.sys;
  }

  bool
  timer::time_var::is_zero ()
  {
    return true
	    && elapsed.wall == 0
	    && elapsed.user == 0
	    && elapsed.sys  == 0;
  }

  /*--------.
  | timer.  |
  `--------*/

  timer::timer () :
    dump_stream (0)
  { }

  // Duplicate a timer. No tasks should be running.
  timer::timer (const timer& rhs) :
    intmap (rhs.intmap),
    total (rhs.total),
    dump_stream (rhs.dump_stream)
  {
    precondition (rhs.tasks.empty ());

    for (task_map_type::const_iterator i = rhs.tasksmap.begin ();
	 i != rhs.tasksmap.end (); ++i)
      if (tasksmap.find (i->first) == tasksmap.end ())
	tasksmap[i->first] = new time_var (*i->second);
  }

  timer::~timer ()
  {
    // If magic is asked on destruction, let it happen completely.
    if (dump_stream)
      {
	// Consider that if the tasks were not properly closed, then
	// stop was not invoked either.
	if (!tasks.empty ())
	  {
	    do
	      pop ();
	    while (!tasks.empty ())
	      ;
	    stop ();
	  }
	dump (*dump_stream);
      }

    // Deallocate all our time_var.
    for (task_map_type::iterator i = tasksmap.begin ();
	 i != tasksmap.end (); ++i)
      delete i->second;
  }

  void
  timer::name (int i, std::string task_name)
  {
    intmap[i] = task_name;
  }

  void
  timer::timeinfo (long time, long total_time, std::ostream& out)
  {
    out << setiosflags (std::ios::left);
    out << std::setw (6) << std::setprecision (6)
	<< (float) (time) / clocks_per_sec;
    out << resetiosflags (std::ios::left);
    out << " (";
    out << std::setw (5) << std::setprecision (3)
	<< (total_time ?
	    (float) time * 100 / total_time :
	    (float) time);
    out << "%) ";
  }

  void
  timer::dump (std::ostream& out = std::cerr)
  {
    out << "Execution times (seconds)" << std::endl;
    for (task_map_type::const_iterator i = tasksmap.begin ();
	 i != tasksmap.end (); ++i)
      {
	if (!(i->second->is_zero ()))
	  {
	    out << " " << i->first << std::setw (26 - i->first.length ());
	    out << ": ";
	    timeinfo (i->second->elapsed.user, total.elapsed.user, out);
	    out << "  ";
	    timeinfo (i->second->elapsed.sys, total.elapsed.sys, out);
	    out << "  ";
	    timeinfo (i->second->elapsed.wall, total.elapsed.wall, out);
	    out << std::endl;
	  }
      }
    out << std::endl;

    out << "Cumulated times (seconds)" << std::endl;
    for (task_map_type::const_iterator i = tasksmap.begin ();
	 i != tasksmap.end (); ++i)
      {
	if (0 != (i->second->last.wall - i->second->first.wall))
	  {
	    out << " " << i->first << std::setw (26 - i->first.length ());
	    out << ": ";
	    timeinfo (i->second->last.user - i->second->first.user,
		      total.elapsed.user, out);
	    out << "  ";
	    timeinfo (i->second->last.sys - i->second->first.sys,
		      total.elapsed.sys, out);
	    out << "  ";
	    timeinfo (i->second->last.wall - i->second->first.wall,
		      total.elapsed.wall, out);
	    out << std::endl;
	  }
      }
    out << std::endl;

    out << " TOTAL (seconds)"  << std::setw (11) << ": "

	<< setiosflags (std::ios::left) << std::setw (7)
	<< (float) total.elapsed.user / clocks_per_sec
	<< std::setw (11)
	<< "user,"

	<< std::setw (7)
	<< (float) total.elapsed.sys / clocks_per_sec
	<< std::setw (11)
	<< "system,"

	<< std::setw (7)
	<< (float) total.elapsed.wall / clocks_per_sec
	<< "wall"

	<< resetiosflags (std::ios::left) << std::endl;
  }

  void
  timer::push (const std::string& task_name)
  {
    time_var* current;

    // if stack isn't empty, we set elapsed time for the current task
    if (!tasks.empty ())
      tasks.top ()->stop ();

    if (tasksmap.find (task_name) == tasksmap.end ())
      tasksmap[task_name] = new time_var;

    current = tasksmap[task_name];
    tasks.push (current);
    current->start ();
  }

  void
  timer::pop ()
  {
    precondition (!tasks.empty ());

    // Set the Elapsed time for the task we are closing
    tasks.top ()->stop ();

    // Current task is removed of the stack
    tasks.pop ();

    // We set the start time of the previous task at current time
    if (!tasks.empty ())
      tasks.top ()->start ();
  }

  timer&
  timer::operator<< (const timer& rhs)
  {
    // No task should be running when merging timers.
    precondition (rhs.tasks.empty ());

    for (task_map_type::const_iterator i = rhs.tasksmap.begin ();
	 i != rhs.tasksmap.end (); ++i)
      {
	if (tasksmap.find (i->first) == tasksmap.end ())
	  tasksmap[i->first] = new time_var (*i->second);
      }

    intmap.insert (rhs.intmap.begin (), rhs.intmap.end ());
    return *this;
  }

  const long timer::clocks_per_sec = sysconf (_SC_CLK_TCK);

} // namespace libport
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: diactrl.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:15:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SD_DIACTRL_HXX
#define _SD_DIACTRL_HXX

#pragma hdrstop

#ifndef SD_DLGCTRLS_HXX
#include "dlgctrls.hxx"
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif

#ifndef _SFX_BINDINGS_HXX
#include <sfx2/bindings.hxx>
#endif
#ifndef _SVX_ITEMWIN_HXX //autogen
#include <svx/itemwin.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_FIELD_HXX //autogen
#include <vcl/field.hxx>
#endif

#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _SFXTBXCTRL_HXX //autogen
#include <sfx2/tbxctrl.hxx>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

//========================================================================
// SdPagesField:

class SdPagesField : public SvxMetricField
{
private:
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > m_xFrame;
protected:
    virtual void    Modify();

public:
                    SdPagesField( Window* pParent,
                                  const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame,
                                  WinBits nBits = WB_BORDER | WB_SPIN | WB_REPEAT );
                    ~SdPagesField();

    void            Update( const SfxUInt16Item* pItem );
};

//========================================================================
// SdTbxCtlDiaPages:
//========================================================================

class SdTbxCtlDiaPages : public SfxToolBoxControl
{
public:
    virtual void        StateChanged( USHORT nSID, SfxItemState eState,
                                      const SfxPoolItem* pState );
    virtual Window*     CreateItemWindow( Window *pParent );

    SFX_DECL_TOOLBOX_CONTROL();

    SdTbxCtlDiaPages( USHORT nSlotId, USHORT nId, ToolBox& rTbx );
    ~SdTbxCtlDiaPages();
};

#endif // _SD_DIACTRL_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.288); FILE MERGED 2005/09/05 13:22:56 rt 1.5.288.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: diactrl.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:24:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SD_DIACTRL_HXX
#define _SD_DIACTRL_HXX

#pragma hdrstop

#ifndef SD_DLGCTRLS_HXX
#include "dlgctrls.hxx"
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif

#ifndef _SFX_BINDINGS_HXX
#include <sfx2/bindings.hxx>
#endif
#ifndef _SVX_ITEMWIN_HXX //autogen
#include <svx/itemwin.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_FIELD_HXX //autogen
#include <vcl/field.hxx>
#endif

#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _SFXTBXCTRL_HXX //autogen
#include <sfx2/tbxctrl.hxx>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

//========================================================================
// SdPagesField:

class SdPagesField : public SvxMetricField
{
private:
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > m_xFrame;
protected:
    virtual void    Modify();

public:
                    SdPagesField( Window* pParent,
                                  const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame,
                                  WinBits nBits = WB_BORDER | WB_SPIN | WB_REPEAT );
                    ~SdPagesField();

    void            Update( const SfxUInt16Item* pItem );
};

//========================================================================
// SdTbxCtlDiaPages:
//========================================================================

class SdTbxCtlDiaPages : public SfxToolBoxControl
{
public:
    virtual void        StateChanged( USHORT nSID, SfxItemState eState,
                                      const SfxPoolItem* pState );
    virtual Window*     CreateItemWindow( Window *pParent );

    SFX_DECL_TOOLBOX_CONTROL();

    SdTbxCtlDiaPages( USHORT nSlotId, USHORT nId, ToolBox& rTbx );
    ~SdTbxCtlDiaPages();
};

#endif // _SD_DIACTRL_HXX

<|endoftext|>


<commit_before>#include "connection.h"

hwo_connection::hwo_connection(const std::string& host, const std::string& port)
  : socket(io_service)
{
  tcp::resolver resolver(io_service);
  tcp::resolver::query query(host, port);
  boost::asio::connect(socket, resolver.resolve(query));
  response_buf.prepare(8192);
}

hwo_connection::~hwo_connection()
{
  socket.close();
}

jsoncons::json hwo_connection::receive_response(boost::system::error_code& error)
{
  boost::asio::read_until(socket, response_buf, "\n", error);
  if (error)
  {
    return jsoncons::json();
  }
  std::istream s(&response_buf);
  return jsoncons::json::parse(s);
}

void hwo_connection::send_requests(const std::vector<jsoncons::json>& msgs)
{
  jsoncons::output_format format;
  format.escape_all_non_ascii(true);
  boost::asio::streambuf request_buf;
  std::ostream s(&request_buf);
  for (const auto& m : msgs) {
    m.to_stream(s, format);
    s << std::endl;
  }
  socket.send(request_buf.data());
}
<commit_msg>Fix case where received message was potentially dropped in C++ bot<commit_after>#include "connection.h"

hwo_connection::hwo_connection(const std::string& host, const std::string& port)
  : socket(io_service)
{
  tcp::resolver resolver(io_service);
  tcp::resolver::query query(host, port);
  boost::asio::connect(socket, resolver.resolve(query));
  response_buf.prepare(8192);
}

hwo_connection::~hwo_connection()
{
  socket.close();
}

jsoncons::json hwo_connection::receive_response(boost::system::error_code& error)
{
  auto len = boost::asio::read_until(socket, response_buf, "\n", error);
  if (error)
  {
    return jsoncons::json();
  }
  auto buf = response_buf.data();
  std::string reply(boost::asio::buffers_begin(buf), boost::asio::buffers_begin(buf) + len);
  response_buf.consume(len);
  return jsoncons::json::parse_string(reply);
}

void hwo_connection::send_requests(const std::vector<jsoncons::json>& msgs)
{
  jsoncons::output_format format;
  format.escape_all_non_ascii(true);
  boost::asio::streambuf request_buf;
  std::ostream s(&request_buf);
  for (const auto& m : msgs) {
    m.to_stream(s, format);
    s << std::endl;
  }
  socket.send(request_buf.data());
}
<|endoftext|>