<commit_before>#include <cmdstan/stansummary_helper.hpp>
#include <stan/mcmc/chains.hpp>
#include <stan/io/ends_with.hpp>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>

/**
 * Compute summary statistics over HMC sampler output
 * read in from stan_csv files.
 * Command line options handled by boost::program_options.
 *
 * @param argc Number of arguments
 * @param argv Arguments
 *
 * @return 0 for success,
 *         non-zero otherwise
 */
int main(int argc, const char *argv[]) {
  std::string usage = R"(Usage: stansummary [OPTIONS] stan_csv_file(s)
Report statistics for one or more Stan csv files from a HMC sampler run.
Example:  stansummary model_chain_1.csv model_chain_2.csv
Options:
  -a, --autocorr [n]          Display the chain autocorrelation for the n-th
                              input file, in addition to statistics.
  -c, --csv_filename [file]   Write statistics to a csv file.
  -h, --help                  Produce help message, then exit.
  -p, --percentiles [values]  Percentiles to report as ordered set of
                              comma-separated integers from (1,99), inclusive.
                              Default is 5,50,95.
  -s, --sig_figs [n]          Significant figures reported. Default is 2.
                              Must be an integer from (1, 18), inclusive.
)";
  if (argc < 2) {  // pre-empt boost::program_options
    std::cout << usage << std::endl;
    return -1;
  }

  // Command-line arguments
  int sig_figs;
  int autocorr_idx;
  std::string csv_filename;
  std::string percentiles_spec;
  std::vector<std::string> filenames;
  boost::program_options::options_description desc("Allowed options");
  desc.add_options()("help,h", "Produce help message")(
      "sig_figs,s",
      boost::program_options::value<int>(&sig_figs)->default_value(2),
      "Significant figures, default 2.")(
      "autocorr,a", boost::program_options::value<int>(&autocorr_idx),
      "Display the chain autocorrelation.")(
      "csv_filename,c",
      boost::program_options::value<std::string>(&csv_filename),
      "Write statistics to a csv.")(
      "percentiles,p",
      boost::program_options::value<std::string>(&percentiles_spec)
          ->default_value("5,50,95"),
      "Percentiles to report.")(
      "input_files,i",
      boost::program_options::value<std::vector<std::string> >(&filenames),
      "Sampler csv files. ");
  boost::program_options::positional_options_description p;
  p.add("input_files", -1);

  // Parse, validate command-line
  boost::program_options::variables_map vm;
  try {
    boost::program_options::store(
        boost::program_options::command_line_parser(argc, argv)
            .options(desc)
            .positional(p)
            .run(),
        vm);
    boost::program_options::notify(vm);
  } catch (const boost::program_options::error &e) {
    std::cout << "Invalid argument: " << e.what() << std::endl;
    std::cout << std::endl << usage << std::endl;
    return -1;
  }
  if (vm.count("help")) {
    std::cout << std::endl << usage << std::endl;
    return 0;
  }
  if (vm.count("input_files")) {
    for (size_t i = 0; i < filenames.size(); ++i) {
      if (FILE *file = fopen(filenames[i].c_str(), "r")) {
        fclose(file);
      } else {
        std::cout << "Invalid input file: " << filenames[i] << ", exiting."
                  << std::endl;
        std::cout << std::endl << usage << std::endl;
        return -1;
      }
    }
    if (filenames.size() == 1)
      std::cout << "Input file: ";
    else
      std::cout << "Input files: ";
    for (size_t i = 0; i < filenames.size(); ++i) {
      std::cout << filenames[i];
      if (i < filenames.size() - 1)
        std::cout << ", ";
    }
    std::cout << std::endl;
  } else {
    std::cout
        << "No Stan csv file(s) specified, expecting one or more filenames."
        << std::endl;
    std::cout << std::endl << usage << std::endl;
    return -1;
  }
  if (vm.count("csv_filename")) {
    if (FILE *file = fopen(csv_filename.c_str(), "w")) {
      fclose(file);
    } else {
      std::cout << "Invalid output csv file: " << csv_filename << ", exiting."
                << std::endl;
      std::cout << std::endl << usage << std::endl;
      return -1;
    }
    std::cout << "Ouput csv_file: " << csv_filename << std::endl;
  }
  if (vm.count("sig_figs") && !vm["sig_figs"].defaulted()) {
    if (sig_figs < 1 || sig_figs > 18) {
      std::cout << "Bad value for option --sig_figs: "
                << vm["sig_figs"].as<int>() << ", exiting." << std::endl;
      std::cout << std::endl << usage << std::endl;
      return -1;
    }
    std::cout << "Significant digits: " << vm["sig_figs"].as<int>()
              << std::endl;
  }
  if (vm.count("autocorr")) {
    if (autocorr_idx < 1 || autocorr_idx > filenames.size()) {
      std::cout << "Bad value for option --autocorr: " << autocorr_idx
                << ", exiting." << std::endl;
      std::cout << std::endl << usage << std::endl;
      return -1;
    }
    std::cout << "Autocorrelation for chain: " << autocorr_idx << std::endl;
  }
  if (vm.count("percentiles") && !vm["percentiles"].defaulted()) {
    std::cout << "Percentiles: " << percentiles_spec << std::endl;
  }
  std::vector<std::string> percentiles;
  boost::algorithm::trim(
      percentiles_spec);  // split treats leading space as token
  boost::algorithm::split(percentiles, percentiles_spec, boost::is_any_of(", "),
                          boost::token_compress_on);
  Eigen::VectorXd probs;
  try {
    probs = percentiles_to_probs(percentiles);
  } catch (const boost::program_options::error &e) {
    std::cout << "Bad value for option --percentiles: " << e.what()
              << std::endl;
    std::cout << std::endl << usage << std::endl;
    return -1;
  }

  // Parse csv files into sample, metadata
  stan::io::stan_csv_metadata metadata;
  Eigen::VectorXd warmup_times(filenames.size());
  Eigen::VectorXd sampling_times(filenames.size());
  Eigen::VectorXi thin(filenames.size());
  stan::mcmc::chains<> chains = parse_csv_files(
      filenames, metadata, warmup_times, sampling_times, thin, &std::cout);

  // Get column headers for sampler, model params
  size_t max_name_length = 0;
  size_t num_sampler_params = -1;  // don't count name 'lp__'
  for (int i = 0; i < chains.num_params(); ++i) {
    if (chains.param_name(i).length() > max_name_length)
      max_name_length = chains.param_name(i).length();
    if (stan::io::ends_with("__", chains.param_name(i)))
      num_sampler_params++;
  }
  size_t model_params_offset = num_sampler_params + 1;
  size_t num_model_params = chains.num_params() - model_params_offset;

  std::vector<std::string> header = get_header(percentiles);

  // Compute statistics for sampler and model params
  Eigen::MatrixXd lp_param(1, header.size());
  Eigen::MatrixXd sampler_params(num_sampler_params, header.size());
  Eigen::MatrixXd model_params(num_model_params, header.size());

  get_stats(chains, warmup_times, sampling_times, probs, 0, lp_param);
  get_stats(chains, warmup_times, sampling_times, probs, 1, sampler_params);
  get_stats(chains, warmup_times, sampling_times, probs, model_params_offset,
            model_params);

  // Console output formatting
  Eigen::VectorXi column_sig_figs(header.size());
  Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1> sampler_formats(
      header.size());
  Eigen::VectorXi sampler_widths(header.size());
  sampler_widths = calculate_column_widths(sampler_params, header, sig_figs,
                                           sampler_formats);

  Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1> model_formats(
      header.size());
  Eigen::VectorXi model_widths(header.size());
  model_widths
      = calculate_column_widths(model_params, header, sig_figs, model_formats);

  Eigen::VectorXi column_widths(header.size());
  for (size_t i = 0; i < header.size(); ++i)
    column_widths[i] = sampler_widths[i] > model_widths[i] ? sampler_widths[i]
                                                           : model_widths[i];

  // Print to console
  write_timing(chains, metadata, warmup_times, sampling_times, thin, "",
               &std::cout);
  std::cout << std::endl;

  write_header(header, column_widths, max_name_length, false, &std::cout);
  std::cout << std::endl;
  write_params(chains, lp_param, column_widths, model_formats, max_name_length,
               sig_figs, 0, false, &std::cout);
  write_params(chains, sampler_params, column_widths, sampler_formats,
               max_name_length, sig_figs, 1, false, &std::cout);
  std::cout << std::endl;
  write_params(chains, model_params, column_widths, model_formats,
               max_name_length, sig_figs, model_params_offset, false,
               &std::cout);
  std::cout << std::endl;
  write_sampler_info(metadata, "", &std::cout);

  if (vm.count("autocorr")) {
    autocorrelation(chains, metadata, autocorr_idx, max_name_length);
    std::cout << std::endl;
  }

  // Write to csv file (optional)
  if (vm.count("csv_filename")) {
    std::ofstream csv_file(csv_filename.c_str(), std::ios_base::app);
    write_header(header, column_widths, max_name_length, true, &csv_file);
    write_params(chains, lp_param, column_widths, model_formats,
                 max_name_length, sig_figs, 0, true, &csv_file);
    write_params(chains, sampler_params, column_widths, sampler_formats,
                 max_name_length, sig_figs, 1, true, &csv_file);
    write_params(chains, model_params, column_widths, model_formats,
                 max_name_length, sig_figs, model_params_offset, true,
                 &csv_file);

    write_timing(chains, metadata, warmup_times, sampling_times, thin, "# ",
                 &csv_file);
    write_sampler_info(metadata, "# ", &csv_file);
    csv_file.close();
  }

  return 0;
}
<commit_msg>pushing sig_figs through to stansummary utility csv output files as well as console<commit_after>#include <cmdstan/stansummary_helper.hpp>
#include <stan/mcmc/chains.hpp>
#include <stan/io/ends_with.hpp>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>

/**
 * Compute summary statistics over HMC sampler output
 * read in from stan_csv files.
 * Command line options handled by boost::program_options.
 *
 * @param argc Number of arguments
 * @param argv Arguments
 *
 * @return 0 for success,
 *         non-zero otherwise
 */
int main(int argc, const char *argv[]) {
  std::string usage = R"(Usage: stansummary [OPTIONS] stan_csv_file(s)
Report statistics for one or more Stan csv files from a HMC sampler run.
Example:  stansummary model_chain_1.csv model_chain_2.csv
Options:
  -a, --autocorr [n]          Display the chain autocorrelation for the n-th
                              input file, in addition to statistics.
  -c, --csv_filename [file]   Write statistics to a csv file.
  -h, --help                  Produce help message, then exit.
  -p, --percentiles [values]  Percentiles to report as ordered set of
                              comma-separated integers from (1,99), inclusive.
                              Default is 5,50,95.
  -s, --sig_figs [n]          Significant figures reported. Default is 2.
                              Must be an integer from (1, 18), inclusive.
)";
  if (argc < 2) {  // pre-empt boost::program_options
    std::cout << usage << std::endl;
    return -1;
  }

  // Command-line arguments
  int sig_figs;
  int autocorr_idx;
  std::string csv_filename;
  std::string percentiles_spec;
  std::vector<std::string> filenames;
  boost::program_options::options_description desc("Allowed options");
  desc.add_options()("help,h", "Produce help message")(
      "sig_figs,s",
      boost::program_options::value<int>(&sig_figs)->default_value(2),
      "Significant figures, default 2.")(
      "autocorr,a", boost::program_options::value<int>(&autocorr_idx),
      "Display the chain autocorrelation.")(
      "csv_filename,c",
      boost::program_options::value<std::string>(&csv_filename),
      "Write statistics to a csv.")(
      "percentiles,p",
      boost::program_options::value<std::string>(&percentiles_spec)
          ->default_value("5,50,95"),
      "Percentiles to report.")(
      "input_files,i",
      boost::program_options::value<std::vector<std::string> >(&filenames),
      "Sampler csv files. ");
  boost::program_options::positional_options_description p;
  p.add("input_files", -1);

  // Parse, validate command-line
  boost::program_options::variables_map vm;
  try {
    boost::program_options::store(
        boost::program_options::command_line_parser(argc, argv)
            .options(desc)
            .positional(p)
            .run(),
        vm);
    boost::program_options::notify(vm);
  } catch (const boost::program_options::error &e) {
    std::cout << "Invalid argument: " << e.what() << std::endl;
    std::cout << std::endl << usage << std::endl;
    return -1;
  }
  if (vm.count("help")) {
    std::cout << std::endl << usage << std::endl;
    return 0;
  }
  if (vm.count("input_files")) {
    for (size_t i = 0; i < filenames.size(); ++i) {
      if (FILE *file = fopen(filenames[i].c_str(), "r")) {
        fclose(file);
      } else {
        std::cout << "Invalid input file: " << filenames[i] << ", exiting."
                  << std::endl;
        std::cout << std::endl << usage << std::endl;
        return -1;
      }
    }
    if (filenames.size() == 1)
      std::cout << "Input file: ";
    else
      std::cout << "Input files: ";
    for (size_t i = 0; i < filenames.size(); ++i) {
      std::cout << filenames[i];
      if (i < filenames.size() - 1)
        std::cout << ", ";
    }
    std::cout << std::endl;
  } else {
    std::cout
        << "No Stan csv file(s) specified, expecting one or more filenames."
        << std::endl;
    std::cout << std::endl << usage << std::endl;
    return -1;
  }
  if (vm.count("csv_filename")) {
    if (FILE *file = fopen(csv_filename.c_str(), "w")) {
      fclose(file);
    } else {
      std::cout << "Invalid output csv file: " << csv_filename << ", exiting."
                << std::endl;
      std::cout << std::endl << usage << std::endl;
      return -1;
    }
    std::cout << "Ouput csv_file: " << csv_filename << std::endl;
  }
  if (vm.count("sig_figs") && !vm["sig_figs"].defaulted()) {
    if (sig_figs < 1 || sig_figs > 18) {
      std::cout << "Bad value for option --sig_figs: "
                << vm["sig_figs"].as<int>() << ", exiting." << std::endl;
      std::cout << std::endl << usage << std::endl;
      return -1;
    }
    std::cout << "Significant digits: " << vm["sig_figs"].as<int>()
              << std::endl;
  }
  if (vm.count("autocorr")) {
    if (autocorr_idx < 1 || autocorr_idx > filenames.size()) {
      std::cout << "Bad value for option --autocorr: " << autocorr_idx
                << ", exiting." << std::endl;
      std::cout << std::endl << usage << std::endl;
      return -1;
    }
    std::cout << "Autocorrelation for chain: " << autocorr_idx << std::endl;
  }
  if (vm.count("percentiles") && !vm["percentiles"].defaulted()) {
    std::cout << "Percentiles: " << percentiles_spec << std::endl;
  }
  std::vector<std::string> percentiles;
  boost::algorithm::trim(
      percentiles_spec);  // split treats leading space as token
  boost::algorithm::split(percentiles, percentiles_spec, boost::is_any_of(", "),
                          boost::token_compress_on);
  Eigen::VectorXd probs;
  try {
    probs = percentiles_to_probs(percentiles);
  } catch (const boost::program_options::error &e) {
    std::cout << "Bad value for option --percentiles: " << e.what()
              << std::endl;
    std::cout << std::endl << usage << std::endl;
    return -1;
  }

  // Parse csv files into sample, metadata
  stan::io::stan_csv_metadata metadata;
  Eigen::VectorXd warmup_times(filenames.size());
  Eigen::VectorXd sampling_times(filenames.size());
  Eigen::VectorXi thin(filenames.size());
  stan::mcmc::chains<> chains = parse_csv_files(
      filenames, metadata, warmup_times, sampling_times, thin, &std::cout);

  // Get column headers for sampler, model params
  size_t max_name_length = 0;
  size_t num_sampler_params = -1;  // don't count name 'lp__'
  for (int i = 0; i < chains.num_params(); ++i) {
    if (chains.param_name(i).length() > max_name_length)
      max_name_length = chains.param_name(i).length();
    if (stan::io::ends_with("__", chains.param_name(i)))
      num_sampler_params++;
  }
  size_t model_params_offset = num_sampler_params + 1;
  size_t num_model_params = chains.num_params() - model_params_offset;

  std::vector<std::string> header = get_header(percentiles);

  // Compute statistics for sampler and model params
  Eigen::MatrixXd lp_param(1, header.size());
  Eigen::MatrixXd sampler_params(num_sampler_params, header.size());
  Eigen::MatrixXd model_params(num_model_params, header.size());

  get_stats(chains, warmup_times, sampling_times, probs, 0, lp_param);
  get_stats(chains, warmup_times, sampling_times, probs, 1, sampler_params);
  get_stats(chains, warmup_times, sampling_times, probs, model_params_offset,
            model_params);

  // Console output formatting
  Eigen::VectorXi column_sig_figs(header.size());
  Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1> sampler_formats(
      header.size());
  Eigen::VectorXi sampler_widths(header.size());
  sampler_widths = calculate_column_widths(sampler_params, header, sig_figs,
                                           sampler_formats);

  Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1> model_formats(
      header.size());
  Eigen::VectorXi model_widths(header.size());
  model_widths
      = calculate_column_widths(model_params, header, sig_figs, model_formats);

  Eigen::VectorXi column_widths(header.size());
  for (size_t i = 0; i < header.size(); ++i)
    column_widths[i] = sampler_widths[i] > model_widths[i] ? sampler_widths[i]
                                                           : model_widths[i];

  // Print to console
  write_timing(chains, metadata, warmup_times, sampling_times, thin, "",
               &std::cout);
  std::cout << std::endl;

  write_header(header, column_widths, max_name_length, false, &std::cout);
  std::cout << std::endl;
  write_params(chains, lp_param, column_widths, model_formats, max_name_length,
               sig_figs, 0, false, &std::cout);
  write_params(chains, sampler_params, column_widths, sampler_formats,
               max_name_length, sig_figs, 1, false, &std::cout);
  std::cout << std::endl;
  write_params(chains, model_params, column_widths, model_formats,
               max_name_length, sig_figs, model_params_offset, false,
               &std::cout);
  std::cout << std::endl;
  write_sampler_info(metadata, "", &std::cout);

  if (vm.count("autocorr")) {
    autocorrelation(chains, metadata, autocorr_idx, max_name_length);
    std::cout << std::endl;
  }

  // Write to csv file (optional)
  if (vm.count("csv_filename")) {
    std::ofstream csv_file(csv_filename.c_str(), std::ios_base::app);
    if (vm.count("sig_figs") && !vm["sig_figs"].defaulted()) {
      csv_file << std::setprecision(vm["sig_figs"].as<int>());
    }
    write_header(header, column_widths, max_name_length, true, &csv_file);
    write_params(chains, lp_param, column_widths, model_formats,
                 max_name_length, sig_figs, 0, true, &csv_file);
    write_params(chains, sampler_params, column_widths, sampler_formats,
                 max_name_length, sig_figs, 1, true, &csv_file);
    write_params(chains, model_params, column_widths, model_formats,
                 max_name_length, sig_figs, model_params_offset, true,
                 &csv_file);

    write_timing(chains, metadata, warmup_times, sampling_times, thin, "# ",
                 &csv_file);
    write_sampler_info(metadata, "# ", &csv_file);
    csv_file.close();
  }

  return 0;
}
<|endoftext|>


<commit_before>#pragma once
#include <functional>
#include <vector>
#include <type_traits>

#include <SDL.h>
#undef main

#include "keycode.hpp"

namespace ORCore
{

    enum EventType
    {
        EventNone    = 0,
        Quit         = 1 << 0,
        MouseMove    = 1 << 1,
        WindowClose  = 1 << 2,
        WindowSize  = 1 << 3,
        KeyUp        = 1 << 4,
        KeyDown      = 1 << 5,
        EventAll = Quit | MouseMove | WindowClose | WindowSize | KeyUp | KeyDown
    };

    // enable the use of bitwise operators on flags

    struct MouseMoveEvent
    {
        int x;
        int y;
    };

    struct WindowSizeEvent
    {

        Uint32 id;
        int width;
        int height;
    };

    struct WindowCloseEvent
    {
        Uint32 id;
    };

    struct KeyUpEvent
    {
        KeyCode key;
        ModFlag mod;

    };

    struct KeyDownEvent
    {
        KeyCode key;
        ModFlag mod;

    };

    struct QuitEvent
    {
        bool quit;

    };

    // This is functionally works similar to boost::any but customized to the event system.
    // Basically the idea is to use polymorphism and templates to store any type of data
    // in the same object. We use this idea to deliver many different types of event structs
    // within a single object.
    // Also since this has a lot of template stuff in it, I decided to put the entire implementation
    // in the header.
    struct Event
    {
        EventType type;
        float time;
        template<class Type> friend
        Type event_cast(const Event&);

        Event(Event&& other)
        : ptr(std::move(other.ptr))
        {
            time = other.time;
            type = other.type;
            other.time = 0.0;
            other.type = EventNone;
        }

        Event(const Event& other) {
            if (other.ptr) {
                ptr = other.ptr->clone();
            }
            time = other.time;
            type = other.type;
        }

        Event& operator=(Event&& other) {
            ptr = std::move(other.ptr);
            time = other.time;
            type = other.type;
            other.time = 0.0;
            other.type = EventNone;
            return *this;
        }

        Event& operator=(const Event& other) {
            ptr =  std::move(Event(other).ptr);
            return *this;
        }

        Event()
        : type(EventNone), time(0.0), ptr(nullptr)
        {}

        template<typename T>
        Event(EventType eType, float eTime, const T& event)
        : type(eType), time(eTime), ptr(new Concrete<T>(event))
        {
        }
    private:
        struct Placeholder
        {
            virtual ~Placeholder() {};
            virtual std::unique_ptr<Placeholder> clone() = 0;
        };

        template<typename T>
        struct Concrete : public Placeholder
        {
            Concrete(T&& x)
            : value(std::move(x))
            {}

            Concrete(const T& x)
            : value(x)
            {}

            virtual std::unique_ptr<Placeholder> clone()
            {
                return std::make_unique<Concrete>(value);
            }

            T value;
        };
        std::unique_ptr<Placeholder> ptr;
    };

    // Used to get the event data out of the event.
    template<class Type>
    Type event_cast(const Event& val) {
        return static_cast<Event::Concrete<Type>*>(val.ptr.get())->value;
    }

    struct Listener
    {
        int id;
        EventType mask;
        std::function<bool (const Event&)> handler;
        // more to come
    };

    class EventManager
    {
    public:
        void add_listener(Listener &listener);
        void remove_listener(Listener &listener);
        void broadcast_event(const Event &event);
    private:
        std::vector<Listener*> m_listeners;
    };

    class EventPumpSDL2
    {
    public:
        EventPumpSDL2(EventManager *events);
        void process();
    private:
        EventManager *m_events;
    };
}<commit_msg>Make cast template a bit more consistant with the other parts.<commit_after>#pragma once
#include <functional>
#include <vector>
#include <type_traits>

#include <SDL.h>
#undef main

#include "keycode.hpp"

namespace ORCore
{

    enum EventType
    {
        EventNone    = 0,
        Quit         = 1 << 0,
        MouseMove    = 1 << 1,
        WindowClose  = 1 << 2,
        WindowSize  = 1 << 3,
        KeyUp        = 1 << 4,
        KeyDown      = 1 << 5,
        EventAll = Quit | MouseMove | WindowClose | WindowSize | KeyUp | KeyDown
    };

    // enable the use of bitwise operators on flags

    struct MouseMoveEvent
    {
        int x;
        int y;
    };

    struct WindowSizeEvent
    {

        Uint32 id;
        int width;
        int height;
    };

    struct WindowCloseEvent
    {
        Uint32 id;
    };

    struct KeyUpEvent
    {
        KeyCode key;
        ModFlag mod;

    };

    struct KeyDownEvent
    {
        KeyCode key;
        ModFlag mod;

    };

    struct QuitEvent
    {
        bool quit;

    };

    // This is functionally works similar to boost::any but customized to the event system.
    // Basically the idea is to use polymorphism and templates to store any type of data
    // in the same object. We use this idea to deliver many different types of event structs
    // within a single object.
    // Also since this has a lot of template stuff in it, I decided to put the entire implementation
    // in the header.
    struct Event
    {
        EventType type;
        float time;
        template<class Type> friend
        Type event_cast(const Event&);

        Event(Event&& other)
        : ptr(std::move(other.ptr))
        {
            time = other.time;
            type = other.type;
            other.time = 0.0;
            other.type = EventNone;
        }

        Event(const Event& other) {
            if (other.ptr) {
                ptr = other.ptr->clone();
            }
            time = other.time;
            type = other.type;
        }

        Event& operator=(Event&& other) {
            ptr = std::move(other.ptr);
            time = other.time;
            type = other.type;
            other.time = 0.0;
            other.type = EventNone;
            return *this;
        }

        Event& operator=(const Event& other) {
            ptr =  std::move(Event(other).ptr);
            return *this;
        }

        Event()
        : type(EventNone), time(0.0), ptr(nullptr)
        {}

        template<typename T>
        Event(EventType eType, float eTime, const T& event)
        : type(eType), time(eTime), ptr(new Concrete<T>(event))
        {
        }
    private:
        struct Placeholder
        {
            virtual ~Placeholder() {};
            virtual std::unique_ptr<Placeholder> clone() = 0;
        };

        template<typename T>
        struct Concrete : public Placeholder
        {
            Concrete(T&& x)
            : value(std::move(x))
            {}

            Concrete(const T& x)
            : value(x)
            {}

            virtual std::unique_ptr<Placeholder> clone()
            {
                return std::make_unique<Concrete>(value);
            }

            T value;
        };

        std::unique_ptr<Placeholder> ptr;
    };

    // Used to get the event data out of the event.
    template<typename T>
    T event_cast(const Event& val) {
        return static_cast<Event::Concrete<T>*>(val.ptr.get())->value;
    }

    struct Listener
    {
        int id;
        EventType mask;
        std::function<bool (const Event&)> handler;
        // more to come
    };

    class EventManager
    {
    public:
        void add_listener(Listener &listener);
        void remove_listener(Listener &listener);
        void broadcast_event(const Event &event);
    private:
        std::vector<Listener*> m_listeners;
    };

    class EventPumpSDL2
    {
    public:
        EventPumpSDL2(EventManager *events);
        void process();
    private:
        EventManager *m_events;
    };
}<|endoftext|>


<commit_before>#include "string.h"
#include "cstring"
#include "assert.h"
#include "log.h"
#include <stdlib.h>
#include <errno.h>
#include <algorithm>

namespace Epyx
{
    const char String::spaces[] = " \t\n\v\f\r";
    const std::string String::crlf("\r\n");
    const byte_str String::crlf_bytes((byte*) "\r\n");

    std::string& String::ltrim(std::string& str) {
        str.erase(0, str.find_first_not_of(spaces));
        return str;
    }

    std::string& String::rtrim(std::string& str) {
        str.erase(str.find_last_not_of(spaces) + 1);
        return str;
    }

    std::string& String::trim(std::string& str) {
        return ltrim(rtrim(str));
    }

    std::string& String::toUpper(std::string& str) {
        std::transform(str.begin(), str.end(), str.begin(),
            std::ptr_fun<int, int>(std::toupper));
        return str;
    }

    std::string& String::toLower(std::string& str) {
        std::transform(str.begin(), str.end(), str.begin(),
            std::ptr_fun<int, int>(std::tolower));
        return str;
    }

    long String::toInt(const std::string& s) {
        std::stringstream ss(s);
        long l;
        try {
            ss >> l;
            if (ss.fail())
                throw new std::exception();
        } catch (std::exception& e) {
            throw ParserException("String::toInt", "Invalid characters");
        }
        return l;
    }

    unsigned long String::toULong(const std::string& s) {
        std::stringstream ss(s);
        unsigned long l;
        try {
            ss >> l;
            if (ss.fail())
                throw new std::exception();
        } catch (std::exception& e) {
            throw ParserException("String::toInt", "Invalid characters");
        }
        return l;
    }

    std::string String::fromInt(int n) {
        std::stringstream out;
        out << n;
        return out.str();
    }

    std::string String::fromUnsignedLong(unsigned long n) {
        std::stringstream out;
        out << n;
        return out.str();
    }
}
<commit_msg>Fix bad exception thrown in core/String::toInt<commit_after>#include "string.h"
#include "cstring"
#include "assert.h"
#include "log.h"
#include <stdlib.h>
#include <errno.h>
#include <algorithm>

namespace Epyx
{
    const char String::spaces[] = " \t\n\v\f\r";
    const std::string String::crlf("\r\n");
    const byte_str String::crlf_bytes((byte*) "\r\n");

    std::string& String::ltrim(std::string& str) {
        str.erase(0, str.find_first_not_of(spaces));
        return str;
    }

    std::string& String::rtrim(std::string& str) {
        str.erase(str.find_last_not_of(spaces) + 1);
        return str;
    }

    std::string& String::trim(std::string& str) {
        return ltrim(rtrim(str));
    }

    std::string& String::toUpper(std::string& str) {
        std::transform(str.begin(), str.end(), str.begin(),
            std::ptr_fun<int, int>(std::toupper));
        return str;
    }

    std::string& String::toLower(std::string& str) {
        std::transform(str.begin(), str.end(), str.begin(),
            std::ptr_fun<int, int>(std::tolower));
        return str;
    }

    long String::toInt(const std::string& s) {
        std::stringstream ss(s);
        long l;
        try {
            ss >> l;
            if (ss.fail())
                throw std::exception();
        } catch (std::exception& e) {
            throw ParserException("String::toInt", "Invalid characters");
        }
        return l;
    }

    unsigned long String::toULong(const std::string& s) {
        std::stringstream ss(s);
        unsigned long l;
        try {
            ss >> l;
            if (ss.fail())
                throw std::exception();
        } catch (std::exception& e) {
            throw ParserException("String::toInt", "Invalid characters");
        }
        return l;
    }

    std::string String::fromInt(int n) {
        std::stringstream out;
        out << n;
        return out.str();
    }

    std::string String::fromUnsignedLong(unsigned long n) {
        std::stringstream out;
        out << n;
        return out.str();
    }
}
<|endoftext|>


<commit_before>/* dali_master library by Steve Parker
 */

#include "dali_master.h"

/**
 * Constructor.
 */
Dali_master::Dali_master()
{}

/**
 * Example method.
 */
void Dali_master::begin(uint8_t _address)
{
  	address = _address;
	Wire.begin();

	clearStatusRegister();
    transmitCommand(TERMINATE_C, BLANK_C);
    transmitCommand(RESET_C, BLANK_C);
    transmitCommand(RESET_C, BLANK_C);
}

byte Dali_master::transmitCommand(byte cmd1, byte cmd2, bool &reply, byte &reply1, byte &reply2)
{
	byte a = transmitCommand(cmd1, cmd2);
	reply = false;

	// If we have a valid reply, wait for the data to be available in the register
	if (bitRead(a, VALIDREPLY_S) == 1) {
		while (bitRead(a, REPLY1_S) == 0 && bitRead(a, REPLY2_S) == 0) {
			a = getStatus();
		}

		reply1 = 0x00;
		reply2 = 0x00;
		reply = true;
		getCommandRegister(reply1, reply2);
	}

	return a;
}

byte Dali_master::transmitCommand(byte cmd1, byte cmd2)
{
	// Make sure the command register is clear before continuing
	clearStatusRegister();
	delay(10);

	// Wait until bus is free
	byte b = getStatus();
	while (bitRead(b, BUSY_S) == 1) {
		b = getStatus();
	}

	Wire.beginTransmission(address);
	Wire.write(0x01);
	Wire.write(cmd1);
	Wire.write(cmd2);
	Wire.endTransmission();

	// Wait until the command has been sent
	b = getStatus();
	while (bitRead(b, BUSY_S) == 1) {
		b = getStatus();
	}

	// If we have an error (frameerror or overrun)
	if (bitRead(b, FRAMEERROR_S) == 1 || bitRead(b, OVERRUN_S) == 1) {
		if (bitRead(b, FRAMEERROR_S) == 1) {
			Serial.println("FRAMEERROR");
		} else {
			Serial.println("OVERRUN");
		}
	}

	// Wait until reply timeframe has passed
	b = getStatus();
	while (bitRead(b, REPLYTIMEFRAME_S) == 1) {
		b = getStatus();
	}

	return b;
}

void Dali_master::getCommandRegister(uint8_t &byte1, uint8_t &byte2)
{
	// Wait until we have the correct number of bytes
	while (!getCommandRegisterRaw()) {}

	byte1 = Wire.read();
	byte2 = Wire.read();
}

byte Dali_master::getStatus()
{
	// Wait until we have the correct number of bytes
	while (!getStatusRaw()) {}

	return Wire.read();
}

void Dali_master::flashDevice(byte deviceId)
{
    const uint8_t delayTime = 50;

    for (uint8_t i = 0; i <= 3; i++) {
        transmitCommand(1 + (deviceId << 1), ON_C);
        delay(delayTime);
        transmitCommand(1 + (deviceId << 1), OFF_C);
        delay(delayTime);
    }
}

void Dali_master::explainStatus(byte status)
{
    Serial.print("BUSERR [");
    if (bitRead(status, BUSERROR_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] BUSY [");
    if (bitRead(status, BUSY_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] OVERRUN [");
    if (bitRead(status, OVERRUN_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] FRAMEERROR [");
    if (bitRead(status, FRAMEERROR_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] VALIDREPLY [");
    if (bitRead(status, VALIDREPLY_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] TIMEOUT [");
    if (bitRead(status, REPLYTIMEFRAME_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] REPLY 2[");
    if (bitRead(status, REPLY2_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] REPLY 1[");
    if (bitRead(status, REPLY1_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("]");
}

// PRIVATE METHODS
void Dali_master::clearStatusRegister()
{
	uint8_t a, b;
	byte s = getStatus();

	while (s != 0x00) {
		getCommandRegister(a, b);
		s = getStatus();
	}
}

bool Dali_master::getStatusRaw()
{
	Wire.beginTransmission(address);
	Wire.write(0x00);
	Wire.endTransmission();

	Wire.requestFrom(address, 1);

	return (Wire.available() == 1) ? true : false;
}

bool Dali_master::getCommandRegisterRaw()
{
	Wire.beginTransmission(address);
	Wire.write(0x01);
	Wire.endTransmission();

	Wire.requestFrom(address, 2);

	return (Wire.available() == 2) ? true : false;
}

void Dali_master::splitAdd(long input, uint8_t &highbyte, uint8_t &middlebyte, uint8_t &lowbyte)
{
	highbyte = input >> 16;
	middlebyte = input >> 8;
	lowbyte = input;
}
<commit_msg>Use restart after transmission<commit_after>/* dali_master library by Steve Parker
 */

#include "dali_master.h"

/**
 * Constructor.
 */
Dali_master::Dali_master()
{}

/**
 * Example method.
 */
void Dali_master::begin(uint8_t _address)
{
  	address = _address;
	Wire.begin();

	clearStatusRegister();
    transmitCommand(TERMINATE_C, BLANK_C);
    transmitCommand(RESET_C, BLANK_C);
    transmitCommand(RESET_C, BLANK_C);
}

byte Dali_master::transmitCommand(byte cmd1, byte cmd2, bool &reply, byte &reply1, byte &reply2)
{
	byte a = transmitCommand(cmd1, cmd2);
	reply = false;

	// If we have a valid reply, wait for the data to be available in the register
	if (bitRead(a, VALIDREPLY_S) == 1) {
		while (bitRead(a, REPLY1_S) == 0 && bitRead(a, REPLY2_S) == 0) {
			a = getStatus();
		}

		reply1 = 0x00;
		reply2 = 0x00;
		reply = true;
		getCommandRegister(reply1, reply2);
	}

	return a;
}

byte Dali_master::transmitCommand(byte cmd1, byte cmd2)
{
	// Make sure the command register is clear before continuing
	clearStatusRegister();
	delay(10);

	// Wait until bus is free
	byte b = getStatus();
	while (bitRead(b, BUSY_S) == 1) {
		b = getStatus();
	}

	Wire.beginTransmission(address);
	Wire.write(0x01);
	Wire.write(cmd1);
	Wire.write(cmd2);
	Wire.endTransmission(false);

	// Wait until the command has been sent
	b = getStatus();
	while (bitRead(b, BUSY_S) == 1) {
		b = getStatus();
	}

	// If we have an error (frameerror or overrun)
	if (bitRead(b, FRAMEERROR_S) == 1 || bitRead(b, OVERRUN_S) == 1) {
		if (bitRead(b, FRAMEERROR_S) == 1) {
			Serial.println("FRAMEERROR");
		} else {
			Serial.println("OVERRUN");
		}
	}

	// Wait until reply timeframe has passed
	b = getStatus();
	while (bitRead(b, REPLYTIMEFRAME_S) == 1) {
		b = getStatus();
	}

	return b;
}

void Dali_master::getCommandRegister(uint8_t &byte1, uint8_t &byte2)
{
	// Wait until we have the correct number of bytes
	while (!getCommandRegisterRaw()) {}

	byte1 = Wire.read();
	byte2 = Wire.read();
}

byte Dali_master::getStatus()
{
	// Wait until we have the correct number of bytes
	while (!getStatusRaw()) {}

	return Wire.read();
}

void Dali_master::flashDevice(byte deviceId)
{
    const uint8_t delayTime = 50;

    for (uint8_t i = 0; i <= 3; i++) {
        transmitCommand(1 + (deviceId << 1), ON_C);
        delay(delayTime);
        transmitCommand(1 + (deviceId << 1), OFF_C);
        delay(delayTime);
    }
}

void Dali_master::explainStatus(byte status)
{
    Serial.print("BUSERR [");
    if (bitRead(status, BUSERROR_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] BUSY [");
    if (bitRead(status, BUSY_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] OVERRUN [");
    if (bitRead(status, OVERRUN_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] FRAMEERROR [");
    if (bitRead(status, FRAMEERROR_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] VALIDREPLY [");
    if (bitRead(status, VALIDREPLY_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] TIMEOUT [");
    if (bitRead(status, REPLYTIMEFRAME_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] REPLY 2[");
    if (bitRead(status, REPLY2_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("] REPLY 1[");
    if (bitRead(status, REPLY1_S) == 1) {
        Serial.print("x");
    } else {
        Serial.print(" ");
    }
    Serial.print("]");
}

// PRIVATE METHODS
void Dali_master::clearStatusRegister()
{
	uint8_t a, b;
	byte s = getStatus();

	while (s != 0x00) {
		getCommandRegister(a, b);
		s = getStatus();
	}
}

bool Dali_master::getStatusRaw()
{
	Wire.beginTransmission(address);
	Wire.write(0x00);
	Wire.endTransmission(false);

	Wire.requestFrom(address, 1);

	return (Wire.available() == 1) ? true : false;
}

bool Dali_master::getCommandRegisterRaw()
{
	Wire.beginTransmission(address);
	Wire.write(0x01);
	Wire.endTransmission(false);

	Wire.requestFrom(address, 2);

	return (Wire.available() == 2) ? true : false;
}

void Dali_master::splitAdd(long input, uint8_t &highbyte, uint8_t &middlebyte, uint8_t &lowbyte)
{
	highbyte = input >> 16;
	middlebyte = input >> 8;
	lowbyte = input;
}
<|endoftext|>


<commit_before><commit_msg>add TODO text only<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlitem.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:33:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef CSI_XML_XMLITEM_HXX
#define CSI_XML_XMLITEM_HXX

// USED SERVICES
    // BASE CLASSES
    // COMPONENTS
#include <cosv/template/swelist.hxx>
#include <cosv/template/dyn.hxx>
    // PARAMETERS

namespace csv
{
    class bostream;
}

namespace csi
{
namespace xml
{

/*  Basics:
    Item, Attribute, Element, TextContext
*/

class Item
{
  public:
    virtual             ~Item() {}
    void                WriteOut(
                            csv::bostream &     io_aFile ) const;
  private:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const = 0;
};

typedef csv::SweList_dyn< Item >            ItemList;

class Attribute
{
  public:
    virtual             ~Attribute() {}

    void                WriteOut(
                            csv::bostream &     io_aFile ) const;

    const ::csv::String& Name() const;
    const ::csv::String& Value() const;

  private:
    virtual const ::csv::String &
                        inq_Name() const = 0;
    virtual const ::csv::String &
                        inq_Value() const = 0;
};

typedef csv::SweList_dyn< Attribute >   AttrList;

class Element : public Item
{
  public:
    Element &           operator<<(             /// For multiple content items.
                            DYN Item *          let_dpItem );
    Element &           operator<<(             /// For multiple content items.
                            const ::csv::String& let_drText );
    Element &           operator<<(             /// For multiple content items.
                            const char *        let_dpText );
    Element &           operator<<(
                            DYN Attribute *     let_dpAttr );

    Element &           operator>>(             /// For multiple content items. @return the child Element.
                            DYN Element &       let_drElement );

    Item *              SetContent(             /// For only one content item.
                            DYN Item *          let_dpItem );       /// Replaces previous content. May be 0, then all content is deleted.
  private:
    // Interface Item:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const;
    // Local
    virtual void        op_streamout(
                            DYN Item *          let_dpItem ) = 0;
    virtual void        op_streamout(
                            DYN Attribute *     let_dpAttr ) = 0;

    virtual void        do_SetContent(
                            DYN Item *          let_dpItem ) = 0;
    // Helpers
    virtual const ::csv::String &
                        inq_TagName() const = 0;
    virtual const Item *
                        inq_Content() const = 0;
    virtual const AttrList *
                        inq_Attrs() const = 0;

    virtual bool        FinishEmptyTag_XmlStyle() const;    /// Defaulted to: true

    virtual bool        LineBreakAfterBeginTag() const;     /// Defaulted to: false
    virtual bool        LineBreakAfterEndTag() const;       /// Defaulted to: true, if LineBreakAfterBeginTag()
};

class TextContent : public Item
{
};

/*  Implementation simplifiers:
    EmptyElement, PureElement, SglTag
*/

class EmptyElement : public Element
{
  private:
    // Interface Element:
    virtual void        op_streamout(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual const Item *
                        inq_Content() const;    /// @return 0
    virtual const AttrList *
                        inq_Attrs() const;

    // Local
    virtual AttrList &  inq_RefAttrs() = 0;
    const AttrList &    inq_RefAttrs() const;
};

class PureElement : public Element
{
  private:
    // Interface Element:
    virtual void        op_streamout(
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(          /// does nothing
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(
                            DYN Item *          let_dpItem );
    virtual const Item *
                        inq_Content() const;
    virtual const AttrList *
                        inq_Attrs() const;      /// @return 0
    // Local
    virtual Dyn< Item > &
                        inq_RefContent() = 0;
    const Dyn< Item > & inq_RefContent() const;
};

class SglTag : public Element
{
  private:
    // Interface Element:
    virtual void        op_streamout(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(          /// does nothing
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual const Item *
                        inq_Content() const;    /// @return 0
    virtual const AttrList *
                        inq_Attrs() const;      /// @return 0
};

/*  Standard Element implementations, if there are not any
    specialized ones.
*/

class AnElement : public Element
{
  public:
                        AnElement(
                            const ::csv::String& i_sTagName );
                        AnElement(
                            const char *         i_sTagName );
                        ~AnElement();
  private:
    // Interface Element
    virtual void        op_streamout(
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(
                            DYN Item *          let_dpItem );
    virtual const ::csv::String &
                        inq_TagName() const;
    virtual const Item *
                        inq_Content() const;
    virtual const AttrList *
                        inq_Attrs() const;
    // DATA
    ::csv::String       sTagName;
    Dyn< Item >         pContent;
    AttrList            aAttrs;
};

class AnEmptyElement : public EmptyElement
{
  public:
                        AnEmptyElement(
                            const ::csv::String & i_sTagName );
                        AnEmptyElement(
                            const char * i_sTagName );
                        ~AnEmptyElement();
  private:
    // Interface Element:
    virtual const ::csv::String &
                        inq_TagName() const;
    // Interface EmptyElement:
    virtual AttrList &  inq_RefAttrs();

    // DATA
    ::csv::String       sTagName;
    AttrList            aAttrs;
};

class APureElement : public PureElement
{
  public:
                        APureElement(
                            const ::csv::String &   i_sTagName );
                        APureElement(
                            const char *            i_sTagName );
                        ~APureElement();
  private:
    // Interface Element:
    virtual const ::csv::String &
                        inq_TagName() const;
    // Interface PureElement:
    virtual Dyn< Item > &
                        inq_RefContent();
    // DATA
    ::csv::String         sTagName;
    Dyn< Item >         pContent;
};

class ASglTag : public SglTag
{
  public:
                        ASglTag(
                            const ::csv::String & i_sTagName );
                        ASglTag(
                            const char *          i_sTagName );
                        ~ASglTag();
  private:
    // Interface Element:
    virtual const ::csv::String &
                        inq_TagName() const;
    // DATA
    ::csv::String         sTagName;
};

/* Standard Attribute implementation
*/
class AnAttribute : public Attribute
{
  public:
                        AnAttribute(
                            const ::csv::String & i_sName,
                            const ::csv::String & i_sValue );
                        AnAttribute(
                            const char *          i_sName,
                            const char *          i_sValue );
                        ~AnAttribute();
  private:
    // Interface Attribute:
    virtual const ::csv::String &
                        inq_Name() const;
    virtual const ::csv::String &
                        inq_Value() const;
    // DATA
    ::csv::String         sName;
    ::csv::String         sValue;
};

/*  Implementations of TextContent:

    Text        ( reserved characters will be replaced and appear unchanged )
    XmlCode     ( reserved characters stay and are interpreted
                  by the XML-viewer )
*/
class Text : public TextContent
{
  public:
                        Text(
                            const ::csv::String & i_sText );
                        Text(
                            const char *        i_sText );
                        ~Text();
  private:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const;
    // DATA
    ::csv::String         sText;
};

class XmlCode : public TextContent
{
  public:
                        XmlCode(
                            const ::csv::String & i_sText );
                        XmlCode(
                            const char *          i_sText );
                        ~XmlCode();
  private:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const;
    // DATA
    ::csv::String         sText;
};

// IMPLEMENTATION

inline void
Item::WriteOut( csv::bostream & io_aFile ) const
    { do_WriteOut(io_aFile); }

inline const ::csv::String &
Attribute::Name() const
    { return inq_Name(); }
inline const ::csv::String &
Attribute::Value() const
    { return inq_Value(); }

inline Element &
Element::operator<<( DYN Item * let_dpItem )
    { op_streamout(let_dpItem); return *this; }
inline Element &
Element::operator<<( const ::csv::String & let_drText )
    { op_streamout( new Text(let_drText) ); return *this; }
inline Element &
Element::operator<<( const char * let_drText )
    { op_streamout( new Text(let_drText) ); return *this; }
inline Element &
Element::operator<<( DYN Attribute * let_dpAttr )
    { op_streamout(let_dpAttr); return *this; }
inline Element &
Element::operator>>( DYN Element & let_drElement )
    { op_streamout(&let_drElement); return let_drElement; }
inline Item *
Element::SetContent( DYN Item * let_dpItem )
    { do_SetContent(let_dpItem); return let_dpItem; }

inline const AttrList &
EmptyElement::inq_RefAttrs() const
    { return const_cast< EmptyElement* >(this)->inq_RefAttrs(); }

inline const Dyn< Item > &
PureElement::inq_RefContent() const
    { return const_cast< PureElement* >(this)->inq_RefContent(); }

}   // namespace xml
}   // namespace csi

#endif

<commit_msg>INTEGRATION: CWS warnings01 (1.4.4); FILE MERGED 2005/09/30 15:56:42 np 1.4.4.1: #i53898#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlitem.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 13:09:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef CSI_XML_XMLITEM_HXX
#define CSI_XML_XMLITEM_HXX

// USED SERVICES
    // BASE CLASSES
    // COMPONENTS
#include <cosv/template/swelist.hxx>
#include <cosv/template/dyn.hxx>
    // PARAMETERS

namespace csv
{
    class bostream;
}

namespace csi
{
namespace xml
{

/*  Basics:
    Item, Attribute, Element, TextContext
*/

class Item
{
  public:
    virtual             ~Item() {}
    void                WriteOut(
                            csv::bostream &     io_aFile ) const;
  private:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const = 0;
};

typedef csv::SweList_dyn< Item >            ItemList;

class Attribute
{
  public:
    virtual             ~Attribute() {}

    void                WriteOut(
                            csv::bostream &     io_aFile ) const;

    const ::csv::String& Name() const;
    const ::csv::String& Value() const;

  private:
    virtual const ::csv::String &
                        inq_Name() const = 0;
    virtual const ::csv::String &
                        inq_Value() const = 0;
};

typedef csv::SweList_dyn< Attribute >   AttrList;

class Element : public Item
{
  public:
    Element &           operator<<(             /// For multiple content items.
                            DYN Item *          let_dpItem );
    Element &           operator<<(             /// For multiple content items.
                            const ::csv::String& let_drText );
    Element &           operator<<(             /// For multiple content items.
                            const char *        let_dpText );
    Element &           operator<<(
                            DYN Attribute *     let_dpAttr );

    Element &           operator>>(             /// For multiple content items. @return the child Element.
                            DYN Element &       let_drElement );

    Item *              SetContent(             /// For only one content item.
                            DYN Item *          let_dpItem );       /// Replaces previous content. May be 0, then all content is deleted.
  private:
    // Interface Item:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const;
    // Local
    virtual void        op_streamout(
                            DYN Item *          let_dpItem ) = 0;
    virtual void        op_streamout(
                            DYN Attribute *     let_dpAttr ) = 0;

    virtual void        do_SetContent(
                            DYN Item *          let_dpItem ) = 0;
    // Helpers
    virtual const ::csv::String &
                        inq_TagName() const = 0;
    virtual const Item *
                        inq_Content() const = 0;
    virtual const AttrList *
                        inq_Attrs() const = 0;

    virtual bool        FinishEmptyTag_XmlStyle() const;    /// Defaulted to: true

    virtual bool        LineBreakAfterBeginTag() const;     /// Defaulted to: false
    virtual bool        LineBreakAfterEndTag() const;       /// Defaulted to: true, if LineBreakAfterBeginTag()
};

class TextContent : public Item
{
};

/*  Implementation simplifiers:
    EmptyElement, PureElement, SglTag
*/

class EmptyElement : public Element
{
  private:
    // Interface Element:
    virtual void        op_streamout(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual const Item *
                        inq_Content() const;    /// @return 0
    virtual const AttrList *
                        inq_Attrs() const;

    // Local
    virtual AttrList &  inq_RefAttrs() = 0;
};

class PureElement : public Element
{
  private:
    // Interface Element:
    virtual void        op_streamout(
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(          /// does nothing
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(
                            DYN Item *          let_dpItem );
    virtual const Item *
                        inq_Content() const;
    virtual const AttrList *
                        inq_Attrs() const;      /// @return 0
    // Local
    virtual Dyn< Item > &
                        inq_RefContent() = 0;
};

class SglTag : public Element
{
  private:
    // Interface Element:
    virtual void        op_streamout(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(          /// does nothing
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(          /// does nothing
                            DYN Item *          let_dpItem );
    virtual const Item *
                        inq_Content() const;    /// @return 0
    virtual const AttrList *
                        inq_Attrs() const;      /// @return 0
};

/*  Standard Element implementations, if there are not any
    specialized ones.
*/

class AnElement : public Element
{
  public:
                        AnElement(
                            const ::csv::String& i_sTagName );
                        AnElement(
                            const char *         i_sTagName );
                        ~AnElement();
  private:
    // Interface Element
    virtual void        op_streamout(
                            DYN Item *          let_dpItem );
    virtual void        op_streamout(
                            DYN Attribute *     let_dpAttr );
    virtual void        do_SetContent(
                            DYN Item *          let_dpItem );
    virtual const ::csv::String &
                        inq_TagName() const;
    virtual const Item *
                        inq_Content() const;
    virtual const AttrList *
                        inq_Attrs() const;
    // DATA
    ::csv::String       sTagName;
    Dyn< Item >         pContent;
    AttrList            aAttrs;
};

class AnEmptyElement : public EmptyElement
{
  public:
                        AnEmptyElement(
                            const ::csv::String & i_sTagName );
                        AnEmptyElement(
                            const char * i_sTagName );
                        ~AnEmptyElement();
  private:
    // Interface Element:
    virtual const ::csv::String &
                        inq_TagName() const;
    // Interface EmptyElement:
    virtual AttrList &  inq_RefAttrs();

    // DATA
    ::csv::String       sTagName;
    AttrList            aAttrs;
};

class APureElement : public PureElement
{
  public:
                        APureElement(
                            const ::csv::String &   i_sTagName );
                        APureElement(
                            const char *            i_sTagName );
                        ~APureElement();
  private:
    // Interface Element:
    virtual const ::csv::String &
                        inq_TagName() const;
    // Interface PureElement:
    virtual Dyn< Item > &
                        inq_RefContent();
    // DATA
    ::csv::String       sTagName;
    Dyn< Item >         pContent;
};

class ASglTag : public SglTag
{
  public:
                        ASglTag(
                            const ::csv::String & i_sTagName );
                        ASglTag(
                            const char *          i_sTagName );
                        ~ASglTag();
  private:
    // Interface Element:
    virtual const ::csv::String &
                        inq_TagName() const;
    // DATA
    ::csv::String         sTagName;
};

/* Standard Attribute implementation
*/
class AnAttribute : public Attribute
{
  public:
                        AnAttribute(
                            const ::csv::String & i_sName,
                            const ::csv::String & i_sValue );
                        AnAttribute(
                            const char *          i_sName,
                            const char *          i_sValue );
                        ~AnAttribute();
  private:
    // Interface Attribute:
    virtual const ::csv::String &
                        inq_Name() const;
    virtual const ::csv::String &
                        inq_Value() const;
    // DATA
    ::csv::String         sName;
    ::csv::String         sValue;
};

/*  Implementations of TextContent:

    Text        ( reserved characters will be replaced and appear unchanged )
    XmlCode     ( reserved characters stay and are interpreted
                  by the XML-viewer )
*/
class Text : public TextContent
{
  public:
                        Text(
                            const ::csv::String & i_sText );
                        Text(
                            const char *        i_sText );
                        ~Text();
  private:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const;
    // DATA
    ::csv::String         sText;
};

class XmlCode : public TextContent
{
  public:
                        XmlCode(
                            const ::csv::String & i_sText );
                        XmlCode(
                            const char *          i_sText );
                        ~XmlCode();
  private:
    virtual void        do_WriteOut(
                            csv::bostream &     io_aFile ) const;
    // DATA
    ::csv::String         sText;
};

// IMPLEMENTATION

inline void
Item::WriteOut( csv::bostream & io_aFile ) const
    { do_WriteOut(io_aFile); }

inline const ::csv::String &
Attribute::Name() const
    { return inq_Name(); }
inline const ::csv::String &
Attribute::Value() const
    { return inq_Value(); }

inline Element &
Element::operator<<( DYN Item * let_dpItem )
    { op_streamout(let_dpItem); return *this; }
inline Element &
Element::operator<<( const ::csv::String & let_drText )
    { op_streamout( new Text(let_drText) ); return *this; }
inline Element &
Element::operator<<( const char * let_drText )
    { op_streamout( new Text(let_drText) ); return *this; }
inline Element &
Element::operator<<( DYN Attribute * let_dpAttr )
    { op_streamout(let_dpAttr); return *this; }
inline Element &
Element::operator>>( DYN Element & let_drElement )
    { op_streamout(&let_drElement); return let_drElement; }
inline Item *
Element::SetContent( DYN Item * let_dpItem )
    { do_SetContent(let_dpItem); return let_dpItem; }

}   // namespace xml
}   // namespace csi

#endif
<|endoftext|>


<commit_before>#include "engineuwsgi.h"
#include "plugin.h"

#include <Cutelyst/application.h>
#include <Cutelyst/context.h>
#include <Cutelyst/response.h>
#include <Cutelyst/request.h>

#include <QPluginLoader>
#include <QFile>
#include <QUrl>
#include <QDebug>

extern struct uwsgi_server uwsgi;

using namespace Cutelyst;

EngineUwsgi::EngineUwsgi(QObject *parent) :
    Engine(parent),
    m_loader(0)
{
}

bool EngineUwsgi::loadApplication(const QString &path)
{
    if (m_loader) {
        delete m_loader->instance();
        delete m_loader;
    }

    m_loader = new QPluginLoader(path);
    if (m_loader->load()) {
        QObject *instance = m_loader->instance();
        if (instance) {
            Application *app = qobject_cast<Application *>(instance);
            if (app) {
                qDebug() << "Application"
                         << app->applicationName()
                         << "loaded.";
                return setupApplication(app);
            } else {
                qCritical() << "Could not create an instance of the application:" << instance;
            }
        } else {
            qCritical() << "Could not create an instance:" << path;
        }
    } else {
        qWarning() << "Failed to open app:" << m_loader->errorString();
    }
    return false;
}

void EngineUwsgi::finalizeBody(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(ctx->req()->connectionId());

    uwsgi_response_write_body_do(wsgi_req, res->body().data(), res->body().size());
}

void EngineUwsgi::processRequest(struct wsgi_request *wsgi_req)
{
    Request *request;
    QByteArray host(wsgi_req->host, wsgi_req->host_len);
    QByteArray path(wsgi_req->path_info, wsgi_req->path_info_len);
    QUrlQuery queryString(QByteArray(wsgi_req->query_string, wsgi_req->query_string_len));
    request = newRequest(wsgi_req,
                         wsgi_req->https_len ? "http" : "https",
                         host,
                         path,
                         queryString);

    QByteArray remote(wsgi_req->remote_addr, wsgi_req->remote_addr_len);

    QByteArray method(wsgi_req->method, wsgi_req->method_len);

    QByteArray protocol(wsgi_req->protocol, wsgi_req->protocol_len);

    QHash<QByteArray, QByteArray> headers;
    for (int i = 0; i < wsgi_req->var_cnt; i += 2) {
        if (wsgi_req->hvec[i].iov_len < 6) {
            continue;
        }

        if (!uwsgi_startswith((char *) wsgi_req->hvec[i].iov_base,
                              const_cast<char *>("HTTP_"), 5)) {
            QByteArray key((char *) wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
            QByteArray value((char *) wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
            headers.insert(httpCase(key), value);
        }
    }

    QByteArray remoteUser(wsgi_req->remote_user, wsgi_req->remote_user_len);

    QByteArray bodyArray;
    size_t remains = wsgi_req->post_cl;
    while(remains > 0) {
        ssize_t body_len = 0;
        char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768) , &body_len);
        if (!body || body == uwsgi.empty) {
            break;
        }

        bodyArray.append(body, body_len);
    }

    uint16_t remote_port_len;
    char *remote_port = uwsgi_get_var(wsgi_req, (char *) "REMOTE_PORT", 11, &remote_port_len);
    QByteArray remotePort(remote_port, remote_port_len);

    QFile *upload = new QFile;
    if (wsgi_req->post_file && !upload->open(wsgi_req->post_file, QIODevice::ReadOnly)) {
        qDebug() << "Could not open upload file";
    }

    setupRequest(request,
                 method,
                 protocol,
                 headers,
                 bodyArray,
                 remoteUser,
                 QHostAddress(remote.data()),
                 remotePort.toUInt(),
                 upload);

    handleRequest(request, new Response);
}

QByteArray EngineUwsgi::httpCase(const QByteArray &headerKey) const
{
    QByteArray ret;

    bool lastWasUnderscore = false;

    for (int i = 0 ; i < headerKey.size() ; ++i) {
        QChar buf = headerKey[i];
        if(i == 0 || lastWasUnderscore) {
            ret += buf.toUpper();
            lastWasUnderscore = false;
        } else  if (buf == '_') {
            ret += '-';
            lastWasUnderscore = true;
        } else {
            ret += buf.toLower();
            lastWasUnderscore = false;
        }
    }

    return ret;
}

void EngineUwsgi::finalizeHeaders(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(ctx->req()->connectionId());

    if (uwsgi_response_prepare_headers(wsgi_req,
                                       res->statusCode().data(),
                                       res->statusCode().size())) {
        return;
    }

    QMap<QByteArray, QByteArray> headers = ctx->res()->headers();
    QMap<QByteArray, QByteArray>::Iterator it = headers.begin();
    while (it != headers.end()) {
        QByteArray key = it.key();
        if (uwsgi_response_add_header(wsgi_req,
                                      key.data(),
                                      key.size(),
                                      it.value().data(),
                                      it.value().size())) {
            return;
        }
        ++it;
    }
}

bool EngineUwsgi::init()
{
    return true;
}

EngineUwsgi *engine;

extern "C" int uwsgi_cutelyst_init()
{
    uwsgi_log("Initializing Cutelyst plugin\n");

    engine = new EngineUwsgi;

    return 0;
}

extern "C" int uwsgi_cutelyst_request(struct wsgi_request *wsgi_req)
{
    // empty request ?
    if (!wsgi_req->uh->pktsize) {
        uwsgi_log( "Invalid request. skip.\n");
        goto clear;
    }

    // get uwsgi variables
    if (uwsgi_parse_vars(wsgi_req)) {
        uwsgi_log("Invalid request. skip.\n");
        goto clear;
    }

    engine->processRequest(wsgi_req);

clear:
    return UWSGI_OK;
}

extern "C" void uwsgi_cutelyst_init_apps()
{
    uwsgi_log("Cutelyst Init App\n");

    QString path(options.app);
    if (path.isEmpty()) {
        qCritical() << "Cytelyst Application was not set";
        return;
    }

    qDebug()  << "Loading" << path;
    if (!engine->loadApplication(path)) {
        qCritical() << "Could not load application:" << path;
        return;
    }

    // get the current app id
    int id = uwsgi_apps_cnt;

    // register a new app under a specific "mountpoint"
    uwsgi_add_app(id, CUTELYST_MODIFIER1, NULL, 0, NULL, NULL);
}
<commit_msg>Fix setting Content-Type with uwsgi<commit_after>#include "engineuwsgi.h"
#include "plugin.h"

#include <Cutelyst/application.h>
#include <Cutelyst/context.h>
#include <Cutelyst/response.h>
#include <Cutelyst/request.h>

#include <QPluginLoader>
#include <QFile>
#include <QUrl>
#include <QDebug>

extern struct uwsgi_server uwsgi;

using namespace Cutelyst;

EngineUwsgi::EngineUwsgi(QObject *parent) :
    Engine(parent),
    m_loader(0)
{
}

bool EngineUwsgi::loadApplication(const QString &path)
{
    if (m_loader) {
        delete m_loader->instance();
        delete m_loader;
    }

    m_loader = new QPluginLoader(path);
    if (m_loader->load()) {
        QObject *instance = m_loader->instance();
        if (instance) {
            Application *app = qobject_cast<Application *>(instance);
            if (app) {
                qDebug() << "Application"
                         << app->applicationName()
                         << "loaded.";
                return setupApplication(app);
            } else {
                qCritical() << "Could not create an instance of the application:" << instance;
            }
        } else {
            qCritical() << "Could not create an instance:" << path;
        }
    } else {
        qWarning() << "Failed to open app:" << m_loader->errorString();
    }
    return false;
}

void EngineUwsgi::finalizeBody(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(ctx->req()->connectionId());

    uwsgi_response_write_body_do(wsgi_req, res->body().data(), res->body().size());
}

void EngineUwsgi::processRequest(struct wsgi_request *wsgi_req)
{
    Request *request;
    QByteArray host(wsgi_req->host, wsgi_req->host_len);
    QByteArray path(wsgi_req->path_info, wsgi_req->path_info_len);
    QUrlQuery queryString(QByteArray(wsgi_req->query_string, wsgi_req->query_string_len));
    request = newRequest(wsgi_req,
                         wsgi_req->https_len ? "http" : "https",
                         host,
                         path,
                         queryString);

    QByteArray remote(wsgi_req->remote_addr, wsgi_req->remote_addr_len);

    QByteArray method(wsgi_req->method, wsgi_req->method_len);

    QByteArray protocol(wsgi_req->protocol, wsgi_req->protocol_len);

    QHash<QByteArray, QByteArray> headers;
    for (int i = 0; i < wsgi_req->var_cnt; i += 2) {
        if (wsgi_req->hvec[i].iov_len < 6) {
            continue;
        }

        if (!uwsgi_startswith((char *) wsgi_req->hvec[i].iov_base,
                              const_cast<char *>("HTTP_"), 5)) {
            QByteArray key((char *) wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
            QByteArray value((char *) wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
            headers.insert(httpCase(key), value);
        }
    }

    QByteArray contentType(wsgi_req->content_type, wsgi_req->content_type_len);
    if (!contentType.isNull()) {
        headers.insert("Content-Type", contentType);
    }

    QByteArray contentEncoding(wsgi_req->encoding, wsgi_req->encoding_len);
    if (!contentEncoding.isNull()) {
        headers.insert("Content-Encoding", contentEncoding);
    }

    QByteArray remoteUser(wsgi_req->remote_user, wsgi_req->remote_user_len);

    QByteArray bodyArray;
    size_t remains = wsgi_req->post_cl;
    while(remains > 0) {
        ssize_t body_len = 0;
        char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768) , &body_len);
        if (!body || body == uwsgi.empty) {
            break;
        }

        bodyArray.append(body, body_len);
    }

    uint16_t remote_port_len;
    char *remote_port = uwsgi_get_var(wsgi_req, (char *) "REMOTE_PORT", 11, &remote_port_len);
    QByteArray remotePort(remote_port, remote_port_len);

    QFile *upload = new QFile;
    if (wsgi_req->post_file && !upload->open(wsgi_req->post_file, QIODevice::ReadOnly)) {
        qDebug() << "Could not open upload file";
    }

    setupRequest(request,
                 method,
                 protocol,
                 headers,
                 bodyArray,
                 remoteUser,
                 QHostAddress(remote.data()),
                 remotePort.toUInt(),
                 upload);

    handleRequest(request, new Response);
}

QByteArray EngineUwsgi::httpCase(const QByteArray &headerKey) const
{
    QByteArray ret;

    bool lastWasUnderscore = false;

    for (int i = 0 ; i < headerKey.size() ; ++i) {
        QChar buf = headerKey[i];
        if(i == 0 || lastWasUnderscore) {
            ret += buf.toUpper();
            lastWasUnderscore = false;
        } else  if (buf == '_') {
            ret += '-';
            lastWasUnderscore = true;
        } else {
            ret += buf.toLower();
            lastWasUnderscore = false;
        }
    }

    return ret;
}

void EngineUwsgi::finalizeHeaders(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(ctx->req()->connectionId());

    if (uwsgi_response_prepare_headers(wsgi_req,
                                       res->statusCode().data(),
                                       res->statusCode().size())) {
        return;
    }

    QMap<QByteArray, QByteArray> headers = ctx->res()->headers();
    QMap<QByteArray, QByteArray>::Iterator it = headers.begin();
    while (it != headers.end()) {
        QByteArray key = it.key();
        if (uwsgi_response_add_header(wsgi_req,
                                      key.data(),
                                      key.size(),
                                      it.value().data(),
                                      it.value().size())) {
            return;
        }
        ++it;
    }
}

bool EngineUwsgi::init()
{
    return true;
}

EngineUwsgi *engine;

extern "C" int uwsgi_cutelyst_init()
{
    uwsgi_log("Initializing Cutelyst plugin\n");

    engine = new EngineUwsgi;

    return 0;
}

extern "C" int uwsgi_cutelyst_request(struct wsgi_request *wsgi_req)
{
    // empty request ?
    if (!wsgi_req->uh->pktsize) {
        uwsgi_log( "Invalid request. skip.\n");
        goto clear;
    }

    // get uwsgi variables
    if (uwsgi_parse_vars(wsgi_req)) {
        uwsgi_log("Invalid request. skip.\n");
        goto clear;
    }

    engine->processRequest(wsgi_req);

clear:
    return UWSGI_OK;
}

extern "C" void uwsgi_cutelyst_init_apps()
{
    uwsgi_log("Cutelyst Init App\n");

    QString path(options.app);
    if (path.isEmpty()) {
        qCritical() << "Cytelyst Application was not set";
        return;
    }

    qDebug()  << "Loading" << path;
    if (!engine->loadApplication(path)) {
        qCritical() << "Could not load application:" << path;
        return;
    }

    // get the current app id
    int id = uwsgi_apps_cnt;

    // register a new app under a specific "mountpoint"
    uwsgi_add_app(id, CUTELYST_MODIFIER1, NULL, 0, NULL, NULL);
}
<|endoftext|>


<commit_before><commit_msg>Include the separate tag argument in the __android_log_print() calls<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS dba17 (1.66.70); FILE MERGED 2004/09/20 14:51:02 fs 1.66.70.2: RESYNC: (1.66-1.67); FILE MERGED 2004/09/08 13:18:54 fs 1.66.70.1: #i33728# (approved by ssa) ImplCallEventListeners<commit_after><|endoftext|>


<commit_before>#include <ellis/codec/elm327.hpp>

#include <ctype.h>
#include <ellis/core/array_node.hpp>
#include <ellis/core/map_node.hpp>
#include <ellis/core/defs.hpp>
#include <ellis/core/err.hpp>
#include <ellis/core/system.hpp>
#include <ellis/private/codec/obd/pid.hpp>
#include <ellis/private/core/err.hpp>
#include <ellis/private/using.hpp>

namespace ellis {

using namespace obd;

/** Returns an integer value given a hex character (lowercase or uppercase). If
 * the given value is not a valid hex character, raise an exception.
 */
byte hex_val(byte val)
{
  if (val >= '0' && val <= '9') {
    return val - '0';
  }
  else if (val >= 'a' && val <= 'f') {
    return 0xA + val - 'a';
  }
  else if (val >= 'A' && val <= 'F') {
    return 0xA + val - 'A';
  }
  else {
    const string &msg = ELLIS_SSTRING("value " << val << "is not a valid hex char");
    MAKE_ELLIS_ERR(err_code::VALUE_NOT_HEX, msg);
  }
  assert(0);
}

elm327_decoder::elm327_decoder() :
  m_node(new node(type::ARRAY))
{
}

std::unique_ptr<node> elm327_decoder::make_obd_node(
    const byte *start, size_t bytecount)
{
  /* TODO: how to handle timestamps? */

  /* Make sure the input is formatted as:
   * AB CD EF ...
   * Where AB specifies the mode, CD specifies the pid, and EF ... are
   * between 1 and 4 space-separated hex pairs.
   */
  if (bytecount < 8) {
    return nullptr;
  }
  const byte *end = start + bytecount;
  for (const byte *p = start; p <= end - 2; p += 3) {
    if (! ( isxdigit(*p) && isxdigit(*(p+1)) ) ) {
      return nullptr;
    }
    if ((p < end-2) && (*(p+2) != ' ')) {
      return nullptr;
    }
  }

  const byte *p = start;
  uint16_t mode = 16*hex_val(*p) + hex_val(*(p+1));
  unique_ptr<string> mode_str = get_mode_string(mode);
  if (mode_str == nullptr) {
    return nullptr;
  }
  p += 3;

  uint16_t pid = 16*hex_val(*p) + hex_val(*(p+1));
  const char *pid_str = get_pid_string(pid);
  if (pid_str == nullptr) {
    return nullptr;
  }
  p += 3;

  uint32_t val = 0;
  uint32_t mul = 1;
  for (; p < end; p += 3) {
    val = val*mul + hex_val(*p);
    mul *= 16;
    val = val*mul + hex_val(*(p+1));
    mul *= 16;
  }
  /* decode_value expects values to be in the MSB, so for a 2-byte value, it
   * should look like:
   * BBBBXXXX
   * where BB are the value bytes that you care about.
   * However, the ELM327 would instead give bytes like this:
   * XXXXBBBB
   * So, compute the number of bytes we have and left-shift.
   */
  val <<= __builtin_clz(val);
  double dec_val = decode_value(pid, val);

  unique_ptr<node> m = unique_ptr<node>(new node(type::MAP));
  m->as_mutable_map().insert("mode", std::move(*mode_str));
  m->as_mutable_map().insert("pid", pid_str);
  m->as_mutable_map().insert("value", dec_val);

  return m;
}

decoding_status elm327_decoder::consume_buffer(
    const byte *buf,
    size_t *bytecount)
{
  if (bytecount == nullptr || *bytecount == 0) {
    return decoding_status::ERROR;
  }

  /* We assume that if there are multiple responses coming from the ELM327, then
   * they are separated by newlines.
   */
  const byte *start = buf;
  const byte *end = buf + *bytecount;
  const byte *last_newline = end;
  while (true) {
    const byte *p;
    for (p = start; p < end; p++) {
      if (*p == '\n') {
        last_newline = p;
        break;
      }
    }
    if (p == end) {
      break;
    }

    unique_ptr<node> node = make_obd_node(start, p - start);
    if (node == nullptr) {
      m_err.reset(
        new MAKE_ELLIS_ERR(err_code::PARSING_ERROR, "Failed to parse OBD II node"));
      return decoding_status::ERROR;
    }
    m_node->as_mutable_array().append(*node);

    start = p + 1;
  }

  if (last_newline < end-1) {
    *bytecount = end - last_newline;
    return decoding_status::CONTINUE;
  }

  *bytecount = 0;
  return decoding_status::END;
}

std::unique_ptr<node> elm327_decoder::extract_node()
{
  return std::move(m_node);
}

std::unique_ptr<err> elm327_decoder::extract_error()
{
  return std::move(m_err);
}

void elm327_decoder::reset()
{
  m_node->as_mutable_map().clear();
}

}  /* namespace ellis */
<commit_msg>elm327: use ELLIS_ASSERT_UNREACHABLE<commit_after>#include <ellis/codec/elm327.hpp>

#include <ctype.h>
#include <ellis/core/array_node.hpp>
#include <ellis/core/map_node.hpp>
#include <ellis/core/defs.hpp>
#include <ellis/core/err.hpp>
#include <ellis/core/system.hpp>
#include <ellis/private/codec/obd/pid.hpp>
#include <ellis/private/core/err.hpp>
#include <ellis/private/using.hpp>

namespace ellis {

using namespace obd;

/** Returns an integer value given a hex character (lowercase or uppercase). If
 * the given value is not a valid hex character, raise an exception.
 */
byte hex_val(byte val)
{
  if (val >= '0' && val <= '9') {
    return val - '0';
  }
  else if (val >= 'a' && val <= 'f') {
    return 0xA + val - 'a';
  }
  else if (val >= 'A' && val <= 'F') {
    return 0xA + val - 'A';
  }
  else {
    const string &msg = ELLIS_SSTRING("value " << val << "is not a valid hex char");
    MAKE_ELLIS_ERR(err_code::VALUE_NOT_HEX, msg);
  }
  ELLIS_ASSERT_UNREACHABLE();
}

elm327_decoder::elm327_decoder() :
  m_node(new node(type::ARRAY))
{
}

std::unique_ptr<node> elm327_decoder::make_obd_node(
    const byte *start, size_t bytecount)
{
  /* TODO: how to handle timestamps? */

  /* Make sure the input is formatted as:
   * AB CD EF ...
   * Where AB specifies the mode, CD specifies the pid, and EF ... are
   * between 1 and 4 space-separated hex pairs.
   */
  if (bytecount < 8) {
    return nullptr;
  }
  const byte *end = start + bytecount;
  for (const byte *p = start; p <= end - 2; p += 3) {
    if (! ( isxdigit(*p) && isxdigit(*(p+1)) ) ) {
      return nullptr;
    }
    if ((p < end-2) && (*(p+2) != ' ')) {
      return nullptr;
    }
  }

  const byte *p = start;
  uint16_t mode = 16*hex_val(*p) + hex_val(*(p+1));
  unique_ptr<string> mode_str = get_mode_string(mode);
  if (mode_str == nullptr) {
    return nullptr;
  }
  p += 3;

  uint16_t pid = 16*hex_val(*p) + hex_val(*(p+1));
  const char *pid_str = get_pid_string(pid);
  if (pid_str == nullptr) {
    return nullptr;
  }
  p += 3;

  uint32_t val = 0;
  uint32_t mul = 1;
  for (; p < end; p += 3) {
    val = val*mul + hex_val(*p);
    mul *= 16;
    val = val*mul + hex_val(*(p+1));
    mul *= 16;
  }
  /* decode_value expects values to be in the MSB, so for a 2-byte value, it
   * should look like:
   * BBBBXXXX
   * where BB are the value bytes that you care about.
   * However, the ELM327 would instead give bytes like this:
   * XXXXBBBB
   * So, compute the number of bytes we have and left-shift.
   */
  val <<= __builtin_clz(val);
  double dec_val = decode_value(pid, val);

  unique_ptr<node> m = unique_ptr<node>(new node(type::MAP));
  m->as_mutable_map().insert("mode", std::move(*mode_str));
  m->as_mutable_map().insert("pid", pid_str);
  m->as_mutable_map().insert("value", dec_val);

  return m;
}

decoding_status elm327_decoder::consume_buffer(
    const byte *buf,
    size_t *bytecount)
{
  if (bytecount == nullptr || *bytecount == 0) {
    return decoding_status::ERROR;
  }

  /* We assume that if there are multiple responses coming from the ELM327, then
   * they are separated by newlines.
   */
  const byte *start = buf;
  const byte *end = buf + *bytecount;
  const byte *last_newline = end;
  while (true) {
    const byte *p;
    for (p = start; p < end; p++) {
      if (*p == '\n') {
        last_newline = p;
        break;
      }
    }
    if (p == end) {
      break;
    }

    unique_ptr<node> node = make_obd_node(start, p - start);
    if (node == nullptr) {
      m_err.reset(
        new MAKE_ELLIS_ERR(err_code::PARSING_ERROR, "Failed to parse OBD II node"));
      return decoding_status::ERROR;
    }
    m_node->as_mutable_array().append(*node);

    start = p + 1;
  }

  if (last_newline < end-1) {
    *bytecount = end - last_newline;
    return decoding_status::CONTINUE;
  }

  *bytecount = 0;
  return decoding_status::END;
}

std::unique_ptr<node> elm327_decoder::extract_node()
{
  return std::move(m_node);
}

std::unique_ptr<err> elm327_decoder::extract_error()
{
  return std::move(m_err);
}

void elm327_decoder::reset()
{
  m_node->as_mutable_map().clear();
}

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