<commit_before>/************************************************************************/
/*                                                                      */
/*       Copyright 2009 by Rahul Nair and  Ullrich Koethe               */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_RANDOM_FOREST_IMPEX_HDF5_HXX
#define VIGRA_RANDOM_FOREST_IMPEX_HDF5_HXX

#include "config.hxx"
#include "random_forest.hxx"
#include "hdf5impex.hxx"
#include <string>

namespace vigra
{

static const char *const rf_hdf5_options       = "_options";
static const char *const rf_hdf5_ext_param     = "_ext_param";
static const char *const rf_hdf5_labels        = "labels";
static const char *const rf_hdf5_topology      = "topology";
static const char *const rf_hdf5_parameters    = "parameters";
static const char *const rf_hdf5_tree          = "Tree_";
static const char *const rf_hdf5_version_group = ".";
static const char *const rf_hdf5_version_tag   = "vigra_random_forest_version";
static const double      rf_hdf5_version       =  0.1;

namespace detail
{

VIGRA_EXPORT void options_import_HDF5(HDF5File &, RandomForestOptions &,
                                      const std::string &);

VIGRA_EXPORT void options_export_HDF5(HDF5File &, const RandomForestOptions &,
                                      const std::string &);

VIGRA_EXPORT void dt_import_HDF5(HDF5File &, detail::DecisionTree &,
                                 const std::string &);

VIGRA_EXPORT void dt_export_HDF5(HDF5File &, const detail::DecisionTree &,
                                 const std::string &);

template<class X>
void rf_import_HDF5_to_map(HDF5File & h5context, X & param,
                           const char *const ignored_label = 0)
{
    // read a map containing all the double fields
    typedef typename X::map_type map_type;
    typedef std::pair<typename map_type::iterator, bool> inserter_type;
    typedef typename map_type::value_type value_type;
    typedef typename map_type::mapped_type mapped_type;

    map_type serialized_param;
    bool ignored_seen = ignored_label == 0;

    std::vector<std::string> names = h5context.ls();
    std::vector<std::string>::const_iterator j;
    for (j = names.begin(); j != names.end(); ++j)
    {
        if (ignored_label && *j == ignored_label)
        {
            ignored_seen = true;
            continue;
        }
        // get sort of an iterator to a new empty array vector in the map ...
        inserter_type new_array
            = serialized_param.insert(value_type(*j, mapped_type()));
        // ... and read the data into that place.
        h5context.readAndResize(*j, (*(new_array.first)).second);
    }
    vigra_precondition(ignored_seen, "rf_import_HDF5_to_map(): "
                                                         "labels are missing.");
    param.make_from_map(serialized_param);
}

template<class T>
void problemspec_import_HDF5(HDF5File & h5context, ProblemSpec<T> & param,
                             const std::string & name)
{
    h5context.cd(name);
    rf_import_HDF5_to_map(h5context, param, rf_hdf5_labels);
    // load_class_labels
    ArrayVector<T> labels;
    h5context.readAndResize(rf_hdf5_labels, labels);
    param.classes_(labels.begin(), labels.end());
    h5context.cd_up();
}

template<class X>
void rf_export_map_to_HDF5(HDF5File & h5context, const X & param)
{
    typedef typename X::map_type map_type;
    map_type serialized_param;
    // get a map containing all the double fields
    param.make_map(serialized_param);
    typename map_type::const_iterator j;
    for (j = serialized_param.begin(); j != serialized_param.end(); ++j)
        h5context.write(j->first, j->second);
}

template<class T>
void problemspec_export_HDF5(HDF5File & h5context, ProblemSpec<T> const & param,
                             const std::string & name)
{
    h5context.cd_mk(name);
    rf_export_map_to_HDF5(h5context, param);
    h5context.write(rf_hdf5_labels, param.classes);
    h5context.cd_up();
}

struct padded_number_string_data;
class VIGRA_EXPORT padded_number_string
{
private:
    padded_number_string_data* padded_number;
protected:
    padded_number_string(const padded_number_string &);
    void operator=(const padded_number_string &);
public:
    padded_number_string(int n);
    std::string operator()(int k) const;
    ~padded_number_string();
};

inline std::string get_cwd(HDF5File & h5context)
{
    return h5context.get_absolute_path(h5context.pwd());
}

} // namespace detail

/** \brief Save a random forest to an HDF5File object into a specified HDF5
           group.

    The random forest is saved as a set of HDF5 datasets, groups, and
    attributes below a certain HDF5 group (default: current group of the
    HDF5File object). No additional data should be stored in that group.

    \param rf        Random forest object to be exported
    \param h5context HDF5File object to use
    \param pathname  If empty or not supplied, save the random forest to the
                     current group of the HDF5File object. Otherwise, save to a
                     new-created group specified by the path name, which may
                     be either relative or absolute.
*/
template<class T, class Tag>
void rf_export_HDF5(const RandomForest<T, Tag> & rf,
                    HDF5File & h5context,
                    const std::string & pathname = "")
{
    std::string cwd;
    if (pathname.size()) {
        cwd = detail::get_cwd(h5context);
        h5context.cd_mk(pathname);
    }
    // version attribute
    h5context.writeAttribute(rf_hdf5_version_group, rf_hdf5_version_tag,
                             rf_hdf5_version);
    // save serialized options
    detail::options_export_HDF5(h5context, rf.options(), rf_hdf5_options);
    // save external parameters
    detail::problemspec_export_HDF5(h5context, rf.ext_param(),
                                    rf_hdf5_ext_param);
    // save trees
    int tree_count = rf.options_.tree_count_;
    detail::padded_number_string tree_number(tree_count);
    for (int i = 0; i < tree_count; ++i)
        detail::dt_export_HDF5(h5context, rf.tree(i),
                                                 rf_hdf5_tree + tree_number(i));

    if (pathname.size())
        h5context.cd(cwd);
}

/** \brief Save a random forest to a named HDF5 file into a specified HDF5
           group.

    The random forest is saved as a set of HDF5 datasets, groups, and
    attributes below a certain HDF5 group (default: root). No additional data
    should be stored in that group.

    \param rf       Random forest object to be exported
    \param filename Name of an HDF5 file to open
    \param pathname If empty or not supplied, save the random forest to the
                    root group of the HDF5 file. Otherwise, save to a
                    new-created group specified by the path name (relative
                    to the root group).
*/
template<class T, class Tag>
void rf_export_HDF5(const RandomForest<T, Tag> & rf,
                    const std::string & filename,
                    const std::string & pathname = "")
{
    HDF5File h5context(filename , HDF5File::Open);
    rf_export_HDF5(rf, h5context, pathname);
}

/** \brief Read a random forest from an HDF5File object's specified group.

    The random forest is read from a certain HDF5 group (default: current group
    of the HDF5File object) as a set of HDF5 datasets, groups, and
    attributes. No additional data should be present in that group.

    \param rf        Random forest object to be imported
    \param h5context HDF5File object to use
    \param pathname  If empty or not supplied, read from the random forest
                     from the current group of the HDF5File object. Otherwise,
                     use the group specified by the path name, which may
                     be either relative or absolute.
*/
template<class T, class Tag>
bool rf_import_HDF5(RandomForest<T, Tag> & rf,
                    HDF5File & h5context,
                    const std::string & pathname = "")
{
    std::string cwd;
    if (pathname.size()) {
        cwd = detail::get_cwd(h5context);
        h5context.cd(pathname);
    }
    // version attribute
    if (h5context.existsAttribute(rf_hdf5_version_group, rf_hdf5_version_tag))
    {
        double read_version;
        h5context.readAttribute(rf_hdf5_version_group, rf_hdf5_version_tag,
                                read_version);
        vigra_precondition(read_version <= rf_hdf5_version,
                          "rf_import_HDF5(): unexpected file format version.");
    }
    // get serialized options
    detail::options_import_HDF5(h5context, rf.options_, rf_hdf5_options);
    // get external parameters
    detail::problemspec_import_HDF5(h5context, rf.ext_param_,
                                    rf_hdf5_ext_param);
    // get all groups in base path
    // no check for the rf_hdf5_tree prefix...
    std::vector<std::string> names = h5context.ls();
    std::vector<std::string>::const_iterator j;
    for (j = names.begin(); j != names.end(); ++j)
    {
        if ((*j->rbegin() == '/') && (*j->begin() != '_')) // skip the above
        {
            rf.trees_.push_back(detail::DecisionTree(rf.ext_param_));
            detail::dt_import_HDF5(h5context, rf.trees_.back(), *j);
        }
    }
    if (pathname.size())
        h5context.cd(cwd);
    return true;
}

/** \brief Read a random forest from a named HDF5 file's specified group.

    The random forest is read from a certain HDF5 group (default: root group
    of the HDF5 file) as a set of HDF5 datasets, groups, and attributes.
    No additional data should be present in that group.

    \param rf        Random forest object to be imported
    \param filename Name of an HDF5 file to open
    \param pathname  If empty or not supplied, read from the random forest
                     from the current group of the HDF5 file. Otherwise,
                     use the group specified by the path name, which may
                     be either relative or absolute.
*/
template<class T, class Tag>
bool rf_import_HDF5(RandomForest<T, Tag> & rf,
                    const std::string & filename,
                    const std::string & pathname = "")
{
    HDF5File h5context(filename, HDF5File::Open);
    return rf_import_HDF5(rf, h5context, pathname);
}

} // namespace vigra

#endif // VIGRA_RANDOM_FOREST_HDF5_IMPEX_HXX
<commit_msg>RandomForest: When importing from Hdf5, open file in read-only mode.<commit_after>/************************************************************************/
/*                                                                      */
/*       Copyright 2009 by Rahul Nair and  Ullrich Koethe               */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_RANDOM_FOREST_IMPEX_HDF5_HXX
#define VIGRA_RANDOM_FOREST_IMPEX_HDF5_HXX

#include "config.hxx"
#include "random_forest.hxx"
#include "hdf5impex.hxx"
#include <string>

namespace vigra
{

static const char *const rf_hdf5_options       = "_options";
static const char *const rf_hdf5_ext_param     = "_ext_param";
static const char *const rf_hdf5_labels        = "labels";
static const char *const rf_hdf5_topology      = "topology";
static const char *const rf_hdf5_parameters    = "parameters";
static const char *const rf_hdf5_tree          = "Tree_";
static const char *const rf_hdf5_version_group = ".";
static const char *const rf_hdf5_version_tag   = "vigra_random_forest_version";
static const double      rf_hdf5_version       =  0.1;

namespace detail
{

VIGRA_EXPORT void options_import_HDF5(HDF5File &, RandomForestOptions &,
                                      const std::string &);

VIGRA_EXPORT void options_export_HDF5(HDF5File &, const RandomForestOptions &,
                                      const std::string &);

VIGRA_EXPORT void dt_import_HDF5(HDF5File &, detail::DecisionTree &,
                                 const std::string &);

VIGRA_EXPORT void dt_export_HDF5(HDF5File &, const detail::DecisionTree &,
                                 const std::string &);

template<class X>
void rf_import_HDF5_to_map(HDF5File & h5context, X & param,
                           const char *const ignored_label = 0)
{
    // read a map containing all the double fields
    typedef typename X::map_type map_type;
    typedef std::pair<typename map_type::iterator, bool> inserter_type;
    typedef typename map_type::value_type value_type;
    typedef typename map_type::mapped_type mapped_type;

    map_type serialized_param;
    bool ignored_seen = ignored_label == 0;

    std::vector<std::string> names = h5context.ls();
    std::vector<std::string>::const_iterator j;
    for (j = names.begin(); j != names.end(); ++j)
    {
        if (ignored_label && *j == ignored_label)
        {
            ignored_seen = true;
            continue;
        }
        // get sort of an iterator to a new empty array vector in the map ...
        inserter_type new_array
            = serialized_param.insert(value_type(*j, mapped_type()));
        // ... and read the data into that place.
        h5context.readAndResize(*j, (*(new_array.first)).second);
    }
    vigra_precondition(ignored_seen, "rf_import_HDF5_to_map(): "
                                                         "labels are missing.");
    param.make_from_map(serialized_param);
}

template<class T>
void problemspec_import_HDF5(HDF5File & h5context, ProblemSpec<T> & param,
                             const std::string & name)
{
    h5context.cd(name);
    rf_import_HDF5_to_map(h5context, param, rf_hdf5_labels);
    // load_class_labels
    ArrayVector<T> labels;
    h5context.readAndResize(rf_hdf5_labels, labels);
    param.classes_(labels.begin(), labels.end());
    h5context.cd_up();
}

template<class X>
void rf_export_map_to_HDF5(HDF5File & h5context, const X & param)
{
    typedef typename X::map_type map_type;
    map_type serialized_param;
    // get a map containing all the double fields
    param.make_map(serialized_param);
    typename map_type::const_iterator j;
    for (j = serialized_param.begin(); j != serialized_param.end(); ++j)
        h5context.write(j->first, j->second);
}

template<class T>
void problemspec_export_HDF5(HDF5File & h5context, ProblemSpec<T> const & param,
                             const std::string & name)
{
    h5context.cd_mk(name);
    rf_export_map_to_HDF5(h5context, param);
    h5context.write(rf_hdf5_labels, param.classes);
    h5context.cd_up();
}

struct padded_number_string_data;
class VIGRA_EXPORT padded_number_string
{
private:
    padded_number_string_data* padded_number;
protected:
    padded_number_string(const padded_number_string &);
    void operator=(const padded_number_string &);
public:
    padded_number_string(int n);
    std::string operator()(int k) const;
    ~padded_number_string();
};

inline std::string get_cwd(HDF5File & h5context)
{
    return h5context.get_absolute_path(h5context.pwd());
}

} // namespace detail

/** \brief Save a random forest to an HDF5File object into a specified HDF5
           group.

    The random forest is saved as a set of HDF5 datasets, groups, and
    attributes below a certain HDF5 group (default: current group of the
    HDF5File object). No additional data should be stored in that group.

    \param rf        Random forest object to be exported
    \param h5context HDF5File object to use
    \param pathname  If empty or not supplied, save the random forest to the
                     current group of the HDF5File object. Otherwise, save to a
                     new-created group specified by the path name, which may
                     be either relative or absolute.
*/
template<class T, class Tag>
void rf_export_HDF5(const RandomForest<T, Tag> & rf,
                    HDF5File & h5context,
                    const std::string & pathname = "")
{
    std::string cwd;
    if (pathname.size()) {
        cwd = detail::get_cwd(h5context);
        h5context.cd_mk(pathname);
    }
    // version attribute
    h5context.writeAttribute(rf_hdf5_version_group, rf_hdf5_version_tag,
                             rf_hdf5_version);
    // save serialized options
    detail::options_export_HDF5(h5context, rf.options(), rf_hdf5_options);
    // save external parameters
    detail::problemspec_export_HDF5(h5context, rf.ext_param(),
                                    rf_hdf5_ext_param);
    // save trees
    int tree_count = rf.options_.tree_count_;
    detail::padded_number_string tree_number(tree_count);
    for (int i = 0; i < tree_count; ++i)
        detail::dt_export_HDF5(h5context, rf.tree(i),
                                                 rf_hdf5_tree + tree_number(i));

    if (pathname.size())
        h5context.cd(cwd);
}

/** \brief Save a random forest to a named HDF5 file into a specified HDF5
           group.

    The random forest is saved as a set of HDF5 datasets, groups, and
    attributes below a certain HDF5 group (default: root). No additional data
    should be stored in that group.

    \param rf       Random forest object to be exported
    \param filename Name of an HDF5 file to open
    \param pathname If empty or not supplied, save the random forest to the
                    root group of the HDF5 file. Otherwise, save to a
                    new-created group specified by the path name (relative
                    to the root group).
*/
template<class T, class Tag>
void rf_export_HDF5(const RandomForest<T, Tag> & rf,
                    const std::string & filename,
                    const std::string & pathname = "")
{
    HDF5File h5context(filename , HDF5File::Open);
    rf_export_HDF5(rf, h5context, pathname);
}

/** \brief Read a random forest from an HDF5File object's specified group.

    The random forest is read from a certain HDF5 group (default: current group
    of the HDF5File object) as a set of HDF5 datasets, groups, and
    attributes. No additional data should be present in that group.

    \param rf        Random forest object to be imported
    \param h5context HDF5File object to use
    \param pathname  If empty or not supplied, read from the random forest
                     from the current group of the HDF5File object. Otherwise,
                     use the group specified by the path name, which may
                     be either relative or absolute.
*/
template<class T, class Tag>
bool rf_import_HDF5(RandomForest<T, Tag> & rf,
                    HDF5File & h5context,
                    const std::string & pathname = "")
{
    std::string cwd;
    if (pathname.size()) {
        cwd = detail::get_cwd(h5context);
        h5context.cd(pathname);
    }
    // version attribute
    if (h5context.existsAttribute(rf_hdf5_version_group, rf_hdf5_version_tag))
    {
        double read_version;
        h5context.readAttribute(rf_hdf5_version_group, rf_hdf5_version_tag,
                                read_version);
        vigra_precondition(read_version <= rf_hdf5_version,
                          "rf_import_HDF5(): unexpected file format version.");
    }
    // get serialized options
    detail::options_import_HDF5(h5context, rf.options_, rf_hdf5_options);
    // get external parameters
    detail::problemspec_import_HDF5(h5context, rf.ext_param_,
                                    rf_hdf5_ext_param);
    // get all groups in base path
    // no check for the rf_hdf5_tree prefix...
    std::vector<std::string> names = h5context.ls();
    std::vector<std::string>::const_iterator j;
    for (j = names.begin(); j != names.end(); ++j)
    {
        if ((*j->rbegin() == '/') && (*j->begin() != '_')) // skip the above
        {
            rf.trees_.push_back(detail::DecisionTree(rf.ext_param_));
            detail::dt_import_HDF5(h5context, rf.trees_.back(), *j);
        }
    }
    if (pathname.size())
        h5context.cd(cwd);
    return true;
}

/** \brief Read a random forest from a named HDF5 file's specified group.

    The random forest is read from a certain HDF5 group (default: root group
    of the HDF5 file) as a set of HDF5 datasets, groups, and attributes.
    No additional data should be present in that group.

    \param rf        Random forest object to be imported
    \param filename Name of an HDF5 file to open
    \param pathname  If empty or not supplied, read from the random forest
                     from the current group of the HDF5 file. Otherwise,
                     use the group specified by the path name, which may
                     be either relative or absolute.
*/
template<class T, class Tag>
bool rf_import_HDF5(RandomForest<T, Tag> & rf,
                    const std::string & filename,
                    const std::string & pathname = "")
{
    HDF5File h5context(filename, HDF5File::OpenReadOnly);
    return rf_import_HDF5(rf, h5context, pathname);
}

} // namespace vigra

#endif // VIGRA_RANDOM_FOREST_HDF5_IMPEX_HXX
<|endoftext|>


<commit_before>#include "Utility/String.h"

#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <cctype>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <cmath>
#include <cctype>
#include <iterator>

std::vector<std::string> String::split(const std::string& s, const std::string& delim, const size_t count) noexcept
{
    if(s.empty())
    {
        return {};
    }

    std::vector<std::string> result;
    if(delim.empty())
    {
        auto ss = std::istringstream(s);
        std::copy(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>(), std::back_inserter(result));
    }
    else
    {
        size_t start_index = 0;
        size_t end_index = 0;
        size_t split_count = 0;
        while(end_index < s.size() && split_count < count)
        {
            end_index = std::min(s.find(delim, start_index), s.size());
            result.push_back(s.substr(start_index, end_index - start_index));
            start_index = end_index + delim.size();
            ++split_count;
        }

        if(start_index <= s.size())
        {
            result.push_back(s.substr(start_index));
        }
    }

    return result;
}

bool String::starts_with(const std::string& s, const std::string& beginning) noexcept
{
    return std::mismatch(beginning.begin(), beginning.end(), s.begin(), s.end()).first == beginning.end();
}

std::string String::trim_outer_whitespace(const std::string& s) noexcept
{
    const auto text_start = std::find_if_not(s.begin(), s.end(), String::isspace);
    if(text_start == s.end())
    {
        return {};
    }

    const auto text_end = std::find_if_not(s.rbegin(), s.rend(), String::isspace).base();
    return std::string(text_start, text_end);
}

std::string String::remove_extra_whitespace(const std::string& s) noexcept
{
    const auto words = split(s);
    return join(words.begin(), words.end(), " ");
}

std::string String::strip_comments(const std::string& str, const std::string& comment) noexcept
{
    return trim_outer_whitespace(str.substr(0, str.find(comment)));
}

std::string String::strip_block_comment(const std::string& str, const std::string& start, const std::string& end)
{
    const auto start_comment_index = str.find(start);
    const auto end_comment_index = str.find(end);

    if(start_comment_index == std::string::npos && end_comment_index == std::string::npos)
    {
        return trim_outer_whitespace(str);
    }

    if(start_comment_index == std::string::npos || end_comment_index == std::string::npos)
    {
        throw std::invalid_argument("\"" + str + "\" is missing a comment delimiter: " + start + end);
    }

    if(start_comment_index >= end_comment_index)
    {
        throw std::invalid_argument("\"" + str + "\" contains bad comment delimiters: " + start + end);
    }

    try
    {
        const auto first_part = str.substr(0, start_comment_index);
        const auto last_part = str.substr(end_comment_index + end.size());
        return strip_block_comment(trim_outer_whitespace(first_part) + " " + trim_outer_whitespace(last_part), start, end);
    }
    catch(const std::invalid_argument& e)
    {
        throw std::invalid_argument(e.what() + std::string("\nOriginal line: ") + str);
    }
}

std::string String::strip_nested_block_comments(const std::string& str, const std::string& start, const std::string& end)
{
    if(contains(start, end) || contains(end, start))
    {
        throw std::invalid_argument("Delimiters cannot share substrings: " + start + "," + end + ".");
    }

    const auto error_message = "Invalid nesting of delimiters " + start + "," + end + ": " + str;
    std::string result;
    auto depth = 0;
    size_t index = 0;
    while(index < str.size())
    {
        auto start_index = str.find(start, index);
        auto end_index = str.find(end, index);
        if(start_index < end_index)
        {
            if(depth == 0)
            {
                result += str.substr(index, start_index - index);
            }
            ++depth;
            index = start_index + start.size();
        }
        else if(end_index < start_index)
        {
            if(depth == 0)
            {
                throw std::invalid_argument(error_message);
            }
            --depth;
            index = end_index + end.size();
        }
        else // start_index == end_index == std::string::npos
        {
            result += str.substr(index);
            break;
        }
    }

    if(depth != 0)
    {
        throw std::invalid_argument(error_message);
    }

    return result;
}

std::string String::remove_pgn_comments(const std::string& line)
{
    const auto index = line.find_first_of(";({");
    const auto delimiter = index < std::string::npos ? line[index] : '\0';

    switch(delimiter)
    {
        case ';' : return remove_pgn_comments(strip_comments(line, ";"));
        case '(' : return remove_pgn_comments(strip_nested_block_comments(line, "(", ")"));
        case '{' : return remove_pgn_comments(strip_block_comment(line, "{", "}"));
        default  : return remove_extra_whitespace(line);
    }
}

std::string String::extract_delimited_text(const std::string& str, const std::string& start, const std::string& end)
{
    const auto first_delimiter_index = str.find(start);
    if(first_delimiter_index == std::string::npos)
    {
        throw std::invalid_argument("Starting delimiter not found in \"" + str + "\": " + start + " " + end);
    }
    const auto text_start_index = first_delimiter_index + start.size();

    const auto second_delimiter_index = str.find(end, text_start_index);
    if(second_delimiter_index == std::string::npos)
    {
        throw std::invalid_argument("Ending delimiter not found in \"" + str + "\": " + start + " " + end);
    }
    const auto text_length = second_delimiter_index - text_start_index;

    return str.substr(text_start_index, text_length);
}

char String::tolower(const char letter) noexcept
{
    return char(std::tolower(letter));
}

char String::toupper(const char letter) noexcept
{
    return char(std::toupper(letter));
}

std::string String::lowercase(std::string s) noexcept
{
    std::transform(s.begin(), s.end(), s.begin(), String::tolower);
    return s;
}

bool String::isdigit(const char c) noexcept
{
    return std::isdigit(c);
}

bool String::isspace(char c) noexcept
{
    return std::isspace(c);
}

std::string String::round_to_decimals(const double x, const size_t decimal_places) noexcept
{
    auto result = std::ostringstream();
    result << std::fixed << std::setprecision(int(decimal_places)) << x;
    return result.str();
}

std::string String::date_and_time_format(const std::chrono::system_clock::time_point& point_in_time,
                                         const std::string& format) noexcept
{
    const auto time_c = std::chrono::system_clock::to_time_t(point_in_time);
    std::tm time_out;
#ifdef _WIN32
    localtime_s(&time_out, &time_c);
#elif defined(__linux__)
    localtime_r(&time_c, &time_out);
#endif
    auto ss = std::ostringstream{};
    ss << std::put_time(&time_out, format.c_str());
    return ss.str();
}

std::string String::add_to_file_name(const std::string& original_file_name, const std::string& addition) noexcept
{
    const auto dot_index = std::min(original_file_name.find_last_of('.'), original_file_name.size());
    return original_file_name.substr(0, dot_index) + addition + original_file_name.substr(dot_index);
}

std::string String::pluralize(int count, const std::string& noun) noexcept
{
    return std::to_string(count) + " " + noun + (count == 1 ? "" : "s");
}

std::string String::word_wrap(const size_t line_length, const size_t indent, const std::string& text) noexcept
{
    const auto text_length = line_length - indent;

    std::vector<std::string> lines{""};
    for(const auto& word : split(text))
    {
        std::string space = lines.back().empty() ? "" : " ";
        if(lines.back().size() + space.size() + word.size() > text_length)
        {
            lines.push_back("");
            space = "";
        }
        lines.back() += space + word;
    }

    const auto indent_space = std::string(indent, ' ');
    auto wrapped = indent_space + join(lines.begin(), lines.end(), "\n" + indent_space);
    std::transform(wrapped.begin(), wrapped.end(), wrapped.begin(), [](auto& c) { return c == '~' ? ' ' : c;  });
    return wrapped;
}
<commit_msg>Replace std::transform with std::replace<commit_after>#include "Utility/String.h"

#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <cctype>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <cmath>
#include <cctype>
#include <iterator>

std::vector<std::string> String::split(const std::string& s, const std::string& delim, const size_t count) noexcept
{
    if(s.empty())
    {
        return {};
    }

    std::vector<std::string> result;
    if(delim.empty())
    {
        auto ss = std::istringstream(s);
        std::copy(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>(), std::back_inserter(result));
    }
    else
    {
        size_t start_index = 0;
        size_t end_index = 0;
        size_t split_count = 0;
        while(end_index < s.size() && split_count < count)
        {
            end_index = std::min(s.find(delim, start_index), s.size());
            result.push_back(s.substr(start_index, end_index - start_index));
            start_index = end_index + delim.size();
            ++split_count;
        }

        if(start_index <= s.size())
        {
            result.push_back(s.substr(start_index));
        }
    }

    return result;
}

bool String::starts_with(const std::string& s, const std::string& beginning) noexcept
{
    return std::mismatch(beginning.begin(), beginning.end(), s.begin(), s.end()).first == beginning.end();
}

std::string String::trim_outer_whitespace(const std::string& s) noexcept
{
    const auto text_start = std::find_if_not(s.begin(), s.end(), String::isspace);
    if(text_start == s.end())
    {
        return {};
    }

    const auto text_end = std::find_if_not(s.rbegin(), s.rend(), String::isspace).base();
    return std::string(text_start, text_end);
}

std::string String::remove_extra_whitespace(const std::string& s) noexcept
{
    const auto words = split(s);
    return join(words.begin(), words.end(), " ");
}

std::string String::strip_comments(const std::string& str, const std::string& comment) noexcept
{
    return trim_outer_whitespace(str.substr(0, str.find(comment)));
}

std::string String::strip_block_comment(const std::string& str, const std::string& start, const std::string& end)
{
    const auto start_comment_index = str.find(start);
    const auto end_comment_index = str.find(end);

    if(start_comment_index == std::string::npos && end_comment_index == std::string::npos)
    {
        return trim_outer_whitespace(str);
    }

    if(start_comment_index == std::string::npos || end_comment_index == std::string::npos)
    {
        throw std::invalid_argument("\"" + str + "\" is missing a comment delimiter: " + start + end);
    }

    if(start_comment_index >= end_comment_index)
    {
        throw std::invalid_argument("\"" + str + "\" contains bad comment delimiters: " + start + end);
    }

    try
    {
        const auto first_part = str.substr(0, start_comment_index);
        const auto last_part = str.substr(end_comment_index + end.size());
        return strip_block_comment(trim_outer_whitespace(first_part) + " " + trim_outer_whitespace(last_part), start, end);
    }
    catch(const std::invalid_argument& e)
    {
        throw std::invalid_argument(e.what() + std::string("\nOriginal line: ") + str);
    }
}

std::string String::strip_nested_block_comments(const std::string& str, const std::string& start, const std::string& end)
{
    if(contains(start, end) || contains(end, start))
    {
        throw std::invalid_argument("Delimiters cannot share substrings: " + start + "," + end + ".");
    }

    const auto error_message = "Invalid nesting of delimiters " + start + "," + end + ": " + str;
    std::string result;
    auto depth = 0;
    size_t index = 0;
    while(index < str.size())
    {
        auto start_index = str.find(start, index);
        auto end_index = str.find(end, index);
        if(start_index < end_index)
        {
            if(depth == 0)
            {
                result += str.substr(index, start_index - index);
            }
            ++depth;
            index = start_index + start.size();
        }
        else if(end_index < start_index)
        {
            if(depth == 0)
            {
                throw std::invalid_argument(error_message);
            }
            --depth;
            index = end_index + end.size();
        }
        else // start_index == end_index == std::string::npos
        {
            result += str.substr(index);
            break;
        }
    }

    if(depth != 0)
    {
        throw std::invalid_argument(error_message);
    }

    return result;
}

std::string String::remove_pgn_comments(const std::string& line)
{
    const auto index = line.find_first_of(";({");
    const auto delimiter = index < std::string::npos ? line[index] : '\0';

    switch(delimiter)
    {
        case ';' : return remove_pgn_comments(strip_comments(line, ";"));
        case '(' : return remove_pgn_comments(strip_nested_block_comments(line, "(", ")"));
        case '{' : return remove_pgn_comments(strip_block_comment(line, "{", "}"));
        default  : return remove_extra_whitespace(line);
    }
}

std::string String::extract_delimited_text(const std::string& str, const std::string& start, const std::string& end)
{
    const auto first_delimiter_index = str.find(start);
    if(first_delimiter_index == std::string::npos)
    {
        throw std::invalid_argument("Starting delimiter not found in \"" + str + "\": " + start + " " + end);
    }
    const auto text_start_index = first_delimiter_index + start.size();

    const auto second_delimiter_index = str.find(end, text_start_index);
    if(second_delimiter_index == std::string::npos)
    {
        throw std::invalid_argument("Ending delimiter not found in \"" + str + "\": " + start + " " + end);
    }
    const auto text_length = second_delimiter_index - text_start_index;

    return str.substr(text_start_index, text_length);
}

char String::tolower(const char letter) noexcept
{
    return char(std::tolower(letter));
}

char String::toupper(const char letter) noexcept
{
    return char(std::toupper(letter));
}

std::string String::lowercase(std::string s) noexcept
{
    std::transform(s.begin(), s.end(), s.begin(), String::tolower);
    return s;
}

bool String::isdigit(const char c) noexcept
{
    return std::isdigit(c);
}

bool String::isspace(char c) noexcept
{
    return std::isspace(c);
}

std::string String::round_to_decimals(const double x, const size_t decimal_places) noexcept
{
    auto result = std::ostringstream();
    result << std::fixed << std::setprecision(int(decimal_places)) << x;
    return result.str();
}

std::string String::date_and_time_format(const std::chrono::system_clock::time_point& point_in_time,
                                         const std::string& format) noexcept
{
    const auto time_c = std::chrono::system_clock::to_time_t(point_in_time);
    std::tm time_out;
#ifdef _WIN32
    localtime_s(&time_out, &time_c);
#elif defined(__linux__)
    localtime_r(&time_c, &time_out);
#endif
    auto ss = std::ostringstream{};
    ss << std::put_time(&time_out, format.c_str());
    return ss.str();
}

std::string String::add_to_file_name(const std::string& original_file_name, const std::string& addition) noexcept
{
    const auto dot_index = std::min(original_file_name.find_last_of('.'), original_file_name.size());
    return original_file_name.substr(0, dot_index) + addition + original_file_name.substr(dot_index);
}

std::string String::pluralize(int count, const std::string& noun) noexcept
{
    return std::to_string(count) + " " + noun + (count == 1 ? "" : "s");
}

std::string String::word_wrap(const size_t line_length, const size_t indent, const std::string& text) noexcept
{
    const auto text_length = line_length - indent;

    std::vector<std::string> lines{""};
    for(const auto& word : split(text))
    {
        std::string space = lines.back().empty() ? "" : " ";
        if(lines.back().size() + space.size() + word.size() > text_length)
        {
            lines.push_back("");
            space = "";
        }
        lines.back() += space + word;
    }

    const auto indent_space = std::string(indent, ' ');
    auto wrapped = indent_space + join(lines.begin(), lines.end(), "\n" + indent_space);
    std::replace(wrapped.begin(), wrapped.end(), '~', ' ');
    return wrapped;
}
<|endoftext|>


<commit_before>/*
 * VisualOdometer.cpp
 *
 *  Created on: Feb 21, 2013
 *      Author: Michał Orynicz
 */

#include "VisualOdometer.hpp"
#include "TangentRotationReader.hpp"
#include "ShiThomasFeatureExtractor.hpp"
#include "LucasCandaePyramidTracker.hpp"
#include "BirdsEyeTranslationReader.hpp"

const unsigned int DEFAULT_MAX_FEATURES = 500;

VisualOdometer::VisualOdometer() {
	_filters.clear();
	//TODO Add default smoothness filter instead of empty list.
	_translationReader = new BirdsEyeTranslationReader(
			cv::Mat::eye(3, 3, CV_32F), ShiThomasFeatureExtractor(),
			LucasCandaePyramidTracker(),DEFAULT_MAX_FEATURES,std::list<FeatureFilter*>());
	_rotationReader = new TangentRotationReader(ShiThomasFeatureExtractor(),
			LucasCandaePyramidTracker(),std::list<FeatureFilter*>());

	_deadZoneWidth = 0;
	_horizonHeight = 0.5;
	_featuresNumber = 100;

}

VisualOdometer::~VisualOdometer() {
	if (NULL != _translationReader) {
		delete _translationReader;
	}
	if (NULL != _rotationReader) {
		delete _rotationReader;
	}

	for (std::list<FeatureFilter*>::iterator it = _filters.begin();
			_filters.end() != it; ++it) {
		if (NULL != *it) {
			delete *it;
		}
	}
}

VisualOdometer::VisualOdometer(const RotationReader &rotationReader,
		const TranslationReader &translationReader,
		const std::list<FeatureFilter*> filters, const int &horizonHeight,
		const int &deadZoneWidth, const int &featuresNumber) :
		_featuresNumber(featuresNumber), _horizonHeight(horizonHeight), _deadZoneWidth(
				deadZoneWidth) {
	_translationReader = translationReader.constructCopy();
	_rotationReader = rotationReader.constructCopy();

	for (std::list<FeatureFilter*>::const_iterator it = filters.begin();
			filters.end() != it; ++it) {
		_filters.push_back(*it);
	}
}

cv::Point3f VisualOdometer::calculateDisplacement(const cv::Mat &newFrame) {
	cv::Point3f result(0, 0, 0);

	double alpha = _rotationReader->readRotation(newFrame);
	result = _translationReader->readTranslation(newFrame, alpha);

	return result;
}
<commit_msg>Fixed code formatting of VisualOdometer.cpp<commit_after>/*
 * VisualOdometer.cpp
 *
 *  Created on: Feb 21, 2013
 *      Author: Michał Orynicz
 */

#include "VisualOdometer.hpp"
#include "TangentRotationReader.hpp"
#include "ShiThomasFeatureExtractor.hpp"
#include "LucasCandaePyramidTracker.hpp"
#include "BirdsEyeTranslationReader.hpp"

const unsigned int DEFAULT_MAX_FEATURES = 500;

VisualOdometer::VisualOdometer() {
	_filters.clear();
	//TODO Add default smoothness filter instead of empty list.
	_translationReader = new BirdsEyeTranslationReader(
			cv::Mat::eye(3, 3, CV_32F), ShiThomasFeatureExtractor(),
			LucasCandaePyramidTracker(), DEFAULT_MAX_FEATURES,
			std::list<FeatureFilter*>(), cv::Point2f(0, 0));
	_rotationReader = new TangentRotationReader(ShiThomasFeatureExtractor(),
			LucasCandaePyramidTracker(), std::list<FeatureFilter*>());

	_deadZoneWidth = 0;
	_horizonHeight = 0.5;
	_featuresNumber = 100;

}

VisualOdometer::~VisualOdometer() {
	if (NULL != _translationReader) {
		delete _translationReader;
	}
	if (NULL != _rotationReader) {
		delete _rotationReader;
	}

	for (std::list<FeatureFilter*>::iterator it = _filters.begin();
			_filters.end() != it; ++it) {
		if (NULL != *it) {
			delete *it;
		}
	}
}

VisualOdometer::VisualOdometer(const RotationReader &rotationReader,
		const TranslationReader &translationReader,
		const std::list<FeatureFilter*> filters, const int &horizonHeight,
		const int &deadZoneWidth, const int &featuresNumber) :
		_featuresNumber(featuresNumber), _horizonHeight(horizonHeight), _deadZoneWidth(
				deadZoneWidth) {
	_translationReader = translationReader.constructCopy();
	_rotationReader = rotationReader.constructCopy();

	for (std::list<FeatureFilter*>::const_iterator it = filters.begin();
			filters.end() != it; ++it) {
		_filters.push_back(*it);
	}
}

cv::Point3f VisualOdometer::calculateDisplacement(const cv::Mat &newFrame) {
	cv::Point3f result(0, 0, 0);

	double alpha = _rotationReader->readRotation(newFrame);
	result = _translationReader->readTranslation(newFrame, alpha);

	return result;
}
<|endoftext|>


<commit_before>#include "qutil.h"
#include "caoper.h"
#include "session.h"

#include <QApplication>
#include <QStringList>
#include <QFile>
#include <QtXml>
#include <QUrl>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QClipboard>

QUtil::QUtil(QObject *parent) :
    QObject(parent)
{
    m_manager = new QNetworkAccessManager(this);
}

QUtil * QUtil::m_instance = NULL;

void QUtil::SplitJIDCode(QString randstr, QString &qjid, QString &qcode)
{
    QStringList list = randstr.split(QRegExp(":"));
    if (list.count() > 1)
    {
        qjid = list.at(0);
        qcode = list.at(1);
    }else
        return;
}
void QUtil::readFileServerPort(const QString fconf, QString &ip, int &port)
{
    QFile file(fconf);
    if (!file.exists())
        return;
    if (!file.open(QIODevice::ReadOnly))
    {
        file.close();
        return;
    }
    while (!file.atEnd())
    {
        QString sline = file.readLine(128);
        if (sline[0] == QChar('#'))
            continue;
        QStringList ls = sline.split("=",QString::SkipEmptyParts);
        if (ls.count() <= 0)
            continue;

        if (ls[0].indexOf("IP") >= 0)
        {

            ip = ls[1];
            ip = ip.trimmed();
        }else if(ls[0].indexOf("Port") >= 0)
        {
            port = ls[1].toInt();
        }

    }
    file.close();
}
QUtil * QUtil::Instance()
{
    if ( NULL == m_instance )
        m_instance = new QUtil(0);
    return m_instance;
}
yswift_apps* QUtil::getAppsFromXml(QString xml)
{
    QDomDocument    dom;
    QDomElement     elem;
    QFile           file;
    yswift_apps     *apps = new yswift_apps;
    file.setFileName(xml);
    if ( ! file.open(QIODevice::ReadOnly) )
        return NULL;
    QString str_xml = QString::fromLocal8Bit(file.readAll());
    if ( !dom.setContent(str_xml))
    {
        file.close();
        return NULL;
    }
    file.close();
    elem = dom.documentElement();
    elem = elem.firstChildElement("app");
    while (!elem.isNull())
    {
        yswift_app  app;
        QString     version = elem.attribute("version","");
        QString     url = elem.attribute("url","");
        QString     name = elem.attribute("name","");
        QDomElement desc = elem.firstChildElement("desc");
        app.version = version;
        app.url = url;
        app.name = name;
        if (!desc.isNull())
        {
            app.desc = desc.lastChild().nodeValue();
        }

        QDomElement elem_size = elem.firstChildElement("size");
        if ( !elem_size.isNull())
        {
           QString str_size = elem_size.lastChild().nodeValue();
           app.size = str_size.toInt();
        }
        QDomElement elem_author = elem.firstChildElement("author");
        if ( !elem_author.isNull() )
        {
            QString str_author = elem_author.lastChild().nodeValue();
            app.author = str_author;
        }
        apps->append(app);
        elem = elem.nextSiblingElement("app");
    }
    return apps;
}
QString QUtil::createDCode()
{
    QClipboard *board = QApplication::clipboard();
    QString     code = CAOper::getCode();
    QString     toboard = Session::Instance()->getJID() + ":" + code;
    board->setText(toboard);

    return code;
}

QString QUtil::getUpdatePage()
{
    QString ret;
    QFile file("config/update.conf");
    if (!file.exists())
    {
        qDebug()<<"no config file named 'update.conf'";
        return "";
    }
    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"can not open update.conf";
        file.close();
        return "";
    }
    while( !file.atEnd())
    {
        QString line = file.readLine();
        if( line.indexOf("mainpage") < 0)
            continue;
        int pos = line.indexOf("=");
        QString substr = line.right(line.length() - pos-1);
        ret = substr.trimmed();
        break;
    }
    file.close();
    return ret;
}
QString QUtil::size2string(int size)
{
    char c_size[16] = {0};
    float ksize = size / 1024.0f;
    sprintf(c_size,"%.1f K",ksize);
    ksize = ksize / 1024.0f;
    if (ksize > 1)
        sprintf(c_size,"%.1f M",ksize/1024.0f);
    return QString::fromAscii(c_size);
}

void QUtil::sendFile(QString fn,QString to )
{
    /*
    TransProgress *tp = new TransProgress(0);
    tp->setFileName(fn);
    tp->setSendTo(to);
    tp->exec();
    delete tp;
    */
}

QUtil::~QUtil()
{
    if ( m_instance )
        delete m_instance;
    m_instance = NULL;
}
<commit_msg>add timeout<commit_after>#include "qutil.h"
#include "caoper.h"
#include "session.h"

#include <QApplication>
#include <QStringList>
#include <QFile>
#include <QtXml>
#include <QUrl>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QClipboard>

QUtil::QUtil(QObject *parent) :
    QObject(parent)
{
    m_manager = new QNetworkAccessManager(this);
}

QUtil * QUtil::m_instance = NULL;

void QUtil::SplitJIDCode(QString randstr, QString &qjid, QString &qcode)
{
    QStringList list = randstr.split(QRegExp(":"));
    if (list.count() > 1)
    {
        qjid = list.at(0);
        qcode = list.at(1);
    }else
        return;
}
void QUtil::readFileServerPort(const QString fconf, QString &ip, int &port)
{
    QFile file(fconf);
    if (!file.exists())
        return;
    if (!file.open(QIODevice::ReadOnly))
    {
        file.close();
        return;
    }
    while (!file.atEnd())
    {
        QString sline = file.readLine(128);
        if (sline[0] == QChar('#'))
            continue;
        QStringList ls = sline.split("=",QString::SkipEmptyParts);
        if (ls.count() <= 0)
            continue;

        if (ls[0].indexOf("IP") >= 0)
        {

            ip = ls[1];
            ip = ip.trimmed();
        }else if(ls[0].indexOf("Port") >= 0)
        {
            port = ls[1].toInt();
        }

    }
    file.close();
}
QUtil * QUtil::Instance()
{
    if ( NULL == m_instance )
        m_instance = new QUtil(0);
    return m_instance;
}
yswift_apps* QUtil::getAppsFromXml(QString xml)
{
    QDomDocument    dom;
    QDomElement     elem;
    QFile           file;
    yswift_apps     *apps = new yswift_apps;
    file.setFileName(xml);
    if ( ! file.open(QIODevice::ReadOnly) )
        return NULL;
    QString str_xml = QString::fromLocal8Bit(file.readAll());
    if ( !dom.setContent(str_xml))
    {
        file.close();
        return NULL;
    }
    file.close();
    elem = dom.documentElement();
    elem = elem.firstChildElement("app");
    while (!elem.isNull())
    {
        yswift_app  app;
        QString     version = elem.attribute("version","");
        QString     url = elem.attribute("url","");
        QString     name = elem.attribute("name","");
        QDomElement desc = elem.firstChildElement("desc");
        app.version = version;
        app.url = url;
        app.name = name;
        if (!desc.isNull())
        {
            app.desc = desc.lastChild().nodeValue();
        }

        QDomElement elem_size = elem.firstChildElement("size");
        if ( !elem_size.isNull())
        {
           QString str_size = elem_size.lastChild().nodeValue();
           app.size = str_size.toInt();
        }
        QDomElement elem_author = elem.firstChildElement("author");
        if ( !elem_author.isNull() )
        {
            QString str_author = elem_author.lastChild().nodeValue();
            app.author = str_author;
        }
        apps->append(app);
        elem = elem.nextSiblingElement("app");
    }
    return apps;
}
QString QUtil::createDCode()
{
    QClipboard *board = QApplication::clipboard();
    QString     code = CAOper::getCode();
    Session::Instance()->setDCode("app",code);
    QString     toboard = Session::Instance()->getJID() + ":" + code;
    board->setText(toboard);

    return toboard;
}

QString QUtil::getUpdatePage()
{
    QString ret;
    QFile file("config/update.conf");
    if (!file.exists())
    {
        qDebug()<<"no config file named 'update.conf'";
        return "";
    }
    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"can not open update.conf";
        file.close();
        return "";
    }
    while( !file.atEnd())
    {
        QString line = file.readLine();
        if( line.indexOf("mainpage") < 0)
            continue;
        int pos = line.indexOf("=");
        QString substr = line.right(line.length() - pos-1);
        ret = substr.trimmed();
        break;
    }
    file.close();
    return ret;
}
QString QUtil::size2string(int size)
{
    char c_size[16] = {0};
    float ksize = size / 1024.0f;
    sprintf(c_size,"%.1f K",ksize);
    ksize = ksize / 1024.0f;
    if (ksize > 1)
        sprintf(c_size,"%.1f M",ksize/1024.0f);
    return QString::fromAscii(c_size);
}

void QUtil::sendFile(QString fn,QString to )
{
    /*
    TransProgress *tp = new TransProgress(0);
    tp->setFileName(fn);
    tp->setSendTo(to);
    tp->exec();
    delete tp;
    */
}

QUtil::~QUtil()
{
    if ( m_instance )
        delete m_instance;
    m_instance = NULL;
}
<|endoftext|>


<commit_before>#include <string>
#include <vector>

#include "XslValueOf.hpp"

#include "../Xml/XmlDocument.hpp"
#include "../Xml/XmlElement.hpp"
#include "../Xml/XmlNode.hpp"
#include "../Xml/XmlText.hpp"

std::vector<Xml::Node *>
Xsl::ValueOf::operator () (Xml::Element const * context,
    Xml::Document const &, Xml::Element const * xslElement) const
{
    std::vector<Xml::Node *> resultNodes;
    std::string resultText = xslElement->attribute("select");

    resultText = context->valueOf(resultText);
    Xml::Text * textValue = new Xml::Text(resultText);

    resultNodes.push_back(textValue);
    return resultNodes;
}
<commit_msg>Added app_assert<commit_after>#include <string>
#include <vector>

#include "XslValueOf.hpp"

#include "../Xml/XmlDocument.hpp"
#include "../Xml/XmlElement.hpp"
#include "../Xml/XmlNode.hpp"
#include "../Xml/XmlText.hpp"

#include "../AppDebug.hpp"

std::vector<Xml::Node *>
Xsl::ValueOf::operator () (Xml::Element const * context,
    Xml::Document const &, Xml::Element const * xslElement) const
{
    app_assert(context != nullptr);
    app_assert(xslElement != nullptr);

    std::vector<Xml::Node *> resultNodes;
    std::string resultText = xslElement->attribute("select");

    resultText = context->valueOf(resultText);
    Xml::Text * textValue = new Xml::Text(resultText);

    resultNodes.push_back(textValue);
    return resultNodes;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Galaxy Authors. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: wangtaize@baidu.com

#include "agent/workspace.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sstream>
#include <unistd.h>
#include "common/logging.h"
#include "agent/utils.h"
#include <gflags/gflags.h>

DECLARE_string(task_acct);

namespace galaxy {

int DefaultWorkspace::Create() {
    LOG(INFO, "create workspace for task %d", m_task_info.task_id());
    if (m_has_created) {
        return 0;
    }
    //TODO safe path join
    //create work dir
    std::stringstream private_path;
    private_path << "/" << m_root_path;
    int status = 0;
    private_path << "/" << FLAGS_task_acct;
    status = MakePath(private_path.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    m_task_root_path = private_path.str();
    if (0 != status) {
        LOG(WARNING, "create task root path failed %s err[%d: %s]",
                m_task_root_path.c_str(), errno, strerror(errno));
        return status;
    }

    private_path << "/" << m_task_info.task_id();
    status = MakePath(private_path.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

    if (status == 0) {
        m_task_root_path = private_path.str();
        m_has_created = true;
    } else {
        LOG(WARNING, "create task root path failed %s err[%d: %s]",
                m_task_root_path.c_str(), errno, strerror(errno));
        return status;
    }
    private_path.str("");
    private_path << m_task_root_path << "/bin";
    status = symlink("/bin", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/dev";
    status = symlink("/dev", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/lib";
    status = symlink("/lib", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/lib64";
    status = symlink("/lib64", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/proc";
    status = symlink("/proc", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/sbin";
    status = symlink("/sbin", private_path.str().c_str());

    if (0 != status) {
        LOG(WARNING, "create jail symlink failed err[%d: %s]", errno, strerror(errno));
        rmdir(m_task_root_path.c_str());
        return status;
    }

    return status;
}

int DefaultWorkspace::MakePath(const char *path, mode_t mode)
{
    struct stat st;
    memset(&st, 0, sizeof(st));
    int status = 0;
    if (stat(path, &st) != 0) {
        if (mkdir(path, mode) != 0 && errno != EEXIST) {
            status = -1;
        }
    }
    else if (!S_ISDIR(st.st_mode)) {
        errno = ENOTDIR;
        status = -1;
    }
    return status;
}

std::string DefaultWorkspace::GetPath() {
    return m_task_root_path;
}

int DefaultWorkspace::Clean() {
    LOG(INFO,"clean task %d workspace",m_task_info.task_id());
    if (!m_has_created) {
        return 0;
    }
    struct stat st;
    int ret = 0;
    if (stat(m_task_root_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
        if (!file::Remove(m_task_root_path)) {
            LOG(WARNING, "clean task %d workspace %s failed",
                    m_task_info.task_id(),
                    m_task_root_path.c_str());
            ret = -1;
        } else {
            LOG(INFO, "clean task %d success", m_task_info.task_id());
            ret = 0;
        }
    }
    return ret;
}
bool DefaultWorkspace::IsExpire() {
    return false;
}

TaskInfo DefaultWorkspace::GetTaskInfo() {
    return m_task_info;
}

int DefaultWorkspace::MoveTo(const std::string& new_dir) {
    if (access(new_dir.c_str(), F_OK) != 0) {
        LOG(WARNING, "access path %s failed",
                new_dir.c_str());
        return -1;
    }

    std::string time_str;
    GetStrFTime(&time_str);
    std::stringstream ss;
    ss << new_dir << "/" << m_task_info.task_id() << "_" << time_str;
    std::string new_task_root_path = ss.str();
    if (access(new_task_root_path.c_str(), F_OK) == 0) {
        LOG(FATAL, "path %s already exists",
                new_task_root_path.c_str());
        return -1;
    }

    int ret = rename(m_task_root_path.c_str(), new_task_root_path.c_str());
    if (ret == -1) {
        LOG(WARNING, "rename %s failed err[%d: %s]",
                m_task_root_path.c_str(), errno, strerror(errno));
        return -1;
    }
    m_task_root_path = new_task_root_path;
    return 0;
}

}

<commit_msg>Revert "Revert "fix bugs""<commit_after>// Copyright (c) 2015, Galaxy Authors. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: wangtaize@baidu.com

#include "agent/workspace.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sstream>
#include <unistd.h>
#include "common/logging.h"
#include "agent/utils.h"
#include <gflags/gflags.h>

DECLARE_string(task_acct);

namespace galaxy {

int DefaultWorkspace::Create() {
    const int MKDIR_MODE = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
    LOG(INFO, "create workspace for task %d", m_task_info.task_id());
    if (m_has_created) {
        return 0;
    }
    //TODO safe path join
    //create work dir
    std::stringstream private_path;
    private_path << m_root_path;
    int status = 0;
    private_path << "/" << FLAGS_task_acct;
    status = MakePath(private_path.str().c_str(), MKDIR_MODE);
    m_task_root_path = private_path.str();
    if (0 != status) {
        LOG(WARNING, "create task root path failed %s err[%d: %s]",
                m_task_root_path.c_str(), errno, strerror(errno));
        return status;
    }

    private_path << "/" << m_task_info.task_id();
    status = MakePath(private_path.str().c_str(), MKDIR_MODE);

    if (status == 0) {
        m_task_root_path = private_path.str();
        m_has_created = true;
    } else {
        LOG(WARNING, "create task root path failed %s err[%d: %s]",
                m_task_root_path.c_str(), errno, strerror(errno));
        return status;
    }
    private_path.str("");
    private_path << m_task_root_path << "/bin";
    status = symlink("/bin", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/dev";
    status = symlink("/dev", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/lib";
    status = symlink("/lib", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/lib64";
    status = symlink("/lib64", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/proc";
    status = symlink("/proc", private_path.str().c_str());
    private_path.str("");
    private_path << m_task_root_path << "/sbin";
    status = symlink("/sbin", private_path.str().c_str());

    if (0 != status) {
        LOG(WARNING, "create jail symlink failed err[%d: %s]", errno, strerror(errno));
        rmdir(m_task_root_path.c_str());
        return status;
    }

    return status;
}

int DefaultWorkspace::MakePath(const char *path, mode_t mode)
{
    struct stat st;
    memset(&st, 0, sizeof(st));
    int status = 0;
    if (stat(path, &st) != 0) {
        if (mkdir(path, mode) != 0 && errno != EEXIST) {
            status = -1;
        }
    }
    else if (!S_ISDIR(st.st_mode)) {
        errno = ENOTDIR;
        status = -1;
    }
    return status;
}

std::string DefaultWorkspace::GetPath() {
    return m_task_root_path;
}

int DefaultWorkspace::Clean() {
    LOG(INFO,"clean task %d workspace",m_task_info.task_id());
    if (!m_has_created) {
        return 0;
    }
    struct stat st;
    int ret = 0;
    if (stat(m_task_root_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
        if (!file::Remove(m_task_root_path)) {
            LOG(WARNING, "clean task %d workspace %s failed",
                    m_task_info.task_id(),
                    m_task_root_path.c_str());
            ret = -1;
        } else {
            LOG(INFO, "clean task %d success", m_task_info.task_id());
            ret = 0;
        }
    }
    return ret;
}
bool DefaultWorkspace::IsExpire() {
    return false;
}

TaskInfo DefaultWorkspace::GetTaskInfo() {
    return m_task_info;
}

int DefaultWorkspace::MoveTo(const std::string& new_dir) {
    if (access(new_dir.c_str(), F_OK) != 0) {
        LOG(WARNING, "access path %s failed",
                new_dir.c_str());
        return -1;
    }

    std::string time_str;
    GetStrFTime(&time_str);
    std::stringstream ss;
    ss << new_dir << "/" << m_task_info.task_id() << "_" << time_str;
    std::string new_task_root_path = ss.str();
    if (access(new_task_root_path.c_str(), F_OK) == 0) {
        LOG(FATAL, "path %s already exists",
                new_task_root_path.c_str());
        return -1;
    }

    int ret = rename(m_task_root_path.c_str(), new_task_root_path.c_str());
    if (ret == -1) {
        LOG(WARNING, "rename %s failed err[%d: %s]",
                m_task_root_path.c_str(), errno, strerror(errno));
        return -1;
    }
    m_task_root_path = new_task_root_path;
    return 0;
}

}

<|endoftext|>


<commit_before>/**
 * @file property.hpp
 * @author Robin Dietrich <me (at) invokr (dot) org>
 * @version 1.1
 *
 * @par License
 *    Alice Replay Parser
 *    Copyright 2014 Robin Dietrich
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *
 */

#ifndef _DOTA_PROPERTY_HPP_
#define _DOTA_PROPERTY_HPP_

#include <array>
#include <memory>
#include <utility>
#include <string>
#include <type_traits>

#include <boost/variant.hpp>

#include <alice/exception.hpp>
#include <alice/sendprop.hpp>

/// Specifies the maximum length of a string
#define PROPERTY_MAX_STRING_LENGTH 0x200

/// Specifies the maximum elements an array property can hold
#define PROPERTY_MAX_ELEMENTS 100

namespace dota {
    /// @defgroup EXCEPTIONS Exceptions
    /// @{

    /// Thrown when the property seems to have an unkown type
    CREATE_EXCEPTION( propertyInvalidType, "Property has unkown / invalid type." )
    /// Thrown when the type of float serialized cannot be read
    CREATE_EXCEPTION( propertyInvalidFloatCoord, "Type of float coord is not implemented" )
    /// Thrown when the string length exceeds #PROPERTY_MAX_STRING_LENGTH
    CREATE_EXCEPTION( propertyInvalidStringLength, "Trying to read large string" )
    /// Thrown when the type of int serialized cannot be read
    CREATE_EXCEPTION( propertyInvalidInt64Type, "Type of int64 is not implemented" )
    /// Thrown when the number of array elements exceeds #PROPERTY_MAX_ELEMENTS
    CREATE_EXCEPTION( propertyInvalidNumberOfElements, "Unnaturaly large number of elements" )

    /// @}

    // forward declaration
    class bitstream;

    /// @defgroup CORE Core
    /// @{

    class property;

    /** Underlying type for an IntProperty */
    typedef int32_t IntProperty;

    /** Underlying type for an UIntProperty */
    typedef uint32_t UIntProperty;

    /** Underlying type for a FloatProperty */
    typedef float FloatProperty;

    /** Underlying type for a Vector Property */
    typedef std::array<float, 3> VectorProperty;

    /** Underlying type for a VectorXY Property */
    typedef std::array<float, 2> VectorXYProperty;

    /** Underlying type for a String Property */
    typedef std::string StringProperty;

    /** Underlying type for an Array Property */
    typedef std::vector<property> ArrayProperty;

    /** Underlying type for a 64 bit Int Property */
    typedef int64_t Int64Property;

    /** Underlying type for a 64 bit Int Property */
    typedef uint64_t UInt64Property;

    namespace detail {
        template <typename T>
        inline std::string to_string_helper(const T& t, std::true_type) {
            return std::to_string(t);
        }

        template <typename T>
        inline std::string to_string_helper(const T& t, std::false_type) {
            return "unkown";
        }

        /** Helper converting a type T into a string */
        template <typename T>
        inline std::string to_string(const T& t) {
            return to_string_helper(t, std::is_arithmetic<T>{});
        }

        template <>
        inline std::string to_string(const std::array<float, 3>& t) {
            std::stringstream s("");
            s << "[" << t[0] << "|" << t[1] << "|" << t[2] << "]";
            return s.str();
        }

        template <>
        inline std::string to_string(const std::array<float, 2>& t) {
            std::stringstream s("");
            s << "[" << t[0] << "|" << t[1] << "]";
            return s.str();
        }

        template <>
        inline std::string to_string(const std::string& t) {
            return t;
        }

        template <>
        inline std::string to_string(const std::vector<property>& t) {
            return "Vector Unimplemented";
        }

        /** Visitor to call to_string on a Boost.Variant. */
        class propertyToString : public boost::static_visitor<> {
            private:
                /** String to fill */
                std::string &toFill;
            public:
                /** Sets internal string as a reference to r */
                propertyToString(std::string &r) : toFill(r) {}

                /** Invoking this does the actual string conversion */
                template <typename T>
                void operator()(const T& t) const {
                    toFill = to_string(t);
                }
        };
    }

    /**
     * This is the actual property, consisting of it's data and definition.
     *
     * Properties are not created on their own but are part of an entity which can contain an
     * unlimited number of these. These are very likely directly tied to a class in the Source Engine,
     * so that they can be automatically updated once new data arrives on the wire.
     *
     * Instead of implementing this, the property class is a more general approach. It can currently hold
     * all different possible values that are send and provides some convinience functions to get to the
     * data.
     */
    class property {
        public:
            /** Type for the underlying definition */
            typedef sendprop::type type_t;
            /** Type for the variant used internally */
            typedef boost::variant<
                IntProperty,        // T_Int
                UIntProperty,       // T_Int & SPROP_UNSIGNED
                FloatProperty,      // T_Float
                VectorProperty,     // T_Vector
                VectorXYProperty,   // T_VectorXY
                StringProperty,     // T_String
                ArrayProperty,      // T_Array
                Int64Property,      // T_Int64
                UInt64Property      // T_Int64 & SPROP_UNSIGNED
            > value_type;

            /** Empty constructor */
            property() : init(false) {}

            /** Returns whether this property has been initialized */
            bool isInitialized() {
                return init;
            }

            /** Returns the type of this property */
            inline const type_t& getType() const {
                return type;
            }

            /** Returns value as type T, throws if conversion fails */
            template <typename T>
            const T& as() {
                return boost::get<T>(value);
            }

            /** Sets value as type T with data provided */
            template <typename T>
            void set(T data) {
                value = std::move(data);
            }

            /** Returns name of this property based on it's sendprop */
            std::string getName() {
                return prop->getNetname() + "." + prop->getName();
            }

            /** Return value as string */
            std::string asString() {
                // this has gotten a bit ugly using variant, but as this function should only be used to debug
                // it's probably fine

                std::string ret;
                detail::propertyToString v(ret);
                boost::apply_visitor( v, value );

                return ret;
            }

            /** Returns definition for this property */
            sendprop* getSendprop() {
                return prop;
            }

            /** Updates this property from a bitstream */
            void update(bitstream& stream);

            /** Creates property from bitstream and corresponding sendprop definition */
            static property create(bitstream& stream, sendprop* prop);

            /** Skips property contents in the bitstream */
            static void skip(bitstream& stream, sendprop* prop);
        protected:
            /** Type for this paticular property */
            type_t type;
            /** Value for this property */
            value_type value;
            /** Sendprop definition for the type */
            sendprop* prop;
            /** Whether this property has been initialized */
            bool init;

            /** Private constructor, we only want our create function to instantize new properties */
            property(sendprop* p) : type(p->getType()), prop(p) {

            }
    };

    /// @}
}

#endif /* _DOTA_PROPERTY_HPP_ */<commit_msg>Better exception for invalid property casts<commit_after>/**
 * @file property.hpp
 * @author Robin Dietrich <me (at) invokr (dot) org>
 * @version 1.1
 *
 * @par License
 *    Alice Replay Parser
 *    Copyright 2014 Robin Dietrich
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *
 */

#ifndef _DOTA_PROPERTY_HPP_
#define _DOTA_PROPERTY_HPP_

#include <array>
#include <memory>
#include <utility>
#include <string>
#include <type_traits>

#include <boost/variant.hpp>

#include <alice/exception.hpp>
#include <alice/sendprop.hpp>

/// Specifies the maximum length of a string
#define PROPERTY_MAX_STRING_LENGTH 0x200

/// Specifies the maximum elements an array property can hold
#define PROPERTY_MAX_ELEMENTS 100

namespace dota {
    /// @defgroup EXCEPTIONS Exceptions
    /// @{

    /// Thrown when the property seems to have an unkown type
    CREATE_EXCEPTION( propertyInvalidType, "Property has unkown / invalid type." )
    /// Thrown when the type of float serialized cannot be read
    CREATE_EXCEPTION( propertyInvalidFloatCoord, "Type of float coord is not implemented" )
    /// Thrown when the string length exceeds #PROPERTY_MAX_STRING_LENGTH
    CREATE_EXCEPTION( propertyInvalidStringLength, "Trying to read large string" )
    /// Thrown when the type of int serialized cannot be read
    CREATE_EXCEPTION( propertyInvalidInt64Type, "Type of int64 is not implemented" )
    /// Thrown when the number of array elements exceeds #PROPERTY_MAX_ELEMENTS
    CREATE_EXCEPTION( propertyInvalidNumberOfElements, "Unnaturaly large number of elements" )
    /// Thrown when trying to access property as invalid Type
    CREATE_EXCEPTION( propertyBadCast, "Property requested as wrong type" )

    /// @}

    // forward declaration
    class bitstream;

    /// @defgroup CORE Core
    /// @{

    class property;

    /** Underlying type for an IntProperty */
    typedef int32_t IntProperty;

    /** Underlying type for an UIntProperty */
    typedef uint32_t UIntProperty;

    /** Underlying type for a FloatProperty */
    typedef float FloatProperty;

    /** Underlying type for a Vector Property */
    typedef std::array<float, 3> VectorProperty;

    /** Underlying type for a VectorXY Property */
    typedef std::array<float, 2> VectorXYProperty;

    /** Underlying type for a String Property */
    typedef std::string StringProperty;

    /** Underlying type for an Array Property */
    typedef std::vector<property> ArrayProperty;

    /** Underlying type for a 64 bit Int Property */
    typedef int64_t Int64Property;

    /** Underlying type for a 64 bit Int Property */
    typedef uint64_t UInt64Property;

    namespace detail {
        template <typename T>
        inline std::string to_string_helper(const T& t, std::true_type) {
            return std::to_string(t);
        }

        template <typename T>
        inline std::string to_string_helper(const T& t, std::false_type) {
            return "unkown";
        }

        /** Helper converting a type T into a string */
        template <typename T>
        inline std::string to_string(const T& t) {
            return to_string_helper(t, std::is_arithmetic<T>{});
        }

        template <>
        inline std::string to_string(const std::array<float, 3>& t) {
            std::stringstream s("");
            s << "[" << t[0] << "|" << t[1] << "|" << t[2] << "]";
            return s.str();
        }

        template <>
        inline std::string to_string(const std::array<float, 2>& t) {
            std::stringstream s("");
            s << "[" << t[0] << "|" << t[1] << "]";
            return s.str();
        }

        template <>
        inline std::string to_string(const std::string& t) {
            return t;
        }

        template <>
        inline std::string to_string(const std::vector<property>& t) {
            return "Vector Unimplemented";
        }

        /** Visitor to call to_string on a Boost.Variant. */
        class propertyToString : public boost::static_visitor<> {
            private:
                /** String to fill */
                std::string &toFill;
            public:
                /** Sets internal string as a reference to r */
                propertyToString(std::string &r) : toFill(r) {}

                /** Invoking this does the actual string conversion */
                template <typename T>
                void operator()(const T& t) const {
                    toFill = to_string(t);
                }
        };
    }

    /**
     * This is the actual property, consisting of it's data and definition.
     *
     * Properties are not created on their own but are part of an entity which can contain an
     * unlimited number of these. These are very likely directly tied to a class in the Source Engine,
     * so that they can be automatically updated once new data arrives on the wire.
     *
     * Instead of implementing this, the property class is a more general approach. It can currently hold
     * all different possible values that are send and provides some convinience functions to get to the
     * data.
     */
    class property {
        public:
            /** Type for the underlying definition */
            typedef sendprop::type type_t;
            /** Type for the variant used internally */
            typedef boost::variant<
                IntProperty,        // T_Int
                UIntProperty,       // T_Int & SPROP_UNSIGNED
                FloatProperty,      // T_Float
                VectorProperty,     // T_Vector
                VectorXYProperty,   // T_VectorXY
                StringProperty,     // T_String
                ArrayProperty,      // T_Array
                Int64Property,      // T_Int64
                UInt64Property      // T_Int64 & SPROP_UNSIGNED
            > value_type;

            /** Empty constructor */
            property() : init(false) {}

            /** Returns whether this property has been initialized */
            bool isInitialized() {
                return init;
            }

            /** Returns the type of this property */
            inline const type_t& getType() const {
                return type;
            }

            /** Returns value as type T, throws if conversion fails */
            template <typename T>
            const T& as() {
                try {
                    return boost::get<T>(value);
                } catch (boost::bad_get &e) {
                    BOOST_THROW_EXCEPTION( propertyBadCast()
                        << EArg<1>::info(getName())
                    );
                }
            }

            /** Sets value as type T with data provided */
            template <typename T>
            void set(T data) {
                value = std::move(data);
            }

            /** Returns name of this property based on it's sendprop */
            std::string getName() {
                return prop->getNetname() + "." + prop->getName();
            }

            /** Return value as string */
            std::string asString() {
                // this has gotten a bit ugly using variant, but as this function should only be used to debug
                // it's probably fine

                std::string ret;
                detail::propertyToString v(ret);
                boost::apply_visitor( v, value );

                return ret;
            }

            /** Returns definition for this property */
            sendprop* getSendprop() {
                return prop;
            }

            /** Updates this property from a bitstream */
            void update(bitstream& stream);

            /** Creates property from bitstream and corresponding sendprop definition */
            static property create(bitstream& stream, sendprop* prop);

            /** Skips property contents in the bitstream */
            static void skip(bitstream& stream, sendprop* prop);
        protected:
            /** Type for this paticular property */
            type_t type;
            /** Value for this property */
            value_type value;
            /** Sendprop definition for the type */
            sendprop* prop;
            /** Whether this property has been initialized */
            bool init;

            /** Private constructor, we only want our create function to instantize new properties */
            property(sendprop* p) : type(p->getType()), prop(p) {

            }
    };

    /// @}
}

#endif /* _DOTA_PROPERTY_HPP_ */<|endoftext|>


<commit_before>#include "ast.h"

void ExternASTNode::inject(NodeTraverser &functor) const { functor.apply(*this); }
void DefnASTNode::inject(NodeTraverser &functor) const { functor.apply(*this); }
void VariableASTExpr::inject(ExprTraverser &functor) const { functor.apply(*this); }
void LiteralDoubleASTExpr::inject(ExprTraverser &functor) const { functor.apply(*this); }
void BinOpASTExpr::inject(ExprTraverser &functor) const { functor.apply(*this); }
void CallASTExpr::inject(ExprTraverser &functor) const { functor.apply(*this); }
<commit_msg>renaming methods<commit_after>#include "ast.h"

void ExternASTNode::inject(NodeTraverser &traverser) const { traverser.apply_to(*this); }
void DefnASTNode::inject(NodeTraverser &traverser) const { traverser.apply_to(*this); }
void VariableASTExpr::inject(ExprTraverser &traverser) const { traverser.apply_to(*this); }
void LiteralDoubleASTExpr::inject(ExprTraverser &traverser) const { traverser.apply_to(*this); }
void BinOpASTExpr::inject(ExprTraverser &traverser) const { traverser.apply_to(*this); }
void CallASTExpr::inject(ExprTraverser &traverser) const { traverser.apply_to(*this); }
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <string.h>
#include <cstdlib>
#include <fstream>

#include "../UCT.h"
#include "../Common.h"

//UCTNode *currentMove;
int boardSize = 9;
float millaSecondsToThink = 14000;
char name[] = "TestGoBot";
char version[] = "3.5.11";

Board* b = NULL;

void switchTurnTo(Player color) {
  if (b->turn == color) {
    return;
  } else {
    // Pass
    b->makeMove(Point(boardSize, boardSize));
  }
}

Player readColor() {
  char colorStr[10];
  std::cin >> colorStr;
  if (!strcmp(colorStr, "w")) {
    return White;
  } else if (!strcmp(colorStr, "b")) {
    return Black;
  } else {
    printf("? Unknown Player color\n");
    return Empty;
  }
}

void doPlay() {
  Player color = readColor();
  if (color == Empty)
    return;

  char moveStr[10];
  std::cin >> moveStr;
  int row = boardSize, column = boardSize;
  if (strcmp(moveStr, "pass")) {
    row = moveStr[0] - 'a';
    if (moveStr[0] >= 'i') {
      row--;
    }
    column = atoi(moveStr+1)-1;
  }

  switchTurnTo(color);
  b->makeMove(Point(row, column));
  printf("=\n\n");

  char buffer[100];
  sprintf(buffer, "Play %d at %d %d", color, row, column);
  Log(buffer);
}

void doGenMove() {
  Player color = readColor();
  if (color == Empty)
    return;

  switchTurnTo(color);

  UCTNode* currentMove = new UCTNode(Point(-1, -1), NULL);
  currentMove->state = b->clone();
  Point bestMove = UCTSearch(currentMove, millaSecondsToThink)->move;
  delete currentMove;

  b->makeMove(bestMove);

  char rowChar = (char)(bestMove.row+'a');
  if (bestMove.row > 7)
    rowChar++;
  if (bestMove == *b->pass)
    printf("= pass\n\n");
  else
    printf("= %c%d\n\n", rowChar, bestMove.column+1);

  char buffer[100];
  sprintf(buffer, "GenMove %d %d", bestMove.row, bestMove.column);
  Log(buffer);
}

void doBoardSize() {
  std::cin >> boardSize;
  delete b;
  b = new Board(boardSize);
  b->init();

  printf("= \n\n");
}

int main() {
  b = new Board(boardSize);
  b->init();
  //currentMove = new UCTNode(Point(-1, -1), b, NULL);

  while (true) {
    char command[128];
    std::cin >> command;

    Log(command);

    if (!strcmp(command, "boardsize")) {
      doBoardSize();
    } else if (!strcmp(command, "clear_board")) {
      delete b;
      b = new Board(boardSize);
      b->init();
      printf("= \n\n");
    } else if (!strcmp(command, "exit")) {
      exit(0);
    } else if (!strcmp(command, "genmove")) {
      doGenMove();
    } else if (!strcmp(command, "komi")) {
      float throwaway;
      std::cin >> throwaway;
      printf("= \n\n");
    } else if (!strcmp(command, "list_commands")) {
      printf("= boardsize\n");
      printf("clear_board\n");
      printf("genmove\n");
      printf("komi\n");
      printf("list_commands\n");
      printf("name\n");
      printf("play\n");
      printf("quit\n");
      printf("time_left\n");
      printf("version\n");
      printf("\n");
    } else if (!strcmp(command, "name")) {
      printf("= %s\n\n", name);
    } else if (!strcmp(command, "play")) {
      doPlay();
    } else if (!strcmp(command, "quit")) {
      printf("= \n\n");
    } else if (!strcmp(command, "special")) {
      printf("%d\n", b->isSuicide(Point(4,1)));
      printf("%d %d\n", b->koPoint->row, b->koPoint->column);
    } else if (!strcmp(command, "show_board")) {
      b->show();
      printf("\n\n");
    } else if (!strcmp(command, "show_moves")) {
      b->getPossibleMoves();
      for(Point *p : b->possibleMoves)
        printf("%d%d ", p->row, p->column);
      printf("\n\n");
    } else if (!strcmp(command, "time_left")) {
      char throwawayColor[10];
      std::cin >> throwawayColor;

      int throwawayFirstNumber;
      std::cin >> throwawayFirstNumber;

      int throwawaySecondNumber;
      std::cin >> throwawaySecondNumber;

      printf("= \n\n");
    } else if (!strcmp(command, "version")) {
      printf("= %s\n\n", version);
    } else {
      printf("? unknown command \n\n");
      Log("? unknown command");
      Log("command");
    }
  }

}
<commit_msg>Changed the KGS application to wait to delete UCTNodes and make the chosen move until after notifying the server<commit_after>#include <iostream>
#include <cstdio>
#include <string.h>
#include <cstdlib>
#include <fstream>

#include "../UCT.h"
#include "../Common.h"

//UCTNode *currentMove;
int boardSize = 9;
float millaSecondsToThink = 14000;
char name[] = "TestGoBot";
char version[] = "3.5.11";

Board* b = NULL;

void switchTurnTo(Player color) {
  if (b->turn == color) {
    return;
  } else {
    // Pass
    b->makeMove(Point(boardSize, boardSize));
  }
}

Player readColor() {
  char colorStr[10];
  std::cin >> colorStr;
  if (!strcmp(colorStr, "w")) {
    return White;
  } else if (!strcmp(colorStr, "b")) {
    return Black;
  } else {
    printf("? Unknown Player color\n");
    return Empty;
  }
}

void doPlay() {
  Player color = readColor();
  if (color == Empty)
    return;

  char moveStr[10];
  std::cin >> moveStr;
  int row = boardSize, column = boardSize;
  if (strcmp(moveStr, "pass")) {
    row = moveStr[0] - 'a';
    if (moveStr[0] >= 'i') {
      row--;
    }
    column = atoi(moveStr+1)-1;
  }

  switchTurnTo(color);
  b->makeMove(Point(row, column));
  printf("=\n\n");

  char buffer[100];
  sprintf(buffer, "Play %d at %d %d", color, row, column);
  Log(buffer);
}

void doGenMove() {
  Player color = readColor();
  if (color == Empty)
    return;

  switchTurnTo(color);

  UCTNode* currentMove = new UCTNode(Point(-1, -1), NULL);
  currentMove->state = b->clone();
  Point bestMove = UCTSearch(currentMove, millaSecondsToThink)->move;

  char rowChar = (char)(bestMove.row+'a');
  if (bestMove.row > 7)
    rowChar++;
  if (bestMove == *b->pass)
    printf("= pass\n\n");
  else
    printf("= %c%d\n\n", rowChar, bestMove.column+1);

  char buffer[100];
  sprintf(buffer, "GenMove %d %d", bestMove.row, bestMove.column);
  Log(buffer);

  // Takes a long time, print out message to send to server first
  delete currentMove;

  b->makeMove(bestMove);
}

void doBoardSize() {
  std::cin >> boardSize;
  delete b;
  b = new Board(boardSize);
  b->init();

  printf("= \n\n");
}

int main() {
  b = new Board(boardSize);
  b->init();
  //currentMove = new UCTNode(Point(-1, -1), b, NULL);

  while (true) {
    char command[128];
    std::cin >> command;

    Log(command);

    if (!strcmp(command, "boardsize")) {
      doBoardSize();
    } else if (!strcmp(command, "clear_board")) {
      delete b;
      b = new Board(boardSize);
      b->init();
      printf("= \n\n");
    } else if (!strcmp(command, "exit")) {
      exit(0);
    } else if (!strcmp(command, "genmove")) {
      doGenMove();
    } else if (!strcmp(command, "komi")) {
      float throwaway;
      std::cin >> throwaway;
      printf("= \n\n");
    } else if (!strcmp(command, "list_commands")) {
      printf("= boardsize\n");
      printf("clear_board\n");
      printf("genmove\n");
      printf("komi\n");
      printf("list_commands\n");
      printf("name\n");
      printf("play\n");
      printf("quit\n");
      printf("time_left\n");
      printf("version\n");
      printf("\n");
    } else if (!strcmp(command, "name")) {
      printf("= %s\n\n", name);
    } else if (!strcmp(command, "play")) {
      doPlay();
    } else if (!strcmp(command, "quit")) {
      printf("= \n\n");
    } else if (!strcmp(command, "special")) {
      printf("%d\n", b->isSuicide(Point(4,1)));
      printf("%d %d\n", b->koPoint->row, b->koPoint->column);
    } else if (!strcmp(command, "show_board")) {
      b->show();
      printf("\n\n");
    } else if (!strcmp(command, "show_moves")) {
      b->getPossibleMoves();
      for (int i = 0; i < b->numLegalMoves; i++)
        printf("%d%d ", b->legalMoves[i]->row, b->legalMoves[i]->column);
      printf("\n\n");
    } else if (!strcmp(command, "time_left")) {
      char throwawayColor[10];
      std::cin >> throwawayColor;

      int throwawayFirstNumber;
      std::cin >> throwawayFirstNumber;

      int throwawaySecondNumber;
      std::cin >> throwawaySecondNumber;

      printf("= \n\n");
    } else if (!strcmp(command, "version")) {
      printf("= %s\n\n", version);
    } else {
      printf("? unknown command \n\n");
      Log("? unknown command");
      Log("command");
    }
  }

}
<|endoftext|>