<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: map.cpp 17 2005-03-08 23:58:43Z pavlenko $,

#include <mapnik/style.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/filter_featureset.hpp>
#include <mapnik/hit_test_filter.hpp>
#include <mapnik/map.hpp>

namespace mapnik
{
    Map::Map()
        : width_(400),
          height_(400),
          srs_("+proj=latlong +datum=WGS84") {}

    Map::Map(int width,int height, std::string const& srs)
        : width_(width),
          height_(height),
          srs_(srs),
          background_(Color(255,255,255)) {}

    Map::Map(const Map& rhs)
        : width_(rhs.width_),
          height_(rhs.height_),
          srs_(rhs.srs_),
          background_(rhs.background_),
          styles_(rhs.styles_),
          layers_(rhs.layers_),
          currentExtent_(rhs.currentExtent_) {}

    Map& Map::operator=(const Map& rhs)
    {
        if (this==&rhs) return *this;
        width_=rhs.width_;
        height_=rhs.height_;
        srs_=rhs.srs_;
        background_=rhs.background_;
        styles_=rhs.styles_;
        layers_=rhs.layers_;
        return *this;
    }

    Map::style_iterator Map::begin_styles()
    {
        return styles_.begin();
    }

    Map::style_iterator Map::end_styles()
    {
        return styles_.end();
    }

    Map::const_style_iterator  Map::begin_styles() const
    {
        return styles_.begin();
    }

    Map::const_style_iterator  Map::end_styles() const
    {
        return styles_.end();
    }

    bool Map::insert_style(std::string const& name,feature_type_style const& style)
    {
        return styles_.insert(make_pair(name,style)).second;
    }

    void Map::remove_style(std::string const& name)
    {
        styles_.erase(name);
    }

    feature_type_style const& Map::find_style(std::string const& name) const
    {
        std::map<std::string,feature_type_style>::const_iterator itr = styles_.find(name);
        if (itr!=styles_.end())
            return itr->second;
        static feature_type_style default_style;
        return default_style;
    }

    size_t Map::layerCount() const
    {
        return layers_.size();
    }

    void Map::addLayer(const Layer& l)
    {
        layers_.push_back(l);
    }
    void Map::removeLayer(size_t index)
    {
        layers_.erase(layers_.begin()+index);
    }

    void Map::remove_all()
    {
        layers_.clear();
        styles_.clear();
    }

    const Layer& Map::getLayer(size_t index) const
    {
        return layers_[index];
    }

    Layer& Map::getLayer(size_t index)
    {
        return layers_[index];
    }

    std::vector<Layer> const& Map::layers() const
    {
        return layers_;
    }

    std::vector<Layer> & Map::layers()
    {
        return layers_;
    }

    unsigned Map::getWidth() const
    {
        return width_;
    }

    unsigned Map::getHeight() const
    {
        return height_;
    }

    void Map::setWidth(unsigned width)
    {
        if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE)
        {
            width_=width;
            fixAspectRatio();
        }
    }

    void Map::setHeight(unsigned height)
    {
        if (height >= MIN_MAPSIZE && height <= MAX_MAPSIZE)
        {
            height_=height;
            fixAspectRatio();
        }
    }

    void Map::resize(unsigned width,unsigned height)
    {
        if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE &&
            height >= MIN_MAPSIZE && height <= MAX_MAPSIZE)
        {
            width_=width;
            height_=height;
            fixAspectRatio();
        }
    }

    std::string const&  Map::srs() const
    {
        return srs_;
    }

    void Map::set_srs(std::string const& srs)
    {
        srs_ = srs;
    }

    void Map::setBackground(const Color& c)
    {
        background_=c;
    }

    const Color& Map::getBackground() const
    {
        return background_;
    }

    void Map::zoom(double factor)
    {
        coord2d center = currentExtent_.center();
        double w = factor * currentExtent_.width();
        double h = factor * currentExtent_.height();
        currentExtent_ = Envelope<double>(center.x - 0.5 * w,
                                          center.y - 0.5 * h,
                                          center.x + 0.5 * w,
                                          center.y + 0.5 * h);
        fixAspectRatio();
    }

    void Map::zoom_all()
    {
        try
        {
            projection proj0(srs_);
            Envelope<double> ext;
            bool first = true;
            std::vector<Layer>::const_iterator itr = layers_.begin();
            std::vector<Layer>::const_iterator end = layers_.end();
            while (itr != end)
            {
                std::string const& layer_srs = itr->srs();
                projection proj1(layer_srs);
                proj_transform prj_trans(proj0,proj1);

                Envelope<double> layerExt = itr->envelope();
                double x0 = layerExt.minx();
                double y0 = layerExt.miny();
                double z0 = 0.0;
                double x1 = layerExt.maxx();
                double y1 = layerExt.maxy();
                double z1 = 0.0;
                prj_trans.backward(x0,y0,z0);
                prj_trans.backward(x1,y1,z1);

                Envelope<double> layerExt2(x0,y0,x1,y1);
#ifdef MAPNIK_DEBUG
                std::clog << " layer1 - > " << layerExt << "\n";
                std::clog << " layer2 - > " << layerExt2 << "\n";
#endif
                if (first)
                {
                    ext = layerExt2;
                    first = false;
                }
                else
                {
                    ext.expand_to_include(layerExt2);
                }
                ++itr;
            }
            zoomToBox(ext);
        }
        catch (proj_init_error & ex)
        {
            std::clog << ex.what() << '\n';
        }
    }

    void Map::zoomToBox(const Envelope<double> &box)
    {
        currentExtent_=box;
        fixAspectRatio();
    }

    void Map::fixAspectRatio()
    {
        double ratio1 = (double) width_ / (double) height_;
        double ratio2 = currentExtent_.width() / currentExtent_.height();

        if (ratio2 > ratio1)
        {
            currentExtent_.height(currentExtent_.width() / ratio1);
        }
        else if (ratio2 < ratio1)
        {
            currentExtent_.width(currentExtent_.height() * ratio1);
        }
    }

    const Envelope<double>& Map::getCurrentExtent() const
    {
        return currentExtent_;
    }

    void Map::pan(int x,int y)
    {
        int dx = x - int(0.5 * width_);
        int dy = int(0.5 * height_) - y;
        double s = width_/currentExtent_.width();
        double minx  = currentExtent_.minx() + dx/s;
        double maxx  = currentExtent_.maxx() + dx/s;
        double miny  = currentExtent_.miny() + dy/s;
        double maxy  = currentExtent_.maxy() + dy/s;
        currentExtent_.init(minx,miny,maxx,maxy);
    }

    void Map::pan_and_zoom(int x,int y,double factor)
    {
        pan(x,y);
        zoom(factor);
    }

    double Map::scale() const
    {
        if (width_>0)
            return currentExtent_.width()/width_;
        return currentExtent_.width();
    }

    CoordTransform Map::view_transform() const
    {
        return CoordTransform(width_,height_,currentExtent_);
    }

    featureset_ptr Map::query_point(unsigned index, double lat, double lon) const
    {
        if ( index< layers_.size())
        {
            mapnik::Layer const& layer = layers_[index];
            try
            {
                double x = lon;
                double y = lat;
                double z = 0;
                mapnik::projection dest(srs_);
                dest.forward(x,y);
                mapnik::projection source(layer.srs());
                proj_transform prj_trans(source,dest);
                prj_trans.backward(x,y,z);

                double minx = currentExtent_.minx();
                double miny = currentExtent_.miny();
                double maxx = currentExtent_.maxx();
                double maxy = currentExtent_.maxy();

                prj_trans.backward(minx,miny,z);
                prj_trans.backward(maxx,maxy,z);
                double tol = (maxx - minx) / width_ * 3;
                mapnik::datasource_ptr ds = layer.datasource();
                if (ds)
                {
#ifdef MAPNIK_DEBUG
                    std::clog << " query at point tol = " << tol << " (" << x << "," << y << ")\n";
#endif
                    featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y));
                    if (fs)
                        return featureset_ptr(new filter_featureset<hit_test_filter>(fs,hit_test_filter(x,y,tol)));
                }
            }
            catch (...)
            {
#ifdef MAPNIK_DEBUG
                std::clog << "exception caught in \"query_map_point\"\n";
#endif
            }
        }
        return featureset_ptr();
    }

    featureset_ptr Map::query_map_point(unsigned index, double x, double y) const
    {
        if ( index< layers_.size())
        {
            mapnik::Layer const& layer = layers_[index];
            CoordTransform tr = view_transform();
            tr.backward(&x,&y);

            try
            {
                mapnik::projection dest(srs_);
                mapnik::projection source(layer.srs());
                proj_transform prj_trans(source,dest);
                double z = 0;
                prj_trans.backward(x,y,z);

                double minx = currentExtent_.minx();
                double miny = currentExtent_.miny();
                double maxx = currentExtent_.maxx();
                double maxy = currentExtent_.maxy();

                prj_trans.backward(minx,miny,z);
                prj_trans.backward(maxx,maxy,z);
                double tol = (maxx - minx) / width_ * 3;
                mapnik::datasource_ptr ds = layer.datasource();
                if (ds)
                {
#ifdef MAPNIK_DEBUG
                    std::clog << " query at point tol = " << tol << " (" << x << "," << y << ")\n";
#endif
                    featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y));
                    if (fs)
                        return featureset_ptr(new filter_featureset<hit_test_filter>(fs,hit_test_filter(x,y,tol)));
                }
            }
            catch (...)
            {
#ifdef MAPNIK_DEBUG
                std::clog << "exception caught in \"query_map_point\"\n";
#endif
            }
        }
        return featureset_ptr();
    }

    Map::~Map() {}
}
<commit_msg>don't project query point if host projection is geographic<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: map.cpp 17 2005-03-08 23:58:43Z pavlenko $,

#include <mapnik/style.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/filter_featureset.hpp>
#include <mapnik/hit_test_filter.hpp>
#include <mapnik/map.hpp>

namespace mapnik
{
    Map::Map()
        : width_(400),
          height_(400),
          srs_("+proj=latlong +datum=WGS84") {}

    Map::Map(int width,int height, std::string const& srs)
        : width_(width),
          height_(height),
          srs_(srs),
          background_(Color(255,255,255)) {}

    Map::Map(const Map& rhs)
        : width_(rhs.width_),
          height_(rhs.height_),
          srs_(rhs.srs_),
          background_(rhs.background_),
          styles_(rhs.styles_),
          layers_(rhs.layers_),
          currentExtent_(rhs.currentExtent_) {}

    Map& Map::operator=(const Map& rhs)
    {
        if (this==&rhs) return *this;
        width_=rhs.width_;
        height_=rhs.height_;
        srs_=rhs.srs_;
        background_=rhs.background_;
        styles_=rhs.styles_;
        layers_=rhs.layers_;
        return *this;
    }

    Map::style_iterator Map::begin_styles()
    {
        return styles_.begin();
    }

    Map::style_iterator Map::end_styles()
    {
        return styles_.end();
    }

    Map::const_style_iterator  Map::begin_styles() const
    {
        return styles_.begin();
    }

    Map::const_style_iterator  Map::end_styles() const
    {
        return styles_.end();
    }

    bool Map::insert_style(std::string const& name,feature_type_style const& style)
    {
        return styles_.insert(make_pair(name,style)).second;
    }

    void Map::remove_style(std::string const& name)
    {
        styles_.erase(name);
    }

    feature_type_style const& Map::find_style(std::string const& name) const
    {
        std::map<std::string,feature_type_style>::const_iterator itr = styles_.find(name);
        if (itr!=styles_.end())
            return itr->second;
        static feature_type_style default_style;
        return default_style;
    }

    size_t Map::layerCount() const
    {
        return layers_.size();
    }

    void Map::addLayer(const Layer& l)
    {
        layers_.push_back(l);
    }
    void Map::removeLayer(size_t index)
    {
        layers_.erase(layers_.begin()+index);
    }

    void Map::remove_all()
    {
        layers_.clear();
        styles_.clear();
    }

    const Layer& Map::getLayer(size_t index) const
    {
        return layers_[index];
    }

    Layer& Map::getLayer(size_t index)
    {
        return layers_[index];
    }

    std::vector<Layer> const& Map::layers() const
    {
        return layers_;
    }

    std::vector<Layer> & Map::layers()
    {
        return layers_;
    }

    unsigned Map::getWidth() const
    {
        return width_;
    }

    unsigned Map::getHeight() const
    {
        return height_;
    }

    void Map::setWidth(unsigned width)
    {
        if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE)
        {
            width_=width;
            fixAspectRatio();
        }
    }

    void Map::setHeight(unsigned height)
    {
        if (height >= MIN_MAPSIZE && height <= MAX_MAPSIZE)
        {
            height_=height;
            fixAspectRatio();
        }
    }

    void Map::resize(unsigned width,unsigned height)
    {
        if (width >= MIN_MAPSIZE && width <= MAX_MAPSIZE &&
            height >= MIN_MAPSIZE && height <= MAX_MAPSIZE)
        {
            width_=width;
            height_=height;
            fixAspectRatio();
        }
    }

    std::string const&  Map::srs() const
    {
        return srs_;
    }

    void Map::set_srs(std::string const& srs)
    {
        srs_ = srs;
    }

    void Map::setBackground(const Color& c)
    {
        background_=c;
    }

    const Color& Map::getBackground() const
    {
        return background_;
    }

    void Map::zoom(double factor)
    {
        coord2d center = currentExtent_.center();
        double w = factor * currentExtent_.width();
        double h = factor * currentExtent_.height();
        currentExtent_ = Envelope<double>(center.x - 0.5 * w,
                                          center.y - 0.5 * h,
                                          center.x + 0.5 * w,
                                          center.y + 0.5 * h);
        fixAspectRatio();
    }

    void Map::zoom_all()
    {
        try
        {
            projection proj0(srs_);
            Envelope<double> ext;
            bool first = true;
            std::vector<Layer>::const_iterator itr = layers_.begin();
            std::vector<Layer>::const_iterator end = layers_.end();
            while (itr != end)
            {
                std::string const& layer_srs = itr->srs();
                projection proj1(layer_srs);
                proj_transform prj_trans(proj0,proj1);

                Envelope<double> layerExt = itr->envelope();
                double x0 = layerExt.minx();
                double y0 = layerExt.miny();
                double z0 = 0.0;
                double x1 = layerExt.maxx();
                double y1 = layerExt.maxy();
                double z1 = 0.0;
                prj_trans.backward(x0,y0,z0);
                prj_trans.backward(x1,y1,z1);

                Envelope<double> layerExt2(x0,y0,x1,y1);
#ifdef MAPNIK_DEBUG
                std::clog << " layer1 - > " << layerExt << "\n";
                std::clog << " layer2 - > " << layerExt2 << "\n";
#endif
                if (first)
                {
                    ext = layerExt2;
                    first = false;
                }
                else
                {
                    ext.expand_to_include(layerExt2);
                }
                ++itr;
            }
            zoomToBox(ext);
        }
        catch (proj_init_error & ex)
        {
            std::clog << ex.what() << '\n';
        }
    }

    void Map::zoomToBox(const Envelope<double> &box)
    {
        currentExtent_=box;
        fixAspectRatio();
    }

    void Map::fixAspectRatio()
    {
        double ratio1 = (double) width_ / (double) height_;
        double ratio2 = currentExtent_.width() / currentExtent_.height();

        if (ratio2 > ratio1)
        {
            currentExtent_.height(currentExtent_.width() / ratio1);
        }
        else if (ratio2 < ratio1)
        {
            currentExtent_.width(currentExtent_.height() * ratio1);
        }
    }

    const Envelope<double>& Map::getCurrentExtent() const
    {
        return currentExtent_;
    }

    void Map::pan(int x,int y)
    {
        int dx = x - int(0.5 * width_);
        int dy = int(0.5 * height_) - y;
        double s = width_/currentExtent_.width();
        double minx  = currentExtent_.minx() + dx/s;
        double maxx  = currentExtent_.maxx() + dx/s;
        double miny  = currentExtent_.miny() + dy/s;
        double maxy  = currentExtent_.maxy() + dy/s;
        currentExtent_.init(minx,miny,maxx,maxy);
    }

    void Map::pan_and_zoom(int x,int y,double factor)
    {
        pan(x,y);
        zoom(factor);
    }

    double Map::scale() const
    {
        if (width_>0)
            return currentExtent_.width()/width_;
        return currentExtent_.width();
    }

    CoordTransform Map::view_transform() const
    {
        return CoordTransform(width_,height_,currentExtent_);
    }

    featureset_ptr Map::query_point(unsigned index, double lat, double lon) const
    {
        if ( index< layers_.size())
        {
            mapnik::Layer const& layer = layers_[index];
            try
            {
                double x = lon;
                double y = lat;
                double z = 0;
                mapnik::projection dest(srs_);

		if (!dest.is_geographic())
		{
		    dest.forward(x,y);
		}

                mapnik::projection source(layer.srs());
                proj_transform prj_trans(source,dest);
                prj_trans.backward(x,y,z);

                double minx = currentExtent_.minx();
                double miny = currentExtent_.miny();
                double maxx = currentExtent_.maxx();
                double maxy = currentExtent_.maxy();

                prj_trans.backward(minx,miny,z);
                prj_trans.backward(maxx,maxy,z);
                double tol = (maxx - minx) / width_ * 3;
                mapnik::datasource_ptr ds = layer.datasource();
                if (ds)
                {
#ifdef MAPNIK_DEBUG
                    std::clog << " query at point tol = " << tol << " (" << x << "," << y << ")\n";
#endif
                    featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y));
                    if (fs)
                        return featureset_ptr(new filter_featureset<hit_test_filter>(fs,hit_test_filter(x,y,tol)));
                }
            }
            catch (...)
            {
#ifdef MAPNIK_DEBUG
                std::clog << "exception caught in \"query_map_point\"\n";
#endif
            }
        }
        return featureset_ptr();
    }

    featureset_ptr Map::query_map_point(unsigned index, double x, double y) const
    {
        if ( index< layers_.size())
        {
            mapnik::Layer const& layer = layers_[index];
            CoordTransform tr = view_transform();
            tr.backward(&x,&y);

            try
            {
                mapnik::projection dest(srs_);
                mapnik::projection source(layer.srs());
                proj_transform prj_trans(source,dest);
                double z = 0;
                prj_trans.backward(x,y,z);

                double minx = currentExtent_.minx();
                double miny = currentExtent_.miny();
                double maxx = currentExtent_.maxx();
                double maxy = currentExtent_.maxy();

                prj_trans.backward(minx,miny,z);
                prj_trans.backward(maxx,maxy,z);
                double tol = (maxx - minx) / width_ * 3;
                mapnik::datasource_ptr ds = layer.datasource();
                if (ds)
                {
#ifdef MAPNIK_DEBUG
                    std::clog << " query at point tol = " << tol << " (" << x << "," << y << ")\n";
#endif
                    featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y));
                    if (fs)
                        return featureset_ptr(new filter_featureset<hit_test_filter>(fs,hit_test_filter(x,y,tol)));
                }
            }
            catch (...)
            {
#ifdef MAPNIK_DEBUG
                std::clog << "exception caught in \"query_map_point\"\n";
#endif
            }
        }
        return featureset_ptr();
    }

    Map::~Map() {}
}
<|endoftext|>


<commit_before>#include <ncurses.h>
#include "newmove.hh"
#include "move.hh"
#include "file_contents.hh"
#include "show_message.hh"
#include "int_to_str.hh"

static void show() {
    int vy,vx;
    getyx(stdscr,vy,vx);
    show_message((std::string("x,y,vx,vy: ")
                  + int_to_str(get_contents().get_x()) + ","
                  + int_to_str(get_contents().get_y()) + ","
                  + int_to_str(vx) + ","
                  + int_to_str(vy)).c_str());
}

void mvrel(long y, long x) {
    mvrel(get_contents(),y,x);
    show();
}

void mvcol(long col) {
    mvcol(get_contents(),col);
    show();
}

void mvsot() {
    mvsot(get_contents());
    show();
}

void mveol() {
    mveol(get_contents());
    show();
}
void mvsol() {
    mvsol(get_contents());
    show();
}

void mvsop() {
    mvsop(get_contents());
    show();
}
void mveop() {
    mveop(get_contents());
    show();
}

void mvd(long times) {
    mvd(get_contents(),times);
    show();
}
void mvu(long times) {
    mvu(get_contents(),times);
    show();
}

void mvfw(unsigned long words) {
    mvfw(get_contents(),words);
    show();
}
void mvbw(unsigned long words) {
    mvbw(get_contents(),words);
    show();
}

void mvf(unsigned long times) {
    mvf(get_contents(),times);
    show();
}
void mvb(unsigned long times) {
    mvb(get_contents(),times);
    show();
}

// the following are used for function pointers.
void mvd1 () { mvd (); }
void mvu1 () { mvu (); }
void mvf1w() { mvfw(); }
void mvb1w() { mvbw(); }
void mvf1 () { mvf (); }
void mvb1 () { mvb (); }
<commit_msg>Make only ``show'' position ``ifdef'' _DEBUG<commit_after>#include <ncurses.h>
#include "newmove.hh"
#include "move.hh"
#include "file_contents.hh"
#include "show_message.hh"
#include "int_to_str.hh"

#define _DEBUG

static void show() {
#ifdef _DEBUG
    int vy,vx;
    getyx(stdscr,vy,vx);
    show_message((std::string("x,y,vx,vy: ")
                  + int_to_str(get_contents().get_x()) + ","
                  + int_to_str(get_contents().get_y()) + ","
                  + int_to_str(vx) + ","
                  + int_to_str(vy)).c_str());
#endif
}

void mvrel(long y, long x) {
    mvrel(get_contents(),y,x);
    show();
}

void mvcol(long col) {
    mvcol(get_contents(),col);
    show();
}

void mvsot() {
    mvsot(get_contents());
    show();
}

void mveol() {
    mveol(get_contents());
    show();
}
void mvsol() {
    mvsol(get_contents());
    show();
}

void mvsop() {
    mvsop(get_contents());
    show();
}
void mveop() {
    mveop(get_contents());
    show();
}

void mvd(long times) {
    mvd(get_contents(),times);
    show();
}
void mvu(long times) {
    mvu(get_contents(),times);
    show();
}

void mvfw(unsigned long words) {
    mvfw(get_contents(),words);
    show();
}
void mvbw(unsigned long words) {
    mvbw(get_contents(),words);
    show();
}

void mvf(unsigned long times) {
    mvf(get_contents(),times);
    show();
}
void mvb(unsigned long times) {
    mvb(get_contents(),times);
    show();
}

// the following are used for function pointers.
void mvd1 () { mvd (); }
void mvu1 () { mvu (); }
void mvf1w() { mvfw(); }
void mvb1w() { mvbw(); }
void mvf1 () { mvf (); }
void mvb1 () { mvb (); }
<|endoftext|>


<commit_before>#include <cstdio>
#include <memory>

class A {
 private:
  int id;

 public:
  A(int id): id(id) {
    printf("constructed %d\n", this->id);
  }
  ~A() {
    printf("destructed %d\n", this->id);
  }
};

int main(void) {
  std::unique_ptr<A> a = std::unique_ptr<A>(new A(0));

  std::unique_ptr<A> b = nullptr;
  b = std::unique_ptr<A>(new A(1));

  a = std::unique_ptr<A>(new A(2));
  return 0;
}
<commit_msg>[C++] Compare unique_ptr.<commit_after>#include <cstdio>
#include <memory>

class A {
 private:
  int id;

 public:
  A(int id): id(id) {
    printf("constructed %d\n", this->id);
  }
  ~A() {
    printf("destructed %d\n", this->id);
  }
};

int main(void) {
  std::unique_ptr<A> a = std::unique_ptr<A>(new A(0));

  std::unique_ptr<A> b = nullptr;
  printf("%p %s\n", a.get(), a ? "true" : "false");
  printf("%p %s\n", b.get(), b ? "true" : "false");

  b = std::unique_ptr<A>(new A(1));

  a = std::unique_ptr<A>(new A(2));
  return 0;
}
<|endoftext|>


<commit_before>#include <fstream>
#include "Set.hpp"

void BFS_corners(FILE *file, int end);

void BFS_edges1(FILE *file, int end);

void BFS_edges2(FILE *file, int end);

int main(int argc, char const *argv[]) {
    FILE *file;
    int end = -1;

    if (argc > 1) {
        end = 1 + atoi(argv[1]);
    }

    // file = fopen("../pdbs/cPDB.bin", "wb");
    // if (file == NULL) {
    //     error("main | file cPDB did not open correctly", __LINE__, __FILE__);
    // }
    // BFS_corners(file, end);
    // fclose(file);

    file = fopen("../pdbs/e1PDB.bin", "w");
    if (file == NULL) {
        error("main | file cPDB did not open correctly", __LINE__, __FILE__);
    }
    BFS_edges1(file, end);
    fclose(file);

    return 0;
}

void BFS_corners(FILE *file, int end) {
    std::queue<std::tuple<int, int, int8_t>> queue;     // <rank, last, level>
    std::queue<Cube*> *succ;
    Set closed(1);

    Cube* cube = new Cube;
    int info, size;
    int8_t level = 0, last_level = -1;
    int *corners;
    int last;
    std::tuple<int, int, int8_t> node;

    std::cout << "starting cPDB\n" << std::flush;

    corners = cube->get_corners();
    info = rank(8, corners, 8, 3);
    last = cube->get_last();

    node = std::make_tuple(info, last, level);

    queue.push(node);

    closed.insert(info, level);

    delete cube;

    while (!queue.empty()) {
        std::tie(info, last, level) = queue.front();
        queue.pop();

        cube = new Cube(info, 0, last);

        if (level == end) {
            delete cube;
            break;
        }

        if (level != last_level) {
            last_level = level;
            std::cout << "LEVEL " << int_to_string(last_level) << " | queue " << queue.size();
            std::cout << " | closed " << closed.size() << std::endl;
            std::cout << std::flush;
        }

        succ = cube->succ();
        size = succ->size();

        delete cube;

        for (int i = 0; i < size; ++i) {
            cube = succ->front();
            succ->pop();

            corners = cube->get_corners();
            info = rank(8, corners, 8, 3);
            last = cube->get_last();

            if (!closed.contains(info)) {
                node = std::make_tuple(info, last, level + 1);

                queue.push(node);
                closed.insert(info, level);
            }

            delete cube;
        }

        delete succ;
    }

    // if the 'end' argument was modified
    while (!queue.empty()) {
        std::tie(info, last, level) = queue.front();

        queue.pop();
    }

    //binary write, all at once
    closed.print(file,1);

    std::cout << "ending cPDB\n";
}

void BFS_edges1(FILE *file, int end) {
    std::queue<std::tuple<Cube*, int8_t>> queue;     // <rank, last, level>
    std::queue<Cube*> *succ;
    Set closed(2);

    Cube* cube = new Cube;
    int info, size;
    int8_t level = 0, last_level = -1;
    int *edges;
    std::tuple<Cube*, int8_t> node;

    std::cout << "starting e1PDB\n" << std::flush;

    edges = cube->get_edges();
    info = rank(12, edges, 6, 2);

    node = std::make_tuple(cube, level);

    queue.push(node);

    closed.insert(info, level);

    while (!queue.empty()) {
        std::tie(cube, level) = queue.front();
        queue.pop();

        if (level == end) {
            delete cube;
            break;
        }

        if (level != last_level) {
            last_level = level;
            std::cout << "LEVEL " << int_to_string(last_level) << " | queue " << queue.size();
            std::cout << " | closed " << closed.size() << std::endl;
            std::cout << std::flush;
        }

        edges = cube->get_edges();
        fprintf(file, "%s %d\n", array_to_string(edges, 12).c_str(), info);
        delete edges;

        succ = cube->succ();
        size = succ->size();

        delete cube;

        for (int i = 0; i < size; ++i) {
            cube = succ->front();
            succ->pop();

            edges = cube->get_edges();
            info = rank(12, edges, 6, 2);

            if (!closed.contains(info)) {
                node = std::make_tuple(cube, level + 1);
                queue.push(node);
                closed.insert(info, level);
            } else {
                delete cube;
            }
        }

        delete succ;
    }

    // if the 'end' argument was modified
    while (!queue.empty()) {
        std::tie(cube, level) = queue.front();
        queue.pop();

        delete cube;
    }

    //binary write, all at once
    // closed.print(file,1); ///////////////////////////////

    std::cout << "ending e1PDB\n";
}
<commit_msg>Se genera la PDB de edges.<commit_after>#include <fstream>
#include "Set.hpp"

void BFS_corners(FILE *file, int end);

void BFS_edges1(FILE *file, int end);

void BFS_edges2(FILE *file, int end);

int main(int argc, char const *argv[]) {
    FILE *file;
    int end = -1;

    if (argc > 1) {
        end = 1 + atoi(argv[1]);
    }

    // file = fopen("../pdbs/cPDB.bin", "wb");
    // if (file == NULL) {
    //     error("main | file cPDB did not open correctly", __LINE__, __FILE__);
    // }
    // BFS_corners(file, end);
    // fclose(file);

    file = fopen("../pdbs/e1PDB.bin", "w");
    if (file == NULL) {
        error("main | file cPDB did not open correctly", __LINE__, __FILE__);
    }
    BFS_edges1(file, end);
    fclose(file);

    return 0;
}

void BFS_corners(FILE *file, int end) {
    std::queue<std::tuple<int, int, int8_t>> queue;     // <rank, last, level>
    std::queue<Cube*> *succ;
    Set closed(1);

    Cube* cube = new Cube;
    int info, size;
    int8_t level = 0, last_level = -1;
    int *corners;
    int last;
    std::tuple<int, int, int8_t> node;

    std::cout << "starting cPDB\n" << std::flush;

    corners = cube->get_corners();
    info = rank(8, corners, 8, 3);
    last = cube->get_last();

    node = std::make_tuple(info, last, level);

    queue.push(node);

    closed.insert(info, level);

    delete cube;

    while (!queue.empty()) {
        std::tie(info, last, level) = queue.front();
        queue.pop();

        cube = new Cube(info, 0, last);

        if (level == end) {
            delete cube;
            break;
        }

        if (level != last_level) {
            last_level = level;
            std::cout << "LEVEL " << int_to_string(last_level) << " | queue " << queue.size();
            std::cout << " | closed " << closed.size() << std::endl;
            std::cout << std::flush;
        }

        succ = cube->succ();
        size = succ->size();

        delete cube;

        for (int i = 0; i < size; ++i) {
            cube = succ->front();
            succ->pop();

            corners = cube->get_corners();
            info = rank(8, corners, 8, 3);
            last = cube->get_last();

            if (!closed.contains(info)) {
                node = std::make_tuple(info, last, level + 1);

                queue.push(node);
                closed.insert(info, level);
            }

            delete cube;
        }

        delete succ;
    }

    // if the 'end' argument was modified
    while (!queue.empty()) {
        std::tie(info, last, level) = queue.front();

        queue.pop();
    }

    //binary write, all at once
    closed.print(file,1);

    std::cout << "ending cPDB\n";
}

void BFS_edges1(FILE *file, int end) {
    std::queue<std::tuple<int, int, int8_t>> queue;     // <rank, last, level>
    std::queue<Cube*> *succ;
    Set closed(2);

    Cube* cube = new Cube;
    int info, size;
    int8_t level = 0, last_level = -1;
    int *edges;
    int last;
    std::tuple<int, int, int8_t> node;

    std::cout << "starting e1PDB\n" << std::flush;

    edges = cube->get_edges();
    info = rank(12, edges, 6, 2);
    last = cube->get_last();

    node = std::make_tuple(info, last, level);

    queue.push(node);

    closed.insert(info, level);

    delete cube;

    while (!queue.empty()) {
        std::tie(info, last, level) = queue.front();
        queue.pop();

        cube = new Cube(0, info, last);

        if (level == end) {
            delete cube;
            break;
        }

        if (level != last_level) {
            last_level = level;
            std::cout << "LEVEL " << int_to_string(last_level) << " | queue " << queue.size();
            std::cout << " | closed " << closed.size() << std::endl;
            std::cout << std::flush;
        }

        succ = cube->succ();
        size = succ->size();

        edges = cube->get_edges();
        fprintf(file, "%s %d\n", array_to_string(edges, 12).c_str(), info);
        delete edges;

        delete cube;

        for (int i = 0; i < size; ++i) {
            cube = succ->front();
            succ->pop();

            edges = cube->get_edges();
            info = rank(12, edges, 6, 2);
            last = cube->get_last();

            if (!closed.contains(info)) {
                node = std::make_tuple(info, last, level + 1);

                queue.push(node);
                closed.insert(info, level);
            }

            delete cube;
        }

        delete succ;
    }

    // if the 'end' argument was modified
    while (!queue.empty()) {
        std::tie(info, last, level) = queue.front();

        queue.pop();
    }

    //binary write, all at once
    // closed.print(file,1);

    std::cout << "ending cPDB\n";
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 The Imaging Source Europe GmbH
 *
 * 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.
 */

#include "CaptureDeviceImpl.h"

#include "DeviceIndex.h"
#include "DeviceInterface.h"
#include "PipelineManager.h"
#include "SoftwareProperties.h"
#include "logging.h"
#include "utils.h"

#include <exception>

using namespace tcam;

struct bad_device : std::exception
{
    const char* what() const noexcept
    {
        return "Device did not comply with commands.";
    }
};

CaptureDeviceImpl::CaptureDeviceImpl() : pipeline(nullptr), device(nullptr), index_() {}

CaptureDeviceImpl::CaptureDeviceImpl(const DeviceInfo& _device)
    : pipeline(nullptr), device(nullptr), index_()
{
    if (!open_device(_device))
    {
        SPDLOG_ERROR("Unable to open device");
        throw bad_device();
    }
    const auto serial = open_device_info.get_serial();
    index_.register_device_lost(deviceindex_lost_cb, this, serial);
}

CaptureDeviceImpl::~CaptureDeviceImpl()
{
    close_device();
}

bool CaptureDeviceImpl::open_device(const DeviceInfo& device_desc)
{
    if (is_device_open())
    {
        bool ret = close_device();
        if (ret == false)
        {
            SPDLOG_ERROR("Unable to close previous device.");
            // setError(Error("A device is already open", EPERM));
            return false;
        }
    }

    open_device_info = device_desc;

    device = openDeviceInterface(open_device_info);

    if (device == nullptr)
    {
        return false;
    }

    pipeline = std::make_shared<PipelineManager>();
    pipeline->setSource(device);

    auto props = device->get_properties();

    return true;
}

bool CaptureDeviceImpl::is_device_open() const
{
    if (device != nullptr)
    {
        return true;
    }

    return false;
}

DeviceInfo CaptureDeviceImpl::get_device() const
{
    return this->open_device_info;
}

bool CaptureDeviceImpl::register_device_lost_callback(tcam_device_lost_callback callback,
                                                      void* user_data)
{
    if (!is_device_open())
    {
        return false;
    }

    struct device_lost_cb_data data;
    data.callback = callback;
    data.user_data = user_data;

    device_lost_callback_data_.push_back(data);

    return device->register_device_lost_callback(callback, user_data);
}

void CaptureDeviceImpl::deviceindex_lost_cb(const DeviceInfo& info, void* user_data)
{
    auto self = (CaptureDeviceImpl*)user_data;

    const auto i = info.get_info();

    SPDLOG_INFO("Received lost from index");

    for (const auto& data : self->device_lost_callback_data_)
    {
        (*data.callback)(&i, data.user_data);
    }
}

bool CaptureDeviceImpl::close_device()
{
    if (!is_device_open())
    {
        return true;
    }

    std::string name = open_device_info.get_name();

    pipeline->destroyPipeline();

    pipeline = nullptr;

    open_device_info = DeviceInfo();
    device.reset();

    SPDLOG_INFO("Closed device {}.", name.c_str());

    return true;
}

std::vector<std::shared_ptr<tcam::property::IPropertyBase>> CaptureDeviceImpl::get_properties()
{
    if (!is_device_open())
    {
        return std::vector<std::shared_ptr<tcam::property::IPropertyBase>>();
    }
    return pipeline->get_properties();
}

std::shared_ptr<tcam::property::IPropertyBase> CaptureDeviceImpl::get_property(
    const std::string& name)
{
    auto props = pipeline->get_properties();

    for (auto& p : props)
    {
        if (p->get_name() == name)
        {
            return p;
        }
    }

    return nullptr;
}

std::vector<VideoFormatDescription> CaptureDeviceImpl::get_available_video_formats() const
{
    if (!is_device_open())
    {
        return std::vector<VideoFormatDescription>();
    }

    return pipeline->getAvailableVideoFormats();
}

bool CaptureDeviceImpl::set_video_format(const VideoFormat& new_format)
{
    if (!is_device_open())
    {
        return false;
    }

    pipeline->setVideoFormat(new_format);

    return this->device->set_video_format(new_format);
}

VideoFormat CaptureDeviceImpl::get_active_video_format() const
{
    if (!is_device_open())
    {
        return VideoFormat();
    }

    return device->get_active_video_format();
}

bool CaptureDeviceImpl::start_stream(std::shared_ptr<SinkInterface> sink)
{
    if (!is_device_open())
    {
        SPDLOG_ERROR("Device is not open");
        return false;
    }

    if (!pipeline->setSink(sink))
    {
        return false;
    }

    return pipeline->set_status(TCAM_PIPELINE_PLAYING);
}

bool CaptureDeviceImpl::stop_stream()
{
    if (!is_device_open())
    {
        return false;
    }

    return pipeline->set_status(TCAM_PIPELINE_STOPPED);
}
<commit_msg>srcs: Ensure indexer always reports device lost<commit_after>/*
 * Copyright 2014 The Imaging Source Europe GmbH
 *
 * 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.
 */

#include "CaptureDeviceImpl.h"

#include "DeviceIndex.h"
#include "DeviceInterface.h"
#include "PipelineManager.h"
#include "SoftwareProperties.h"
#include "logging.h"
#include "utils.h"

#include <exception>

using namespace tcam;

struct bad_device : std::exception
{
    const char* what() const noexcept
    {
        return "Device did not comply with commands.";
    }
};

CaptureDeviceImpl::CaptureDeviceImpl() : pipeline(nullptr), device(nullptr), index_() {}

CaptureDeviceImpl::CaptureDeviceImpl(const DeviceInfo& _device)
    : pipeline(nullptr), device(nullptr), index_()
{
    if (!open_device(_device))
    {
        SPDLOG_ERROR("Unable to open device");
        throw bad_device();
    }
}

CaptureDeviceImpl::~CaptureDeviceImpl()
{
    close_device();
}

bool CaptureDeviceImpl::open_device(const DeviceInfo& device_desc)
{
    if (is_device_open())
    {
        bool ret = close_device();
        if (ret == false)
        {
            SPDLOG_ERROR("Unable to close previous device.");
            // setError(Error("A device is already open", EPERM));
            return false;
        }
    }

    open_device_info = device_desc;

    device = openDeviceInterface(open_device_info);

    if (device == nullptr)
    {
        return false;
    }

    pipeline = std::make_shared<PipelineManager>();
    pipeline->setSource(device);

    auto props = device->get_properties();

    const auto serial = open_device_info.get_serial();
    index_.register_device_lost(deviceindex_lost_cb, this, serial);

    return true;
}

bool CaptureDeviceImpl::is_device_open() const
{
    if (device != nullptr)
    {
        return true;
    }

    return false;
}

DeviceInfo CaptureDeviceImpl::get_device() const
{
    return this->open_device_info;
}

bool CaptureDeviceImpl::register_device_lost_callback(tcam_device_lost_callback callback,
                                                      void* user_data)
{
    if (!is_device_open())
    {
        return false;
    }

    struct device_lost_cb_data data;
    data.callback = callback;
    data.user_data = user_data;

    device_lost_callback_data_.push_back(data);

    return device->register_device_lost_callback(callback, user_data);
}

void CaptureDeviceImpl::deviceindex_lost_cb(const DeviceInfo& info, void* user_data)
{
    auto self = (CaptureDeviceImpl*)user_data;

    const auto i = info.get_info();

    SPDLOG_INFO("Received lost from index");

    for (const auto& data : self->device_lost_callback_data_)
    {
        (*data.callback)(&i, data.user_data);
    }
}

bool CaptureDeviceImpl::close_device()
{
    if (!is_device_open())
    {
        return true;
    }

    std::string name = open_device_info.get_name();

    pipeline->destroyPipeline();

    pipeline = nullptr;

    open_device_info = DeviceInfo();
    device.reset();

    SPDLOG_INFO("Closed device {}.", name.c_str());

    return true;
}

std::vector<std::shared_ptr<tcam::property::IPropertyBase>> CaptureDeviceImpl::get_properties()
{
    if (!is_device_open())
    {
        return std::vector<std::shared_ptr<tcam::property::IPropertyBase>>();
    }
    return pipeline->get_properties();
}

std::shared_ptr<tcam::property::IPropertyBase> CaptureDeviceImpl::get_property(
    const std::string& name)
{
    auto props = pipeline->get_properties();

    for (auto& p : props)
    {
        if (p->get_name() == name)
        {
            return p;
        }
    }

    return nullptr;
}

std::vector<VideoFormatDescription> CaptureDeviceImpl::get_available_video_formats() const
{
    if (!is_device_open())
    {
        return std::vector<VideoFormatDescription>();
    }

    return pipeline->getAvailableVideoFormats();
}

bool CaptureDeviceImpl::set_video_format(const VideoFormat& new_format)
{
    if (!is_device_open())
    {
        return false;
    }

    pipeline->setVideoFormat(new_format);

    return this->device->set_video_format(new_format);
}

VideoFormat CaptureDeviceImpl::get_active_video_format() const
{
    if (!is_device_open())
    {
        return VideoFormat();
    }

    return device->get_active_video_format();
}

bool CaptureDeviceImpl::start_stream(std::shared_ptr<SinkInterface> sink)
{
    if (!is_device_open())
    {
        SPDLOG_ERROR("Device is not open");
        return false;
    }

    if (!pipeline->setSink(sink))
    {
        return false;
    }

    return pipeline->set_status(TCAM_PIPELINE_PLAYING);
}

bool CaptureDeviceImpl::stop_stream()
{
    if (!is_device_open())
    {
        return false;
    }

    return pipeline->set_status(TCAM_PIPELINE_STOPPED);
}
<|endoftext|>


<commit_before>#include "sbridge.h"

sbridge::sbridge(std::string publishedName) {

    ros::NodeHandle sNH;

    driveControlSubscriber = sNH.subscribe((publishedName + "/driveControl"), 10, &sbridge::cmdHandler, this);

    heartbeatPublisher = sNH.advertise<std_msgs::String>((publishedName + "/sbridge/heartbeat"), 1, false);
    skidsteerPublish = sNH.advertise<geometry_msgs::Twist>((publishedName + "/skidsteer"), 10);
    infoLogPublisher = sNH.advertise<std_msgs::String>("/infoLog", 1, true);
    modeSubscriber = sNH.subscribe((publishedName + "/mode"), 1, &sbridge::modeHandler, this);

    float heartbeat_publish_interval = 2;
    publish_heartbeat_timer = sNH.createTimer(ros::Duration(heartbeat_publish_interval), &sbridge::publishHeartBeatTimerEventHandler, this);

     ROS_INFO("constructor");

}

void sbridge::cmdHandler(const geometry_msgs::Twist::ConstPtr& message) {
    double left = (message->linear.x);
    double right = (message->angular.z);

    float turn = 0;
    float forward = 0;

    if (currentMode == 1) {
        forward = left*0.6;
        turn = right*1.4;
        if (forward >= 0.4){

            forward -= (abs(turn)/5);
        }

    }
    else
    {

        float linearVel = (left + right)/2;
        float angularVel = (right-left)/2;

        turn = angularVel/180;
        forward = linearVel/400;
        if (forward >= 150){

            forward -= (abs(turn)/5);
        }

        if (linearVel >= 0 && forward <= 0)
        {
            forward = 0;
        }
        if (linearVel <= 0 && forward >= 0)
        {
            forward = 0;
        }
    }

    if (fabs(forward) >= 0.8) {
        forward = forward/fabs(forward) * 0.8;
    }

    if (fabs(turn) >= 1.0) { //max value needs tuning
        turn = turn/fabs(turn) * 1.0;
    }

    velocity.linear.x = forward,
            velocity.angular.z = turn;
    skidsteerPublish.publish(velocity);
}

void sbridge::publishHeartBeatTimerEventHandler(const ros::TimerEvent& event) {
    std_msgs::String msg;
    msg.data = "";
    heartbeatPublisher.publish(msg);

    ROS_INFO("%ds, %dnsec", event.last_real.sec, event.last_real.nsec);
}

void sbridge::modeHandler(const std_msgs::UInt8::ConstPtr& message) {
    currentMode = message->data;
}

sbridge::~sbridge() {
}
<commit_msg>made sim robot driving come more inline with real robots<commit_after>#include "sbridge.h"

sbridge::sbridge(std::string publishedName) {

    ros::NodeHandle sNH;

    driveControlSubscriber = sNH.subscribe((publishedName + "/driveControl"), 10, &sbridge::cmdHandler, this);

    heartbeatPublisher = sNH.advertise<std_msgs::String>((publishedName + "/sbridge/heartbeat"), 1, false);
    skidsteerPublish = sNH.advertise<geometry_msgs::Twist>((publishedName + "/skidsteer"), 10);
    infoLogPublisher = sNH.advertise<std_msgs::String>("/infoLog", 1, true);
    modeSubscriber = sNH.subscribe((publishedName + "/mode"), 1, &sbridge::modeHandler, this);

    float heartbeat_publish_interval = 2;
    publish_heartbeat_timer = sNH.createTimer(ros::Duration(heartbeat_publish_interval), &sbridge::publishHeartBeatTimerEventHandler, this);

     ROS_INFO("constructor");

}

void sbridge::cmdHandler(const geometry_msgs::Twist::ConstPtr& message) {
    double left = (message->linear.x);
    double right = (message->angular.z);

    float max_turn_rate = 3.14; //radians per second
    float max_linear_velocity = 0.6; // meters per second

    float turn = 0;
    float forward = 0;

    if (currentMode == 1)
    {
        forward = left*max_linear_velocity;
        turn = right*max_turn_rate;
        if (forward >= 0.1)
        {

            forward -= right*max_linear_velocity/2;
        }

    }
    else
    {

        float linearVel = (left + right)/2;
        float angularVel = (right-left)/2;

        turn = angularVel/180;
        forward = linearVel/400;
        if (forward >= 150){

            forward -= (abs(turn)/5);
        }

        if (linearVel >= 0 && forward <= 0)
        {
            forward = 0;
        }
        if (linearVel <= 0 && forward >= 0)
        {
            forward = 0;
        }
    }

    if (fabs(forward) >= max_linear_velocity) {
        forward = forward/fabs(forward) * max_linear_velocity;
    }

    if (fabs(turn) >= max_turn_rate) { //max value needs tuning
        turn = turn/fabs(turn) * max_turn_rate;
    }

    velocity.linear.x = forward,
            velocity.angular.z = turn;
    skidsteerPublish.publish(velocity);
}

void sbridge::publishHeartBeatTimerEventHandler(const ros::TimerEvent& event) {
    std_msgs::String msg;
    msg.data = "";
    heartbeatPublisher.publish(msg);

    ROS_INFO("%ds, %dnsec", event.last_real.sec, event.last_real.nsec);
}

void sbridge::modeHandler(const std_msgs::UInt8::ConstPtr& message) {
    currentMode = message->data;
}

sbridge::~sbridge() {
}
<|endoftext|>


<commit_before>#include "Write_Solution.hxx"

#include <boost/algorithm/string.hpp>

#include <stdexcept>

Write_Solution::Write_Solution(const std::string &input)
    : input_string(input)
{
  std::vector<std::string> solutions;
  using namespace std::string_literals;
  boost::split(solutions, input_string, boost::is_any_of(", "s));
  for(auto &solution : solutions)
    {
      switch(solution.size())
        {
        case 0: break;
        case 1:
          switch(solution.front())
            {
            case 'x': vector_x = true; break;
            case 'y': vector_y = true; break;
            case 'X': matrix_X = true; break;
            case 'Y': matrix_Y = true; break;
            default:
              throw std::runtime_error(
                "Invalid argument for writeSolution.  Expected a comma "
                "separated list containing x, y, X, and/or Y, but found: "
                + solution);
            }
          break;
        default:
          throw std::runtime_error(
            "Invalid argument for writeSolution.  Expected a comma "
            "separated list containing x, y, X, and/or Y, but found: "
            + solution);
          break;
        }
    }
}
<commit_msg>Add a missing #include<commit_after>#include "Write_Solution.hxx"

#include <boost/algorithm/string.hpp>

#include <stdexcept>
#include <vector>

Write_Solution::Write_Solution(const std::string &input)
    : input_string(input)
{
  std::vector<std::string> solutions;
  using namespace std::string_literals;
  boost::split(solutions, input_string, boost::is_any_of(", "s));
  for(auto &solution : solutions)
    {
      switch(solution.size())
        {
        case 0: break;
        case 1:
          switch(solution.front())
            {
            case 'x': vector_x = true; break;
            case 'y': vector_y = true; break;
            case 'X': matrix_X = true; break;
            case 'Y': matrix_Y = true; break;
            default:
              throw std::runtime_error(
                "Invalid argument for writeSolution.  Expected a comma "
                "separated list containing x, y, X, and/or Y, but found: "
                + solution);
            }
          break;
        default:
          throw std::runtime_error(
            "Invalid argument for writeSolution.  Expected a comma "
            "separated list containing x, y, X, and/or Y, but found: "
            + solution);
          break;
        }
    }
}
<|endoftext|>


<commit_before>#include <sstream>
#include <string>
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "ProxyHandler.h"

void ProxyHandler::Configure(const NginxConfig& child_config_block) {
}

std::string ProxyHandler::HandleRequest(const HTTPRequest& req) {
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    // Construct query using name of server and service
    boost::asio::ip::tcp::resolver::query query("localhost", "1080");
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    boost::asio::ip::tcp::socket socket(io_service);
    // Try connecting to server
    boost::asio::connect(socket,endpoint_iterator);
    for (;;)
    {
        boost::array<char, 128> buf;
        boost::system::error_code error;
        // Send get request
        std::stringstream request_;
        request_ << "GET / HTTP/1.1\r\n";
        request_ << "\r\n";
        boost::asio::write(socket, boost::asio::buffer(request_.str()), error);
        // Read reply from server
        size_t len = socket.read_some(boost::asio::buffer(buf), error);
        if (error == boost::asio::error::eof)
        {
            break;
        }
        else if (error)
        {
            throw boost::system::system_error(error);
        }
        std::cout.write(buf.data(), len);
    }
    return "";
}
<commit_msg>Added some proxy implementation.<commit_after>#include <sstream>
#include <string>
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "ProxyHandler.h"

void ProxyHandler::Configure(const NginxConfig& child_config_block) {
}

std::string ProxyHandler::HandleRequest(const HTTPRequest& req) {
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    // Construct query using name of server and service
    boost::asio::ip::tcp::resolver::query query("localhost", "1080");
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    boost::asio::ip::tcp::socket socket(io_service);

    // Try connecting to server
    boost::asio::connect(socket,endpoint_iterator);

    // Send get request
    std::stringstream request_;
    request_ << req.method + " " + req.path + " HTTP/1.1\r\n";
    for (int i = 0; i < req.headers.size(); i++) {
        request_ << req.headers.first + " " + req.headers.second + "\r\n";
    }
    request_ << "\r\n" + req.request_body;
    boost::asio::write(socket, boost::asio::buffer(request_.str()), error);

    std::string response = "";
    for (;;) {
        boost::array<char, 128> buf;
        boost::system::error_code error;
        // Read reply from server
        size_t len = socket.read_some(boost::asio::buffer(buf), error);
        if (error == boost::asio::error::eof)
        {
            break;
        }
        else if (error)
        {
            throw boost::system::system_error(error);
        }
        std::string str_buffer(buf.data(), len);
        response += str_buffer;
    }
    std::cout << "Response: " << response << '\n';
    return response;
}
<|endoftext|>


<commit_before>
/*
 * MaskLayer.cpp
 *
 *  Created on: Mar 21, 2014
 *      Author: slundquist
 */

#include "MaskLayer.hpp"

namespace PV {

MaskLayer::MaskLayer(const char * name, HyPerCol * hc){
   initialize_base();
   initialize(name, hc);
}

MaskLayer::MaskLayer() {
   initialize_base();
   // initialize() gets called by subclass's initialize method
}

MaskLayer::~MaskLayer(){
   if(maskLayerName){
      free(maskLayerName);
   }
   if(features){
      free(features);
   }
   if(maskMethod){
      free(maskMethod);
   }
}

int MaskLayer::initialize_base(){
   maskLayerName = NULL;
   maskLayer = NULL;
   maskMethod = NULL;
   features = NULL;

   return PV_SUCCESS;
}

int MaskLayer::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
   int status = ANNLayer::ioParamsFillGroup(ioFlag);
   ioParam_maskMethod(ioFlag);
   ioParam_maskLayerName(ioFlag);
   ioParam_featureIdxs(ioFlag);
   return status;
}

void MaskLayer::ioParam_maskMethod(enum ParamsIOFlag ioFlag) {
   parent->ioParamStringRequired(ioFlag, name, "maskMethod", &maskMethod);
   //Check valid methods
   if(strcmp(maskMethod, "layer") == 0){
   }
   else if(strcmp(maskMethod, "maskFeatures") == 0){
   }
   else if(strcmp(maskMethod, "noMaskFeatures") == 0){
   }
   else{
      if (parent->columnId()==0) {
         fprintf(stderr, "%s \"%s\" error: \"%s\" is not a valid maskMethod. Options are \"layer\", \"maskFeatures\", or \"noMaskFeatures\".\n",
                 getKeyword(), name, maskMethod);
      }
      exit(-1);
   }
}

void MaskLayer::ioParam_maskLayerName(enum ParamsIOFlag ioFlag) {
   assert(!parent->parameters()->presentAndNotBeenRead(name, "maskMethod"));
   if(strcmp(maskMethod, "layer") == 0){
      parent->ioParamStringRequired(ioFlag, name, "maskLayerName", &maskLayerName);
   }
}

void MaskLayer::ioParam_featureIdxs(enum ParamsIOFlag ioFlag) {
   assert(!parent->parameters()->presentAndNotBeenRead(name, "maskMethod"));
   if(strcmp(maskMethod, "maskFeatures") == 0 || strcmp(maskMethod, "noMaskFeatures") == 0){
      parent->ioParamArray(ioFlag, name, "featureIdxs", &features, &numSpecifiedFeatures);
      if(numSpecifiedFeatures == 0){
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: MaskLayer must specify at least one feature for maskMethod \"%s\".\n",
                    getKeyword(), name, maskMethod);
         }
         exit(-1);
      }
   }
}

int MaskLayer::communicateInitInfo() {
   int status = ANNLayer::communicateInitInfo();
   if(strcmp(maskMethod, "layer") == 0){
      maskLayer = parent->getLayerFromName(maskLayerName);
      if (maskLayer==NULL) {
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: maskLayerName \"%s\" is not a layer in the HyPerCol.\n",
                    getKeyword(), name, maskLayerName);
         }
         MPI_Barrier(parent->icCommunicator()->communicator());
         exit(EXIT_FAILURE);
      }

      const PVLayerLoc * maskLoc = maskLayer->getLayerLoc();
      const PVLayerLoc * loc = getLayerLoc();
      assert(maskLoc != NULL && loc != NULL);
      if (maskLoc->nxGlobal != loc->nxGlobal || maskLoc->nyGlobal != loc->nyGlobal) {
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: maskLayerName \"%s\" does not have the same x and y dimensions.\n",
                    getKeyword(), name, maskLayerName);
            fprintf(stderr, "    original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
                    maskLoc->nxGlobal, maskLoc->nyGlobal, maskLoc->nf, loc->nxGlobal, loc->nyGlobal, loc->nf);
         }
         MPI_Barrier(parent->icCommunicator()->communicator());
         exit(EXIT_FAILURE);
      }

      if(maskLoc->nf != 1 && maskLoc->nf != loc->nf){
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: maskLayerName \"%s\" must either have the same number of features as this layer, or one feature.\n",
                    getKeyword(), name, maskLayerName);
            fprintf(stderr, "    original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
                    maskLoc->nxGlobal, maskLoc->nyGlobal, maskLoc->nf, loc->nxGlobal, loc->nyGlobal, loc->nf);
         }
         MPI_Barrier(parent->icCommunicator()->communicator());
         exit(EXIT_FAILURE);
      }

      assert(maskLoc->nx==loc->nx && maskLoc->ny==loc->ny);
   }
   else{
      //Check for in bounds featureIdxs
      assert(features);
      const PVLayerLoc * loc = getLayerLoc();
      for(int f = 0; f < numSpecifiedFeatures; f++){
         if(features[f] < 0 || features[f] >= loc->nf){
            std::cout << "Specified feature " << features[f] << "out of bounds\n";
            exit(-1);
         }

      }
   }

   return status;
}

int MaskLayer::updateState(double time, double dt)
{
   ANNLayer::updateState(time, dt);
   const PVLayerLoc * loc = getLayerLoc();
   const PVLayerLoc * maskLoc = maskLayer->getLayerLoc();
   pvdata_t * maskActivity = maskLayer->getActivity();
   pvdata_t * A = getActivity();

   int nx = loc->nx;
   int ny = loc->ny;
   int nf = loc->nf;
   int num_neurons = nx*ny*nf;
   int nbatch = loc->nbatch;

   for(int b = 0; b < nbatch; b++){
      pvdata_t * maskActivityBatch = maskActivity + b * getNumExtended();
      pvdata_t * ABatch = A + b * getNumExtended();
#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
      for(int ni = 0; ni < num_neurons; ni++){
         int kThisRes = ni;
         int kThisExt = kIndexExtended(ni, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up);
         int maskVal;
         if(strcmp(maskMethod, "layer") == 0){
            int kMaskRes;
            if(maskLoc->nf == 1){
               kMaskRes = ni/nf;
            }
            else{
               kMaskRes = ni;
            }
            int kMaskExt = kIndexExtended(ni, nx, ny, maskLoc->nf, maskLoc->halo.lt, maskLoc->halo.rt, maskLoc->halo.dn, maskLoc->halo.up);
            maskVal = maskActivityBatch[kMaskExt];
         }
         else if(strcmp(maskMethod, "maskFeatures") == 0){
            //Calculate feature index of ni
            int featureNum = featureIndex(ni, nx, ny, nf);
            maskVal = 1; //If nothing specified, copy everything
            for(int specF = 0; specF < numSpecifiedFeatures; specF++){
               if(featureNum == features[specF]){
                  maskVal = 0;
                  break;
               }
            }
         }
         else if(strcmp(maskMethod, "noMaskFeatures") == 0){
            //Calculate feature index of ni
            int featureNum = featureIndex(ni, nx, ny, nf);
            maskVal = 0; //If nothing specified, copy nothing
            for(int specF = 0; specF < numSpecifiedFeatures; specF++){
               if(featureNum == features[specF]){
                  maskVal = 1;
                  break;
               }
            }
         }

         //Set value to 0, otherwise, updateState from ANNLayer should have taken care of it
         if(maskVal == 0){
            ABatch[kThisExt] = 0;
         }
      }
   }
   return PV_SUCCESS;
}

} /* namespace PV */
<commit_msg>Fixed a bug with MaskLayer not having a target mask layer when using an index for maskMethod<commit_after>
/*
 * MaskLayer.cpp
 *
 *  Created on: Mar 21, 2014
 *      Author: slundquist
 */

#include "MaskLayer.hpp"

namespace PV {

MaskLayer::MaskLayer(const char * name, HyPerCol * hc){
   initialize_base();
   initialize(name, hc);
}

MaskLayer::MaskLayer() {
   initialize_base();
   // initialize() gets called by subclass's initialize method
}

MaskLayer::~MaskLayer(){
   if(maskLayerName){
      free(maskLayerName);
   }
   if(features){
      free(features);
   }
   if(maskMethod){
      free(maskMethod);
   }
}

int MaskLayer::initialize_base(){
   maskLayerName = NULL;
   maskLayer = NULL;
   maskMethod = NULL;
   features = NULL;

   return PV_SUCCESS;
}

int MaskLayer::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
   int status = ANNLayer::ioParamsFillGroup(ioFlag);
   ioParam_maskMethod(ioFlag);
   ioParam_maskLayerName(ioFlag);
   ioParam_featureIdxs(ioFlag);
   return status;
}

void MaskLayer::ioParam_maskMethod(enum ParamsIOFlag ioFlag) {
   parent->ioParamStringRequired(ioFlag, name, "maskMethod", &maskMethod);
   //Check valid methods
   if(strcmp(maskMethod, "layer") == 0){
   }
   else if(strcmp(maskMethod, "maskFeatures") == 0){
   }
   else if(strcmp(maskMethod, "noMaskFeatures") == 0){
   }
   else{
      if (parent->columnId()==0) {
         fprintf(stderr, "%s \"%s\" error: \"%s\" is not a valid maskMethod. Options are \"layer\", \"maskFeatures\", or \"noMaskFeatures\".\n",
                 getKeyword(), name, maskMethod);
      }
      exit(-1);
   }
}

void MaskLayer::ioParam_maskLayerName(enum ParamsIOFlag ioFlag) {
   assert(!parent->parameters()->presentAndNotBeenRead(name, "maskMethod"));
   if(strcmp(maskMethod, "layer") == 0){
      parent->ioParamStringRequired(ioFlag, name, "maskLayerName", &maskLayerName);
   }
}

void MaskLayer::ioParam_featureIdxs(enum ParamsIOFlag ioFlag) {
   assert(!parent->parameters()->presentAndNotBeenRead(name, "maskMethod"));
   if(strcmp(maskMethod, "maskFeatures") == 0 || strcmp(maskMethod, "noMaskFeatures") == 0){
      parent->ioParamArray(ioFlag, name, "featureIdxs", &features, &numSpecifiedFeatures);
      if(numSpecifiedFeatures == 0){
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: MaskLayer must specify at least one feature for maskMethod \"%s\".\n",
                    getKeyword(), name, maskMethod);
         }
         exit(-1);
      }
   }
}

int MaskLayer::communicateInitInfo() {
   int status = ANNLayer::communicateInitInfo();
   if(strcmp(maskMethod, "layer") == 0){
      maskLayer = parent->getLayerFromName(maskLayerName);
      if (maskLayer==NULL) {
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: maskLayerName \"%s\" is not a layer in the HyPerCol.\n",
                    getKeyword(), name, maskLayerName);
         }
         MPI_Barrier(parent->icCommunicator()->communicator());
         exit(EXIT_FAILURE);
      }

      const PVLayerLoc * maskLoc = maskLayer->getLayerLoc();
      const PVLayerLoc * loc = getLayerLoc();
      assert(maskLoc != NULL && loc != NULL);
      if (maskLoc->nxGlobal != loc->nxGlobal || maskLoc->nyGlobal != loc->nyGlobal) {
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: maskLayerName \"%s\" does not have the same x and y dimensions.\n",
                    getKeyword(), name, maskLayerName);
            fprintf(stderr, "    original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
                    maskLoc->nxGlobal, maskLoc->nyGlobal, maskLoc->nf, loc->nxGlobal, loc->nyGlobal, loc->nf);
         }
         MPI_Barrier(parent->icCommunicator()->communicator());
         exit(EXIT_FAILURE);
      }

      if(maskLoc->nf != 1 && maskLoc->nf != loc->nf){
         if (parent->columnId()==0) {
            fprintf(stderr, "%s \"%s\" error: maskLayerName \"%s\" must either have the same number of features as this layer, or one feature.\n",
                    getKeyword(), name, maskLayerName);
            fprintf(stderr, "    original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
                    maskLoc->nxGlobal, maskLoc->nyGlobal, maskLoc->nf, loc->nxGlobal, loc->nyGlobal, loc->nf);
         }
         MPI_Barrier(parent->icCommunicator()->communicator());
         exit(EXIT_FAILURE);
      }

      assert(maskLoc->nx==loc->nx && maskLoc->ny==loc->ny);
   }
   else{
      //Check for in bounds featureIdxs
      assert(features);
      const PVLayerLoc * loc = getLayerLoc();
      for(int f = 0; f < numSpecifiedFeatures; f++){
         if(features[f] < 0 || features[f] >= loc->nf){
            std::cout << "Specified feature " << features[f] << "out of bounds\n";
            exit(-1);
         }

      }
   }

   return status;
}

int MaskLayer::updateState(double time, double dt)
{
   ANNLayer::updateState(time, dt);
   const PVLayerLoc * loc = getLayerLoc();
   pvdata_t * A = getActivity();

   int nx = loc->nx;
   int ny = loc->ny;
   int nf = loc->nf;
   int num_neurons = nx*ny*nf;
   int nbatch = loc->nbatch;

   for(int b = 0; b < nbatch; b++){
      pvdata_t * ABatch = A + b * getNumExtended();
#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
      for(int ni = 0; ni < num_neurons; ni++){
         int kThisRes = ni;
         int kThisExt = kIndexExtended(ni, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up);
         int maskVal;
         if(strcmp(maskMethod, "layer") == 0){
            const PVLayerLoc * maskLoc = maskLayer->getLayerLoc();
            pvdata_t * maskActivity = maskLayer->getActivity();
            pvdata_t * maskActivityBatch = maskActivity + b * getNumExtended();
            int kMaskRes;
            if(maskLoc->nf == 1){
               kMaskRes = ni/nf;
            }
            else{
               kMaskRes = ni;
            }
            int kMaskExt = kIndexExtended(ni, nx, ny, maskLoc->nf, maskLoc->halo.lt, maskLoc->halo.rt, maskLoc->halo.dn, maskLoc->halo.up);
            maskVal = maskActivityBatch[kMaskExt];
         }
         else if(strcmp(maskMethod, "maskFeatures") == 0){
            //Calculate feature index of ni
            int featureNum = featureIndex(ni, nx, ny, nf);
            maskVal = 1; //If nothing specified, copy everything
            for(int specF = 0; specF < numSpecifiedFeatures; specF++){
               if(featureNum == features[specF]){
                  maskVal = 0;
                  break;
               }
            }
         }
         else if(strcmp(maskMethod, "noMaskFeatures") == 0){
            //Calculate feature index of ni
            int featureNum = featureIndex(ni, nx, ny, nf);
            maskVal = 0; //If nothing specified, copy nothing
            for(int specF = 0; specF < numSpecifiedFeatures; specF++){
               if(featureNum == features[specF]){
                  maskVal = 1;
                  break;
               }
            }
         }

         //Set value to 0, otherwise, updateState from ANNLayer should have taken care of it
         if(maskVal == 0){
            ABatch[kThisExt] = 0;
         }
      }
   }
   return PV_SUCCESS;
}

} /* namespace PV */
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <stdexcept>
#include <vector>
#include <map>
#include <stack>

#include "rapidjson/reader.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"

#include "acmacs-base/read-file.hh"

// ----------------------------------------------------------------------

namespace json_reader
{
    class Error : public std::runtime_error { public: using std::runtime_error::runtime_error; };

    class Failure : public std::exception { public: using std::exception::exception; };
    class Pop : public std::exception { public: using std::exception::exception; };

// ----------------------------------------------------------------------

    template <typename Target> class HandlerBase
    {
     public:
        inline HandlerBase(Target& aTarget) : mTarget(aTarget), mIgnore(false) {}
        virtual ~HandlerBase() {}

        inline virtual HandlerBase* StartObject() { std::cerr << "HandlerBase StartObject " << typeid(*this).name() << std::endl; throw Failure(); }
        inline virtual HandlerBase* EndObject() { throw Pop(); }
        inline virtual HandlerBase* StartArray() { throw Failure(); }
        inline virtual HandlerBase* EndArray() { throw Pop(); }
        inline virtual HandlerBase* Double(double d) { std::cerr << "Double: " << d << std::endl; throw Failure(); }
        inline virtual HandlerBase* Int(int i) { std::cerr << "Int: " << i << std::endl; throw Failure(); }
        inline virtual HandlerBase* Uint(unsigned u) { std::cerr << "Uint: " << u << std::endl; throw Failure(); }

        inline virtual HandlerBase* Key(const char* str, rapidjson::SizeType length)
            {
                if ((length == 1 && *str == '_') || (length > 0 && *str == '?')) {
                    mIgnore = true;
                }
                else {
                    std::cerr << "Key: \"" << std::string(str, length) << '"' << std::endl;
                    throw Failure();
                }
                return nullptr;
            }

        inline virtual HandlerBase* String(const char* str, rapidjson::SizeType length)
            {
                if (mIgnore) {
                    mIgnore = false;
                }
                else {
                    std::cerr << "String: \"" << std::string(str, length) << '"' << std::endl;
                    throw Failure();
                }
                return nullptr;
            }

     protected:
        Target& mTarget;
        bool mIgnore;
    };

// ----------------------------------------------------------------------

    template <typename Target> class StringListHandler : public HandlerBase<Target>
    {
     public:
        inline StringListHandler(Target& aTarget, std::vector<std::string>& aList)
            : HandlerBase<Target>(aTarget), mList(aList), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartArray()
            {
                if (mStarted)
                    throw Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* EndObject() { throw Failure(); }

        inline virtual HandlerBase<Target>* String(const char* str, rapidjson::SizeType length)
            {
                mList.emplace_back(str, length);
                return nullptr;
            }

     private:
        std::vector<std::string>& mList;
        bool mStarted;

    }; // class StringListHandler

// ----------------------------------------------------------------------

    template <typename Target> class MapListHandler : public HandlerBase<Target>
    {
     public:
        inline MapListHandler(Target& aTarget, std::map<std::string, std::vector<std::string>>& aMap)
            : HandlerBase<Target>{aTarget}, mMap(aMap), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartObject()
            {
                if (mStarted)
                    throw Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* EndArray() { throw Failure(); }

        inline virtual HandlerBase<Target>* Key(const char* str, rapidjson::SizeType length)
            {
                return new StringListHandler<Target>(HandlerBase<Target>::mTarget, mMap[{str, length}]);
            }

     private:
        std::map<std::string, std::vector<std::string>>& mMap;
        bool mStarted;

    }; // class MapListHandler

// ----------------------------------------------------------------------

    template <typename Target> class StringMappingHandler : public HandlerBase<Target>
    {
     public:
        inline StringMappingHandler(Target& aTarget, std::vector<std::pair<std::string, std::string>>& aMapping)
            : HandlerBase<Target>{aTarget}, mMapping(aMapping), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartObject()
            {
                if (mStarted)
                    throw json_reader::Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* Key(const char* str, rapidjson::SizeType length)
            {
                mKey.assign(str, length);
                return nullptr;
            }

        inline virtual HandlerBase<Target>* String(const char* str, rapidjson::SizeType length)
            {
                if (mKey.empty())
                    throw json_reader::Failure();
                mMapping.emplace_back(mKey, std::string(str, length));
                mKey.erase();
                return nullptr;
            }

     private:
        std::vector<std::pair<std::string, std::string>>& mMapping;
        bool mStarted;
        std::string mKey;

    }; // class StringMappingHandler

// ----------------------------------------------------------------------

    template <typename Target, typename RootHandler> class DocRootHandler : public HandlerBase<Target>
    {
     public:
        inline DocRootHandler(Target& aTarget) : HandlerBase<Target>(aTarget) {}

        inline virtual HandlerBase<Target>* StartObject() { return new RootHandler(HandlerBase<Target>::mTarget); }
    };

// ----------------------------------------------------------------------

    template <typename Target, typename RootHandler> class ReaderEventHandler : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, ReaderEventHandler<Target, RootHandler>>
    {
     private:
        template <typename... Args> inline bool handler(HandlerBase<Target>* (HandlerBase<Target>::*aHandler)(Args... args), Args... args)
            {
                try {
                    auto new_handler = ((*mHandler.top()).*aHandler)(args...);
                    if (new_handler)
                        mHandler.emplace(new_handler);
                }
                catch (Pop&) {
                    if (mHandler.empty())
                        return false;
                    mHandler.pop();
                }
                catch (Failure&) {
                    return false;
                }
                return true;
            }

     public:
        inline ReaderEventHandler(Target& aTarget)
            : mTarget(aTarget)
            {
                mHandler.emplace(new DocRootHandler<Target, RootHandler>(mTarget));
            }

        inline bool StartObject() { return handler(&HandlerBase<Target>::StartObject); }
        inline bool EndObject(rapidjson::SizeType /*memberCount*/) { return handler(&HandlerBase<Target>::EndObject); }
        inline bool StartArray() { return handler(&HandlerBase<Target>::StartArray); }
        inline bool EndArray(rapidjson::SizeType /*elementCount*/) { return handler(&HandlerBase<Target>::EndArray); }
        inline bool Key(const char* str, rapidjson::SizeType length, bool /*copy*/) { return handler(&HandlerBase<Target>::Key, str, length); }
        inline bool String(const char* str, rapidjson::SizeType length, bool /*copy*/) { return handler(&HandlerBase<Target>::String, str, length); }
        inline bool Int(int i) { return handler(&HandlerBase<Target>::Int, i); }
        inline bool Uint(unsigned u) { return handler(&HandlerBase<Target>::Uint, u); }
        inline bool Double(double d) { return handler(&HandlerBase<Target>::Double, d); }

          // inline bool Bool(bool /*b*/) { return false; }
          // inline bool Null() { std::cout << "Null()" << std::endl; return false; }
          // inline bool Int64(int64_t i) { std::cout << "Int64(" << i << ")" << std::endl; return false; }
          // inline bool Uint64(uint64_t u) { std::cout << "Uint64(" << u << ")" << std::endl; return false; }

     private:
        Target& mTarget;
        std::stack<std::unique_ptr<HandlerBase<Target>>> mHandler;
    };

// ----------------------------------------------------------------------

    template <typename Target, typename RootHandler> inline void read_from_file(std::string aFilename, Target& aTarget)
    {
        const std::string buffer = aFilename == "-" ? acmacs_base::read_stdin() : acmacs_base::read_file(aFilename);
        if (buffer[0] == '{') {
            ReaderEventHandler<Target, RootHandler> handler{aTarget};
            rapidjson::Reader reader;
            rapidjson::StringStream stream{buffer.c_str()};
            reader.Parse(stream, handler);
            if (reader.HasParseError())
                throw Error("cannot read " + aFilename + ": data parsing failed at pos " + std::to_string(reader.GetErrorOffset()) + ": " +  GetParseError_En(reader.GetParseErrorCode()) + "\n" + buffer.substr(reader.GetErrorOffset(), 50));
        }
        else
            throw json_reader::Error("cannot read " + aFilename + ": unrecognized source format");
    }

// ----------------------------------------------------------------------

} // namespace json_reader

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>ListHandler<> added<commit_after>#pragma once

#include <iostream>
#include <stdexcept>
#include <vector>
#include <map>
#include <stack>

#include "rapidjson/reader.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"

#include "acmacs-base/read-file.hh"

// ----------------------------------------------------------------------

namespace json_reader
{
    class Error : public std::runtime_error { public: using std::runtime_error::runtime_error; };

    class Failure : public std::exception { public: using std::exception::exception; };
    class Pop : public std::exception { public: using std::exception::exception; };

// ----------------------------------------------------------------------

    template <typename Target> class HandlerBase
    {
     public:
        inline HandlerBase(Target& aTarget) : mTarget(aTarget), mIgnore(false) {}
        virtual ~HandlerBase() {}

        inline virtual HandlerBase* StartObject() { std::cerr << "HandlerBase StartObject " << typeid(*this).name() << std::endl; throw Failure(); }
        inline virtual HandlerBase* EndObject() { throw Pop(); }
        inline virtual HandlerBase* StartArray() { throw Failure(); }
        inline virtual HandlerBase* EndArray() { throw Pop(); }
        inline virtual HandlerBase* Double(double d) { std::cerr << "Double: " << d << std::endl; throw Failure(); }
        inline virtual HandlerBase* Int(int i) { std::cerr << "Int: " << i << std::endl; throw Failure(); }
        inline virtual HandlerBase* Uint(unsigned u) { std::cerr << "Uint: " << u << std::endl; throw Failure(); }

        inline virtual HandlerBase* Key(const char* str, rapidjson::SizeType length)
            {
                if ((length == 1 && *str == '_') || (length > 0 && *str == '?')) {
                    mIgnore = true;
                }
                else {
                    std::cerr << "Key: \"" << std::string(str, length) << '"' << std::endl;
                    throw Failure();
                }
                return nullptr;
            }

        inline virtual HandlerBase* String(const char* str, rapidjson::SizeType length)
            {
                if (mIgnore) {
                    mIgnore = false;
                }
                else {
                    std::cerr << "String: \"" << std::string(str, length) << '"' << std::endl;
                    throw Failure();
                }
                return nullptr;
            }

     protected:
        Target& mTarget;
        bool mIgnore;
    };

// ----------------------------------------------------------------------

    template <typename Target, typename Element, typename ElementHandler> class ListHandler : public HandlerBase<Target>
    {
     public:
        inline ListHandler(Target& aTarget, std::vector<Element>& aList)
            : HandlerBase<Target>(aTarget), mList(aList), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartArray()
            {
                if (mStarted)
                    throw Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* StartObject()
            {
                if (!mStarted)
                    throw Failure();
                mList.emplace_back();
                return new ElementHandler(HandlerBase<Target>::mTarget, mList.back());
            }

        inline virtual HandlerBase<Target>* EndObject() { throw Failure(); }

     private:
        std::vector<Element>& mList;
        bool mStarted;

    }; // class StringListHandler

// ----------------------------------------------------------------------

    template <typename Target> class StringListHandler : public HandlerBase<Target>
    {
     public:
        inline StringListHandler(Target& aTarget, std::vector<std::string>& aList)
            : HandlerBase<Target>(aTarget), mList(aList), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartArray()
            {
                if (mStarted)
                    throw Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* EndObject() { throw Failure(); }

        inline virtual HandlerBase<Target>* String(const char* str, rapidjson::SizeType length)
            {
                mList.emplace_back(str, length);
                return nullptr;
            }

     private:
        std::vector<std::string>& mList;
        bool mStarted;

    }; // class StringListHandler

// ----------------------------------------------------------------------

    template <typename Target> class MapListHandler : public HandlerBase<Target>
    {
     public:
        inline MapListHandler(Target& aTarget, std::map<std::string, std::vector<std::string>>& aMap)
            : HandlerBase<Target>{aTarget}, mMap(aMap), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartObject()
            {
                if (mStarted)
                    throw Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* EndArray() { throw Failure(); }

        inline virtual HandlerBase<Target>* Key(const char* str, rapidjson::SizeType length)
            {
                return new StringListHandler<Target>(HandlerBase<Target>::mTarget, mMap[{str, length}]);
            }

     private:
        std::map<std::string, std::vector<std::string>>& mMap;
        bool mStarted;

    }; // class MapListHandler

// ----------------------------------------------------------------------

    template <typename Target> class StringMappingHandler : public HandlerBase<Target>
    {
     public:
        inline StringMappingHandler(Target& aTarget, std::vector<std::pair<std::string, std::string>>& aMapping)
            : HandlerBase<Target>{aTarget}, mMapping(aMapping), mStarted(false) {}

        inline virtual HandlerBase<Target>* StartObject()
            {
                if (mStarted)
                    throw json_reader::Failure();
                mStarted = true;
                return nullptr;
            }

        inline virtual HandlerBase<Target>* Key(const char* str, rapidjson::SizeType length)
            {
                mKey.assign(str, length);
                return nullptr;
            }

        inline virtual HandlerBase<Target>* String(const char* str, rapidjson::SizeType length)
            {
                if (mKey.empty())
                    throw json_reader::Failure();
                mMapping.emplace_back(mKey, std::string(str, length));
                mKey.erase();
                return nullptr;
            }

     private:
        std::vector<std::pair<std::string, std::string>>& mMapping;
        bool mStarted;
        std::string mKey;

    }; // class StringMappingHandler

// ----------------------------------------------------------------------

    template <typename Target, typename RootHandler> class DocRootHandler : public HandlerBase<Target>
    {
     public:
        inline DocRootHandler(Target& aTarget) : HandlerBase<Target>(aTarget) {}

        inline virtual HandlerBase<Target>* StartObject() { return new RootHandler(HandlerBase<Target>::mTarget); }
    };

// ----------------------------------------------------------------------

    template <typename Target, typename RootHandler> class ReaderEventHandler : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, ReaderEventHandler<Target, RootHandler>>
    {
     private:
        template <typename... Args> inline bool handler(HandlerBase<Target>* (HandlerBase<Target>::*aHandler)(Args... args), Args... args)
            {
                try {
                    auto new_handler = ((*mHandler.top()).*aHandler)(args...);
                    if (new_handler)
                        mHandler.emplace(new_handler);
                }
                catch (Pop&) {
                    if (mHandler.empty())
                        return false;
                    mHandler.pop();
                }
                catch (Failure&) {
                    return false;
                }
                return true;
            }

     public:
        inline ReaderEventHandler(Target& aTarget)
            : mTarget(aTarget)
            {
                mHandler.emplace(new DocRootHandler<Target, RootHandler>(mTarget));
            }

        inline bool StartObject() { return handler(&HandlerBase<Target>::StartObject); }
        inline bool EndObject(rapidjson::SizeType /*memberCount*/) { return handler(&HandlerBase<Target>::EndObject); }
        inline bool StartArray() { return handler(&HandlerBase<Target>::StartArray); }
        inline bool EndArray(rapidjson::SizeType /*elementCount*/) { return handler(&HandlerBase<Target>::EndArray); }
        inline bool Key(const char* str, rapidjson::SizeType length, bool /*copy*/) { return handler(&HandlerBase<Target>::Key, str, length); }
        inline bool String(const char* str, rapidjson::SizeType length, bool /*copy*/) { return handler(&HandlerBase<Target>::String, str, length); }
        inline bool Int(int i) { return handler(&HandlerBase<Target>::Int, i); }
        inline bool Uint(unsigned u) { return handler(&HandlerBase<Target>::Uint, u); }
        inline bool Double(double d) { return handler(&HandlerBase<Target>::Double, d); }

          // inline bool Bool(bool /*b*/) { return false; }
          // inline bool Null() { std::cout << "Null()" << std::endl; return false; }
          // inline bool Int64(int64_t i) { std::cout << "Int64(" << i << ")" << std::endl; return false; }
          // inline bool Uint64(uint64_t u) { std::cout << "Uint64(" << u << ")" << std::endl; return false; }

     private:
        Target& mTarget;
        std::stack<std::unique_ptr<HandlerBase<Target>>> mHandler;
    };

// ----------------------------------------------------------------------

    template <typename Target, typename RootHandler> inline void read_from_file(std::string aFilename, Target& aTarget)
    {
        const std::string buffer = aFilename == "-" ? acmacs_base::read_stdin() : acmacs_base::read_file(aFilename);
        if (buffer[0] == '{') {
            ReaderEventHandler<Target, RootHandler> handler{aTarget};
            rapidjson::Reader reader;
            rapidjson::StringStream stream{buffer.c_str()};
            reader.Parse(stream, handler);
            if (reader.HasParseError())
                throw Error("cannot read " + aFilename + ": data parsing failed at pos " + std::to_string(reader.GetErrorOffset()) + ": " +  GetParseError_En(reader.GetParseErrorCode()) + "\n" + buffer.substr(reader.GetErrorOffset(), 50));
        }
        else
            throw json_reader::Error("cannot read " + aFilename + ": unrecognized source format");
    }

// ----------------------------------------------------------------------

} // namespace json_reader

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>