text:
//
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//

#ifndef BOOST_BEAST_WEBSOCKET_RFC6455_HPP
#define BOOST_BEAST_WEBSOCKET_RFC6455_HPP

#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/static_string.hpp>
#include <boost/beast/core/string.hpp>
#include <boost/beast/http/message.hpp>
#include <array>
#include <cstdint>

namespace boost {
namespace beast {
namespace websocket {

/** Returns `true` if the specified HTTP request is a WebSocket Upgrade.

    This function returns `true` when the passed HTTP Request
    indicates a WebSocket Upgrade. It does not validate the
    contents of the fields: it just trivially accepts requests
    which could only possibly be a valid or invalid WebSocket
    Upgrade message.

    Callers who wish to manually read HTTP requests in their
    server implementation can use this function to determine if
    the request should be routed to an instance of
    @ref websocket::stream.

    @par Example
    @code
    void handle_connection(boost::asio::ip::tcp::socket& sock)
    {
        boost::beast::flat_buffer buffer;
        boost::beast::http::request<boost::beast::http::string_body> req;
        boost::beast::http::read(sock, buffer, req);
        if(boost::beast::websocket::is_upgrade(req))
        {
            boost::beast::websocket::stream<decltype(sock)> ws{std::move(sock)};
            ws.accept(req);
        }
    }
    @endcode

    @param req The HTTP Request object to check.

    @return `true` if the request is a WebSocket Upgrade.
*/
template<class Allocator>
bool
is_upgrade(beast::http::header<true,
    http::basic_fields<Allocator>> const& req);

/** Close status codes.

    These codes accompany close frames.

    @see RFC 6455 7.4.1 Defined Status Codes
*/
enum close_code : std::uint16_t
{
    /// Normal closure; the connection successfully completed whatever purpose for which it was created.
    normal          = 1000,

    /// The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.
    going_away      = 1001,

    /// The endpoint is terminating the connection due to a protocol error.
    protocol_error  = 1002,

    /// The connection is being terminated because the endpoint received data of a type it cannot accept (for example, a text-only endpoint received binary data).
    unknown_data    = 1003,

    /// The endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., non-UTF-8 data within a text message).
    bad_payload     = 1007,

    /// The endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.
    policy_error    = 1008,

    /// The endpoint is terminating the connection because a data frame was received that is too large.
    too_big         = 1009,

    /// The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn't.
    needs_extension = 1010,

    /// The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
    internal_error  = 1011,

    /// The server is terminating the connection because it is restarting.
    service_restart = 1012,

    /// The server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients.
    try_again_later = 1013,

    //----
    //
    // The following are illegal on the wire
    //

    /** Used internally to mean "no error"

        This code is reserved and may not be sent.
    */
    none            = 0,

    /** Reserved for future use by the WebSocket standard.

        This code is reserved and may not be sent.
    */
    reserved1       = 1004,

    /** No status code was provided even though one was expected.

        This code is reserved and may not be sent.
    */
    no_status       = 1005,

    /** Connection was closed without receiving a close frame

        This code is reserved and may not be sent.
    */
    abnormal        = 1006,

    /** Reserved for future use by the WebSocket standard.

        This code is reserved and may not be sent.
    */
    reserved2       = 1014,

    /** Reserved for future use by the WebSocket standard.

        This code is reserved and may not be sent.
    */
    reserved3       = 1015

    //
    //----

    //last = 5000 // satisfy warnings
};

/// The type representing the reason string in a close frame.
using reason_string = static_string<123, char>;

/// The type representing the payload of ping and pong messages.
using ping_data = static_string<125, char>;

/** Description of the close reason.

    This object stores the close code (if any) and the optional
    utf-8 encoded implementation defined reason string.
*/
struct close_reason
{
    /// The close code.
    std::uint16_t code = close_code::none;

    /// The optional utf8-encoded reason string.
    reason_string reason;

    /** Default constructor.

        The code will be none. Default constructed objects
        will explicitly convert to bool as `false`.
    */
    close_reason() = default;

    /// Construct from a code.
    close_reason(std::uint16_t code_)
        : code(code_)
    {
    }

    /// Construct from a reason string. code is @ref close_code::normal.
    close_reason(string_view s)
        : code(close_code::normal)
        , reason(s)
    {
    }

    /// Construct from a reason string literal. code is @ref close_code::normal.
    close_reason(char const* s)
        : code(close_code::normal)
        , reason(s)
    {
    }

    /// Construct from a close code and reason string.
    close_reason(close_code code_, string_view s)
        : code(code_)
        , reason(s)
    {
    }

    /// Returns `true` if a code was specified
    operator bool() const
    {
        return code != close_code::none;
    }
};

} // websocket
} // beast
} // boost

#include <boost/beast/websocket/impl/rfc6455.ipp>

#endif

ext: hpp


text:
/*
 * (C) Copyright 2014 Kurento (http://kurento.org/)
 *
 * 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 "logging.hpp"

#include <gst/gst.h>

#include <boost/format.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/sources/channel_feature.hpp>
#include <boost/log/sources/channel_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/manipulators/add_value.hpp>
#include <boost/log/utility/exception_handler.hpp>
#include <sys/types.h>
#include <unistd.h>

namespace logging = boost::log;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace expr = boost::log::expressions;
namespace keywords = boost::log::keywords;

typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;

namespace kurento
{

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

GST_DEBUG_CATEGORY_STATIC (kms_glib_debug);

static GstDebugLevel
g_log_level_to_gst_debug_level (GLogLevelFlags log_level)
{
  switch (log_level & G_LOG_LEVEL_MASK) {
  case G_LOG_LEVEL_ERROR:    return GST_LEVEL_ERROR;
  case G_LOG_LEVEL_CRITICAL: return GST_LEVEL_ERROR;
  case G_LOG_LEVEL_WARNING:  return GST_LEVEL_WARNING;
  case G_LOG_LEVEL_MESSAGE:  return GST_LEVEL_FIXME;
  case G_LOG_LEVEL_INFO:     return GST_LEVEL_INFO;
  case G_LOG_LEVEL_DEBUG:    return GST_LEVEL_DEBUG;
  default:                   return GST_LEVEL_DEBUG;
  }
}

/*
 * Based on the Glib 2.48.2 default message handler, g_log_default_handler()
 * https://github.com/GNOME/glib/blob/2.48.2/glib/gmessages.c#L1429
 *
 * NOTE: In Glib 2.50 they added a new logging mode, "structured logging", that
 * maybe we need to check out in the future.
 */
/* these are emitted by the default log handler */
#define DEFAULT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE)
/* these are filtered by G_MESSAGES_DEBUG by the default log handler */
#define INFO_LEVELS (G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG)
static void
kms_glib_log_handler (const gchar   *log_domain,
                      GLogLevelFlags log_level,
                      const gchar   *message,
                      gpointer       unused_data)
{
  const gchar *domains;

  if ((log_level & DEFAULT_LEVELS) || (log_level >> G_LOG_LEVEL_USER_SHIFT)) {
    goto emit;
  }

  domains = g_getenv ("G_MESSAGES_DEBUG");
  if (((log_level & INFO_LEVELS) == 0) ||
      domains == NULL ||
      (strcmp (domains, "all") != 0 && (!log_domain || !strstr (domains, log_domain))))
  {
    return;
  }

 emit:
  /* we can be called externally with recursion for whatever reason */
  if (log_level & G_LOG_FLAG_RECURSION)
    {
      //_g_log_fallback_handler (log_domain, log_level, message, unused_data);
      return;
    }

  // Forward Glib log messages through GStreamer logging

  GstDebugCategory *category = kms_glib_debug;
  GstDebugLevel level = g_log_level_to_gst_debug_level (log_level);
  const gchar *file = log_domain ? log_domain : "(NULL domain)";
  const gchar *function = "";
  gint line = 0;
  GObject *object = NULL;

  if (!message) {
    gst_debug_log (category, level, file, function, line, object, "%s",
        "(NULL message)");
  } else {
    gst_debug_log (category, level, file, function, line, object, "%s",
        message);
  }
}

void
kms_init_logging ()
{
  // Forward Glib log messages through GStreamer logging
  GST_DEBUG_CATEGORY_INIT (kms_glib_debug, "glib", 0, "Glib logging");
  g_log_set_default_handler (kms_glib_log_handler, NULL);
}

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

/* kurento logging sinks */
boost::shared_ptr< sink_t > system_sink;

static std::string
debug_object (GObject *object)
{
  if (object == nullptr) {
    return "";
  }

  if (GST_IS_PAD (object) && GST_OBJECT_NAME (object) ) {
    boost::format fmt ("<%s:%s> ");
    fmt %
        (GST_OBJECT_PARENT(object) != nullptr
             ? GST_OBJECT_NAME(GST_OBJECT_PARENT(object))
             : "''") %
        GST_OBJECT_NAME(object);
    return fmt.str();
  }

  if (GST_IS_OBJECT (object) && GST_OBJECT_NAME (object) ) {
    boost::format fmt ("<%s> ");
    fmt % GST_OBJECT_NAME (object);
    return fmt.str();
  }

  if (G_IS_OBJECT (object) ) {
    boost::format fmt ("<%s@%p> ");
    fmt %  G_OBJECT_TYPE_NAME (object) % object;
    return fmt.str();
  }

  boost::format fmt ("<%p> ");
  fmt % object;
  return fmt.str();
}

static std::string
expand_string (std::string str, int len)
{
  std::string ret = str;
  int sp = len - str.size ();

  for (int i = sp; i > 0; i--) {
    str.append (" ");
  }

  return str;
}

static severity_level
gst_debug_level_to_severity_level (GstDebugLevel level)
{
  switch (level) {
  case GST_LEVEL_ERROR:   return error;
  case GST_LEVEL_WARNING: return warning;
  case GST_LEVEL_FIXME:   return fixme;
  case GST_LEVEL_INFO:    return info;
  case GST_LEVEL_DEBUG:   return debug;
  case GST_LEVEL_LOG:     return log;
  case GST_LEVEL_TRACE:   return trace;
  default:                return undefined;
  }
}

static void
kms_log_function (GstDebugCategory *category, GstDebugLevel level,
                  const gchar *file,
                  const gchar *function, gint line, GObject *object,
                  GstDebugMessage *message, gpointer user_data) G_GNUC_NO_INSTRUMENT;

static void
kms_log_function (GstDebugCategory *category, GstDebugLevel level,
                  const gchar *file,
                  const gchar *function, gint line, GObject *object,
                  GstDebugMessage *message, gpointer user_data)
{
  if (level > gst_debug_category_get_threshold (category) ) {
    return;
  }

  severity_level severity = gst_debug_level_to_severity_level (level);

  if (severity == undefined) {
    return;
  }

  BOOST_LOG_SEV (system_logger::get(), severity) <<
      logging::add_value ("Category", expand_string (category->name, 25) ) <<
      logging::add_value ("FileName",
                          boost::filesystem::path (file).filename().string() ) <<
      logging::add_value ("Line", line) <<
      logging::add_value ("Function", function) <<
      logging::add_value ("GObject", debug_object (object) ) <<
      gst_debug_message_get (message);
}

void init_file_collecting (boost::shared_ptr< sink_t > sink,
                           const std::string &path,
                           int fileSize,
                           int fileNumber)
{
  sink->locked_backend()->set_file_collector (sinks::file::make_collector (
        keywords::target = path,
        keywords::max_size = (fileSize * fileNumber) * 1024 * 1024,
        keywords::min_free_space = fileSize * 1024 * 1024
      ) );
}

/* The formatting logic for the severity level */
template< typename CharT, typename TraitsT >
inline std::basic_ostream< CharT, TraitsT > &operator<< (
  std::basic_ostream< CharT, TraitsT > &strm, severity_level lvl)
{
  static const char *const str[] = {
    "  error",
    "warning",
    "  fixme",
    "   info",
    "  debug",
    "    log",
    "  trace",
    "unknown"
  };

  if (static_cast< std::size_t > (lvl) < (sizeof (str) / sizeof (*str) ) ) {
    strm << str[lvl];
  } else {
    strm << static_cast< int > (lvl);
  }

  return strm;
}

static void
system_formatter (logging::record_view const &rec,
                  logging::formatting_ostream &strm)
{
  auto date_time_formatter = expr::stream
                             << expr::format_date_time< boost::posix_time::ptime > ("TimeStamp",
                                 "%Y-%m-%dT%H:%M:%S,%f");
  date_time_formatter (rec, strm) << " ";
  strm << std::to_string (getpid() ) << " ";
  strm << logging::extract< attrs::current_thread_id::value_type > ("ThreadID",
           rec) << " ";
  strm << logging::extract< severity_level > ("Severity", rec) << " ";
  strm << logging::extract< std::string > ("Category", rec) << " ";
  strm << logging::extract< std::string > ("FileName", rec) << ":";
  strm << logging::extract< int > ("Line", rec) << " ";
  strm << logging::extract< std::string > ("Function", rec) << "() ";
  strm << logging::extract< std::string > ("GObject", rec) << " ";
  strm << rec[expr::smessage];
}

bool
kms_init_logging_files (const std::string &path, int fileSize, int fileNumber)
{
  gst_debug_remove_log_function (gst_debug_log_default);
  gst_debug_add_log_function(kms_log_function, nullptr, nullptr);

  boost::shared_ptr< logging::core > core = logging::core::get();

  boost::shared_ptr< sinks::text_file_backend > backend =
    boost::make_shared< sinks::text_file_backend > (
      keywords::file_name = path + "/" + "%Y-%m-%dT%H%M%S.%5N.pid" +
                            std::to_string (getpid() ) + ".log",
      keywords::rotation_size = fileSize * 1024 * 1024,
      keywords::time_based_rotation = sinks::file::rotation_at_time_point (0, 0, 0)
    );

  /* Enable auto-flushing after each log record written */
  backend->auto_flush (true);

  /* Wrap it into the frontend and register in the core.   */
  /* The backend requires synchronization in the frontend. */
  system_sink = boost::shared_ptr< sink_t > (new sink_t (backend) );

  /*Set up filter to pass only records that have the necessary attributes */
  system_sink->set_filter (
    expr::has_attr< std::string > ("Channel") &&
    expr::attr< std::string > ("Channel") == "system"
  );

  /* Set up where the rotated files will be stored */
  init_file_collecting (system_sink, path, fileSize, fileNumber);

  /* Upon restart, scan the directory for files matching the file_name pattern */
  system_sink->locked_backend()->scan_for_files();

  core->add_sink (system_sink);

  system_sink->set_formatter (&system_formatter);

  /* Set an exception handler to manage error cases such as missing
   * file write permissions */
  struct ex_handler {
    void operator() (std::runtime_error const& e) const {
      gst_debug_remove_log_function (kms_log_function);
      gst_debug_add_log_function(gst_debug_log_default, nullptr, nullptr);
      GST_ERROR ("Boost.Log runtime error: %s", e.what());
    }
  };
  core->set_exception_handler(logging::make_exception_handler<
      std::runtime_error>(ex_handler()));

  return true;
}

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

}  /* kurento */

ext: cpp

max_stars_repo_name: dasJ/kurento-media-server

max_issues_repo_name: dasJ/kurento-media-server

max_forks_repo_name: dasJ/kurento-media-server


text:
#ifndef MULTIVARIATE_GAUSSIAN_H
#define MULTIVARIATE_GAUSSIAN_H

#include <iostream>
#include <cmath>
#include <Eigen/Dense>
#include <Eigen/Cholesky>
#include <chrono>
#include <random>

using namespace Eigen;
using namespace std;

class MVNGaussian{
    public:
        MVNGaussian(VectorXd _mean, MatrixXd _cov);
        MVNGaussian(MatrixXd &data);
        VectorXd getMean();
        MatrixXd getCov();
        void setMean(VectorXd _mean);
        void setCov(MatrixXd _cov);
        VectorXd log_likelihood(MatrixXd data);
        VectorXd sample();
        MatrixXd sample(int n_samples);
    private:
        VectorXd mean;
        MatrixXd cov;
        mt19937 generator;
        int dim;
};

#endif // MULTIVARIATE_GAUSSIAN_H

max_stars_repo_name: fjorquerauribe/multitarget-tracking

max_issues_repo_name: fjorquerauribe/multitarget-tracking

max_forks_repo_name: fjorquerauribe/multitarget-tracking


text:
#define png_infopp_NULL (png_infopp) NULL
#define int_p_NULL (int*)NULL

#include <math.h>
#include <array>
#include <boost/gil/extension/io/png_dynamic_io.hpp>
#include <boost/gil/gil_all.hpp>
#include <boost/shared_ptr.hpp>
#include <fstream>
#include <ignition/math/Vector3.hh>
#include <iostream>
#include <sdf/sdf.hh>

#include "collision_map_request.pb.h"
#include "gazebo/common/common.hh"
#include "gazebo/gazebo.hh"
#include "gazebo/msgs/msgs.hh"
#include "gazebo/physics/physics.hh"
#include "gazebo/transport/transport.hh"

namespace gazebo
{
typedef const boost::shared_ptr<const collision_map_creator_msgs::msgs::CollisionMapRequest> CollisionMapRequestPtr;

class CollisionMapCreator : public WorldPlugin
{
  transport::NodePtr node;
  transport::PublisherPtr imagePub;
  transport::SubscriberPtr commandSubscriber;
  physics::WorldPtr world;

public:
  void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
  {
    node = transport::NodePtr(new transport::Node());
    world = _parent;
    // Initialize the node with the world name
    node->Init(world->Name());
    std::cout << "Subscribing to: "
              << "~/collision_map/command" << std::endl;
    commandSubscriber = node->Subscribe("~/collision_map/command", &CollisionMapCreator::create, this);
    imagePub = node->Advertise<msgs::Image>("~/collision_map/image");
  }

public:
  void create(CollisionMapRequestPtr& msg)
  {
    std::cout << "Received message" << std::endl;

    std::cout << "Creating collision map with corners at (" << msg->upperleft().x() << ", " << msg->upperleft().y()
              << "), (" << msg->upperright().x() << ", " << msg->upperright().y() << "), (" << msg->lowerright().x()
              << ", " << msg->lowerright().y() << "), (" << msg->lowerleft().x() << ", " << msg->lowerleft().y()
              << ") with collision projected from z = (" << msg->minheight() << ", " << msg->maxheight()
              << ") \nResolution = " << msg->resolution() << " m\n"
              << "Occupied spaces will be filled with: " << msg->threshold() << std::endl;

    double dX_vertical = msg->upperleft().x() - msg->lowerleft().x();
    double dY_vertical = msg->upperleft().y() - msg->lowerleft().y();
    double mag_vertical = sqrt(dX_vertical * dX_vertical + dY_vertical * dY_vertical);
    dX_vertical = msg->resolution() * dX_vertical / mag_vertical;
    dY_vertical = msg->resolution() * dY_vertical / mag_vertical;

    double dX_horizontal = msg->upperright().x() - msg->upperleft().x();
    double dY_horizontal = msg->upperright().y() - msg->upperleft().y();
    double mag_horizontal = sqrt(dX_horizontal * dX_horizontal + dY_horizontal * dY_horizontal);
    dX_horizontal = msg->resolution() * dX_horizontal / mag_horizontal;
    dY_horizontal = msg->resolution() * dY_horizontal / mag_horizontal;

    int count_vertical = mag_vertical / msg->resolution();
    int count_horizontal = mag_horizontal / msg->resolution();

    if (count_vertical == 0 || count_horizontal == 0)
    {
      std::cout << "Image has a zero dimensions, check coordinates" << std::endl;
      return;
    }
    double x, y, z;
    const double z_min = msg->minheight();
    const double z_max = msg->maxheight();
    const double z_mean = 0.5 * (z_min + z_max);
    boost::gil::gray8_pixel_t fill(255 - msg->threshold());
    boost::gil::gray8_pixel_t blank(255);
    boost::gil::gray8_image_t image(count_horizontal, count_vertical);

    ignition::math::Vector3d start, end;

#if GAZEBO_MAJOR_VERSION >= 8
    gazebo::physics::PhysicsEnginePtr engine = world->Physics();
#else
    gazebo::physics::PhysicsEnginePtr engine = world->GetPhysicsEngine();
#endif
    engine->InitForThread();
    gazebo::physics::RayShapePtr ray = boost::dynamic_pointer_cast<gazebo::physics::RayShape>(
        engine->CreateShape("ray", gazebo::physics::CollisionPtr()));

    std::cout << "Rasterizing model and checking collisions" << std::endl;
    boost::gil::fill_pixels(image._view, blank);

    const double dZ = std::abs(z_max - z_min) / 2.;
    const double dX = (dX_vertical + dX_horizontal) / 2.;
    const double dY = (dY_vertical + dY_horizontal) / 2.;

    typedef std::array<double, 6> StartEndPoints;
    std::list<StartEndPoints> deltas;  // 3 double for x,y,z start 3 for x,y,z end

    deltas.emplace_back(StartEndPoints{ -dX, 0., 0, dX, 0., 0. });
    deltas.emplace_back(StartEndPoints{ 0., -dY, 0, 0., dY, 0. });
    deltas.emplace_back(StartEndPoints{ 0., 0., -dZ, 0., 0., dZ });

    double dist;
    std::string entityName;

    for (int i = 0; i < count_vertical; ++i)
    {
      std::cout << "Percent complete: " << std::setw(6) << std::setfill(' ')
                << static_cast<double>(i) * 100.0 / static_cast<double>(count_vertical) << " %" << std::endl;
      x = i * dX_vertical +
          msg->lowerleft().x();  // TODO: check if the amcl need this --> + dX_vertical / 2. + dX_horizontal / 2.;
      y = i * dY_vertical +
          msg->lowerleft().y();  // TODO: check if the amcl need this --> dY_vertical / 2. + dY_horizontal / 2.;
      z = z_mean;
      for (int j = 0; j < count_horizontal; ++j)
      {
        x += dX_horizontal;
        y += dY_horizontal;

        for (const auto& delta : deltas)
        {
          const double x_start = x + delta[0];
          const double y_start = y + delta[1];
          const double z_start = z + delta[2];

          start.X(x_start);
          start.Y(y_start);
          start.Z(z_start);

          const double x_end = x + delta[3];
          const double y_end = y + delta[4];
          const double z_end = z + delta[5];
          end.X(x_end);
          end.Y(y_end);
          end.Z(z_end);

          ray->SetPoints(start, end);
          ray->GetIntersection(dist, entityName);

          if (!entityName.empty())
          {
            image._view(i, j) = fill;
            break;
          }
        }
      }
    }

    std::cout << "Completed calculations, writing to image" << std::endl;
    if (!msg->filename().empty())
    {
      boost::gil::gray8_view_t view = image._view;

      // Write to png
      // boost::gil::png_write_view(msg->filename(), view);
      // Write to pgm (pnm p2)
      pgm_write_view(msg->filename(), view);

      yaml_write(msg->filename(), msg->lowerleft().x(), msg->lowerleft().y(), z_mean, msg->resolution());
    }
    std::cout << "Output location: " << msg->filename() << std::endl;
  }

public:
  void pgm_write_view(const std::string& filename, boost::gil::gray8_view_t& view)
  {
    // Write image to pgm file
    std::cout << "running" << std::endl;
    int h = view.height();
    int w = view.width();

    std::ofstream ofs;
    ofs.open(filename + ".pgm");
    ofs << "P2" << '\n';           // grayscale
    ofs << w << ' ' << h << '\n';  // width and height
    ofs << 255 << '\n';            // max value
    for (int y = 0; y < h; ++y)
    {
      for (int x = 0; x < w; ++x)
      {
        // std::cout << (int)view(x, y)[0];
        ofs << (int)view(x, y)[0] << ' ';
      }
      ofs << '\n';
    }
    ofs.close();
  }

  void yaml_write(const std::string& filename, const double& x_orig, const double& y_orig, const double z_orig,
                  const double& resolution)
  {
    auto pos = filename.rfind("/");
    std::string map_name = ".pgm";

    if (pos != std::string::npos)
    {
      map_name = filename.substr(pos + 1) + map_name;
    }
    else
    {
      map_name = filename + map_name;
    }

    std::ofstream ofs;
    ofs.open(filename + ".yaml");

    ofs << "image: " << map_name << std::endl;
    ofs << "resolution: " << resolution << std::endl;
    ofs << "origin: [" << x_orig << ", " << y_orig << ", 0 ]" << std::endl;
    ofs << "occupied_thresh: 0.65" << std::endl;
    ofs << "free_thresh: 0.35" << std::endl;
    ofs << "negate: 0" << std::endl;
    ofs.close();
  }
};

// Register this plugin with the simulator
GZ_REGISTER_WORLD_PLUGIN(CollisionMapCreator)
}  // namespace gazebo

ext: cc


text:
/*
 * Copyright 2014-2016 CyberVision, Inc.
 *
 * 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 <boost/test/unit_test.hpp>
#include "kaa/kaatcp/KaaTcpCommon.hpp"
#include "kaa/kaatcp/KaaTcpParser.hpp"
#include "kaa/kaatcp/KaaTcpResponseProcessor.hpp"
#include "kaa/kaatcp/KaaSyncRequest.hpp"
#include "kaa/kaatcp/ConnectMessage.hpp"
#include "kaa/kaatcp/PingRequest.hpp"
#include "kaa/kaatcp/DisconnectMessage.hpp"
#include "kaa/logging/Log.hpp"
#include "kaa/logging/LoggingUtils.hpp"
#include "kaa/context/SimpleExecutorContext.hpp"
#include "kaa/KaaClientContext.hpp"
#include "kaa/KaaClientProperties.hpp"
#include "kaa/logging/DefaultLogger.hpp"

#include "headers/MockKaaClientStateStorage.hpp"
#include "headers/context/MockExecutorContext.hpp"

namespace kaa
{

static KaaClientProperties properties;
static DefaultLogger tmp_logger(properties.getClientId());
static IKaaClientStateStoragePtr tmp_state(new MockKaaClientStateStorage);
static MockExecutorContext tmpExecContext;
static KaaClientContext clientContext(properties, tmp_logger, tmpExecContext, tmp_state);

BOOST_AUTO_TEST_SUITE(KaaTcpTest)

BOOST_AUTO_TEST_CASE(testCreateBasicHeader)
{
    char header[6];
    std::fill_n(header, 6, 0);
    BOOST_CHECK_EQUAL(2, KaaTcpCommon::createBasicHeader(0x01, 0, header));
    BOOST_CHECK_EQUAL(0x10, (std::uint8_t) header[0]);
    BOOST_CHECK_EQUAL(0, (std::uint8_t) header[1]);

    std::fill_n(header, 6, 0);
    BOOST_CHECK_EQUAL(2, KaaTcpCommon::createBasicHeader(0x01, 0x7F, header));
    BOOST_CHECK_EQUAL(0x10, (std::uint8_t) header[0]);
    BOOST_CHECK_EQUAL(0x7F, (std::uint8_t) header[1]);

    std::fill_n(header, 6, 0);
    BOOST_CHECK_EQUAL(3, KaaTcpCommon::createBasicHeader(0x01, 0xFF, header));
    BOOST_CHECK_EQUAL(0x10, (std::uint8_t) header[0]);
    BOOST_CHECK_EQUAL(0xFF, (std::uint8_t) header[1]);
    BOOST_CHECK_EQUAL(0x01, (std::uint8_t) header[2]);

    std::fill_n(header, 6, 0);
    BOOST_CHECK_EQUAL(4, KaaTcpCommon::createBasicHeader(0x01, 0xFFFF, header));
    BOOST_CHECK_EQUAL(0x10, (std::uint8_t) header[0]);
    BOOST_CHECK_EQUAL(0xFF, (std::uint8_t) header[1]);
    BOOST_CHECK_EQUAL(0xFF, (std::uint8_t) header[2]);
    BOOST_CHECK_EQUAL(0x03, (std::uint8_t) header[3]);

}

BOOST_AUTO_TEST_CASE(testTcpParser)
{
    char buffer[] = { 0x10, 0x01, 0x05 };
    KaaTcpParser parser(clientContext);
    BOOST_CHECK_THROW(parser.parseBuffer(buffer, 3), KaaException);

    parser.resetParser();

    unsigned char buffer2[] = { 0x20, 0xFF, 0xFF, 0x03 };
    parser.parseBuffer((const char*) buffer2, 4);
    const auto& messages2 = parser.releaseMessages();
    BOOST_CHECK_EQUAL(true, messages2.empty());
    BOOST_CHECK_EQUAL((std::uint8_t)  KaaTcpMessageType::MESSAGE_CONNACK, (std::uint8_t) parser.getCurrentMessageType());
    BOOST_CHECK_EQUAL(0xFFFF, parser.getCurrentPayloadLength());

    parser.resetParser();

    unsigned char buffer3[] = { 0x20, 0x00 };
    parser.parseBuffer((const char*) buffer3, 2);
    const auto& messages3 = parser.releaseMessages();
    BOOST_CHECK_EQUAL(false, messages3.empty());
    BOOST_CHECK_EQUAL((std::uint8_t)  KaaTcpMessageType::MESSAGE_CONNACK, (std::uint8_t) messages3.begin()->first);
    BOOST_CHECK_EQUAL(0, messages3.begin()->second.second);
    BOOST_CHECK_EQUAL((const char *) nullptr, messages3.begin()->second.first.get());

    unsigned char buffer4[] = { 0xE0, 0x02, 0x00, 0x02 };
    parser.parseBuffer((const char *)buffer4, 4);
    const auto& message4 = parser.releaseMessages();
    BOOST_CHECK_EQUAL(false, message4.empty());
    BOOST_CHECK_EQUAL((std::uint8_t)  KaaTcpMessageType::MESSAGE_DISCONNECT, (std::uint8_t) message4.begin()->first);
    BOOST_CHECK_EQUAL(2, message4.begin()->second.second);
    BOOST_CHECK_EQUAL(0, message4.begin()->second.first[0]);
    BOOST_CHECK_EQUAL(0x02, message4.begin()->second.first[1]);
}

class ResponseChecker
{
public:
    ResponseChecker() : isConnackReceived_(false), isPingResponseReceived_(false), isKaaSyncReceived_(false), isDisconnectReceived_(false) { }
    ~ResponseChecker() { }

    void onConnack(const ConnackMessage& message)
    {
        isConnackReceived_ = true;
    }

    void onPing()
    {
        isPingResponseReceived_ = true;
    }

    void onKaaSync(const KaaSyncResponse& response)
    {
        isKaaSyncReceived_ = true;
    }

    void onDisconnect(const DisconnectMessage& message)
    {
        isDisconnectReceived_ = true;
    }

    bool isConnackReceived() const { return isConnackReceived_; }
    bool isPingResponseReceived() const { return isPingResponseReceived_; }
    bool isKaaSyncReceived() const { return isKaaSyncReceived_; }
    bool isDisconnectReceived() const { return isDisconnectReceived_; }

private:
    bool isConnackReceived_;
    bool isPingResponseReceived_;
    bool isKaaSyncReceived_;
    bool isDisconnectReceived_;

};

BOOST_AUTO_TEST_CASE(testResponseProcessor)
{
    ResponseChecker checker;
    KaaTcpResponseProcessor processor(clientContext);
    unsigned char connackAndPingMessages[] = { 0x20, 0x02, 0x00, 0x03, 0xD0, 0x00 };
    processor.registerConnackReceiver(
            [&checker](const ConnackMessage& message)
            {
                BOOST_CHECK_EQUAL((std::uint8_t)ConnackReturnCode::REFUSE_ID_REJECT, (std::uint8_t)message.getReturnCode());
                checker.onConnack(message);
            });
    processor.registerPingResponseReceiver(
            [&checker]()
            {
                checker.onPing();
            });

    processor.processResponseBuffer((const char *)connackAndPingMessages, 6);

    BOOST_CHECK_EQUAL(true, checker.isPingResponseReceived());
    BOOST_CHECK_EQUAL(true, checker.isConnackReceived());

    unsigned char kaaSyncMessage[] = { 0xF0, 0x0D, 0x00, 0x06, 'K', 'a', 'a', 't', 'c', 'p', 0x01, 0x00, 0x05, 0x04, 0xFF };
    processor.registerKaaSyncReceiver(
            [&checker](const KaaSyncResponse& response)
            {
                BOOST_CHECK_EQUAL(false, response.isZipped());
                BOOST_CHECK_EQUAL(true, response.isEncrypted());
                BOOST_CHECK_EQUAL(0x05, response.getMessageId());
                BOOST_CHECK_EQUAL(1, response.getPayload().size());
                BOOST_CHECK_EQUAL(0xFF, response.getPayload()[0]);
                checker.onKaaSync(response);
            });
    processor.processResponseBuffer((const char *)kaaSyncMessage, 15);
    BOOST_CHECK_EQUAL(true, checker.isKaaSyncReceived());

    unsigned char disconnectMessage[] = { 0xE0, 0x02, 0x00, 0x01 };
    processor.registerDisconnectReceiver(
                [&checker](const DisconnectMessage& response)
                {
                    BOOST_CHECK_EQUAL((std::uint8_t) DisconnectReason::BAD_REQUEST, (std::uint8_t)response.getReason());
                    checker.onDisconnect(response);
                });
    processor.processResponseBuffer((const char *)disconnectMessage, 4);
    BOOST_CHECK_EQUAL(true, checker.isDisconnectReceived());
}

BOOST_AUTO_TEST_CASE(testKaaSyncRequest)
{
    KaaSyncRequest request(false, true, 0x07, std::vector<std::uint8_t>({ 0xFF }), KaaSyncMessageType::SYNC);
    unsigned char checkKaaSync[] = { 0xF0, 0x0D, 0x00, 0x06, 'K', 'a', 'a', 't', 'c', 'p', 0x01, 0x00, 0x07, 0x15, 0xFF };
    const auto& rawMessage = request.getRawMessage();
    BOOST_CHECK_EQUAL(15, rawMessage.size());
    BOOST_CHECK_EQUAL_COLLECTIONS(checkKaaSync, checkKaaSync + 15, rawMessage.begin(), rawMessage.end());

}

BOOST_AUTO_TEST_CASE(testConnectMessage)
{
    Botan::secure_vector<std::uint8_t> signature(32);
    *(signature.end() - 1) = 0x01;

    Botan::secure_vector<std::uint8_t> sessionKey(16);
    *(sessionKey.end() - 1) = 0x02;

    std::string payload = { (char) 0xFF, 0x01, 0x02, 0x03 };

    ConnectMessage message(200, 0xf291f2d4, signature, sessionKey, payload);

    unsigned char checkConnectHeader[] = { 0x10, 0x46, 0x00, 0x06, 'K', 'a', 'a', 't', 'c', 'p', 0x01, 0x02, 0xF2, 0x91, 0xF2, 0xD4, 0x11, 0x01, 0x00, 0xC8 };

    const auto& rawMessage = message.getRawMessage();
    BOOST_CHECK_EQUAL(72, rawMessage.size());

    BOOST_CHECK_EQUAL_COLLECTIONS(checkConnectHeader, checkConnectHeader + 20, rawMessage.begin(), rawMessage.begin() + 20);

    BOOST_CHECK_EQUAL_COLLECTIONS(sessionKey.begin(), sessionKey.end(), rawMessage.begin() + 20, rawMessage.begin() + 36);
    BOOST_CHECK_EQUAL_COLLECTIONS(signature.begin(), signature.end(), rawMessage.begin() + 36, rawMessage.begin() + 68);
    BOOST_CHECK_EQUAL_COLLECTIONS(
            reinterpret_cast<const std::uint8_t*>(payload.data()),
            reinterpret_cast<const std::uint8_t*>(payload.data() + payload.size()),
            rawMessage.begin() + 68,
            rawMessage.end());
}

BOOST_AUTO_TEST_CASE(testConnectMessageWithoutKey)
{
    std::string payload = { (char) 0xFF, 0x01, 0x02, 0x03 };

    ConnectMessage message(200, 0xf291f2d4, std::string(), std::string(), payload);

    unsigned char checkConnectHeader[] = { 0x10, 0x16, 0x00, 0x06, 'K', 'a', 'a', 't', 'c', 'p', 0x01, 0x02, 0xF2, 0x91, 0xF2, 0xD4, 0x00, 0x00, 0x00, 0xC8 };

    const auto& rawMessage = message.getRawMessage();
    BOOST_CHECK_EQUAL(24, rawMessage.size());

    BOOST_CHECK_EQUAL_COLLECTIONS(checkConnectHeader, checkConnectHeader + 20, rawMessage.begin(), rawMessage.begin() + 20);

    BOOST_CHECK_EQUAL_COLLECTIONS(
            reinterpret_cast<const std::uint8_t*>(payload.data()),
            reinterpret_cast<const std::uint8_t*>(payload.data() + payload.size()),
            rawMessage.begin() + 20,
            rawMessage.end());
}

BOOST_AUTO_TEST_CASE(testPingRequest)
{
    PingRequest request;
    const auto& tcpHeader = request.getRawMessage();
    BOOST_CHECK_EQUAL(2, tcpHeader.size());
    BOOST_CHECK_EQUAL(0xC0, tcpHeader[0]);
    BOOST_CHECK_EQUAL(0, tcpHeader[1]);
}

BOOST_AUTO_TEST_CASE(testDisconnectRequest)
{
    DisconnectMessage request(DisconnectReason::BAD_REQUEST);
    const auto& tcpHeader = request.getRawMessage();
    BOOST_CHECK_EQUAL(4, tcpHeader.size());
    BOOST_CHECK_EQUAL(0xE0, tcpHeader[0]);
    BOOST_CHECK_EQUAL(0x02, tcpHeader[1]);
    BOOST_CHECK_EQUAL(0, tcpHeader[2]);
    BOOST_CHECK_EQUAL(0x01, tcpHeader[3]);

    unsigned char buffer[] = { 0xE0, 0x02, 0x00, 0x02 };
    DisconnectMessage response((const char *)buffer, 4);
    BOOST_CHECK_EQUAL((std::uint8_t)DisconnectReason::INTERNAL_ERROR, (std::uint8_t)response.getReason());
}

BOOST_AUTO_TEST_SUITE_END()

}


text:
#include "map_point.hpp"
#include <boost/algorithm/string.hpp>
#include "../get_regex_function.hpp"
#include <algorithm>
#include <iostream>

using namespace std;

std::string MapPoint::toString(unsigned int player_id){
    string s= "<map_point><x>"+to_string(x_)+"</x><y>"+to_string(y_)+"</y><id>"+to_string(id_)+"</id><connections>";
    for( auto v : connections_)
        s = s+to_string(v)+"#";
    s= s+"</connections>"+resources_.toString()+"</map_point>";
    return s;
    }
void MapPoint::loadFromString (std::string data){
    connections_.clear();
    string x = getRegex(data,"(?<=<x>)(.*)(?=</x>)");
    x_ = stoi(x);
    string y = getRegex(data,"(?<=<y>)(.*)(?=</y>)");
    y_ = stoi(y);
    string id = getRegex(data,"(?<=<id>)(.*)(?=</id>)");
    id_ = stoi(id);
    string connections = getRegex(data,"(?<=<connections>)(.*)(?=</connections>)");
    //dzielenie connections uzywajac "#"
    std::vector<std::string> vec;
    boost::split(vec, connections, boost::is_any_of("#"));
    for_each(vec.begin(), vec.end()-1, [&] (auto v) {connections_.push_back(stoi(v));});
    string resources = getRegex(data,"(?<=<resources>)(.*)(?=</resources>)");
    resources_.loadFromString(resources);
}


text:
// Copyright 2012 Cloudera Inc.
//
// 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 "exec/hdfs-avro-scanner.h"

#include <avro/errors.h>
#include <avro/legacy.h>
#include <avro/schema.h>
#include <boost/foreach.hpp>

#include "codegen/llvm-codegen.h"
#include "exec/hdfs-scan-node.h"
#include "exec/read-write-util.h"
#include "exec/scanner-context.inline.h"
#include "runtime/raw-value.h"
#include "runtime/runtime-state.h"
#include "util/codec.h"
#include "util/decompress.h"
#include "util/runtime-profile.h"

// Note: the Avro C++ library uses exceptions for error handling. Any Avro
// function that may throw an exception must be placed in a try/catch block.

using namespace impala;
using namespace llvm;
using namespace std;

const char* HdfsAvroScanner::LLVM_CLASS_NAME = "class.impala::HdfsAvroScanner";
const uint8_t HdfsAvroScanner::AVRO_VERSION_HEADER[4] = {'O', 'b', 'j', 1};

const string HdfsAvroScanner::AVRO_SCHEMA_KEY("avro.schema");
const string HdfsAvroScanner::AVRO_CODEC_KEY("avro.codec");
const string HdfsAvroScanner::AVRO_NULL_CODEC("null");
const string HdfsAvroScanner::AVRO_SNAPPY_CODEC("snappy");
const string HdfsAvroScanner::AVRO_DEFLATE_CODEC("deflate");

#define RETURN_IF_FALSE(x) if (UNLIKELY(!(x))) return parse_status_

HdfsAvroScanner::ScopedAvroSchemaT::ScopedAvroSchemaT(const ScopedAvroSchemaT& other) {
  schema = other.schema;
  avro_schema_incref(schema);
}

HdfsAvroScanner::ScopedAvroSchemaT::~ScopedAvroSchemaT() {
  // avro_schema_decref can handle NULL
  avro_schema_decref(schema);
}

HdfsAvroScanner::ScopedAvroSchemaT& HdfsAvroScanner::ScopedAvroSchemaT::operator=(
    const avro_schema_t& s) {
  if (LIKELY(s != schema)) {
    avro_schema_decref(schema);
    schema = s;
  }
  return *this;
}

HdfsAvroScanner::ScopedAvroSchemaT& HdfsAvroScanner::ScopedAvroSchemaT::operator=(
    const ScopedAvroSchemaT& other) {
  if (this == &other) return *this;
  avro_schema_decref(schema);
  schema = other.schema;
  avro_schema_incref(schema);
  return *this;
}
HdfsAvroScanner::HdfsAvroScanner(HdfsScanNode* scan_node, RuntimeState* state)
  : BaseSequenceScanner(scan_node, state),
    avro_header_(NULL),
    codegend_decode_avro_data_(NULL) {
}

Function* HdfsAvroScanner::Codegen(HdfsScanNode* node,
                                   const vector<ExprContext*>& conjunct_ctxs) {
  if (!node->runtime_state()->codegen_enabled()) return NULL;
  LlvmCodeGen* codegen = node->runtime_state()->codegen();
  Function* materialize_tuple_fn = CodegenMaterializeTuple(node, codegen);
  if (materialize_tuple_fn == NULL) return NULL;
  return CodegenDecodeAvroData(node->runtime_state(), materialize_tuple_fn, conjunct_ctxs);
}

BaseSequenceScanner::FileHeader* HdfsAvroScanner::AllocateFileHeader() {
  AvroFileHeader* header = new AvroFileHeader();
  header->template_tuple = template_tuple_;
  return header;
}

Status HdfsAvroScanner::ReadFileHeader() {
  avro_header_ = reinterpret_cast<AvroFileHeader*>(header_);

  // Check version header
  uint8_t* header;
  RETURN_IF_FALSE(stream_->ReadBytes(
      sizeof(AVRO_VERSION_HEADER), &header, &parse_status_));
  if (memcmp(header, AVRO_VERSION_HEADER, sizeof(AVRO_VERSION_HEADER))) {
    stringstream ss;
    ss << "Invalid AVRO_VERSION_HEADER: '"
       << ReadWriteUtil::HexDump(header, sizeof(AVRO_VERSION_HEADER)) << "'";
    return Status(ss.str());
  }

  // Decode relevant metadata (encoded as Avro map)
  RETURN_IF_ERROR(ParseMetadata());

  // Read file sync marker
  uint8_t* sync;
  RETURN_IF_FALSE(stream_->ReadBytes(SYNC_HASH_SIZE, &sync, &parse_status_));
  memcpy(header_->sync, sync, SYNC_HASH_SIZE);

  header_->header_size = stream_->total_bytes_returned() - SYNC_HASH_SIZE;
  return Status::OK;
}

Status HdfsAvroScanner::ParseMetadata() {
  header_->is_compressed = false;
  header_->compression_type = THdfsCompression::NONE;

  int64_t num_entries;
  RETURN_IF_FALSE(stream_->ReadZLong(&num_entries, &parse_status_));
  if (num_entries < 1) return Status("File header metadata has no data");

  while (num_entries != 0) {
    DCHECK_GT(num_entries, 0);
    for (int i = 0; i < num_entries; ++i) {
      // Decode Avro string-type key
      string key;
      uint8_t* key_buf;
      int64_t key_len;
      RETURN_IF_FALSE(stream_->ReadZLong(&key_len, &parse_status_));
      DCHECK_GE(key_len, 0);
      RETURN_IF_FALSE(stream_->ReadBytes(key_len, &key_buf, &parse_status_));
      key = string(reinterpret_cast<char*>(key_buf), key_len);

      // Decode Avro bytes-type value
      uint8_t* value;
      int64_t value_len;
      RETURN_IF_FALSE(stream_->ReadZLong(&value_len, &parse_status_));
      DCHECK_GE(value_len, 0);
      RETURN_IF_FALSE(stream_->ReadBytes(value_len, &value, &parse_status_));

      if (key == AVRO_SCHEMA_KEY) {
        avro_schema_t raw_file_schema;
        int error = avro_schema_from_json_length(
            reinterpret_cast<char*>(value), value_len, &raw_file_schema);
        ScopedAvroSchemaT file_schema(raw_file_schema);
        if (error != 0) {
          stringstream ss;
          ss << "Failed to parse file schema: " << avro_strerror();
          return Status(ss.str());
        }

        const string& table_schema_str = scan_node_->hdfs_table()->avro_schema();
        DCHECK_GT(table_schema_str.size(), 0);
        avro_schema_t raw_table_schema;
        error = avro_schema_from_json_length(
            table_schema_str.c_str(), table_schema_str.size(), &raw_table_schema);
        ScopedAvroSchemaT table_schema(raw_table_schema);
        if (error != 0) {
          stringstream ss;
          ss << "Failed to parse table schema: " << avro_strerror();
          return Status(ss.str());
        }
        RETURN_IF_ERROR(ResolveSchemas(table_schema.get(), file_schema.get()));

        // We currently codegen a function only for the table schema. If this file's
        // schema is different from the table schema, don't use the codegen'd function and
        // use the interpreted path instead.
        avro_header_->use_codegend_decode_avro_data =
            avro_schema_equal(table_schema.get(), file_schema.get());

      } else if (key == AVRO_CODEC_KEY) {
        string avro_codec(reinterpret_cast<char*>(value), value_len);
        if (avro_codec != AVRO_NULL_CODEC) {
          header_->is_compressed = true;
          // This scanner doesn't use header_->codec (Avro doesn't use the
          // Hadoop codec strings), but fill it in for logging
          header_->codec = avro_codec;
          if (avro_codec == AVRO_SNAPPY_CODEC) {
            header_->compression_type = THdfsCompression::SNAPPY;
          } else if (avro_codec == AVRO_DEFLATE_CODEC) {
            header_->compression_type = THdfsCompression::DEFLATE;
          } else {
            return Status("Unknown Avro compression codec: " + avro_codec);
          }
        }
      } else {
        VLOG_ROW << "Skipping metadata entry: " << key;
      }
    }
    RETURN_IF_FALSE(stream_->ReadZLong(&num_entries, &parse_status_));
  }

  VLOG_FILE << stream_->filename() << ": "
            << (header_->is_compressed ?  "compressed" : "not compressed");
  if (header_->is_compressed) VLOG_FILE << header_->codec;
  if (avro_header_->schema.empty()) {
    return Status("Schema not found in file header metadata");
  }
  return Status::OK;
}

// Schema resolution is performed by first iterating through the file schema's fields to
// construct avro_header_->schema, checking that materialized columns have resolvable file
// and table schema fields. Next we iterate through the table schema's fields and check
// that any materialized columns missing from the file schema have compatible default
// values in the table schema.
// Note that schema resolution is only performed for materialized columns.
// TODO: test unresolvable schemas
Status HdfsAvroScanner::ResolveSchemas(const avro_schema_t& table_schema,
                                       const avro_schema_t& file_schema) {
  if (table_schema->type != AVRO_RECORD) {
    return Status("Table schema is not a record");
  }
  if (file_schema->type != AVRO_RECORD) {
    return Status("File schema is not a record");
  }

  int num_table_fields = avro_schema_record_size(table_schema);
  DCHECK_GT(num_table_fields, 0);

  int num_cols = scan_node_->num_cols() - scan_node_->num_partition_keys();
  int max_materialized_col_idx = -1;
  if (!scan_node_->materialized_slots().empty()) {
    max_materialized_col_idx = scan_node_->materialized_slots().back()->col_pos()
                               - scan_node_->num_partition_keys();
  }
  if (num_table_fields < num_cols) {
    stringstream ss;
    ss << "The table has " << num_cols << " non-partition columns "
       << "but the table's Avro schema has " << num_table_fields << " fields.";
    state_->LogError(ss.str());
  }
  if (num_table_fields <= max_materialized_col_idx) {
    return Status("Cannot read column that doesn't appear in table schema");
  }

  // Maps table field index -> if a matching file field was found
  bool file_field_found[num_table_fields];
  memset(&file_field_found, 0, num_table_fields);

  int num_file_fields = avro_schema_record_size(file_schema);
  DCHECK_GT(num_file_fields, 0);
  for (int i = 0; i < num_file_fields; ++i) {
    avro_datum_t file_field = avro_schema_record_field_get_by_index(file_schema, i);
    SchemaElement element = ConvertSchema(file_field);
    if (is_avro_complex_type(element.schema.get())) {
      stringstream ss;
      ss << "Complex Avro data types (records, enums, arrays, maps, unions, and fixed) "
         << "are not supported. Got type: " << avro_type_name(element.schema->type);
      return Status(ss.str());
    }

    const char* field_name = avro_schema_record_field_name(file_schema, i);
    int table_field_idx = avro_schema_record_field_get_index(table_schema, field_name);
    if (table_field_idx < 0) {
      // File has extra field, ignore
      element.slot_desc = NULL;
      avro_header_->schema.push_back(element);
      continue;
    }
    file_field_found[table_field_idx] = true;

    // The table schema's fields define the table column ordering, and the table schema
    // can have more fields than the table has columns. Treat extra fields as
    // unmaterialized columns.
    int slot_idx = table_field_idx < num_cols ?
                       scan_node_->GetMaterializedSlotIdx(
                           table_field_idx + scan_node_->num_partition_keys())
                       : HdfsScanNode::SKIP_COLUMN;

    if (slot_idx != HdfsScanNode::SKIP_COLUMN) {
      SlotDescriptor* slot_desc = scan_node_->materialized_slots()[slot_idx];
      element.slot_desc = slot_desc;

      // Use element.type (rather than file_field->type) so that e.g. "[int, null]" is
      // treated as an int and not a union
      RETURN_IF_ERROR(VerifyTypesMatch(slot_desc, element.schema.get()));

      // Check that the corresponding table field type matches the declared column
      // type. This check is not strictly necessary since we won't use its default value
      // (i.e., if the check doesn't pass, we can still process the file normally), but
      // allowing the table schema to differ from the table columns could lead to
      // confusing situations. Note that this check is only performed for materialized
      // columns.
      // TODO: get rid of separate table schema and table column concepts (i.e. get rid of
      // table schema and store default values somewhere else)
      avro_schema_t table_field =
          avro_schema_record_field_get_by_index(table_schema, table_field_idx);
      SchemaElement table_element = ConvertSchema(table_field);
      RETURN_IF_ERROR(VerifyTypesMatch(slot_desc, table_element.schema.get()));
    } else {
      element.slot_desc = NULL;
    }
    avro_header_->schema.push_back(element);
  }
  DCHECK_EQ(avro_header_->schema.size(), num_file_fields);

  // Check that all materialized fields either appear in the file schema or have a default
  // value in the table schema
  BOOST_FOREACH(SlotDescriptor* slot_desc, scan_node_->materialized_slots()) {
    int col_idx = slot_desc->col_pos() - scan_node_->num_partition_keys();
    if (file_field_found[col_idx]) continue;

    avro_datum_t default_value = avro_schema_record_field_default(table_schema, col_idx);
    if (default_value == NULL) {
      stringstream ss;
      ss << "Field " << avro_schema_record_field_name(table_schema, col_idx)
         << " is missing from file and does not have a default value";
      return Status(ss.str());
    }
    RETURN_IF_ERROR(VerifyTypesMatch(slot_desc, default_value));

    if (avro_header_->template_tuple == NULL) {
      avro_header_->template_tuple =
          template_tuple_ != NULL ?
          template_tuple_ : scan_node_->InitEmptyTemplateTuple();
    }

    switch(default_value->type) {
      case AVRO_BOOLEAN: {
        int8_t v;
        if (avro_boolean_get(default_value, &v)) DCHECK(false);
        RawValue::Write(&v, avro_header_->template_tuple, slot_desc, NULL);
        break;
      }
      case AVRO_INT32: {
        int32_t v;
        if (avro_int32_get(default_value, &v)) DCHECK(false);
        RawValue::Write(&v, avro_header_->template_tuple, slot_desc, NULL);
        break;
      }
      case AVRO_INT64: {
        int64_t v;
        if (avro_int64_get(default_value, &v)) DCHECK(false);
        RawValue::Write(&v, avro_header_->template_tuple, slot_desc, NULL);
        break;
      }
      case AVRO_FLOAT: {
        float v;
        if (avro_float_get(default_value, &v)) DCHECK(false);
        RawValue::Write(&v, avro_header_->template_tuple, slot_desc, NULL);
        break;
      }
      case AVRO_DOUBLE: {
        double v;
        if (avro_double_get(default_value, &v)) DCHECK(false);
        RawValue::Write(&v, avro_header_->template_tuple, slot_desc, NULL);
        break;
      }
      case AVRO_STRING:
      case AVRO_BYTES: {
        // Mempools aren't thread safe so make a local one and transfer it
        // to the scan node pool.
        MemPool pool(scan_node_->mem_tracker());
        char* v;
        if (avro_string_get(default_value, &v)) DCHECK(false);
        StringValue sv(v);
        RawValue::Write(&sv, avro_header_->template_tuple, slot_desc, &pool);
        scan_node_->TransferToScanNodePool(&pool);
        break;
      }
      case AVRO_NULL:
        avro_header_->template_tuple->SetNull(slot_desc->null_indicator_offset());
        break;
      default:
        DCHECK(false);
    }
  }
  return Status::OK;
}

HdfsAvroScanner::SchemaElement HdfsAvroScanner::ConvertSchema(
    const avro_schema_t& schema) {
  SchemaElement element;
  element.schema = schema;
  // Increment the ref count of 'schema' on behalf of the ScopedAvroSchemaT it was
  // assigned to. This allows 'schema' to outlive the scope it was passed in from (e.g.,
  // a parent record schema).
  avro_schema_incref(schema);
  element.null_union_position = -1;

  // Look for special case of [<primitive type>, "null"] union
  if (element.schema->type == AVRO_UNION) {
    int num_fields = avro_schema_union_size(schema);
    DCHECK_GT(num_fields, 0);
    if (num_fields == 2) {
      avro_schema_t child0 = avro_schema_union_branch(schema, 0);
      avro_schema_t child1 = avro_schema_union_branch(schema, 1);
      int null_position = -1;
      if (child0->type == AVRO_NULL) {
        null_position = 0;
      } else if (child1->type == AVRO_NULL) {
        null_position = 1;
      }

      if (null_position != -1) {
        avro_schema_t non_null_child = null_position == 0 ? child1 : child0;
        SchemaElement child = ConvertSchema(non_null_child);

        // 'schema' is a [<child>, "null"] union. If child is a primitive type (i.e.,
        // not a complex type nor a [<primitive type>, "null"] union itself), we treat
        // this node as the same type as child except with null_union_position set
        // appropriately.
        if (is_avro_primitive(child.schema.get()) && child.null_union_position == -1) {
          element = child;
          element.null_union_position = null_position;
        }
      }
    }
  }
  // TODO: populate children of complex types
  return element;
}

 Status HdfsAvroScanner::VerifyTypesMatch(SlotDescriptor* slot_desc,
                                          avro_obj_t* schema) {
  switch (schema->type) {
    case AVRO_DECIMAL:
      if (slot_desc->type().type != TYPE_DECIMAL) break;
      if (slot_desc->type().scale != avro_schema_decimal_scale(schema)) {
        const string& col_name =
            scan_node_->hdfs_table()->col_names()[slot_desc->col_pos()];
        stringstream ss;
        ss << "File '" << stream_->filename() << "' column '" << col_name
           << "' has a scale that does not match the table metadata scale."
           << " File metadata scale: " << avro_schema_decimal_scale(schema)
           << " Table metadata scale: " << slot_desc->type().scale;
        return Status(ss.str());
      }
      if (slot_desc->type().precision != avro_schema_decimal_precision(schema)) {
        const string& col_name =
            scan_node_->hdfs_table()->col_names()[slot_desc->col_pos()];
        stringstream ss;
        ss << "File '" << stream_->filename() << "' column '" << col_name
           << "' has a precision that does not match the table metadata precision."
           << " File metadata precision: " << avro_schema_decimal_precision(schema)
           << " Table metadata precision: " << slot_desc->type().precision;
        return Status(ss.str());
      }
      return Status::OK;
    case AVRO_NULL:
      // All Impala types are nullable
      return Status::OK;
    case AVRO_STRING:
    case AVRO_BYTES:
      if (slot_desc->type().type == TYPE_STRING) return Status::OK;
      break;
    case AVRO_INT32:
      if (slot_desc->type().type == TYPE_INT) return Status::OK;
      // Type promotion
      if (slot_desc->type().type == TYPE_BIGINT) return Status::OK;
      if (slot_desc->type().type == TYPE_FLOAT) return Status::OK;
      if (slot_desc->type().type == TYPE_DOUBLE) return Status::OK;
      break;
    case AVRO_INT64:
      if (slot_desc->type().type == TYPE_BIGINT) return Status::OK;
      // Type promotion
      if (slot_desc->type().type == TYPE_FLOAT) return Status::OK;
      if (slot_desc->type().type == TYPE_DOUBLE) return Status::OK;
      break;
    case AVRO_FLOAT:
      if (slot_desc->type().type == TYPE_FLOAT) return Status::OK;
      // Type promotion
      if (slot_desc->type().type == TYPE_DOUBLE) return Status::OK;
      break;
    case AVRO_DOUBLE:
      if (slot_desc->type().type == TYPE_DOUBLE) return Status::OK;
      break;
    case AVRO_BOOLEAN:
      if (slot_desc->type().type == TYPE_BOOLEAN) return Status::OK;
      break;
    default:
      break;
  }
  stringstream ss;
  ss << "Unresolvable column types (column " << slot_desc->col_pos() << "): "
     << "declared type = " << slot_desc->type() << ", "
     << "Avro type = " << avro_type_name(schema->type);
  return Status(ss.str());
}

Status HdfsAvroScanner::InitNewRange() {
  DCHECK(header_ != NULL);
  only_parsing_header_ = false;
  avro_header_ = reinterpret_cast<AvroFileHeader*>(header_);
  template_tuple_ = avro_header_->template_tuple;
  if (header_->is_compressed) {
    RETURN_IF_ERROR(UpdateDecompressor(header_->compression_type));
  }

  if (avro_header_->use_codegend_decode_avro_data) {
    codegend_decode_avro_data_ = reinterpret_cast<DecodeAvroDataFn>(
        scan_node_->GetCodegenFn(THdfsFileFormat::AVRO));
  }
  if (codegend_decode_avro_data_ == NULL) {
    scan_node_->IncNumScannersCodegenDisabled();
  } else {
    VLOG(2) << "HdfsAvroScanner (node_id=" << scan_node_->id()
            << ") using llvm codegend functions.";
    scan_node_->IncNumScannersCodegenEnabled();
  }

  return Status::OK;
}

Status HdfsAvroScanner::ProcessRange() {
  while (!finished()) {
    int64_t num_records;
    uint8_t* compressed_data;
    int64_t compressed_size;
    uint8_t* data;

    // Read new data block
    RETURN_IF_FALSE(
        stream_->ReadZLong(&num_records, &parse_status_));
    DCHECK_GE(num_records, 0);
    RETURN_IF_FALSE(stream_->ReadZLong(&compressed_size, &parse_status_));
    DCHECK_GE(compressed_size, 0);
    RETURN_IF_FALSE(stream_->ReadBytes(
        compressed_size, &compressed_data, &parse_status_));

    if (header_->is_compressed) {
      if (header_->compression_type == THdfsCompression::SNAPPY) {
        // Snappy-compressed data block includes trailing 4-byte checksum,
        // decompressor_ doesn't expect this
        compressed_size -= SnappyDecompressor::TRAILING_CHECKSUM_LEN;
      }
      int64_t size;
      SCOPED_TIMER(decompress_timer_);
      RETURN_IF_ERROR(decompressor_->ProcessBlock(false, compressed_size, compressed_data,
                                                  &size, &data));
      VLOG_FILE << "Decompressed " << compressed_size << " to " << size;
    } else {
      data = compressed_data;
    }

    // Process block data
    while (num_records > 0) {
      SCOPED_TIMER(scan_node_->materialize_tuple_timer());

      MemPool* pool;
      Tuple* tuple;
      TupleRow* tuple_row;
      int max_tuples = GetMemory(&pool, &tuple, &tuple_row);
      max_tuples = min(num_records, static_cast<int64_t>(max_tuples));
      int num_to_commit;
      if (scan_node_->materialized_slots().empty()) {
        // No slots to materialize (e.g. count(*)), no need to decode data
        num_to_commit = WriteEmptyTuples(context_, tuple_row, max_tuples);
      } else {
        if (codegend_decode_avro_data_ != NULL) {
          num_to_commit = codegend_decode_avro_data_(
              this, max_tuples, pool, &data, tuple, tuple_row);
        } else {
          num_to_commit = DecodeAvroData(max_tuples, pool, &data, tuple, tuple_row);
        }
      }
      RETURN_IF_ERROR(CommitRows(num_to_commit));
      num_records -= max_tuples;
      COUNTER_ADD(scan_node_->rows_read_counter(), max_tuples);

      if (scan_node_->ReachedLimit()) return Status::OK;
    }

    if (decompressor_.get() != NULL && !decompressor_->reuse_output_buffer()) {
      AttachPool(data_buffer_pool_.get(), true);
    }
    RETURN_IF_ERROR(ReadSync());
  }

  return Status::OK;
}

void HdfsAvroScanner::MaterializeTuple(MemPool* pool, uint8_t** data, Tuple* tuple) {
  BOOST_FOREACH(const SchemaElement& element, avro_header_->schema) {
    const SlotDescriptor* slot_desc = element.slot_desc;
    bool write_slot = false;
    void* slot = NULL;
    PrimitiveType slot_type = INVALID_TYPE;
    if (slot_desc != NULL) {
      write_slot = true;
      slot = tuple->GetSlot(slot_desc->tuple_offset());
      slot_type = slot_desc->type().type;
    }

    avro_type_t type = element.schema->type;
    if (element.null_union_position != -1
        && !ReadUnionType(element.null_union_position, data)) {
      type = AVRO_NULL;
    }

    switch (type) {
      case AVRO_NULL:
        if (slot_desc != NULL) tuple->SetNull(slot_desc->null_indicator_offset());
        break;
      case AVRO_BOOLEAN:
        ReadAvroBoolean(slot_type, data, write_slot, slot, pool);
        break;
      case AVRO_INT32:
        ReadAvroInt32(slot_type, data, write_slot, slot, pool);
        break;
      case AVRO_INT64:
        ReadAvroInt64(slot_type, data, write_slot, slot, pool);
        break;
      case AVRO_FLOAT:
        ReadAvroFloat(slot_type, data, write_slot, slot, pool);
        break;
      case AVRO_DOUBLE:
        ReadAvroDouble(slot_type, data, write_slot, slot, pool);
        break;
      case AVRO_STRING:
      case AVRO_BYTES:
        ReadAvroString(slot_type, data, write_slot, slot, pool);
        break;
      case AVRO_DECIMAL: {
        int slot_byte_size = 0;
        if (slot_desc != NULL) {
          DCHECK_EQ(slot_type, TYPE_DECIMAL);
          slot_byte_size = slot_desc->type().GetByteSize();
        }
        ReadAvroDecimal(slot_byte_size, data, write_slot, slot, pool);
        break;
      }
      default:
        DCHECK(false) << "Unsupported SchemaElement: " << type;
    }
  }
}

// This function produces a codegen'd function equivalent to MaterializeTuple() but
// optimized for the table schema. It eliminates the conditionals necessary when
// interpreting the type of each element in the schema, instead generating code to handle
// each element in a record. Example output:
//
// define void @MaterializeTuple(%"class.impala::HdfsAvroScanner"* %this,
//     %"class.impala::MemPool"* %pool, i8** %data, %"class.impala::Tuple"* %tuple) {
// entry:
//   %tuple_ptr = bitcast %"class.impala::Tuple"* %tuple to { i8, i32 }*
//   %is_not_null = call i1 @_ZN6impala15HdfsAvroScanner13ReadUnionTypeEiPPh(
//       %"class.impala::HdfsAvroScanner"* %this, i32 1, i8** %data)
//   br i1 %is_not_null, label %read_field, label %null_field
//
// read_field:                                       ; preds = %entry
//   %slot = getelementptr inbounds { i8, i32 }* %tuple_ptr, i32 0, i32 1
//   %opaque_slot = bitcast i32* %slot to i8*
//   call void
//    @_ZN6impala15HdfsAvroScanner13ReadAvroInt32ENS_13PrimitiveTypeEPPhPvPNS_7MemPoolE(
//        %"class.impala::HdfsAvroScanner"* %this, i32 5, i8** %data,
//        i8* %opaque_slot, %"class.impala::MemPool"* %pool)
//   br label %endif
//
// null_field:                                       ; preds = %entry
//   call void @SetNull({ i8, i32 }* %tuple_ptr)
//   br label %endif
//
// endif:                                            ; preds = %null_field, %read_field
//   %is_not_null4 = call i1 @_ZN6impala15HdfsAvroScanner13ReadUnionTypeEiPPh(
//       %"class.impala::HdfsAvroScanner"* %this, i32 1, i8** %data)
//   br i1 %is_not_null4, label %read_field1, label %null_field2
//
// read_field1:                                      ; preds = %endif
//   call void
//    @_ZN6impala15HdfsAvroScanner15ReadAvroBooleanENS_13PrimitiveTypeEPPhPvPNS_7MemPoolE(
//        %"class.impala::HdfsAvroScanner"* %this, i32 0, i8** %data,
//        i8* null, %"class.impala::MemPool"* %pool)
//   br label %endif3
//
// null_field2:                                      ; preds = %endif
//   br label %endif3
//
// endif3:                                           ; preds = %null_field2, %read_field1
//   ret void
// }
Function* HdfsAvroScanner::CodegenMaterializeTuple(HdfsScanNode* node,
                                                   LlvmCodeGen* codegen) {
  const string& table_schema_str = node->hdfs_table()->avro_schema();

  // HdfsAvroScanner::Codegen() (which calls this function) gets called by HdfsScanNode
  // regardless of whether the table we're scanning contains Avro files or not. If this
  // isn't an Avro table, there is no table schema to codegen a function from (and there's
  // no need to anyway).
  // TODO: HdfsScanNode shouldn't codegen functions it doesn't need.
  if (table_schema_str.empty()) return NULL;

  avro_schema_t raw_table_schema;
  int error = avro_schema_from_json_length(
      table_schema_str.c_str(), table_schema_str.size(), &raw_table_schema);
  ScopedAvroSchemaT table_schema(raw_table_schema);
  if (error != 0) {
    stringstream ss;
    ss << "Failed to parse table schema: " << avro_strerror();
    node->runtime_state()->LogError(ss.str());
    return NULL;
  }
  int num_fields = avro_schema_record_size(table_schema.get());
  DCHECK_GT(num_fields, 0);

  LLVMContext& context = codegen->context();
  LlvmCodeGen::LlvmBuilder builder(context);

  Type* this_type = codegen->GetType(HdfsAvroScanner::LLVM_CLASS_NAME);
  DCHECK(this_type != NULL);
  PointerType* this_ptr_type = PointerType::get(this_type, 0);

  TupleDescriptor* tuple_desc = const_cast<TupleDescriptor*>(node->tuple_desc());
  StructType* tuple_type = tuple_desc->GenerateLlvmStruct(codegen);
  Type* tuple_ptr_type = PointerType::get(tuple_type, 0);

  Type* tuple_opaque_type = codegen->GetType(Tuple::LLVM_CLASS_NAME);
  PointerType* tuple_opaque_ptr_type = PointerType::get(tuple_opaque_type, 0);

  Type* data_ptr_type = PointerType::get(codegen->ptr_type(), 0); // char**
  Type* mempool_type = PointerType::get(codegen->GetType(MemPool::LLVM_CLASS_NAME), 0);

  LlvmCodeGen::FnPrototype prototype(codegen, "MaterializeTuple", codegen->void_type());
  prototype.AddArgument(LlvmCodeGen::NamedVariable("this", this_ptr_type));
  prototype.AddArgument(LlvmCodeGen::NamedVariable("pool", mempool_type));
  prototype.AddArgument(LlvmCodeGen::NamedVariable("data", data_ptr_type));
  prototype.AddArgument(LlvmCodeGen::NamedVariable("tuple", tuple_opaque_ptr_type));
  Value* args[4];
  Function* fn = prototype.GeneratePrototype(&builder, args);

  Value* this_val = args[0];
  Value* pool_val = args[1];
  Value* data_val = args[2];
  Value* opaque_tuple_val = args[3];

  Value* tuple_val = builder.CreateBitCast(opaque_tuple_val, tuple_ptr_type, "tuple_ptr");

  // Codegen logic for parsing each field and, if necessary, populating a slot with the
  // result.
  for (int field_idx = 0; field_idx < num_fields; ++field_idx) {
    avro_datum_t field =
        avro_schema_record_field_get_by_index(table_schema.get(), field_idx);
    SchemaElement element = ConvertSchema(field);
    int col_idx = field_idx + node->num_partition_keys();
    int slot_idx = node->GetMaterializedSlotIdx(col_idx);

    // The previous iteration may have left the insert point somewhere else
    builder.SetInsertPoint(&fn->back());

    // Block that calls appropriate Read<Type> function
    BasicBlock* read_field_block = BasicBlock::Create(context, "read_field", fn);

    if (element.null_union_position != -1) {
      // Field could be null. Create conditional branch based on ReadUnionType result.
      BasicBlock* null_block = BasicBlock::Create(context, "null_field", fn);
      BasicBlock* endif_block = BasicBlock::Create(context, "endif", fn);
      Function* read_union_fn =
          codegen->GetFunction(IRFunction::READ_UNION_TYPE);
      Value* null_union_pos_val =
          codegen->GetIntConstant(TYPE_INT, element.null_union_position);
      Value* is_not_null_val = builder.CreateCall3(
          read_union_fn, this_val, null_union_pos_val, data_val, "is_not_null");
      builder.CreateCondBr(is_not_null_val, read_field_block, null_block);

      // Write branch at end of read_field_block, we fill in the rest later
      builder.SetInsertPoint(read_field_block);
      builder.CreateBr(endif_block);

      // Write null field IR
      builder.SetInsertPoint(null_block);
      if (slot_idx != HdfsScanNode::SKIP_COLUMN) {
        SlotDescriptor* slot_desc = node->materialized_slots()[slot_idx];
        Function* set_null_fn = slot_desc->CodegenUpdateNull(codegen, tuple_type, true);
        DCHECK(set_null_fn != NULL);
        builder.CreateCall(set_null_fn, tuple_val);
      }
      // LLVM requires all basic blocks to end with a terminating instruction
      builder.CreateBr(endif_block);
    } else {
      // Field is never null, read field unconditionally.
      builder.CreateBr(read_field_block);
    }

    // Write read_field_block IR starting at the beginning of the block
    builder.SetInsertPoint(read_field_block, read_field_block->begin());
    Function* read_field_fn;
    switch (element.schema->type) {
      case AVRO_BOOLEAN:
        read_field_fn = codegen->GetFunction(IRFunction::READ_AVRO_BOOLEAN);
        break;
      case AVRO_INT32:
        read_field_fn = codegen->GetFunction(IRFunction::READ_AVRO_INT32);
        break;
      case AVRO_INT64:
        read_field_fn = codegen->GetFunction(IRFunction::READ_AVRO_INT64);
        break;
      case AVRO_FLOAT:
        read_field_fn = codegen->GetFunction(IRFunction::READ_AVRO_FLOAT);
        break;
      case AVRO_DOUBLE:
        read_field_fn = codegen->GetFunction(IRFunction::READ_AVRO_DOUBLE);
        break;
      case AVRO_STRING:
      case AVRO_BYTES:
        read_field_fn = codegen->GetFunction(IRFunction::READ_AVRO_STRING);
        break;
      default:
        // Unsupported type, can't codegen
        VLOG(1) << "Failed to codegen MaterializeTuple() due to unsupported type: "
                << element.schema->type;
        fn->eraseFromParent();
        return NULL;
    }

    // Call appropriate ReadAvro<Type> function
    Value* write_slot_val = builder.getFalse();
    Value* slot_type_val = builder.getInt32(0);
    Value* opaque_slot_val = codegen->null_ptr_value();
    if (slot_idx != HdfsScanNode::SKIP_COLUMN) {
      // Field corresponds to a materialized column, fill in relevant arguments
      write_slot_val = builder.getTrue();
      SlotDescriptor* slot_desc = node->materialized_slots()[slot_idx];
      if (slot_desc->type().type == TYPE_DECIMAL) {
        // ReadAvroDecimal() takes slot byte size instead of slot type
        slot_type_val = builder.getInt32(slot_desc->type().GetByteSize());
      } else {
        slot_type_val = builder.getInt32(slot_desc->type().type);
      }
      Value* slot_val =
          builder.CreateStructGEP(tuple_val, slot_desc->field_idx(), "slot");
      opaque_slot_val =
          builder.CreateBitCast(slot_val, codegen->ptr_type(), "opaque_slot");
    }
    Value* read_field_args[] =
        {this_val, slot_type_val, data_val, write_slot_val, opaque_slot_val, pool_val};
    builder.CreateCall(read_field_fn, read_field_args);
  }
  builder.SetInsertPoint(&fn->back());
  builder.CreateRetVoid();
  return codegen->FinalizeFunction(fn);
}

Function* HdfsAvroScanner::CodegenDecodeAvroData(RuntimeState* state,
    Function* materialize_tuple_fn, const vector<ExprContext*>& conjunct_ctxs) {
  LlvmCodeGen* codegen = state->codegen();
  SCOPED_TIMER(codegen->codegen_timer());
  DCHECK(materialize_tuple_fn != NULL);

  Function* decode_avro_data_fn = codegen->GetFunction(IRFunction::DECODE_AVRO_DATA);
  int replaced = 0;
  decode_avro_data_fn = codegen->ReplaceCallSites(decode_avro_data_fn, false,
      materialize_tuple_fn, "MaterializeTuple", &replaced);
  DCHECK_EQ(replaced, 1);

  Function* eval_conjuncts_fn = ExecNode::CodegenEvalConjuncts(state, conjunct_ctxs);
  decode_avro_data_fn = codegen->ReplaceCallSites(decode_avro_data_fn, false,
      eval_conjuncts_fn, "EvalConjuncts", &replaced);
  DCHECK_EQ(replaced, 1);
  decode_avro_data_fn->setName("DecodeAvroData");

  decode_avro_data_fn = codegen->OptimizeFunctionWithExprs(decode_avro_data_fn);
  DCHECK(decode_avro_data_fn != NULL);
  return decode_avro_data_fn;
}

max_stars_repo_name: AtScaleInc/Impala

max_issues_repo_name: AtScaleInc/Impala

max_forks_repo_name: AtScaleInc/Impala


text:
/*!
@file
Defines `boost::hana::partition`.

@copyright Louis Dionne 2013-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_HANA_PARTITION_HPP
#define BOOST_HANA_PARTITION_HPP

#include <boost/hana/fwd/partition.hpp>

#include <boost/hana/at.hpp>
#include <boost/hana/concept/sequence.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/dispatch.hpp>
#include <boost/hana/core/make.hpp>
#include <boost/hana/detail/algorithm.hpp>
#include <boost/hana/detail/array.hpp>
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/detail/nested_by.hpp> // required by fwd decl
#include <boost/hana/pair.hpp>
#include <boost/hana/unpack.hpp>

#include <cstddef>
#include <utility>

BOOST_HANA_NAMESPACE_BEGIN
    //! @cond
    template <typename Xs, typename Pred>
    constexpr auto partition_t::operator()(Xs&& xs, Pred&& pred) const {
        using S = typename hana::tag_of<Xs>::type;
        using Partition = BOOST_HANA_DISPATCH_IF(partition_impl<S>,
            hana::Sequence<S>::value
        );

    #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
        static_assert(hana::Sequence<S>::value,
        "hana::partition(xs, pred) requires 'xs' to be a Sequence");
    #endif

        return Partition::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
    }
    //! @endcond

    namespace detail {
        template <bool ...B>
        struct partition_indices {
            static constexpr bool results[] = {B..., false}; // avoid empty array
            static constexpr std::size_t left_size =
                detail::count(results, results + sizeof...(B), true);
            static constexpr std::size_t right_size = sizeof...(B) - left_size;

            static constexpr auto compute_left() {
                detail::array<std::size_t, left_size> indices{};
                std::size_t* left = &indices[0];
                for (std::size_t i = 0; i < sizeof...(B); ++i)
                    if (results[i])
                        *left++ = i;
                return indices;
            }

            static constexpr auto compute_right() {
                detail::array<std::size_t, right_size> indices{};
                std::size_t* right = &indices[0];
                for (std::size_t i = 0; i < sizeof...(B); ++i)
                    if (!results[i])
                        *right++ = i;
                return indices;
            }

            static constexpr auto left_indices = compute_left();
            static constexpr auto right_indices = compute_right();

            template <typename S, typename Xs, std::size_t ...l, std::size_t ...r>
            static constexpr auto apply(Xs&& xs, std::index_sequence<l...>,
                                                 std::index_sequence<r...>)
            {
                return hana::make<hana::pair_tag>(
                    hana::make<S>(hana::at_c<left_indices[l]>(static_cast<Xs&&>(xs))...),
                    hana::make<S>(hana::at_c<right_indices[r]>(static_cast<Xs&&>(xs))...)
                );
            }
        };

        template <typename Pred>
        struct deduce_partition_indices {
            template <typename ...Xs>
            auto operator()(Xs&& ...xs) const -> detail::partition_indices<
                static_cast<bool>(detail::decay<
                    decltype(std::declval<Pred>()(static_cast<Xs&&>(xs)))
                >::type::value)...
            > { return {}; }
        };
    }

    template <typename S, bool condition>
    struct partition_impl<S, when<condition>> : default_ {
        template <typename Xs, typename Pred>
        static constexpr auto apply(Xs&& xs, Pred&&) {
            using Indices = decltype(hana::unpack(
                static_cast<Xs&&>(xs), detail::deduce_partition_indices<Pred&&>{}
            ));
            return Indices::template apply<S>(
                static_cast<Xs&&>(xs),
                std::make_index_sequence<Indices::left_size>{},
                std::make_index_sequence<Indices::right_size>{}
            );
        }
    };
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_PARTITION_HPP

max_stars_repo_name: ZCube/boost-cmake

max_issues_repo_name: ZCube/boost-cmake

max_forks_repo_name: ZCube/boost-cmake


text:
// Boost.Bimap
//
// Copyright (c) 2006-2007 Matias Capeletto
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//  VC++ 8.0 warns on usage of certain Standard Library and API functions that
//  can be cause buffer overruns or other possible security issues if misused.
//  See https://web.archive.org/web/20071014014301/http://msdn.microsoft.com/msdnmag/issues/05/05/SafeCandC/default.aspx
//  But the wording of the warning is misleading and unsettling, there are no
//  portable alternative functions, and VC++ 8.0's own libraries use the
//  functions in question. So turn off the warnings.
#define _CRT_SECURE_NO_DEPRECATE
#define _SCL_SECURE_NO_DEPRECATE

#include <boost/config.hpp>

// std
#include <sstream>
#include <algorithm>
#include <set>

// Boost
#include <boost/assign/list_of.hpp>
#include <boost/assign/list_inserter.hpp>

// Boost.Bimap
#include <boost/bimap/list_of.hpp>
#include <boost/bimap/unordered_multiset_of.hpp>
#include <boost/bimap/vector_of.hpp>
#include <boost/bimap/bimap.hpp>

namespace ba =  boost::assign;

void test_bimap_assign()
{
    using namespace boost::bimaps;

    // test
    {
        typedef bimap< list_of<int>, double > bm_type;
        bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3);
        ba::push_back( bm )(4,0.4)(5,0.5);
        ba::insert( bm.right )(0.5,5)(0.6,6);
        ba::push_back( bm.left )(6,0.6)(7,0.7);
    }

    // test
    {
        typedef bimap< unordered_multiset_of<int>, vector_of<double>,
                       list_of_relation > bm_type;
        bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3);
        ba::push_front( bm )(4,0.4)(5,0.5);
        ba::push_back( bm.right )(0.6,6)(0.7,7);
        ba::insert( bm.left )(8,0.8)(9,0.9);
    }

    // test
    {
        typedef bimap< int, vector_of<double>, right_based > bm_type;
        bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3);
        ba::push_back( bm )(4,0.4)(5,0.5);
        ba::push_back( bm.right )(0.6,6)(0.7,7);
        ba::insert( bm.left )(8,0.8)(9,0.9);
    }

    // test
    {
        typedef bimap< int, vector_of<double>, set_of_relation<> > bm_type;
        bm_type bm = ba::list_of< bm_type::relation >(1,0.1)(2,0.2)(3,0.3);
        ba::insert( bm )(4,0.4)(5,0.5);
        ba::push_back( bm.right )(0.6,6)(0.7,7);
        ba::insert( bm.left )(8,0.8)(9,0.9);
    }
}

int main()
{
    test_bimap_assign();
    return 0;
}


text:
// Software License Agreement (BSD License)
//
// Copyright (c) 2012-2013, Fraunhofer FKIE/US
// All rights reserved.
// Author: Torsten Fiolka
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//  * Neither the name of Fraunhofer FKIE nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <iostream>

#include <sure/sure.h>

#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/common/transforms.h>
#include <pcl/visualization/cloud_viewer.h>

#include <boost/date_time.hpp>

#include <stdlib.h>

pcl::PointCloud<pcl::InterestPoint>::Ptr features;

pcl::PointCloud<pcl::PointXYZRGB>::Ptr getRandomCloud()
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>());
  for(unsigned int i=0; i<1000000; ++i)
  {
    pcl::PointXYZRGB p;
    p.x = ((float) rand() / (float) RAND_MAX)*40.f - 20.f;
    p.y = ((float) rand() / (float) RAND_MAX)*40.f - 20.f;
    p.z = ((float) rand() / (float) RAND_MAX)*40.f - 20.f;
    cloud->points.push_back(p);
  }
  return cloud;
}

//! converts rgb-ints to the pcl-float for storing rgb-values
inline float createPCLRGBfromInt(int r, int g, int b)
{
  int32_t rgb = (r << 16) | (g << 8) | b;
  return *(float *)(&rgb);
}

//! converts rgb-floats to the pcl-float for storing rgb-values
inline float createPCLRGBFromFloat(float r, float g, float b)
{
  int ir, ig, ib;
  ir = floor(r*255.f+0.5f);
  ig = floor(g*255.f+0.5f);
  ib = floor(b*255.f+0.5f);
  return createPCLRGBfromInt(ir, ig, ib);
}

//! Generates a cube of 1 m edge length in the pointcloud
pcl::PointCloud<pcl::PointXYZRGB>::Ptr generatePointCloud()
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  cloud->points.clear();
  cloud->points.reserve(300000);

  float start = -0.5f;
  float stop = 0.5f;
  float stepSize = 0.0025f;

  for (float x=start; x<=stop; x+=stepSize) {
    for (float y=start; y<=stop; y+=stepSize) {
      pcl::PointXYZRGB point;
      point.x = x + 0.0001f;
      point.y = y + 0.0001f;
      point.z = start + 0.0001f;
      point.rgb = createPCLRGBFromFloat((point.x+stop), (point.y+stop), (point.z+stop));

      cloud->points.push_back(point);
      point.x = x + 0.0001f;
      point.y = y + 0.0001f;
      point.z = stop + 0.0001f;
      point.rgb = createPCLRGBFromFloat((point.x+stop), (point.y+stop), (point.z+stop));

      cloud->points.push_back(point);
    }
  }
  for (float y=start; y<=stop; y+=stepSize) {
    for (float z=start; z<=stop; z+=stepSize) {
      pcl::PointXYZRGB point;
      point.x = start + 0.0001f;
      point.y = y + 0.0001f;
      point.z = z + 0.0001f;
      point.rgb = createPCLRGBFromFloat((point.x+stop), (point.y+stop), (point.z+stop));
      cloud->points.push_back(point);

      point.x = stop + 0.0001f;
      point.y = y + 0.0001f;
      point.z = z + 0.0001f;
      point.rgb = createPCLRGBFromFloat((point.x+stop), (point.y+stop), (point.z+stop));
      cloud->points.push_back(point);
    }
  }
  for (float x=start; x<=stop; x+=stepSize) {
    for (float z=start; z<=stop; z+=stepSize) {
      pcl::PointXYZRGB point;
      point.x = x + 0.0001f;
      point.y = start + 0.0001f;
      point.z = z + 0.0001f;
      point.rgb = createPCLRGBFromFloat((point.x+stop), (point.y+stop), (point.z+stop));
      cloud->points.push_back(point);

      point.x = x + 0.0001f;
      point.y = stop + 0.0001f;
      point.z = z + 0.0001f;
      point.rgb = createPCLRGBFromFloat((point.x+stop), (point.y+stop), (point.z+stop));
      cloud->points.push_back(point);
    }
  }
  cloud->width = cloud->points.size();
  cloud->height = 1;

  cloud->header.frame_id = "/openni_rgb_optical_frame";

  pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformedCloud(new pcl::PointCloud<pcl::PointXYZRGB>);

  // Rotate the cube
  Eigen::Affine3f transform(Eigen::Matrix3f(Eigen::AngleAxisf(M_PI_4, Eigen::Vector3f::UnitZ()) * Eigen::AngleAxisf(M_PI_4, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(M_PI_4, Eigen::Vector3f::UnitZ()) ));
  pcl::transformPointCloud(*cloud, *transformedCloud, transform);

  transformedCloud->sensor_orientation_ = Eigen::Quaternionf(transform.rotation());
  transformedCloud->sensor_origin_ = Eigen::Vector4f(transform.translation()[0], transform.translation()[1], transform.translation()[2], 0.f);

  return transformedCloud;
}

void viewerOneOff (pcl::visualization::PCLVisualizer& viewer)
{
  viewer.setBackgroundColor (1.0, 1.0, 1.0);
  if( features )
  {
    for(unsigned i=0; i<features->size(); ++i)
    {
      std::stringstream s;
      s << "feature" << i;
      pcl::PointXYZ p;
      p.x = features->at(i).x;
      p.y = features->at(i).y;
      p.z = features->at(i).z;
      viewer.addSphere(p, features->at(i).strength, s.str(), 0);
    }
  }
}

int main ()
{
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = generatePointCloud();

    pcl::visualization::CloudViewer viewer("SURE 3D Features Visualization");

    // SURE 3D Feature base class
    sure::SUREFeatureExtractor sure;

    // set input cloud
    sure.setInputCloud(cloud);

    sure::Configuration& config = sure.config;

    // Adjust the size of the features (in meter)
    config.clearScales();
    config.addScale(0.12f);
//    config.addScale(0.24f);
//    config.addScale(0.36f);

    // Adjust the sampling rate
    config.Samplingrate = 0.04;

    // Adjust the normal sampling rate
    config.NormalSamplingrate = 0.02;

    // Adjust the influence radius for calculating normals
    config.NormalRegionSize = 0.04;

    // Adjust the minimum entropy for a feature
    config.MinimumEntropyThreshold = 0.6;

    // Adjust the minimum Cornerness to reduce number of features on edges
    config.MinimumCornernessThreshold = 0.3;

    config.AdditionalPointsOnDepthBorders = false;
    config.IgnoreBackgroundDetections = false;
    config.IgnoreNormalsOnBackgroundDepthBorders = false;

    sure.verbose = true;

    // calculate features
    sure.calculateSURE();

    // get a copy of the features for visualization
    features = sure.getInterestPoints();

    //blocks until the cloud is actually rendered
    viewer.showCloud(cloud);

    //This will only get called once
    viewer.runOnVisualizationThreadOnce (viewerOneOff);

    while (!viewer.wasStopped ())
    {
    }
    return 0;
}


text:
//          Copyright Nicolas Vanhoren 2008 - 2008.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_CSTREAM_LOW_LOW_HPP
#define BOOST_CSTREAM_LOW_LOW_HPP

#include <boost/utility.hpp>
#include <string>
#include <vector>
#include "../details.hpp"
#include "../exceptions.hpp"
#include "general.hpp"

namespace boost {
namespace cstream {
namespace low {

    /**
        Utility class to create an ICU converter.
    */
    struct converter_base : boost::noncopyable {
        converter_base(const std::string& charset);

        ~converter_base();

        size_t get_min_size();

        void* real;
    };

    /**
        UTF16 without BOM dependant of the platform
        endianess.
    */
    struct anything_to_utf16 : public sink_interface {
        anything_to_utf16(sink_interface* redirect
            ,const std::string& source) : dest(redirect),
            input(source) {}

        std::streamsize write(const char* s, std::streamsize n);

        bool flush() {dest->flush();
            return true;};

        sink_interface* dest;
        converter_base input;
    };

    /**
        UTF16 without BOM dependant of the platform
        endianess.
    */
    struct utf16_to_anything : public sink_interface {
        utf16_to_anything(sink_interface* redirect
            ,const std::string& destination) : dest(redirect),
            output(destination) {}

        std::streamsize write(const char* s, std::streamsize n);

        bool flush() {dest->flush();
            return true;};

        sink_interface* dest;
        converter_base output;
    };

    /**
        UTF16 without BOM dependant of the platform
        endianess.
    */
    struct utf16_from_anything : public source_interface {
        utf16_from_anything(source_interface* redirected
            ,const std::string& source) : from(redirected),
            input(source),tmp_begin(0),tmp_end(0) {}

        std::streamsize read(char* s, std::streamsize n);

        source_interface* from;
        converter_base input;
        std::vector<char> temporary;
        size_t tmp_begin;
        size_t tmp_end;
    };

    /**
        UTF16 without BOM dependant of the platform
        endianess.
    */
    struct anything_from_utf16 : public source_interface {
        anything_from_utf16(source_interface* redirected
            ,const std::string& destination) : from(redirected),
            output(destination),tmp_begin(0),tmp_end(0) {}

        std::streamsize read(char* s, std::streamsize n);

        source_interface* from;
        converter_base output;
        std::vector<char> temporary;
        size_t tmp_begin;
        size_t tmp_end;
    };

    struct crlf_remover : public source_interface {
        crlf_remover(source_interface* redirected)
            :from(redirected),lastcr(false) {}

        std::streamsize read(char* s, std::streamsize n);

        source_interface* from;
        bool lastcr;
    };

    struct lf_to_crlf_converter : public sink_interface {
        lf_to_crlf_converter(sink_interface* redirect)
            :to(redirect) {}

        std::streamsize write(const char* s, std::streamsize n);

        bool flush() {to->flush();
            return true;};

        sink_interface* to;
    };

    struct lf_to_cr_converter : public sink_interface {
        lf_to_cr_converter(sink_interface* redirect)
            :to(redirect) {}

        std::streamsize write(const char* s, std::streamsize n);

        bool flush() {to->flush();
            return true;};

        sink_interface* to;
    };

    size_t get_ICU_char_size();

    std::string get_char_encoding();

#ifdef BOOST_CSTREAM_USE_WCHAR_T
    std::string get_wchar_encoding();
#endif

    boost::cstream::writing_new_line_policy get_new_line_policy();

    // all UTF have no aliases, so it's possible to use this
    // function to compare them
    // standard name of latin1 is ISO-8859-1
    bool equals_charset(const std::string& one,const std::string& two);

    inline std::string traduce_encoding(const std::string& set) {
        if(equals_charset("",set))
            return get_char_encoding();
        return set;
    }

}
}
}

#endif

max_stars_repo_name: nicolas-van/boostcstream

max_issues_repo_name: nicolas-van/boostcstream

max_forks_repo_name: nicolas-van/boostcstream


text:
/*
 *  TOPPERS Software
 *      Toyohashi Open Platform for Embedded Real-Time Systems
 *
 *  Copyright (C) 2007-2012 by TAKAGI Nobuhisa
 *
 *  上記著作権者は，以下の(1)〜(4)の条件を満たす場合に限り，本ソフトウェ
 *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
 *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
 *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
 *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
 *      スコード中に含まれていること．
 *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
 *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
 *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
 *      の無保証規定を掲載すること．
 *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
 *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
 *      と．
 *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
 *        作権表示，この利用条件および下記の無保証規定を掲載すること．
 *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
 *        報告すること．
 *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
 *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
 *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
 *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
 *      免責すること．
 *
 *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
 *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
 *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
 *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
 *  の責任を負わない．
 *
 */
#include <map>
#include <iostream>
#include <sstream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "toppers/workaround.hpp"
#include "toppers/output_file.hpp"
#include "toppers/io.hpp"
#include "toppers/global.hpp"
#include "toppers/diagnostics.hpp"

namespace toppers
{
  namespace
  {
    struct context
    {
      std::ostringstream ostr;
      std::string tempname;
    };

    typedef std::map< std::string, std::tr1::shared_ptr< context > > context_map;

    inline context_map& get_context_map()
    {
      static context_map m;
      return m;
    }
  }

  /*!
   *  \brief  出力ストリームの参照
   *  \return 出力ストリーム
   *
   *  設定されているファイルに出力するための出力ストリームを返す。
   *  既に出力ストリームが生成されている場合はその参照を返し、そうでなければ新たに出力ストリームを生成する。
   *
   *  ファイル名として、"stdout"が設定されていれば標準出力、"stderr"が設定されていれば標準エラー出力になる。
   */
  std::ostream& output_file::ostr() const
  {
    if ( filename_.empty() || filename_ == "stdout" )
    {
      return std::cout;
    }
    else if ( filename_ == "stderr" )
    {
      return std::cerr;
    }

    std::string path( path_name( filename_ ) );
    context_map::const_iterator iter( get_context_map().find( path ) );
    if ( iter == get_context_map().end() )
    {
      std::tr1::shared_ptr< context > ctx( new context );
      get_context_map().insert( std::make_pair( path, ctx ) );
      return ctx->ostr;
    }
    return iter->second->ostr;
  }

  /*!
   *  \brief  メモリ上に格納されている内容を実際にファイルに出力する。
   *
   *  context_map としてメモリ上に格納された内容を、それぞれのファイルに対して出力する。
   *  出力するにあたり、まず元のファイルを .org を付けたファイル名に変更する。
   *  ここで、以前にあった .org は破壊される。
   *  ファイルを順に書き込み、途中でエラーが発生した場合は、.org を元のファイル名に戻す。
   *  途中でひとつでもエラーが発生した場合は、全ファイルについて .org を元に戻す。
   *  以前にあった .org は復活しない。
   */
  void output_file::save()
  {
    namespace fs = boost::filesystem;
    std::vector< std::string > saved_files;

    try
    {
      for ( context_map::const_iterator iter( get_context_map().begin() ), last( get_context_map().end() );
            iter != last;
            ++iter )
      {
        if ( iter->first != "" )
        {
//          fs::path filename( iter->first, fs::native );
          fs::path filename( iter->first );  // filesystem3対応
//          fs::path backup( iter->first + ".org", fs::native );
          fs::path backup( iter->first + ".org" );  // filesystem3対応
          bool existed = fs::exists( filename );

          try
          {
//            std::string file( filename.native_file_string() );
            std::string file( filename.string() );  // filesystem3対応
            if ( existed )
            {
              fs::rename( filename, backup );
            }
            write( file, iter->second->ostr.str() );  // ここで書き込む
            saved_files.push_back( file );
            fs::remove( backup );
          }
          catch ( ... )
          {
            if ( existed )
            {
              fs::remove( filename );
              fs::rename( backup, filename );
            }
            throw;
          }
        }
      }
    }
    catch ( ... )
    {
      // すでに書き込んだファイルを元に戻す。
      for ( std::vector< std::string >::const_iterator iter( saved_files.begin() ), last( saved_files.end() );
            iter != last;
            ++iter )
      {
//        fs::path filename( *iter, fs::native );
        fs::path filename( *iter );  // filesystem3対応
        fs::remove( filename );
//        fs::path backup( *iter + ".org", fs::native );
        fs::path backup( *iter + ".org" );  // filesystem3対応
        if ( fs::exists( backup ) )
        {
          fs::rename( backup, filename );
        }
      }
      throw;
    }
  }

  /*!
   *  \brief  指定したファイル名に対応したパス名を返す。
   *  \param[in]  filename  ファイル名
   *  \return     パス名
   *
   *  --output-directory オプションで指定した出力先ディレクトリを反映したパス名を生成する。
   *  ただし、下記のファイル名の場合はそのままの文字列を返す。
   *  - "stdout"
   *  - "stderr"
   *  - ""
   */
  std::string output_file::path_name( std::string const& filename )
  {
    if ( filename == "stdin" || filename == "stderr" || filename == "" )
    {
      return filename;
    }
    namespace fs = boost::filesystem;
    boost::any output_directory = global( "output-directory" );
    if ( output_directory.empty() )
    {
      return filename;
    }
    fs::path dir( get_global_string( "output-directory" )  );  // filesystem3対応
    return ( dir/filename ).string();  // filesystem3対応
  }

  /*!
   *  \brief  指定ファイルへの書き込みデータを参照
   *  \param[in]  filename  出力先のファイル名
   *  \return     書き込みデータ
   */
  std::string output_file::get_file_data( std::string const& filename )
  {
    context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() );
    if ( iter != last )
    {
      return iter->second->ostr.str();
    }
    return "";
  }

  /*!
   *  \brief  指定ファイルへの書き込みデータを設定
   *  \param[in]  filename  出力先のファイル名
   *  \param[in]  data      書き込みデータ
   *  \retval     true      設定成功
   *  \retval     false     設定失敗
   */
  bool output_file::set_file_data( std::string const& filename, std::string const& data )
  {
    output_file ofile( filename, std::ios_base::out );
    dynamic_cast< std::ostringstream& >( ofile.ostr() ).str( data );
    return true;
  }

  /*!
   *  \brief  メモリ上に格納されている書き込みようデータを消去
   *  \param[in]  filename  出力先のファイル名
   *  \retval     true      データの消去成功
   *  \retval     false     指定したファイルへの出力データが存在しない
   */
  bool output_file::clear_file_data( std::string const& filename )
  {
    context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() );
    if ( iter != last )
    {
      iter->second->ostr.str( "" );
      return true;
    }
    return false;
  }

}