<commit_before>/*
 * FixedContextCategory.hh
 *
 * Copyright 2001, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2001, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#ifndef _LOG4CPP_FIXEDCONTEXTCATEGORY_HH
#define _LOG4CPP_FIXEDCONTEXTCATEGORY_HH

#include "log4cpp/Export.hh"
#include "log4cpp/Category.hh"

namespace log4cpp {

    /**
     * This Category subclass replaces the NDC field in LoggingEvents with
     * a fixed context string. All handling of Appenders, etc. is delgated
     * to the 'normal' Category with the same name. Its intended use is
     * for object instances that serve a single client: they contruct a
     * FixedContextCategory with the client identifier as context.
     * Unlike with regular Category instances one has to explicitly create
     * FixedContextCategory instances using the constructor. This also
     * implies one has to take cake of destruction of the instance as well.
     * @since 0.2.4
     **/
    class LOG4CPP_EXPORT FixedContextCategory : public Category {

        public:

        /**
         * Constructor
         * @param name the fully qualified name of this Categories delegate
         * Category.
         * @param context the context to fill the NDC field of LoggingEvents
         * with.
         * @param priority the priority for this Category. Defaults to
         * Priority::NOTSET
         **/
        FixedContextCategory(const std::string& name,
                             const std::string& context);

        /**
         * Destructor for Category.
         **/
        virtual ~FixedContextCategory();

        /**
         * Set the context string used as NDC.
         * @param context the context string
         **/
        virtual void setContext(const std::string& context);

        /**
         * Return the context string used as NDC.
         * @return the context string.
         **/
        virtual std::string getContext() const;

        /**
         * Returns the assigned Priority, if any, for this Category.
         * @return Priority - the assigned Priority, can be Priority::NOTSET
         **/
        virtual Priority::Value getPriority() const throw();

        /**
         * Starting from this Category, search the category hierarchy for a
         * set priority and return it. Otherwise, return the priority
         *  of the root category.
         *
         *
The Category class is designed so that this method executes as
         * quickly as possible.
         **/
        virtual Priority::Value getChainedPriority() const throw();

        /**
         * Sets an Appender for this Category.
         * This method passes ownership from the caller to the Category.
         * @param appender The Appender this category has to log to.
         **/
        virtual void setAppender(Appender* appender);

        /**
         * Sets an Appender for this Category.
         * This method does not pass ownership from the caller to the Category.
         * @param appender The Appender this category has to log to.
         **/
        virtual void setAppender(Appender& appender);

        /**
         * Returns the Appender for this Category, or NULL if no Appender has
         * been set.
         * @returns The Appender.
         **/
        virtual Appender* getAppender() const;

        /**
         * Removes all appenders set for this Category. Currently a Category
         * can have only one appender, but this may change in the future.
         **/
        virtual void removeAllAppenders();

        /**
         * Returns true if the Category owns the Appender. In that case the
         * Category destructor will delete the Appender.
         **/
        virtual bool ownsAppender() const throw();

        /**
         * Call the appenders in the hierarchy starting at
         *  this.  If no appenders could be found, emit a
         * warning.
         *
         *
This method always calls all the appenders inherited form the
         * hierracy circumventing any evaluation of whether to log or not to
         * log the particular log request.
         *
         * @param LoggingEvent the event to log.
         **/
        virtual void callAppenders(const LoggingEvent& event) throw();

        /**
         * Set the additivity flag for this Category instance.
         **/
        virtual void setAdditivity(bool additivity);

        /**
         * Returns the additivity flag for this Category instance.
         **/
        virtual bool getAdditivity() const throw();

       protected:

         /**
         * Unconditionally log a message with the specified priority.
         * @param priority The priority of this log message.
         * @param message string to write in the log file
         **/
        virtual void _logUnconditionally2(Priority::Value priority,
                                          const std::string& message) throw();

        private:

        /**
         * The delegate category of this FixedContextCategory.
         **/
        Category& _delegate;

        /** The context of this FixedContextCategory. */
         std::string _context;

    };

}
#endif // _LOG4CPP_FIXEDCONTEXTCATEGORY_HH
<commit_msg>Added default value for context parameter in constructor.<commit_after>/*
 * FixedContextCategory.hh
 *
 * Copyright 2001, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2001, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#ifndef _LOG4CPP_FIXEDCONTEXTCATEGORY_HH
#define _LOG4CPP_FIXEDCONTEXTCATEGORY_HH

#include "log4cpp/Export.hh"
#include "log4cpp/Category.hh"

namespace log4cpp {

    /**
     * This Category subclass replaces the NDC field in LoggingEvents with
     * a fixed context string. All handling of Appenders, etc. is delgated
     * to the 'normal' Category with the same name. Its intended use is
     * for object instances that serve a single client: they contruct a
     * FixedContextCategory with the client identifier as context.
     * Unlike with regular Category instances one has to explicitly create
     * FixedContextCategory instances using the constructor. This also
     * implies one has to take cake of destruction of the instance as well.
     * @since 0.2.4
     **/
    class LOG4CPP_EXPORT FixedContextCategory : public Category {

        public:

        /**
         * Constructor
         * @param name the fully qualified name of this Categories delegate
         * Category.
         * @param context the context to fill the NDC field of LoggingEvents
         * with.
         * @param priority the priority for this Category. Defaults to
         * Priority::NOTSET
         **/
        FixedContextCategory(const std::string& name,
                             const std::string& context = "");

        /**
         * Destructor for Category.
         **/
        virtual ~FixedContextCategory();

        /**
         * Set the context string used as NDC.
         * @param context the context string
         **/
        virtual void setContext(const std::string& context);

        /**
         * Return the context string used as NDC.
         * @return the context string.
         **/
        virtual std::string getContext() const;

        /**
         * Returns the assigned Priority, if any, for this Category.
         * @return Priority - the assigned Priority, can be Priority::NOTSET
         **/
        virtual Priority::Value getPriority() const throw();

        /**
         * Starting from this Category, search the category hierarchy for a
         * set priority and return it. Otherwise, return the priority
         *  of the root category.
         *
         *
The Category class is designed so that this method executes as
         * quickly as possible.
         **/
        virtual Priority::Value getChainedPriority() const throw();

        /**
         * Sets an Appender for this Category.
         * This method passes ownership from the caller to the Category.
         * @param appender The Appender this category has to log to.
         **/
        virtual void setAppender(Appender* appender);

        /**
         * Sets an Appender for this Category.
         * This method does not pass ownership from the caller to the Category.
         * @param appender The Appender this category has to log to.
         **/
        virtual void setAppender(Appender& appender);

        /**
         * Returns the Appender for this Category, or NULL if no Appender has
         * been set.
         * @returns The Appender.
         **/
        virtual Appender* getAppender() const;

        /**
         * Removes all appenders set for this Category. Currently a Category
         * can have only one appender, but this may change in the future.
         **/
        virtual void removeAllAppenders();

        /**
         * Returns true if the Category owns the Appender. In that case the
         * Category destructor will delete the Appender.
         **/
        virtual bool ownsAppender() const throw();

        /**
         * Call the appenders in the hierarchy starting at
         *  this.  If no appenders could be found, emit a
         * warning.
         *
         *
This method always calls all the appenders inherited form the
         * hierracy circumventing any evaluation of whether to log or not to
         * log the particular log request.
         *
         * @param LoggingEvent the event to log.
         **/
        virtual void callAppenders(const LoggingEvent& event) throw();

        /**
         * Set the additivity flag for this Category instance.
         **/
        virtual void setAdditivity(bool additivity);

        /**
         * Returns the additivity flag for this Category instance.
         **/
        virtual bool getAdditivity() const throw();

       protected:

         /**
         * Unconditionally log a message with the specified priority.
         * @param priority The priority of this log message.
         * @param message string to write in the log file
         **/
        virtual void _logUnconditionally2(Priority::Value priority,
                                          const std::string& message) throw();

        private:

        /**
         * The delegate category of this FixedContextCategory.
         **/
        Category& _delegate;

        /** The context of this FixedContextCategory. */
         std::string _context;

    };

}
#endif // _LOG4CPP_FIXEDCONTEXTCATEGORY_HH
<|endoftext|>


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

#ifndef MAPNIK_ATTRIBUTE_DESCRIPTOR_HPP
#define MAPNIK_ATTRIBUTE_DESCRIPTOR_HPP

#include <string>

namespace mapnik {

enum eAttributeType {
    Integer=1,
    Float  =2,
    Double =3,
    String =4,
    Boolean =5,
    Geometry=6,
    Object=7
};

class attribute_descriptor
{
public:
    attribute_descriptor(std::string const& name,unsigned type,
                         bool primary_key=false,
                         int size=-1,
                         int precision=-1)
        : name_(name),
          type_(type),
          primary_key_(primary_key),
          size_(size),
          precision_(precision) {}

    attribute_descriptor(attribute_descriptor const& other)
        : name_(other.name_),
          type_(other.type_),
          primary_key_(other.primary_key_),
          size_(other.size_),
          precision_(other.precision_) {}

    attribute_descriptor& operator=(attribute_descriptor const& other)
    {
        if (this == &other)
        {
            return *this;
        }
        else
        {
            name_=other.name_;
            type_=other.type_;
            primary_key_=other.primary_key_;
            size_=other.size_;
            precision_=other.precision_;
            return *this;
        }
    }

    std::string const& get_name() const
    {
        return name_;
    }

    unsigned get_type() const
    {
        return type_;
    }

    bool is_primary_key() const
    {
        return primary_key_;
    }

    int get_size() const
    {
        return size_;
    }

    int get_precision() const
    {
        return precision_;
    }

private:
    std::string name_;
    int type_;
    bool primary_key_;
    int size_;
    int precision_;
};

template <typename charT,typename traits>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
             attribute_descriptor const& ad)
{
    out << "name=" << ad.get_name() << "\n";
    out << "type=" << ad.get_type() << "\n";
    out << "size=" << ad.get_size() << "\n";
    return out;
}

}

#endif // MAPNIK_ATTRIBUTE_DESCRIPTOR_HPP
<commit_msg>return the correct type in attribute.get_type<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 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
 *
 *****************************************************************************/

#ifndef MAPNIK_ATTRIBUTE_DESCRIPTOR_HPP
#define MAPNIK_ATTRIBUTE_DESCRIPTOR_HPP

#include <string>

namespace mapnik {

enum eAttributeType {
    Integer=1,
    Float  =2,
    Double =3,
    String =4,
    Boolean =5,
    Geometry=6,
    Object=7
};

class attribute_descriptor
{
public:
    attribute_descriptor(std::string const& name,unsigned type,
                         bool primary_key=false,
                         int size=-1,
                         int precision=-1)
        : name_(name),
          type_(type),
          primary_key_(primary_key),
          size_(size),
          precision_(precision) {}

    attribute_descriptor(attribute_descriptor const& other)
        : name_(other.name_),
          type_(other.type_),
          primary_key_(other.primary_key_),
          size_(other.size_),
          precision_(other.precision_) {}

    attribute_descriptor& operator=(attribute_descriptor const& other)
    {
        if (this == &other)
        {
            return *this;
        }
        else
        {
            name_=other.name_;
            type_=other.type_;
            primary_key_=other.primary_key_;
            size_=other.size_;
            precision_=other.precision_;
            return *this;
        }
    }

    std::string const& get_name() const
    {
        return name_;
    }

    unsigned int get_type() const
    {
        return type_;
    }

    bool is_primary_key() const
    {
        return primary_key_;
    }

    int get_size() const
    {
        return size_;
    }

    int get_precision() const
    {
        return precision_;
    }

private:
    std::string name_;
    unsigned int type_;
    bool primary_key_;
    int size_;
    int precision_;
};

template <typename charT,typename traits>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
             attribute_descriptor const& ad)
{
    out << "name=" << ad.get_name() << "\n";
    out << "type=" << ad.get_type() << "\n";
    out << "size=" << ad.get_size() << "\n";
    return out;
}

}

#endif // MAPNIK_ATTRIBUTE_DESCRIPTOR_HPP
<|endoftext|>


<commit_before>#include "phys.hpp"
#include "graphics/displayimage.hpp"

int main(int argc, char **argv)
{
  cairo_surface_t *surface;
  cairo_t *context;
  int x, y, i,
      width, height, depth,
      screen, pressed_key;
  double r, b;

  /* Set window size */
  width = 1024;
  height = 1024;
  depth = 32;

  /* Create the X11 window */
  struct XWin **xwin = (struct XWin **)calloc(sizeof(struct XWin *), 1);
  xwindow_init(width, height, depth, xwin);

  /* Create the drawing surface */
  surface = cairo_xlib_surface_create((*xwin)->dsp, (*xwin)->win, DefaultVisual((*xwin)->dsp, screen), width, height);
  cairo_xlib_surface_set_size(surface, width, height);
  context = cairo_create(surface);
  cairo_scale(context, width, height);

  /* Initialize the physics web-scale cloud */
  phys_init(5000);

  while(!((*xwin)->should_close)) {

    /* Wait on the input (also sync up to disable flickering) */
    if(input_ready(xwin)) {
      pressed_key = get_key(xwin);
    }

    /* Clear the surface with black */
    cairo_set_source_rgb(context, 0.0, 0.0, 0.0);
    cairo_paint(context);

    /* Draw the particles */
    for(i = 0; i < N; ++i) {
      r = f2_norm(particles[i].vel);
      b = 0.6 - r;
      printf("%f, %f\n", r, b);
      cairo_set_source_rgba(context, r, 0.0, b, 1.0);
      cairo_rectangle(context, particles[i].pos.x,
                      particles[i].pos.y, 2e-3, 2e-3);
    }
    cairo_fill(context);

    /* Flush the X window */
    flush_input(xwin);
    update_screen(xwin);

    /* Get the new particles */
    phys_step(1/60.0);
  }

  cairo_destroy(context);
  cairo_surface_destroy(surface);
  xwindow_del(xwin);

  return 0;
}
<commit_msg>Harsh red/blue coloring finished<commit_after>#include "phys.hpp"
#include "graphics/displayimage.hpp"

int main(int argc, char **argv)
{
  cairo_surface_t *surface;
  cairo_t *context;
  int x, y, i,
      width, height, depth,
      screen, pressed_key;
  double r, b, v;

  /* Set window size */
  width = 1024;
  height = 1024;
  depth = 32;

  /* Create the X11 window */
  struct XWin **xwin = (struct XWin **)calloc(sizeof(struct XWin *), 1);
  xwindow_init(width, height, depth, xwin);

  /* Create the drawing surface */
  surface = cairo_xlib_surface_create((*xwin)->dsp, (*xwin)->win, DefaultVisual((*xwin)->dsp, screen), width, height);
  cairo_xlib_surface_set_size(surface, width, height);
  context = cairo_create(surface);
  cairo_scale(context, width, height);

  /* Initialize the physics web-scale cloud */
  phys_init(2000);

  while(!((*xwin)->should_close)) {

    /* Wait on the input (also sync up to disable flickering) */
    if(input_ready(xwin)) {
      pressed_key = get_key(xwin);
    }

    /* Clear the surface with black */
    cairo_set_source_rgb(context, 0.0, 0.0, 0.0);
    cairo_paint(context);

    /* Draw the particles */
    for(i = 0; i < N; ++i) {
      v = f2_norm(particles[i].vel);
      if(v >= 0.4) {
        r = 1.0; b = 0.0;
      } else if(v < 0.5) {
        b = 1.0; r = 0.0;
      }
      cairo_set_source_rgba(context, (double)r, 0.0, (double)b, 1.0);
      cairo_rectangle(context, particles[i].pos.x,
                      particles[i].pos.y, 2e-3, 2e-3);
      cairo_fill(context);
    }

    /* Flush the X window */
    flush_input(xwin);
    update_screen(xwin);

    /* Get the new particles */
    phys_step(1/60.0);
  }

  cairo_destroy(context);
  cairo_surface_destroy(surface);
  xwindow_del(xwin);

  return 0;
}
<|endoftext|>


<commit_before>#ifndef __FAST5_HPP
#define __FAST5_HPP

#include <cassert>
#include <exception>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include "hdf5_tools.hpp"

namespace fast5
{

//
// This struct represents the expected signal measured
// given the kmer sequence that is in the pore when the
// the observations are made. A pore model consists
// of 1024 of these entries (one per 5-mer) and global
// shift/scaling parameters.
//
struct Model_Entry
{
    char kmer[6];
    long long variant;
    double level_mean;
    double level_stdv;
    double sd_mean;
    double sd_stdv;
    double weight;
}; // struct Model_Entry

//
// This struct represents the global transformations
// that must be applied to each Model_Entry
//
struct Model_Parameters
{
    double drift;
    double scale;
    double scale_sd;
    double shift;
    double var;
    double var_sd;
}; // struct Model_Parameters

//
// This struct represents an observed event.
// The members of the struct are the same as
// the fields encoded in the FAST5 file.
//
struct Event_Entry
{
    double mean;
    double start;
    double stdv;
    double length;
    char model_state[6];
    double model_level;
    long long move;
    double p_model_state;
    char mp_state[6];
    double p_mp_state;
    double p_A;
    double p_C;
    double p_G;
    double p_T;
}; // struct Event_Entry

//
// This struct represents a template-to-complement
// match that is emitted by ONT's 2D basecaller
//
struct Event_Alignment_Entry
{
    long long template_index;
    long long complement_index;
    char kmer[6];
}; // struct Event_Alignment_Entry

class File
    : private hdf5_tools::File_Reader
{
private:
    typedef hdf5_tools::File_Reader Base;
public:
    using Base::Base;

    using Base::is_open;
    using Base::file_name;
    using Base::open;
    using Base::close;

    std::string file_version() const
    {
        double v;
        assert(Base::exists("/file_version"));
        Base::read< double >("/file_version", v);
        // convert it to string
        std::ostringstream os;
        os << v;
        return os.str();
    }

    std::string basecall_version() const
    {
        std::string res;
        assert(Base::exists("/Analyses/Basecall_2D_000/version"));
        Base::read< std::string >("/Analyses/Basecall_2D_000/version", res);
        return res;
    }

    std::string eventdetection_version() const
    {
        std::string res;
        assert(Base::exists("/Analyses/EventDetection_000/version"));
        Base::read< std::string >("/Analyses/EventDetection_000/version", res);
        return res;
    }

    std::string get_log() const
    {
        std::string res;
        assert(Base::exists("/Analyses/Basecall_2D_000/Log"));
        Base::read< std::string >("/Analyses/Basecall_2D_000/Log", res);
        return res;
    }

    double get_sampling_rate() const
    {
    	assert(have_sampling_rate());

        auto lg = get_log();
        auto idx = lg.find("Sampling rate is");

        std::string line;
        std::stringstream ss1(lg.substr(idx));
        std::getline(ss1,line,'\n');

        std::stringstream ss2(line);

        std::string token;
        std::getline(ss2,token,' ');	//Sampling
        std::getline(ss2,token,' ');	//rate
        std::getline(ss2,token,' ');	//is
        std::getline(ss2,token,' ');	//Hz value

        return std::atof(token.c_str());
    }

    bool have_sampling_rate() const
    {
    	auto lg = get_log();
    	auto idx = lg.find("Sampling rate is");
    	return idx != std::string::npos;
    }

    std::string get_model_file(size_t i) const
    {
        std::string res;
        assert(Base::exists(model_file_path(i)));
        Base::read< std::string >(model_file_path(i), res);
        return res;
    }

    std::string sequences_version() const
    {
        std::vector< std::string > tmp;
        assert(Base::exists("/Sequences/Meta/version"));
        Base::read< std::string >("/Sequences/Meta/version", tmp);
        std::string res;
        for (const auto& s: tmp)
        {
            res += s;
        }
        return res;
    }

    bool have_basecalled_2D() const
    {
        return Base::exists("/Analyses/Basecall_2D_000/BaseCalled_2D/Fastq");
    }

    std::string basecalled_2D() const
    {
        std::string res;
        Base::read< std::string >("/Analyses/Basecall_2D_000/BaseCalled_2D/Fastq", res);

        // Split the FASTQ record on newlines
        size_t nl1 = res.find_first_of('\n');
        size_t nl2 = res.find_first_of('\n', nl1 + 1);

        if(nl1 == std::string::npos || nl2 == std::string::npos)
            return "";
        else
            return res.substr(nl1 + 1, nl2 - nl1 - 1);
    }

    std::vector< Event_Alignment_Entry > get_event_alignments() const
    {
        std::vector< Event_Alignment_Entry > res;
        hdf5_tools::Compound_Map m;
        m.add_member("template", &Event_Alignment_Entry::template_index);
        m.add_member("complement", &Event_Alignment_Entry::complement_index);
        m.add_member("kmer", &Event_Alignment_Entry::kmer);
        Base::read< Event_Alignment_Entry >("/Analyses/Basecall_2D_000/BaseCalled_2D/Alignment", res, &m);
        return res;
    }

    bool have_model(size_t i) const
    {
        return Base::exists(model_path(i));
    }
    bool have_events(size_t i) const
    {
        return Base::exists(events_path(i));
    }

    std::vector< Model_Entry > get_model(size_t i) const
    {
        std::vector< Model_Entry > res;
        hdf5_tools::Compound_Map m;
        m.add_member("kmer", &Model_Entry::kmer);
        m.add_member("level_mean", &Model_Entry::level_mean);
        m.add_member("level_stdv", &Model_Entry::level_stdv);
        Base::read< Model_Entry >(model_path(i), res, &m);
        return res;
    }

    Model_Parameters get_model_parameters(size_t i) const
    {
        Model_Parameters res;
        std::string path = model_path(i);
        Base::read< double >(path + "/drift", res.drift);
        Base::read< double >(path + "/scale", res.scale);
        Base::read< double >(path + "/scale_sd", res.scale_sd);
        Base::read< double >(path + "/shift", res.shift);
        Base::read< double >(path + "/var", res.var);
        Base::read< double >(path + "/var_sd", res.var_sd);
        return res;
    }

    std::vector< Event_Entry > get_events(size_t i) const
    {
        std::vector< Event_Entry > res;
        hdf5_tools::Compound_Map m;
        m.add_member("mean", &Event_Entry::mean);
        m.add_member("start", &Event_Entry::start);
        m.add_member("stdv", &Event_Entry::stdv);
        m.add_member("length", &Event_Entry::length);
        Base::read< Event_Entry >(events_path(i), res, &m);
        return res;
    }

private:
    static const std::string& model_path(size_t i)
    {
        static std::vector< std::string > _model_path =
            { "/Analyses/Basecall_2D_000/BaseCalled_template/Model",
              "/Analyses/Basecall_2D_000/BaseCalled_complement/Model" };
        return _model_path.at(i);
    }

    static const std::string& events_path(size_t i)
    {
        static std::vector< std::string > _events_path =
            { "/Analyses/Basecall_2D_000/BaseCalled_template/Events",
              "/Analyses/Basecall_2D_000/BaseCalled_complement/Events" };
        return _events_path.at(i);
    }

    static const std::string& model_file_path(size_t i)
    {
        static std::vector< std::string > _model_file_path =
            { "/Analyses/Basecall_2D_000/Summary/basecall_1d_template/model_file",
              "/Analyses/Basecall_2D_000/Summary/basecall_1d_complement/model_file" };
        return _model_file_path.at(i);
    }

}; // class File

} // namespace fast5

#endif
<commit_msg>removed tabs<commit_after>#ifndef __FAST5_HPP
#define __FAST5_HPP

#include <cassert>
#include <exception>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include "hdf5_tools.hpp"

namespace fast5
{

//
// This struct represents the expected signal measured
// given the kmer sequence that is in the pore when the
// the observations are made. A pore model consists
// of 1024 of these entries (one per 5-mer) and global
// shift/scaling parameters.
//
struct Model_Entry
{
    char kmer[6];
    long long variant;
    double level_mean;
    double level_stdv;
    double sd_mean;
    double sd_stdv;
    double weight;
}; // struct Model_Entry

//
// This struct represents the global transformations
// that must be applied to each Model_Entry
//
struct Model_Parameters
{
    double drift;
    double scale;
    double scale_sd;
    double shift;
    double var;
    double var_sd;
}; // struct Model_Parameters

//
// This struct represents an observed event.
// The members of the struct are the same as
// the fields encoded in the FAST5 file.
//
struct Event_Entry
{
    double mean;
    double start;
    double stdv;
    double length;
    char model_state[6];
    double model_level;
    long long move;
    double p_model_state;
    char mp_state[6];
    double p_mp_state;
    double p_A;
    double p_C;
    double p_G;
    double p_T;
}; // struct Event_Entry

//
// This struct represents a template-to-complement
// match that is emitted by ONT's 2D basecaller
//
struct Event_Alignment_Entry
{
    long long template_index;
    long long complement_index;
    char kmer[6];
}; // struct Event_Alignment_Entry

class File
    : private hdf5_tools::File_Reader
{
private:
    typedef hdf5_tools::File_Reader Base;
public:
    using Base::Base;

    using Base::is_open;
    using Base::file_name;
    using Base::open;
    using Base::close;

    std::string file_version() const
    {
        double v;
        assert(Base::exists("/file_version"));
        Base::read< double >("/file_version", v);
        // convert it to string
        std::ostringstream os;
        os << v;
        return os.str();
    }

    std::string basecall_version() const
    {
        std::string res;
        assert(Base::exists("/Analyses/Basecall_2D_000/version"));
        Base::read< std::string >("/Analyses/Basecall_2D_000/version", res);
        return res;
    }

    std::string eventdetection_version() const
    {
        std::string res;
        assert(Base::exists("/Analyses/EventDetection_000/version"));
        Base::read< std::string >("/Analyses/EventDetection_000/version", res);
        return res;
    }

    std::string get_log() const
    {
        std::string res;
        assert(Base::exists("/Analyses/Basecall_2D_000/Log"));
        Base::read< std::string >("/Analyses/Basecall_2D_000/Log", res);
        return res;
    }

    double get_sampling_rate() const
    {
        assert(have_sampling_rate());

        auto lg = get_log();
        auto idx = lg.find("Sampling rate is");

        std::string line;
        std::stringstream ss1(lg.substr(idx));
        std::getline(ss1,line,'\n');

        std::stringstream ss2(line);

        std::string token;
        std::getline(ss2,token,' ');    //Sampling
        std::getline(ss2,token,' ');    //rate
        std::getline(ss2,token,' ');    //is
        std::getline(ss2,token,' ');    //Hz value

        return std::atof(token.c_str());
    }

    bool have_sampling_rate() const
    {
        auto lg = get_log();
        auto idx = lg.find("Sampling rate is");
        return idx != std::string::npos;
    }

    std::string get_model_file(size_t i) const
    {
        std::string res;
        assert(Base::exists(model_file_path(i)));
        Base::read< std::string >(model_file_path(i), res);
        return res;
    }

    std::string sequences_version() const
    {
        std::vector< std::string > tmp;
        assert(Base::exists("/Sequences/Meta/version"));
        Base::read< std::string >("/Sequences/Meta/version", tmp);
        std::string res;
        for (const auto& s: tmp)
        {
            res += s;
        }
        return res;
    }

    bool have_basecalled_2D() const
    {
        return Base::exists("/Analyses/Basecall_2D_000/BaseCalled_2D/Fastq");
    }

    std::string basecalled_2D() const
    {
        std::string res;
        Base::read< std::string >("/Analyses/Basecall_2D_000/BaseCalled_2D/Fastq", res);

        // Split the FASTQ record on newlines
        size_t nl1 = res.find_first_of('\n');
        size_t nl2 = res.find_first_of('\n', nl1 + 1);

        if(nl1 == std::string::npos || nl2 == std::string::npos)
            return "";
        else
            return res.substr(nl1 + 1, nl2 - nl1 - 1);
    }

    std::vector< Event_Alignment_Entry > get_event_alignments() const
    {
        std::vector< Event_Alignment_Entry > res;
        hdf5_tools::Compound_Map m;
        m.add_member("template", &Event_Alignment_Entry::template_index);
        m.add_member("complement", &Event_Alignment_Entry::complement_index);
        m.add_member("kmer", &Event_Alignment_Entry::kmer);
        Base::read< Event_Alignment_Entry >("/Analyses/Basecall_2D_000/BaseCalled_2D/Alignment", res, &m);
        return res;
    }

    bool have_model(size_t i) const
    {
        return Base::exists(model_path(i));
    }
    bool have_events(size_t i) const
    {
        return Base::exists(events_path(i));
    }

    std::vector< Model_Entry > get_model(size_t i) const
    {
        std::vector< Model_Entry > res;
        hdf5_tools::Compound_Map m;
        m.add_member("kmer", &Model_Entry::kmer);
        m.add_member("level_mean", &Model_Entry::level_mean);
        m.add_member("level_stdv", &Model_Entry::level_stdv);
        Base::read< Model_Entry >(model_path(i), res, &m);
        return res;
    }

    Model_Parameters get_model_parameters(size_t i) const
    {
        Model_Parameters res;
        std::string path = model_path(i);
        Base::read< double >(path + "/drift", res.drift);
        Base::read< double >(path + "/scale", res.scale);
        Base::read< double >(path + "/scale_sd", res.scale_sd);
        Base::read< double >(path + "/shift", res.shift);
        Base::read< double >(path + "/var", res.var);
        Base::read< double >(path + "/var_sd", res.var_sd);
        return res;
    }

    std::vector< Event_Entry > get_events(size_t i) const
    {
        std::vector< Event_Entry > res;
        hdf5_tools::Compound_Map m;
        m.add_member("mean", &Event_Entry::mean);
        m.add_member("start", &Event_Entry::start);
        m.add_member("stdv", &Event_Entry::stdv);
        m.add_member("length", &Event_Entry::length);
        Base::read< Event_Entry >(events_path(i), res, &m);
        return res;
    }

private:
    static const std::string& model_path(size_t i)
    {
        static std::vector< std::string > _model_path =
            { "/Analyses/Basecall_2D_000/BaseCalled_template/Model",
              "/Analyses/Basecall_2D_000/BaseCalled_complement/Model" };
        return _model_path.at(i);
    }

    static const std::string& events_path(size_t i)
    {
        static std::vector< std::string > _events_path =
            { "/Analyses/Basecall_2D_000/BaseCalled_template/Events",
              "/Analyses/Basecall_2D_000/BaseCalled_complement/Events" };
        return _events_path.at(i);
    }

    static const std::string& model_file_path(size_t i)
    {
        static std::vector< std::string > _model_file_path =
            { "/Analyses/Basecall_2D_000/Summary/basecall_1d_template/model_file",
              "/Analyses/Basecall_2D_000/Summary/basecall_1d_complement/model_file" };
        return _model_file_path.at(i);
    }

}; // class File

} // namespace fast5

#endif
<|endoftext|>


<commit_before>/****************************************************************************
 * stermcom.cc
 *
 *   Copyright (c) 2015 Yoshinori Sugino
 *   This software is released under the MIT License.
 ****************************************************************************/
#include <fcntl.h>
#include <libgen.h>
#include <sys/select.h>
#include <unistd.h>

#include <cassert>
#include <cerrno>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <list>

#include "common_type.h"
#include "debug.h"
#include "file_descriptor.h"
#include "signal_settings.h"
#include "terminal_interface.h"

namespace {

using status_t = common::status_t;

volatile sig_atomic_t g_should_continue = 1;

struct Arguments {
  uint32_t baud_rate;
};

status_t mainLoop(const int32_t &tty_fd, const Arguments &args) {
  fd_set fds_r, fds_w;
  uint8_t one_char;
  std::list<uint8_t> string_buffer{};
  ssize_t rw_size;
  util::TerminalInterface stdin_term(STDIN_FILENO), tty_term(tty_fd);

  if (stdin_term.SetRawMode() == status_t::kFailure)
    return status_t::kFailure;
  if (tty_term.SetRawMode() == status_t::kFailure)
    return status_t::kFailure;
  if (tty_term.SetBaudRate(args.baud_rate, util::direction_t::kOut) ==
      status_t::kFailure)
    return status_t::kFailure;
  if (tty_term.SetBaudRate(0, util::direction_t::kIn) == status_t::kFailure)
    return status_t::kFailure;

  assert(tty_fd > STDIN_FILENO && "Assertion for select()");

  while (g_should_continue) {
    FD_ZERO(&fds_r);
    FD_ZERO(&fds_r);

    FD_SET(STDIN_FILENO, &fds_r);
    FD_SET(tty_fd, &fds_r);
    FD_SET(tty_fd, &fds_w);

    errno = 0;
    auto ret = select(tty_fd + 1, &fds_r, &fds_w, nullptr, nullptr);
    if (ret == -1) {
      if (errno == EINTR) {
        DEBUG_PRINTF("Signal was caught when select() is waiting");
      } else {
        printf("Error\n");
        return status_t::kFailure;
      }
      break;
    }

    if (FD_ISSET(STDIN_FILENO, &fds_r)) {
      rw_size = read(STDIN_FILENO, &one_char, 1);
      if (one_char == 0x18) break;  // 0x18: Ctrl-x
      if (rw_size > 0) string_buffer.push_back(one_char);
    }
    if (FD_ISSET(tty_fd, &fds_w)) {
      if (!string_buffer.empty()) {
        rw_size = write(tty_fd, &string_buffer.front(), 1);
        if (rw_size > 0) string_buffer.pop_front();
      }
    }
    if (FD_ISSET(tty_fd, &fds_r)) {
      uint8_t tty_read_buffer;
      rw_size = read(tty_fd, &tty_read_buffer, 1);
      if (rw_size > 0) write(STDOUT_FILENO, &tty_read_buffer, 1);
    }
  }

  return status_t::kSuccess;
}

}  // namespace

int main(int argc, char *argv[]) {
  if (argc != 3) {
    auto path_name = argv[0];
    printf("USAGE: ./%s baud_rate device_node\n", basename(path_name));
    return EXIT_FAILURE;
  }

  Arguments args;
  args.baud_rate = strtol(argv[1], nullptr, 10);

  util::FileDescriptor fd(argv[2], O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fd.IsSuccess() == false) {
    return EXIT_FAILURE;
  }
  if (!isatty(fd)) {
    return EXIT_FAILURE;
  }

#ifndef PRIVATE_DEBUG
  if (util::InitializeSignalAction(
        SIG_IGN,
        // +: decay operator
        +[](int32_t) -> void {
          // When signal is caught, select() is not always waiting.
          g_should_continue = 0;
        }
      ) == status_t::kFailure) return EXIT_FAILURE;
#else
  if (util::InitializeSignalAction(
        +[](int32_t) -> void {
          // write(): Async-Signal-Safe
          (void)write(STDOUT_FILENO, "Ignore signal\n", 14);
        },
        +[](int32_t) -> void {
          (void)write(STDOUT_FILENO, "Disconnect\n", 11);
          g_should_continue = 0;
        }
      ) == status_t::kFailure) return EXIT_FAILURE;
#endif  // PRIVATE_DEBUG

  auto ret = mainLoop(fd, args);
  if (ret == status_t::kFailure) return EXIT_FAILURE;

  return EXIT_SUCCESS;
}

<commit_msg>Support piping and redirection<commit_after>/****************************************************************************
 * stermcom.cc
 *
 *   Copyright (c) 2015 Yoshinori Sugino
 *   This software is released under the MIT License.
 ****************************************************************************/
#include <fcntl.h>
#include <libgen.h>
#include <sys/select.h>
#include <unistd.h>

#include <cassert>
#include <cerrno>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <list>

#include "common_type.h"
#include "debug.h"
#include "file_descriptor.h"
#include "signal_settings.h"
#include "terminal_interface.h"

namespace {

using status_t = common::status_t;

volatile sig_atomic_t g_should_continue = 1;

struct Arguments {
  uint32_t baud_rate;
};

status_t setStdinToNonblock() {
  auto flags = fcntl(STDIN_FILENO, F_GETFL, 0);
  if (flags == -1) return status_t::kFailure;

  auto ret = fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
  if (ret == -1) return status_t::kFailure;

  return status_t::kSuccess;
}

status_t reopenStdin() {
  util::FileDescriptor fd("/dev/tty", O_RDONLY);
  if (fd.IsSuccess() == false) return status_t::kFailure;

  // Assign /dev/tty to STDIN_FILENO (/dev/tty is also being assigned to fd)
  dup2(fd, STDIN_FILENO);

  // fd is closed automatically
  return status_t::kSuccess;
}

status_t mainLoop(const int32_t &tty_fd, const Arguments &args) {
  fd_set fds_r, fds_w;
  uint8_t one_char;
  std::list<uint8_t> string_buffer{};
  ssize_t rw_size;

  // Support piping and redirection
  if (setStdinToNonblock() == status_t::kFailure) return status_t::kFailure;
  while (true) {
    rw_size = read(STDIN_FILENO, &one_char, 1);
    if (rw_size > 0) {
      string_buffer.push_back(one_char);
    } else {
      break;
    }
  }
  if (reopenStdin() == status_t::kFailure) return status_t::kFailure;

  util::TerminalInterface stdin_term(STDIN_FILENO), tty_term(tty_fd);

  if (stdin_term.SetRawMode() == status_t::kFailure)
    return status_t::kFailure;
  if (tty_term.SetRawMode() == status_t::kFailure)
    return status_t::kFailure;
  if (tty_term.SetBaudRate(args.baud_rate, util::direction_t::kOut) ==
      status_t::kFailure)
    return status_t::kFailure;
  if (tty_term.SetBaudRate(0, util::direction_t::kIn) == status_t::kFailure)
    return status_t::kFailure;

  assert(tty_fd > STDIN_FILENO && "Assertion for select()");

  while (g_should_continue) {
    FD_ZERO(&fds_r);
    FD_ZERO(&fds_r);

    FD_SET(STDIN_FILENO, &fds_r);
    FD_SET(tty_fd, &fds_r);
    FD_SET(tty_fd, &fds_w);

    errno = 0;
    auto ret = select(tty_fd + 1, &fds_r, &fds_w, nullptr, nullptr);
    if (ret == -1) {
      if (errno == EINTR) {
        DEBUG_PRINTF("Signal was caught when select() is waiting");
      } else {
        printf("Error\n");
        return status_t::kFailure;
      }
      break;
    }

    if (FD_ISSET(STDIN_FILENO, &fds_r)) {
      rw_size = read(STDIN_FILENO, &one_char, 1);
      if (one_char == 0x18) break;  // 0x18: Ctrl-x
      if (rw_size > 0) string_buffer.push_back(one_char);
    }
    if (FD_ISSET(tty_fd, &fds_w)) {
      if (!string_buffer.empty()) {
        rw_size = write(tty_fd, &string_buffer.front(), 1);
        if (rw_size > 0) string_buffer.pop_front();
      }
    }
    if (FD_ISSET(tty_fd, &fds_r)) {
      uint8_t tty_read_buffer;
      rw_size = read(tty_fd, &tty_read_buffer, 1);
      if (rw_size > 0) write(STDOUT_FILENO, &tty_read_buffer, 1);
    }
  }

  return status_t::kSuccess;
}

}  // namespace

int main(int argc, char *argv[]) {
  if (argc != 3) {
    auto path_name = argv[0];
    printf("USAGE: ./%s baud_rate device_node\n", basename(path_name));
    return EXIT_FAILURE;
  }

  Arguments args;
  args.baud_rate = strtol(argv[1], nullptr, 10);

  util::FileDescriptor fd(argv[2], O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fd.IsSuccess() == false) {
    return EXIT_FAILURE;
  }
  if (!isatty(fd)) {
    return EXIT_FAILURE;
  }

#ifndef PRIVATE_DEBUG
  if (util::InitializeSignalAction(
        SIG_IGN,
        // +: decay operator
        +[](int32_t) -> void {
          // When signal is caught, select() is not always waiting.
          g_should_continue = 0;
        }
      ) == status_t::kFailure) return EXIT_FAILURE;
#else
  if (util::InitializeSignalAction(
        +[](int32_t) -> void {
          // write(): Async-Signal-Safe
          (void)write(STDOUT_FILENO, "Ignore signal\n", 14);
        },
        +[](int32_t) -> void {
          (void)write(STDOUT_FILENO, "Disconnect\n", 11);
          g_should_continue = 0;
        }
      ) == status_t::kFailure) return EXIT_FAILURE;
#endif  // PRIVATE_DEBUG

  auto ret = mainLoop(fd, args);
  if (ret == status_t::kFailure) return EXIT_FAILURE;

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/filesystem/operations.hpp>

#include "test.hpp"
#include "setup_transfer.hpp"

using boost::filesystem::remove_all;
using boost::filesystem::exists;

void test_swarm()
{
	using namespace libtorrent;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48000, 49000));
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49000, 50000));
	session ses3(fingerprint("LT", 0, 1, 0, 0), std::make_pair(50000, 51000));

	ses1.set_severity_level(alert::debug);
	ses2.set_severity_level(alert::debug);
	ses3.set_severity_level(alert::debug);

	// this is to avoid everything finish from a single peer
	// immediately. To make the swarm actually connect all
	// three peers before finishing.
	float rate_limit = 100000;
	ses1.set_upload_rate_limit(int(rate_limit));
	ses2.set_download_rate_limit(int(rate_limit));
	ses3.set_download_rate_limit(int(rate_limit));
	ses2.set_upload_rate_limit(int(rate_limit / 2));
	ses3.set_upload_rate_limit(int(rate_limit / 2));

	session_settings settings;
	settings.allow_multiple_connections_per_ip = true;
	settings.ignore_limits_on_local_network = false;
	ses1.set_settings(settings);
	ses2.set_settings(settings);
	ses3.set_settings(settings);

#ifndef TORRENT_DISABLE_ENCRYPTION
	pe_settings pes;
	pes.out_enc_policy = pe_settings::forced;
	pes.in_enc_policy = pe_settings::forced;
	ses1.set_pe_settings(pes);
	ses2.set_pe_settings(pes);
	ses3.set_pe_settings(pes);
#endif

	torrent_handle tor1;
	torrent_handle tor2;
	torrent_handle tor3;

	boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, true, "_swarm");

	float sum_dl_rate2 = 0.f;
	float sum_dl_rate3 = 0.f;
	int count_dl_rates2 = 0;
	int count_dl_rates3 = 0;

	for (int i = 0; i < 27; ++i)
	{
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");
		print_alerts(ses3, "ses3");

		torrent_status st1 = tor1.status();
		torrent_status st2 = tor2.status();
		torrent_status st3 = tor3.status();

		if (st2.progress < 1.f && st2.progress > 0.5f)
		{
			sum_dl_rate2 += st2.download_payload_rate;
			++count_dl_rates2;
		}
		if (st3.progress < 1.f && st3.progress > 0.5f)
		{
			sum_dl_rate3 += st3.download_rate;
			++count_dl_rates3;
		}

		std::cerr
			<< "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
			<< st1.num_peers << ": "
			<< "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st2.progress * 100) << "% "
			<< st2.num_peers << " - "
			<< "\033[32m" << int(st3.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st3.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st3.progress * 100) << "% "
			<< st3.num_peers
			<< std::endl;

		if (tor2.is_seed() && tor3.is_seed()) break;
		test_sleep(1000);
	}

	TEST_CHECK(tor2.is_seed());
	TEST_CHECK(tor3.is_seed());

	float average2 = sum_dl_rate2 / float(count_dl_rates2);
	float average3 = sum_dl_rate3 / float(count_dl_rates3);

	std::cerr << average2 << std::endl;
	std::cerr << "average rate: " << (average2 / 1000.f) << "kB/s - "
		<< (average3 / 1000.f) << "kB/s" << std::endl;

	TEST_CHECK(std::fabs(average2 - float(rate_limit)) < rate_limit / 11.f);
	TEST_CHECK(std::fabs(average3 - float(rate_limit)) < rate_limit / 11.f);
	if (tor2.is_seed() && tor3.is_seed()) std::cerr << "done\n";

	// make sure the files are deleted
	ses1.remove_torrent(tor1, session::delete_files);
	ses2.remove_torrent(tor2, session::delete_files);
	ses3.remove_torrent(tor3, session::delete_files);

	std::auto_ptr<alert> a = ses1.pop_alert();
	ptime end = time_now() + seconds(20);
	while (a.get() == 0 || dynamic_cast<torrent_deleted_alert*>(a.get()) == 0)
	{
		if (ses1.wait_for_alert(end - time_now()) == 0)
		{
			std::cerr << "wait_for_alert() expired" << std::endl;
			break;
		}
		a = ses1.pop_alert();
		assert(a.get());
		std::cerr << a->msg() << std::endl;
	}

	TEST_CHECK(dynamic_cast<torrent_deleted_alert*>(a.get()) != 0);

	// there shouldn't be any alerts generated from now on
	// make sure that the timer in wait_for_alert() works
	// this should time out (ret == 0) and it should take
	// about 2 seconds
	ptime start = time_now();
	alert const* ret = ses1.wait_for_alert(seconds(2));
	TEST_CHECK(ret == 0);
	if (ret != 0) std::cerr << ret->msg() << std::endl;
	TEST_CHECK(time_now() - start < seconds(3));
	TEST_CHECK(time_now() - start > seconds(2));
}

int test_main()
{
	using namespace libtorrent;
	using namespace boost::filesystem;

	// in case the previous run was terminated
	try { remove_all("./tmp1_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp2_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp3_swarm"); } catch (std::exception&) {}

	test_swarm();

	test_sleep(2000);
	TEST_CHECK(!exists("./tmp1_swarm/temporary"));
	TEST_CHECK(!exists("./tmp2_swarm/temporary"));
	TEST_CHECK(!exists("./tmp3_swarm/temporary"));

	remove_all("./tmp1_swarm");
	remove_all("./tmp2_swarm");
	remove_all("./tmp3_swarm");

	return 0;
}

<commit_msg>test_swarm fix<commit_after>#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/filesystem/operations.hpp>

#include "test.hpp"
#include "setup_transfer.hpp"

using boost::filesystem::remove_all;
using boost::filesystem::exists;

void test_swarm()
{
	using namespace libtorrent;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48000, 49000));
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49000, 50000));
	session ses3(fingerprint("LT", 0, 1, 0, 0), std::make_pair(50000, 51000));

	ses1.set_severity_level(alert::debug);
	ses2.set_severity_level(alert::debug);
	ses3.set_severity_level(alert::debug);

	// this is to avoid everything finish from a single peer
	// immediately. To make the swarm actually connect all
	// three peers before finishing.
	float rate_limit = 100000;
	ses1.set_upload_rate_limit(int(rate_limit));
	ses2.set_download_rate_limit(int(rate_limit));
	ses3.set_download_rate_limit(int(rate_limit));
	ses2.set_upload_rate_limit(int(rate_limit / 2));
	ses3.set_upload_rate_limit(int(rate_limit / 2));

	session_settings settings;
	settings.allow_multiple_connections_per_ip = true;
	settings.ignore_limits_on_local_network = false;
	ses1.set_settings(settings);
	ses2.set_settings(settings);
	ses3.set_settings(settings);

#ifndef TORRENT_DISABLE_ENCRYPTION
	pe_settings pes;
	pes.out_enc_policy = pe_settings::forced;
	pes.in_enc_policy = pe_settings::forced;
	ses1.set_pe_settings(pes);
	ses2.set_pe_settings(pes);
	ses3.set_pe_settings(pes);
#endif

	torrent_handle tor1;
	torrent_handle tor2;
	torrent_handle tor3;

	boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, true, "_swarm");

	float sum_dl_rate2 = 0.f;
	float sum_dl_rate3 = 0.f;
	int count_dl_rates2 = 0;
	int count_dl_rates3 = 0;

	for (int i = 0; i < 30; ++i)
	{
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");
		print_alerts(ses3, "ses3");

		torrent_status st1 = tor1.status();
		torrent_status st2 = tor2.status();
		torrent_status st3 = tor3.status();

		if (st2.progress < 1.f && st2.progress > 0.5f)
		{
			sum_dl_rate2 += st2.download_payload_rate;
			++count_dl_rates2;
		}
		if (st3.progress < 1.f && st3.progress > 0.5f)
		{
			sum_dl_rate3 += st3.download_rate;
			++count_dl_rates3;
		}

		std::cerr
			<< "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
			<< st1.num_peers << ": "
			<< "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st2.progress * 100) << "% "
			<< st2.num_peers << " - "
			<< "\033[32m" << int(st3.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st3.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st3.progress * 100) << "% "
			<< st3.num_peers
			<< std::endl;

		if (tor2.is_seed() && tor3.is_seed()) break;
		test_sleep(1000);
	}

	TEST_CHECK(tor2.is_seed());
	TEST_CHECK(tor3.is_seed());

	float average2 = sum_dl_rate2 / float(count_dl_rates2);
	float average3 = sum_dl_rate3 / float(count_dl_rates3);

	std::cerr << average2 << std::endl;
	std::cerr << "average rate: " << (average2 / 1000.f) << "kB/s - "
		<< (average3 / 1000.f) << "kB/s" << std::endl;

	TEST_CHECK(std::fabs(average2 - float(rate_limit)) < rate_limit / 11.f);
	TEST_CHECK(std::fabs(average3 - float(rate_limit)) < rate_limit / 11.f);
	if (tor2.is_seed() && tor3.is_seed()) std::cerr << "done\n";

	// make sure the files are deleted
	ses1.remove_torrent(tor1, session::delete_files);
	ses2.remove_torrent(tor2, session::delete_files);
	ses3.remove_torrent(tor3, session::delete_files);

	std::auto_ptr<alert> a = ses1.pop_alert();
	ptime end = time_now() + seconds(20);
	while (a.get() == 0 || dynamic_cast<torrent_deleted_alert*>(a.get()) == 0)
	{
		if (ses1.wait_for_alert(end - time_now()) == 0)
		{
			std::cerr << "wait_for_alert() expired" << std::endl;
			break;
		}
		a = ses1.pop_alert();
		assert(a.get());
		std::cerr << a->msg() << std::endl;
	}

	TEST_CHECK(dynamic_cast<torrent_deleted_alert*>(a.get()) != 0);

	// there shouldn't be any alerts generated from now on
	// make sure that the timer in wait_for_alert() works
	// this should time out (ret == 0) and it should take
	// about 2 seconds
	ptime start = time_now();
	alert const* ret = ses1.wait_for_alert(seconds(2));
	TEST_CHECK(ret == 0);
	if (ret != 0) std::cerr << ret->msg() << std::endl;
	TEST_CHECK(time_now() - start < seconds(3));
	TEST_CHECK(time_now() - start > seconds(2));
}

int test_main()
{
	using namespace libtorrent;
	using namespace boost::filesystem;

	// in case the previous run was terminated
	try { remove_all("./tmp1_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp2_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp3_swarm"); } catch (std::exception&) {}

	test_swarm();

	test_sleep(2000);
	TEST_CHECK(!exists("./tmp1_swarm/temporary"));
	TEST_CHECK(!exists("./tmp2_swarm/temporary"));
	TEST_CHECK(!exists("./tmp3_swarm/temporary"));

	remove_all("./tmp1_swarm");
	remove_all("./tmp2_swarm");
	remove_all("./tmp3_swarm");

	return 0;
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "Pkd.h"
#include <iostream>
#include <stdint.h>
#include <thread>

#define POS(idx, dim) pos(idx, dim)

using namespace megamol;

ospray::PkdBuilder::PkdBuilder()
    : megamol::stdplugin::datatools::AbstractParticleManipulator("outData", "inData")
    , inDataHash(0)
    , outDataHash(0)
    /*, numParticles(0)
    , numInnerNodes(0)*/ {
    //model = std::make_shared<ParticleModel>();
}

ospray::PkdBuilder::~PkdBuilder() { Release(); }

bool ospray::PkdBuilder::manipulateData(
    core::moldyn::MultiParticleDataCall& outData, core::moldyn::MultiParticleDataCall& inData) {

    if ((inData.DataHash() != inDataHash) || (inData.FrameID() != frameID) || (inData.DataHash() == 0)) {
        inDataHash = inData.DataHash();
        //outDataHash++;
        frameID = inData.FrameID();

        // outData = inData;

        outData.SetFrameID(frameID);
        outData.SetDataHash(inDataHash);
        outData.SetParticleListCount(inData.GetParticleListCount());
        outData.AccessBoundingBoxes().SetObjectSpaceBBox(inData.AccessBoundingBoxes().ObjectSpaceBBox());
        outData.AccessBoundingBoxes().SetObjectSpaceClipBox(inData.AccessBoundingBoxes().ObjectSpaceClipBox());

        outData.SetUnlocker(inData.GetUnlocker());

        models.resize(inData.GetParticleListCount());

        for (unsigned int i = 0; i < inData.GetParticleListCount(); ++i) {
            auto& parts = inData.AccessParticles(i);
            auto& out = outData.AccessParticles(i);

            // empty the model
            // this->model->position.clear();
            models[i].position.clear();

            // put data the data into the model
            // and build the pkd tree
            // this->model->fill(parts);
            models[i].fill(parts);
            // this->build();
            Pkd pkd;
            pkd.model = &models[i];
            pkd.build();

            out.SetCount(parts.GetCount());
            out.SetVertexData(
                megamol::core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZ, &models[i].position[0].x, 16);
            out.SetColourData(
                megamol::core::moldyn::SimpleSphericalParticles::COLDATA_UINT8_RGBA, &models[i].position[0].w, 16);
            out.SetGlobalRadius(parts.GetGlobalRadius());
        }
    }

    inData.SetUnlocker(nullptr, false);

    return true;
}

void ospray::Pkd::setDim(size_t ID, int dim) const {
#if DIM_FROM_DEPTH
    return;
#else
    ospcommon::vec3f& particle = (ospcommon::vec3f&)this->model->position[ID];
    int& pxAsInt = (int&)particle.x;
    pxAsInt = (pxAsInt & ~3) | dim;
#endif
}

inline size_t ospray::Pkd::maxDim(const ospcommon::vec3f& v) const {
    const float maxVal = ospcommon::reduce_max(v);
    if (maxVal == v.x) {
        return 0;
    } else if (maxVal == v.y) {
        return 1;
    } else if (maxVal == v.z) {
        return 2;
    } else {
        assert(false && "Invalid max val index for vec!?");
        return -1;
    }
}

inline void ospray::Pkd::swap(const size_t a, const size_t b) const {
    std::swap(model->position[a], model->position[b]);
}

void ospray::Pkd::build() {
    // PING;
    assert(this->model != NULL);

    assert(!model->position.empty());
    numParticles = model->position.size();
    assert(numParticles <= (1ULL << 31));

#if 0
    cout << "#osp:pkd: TEST: RANDOMIZING PARTICLES" << endl;
    for (size_t i = numParticles - 1; i>0; --i) {
        size_t j = size_t(drand48()*i);
        if (i != j) swap(i, j);
    }
    cout << "#osp:pkd: RANDOMIZED" << endl;
#endif

    numInnerNodes = numInnerNodesOf(numParticles);

    // determine num levels
    numLevels = 0;
    size_t nodeID = 0;
    while (isValidNode(nodeID)) {
        ++numLevels;
        nodeID = leftChildOf(nodeID);
    }
    // PRINT(numLevels);

    const ospcommon::box3f& bounds = model->getBounds();
    /*std::cout << "#osp:pkd: bounds of model " << bounds << std::endl;
    std::cout << "#osp:pkd: number of input particles " << numParticles << std::endl;*/
    this->buildRec(0, bounds, 0);
}

void ospray::Pkd::buildRec(const size_t nodeID, const ospcommon::box3f& bounds, const size_t depth) const {
    // if (depth < 4)
    // std::cout << "#osp:pkd: building subtree " << nodeID << std::endl;
    if (!hasLeftChild(nodeID))
        // has no children -> it's a valid kd-tree already :-)
        return;

    // we have at least one child.
    const size_t dim = this->maxDim(bounds.size());
    // if (depth < 4) { PRINT(bounds); printf("depth %ld-> dim %ld\n",depth,dim); }
    const size_t N = numParticles;

    if (!hasRightChild(nodeID)) {
        // no right child, but not a leaf emtpy. must have exactly one
        // child on the left. see if we have to swap, but otherwise
        // nothing to do.
        size_t lChild = leftChildOf(nodeID);
        if (POS(lChild, dim) > POS(nodeID, dim)) swap(nodeID, lChild);
        // and done
        setDim(nodeID, dim);
        return;
    }

    {

        // we have a left and a right subtree, each of at least 1 node.
        SubtreeIterator l0(leftChildOf(nodeID));
        SubtreeIterator r0(rightChildOf(nodeID));

        SubtreeIterator l((size_t)l0); //(leftChildOf(nodeID));
        SubtreeIterator r((size_t)r0); //(rightChildOf(nodeID));

        // size_t numSwaps = 0, numComps = 0;
        float rootPos = POS(nodeID, dim);
        while (1) {

            while (isValidNode(l, N) && (POS(l, dim) <= rootPos)) ++l;
            while (isValidNode(r, N) && (POS(r, dim) >= rootPos)) ++r;

            if (isValidNode(l, N)) {
                if (isValidNode(r, N)) {
                    // both mis-mathces valid, just swap them and go on
                    swap(l, r);
                    ++l;
                    ++r;
                    continue;
                } else {
                    // mis-match on left side, but nothing on right side to swap with: swap with root
                    // --> can't go on on right side any more, but can still compact matches on left
                    l0 = l;
                    ++l;
                    while (isValidNode(l, N)) {
                        if (POS(l, dim) <= rootPos) {
                            swap(l0, l);
                            ++l0;
                        }
                        ++l;
                    }
                    swap(nodeID, l0);
                    ++l0;
                    rootPos = POS(nodeID, dim);

                    l = l0;
                    r = r0;
                    continue;
                }
            } else {
                if (isValidNode(r, N)) {
                    // mis-match on left side, but nothing on right side to swap with: swap with root
                    // --> can't go on on right side any more, but can still compact matches on left
                    r0 = r;
                    ++r;
                    while (isValidNode(r, N)) {
                        if (POS(r, dim) >= rootPos) {
                            swap(r0, r);
                            ++r0;
                        }
                        ++r;
                    }
                    swap(nodeID, r0);
                    ++r0;
                    rootPos = POS(nodeID, dim);

                    l = l0;
                    r = r0;
                    continue;
                } else {
                    // no mis-match on either side ... done.
                    break;
                }
            }
        }
    }

    ospcommon::box3f lBounds = bounds;
    ospcommon::box3f rBounds = bounds;

    setDim(nodeID, dim);

    lBounds.upper[dim] = rBounds.lower[dim] = pos(nodeID, dim);

    if ((numLevels - depth) > 20) {
        std::thread lThread(&pkdBuildThread, new PKDBuildJob(this, leftChildOf(nodeID), lBounds, depth + 1));
        buildRec(rightChildOf(nodeID), rBounds, depth + 1);
        lThread.join();
    } else {
        buildRec(leftChildOf(nodeID), lBounds, depth + 1);
        buildRec(rightChildOf(nodeID), rBounds, depth + 1);
    }
}

<commit_msg>fix for weird data update<commit_after>#include "stdafx.h"
#include "Pkd.h"
#include <iostream>
#include <stdint.h>
#include <thread>

#define POS(idx, dim) pos(idx, dim)

using namespace megamol;

ospray::PkdBuilder::PkdBuilder()
    : megamol::stdplugin::datatools::AbstractParticleManipulator("outData", "inData")
    , inDataHash(0)
    , outDataHash(0)
    /*, numParticles(0)
    , numInnerNodes(0)*/ {
    //model = std::make_shared<ParticleModel>();
}

ospray::PkdBuilder::~PkdBuilder() { Release(); }

bool ospray::PkdBuilder::manipulateData(
    core::moldyn::MultiParticleDataCall& outData, core::moldyn::MultiParticleDataCall& inData) {

    if ((inData.DataHash() != inDataHash) || (inData.FrameID() != frameID)) {
        inDataHash = inData.DataHash();
        //outDataHash++;
        frameID = inData.FrameID();

        outData = inData;

        models.resize(inData.GetParticleListCount());

        for (unsigned int i = 0; i < inData.GetParticleListCount(); ++i) {
            auto& parts = inData.AccessParticles(i);
            auto& out = outData.AccessParticles(i);

            // empty the model
            // this->model->position.clear();
            models[i].position.clear();

            // put data the data into the model
            // and build the pkd tree
            // this->model->fill(parts);
            models[i].fill(parts);
            // this->build();
            Pkd pkd;
            pkd.model = &models[i];
            pkd.build();

            out.SetCount(parts.GetCount());
            out.SetVertexData(
                megamol::core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZ, &models[i].position[0].x, 16);
            out.SetColourData(
                megamol::core::moldyn::SimpleSphericalParticles::COLDATA_UINT8_RGBA, &models[i].position[0].w, 16);
            out.SetGlobalRadius(parts.GetGlobalRadius());
        }

        outData.SetUnlocker(nullptr, false);
    }

    return true;
}

void ospray::Pkd::setDim(size_t ID, int dim) const {
#if DIM_FROM_DEPTH
    return;
#else
    ospcommon::vec3f& particle = (ospcommon::vec3f&)this->model->position[ID];
    int& pxAsInt = (int&)particle.x;
    pxAsInt = (pxAsInt & ~3) | dim;
#endif
}

inline size_t ospray::Pkd::maxDim(const ospcommon::vec3f& v) const {
    const float maxVal = ospcommon::reduce_max(v);
    if (maxVal == v.x) {
        return 0;
    } else if (maxVal == v.y) {
        return 1;
    } else if (maxVal == v.z) {
        return 2;
    } else {
        assert(false && "Invalid max val index for vec!?");
        return -1;
    }
}

inline void ospray::Pkd::swap(const size_t a, const size_t b) const {
    std::swap(model->position[a], model->position[b]);
}

void ospray::Pkd::build() {
    // PING;
    assert(this->model != NULL);

    assert(!model->position.empty());
    numParticles = model->position.size();
    assert(numParticles <= (1ULL << 31));

#if 0
    cout << "#osp:pkd: TEST: RANDOMIZING PARTICLES" << endl;
    for (size_t i = numParticles - 1; i>0; --i) {
        size_t j = size_t(drand48()*i);
        if (i != j) swap(i, j);
    }
    cout << "#osp:pkd: RANDOMIZED" << endl;
#endif

    numInnerNodes = numInnerNodesOf(numParticles);

    // determine num levels
    numLevels = 0;
    size_t nodeID = 0;
    while (isValidNode(nodeID)) {
        ++numLevels;
        nodeID = leftChildOf(nodeID);
    }
    // PRINT(numLevels);

    const ospcommon::box3f& bounds = model->getBounds();
    /*std::cout << "#osp:pkd: bounds of model " << bounds << std::endl;
    std::cout << "#osp:pkd: number of input particles " << numParticles << std::endl;*/
    this->buildRec(0, bounds, 0);
}

void ospray::Pkd::buildRec(const size_t nodeID, const ospcommon::box3f& bounds, const size_t depth) const {
    // if (depth < 4)
    // std::cout << "#osp:pkd: building subtree " << nodeID << std::endl;
    if (!hasLeftChild(nodeID))
        // has no children -> it's a valid kd-tree already :-)
        return;

    // we have at least one child.
    const size_t dim = this->maxDim(bounds.size());
    // if (depth < 4) { PRINT(bounds); printf("depth %ld-> dim %ld\n",depth,dim); }
    const size_t N = numParticles;

    if (!hasRightChild(nodeID)) {
        // no right child, but not a leaf emtpy. must have exactly one
        // child on the left. see if we have to swap, but otherwise
        // nothing to do.
        size_t lChild = leftChildOf(nodeID);
        if (POS(lChild, dim) > POS(nodeID, dim)) swap(nodeID, lChild);
        // and done
        setDim(nodeID, dim);
        return;
    }

    {

        // we have a left and a right subtree, each of at least 1 node.
        SubtreeIterator l0(leftChildOf(nodeID));
        SubtreeIterator r0(rightChildOf(nodeID));

        SubtreeIterator l((size_t)l0); //(leftChildOf(nodeID));
        SubtreeIterator r((size_t)r0); //(rightChildOf(nodeID));

        // size_t numSwaps = 0, numComps = 0;
        float rootPos = POS(nodeID, dim);
        while (1) {

            while (isValidNode(l, N) && (POS(l, dim) <= rootPos)) ++l;
            while (isValidNode(r, N) && (POS(r, dim) >= rootPos)) ++r;

            if (isValidNode(l, N)) {
                if (isValidNode(r, N)) {
                    // both mis-mathces valid, just swap them and go on
                    swap(l, r);
                    ++l;
                    ++r;
                    continue;
                } else {
                    // mis-match on left side, but nothing on right side to swap with: swap with root
                    // --> can't go on on right side any more, but can still compact matches on left
                    l0 = l;
                    ++l;
                    while (isValidNode(l, N)) {
                        if (POS(l, dim) <= rootPos) {
                            swap(l0, l);
                            ++l0;
                        }
                        ++l;
                    }
                    swap(nodeID, l0);
                    ++l0;
                    rootPos = POS(nodeID, dim);

                    l = l0;
                    r = r0;
                    continue;
                }
            } else {
                if (isValidNode(r, N)) {
                    // mis-match on left side, but nothing on right side to swap with: swap with root
                    // --> can't go on on right side any more, but can still compact matches on left
                    r0 = r;
                    ++r;
                    while (isValidNode(r, N)) {
                        if (POS(r, dim) >= rootPos) {
                            swap(r0, r);
                            ++r0;
                        }
                        ++r;
                    }
                    swap(nodeID, r0);
                    ++r0;
                    rootPos = POS(nodeID, dim);

                    l = l0;
                    r = r0;
                    continue;
                } else {
                    // no mis-match on either side ... done.
                    break;
                }
            }
        }
    }

    ospcommon::box3f lBounds = bounds;
    ospcommon::box3f rBounds = bounds;

    setDim(nodeID, dim);

    lBounds.upper[dim] = rBounds.lower[dim] = pos(nodeID, dim);

    if ((numLevels - depth) > 20) {
        std::thread lThread(&pkdBuildThread, new PKDBuildJob(this, leftChildOf(nodeID), lBounds, depth + 1));
        buildRec(rightChildOf(nodeID), rBounds, depth + 1);
        lThread.join();
    } else {
        buildRec(leftChildOf(nodeID), lBounds, depth + 1);
        buildRec(rightChildOf(nodeID), rBounds, depth + 1);
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include <limits>

#define FLATC_VERSION "1.3.0 (" __DATE__ ")"

static void Error(const std::string &err, bool usage = false,
                  bool show_exe_name = true);

// This struct allows us to create a table of all possible output generators
// for the various programming languages and formats we support.
struct Generator {
  bool (*generate)(const flatbuffers::Parser &parser,
                   const std::string &path,
                   const std::string &file_name);
  const char *generator_opt_short;
  const char *generator_opt_long;
  const char *lang_name;
  flatbuffers::IDLOptions::Language lang;
  const char *generator_help;

  std::string (*make_rule)(const flatbuffers::Parser &parser,
                           const std::string &path,
                           const std::string &file_name);
};

const Generator generators[] = {
  { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
    flatbuffers::IDLOptions::kMAX,
    "Generate wire format binaries for any data definitions",
    flatbuffers::BinaryMakeRule },
  { flatbuffers::GenerateTextFile, "-t", "--json", "text",
    flatbuffers::IDLOptions::kMAX,
    "Generate text output for any data definitions",
    flatbuffers::TextMakeRule },
  { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
    flatbuffers::IDLOptions::kMAX,
    "Generate C++ headers for tables/structs",
    flatbuffers::CPPMakeRule },
  { flatbuffers::GenerateGo,       "-g", "--go", "Go",
    flatbuffers::IDLOptions::kGo,
    "Generate Go files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGeneral,  "-j", "--java", "Java",
    flatbuffers::IDLOptions::kJava,
    "Generate Java classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
    flatbuffers::IDLOptions::kMAX,
    "Generate JavaScript code for tables/structs",
    flatbuffers::JSMakeRule },
  { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
    flatbuffers::IDLOptions::kCSharp,
    "Generate C# classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePython,   "-p", "--python", "Python",
    flatbuffers::IDLOptions::kMAX,
    "Generate Python files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
    flatbuffers::IDLOptions::kMAX,
    "Generate PHP files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGRPC, nullptr, "--grpc", "GRPC",
    flatbuffers::IDLOptions::kMAX,
    "Generate GRPC interfaces",
    flatbuffers::CPPMakeRule },
};

const char *program_name = nullptr;
flatbuffers::Parser *parser = nullptr;

static void Error(const std::string &err, bool usage, bool show_exe_name) {
  if (show_exe_name) printf("%s: ", program_name);
  printf("%s\n", err.c_str());
  if (usage) {
    printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", program_name);
    for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
      printf("  %-12s %s %s.\n",
             generators[i].generator_opt_long,
             generators[i].generator_opt_short
               ? generators[i].generator_opt_short
               : "  ",
             generators[i].generator_help);
    printf(
      "  -o PATH            Prefix PATH to all generated files.\n"
      "  -I PATH            Search for includes in the specified path.\n"
      "  -M                 Print make rules for generated files.\n"
      "  --version          Print the version number of flatc and exit.\n"
      "  --strict-json      Strict JSON: field names must be / will be quoted,\n"
      "                     no trailing commas in tables/vectors.\n"
      "  --defaults-json    Output fields whose value is the default when\n"
      "                     writing JSON\n"
      "  --unknown-json     Allow fields in JSON that are not defined in the\n"
      "                     schema. These fields will be discared when generating\n"
      "                     binaries.\n"
      "  --no-prefix        Don\'t prefix enum values with the enum type in C++.\n"
      "  --scoped-enums     Use C++11 style scoped and strongly typed enums.\n"
      "                     also implies --no-prefix.\n"
      "  --gen-includes     (deprecated), this is the default behavior.\n"
      "                     If the original behavior is required (no include\n"
      "                     statements) use --no-includes.\n"
      "  --no-includes      Don\'t generate include statements for included\n"
      "                     schemas the generated file depends on (C++).\n"
      "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
      "  --gen-onefile      Generate single output file for C#.\n"
      "  --gen-name-strings		 Generate type name functions for C++.\n"
      "  --escape-proto-identifiers      Disable appending '_' in namespaces names.\n"
      "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
      "                     This may crash flatc given a mismatched schema.\n"
      "  --proto            Input is a .proto, translate to .fbs.\n"
      "  --schema           Serialize schemas instead of JSON (use with -b)\n"
      "FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
      "FILEs after the -- must be binary flatbuffer format files.\n"
      "Output files are named using the base file name of the input,\n"
      "and written to the current directory or the path given by -o.\n"
      "example: %s -c -b schema1.fbs schema2.fbs data.json\n",
      program_name);
  }
  if (parser) delete parser;
  exit(1);
}

int main(int argc, const char *argv[]) {
  program_name = argv[0];
  flatbuffers::IDLOptions opts;
  std::string output_path;
  const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
  bool generator_enabled[num_generators] = { false };
  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  std::vector<std::string> filenames;
  std::vector<const char *> include_directories;
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(argv[argi], "");
      } else if(arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories.push_back(argv[argi]);
      } else if(arg == "--strict-json") {
        opts.strict_json = true;
      } else if(arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if(arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if(arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if(arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if(arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if(arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if(arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if(arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if(arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if(arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
      } else if (arg == "--escape-proto-identifiers") {
	opts.escape_proto_identifiers = true;
      } else if (arg == "--schema") {
        schema_binary = true;
      } else if(arg == "-M") {
        print_make_rules = true;
      } else if(arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION);
        exit(0);
      } else {
        for (size_t i = 0; i < num_generators; ++i) {
          if (arg == generators[i].generator_opt_long ||
              (generators[i].generator_opt_short &&
               arg == generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            goto found;
          }
        }
        Error("unknown commandline argument" + arg, true);
        found:;
      }
    } else {
      filenames.push_back(argv[argi]);
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (opts.proto_mode) {
    if (any_generator)
      Error("cannot generate code directly from .proto files", true);
  } else if (!any_generator) {
    Error("no options: specify at least one generator.", true);
  }

  // Now process the files:
  parser = new flatbuffers::Parser(opts);
  for (auto file_it = filenames.begin();
            file_it != filenames.end();
          ++file_it) {
      std::string contents;
      if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents))
        Error("unable to load file: " + *file_it);

      bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
                       binary_files_from;
      if (is_binary) {
        parser->builder_.Clear();
        parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
        if (!raw_binary) {
          // Generally reading binaries that do not correspond to the schema
          // will crash, and sadly there's no way around that when the binary
          // does not contain a file identifier.
          // We'd expect that typically any binary used as a file would have
          // such an identifier, so by default we require them to match.
          if (!parser->file_identifier_.length()) {
            Error("current schema has no file_identifier: cannot test if \"" +
                 *file_it +
                 "\" matches the schema, use --raw-binary to read this file"
                 " anyway.");
          } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
                                             parser->file_identifier_.c_str())) {
            Error("binary \"" +
                 *file_it +
                 "\" does not have expected file_identifier \"" +
                 parser->file_identifier_ +
                 "\", use --raw-binary to read this file anyway.");
          }
        }
      } else {
        // Check if file contains 0 bytes.
        if (contents.length() != strlen(contents.c_str())) {
          Error("input file appears to be binary: " + *file_it, true);
        }
        if (flatbuffers::GetExtension(*file_it) == "fbs") {
          // If we're processing multiple schemas, make sure to start each
          // one from scratch. If it depends on previous schemas it must do
          // so explicitly using an include.
          delete parser;
          parser = new flatbuffers::Parser(opts);
        }
        auto local_include_directory = flatbuffers::StripFileName(*file_it);
        include_directories.push_back(local_include_directory.c_str());
        include_directories.push_back(nullptr);
        if (!parser->Parse(contents.c_str(), &include_directories[0],
                          file_it->c_str()))
          Error(parser->error_, false, false);
        if (schema_binary) {
          parser->Serialize();
          parser->file_extension_ = reflection::SchemaExtension();
        }
        include_directories.pop_back();
        include_directories.pop_back();
      }

      std::string filebase = flatbuffers::StripPath(
                               flatbuffers::StripExtension(*file_it));

      for (size_t i = 0; i < num_generators; ++i) {
        parser->opts.lang = generators[i].lang;
        if (generator_enabled[i]) {
          if (!print_make_rules) {
            flatbuffers::EnsureDirExists(output_path);
            if (!generators[i].generate(*parser, output_path, filebase)) {
              Error(std::string("Unable to generate ") +
                    generators[i].lang_name +
                    " for " +
                    filebase);
            }
          } else {
            std::string make_rule = generators[i].make_rule(
                *parser, output_path, *file_it);
            if (!make_rule.empty())
              printf("%s\n", flatbuffers::WordWrap(
                  make_rule, 80, " ", " \\").c_str());
          }
        }
      }

      if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase, opts.escape_proto_identifiers);

      // We do not want to generate code for the definitions in this file
      // in any files coming up next.
      parser->MarkGenerated();
  }

  delete parser;
  return 0;
}
<commit_msg>Update flatc.cpp<commit_after>/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include <limits>

#define FLATC_VERSION "1.3.0 (" __DATE__ ")"

static void Error(const std::string &err, bool usage = false,
                  bool show_exe_name = true);

// This struct allows us to create a table of all possible output generators
// for the various programming languages and formats we support.
struct Generator {
  bool (*generate)(const flatbuffers::Parser &parser,
                   const std::string &path,
                   const std::string &file_name);
  const char *generator_opt_short;
  const char *generator_opt_long;
  const char *lang_name;
  flatbuffers::IDLOptions::Language lang;
  const char *generator_help;

  std::string (*make_rule)(const flatbuffers::Parser &parser,
                           const std::string &path,
                           const std::string &file_name);
};

const Generator generators[] = {
  { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
    flatbuffers::IDLOptions::kMAX,
    "Generate wire format binaries for any data definitions",
    flatbuffers::BinaryMakeRule },
  { flatbuffers::GenerateTextFile, "-t", "--json", "text",
    flatbuffers::IDLOptions::kMAX,
    "Generate text output for any data definitions",
    flatbuffers::TextMakeRule },
  { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
    flatbuffers::IDLOptions::kMAX,
    "Generate C++ headers for tables/structs",
    flatbuffers::CPPMakeRule },
  { flatbuffers::GenerateGo,       "-g", "--go", "Go",
    flatbuffers::IDLOptions::kGo,
    "Generate Go files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGeneral,  "-j", "--java", "Java",
    flatbuffers::IDLOptions::kJava,
    "Generate Java classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
    flatbuffers::IDLOptions::kMAX,
    "Generate JavaScript code for tables/structs",
    flatbuffers::JSMakeRule },
  { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
    flatbuffers::IDLOptions::kCSharp,
    "Generate C# classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePython,   "-p", "--python", "Python",
    flatbuffers::IDLOptions::kMAX,
    "Generate Python files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
    flatbuffers::IDLOptions::kMAX,
    "Generate PHP files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGRPC, nullptr, "--grpc", "GRPC",
    flatbuffers::IDLOptions::kMAX,
    "Generate GRPC interfaces",
    flatbuffers::CPPMakeRule },
};

const char *program_name = nullptr;
flatbuffers::Parser *parser = nullptr;

static void Error(const std::string &err, bool usage, bool show_exe_name) {
  if (show_exe_name) printf("%s: ", program_name);
  printf("%s\n", err.c_str());
  if (usage) {
    printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", program_name);
    for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
      printf("  %-12s %s %s.\n",
             generators[i].generator_opt_long,
             generators[i].generator_opt_short
               ? generators[i].generator_opt_short
               : "  ",
             generators[i].generator_help);
    printf(
      "  -o PATH            Prefix PATH to all generated files.\n"
      "  -I PATH            Search for includes in the specified path.\n"
      "  -M                 Print make rules for generated files.\n"
      "  --version          Print the version number of flatc and exit.\n"
      "  --strict-json      Strict JSON: field names must be / will be quoted,\n"
      "                     no trailing commas in tables/vectors.\n"
      "  --defaults-json    Output fields whose value is the default when\n"
      "                     writing JSON\n"
      "  --unknown-json     Allow fields in JSON that are not defined in the\n"
      "                     schema. These fields will be discared when generating\n"
      "                     binaries.\n"
      "  --no-prefix        Don\'t prefix enum values with the enum type in C++.\n"
      "  --scoped-enums     Use C++11 style scoped and strongly typed enums.\n"
      "                     also implies --no-prefix.\n"
      "  --gen-includes     (deprecated), this is the default behavior.\n"
      "                     If the original behavior is required (no include\n"
      "                     statements) use --no-includes.\n"
      "  --no-includes      Don\'t generate include statements for included\n"
      "                     schemas the generated file depends on (C++).\n"
      "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
      "  --gen-onefile      Generate single output file for C#.\n"
      "  --gen-name-strings Generate type name functions for C++.\n"
      "  --escape-proto-ids Disable appending '_' in namespaces names.\n"
      "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
      "                     This may crash flatc given a mismatched schema.\n"
      "  --proto            Input is a .proto, translate to .fbs.\n"
      "  --schema           Serialize schemas instead of JSON (use with -b)\n"
      "FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
      "FILEs after the -- must be binary flatbuffer format files.\n"
      "Output files are named using the base file name of the input,\n"
      "and written to the current directory or the path given by -o.\n"
      "example: %s -c -b schema1.fbs schema2.fbs data.json\n",
      program_name);
  }
  if (parser) delete parser;
  exit(1);
}

int main(int argc, const char *argv[]) {
  program_name = argv[0];
  flatbuffers::IDLOptions opts;
  std::string output_path;
  const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
  bool generator_enabled[num_generators] = { false };
  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  std::vector<std::string> filenames;
  std::vector<const char *> include_directories;
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(argv[argi], "");
      } else if(arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories.push_back(argv[argi]);
      } else if(arg == "--strict-json") {
        opts.strict_json = true;
      } else if(arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if(arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if(arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if(arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if(arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if(arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if(arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if(arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if(arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if(arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
      } else if (arg == "--escape-proto-ids") {
        opts.escape_proto_identifiers = true;
      } else if (arg == "--schema") {
        schema_binary = true;
      } else if(arg == "-M") {
        print_make_rules = true;
      } else if(arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION);
        exit(0);
      } else {
        for (size_t i = 0; i < num_generators; ++i) {
          if (arg == generators[i].generator_opt_long ||
              (generators[i].generator_opt_short &&
               arg == generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            goto found;
          }
        }
        Error("unknown commandline argument" + arg, true);
        found:;
      }
    } else {
      filenames.push_back(argv[argi]);
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (opts.proto_mode) {
    if (any_generator)
      Error("cannot generate code directly from .proto files", true);
  } else if (!any_generator) {
    Error("no options: specify at least one generator.", true);
  }

  // Now process the files:
  parser = new flatbuffers::Parser(opts);
  for (auto file_it = filenames.begin();
            file_it != filenames.end();
          ++file_it) {
      std::string contents;
      if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents))
        Error("unable to load file: " + *file_it);

      bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
                       binary_files_from;
      if (is_binary) {
        parser->builder_.Clear();
        parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
        if (!raw_binary) {
          // Generally reading binaries that do not correspond to the schema
          // will crash, and sadly there's no way around that when the binary
          // does not contain a file identifier.
          // We'd expect that typically any binary used as a file would have
          // such an identifier, so by default we require them to match.
          if (!parser->file_identifier_.length()) {
            Error("current schema has no file_identifier: cannot test if \"" +
                 *file_it +
                 "\" matches the schema, use --raw-binary to read this file"
                 " anyway.");
          } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
                                             parser->file_identifier_.c_str())) {
            Error("binary \"" +
                 *file_it +
                 "\" does not have expected file_identifier \"" +
                 parser->file_identifier_ +
                 "\", use --raw-binary to read this file anyway.");
          }
        }
      } else {
        // Check if file contains 0 bytes.
        if (contents.length() != strlen(contents.c_str())) {
          Error("input file appears to be binary: " + *file_it, true);
        }
        if (flatbuffers::GetExtension(*file_it) == "fbs") {
          // If we're processing multiple schemas, make sure to start each
          // one from scratch. If it depends on previous schemas it must do
          // so explicitly using an include.
          delete parser;
          parser = new flatbuffers::Parser(opts);
        }
        auto local_include_directory = flatbuffers::StripFileName(*file_it);
        include_directories.push_back(local_include_directory.c_str());
        include_directories.push_back(nullptr);
        if (!parser->Parse(contents.c_str(), &include_directories[0],
                          file_it->c_str()))
          Error(parser->error_, false, false);
        if (schema_binary) {
          parser->Serialize();
          parser->file_extension_ = reflection::SchemaExtension();
        }
        include_directories.pop_back();
        include_directories.pop_back();
      }

      std::string filebase = flatbuffers::StripPath(
                               flatbuffers::StripExtension(*file_it));

      for (size_t i = 0; i < num_generators; ++i) {
        parser->opts.lang = generators[i].lang;
        if (generator_enabled[i]) {
          if (!print_make_rules) {
            flatbuffers::EnsureDirExists(output_path);
            if (!generators[i].generate(*parser, output_path, filebase)) {
              Error(std::string("Unable to generate ") +
                    generators[i].lang_name +
                    " for " +
                    filebase);
            }
          } else {
            std::string make_rule = generators[i].make_rule(
                *parser, output_path, *file_it);
            if (!make_rule.empty())
              printf("%s\n", flatbuffers::WordWrap(
                  make_rule, 80, " ", " \\").c_str());
          }
        }
      }

      if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase);

      // We do not want to generate code for the definitions in this file
      // in any files coming up next.
      parser->MarkGenerated();
  }

  delete parser;
  return 0;
}
<|endoftext|>