<commit_before>// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
template struct internal::basic_data<void>;
template internal::locale_ref::locale_ref(const std::locale &loc);

// Explicit instantiations for char.

template FMT_API char internal::thousands_sep_impl(locale_ref);

template void internal::basic_buffer<char>::append(const char *, const char *);

template void internal::arg_map<format_context>::init(
    const basic_format_args<format_context> &args);

template FMT_API int internal::char_traits<char>::format_float(
    char *, std::size_t, const char *, int, double);

template FMT_API int internal::char_traits<char>::format_float(
    char *, std::size_t, const char *, int, long double);

template FMT_API std::string internal::vformat<char>(
    string_view, basic_format_args<format_context>);

template format_context::iterator internal::vformat_to(
    internal::buffer &, string_view, basic_format_args<format_context>);

template FMT_API void internal::sprintf_format(
    double, internal::buffer &, core_format_specs);
template FMT_API void internal::sprintf_format(
    long double, internal::buffer &, core_format_specs);

// Explicit instantiations for wchar_t.

template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);

template void internal::basic_buffer<wchar_t>::append(
    const wchar_t *, const wchar_t *);

template void internal::arg_map<wformat_context>::init(
    const basic_format_args<wformat_context> &);

template FMT_API int internal::char_traits<wchar_t>::format_float(
    wchar_t *, std::size_t, const wchar_t *, int, double);

template FMT_API int internal::char_traits<wchar_t>::format_float(
    wchar_t *, std::size_t, const wchar_t *, int, long double);

template FMT_API std::wstring internal::vformat<wchar_t>(
    wstring_view, basic_format_args<wformat_context>);
FMT_END_NAMESPACE
<commit_msg>Fix link error in windows with shared library.<commit_after>// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
template struct internal::basic_data<void>;
template internal::locale_ref::locale_ref(const std::locale &loc);

// Explicit instantiations for char.

template FMT_API char internal::thousands_sep_impl(locale_ref);

template FMT_API void internal::basic_buffer<char>::append(const char *, const char *);

template void internal::arg_map<format_context>::init(
    const basic_format_args<format_context> &args);

template FMT_API int internal::char_traits<char>::format_float(
    char *, std::size_t, const char *, int, double);

template FMT_API int internal::char_traits<char>::format_float(
    char *, std::size_t, const char *, int, long double);

template FMT_API std::string internal::vformat<char>(
    string_view, basic_format_args<format_context>);

template format_context::iterator internal::vformat_to(
    internal::buffer &, string_view, basic_format_args<format_context>);

template FMT_API void internal::sprintf_format(
    double, internal::buffer &, core_format_specs);
template FMT_API void internal::sprintf_format(
    long double, internal::buffer &, core_format_specs);

// Explicit instantiations for wchar_t.

template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);

template void internal::basic_buffer<wchar_t>::append(
    const wchar_t *, const wchar_t *);

template void internal::arg_map<wformat_context>::init(
    const basic_format_args<wformat_context> &);

template FMT_API int internal::char_traits<wchar_t>::format_float(
    wchar_t *, std::size_t, const wchar_t *, int, double);

template FMT_API int internal::char_traits<wchar_t>::format_float(
    wchar_t *, std::size_t, const wchar_t *, int, long double);

template FMT_API std::wstring internal::vformat<wchar_t>(
    wstring_view, basic_format_args<wformat_context>);
FMT_END_NAMESPACE
<|endoftext|>


<commit_before>/* Reference documentation for libpqxx.
 *
 * Documentation is generated from header files.  This header is here only to
 * provide parts of that documentation.  There is no need to include it from
 * client code.
 *
 * Copyright 2001-2017, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */

/** @mainpage
 * @author Jeroen T. Vermeulen
 *
 * Welcome to libpqxx, the C++ API to the PostgreSQL database management system.
 *
 * Compiling this package requires PostgreSQL to be installed -- including the
 * C headers for client development.  The library builds on top of PostgreSQL's
 * standard C API, libpq.  The libpq headers are not needed to compile client
 * programs, however.
 *
 * For a quick introduction to installing and using libpqxx, see the README.md
 * file; a more extensive tutorial is available in doc/html/Tutorial/index.html.
 *
 * The latest information can be found at http://pqxx.org/
 *
 * Some links that should help you find your bearings:
 * \li \ref gettingstarted
 * \li \ref threading
 * \li \ref connection
 * \li \ref transaction
 * \li \ref performance
 * \li \ref transactor
 *
 * @see http://pqxx.org/
 */

/** @page gettingstarted Getting started
 * The most basic three types in libpqxx are the connection (which inherits its
 * API from pqxx::connection_base and its setup behaviour from
 * pqxx::connectionpolicy), the transaction (derived from
 * pqxx::transaction_base), and the result (pqxx::result).
 *
 * They fit together as follows:
 * \li You connect to the database by creating a
 * connection object (see \ref connection).  The connection type you'll usually
 * want is pqxx::connection.
 * \li You create a transaction object (see \ref transaction) operating on that
 * connection.  You'll usually want the pqxx::work variety.  If you don't want
 * transactional behaviour, use pqxx::nontransaction.  Once you're done you call
 * the transaction's @c commit function to make its work final.  If you don't
 * call this, the work will be rolled back when the transaction object is
 * destroyed.
 * \li Until then, use the transaction's @c exec() functions to execute
 * queries, which you pass in as simple strings.
 * \li Most of the @c exec() functions return a pqxx::result object, which acts
 * as a standard container of rows.  Each row in itself acts as a container of
 * fields.  You can use array indexing and/or iterators to access either.
 * \li The field's data is stored as a text string.  You can read it as such
 * using its @c c_str() function, or convert it to other types using its @c as()
 * and @c to() member functions.  These are templated on the destination type:
 * @c myfield.as<int>(); or @c myfield.to(myint);
 * \li After you've closed the transaction, the connection is free to run a next
 * transaction.
 *
 * Here's a very basic example.  It connects to the default database (you'll
 * need to have one set up), queries it for a very simple result, converts it to
 * an @c int, and prints it out.  It also contains some basic error handling.
 *
 * @code
 * #include <iostream>
 * #include <pqxx/pqxx>
 *
 * int main()
 * {
 *   try
 *   {
 *     // Connect to the database.  In practice we may have to pass some
 *     // arguments to say where the database server is, and so on.
 *     pqxx::connection c;
 *
 *     // Start a transaction.  In libpqxx, you always work in one.
 *     pqxx::work w(c);
 *
 *     // work::exec1() executes a query returning a single row of data.
 *     // We'll just ask the database to return the number 1 to us.
 *     pqxx::row r = w.exec1("SELECT 1");
 *
 *     // Commit your transaction.  If an exception occurred before this
 *     // point, execution will have left the block, and the transaction will
 *     // have been destroyed along the way.  In that case, the failed
 *     // transaction would implicitly abort instead of getting to this point.
 *     w.commit();
 *
 *     // Look at the first and only field in the row, parse it as an integer,
 *     // and print it.
 *     std::cout << r[0].as<int>() << std::endl;
 *   }
 *   catch (const std::exception &e)
 *   {
 *     std::cerr << e.what() << std::endl;
 *     return 1;
 *   }
 * }
 * @endcode
 *
 * This prints the number 1.  Notice that you can keep the result object
 * around after the transaction (or even the connection) has been closed.
 *
 * Here's a slightly more complicated example.  It takes an argument from the
 * command line and retrieves a string with that value.  The interesting part is
 * that it uses the escaping-and-quoting function @c quote() to embed this
 * string value in SQL safely.  It also reads the result field's value as a
 * plain C-style string using its @c c_str() function.
 *
 * @code
 * #include <iostream>
 * #include <stdexcept>
 * #include <pqxx/pqxx>
 *
 * int main(int argc, char *argv[])
 * {
 *   try
 *   {
 *     if (!argv[1]) throw std::runtime_error("Give me a string!");
 *
 *     pqxx::connection c;
 *     pqxx::work w(c);
 *
 *     // work::exec() returns a full result set, which can consist of any
 *     // number of rows.
 *     pqxx::result r = w.exec("SELECT " + w.quote(argv[1]));
 *
 *     // End our transaction here.  We can still use the result afterwards.
 *     w.commit();
 *
 *     // Print the first field of the first row.  Read it as a C string,
 *     // just like std::string::c_str() does.
 *     std::cout << r[0][0].c_str() << std::endl;
 *   }
 *   catch (const std::exception &e)
 *   {
 *     std::cerr << e.what() << std::endl;
 *     return 1;
 *   }
 * }
 * @endcode
 *
 * You can find more about converting field values to native types, or
 * converting values to strings for use with libpqxx, under
 * \ref stringconversion.  More about getting to the rows and fields of a
 * result is under \ref accessingresults.
 *
 * If you want to handle exceptions thrown by libpqxx in more detail, for
 * example to print the SQL contents of a query that failed, see \ref exception.
 */

/** @page accessingresults Accessing results and result rows
 *
 * Let's say you have a result object.  For example, your program may have done:
 *
 * @code
 * pqxx::result r = w.exec("SELECT * FROM mytable");
 * @endcode
 *
 * Now how do you access the data inside @c r?
 *
 * The simplest way is array indexing.  A result acts as an array of rows,
 * and a row acts as an array of fields.
 *
 * @code
 * const int num_rows = r.size();
 * for (int rownum=0; rownum < num_rows; ++rownum)
 * {
 *   const pqxx::row row = r[rownum];
 *   const int num_cols = row.size();
 *   for (int colnum=0; colnum < num_cols; ++colnum)
 *   {
 *     const pqxx::field field = row[colnum];
 *     std::cout << field.c_str() << '\t';
 *   }
 *
 *   std::cout << std::endl;
 * }
 * @endcode
 *
 * But results and rows also define @c const_iterator types:
 *
 * @code
 * for (const auto &row: r)
 *  {
 *    for (const auto &field: row) std::cout << field.c_str() << '\t';
 *    std::cout << std::endl;
 *  }
 * @endcode
 *
 * They also have @c const_reverse_iterator types, which iterate backwards from
 * @c rbegin() to @c rend() exclusive.
 *
 * All these iterator types provide one extra bit of convenience that you won't
 * normally find in C++ iterators: referential transparency.  You don't need to
 * dereference them to get to the row or field they refer to.  That is, instead
 * of @c row->end() you can also choose to say @c row.end().  Similarly, you
 * may prefer @c field.c_str() over @c field->c_str().
 *
 * This becomes really helpful with the array-indexing operator.  With regular
 * C++ iterators you would need ugly expressions like @c (*row)[0] or
 * @c row->operator[](0).  With the iterator types defined by the result and
 * row classes you can simply say @c row[0].
 */

/** @page threading Thread safety
 *
 * This library does not contain any locking code to protect objects against
 * simultaneous modification in multi-threaded programs.  Therefore it is up
 * to you, the user of the library, to ensure that your threaded client
 * programs perform no conflicting operations concurrently.
 *
 * Most of the time this isn't hard.  Result sets are immutable, so you can
 * share them between threads without problem.  The main rule is:
 *
 * \li Treat a connection, together with any and all objects related to it, as
 * a "world" of its own.  You should generally make sure that the same "world"
 * is never accessed by another thread while you're doing anything non-const
 * in there.
 *
 * That means: don't issue a query on a transaction while you're also opening
 * a subtransaction, don't access a cursor while you may also be committing,
 * and so on.
 *
 * In particular, cursors are tricky.  It's easy to perform a non-const
 * operation without noticing.  So, if you're going to share cursors or
 * cursor-related objects between threads, lock very conservatively!
 *
 * Use @c pqxx::describe_thread_safety to find out at runtime what level of
 * thread safety is implemented in your build and version of libpqxx.  It
 * returns a pqxx::thread_safety_model describing what you can and cannot rely
 * on.  A command-line utility @c tools/pqxxthreadsafety prints out the same
 * information.
 */
<commit_msg>Documentation: suggest easiest iterations first.<commit_after>/* Reference documentation for libpqxx.
 *
 * Documentation is generated from header files.  This header is here only to
 * provide parts of that documentation.  There is no need to include it from
 * client code.
 *
 * Copyright 2001-2017, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */

/** @mainpage
 * @author Jeroen T. Vermeulen
 *
 * Welcome to libpqxx, the C++ API to the PostgreSQL database management system.
 *
 * Compiling this package requires PostgreSQL to be installed -- including the
 * C headers for client development.  The library builds on top of PostgreSQL's
 * standard C API, libpq.  The libpq headers are not needed to compile client
 * programs, however.
 *
 * For a quick introduction to installing and using libpqxx, see the README.md
 * file; a more extensive tutorial is available in doc/html/Tutorial/index.html.
 *
 * The latest information can be found at http://pqxx.org/
 *
 * Some links that should help you find your bearings:
 * \li \ref gettingstarted
 * \li \ref threading
 * \li \ref connection
 * \li \ref transaction
 * \li \ref performance
 * \li \ref transactor
 *
 * @see http://pqxx.org/
 */

/** @page gettingstarted Getting started
 * The most basic three types in libpqxx are the connection (which inherits its
 * API from pqxx::connection_base and its setup behaviour from
 * pqxx::connectionpolicy), the transaction (derived from
 * pqxx::transaction_base), and the result (pqxx::result).
 *
 * They fit together as follows:
 * \li You connect to the database by creating a
 * connection object (see \ref connection).  The connection type you'll usually
 * want is pqxx::connection.
 * \li You create a transaction object (see \ref transaction) operating on that
 * connection.  You'll usually want the pqxx::work variety.  If you don't want
 * transactional behaviour, use pqxx::nontransaction.  Once you're done you call
 * the transaction's @c commit function to make its work final.  If you don't
 * call this, the work will be rolled back when the transaction object is
 * destroyed.
 * \li Until then, use the transaction's @c exec() functions to execute
 * queries, which you pass in as simple strings.
 * \li Most of the @c exec() functions return a pqxx::result object, which acts
 * as a standard container of rows.  Each row in itself acts as a container of
 * fields.  You can use array indexing and/or iterators to access either.
 * \li The field's data is stored as a text string.  You can read it as such
 * using its @c c_str() function, or convert it to other types using its @c as()
 * and @c to() member functions.  These are templated on the destination type:
 * @c myfield.as<int>(); or @c myfield.to(myint);
 * \li After you've closed the transaction, the connection is free to run a next
 * transaction.
 *
 * Here's a very basic example.  It connects to the default database (you'll
 * need to have one set up), queries it for a very simple result, converts it to
 * an @c int, and prints it out.  It also contains some basic error handling.
 *
 * @code
 * #include <iostream>
 * #include <pqxx/pqxx>
 *
 * int main()
 * {
 *   try
 *   {
 *     // Connect to the database.  In practice we may have to pass some
 *     // arguments to say where the database server is, and so on.
 *     pqxx::connection c;
 *
 *     // Start a transaction.  In libpqxx, you always work in one.
 *     pqxx::work w(c);
 *
 *     // work::exec1() executes a query returning a single row of data.
 *     // We'll just ask the database to return the number 1 to us.
 *     pqxx::row r = w.exec1("SELECT 1");
 *
 *     // Commit your transaction.  If an exception occurred before this
 *     // point, execution will have left the block, and the transaction will
 *     // have been destroyed along the way.  In that case, the failed
 *     // transaction would implicitly abort instead of getting to this point.
 *     w.commit();
 *
 *     // Look at the first and only field in the row, parse it as an integer,
 *     // and print it.
 *     std::cout << r[0].as<int>() << std::endl;
 *   }
 *   catch (const std::exception &e)
 *   {
 *     std::cerr << e.what() << std::endl;
 *     return 1;
 *   }
 * }
 * @endcode
 *
 * This prints the number 1.  Notice that you can keep the result object
 * around after the transaction (or even the connection) has been closed.
 *
 * Here's a slightly more complicated example.  It takes an argument from the
 * command line and retrieves a string with that value.  The interesting part is
 * that it uses the escaping-and-quoting function @c quote() to embed this
 * string value in SQL safely.  It also reads the result field's value as a
 * plain C-style string using its @c c_str() function.
 *
 * @code
 * #include <iostream>
 * #include <stdexcept>
 * #include <pqxx/pqxx>
 *
 * int main(int argc, char *argv[])
 * {
 *   try
 *   {
 *     if (!argv[1]) throw std::runtime_error("Give me a string!");
 *
 *     pqxx::connection c;
 *     pqxx::work w(c);
 *
 *     // work::exec() returns a full result set, which can consist of any
 *     // number of rows.
 *     pqxx::result r = w.exec("SELECT " + w.quote(argv[1]));
 *
 *     // End our transaction here.  We can still use the result afterwards.
 *     w.commit();
 *
 *     // Print the first field of the first row.  Read it as a C string,
 *     // just like std::string::c_str() does.
 *     std::cout << r[0][0].c_str() << std::endl;
 *   }
 *   catch (const std::exception &e)
 *   {
 *     std::cerr << e.what() << std::endl;
 *     return 1;
 *   }
 * }
 * @endcode
 *
 * You can find more about converting field values to native types, or
 * converting values to strings for use with libpqxx, under
 * \ref stringconversion.  More about getting to the rows and fields of a
 * result is under \ref accessingresults.
 *
 * If you want to handle exceptions thrown by libpqxx in more detail, for
 * example to print the SQL contents of a query that failed, see \ref exception.
 */

/** @page accessingresults Accessing results and result rows
 *
 * Let's say you have a result object.  For example, your program may have done:
 *
 * @code
 * pqxx::result r = w.exec("SELECT * FROM mytable");
 * @endcode
 *
 * Now how do you access the data inside @c r?
 *
 * Result sets act as standard C++ containers of rows.  Rows act as standard
 * C++ containers of fields.  So the easiest way to go through them is:
 *
 * @code
 * for (const auto &row: r)
 * {
 *    for (const auto &field: row) std::cout << field.c_str() << '\t';
 *    std::cout << std::endl;
 * }
 * @endcode
 *
 * But results and rows also support other kinds of access.  Array-style
 * indexing, for instance:
 *
 * @code
 * const int num_rows = r.size();
 * for (int rownum=0; rownum < num_rows; ++rownum)
 * {
 *   const pqxx::row row = r[rownum];
 *   const int num_cols = row.size();
 *   for (int colnum=0; colnum < num_cols; ++colnum)
 *   {
 *     const pqxx::field field = row[colnum];
 *     std::cout << field.c_str() << '\t';
 *   }
 *
 *   std::cout << std::endl;
 * }
 * @endcode
 *
 * And of course you can use classic "begin/end" loops:
 *
 * @code
 * for (auto row = r.begin(); row != r.end(); row++)
 * {
 *   for (auto field = row.begin(); field != row.end(); field++)
 *     std::cout << field->c_str() << '\t';
 *     std::cout << std::endl;
 * }
 * @endcode
 *
 * Result sets are immutable, so all iterators on results and rows are actually
 * @c const_iterators.  There are also @c const_reverse_iterator types, which
 * iterate backwards from @c rbegin() to @c rend() exclusive.
 *
 * All these iterator types provide one extra bit of convenience that you won't
 * normally find in C++ iterators: referential transparency.  You don't need to
 * dereference them to get to the row or field they refer to.  That is, instead
 * of @c row->end() you can also choose to say @c row.end().  Similarly, you
 * may prefer @c field.c_str() over @c field->c_str().
 *
 * This becomes really helpful with the array-indexing operator.  With regular
 * C++ iterators you would need ugly expressions like @c (*row)[0] or
 * @c row->operator[](0).  With the iterator types defined by the result and
 * row classes you can simply say @c row[0].
 */

/** @page threading Thread safety
 *
 * This library does not contain any locking code to protect objects against
 * simultaneous modification in multi-threaded programs.  Therefore it is up
 * to you, the user of the library, to ensure that your threaded client
 * programs perform no conflicting operations concurrently.
 *
 * Most of the time this isn't hard.  Result sets are immutable, so you can
 * share them between threads without problem.  The main rule is:
 *
 * \li Treat a connection, together with any and all objects related to it, as
 * a "world" of its own.  You should generally make sure that the same "world"
 * is never accessed by another thread while you're doing anything non-const
 * in there.
 *
 * That means: don't issue a query on a transaction while you're also opening
 * a subtransaction, don't access a cursor while you may also be committing,
 * and so on.
 *
 * In particular, cursors are tricky.  It's easy to perform a non-const
 * operation without noticing.  So, if you're going to share cursors or
 * cursor-related objects between threads, lock very conservatively!
 *
 * Use @c pqxx::describe_thread_safety to find out at runtime what level of
 * thread safety is implemented in your build and version of libpqxx.  It
 * returns a pqxx::thread_safety_model describing what you can and cannot rely
 * on.  A command-line utility @c tools/pqxxthreadsafety prints out the same
 * information.
 */
<|endoftext|>


<commit_before>#include "hsApp.h"

//--------------------------------------------------------------
void hsApp::setup()
{
	//ofBackground(34, 34, 34);
	ofSetVerticalSync(true);

	widthi = 512;
	widthf = widthi;

	mesh.setMode(OF_PRIMITIVE_POINTS);

	for(int y = 0; y < widthi; y++ )
	{
		for(int x = 0; x < widthi; x++ )
		{
			ofFloatColor color(x/widthf,y/widthf,1.f,0.5f);
			mesh.addColor(color);
			ofVec3f pos(x-widthf/2.f, y-widthf/2.f, 0);
			mesh.addVertex(pos);
		}
	}

	ofEnableDepthTest();
	glEnable(GL_POINT_SMOOTH); // use circular points instead of square points
	glPointSize(2); // make the points bigger

	// 2 output channels,
	// 0 input channels
	// 44100 samples per second
	// 512 samples per buffer
	// 4 num buffers (latency)

	int bufferSize		= 512;
	sampleRate 			= 44100;

	phase1				= 0;
	phase2				= 0;
	phase3				= 0;

	shape1				= 0;
	shape2				= 0;
	shape3				= 0;

	freeze1				= 0;
	freeze2				= 0;
	freeze3				= 0;

	phaseAdder 			= 0.0f;
	volume				= 0.2f;
	bNoise 				= false;

	voice1.assign(bufferSize, 0.0);
	voice2.assign(bufferSize, 0.0);
	voice3.assign(bufferSize, 0.0);

	voices.push_back(&voice1);
	voices.push_back(&voice2);
	voices.push_back(&voice3);

	frequency = targetFrequency = 110;
	numerator1 = numerator2 = 2;
	denominator1 = denominator2 = 3;
	rotator = 0;

	//soundStream.listDevices();

	//if you want to set the device id to be different than the default
	//soundStream.setDeviceID(1); 	//note some devices are input only and some are output only

	soundStream.setup(this, 2, 0, sampleRate, bufferSize, 4);

	//

	plotHeight = 100;

	//fft = ofxFft::create(bufferSize, OF_FFT_WINDOW_HAMMING, OF_FFT_FFTW);
	fft = ofxFft::create(bufferSize, OF_FFT_WINDOW_HAMMING);

	drawBins.resize(fft->getBinSize());
	middleBins.resize(fft->getBinSize());
	audioBins.resize(fft->getBinSize());

	ofSetFrameRate(30);
}

//--------------------------------------------------------------
void hsApp::update()
{
}

//--------------------------------------------------------------
void hsApp::draw()
{
	ofBackground(34, 34, 34);

	int W = (ofGetWidth()-64.f)/2.f;
	int H = 100;

	vector<ofVec3f>& verts = mesh.getVertices();
	vector<ofFloatColor>& color = mesh.getColors();

	for(unsigned int i = 0; i < verts.size(); i++)
	{
		int j = ofMap(i, 0, verts.size(), 0, widthf);

		verts[i].x = voice1[j] * W;
		verts[i].y = voice2[j] * W;
		verts[i].z = voice3[j] * W;

		color[i].r = 1.f - voice1[j];
		color[i].g = 1.f - voice2[j];
		color[i].b = 1.f - voice3[j];
	}

	ofPushMatrix();
	ofTranslate(32+W/2+ofGetWidth()/2, 450, 0);
	ofRotateY(pan*360);
	ofRotateX(rotator);
	rotator += 0.1f;
	mesh.draw();
	ofPopMatrix();

	//

	ofSetColor(225);
	ofDrawBitmapString("HyperScope", 32, 32);
	ofDrawBitmapString("press 'z' to unpause the audio, press 'x' to pause the audio", 32, 92);

	ofNoFill();

	// draw voices

	ofPushStyle();
	ofPushMatrix();
	ofTranslate(32, 150, 0);

	for(vector<float>::size_type i = 0; i != voices.size(); i++)
	{
		vector<float> voice = *voices[i];

		ofSetColor(225);
		ofDrawBitmapString("Voice " + ofToString(i+1), 4, 18);

		ofSetLineWidth(1);
		ofRect(0, 0, W, H);

		ofSetColor(245, 58, 135);
		ofBeginShape();
		for (unsigned int j = 0; j < voice.size(); j++)
		{
			float x = ofMap(j, 0, voice.size(), 0, W, true);
			ofVertex(x, H/2 - voice[j]*80.0f);
		}
		ofEndShape(false);

		ofTranslate(0, H, 0);
	}

	ofPopMatrix();
	ofPopStyle();

	// draw output

	ofPushStyle();
	ofPushMatrix();
	ofTranslate(32, 450, 0);

	ofSetColor(225);
	ofDrawBitmapString("Output", 4, 18);

	ofSetLineWidth(1);
	ofRect(0, 0, W, 100);

	ofSetColor(245, 58, 135);
	ofSetLineWidth(1);

	ofBeginShape();
	for (unsigned int i = 0; i < voice3.size(); i++)
	{
		float x =  ofMap(i, 0, voice3.size(), 0, W, true);
		ofVertex(x, 50 -(voice1[i]+voice2[i]+voice3[i])*80.0f);
	}
	ofEndShape(false);

	ofPopMatrix();
	ofPopStyle();

	// again

	ofPushStyle();
	ofPushMatrix();
	ofTranslate(32+W/2+ofGetWidth()/2, 250, 0);
	ofRotateY(pan*360);
	ofRotateX(rotator);

	ofSetColor(245, 58, 135);
	ofSetLineWidth(1);

	ofBeginShape();
	for (unsigned int i = 0; i < voice3.size(); i++)
	{
		ofVertex(voice1[i]*W, voice2[i]*W, voice3[i]*W);
	}
	ofEndShape(false);

	ofPopMatrix();
	ofPopStyle();

	// draw info

	ofSetColor(225);
	string reportString = "volume: ("+ofToString(volume, 2)+") modify with -/+ keys\n";//pan: ("+ofToString(pan, 2)+") modify with mouse x\nsynthesis: ";
	if( !bNoise )
	{
		reportString += "sine wave (" + ofToString(frequency, 2) + " > " + ofToString(targetFrequency, 2) + "hz) modify with mouse y";
	}
	else
	{
		reportString += "noise";
	}
	reportString += "\nratios = " + ofToString(numerator1) + ":" + ofToString(denominator1) + ", " + ofToString(numerator2) + ":" + ofToString(denominator2);

	reportString += "\nchange ratios: 'q/a':'w/s', 'e/d':'r/f'";
	reportString += "\nchange waveforms: 'y/h/n'";
	reportString += "\nfreeze waveforms: 'u/j/m'";

	ofDrawBitmapString(reportString, 32, 579);

	// fft

	ofSetColor(255);
	ofPushMatrix();
	ofTranslate(ofGetWidth() - (256+16), ofGetHeight() - 116);

	soundMutex.lock();
	drawBins = middleBins;
	soundMutex.unlock();

	ofDrawBitmapString("Frequency Domain", 0, 0);
	plot(drawBins, -plotHeight, plotHeight / 2);
	ofPopMatrix();
	//string msg = ofToString((int) ofGetFrameRate()) + " fps";
	//ofDrawBitmapString(msg, ofGetWidth() - 80, ofGetHeight() - 20);
}

//--------------------------------------------------------------
void hsApp::plot(vector<float>& buffer, float scale, float offset)
{
	ofNoFill();
	int n = buffer.size()/2;
	ofRect(0, 0, n, plotHeight);
	glPushMatrix();
	glTranslatef(0, plotHeight / 2 + offset, 0);
	ofBeginShape();
	for (int i = 0; i < n; i++)
	{
		ofVertex(i, sqrt(buffer[i]) * scale);
	}
	ofEndShape();
	glPopMatrix();
}

//--------------------------------------------------------------
void hsApp::keyPressed  (int key)
{
	if (key == '-' || key == '_' )
	{
		volume -= 0.05;
		volume = MAX(volume, 0);
	}
	else if (key == '+' || key == '=' )
	{
		volume += 0.05;
		volume = MIN(volume, 1);
	}

	if( key == 'z' )
	{
		soundStream.start();
	}

	if( key == 'x' )
	{
		soundStream.stop();
	}

	if( key == 'a' )
	{
		numerator1--;
		if( numerator1 < 1 ) numerator1 = 1;
	}

	if( key == 'q' )
	{
		numerator1++;
	}

	if( key == 's' )
	{
		denominator1--;
		if( denominator1 < 1 ) denominator1 = 1;
	}

	if( key == 'w' )
	{
		denominator1++;
	}

	if( key == 'd' )
	{
		numerator2--;
		if( numerator2 < 1 ) numerator2 = 1;
	}

	if( key == 'e' )
	{
		numerator2++;
	}

	if( key == 'f' )
	{
		denominator2--;
		if( denominator2 < 1 ) denominator2 = 1;
	}

	if( key == 'r' )
	{
		denominator2++;
	}

	int N_SHAPES = 3;

	if( key == 'y' )
	{
		shape1 = (shape1 + 1) % N_SHAPES;
	}
	if( key == 'h' )
	{
		shape2 = (shape2 + 1) % N_SHAPES;
	}
	if( key == 'n' )
	{
		shape3 = (shape3 + 1) % N_SHAPES;
	}

	if( key == 'u' )
	{
		freeze1 = freeze1 ? 0 : 1;
	}
	if( key == 'j' )
	{
		freeze2 = freeze2 ? 0 : 1;
	}
	if( key == 'm' )
	{
		freeze3 = freeze3 ? 0 : 1;
	}

}

//--------------------------------------------------------------
void hsApp::keyReleased  (int key)
{
}

//--------------------------------------------------------------
void hsApp::mouseMoved(int x, int y )
{
	int width = ofGetWidth();
	pan = (float)x / (float)width;
	float height = (float)ofGetHeight();
	targetFrequency = 27.f * (height-y);
}

//--------------------------------------------------------------
void hsApp::mouseDragged(int x, int y, int button)
{
	int width = ofGetWidth();
	pan = (float)x / (float)width;
}

//--------------------------------------------------------------
void hsApp::mousePressed(int x, int y, int button)
{
	//bNoise = true;
}

//--------------------------------------------------------------
void hsApp::mouseReleased(int x, int y, int button)
{
	//bNoise = false;
}

//--------------------------------------------------------------
void hsApp::windowResized(int w, int h)
{
}

//--------------------------------------------------------------
void hsApp::audioOut(float * output, int bufferSize, int nChannels)
{
	while (phase1 > TWO_PI)
	{
		phase1 -= TWO_PI;
	}
	while (phase2 > TWO_PI)
	{
		phase2 -= TWO_PI;
	}
	while (phase3 > TWO_PI)
	{
		phase3 -= TWO_PI;
	}

	if ( bNoise == true)
	{
		// ---------------------- noise --------------
		for (int i = 0; i < bufferSize; i++)
		{
			voice1[i] = ofRandom(0, 1) * volume;
			voice2[i] = ofRandom(0, 1) * volume;
			voice3[i] = ofRandom(0, 1) * volume;

			output[i*nChannels] = output[i*nChannels + 1] = voice1[i] + voice2[i] + voice3[i];
		}
	}
	else
	{
		frequency = 0.98f * frequency + 0.02f * targetFrequency;
		phaseAdder = (frequency / (float) sampleRate) * TWO_PI;

		for (int i = 0; i < bufferSize; i++)
		{
			phase1 += freeze1 ? 0 : phaseAdder;
			phase2 += freeze2 ? 0 : phaseAdder*float(numerator1)/float(denominator1);
			phase3 += freeze3 ? 0 : (phaseAdder*float(numerator1)/float(denominator1))*float(numerator2)/float(denominator2);

			// sine wave
			float sample1 = sin(phase1);
			float sample2 = sin(phase2);
			float sample3 = sin(phase3);

			// square wave
			if( shape1 == 1 ) sample1 = sample1 > 0 ? 1 : -1;
			if( shape2 == 1 ) sample2 = sample2 > 0 ? 1 : -1;
			if( shape3 == 1 ) sample3 = sample3 > 0 ? 1 : -1;

			// sawtooth wave
			if( shape1 == 2 ) sample1 = (fmodf(phase1,TWO_PI) - PI)/2.f;
			if( shape2 == 2 ) sample2 = (fmodf(phase2,TWO_PI) - PI)/2.f;
			if( shape3 == 2 ) sample3 = (fmodf(phase3,TWO_PI) - PI)/2.f;

			// scale by volume
			voice1[i] = sample1 * volume;
			voice2[i] = sample2 * volume;
			voice3[i] = sample3 * volume;

			output[i*nChannels] = output[i*nChannels + 1] = voice1[i] + voice2[i] + voice3[i];
		}
	}

	// fft

	fft->setSignal(output);

	float* curFft = fft->getAmplitude();
	memcpy(&audioBins[0], curFft, sizeof(float) * fft->getBinSize());

	soundMutex.lock();
	middleBins = audioBins;
	soundMutex.unlock();
}

//--------------------------------------------------------------
void hsApp::gotMessage(ofMessage msg)
{
}

//--------------------------------------------------------------
void hsApp::dragEvent(ofDragInfo dragInfo)
{
}
<commit_msg>new layout<commit_after>#include "hsApp.h"

//--------------------------------------------------------------
void hsApp::setup()
{
	//ofBackground(34, 34, 34);
	ofSetVerticalSync(true);

	widthi = 512;
	widthf = widthi;

	mesh.setMode(OF_PRIMITIVE_POINTS);

	for(int y = 0; y < widthi; y++ )
	{
		for(int x = 0; x < widthi; x++ )
		{
			ofFloatColor color(x/widthf,y/widthf,1.f,0.5f);
			mesh.addColor(color);
			ofVec3f pos(x-widthf/2.f, y-widthf/2.f, 0);
			mesh.addVertex(pos);
		}
	}

	ofEnableDepthTest();
	glEnable(GL_POINT_SMOOTH); // use circular points instead of square points
	glPointSize(2); // make the points bigger

	// 2 output channels,
	// 0 input channels
	// 44100 samples per second
	// 512 samples per buffer
	// 4 num buffers (latency)

	int bufferSize		= 512;
	sampleRate 			= 44100;

	phase1				= 0;
	phase2				= 0;
	phase3				= 0;

	shape1				= 0;
	shape2				= 0;
	shape3				= 0;

	freeze1				= 0;
	freeze2				= 0;
	freeze3				= 0;

	phaseAdder 			= 0.0f;
	volume				= 0.2f;
	bNoise 				= false;

	voice1.assign(bufferSize, 0.0);
	voice2.assign(bufferSize, 0.0);
	voice3.assign(bufferSize, 0.0);

	voices.push_back(&voice1);
	voices.push_back(&voice2);
	voices.push_back(&voice3);

	frequency = targetFrequency = 110;
	numerator1 = numerator2 = 2;
	denominator1 = denominator2 = 3;
	rotator = 0;

	//soundStream.listDevices();

	//if you want to set the device id to be different than the default
	//soundStream.setDeviceID(1); 	//note some devices are input only and some are output only

	soundStream.setup(this, 2, 0, sampleRate, bufferSize, 4);

	//

	plotHeight = 100;

	//fft = ofxFft::create(bufferSize, OF_FFT_WINDOW_HAMMING, OF_FFT_FFTW);
	fft = ofxFft::create(bufferSize, OF_FFT_WINDOW_HAMMING);

	drawBins.resize(fft->getBinSize());
	middleBins.resize(fft->getBinSize());
	audioBins.resize(fft->getBinSize());

	ofSetFrameRate(30);
}

//--------------------------------------------------------------
void hsApp::update()
{
}

//--------------------------------------------------------------
void hsApp::draw()
{
	ofBackground(34, 34, 34);

	int W = 256;
	int H = 64;

	vector<ofVec3f>& verts = mesh.getVertices();
	vector<ofFloatColor>& color = mesh.getColors();

	for(unsigned int i = 0; i < verts.size(); i++)
	{
		int j = ofMap(i, 0, verts.size(), 0, widthf);

		verts[i].x = voice1[j] * W;
		verts[i].y = voice2[j] * W;
		verts[i].z = voice3[j] * W;

		color[i].r = 1.f - voice1[j];
		color[i].g = 1.f - voice2[j];
		color[i].b = 1.f - voice3[j];
	}

	ofPushMatrix();
	ofTranslate(512, 528, 0);
	ofRotateY(pan*360);
	ofRotateX(rotator);
	rotator += 0.1f;
	mesh.draw();
	ofPopMatrix();

	//

	ofSetColor(225);
	ofDrawBitmapString("HyperScope", 64, 64);
//	ofDrawBitmapString("press 'z' to unpause the audio, press 'x' to pause the audio", 32, 92);

	ofNoFill();

	// draw voices

	ofPushStyle();
	ofPushMatrix();
	ofTranslate(64, 128, 0);

	for(vector<float>::size_type i = 0; i != voices.size(); i++)
	{
		vector<float> voice = *voices[i];

		ofSetColor(225);
		ofDrawBitmapString("Voice " + ofToString(i+1), 4, 18);

		ofSetLineWidth(1);
		//ofRect(0, 0, W, H);

		ofSetColor(245, 58, 135);
		ofBeginShape();
		for (unsigned int j = 0; j < voice.size(); j++)
		{
			float x = ofMap(j, 0, voice.size(), 0, W, true);
			ofVertex(x, H/2 - voice[j]*80.0f);
		}
		ofEndShape(false);

		ofTranslate(0, H, 0);
	}

	ofPopMatrix();
	ofPopStyle();

	// draw output

	ofPushStyle();
	ofPushMatrix();
	ofTranslate(64, 368, 0);

	ofSetColor(225);
	ofDrawBitmapString("Output", 4, 18);

	ofSetLineWidth(1);
	//ofRect(0, 0, W, 100);

	ofSetColor(245, 58, 135);
	ofSetLineWidth(1);

	ofBeginShape();
	for (unsigned int i = 0; i < voice3.size(); i++)
	{
		float x =  ofMap(i, 0, voice3.size(), 0, W, true);
		ofVertex(x, H/2 -(voice1[i]+voice2[i]+voice3[i])*80.0f);
	}
	ofEndShape(false);

	ofPopMatrix();
	ofPopStyle();

	// again

	ofPushStyle();
	ofPushMatrix();
	ofTranslate(512, 256, 0);
	ofRotateY(pan*360);
	ofRotateX(rotator);

	ofSetColor(245, 58, 135);
	ofSetLineWidth(1);

	ofBeginShape();
	for (unsigned int i = 0; i < voice3.size(); i++)
	{
		ofVertex(voice1[i]*W, voice2[i]*W, voice3[i]*W);
	}
	ofEndShape(false);

	ofPopMatrix();
	ofPopStyle();

	// draw info

	ofSetColor(225);
	string reportString = "volume: ("+ofToString(volume, 2)+") modify with -/+ keys\n";//pan: ("+ofToString(pan, 2)+") modify with mouse x\nsynthesis: ";
	if( !bNoise )
	{
		reportString += "sine wave (" + ofToString(frequency, 2) + " > " + ofToString(targetFrequency, 2) + "hz) modify with mouse y";
	}
	else
	{
		reportString += "noise";
	}
	reportString += "\nratios = " + ofToString(numerator1) + ":" + ofToString(denominator1) + ", " + ofToString(numerator2) + ":" + ofToString(denominator2);

	reportString += "\nchange ratios: 'q/a':'w/s', 'e/d':'r/f'";
	reportString += "\nchange waveforms: 'y/h/n'";
	reportString += "\nfreeze waveforms: 'u/j/m'";

	ofDrawBitmapString(reportString, 32, 579);

	// fft

	ofSetColor(255);
	ofPushMatrix();
	ofTranslate(704, 128);

	soundMutex.lock();
	drawBins = middleBins;
	soundMutex.unlock();

	ofDrawBitmapString("Frequency Domain", 4, 18);
	plot(drawBins, -plotHeight, plotHeight / 2);
	ofPopMatrix();
	//string msg = ofToString((int) ofGetFrameRate()) + " fps";
	//ofDrawBitmapString(msg, ofGetWidth() - 80, ofGetHeight() - 20);
}

//--------------------------------------------------------------
void hsApp::plot(vector<float>& buffer, float scale, float offset)
{
	ofNoFill();
	int n = buffer.size()/2;
	//ofRect(0, 0, n, plotHeight);
	glPushMatrix();
	glTranslatef(0, plotHeight / 2 + offset, 0);
	ofBeginShape();
	for (int i = 0; i < n; i++)
	{
		ofVertex(i, sqrt(buffer[i]) * scale);
	}
	ofEndShape();
	glPopMatrix();
}

//--------------------------------------------------------------
void hsApp::keyPressed  (int key)
{
	if (key == '-' || key == '_' )
	{
		volume -= 0.05;
		volume = MAX(volume, 0);
	}
	else if (key == '+' || key == '=' )
	{
		volume += 0.05;
		volume = MIN(volume, 1);
	}

	if( key == 'z' )
	{
		soundStream.start();
	}

	if( key == 'x' )
	{
		soundStream.stop();
	}

	if( key == 'a' )
	{
		numerator1--;
		if( numerator1 < 1 ) numerator1 = 1;
	}

	if( key == 'q' )
	{
		numerator1++;
	}

	if( key == 's' )
	{
		denominator1--;
		if( denominator1 < 1 ) denominator1 = 1;
	}

	if( key == 'w' )
	{
		denominator1++;
	}

	if( key == 'd' )
	{
		numerator2--;
		if( numerator2 < 1 ) numerator2 = 1;
	}

	if( key == 'e' )
	{
		numerator2++;
	}

	if( key == 'f' )
	{
		denominator2--;
		if( denominator2 < 1 ) denominator2 = 1;
	}

	if( key == 'r' )
	{
		denominator2++;
	}

	int N_SHAPES = 3;

	if( key == 'y' )
	{
		shape1 = (shape1 + 1) % N_SHAPES;
	}
	if( key == 'h' )
	{
		shape2 = (shape2 + 1) % N_SHAPES;
	}
	if( key == 'n' )
	{
		shape3 = (shape3 + 1) % N_SHAPES;
	}

	if( key == 'u' )
	{
		freeze1 = freeze1 ? 0 : 1;
	}
	if( key == 'j' )
	{
		freeze2 = freeze2 ? 0 : 1;
	}
	if( key == 'm' )
	{
		freeze3 = freeze3 ? 0 : 1;
	}

}

//--------------------------------------------------------------
void hsApp::keyReleased  (int key)
{
}

//--------------------------------------------------------------
void hsApp::mouseMoved(int x, int y )
{
	int width = ofGetWidth();
	pan = (float)x / (float)width;
	float height = (float)ofGetHeight();
	targetFrequency = 27.f * (height-y);
}

//--------------------------------------------------------------
void hsApp::mouseDragged(int x, int y, int button)
{
	int width = ofGetWidth();
	pan = (float)x / (float)width;
}

//--------------------------------------------------------------
void hsApp::mousePressed(int x, int y, int button)
{
	//bNoise = true;
}

//--------------------------------------------------------------
void hsApp::mouseReleased(int x, int y, int button)
{
	//bNoise = false;
}

//--------------------------------------------------------------
void hsApp::windowResized(int w, int h)
{
}

//--------------------------------------------------------------
void hsApp::audioOut(float * output, int bufferSize, int nChannels)
{
	while (phase1 > TWO_PI)
	{
		phase1 -= TWO_PI;
	}
	while (phase2 > TWO_PI)
	{
		phase2 -= TWO_PI;
	}
	while (phase3 > TWO_PI)
	{
		phase3 -= TWO_PI;
	}

	if ( bNoise == true)
	{
		// ---------------------- noise --------------
		for (int i = 0; i < bufferSize; i++)
		{
			voice1[i] = ofRandom(0, 1) * volume;
			voice2[i] = ofRandom(0, 1) * volume;
			voice3[i] = ofRandom(0, 1) * volume;

			output[i*nChannels] = output[i*nChannels + 1] = voice1[i] + voice2[i] + voice3[i];
		}
	}
	else
	{
		frequency = 0.98f * frequency + 0.02f * targetFrequency;
		phaseAdder = (frequency / (float) sampleRate) * TWO_PI;

		for (int i = 0; i < bufferSize; i++)
		{
			phase1 += freeze1 ? 0 : phaseAdder;
			phase2 += freeze2 ? 0 : phaseAdder*float(numerator1)/float(denominator1);
			phase3 += freeze3 ? 0 : (phaseAdder*float(numerator1)/float(denominator1))*float(numerator2)/float(denominator2);

			// sine wave
			float sample1 = sin(phase1);
			float sample2 = sin(phase2);
			float sample3 = sin(phase3);

			// square wave
			if( shape1 == 1 ) sample1 = sample1 > 0 ? 1 : -1;
			if( shape2 == 1 ) sample2 = sample2 > 0 ? 1 : -1;
			if( shape3 == 1 ) sample3 = sample3 > 0 ? 1 : -1;

			// sawtooth wave
			if( shape1 == 2 ) sample1 = (fmodf(phase1,TWO_PI) - PI)/2.f;
			if( shape2 == 2 ) sample2 = (fmodf(phase2,TWO_PI) - PI)/2.f;
			if( shape3 == 2 ) sample3 = (fmodf(phase3,TWO_PI) - PI)/2.f;

			// scale by volume
			voice1[i] = sample1 * volume;
			voice2[i] = sample2 * volume;
			voice3[i] = sample3 * volume;

			output[i*nChannels] = output[i*nChannels + 1] = voice1[i] + voice2[i] + voice3[i];
		}
	}

	// fft

	fft->setSignal(output);

	float* curFft = fft->getAmplitude();
	memcpy(&audioBins[0], curFft, sizeof(float) * fft->getBinSize());

	soundMutex.lock();
	middleBins = audioBins;
	soundMutex.unlock();
}

//--------------------------------------------------------------
void hsApp::gotMessage(ofMessage msg)
{
}

//--------------------------------------------------------------
void hsApp::dragEvent(ofDragInfo dragInfo)
{
}
<|endoftext|>


<commit_before>/*******************************************************************************
Copyright (c) 2014, Jan Koester jan.koester@gmx.net
All rights reserved.

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 the <organization> 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 <COPYRIGHT HOLDER> 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 <cstring>
#include <cstdlib>

#include "os/os.h"
#include "utils.h"
#include "httpd.h"

#define KTKEY 0
#define KTSKEY 1

libhttppp::HTTPDCmd::HTTPDCmd() {
    _Key = NULL;
    _SKey = '\0';
    _Value = NULL;
    _Help = NULL;
    _Found = false;
    _Required = false;
    _nextHTTPDCmd = NULL;
}

const char *libhttppp::HTTPDCmd::getKey() {
    return _Key;
}

const char libhttppp::HTTPDCmd::getShortkey() {
    return _SKey;
}

const char *libhttppp::HTTPDCmd::getValue() {
    return _Value;
}

size_t libhttppp::HTTPDCmd::getValueSize_t() {
    return atoi(_Value);
}

int libhttppp::HTTPDCmd::getValueInt() {
    return atoi(_Value);
}

const char *libhttppp::HTTPDCmd::getHelp() {
    return _Help;
}

bool libhttppp::HTTPDCmd::getFound() {
    return _Found;
}

bool libhttppp::HTTPDCmd::getRequired() {
    return _Required;
}

libhttppp::HTTPDCmd *libhttppp::HTTPDCmd::nextHTTPDCmd() {
    return _nextHTTPDCmd;
}

libhttppp::HTTPDCmd::~HTTPDCmd() {
    delete[] _Key;
    delete[] _Value;
    delete[] _Help;
    delete _nextHTTPDCmd;
}

libhttppp::HTTPDCmdController::HTTPDCmdController() {
    _firstHTTPDCmd = NULL;
    _lastHTTPDCmd = NULL;
}

void libhttppp::HTTPDCmdController::registerCmd(const char *key, const char skey,bool required, const char *defaultvalue, const char *help) {
    if (!key || !skey || !help) {
        _httpexception[HTTPException::Critical] << "cmd parser key,skey or help not set!";
        throw _httpexception;
    }
    /*if key exist overwriting options*/
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd=curhttpdcmd->nextHTTPDCmd()) {
        if (strncmp(curhttpdcmd->getKey(), key, getlen(curhttpdcmd->getKey())) == 0) {
            /*set new shortkey*/
            curhttpdcmd->_SKey = skey;
            /*set reqirement flag*/
            curhttpdcmd->_Required = required;
            /*set new value*/
            delete[] curhttpdcmd->_Value;
            curhttpdcmd->_Value = new char[getlen(defaultvalue)+1];
            scopy(defaultvalue, defaultvalue+getlen(defaultvalue),curhttpdcmd->_Value);
            curhttpdcmd->_Value[getlen(defaultvalue)] = '\0';
            /*set new help*/
            delete[] curhttpdcmd->_Help;
            curhttpdcmd->_Help = new char[getlen(help) + 1];
            scopy(help, help + getlen(help), curhttpdcmd->_Help);
            curhttpdcmd->_Help[getlen(help)] = '\0';
            return;
        }
    }
    /*create new key value store*/
    if (!_firstHTTPDCmd) {
        _firstHTTPDCmd = new HTTPDCmd;
        _lastHTTPDCmd = _firstHTTPDCmd;
    }
    else {
        _lastHTTPDCmd->_nextHTTPDCmd = new HTTPDCmd;
        _lastHTTPDCmd = _lastHTTPDCmd->_nextHTTPDCmd;
    }
    /*set new key*/
    _lastHTTPDCmd->_Key = new char[getlen(key) + 1];
    scopy(key,key+getlen(key),_lastHTTPDCmd->_Key);
    _lastHTTPDCmd->_Key[getlen(key)] = '\0';
    /*set new shortkey*/
    _lastHTTPDCmd->_SKey = skey;
    /*set reqirement flag*/
    _lastHTTPDCmd->_Required = required;
    /*set new value*/
    if (defaultvalue) {
        _lastHTTPDCmd->_Value = new char[getlen(defaultvalue) + 1];
        scopy(defaultvalue, defaultvalue + getlen(defaultvalue), _lastHTTPDCmd->_Value);
        _lastHTTPDCmd->_Value[getlen(defaultvalue)] = '\0';
    }
    /*set new help*/
    _lastHTTPDCmd->_Help = new char[getlen(help) + 1];
    scopy(help, help + getlen(help), _lastHTTPDCmd->_Help);
    _lastHTTPDCmd->_Help[getlen(help)] = '\0';

}

void libhttppp::HTTPDCmdController::registerCmd(const char *key, const char skey, bool required, size_t defaultvalue, const char *help) {
    char buf[255];
    itoa(defaultvalue,buf);
    registerCmd(key,skey,required,buf,help);
}

void libhttppp::HTTPDCmdController::registerCmd(const char *key, const char skey, bool required, int defaultvalue, const char *help) {
    char buf[255];
    itoa(defaultvalue,buf);
    registerCmd(key, skey, required, buf, help);
}

void libhttppp::HTTPDCmdController::parseCmd(int argc, char** argv){
    for (int args = 1; args < argc; args++) {
        int keytype = -1;
        if (argv[args][0]=='-' && argv[args][1] == '-') {
            keytype = KTKEY;
        }else if (argv[args][0] == '-'){
            keytype = KTSKEY;
        }else {
            break;
        }

        size_t kendpos = getlen(argv[args]);
        for (size_t cmdpos = 0; cmdpos < getlen(argv[args])+1; cmdpos++) {
            switch (argv[args][cmdpos]) {
                case '=': {
                    kendpos = cmdpos;
                };
            }
        }

        char *key = NULL;
        char skey = '0';
        if (keytype == KTKEY) {
            key = new char[kendpos-1];
            scopy(argv[args] +2, argv[args] +kendpos, key);
            key[kendpos - 2] = '\0';
        } else if (keytype == KTSKEY){
            skey = argv[args][1];
        }

        for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
            if (keytype == KTKEY) {
                if (strncmp(curhttpdcmd->getKey(), key, getlen(curhttpdcmd->getKey())) == 0) {
                    curhttpdcmd->_Found = true;
                    int valuesize = (getlen(argv[args]) - (kendpos+1));
                    if (valuesize > 0) {
                        delete[] curhttpdcmd->_Value;
                        curhttpdcmd->_Value = new char[valuesize+1];
                        scopy(argv[args]+(kendpos+1), argv[args] + getlen(argv[args]),curhttpdcmd->_Value);
                        curhttpdcmd->_Value[valuesize] = '\0';
                    }
                }
            } else if (keytype == KTSKEY) {
                if (curhttpdcmd->getShortkey()== skey) {
                    curhttpdcmd->_Found = true;
                    if (args<argc) {
                        int valuesize = getlen(argv[++args]);
                        delete[] curhttpdcmd->_Value;
                        curhttpdcmd->_Value = new char[valuesize + 1];
                        scopy(argv[args], argv[args] + getlen(argv[args]), curhttpdcmd->_Value);
                        curhttpdcmd->_Value[valuesize] = '\0';
                    }
                }
            }
        }

        delete[] key;
    }
}

bool libhttppp::HTTPDCmdController::checkRequired() {
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
        if (curhttpdcmd->getRequired() && !curhttpdcmd->_Found) {
            return false;
        }
    }
    return true;
}

void libhttppp::HTTPDCmdController::printHelp() {
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
        Console con;
        con << "--" << curhttpdcmd->getKey()
            << " -" << curhttpdcmd->getShortkey()
            << " "  << curhttpdcmd->getHelp() << Console::endl;
    }
}

libhttppp::HTTPDCmd *libhttppp::HTTPDCmdController::getHTTPDCmdbyKey(const char *key) {
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
        if (strncmp(curhttpdcmd->getKey(), key, getlen(curhttpdcmd->getKey())) == 0) {
            return curhttpdcmd;
        }
    }
    return NULL;
}

libhttppp::HTTPDCmdController::~HTTPDCmdController() {
    delete _firstHTTPDCmd;
    _lastHTTPDCmd = NULL;
}

libhttppp::HttpD::HttpD(int argc, char** argv){
    CmdController= new HTTPDCmdController;
    /*Register Parameters*/
    CmdController->registerCmd("help", 'h', false, (const char*) NULL, "Helpmenu");
    CmdController->registerCmd("httpaddr",'a', true,(const char*) NULL,"Address to listen");
    CmdController->registerCmd("httpport", 'p', false, 8080, "Port to listen");
    CmdController->registerCmd("maxconnections", 'm',false, MAXDEFAULTCONN, "Max connections that can connect");
    CmdController->registerCmd("httpscert", 'c',false,(const char*) NULL, "HTTPS Certfile");
    CmdController->registerCmd("httpskey", 'k',false, (const char*) NULL, "HTTPS Keyfile");
    /*Parse Parameters*/
    CmdController->parseCmd(argc,argv);

    if (CmdController->getHTTPDCmdbyKey("help") && CmdController->getHTTPDCmdbyKey("help")->getFound()) {
        CmdController->printHelp();
        throw _httpexception[HTTPException::Note] << "Help Menu printed";
    }

    if (!CmdController->checkRequired()) {
        CmdController->printHelp();
        _httpexception[HTTPException::Critical] << "cmd parser not enough arguments given";
        throw _httpexception;
    }

    /*get port from console paramter*/
    int port = 0;
    bool portset=false;
    if(CmdController->getHTTPDCmdbyKey("httpport")){
        port = CmdController->getHTTPDCmdbyKey("httpport")->getValueInt();
        portset = CmdController->getHTTPDCmdbyKey("httpport")->getFound();
    }

    /*get httpaddress from console paramter*/
    const char *httpaddr = NULL;
    if (CmdController->getHTTPDCmdbyKey("httpaddr"))
        httpaddr = CmdController->getHTTPDCmdbyKey("httpaddr")->getValue();

    /*get max connections from console paramter*/
    int maxconnections = 0;
    if (CmdController->getHTTPDCmdbyKey("maxconnections"))
        maxconnections = CmdController->getHTTPDCmdbyKey("maxconnections")->getValueInt();

    /*get httpaddress from console paramter*/
    const char *sslcertpath = NULL;
    if (CmdController->getHTTPDCmdbyKey("httpscert"))
        sslcertpath = CmdController->getHTTPDCmdbyKey("httpscert")->getValue();

    /*get httpaddress from console paramter*/
    const char *sslkeypath = NULL;
    if (CmdController->getHTTPDCmdbyKey("httpskey"))
        sslkeypath = CmdController->getHTTPDCmdbyKey("httpskey")->getValue();

    try {
        #ifndef Windows
        if (portset == true)
            _ServerSocket = new ServerSocket(httpaddr, port, maxconnections);
        else
            _ServerSocket = new ServerSocket(httpaddr, maxconnections);
        #else
        _ServerSocket = new ServerSocket(httpaddr, port, maxconnections);
        #endif

        if (sslcertpath && sslkeypath) {
            _ServerSocket->createContext();
            _ServerSocket->loadCertfile(sslcertpath);
            _ServerSocket->loadKeyfile(sslkeypath);
        }
    }catch (HTTPException &e) {
        throw e;
    }
}

libhttppp::ServerSocket *libhttppp::HttpD::getServerSocket(){
  return _ServerSocket;
}

libhttppp::HttpD::~HttpD(){
  delete _ServerSocket;
  delete CmdController;
}
<commit_msg>fixed len bug<commit_after>/*******************************************************************************
Copyright (c) 2014, Jan Koester jan.koester@gmx.net
All rights reserved.

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 the <organization> 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 <COPYRIGHT HOLDER> 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 <cstring>
#include <cstdlib>

#include "os/os.h"
#include "utils.h"
#include "httpd.h"

#define KTKEY 0
#define KTSKEY 1

libhttppp::HTTPDCmd::HTTPDCmd() {
    _Key = NULL;
    _SKey = '\0';
    _Value = NULL;
    _Help = NULL;
    _Found = false;
    _Required = false;
    _nextHTTPDCmd = NULL;
}

const char *libhttppp::HTTPDCmd::getKey() {
    return _Key;
}

const char libhttppp::HTTPDCmd::getShortkey() {
    return _SKey;
}

const char *libhttppp::HTTPDCmd::getValue() {
    return _Value;
}

size_t libhttppp::HTTPDCmd::getValueSize_t() {
    return atoi(_Value);
}

int libhttppp::HTTPDCmd::getValueInt() {
    return atoi(_Value);
}

const char *libhttppp::HTTPDCmd::getHelp() {
    return _Help;
}

bool libhttppp::HTTPDCmd::getFound() {
    return _Found;
}

bool libhttppp::HTTPDCmd::getRequired() {
    return _Required;
}

libhttppp::HTTPDCmd *libhttppp::HTTPDCmd::nextHTTPDCmd() {
    return _nextHTTPDCmd;
}

libhttppp::HTTPDCmd::~HTTPDCmd() {
    delete[] _Key;
    delete[] _Value;
    delete[] _Help;
    delete _nextHTTPDCmd;
}

libhttppp::HTTPDCmdController::HTTPDCmdController() {
    _firstHTTPDCmd = NULL;
    _lastHTTPDCmd = NULL;
}

void libhttppp::HTTPDCmdController::registerCmd(const char *key, const char skey,bool required, const char *defaultvalue, const char *help) {
    if (!key || !skey || !help) {
        _httpexception[HTTPException::Critical] << "cmd parser key,skey or help not set!";
        throw _httpexception;
    }
    /*if key exist overwriting options*/
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd=curhttpdcmd->nextHTTPDCmd()) {
        if (strncmp(curhttpdcmd->getKey(), key, getlen(curhttpdcmd->getKey())) == 0) {
            /*set new shortkey*/
            curhttpdcmd->_SKey = skey;
            /*set reqirement flag*/
            curhttpdcmd->_Required = required;
            /*set new value*/
            delete[] curhttpdcmd->_Value;
            curhttpdcmd->_Value = new char[getlen(defaultvalue)+1];
            scopy(defaultvalue, defaultvalue+getlen(defaultvalue),curhttpdcmd->_Value);
            curhttpdcmd->_Value[getlen(defaultvalue)] = '\0';
            /*set new help*/
            delete[] curhttpdcmd->_Help;
            curhttpdcmd->_Help = new char[getlen(help) + 1];
            scopy(help, help + getlen(help), curhttpdcmd->_Help);
            curhttpdcmd->_Help[getlen(help)] = '\0';
            return;
        }
    }
    /*create new key value store*/
    if (!_firstHTTPDCmd) {
        _firstHTTPDCmd = new HTTPDCmd;
        _lastHTTPDCmd = _firstHTTPDCmd;
    }
    else {
        _lastHTTPDCmd->_nextHTTPDCmd = new HTTPDCmd;
        _lastHTTPDCmd = _lastHTTPDCmd->_nextHTTPDCmd;
    }
    /*set new key*/
    _lastHTTPDCmd->_Key = new char[getlen(key) + 1];
    scopy(key,key+getlen(key),_lastHTTPDCmd->_Key);
    _lastHTTPDCmd->_Key[getlen(key)] = '\0';
    /*set new shortkey*/
    _lastHTTPDCmd->_SKey = skey;
    /*set reqirement flag*/
    _lastHTTPDCmd->_Required = required;
    /*set new value*/
    if (defaultvalue) {
        _lastHTTPDCmd->_Value = new char[getlen(defaultvalue) + 1];
        scopy(defaultvalue, defaultvalue + getlen(defaultvalue), _lastHTTPDCmd->_Value);
        _lastHTTPDCmd->_Value[getlen(defaultvalue)] = '\0';
    }
    /*set new help*/
    _lastHTTPDCmd->_Help = new char[getlen(help) + 1];
    scopy(help, help + getlen(help), _lastHTTPDCmd->_Help);
    _lastHTTPDCmd->_Help[getlen(help)] = '\0';

}

void libhttppp::HTTPDCmdController::registerCmd(const char *key, const char skey, bool required, size_t defaultvalue, const char *help) {
    char buf[255];
    itoa(defaultvalue,buf);
    registerCmd(key,skey,required,buf,help);
}

void libhttppp::HTTPDCmdController::registerCmd(const char *key, const char skey, bool required, int defaultvalue, const char *help) {
    char buf[255];
    itoa(defaultvalue,buf);
    registerCmd(key, skey, required, buf, help);
}

void libhttppp::HTTPDCmdController::parseCmd(int argc, char** argv){
    for (int args = 1; args < argc; args++) {
        int keytype = -1;
        if (argv[args][0]=='-' && argv[args][1] == '-') {
            keytype = KTKEY;
        }else if (argv[args][0] == '-'){
            keytype = KTSKEY;
        }else {
            break;
        }

        size_t kendpos = getlen(argv[args]);
        for (size_t cmdpos = 0; cmdpos < getlen(argv[args])+1; cmdpos++) {
            switch (argv[args][cmdpos]) {
                case '=': {
                    kendpos = cmdpos;
                };
            }
        }

        char *key = NULL;
        char skey = '0';
        if (keytype == KTKEY) {
            key = new char[kendpos-1];
            scopy(argv[args] +2, argv[args] +kendpos, key);
            key[kendpos - 2] = '\0';
        } else if (keytype == KTSKEY){
            skey = argv[args][1];
        }

        for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
            if (keytype == KTKEY) {
                if (strncmp(curhttpdcmd->getKey(), key, getlen(curhttpdcmd->getKey())) == 0) {
                    curhttpdcmd->_Found = true;
                    int valuesize = (getlen(argv[args]) - (kendpos+1));
                    if (valuesize > 0) {
                        delete[] curhttpdcmd->_Value;
                        curhttpdcmd->_Value = new char[valuesize+1];
                        scopy(argv[args]+(kendpos+1), argv[args] + getlen(argv[args]),curhttpdcmd->_Value);
                        curhttpdcmd->_Value[valuesize] = '\0';
                    }
                }
            } else if (keytype == KTSKEY) {
                if (curhttpdcmd->getShortkey()== skey) {
                    curhttpdcmd->_Found = true;
                    if (++args<argc) {
                        int valuesize = getlen(argv[args]);
                        delete[] curhttpdcmd->_Value;
                        curhttpdcmd->_Value = new char[valuesize + 1];
                        scopy(argv[args], argv[args] + getlen(argv[args]), curhttpdcmd->_Value);
                        curhttpdcmd->_Value[valuesize] = '\0';
                    }
                }
            }
        }

        delete[] key;
    }
}

bool libhttppp::HTTPDCmdController::checkRequired() {
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
        if (curhttpdcmd->getRequired() && !curhttpdcmd->_Found) {
            return false;
        }
    }
    return true;
}

void libhttppp::HTTPDCmdController::printHelp() {
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
        Console con;
        con << "--" << curhttpdcmd->getKey()
            << " -" << curhttpdcmd->getShortkey()
            << " "  << curhttpdcmd->getHelp() << Console::endl;
    }
}

libhttppp::HTTPDCmd *libhttppp::HTTPDCmdController::getHTTPDCmdbyKey(const char *key) {
    for (HTTPDCmd *curhttpdcmd = _firstHTTPDCmd; curhttpdcmd; curhttpdcmd = curhttpdcmd->nextHTTPDCmd()) {
        if (strncmp(curhttpdcmd->getKey(), key, getlen(curhttpdcmd->getKey())) == 0) {
            return curhttpdcmd;
        }
    }
    return NULL;
}

libhttppp::HTTPDCmdController::~HTTPDCmdController() {
    delete _firstHTTPDCmd;
    _lastHTTPDCmd = NULL;
}

libhttppp::HttpD::HttpD(int argc, char** argv){
    CmdController= new HTTPDCmdController;
    /*Register Parameters*/
    CmdController->registerCmd("help", 'h', false, (const char*) NULL, "Helpmenu");
    CmdController->registerCmd("httpaddr",'a', true,(const char*) NULL,"Address to listen");
    CmdController->registerCmd("httpport", 'p', false, 8080, "Port to listen");
    CmdController->registerCmd("maxconnections", 'm',false, MAXDEFAULTCONN, "Max connections that can connect");
    CmdController->registerCmd("httpscert", 'c',false,(const char*) NULL, "HTTPS Certfile");
    CmdController->registerCmd("httpskey", 'k',false, (const char*) NULL, "HTTPS Keyfile");
    /*Parse Parameters*/
    CmdController->parseCmd(argc,argv);

    if (CmdController->getHTTPDCmdbyKey("help") && CmdController->getHTTPDCmdbyKey("help")->getFound()) {
        CmdController->printHelp();
        throw _httpexception[HTTPException::Note] << "Help Menu printed";
    }

    if (!CmdController->checkRequired()) {
        CmdController->printHelp();
        _httpexception[HTTPException::Critical] << "cmd parser not enough arguments given";
        throw _httpexception;
    }

    /*get port from console paramter*/
    int port = 0;
    bool portset=false;
    if(CmdController->getHTTPDCmdbyKey("httpport")){
        port = CmdController->getHTTPDCmdbyKey("httpport")->getValueInt();
        portset = CmdController->getHTTPDCmdbyKey("httpport")->getFound();
    }

    /*get httpaddress from console paramter*/
    const char *httpaddr = NULL;
    if (CmdController->getHTTPDCmdbyKey("httpaddr"))
        httpaddr = CmdController->getHTTPDCmdbyKey("httpaddr")->getValue();

    /*get max connections from console paramter*/
    int maxconnections = 0;
    if (CmdController->getHTTPDCmdbyKey("maxconnections"))
        maxconnections = CmdController->getHTTPDCmdbyKey("maxconnections")->getValueInt();

    /*get httpaddress from console paramter*/
    const char *sslcertpath = NULL;
    if (CmdController->getHTTPDCmdbyKey("httpscert"))
        sslcertpath = CmdController->getHTTPDCmdbyKey("httpscert")->getValue();

    /*get httpaddress from console paramter*/
    const char *sslkeypath = NULL;
    if (CmdController->getHTTPDCmdbyKey("httpskey"))
        sslkeypath = CmdController->getHTTPDCmdbyKey("httpskey")->getValue();

    try {
        #ifndef Windows
        if (portset == true)
            _ServerSocket = new ServerSocket(httpaddr, port, maxconnections);
        else
            _ServerSocket = new ServerSocket(httpaddr, maxconnections);
        #else
        _ServerSocket = new ServerSocket(httpaddr, port, maxconnections);
        #endif

        if (sslcertpath && sslkeypath) {
            _ServerSocket->createContext();
            _ServerSocket->loadCertfile(sslcertpath);
            _ServerSocket->loadKeyfile(sslkeypath);
        }
    }catch (HTTPException &e) {
        throw e;
    }
}

libhttppp::ServerSocket *libhttppp::HttpD::getServerSocket(){
  return _ServerSocket;
}

libhttppp::HttpD::~HttpD(){
  delete _ServerSocket;
  delete CmdController;
}
<|endoftext|>


<commit_before>#ifndef V_SMC_SAMPLER_HPP
#define V_SMC_SAMPLER_HPP

#include <vSMC/config.hpp>

#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <stdexcept>
#include <string>
#include <vector>
#include <mkl_cblas.h>
#include <boost/function.hpp>
#include <vDist/rng/gsl.hpp>
#include <vDist/tool/buffer.hpp>
#include <vSMC/monitor.hpp>
#include <vSMC/particle.hpp>
#include <vSMC/path.hpp>

namespace vSMC {

template <typename T>
class Sampler
{
    public :

    /// The type of initialization functor
    typedef boost::function<std::size_t
        (Particle<T> &, void *)> init_type;
    /// The type of move functor
    typedef boost::function<std::size_t
        (std::size_t, Particle<T> &)> move_type;
    /// The type of importance sampling integral functor
    typedef boost::function<void
        (std::size_t, Particle<T> &, double *, void *)> integral_type;

    /// \brief Sampler does not have a default constructor
    ///
    /// \param N The number of particles
    /// \param init The functor used to initialize the particles
    /// \param move The functor used to move the particles and weights
    /// \param mcmc The functor used to perform MCMC move
    /// \param scheme The resampling scheme. See ResampleScheme
    /// \param threshold The threshold for performing resampling
    /// \param seed The seed for the reampling RNG. See documentation of vDist
    /// \param brng The basic RNG for resampling RNG. See documentation of GSL
    Sampler (
            std::size_t N,
            const init_type &init,
            const move_type &move,
            const move_type &mcmc = NULL,
            ResampleScheme scheme = RESIDUAL,
            double threshold = 0.5,
            const int seed = V_DIST_SEED,
            const gsl_rng_type *brng = V_DIST_GSL_BRNG) :
        initialized_(false), init_(init), move_(move), mcmc_(mcmc),
        rng_(seed, brng), scheme_(scheme), threshold_(threshold * N),
        particle_(N), iter_num_(0), show_progress_(false) {}

    /// \brief Size of the particle set
    ///
    /// \return The number of particles
    std::size_t size () const
    {
        return particle_.size();
    }

    /// \brief Size of records
    ///
    /// \return The number of iterations recorded (including the
    /// initialization step)
    std::size_t iter_size () const
    {
        return ess_.size();
    }

    /// \brief ESS
    ///
    /// \return The ESS value of the latest iteration
    double ess () const
    {
        return ess_.back();
    }

    /// \brief ESS history
    ///
    /// \return A const reference to the history of ESS
    const std::vector<double> &ess_history () const
    {
        return ess_;
    }

    /// \brief ESS history
    ///
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void ess_history (OIter first) const
    {
        for (std::vector<double>::const_iterator iter = ess_.begin();
                iter != ess_.end(); ++iter)
            *first++ = *iter;
    }

    /// \brief Indicator of resampling
    ///
    /// \return A bool value, \b true if the latest iteration was resampled
    bool resampled () const
    {
        return resampled_.back();
    }

    /// \brief Resampling history
    ///
    /// \return A const reference to the history of resampling
    const std::vector<bool> &resampled_history () const
    {
        return resampled_;
    }

    /// \brief Resampling history
    ///
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void resampled_history (OIter first) const
    {
        for (std::vector<bool>::const_iterator iter = resampled_.begin();
                iter != resampled_.end(); ++iter)
            *first++ = *iter;
    }

    /// \brief Accept count
    ///
    /// \return The accept count of the latest iteration
    std::size_t accept () const
    {
        return accept_.back();
    }

    /// \brief Accept count history
    ///
    /// \return A const reference to the history of accept count
    const std::vector<std::size_t> &accept_history () const
    {
        return accept_;
    }

    /// \brief Accept count history
    ///
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void accept_history (OIter first) const
    {
        for (std::vector<std::size_t>::const_iterator iter = accept_.begin();
                iter != accept_.end(); ++iter)
            *first++ = *iter;
    }

    /// \brief Read and write access to the particle set
    ///
    /// \return A reference to the latest particle set
    ///
    /// \note The Sampler class guarantee that during the life type of the
    /// object, the reference returned by this member will no be a dangle
    /// handler.
    Particle<T> &particle ()
    {
        return particle_;
    }

    /// \brief Read only access to the particle set
    ///
    /// \return A const reference to the latest particle set.
    const Particle<T> &particle () const
    {
        return particle_;
    }

    /// \brief Initialize the particle set
    ///
    /// \param param Additional parameters passed to the initialization
    /// functor
    void initialize (void *param = NULL)
    {
        ess_.clear();
        resampled_.clear();
        accept_.clear();
        path_.clear();

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap)
            imap->second.clear();

        iter_num_ = 0;
        accept_.push_back(init_(particle_, param));
        post_move();
        particle_.reset_zconst();

        initialized_ = true;
    }

    /// \brief Perform iteration
    void iterate ()
    {
        if (!initialized_) {
            throw std::runtime_error(
                    "ERROR: vSMC::Sampler::iterate: "
                    "Sampler has not been initialized yet");
        }

        ++iter_num_;
        accept_.push_back(move_(iter_num_, particle_));
        if (mcmc_)
            accept_.back() = mcmc_(iter_num_, particle_);
        post_move();
    }

    /// \brief Perform iteration
    ///
    /// \param n The number of iterations to be performed
    void iterate (std::size_t n)
    {
        for (std::size_t i = 0; i != n; ++i)
            iterate();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param integral The functor used to compute the integrands
    double integrate (typename Monitor<T>::integral_type integral)
    {
        buffer_.resize(size());
        integral(iter_num_, particle_, buffer_);

        return cblas_ddot(size(), particle_.weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param integral The functor used to compute the integrands
    /// \param param Additional parameters passed to the integral functor
    double integrate (integral_type integral, void *param) const
    {
        buffer_.resize(size());
        integral(iter_num_, particle_, buffer_, param);

        return cblas_ddot(size(), particle_.weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param integral The functor used to compute the integrands
    void monitor (const std::string &name,
            const typename Monitor<T>::integral_type &integral)
    {
        monitor_.insert(std::make_pair(name, Monitor<T>(integral)));
        monitor_name_.insert(name);
    }

    /// \brief Read and write access to a named monitor through iterator
    ///
    /// \param name The name of the monitor
    /// \return An iterator point to the monitor for the given name
    typename std::map<std::string, Monitor<T> >::iterator
        monitor (const std::string &name)
    {
        return monitor_.find(name);
    }

    /// \brief Read only access to a named monitor through iterator
    ///
    /// \param name The name of the monitor
    /// \return An const_iterator point to the monitor for the given name
    typename std::map<std::string, Monitor<T> >::const_iterator
        monitor (const std::string &name) const
    {
        return monitor_.find(name);
    }

    /// \brief Read and write access to all monitors
    ///
    /// \return A reference to monitors
    std::map<std::string, Monitor<T> > &monitor ()
    {
        return monitor_;
    }

    /// \brief Read only access to all monitors
    ///
    /// \return A const reference to monitors
    const std::map<std::string, Monitor<T> > &monitor () const
    {
        return monitor_;
    }

    /// \brief Erase a named monitor
    ///
    /// \param name The name of the monitor
    void erase_monitor (const std::string &name)
    {
        monitor_.erase(name);
        monitor_name_.erase(name);
    }

    /// \brief Erase (clear) all monitors
    void clear_monitor ()
    {
        monitor_.clear();
        monitor_name_.clear();
    }

    /// \brief Read and write access to the Path sampling monitor
    ///
    /// \return A reference to the Path sampling monitor
    Path<T> &path ()
    {
        return path_;
    }

    /// \brief Read only access to the Path sampling monitor
    ///
    /// \return A const reference to the Path sampling monitor
    const Path<T> &path () const
    {
        return path_;
    }

    /// \brief Set the path sampling integral
    ///
    /// \param integral The functor used to compute the integrands
    ///
    /// \note Set integral = NULL will stop path sampling recording
    void path_sampling (const typename Path<T>::integral_type &integral)
    {
        path_.integral(integral);
    }

    /// \brief Path sampling estimate of normalizing constant
    ///
    /// \return The log ratio of normalizing constants
    double path_sampling_zconst () const
    {
        return path_.zconst();
    }

    /// \brief Toggle whether or not record SMC normalizing constant
    ///
    /// \param estimate_zconst Start estimating normalzing constant if true.
    void zconst (bool estimate_zconst)
    {
        particle_.zconst(estimate_zconst);
    }

    /// \brief SMC estimate of normalizing constant
    ///
    /// \return The SMC normalizng constant estimate
    double zconst () const
    {
        return particle_.zconst();
    }

    /// \brief Print the history of the sampler
    ///
    /// \param output The ostream to which the contents are printed
    /// \param print_header Print header if \b true
    void print (std::ostream &output = std::cout,
            bool print_header = true) const
    {
        print(output, print_header, !path_.index().empty(), monitor_name_);
    }

    /// \brief Print the history of the sampler
    ///
    /// \param output The ostream to which the contents are printed
    /// \param print_path Print path sampling history if \b true
    /// \param print_monitor A set of monitor names to be printed
    /// \param print_header Print header if \b true
    void print (std::ostream &output,
            bool print_header, bool print_path,
            const std::set<std::string> &print_monitor) const
    {
        if (print_header) {
            output << "iter\tESS\tresample\taccept\t";
            if (print_path)
                output << "path.integrand\tpath.width\tpath.grid\t";
        }

        std::vector<std::size_t>::const_iterator iter_path_index
            = path_.index().begin();
        std::vector<double>::const_iterator iter_path_integrand
            = path_.integrand().begin();
        std::vector<double>::const_iterator iter_path_width
            = path_.width().begin();
        std::vector<double>::const_iterator iter_path_grid
            = path_.grid().begin();

        std::vector<bool> monitor_index_empty;
        std::vector<std::vector<std::size_t>::const_iterator>
            iter_monitor_index;
        std::vector<std::vector<double>::const_iterator>
            iter_monitor_record;
        for (typename std::map<std::string, Monitor<T> >::const_iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (print_monitor.count(imap->first)) {
                monitor_index_empty.push_back(imap->second.index().empty());
                iter_monitor_index.push_back(imap->second.index().begin());
                iter_monitor_record.push_back(imap->second.record().begin());
                if (print_header)
                    output << imap->first << '\t';
            }
        }

        if (print_header)
            output << '\n';

        for (std::size_t i = 0; i != iter_size(); ++i) {
            output
                << i << '\t' << ess_[i] / size()
                << '\t' << resampled_[i]
                << '\t' << static_cast<double>(accept_[i]) / size();

            if (print_path) {
                if (!path_.index().empty() && *iter_path_index == i) {
                    output
                        << '\t' << *iter_path_integrand++
                        << '\t' << *iter_path_width++
                        << '\t' << *iter_path_grid++;
                    ++iter_path_index;
                } else {
                    output << '\t' << '.' << '\t' << '.' << '\t' << '.';
                }
            }

            for (std::size_t m = 0; m != monitor_index_empty.size(); ++m) {
                if (!monitor_index_empty[m] && *iter_monitor_index[m] == i) {
                    output << '\t' << *iter_monitor_record[m]++;
                    ++iter_monitor_index[m];
                } else {
                    output << '\t' << '.';
                }
            }

            output << '\n';
        }
    }

    private :

    /// Initialization indicator
    bool initialized_;

    /// Initialization and movement
    init_type init_;
    move_type move_;
    move_type mcmc_;

    /// Resampling
    vDist::RngGSL rng_;
    ResampleScheme scheme_;
    double threshold_;

    /// Particle sets
    Particle<T> particle_;
    std::size_t iter_num_;
    std::vector<double> ess_;
    std::vector<bool> resampled_;
    std::vector<std::size_t> accept_;

    /// Monte Carlo estimation by integration
    vDist::tool::Buffer<double> buffer_;
    std::map<std::string, Monitor<T> > monitor_;
    std::set<std::string> monitor_name_;

    /// Path sampling
    Path<T> path_;

    /// Whether to show prograss while iterating
    bool show_progress_;

    void post_move ()
    {
        ess_.push_back(particle_.ess());
        particle_.resampled(ess_.back() < threshold_);
        resampled_.push_back(particle_.resampled());
        if (particle_.resampled())
            particle_.resample(scheme_, rng_.get_rng());

        if (!path_.empty())
            path_.eval(iter_num_, particle_);

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (!imap->second.empty())
                imap->second.eval(iter_num_, particle_);
        }

        if (show_progress_) {
            if (iter_num_)
                std::cerr << '.';
            else
                std::cerr << '*';
            std::cerr.flush();
        }
    }
}; // class Sampler

} // namespace vSMC

namespace std {

template<typename T>
std::ostream & operator<< (std::ostream &output,
        const vSMC::Sampler<T> &sampler)
{
    sampler.print(output);

    return output;
}

} // namespace std

#endif // V_SMC_SAMPLER_HPP
<commit_msg>documentation of the examples<commit_after>#ifndef V_SMC_SAMPLER_HPP
#define V_SMC_SAMPLER_HPP

#include <vSMC/config.hpp>

#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <stdexcept>
#include <string>
#include <vector>
#include <mkl_cblas.h>
#include <boost/function.hpp>
#include <vDist/rng/gsl.hpp>
#include <vDist/tool/buffer.hpp>
#include <vSMC/monitor.hpp>
#include <vSMC/particle.hpp>
#include <vSMC/path.hpp>

/*************************************************************************//**
 * \page pf_seq Sequential implementation of particle filter example
 *
 * This example is implemented with sequential code. Most of the code is no
 * more complex than those found in SMCTC. This is only a proof of concept that
 * vSMC can also be used in a similar fashion as in SMCTC. But for sequential
 * implementation, SMCTC is much more stable and matured. For a vectorized
 * implementation, which really takes the advantage of vSMC, see \ref pf_eigen.
 *
 * \include pf/pf_seq.cpp
 *
 * \page pf_eigen Vectorized implementation of particle filter example
 *
 * This example is implemented with the Eigen library. Its syntax is quite
 * elegent and in most case its use shall be self-explained by the code. It
 * also use the vDist library for vectorized computation of pdf, kernel,
 * generating random variates, etc. For a sequential implementation without any
 * use of SIMD see \ref pf_seq.
 *
 * \include pf/pf_eigen.cpp
 ****************************************************************************/

namespace vSMC {

template <typename T>
class Sampler
{
    public :

    /// The type of initialization functor
    typedef boost::function<std::size_t
        (Particle<T> &, void *)> init_type;
    /// The type of move functor
    typedef boost::function<std::size_t
        (std::size_t, Particle<T> &)> move_type;
    /// The type of importance sampling integral functor
    typedef boost::function<void
        (std::size_t, Particle<T> &, double *, void *)> integral_type;

    /// \brief Sampler does not have a default constructor
    ///
    /// \param N The number of particles
    /// \param init The functor used to initialize the particles
    /// \param move The functor used to move the particles and weights
    /// \param mcmc The functor used to perform MCMC move
    /// \param scheme The resampling scheme. See ResampleScheme
    /// \param threshold The threshold for performing resampling
    /// \param seed The seed for the reampling RNG. See documentation of vDist
    /// \param brng The basic RNG for resampling RNG. See documentation of GSL
    Sampler (
            std::size_t N,
            const init_type &init,
            const move_type &move,
            const move_type &mcmc = NULL,
            ResampleScheme scheme = RESIDUAL,
            double threshold = 0.5,
            const int seed = V_DIST_SEED,
            const gsl_rng_type *brng = V_DIST_GSL_BRNG) :
        initialized_(false), init_(init), move_(move), mcmc_(mcmc),
        rng_(seed, brng), scheme_(scheme), threshold_(threshold * N),
        particle_(N), iter_num_(0), show_progress_(false) {}

    /// \brief Size of the particle set
    ///
    /// \return The number of particles
    std::size_t size () const
    {
        return particle_.size();
    }

    /// \brief Size of records
    ///
    /// \return The number of iterations recorded (including the
    /// initialization step)
    std::size_t iter_size () const
    {
        return ess_.size();
    }

    /// \brief ESS
    ///
    /// \return The ESS value of the latest iteration
    double ess () const
    {
        return ess_.back();
    }

    /// \brief ESS history
    ///
    /// \return A const reference to the history of ESS
    const std::vector<double> &ess_history () const
    {
        return ess_;
    }

    /// \brief ESS history
    ///
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void ess_history (OIter first) const
    {
        for (std::vector<double>::const_iterator iter = ess_.begin();
                iter != ess_.end(); ++iter)
            *first++ = *iter;
    }

    /// \brief Indicator of resampling
    ///
    /// \return A bool value, \b true if the latest iteration was resampled
    bool resampled () const
    {
        return resampled_.back();
    }

    /// \brief Resampling history
    ///
    /// \return A const reference to the history of resampling
    const std::vector<bool> &resampled_history () const
    {
        return resampled_;
    }

    /// \brief Resampling history
    ///
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void resampled_history (OIter first) const
    {
        for (std::vector<bool>::const_iterator iter = resampled_.begin();
                iter != resampled_.end(); ++iter)
            *first++ = *iter;
    }

    /// \brief Accept count
    ///
    /// \return The accept count of the latest iteration
    std::size_t accept () const
    {
        return accept_.back();
    }

    /// \brief Accept count history
    ///
    /// \return A const reference to the history of accept count
    const std::vector<std::size_t> &accept_history () const
    {
        return accept_;
    }

    /// \brief Accept count history
    ///
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void accept_history (OIter first) const
    {
        for (std::vector<std::size_t>::const_iterator iter = accept_.begin();
                iter != accept_.end(); ++iter)
            *first++ = *iter;
    }

    /// \brief Read and write access to the particle set
    ///
    /// \return A reference to the latest particle set
    ///
    /// \note The Sampler class guarantee that during the life type of the
    /// object, the reference returned by this member will no be a dangle
    /// handler.
    Particle<T> &particle ()
    {
        return particle_;
    }

    /// \brief Read only access to the particle set
    ///
    /// \return A const reference to the latest particle set.
    const Particle<T> &particle () const
    {
        return particle_;
    }

    /// \brief Initialize the particle set
    ///
    /// \param param Additional parameters passed to the initialization
    /// functor
    void initialize (void *param = NULL)
    {
        ess_.clear();
        resampled_.clear();
        accept_.clear();
        path_.clear();

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap)
            imap->second.clear();

        iter_num_ = 0;
        accept_.push_back(init_(particle_, param));
        post_move();
        particle_.reset_zconst();

        initialized_ = true;
    }

    /// \brief Perform iteration
    void iterate ()
    {
        if (!initialized_) {
            throw std::runtime_error(
                    "ERROR: vSMC::Sampler::iterate: "
                    "Sampler has not been initialized yet");
        }

        ++iter_num_;
        accept_.push_back(move_(iter_num_, particle_));
        if (mcmc_)
            accept_.back() = mcmc_(iter_num_, particle_);
        post_move();
    }

    /// \brief Perform iteration
    ///
    /// \param n The number of iterations to be performed
    void iterate (std::size_t n)
    {
        for (std::size_t i = 0; i != n; ++i)
            iterate();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param integral The functor used to compute the integrands
    double integrate (typename Monitor<T>::integral_type integral)
    {
        buffer_.resize(size());
        integral(iter_num_, particle_, buffer_);

        return cblas_ddot(size(), particle_.weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param integral The functor used to compute the integrands
    /// \param param Additional parameters passed to the integral functor
    double integrate (integral_type integral, void *param) const
    {
        buffer_.resize(size());
        integral(iter_num_, particle_, buffer_, param);

        return cblas_ddot(size(), particle_.weight_ptr(), 1, buffer_, 1);
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param integral The functor used to compute the integrands
    void monitor (const std::string &name,
            const typename Monitor<T>::integral_type &integral)
    {
        monitor_.insert(std::make_pair(name, Monitor<T>(integral)));
        monitor_name_.insert(name);
    }

    /// \brief Read and write access to a named monitor through iterator
    ///
    /// \param name The name of the monitor
    /// \return An iterator point to the monitor for the given name
    typename std::map<std::string, Monitor<T> >::iterator
        monitor (const std::string &name)
    {
        return monitor_.find(name);
    }

    /// \brief Read only access to a named monitor through iterator
    ///
    /// \param name The name of the monitor
    /// \return An const_iterator point to the monitor for the given name
    typename std::map<std::string, Monitor<T> >::const_iterator
        monitor (const std::string &name) const
    {
        return monitor_.find(name);
    }

    /// \brief Read and write access to all monitors
    ///
    /// \return A reference to monitors
    std::map<std::string, Monitor<T> > &monitor ()
    {
        return monitor_;
    }

    /// \brief Read only access to all monitors
    ///
    /// \return A const reference to monitors
    const std::map<std::string, Monitor<T> > &monitor () const
    {
        return monitor_;
    }

    /// \brief Erase a named monitor
    ///
    /// \param name The name of the monitor
    void erase_monitor (const std::string &name)
    {
        monitor_.erase(name);
        monitor_name_.erase(name);
    }

    /// \brief Erase (clear) all monitors
    void clear_monitor ()
    {
        monitor_.clear();
        monitor_name_.clear();
    }

    /// \brief Read and write access to the Path sampling monitor
    ///
    /// \return A reference to the Path sampling monitor
    Path<T> &path ()
    {
        return path_;
    }

    /// \brief Read only access to the Path sampling monitor
    ///
    /// \return A const reference to the Path sampling monitor
    const Path<T> &path () const
    {
        return path_;
    }

    /// \brief Set the path sampling integral
    ///
    /// \param integral The functor used to compute the integrands
    ///
    /// \note Set integral = NULL will stop path sampling recording
    void path_sampling (const typename Path<T>::integral_type &integral)
    {
        path_.integral(integral);
    }

    /// \brief Path sampling estimate of normalizing constant
    ///
    /// \return The log ratio of normalizing constants
    double path_sampling_zconst () const
    {
        return path_.zconst();
    }

    /// \brief Toggle whether or not record SMC normalizing constant
    ///
    /// \param estimate_zconst Start estimating normalzing constant if true.
    void zconst (bool estimate_zconst)
    {
        particle_.zconst(estimate_zconst);
    }

    /// \brief SMC estimate of normalizing constant
    ///
    /// \return The SMC normalizng constant estimate
    double zconst () const
    {
        return particle_.zconst();
    }

    /// \brief Print the history of the sampler
    ///
    /// \param output The ostream to which the contents are printed
    /// \param print_header Print header if \b true
    void print (std::ostream &output = std::cout,
            bool print_header = true) const
    {
        print(output, print_header, !path_.index().empty(), monitor_name_);
    }

    /// \brief Print the history of the sampler
    ///
    /// \param output The ostream to which the contents are printed
    /// \param print_path Print path sampling history if \b true
    /// \param print_monitor A set of monitor names to be printed
    /// \param print_header Print header if \b true
    void print (std::ostream &output,
            bool print_header, bool print_path,
            const std::set<std::string> &print_monitor) const
    {
        if (print_header) {
            output << "iter\tESS\tresample\taccept\t";
            if (print_path)
                output << "path.integrand\tpath.width\tpath.grid\t";
        }

        std::vector<std::size_t>::const_iterator iter_path_index
            = path_.index().begin();
        std::vector<double>::const_iterator iter_path_integrand
            = path_.integrand().begin();
        std::vector<double>::const_iterator iter_path_width
            = path_.width().begin();
        std::vector<double>::const_iterator iter_path_grid
            = path_.grid().begin();

        std::vector<bool> monitor_index_empty;
        std::vector<std::vector<std::size_t>::const_iterator>
            iter_monitor_index;
        std::vector<std::vector<double>::const_iterator>
            iter_monitor_record;
        for (typename std::map<std::string, Monitor<T> >::const_iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (print_monitor.count(imap->first)) {
                monitor_index_empty.push_back(imap->second.index().empty());
                iter_monitor_index.push_back(imap->second.index().begin());
                iter_monitor_record.push_back(imap->second.record().begin());
                if (print_header)
                    output << imap->first << '\t';
            }
        }

        if (print_header)
            output << '\n';

        for (std::size_t i = 0; i != iter_size(); ++i) {
            output
                << i << '\t' << ess_[i] / size()
                << '\t' << resampled_[i]
                << '\t' << static_cast<double>(accept_[i]) / size();

            if (print_path) {
                if (!path_.index().empty() && *iter_path_index == i) {
                    output
                        << '\t' << *iter_path_integrand++
                        << '\t' << *iter_path_width++
                        << '\t' << *iter_path_grid++;
                    ++iter_path_index;
                } else {
                    output << '\t' << '.' << '\t' << '.' << '\t' << '.';
                }
            }

            for (std::size_t m = 0; m != monitor_index_empty.size(); ++m) {
                if (!monitor_index_empty[m] && *iter_monitor_index[m] == i) {
                    output << '\t' << *iter_monitor_record[m]++;
                    ++iter_monitor_index[m];
                } else {
                    output << '\t' << '.';
                }
            }

            output << '\n';
        }
    }

    private :

    /// Initialization indicator
    bool initialized_;

    /// Initialization and movement
    init_type init_;
    move_type move_;
    move_type mcmc_;

    /// Resampling
    vDist::RngGSL rng_;
    ResampleScheme scheme_;
    double threshold_;

    /// Particle sets
    Particle<T> particle_;
    std::size_t iter_num_;
    std::vector<double> ess_;
    std::vector<bool> resampled_;
    std::vector<std::size_t> accept_;

    /// Monte Carlo estimation by integration
    vDist::tool::Buffer<double> buffer_;
    std::map<std::string, Monitor<T> > monitor_;
    std::set<std::string> monitor_name_;

    /// Path sampling
    Path<T> path_;

    /// Whether to show prograss while iterating
    bool show_progress_;

    void post_move ()
    {
        ess_.push_back(particle_.ess());
        particle_.resampled(ess_.back() < threshold_);
        resampled_.push_back(particle_.resampled());
        if (particle_.resampled())
            particle_.resample(scheme_, rng_.get_rng());

        if (!path_.empty())
            path_.eval(iter_num_, particle_);

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (!imap->second.empty())
                imap->second.eval(iter_num_, particle_);
        }

        if (show_progress_) {
            if (iter_num_)
                std::cerr << '.';
            else
                std::cerr << '*';
            std::cerr.flush();
        }
    }
}; // class Sampler

} // namespace vSMC

namespace std {

template<typename T>
std::ostream & operator<< (std::ostream &output,
        const vSMC::Sampler<T> &sampler)
{
    sampler.print(output);

    return output;
}

} // namespace std

#endif // V_SMC_SAMPLER_HPP
<|endoftext|>