<commit_before>//-------------------------------------------------------------------
//  MetaInfo Framework (MIF)
//  https://github.com/tdv/mif
//  Created:     11.2020
//  Copyright (C) 2016-2020 tdv
//-------------------------------------------------------------------

// STD
#include <deque>
#include <utility>

// BOOST
#include <boost/beast/websocket.hpp>
#include <boost/make_unique.hpp>

// MIF
#include "mif/common/log.h"
#include "mif/common/unused.h"
#include "mif/net/http/constants.h"

// THIS
#include "input_pack.h"
#include "output_pack.h"
#include "session.h"
#include "utility.h"

namespace Mif
{
    namespace Net
    {
        namespace Http
        {
            namespace Detail
            {

                class Session::Queue final
                {
                public:
                    Queue(Session &session, std::size_t limit)
                        : m_session{session}
                        , m_limit{limit}
                    {
                    }

                    bool IsFull() const noexcept
                    {
                        return m_tasks.size() >= m_limit;
                    }

                    template <typename TBody, typename TFields>
                    using Response = boost::beast::http::response<TBody, TFields>;

                    template <typename TBody, typename TFields>
                    void Post(Response<TBody, TFields> &&response)
                    {
                        auto resp = std::make_shared<Response<TBody, TFields>>(std::move(response));

                        auto task = [this, resp]
                        {
                            boost::beast::http::async_write(m_session.m_stream, *resp,
                                    boost::beast::bind_front_handler(&Session::OnWrite,
                                    m_session.shared_from_this(), resp->need_eof()));
                        };

                        m_tasks.emplace_back(std::move(task));

                        if (m_tasks.size() == 1)
                            m_tasks.front()();
                    }

                    bool Pop()
                    {
                        if (m_tasks.empty())
                        {
                            throw std::runtime_error{"[Mif::Net::Http::Detail::Session::Queue::Pop] "
                                    "Empty queue."};
                        }

                        auto const wasFull = IsFull();

                        m_tasks.pop_front();

                        if (!m_tasks.empty())
                            m_tasks.front()();

                        return wasFull;
                    }

                private:
                    Session &m_session;
                    std::size_t const m_limit;

                    std::deque<std::function<void ()>> m_tasks;
                };

                Session::Session(boost::asio::ip::tcp::socket &&socket, Params const &params)
                    : m_stream{std::move(socket)}
                    , m_params{params}
                    , m_queue{boost::make_unique<Queue>(*this,
                            std::max<std::size_t>(m_params.pipelineLimit, 1))
                        }
                {
                }

                Session::~Session()
                {
                }

                void Session::Run()
                {
                    boost::asio::dispatch(m_stream.get_executor(),
                            boost::beast::bind_front_handler(&Session::Read,
                            shared_from_this())
                        );
                }

                void Session::Read()
                {
                    m_parser.emplace();

                    m_parser->header_limit(m_params.headersSize);
                    m_parser->body_limit(m_params.bodySize);
                    m_stream.expires_after(m_params.requestTimeout);

                    boost::beast::http::async_read(m_stream, m_buffer, *m_parser,
                            boost::beast::bind_front_handler(&Session::OnRead,
                            shared_from_this())
                        );
                }

                void Session::OnRead(boost::beast::error_code ec, std::size_t bytes)
                {
                    Common::Unused(bytes);

                    if (ec == boost::beast::http::error::end_of_stream)
                    {
                        Close();
                        return;
                    }

                    if (ec)
                    {
                        MIF_LOG(Warning) << "[Mif::Net::Http::Detail::Session::OnRead] "
                                << "Failed to read data. Error: " << ec.message();

                        return;
                    }

                    if (boost::beast::websocket::is_upgrade(m_parser->get()))
                    {
                        MIF_LOG(Warning) << "[Mif::Net::Http::Detail::Session::OnRead] "
                                << "Failed to upgrade for starting websocket. Error: it has not implemented yet.";

                        Close();
                        return;
                    }

                    HandleRequest(m_parser->release());
                    // TODO:
                }

                void Session::OnWrite(bool close, boost::beast::error_code ec, std::size_t bytes)
                {
                    Common::Unused(bytes);

                    if (ec)
                    {
                        MIF_LOG(Info) << "[Mif::Net::Http::Detail::Session::OnWrite] "
                                << "Failed to write data. Error: " << ec.message();

                        return;
                    }

                    if (close)
                    {
                        Close();
                        return;
                    }

                    if (m_queue->Pop())
                        Read();
                }

                void Session::Close()
                {
                    boost::beast::error_code ec;
                    m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);

                    if (ec)
                    {
                        MIF_LOG(Warning) << "[Mif::Net::Http::Detail::Session::Close] "
                                << "Failed to close socket. Error: " << ec.message();
                    }
                }

                template <typename TBody, typename TAllocator>
                void Session::HandleRequest(Request<TBody, TAllocator> &&request)
                {
                    try
                    {
                        auto const &path = request.target();

                        if (path.empty() || path[0] != '/' ||
                                path.find("..") != boost::beast::string_view::npos)
                        {
                            ReplyError(boost::beast::http::status::bad_request, "Bad path.", request.keep_alive());
                            return;
                        }

                        if (m_params.allowedMethods.find(
                                Utility::ConvertMethodType(request.method())) ==
                                std::end(m_params.allowedMethods))
                        {
                            ReplyError(boost::beast::http::status::method_not_allowed, "The method is not allowed.",
                                    request.keep_alive());
                            return;
                        }

                        if (m_params.handlers.empty())
                        {
                            ReplyError(boost::beast::http::status::method_not_allowed,
                                    "There is no any method for handling the request.",
                                    request.keep_alive());

                            return;
                        }

                        Response response;

                        std::shared_ptr<IInputPack> in = std::make_shared<InputPack<Request<TBody, TAllocator>>>(request);
                        auto out = std::make_shared<OutputPack<Response>>(response);

                        auto process = [this, &in, &out] (std::string const &path)
                        {
                            auto iter = m_params.handlers.find(path);
                            if (iter != std::end(m_params.handlers))
                            {
                                iter->second(*in, *out);
                                return true;
                            }
                            return false;
                        };

                        auto handled = false;
                        std::string url{in->GetPath()};

                        if (process(url))
                            handled = true;
                        else
                        {
                            if (!url.empty() && url.back() != '/')
                                url.append("/");

                            for (auto pos = url.find_last_of('/') ; pos != std::string::npos ; pos = url.find_last_of('/'))
                            {
                                url = url.substr(0, pos);
                                auto const path = url.empty() ? std::string{"/"} : url;

                                if (process(path))
                                {
                                    handled = true;
                                    break;
                                }
                            }
                        }

                        if (!handled)
                        {
                            ReplyError(boost::beast::http::status::method_not_allowed,
                                    "Handler for the request processing was not found.",
                                    request.keep_alive());

                            return;
                        }

                        Reply(std::move(response), request.keep_alive());
                    }
                    catch (std::exception const &e)
                    {
                        MIF_LOG(Error) << "[Mif::Net::Http::Detail::Session::HandleRequest] "
                                << "Failed to process request. Error: " << e.what();

                        ReplyError(boost::beast::http::status::internal_server_error, "An internal error has occurred.",
                                request.keep_alive());
                    }
                }

                void Session::ReplyError(boost::beast::http::status status, std::string const &reason,
                        bool isKeepAlive)
                {
                    boost::beast::http::response<boost::beast::http::string_body> response;

                    response.result(status);
                    //response.set(boost::beast::http::field::server, "Mif");
                    response.set(boost::beast::http::field::content_type, "text/plain");
                    response.set(boost::beast::http::field::date, Utility::CreateTimestamp());
                    response.keep_alive(isKeepAlive);
                    response.version(11);
                    response.body() = std::string(reason);

                    response.prepare_payload();

                    m_queue->Post(std::move(response));
                }

                void Session::Reply(Response &&response, bool isKeepAlive)
                {
                    response.result(boost::beast::http::status::ok);
                    //response.set(boost::beast::http::field::server, "Mif");
                    response.set(boost::beast::http::field::date, Utility::CreateTimestamp());
                    response.version(11);
                    response.keep_alive(isKeepAlive);

                    response.prepare_payload();

                    m_queue->Post(std::move(response));
                }

            } // namespace Detail
        }   // namespace Http
    }   // namespace Net
}   // namespace Mif
<commit_msg>Http server session has fixed.<commit_after>//-------------------------------------------------------------------
//  MetaInfo Framework (MIF)
//  https://github.com/tdv/mif
//  Created:     11.2020
//  Copyright (C) 2016-2020 tdv
//-------------------------------------------------------------------

// STD
#include <deque>
#include <utility>

// BOOST
#include <boost/beast/websocket.hpp>
#include <boost/make_unique.hpp>

// MIF
#include "mif/common/log.h"
#include "mif/common/unused.h"
#include "mif/net/http/constants.h"

// THIS
#include "input_pack.h"
#include "output_pack.h"
#include "session.h"
#include "utility.h"

namespace Mif
{
    namespace Net
    {
        namespace Http
        {
            namespace Detail
            {

                class Session::Queue final
                {
                public:
                    Queue(Session &session, std::size_t limit)
                        : m_session{session}
                        , m_limit{limit}
                    {
                    }

                    bool IsFull() const noexcept
                    {
                        return m_tasks.size() >= m_limit;
                    }

                    template <typename TBody, typename TFields>
                    using Response = boost::beast::http::response<TBody, TFields>;

                    template <typename TBody, typename TFields>
                    void Post(Response<TBody, TFields> &&response)
                    {
                        auto resp = std::make_shared<Response<TBody, TFields>>(std::move(response));

                        auto task = [this, resp]
                        {
                            boost::beast::http::async_write(m_session.m_stream, *resp,
                                    boost::beast::bind_front_handler(&Session::OnWrite,
                                    m_session.shared_from_this(), resp->need_eof()));
                        };

                        m_tasks.emplace_back(std::move(task));

                        if (m_tasks.size() == 1)
                            m_tasks.front()();
                    }

                    bool Pop()
                    {
                        if (m_tasks.empty())
                        {
                            throw std::runtime_error{"[Mif::Net::Http::Detail::Session::Queue::Pop] "
                                    "Empty queue."};
                        }

                        auto const wasFull = IsFull();

                        m_tasks.pop_front();

                        if (!m_tasks.empty())
                            m_tasks.front()();

                        return wasFull;
                    }

                private:
                    Session &m_session;
                    std::size_t const m_limit;

                    std::deque<std::function<void ()>> m_tasks;
                };

                Session::Session(boost::asio::ip::tcp::socket &&socket, Params const &params)
                    : m_stream{std::move(socket)}
                    , m_params{params}
                    , m_queue{boost::make_unique<Queue>(*this,
                            std::max<std::size_t>(m_params.pipelineLimit, 1))
                        }
                {
                }

                Session::~Session()
                {
                }

                void Session::Run()
                {
                    boost::asio::dispatch(m_stream.get_executor(),
                            boost::beast::bind_front_handler(&Session::Read,
                            shared_from_this())
                        );
                }

                void Session::Read()
                {
                    m_parser.emplace();

                    m_parser->header_limit(m_params.headersSize);
                    m_parser->body_limit(m_params.bodySize);
                    m_stream.expires_after(m_params.requestTimeout);

                    boost::beast::http::async_read(m_stream, m_buffer, *m_parser,
                            boost::beast::bind_front_handler(&Session::OnRead,
                            shared_from_this())
                        );
                }

                void Session::OnRead(boost::beast::error_code ec, std::size_t bytes)
                {
                    Common::Unused(bytes);

                    if (ec == boost::beast::http::error::end_of_stream)
                    {
                        Close();
                        return;
                    }

                    if (ec)
                    {
                        MIF_LOG(Warning) << "[Mif::Net::Http::Detail::Session::OnRead] "
                                << "Failed to read data. Error: " << ec.message();

                        return;
                    }

                    if (boost::beast::websocket::is_upgrade(m_parser->get()))
                    {
                        MIF_LOG(Warning) << "[Mif::Net::Http::Detail::Session::OnRead] "
                                << "Failed to upgrade for starting websocket. Error: it has not implemented yet.";

                        Close();
                        return;
                    }

                    HandleRequest(m_parser->release());
                    // TODO:
                }

                void Session::OnWrite(bool close, boost::beast::error_code ec, std::size_t bytes)
                {
                    Common::Unused(bytes);

                    if (ec)
                    {
                        MIF_LOG(Info) << "[Mif::Net::Http::Detail::Session::OnWrite] "
                                << "Failed to write data. Error: " << ec.message();

                        return;
                    }

                    if (close)
                    {
                        Close();
                        return;
                    }

                    if (m_queue->Pop())
                        Read();
                }

                void Session::Close()
                {
                    boost::beast::error_code ec;
                    m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);

                    if (ec)
                    {
                        MIF_LOG(Warning) << "[Mif::Net::Http::Detail::Session::Close] "
                                << "Failed to close socket. Error: " << ec.message();
                    }
                }

                template <typename TBody, typename TAllocator>
                void Session::HandleRequest(Request<TBody, TAllocator> &&request)
                {
                    try
                    {
                        auto const &path = request.target();

                        if (path.empty() || path[0] != '/' ||
                                path.find("..") != boost::beast::string_view::npos)
                        {
                            ReplyError(boost::beast::http::status::bad_request, "Bad path.", request.keep_alive());
                            return;
                        }

                        if (m_params.allowedMethods.find(
                                Utility::ConvertMethodType(request.method())) ==
                                std::end(m_params.allowedMethods))
                        {
                            ReplyError(boost::beast::http::status::method_not_allowed, "The method is not allowed.",
                                    request.keep_alive());
                            return;
                        }

                        if (m_params.handlers.empty())
                        {
                            ReplyError(boost::beast::http::status::method_not_allowed,
                                    "There is no any method for handling the request.",
                                    request.keep_alive());

                            return;
                        }

                        Response response;

                        std::shared_ptr<IInputPack> in = std::make_shared<InputPack<Request<TBody, TAllocator>>>(request);
                        auto out = std::make_shared<OutputPack<Response>>(response);

                        auto process = [this, &in, &out] (std::string const &path)
                        {
                            auto iter = m_params.handlers.find(path);
                            if (iter != std::end(m_params.handlers))
                            {
                                iter->second(*in, *out);
                                return true;
                            }
                            return false;
                        };

                        auto handled = false;
                        std::string url{in->GetPath()};

                        if (process(url))
                            handled = true;
                        else
                        {
                            if (!url.empty() && url.back() != '/')
                                url.append("/");

                            for (auto pos = url.find_last_of('/') ; pos != std::string::npos ; pos = url.find_last_of('/'))
                            {
                                url = url.substr(0, pos);
                                auto const path = url.empty() ? std::string{"/"} : url;

                                if (process(path))
                                {
                                    handled = true;
                                    break;
                                }
                            }
                        }

                        if (!handled)
                        {
                            ReplyError(boost::beast::http::status::method_not_allowed,
                                    "Handler for the request processing was not found.",
                                    request.keep_alive());

                            return;
                        }

                        Reply(std::move(response), request.keep_alive());
                    }
                    catch (std::exception const &e)
                    {
                        MIF_LOG(Error) << "[Mif::Net::Http::Detail::Session::HandleRequest] "
                                << "Failed to process request. Error: " << e.what();

                        ReplyError(boost::beast::http::status::internal_server_error, "An internal error has occurred.",
                                request.keep_alive());
                    }
                }

                void Session::ReplyError(boost::beast::http::status status, std::string const &reason,
                        bool isKeepAlive)
                {
                    boost::beast::http::response<boost::beast::http::string_body> response;

                    response.result(status);
                    //response.set(boost::beast::http::field::server, "Mif");
                    response.set(boost::beast::http::field::content_type, "text/plain");
                    response.set(boost::beast::http::field::date, Utility::CreateTimestamp());
                    response.keep_alive(isKeepAlive);
                    response.version(11);
                    response.body() = std::string(reason);

                    response.prepare_payload();

                    m_queue->Post(std::move(response));
                }

                void Session::Reply(Response &&response, bool isKeepAlive)
                {
                    //response.result(boost::beast::http::status::ok);
                    //response.set(boost::beast::http::field::server, "Mif");
                    response.set(boost::beast::http::field::date, Utility::CreateTimestamp());
                    response.version(11);
                    response.keep_alive(isKeepAlive);

                    response.prepare_payload();

                    m_queue->Post(std::move(response));
                }

            } // namespace Detail
        }   // namespace Http
    }   // namespace Net
}   // namespace Mif
<|endoftext|>


<commit_before>/**
 * @author Parikshit Ram (pram@cc.gatech.edu)
 * @file gmm_main.cpp
 *
 * This program trains a mixture of Gaussians on a given data matrix.
 */
#include "gmm.hpp"

PROGRAM_INFO("Gaussian Mixture Model (GMM) Training",
    "This program takes a parametric estimate of a Gaussian mixture model (GMM)"
    " using the EM algorithm to find the maximum likelihood estimate.  The "
    "model is saved to an XML file, which contains information about each "
    "Gaussian.");

PARAM_STRING_REQ("input_file", "File containing the data on which the model "
    "will be fit.", "i");
PARAM_INT("gaussians", "Number of Gaussians in the GMM.", "g", 1);
PARAM_STRING("output_file", "The file to write the trained GMM parameters into "
    "(as XML).", "o", "gmm.xml");
PARAM_INT("seed", "Random seed.  If 0, 'std::time(NULL)' is used.", "s", 0);

using namespace mlpack;
using namespace mlpack::gmm;
using namespace mlpack::util;

int main(int argc, char* argv[])
{
  CLI::ParseCommandLine(argc, argv);

  // Check parameters and load data.
  if (CLI::GetParam<int>("seed") != 0)
    math::RandomSeed((size_t) CLI::GetParam<int>("seed"));
  else
    math::RandomSeed((size_t) std::time(NULL));

  arma::mat dataPoints;
  data::Load(CLI::GetParam<std::string>("input_file").c_str(), dataPoints,
      true);

  int gaussians = CLI::GetParam<int>("gaussians");
  if (gaussians <= 0)
  {
    Log::Fatal << "Invalid number of Gaussians (" << gaussians << "); must "
        "be greater than or equal to 1." << std::endl;
  }

  // Calculate mixture of Gaussians.
  GMM<> gmm(size_t(gaussians), dataPoints.n_rows);

  ////// Computing the parameters of the model using the EM algorithm //////
  Timer::Start("em");
  double likelihood = gmm.Estimate(dataPoints);
  Timer::Stop("em");

  Log::Info << "Log-likelihood of estimate: " << likelihood << ".\n";

  ////// OUTPUT RESULTS //////
  SaveRestoreUtility save;
  save.SaveParameter(gmm.Gaussians(), "gaussians");
  save.SaveParameter(gmm.Dimensionality(), "dimensionality");
  save.SaveParameter(trans(gmm.Weights()), "weights");
  for (size_t i = 0; i < gmm.Gaussians(); ++i)
  {
    // Generate names for the XML nodes.
    std::stringstream o;
    o << i;
    std::string meanName = "mean" + o.str();
    std::string covName = "covariance" + o.str();

    // Now save them.
    save.SaveParameter(trans(gmm.Means()[i]), meanName);
    save.SaveParameter(gmm.Covariances()[i], covName);
  }

  save.WriteFile(CLI::GetParam<std::string>("output_file").c_str());
}
<commit_msg>Superfluous c_str().<commit_after>/**
 * @author Parikshit Ram (pram@cc.gatech.edu)
 * @file gmm_main.cpp
 *
 * This program trains a mixture of Gaussians on a given data matrix.
 */
#include "gmm.hpp"

PROGRAM_INFO("Gaussian Mixture Model (GMM) Training",
    "This program takes a parametric estimate of a Gaussian mixture model (GMM)"
    " using the EM algorithm to find the maximum likelihood estimate.  The "
    "model is saved to an XML file, which contains information about each "
    "Gaussian.");

PARAM_STRING_REQ("input_file", "File containing the data on which the model "
    "will be fit.", "i");
PARAM_INT("gaussians", "Number of Gaussians in the GMM.", "g", 1);
PARAM_STRING("output_file", "The file to write the trained GMM parameters into "
    "(as XML).", "o", "gmm.xml");
PARAM_INT("seed", "Random seed.  If 0, 'std::time(NULL)' is used.", "s", 0);

using namespace mlpack;
using namespace mlpack::gmm;
using namespace mlpack::util;

int main(int argc, char* argv[])
{
  CLI::ParseCommandLine(argc, argv);

  // Check parameters and load data.
  if (CLI::GetParam<int>("seed") != 0)
    math::RandomSeed((size_t) CLI::GetParam<int>("seed"));
  else
    math::RandomSeed((size_t) std::time(NULL));

  arma::mat dataPoints;
  data::Load(CLI::GetParam<std::string>("input_file").c_str(), dataPoints,
      true);

  int gaussians = CLI::GetParam<int>("gaussians");
  if (gaussians <= 0)
  {
    Log::Fatal << "Invalid number of Gaussians (" << gaussians << "); must "
        "be greater than or equal to 1." << std::endl;
  }

  // Calculate mixture of Gaussians.
  GMM<> gmm(size_t(gaussians), dataPoints.n_rows);

  ////// Computing the parameters of the model using the EM algorithm //////
  Timer::Start("em");
  double likelihood = gmm.Estimate(dataPoints);
  Timer::Stop("em");

  Log::Info << "Log-likelihood of estimate: " << likelihood << ".\n";

  ////// OUTPUT RESULTS //////
  SaveRestoreUtility save;
  save.SaveParameter(gmm.Gaussians(), "gaussians");
  save.SaveParameter(gmm.Dimensionality(), "dimensionality");
  save.SaveParameter(trans(gmm.Weights()), "weights");
  for (size_t i = 0; i < gmm.Gaussians(); ++i)
  {
    // Generate names for the XML nodes.
    std::stringstream o;
    o << i;
    std::string meanName = "mean" + o.str();
    std::string covName = "covariance" + o.str();

    // Now save them.
    save.SaveParameter(trans(gmm.Means()[i]), meanName);
    save.SaveParameter(gmm.Covariances()[i], covName);
  }

  save.WriteFile(CLI::GetParam<std::string>("output_file"));
}
<|endoftext|>


<commit_before>#ifdef WIN32
#define UNICODE
#define _UNICODE

#include <stdlib.h>

#include "win32bindings.h"
#include "javasigar.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL SIGAR_JNI(win32_RegistryKey_RegCloseKey)
(JNIEnv *, jclass, jlong hkey)
{
    return RegCloseKey((HKEY)hkey);
}

JNIEXPORT jlong JNICALL SIGAR_JNI(win32_RegistryKey_RegCreateKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);

    RegCreateKeyEx((HKEY)hkey, lpSubkey, 0, NULL,
                   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
                   NULL, &hkeyResult, NULL);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LONG    lResult  = RegDeleteKey((HKEY)hkey, lpSubkey);
    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return lResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lResult     = RegDeleteValue((HKEY)hkey, lpValueName);
    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return lResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumKey)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szBuffer[MAX_PATH + 1];

    if(RegEnumKey((HKEY)hkey, index, szBuffer,
                  sizeof(szBuffer)) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szBuffer,
                                   lstrlen(szBuffer));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumValueName)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szValueName[MAX_PATH + 1];
    DWORD   cbValueName = sizeof(szValueName);

    if(RegEnumValue((HKEY)hkey, index, szValueName,
                    &cbValueName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szValueName,
                                   lstrlen(szValueName));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegFlushKey)
(JNIEnv *env, jclass, long hkey)
{
    return RegFlushKey((HKEY)hkey);
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegLoadKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey, jstring file)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LPCTSTR lpFile   = (LPCTSTR)env->GetStringChars(file, NULL);

    LONG lResult = RegLoadKey((HKEY)hkey, lpSubkey, lpFile);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    env->ReleaseStringChars(file, (const jchar *)lpFile);

    return lResult;
}

JNIEXPORT jlong SIGAR_JNI(win32_RegistryKey_RegOpenKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    jsize len = env->GetStringLength(subkey);
    LPTSTR lpSubkey = (LPTSTR)env->GetStringChars(subkey, NULL);
    char orig = lpSubkey[len];
    /* required under IBM/WebSphere 4.0 for certain keys */
    lpSubkey[len] = '\0';
    RegOpenKey((HKEY)hkey, lpSubkey, &hkeyResult);
    lpSubkey[len] = orig;
    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegQueryIntValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    DWORD   dwResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;

    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lErr        = RegQueryValueEx((HKEY)hkey, lpValueName,
                                          NULL, (LPDWORD)&dwType,
                                          NULL, &cbValue);

    if(lErr == ERROR_SUCCESS) {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL,
                           NULL, lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                dwResult = *(LPDWORD)lpValue;
                break;
            case REG_SZ:
                dwResult = _ttol((LPCTSTR)lpValue);
                break;
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }
    else
        // Make an error out of not seeing a REG_DWORD
        lErr = ERROR_SUCCESS - 1;

    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    if(lErr != ERROR_SUCCESS)
    {
        jclass cls =
            env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, NULL);
    }

    return dwResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegQueryStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name)
{
    jstring strResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;

    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    LONG    lErr        = RegQueryValueEx((HKEY)hkey,
                                          lpValueName, NULL,
                                          (LPDWORD)&dwType, NULL, &cbValue);

    if(lErr == ERROR_SUCCESS)
    {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL, NULL,
                           lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                TCHAR   szBuf[20];
                _ltot(*(LPDWORD)lpValue, szBuf, 10);
                strResult = env->NewString((const jchar *)szBuf,
                                           lstrlen(szBuf));
                break;
            case REG_SZ:
            case REG_EXPAND_SZ: {
                DWORD len;
                LPTSTR dest = NULL;
                len = ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, 0);
                dest = (LPTSTR)malloc(len * sizeof(TCHAR));
                ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, len);
                strResult = env->NewString((const jchar *)dest, len);
                free(dest);
                break;
            }
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }

    env->ReleaseStringChars(name, (const jchar *)lpValueName);

    if(lErr == ERROR_SUCCESS)
        return strResult;
    else
    {
        jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, "");
        return NULL;
    }
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetIntValue)
(JNIEnv * env, jclass, jlong hkey, jstring valueName, jint value)
{
    LPCTSTR lpValueName;

    if(valueName != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    else
        lpValueName = NULL;

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_DWORD, (LPBYTE)&value, sizeof(value));

    if(valueName != NULL)
        env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return iResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name, jstring value)
{
    LPCTSTR lpValueName;

    if(name != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    else
        lpValueName = NULL;

    LPCTSTR lpValue = (LPCTSTR)env->GetStringChars(value, NULL);

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_SZ, (LPBYTE)lpValue,
                                (lstrlen(lpValue) + 1) * sizeof(TCHAR));

    if(name != NULL)
        env->ReleaseStringChars(name, (const jchar *)lpValueName);
    env->ReleaseStringChars(value, (const jchar *)lpValue);

    return iResult;
}

#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
<commit_msg>better to make a copy than modify the const string<commit_after>#ifdef WIN32
#define UNICODE
#define _UNICODE

#include <stdlib.h>

#include "win32bindings.h"
#include "javasigar.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL SIGAR_JNI(win32_RegistryKey_RegCloseKey)
(JNIEnv *, jclass, jlong hkey)
{
    return RegCloseKey((HKEY)hkey);
}

JNIEXPORT jlong JNICALL SIGAR_JNI(win32_RegistryKey_RegCreateKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);

    RegCreateKeyEx((HKEY)hkey, lpSubkey, 0, NULL,
                   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
                   NULL, &hkeyResult, NULL);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LONG    lResult  = RegDeleteKey((HKEY)hkey, lpSubkey);
    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);

    return lResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lResult     = RegDeleteValue((HKEY)hkey, lpValueName);
    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return lResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumKey)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szBuffer[MAX_PATH + 1];

    if(RegEnumKey((HKEY)hkey, index, szBuffer,
                  sizeof(szBuffer)) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szBuffer,
                                   lstrlen(szBuffer));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumValueName)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
    jstring strResult;
    TCHAR   szValueName[MAX_PATH + 1];
    DWORD   cbValueName = sizeof(szValueName);

    if(RegEnumValue((HKEY)hkey, index, szValueName,
                    &cbValueName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        strResult = env->NewString((const jchar *)szValueName,
                                   lstrlen(szValueName));
    else
        strResult = NULL;

    return strResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegFlushKey)
(JNIEnv *env, jclass, long hkey)
{
    return RegFlushKey((HKEY)hkey);
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegLoadKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey, jstring file)
{
    LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
    LPCTSTR lpFile   = (LPCTSTR)env->GetStringChars(file, NULL);

    LONG lResult = RegLoadKey((HKEY)hkey, lpSubkey, lpFile);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    env->ReleaseStringChars(file, (const jchar *)lpFile);

    return lResult;
}

JNIEXPORT jlong SIGAR_JNI(win32_RegistryKey_RegOpenKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
    HKEY    hkeyResult = NULL;
    jsize len = env->GetStringLength(subkey);
    LPTSTR lpSubkey = (LPTSTR)env->GetStringChars(subkey, NULL);
    LPTSTR copy;

    /* required under IBM/WebSphere 4.0 for certain keys */
    if (lpSubkey[len] != '\0') {
        copy = wcsdup(lpSubkey);
        copy[len] = '\0';
    }
    else {
        copy = lpSubkey;
    }
    RegOpenKey((HKEY)hkey, copy, &hkeyResult);

    env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
    if (copy != lpSubkey) {
        free(copy);
    }
    return (jlong)hkeyResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegQueryIntValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
    DWORD   dwResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;

    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    LONG    lErr        = RegQueryValueEx((HKEY)hkey, lpValueName,
                                          NULL, (LPDWORD)&dwType,
                                          NULL, &cbValue);

    if(lErr == ERROR_SUCCESS) {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL,
                           NULL, lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                dwResult = *(LPDWORD)lpValue;
                break;
            case REG_SZ:
                dwResult = _ttol((LPCTSTR)lpValue);
                break;
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }
    else
        // Make an error out of not seeing a REG_DWORD
        lErr = ERROR_SUCCESS - 1;

    env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    if(lErr != ERROR_SUCCESS)
    {
        jclass cls =
            env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, NULL);
    }

    return dwResult;
}

JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegQueryStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name)
{
    jstring strResult;
    DWORD   dwType;
    LPBYTE  lpValue;
    DWORD   cbValue;

    LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    LONG    lErr        = RegQueryValueEx((HKEY)hkey,
                                          lpValueName, NULL,
                                          (LPDWORD)&dwType, NULL, &cbValue);

    if(lErr == ERROR_SUCCESS)
    {
        lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY, cbValue);

        if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL, NULL,
                           lpValue, &cbValue) == ERROR_SUCCESS)
        {
            switch(dwType) {
            case REG_DWORD:
                TCHAR   szBuf[20];
                _ltot(*(LPDWORD)lpValue, szBuf, 10);
                strResult = env->NewString((const jchar *)szBuf,
                                           lstrlen(szBuf));
                break;
            case REG_SZ:
            case REG_EXPAND_SZ: {
                DWORD len;
                LPTSTR dest = NULL;
                len = ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, 0);
                dest = (LPTSTR)malloc(len * sizeof(TCHAR));
                ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, len);
                strResult = env->NewString((const jchar *)dest, len);
                free(dest);
                break;
            }
            default:
                lErr = ERROR_SUCCESS - 1; // Make an error
            }
        }

        HeapFree(GetProcessHeap(), 0, lpValue);
    }

    env->ReleaseStringChars(name, (const jchar *)lpValueName);

    if(lErr == ERROR_SUCCESS)
        return strResult;
    else
    {
        jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
        env->ThrowNew(cls, "");
        return NULL;
    }
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetIntValue)
(JNIEnv * env, jclass, jlong hkey, jstring valueName, jint value)
{
    LPCTSTR lpValueName;

    if(valueName != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
    else
        lpValueName = NULL;

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_DWORD, (LPBYTE)&value, sizeof(value));

    if(valueName != NULL)
        env->ReleaseStringChars(valueName, (const jchar *)lpValueName);

    return iResult;
}

JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name, jstring value)
{
    LPCTSTR lpValueName;

    if(name != NULL)
        lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
    else
        lpValueName = NULL;

    LPCTSTR lpValue = (LPCTSTR)env->GetStringChars(value, NULL);

    int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
                                REG_SZ, (LPBYTE)lpValue,
                                (lstrlen(lpValue) + 1) * sizeof(TCHAR));

    if(name != NULL)
        env->ReleaseStringChars(name, (const jchar *)lpValueName);
    env->ReleaseStringChars(value, (const jchar *)lpValue);

    return iResult;
}

#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
<|endoftext|>


<commit_before>/**
 * @file nca_main.cpp
 * @author Ryan Curtin
 *
 * Executable for Neighborhood Components Analysis.
 */
#include <mlpack/core.hpp>
#include <mlpack/core/metrics/lmetric.hpp>

#include "nca.hpp"

// Define parameters.
PROGRAM_INFO("Neighborhood Components Analysis (NCA)",
    "This program implements Neighborhood Components Analysis, both a linear "
    "dimensionality reduction technique and a distance learning technique.  The"
    " method seeks to improve k-nearest-neighbor classification on a dataset "
    "by scaling the dimensions.  The method is nonparametric, and does not "
    "require a value of k.  It works by using stochastic (\"soft\") neighbor "
    "assignments and using optimization techniques over the gradient of the "
    "accuracy of the neighbor assignments.\n"
    "\n"
    "For more details, see the following published paper:\n\n"
    "@inproceedings{\n"
    "  author = {Goldberge, Jacob and Roweis, Sam and Hinton, Geoff and\n"
    "      Salakhutdinov, Ruslan},\n"
    "  booktitle = {Advances in Neural Information Processing Systems 17},\n"
    "  pages = {513--520},\n"
    "  publisher = {MIT Press},\n"
    "  title = {{Neighbourhood Components Analysis}},\n"
    "  year = {2004}\n"
    "}\n"
    "\n"
    "To work, this algorithm needs labeled data.  It can be given as the last "
    "row of the input dataset (--input_file), or alternatively in a separate "
    "file (--labels_file).");

PARAM_STRING_REQ("input_file", "Input dataset to run NCA on.", "i");
PARAM_STRING_REQ("output_file", "Output file for learned distance matrix.",
    "o");
PARAM_STRING("labels_file", "File of labels for input dataset.", "l", "");

using namespace mlpack;
using namespace mlpack::nca;
using namespace mlpack::metric;
using namespace std;
using namespace arma;

int main(int argc, char* argv[])
{
  // Parse command line.
  CLI::ParseCommandLine(argc, argv);

  const string inputFile = CLI::GetParam<string>("input_file");
  const string labelsFile = CLI::GetParam<string>("labels_file");
  const string outputFile = CLI::GetParam<string>("output_file");

  // Load data.
  mat data;
  data::Load(inputFile.c_str(), data, true);

  // Do we want to load labels separately?
  umat labels(data.n_cols, 1);
  if (labelsFile != "")
  {
    data::Load(labelsFile.c_str(), labels, true);

    if (labels.n_rows == 1)
      labels = trans(labels);

    if (labels.n_cols > 1)
      Log::Fatal << "Labels must have only one column or row!" << endl;
  }
  else
  {
    for (size_t i = 0; i < data.n_cols; i++)
      labels[i] = (int) data(data.n_rows - 1, i);

    data.shed_row(data.n_rows - 1);
  }

  // Now create the NCA object and run the optimization.
  NCA<LMetric<2> > nca(data, labels.unsafe_col(0));

  mat distance;
  nca.LearnDistance(distance);

  // Save the output.
  data::Save(CLI::GetParam<string>("output_file").c_str(), distance, true);
}
<commit_msg>Fix spelling error.<commit_after>/**
 * @file nca_main.cpp
 * @author Ryan Curtin
 *
 * Executable for Neighborhood Components Analysis.
 */
#include <mlpack/core.hpp>
#include <mlpack/core/metrics/lmetric.hpp>

#include "nca.hpp"

// Define parameters.
PROGRAM_INFO("Neighborhood Components Analysis (NCA)",
    "This program implements Neighborhood Components Analysis, both a linear "
    "dimensionality reduction technique and a distance learning technique.  The"
    " method seeks to improve k-nearest-neighbor classification on a dataset "
    "by scaling the dimensions.  The method is nonparametric, and does not "
    "require a value of k.  It works by using stochastic (\"soft\") neighbor "
    "assignments and using optimization techniques over the gradient of the "
    "accuracy of the neighbor assignments.\n"
    "\n"
    "For more details, see the following published paper:\n\n"
    "@inproceedings{\n"
    "  author = {Goldberger, Jacob and Roweis, Sam and Hinton, Geoff and\n"
    "      Salakhutdinov, Ruslan},\n"
    "  booktitle = {Advances in Neural Information Processing Systems 17},\n"
    "  pages = {513--520},\n"
    "  publisher = {MIT Press},\n"
    "  title = {{Neighbourhood Components Analysis}},\n"
    "  year = {2004}\n"
    "}\n"
    "\n"
    "To work, this algorithm needs labeled data.  It can be given as the last "
    "row of the input dataset (--input_file), or alternatively in a separate "
    "file (--labels_file).");

PARAM_STRING_REQ("input_file", "Input dataset to run NCA on.", "i");
PARAM_STRING_REQ("output_file", "Output file for learned distance matrix.",
    "o");
PARAM_STRING("labels_file", "File of labels for input dataset.", "l", "");

using namespace mlpack;
using namespace mlpack::nca;
using namespace mlpack::metric;
using namespace std;
using namespace arma;

int main(int argc, char* argv[])
{
  // Parse command line.
  CLI::ParseCommandLine(argc, argv);

  const string inputFile = CLI::GetParam<string>("input_file");
  const string labelsFile = CLI::GetParam<string>("labels_file");
  const string outputFile = CLI::GetParam<string>("output_file");

  // Load data.
  mat data;
  data::Load(inputFile.c_str(), data, true);

  // Do we want to load labels separately?
  umat labels(data.n_cols, 1);
  if (labelsFile != "")
  {
    data::Load(labelsFile.c_str(), labels, true);

    if (labels.n_rows == 1)
      labels = trans(labels);

    if (labels.n_cols > 1)
      Log::Fatal << "Labels must have only one column or row!" << endl;
  }
  else
  {
    for (size_t i = 0; i < data.n_cols; i++)
      labels[i] = (int) data(data.n_rows - 1, i);

    data.shed_row(data.n_rows - 1);
  }

  // Now create the NCA object and run the optimization.
  NCA<LMetric<2> > nca(data, labels.unsafe_col(0));

  mat distance;
  nca.LearnDistance(distance);

  // Save the output.
  data::Save(CLI::GetParam<string>("output_file").c_str(), distance, true);
}
<|endoftext|>


<commit_before>/**
 * @file pca_main.cpp
 * @author Ryan Curtin
 *
 * Main executable to run PCA.
 */
#include <mlpack/core.hpp>

#include "pca.hpp"

using namespace mlpack;
using namespace mlpack::pca;
using namespace std;

// Document program.
PROGRAM_INFO("Principal Components Analysis", "This program performs principal "
    "components analysis on the given dataset.  It will transform the data "
    "onto its principal components, optionally performing dimensionality "
    "reduction by ignoring the principal components with the smallest "
    "eigenvalues.", "");

// Parameters for program.
PARAM_STRING_REQ("input_file", "Input dataset to perform PCA on.", "");
PARAM_STRING_REQ("output_file", "Output dataset to perform PCA on.", "");
PARAM_INT("new_dimensionality", "Desired dimensionality of output dataset.",
    "", 0);

int main(int argc, char** argv)
{
  // Parse commandline.
  CLI::ParseCommandLine(argc, argv);

  // Load input dataset.
  string inputFile = CLI::GetParam<string>("input_file");
  arma::mat dataset;
  data::Load(inputFile.c_str(), dataset);

  // Find out what dimension we want.
  size_t newDimension = dataset.n_rows; // No reduction, by default.
  if (CLI::HasParam("new_dimensionality"))
  {
    // Validate the parameter.
    newDimension = (size_t) CLI::GetParam<int>("new_dimensionality");
    if (newDimension < 1);
    {
      Log::Fatal << "Invalid value for new dimensionality (" << newDimension
          << ")!  Must be greater than or equal to 1." << std::endl;
    }
  }

  // Perform PCA.
  PCA p;
  Log::Info << "Performing PCA on dataset..." << std::endl;
  p.Apply(dataset, newDimension);

  // Now save the results.
  string outputFile = CLI::GetParam<string>("output_file");
  data::Save(outputFile.c_str(), dataset);
}
<commit_msg>Fix for integer parameter.<commit_after>/**
 * @file pca_main.cpp
 * @author Ryan Curtin
 *
 * Main executable to run PCA.
 */
#include <mlpack/core.hpp>

#include "pca.hpp"

using namespace mlpack;
using namespace mlpack::pca;
using namespace std;

// Document program.
PROGRAM_INFO("Principal Components Analysis", "This program performs principal "
    "components analysis on the given dataset.  It will transform the data "
    "onto its principal components, optionally performing dimensionality "
    "reduction by ignoring the principal components with the smallest "
    "eigenvalues.", "");

// Parameters for program.
PARAM_STRING_REQ("input_file", "Input dataset to perform PCA on.", "");
PARAM_STRING_REQ("output_file", "Output dataset to perform PCA on.", "");
PARAM_INT("new_dimensionality", "Desired dimensionality of output dataset.",
    "", 0);

int main(int argc, char** argv)
{
  // Parse commandline.
  CLI::ParseCommandLine(argc, argv);

  // Load input dataset.
  string inputFile = CLI::GetParam<string>("input_file");
  arma::mat dataset;
  data::Load(inputFile.c_str(), dataset);

  // Find out what dimension we want.
  size_t newDimension = dataset.n_rows; // No reduction, by default.
  if (CLI::GetParam<int>("new_dimensionality") != 0)
  {
    // Validate the parameter.
    newDimension = (size_t) CLI::GetParam<int>("new_dimensionality");
    if (newDimension < 1);
    {
      Log::Fatal << "Invalid value for new dimensionality (" << newDimension
          << ")!  Must be greater than or equal to 1." << std::endl;
    }
  }

  // Perform PCA.
  PCA p;
  Log::Info << "Performing PCA on dataset..." << std::endl;
  p.Apply(dataset, newDimension);

  // Now save the results.
  string outputFile = CLI::GetParam<string>("output_file");
  data::Save(outputFile.c_str(), dataset);
}
<|endoftext|>


<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation; either version 2.1 of the License,               *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa is distributed in the hope that it will be useful,                 *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       *
 * See the GNU Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#include <poll.h>
#include "cppa/network/middleman_event_handler.hpp"

#ifndef POLLRDHUP
#define POLLRDHUP POLLHUP
#endif

namespace cppa { namespace network {

namespace {

bool pollfd_less(const pollfd& lhs, native_socket_type rhs) {
    return lhs.fd < rhs;
}

short to_poll_bitmask(event_bitmask mask) {
    switch (mask) {
        case event::read:  return POLLIN;
        case event::write: return POLLOUT;
        case event::both:  return (POLLIN|POLLOUT);
        default: CPPA_CRITICAL("invalid event bitmask");
    }
}

class middleman_event_handler_impl : public middleman_event_handler {

 public:

    void init() { }

 protected:

    void poll_impl() {
        CPPA_REQUIRE(m_pollset.empty() == false);
        CPPA_REQUIRE(m_pollset.size() == m_meta.size());
        int presult;
        do {
            presult = ::poll(m_pollset.data(), m_pollset.size(), -1);
            CPPA_LOGMF(CPPA_DEBUG, self, "poll() on " << num_sockets()
                           << " sockets returned " << presult);
            if (presult < 0) {
                switch (errno) {
                    // a signal was caught
                    case EINTR: {
                        // just try again
                        break;
                    }
                    case ENOMEM: {
                        CPPA_LOGMF(CPPA_ERROR, self, "poll() failed for reason ENOMEM");
                        // there's not much we can do other than try again
                        // in hope someone releases memory
                        //this_thread::yield();
                        break;
                    }
                    default: {
                        perror("poll() failed");
                        CPPA_CRITICAL("poll() failed");
                    }
                }
            }
            else {
                for (size_t i = 0; i < m_pollset.size(); ++i) {
                    event_bitmask eb = event::none;
                    auto& revents = m_pollset[i].revents;
                    if (revents & (POLLRDHUP | POLLERR | POLLHUP | POLLNVAL)) {
                        eb = event::error;
                    }
                    else {
                        if (revents & (POLLIN | POLLPRI)) eb |= event::read;
                        if (revents & POLLOUT) eb |= event::write;
                    }
                    revents = 0;
                    m_events.emplace_back(eb, m_meta[i].ptr.get());
                }
            }
        } while (presult < 0);
    }

    void handle_event(fd_meta_event me,
                      native_socket_type fd,
                      event_bitmask,
                      event_bitmask new_bitmask,
                      continuable_io*) {
        auto last = m_pollset.end();
        auto iter = std::lower_bound(m_pollset.begin(), last, fd, pollfd_less);
        switch (me) {
            case fd_meta_event::add: {
                pollfd tmp;
                tmp.fd = fd;
                tmp.events = to_poll_bitmask(new_bitmask);
                tmp.revents = 0;
                m_pollset.insert(iter, tmp);
                CPPA_LOGMF(CPPA_DEBUG, self, "inserted new element");
                break;
            }
            case fd_meta_event::erase: {
                CPPA_LOG_ERROR_IF(iter == last || iter->fd != fd,
                                  "m_meta and m_pollset out of sync; "
                                  "no element found for fd (cannot erase)");
                if (iter != last && iter->fd == fd) {
                    CPPA_LOGMF(CPPA_DEBUG, self, "erased element");
                    m_pollset.erase(iter);
                }
                break;
            }
            case fd_meta_event::mod: {
                CPPA_LOG_ERROR_IF(iter == last || iter->fd != fd,
                                  "m_meta and m_pollset out of sync; "
                                  "no element found for fd (cannot erase)");
                if (iter != last && iter->fd == fd) {
                    CPPA_LOGMF(CPPA_DEBUG, self, "updated bitmask");
                    iter->events = to_poll_bitmask(new_bitmask);
                }
                break;
            }
        }
    }

 private:

    std::vector<pollfd> m_pollset; // always in sync with m_meta

};

} // namespace <anonymous>

std::unique_ptr<middleman_event_handler> middleman_event_handler::create() {
    return std::unique_ptr<middleman_event_handler>{new middleman_event_handler_impl};
}

} } // namespace cppa::network
<commit_msg>ignore POLLHUP until there's no more data to read<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation; either version 2.1 of the License,               *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa is distributed in the hope that it will be useful,                 *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       *
 * See the GNU Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#include <poll.h>
#include "cppa/network/middleman_event_handler.hpp"

#ifndef POLLRDHUP
#define POLLRDHUP POLLHUP
#endif

namespace cppa { namespace network {

namespace {

bool pollfd_less(const pollfd& lhs, native_socket_type rhs) {
    return lhs.fd < rhs;
}

short to_poll_bitmask(event_bitmask mask) {
    switch (mask) {
        case event::read:  return POLLIN;
        case event::write: return POLLOUT;
        case event::both:  return (POLLIN|POLLOUT);
        default: CPPA_CRITICAL("invalid event bitmask");
    }
}

class middleman_event_handler_impl : public middleman_event_handler {

 public:

    void init() { }

 protected:

    void poll_impl() {
        CPPA_REQUIRE(m_pollset.empty() == false);
        CPPA_REQUIRE(m_pollset.size() == m_meta.size());
        int presult;
        do {
            presult = ::poll(m_pollset.data(), m_pollset.size(), -1);
            CPPA_LOG_DEBUG("poll() on " << num_sockets()
                           << " sockets returned " << presult);
            if (presult < 0) {
                switch (errno) {
                    // a signal was caught
                    case EINTR: {
                        // just try again
                        break;
                    }
                    case ENOMEM: {
                        CPPA_LOGMF(CPPA_ERROR, self, "poll() failed for reason ENOMEM");
                        // there's not much we can do other than try again
                        // in hope someone releases memory
                        //this_thread::yield();
                        break;
                    }
                    default: {
                        perror("poll() failed");
                        CPPA_CRITICAL("poll() failed");
                    }
                }
            }
            else {
                for (size_t i = 0; i < m_pollset.size(); ++i) {
                    event_bitmask eb = event::none;
                    auto& revents = m_pollset[i].revents;
                    // read as long as possible, ignore POLLHUP as long as
                    // there is still data available
                    if (revents & (POLLIN | POLLPRI)) eb |= event::read;
                    else if (revents & (POLLRDHUP | POLLERR | POLLHUP | POLLNVAL)) {
                        CPPA_LOG_DEBUG_IF(revents & POLLRDHUP, "POLLRDHUP");
                        CPPA_LOG_DEBUG_IF(revents & POLLERR,   "POLLERR");
                        CPPA_LOG_DEBUG_IF(revents & POLLHUP,   "POLLHUP");
                        CPPA_LOG_DEBUG_IF(revents & POLLNVAL,  "POLLNVAL");
                        eb = event::error;
                    }
                    // POLLOUT and POLLHUP are mutually exclusive:
                    // no need to check wheter event::error has been set
                    if (revents & POLLOUT) eb |= event::write;
                    revents = 0;
                    m_events.emplace_back(eb, m_meta[i].ptr.get());
                }
            }
        } while (presult < 0);
    }

    void handle_event(fd_meta_event me,
                      native_socket_type fd,
                      event_bitmask,
                      event_bitmask new_bitmask,
                      continuable_io*) {
        auto last = m_pollset.end();
        auto iter = std::lower_bound(m_pollset.begin(), last, fd, pollfd_less);
        switch (me) {
            case fd_meta_event::add: {
                pollfd tmp;
                tmp.fd = fd;
                tmp.events = to_poll_bitmask(new_bitmask);
                tmp.revents = 0;
                m_pollset.insert(iter, tmp);
                CPPA_LOGMF(CPPA_DEBUG, self, "inserted new element");
                break;
            }
            case fd_meta_event::erase: {
                CPPA_LOG_ERROR_IF(iter == last || iter->fd != fd,
                                  "m_meta and m_pollset out of sync; "
                                  "no element found for fd (cannot erase)");
                if (iter != last && iter->fd == fd) {
                    CPPA_LOGMF(CPPA_DEBUG, self, "erased element");
                    m_pollset.erase(iter);
                }
                break;
            }
            case fd_meta_event::mod: {
                CPPA_LOG_ERROR_IF(iter == last || iter->fd != fd,
                                  "m_meta and m_pollset out of sync; "
                                  "no element found for fd (cannot erase)");
                if (iter != last && iter->fd == fd) {
                    CPPA_LOGMF(CPPA_DEBUG, self, "updated bitmask");
                    iter->events = to_poll_bitmask(new_bitmask);
                }
                break;
            }
        }
    }

 private:

    std::vector<pollfd> m_pollset; // always in sync with m_meta

};

} // namespace <anonymous>

std::unique_ptr<middleman_event_handler> middleman_event_handler::create() {
    return std::unique_ptr<middleman_event_handler>{new middleman_event_handler_impl};
}

} } // namespace cppa::network
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: clang -shared %S/call_lib.c -o%T/libcall_lib%shlibext && ls %T/libcall_lib%shlibext && cat %s | %cling -L%T | FileCheck %s

.L libcall_lib
extern "C" int cling_testlibrary_function();
int i = cling_testlibrary_function();
extern "C" int printf(const char* fmt, ...);
printf("got i=%d\n", i); // CHECK: got i=66
.q
<commit_msg>Changing output name call.C test.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: clang -shared %S/call_lib.c -o%T/libcall_lib2%shlibext
// RUN: cat %s | %cling -L%T | FileCheck %s

.L libcall_lib2
extern "C" int cling_testlibrary_function();
int i = cling_testlibrary_function();
extern "C" int printf(const char* fmt, ...);
printf("got i=%d\n", i); // CHECK: got i=66
.q
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef ARRAY_MAP_HH_
#define ARRAY_MAP_HH_

#include <array>

// unordered_map implemented as a simple array

template <typename Value, size_t Max>
class array_map {
    std::array<Value, Max> _a;
public:
    array_map(std::initializer_list<std::pair<size_t, Value>> i) {
        for (auto kv : i) {
            _a[kv.first] = kv.second;
        }
    }
    Value& operator[](size_t key) { return _a[key]; }
    const Value& operator[](size_t key) const { return _a[key]; }
};

#endif /* ARRAY_MAP_HH_ */
<commit_msg>array_map: introduce at()<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef ARRAY_MAP_HH_
#define ARRAY_MAP_HH_

#include <array>

// unordered_map implemented as a simple array

template <typename Value, size_t Max>
class array_map {
    std::array<Value, Max> _a;
public:
    array_map(std::initializer_list<std::pair<size_t, Value>> i) {
        for (auto kv : i) {
            _a[kv.first] = kv.second;
        }
    }
    Value& operator[](size_t key) { return _a[key]; }
    const Value& operator[](size_t key) const { return _a[key]; }

    Value& at(size_t key) {
        if (key >= Max) {
            throw std::out_of_range(std::to_string(key) + " >= " + std::to_string(Max));
        }
        return _a[key];
    }
};

#endif /* ARRAY_MAP_HH_ */
<|endoftext|>


<commit_before><commit_msg>Len() != isEmpty()<commit_after><|endoftext|>


<commit_before>/*!
@file

@copyright Edouard Alligand and Joel Falcou 2015-2017
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_BRIGAND_TYPES_NO_SUCH_TYPE_HPP
#define BOOST_BRIGAND_TYPES_NO_SUCH_TYPE_HPP

namespace brigand
{
    // type to return when finding something fails
    // I wanted to call it "not sure if type" but Joel didn't want to :(
    struct no_such_type_ {};
}
#endif
<commit_msg>Delete no_such_type.hpp<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"

// The end-to-end test exercises the asynchronous APIs in ObjectProxy and
// ExportedObject.
class EndToEndAsyncTest : public testing::Test {
 public:
  EndToEndAsyncTest() {
  }

  virtual void SetUp() {
    // Make the main thread not to allow IO.
    base::ThreadRestrictions::SetIOAllowed(false);

    // Start the D-Bus thread.
    dbus_thread_.reset(new base::Thread("D-Bus Thread"));
    base::Thread::Options thread_options;
    thread_options.message_loop_type = MessageLoop::TYPE_IO;
    ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options));

    // Start the test service, using the D-Bus thread.
    dbus::TestService::Options options;
    options.dbus_thread_message_loop_proxy = dbus_thread_->message_loop_proxy();
    test_service_.reset(new dbus::TestService(options));
    ASSERT_TRUE(test_service_->StartService());
    ASSERT_TRUE(test_service_->WaitUntilServiceIsStarted());
    ASSERT_TRUE(test_service_->HasDBusThread());

    // Create the client, using the D-Bus thread.
    dbus::Bus::Options bus_options;
    bus_options.bus_type = dbus::Bus::SESSION;
    bus_options.connection_type = dbus::Bus::PRIVATE;
    bus_options.dbus_thread_message_loop_proxy =
        dbus_thread_->message_loop_proxy();
    bus_ = new dbus::Bus(bus_options);
    object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService",
                                         "/org/chromium/TestObject");
    ASSERT_TRUE(bus_->HasDBusThread());

    // Connect to the "Test" signal of "org.chromium.TestInterface" from
    // the remote object.
    object_proxy_->ConnectToSignal(
        "org.chromium.TestInterface",
        "Test",
        base::Bind(&EndToEndAsyncTest::OnTestSignal,
                   base::Unretained(this)),
        base::Bind(&EndToEndAsyncTest::OnConnected,
                   base::Unretained(this)));
    // Connect to the "Test2" signal of "org.chromium.TestInterface" from
    // the remote object. There was a bug where we were emitting error
    // messages like "Requested to remove an unknown match rule: ..." at
    // the shutdown of Bus when an object proxy is connected to more than
    // one signal of the same interface. See crosbug.com/23382 for details.
    object_proxy_->ConnectToSignal(
        "org.chromium.TestInterface",
        "Test2",
        base::Bind(&EndToEndAsyncTest::OnTest2Signal,
                   base::Unretained(this)),
        base::Bind(&EndToEndAsyncTest::OnConnected,
                   base::Unretained(this)));
    // Wait until the object proxy is connected to the signal.
    message_loop_.Run();
  }

  virtual void TearDown() {
    bus_->ShutdownOnDBusThreadAndBlock();

    // Shut down the service.
    test_service_->ShutdownAndBlock();

    // Reset to the default.
    base::ThreadRestrictions::SetIOAllowed(true);

    // Stopping a thread is considered an IO operation, so do this after
    // allowing IO.
    test_service_->Stop();
  }

 protected:
  // Calls the method asynchronously. OnResponse() will be called once the
  // response is received.
  void CallMethod(dbus::MethodCall* method_call,
                  int timeout_ms) {
    object_proxy_->CallMethod(method_call,
                              timeout_ms,
                              base::Bind(&EndToEndAsyncTest::OnResponse,
                                         base::Unretained(this)));
  }

  // Wait for the give number of responses.
  void WaitForResponses(size_t num_responses) {
    while (response_strings_.size() < num_responses) {
      message_loop_.Run();
    }
  }

  // Called when the response is received.
  void OnResponse(dbus::Response* response) {
    // |response| will be deleted on exit of the function. Copy the
    // payload to |response_strings_|.
    if (response) {
      dbus::MessageReader reader(response);
      std::string response_string;
      ASSERT_TRUE(reader.PopString(&response_string));
      response_strings_.push_back(response_string);
    } else {
      response_strings_.push_back("");
    }
    message_loop_.Quit();
  };

  // Called when the "Test" signal is received, in the main thread.
  // Copy the string payload to |test_signal_string_|.
  void OnTestSignal(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    ASSERT_TRUE(reader.PopString(&test_signal_string_));
    message_loop_.Quit();
  }

  // Called when the "Test2" signal is received, in the main thread.
  void OnTest2Signal(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    message_loop_.Quit();
  }

  // Called when connected to the signal.
  void OnConnected(const std::string& interface_name,
                   const std::string& signal_name,
                   bool success) {
    ASSERT_TRUE(success);
    message_loop_.Quit();
  }

  // Wait for the hey signal to be received.
  void WaitForTestSignal() {
    // OnTestSignal() will quit the message loop.
    message_loop_.Run();
  }

  MessageLoop message_loop_;
  std::vector<std::string> response_strings_;
  scoped_ptr<base::Thread> dbus_thread_;
  scoped_refptr<dbus::Bus> bus_;
  dbus::ObjectProxy* object_proxy_;
  scoped_ptr<dbus::TestService> test_service_;
  // Text message from "Test" signal.
  std::string test_signal_string_;
};

TEST_F(EndToEndAsyncTest, Echo) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method.
  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);

  // Check the response.
  WaitForResponses(1);
  EXPECT_EQ(kHello, response_strings_[0]);
}

// Call Echo method three times.
TEST_F(EndToEndAsyncTest, EchoThreeTimes) {
  const char* kMessages[] = { "foo", "bar", "baz" };

  for (size_t i = 0; i < arraysize(kMessages); ++i) {
    // Create the method call.
    dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(kMessages[i]);

    // Call the method.
    const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
    CallMethod(&method_call, timeout_ms);
  }

  // Check the responses.
  WaitForResponses(3);
  // Sort as the order of the returned messages is not deterministic.
  std::sort(response_strings_.begin(), response_strings_.end());
  EXPECT_EQ("bar", response_strings_[0]);
  EXPECT_EQ("baz", response_strings_[1]);
  EXPECT_EQ("foo", response_strings_[2]);
}

TEST_F(EndToEndAsyncTest, Timeout) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "SlowEcho");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method with timeout of 0ms.
  const int timeout_ms = 0;
  CallMethod(&method_call, timeout_ms);
  WaitForResponses(1);

  // Should fail because of timeout.
  ASSERT_EQ("", response_strings_[0]);
}

// Tests calling a method that sends its reply asynchronously.
TEST_F(EndToEndAsyncTest, AsyncEcho) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "AsyncEcho");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method.
  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);

  // Check the response.
  WaitForResponses(1);
  EXPECT_EQ(kHello, response_strings_[0]);
}

TEST_F(EndToEndAsyncTest, NonexistentMethod) {
  dbus::MethodCall method_call("org.chromium.TestInterface", "Nonexistent");

  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);
  WaitForResponses(1);

  // Should fail because the method is nonexistent.
  ASSERT_EQ("", response_strings_[0]);
}

TEST_F(EndToEndAsyncTest, BrokenMethod) {
  dbus::MethodCall method_call("org.chromium.TestInterface", "BrokenMethod");

  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);
  WaitForResponses(1);

  // Should fail because the method is broken.
  ASSERT_EQ("", response_strings_[0]);
}

TEST_F(EndToEndAsyncTest, EmptyResponseCallback) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method with an empty callback.
  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  object_proxy_->CallMethod(&method_call,
                            timeout_ms,
                            dbus::ObjectProxy::EmptyResponseCallback());
  // Post a delayed task to quit the message loop.
  message_loop_.PostDelayedTask(FROM_HERE,
                                MessageLoop::QuitClosure(),
                                TestTimeouts::tiny_timeout_ms());
  message_loop_.Run();
  // We cannot tell if the empty callback is called, but at least we can
  // check if the test does not crash.
}

TEST_F(EndToEndAsyncTest, TestSignal) {
  const char kMessage[] = "hello, world";
  // Send the test signal from the exported object.
  test_service_->SendTestSignal(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // EndToEndAsyncTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);
}

// Flaky, http://crbug.com/106796
TEST_F(EndToEndAsyncTest, FLAKY_TestSignalFromRoot) {
  const char kMessage[] = "hello, world";
  // Send the test signal from the root object path, to see if we can
  // handle signals sent from "/", like dbus-send does.
  test_service_->SendTestSignalFromRoot(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // EndToEndAsyncTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);
}
<commit_msg>Mark EndToEndAsyncTest.TestSignal as flaky<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"

// The end-to-end test exercises the asynchronous APIs in ObjectProxy and
// ExportedObject.
class EndToEndAsyncTest : public testing::Test {
 public:
  EndToEndAsyncTest() {
  }

  virtual void SetUp() {
    // Make the main thread not to allow IO.
    base::ThreadRestrictions::SetIOAllowed(false);

    // Start the D-Bus thread.
    dbus_thread_.reset(new base::Thread("D-Bus Thread"));
    base::Thread::Options thread_options;
    thread_options.message_loop_type = MessageLoop::TYPE_IO;
    ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options));

    // Start the test service, using the D-Bus thread.
    dbus::TestService::Options options;
    options.dbus_thread_message_loop_proxy = dbus_thread_->message_loop_proxy();
    test_service_.reset(new dbus::TestService(options));
    ASSERT_TRUE(test_service_->StartService());
    ASSERT_TRUE(test_service_->WaitUntilServiceIsStarted());
    ASSERT_TRUE(test_service_->HasDBusThread());

    // Create the client, using the D-Bus thread.
    dbus::Bus::Options bus_options;
    bus_options.bus_type = dbus::Bus::SESSION;
    bus_options.connection_type = dbus::Bus::PRIVATE;
    bus_options.dbus_thread_message_loop_proxy =
        dbus_thread_->message_loop_proxy();
    bus_ = new dbus::Bus(bus_options);
    object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService",
                                         "/org/chromium/TestObject");
    ASSERT_TRUE(bus_->HasDBusThread());

    // Connect to the "Test" signal of "org.chromium.TestInterface" from
    // the remote object.
    object_proxy_->ConnectToSignal(
        "org.chromium.TestInterface",
        "Test",
        base::Bind(&EndToEndAsyncTest::OnTestSignal,
                   base::Unretained(this)),
        base::Bind(&EndToEndAsyncTest::OnConnected,
                   base::Unretained(this)));
    // Connect to the "Test2" signal of "org.chromium.TestInterface" from
    // the remote object. There was a bug where we were emitting error
    // messages like "Requested to remove an unknown match rule: ..." at
    // the shutdown of Bus when an object proxy is connected to more than
    // one signal of the same interface. See crosbug.com/23382 for details.
    object_proxy_->ConnectToSignal(
        "org.chromium.TestInterface",
        "Test2",
        base::Bind(&EndToEndAsyncTest::OnTest2Signal,
                   base::Unretained(this)),
        base::Bind(&EndToEndAsyncTest::OnConnected,
                   base::Unretained(this)));
    // Wait until the object proxy is connected to the signal.
    message_loop_.Run();
  }

  virtual void TearDown() {
    bus_->ShutdownOnDBusThreadAndBlock();

    // Shut down the service.
    test_service_->ShutdownAndBlock();

    // Reset to the default.
    base::ThreadRestrictions::SetIOAllowed(true);

    // Stopping a thread is considered an IO operation, so do this after
    // allowing IO.
    test_service_->Stop();
  }

 protected:
  // Calls the method asynchronously. OnResponse() will be called once the
  // response is received.
  void CallMethod(dbus::MethodCall* method_call,
                  int timeout_ms) {
    object_proxy_->CallMethod(method_call,
                              timeout_ms,
                              base::Bind(&EndToEndAsyncTest::OnResponse,
                                         base::Unretained(this)));
  }

  // Wait for the give number of responses.
  void WaitForResponses(size_t num_responses) {
    while (response_strings_.size() < num_responses) {
      message_loop_.Run();
    }
  }

  // Called when the response is received.
  void OnResponse(dbus::Response* response) {
    // |response| will be deleted on exit of the function. Copy the
    // payload to |response_strings_|.
    if (response) {
      dbus::MessageReader reader(response);
      std::string response_string;
      ASSERT_TRUE(reader.PopString(&response_string));
      response_strings_.push_back(response_string);
    } else {
      response_strings_.push_back("");
    }
    message_loop_.Quit();
  };

  // Called when the "Test" signal is received, in the main thread.
  // Copy the string payload to |test_signal_string_|.
  void OnTestSignal(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    ASSERT_TRUE(reader.PopString(&test_signal_string_));
    message_loop_.Quit();
  }

  // Called when the "Test2" signal is received, in the main thread.
  void OnTest2Signal(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    message_loop_.Quit();
  }

  // Called when connected to the signal.
  void OnConnected(const std::string& interface_name,
                   const std::string& signal_name,
                   bool success) {
    ASSERT_TRUE(success);
    message_loop_.Quit();
  }

  // Wait for the hey signal to be received.
  void WaitForTestSignal() {
    // OnTestSignal() will quit the message loop.
    message_loop_.Run();
  }

  MessageLoop message_loop_;
  std::vector<std::string> response_strings_;
  scoped_ptr<base::Thread> dbus_thread_;
  scoped_refptr<dbus::Bus> bus_;
  dbus::ObjectProxy* object_proxy_;
  scoped_ptr<dbus::TestService> test_service_;
  // Text message from "Test" signal.
  std::string test_signal_string_;
};

TEST_F(EndToEndAsyncTest, Echo) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method.
  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);

  // Check the response.
  WaitForResponses(1);
  EXPECT_EQ(kHello, response_strings_[0]);
}

// Call Echo method three times.
TEST_F(EndToEndAsyncTest, EchoThreeTimes) {
  const char* kMessages[] = { "foo", "bar", "baz" };

  for (size_t i = 0; i < arraysize(kMessages); ++i) {
    // Create the method call.
    dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(kMessages[i]);

    // Call the method.
    const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
    CallMethod(&method_call, timeout_ms);
  }

  // Check the responses.
  WaitForResponses(3);
  // Sort as the order of the returned messages is not deterministic.
  std::sort(response_strings_.begin(), response_strings_.end());
  EXPECT_EQ("bar", response_strings_[0]);
  EXPECT_EQ("baz", response_strings_[1]);
  EXPECT_EQ("foo", response_strings_[2]);
}

TEST_F(EndToEndAsyncTest, Timeout) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "SlowEcho");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method with timeout of 0ms.
  const int timeout_ms = 0;
  CallMethod(&method_call, timeout_ms);
  WaitForResponses(1);

  // Should fail because of timeout.
  ASSERT_EQ("", response_strings_[0]);
}

// Tests calling a method that sends its reply asynchronously.
TEST_F(EndToEndAsyncTest, AsyncEcho) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "AsyncEcho");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method.
  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);

  // Check the response.
  WaitForResponses(1);
  EXPECT_EQ(kHello, response_strings_[0]);
}

TEST_F(EndToEndAsyncTest, NonexistentMethod) {
  dbus::MethodCall method_call("org.chromium.TestInterface", "Nonexistent");

  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);
  WaitForResponses(1);

  // Should fail because the method is nonexistent.
  ASSERT_EQ("", response_strings_[0]);
}

TEST_F(EndToEndAsyncTest, BrokenMethod) {
  dbus::MethodCall method_call("org.chromium.TestInterface", "BrokenMethod");

  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  CallMethod(&method_call, timeout_ms);
  WaitForResponses(1);

  // Should fail because the method is broken.
  ASSERT_EQ("", response_strings_[0]);
}

TEST_F(EndToEndAsyncTest, EmptyResponseCallback) {
  const char* kHello = "hello";

  // Create the method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method with an empty callback.
  const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
  object_proxy_->CallMethod(&method_call,
                            timeout_ms,
                            dbus::ObjectProxy::EmptyResponseCallback());
  // Post a delayed task to quit the message loop.
  message_loop_.PostDelayedTask(FROM_HERE,
                                MessageLoop::QuitClosure(),
                                TestTimeouts::tiny_timeout_ms());
  message_loop_.Run();
  // We cannot tell if the empty callback is called, but at least we can
  // check if the test does not crash.
}

// Flaky, http://crbug.com/107301
TEST_F(EndToEndAsyncTest, FLAKY_TestSignal) {
  const char kMessage[] = "hello, world";
  // Send the test signal from the exported object.
  test_service_->SendTestSignal(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // EndToEndAsyncTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);
}

// Flaky, http://crbug.com/106796
TEST_F(EndToEndAsyncTest, FLAKY_TestSignalFromRoot) {
  const char kMessage[] = "hello, world";
  // Send the test signal from the root object path, to see if we can
  // handle signals sent from "/", like dbus-send does.
  test_service_->SendTestSignalFromRoot(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // EndToEndAsyncTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);
}
<|endoftext|>