<commit_before>//
//  main.cpp
//  TonicStandaloneDemo
//
//  Created by Nick Donaldson on 5/16/13.
//
//

// This is a super-simple demo showing a very basic command-line C++ program to play a Tonic synth

#include <iostream>
#include "Tonic.h"
#include "RtAudio.h"

using namespace Tonic;

const unsigned int nChannels = 2;

Synth * synth = NULL;

int renderCallback( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
        double streamTime, RtAudioStreamStatus status, void *userData )
{
    if (synth != NULL){
        synth->fillBufferOfFloats((float*)outputBuffer, nBufferFrames, nChannels);
    }

    return 0;
}

int main(int argc, const char * argv[])
{
    // Configure RtAudio
    RtAudio dac;
    RtAudio::StreamParameters rtParams;
    rtParams.deviceId = dac.getDefaultOutputDevice();
    rtParams.nChannels = nChannels;
    unsigned int sampleRate = 44100;
    unsigned int bufferFrames = 256; // 256 sample frames

    // You don't necessarily have to do this - it will default to 44100 if not set.
    Tonic::setSampleRate(sampleRate);

    // --------- MAKE A SYNTH HERE -----------

    synth = new Synth();

    synth->setLimitOutput(false);

//    ControlGenerator ctrlGen1 = ControlValue(2);
//    Generator gen1 = ctrlGen1 + FixedValue(3) * ctrlGen1;

    ControlGenerator val1 = ControlValue(2);
  ControlGenerator val2 = ControlValue(2);
  ControlGenerator final = val1 + val1 * val2;
  Tonic_::SynthesisContext_ context;
  final.tick(context);

  //  synth->setOutputGen(FixedValue());

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

    // open rtaudio stream
    try {
        dac.openStream( &rtParams, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &renderCallback, NULL, NULL );

        dac.startStream();

        // hacky, yes, but let's just hang out for awhile until someone presses a key
        printf("\n\nPress any key to stop\n\n");
        cin.get();

        dac.stopStream();
    }
    catch ( RtError& e ) {
        std::cout << '\n' << e.getMessage() << '\n' << std::endl;
        exit( 0 );
    }

    return 0;
}

<commit_msg>Reverting accidentally committed changes to main.cpp in standalone demo<commit_after>//
//  main.cpp
//  TonicStandaloneDemo
//
//  Created by Nick Donaldson on 5/16/13.
//
//

// This is a super-simple demo showing a very basic command-line C++ program to play a Tonic synth

#include <iostream>
#include "Tonic.h"
#include "RtAudio.h"

using namespace Tonic;

const unsigned int nChannels = 2;

Synth * synth = NULL;

int renderCallback( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
        double streamTime, RtAudioStreamStatus status, void *userData )
{
    if (synth != NULL){
        synth->fillBufferOfFloats((float*)outputBuffer, nBufferFrames, nChannels);
    }

    return 0;
}

int main(int argc, const char * argv[])
{
    // Configure RtAudio
    RtAudio dac;
    RtAudio::StreamParameters rtParams;
    rtParams.deviceId = dac.getDefaultOutputDevice();
    rtParams.nChannels = nChannels;
    unsigned int sampleRate = 44100;
    unsigned int bufferFrames = 256; // 256 sample frames

    // You don't necessarily have to do this - it will default to 44100 if not set.
    Tonic::setSampleRate(sampleRate);

    // --------- MAKE A SYNTH HERE -----------

    synth = new Synth();

    ControlMetro metro = ControlMetro().bpm(100);
    ControlGenerator freq = ControlRandom().trigger(metro).min(0).max(1);

    Generator tone = RectWave().freq(
                                     freq * 0.25 + 100
                                     + 400
                                     ) * SineWave().freq(50);

    ADSR env = ADSR()
    .attack(0.01)
    .decay( 0.4 )
    .sustain(0)
    .release(0)
    .doesSustain(false)
    .trigger(metro);

    StereoDelay delay = StereoDelay(3.0f,3.0f)
    .delayTimeLeft( 0.5 + SineWave().freq(0.2) * 0.01)
    .delayTimeRight(0.55 + SineWave().freq(0.23) * 0.01)
    .feedback(0.3)
    .dryLevel(0.8)
    .wetLevel(0.2);

    Generator filterFreq = (SineWave().freq(0.01) + 1) * 200 + 225;

    LPF24 filter = LPF24().Q(2).cutoff( filterFreq );

    Generator output = (( tone * env ) >> filter >> delay) * 0.3;

    synth->setOutputGen(output);

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

    // open rtaudio stream
    try {
        dac.openStream( &rtParams, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &renderCallback, NULL, NULL );

        dac.startStream();

        // hacky, yes, but let's just hang out for awhile until someone presses a key
        printf("\n\nPress any key to stop\n\n");
        cin.get();

        dac.stopStream();
    }
    catch ( RtError& e ) {
        std::cout << '\n' << e.getMessage() << '\n' << std::endl;
        exit( 0 );
    }

    return 0;
}

<|endoftext|>


<commit_before>#include "vector_tile_projection.hpp"
#include "vector_tile_geometry_decoder.hpp"

#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/version.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/well_known_srs.hpp>
#include <mapnik/version.hpp>
#include <mapnik/vertex.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/image.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/view_transform.hpp>
#include <mapnik/util/variant.hpp>

#include <memory>
#include <stdexcept>
#include <string>

#include <boost/optional.hpp>
#include <unicode/unistr.h>

namespace mapnik { namespace vector_tile_impl {

    template <typename Filter>
    class tile_featureset_pbf : public Featureset
    {
    public:
        tile_featureset_pbf(Filter const& filter,
                        mapnik::box2d<double> const& tile_extent,
                        mapnik::box2d<double> const& unbuffered_query,
                        std::set<std::string> const& attribute_names,
                        std::vector<mapbox::util::pbf> const& features,
                        double tile_x,
                        double tile_y,
                        double scale,
                        std::vector<std::string> const& layer_keys,
                        layer_pbf_attr_type const& layer_values)
            : filter_(filter),
              tile_extent_(tile_extent),
              unbuffered_query_(unbuffered_query),
              features_(features),
              layer_keys_(layer_keys),
              layer_values_(layer_values),
              tile_x_(tile_x),
              tile_y_(tile_y),
              scale_(scale),
              itr_(0),
              tr_("utf-8"),
              ctx_(std::make_shared<mapnik::context_type>())
        {
            std::set<std::string>::const_iterator pos = attribute_names.begin();
            std::set<std::string>::const_iterator end = attribute_names.end();
            for ( ;pos !=end; ++pos)
            {
                for (auto const& key : layer_keys_)
                {
                    if (key == *pos)
                    {
                        ctx_->push(*pos);
                        break;
                    }
                }
            }
        }

        virtual ~tile_featureset_pbf() {}

        feature_ptr next()
        {
            while ( itr_ < features_.size() )
            {
                mapbox::util::pbf f = features_.at(itr_);
                // TODO: auto-increment feature id counter here
                mapnik::feature_ptr feature = mapnik::feature_factory::create(ctx_,itr_);
                pbf_attr_value_type val;

                ++itr_;
                int tagcount=0;
                uint32_t key_idx, val_idx;
                int32_t geometry_type = 0; // vector_tile::Tile_GeomType_UNKNOWN
                while (f.next())
                {
                    switch(f.tag())
                    {
                        case 1:
                            feature->set_id(f.get_uint64());
                            break;
                        case 2:
                            {
                                auto tag_iterator = f.packed_uint32();

                                for (auto _i = tag_iterator.first; _i != tag_iterator.second; ++_i)
                                {
                                    if (tagcount % 2 == 0)
                                    {
                                        key_idx = *_i;
                                        ++tagcount;
                                    }
                                    else
                                    {
                                        val_idx = *_i;
                                        val = layer_values_.at(val_idx);
                                        std::string name = layer_keys_.at(key_idx);
                                        if (feature->has_key(name))
                                        {
                                            if (val.is<std::string>())
                                            {
                                                feature->put(name, tr_.transcode(val.get<std::string>().data(), val.get<std::string>().length()));
                                            }
                                            else if (val.is<bool>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_bool>(val.get<bool>()));
                                            }
                                            else if (val.is<int64_t>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_integer>(val.get<int64_t>()));
                                            }
                                            else if (val.is<uint64_t>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_integer>(val.get<uint64_t>()));
                                            }
                                            else if (val.is<double>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_double>(val.get<double>()));
                                            }
                                            else if (val.is<float>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_double>(val.get<float>()));
                                            } else {
                                                throw std::runtime_error("unknown attribute type while reading feature");
                                            }
                                            ++tagcount;
                                        }
                                    }
                                }
                            }
                            break;
                        case 3:
                            geometry_type = f.get_enum();
                            switch (geometry_type)
                            {
                              case 1: //vector_tile::Tile_GeomType_POINT
                              case 2: // vector_tile::Tile_GeomType_LINESTRING
                              case 3: // vector_tile::Tile_GeomType_POLYGON
                                break;
                              default:  // vector_tile::Tile_GeomType_UNKNOWN or any other value
                                throw std::runtime_error("unknown geometry type " + std::to_string(geometry_type) + " in feature");
                            }
                            break;
                        case 5:
                            {
                            std::string const& image_buffer = f.get_bytes();
                            std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(image_buffer.data(),image_buffer.size()));
                            if (reader.get())
                            {
                                int image_width = reader->width();
                                int image_height = reader->height();
                                if (image_width > 0 && image_height > 0)
                                {
                                    mapnik::view_transform t(image_width, image_height, tile_extent_, 0, 0);
                                    box2d<double> intersect = tile_extent_.intersect(unbuffered_query_);
                                    box2d<double> ext = t.forward(intersect);
                                    if (ext.width() > 0.5 && ext.height() > 0.5 )
                                    {
                                        // select minimum raster containing whole ext
                                        int x_off = static_cast<int>(std::floor(ext.minx() +.5));
                                        int y_off = static_cast<int>(std::floor(ext.miny() +.5));
                                        int end_x = static_cast<int>(std::floor(ext.maxx() +.5));
                                        int end_y = static_cast<int>(std::floor(ext.maxy() +.5));

                                        // clip to available data
                                        if (x_off < 0)
                                            x_off = 0;
                                        if (y_off < 0)
                                            y_off = 0;
                                        if (end_x > image_width)
                                            end_x = image_width;
                                        if (end_y > image_height)
                                            end_y = image_height;
                                        int width = end_x - x_off;
                                        int height = end_y - y_off;
                                        box2d<double> feature_raster_extent(x_off,
                                                                            y_off,
                                                                            x_off + width,
                                                                            y_off + height);
                                        intersect = t.backward(feature_raster_extent);
                                        double filter_factor = 1.0;
                                        mapnik::image_any data = reader->read(x_off, y_off, width, height);
                                        mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect,
                                                                      data,
                                                                      filter_factor
                                                                      );
                                        feature->set_raster(raster);
                                        return feature;
                                    }
                                }
                            }
                          }
                            break;
                        case 4:
                            {
                                auto geom_itr = f.packed_uint32();
                                mapnik::vector_tile_impl::GeometryPBF geoms(geom_itr, tile_x_,tile_y_,scale_,-1*scale_);
                                mapnik::geometry::geometry<double> geom = decode_geometry(geoms, geometry_type);
                                if (geom.is<mapnik::geometry::geometry_empty>())
                                {
                                    continue;
                                }
                                mapnik::box2d<double> envelope = mapnik::geometry::envelope(geom);
                                if (!filter_.pass(envelope))
                                {
                                    continue;
                                }
                                feature->set_geometry(std::move(geom));
                                return feature;
                            }
                            break;
                        default:
                            // NOTE:  The vector_tile.proto file technically allows for extension fields
                            //        of values 16 to max here.  Technically, we should just skip() those
                            //        fields.
                            //        However, if we're fed a corrupt file (or random data), we don't
                            //        want to just blindly follow the bytes, so we have made the decision
                            //        to abort cleanly, rather than doing GIGO.
                            throw std::runtime_error("unknown field type " + std::to_string(f.tag()) +" in feature");

                    }
                }
            }
            return feature_ptr();
        }

    private:
        Filter filter_;
        mapnik::box2d<double> tile_extent_;
        mapnik::box2d<double> unbuffered_query_;
        std::vector<mapbox::util::pbf> const& features_;
        std::vector<std::string> const& layer_keys_;
        layer_pbf_attr_type const& layer_values_;

        double tile_x_;
        double tile_y_;
        double scale_;
        unsigned itr_;
        mapnik::transcoder tr_;
        mapnik::context_ptr ctx_;

    };

    // tile_datasource impl
    tile_datasource_pbf::tile_datasource_pbf(mapbox::util::pbf const& layer,
                                     unsigned x,
                                     unsigned y,
                                     unsigned z,
                                     unsigned tile_size)
        : datasource(parameters()),
          desc_("in-memory PBF encoded datasource","utf-8"),
          attributes_added_(false),
          layer_(layer),
          x_(x),
          y_(y),
          z_(z),
          tile_size_(tile_size),
          extent_initialized_(false),
          tile_x_(0.0),
          tile_y_(0.0),
          scale_(0.0),
          layer_extent_(0)
    {
        double resolution = mapnik::EARTH_CIRCUMFERENCE/(1 << z_);
        tile_x_ = -0.5 * mapnik::EARTH_CIRCUMFERENCE + x_ * resolution;
        tile_y_ =  0.5 * mapnik::EARTH_CIRCUMFERENCE - y_ * resolution;

        mapbox::util::pbf val_msg;

        while (layer_.next())
        {
            switch(layer_.tag())
            {
                case 1:
                    name_ = layer_.get_string();
                    break;
                case 2:
                    features_.push_back(layer_.get_message());
                    break;
                case 3:
                    layer_keys_.push_back(layer_.get_string());
                    break;
                case 4:
                    val_msg = layer_.get_message();
                    while (val_msg.next())
                    {
                        switch(val_msg.tag()) {
                            case 1:
                                layer_values_.push_back(val_msg.get_string());
                                break;
                            case 2:
                                layer_values_.push_back(val_msg.get_float());
                                break;
                            case 3:
                                layer_values_.push_back(val_msg.get_double());
                                break;
                            case 4:
                                layer_values_.push_back(val_msg.get_int64());
                                break;
                            case 5:
                                layer_values_.push_back(val_msg.get_uint64());
                                break;
                            case 6:
                                layer_values_.push_back(val_msg.get_sint64());
                                break;
                            case 7:
                                layer_values_.push_back(val_msg.get_bool());
                                break;
                            default:
                                throw std::runtime_error("unknown Value type " + std::to_string(layer_.tag()) + " in layer.values");
                        }
                    }
                    break;
                case 5:
                    layer_extent_ = layer_.get_uint32();
                    break;
                case 15:
                    layer_.skip();
                    break;
                default:
                    throw std::runtime_error("unknown field type " + std::to_string(layer_.tag()) + " in layer");
            }
        }
        scale_ = (static_cast<double>(layer_extent_) / tile_size_) * tile_size_/resolution;
    }

    tile_datasource_pbf::~tile_datasource_pbf() {}

    datasource::datasource_t tile_datasource_pbf::type() const
    {
        return datasource::Vector;
    }

    featureset_ptr tile_datasource_pbf::features(query const& q) const
    {
        mapnik::filter_in_box filter(q.get_bbox());
        return std::make_shared<tile_featureset_pbf<mapnik::filter_in_box> >
            (filter, get_tile_extent(), q.get_unbuffered_bbox(), q.property_names(), features_, tile_x_, tile_y_, scale_, layer_keys_, layer_values_);
    }

    featureset_ptr tile_datasource_pbf::features_at_point(coord2d const& pt, double tol) const
    {
        mapnik::filter_at_point filter(pt,tol);
        std::set<std::string> names;
        for (auto const& key : layer_keys_)
        {
            names.insert(key);
        }
        return std::make_shared<tile_featureset_pbf<filter_at_point> >
            (filter, get_tile_extent(), get_tile_extent(), names, features_, tile_x_, tile_y_, scale_, layer_keys_, layer_values_);
    }

    void tile_datasource_pbf::set_envelope(box2d<double> const& bbox)
    {
        extent_initialized_ = true;
        extent_ = bbox;
    }

    box2d<double> tile_datasource_pbf::get_tile_extent() const
    {
        spherical_mercator merc(tile_size_);
        double minx,miny,maxx,maxy;
        merc.xyz(x_,y_,z_,minx,miny,maxx,maxy);
        return box2d<double>(minx,miny,maxx,maxy);
    }

    box2d<double> tile_datasource_pbf::envelope() const
    {
        if (!extent_initialized_)
        {
            extent_ = get_tile_extent();
            extent_initialized_ = true;
        }
        return extent_;
    }

    boost::optional<mapnik::datasource_geometry_t> tile_datasource_pbf::get_geometry_type() const
    {
        return mapnik::datasource_geometry_t::Collection;
    }

    layer_descriptor tile_datasource_pbf::get_descriptor() const
    {
        if (!attributes_added_)
        {
            for (auto const& key : layer_keys_)
            {
                // Object type here because we don't know the precise value until features are unpacked
                desc_.add_descriptor(attribute_descriptor(key, Object));
            }
            attributes_added_ = true;
        }
        return desc_;
    }

    }} // end ns
<commit_msg>fix #132<commit_after>#include "vector_tile_projection.hpp"
#include "vector_tile_geometry_decoder.hpp"

#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/version.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/well_known_srs.hpp>
#include <mapnik/version.hpp>
#include <mapnik/vertex.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/image.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/view_transform.hpp>
#include <mapnik/util/variant.hpp>

#include <memory>
#include <stdexcept>
#include <string>

#include <boost/optional.hpp>
#include <unicode/unistr.h>

namespace mapnik { namespace vector_tile_impl {

    template <typename Filter>
    class tile_featureset_pbf : public Featureset
    {
    public:
        tile_featureset_pbf(Filter const& filter,
                        mapnik::box2d<double> const& tile_extent,
                        mapnik::box2d<double> const& unbuffered_query,
                        std::set<std::string> const& attribute_names,
                        std::vector<mapbox::util::pbf> const& features,
                        double tile_x,
                        double tile_y,
                        double scale,
                        std::vector<std::string> const& layer_keys,
                        layer_pbf_attr_type const& layer_values)
            : filter_(filter),
              tile_extent_(tile_extent),
              unbuffered_query_(unbuffered_query),
              features_(features),
              layer_keys_(layer_keys),
              layer_values_(layer_values),
              tile_x_(tile_x),
              tile_y_(tile_y),
              scale_(scale),
              itr_(0),
              tr_("utf-8"),
              ctx_(std::make_shared<mapnik::context_type>())
        {
            std::set<std::string>::const_iterator pos = attribute_names.begin();
            std::set<std::string>::const_iterator end = attribute_names.end();
            for ( ;pos !=end; ++pos)
            {
                for (auto const& key : layer_keys_)
                {
                    if (key == *pos)
                    {
                        ctx_->push(*pos);
                        break;
                    }
                }
            }
        }

        virtual ~tile_featureset_pbf() {}

        feature_ptr next()
        {
            while ( itr_ < features_.size() )
            {
                mapbox::util::pbf f = features_.at(itr_);
                // TODO: auto-increment feature id counter here
                mapnik::feature_ptr feature = mapnik::feature_factory::create(ctx_,itr_);
                pbf_attr_value_type val;

                ++itr_;
                int tagcount=0;
                uint32_t key_idx, val_idx;
                int32_t geometry_type = 0; // vector_tile::Tile_GeomType_UNKNOWN
                while (f.next())
                {
                    switch(f.tag())
                    {
                        case 1:
                            feature->set_id(f.get_uint64());
                            break;
                        case 2:
                            {
                                auto tag_iterator = f.packed_uint32();

                                for (auto _i = tag_iterator.first; _i != tag_iterator.second; ++_i)
                                {
                                    if (tagcount % 2 == 0)
                                    {
                                        key_idx = *_i;
                                        ++tagcount;
                                    }
                                    else
                                    {
                                        val_idx = *_i;
                                        std::string name = layer_keys_.at(key_idx);
                                        if (feature->has_key(name))
                                        {
                                            val = layer_values_.at(val_idx);
                                            if (val.is<std::string>())
                                            {
                                                feature->put(name, tr_.transcode(val.get<std::string>().data(), val.get<std::string>().length()));
                                            }
                                            else if (val.is<bool>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_bool>(val.get<bool>()));
                                            }
                                            else if (val.is<int64_t>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_integer>(val.get<int64_t>()));
                                            }
                                            else if (val.is<uint64_t>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_integer>(val.get<uint64_t>()));
                                            }
                                            else if (val.is<double>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_double>(val.get<double>()));
                                            }
                                            else if (val.is<float>())
                                            {
                                                feature->put(name, static_cast<mapnik::value_double>(val.get<float>()));
                                            } else {
                                                throw std::runtime_error("unknown attribute type while reading feature");
                                            }
                                            ++tagcount;
                                        }
                                    }
                                }
                            }
                            break;
                        case 3:
                            geometry_type = f.get_enum();
                            switch (geometry_type)
                            {
                              case 1: //vector_tile::Tile_GeomType_POINT
                              case 2: // vector_tile::Tile_GeomType_LINESTRING
                              case 3: // vector_tile::Tile_GeomType_POLYGON
                                break;
                              default:  // vector_tile::Tile_GeomType_UNKNOWN or any other value
                                throw std::runtime_error("unknown geometry type " + std::to_string(geometry_type) + " in feature");
                            }
                            break;
                        case 5:
                            {
                            std::string const& image_buffer = f.get_bytes();
                            std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(image_buffer.data(),image_buffer.size()));
                            if (reader.get())
                            {
                                int image_width = reader->width();
                                int image_height = reader->height();
                                if (image_width > 0 && image_height > 0)
                                {
                                    mapnik::view_transform t(image_width, image_height, tile_extent_, 0, 0);
                                    box2d<double> intersect = tile_extent_.intersect(unbuffered_query_);
                                    box2d<double> ext = t.forward(intersect);
                                    if (ext.width() > 0.5 && ext.height() > 0.5 )
                                    {
                                        // select minimum raster containing whole ext
                                        int x_off = static_cast<int>(std::floor(ext.minx() +.5));
                                        int y_off = static_cast<int>(std::floor(ext.miny() +.5));
                                        int end_x = static_cast<int>(std::floor(ext.maxx() +.5));
                                        int end_y = static_cast<int>(std::floor(ext.maxy() +.5));

                                        // clip to available data
                                        if (x_off < 0)
                                            x_off = 0;
                                        if (y_off < 0)
                                            y_off = 0;
                                        if (end_x > image_width)
                                            end_x = image_width;
                                        if (end_y > image_height)
                                            end_y = image_height;
                                        int width = end_x - x_off;
                                        int height = end_y - y_off;
                                        box2d<double> feature_raster_extent(x_off,
                                                                            y_off,
                                                                            x_off + width,
                                                                            y_off + height);
                                        intersect = t.backward(feature_raster_extent);
                                        double filter_factor = 1.0;
                                        mapnik::image_any data = reader->read(x_off, y_off, width, height);
                                        mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect,
                                                                      data,
                                                                      filter_factor
                                                                      );
                                        feature->set_raster(raster);
                                        return feature;
                                    }
                                }
                            }
                          }
                            break;
                        case 4:
                            {
                                auto geom_itr = f.packed_uint32();
                                mapnik::vector_tile_impl::GeometryPBF geoms(geom_itr, tile_x_,tile_y_,scale_,-1*scale_);
                                mapnik::geometry::geometry<double> geom = decode_geometry(geoms, geometry_type);
                                if (geom.is<mapnik::geometry::geometry_empty>())
                                {
                                    continue;
                                }
                                mapnik::box2d<double> envelope = mapnik::geometry::envelope(geom);
                                if (!filter_.pass(envelope))
                                {
                                    continue;
                                }
                                feature->set_geometry(std::move(geom));
                                return feature;
                            }
                            break;
                        default:
                            // NOTE:  The vector_tile.proto file technically allows for extension fields
                            //        of values 16 to max here.  Technically, we should just skip() those
                            //        fields.
                            //        However, if we're fed a corrupt file (or random data), we don't
                            //        want to just blindly follow the bytes, so we have made the decision
                            //        to abort cleanly, rather than doing GIGO.
                            throw std::runtime_error("unknown field type " + std::to_string(f.tag()) +" in feature");

                    }
                }
            }
            return feature_ptr();
        }

    private:
        Filter filter_;
        mapnik::box2d<double> tile_extent_;
        mapnik::box2d<double> unbuffered_query_;
        std::vector<mapbox::util::pbf> const& features_;
        std::vector<std::string> const& layer_keys_;
        layer_pbf_attr_type const& layer_values_;

        double tile_x_;
        double tile_y_;
        double scale_;
        unsigned itr_;
        mapnik::transcoder tr_;
        mapnik::context_ptr ctx_;

    };

    // tile_datasource impl
    tile_datasource_pbf::tile_datasource_pbf(mapbox::util::pbf const& layer,
                                     unsigned x,
                                     unsigned y,
                                     unsigned z,
                                     unsigned tile_size)
        : datasource(parameters()),
          desc_("in-memory PBF encoded datasource","utf-8"),
          attributes_added_(false),
          layer_(layer),
          x_(x),
          y_(y),
          z_(z),
          tile_size_(tile_size),
          extent_initialized_(false),
          tile_x_(0.0),
          tile_y_(0.0),
          scale_(0.0),
          layer_extent_(0)
    {
        double resolution = mapnik::EARTH_CIRCUMFERENCE/(1 << z_);
        tile_x_ = -0.5 * mapnik::EARTH_CIRCUMFERENCE + x_ * resolution;
        tile_y_ =  0.5 * mapnik::EARTH_CIRCUMFERENCE - y_ * resolution;

        mapbox::util::pbf val_msg;

        while (layer_.next())
        {
            switch(layer_.tag())
            {
                case 1:
                    name_ = layer_.get_string();
                    break;
                case 2:
                    features_.push_back(layer_.get_message());
                    break;
                case 3:
                    layer_keys_.push_back(layer_.get_string());
                    break;
                case 4:
                    val_msg = layer_.get_message();
                    while (val_msg.next())
                    {
                        switch(val_msg.tag()) {
                            case 1:
                                layer_values_.push_back(val_msg.get_string());
                                break;
                            case 2:
                                layer_values_.push_back(val_msg.get_float());
                                break;
                            case 3:
                                layer_values_.push_back(val_msg.get_double());
                                break;
                            case 4:
                                layer_values_.push_back(val_msg.get_int64());
                                break;
                            case 5:
                                layer_values_.push_back(val_msg.get_uint64());
                                break;
                            case 6:
                                layer_values_.push_back(val_msg.get_sint64());
                                break;
                            case 7:
                                layer_values_.push_back(val_msg.get_bool());
                                break;
                            default:
                                throw std::runtime_error("unknown Value type " + std::to_string(layer_.tag()) + " in layer.values");
                        }
                    }
                    break;
                case 5:
                    layer_extent_ = layer_.get_uint32();
                    break;
                case 15:
                    layer_.skip();
                    break;
                default:
                    throw std::runtime_error("unknown field type " + std::to_string(layer_.tag()) + " in layer");
            }
        }
        scale_ = (static_cast<double>(layer_extent_) / tile_size_) * tile_size_/resolution;
    }

    tile_datasource_pbf::~tile_datasource_pbf() {}

    datasource::datasource_t tile_datasource_pbf::type() const
    {
        return datasource::Vector;
    }

    featureset_ptr tile_datasource_pbf::features(query const& q) const
    {
        mapnik::filter_in_box filter(q.get_bbox());
        return std::make_shared<tile_featureset_pbf<mapnik::filter_in_box> >
            (filter, get_tile_extent(), q.get_unbuffered_bbox(), q.property_names(), features_, tile_x_, tile_y_, scale_, layer_keys_, layer_values_);
    }

    featureset_ptr tile_datasource_pbf::features_at_point(coord2d const& pt, double tol) const
    {
        mapnik::filter_at_point filter(pt,tol);
        std::set<std::string> names;
        for (auto const& key : layer_keys_)
        {
            names.insert(key);
        }
        return std::make_shared<tile_featureset_pbf<filter_at_point> >
            (filter, get_tile_extent(), get_tile_extent(), names, features_, tile_x_, tile_y_, scale_, layer_keys_, layer_values_);
    }

    void tile_datasource_pbf::set_envelope(box2d<double> const& bbox)
    {
        extent_initialized_ = true;
        extent_ = bbox;
    }

    box2d<double> tile_datasource_pbf::get_tile_extent() const
    {
        spherical_mercator merc(tile_size_);
        double minx,miny,maxx,maxy;
        merc.xyz(x_,y_,z_,minx,miny,maxx,maxy);
        return box2d<double>(minx,miny,maxx,maxy);
    }

    box2d<double> tile_datasource_pbf::envelope() const
    {
        if (!extent_initialized_)
        {
            extent_ = get_tile_extent();
            extent_initialized_ = true;
        }
        return extent_;
    }

    boost::optional<mapnik::datasource_geometry_t> tile_datasource_pbf::get_geometry_type() const
    {
        return mapnik::datasource_geometry_t::Collection;
    }

    layer_descriptor tile_datasource_pbf::get_descriptor() const
    {
        if (!attributes_added_)
        {
            for (auto const& key : layer_keys_)
            {
                // Object type here because we don't know the precise value until features are unpacked
                desc_.add_descriptor(attribute_descriptor(key, Object));
            }
            attributes_added_ = true;
        }
        return desc_;
    }

    }} // end ns
<|endoftext|>


<commit_before>// vrkit is (C) Copyright 2005-2007
//    by Allen Bierbaum, Aron Bierbuam, Patrick Hartling, and Daniel Shipton
//
// This file is part of vrkit.
//
// vrkit 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 of the License, or (at your option)
// any later version.
//
// vrkit 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 program.  If not, see <http://www.gnu.org/licenses/>.

#include <sstream>

#include <vrkit/AbstractPlugin.h>
#include <vrkit/plugin/Module.h>
#include <vrkit/plugin/RegistryEntry.h>

namespace vrkit
{

namespace plugin
{

RegistryEntry::RegistryEntry(vpr::LibraryPtr module)
   : mModule(module)
   , mModuleInfo(getModuleInfo(module))
{
   /* Do nothing. */ ;
   std::cout << "Registry entry for " << mModule->getName() << " created"
             << std::endl;
}

RegistryEntry::~RegistryEntry()
{
}

CreatorBase*
RegistryEntry::getCreatorFunc(vpr::LibraryPtr module,
                              const std::string& getCreatorFuncName)
   const
{
   Module pm(module);
   return pm.getFunction<CreatorBase* ()>(getCreatorFuncName)();
}

Info RegistryEntry::getModuleInfo(vpr::LibraryPtr module)
{
   Module pm(module);
   typedef const Info* sig_type();
   return *pm.getFunction<sig_type>(AbstractPlugin::getInfoFuncName())();
}

}

}
<commit_msg>Removed debug output that I did not mean to commit with the last revision.<commit_after>// vrkit is (C) Copyright 2005-2007
//    by Allen Bierbaum, Aron Bierbuam, Patrick Hartling, and Daniel Shipton
//
// This file is part of vrkit.
//
// vrkit 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 of the License, or (at your option)
// any later version.
//
// vrkit 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 program.  If not, see <http://www.gnu.org/licenses/>.

#include <sstream>

#include <vrkit/AbstractPlugin.h>
#include <vrkit/plugin/Module.h>
#include <vrkit/plugin/RegistryEntry.h>

namespace vrkit
{

namespace plugin
{

RegistryEntry::RegistryEntry(vpr::LibraryPtr module)
   : mModule(module)
   , mModuleInfo(getModuleInfo(module))
{
   /* Do nothing. */ ;
}

RegistryEntry::~RegistryEntry()
{
}

CreatorBase*
RegistryEntry::getCreatorFunc(vpr::LibraryPtr module,
                              const std::string& getCreatorFuncName)
   const
{
   Module pm(module);
   return pm.getFunction<CreatorBase* ()>(getCreatorFuncName)();
}

Info RegistryEntry::getModuleInfo(vpr::LibraryPtr module)
{
   Module pm(module);
   typedef const Info* sig_type();
   return *pm.getFunction<sig_type>(AbstractPlugin::getInfoFuncName())();
}

}

}
<|endoftext|>


<commit_before>/*
 * xmpp_features.cpp - XMPP entity features
 * Copyright (C) 2003  Justin Karneges
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <QCoreApplication>
#include <QString>
#include <QMap>
#include <QStringList>

#include "xmpp_features.h"

using namespace XMPP;

Features::Features()
{
}

Features::Features(const QStringList &l)
{
	setList(l);
}

Features::Features(const QString &str)
{
	QStringList l;
	l << str;

	setList(l);
}

Features::~Features()
{
}

QStringList Features::list() const
{
	return _list;
}

void Features::setList(const QStringList &l)
{
	_list = l;
}

void Features::addFeature(const QString& s)
{
	_list += s;
}

bool Features::test(const QStringList &ns) const
{
	QStringList::ConstIterator it = ns.begin();
	for ( ; it != ns.end(); ++it) {
		if ( _list.contains( *it )) {
			return true;
		}
	}
	return false;
}

#define FID_MULTICAST "http://jabber.org/protocol/address"
bool Features::canMulticast() const
{
	QStringList ns;
	ns << FID_MULTICAST;

	return test(ns);
}

#define FID_AHCOMMAND "http://jabber.org/protocol/commands"
bool Features::canCommand() const
{
	QStringList ns;
	ns << FID_AHCOMMAND;

	return test(ns);
}

#define FID_REGISTER "jabber:iq:register"
bool Features::canRegister() const
{
	QStringList ns;
	ns << FID_REGISTER;

	return test(ns);
}

#define FID_SEARCH "jabber:iq:search"
bool Features::canSearch() const
{
	QStringList ns;
	ns << FID_SEARCH;

	return test(ns);
}

#define FID_GROUPCHAT "jabber:iq:conference"
bool Features::canGroupchat() const
{
	QStringList ns;
	ns << "http://jabber.org/protocol/muc";
	ns << FID_GROUPCHAT;

	return test(ns);
}

#define FID_VOICE "http://www.google.com/xmpp/protocol/voice/v1"
bool Features::canVoice() const
{
	QStringList ns;
	ns << FID_VOICE;

	return test(ns);
}

#define FID_GATEWAY "jabber:iq:gateway"
bool Features::isGateway() const
{
	QStringList ns;
	ns << FID_GATEWAY;

	return test(ns);
}

#define FID_DISCO "http://jabber.org/protocol/disco"
bool Features::canDisco() const
{
	QStringList ns;
	ns << FID_DISCO;
	ns << "http://jabber.org/protocol/disco#info";
	ns << "http://jabber.org/protocol/disco#items";

	return test(ns);
}

#define FID_CHATSTATE "http://jabber.org/protocol/chatstates"
bool Features::canChatState() const
{
	QStringList ns;
	ns << FID_CHATSTATE;

	return test(ns);
}

#define FID_VCARD "vcard-temp"
bool Features::haveVCard() const
{
	QStringList ns;
	ns << FID_VCARD;

	return test(ns);
}

// custom Psi acitons
#define FID_ADD "psi:add"

class Features::FeatureName : public QObject
{
	Q_OBJECT

public:
	FeatureName()
	: QObject(qApp)
	{
		id2s[FID_Invalid]	= tr("ERROR: Incorrect usage of Features class");
		id2s[FID_None]		= tr("None");
		id2s[FID_Register]	= tr("Register");
		id2s[FID_Search]	= tr("Search");
		id2s[FID_Groupchat]	= tr("Groupchat");
		id2s[FID_Gateway]	= tr("Gateway");
		id2s[FID_Disco]		= tr("Service Discovery");
		id2s[FID_VCard]		= tr("VCard");
		id2s[FID_AHCommand]	= tr("Execute command");

		// custom Psi actions
		id2s[FID_Add]		= tr("Add to roster");

		// compute reverse map
		//QMap<QString, long>::Iterator it = id2s.begin();
		//for ( ; it != id2s.end(); ++it)
		//	s2id[it.data()] = it.key();

		id2f[FID_Register]	= FID_REGISTER;
		id2f[FID_Search]	= FID_SEARCH;
		id2f[FID_Groupchat]	= FID_GROUPCHAT;
		id2f[FID_Gateway]	= FID_GATEWAY;
		id2f[FID_Disco]		= FID_DISCO;
		id2f[FID_VCard]		= FID_VCARD;
		id2f[FID_AHCommand]	= FID_AHCOMMAND;

		// custom Psi actions
		id2f[FID_Add]		= FID_ADD;
	}

	//QMap<QString, long> s2id;
	QMap<long, QString> id2s;
	QMap<long, QString> id2f;
};

static Features::FeatureName *featureName = 0;

long Features::id() const
{
	if ( _list.count() > 1 )
		return FID_Invalid;
	else if ( canRegister() )
		return FID_Register;
	else if ( canSearch() )
		return FID_Search;
	else if ( canGroupchat() )
		return FID_Groupchat;
	else if ( isGateway() )
		return FID_Gateway;
	else if ( canDisco() )
		return FID_Disco;
	else if ( haveVCard() )
		return FID_VCard;
	else if ( canCommand() )
		return FID_AHCommand;
	else if ( test(QStringList(FID_ADD)) )
		return FID_Add;

	return FID_None;
}

long Features::id(const QString &feature)
{
	Features f(feature);
	return f.id();
}

QString Features::feature(long id)
{
	if ( !featureName )
		featureName = new FeatureName();

	return featureName->id2f[id];
}

QString Features::name(long id)
{
	if ( !featureName )
		featureName = new FeatureName();

	return featureName->id2s[id];
}

QString Features::name() const
{
	return name(id());
}

QString Features::name(const QString &feature)
{
	Features f(feature);
	return f.name(f.id());
}

#include "xmpp_features.moc"
<commit_msg>fix compile on qt 4.3<commit_after>/*
 * xmpp_features.cpp - XMPP entity features
 * Copyright (C) 2003  Justin Karneges
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <QCoreApplication>
#include <QString>
#include <QMap>
#include <QStringList>

#include "xmpp_features.h"

using namespace XMPP;

Features::Features()
{
}

Features::Features(const QStringList &l)
{
	setList(l);
}

Features::Features(const QString &str)
{
	QStringList l;
	l << str;

	setList(l);
}

Features::~Features()
{
}

QStringList Features::list() const
{
	return _list;
}

void Features::setList(const QStringList &l)
{
	_list = l;
}

void Features::addFeature(const QString& s)
{
	_list += s;
}

bool Features::test(const QStringList &ns) const
{
	QStringList::ConstIterator it = ns.begin();
	for ( ; it != ns.end(); ++it) {
		if ( _list.contains( *it )) {
			return true;
		}
	}
	return false;
}

#define FID_MULTICAST "http://jabber.org/protocol/address"
bool Features::canMulticast() const
{
	QStringList ns;
	ns << FID_MULTICAST;

	return test(ns);
}

#define FID_AHCOMMAND "http://jabber.org/protocol/commands"
bool Features::canCommand() const
{
	QStringList ns;
	ns << FID_AHCOMMAND;

	return test(ns);
}

#define FID_REGISTER "jabber:iq:register"
bool Features::canRegister() const
{
	QStringList ns;
	ns << FID_REGISTER;

	return test(ns);
}

#define FID_SEARCH "jabber:iq:search"
bool Features::canSearch() const
{
	QStringList ns;
	ns << FID_SEARCH;

	return test(ns);
}

#define FID_GROUPCHAT "jabber:iq:conference"
bool Features::canGroupchat() const
{
	QStringList ns;
	ns << "http://jabber.org/protocol/muc";
	ns << FID_GROUPCHAT;

	return test(ns);
}

#define FID_VOICE "http://www.google.com/xmpp/protocol/voice/v1"
bool Features::canVoice() const
{
	QStringList ns;
	ns << FID_VOICE;

	return test(ns);
}

#define FID_GATEWAY "jabber:iq:gateway"
bool Features::isGateway() const
{
	QStringList ns;
	ns << FID_GATEWAY;

	return test(ns);
}

#define FID_DISCO "http://jabber.org/protocol/disco"
bool Features::canDisco() const
{
	QStringList ns;
	ns << FID_DISCO;
	ns << "http://jabber.org/protocol/disco#info";
	ns << "http://jabber.org/protocol/disco#items";

	return test(ns);
}

#define FID_CHATSTATE "http://jabber.org/protocol/chatstates"
bool Features::canChatState() const
{
	QStringList ns;
	ns << FID_CHATSTATE;

	return test(ns);
}

#define FID_VCARD "vcard-temp"
bool Features::haveVCard() const
{
	QStringList ns;
	ns << FID_VCARD;

	return test(ns);
}

// custom Psi acitons
#define FID_ADD "psi:add"

class Features::FeatureName : public QObject
{
	Q_OBJECT

public:
	FeatureName()
	: QObject(QCoreApplication::instance())
	{
		id2s[FID_Invalid]	= tr("ERROR: Incorrect usage of Features class");
		id2s[FID_None]		= tr("None");
		id2s[FID_Register]	= tr("Register");
		id2s[FID_Search]	= tr("Search");
		id2s[FID_Groupchat]	= tr("Groupchat");
		id2s[FID_Gateway]	= tr("Gateway");
		id2s[FID_Disco]		= tr("Service Discovery");
		id2s[FID_VCard]		= tr("VCard");
		id2s[FID_AHCommand]	= tr("Execute command");

		// custom Psi actions
		id2s[FID_Add]		= tr("Add to roster");

		// compute reverse map
		//QMap<QString, long>::Iterator it = id2s.begin();
		//for ( ; it != id2s.end(); ++it)
		//	s2id[it.data()] = it.key();

		id2f[FID_Register]	= FID_REGISTER;
		id2f[FID_Search]	= FID_SEARCH;
		id2f[FID_Groupchat]	= FID_GROUPCHAT;
		id2f[FID_Gateway]	= FID_GATEWAY;
		id2f[FID_Disco]		= FID_DISCO;
		id2f[FID_VCard]		= FID_VCARD;
		id2f[FID_AHCommand]	= FID_AHCOMMAND;

		// custom Psi actions
		id2f[FID_Add]		= FID_ADD;
	}

	//QMap<QString, long> s2id;
	QMap<long, QString> id2s;
	QMap<long, QString> id2f;
};

static Features::FeatureName *featureName = 0;

long Features::id() const
{
	if ( _list.count() > 1 )
		return FID_Invalid;
	else if ( canRegister() )
		return FID_Register;
	else if ( canSearch() )
		return FID_Search;
	else if ( canGroupchat() )
		return FID_Groupchat;
	else if ( isGateway() )
		return FID_Gateway;
	else if ( canDisco() )
		return FID_Disco;
	else if ( haveVCard() )
		return FID_VCard;
	else if ( canCommand() )
		return FID_AHCommand;
	else if ( test(QStringList(FID_ADD)) )
		return FID_Add;

	return FID_None;
}

long Features::id(const QString &feature)
{
	Features f(feature);
	return f.id();
}

QString Features::feature(long id)
{
	if ( !featureName )
		featureName = new FeatureName();

	return featureName->id2f[id];
}

QString Features::name(long id)
{
	if ( !featureName )
		featureName = new FeatureName();

	return featureName->id2s[id];
}

QString Features::name() const
{
	return name(id());
}

QString Features::name(const QString &feature)
{
	Features f(feature);
	return f.name(f.id());
}

#include "xmpp_features.moc"
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2014 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin_explorer.
 *
 * libbitcoin_explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef BX_FETCH_CONFIRMATIONS_HPP
#define BX_FETCH_CONFIRMATIONS_HPP

#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/explorer/command.hpp>
#include <bitcoin/explorer/define.hpp>
#include <bitcoin/explorer/generated.hpp>
#include <bitcoin/explorer/primitives/address.hpp>
#include <bitcoin/explorer/primitives/base16.hpp>
#include <bitcoin/explorer/primitives/base2.hpp>
#include <bitcoin/explorer/primitives/base58.hpp>
#include <bitcoin/explorer/primitives/btc.hpp>
#include <bitcoin/explorer/primitives/btc160.hpp>
#include <bitcoin/explorer/primitives/btc256.hpp>
#include <bitcoin/explorer/primitives/ec_private.hpp>
#include <bitcoin/explorer/primitives/ec_public.hpp>
#include <bitcoin/explorer/primitives/encoding.hpp>
#include <bitcoin/explorer/primitives/hashtype.hpp>
#include <bitcoin/explorer/primitives/hd_key.hpp>
#include <bitcoin/explorer/primitives/hd_priv.hpp>
#include <bitcoin/explorer/primitives/hd_pub.hpp>
#include <bitcoin/explorer/primitives/header.hpp>
#include <bitcoin/explorer/primitives/input.hpp>
#include <bitcoin/explorer/primitives/output.hpp>
#include <bitcoin/explorer/primitives/raw.hpp>
#include <bitcoin/explorer/primitives/script.hpp>
#include <bitcoin/explorer/primitives/stealth.hpp>
#include <bitcoin/explorer/primitives/transaction.hpp>
#include <bitcoin/explorer/primitives/wif.hpp>
#include <bitcoin/explorer/primitives/wrapper.hpp>
#include <bitcoin/explorer/utility/compat.hpp>
#include <bitcoin/explorer/utility/config.hpp>
#include <bitcoin/explorer/utility/utility.hpp>

/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/

namespace libbitcoin {
namespace explorer {
namespace commands {

/**
 * Various localizable strings.
 */
#define BX_FETCH_CONFIRMATIONS_OUTPUT \
    "[%1%] Confirmations: %2%"

/**
 * Class to implement the fetch-confirmations command.
 */
class fetch_confirmations
    : public command
{
public:

    /**
     * The symbolic (not localizable) command name, lower case.
     */
    static const char* symbol() { return "fetch-confirmations"; }

    /**
     * The member symbolic (not localizable) command name, lower case.
     */
    virtual const char* name()
    {
        return fetch_confirmations::symbol();
    }

    /**
     * The localizable command category name, upper case.
     */
    virtual const char* category()
    {
        return "ONLINE";
    }

    /**
     * Load program argument definitions.
     * A value of -1 indicates that the number of instances is unlimited.
     * @return  The loaded program argument definitions.
     */
    virtual arguments_metadata& load_arguments()
    {
        return get_argument_metadata()
            .add("TRANSACTION", -1);
    }

	/**
     * Load parameter fallbacks from file or input as appropriate.
     * @param[in]  input  The input stream for loading the parameters.
     * @param[in]         The loaded variables.
     */
    virtual void load_fallbacks(std::istream& input,
        po::variables_map& variables)
    {
        //load_path(get_transactions_argument(), "TRANSACTION", variables);
        //load_input(get_transactions_argument(), "TRANSACTION", variables, input);
    }

    /**
     * Load program option definitions.
     * The implicit_value call allows flags to be strongly-typed on read while
     * allowing but not requiring a value on the command line for the option.
     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009
     * @return  The loaded program option definitions.
     */
    virtual options_metadata& load_options()
    {
        using namespace po;
        options_description& options = get_option_metadata();
        options.add_options()
            (
                BX_CONFIG_VARIABLE ",c",
                value<boost::filesystem::path>(),
                "The path and file name for the configuration settings file to be used in the execution of the command."
            )
            (
                "help,h",
                value<bool>(&option_.help)->implicit_value(true),
                "Get confirmations for a set of transactions. Requires an Obelisk server connection."
            )
            (
                "format,f",
                value<primitives::encoding>(&option_.format),
                "The output format. Options are 'json', 'xml', 'info' or 'native', defaults to native."
            )
            (
                "TRANSACTION",
                value<std::string>(),
                "The file path of the set of Base16 transactions. If not specified the transactions are read from STDIN."
            );

        return options;
    }

    /**
     * Invoke the command.
     * @param[out]  output  The input stream for the command execution.
     * @param[out]  error   The input stream for the command execution.
     * @return              The appropriate console return code { -1, 0, 1 }.
     */
    virtual console_result invoke(std::ostream& output, std::ostream& cerr);

    /* Properties */

    /**
     * Get the value of the TRANSACTION arguments.
     */
    virtual std::vector<primitives::transaction>& get_transactions_argument()
    {
        return argument_.transactions;
    }

    /**
     * Set the value of the TRANSACTION arguments.
     */
    virtual void set_transactions_argument(
        const std::vector<primitives::transaction>& value)
    {
        argument_.transactions = value;
    }

    /**
     * Get the value of the help option.
     */
    virtual bool& get_help_option()
    {
        return option_.help;
    }

    /**
     * Set the value of the help option.
     */
    virtual void set_help_option(
        const bool& value)
    {
        option_.help = value;
    }

    /**
     * Get the value of the format option.
     */
    virtual primitives::encoding& get_format_option()
    {
        return option_.format;
    }

    /**
     * Set the value of the format option.
     */
    virtual void set_format_option(
        const primitives::encoding& value)
    {
        option_.format = value;
    }

private:

    /**
     * Command line argument bound variables.
     * Uses cross-compiler safe constructor-based zeroize.
     * Zeroize for unit test consistency with program_options initialization.
     */
    struct argument
    {
        argument()
          : transactions()
        {
        }

        std::vector<primitives::transaction> transactions;
    } argument_;

    /**
     * Command line option bound variables.
     * Uses cross-compiler safe constructor-based zeroize.
     * Zeroize for unit test consistency with program_options initialization.
     */
    struct option
    {
        option()
          : help(),
            format()
        {
        }

        bool help;
        primitives::encoding format;
    } option_;
};

} // namespace commands
} // namespace explorer
} // namespace libbitcoin

#endif
<commit_msg>Disable fetch-configmrations format option.<commit_after>/**
 * Copyright (c) 2011-2014 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin_explorer.
 *
 * libbitcoin_explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef BX_FETCH_CONFIRMATIONS_HPP
#define BX_FETCH_CONFIRMATIONS_HPP

#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/explorer/command.hpp>
#include <bitcoin/explorer/define.hpp>
#include <bitcoin/explorer/generated.hpp>
#include <bitcoin/explorer/primitives/address.hpp>
#include <bitcoin/explorer/primitives/base16.hpp>
#include <bitcoin/explorer/primitives/base2.hpp>
#include <bitcoin/explorer/primitives/base58.hpp>
#include <bitcoin/explorer/primitives/btc.hpp>
#include <bitcoin/explorer/primitives/btc160.hpp>
#include <bitcoin/explorer/primitives/btc256.hpp>
#include <bitcoin/explorer/primitives/ec_private.hpp>
#include <bitcoin/explorer/primitives/ec_public.hpp>
#include <bitcoin/explorer/primitives/encoding.hpp>
#include <bitcoin/explorer/primitives/hashtype.hpp>
#include <bitcoin/explorer/primitives/hd_key.hpp>
#include <bitcoin/explorer/primitives/hd_priv.hpp>
#include <bitcoin/explorer/primitives/hd_pub.hpp>
#include <bitcoin/explorer/primitives/header.hpp>
#include <bitcoin/explorer/primitives/input.hpp>
#include <bitcoin/explorer/primitives/output.hpp>
#include <bitcoin/explorer/primitives/raw.hpp>
#include <bitcoin/explorer/primitives/script.hpp>
#include <bitcoin/explorer/primitives/stealth.hpp>
#include <bitcoin/explorer/primitives/transaction.hpp>
#include <bitcoin/explorer/primitives/wif.hpp>
#include <bitcoin/explorer/primitives/wrapper.hpp>
#include <bitcoin/explorer/utility/compat.hpp>
#include <bitcoin/explorer/utility/config.hpp>
#include <bitcoin/explorer/utility/utility.hpp>

/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/

namespace libbitcoin {
namespace explorer {
namespace commands {

/**
 * Various localizable strings.
 */
#define BX_FETCH_CONFIRMATIONS_OUTPUT \
    "[%1%] Confirmations: %2%"

/**
 * Class to implement the fetch-confirmations command.
 */
class fetch_confirmations
    : public command
{
public:

    /**
     * The symbolic (not localizable) command name, lower case.
     */
    static const char* symbol() { return "fetch-confirmations"; }

    /**
     * The member symbolic (not localizable) command name, lower case.
     */
    virtual const char* name()
    {
        return fetch_confirmations::symbol();
    }

    /**
     * The localizable command category name, upper case.
     */
    virtual const char* category()
    {
        return "ONLINE";
    }

    /**
     * Load program argument definitions.
     * A value of -1 indicates that the number of instances is unlimited.
     * @return  The loaded program argument definitions.
     */
    virtual arguments_metadata& load_arguments()
    {
        return get_argument_metadata()
            .add("TRANSACTION", -1);
    }

	/**
     * Load parameter fallbacks from file or input as appropriate.
     * @param[in]  input  The input stream for loading the parameters.
     * @param[in]         The loaded variables.
     */
    virtual void load_fallbacks(std::istream& input,
        po::variables_map& variables)
    {
        //load_path(get_transactions_argument(), "TRANSACTION", variables);
        //load_input(get_transactions_argument(), "TRANSACTION", variables, input);
    }

    /**
     * Load program option definitions.
     * The implicit_value call allows flags to be strongly-typed on read while
     * allowing but not requiring a value on the command line for the option.
     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009
     * @return  The loaded program option definitions.
     */
    virtual options_metadata& load_options()
    {
        using namespace po;
        options_description& options = get_option_metadata();
        options.add_options()
            (
                BX_CONFIG_VARIABLE ",c",
                value<boost::filesystem::path>(),
                "The path and file name for the configuration settings file to be used in the execution of the command."
            )
            (
                "help,h",
                value<bool>(&option_.help)->implicit_value(true),
                "Get confirmations for a set of transactions. Requires an Obelisk server connection."
            )
            (
                "TRANSACTION",
                value<std::string>(),
                "The file path of the set of Base16 transactions. If not specified the transactions are read from STDIN."
            );

        return options;
    }

    /**
     * Invoke the command.
     * @param[out]  output  The input stream for the command execution.
     * @param[out]  error   The input stream for the command execution.
     * @return              The appropriate console return code { -1, 0, 1 }.
     */
    virtual console_result invoke(std::ostream& output, std::ostream& cerr);

    /* Properties */

    /**
     * Get the value of the TRANSACTION arguments.
     */
    virtual std::vector<primitives::transaction>& get_transactions_argument()
    {
        return argument_.transactions;
    }

    /**
     * Set the value of the TRANSACTION arguments.
     */
    virtual void set_transactions_argument(
        const std::vector<primitives::transaction>& value)
    {
        argument_.transactions = value;
    }

    /**
     * Get the value of the help option.
     */
    virtual bool& get_help_option()
    {
        return option_.help;
    }

    /**
     * Set the value of the help option.
     */
    virtual void set_help_option(
        const bool& value)
    {
        option_.help = value;
    }

private:

    /**
     * Command line argument bound variables.
     * Uses cross-compiler safe constructor-based zeroize.
     * Zeroize for unit test consistency with program_options initialization.
     */
    struct argument
    {
        argument()
          : transactions()
        {
        }

        std::vector<primitives::transaction> transactions;
    } argument_;

    /**
     * Command line option bound variables.
     * Uses cross-compiler safe constructor-based zeroize.
     * Zeroize for unit test consistency with program_options initialization.
     */
    struct option
    {
        option()
          : help()
        {
        }

        bool help;
    } option_;
};

} // namespace commands
} // namespace explorer
} // namespace libbitcoin

#endif
<|endoftext|>


<commit_before>#pragma once
#include <set>
#include <memory>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>

#include "timing_analyzers.hpp"
#include "TimingGraph.hpp"
#include "TimingConstraints.hpp"
#include "TimingTags.hpp"
#include "FixedDelayCalculator.hpp"

namespace tatum {

float time_sec(struct timespec start, struct timespec end);

void print_histogram(const std::vector<float>& values, int nbuckets);

void print_level_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanin_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanout_histogram(const TimingGraph& tg, int nbuckets);

void print_timing_graph(std::shared_ptr<const TimingGraph> tg);
void print_levelization(std::shared_ptr<const TimingGraph> tg);

void dump_level_times(std::string fname, const TimingGraph& timing_graph, std::map<std::string,float> serial_prof_data, std::map<std::string,float> parallel_prof_data);

std::vector<NodeId> find_related_nodes(const TimingGraph& tg, const std::vector<NodeId> through_nodes, size_t max_depth=std::numeric_limits<size_t>::max());
void find_transitive_fanout_nodes(const TimingGraph& tg, std::vector<NodeId>& nodes, const NodeId node, size_t max_depth=std::numeric_limits<size_t>::max(), size_t depth=0);
void find_transitive_fanin_nodes(const TimingGraph& tg, std::vector<NodeId>& nodes, const NodeId node, size_t max_depth=std::numeric_limits<size_t>::max(), size_t depth=0);

std::string print_tag_domain_from_to(const TimingTag& tag);

/*
 * Templated function implementations
 */

template<class DelayCalc=FixedDelayCalculator>
void write_dot_file_setup(std::string filename,
                          const TimingGraph& tg,
                          const DelayCalc& delay_calc = DelayCalc(),
                          const SetupTimingAnalyzer& analyzer = SetupTimingAnalyzer(),
                          std::vector<NodeId> nodes = std::vector<NodeId>()) {

    if(tg.nodes().size() > 1000 && nodes.empty()) {
        std::cout << "Skipping setup dot file due to large timing graph size\n";
        return;
    }

    std::ofstream os(filename);

    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    if(nodes.empty()) {
        auto tg_nodes = tg.nodes();
        std::copy(tg_nodes.begin(), tg_nodes.end(), std::back_inserter(nodes));
    }

    for(const NodeId inode : nodes) {
        os << "\tnode" << size_t(inode);
        os << "[label=\"";
        os << "{" << inode << " (" << tg.node_type(inode) << ")";
        for(const auto& tags : {analyzer.setup_tags(inode), analyzer.setup_slacks(inode)}) {
            for(const TimingTag& tag : tags) {
                os << " | {";
                os << tag.type() << "\\n";
                os << print_tag_domain_from_to(tag);
                if(tag.origin_node()) {
                    if(tag.type() == TagType::CLOCK_LAUNCH || tag.type() == TagType::CLOCK_CAPTURE || tag.type() == TagType::DATA_ARRIVAL) {
                        os << " from ";
                    } else {
                        os << " for ";
                    }
                    os << tag.origin_node();
                } else {
                    os << " [Origin] ";
                }
                os << "\\n";
                os << "time: " << tag.time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level_nodes(ilevel)) {
            if(std::binary_search(nodes.begin(), nodes.end(), node_id)) {
                os << " node" << size_t(node_id) <<";";
            }
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(EdgeId edge_id : tg.edges()) {
        NodeId node_id = tg.edge_src_node(edge_id);
        NodeId sink_node_id = tg.edge_sink_node(edge_id);

        if(std::binary_search(nodes.begin(), nodes.end(), node_id)
           && std::binary_search(nodes.begin(), nodes.end(), sink_node_id)) {
            //Only draw edges to nodes in the set of nodes being printed

            os << "\tnode" << size_t(node_id) << " -> node" << size_t(sink_node_id);
            os << " [ label=\"" << edge_id;
            if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SINK) {
                os << "\\n"<< -delay_calc.setup_time(tg, edge_id) << " (-tsu)";
            } else if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SOURCE) {
                os << "\\n" << delay_calc.max_edge_delay(tg, edge_id) << " (tcq)";
            } else {
                os << "\\n" << delay_calc.max_edge_delay(tg, edge_id);
            }
            auto slacks = analyzer.setup_slacks(edge_id);
            for(const auto& tag : slacks) {
                os << "\\n" << " (slack " << print_tag_domain_from_to(tag) << ": " << tag.time().value() << ")";
            }
            if(tg.edge_disabled(edge_id)) {
                os << "\\n" << "(disabled)";
            }
            os << "\""; //end label
            if(tg.edge_disabled(edge_id)) {
                os << " style=\"dashed\"";
                os << " color=\"#aaaaaa\""; //grey
                os << " fontcolor=\"#aaaaaa\""; //grey
            }
            os << "]";
            os << ";" <<std::endl;
        }
    }

    os << "}" <<std::endl;
}

template<class DelayCalc=FixedDelayCalculator>
void write_dot_file_hold(std::string filename,
                         const TimingGraph& tg,
                         const DelayCalc& delay_calc = DelayCalc(),
                         const HoldTimingAnalyzer& analyzer = TimingAnalyzer(),
                         std::vector<NodeId> nodes = std::vector<NodeId>()) {

    if(tg.nodes().size() > 1000 && nodes.empty()) {
        std::cout << "Skipping hold dot file due to large timing graph size\n";
        return;
    }

    std::ofstream os(filename);

    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    if(nodes.empty()) {
        auto tg_nodes = tg.nodes();
        std::copy(tg_nodes.begin(), tg_nodes.end(), std::back_inserter(nodes));
    }

    for(const NodeId inode : nodes) {
        os << "\tnode" << size_t(inode);
        os << "[label=\"";
        os << "{" << inode << " (" << tg.node_type(inode) << ")";
        for(const auto& tags : {analyzer.hold_tags(inode), analyzer.hold_slacks(inode)}) {
            for(const TimingTag& tag : tags) {
                os << " | {";
                os << tag.type() << "\\n";
                os << print_tag_domain_from_to(tag);
                if(tag.origin_node()) {
                    if(tag.type() == TagType::CLOCK_LAUNCH || tag.type() == TagType::CLOCK_CAPTURE || tag.type() == TagType::DATA_ARRIVAL) {
                        os << " from ";
                    } else {
                        os << " for ";
                    }
                    os << tag.origin_node();
                } else {
                    os << " [Origin] ";
                }
                os << "\\n";
                os << " time: " << tag.time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level_nodes(ilevel)) {
            if(std::binary_search(nodes.begin(), nodes.end(), node_id)) {
                os << " node" << size_t(node_id) <<";";
            }
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(EdgeId edge_id : tg.edges()) {
        NodeId node_id = tg.edge_src_node(edge_id);
        NodeId sink_node_id = tg.edge_sink_node(edge_id);

        if(std::binary_search(nodes.begin(), nodes.end(), node_id)
           && std::binary_search(nodes.begin(), nodes.end(), sink_node_id)) {
            //Only draw edges to nodes in the set of nodes being printed

            os << "\tnode" << size_t(node_id) << " -> node" << size_t(sink_node_id);
            os << " [ label=\"" << edge_id;
            if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SINK) {
                os << " [ label=\"" << edge_id << "\n" << delay_calc.hold_time(tg, edge_id) << " (thld)\" ]";
            } else if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SOURCE) {
                os << " [ label=\"" << edge_id << "\n" << delay_calc.min_edge_delay(tg, edge_id) << " (tcq)\" ]";
            } else {
                os << " [ label=\"" << edge_id << "\n" << delay_calc.min_edge_delay(tg, edge_id) << "\" ]";
            }
            auto slacks = analyzer.hold_slacks(edge_id);
            for(const auto& tag : slacks) {
                os << "\\n" << " (slack " << print_tag_domain_from_to(tag) << ": " << tag.time().value() << ")";
            }
            if(tg.edge_disabled(edge_id)) {
                os << "\\n" << "(disabled)";
            }
            os << "\""; //end label
            if(tg.edge_disabled(edge_id)) {
                os << " style=\"dashed\"";
                os << " color=\"#aaaaaa\""; //grey
                os << " fontcolor=\"#aaaaaa\""; //grey
            }
            os << "]";
            os << ";" <<std::endl;
        }
    }

    os << "}" <<std::endl;
}

void print_setup_tags_histogram(const TimingGraph& tg, const SetupTimingAnalyzer& analyzer);
void print_hold_tags_histogram(const TimingGraph& tg, const HoldTimingAnalyzer& analyzer);

void print_setup_tags(const TimingGraph& tg, const SetupTimingAnalyzer& analyzer);
void print_hold_tags(const TimingGraph& tg, const HoldTimingAnalyzer& analyzer);

} //namepsace
<commit_msg>Fix hold dot file output<commit_after>#pragma once
#include <set>
#include <memory>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>

#include "timing_analyzers.hpp"
#include "TimingGraph.hpp"
#include "TimingConstraints.hpp"
#include "TimingTags.hpp"
#include "FixedDelayCalculator.hpp"

namespace tatum {

float time_sec(struct timespec start, struct timespec end);

void print_histogram(const std::vector<float>& values, int nbuckets);

void print_level_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanin_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanout_histogram(const TimingGraph& tg, int nbuckets);

void print_timing_graph(std::shared_ptr<const TimingGraph> tg);
void print_levelization(std::shared_ptr<const TimingGraph> tg);

void dump_level_times(std::string fname, const TimingGraph& timing_graph, std::map<std::string,float> serial_prof_data, std::map<std::string,float> parallel_prof_data);

std::vector<NodeId> find_related_nodes(const TimingGraph& tg, const std::vector<NodeId> through_nodes, size_t max_depth=std::numeric_limits<size_t>::max());
void find_transitive_fanout_nodes(const TimingGraph& tg, std::vector<NodeId>& nodes, const NodeId node, size_t max_depth=std::numeric_limits<size_t>::max(), size_t depth=0);
void find_transitive_fanin_nodes(const TimingGraph& tg, std::vector<NodeId>& nodes, const NodeId node, size_t max_depth=std::numeric_limits<size_t>::max(), size_t depth=0);

std::string print_tag_domain_from_to(const TimingTag& tag);

/*
 * Templated function implementations
 */

template<class DelayCalc=FixedDelayCalculator>
void write_dot_file_setup(std::string filename,
                          const TimingGraph& tg,
                          const DelayCalc& delay_calc = DelayCalc(),
                          const SetupTimingAnalyzer& analyzer = SetupTimingAnalyzer(),
                          std::vector<NodeId> nodes = std::vector<NodeId>()) {

    if(tg.nodes().size() > 1000 && nodes.empty()) {
        std::cout << "Skipping setup dot file due to large timing graph size\n";
        return;
    }

    std::ofstream os(filename);

    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    if(nodes.empty()) {
        auto tg_nodes = tg.nodes();
        std::copy(tg_nodes.begin(), tg_nodes.end(), std::back_inserter(nodes));
    }

    for(const NodeId inode : nodes) {
        os << "\tnode" << size_t(inode);
        os << "[label=\"";
        os << "{" << inode << " (" << tg.node_type(inode) << ")";
        for(const auto& tags : {analyzer.setup_tags(inode), analyzer.setup_slacks(inode)}) {
            for(const TimingTag& tag : tags) {
                os << " | {";
                os << tag.type() << "\\n";
                os << print_tag_domain_from_to(tag);
                if(tag.origin_node()) {
                    if(tag.type() == TagType::CLOCK_LAUNCH || tag.type() == TagType::CLOCK_CAPTURE || tag.type() == TagType::DATA_ARRIVAL) {
                        os << " from ";
                    } else {
                        os << " for ";
                    }
                    os << tag.origin_node();
                } else {
                    os << " [Origin] ";
                }
                os << "\\n";
                os << "time: " << tag.time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level_nodes(ilevel)) {
            if(std::binary_search(nodes.begin(), nodes.end(), node_id)) {
                os << " node" << size_t(node_id) <<";";
            }
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(EdgeId edge_id : tg.edges()) {
        NodeId node_id = tg.edge_src_node(edge_id);
        NodeId sink_node_id = tg.edge_sink_node(edge_id);

        if(std::binary_search(nodes.begin(), nodes.end(), node_id)
           && std::binary_search(nodes.begin(), nodes.end(), sink_node_id)) {
            //Only draw edges to nodes in the set of nodes being printed

            os << "\tnode" << size_t(node_id) << " -> node" << size_t(sink_node_id);
            os << " [ label=\"" << edge_id;
            if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SINK) {
                os << "\\n"<< -delay_calc.setup_time(tg, edge_id) << " (-tsu)";
            } else if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SOURCE) {
                os << "\\n" << delay_calc.max_edge_delay(tg, edge_id) << " (tcq)";
            } else {
                os << "\\n" << delay_calc.max_edge_delay(tg, edge_id);
            }
            auto slacks = analyzer.setup_slacks(edge_id);
            for(const auto& tag : slacks) {
                os << "\\n" << " (slack " << print_tag_domain_from_to(tag) << ": " << tag.time().value() << ")";
            }
            if(tg.edge_disabled(edge_id)) {
                os << "\\n" << "(disabled)";
            }
            os << "\""; //end label
            if(tg.edge_disabled(edge_id)) {
                os << " style=\"dashed\"";
                os << " color=\"#aaaaaa\""; //grey
                os << " fontcolor=\"#aaaaaa\""; //grey
            }
            os << "]";
            os << ";" <<std::endl;
        }
    }

    os << "}" <<std::endl;
}

template<class DelayCalc=FixedDelayCalculator>
void write_dot_file_hold(std::string filename,
                         const TimingGraph& tg,
                         const DelayCalc& delay_calc = DelayCalc(),
                         const HoldTimingAnalyzer& analyzer = TimingAnalyzer(),
                         std::vector<NodeId> nodes = std::vector<NodeId>()) {

    if(tg.nodes().size() > 1000 && nodes.empty()) {
        std::cout << "Skipping hold dot file due to large timing graph size\n";
        return;
    }

    std::ofstream os(filename);

    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    if(nodes.empty()) {
        auto tg_nodes = tg.nodes();
        std::copy(tg_nodes.begin(), tg_nodes.end(), std::back_inserter(nodes));
    }

    for(const NodeId inode : nodes) {
        os << "\tnode" << size_t(inode);
        os << "[label=\"";
        os << "{" << inode << " (" << tg.node_type(inode) << ")";
        for(const auto& tags : {analyzer.hold_tags(inode), analyzer.hold_slacks(inode)}) {
            for(const TimingTag& tag : tags) {
                os << " | {";
                os << tag.type() << "\\n";
                os << print_tag_domain_from_to(tag);
                if(tag.origin_node()) {
                    if(tag.type() == TagType::CLOCK_LAUNCH || tag.type() == TagType::CLOCK_CAPTURE || tag.type() == TagType::DATA_ARRIVAL) {
                        os << " from ";
                    } else {
                        os << " for ";
                    }
                    os << tag.origin_node();
                } else {
                    os << " [Origin] ";
                }
                os << "\\n";
                os << " time: " << tag.time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level_nodes(ilevel)) {
            if(std::binary_search(nodes.begin(), nodes.end(), node_id)) {
                os << " node" << size_t(node_id) <<";";
            }
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(EdgeId edge_id : tg.edges()) {
        NodeId node_id = tg.edge_src_node(edge_id);
        NodeId sink_node_id = tg.edge_sink_node(edge_id);

        if(std::binary_search(nodes.begin(), nodes.end(), node_id)
           && std::binary_search(nodes.begin(), nodes.end(), sink_node_id)) {
            //Only draw edges to nodes in the set of nodes being printed

            os << "\tnode" << size_t(node_id) << " -> node" << size_t(sink_node_id);
            os << " [ label=\"" << edge_id;
            if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SINK) {
                os << "\\n" << delay_calc.hold_time(tg, edge_id) << " (thld)";
            } else if(tg.node_type(node_id) == NodeType::CPIN && tg.node_type(sink_node_id) == NodeType::SOURCE) {
                os << "\\n" << delay_calc.min_edge_delay(tg, edge_id) << " (tcq)";
            } else {
                os << "\\n" << delay_calc.min_edge_delay(tg, edge_id);
            }
            auto slacks = analyzer.hold_slacks(edge_id);
            for(const auto& tag : slacks) {
                os << "\\n" << " (slack " << print_tag_domain_from_to(tag) << ": " << tag.time().value() << ")";
            }
            if(tg.edge_disabled(edge_id)) {
                os << "\\n" << "(disabled)";
            }
            os << "\""; //end label
            if(tg.edge_disabled(edge_id)) {
                os << " style=\"dashed\"";
                os << " color=\"#aaaaaa\""; //grey
                os << " fontcolor=\"#aaaaaa\""; //grey
            }
            os << "]";
            os << ";" <<std::endl;
        }
    }

    os << "}" <<std::endl;
}

void print_setup_tags_histogram(const TimingGraph& tg, const SetupTimingAnalyzer& analyzer);
void print_hold_tags_histogram(const TimingGraph& tg, const HoldTimingAnalyzer& analyzer);

void print_setup_tags(const TimingGraph& tg, const SetupTimingAnalyzer& analyzer);
void print_hold_tags(const TimingGraph& tg, const HoldTimingAnalyzer& analyzer);

} //namepsace
<|endoftext|>