<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 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$

#include <iostream>
#include <fstream>
#include <stdexcept>
#include <cstdarg>

#include "geos_datasource.hpp"
#include "geos_featureset.hpp"

// mapnik
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/geom_util.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/limits.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/filesystem/operations.hpp>

// geos
#include <geos_c.h>

using std::clog;
using std::endl;

using boost::lexical_cast;
using boost::bad_lexical_cast;

using mapnik::datasource;
using mapnik::parameters;

DATASOURCE_PLUGIN(geos_datasource)

using mapnik::box2d;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;

void notice(const char* fmt, ...)
{
    va_list ap;
    fprintf( stdout, "NOTICE: ");

    va_start (ap, fmt);
    vfprintf( stdout, fmt, ap);
    va_end(ap);
    fprintf( stdout, "\n" );
}

void log_and_exit(const char* fmt, ...)
{
    va_list ap;
    fprintf( stdout, "ERROR: ");

    va_start (ap, fmt);
    vfprintf( stdout, fmt, ap);
    va_end(ap);
    fprintf( stdout, "\n" );
}

geos_datasource::geos_datasource(parameters const& params, bool bind)
   : datasource(params),
     extent_(),
     extent_initialized_(false),
     type_(datasource::Vector),
     desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")),
     geometry_id_(0),
     geometry_data_(""),
     geometry_data_name_("name")
{
    boost::optional<std::string> geometry = params.get<std::string>("wkt");
    if (!geometry) throw datasource_exception("missing <wkt> parameter");
    geometry_string_ = *geometry;

    multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);

    boost::optional<std::string> ext = params_.get<std::string>("extent");
    if (ext) extent_initialized_ = extent_.from_string(*ext);

    boost::optional<int> id = params_.get<int>("gid");
    if (id) geometry_id_ = *id;

    boost::optional<std::string> gdata = params_.get<std::string>("field_data");
    if (gdata) geometry_data_ = *gdata;

    boost::optional<std::string> gdata_name = params_.get<std::string>("field_name");
    if (gdata) geometry_data_name_ = *gdata_name;

    desc_.add_descriptor(attribute_descriptor(geometry_data_name_, mapnik::String));

    if (bind)
    {
        this->bind();
    }
}

geos_datasource::~geos_datasource()
{
    if (is_bound_)
    {
        geometry_.set_feature(0);

#ifdef MAPNIK_DEBUG
        clog << "finalizing GEOS...";
#endif

        finishGEOS();

#ifdef MAPNIK_DEBUG
        clog << " finalized !" << endl;
#endif
    }
}

void geos_datasource::bind() const
{
    if (is_bound_) return;

#ifdef MAPNIK_DEBUG
    clog << "initializing GEOS...";
#endif

    // open ogr driver
    initGEOS(notice, log_and_exit);

#ifdef MAPNIK_DEBUG
    clog << " initialized !" << endl;
#endif

    // parse the string into geometry
    geometry_.set_feature(GEOSGeomFromWKT(geometry_string_.c_str()));

    if (*geometry_ == NULL || ! GEOSisValid(*geometry_))
    {
        throw datasource_exception("invalid <wkt> geometry specified");
    }

#ifdef MAPNIK_DEBUG
    clog << "geometry correctly parsed" << endl;
#endif

    // try to obtain the extent from the geometry itself
    if (! extent_initialized_)
    {
#ifdef MAPNIK_DEBUG
        clog << "initializing extent from geometry" << endl;
#endif

        geos_feature_ptr envelope (GEOSEnvelope(*geometry_));

        if (*envelope != NULL && GEOSisValid(*envelope))
        {
#ifdef MAPNIK_DEBUG
            char* wkt = GEOSGeomToWKT(*envelope);
            clog << "getting coord sequence from: " << wkt << endl;
            GEOSFree(wkt);
#endif

            const GEOSGeometry* exterior = GEOSGetExteriorRing(*envelope);

            if (exterior != NULL && GEOSisValid(exterior))
            {
                const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq(exterior);
                if (cs != NULL)
                {
#ifdef MAPNIK_DEBUG
                    clog << "iterating boundary points" << endl;
#endif

                    double x, y;
                    double minx = std::numeric_limits<float>::max(),
                           miny = std::numeric_limits<float>::max(),
                           maxx = -std::numeric_limits<float>::max(),
                           maxy = -std::numeric_limits<float>::max();
                    unsigned int num_points;

                    GEOSCoordSeq_getSize(cs, &num_points);

                    for (unsigned int i = 0; i < num_points; ++i)
                    {
                        GEOSCoordSeq_getX(cs, i, &x);
                        GEOSCoordSeq_getY(cs, i, &y);

                        if (x < minx) minx = x;
                        if (x > maxx) maxx = x;
                        if (y < miny) miny = y;
                        if (y > maxy) maxy = y;
                    }

                    extent_.init(minx,miny,maxx,maxy);
                    extent_initialized_ = true;
                }
            }
        }
    }

    if (! extent_initialized_)
        throw datasource_exception("cannot determine extent for <wkt> geometry");

    is_bound_ = true;
}

std::string geos_datasource::name()
{
    return "geos";
}

int geos_datasource::type() const
{
    return type_;
}

box2d<double> geos_datasource::envelope() const
{
    if (!is_bound_) bind();

    return extent_;
}

layer_descriptor geos_datasource::get_descriptor() const
{
    if (!is_bound_) bind();

    return desc_;
}

featureset_ptr geos_datasource::features(query const& q) const
{
    if (!is_bound_) bind();

    const mapnik::box2d<double> extent = q.get_bbox();

    std::ostringstream s;
    s << "POLYGON(("
      << extent.minx() << " " << extent.miny() << ","
      << extent.maxx() << " " << extent.miny() << ","
      << extent.maxx() << " " << extent.maxy() << ","
      << extent.minx() << " " << extent.maxy() << ","
      << extent.minx() << " " << extent.miny()
      << "))";

#ifdef MAPNIK_DEBUG
    clog << "using extent: " << s.str() << endl;
#endif

    return featureset_ptr(new geos_featureset (*geometry_,
                                               GEOSGeomFromWKT(s.str().c_str()),
                                               geometry_id_,
                                               geometry_data_,
                                               geometry_data_name_,
                                               desc_.get_encoding(),
                                               multiple_geometries_));
}

featureset_ptr geos_datasource::features_at_point(coord2d const& pt) const
{
    if (!is_bound_) bind();

    std::ostringstream s;
    s << "POINT(" << pt.x << " " << pt.y << ")";

#ifdef MAPNIK_DEBUG
    clog << "using point: " << s.str() << endl;
#endif

    return featureset_ptr(new geos_featureset (*geometry_,
                                               GEOSGeomFromWKT(s.str().c_str()),
                                               geometry_id_,
                                               geometry_data_,
                                               geometry_data_name_,
                                               desc_.get_encoding(),
                                               multiple_geometries_));
}

<commit_msg>+ fixed a compiler warning<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 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$

#include <iostream>
#include <fstream>
#include <stdexcept>
#include <cstdarg>

#include "geos_datasource.hpp"
#include "geos_featureset.hpp"

// mapnik
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/geom_util.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/limits.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/filesystem/operations.hpp>

// geos
#include <geos_c.h>

using std::clog;
using std::endl;

using boost::lexical_cast;
using boost::bad_lexical_cast;

using mapnik::datasource;
using mapnik::parameters;

DATASOURCE_PLUGIN(geos_datasource)

using mapnik::box2d;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;

void notice(const char* fmt, ...)
{
    va_list ap;
    fprintf( stdout, "NOTICE: ");

    va_start (ap, fmt);
    vfprintf( stdout, fmt, ap);
    va_end(ap);
    fprintf( stdout, "\n" );
}

void log_and_exit(const char* fmt, ...)
{
    va_list ap;
    fprintf( stdout, "ERROR: ");

    va_start (ap, fmt);
    vfprintf( stdout, fmt, ap);
    va_end(ap);
    fprintf( stdout, "\n" );
}

geos_datasource::geos_datasource(parameters const& params, bool bind)
   : datasource(params),
     extent_(),
     extent_initialized_(false),
     type_(datasource::Vector),
     desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")),
     geometry_data_(""),
     geometry_data_name_("name"),
     geometry_id_(0)
{
    boost::optional<std::string> geometry = params.get<std::string>("wkt");
    if (!geometry) throw datasource_exception("missing <wkt> parameter");
    geometry_string_ = *geometry;

    multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);

    boost::optional<std::string> ext = params_.get<std::string>("extent");
    if (ext) extent_initialized_ = extent_.from_string(*ext);

    boost::optional<int> id = params_.get<int>("gid");
    if (id) geometry_id_ = *id;

    boost::optional<std::string> gdata = params_.get<std::string>("field_data");
    if (gdata) geometry_data_ = *gdata;

    boost::optional<std::string> gdata_name = params_.get<std::string>("field_name");
    if (gdata) geometry_data_name_ = *gdata_name;

    desc_.add_descriptor(attribute_descriptor(geometry_data_name_, mapnik::String));

    if (bind)
    {
        this->bind();
    }
}

geos_datasource::~geos_datasource()
{
    if (is_bound_)
    {
        geometry_.set_feature(0);

#ifdef MAPNIK_DEBUG
        clog << "finalizing GEOS...";
#endif

        finishGEOS();

#ifdef MAPNIK_DEBUG
        clog << " finalized !" << endl;
#endif
    }
}

void geos_datasource::bind() const
{
    if (is_bound_) return;

#ifdef MAPNIK_DEBUG
    clog << "initializing GEOS...";
#endif

    // open ogr driver
    initGEOS(notice, log_and_exit);

#ifdef MAPNIK_DEBUG
    clog << " initialized !" << endl;
#endif

    // parse the string into geometry
    geometry_.set_feature(GEOSGeomFromWKT(geometry_string_.c_str()));

    if (*geometry_ == NULL || ! GEOSisValid(*geometry_))
    {
        throw datasource_exception("invalid <wkt> geometry specified");
    }

#ifdef MAPNIK_DEBUG
    clog << "geometry correctly parsed" << endl;
#endif

    // try to obtain the extent from the geometry itself
    if (! extent_initialized_)
    {
#ifdef MAPNIK_DEBUG
        clog << "initializing extent from geometry" << endl;
#endif

        geos_feature_ptr envelope (GEOSEnvelope(*geometry_));

        if (*envelope != NULL && GEOSisValid(*envelope))
        {
#ifdef MAPNIK_DEBUG
            char* wkt = GEOSGeomToWKT(*envelope);
            clog << "getting coord sequence from: " << wkt << endl;
            GEOSFree(wkt);
#endif

            const GEOSGeometry* exterior = GEOSGetExteriorRing(*envelope);

            if (exterior != NULL && GEOSisValid(exterior))
            {
                const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq(exterior);
                if (cs != NULL)
                {
#ifdef MAPNIK_DEBUG
                    clog << "iterating boundary points" << endl;
#endif

                    double x, y;
                    double minx = std::numeric_limits<float>::max(),
                           miny = std::numeric_limits<float>::max(),
                           maxx = -std::numeric_limits<float>::max(),
                           maxy = -std::numeric_limits<float>::max();
                    unsigned int num_points;

                    GEOSCoordSeq_getSize(cs, &num_points);

                    for (unsigned int i = 0; i < num_points; ++i)
                    {
                        GEOSCoordSeq_getX(cs, i, &x);
                        GEOSCoordSeq_getY(cs, i, &y);

                        if (x < minx) minx = x;
                        if (x > maxx) maxx = x;
                        if (y < miny) miny = y;
                        if (y > maxy) maxy = y;
                    }

                    extent_.init(minx,miny,maxx,maxy);
                    extent_initialized_ = true;
                }
            }
        }
    }

    if (! extent_initialized_)
        throw datasource_exception("cannot determine extent for <wkt> geometry");

    is_bound_ = true;
}

std::string geos_datasource::name()
{
    return "geos";
}

int geos_datasource::type() const
{
    return type_;
}

box2d<double> geos_datasource::envelope() const
{
    if (!is_bound_) bind();

    return extent_;
}

layer_descriptor geos_datasource::get_descriptor() const
{
    if (!is_bound_) bind();

    return desc_;
}

featureset_ptr geos_datasource::features(query const& q) const
{
    if (!is_bound_) bind();

    const mapnik::box2d<double> extent = q.get_bbox();

    std::ostringstream s;
    s << "POLYGON(("
      << extent.minx() << " " << extent.miny() << ","
      << extent.maxx() << " " << extent.miny() << ","
      << extent.maxx() << " " << extent.maxy() << ","
      << extent.minx() << " " << extent.maxy() << ","
      << extent.minx() << " " << extent.miny()
      << "))";

#ifdef MAPNIK_DEBUG
    clog << "using extent: " << s.str() << endl;
#endif

    return featureset_ptr(new geos_featureset (*geometry_,
                                               GEOSGeomFromWKT(s.str().c_str()),
                                               geometry_id_,
                                               geometry_data_,
                                               geometry_data_name_,
                                               desc_.get_encoding(),
                                               multiple_geometries_));
}

featureset_ptr geos_datasource::features_at_point(coord2d const& pt) const
{
    if (!is_bound_) bind();

    std::ostringstream s;
    s << "POINT(" << pt.x << " " << pt.y << ")";

#ifdef MAPNIK_DEBUG
    clog << "using point: " << s.str() << endl;
#endif

    return featureset_ptr(new geos_featureset (*geometry_,
                                               GEOSGeomFromWKT(s.str().c_str()),
                                               geometry_id_,
                                               geometry_data_,
                                               geometry_data_name_,
                                               desc_.get_encoding(),
                                               multiple_geometries_));
}

<|endoftext|>


<commit_before>#include "kernelconnection.h"
#include "trace.h"
#include "pcfparser/ParaverTraceConfig.h"
#include "pcfparser/ParaverStatesColor.h"
#include "pcfparser/ParaverGradientColor.h"

using namespace domain;

Trace *Trace::create( KernelConnection *whichKernel, const string& whichFile )
{
  return new TraceProxy( whichKernel, whichFile );
}

Trace::Trace( KernelConnection *whichKernel ):
    myKernel( whichKernel )
{}

TraceProxy::TraceProxy( KernelConnection *whichKernel, const string& whichFile ):
    Trace( whichKernel )
{
  myTrace = myKernel->newTrace( whichFile );
  string pcfFile( whichFile.substr( 0, whichFile.length() - 3 ) );
  pcfFile.append( "pcf" );
  parsePCF( pcfFile );
}

TraceProxy::~TraceProxy()
{
  delete myTrace;
}

string TraceProxy::getFileName()const
{
  return myTrace->getFileName();
}

void TraceProxy::dumpFile( const string& whichFile ) const
{
  myTrace->dumpFile( whichFile );
}

TApplOrder TraceProxy::totalApplications() const
{
  return myTrace->totalApplications();
}

TTaskOrder TraceProxy::totalTasks() const
{
  return myTrace->totalTasks();
}

TTaskOrder TraceProxy::getGlobalTask( const TApplOrder& inAppl,
                                      const TTaskOrder& inTask ) const
{
  return myTrace->getGlobalTask( inAppl, inTask );
}

void TraceProxy::getTaskLocation( TTaskOrder globalTask,
                                  TApplOrder& inAppl,
                                  TTaskOrder& inTask ) const
{
  myTrace->getTaskLocation( globalTask, inAppl, inTask );
}

TTaskOrder TraceProxy::getFirstTask( TApplOrder inAppl ) const
{
  return myTrace->getFirstTask( inAppl );
}

TTaskOrder TraceProxy::getLastTask( TApplOrder inAppl ) const
{
  return myTrace->getLastTask( inAppl );
}

TThreadOrder TraceProxy::totalThreads() const
{
  return myTrace->totalThreads();
}

TThreadOrder TraceProxy::getGlobalThread( const TApplOrder& inAppl,
    const TTaskOrder& inTask,
    const TThreadOrder& inThread ) const
{
  return myTrace->getGlobalThread( inAppl, inTask, inThread );
}

void TraceProxy::getThreadLocation( TThreadOrder globalThread,
                                    TApplOrder& inAppl,
                                    TTaskOrder& inTask,
                                    TThreadOrder& inThread ) const
{
  myTrace->getThreadLocation( globalThread, inAppl, inTask, inThread );
}

TThreadOrder TraceProxy::getFirstThread( TApplOrder inAppl, TTaskOrder inTask ) const
{
  return myTrace->getFirstThread( inAppl, inTask );
}

TThreadOrder TraceProxy::getLastThread( TApplOrder inAppl, TTaskOrder inTask ) const
{
  return myTrace->getLastThread( inAppl, inTask );
}

bool TraceProxy::existResourceInfo() const
{
  return myTrace->existResourceInfo();
}

TNodeOrder TraceProxy::totalNodes() const
{
  return myTrace->totalNodes();
}

TCPUOrder TraceProxy::totalCPUs() const
{
  return myTrace->totalCPUs();
}

TCPUOrder TraceProxy::getGlobalCPU( const TNodeOrder& inNode,
                                    const TCPUOrder& inCPU ) const
{
  return myTrace->getGlobalCPU( inNode, inCPU );
}

void TraceProxy::getCPULocation( TCPUOrder globalCPU,
                                 TNodeOrder& inNode,
                                 TCPUOrder& inCPU ) const
{
  myTrace->getCPULocation( globalCPU, inNode, inCPU );
}

TCPUOrder TraceProxy::getFirstCPU( TNodeOrder inNode ) const
{
  return myTrace->getFirstCPU( inNode );
}

TCPUOrder TraceProxy::getLastCPU( TNodeOrder inNode ) const
{
  return myTrace->getLastCPU( inNode );
}

TObjectOrder TraceProxy::getFirst( TObjectOrder globalOrder,
                                   TWindowLevel fromLevel,
                                   TWindowLevel toLevel ) const
{
  return myTrace->getFirst( globalOrder, fromLevel, toLevel );
}

TObjectOrder TraceProxy::getLast( TObjectOrder globalOrder,
                                  TWindowLevel fromLevel,
                                  TWindowLevel toLevel ) const
{
  return myTrace->getLast( globalOrder, fromLevel, toLevel );
}

TThreadOrder TraceProxy::getSenderThread( TCommID whichComm ) const
{
  return myTrace->getSenderThread( whichComm );
}

TCPUOrder TraceProxy::getSenderCPU( TCommID whichComm ) const
{
  return myTrace->getSenderCPU( whichComm );
}

TThreadOrder TraceProxy::getReceiverThread( TCommID whichComm ) const
{
  return myTrace->getReceiverThread( whichComm );
}

TCPUOrder TraceProxy::getReceiverCPU( TCommID whichComm ) const
{
  return myTrace->getReceiverCPU( whichComm );
}

TCommTag TraceProxy::getCommTag( TCommID whichComm ) const
{
  return myTrace->getCommTag( whichComm );
}

TCommSize TraceProxy::getCommSize( TCommID whichComm ) const
{
  return myTrace->getCommSize( whichComm );
}

TRecordTime TraceProxy::getLogicalSend( TCommID whichComm ) const
{
  return myTrace->getLogicalSend( whichComm );
}

TRecordTime TraceProxy::getLogicalReceive( TCommID whichComm ) const
{
  return myTrace->getLogicalReceive( whichComm );
}

TRecordTime TraceProxy::getPhysicalSend( TCommID whichComm ) const
{
  return myTrace->getPhysicalSend( whichComm );
}

TRecordTime TraceProxy::getPhysicalReceive( TCommID whichComm ) const
{
  return myTrace->getPhysicalReceive( whichComm );
}

TTime TraceProxy::getEndTime() const
{
  return myTrace->getEndTime();
}

TTimeUnit TraceProxy::getTimeUnit() const
{
  return myTrace->getTimeUnit();
}

Trace *TraceProxy::getConcrete() const
{
  return myTrace;
}

void TraceProxy::parsePCF( const string& whichFile )
{
  ParaverTraceConfig *config;

  try
  {
    config = new ParaverTraceConfig( whichFile );
  }
  catch( ... )
  {
    return;
  }

  rgb tmpColor;
  for ( vector<ParaverStatesColor *>::const_iterator it = config->get_statesColor().begin();
        it != config->get_statesColor().end(); it++ )
  {
    tmpColor.red = (*it)->get_color1();
    tmpColor.green = (*it)->get_color2();
    tmpColor.blue = (*it)->get_color3();
    if( (UINT32)(*it)->get_key() < myCodeColor.getNumColors() )
      myCodeColor.setColor( (UINT32)(*it)->get_key(), tmpColor );
    else
      myCodeColor.addColor( tmpColor );
  }

  ParaverGradientColor *grad = ( config->get_gradientColors() )[ 0 ];
  tmpColor.red = grad->get_color1();
  tmpColor.green = grad->get_color2();
  tmpColor.blue = grad->get_color3();
  myGradientColor.setBeginGradientColor( tmpColor );

  grad = ( config->get_gradientColors() )[ config->get_gradientColors().size() ];
  tmpColor.red = grad->get_color1();
  tmpColor.green = grad->get_color2();
  tmpColor.blue = grad->get_color3();
  myGradientColor.setEndGradientColor( tmpColor );

  delete config;
}

const CodeColor& TraceProxy::getCodeColor() const
{
  return myCodeColor;
}

const GradientColor& TraceProxy::getGradientColor() const
{
  return myGradientColor;
}
<commit_msg>*** empty log message ***<commit_after>#include "kernelconnection.h"
#include "trace.h"
#include "pcfparser/ParaverTraceConfig.h"
#include "pcfparser/ParaverStatesColor.h"
#include "pcfparser/ParaverGradientColor.h"

using namespace domain;

Trace *Trace::create( KernelConnection *whichKernel, const string& whichFile )
{
  return new TraceProxy( whichKernel, whichFile );
}

Trace::Trace( KernelConnection *whichKernel ):
    myKernel( whichKernel )
{}

TraceProxy::TraceProxy( KernelConnection *whichKernel, const string& whichFile ):
    Trace( whichKernel )
{
  myTrace = myKernel->newTrace( whichFile );
  string pcfFile( whichFile.substr( 0, whichFile.length() - 3 ) );
  pcfFile.append( "pcf" );
  parsePCF( pcfFile );
}

TraceProxy::~TraceProxy()
{
  delete myTrace;
}

string TraceProxy::getFileName()const
{
  return myTrace->getFileName();
}

void TraceProxy::dumpFile( const string& whichFile ) const
{
  myTrace->dumpFile( whichFile );
}

TApplOrder TraceProxy::totalApplications() const
{
  return myTrace->totalApplications();
}

TTaskOrder TraceProxy::totalTasks() const
{
  return myTrace->totalTasks();
}

TTaskOrder TraceProxy::getGlobalTask( const TApplOrder& inAppl,
                                      const TTaskOrder& inTask ) const
{
  return myTrace->getGlobalTask( inAppl, inTask );
}

void TraceProxy::getTaskLocation( TTaskOrder globalTask,
                                  TApplOrder& inAppl,
                                  TTaskOrder& inTask ) const
{
  myTrace->getTaskLocation( globalTask, inAppl, inTask );
}

TTaskOrder TraceProxy::getFirstTask( TApplOrder inAppl ) const
{
  return myTrace->getFirstTask( inAppl );
}

TTaskOrder TraceProxy::getLastTask( TApplOrder inAppl ) const
{
  return myTrace->getLastTask( inAppl );
}

TThreadOrder TraceProxy::totalThreads() const
{
  return myTrace->totalThreads();
}

TThreadOrder TraceProxy::getGlobalThread( const TApplOrder& inAppl,
    const TTaskOrder& inTask,
    const TThreadOrder& inThread ) const
{
  return myTrace->getGlobalThread( inAppl, inTask, inThread );
}

void TraceProxy::getThreadLocation( TThreadOrder globalThread,
                                    TApplOrder& inAppl,
                                    TTaskOrder& inTask,
                                    TThreadOrder& inThread ) const
{
  myTrace->getThreadLocation( globalThread, inAppl, inTask, inThread );
}

TThreadOrder TraceProxy::getFirstThread( TApplOrder inAppl, TTaskOrder inTask ) const
{
  return myTrace->getFirstThread( inAppl, inTask );
}

TThreadOrder TraceProxy::getLastThread( TApplOrder inAppl, TTaskOrder inTask ) const
{
  return myTrace->getLastThread( inAppl, inTask );
}

bool TraceProxy::existResourceInfo() const
{
  return myTrace->existResourceInfo();
}

TNodeOrder TraceProxy::totalNodes() const
{
  return myTrace->totalNodes();
}

TCPUOrder TraceProxy::totalCPUs() const
{
  return myTrace->totalCPUs();
}

TCPUOrder TraceProxy::getGlobalCPU( const TNodeOrder& inNode,
                                    const TCPUOrder& inCPU ) const
{
  return myTrace->getGlobalCPU( inNode, inCPU );
}

void TraceProxy::getCPULocation( TCPUOrder globalCPU,
                                 TNodeOrder& inNode,
                                 TCPUOrder& inCPU ) const
{
  myTrace->getCPULocation( globalCPU, inNode, inCPU );
}

TCPUOrder TraceProxy::getFirstCPU( TNodeOrder inNode ) const
{
  return myTrace->getFirstCPU( inNode );
}

TCPUOrder TraceProxy::getLastCPU( TNodeOrder inNode ) const
{
  return myTrace->getLastCPU( inNode );
}

TObjectOrder TraceProxy::getFirst( TObjectOrder globalOrder,
                                   TWindowLevel fromLevel,
                                   TWindowLevel toLevel ) const
{
  return myTrace->getFirst( globalOrder, fromLevel, toLevel );
}

TObjectOrder TraceProxy::getLast( TObjectOrder globalOrder,
                                  TWindowLevel fromLevel,
                                  TWindowLevel toLevel ) const
{
  return myTrace->getLast( globalOrder, fromLevel, toLevel );
}

TThreadOrder TraceProxy::getSenderThread( TCommID whichComm ) const
{
  return myTrace->getSenderThread( whichComm );
}

TCPUOrder TraceProxy::getSenderCPU( TCommID whichComm ) const
{
  return myTrace->getSenderCPU( whichComm );
}

TThreadOrder TraceProxy::getReceiverThread( TCommID whichComm ) const
{
  return myTrace->getReceiverThread( whichComm );
}

TCPUOrder TraceProxy::getReceiverCPU( TCommID whichComm ) const
{
  return myTrace->getReceiverCPU( whichComm );
}

TCommTag TraceProxy::getCommTag( TCommID whichComm ) const
{
  return myTrace->getCommTag( whichComm );
}

TCommSize TraceProxy::getCommSize( TCommID whichComm ) const
{
  return myTrace->getCommSize( whichComm );
}

TRecordTime TraceProxy::getLogicalSend( TCommID whichComm ) const
{
  return myTrace->getLogicalSend( whichComm );
}

TRecordTime TraceProxy::getLogicalReceive( TCommID whichComm ) const
{
  return myTrace->getLogicalReceive( whichComm );
}

TRecordTime TraceProxy::getPhysicalSend( TCommID whichComm ) const
{
  return myTrace->getPhysicalSend( whichComm );
}

TRecordTime TraceProxy::getPhysicalReceive( TCommID whichComm ) const
{
  return myTrace->getPhysicalReceive( whichComm );
}

TTime TraceProxy::getEndTime() const
{
  return myTrace->getEndTime();
}

TTimeUnit TraceProxy::getTimeUnit() const
{
  return myTrace->getTimeUnit();
}

Trace *TraceProxy::getConcrete() const
{
  return myTrace;
}

void TraceProxy::parsePCF( const string& whichFile )
{
  ParaverTraceConfig *config;

  try
  {
    config = new ParaverTraceConfig( whichFile );
  }
  catch( ... )
  {
    return;
  }

  rgb tmpColor;
  for ( vector<ParaverStatesColor *>::const_iterator it = config->get_statesColor().begin();
        it != config->get_statesColor().end(); it++ )
  {
    tmpColor.red = (*it)->get_color1();
    tmpColor.green = (*it)->get_color2();
    tmpColor.blue = (*it)->get_color3();
    if( (UINT32)(*it)->get_key() < myCodeColor.getNumColors() )
      myCodeColor.setColor( (UINT32)(*it)->get_key(), tmpColor );
    else
      myCodeColor.addColor( tmpColor );
  }

  ParaverGradientColor *grad = ( config->get_gradientColors() )[ 0 ];
  tmpColor.red = grad->get_color1();
  tmpColor.green = grad->get_color2();
  tmpColor.blue = grad->get_color3();
  myGradientColor.setBeginGradientColor( tmpColor );

  grad = ( config->get_gradientColors() )[ config->get_gradientColors().size() - 1];
  tmpColor.red = grad->get_color1();
  tmpColor.green = grad->get_color2();
  tmpColor.blue = grad->get_color3();
  myGradientColor.setEndGradientColor( tmpColor );

  delete config;
}

const CodeColor& TraceProxy::getCodeColor() const
{
  return myCodeColor;
}

const GradientColor& TraceProxy::getGradientColor() const
{
  return myGradientColor;
}
<|endoftext|>


<commit_before>/* \author Bastian Steder */

/* ---[ */
#include <iostream>
using namespace std;
#include <pcl/io/openni_grabber.h>
#include <pcl/range_image/range_image_planar.h>
#include <pcl/common/common_headers.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/keypoints/narf_keypoint.h>
#include <pcl/console/parse.h>

std::string device_id = "#1";

float angular_resolution = 0.5;
float support_size = 0.2f;
bool set_unseen_to_max_range = true;
int max_no_of_threads = 1;
float min_interest_value = 0.5;

boost::mutex depth_image_mutex,
             ir_image_mutex,
             image_mutex;
pcl::PointCloud<pcl::PointXYZ>::ConstPtr point_cloud_ptr;
boost::shared_ptr<openni_wrapper::DepthImage> depth_image_ptr;
boost::shared_ptr<openni_wrapper::IRImage> ir_image_ptr;
boost::shared_ptr<openni_wrapper::Image> image_ptr;

bool received_new_depth_data = false,
     received_new_ir_image   = false,
     received_new_image   = false;
struct EventHelper
{
  void
  depth_image_cb (const boost::shared_ptr<openni_wrapper::DepthImage>& depth_image)
  {
    if (depth_image_mutex.try_lock ())
    {
      depth_image_ptr = depth_image;
      depth_image_mutex.unlock ();
      received_new_depth_data = true;
    }
  }
};

void
printUsage (const char* progName)
{
  cout << "\n\nUsage: "<<progName<<" [options] [scene.pcd] <model.pcl> [model_2.pcl] ... [model_n.pcl]\n\n"
       << "Options:\n"
       << "-------------------------------------------\n"
       << "-d <device_id>  set the device id (default \""<<device_id<<"\")\n"
       << "-r <float>      angular resolution in degrees (default "<<angular_resolution<<")\n"
       << "-s <float>      support size for the interest points (diameter of the used sphere in meters)"
       <<                 " (default "<<support_size<<")\n"
       << "-i <float>      minimum interest value (0-1) (default "<<min_interest_value<<")"
       << "-t <int>        maximum number of threads to use (default "<< max_no_of_threads<<")\n"
       << "-h              this help\n"
       << "\n\n";
}

int main (int argc, char** argv)
{
  // --------------------------------------
  // -----Parse Command Line Arguments-----
  // --------------------------------------
  if (pcl::console::find_argument (argc, argv, "-h") >= 0)
  {
    printUsage (argv[0]);
    return 0;
  }
  if (pcl::console::parse (argc, argv, "-d", device_id) >= 0)
    cout << "Using device id \""<<device_id<<"\".\n";
  if (pcl::console::parse (argc, argv, "-r", angular_resolution) >= 0)
    cout << "Setting angular resolution to "<<angular_resolution<<"deg.\n";
  angular_resolution = pcl::deg2rad (angular_resolution);
  if (pcl::console::parse (argc, argv, "-s", support_size) >= 0)
    cout << "Setting support size to "<<support_size<<"m.\n";
  if (pcl::console::parse (argc, argv, "-i", min_interest_value) >= 0)
    cout << "Setting minimum interest value to "<<min_interest_value<<".\n";
  if (pcl::console::parse (argc, argv, "-t", max_no_of_threads) >= 0)
    cout << "Setting maximum number of threads to "<<max_no_of_threads<<".\n";

  pcl::visualization::RangeImageVisualizer range_image_widget ("Range Image");

  pcl::visualization::PCLVisualizer viewer ("3D Viewer");
  viewer.addCoordinateSystem (1.0f);
  viewer.setBackgroundColor (1, 1, 1);

  viewer.initCameraParameters ();
  viewer.camera_.pos[0] = 0.0;
  viewer.camera_.pos[1] = -0.3;
  viewer.camera_.pos[2] = -2.0;
  viewer.camera_.focal[0] = 0.0;
  viewer.camera_.focal[1] = 0.0+viewer.camera_.pos[1];
  viewer.camera_.focal[2] = 1.0;
  viewer.camera_.view[0] = 0.0;
  viewer.camera_.view[1] = -1.0;
  viewer.camera_.view[2] = 0.0;
  viewer.updateCamera ();

  openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
  if (driver.getNumberDevices () > 0)
  {
    for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
    {
      cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx)
           << ", product: " << driver.getProductName (deviceIdx) << ", connected: "
           << (int) driver.getBus (deviceIdx) << " @ " << (int) driver.getAddress (deviceIdx)
           << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'\n";
    }
  }
  else
  {
    cout << "\nNo devices connected.\n\n";
    return 1;
  }

  pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id);
  EventHelper event_helper;

  boost::function<void (const boost::shared_ptr<openni_wrapper::DepthImage>&) > f_depth_image =
    boost::bind (&EventHelper::depth_image_cb, &event_helper, _1);
  boost::signals2::connection c_depth_image = interface->registerCallback (f_depth_image);

  cout << "Starting grabber\n";
  interface->start ();
  cout << "Done\n";

  boost::shared_ptr<pcl::RangeImagePlanar> range_image_planar_ptr (new pcl::RangeImagePlanar);
  pcl::RangeImagePlanar& range_image_planar = *range_image_planar_ptr;

  pcl::RangeImageBorderExtractor range_image_border_extractor;
  pcl::NarfKeypoint narf_keypoint_detector;
  narf_keypoint_detector.setRangeImageBorderExtractor (&range_image_border_extractor);
  narf_keypoint_detector.getParameters ().support_size = support_size;
  narf_keypoint_detector.getParameters ().max_no_of_threads = max_no_of_threads;
  narf_keypoint_detector.getParameters ().min_interest_value = min_interest_value;
  //narf_keypoint_detector.getParameters ().calculate_sparse_interest_image = false;
  //narf_keypoint_detector.getParameloadters ().add_points_on_straight_edges = true;

  pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>& keypoints_cloud = *keypoints_cloud_ptr;

  while (!viewer.wasStopped ())
  {
    viewer.spinOnce ();
    range_image_widget.spinOnce ();  // process GUI events
    pcl_sleep (0.01);

    bool got_new_range_image = false;
    if (received_new_depth_data && depth_image_mutex.try_lock ())
    {
      received_new_depth_data = false;

      //unsigned long time_stamp = depth_image_ptr->getTimeStamp ();
      //int frame_id = depth_image_ptr->getFrameID ();
      const unsigned short* depth_map = depth_image_ptr->getDepthMetaData ().Data ();
      int width = depth_image_ptr->getWidth (), height = depth_image_ptr->getHeight ();
      float center_x = width/2, center_y = height/2;
      float focal_length_x = depth_image_ptr->getFocalLength (), focal_length_y = focal_length_x;
      float original_angular_resolution = asinf (0.5f*float (width)/float (focal_length_x)) / (0.5f*float (width));
      float desired_angular_resolution = angular_resolution;
      range_image_planar.setDepthImage (depth_map, width, height, center_x, center_y,
                                        focal_length_x, focal_length_y, desired_angular_resolution);
      depth_image_mutex.unlock ();
      got_new_range_image = !range_image_planar.points.empty ();
    }

    if (!got_new_range_image)
      continue;

    // --------------------------------
    // -----Extract NARF keypoints-----
    // --------------------------------
    if (set_unseen_to_max_range)
      range_image_planar.setUnseenToMaxRange ();
    narf_keypoint_detector.setRangeImage (&range_image_planar);
    pcl::PointCloud<int> keypoint_indices;
    double keypoint_extraction_start_time = pcl::getTime();
    narf_keypoint_detector.compute (keypoint_indices);
    double keypoint_extraction_time = pcl::getTime()-keypoint_extraction_start_time;
    std::cout << "Found "<<keypoint_indices.points.size ()<<" key points. "
              << "This took "<<1000.0*keypoint_extraction_time<<"ms.\n";

    // ----------------------------------------------
    // -----Show keypoints in range image widget-----
    // ----------------------------------------------
    range_image_widget.showRangeImage (range_image_planar, 0.5f, 10.0f);
    //for (size_t i=0; i<keypoint_indices.points.size (); ++i)
      //range_image_widget.markPoint (keypoint_indices.points[i]%range_image_planar.width,
                                    //keypoint_indices.points[i]/range_image_planar.width,
                                    //pcl::visualization::Vector3ub (0,255,0));

    // -------------------------------------
    // -----Show keypoints in 3D viewer-----
    // -------------------------------------
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> color_handler_cloud
      (range_image_planar_ptr, 0, 0, 0);
    if (!viewer.updatePointCloud<pcl::PointWithRange> (range_image_planar_ptr, color_handler_cloud, "range image"))
      viewer.addPointCloud<pcl::PointWithRange> (range_image_planar_ptr, color_handler_cloud, "range image");

    keypoints_cloud.points.resize (keypoint_indices.points.size ());
    for (size_t i=0; i<keypoint_indices.points.size (); ++i)
      keypoints_cloud.points[i].getVector3fMap () =
        range_image_planar.points[keypoint_indices.points[i]].getVector3fMap ();
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler_keypoints
      (keypoints_cloud_ptr, 0, 255, 0);
    if (!viewer.updatePointCloud (keypoints_cloud_ptr, color_handler_keypoints, "keypoints"))
      viewer.addPointCloud (keypoints_cloud_ptr, color_handler_keypoints, "keypoints");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");
  }

  interface->stop ();
}
<commit_msg>another tutorial fix<commit_after>/* \author Bastian Steder */

/* ---[ */
#include <iostream>
using namespace std;
#include <pcl/io/openni_grabber.h>
#include <pcl/range_image/range_image_planar.h>
#include <pcl/common/common_headers.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/keypoints/narf_keypoint.h>
#include <pcl/console/parse.h>

std::string device_id = "#1";

float angular_resolution = 0.5;
float support_size = 0.2f;
bool set_unseen_to_max_range = true;
int max_no_of_threads = 1;
float min_interest_value = 0.5;

boost::mutex depth_image_mutex,
             ir_image_mutex,
             image_mutex;
pcl::PointCloud<pcl::PointXYZ>::ConstPtr point_cloud_ptr;
boost::shared_ptr<openni_wrapper::DepthImage> depth_image_ptr;
boost::shared_ptr<openni_wrapper::IRImage> ir_image_ptr;
boost::shared_ptr<openni_wrapper::Image> image_ptr;

bool received_new_depth_data = false,
     received_new_ir_image   = false,
     received_new_image   = false;
struct EventHelper
{
  void
  depth_image_cb (const boost::shared_ptr<openni_wrapper::DepthImage>& depth_image)
  {
    if (depth_image_mutex.try_lock ())
    {
      depth_image_ptr = depth_image;
      depth_image_mutex.unlock ();
      received_new_depth_data = true;
    }
  }
};

void
printUsage (const char* progName)
{
  cout << "\n\nUsage: "<<progName<<" [options] [scene.pcd] <model.pcl> [model_2.pcl] ... [model_n.pcl]\n\n"
       << "Options:\n"
       << "-------------------------------------------\n"
       << "-d <device_id>  set the device id (default \""<<device_id<<"\")\n"
       << "-r <float>      angular resolution in degrees (default "<<angular_resolution<<")\n"
       << "-s <float>      support size for the interest points (diameter of the used sphere in meters)"
       <<                 " (default "<<support_size<<")\n"
       << "-i <float>      minimum interest value (0-1) (default "<<min_interest_value<<")"
       << "-t <int>        maximum number of threads to use (default "<< max_no_of_threads<<")\n"
       << "-h              this help\n"
       << "\n\n";
}

int main (int argc, char** argv)
{
  // --------------------------------------
  // -----Parse Command Line Arguments-----
  // --------------------------------------
  if (pcl::console::find_argument (argc, argv, "-h") >= 0)
  {
    printUsage (argv[0]);
    return 0;
  }
  if (pcl::console::parse (argc, argv, "-d", device_id) >= 0)
    cout << "Using device id \""<<device_id<<"\".\n";
  if (pcl::console::parse (argc, argv, "-r", angular_resolution) >= 0)
    cout << "Setting angular resolution to "<<angular_resolution<<"deg.\n";
  angular_resolution = pcl::deg2rad (angular_resolution);
  if (pcl::console::parse (argc, argv, "-s", support_size) >= 0)
    cout << "Setting support size to "<<support_size<<"m.\n";
  if (pcl::console::parse (argc, argv, "-i", min_interest_value) >= 0)
    cout << "Setting minimum interest value to "<<min_interest_value<<".\n";
  if (pcl::console::parse (argc, argv, "-t", max_no_of_threads) >= 0)
    cout << "Setting maximum number of threads to "<<max_no_of_threads<<".\n";

  pcl::visualization::RangeImageVisualizer range_image_widget ("Range Image");

  pcl::visualization::PCLVisualizer viewer ("3D Viewer");
  viewer.addCoordinateSystem (1.0f);
  viewer.setBackgroundColor (1, 1, 1);

  viewer.initCameraParameters ();
  viewer.setCameraPosition (0.0, -0.3, -2.0,
                            0.0, -0.3, 1.0,
                            0.0, -1.0, 0.0);

  openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
  if (driver.getNumberDevices () > 0)
  {
    for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
    {
      cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx)
           << ", product: " << driver.getProductName (deviceIdx) << ", connected: "
           << (int) driver.getBus (deviceIdx) << " @ " << (int) driver.getAddress (deviceIdx)
           << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'\n";
    }
  }
  else
  {
    cout << "\nNo devices connected.\n\n";
    return 1;
  }

  pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id);
  EventHelper event_helper;

  boost::function<void (const boost::shared_ptr<openni_wrapper::DepthImage>&) > f_depth_image =
    boost::bind (&EventHelper::depth_image_cb, &event_helper, _1);
  boost::signals2::connection c_depth_image = interface->registerCallback (f_depth_image);

  cout << "Starting grabber\n";
  interface->start ();
  cout << "Done\n";

  boost::shared_ptr<pcl::RangeImagePlanar> range_image_planar_ptr (new pcl::RangeImagePlanar);
  pcl::RangeImagePlanar& range_image_planar = *range_image_planar_ptr;

  pcl::RangeImageBorderExtractor range_image_border_extractor;
  pcl::NarfKeypoint narf_keypoint_detector;
  narf_keypoint_detector.setRangeImageBorderExtractor (&range_image_border_extractor);
  narf_keypoint_detector.getParameters ().support_size = support_size;
  narf_keypoint_detector.getParameters ().max_no_of_threads = max_no_of_threads;
  narf_keypoint_detector.getParameters ().min_interest_value = min_interest_value;
  //narf_keypoint_detector.getParameters ().calculate_sparse_interest_image = false;
  //narf_keypoint_detector.getParameloadters ().add_points_on_straight_edges = true;

  pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>& keypoints_cloud = *keypoints_cloud_ptr;

  while (!viewer.wasStopped ())
  {
    viewer.spinOnce ();
    range_image_widget.spinOnce ();  // process GUI events
    pcl_sleep (0.01);

    bool got_new_range_image = false;
    if (received_new_depth_data && depth_image_mutex.try_lock ())
    {
      received_new_depth_data = false;

      //unsigned long time_stamp = depth_image_ptr->getTimeStamp ();
      //int frame_id = depth_image_ptr->getFrameID ();
      const unsigned short* depth_map = depth_image_ptr->getDepthMetaData ().Data ();
      int width = depth_image_ptr->getWidth (), height = depth_image_ptr->getHeight ();
      float center_x = width/2, center_y = height/2;
      float focal_length_x = depth_image_ptr->getFocalLength (), focal_length_y = focal_length_x;
      float original_angular_resolution = asinf (0.5f*float (width)/float (focal_length_x)) / (0.5f*float (width));
      float desired_angular_resolution = angular_resolution;
      range_image_planar.setDepthImage (depth_map, width, height, center_x, center_y,
                                        focal_length_x, focal_length_y, desired_angular_resolution);
      depth_image_mutex.unlock ();
      got_new_range_image = !range_image_planar.points.empty ();
    }

    if (!got_new_range_image)
      continue;

    // --------------------------------
    // -----Extract NARF keypoints-----
    // --------------------------------
    if (set_unseen_to_max_range)
      range_image_planar.setUnseenToMaxRange ();
    narf_keypoint_detector.setRangeImage (&range_image_planar);
    pcl::PointCloud<int> keypoint_indices;
    double keypoint_extraction_start_time = pcl::getTime();
    narf_keypoint_detector.compute (keypoint_indices);
    double keypoint_extraction_time = pcl::getTime()-keypoint_extraction_start_time;
    std::cout << "Found "<<keypoint_indices.points.size ()<<" key points. "
              << "This took "<<1000.0*keypoint_extraction_time<<"ms.\n";

    // ----------------------------------------------
    // -----Show keypoints in range image widget-----
    // ----------------------------------------------
    range_image_widget.showRangeImage (range_image_planar, 0.5f, 10.0f);
    //for (size_t i=0; i<keypoint_indices.points.size (); ++i)
      //range_image_widget.markPoint (keypoint_indices.points[i]%range_image_planar.width,
                                    //keypoint_indices.points[i]/range_image_planar.width,
                                    //pcl::visualization::Vector3ub (0,255,0));

    // -------------------------------------
    // -----Show keypoints in 3D viewer-----
    // -------------------------------------
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> color_handler_cloud
      (range_image_planar_ptr, 0, 0, 0);
    if (!viewer.updatePointCloud<pcl::PointWithRange> (range_image_planar_ptr, color_handler_cloud, "range image"))
      viewer.addPointCloud<pcl::PointWithRange> (range_image_planar_ptr, color_handler_cloud, "range image");

    keypoints_cloud.points.resize (keypoint_indices.points.size ());
    for (size_t i=0; i<keypoint_indices.points.size (); ++i)
      keypoints_cloud.points[i].getVector3fMap () =
        range_image_planar.points[keypoint_indices.points[i]].getVector3fMap ();
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler_keypoints
      (keypoints_cloud_ptr, 0, 255, 0);
    if (!viewer.updatePointCloud (keypoints_cloud_ptr, color_handler_keypoints, "keypoints"))
      viewer.addPointCloud (keypoints_cloud_ptr, color_handler_keypoints, "keypoints");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");
  }

  interface->stop ();
}
<|endoftext|>


<commit_before>#include <algorithm>    // for std::sort
#include "ac_slow.hpp"
#include "ac_fast.hpp"

uint32
AC_Converter::Calc_State_Sz(const ACS_State *s) const {
    AC_State dummy;
    uint32 sz = offsetof(AC_State, input_vect);
    sz += s->Get_GotoNum() * sizeof(dummy.input_vect[0]);

    if (sz < sizeof(AC_State))
        sz = sizeof(AC_State);

    uint32 align = __alignof__(dummy);
    sz = (sz + align - 1) & ~(align - 1);
    return sz;
}

AC_Buffer*
AC_Converter::Alloc_Buffer() {
    const vector<ACS_State*>& all_states = _acs.Get_All_States();
    const ACS_State* root_state = _acs.Get_Root_State();
    uint32 root_fanout = root_state->Get_GotoNum();

    // Step 1: Calculate the buffer size
    AC_Ofst root_goto_ofst, states_ofst_ofst, first_state_ofst;

    // part 1 :  buffer header
    uint32 sz = root_goto_ofst = sizeof(AC_Buffer);

    // part 2: Root-node's goto function
    if (likely(root_fanout != 255))
        sz += 256;
    else
        root_goto_ofst = 0;

    // part 3: mapping of state's relative position.
    unsigned align = __alignof__(AC_Ofst);
    sz = (sz + align - 1) & ~(align - 1);
    states_ofst_ofst = sz;

    sz += sizeof(AC_Ofst) * all_states.size();

    // part 4: state's contents
    align = __alignof__(AC_State);
    sz = (sz + align - 1) & ~(align - 1);
    first_state_ofst = sz;

    uint32 state_sz = 0;
    for (vector<ACS_State*>::const_iterator i = all_states.begin(),
            e = all_states.end(); i != e; i++) {
        state_sz += Calc_State_Sz(*i);
    }
    state_sz -= Calc_State_Sz(root_state);

    sz += state_sz;

    // Step 2: Allocate buffer, and populate header.
    AC_Buffer* buf = _buf_alloc.alloc(sz);

    buf->hdr.magic_num = AC_MAGIC_NUM;
    buf->hdr.impl_variant = IMPL_FAST_VARIANT;
    buf->buf_len = sz;
    buf->root_goto_ofst = root_goto_ofst;
    buf->states_ofst_ofst = states_ofst_ofst;
    buf->first_state_ofst = first_state_ofst;
    buf->root_goto_num = root_fanout;
    buf->state_num = _acs.Get_State_Num();
    return buf;
}

void
AC_Converter::Populate_Root_Goto_Func(AC_Buffer *buf,
                                      GotoVect& goto_vect) {
    unsigned char *buf_base = (unsigned char*)(buf);
    InputTy* root_gotos = (InputTy*)(buf_base + buf->root_goto_ofst);
    const ACS_State* root_state = _acs.Get_Root_State();

    root_state->Get_Sorted_Gotos(goto_vect);

    // Renumber the ID of root-node's immediate kids.
    uint32 new_id = 1;
    bool full_fantout = (goto_vect.size() == 255);
    if (likely(!full_fantout))
        bzero(root_gotos, 255*sizeof(InputTy));

    for (GotoVect::iterator i = goto_vect.begin(), e = goto_vect.end();
            i != e; i++, new_id++) {
        InputTy c = i->first;
        ACS_State* s = i->second;
        _id_map[s->Get_ID()] = new_id;

        if (likely(!full_fantout))
            root_gotos[c] = new_id;
    }
}

AC_Buffer*
AC_Converter::Convert() {
    // Step 1: Some preparation stuff.
    GotoVect gotovect;

    _id_map.clear();
    _ofst_map.clear();
    _id_map.resize(_acs.Get_Next_Node_Id());
    _ofst_map.resize(_acs.Get_Next_Node_Id());

    // Step 2: allocate buffer to accommodate the entire AC graph.
    AC_Buffer* buf = Alloc_Buffer();
    unsigned char* buf_base = (unsigned char*)buf;

    // Step 3: Root node need special care.
    Populate_Root_Goto_Func(buf, gotovect);
    buf->root_goto_num = gotovect.size();
    _id_map[_acs.Get_Root_State()->Get_ID()] = 0;

    // Step 4: Converting the remaining states by BFSing the graph.
    // First of all, enter root's immediate kids to the working list.
    vector<const ACS_State*> wl;
    State_ID id = 1;
    for (GotoVect::iterator i = gotovect.begin(), e = gotovect.end();
            i != e; i++, id++) {
        ACS_State *s = i->second;
        wl.push_back(s);
        _id_map[s->Get_ID()] = id;
    }

    AC_Ofst* state_ofst_vect = (AC_Ofst*)(buf_base + buf->states_ofst_ofst);
    AC_Ofst ofst = buf->first_state_ofst;
    for (uint32 idx = 0; idx < wl.size(); idx++) {
        const ACS_State* old_s = wl[idx];
        AC_State* new_s = (AC_State*)(buf_base + ofst);

        // This property should hold as we:
        //  - States are appended to worklist in the BFS order.
        //  - sibiling states are appended to worklist in the order of their
        //    corresponding input.
        //
        State_ID state_id = idx + 1;
        ASSERT(_id_map[old_s->Get_ID()] == state_id);

        state_ofst_vect[state_id] = ofst;

        new_s->first_kid = wl.size() + 1;
        new_s->depth = old_s->Get_Depth();
        new_s->is_term = old_s->is_Terminal() ? 1 : 0;

        uint32 gotonum = old_s->Get_GotoNum();
        new_s->goto_num = gotonum;

        // Populate the "input" field
        old_s->Get_Sorted_Gotos(gotovect);
        uint32 input_idx = 0;
        uint32 id = wl.size() + 1;
        InputTy* input_vect = new_s->input_vect;
        for (GotoVect::iterator i = gotovect.begin(), e = gotovect.end();
             i != e; i++, id++, input_idx++) {
            input_vect[input_idx] = i->first;

            ACS_State *kid = i->second;
            _id_map[kid->Get_ID()] = id;
            wl.push_back(kid);
        }

        _ofst_map[old_s->Get_ID()] = ofst;
        ofst += Calc_State_Sz(old_s);
    }

    // Populate the fail-link field.
    for (vector<const ACS_State*>::iterator i = wl.begin(), e = wl.end();
            i != e; i++) {
        const ACS_State* slow_s = *i;
        State_ID fast_s_id = _id_map[slow_s->Get_ID()];
        AC_State* fast_s = (AC_State*)(buf_base + state_ofst_vect[fast_s_id]);
        if (const ACS_State* fl = slow_s->Get_FailLink()) {
            State_ID id = _id_map[fl->Get_ID()];
            fast_s->fail_link = id;
        } else
            fast_s->fail_link = 0;
    }
#ifdef DEBUG
    //dump_buffer(buf, stderr);
#endif
    return buf;
}

static inline AC_State*
Get_State_Addr(unsigned char* buf_base, AC_Ofst* StateOfstVect, uint32 state_id) {
    ASSERT(state_id != 0 && "root node is handled in speical way");
    return (AC_State*)(buf_base + StateOfstVect[state_id]);
}

static inline int
Binary_Search_Input(InputTy* input_vect, int vect_len, InputTy input) {
    int low = 0, high = vect_len - 1;
    while (low <= high) {
        uint32 mid = (low + high)/2;
        InputTy mid_c = input_vect[mid];

        if (input < mid_c)
            high = mid - 1;
        else if (input > mid_c)
            low = mid + 1;
        else
            return mid;
    }
    return -1;
}

ac_result_t
Match(AC_Buffer* buf, const char* str, uint32 len) {
    unsigned char* buf_base = (unsigned char*)(buf);
    unsigned char* root_goto = buf_base + buf->root_goto_ofst;
    AC_Ofst* states_ofst_vect = (AC_Ofst* )(buf_base + buf->states_ofst_ofst);

    AC_State *state;
    uint32 idx = 0;

    // Skip leading chars that are not valid input of root-nodes.
    if (likely(buf->root_goto_num != 255)) {
        while(idx < len) {
            unsigned char c = str[idx++];
            if (unsigned char kid_id = root_goto[c]) {
                state = Get_State_Addr(buf_base, states_ofst_vect, kid_id);
                break;
            }
        }
    } else {
        idx = 1;
        state = Get_State_Addr(buf_base, states_ofst_vect, *str);
    }

    int cnt = 0;
    State_ID fl = 0;
    while (idx < len) {
        cnt ++;
        unsigned char c = str[idx];
        int res = Binary_Search_Input(state->input_vect, state->goto_num, c);
        if (res >= 0) {
            // The "t = goto(c, current_state)" is valid, advance to state "t".
            uint32 kid = state->first_kid + res;
            state = Get_State_Addr(buf_base, states_ofst_vect, kid);
            idx++;
        } else {
            // Follow the fail-link.
            /*State_ID*/ fl = state->fail_link;
            if (fl == 0) {
                // fail-link is root-node, which implies the root-node dosen't
                // have 255 valid transitions (otherwise, the fail-link should
                // points to "goto(root, c)"), so we don't need speical handling
                // as we did before this while-loop is entered.
                //
                while(idx < len) {
                    InputTy c = str[idx++];
                    if (unsigned char kid_id = root_goto[c]) {
                        state =
                            Get_State_Addr(buf_base, states_ofst_vect, kid_id);
                        break;
                    }
                }
            } else {
                state = Get_State_Addr(buf_base, states_ofst_vect, fl);
            }
        }

        // Check to see if the state is terminal state?
        if (state->is_term) {
            ac_result_t r;
            r.match_begin = idx - state->depth;
            r.match_end = idx - 1;
            return r;
        }
    }

    ac_result_t r = {-1, -1};
    return r;
}

#ifdef DEBUG
void
AC_Converter::dump_buffer(AC_Buffer* buf, FILE* f) {
    vector<AC_Ofst> state_ofst;
    state_ofst.resize(_id_map.size());

    fprintf(f, "Id maps between old/slow and new/fast graphs\n");
    int old_id = 0;
    for (vector<uint32>::iterator i = _id_map.begin(), e = _id_map.end();
         i != e; i++, old_id++) {
        State_ID new_id = *i;
        if (new_id != 0) {
            fprintf(f, "%d -> %d, ", old_id, new_id);
        }
    }
    fprintf(f, "\n");

    int idx = 0;
    for (vector<uint32>::iterator i = _id_map.begin(), e = _id_map.end();
         i != e; i++, idx++) {
        uint32 id = *i;
        if (id == 0) continue;
        state_ofst[id] = _ofst_map[idx];
    }

    unsigned char* buf_base = (unsigned char*)buf;

    // dump root goto-function.
    fprintf(f, "root, fanout:%d goto {", buf->root_goto_num);
    if (buf->root_goto_num != 255) {
        unsigned char* root_goto = buf_base + buf->root_goto_ofst;
        for (uint32 i = 0; i < 255; i++) {
            if (root_goto[i] != 0)
                fprintf(f, "%c->S:%d, ", (unsigned char)i, root_goto[i]);
        }
    } else {
        fprintf(f, "full fanout\n");
    }
    fprintf(f, "}\n");

    // dump remaining states.
    AC_Ofst* state_ofst_vect = (AC_Ofst*)(buf_base + buf->states_ofst_ofst);
    for (uint32 i = 1, e = buf->state_num; i < e; i++) {
        AC_Ofst ofst = state_ofst_vect[i];
        ASSERT(ofst == state_ofst[i]);
        fprintf(f, "S:%d, ofst:%d, goto={", i, ofst);

        AC_State* s = (AC_State*)(buf_base + ofst);
        State_ID kid = s->first_kid;
        for (uint32 k = 0, ke = s->goto_num; k < ke; k++, kid++)
            fprintf(f, "%c->S:%d, ", s->input_vect[k], kid);

        fprintf(f, "}, fail-link = S:%d, %s\n", s->fail_link,
                s->is_term ? "terminal" : "");
    }
}
#endif
<commit_msg>Fix a bug where "goto(root, 255)" is not initialized properly.<commit_after>#include <algorithm>    // for std::sort
#include "ac_slow.hpp"
#include "ac_fast.hpp"

uint32
AC_Converter::Calc_State_Sz(const ACS_State *s) const {
    AC_State dummy;
    uint32 sz = offsetof(AC_State, input_vect);
    sz += s->Get_GotoNum() * sizeof(dummy.input_vect[0]);

    if (sz < sizeof(AC_State))
        sz = sizeof(AC_State);

    uint32 align = __alignof__(dummy);
    sz = (sz + align - 1) & ~(align - 1);
    return sz;
}

AC_Buffer*
AC_Converter::Alloc_Buffer() {
    const vector<ACS_State*>& all_states = _acs.Get_All_States();
    const ACS_State* root_state = _acs.Get_Root_State();
    uint32 root_fanout = root_state->Get_GotoNum();

    // Step 1: Calculate the buffer size
    AC_Ofst root_goto_ofst, states_ofst_ofst, first_state_ofst;

    // part 1 :  buffer header
    uint32 sz = root_goto_ofst = sizeof(AC_Buffer);

    // part 2: Root-node's goto function
    if (likely(root_fanout != 255))
        sz += 256;
    else
        root_goto_ofst = 0;

    // part 3: mapping of state's relative position.
    unsigned align = __alignof__(AC_Ofst);
    sz = (sz + align - 1) & ~(align - 1);
    states_ofst_ofst = sz;

    sz += sizeof(AC_Ofst) * all_states.size();

    // part 4: state's contents
    align = __alignof__(AC_State);
    sz = (sz + align - 1) & ~(align - 1);
    first_state_ofst = sz;

    uint32 state_sz = 0;
    for (vector<ACS_State*>::const_iterator i = all_states.begin(),
            e = all_states.end(); i != e; i++) {
        state_sz += Calc_State_Sz(*i);
    }
    state_sz -= Calc_State_Sz(root_state);

    sz += state_sz;

    // Step 2: Allocate buffer, and populate header.
    AC_Buffer* buf = _buf_alloc.alloc(sz);

    buf->hdr.magic_num = AC_MAGIC_NUM;
    buf->hdr.impl_variant = IMPL_FAST_VARIANT;
    buf->buf_len = sz;
    buf->root_goto_ofst = root_goto_ofst;
    buf->states_ofst_ofst = states_ofst_ofst;
    buf->first_state_ofst = first_state_ofst;
    buf->root_goto_num = root_fanout;
    buf->state_num = _acs.Get_State_Num();
    return buf;
}

void
AC_Converter::Populate_Root_Goto_Func(AC_Buffer *buf,
                                      GotoVect& goto_vect) {
    unsigned char *buf_base = (unsigned char*)(buf);
    InputTy* root_gotos = (InputTy*)(buf_base + buf->root_goto_ofst);
    const ACS_State* root_state = _acs.Get_Root_State();

    root_state->Get_Sorted_Gotos(goto_vect);

    // Renumber the ID of root-node's immediate kids.
    uint32 new_id = 1;
    bool full_fantout = (goto_vect.size() == 255);
    if (likely(!full_fantout))
        bzero(root_gotos, 256*sizeof(InputTy));

    for (GotoVect::iterator i = goto_vect.begin(), e = goto_vect.end();
            i != e; i++, new_id++) {
        InputTy c = i->first;
        ACS_State* s = i->second;
        _id_map[s->Get_ID()] = new_id;

        if (likely(!full_fantout))
            root_gotos[c] = new_id;
    }
}

AC_Buffer*
AC_Converter::Convert() {
    // Step 1: Some preparation stuff.
    GotoVect gotovect;

    _id_map.clear();
    _ofst_map.clear();
    _id_map.resize(_acs.Get_Next_Node_Id());
    _ofst_map.resize(_acs.Get_Next_Node_Id());

    // Step 2: allocate buffer to accommodate the entire AC graph.
    AC_Buffer* buf = Alloc_Buffer();
    unsigned char* buf_base = (unsigned char*)buf;

    // Step 3: Root node need special care.
    Populate_Root_Goto_Func(buf, gotovect);
    buf->root_goto_num = gotovect.size();
    _id_map[_acs.Get_Root_State()->Get_ID()] = 0;

    // Step 4: Converting the remaining states by BFSing the graph.
    // First of all, enter root's immediate kids to the working list.
    vector<const ACS_State*> wl;
    State_ID id = 1;
    for (GotoVect::iterator i = gotovect.begin(), e = gotovect.end();
            i != e; i++, id++) {
        ACS_State *s = i->second;
        wl.push_back(s);
        _id_map[s->Get_ID()] = id;
    }

    AC_Ofst* state_ofst_vect = (AC_Ofst*)(buf_base + buf->states_ofst_ofst);
    AC_Ofst ofst = buf->first_state_ofst;
    for (uint32 idx = 0; idx < wl.size(); idx++) {
        const ACS_State* old_s = wl[idx];
        AC_State* new_s = (AC_State*)(buf_base + ofst);

        // This property should hold as we:
        //  - States are appended to worklist in the BFS order.
        //  - sibiling states are appended to worklist in the order of their
        //    corresponding input.
        //
        State_ID state_id = idx + 1;
        ASSERT(_id_map[old_s->Get_ID()] == state_id);

        state_ofst_vect[state_id] = ofst;

        new_s->first_kid = wl.size() + 1;
        new_s->depth = old_s->Get_Depth();
        new_s->is_term = old_s->is_Terminal() ? 1 : 0;

        uint32 gotonum = old_s->Get_GotoNum();
        new_s->goto_num = gotonum;

        // Populate the "input" field
        old_s->Get_Sorted_Gotos(gotovect);
        uint32 input_idx = 0;
        uint32 id = wl.size() + 1;
        InputTy* input_vect = new_s->input_vect;
        for (GotoVect::iterator i = gotovect.begin(), e = gotovect.end();
             i != e; i++, id++, input_idx++) {
            input_vect[input_idx] = i->first;

            ACS_State *kid = i->second;
            _id_map[kid->Get_ID()] = id;
            wl.push_back(kid);
        }

        _ofst_map[old_s->Get_ID()] = ofst;
        ofst += Calc_State_Sz(old_s);
    }

    // Populate the fail-link field.
    for (vector<const ACS_State*>::iterator i = wl.begin(), e = wl.end();
            i != e; i++) {
        const ACS_State* slow_s = *i;
        State_ID fast_s_id = _id_map[slow_s->Get_ID()];
        AC_State* fast_s = (AC_State*)(buf_base + state_ofst_vect[fast_s_id]);
        if (const ACS_State* fl = slow_s->Get_FailLink()) {
            State_ID id = _id_map[fl->Get_ID()];
            fast_s->fail_link = id;
        } else
            fast_s->fail_link = 0;
    }
#ifdef DEBUG
    //dump_buffer(buf, stderr);
#endif
    return buf;
}

static inline AC_State*
Get_State_Addr(unsigned char* buf_base, AC_Ofst* StateOfstVect, uint32 state_id) {
    ASSERT(state_id != 0 && "root node is handled in speical way");
    ASSERT(state_id < ((AC_Buffer*)buf_base)->state_num);
    return (AC_State*)(buf_base + StateOfstVect[state_id]);
}

static inline int
Binary_Search_Input(InputTy* input_vect, int vect_len, InputTy input) {
    int low = 0, high = vect_len - 1;
    while (low <= high) {
        uint32 mid = (low + high)/2;
        InputTy mid_c = input_vect[mid];

        if (input < mid_c)
            high = mid - 1;
        else if (input > mid_c)
            low = mid + 1;
        else
            return mid;
    }
    return -1;
}

ac_result_t
Match(AC_Buffer* buf, const char* str, uint32 len) {
    unsigned char* buf_base = (unsigned char*)(buf);
    unsigned char* root_goto = buf_base + buf->root_goto_ofst;
    AC_Ofst* states_ofst_vect = (AC_Ofst* )(buf_base + buf->states_ofst_ofst);

    AC_State *state;
    uint32 idx = 0;

    // Skip leading chars that are not valid input of root-nodes.
    if (likely(buf->root_goto_num != 255)) {
        while(idx < len) {
            unsigned char c = str[idx++];
            if (unsigned char kid_id = root_goto[c]) {
                state = Get_State_Addr(buf_base, states_ofst_vect, kid_id);
                break;
            }
        }
    } else {
        idx = 1;
        state = Get_State_Addr(buf_base, states_ofst_vect, *str);
    }

    int cnt = 0;
    while (idx < len) {
        cnt ++;
        unsigned char c = str[idx];
        int res = Binary_Search_Input(state->input_vect, state->goto_num, c);
        if (res >= 0) {
            // The "t = goto(c, current_state)" is valid, advance to state "t".
            uint32 kid = state->first_kid + res;
            state = Get_State_Addr(buf_base, states_ofst_vect, kid);
            idx++;
        } else {
            // Follow the fail-link.
            State_ID fl = state->fail_link;
            if (fl == 0) {
                // fail-link is root-node, which implies the root-node dosen't
                // have 255 valid transitions (otherwise, the fail-link should
                // points to "goto(root, c)"), so we don't need speical handling
                // as we did before this while-loop is entered.
                //
                while(idx < len) {
                    InputTy c = str[idx++];
                    if (unsigned char kid_id = root_goto[c]) {
                        state =
                            Get_State_Addr(buf_base, states_ofst_vect, kid_id);
                        break;
                    }
                }
            } else {
                state = Get_State_Addr(buf_base, states_ofst_vect, fl);
            }
        }

        // Check to see if the state is terminal state?
        if (state->is_term) {
            ac_result_t r;
            r.match_begin = idx - state->depth;
            r.match_end = idx - 1;
            return r;
        }
    }

    ac_result_t r = {-1, -1};
    return r;
}

#ifdef DEBUG
void
AC_Converter::dump_buffer(AC_Buffer* buf, FILE* f) {
    vector<AC_Ofst> state_ofst;
    state_ofst.resize(_id_map.size());

    fprintf(f, "Id maps between old/slow and new/fast graphs\n");
    int old_id = 0;
    for (vector<uint32>::iterator i = _id_map.begin(), e = _id_map.end();
         i != e; i++, old_id++) {
        State_ID new_id = *i;
        if (new_id != 0) {
            fprintf(f, "%d -> %d, ", old_id, new_id);
        }
    }
    fprintf(f, "\n");

    int idx = 0;
    for (vector<uint32>::iterator i = _id_map.begin(), e = _id_map.end();
         i != e; i++, idx++) {
        uint32 id = *i;
        if (id == 0) continue;
        state_ofst[id] = _ofst_map[idx];
    }

    unsigned char* buf_base = (unsigned char*)buf;

    // dump root goto-function.
    fprintf(f, "root, fanout:%d goto {", buf->root_goto_num);
    if (buf->root_goto_num != 255) {
        unsigned char* root_goto = buf_base + buf->root_goto_ofst;
        for (uint32 i = 0; i < 255; i++) {
            if (root_goto[i] != 0)
                fprintf(f, "%c->S:%d, ", (unsigned char)i, root_goto[i]);
        }
    } else {
        fprintf(f, "full fanout\n");
    }
    fprintf(f, "}\n");

    // dump remaining states.
    AC_Ofst* state_ofst_vect = (AC_Ofst*)(buf_base + buf->states_ofst_ofst);
    for (uint32 i = 1, e = buf->state_num; i < e; i++) {
        AC_Ofst ofst = state_ofst_vect[i];
        ASSERT(ofst == state_ofst[i]);
        fprintf(f, "S:%d, ofst:%d, goto={", i, ofst);

        AC_State* s = (AC_State*)(buf_base + ofst);
        State_ID kid = s->first_kid;
        for (uint32 k = 0, ke = s->goto_num; k < ke; k++, kid++)
            fprintf(f, "%c->S:%d, ", s->input_vect[k], kid);

        fprintf(f, "}, fail-link = S:%d, %s\n", s->fail_link,
                s->is_term ? "terminal" : "");
    }
}
#endif
<|endoftext|>