text:
/**
 * Copyright (c) 2018 Melown Technologies SE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * *  Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstdlib>
#include <utility>
#include <functional>
#include <map>

#include <boost/thread.hpp>
#include <boost/format.hpp>

#include "dbglog/dbglog.hpp"

#include "utility/streams.hpp"
#include "utility/buildsys.hpp"
#include "utility/openmp.hpp"
#include "service/cmdline.hpp"

#include "geo/geodataset.hpp"

#include "vts-libs/vts/tileop.hpp"
#include "vts-libs/vts/io.hpp"

#include "./tiling.hpp"

namespace fs = boost::filesystem;
namespace vts = vtslibs::vts;

namespace tiling {

namespace {

struct Flag {
    typedef vts::TileIndex::Flag::value_type value_type;
    enum : value_type {
        descend = 0x1
        , analyze = 0x2
    };
};

math::Extents2 extentsPlusHalfPixel(const math::Extents2 &extents
                                    , int pixels)
{
    auto es(math::size(extents));
    const math::Size2f px(es.width / pixels, es.height / pixels);
    const math::Point2 hpx(px.width / 2, px.height / 2);
    return math::Extents2(extents.ll - hpx, extents.ur + hpx);
}

typedef vts::TileIndex::Flag TiFlag;

class TreeWalker {
public:
    TreeWalker(vts::TileIndex &ti, const fs::path &dataset
               , const vts::NodeInfo &root
               , const vts::LodRange &lodRange
               , const vts::LodTileRange::list &tileRanges
               , const Config &config);

private:
    void process(bool parentProductive
                 , const vts::NodeInfo &node, double upscaling = 0.0);
    void descend(const vts::NodeInfo &node, const vts::TileId &tileId
                 , double upscaling);

    const geo::GeoDataset& dataset() {
        return gds_[omp_get_thread_num()];
    }

    void prepareDataset() {
        int count(omp_get_num_threads());
        gds_.reserve(count);
        for (int i(0); i < count; ++i) {
            gds_.emplace_back(geo::GeoDataset::open(dataset_));
        }
    }

    void buildWorld(const vts::LodRange &lodRange
                    , const vts::LodTileRange::list &tileRanges);

    const fs::path dataset_;
    vts::TileIndex &ti_;
    vts::LodRange lodRange_;

    std::vector<geo::GeoDataset> gds_;
    Config config_;

    vts::TileIndex world_;
};

TreeWalker::TreeWalker(vts::TileIndex &ti, const fs::path &dataset
                       , const vts::NodeInfo &root
                       , const vts::LodRange &lodRange
                       , const vts::LodTileRange::list &tileRanges
                       , const Config &config)
    : dataset_(dataset), ti_(ti), lodRange_(lodRange)
    , config_(config)
{
    buildWorld(lodRange, tileRanges);

    if (config_.parallel) {
        UTILITY_OMP(parallel)
            UTILITY_OMP(single)
            {
                prepareDataset();
                process(false, root);
            }
    } else {
        prepareDataset();
        process(false, root);
    }
}

void TreeWalker::buildWorld(const vts::LodRange &lodRange
                            , const vts::LodTileRange::list &tileRanges)
{
    // process whole LOD range from root
    for (auto lod : vts::LodRange(0, lodRange.max)) {
        // set mesh flag everywhere we have to step in
        // set to watertight mesh everywhere we should analyze data
        Flag::value_type flags(Flag::descend);
        if (lod >= lodRange.min) {
            flags |= Flag::analyze;
        }

        for (const auto &tr : tileRanges) {
            auto localRange(vts::shiftRange(tr, lod));
            world_.set(lod, localRange, flags);
        }
    }
}

void TreeWalker::descend(const vts::NodeInfo &node
                         , const vts::TileId &tileId, double upscaling)
{
    if (tileId.lod == lodRange_.max) {
        // no children down there
        return;
    }

    // do not use const otherwise OpenMP makes it shared
    bool parentProductive(node.productive());

    // we can proces children -> go down
    for (auto child : vts::children(tileId)) {
        // compute child node
        auto childNode(node.child(child));

        if (config_.parallel) {
            UTILITY_OMP(task)
                process(parentProductive, childNode, upscaling);
        } else {
            process(parentProductive, childNode, upscaling);
        }
    }
}

void TreeWalker::process(bool parentProductive
                         , const vts::NodeInfo &node, double upscaling)
{
    struct TIDGuard {
        TIDGuard(const std::string &id)
            : old(dbglog::thread_id())
        {
            dbglog::thread_id(id);
        }
        ~TIDGuard() { dbglog::thread_id(old); }

        const std::string old;
    };

    const auto tileId(node.nodeId());
    if ((tileId.lod > lodRange_.max)) {
        // outside of configured area
        return;
    }

    auto fullSubtree([&]()
    {
        UTILITY_OMP(critical(tileIndex))
        {
            ti_.set(vts::LodRange(tileId.lod, lodRange_.max)
                    , vts::tileRange(tileId)
                    , (TiFlag::mesh | TiFlag::watertight));
        }

        return;
    });

    TIDGuard tg(str(boost::format("tile:%s") % tileId));

    if (!node.valid()) {
        // Node is invalid but we can safely say that we have watertight mesh
        // here and down to the maximum LOD to save space in tile index.
        //
        // It is a lie but it will not hurt anyone.

        // set full subtree
        if ((tileId.lod >= lodRange_.min) && parentProductive) {
            (void) parentProductive;
            fullSubtree();
            // stop descent here
            LOG(info3)
                << "Processed tile " << tileId
                << " (extents: " << std::fixed << node.extents()
                << ", srs: " << node.srs()
                << ") [fake watertight subtree in invalid part of a tree].";
        }
        return;
    }

    if (!node.productive()) {
        // unproductive node, immediate descend
        descend(node, tileId, upscaling);
        return;
    }

    LOG(info2) << "Processing tile " << tileId << ".";

    int samples(config_.tileSampling);

    // upscaling, each level decreases size by half
    // use at least 8 samples
    if (upscaling >= 1.0) {
        samples = std::max(int(samples / upscaling), 8);
    }

    math::Size2 size(samples + 1, samples + 1);

    // consult flags
    const auto flags(world_.get(tileId));
    if (!flags) {
        // outside of defined world
        LOG(info1) << "outside of defined world";
        return;
    }

    if (flags & Flag::analyze) {
        // warp input dataset into tile
        const auto &ds(dataset());
        // set some output nodata value to force mask generation
        auto tileDs(geo::GeoDataset::deriveInMemory
                    (ds, node.srsDef(), size
                     , extentsPlusHalfPixel(node.extents(), samples)
                     , GDT_Float32
                     , geo::GeoDataset::NodataValue(-1e6)));

        geo::GeoDataset::WarpOptions wo;
        if (upscaling >= 1.0) {
            // last level used original dataset, we have to enforce it now as
            // well otherwise GeoDataset may choose some overlay automatically
            // based on smaller size
            wo.overview = geo::Overview();
        }

        auto wri([&]() -> geo::GeoDataset::WarpResultInfo
        {

            try {
                // try to warp as in mapproxy
                return ds.warpInto
                    (tileDs, geo::GeoDataset::Resampling::dem, wo);
            } catch (const geo::WarpError &e) {
                // failed -> average could help
                LOG(info3)
                    << "Warp failed (" << e.what()
                    << "), restarting with simpler kernel.";
                return ds.warpInto
                    (tileDs, geo::GeoDataset::Resampling::average, wo);
            }
        }());

        TiFlag::value_type baseFlags(TiFlag::mesh);
        if (!upscaling) {
            baseFlags |= TiFlag::navtile;
        }

        // grab mask of warped dataset
        const auto &mask(tileDs.cmask());

        auto checkMask([&]() -> vts::NodeInfo::CoveredArea {
            auto res(node.checkMask(mask, vts::NodeInfo::CoverageType::grid, 1));

            if (config_.forceWatertight
                && (res == vts::NodeInfo::CoveredArea::some))
            {
                return vts::NodeInfo::CoveredArea::whole;
            }

            return res;
        });

        switch (checkMask()) {
        case vts::NodeInfo::CoveredArea::whole: {
            // fully covered by dataset and by reference frame definition

            if (!wri.overview && wri.truescale >= 1.0) {
                // warped using original dataset and no downscaling
                // which could possibly fill holes, no holes -> always without
                // holes -> set whole subtree to watertight mesh

                fullSubtree();

                // stop descent here
                LOG(info3)
                    << "Processed tile " << tileId
                    << " (extents: " << std::fixed << node.extents()
                    << ", srs: " << node.srs()
                    << ") [watertight subtree].";
                return;
            }

            UTILITY_OMP(critical(tileIndex))
                ti_.set(tileId, (baseFlags | TiFlag::watertight));
            LOG(info3)
                << "Processed tile " << tileId
                << " (extents: " << std::fixed << node.extents()
                << ", srs: " << node.srs()
                << ") [watertight].";
            break;
        }

        case vts::NodeInfo::CoveredArea::some: {
            // partially covered
            UTILITY_OMP(critical(tileIndex))
                ti_.set(tileId, baseFlags);
            LOG(info3)
                << "Processed tile " << tileId
                << " (extents: " << std::fixed << node.extents()
                << ", srs: " << node.srs()
                << ") [partial].";
            break;
        }

        case vts::NodeInfo::CoveredArea::none: {
            // empty -> no children
            LOG(info3)
                << "Processed tile " << tileId
                << " (extents: " << std::fixed << node.extents()
                << ", srs: " << node.srs()
                << ") [empty].";
            return;
        }
        }

        // update upscaling level
        if (!wri.overview) {
            if (!upscaling) {
                upscaling = wri.truescale;
            } else {
                upscaling *= wri.truescale;
            }
        }
    }

    // descend to children
    descend(node, tileId, upscaling);
    // done
}

} // namespace

vtslibs::vts::TileIndex
generate(const fs::path &dataset
         , const vtslibs::registry::ReferenceFrame &referenceFrame
         , const vtslibs::vts::LodRange &lodRange
         , const vtslibs::vts::LodTileRange::list &tileRanges
         , const Config &config)
{
    vtslibs::vts::TileIndex ti;
    TreeWalker(ti, dataset, vts::NodeInfo(referenceFrame)
               , lodRange, tileRanges, config);
    return ti;
}

} // namespace tiling

max_stars_repo_name: maka-io/vts-mapproxy

max_issues_repo_name: maka-io/vts-mapproxy

max_forks_repo_name: maka-io/vts-mapproxy


text:
// Copyright(c) Microsoft.All rights reserved.
// Licensed under the MIT license.See LICENSE file in the project root for full license information.

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4459 4100 4121 4244) /* This is because boost python has a self variable that hides a global */
#endif

#include <boost/python.hpp>
//#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <string>

#include "azure_c_shared_utility/platform.h"
#include "azure_prov_client/prov_device_client.h"
#include "azure_prov_client/prov_transport.h"
#include "azure_prov_client/prov_client_const.h"
#include "azure_prov_client/prov_security_factory.h"
#if USE_HTTP
#include "azure_prov_client/prov_transport_http_client.h"
#endif
#if USE_AMQP
#include "azure_prov_client/prov_transport_amqp_client.h"
#ifdef USE_WEBSOCKETS
#include "azure_prov_client/prov_transport_amqp_ws_client.h"
#endif
#endif
#if USE_MQTT
#include "azure_prov_client/prov_transport_mqtt_client.h"
#ifdef USE_WEBSOCKETS
#include "azure_prov_client/prov_transport_mqtt_ws_client.h"
#endif
#endif

#ifndef IMPORT_NAME
#define IMPORT_NAME provisioning_device_client
#endif

#define VERSION_STRING "1.4.2"

#if PY_MAJOR_VERSION >= 3
#define IS_PY3
#endif

// helper for debugging py objects
#define PRINT_PYTHON_OBJECT_NAME(obj)\
{\
    std::string object_classname = boost::python::extract<std::string>(obj.attr("__class__").attr("__name__"));\
    printf("Object: %s\n", object_classname.c_str());\
}

class PlatformCallHandler
{
private:
    static int init_call_count;
public:
    static void Platform_Init()
    {
        if (init_call_count == 0)
        {
            platform_init();
        }
        init_call_count++;
    }

    static void Platform_DeInit()
    {
        if (init_call_count == 1)
        {
            platform_deinit();
        }
        init_call_count--;
    }
};

int PlatformCallHandler::init_call_count = 0;

//
// note: all new allocations throw a std::bad_alloc exception which trigger a MemoryError in Python
//

// helper classes for transitions between Python and C++ layer

class ScopedGILAcquire : boost::noncopyable
{
public:
    inline ScopedGILAcquire()
    {
        gil_state = PyGILState_Ensure();
    }

    inline ~ScopedGILAcquire()
    {
        PyGILState_Release(gil_state);
    }
private:
    PyGILState_STATE gil_state;
};

class ScopedGILRelease : boost::noncopyable
{
public:
    inline ScopedGILRelease()
    {
        thread_state = PyEval_SaveThread();
    }

    inline ~ScopedGILRelease()
    {
        PyEval_RestoreThread(thread_state);
        thread_state = NULL;
    }
private:
    PyThreadState * thread_state;
};

enum PROV_SECURE_DEVICE_TYPE
{
    UNKNOWN,
    TPM,
    X509
};

//
// iothubtransportxxxx.h
//

#ifdef USE_WEBSOCKETS
enum PROV_TRANSPORT_PROVIDER
{
#if USE_HTTP
    HTTP,
#endif
#if USE_AMQP
    AMQP,
#endif
#if USE_MQTT
    MQTT,
#endif
#if USE_AMQP
    AMQP_WS,
#endif
#if USE_MQTT
    MQTT_WS
#endif
};
#else
enum PROV_TRANSPORT_PROVIDER
{
#if USE_HTTP
    HTTP,
#endif
#if USE_AMQP
    AMQP,
#endif
#if USE_MQTT
    MQTT
#endif
};
#endif

PyObject*
createExceptionClass(
    const char* name,
    PyObject* baseTypeObj = PyExc_Exception
)
{
    namespace bp = boost::python;
    using std::string;
    string scopeName = bp::extract<string>(bp::scope().attr("__name__"));
    string qualifiedName0 = scopeName + "." + name;
    char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

    PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
    if (!typeObj) bp::throw_error_already_set();
    bp::scope().attr(name) = bp::handle<>(bp::borrowed(typeObj));

    return typeObj;
}

PyObject* provisioningErrorType = NULL;

class ProvisioningError : public std::exception
{
public:
    std::string exc;
    std::string cls;
    std::string func;

    ProvisioningError(
        std::string _exc,
        std::string _cls,
        std::string _func
    ) :
        exc(_exc),
        cls(_cls)
    {
        // only display class names in camel case
        func = (_func[0] != 'I') ? CamelToPy(_func) : _func;
    }

    std::string str() const
    {
        std::stringstream s;
        s << cls << "." << func << ", " << decode_error();
        return s.str();
    }

    std::string repr() const
    {
        std::stringstream s;
        s << exc << "(" << str() << ")";
        return s.str();
    }

    virtual std::string decode_error() const = 0;

private:
    std::string CamelToPy(std::string &_func)
    {
        std::string py;
        std::string::size_type len = _func.length();
        for (std::string::size_type i = 0; i < len; i++)
        {
            char ch = _func[i];
            if ((i > 0) && isupper(ch))
            {
                py.push_back('_');
            }
            py.push_back((char)tolower(ch));
        }
        return py;
    }
};

PyObject *provisioningDeviceClientErrorType = NULL;

class ProvisioningDeviceClientError : public ProvisioningError
{
public:
    ProvisioningDeviceClientError(
        std::string _func,
        PROV_DEVICE_RESULT _result
    ) :
        ProvisioningError(
            "ProvisioningDeviceClientError",
            "ProvisioningDeviceClient",
            _func
        )
    {
        result = _result;
    }

    PROV_DEVICE_RESULT result;

    virtual std::string decode_error() const
    {
        std::stringstream s;
        s << "ProvisioningDeviceClientResult.";
        switch (result)
        {
        case PROV_DEVICE_RESULT_OK: s << "OK"; break;
        case PROV_DEVICE_RESULT_INVALID_ARG: s << "INVALID_ARG"; break;
        case PROV_DEVICE_RESULT_SUCCESS: s << "SUCCESS"; break;
        case PROV_DEVICE_RESULT_MEMORY: s << "MEMORY_ERROR"; break;
        case PROV_DEVICE_RESULT_PARSING: s << "PARSING_ERROR"; break;
        case PROV_DEVICE_RESULT_TRANSPORT: s << "TRANSPORT_ERROR"; break;
        case PROV_DEVICE_RESULT_INVALID_STATE: s << "INVALID_STATE"; break;
        case PROV_DEVICE_RESULT_DEV_AUTH_ERROR: s << "DEVICE_AUTHENTICATION_ERROR"; break;
        case PROV_DEVICE_RESULT_TIMEOUT: s << "TIMEOUT"; break;
        case PROV_DEVICE_RESULT_KEY_ERROR: s << "KEY_ERROR"; break;
        case PROV_DEVICE_RESULT_ERROR: s << "ERROR"; break;
        }
        return s.str();
    }
};

void provisioningDeviceClientError(const ProvisioningDeviceClientError& x)
{
    boost::python::object pythonExceptionInstance(x);
    PyErr_SetObject(provisioningDeviceClientErrorType, pythonExceptionInstance.ptr());
};

typedef struct
{
    boost::python::object register_callback;
    boost::python::object userContext;
} RegisterDeviceContext;

typedef struct
{
    boost::python::object register_status_callback;
    boost::python::object status_user_context;
} RegisterDeviceStatusContext;

extern "C"
void
RegisterDeviceCallback(
    PROV_DEVICE_RESULT register_result,
    const char* iothub_uri,
    const char* device_id,
    void* user_context
)
{
    RegisterDeviceContext *registerDeviceContext = (RegisterDeviceContext *)user_context;
    boost::python::object register_callback = registerDeviceContext->register_callback;
    boost::python::object userContext = registerDeviceContext->userContext;
    {
        ScopedGILAcquire acquire;
        try
        {
            register_callback(register_result, iothub_uri, device_id, userContext);
        }
        catch (const boost::python::error_already_set)
        {
            // Catch and ignore exception that is thrown in Python callback.
            // There is nothing we can do about it here.
            PyErr_Print();
        }
    }
}

extern "C"
void
RegisterDeviceStatusCallback(
    PROV_DEVICE_REG_STATUS reg_status,
    void* user_context
)
{
    RegisterDeviceStatusContext *registerDeviceStatusContext = (RegisterDeviceStatusContext *)user_context;
    boost::python::object register_status_callback = registerDeviceStatusContext->register_status_callback;
    boost::python::object status_user_context = registerDeviceStatusContext->status_user_context;
    {
        ScopedGILAcquire acquire;
        try
        {
            register_status_callback(reg_status, status_user_context);
        }
        catch (const boost::python::error_already_set)
        {
            // Catch and ignore exception that is thrown in Python callback.
            // There is nothing we can do about it here.
            PyErr_Print();
        }
    }
}

class HttpProxyOptions
{
public:
    HttpProxyOptions(
        std::string _host_address,
        int _port,
        std::string _username,
        std::string _password
    ) :
        host_address(_host_address),
        port(_port),
        username(_username),
        password(_password)
    {
    }
    std::string host_address;
    int port;
    std::string username;
    std::string password;
};

class ProvisioningDeviceClient
{
    static PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION
        GetProtocol(PROV_TRANSPORT_PROVIDER _protocol)
    {
        PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION protocol = NULL;
        switch (_protocol)
        {
#ifdef USE_HTTP
        case HTTP:
            protocol = Prov_Device_HTTP_Protocol;
            break;
#endif
#ifdef USE_AMQP
        case AMQP:
            protocol = Prov_Device_AMQP_Protocol;
            break;
#endif
#ifdef USE_MQTT
        case MQTT:
            protocol = Prov_Device_MQTT_Protocol;
            break;
#endif
#ifdef USE_WEBSOCKETS
#ifdef USE_AMQP
        case AMQP_WS:
            protocol = Prov_Device_AMQP_WS_Protocol;
            break;
#endif
#ifdef USE_MQTT
        case MQTT_WS:
            protocol = Prov_Device_MQTT_WS_Protocol;
            break;
#endif
#endif
        default:
            PyErr_SetString(PyExc_TypeError, "Provisioning Transport Provider set to unknown protocol");
            boost::python::throw_error_already_set();
            break;
        }
        return protocol;
    }

    static SECURE_DEVICE_TYPE
        GetSecurityDeviceType(PROV_SECURE_DEVICE_TYPE _prov_security_device_type)
    {
        SECURE_DEVICE_TYPE security_device_type = SECURE_DEVICE_TYPE_UNKNOWN;
        switch (_prov_security_device_type)
        {
        case UNKNOWN:
            security_device_type = SECURE_DEVICE_TYPE_UNKNOWN;
            break;
        case TPM:
            security_device_type = SECURE_DEVICE_TYPE_TPM;
            break;
        case X509:
            security_device_type = SECURE_DEVICE_TYPE_X509;
            break;
        default:
            PyErr_SetString(PyExc_TypeError, "Provisioning Security Device Type set to unknown type");
            boost::python::throw_error_already_set();
            break;
        }
        return security_device_type;
    }

    PROV_DEVICE_HANDLE _prov_device_handle;
public:
    PROV_TRANSPORT_PROVIDER _protocol;

    ProvisioningDeviceClient(
        std::string uri,
        std::string id_scope,
        PROV_SECURE_DEVICE_TYPE security_device_type,
        PROV_TRANSPORT_PROVIDER protocol
    ) :
        _prov_device_handle(NULL),
        _protocol(protocol)
    {
        ScopedGILRelease release;
        PlatformCallHandler::Platform_Init();

        if (prov_dev_security_init(GetSecurityDeviceType(security_device_type)) == 0)
        {
            _prov_device_handle = Prov_Device_Create(uri.c_str(), id_scope.c_str(), GetProtocol(protocol));
            if (_prov_device_handle == NULL)
            {
                throw ProvisioningDeviceClientError(__func__, PROV_DEVICE_RESULT_ERROR);
            }
        }
        else
        {
            throw ProvisioningDeviceClientError(__func__, PROV_DEVICE_RESULT_ERROR);
        }
    }

    ~ProvisioningDeviceClient()
    {
        if (_prov_device_handle != NULL)
        {
            {
                ScopedGILRelease release;
                Prov_Device_Destroy(_prov_device_handle);
            }
            _prov_device_handle = NULL;
        }

        prov_dev_security_deinit();

        PlatformCallHandler::Platform_DeInit();
    }

    PROV_DEVICE_RESULT Register_Device(
        boost::python::object& register_callback,
        boost::python::object& user_context,
        boost::python::object& register_status_callback,
        boost::python::object& status_user_context
    )
    {
        if (!PyCallable_Check(register_callback.ptr()))
        {
            PyErr_SetString(PyExc_TypeError, "register_device expected register_callback callable a callable type");
            boost::python::throw_error_already_set();
            return PROV_DEVICE_RESULT_INVALID_ARG;
        }
        if (!PyCallable_Check(register_status_callback.ptr()))
        {
            PyErr_SetString(PyExc_TypeError, "register_device expected register_status_callback callable a callable type");
            boost::python::throw_error_already_set();
            return PROV_DEVICE_RESULT_INVALID_ARG;
        }

        PROV_DEVICE_RESULT result;

        RegisterDeviceContext* registerDeviceContext = new RegisterDeviceContext();
        registerDeviceContext->register_callback = register_callback;
        registerDeviceContext->userContext = user_context;

        RegisterDeviceStatusContext* registerDeviceStatusContext = new RegisterDeviceStatusContext();
        registerDeviceStatusContext->register_status_callback = register_status_callback;
        registerDeviceStatusContext->status_user_context = status_user_context;

        {
            ScopedGILRelease release;
            result = Prov_Device_Register_Device(_prov_device_handle, RegisterDeviceCallback, registerDeviceContext, RegisterDeviceStatusCallback, registerDeviceStatusContext);
        }
        if (result != PROV_DEVICE_RESULT_OK)
        {
            throw ProvisioningDeviceClientError(__func__, result);
        }

        return result;
    }

    void SetOption(
        std::string option_name,
        boost::python::object& option_value
    )
    {
        static const char* OPTION_LOG_TRACE = "logtrace";

        PROV_DEVICE_RESULT result;

        if (option_name == OPTION_TRUSTED_CERT)
        {
            std::string value = (std::string)boost::python::extract<std::string>(option_value);
            {
                ScopedGILRelease release;
                result = Prov_Device_SetOption(_prov_device_handle, option_name.c_str(), value.c_str());
            }
        }
        else if (option_name == OPTION_LOG_TRACE)
        {
            if (PyBool_Check(option_value.ptr()))
            {
                bool value = (bool)boost::python::extract<bool>(option_value);
                {
                    ScopedGILRelease release;
                    result = Prov_Device_SetOption(_prov_device_handle, option_name.c_str(), &value);
                }
            }
            else
            {
                result = PROV_DEVICE_RESULT_ERROR;
            }
        }
        else if (option_name == OPTION_HTTP_PROXY)
        {
            HttpProxyOptions http_proxy_options = (HttpProxyOptions)boost::python::extract<HttpProxyOptions>(option_value);

            HTTP_PROXY_OPTIONS value;
            value.host_address = http_proxy_options.host_address.c_str();
            value.port = http_proxy_options.port;
            value.username = http_proxy_options.username.c_str();
            value.password = http_proxy_options.password.c_str();
            {
                ScopedGILRelease release;
                result = Prov_Device_SetOption(_prov_device_handle, option_name.c_str(), &value);
            }
        }
        else
        {
            result = PROV_DEVICE_RESULT_ERROR;
            throw ProvisioningDeviceClientError(__func__, PROV_DEVICE_RESULT_INVALID_ARG);
        }

        if (result != PROV_DEVICE_RESULT_OK)
        {
            printf("Provisioning Device Client SetOption failed with result: %d", result);
        }
    }

    const char* GetVersionString()
    {
        ScopedGILRelease release;
        return Prov_Device_GetVersionString();
    }
};

using namespace boost::python;

static const char* provisioning_device_client_docstring =
"provisioning_device_client is a Python module for communicating with Azure Device Provisioning Service";

BOOST_PYTHON_MODULE(IMPORT_NAME)
{
    // init threads for callbacks
    PyEval_InitThreads();
    PlatformCallHandler::Platform_Init();

    // by default enable user, py docstring options, disable c++ signatures
    bool show_user_defined = true;
    bool show_py_signatures = true;
    bool show_cpp_signatures = false;
    docstring_options doc_options(show_user_defined, show_py_signatures, show_cpp_signatures);
    scope().attr("__doc__") = provisioning_device_client_docstring;
    scope().attr("__version__") = VERSION_STRING;

    // exception handlers
    class_<ProvisioningDeviceClientError>ProvisioningDeviceClientErrorClass("ProvisioningDeviceClientErrorArg", init<std::string, PROV_DEVICE_RESULT>());
    ProvisioningDeviceClientErrorClass.def_readonly("result", &ProvisioningDeviceClientError::result);
    ProvisioningDeviceClientErrorClass.def_readonly("func", &ProvisioningDeviceClientError::func);
    ProvisioningDeviceClientErrorClass.def("__str__", &ProvisioningDeviceClientError::str);
    ProvisioningDeviceClientErrorClass.def("__repr__", &ProvisioningDeviceClientError::repr);

    register_exception_translator<ProvisioningDeviceClientError>(provisioningDeviceClientError);

    provisioningErrorType = createExceptionClass("ProvisioningError");
    provisioningDeviceClientErrorType = createExceptionClass("ProvisioningDeviceClientError", provisioningErrorType);

    enum_<PROV_DEVICE_REG_STATUS>("ProvisioningDeviceRegistrationStatus")
        .value("CONNECTED", PROV_DEVICE_REG_STATUS_CONNECTED)
        .value("REGISTERING", PROV_DEVICE_REG_STATUS_REGISTERING)
        .value("ASSIGNING", PROV_DEVICE_REG_STATUS_ASSIGNING)
        .value("ASSIGNED", PROV_DEVICE_REG_STATUS_ASSIGNED)
        .value("ERROR", PROV_DEVICE_REG_STATUS_ERROR)
        ;

    enum_<PROV_SECURE_DEVICE_TYPE>("ProvisioningSecurityDeviceType")
        .value("UNKNOWN", UNKNOWN)
        .value("TPM", TPM)
        .value("X509", X509)
        ;

    enum_<PROV_DEVICE_RESULT>("ProvisioningDeviceResult")
        .value("OK", PROV_DEVICE_RESULT_OK)
        .value("INVALID_ARG", PROV_DEVICE_RESULT_INVALID_ARG)
        .value("SUCCESS", PROV_DEVICE_RESULT_SUCCESS)
        .value("MEMORY", PROV_DEVICE_RESULT_MEMORY)
        .value("PARSING", PROV_DEVICE_RESULT_PARSING)
        .value("TRANSPORT", PROV_DEVICE_RESULT_TRANSPORT)
        .value("INVALID_STATE", PROV_DEVICE_RESULT_INVALID_STATE)
        .value("DEV_AUTH_ERROR", PROV_DEVICE_RESULT_DEV_AUTH_ERROR)
        .value("TIMEOUT", PROV_DEVICE_RESULT_TIMEOUT)
        .value("KEY_ERROR", PROV_DEVICE_RESULT_KEY_ERROR)
        .value("ERROR", PROV_DEVICE_RESULT_ERROR)
        ;

    enum_<PROV_TRANSPORT_PROVIDER>("ProvisioningTransportProvider")
#ifdef USE_HTTP
        .value("HTTP", HTTP)
#endif
#ifdef USE_AMQP
        .value("AMQP", AMQP)
#endif
#ifdef USE_MQTT
        .value("MQTT", MQTT)
#endif
#ifdef USE_AMQP
        .value("AMQP_WS", AMQP_WS)
#endif
#ifdef USE_MQTT
        .value("MQTT_WS", MQTT_WS)
#endif
        ;

    // classes
    class_<HttpProxyOptions, boost::noncopyable>("ProvisioningHttpProxyOptions", no_init)
        .def(init<std::string, int, std::string, std::string>())
#ifdef SUPPORT___STR__
        .def("__str__", &HttpProxyOptions::str)
        .def("__repr__", &HttpProxyOptions::repr)
#endif
        ;

    class_<ProvisioningDeviceClient, boost::noncopyable>("ProvisioningDeviceClient", no_init)
        .def(init<std::string, std::string, PROV_SECURE_DEVICE_TYPE, PROV_TRANSPORT_PROVIDER>())
        .def("register_device", &ProvisioningDeviceClient::Register_Device)
        .def("set_option", &ProvisioningDeviceClient::SetOption)
        .def("get_version_string", &ProvisioningDeviceClient::GetVersionString)
        // attributes
        .def_readonly("protocol", &ProvisioningDeviceClient::_protocol)
        // Python helpers
#ifdef SUPPORT___STR__
        .def("__str__", &ProvisioningDeviceClient::str)
        .def("__repr__", &ProvisioningDeviceClient::repr)
#endif
        ;
};

ext: cpp

max_stars_repo_name: Sahithkallakunta/azure-iot-sdk-python

max_issues_repo_name: Sahithkallakunta/azure-iot-sdk-python

max_forks_repo_name: Sahithkallakunta/azure-iot-sdk-python


text:
#ifndef __terark_io_var_int_inline_h__
#define __terark_io_var_int_inline_h__

#ifdef _MSC_VER
#  define TERARK_FORCE_INLINE __forceinline
#elif defined(__GNUC__) || defined(__INTEL_COMPILER)
//#  define TERARK_FORCE_INLINE __attribute__((always_inline))
#  define TERARK_FORCE_INLINE inline
#else
#  define TERARK_FORCE_INLINE inline
#endif

#include "byte_swap.hpp"
#include <boost/predef/other/endian.h>

#if !defined(BOOST_ENDIAN_BIG_BYTE) && !defined(BOOST_ENDIAN_LITTLE_BYTE)
#error must define byte endian
#endif

/*
#include <stdexcept>
#include <assert.h>

namespace terark {
*/

template<class T_uint>
TERARK_FORCE_INLINE
T_uint gg_load_var_uint(const unsigned char* buf, const unsigned char** endp, const char* func)
{
	const int maxshift = sizeof(T_uint) == 4 ? 28 : 63;
	T_uint x = 0;
	const unsigned char* p = buf;
#if 0
	// loop unroll is slower...
	//
#define	VAR_UINT_BYTE_FIRST() \
	b  = *p++; \
	x  = (b & 0x7F); \
	if ( (b & 0x80) == 0) { \
		*endp = p; \
	   	return x; \
	}
#define	VAR_UINT_BYTE_NEXT(shift) \
	b  = *p++; \
	x |= (b & 0x7F) << shift; \
	if ( (b & 0x80) == 0) { \
		*endp = p; \
	   	return x; \
	}
	/////////////////////////////////////////////
		VAR_UINT_BYTE_FIRST()
		VAR_UINT_BYTE_NEXT(07)
		VAR_UINT_BYTE_NEXT(14)
		VAR_UINT_BYTE_NEXT(21)
		VAR_UINT_BYTE_NEXT(28)
	if (sizeof(T_uint) == 8) { // const expr will be optimized
		VAR_UINT_BYTE_NEXT(35)
		VAR_UINT_BYTE_NEXT(42)
		VAR_UINT_BYTE_NEXT(49)
		VAR_UINT_BYTE_NEXT(56)
		VAR_UINT_BYTE_NEXT(63)
	}
#else
	for (int shift = 0; shift <= maxshift; shift += 7)
	{
		T_uint b = *p++;
		x |= (b & 0x7F) << shift;
		if ( (b & 0x80) == 0) {
			*endp = p;
			return x;
		}
	}
#endif
//	assert(0); // should not get here
	throw std::runtime_error(func);
}

template<class Stream, class T_uint>
TERARK_FORCE_INLINE
T_uint gg_load_var_uint_slow(Stream& s, const char* func)
{
	const int maxshift = sizeof(T_uint) == 4 ? 28 : 63;
	T_uint x = 0;
	for (int shift = 0; shift <= maxshift; shift += 7)
	{
		T_uint b = s.readByte(); // slower than *m_pos++
		x |= (b & 0x7F) << shift;
		if ( (b & 0x80) == 0)
			return x;
	}
//	assert(0); // should not get here
	throw std::runtime_error(func);
}

template<class T_uint>
TERARK_FORCE_INLINE
unsigned char* gg_save_var_uint(unsigned char* p, T_uint x)
{
#if 0
	while (x & ~(T_uint)0x7F)
	{
		*p++ = (unsigned char)((x & 0x7f) | 0x80);
		x >>= 7; //doing unsigned shift
	}
	*p++ = (unsigned char)(x);
	return p;
#else
	for (;;) {
		unsigned char b = (unsigned char)(x & 0x7f);
		if (x >>= 7)
			*p++ = b | 0x80;
		else {
			*p++ = b;
			return p;
		}
	}
#endif
}

//////////////////////////////////////////////////////////////////////////

// stream member function will ensure read extra is safe
#define DATA_IO_ALLOW_READ_EXTRA

TERARK_FORCE_INLINE
uint32_t gg_load_var_uint30(const unsigned char* buf, const unsigned char** endp)
{
#if !defined(DATA_IO_ALLOW_READ_EXTRA)
	uint32_t x = buf[0];
	*endp =(x & 3) + 1 + buf;
	switch (x & 3)
	{
	case 3:	x |= (uint32_t)(buf[3]) <<24; // fall through
	case 2:	x |= (uint32_t)(buf[2]) <<16; // fall through
	case 1:	x |= (uint32_t)(buf[1]) << 8; // fall through
	case 0:	break;
	}
#else
	// no branching needed
	// read more bytes, then unmask them
	uint32_t x = *(uint32_t*)buf;
  #if defined(BOOST_ENDIAN_BIG_BYTE)
	x = terark::byte_swap(x);
  #endif
	int n = x & 3;
	*endp = n + 1 + buf;
	x &= 0xFFFFFFFF >> (24 - n*8);
#endif
	return x >> 2;
}

TERARK_FORCE_INLINE
uint64_t gg_load_var_uint61(const unsigned char* buf, const unsigned char** endp)
{
#if !defined(DATA_IO_ALLOW_READ_EXTRA)
	uint64_t x = buf[0];
	*endp =(x & 7) + 1 + buf;
	switch (x & 7)
	{
	case 7:	x |= (uint64_t)(buf[7]) <<56; // fall through
	case 6:	x |= (uint64_t)(buf[6]) <<48; // fall through
	case 5:	x |= (uint64_t)(buf[5]) <<40; // fall through
	case 4:	x |= (uint64_t)(buf[4]) <<32; // fall through
	case 3:	x |= (uint64_t)(buf[3]) <<24; // fall through
	case 2:	x |= (uint64_t)(buf[2]) <<16; // fall through
	case 1:	x |= (uint64_t)(buf[1]) << 8; // fall through
	case 0:	break;
	}
#else
	// no branching needed
	// read more bytes, then unmask them
	uint64_t x = *(uint64_t*)buf;
  #if defined(BOOST_ENDIAN_BIG_BYTE)
	x = terark::byte_swap(x);
  #endif
	int n = x & 7;
	*endp = n + 1 + buf;
	x &= 0xFFFFFFFFFFFFFFFF >> (56 - n*8);
#endif
	return x >> 3;
}

template<class Stream>
TERARK_FORCE_INLINE
uint32_t gg_load_var_uint30_slow(Stream& s)
{
	uint32_t x = s.readByte();
	uint32_t y = 0;
	switch (x & 3)
	{
	case 3:	y =          (uint32_t)(s.readByte()); // fall through
	case 2:	y = y << 8 | (uint32_t)(s.readByte()); // fall through
	case 1:	y = y << 8 | (uint32_t)(s.readByte()); // fall through
	case 0:	break;
	}
	uint32_t z = x | y << 8;
	return z >> 2;
}

template<class Stream>
TERARK_FORCE_INLINE
uint64_t gg_load_var_uint61_slow(Stream& s)
{
	uint64_t x = s.readByte();
	uint64_t y = 0;
	switch (x & 7)
	{
	case 7:	y =          (uint64_t)(s.readByte()); // fall through
	case 6:	y = y << 8 | (uint64_t)(s.readByte()); // fall through
	case 5:	y = y << 8 | (uint64_t)(s.readByte()); // fall through
	case 4:	y = y << 8 | (uint64_t)(s.readByte()); // fall through
	case 3:	y = y << 8 | (uint64_t)(s.readByte()); // fall through
	case 2:	y = y << 8 | (uint64_t)(s.readByte()); // fall through
	case 1:	y = y << 8 | (uint64_t)(s.readByte()); // fall through
	case 0:	break;
	}
	uint64_t z = x | y << 8;
	return z >> 3;
}

// stream member function will ensure overwrite extra is safe
#define DATA_IO_ALLOW_OVERWRITE_EXTRA

TERARK_FORCE_INLINE
unsigned char* gg_save_var_uint30(unsigned char* p, uint32_t x)
{
	assert(x < 1 << 30);

	x <<= 2;

#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64))

// Is this always faster? It seems not, this may slower!

	unsigned long n; // index most significant 1 bit, from least significant bit, based on 0
	if (_BitScanReverse(&n, x)) {
		assert(n >= 0);
		assert(n <= 31);
		n /= 8;
	#if defined(DATA_IO_ALLOW_OVERWRITE_EXTRA)
		#if defined(BOOST_ENDIAN_BIG_BYTE)
			*(uint32_t*)p = terark::byte_swap(x) | terark::byte_swap(n);
		#else
			*(uint32_t*)p = x | n;
		#endif
	#else
		p[0] = (unsigned char)(x) | (unsigned char)(n);
		switch (n)
		{
		case 3: p[3] = (unsigned char)(x>>24); // fall through
		case 2: p[2] = (unsigned char)(x>>16); // fall through
		case 1: p[1] = (unsigned char)(x>> 8); // fall through
		case 0: break;
		}
	#endif
		return p + n + 1;
	}
	else {
		*p = 0;
		return p + 1;
	}
#else
	if (terark_likely(!(x & 0xFFFF0000))) {
		if (terark_likely(!(x & 0xFF00))) {
			p[0] = (unsigned char)(x);
			return p + 1;
		}
		else {
			p[0] = (unsigned char)(x|1);
			p[1] = (unsigned char)(x>>8);
			return p + 2;
		}
	}
	else {
		p[1] = (unsigned char)(x>> 8);
		p[2] = (unsigned char)(x>>16);
		if (terark_likely(!(x & 0xFF000000))) {
			p[0] = (unsigned char)(x|2);
			return p + 3;
		}
		else {
			p[0] = (unsigned char)(x|3);
			p[3] = (unsigned char)(x>>24);
			return p + 4;
		}
	}
	// will not go here
#endif // _MSC_VER
}

//TERARK_FORCE_INLINE
inline // auto inline
unsigned char* gg_save_var_uint61(unsigned char* p, uint64_t x)
{
	assert(x < 1 << 30);

	x <<= 3;

#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IA64))
	unsigned long n; // index most significant 1 bit, from least significant bit, based on 0
	if (_BitScanReverse64(&n, x)) {
		assert(n >= 0);
		assert(n <= 63);
		n /= 8;
	#if defined(DATA_IO_ALLOW_OVERWRITE_EXTRA)
		#if defined(BOOST_ENDIAN_BIG_BYTE)
			*(uint64_t*)p = terark::byte_swap(x) | terark::byte_swap(n);
		#else
			*(uint64_t*)p = x | n;
		#endif
	#else
		p[0] = (unsigned char)(x) | (unsigned char)(n);
		switch (n)
		{
		case 7: p[7] = (unsigned char)(x>>56); // fall through
		case 6: p[6] = (unsigned char)(x>>48); // fall through
		case 5: p[5] = (unsigned char)(x>>40); // fall through
		case 4: p[4] = (unsigned char)(x>>32); // fall through
		case 3: p[3] = (unsigned char)(x>>24); // fall through
		case 2: p[2] = (unsigned char)(x>>16); // fall through
		case 1: p[1] = (unsigned char)(x>> 8); // fall through
		case 0: break;
		}
	#endif
		return p + n + 1;
	}
	else {
		*p = 0;
		return p + 1;
	}
#else
	// branch use binary search, need 3 conditions, 8 branches

	if (terark_likely(!(x & 0xFFFFFFFF00000000))) {
		if (terark_likely(!(x & 0xFFFF0000))) {
			if (terark_likely(!(x & 0xFF00))) {
				p[0] = (unsigned char)(x);
				return p + 1;
			}
			else {
				p[0] = (unsigned char)(x|1);
				p[1] = (unsigned char)(x>>8);
				return p + 2;
			}
		}
		else {
			p[1] = (unsigned char)(x>> 8);
			p[2] = (unsigned char)(x>>16);
			if (terark_likely(!(x & 0xFF000000))) {
				p[0] = (unsigned char)(x|2);
				return p + 3;
			}
			else {
				p[0] = (unsigned char)(x|3);
				p[3] = (unsigned char)(x>>24);
				return p + 4;
			}
		}
	}
	else { // high 32 bit not zero
		p[1] = (unsigned char)(x>> 8);
		p[2] = (unsigned char)(x>>16);
		p[3] = (unsigned char)(x>>24);
		p[4] = (unsigned char)(x>>32);
		if (terark_likely(!(x & 0xFFFF000000000000))) {
			if (terark_likely(!(x & 0x0000FF0000000000))) {
				p[0] = (unsigned char)(x|4);
				return p + 5;
			}
			else {
				p[0] = (unsigned char)(x|5);
				p[5] = (unsigned char)(x>>40);
				return p + 6;
			}
		}
		else {
			p[5] = (unsigned char)(x>>40);
			p[6] = (unsigned char)(x>>48);
			if (terark_likely(!(x & 0xFF00000000000000))) {
				p[0] = (unsigned char)(x|6);
				return p + 7;
			}
			else {
				p[0] = (unsigned char)(x|7);
				p[7] = (unsigned char)(x>>56);
				return p + 8;
			}
		}
	}
#endif // _MSC_VER
}

//} // namespace terark

#endif // __terark_io_var_int_inline_h__

ext: hpp

max_stars_repo_name: noobpwnftw/terark-zip

max_issues_repo_name: noobpwnftw/terark-zip

max_forks_repo_name: noobpwnftw/terark-zip


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#ifndef SD_FRAMEWORK_MODULE_CONTROLLER_HXX
#define SD_FRAMEWORK_MODULE_CONTROLLER_HXX

#include "MutexOwner.hxx"

#include <osl/mutex.hxx>
#include <com/sun/star/drawing/framework/XModuleController.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <cppuhelper/compbase2.hxx>

#include <boost/scoped_ptr.hpp>
#include <set>

namespace css = ::com::sun::star;

namespace {

typedef ::cppu::WeakComponentImplHelper2 <
    css::drawing::framework::XModuleController,
    css::lang::XInitialization
    > ModuleControllerInterfaceBase;

} // end of anonymous namespace.

namespace sd { namespace framework {

/** The ModuleController has to tasks:

    1. It reads the
    org.openoffice.Office.Impress/MultiPaneGUI/Framework/ResourceFactories
    configuration data that maps from resource URLs to service names of
    factories that can create resources for the URLs.  When the
    configuration controller wants to create a resource for which it does
    not have a factory, it asks the ModuleController to provide one.  The
    ModuleController looks up the service name registered for the URL of the
    resource and instantiates this service.  The service is expected to
    register on its creation a factory for the resource in question.

    2. The ModuleController reads on its creation
    org.openoffice.Office.Impress/MultiPaneGUI/Framework/StartupServices
    configuration data and instantiates all listed services.  These servces
    can then register as listeners at the ConfigurationController or do
    whatever they like.
*/
class ModuleController
    : private sd::MutexOwner,
      public ModuleControllerInterfaceBase
{
public:
    static css::uno::Reference<
        css::drawing::framework::XModuleController>
        CreateInstance (
            const css::uno::Reference<css::uno::XComponentContext>&
            rxContext);

    virtual void SAL_CALL disposing (void);

    // XModuleController

    virtual void SAL_CALL requestResource(const ::rtl::OUString& rsResourceURL)
        throw (css::uno::RuntimeException);

    // XInitialization

    virtual void SAL_CALL initialize(
        const css::uno::Sequence<css::uno::Any>& aArguments)
        throw (css::uno::Exception, css::uno::RuntimeException);

private:
    css::uno::Reference<
        css::frame::XController> mxController;

    class ResourceToFactoryMap;
    ::boost::scoped_ptr<ResourceToFactoryMap> mpResourceToFactoryMap;
    class LoadedFactoryContainer;
    ::boost::scoped_ptr<LoadedFactoryContainer> mpLoadedFactories;

    ModuleController (
        const css::uno::Reference<css::uno::XComponentContext>& rxContext)
        throw();
    ModuleController (void); // Not implemented.
    ModuleController (const ModuleController&); // Not implemented.
	virtual ~ModuleController (void) throw();

    /** Load a list of URL to service mappings from the
        /org.openoffice.Office.Impress/MultiPaneGUI/Framework/ResourceFactories
        configuration entry.  The mappings are stored in the
        mpResourceToFactoryMap member.
    */
    void LoadFactories (const css::uno::Reference<css::uno::XComponentContext>& rxContext);

    /** Called for every entry in the ResourceFactories configuration entry.
    */
    void ProcessFactory (const ::std::vector<css::uno::Any>& rValues);

    /** Instantiate all startup services that are found in the
        /org.openoffice.Office.Impress/MultiPaneGUI/Framework/StartupServices
        configuration entry.  This method is called once when a new
        ModuleController object is created.
    */
    void InstantiateStartupServices (void);

    /** Called for one entry in the StartupServices configuration list this
        method instantiates the service described by the entry.  It does not
        hold references to the new object so that the object will be
        destroyed on function exit when it does not register itself
        somewhere.  It typically will register as
        XConfigurationChangeListener at the configuration controller.
    */
    void ProcessStartupService (const ::std::vector<css::uno::Any>& rValues);
};

} } // end of namespace sd::framework

#endif

ext: hxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
// Copyright DEWETRON GmbH 2017

#include "odkfw_stream_reader.h"
#include "odkapi_block_descriptor_xml.h"

#include <boost/test/unit_test.hpp>

using namespace odk;

BOOST_AUTO_TEST_SUITE(stream_reader)

BOOST_AUTO_TEST_CASE(stream_reader_test)
{
    BlockDescriptor bd1;
    bd1.m_stream_id = 123;
    {
        BlockChannelDescriptor bcd;
        bcd.m_channel_id = 1;
        bcd.m_count = 2;
        bcd.m_first_sample_index = 100;
        bcd.m_timestamp = 100;
        bcd.m_offset = 0;
        bd1.m_block_channels.push_back(bcd);
    }
    {
        BlockChannelDescriptor bcd;
        bcd.m_channel_id = 2;
        bcd.m_count = 2;
        bcd.m_first_sample_index = 100;
        bcd.m_timestamp = 100;
        bcd.m_offset = sizeof(double);
        bd1.m_block_channels.push_back(bcd);
    }
    BlockDescriptor bd2;
    bd2.m_stream_id = 123;
    {
        BlockChannelDescriptor bcd;
        bcd.m_channel_id = 1;
        bcd.m_count = 2;
        bcd.m_first_sample_index = 102;
        bcd.m_timestamp = 102;
        bcd.m_offset = 0;
        bd2.m_block_channels.push_back(bcd);
    }
    {
        BlockChannelDescriptor bcd;
        bcd.m_channel_id = 2;
        bcd.m_count = 2;
        bcd.m_first_sample_index = 102;
        bcd.m_timestamp = 102;
        bcd.m_offset = sizeof(double);
        bd2.m_block_channels.push_back(bcd);
    }

    std::vector<BlockDescriptor> bdv = {bd1, bd2};

    StreamDescriptor sd;
    sd.m_stream_id = 123;

    {
        ChannelDescriptor cd;
        cd.m_channel_id = 1;
        cd.m_dimension = 1;
        cd.m_stride = 2 * sizeof(double);
        cd.m_size = 64;
        cd.m_type = SampleType::DOUBLE;
        sd.m_channel_descriptors.push_back(cd);
    }
    {
        ChannelDescriptor cd;
        cd.m_channel_id = 2;
        cd.m_dimension = 1;
        cd.m_stride = 2 * sizeof(double);
        cd.m_size = 64;
        cd.m_type = SampleType::DOUBLE;
        sd.m_channel_descriptors.push_back(cd);
    }

    double data1[4] = {1, 10, 2, 20};
    double data2[4] = {3, 30, 4, 40};

    odk::framework::StreamReader stream_reader(sd);
    stream_reader.addDataBlock(bd1, data1);
    stream_reader.addDataBlock(bd2, data2);
    BOOST_REQUIRE(stream_reader.hasChannel(1));
    BOOST_CHECK(stream_reader.hasChannel(2));

    auto iterator1 = stream_reader.createChannelIterator(1);
    BOOST_CHECK(iterator1.valid());
    BOOST_CHECK_EQUAL(iterator1.data(), data1);
    BOOST_CHECK_EQUAL(iterator1.timestamp(), 100);

    ++iterator1;
    ++iterator1;
    BOOST_CHECK(iterator1.valid());
    BOOST_CHECK_EQUAL(iterator1.data(), data2);
    BOOST_CHECK_EQUAL(iterator1.timestamp(), 102);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: HpLightcorner/OXYGEN-SDK

max_issues_repo_name: HpLightcorner/OXYGEN-SDK

max_forks_repo_name: HpLightcorner/OXYGEN-SDK


text:
// logging.hpp

// Boost Logging library
//
// Author: John Torjo, www.torjo.com
//
// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
//
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
// See http://www.torjo.com/log2/ for more details

#ifndef JT28092007_logging_HPP_DEFINED
#define JT28092007_logging_HPP_DEFINED

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <boost/logging/detail/fwd.hpp>
#include <boost/logging/detail/filter.hpp>
#include <boost/logging/detail/logger.hpp>
#include <boost/logging/detail/log_keeper.hpp>
#include <boost/logging/detail/macros.hpp>
#include <boost/logging/detail/tss/tss.hpp>
#include <boost/logging/detail/level.hpp>
#include <boost/logging/detail/scoped_log.hpp>

// just in case we might think of using formatters
#include <boost/logging/detail/format_msg_type.hpp>

namespace boost { namespace logging {

/**
@file boost/logging/logging.hpp

Include this file when you're using the logging lib, but don't necessarily want to use @ref manipulator "formatters and destinations".
If you want to use @ref manipulator "formatters and destinations", then you can include this one instead:

@code
#include <boost/logging/format_fwd.hpp>
@endcode

*/

}}

#endif

max_stars_repo_name: saga-project/saga-cpp

max_issues_repo_name: saga-project/saga-cpp

max_forks_repo_name: saga-project/saga-cpp


text:
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <iostream>
#include <string>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <petuum_ps_common/include/configs.hpp>
#include "dml_paras.hpp"
#include "dml.hpp"
#include <stdio.h>
#include <stdlib.h>
#include "utils.hpp"

DEFINE_string(hostfile, "", "Path to file containing server ip:port.");
DEFINE_string(parafile, "", "Path to file containing DNN hyperparameters");
DEFINE_int32(num_clients, 1, "Total number of clients");
DEFINE_int32(client_id, 0, "This client's ID");
DEFINE_int32(num_worker_threads, 1, "Number of worker threads");
DEFINE_int32(staleness, 0, "Staleness");
DEFINE_int32(snapshot_clock, 0, "How often to take PS snapshots; 0 disables");
DEFINE_int32(resume_clock, 0, "If nonzero, resume from the PS snapshot with this ID");
DEFINE_string(snapshot_dir, "", "Path to save PS snapshots");
DEFINE_string(resume_dir, "", "Where to retrieve PS snapshots for resuming");
DEFINE_string(model_weight_file, "", "file to save model");
DEFINE_int32(ps_row_in_memory_limit, 1000, \
         "Single-machine version only: max # rows of weight matrices that can be held in memory");
DEFINE_string(feature_file,"","");
DEFINE_string(simi_pairs_file,"","");
DEFINE_string(diff_pairs_file,"","");
// Main function
int main(int argc, char *argv[]) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  // load dnn parameters
  // configure meta
  DmlParas dmlprs;
  LoadDmlParas(&dmlprs, FLAGS_parafile.c_str());
  std::cout << "client " << FLAGS_client_id << " starts working..." << std::endl;
  // Configure Petuum PS
  petuum::TableGroupConfig table_group_config;
  // Global params
  table_group_config.num_total_clients = FLAGS_num_clients;
  table_group_config.num_tables = 1;  // tables storing weights and biases
  // Single-node-PS versus regular distributed PS
#ifdef PETUUM_SINGLE_NODE
  table_group_config.ooc_path_prefix = "mlr_sn.localooc";
  table_group_config.consistency_model = petuum::LocalOOC;
#else
  petuum::GetHostInfos(FLAGS_hostfile, &table_group_config.host_map);
  table_group_config.consistency_model = petuum::SSPPush;
#endif
  // Local parameters for this process
  table_group_config.num_local_app_threads = FLAGS_num_worker_threads + 1;  // +1 for main() thread
  table_group_config.client_id = FLAGS_client_id;
  // snapshots
  table_group_config.snapshot_clock = FLAGS_snapshot_clock;
  table_group_config.resume_clock = FLAGS_resume_clock;
  table_group_config.snapshot_dir = FLAGS_snapshot_dir;
  table_group_config.resume_dir = FLAGS_resume_dir;
  // Configure Petuum PS tables
  petuum::PSTableGroup::RegisterRow<petuum::DenseRow<float> >(0);  // Register dense rows as ID 0
  // Initializing thread does not need table access
  petuum::PSTableGroup::Init(table_group_config, false);
  // Common table settings
  petuum::ClientTableConfig table_config;
  table_config.table_info.row_type = 0;  // Dense rows
  table_config.oplog_capacity = 100;
  //  create weight tables
  table_config.table_info.table_staleness = FLAGS_staleness;
  table_config.table_info.row_capacity = dmlprs.src_feat_dim;
  //  table_config.table_info.row_oplog_type=kDenseRowOpLog;
#ifdef PETUUM_SINGLE_NODE
    table_config.process_cache_capacity = std::min(FLAGS_ps_row_in_memory_limit, \
           dmlprs.dst_feat_dim);
#else
    table_config.process_cache_capacity = dmlprs.dst_feat_dim;
#endif
    petuum::PSTableGroup::CreateTable(0, table_config);
  // Finished creating tables
  petuum::PSTableGroup::CreateTableDone();
  // load data
  DML mydml(dmlprs.src_feat_dim, dmlprs.dst_feat_dim, dmlprs.lambda, dmlprs.thre, \
           FLAGS_client_id, FLAGS_num_worker_threads, \
           dmlprs.num_smps_evaluate, FLAGS_staleness, \
           FLAGS_num_clients, dmlprs.size_mb, dmlprs.num_iters_evaluate );
  mydml.LoadData(dmlprs.num_total_pts,  dmlprs.num_simi_pairs, dmlprs.num_diff_pairs, \
                FLAGS_feature_file.c_str(), FLAGS_simi_pairs_file.c_str(),  FLAGS_diff_pairs_file.c_str());
  boost::thread_group worker_threads;
  std::srand(time(NULL));
  for (int i = 0; i < FLAGS_num_worker_threads; ++i) {
    worker_threads.create_thread(
    boost::bind(&DML::Learn, boost::ref(mydml), dmlprs.learn_rate, dmlprs.epoch, FLAGS_model_weight_file.c_str()));
  }
  worker_threads.join_all();

  // Cleanup and output runtime
  petuum::PSTableGroup::ShutDown();
  std::cout<<"DML training ends"<<std::endl;
  return 0;
}


text:
#include <boost/test/unit_test.hpp>

#include <fc/variant.hpp>
#include <fc/variant_object.hpp>

#include <hive/protocol/operations.hpp>

#include <chrono>

BOOST_AUTO_TEST_SUITE( operation_visitor )

struct stub_visitor
{
  typedef void result_type;

  template<typename Type>
  result_type operator()( const Type& op )const { return;}
};

BOOST_AUTO_TEST_CASE( visit_performance ) {
  try {
    hive::protocol::operation operation_under_test;
    stub_visitor visitor;

    BOOST_TEST_MESSAGE( "Start of visit_performance test" );
    for ( auto type_id = 0; type_id < operation_under_test.count(); ++type_id)
    {
      operation_under_test.set_which(type_id);
      auto start = std::chrono::high_resolution_clock::now();
      for (auto j = 0; j < 100'000'000; j++) {
        operation_under_test.visit(visitor);
      }
      auto end = std::chrono::high_resolution_clock::now();
      BOOST_TEST_MESSAGE( "element " << type_id << " [ns] :" << std::chrono::duration_cast< std::chrono::nanoseconds >(end - start).count() );
    }
    BOOST_TEST_MESSAGE( "End of visit_performance test" );
  }
  FC_LOG_AND_RETHROW()
}

BOOST_AUTO_TEST_CASE(bad_object) {
  bool thrown = false;
  bool verified = false;
  try {
    BOOST_TEST_MESSAGE("Start of static_variant type checks");

    hive::protocol::account_create_operation testOp;
    hive::protocol::operation operation_under_test(testOp);
    /// Ok
    operation_under_test.get<hive::protocol::account_create_operation>();
    verified = true;

    /// Intentially bad
    operation_under_test.get<hive::protocol::transfer_operation>();

  }
  catch(const fc::assert_exception& ae)
  {
    thrown = true;
    BOOST_TEST_MESSAGE("Caught assert exception: " + ae.to_string());
  }
  FC_LOG_AND_RETHROW()

  BOOST_CHECK(thrown);
  BOOST_CHECK(verified);

  BOOST_TEST_MESSAGE("End of static_variant type checks");
}

BOOST_AUTO_TEST_SUITE_END()


text:
#include "tkdCmdParser.h"

#include "vnl/vnl_matrix.h"
#include "vnl/vnl_vector.h"
#include "vnl/algo/vnl_determinant.h"
#include "vnl/algo/vnl_svd.h"

#include <stdlib.h>
#include <math.h>
#include <fstream>

#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random.hpp>
#include <boost/utility.hpp>
#include <boost/accumulators/numeric/functional/vector.hpp>
#include <boost/accumulators/numeric/functional/complex.hpp>
#include <boost/accumulators/numeric/functional/valarray.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>

#include <boost/math/distributions/normal.hpp>

/* Indexer problem... */

/**
 * Option list.
 */
struct parameters
{
	std::string inputFileName;
	std::string link;
	std::string separation;
	int iterations;
	double percentage;
	bool verbose;
	bool printPValues;
	bool printZValues;
};

/**
 * Generalized Linear Model (GLM) is a flexible generalization of ordinary least squares regression.
 *
 * http://en.wikipedia.org/wiki/Generalized_linear_model
 *
 * wim@invivonmr.uu.nl, 02-03-2010.
 *
 */
namespace generalized_linear_model
{
	typedef double PixelType;
	typedef vnl_matrix< PixelType > MatrixType;
	typedef vnl_vector< PixelType > VectorType;
	typedef boost::tokenizer< boost::char_separator< char > > TokType;
	typedef boost::mt19937 random_number_type;
	typedef boost::uniform_int< long > int_distribution_type;
	typedef boost::variate_generator< random_number_type&, int_distribution_type > int_generator_type;

	class GLM
	{
	public:

		/**
		 * Run glm.
		 */
		void Run( parameters& list )
		{
			// read covariates and response-function (latter as last column).
			MatrixType covariates;
			VectorType binaryResponse;

			if( list.verbose )
				std::cout << "Reading input data..." << std::endl;

			ReadData( list.separation, list.inputFileName, covariates, binaryResponse, list.percentage );
			covariates = AddIntercept( covariates );

			if( list.verbose )
				std::cout << "Finished reading input data..." << std::endl;

			if ( list.link == "logistic" )
			{
				// Calculate coefficients...
				VectorType coefficients = IRLS( binaryResponse, covariates, list.iterations, list.verbose );
				std::cout << "Coefficients: " << coefficients << std::endl;

				if( list.printZValues )
					std::cout << "Z-values: " << ZStatistic( coefficients, binaryResponse, covariates ) << std::endl;

				if( list.printPValues )
					std::cout << "P-values: " << PValue( ZStatistic( coefficients, binaryResponse, covariates ) ) << std::endl;
			}
			else
			{
				std::cerr << "*** ERROR ***: Link function not supported!" << std::endl;
				exit( EXIT_FAILURE );
			}
		}

	protected:

		/**
		 * The P values for individual coefficients, given the z values.
		 */
		VectorType PValue( const VectorType& zValues )
		{
			VectorType pValues( zValues.size(), 0.0 );

			for ( unsigned int i = 0; i < zValues.size(); i++ )
			{
				// two-sided
				boost::math::normal s;
				PixelType alpha = boost::math::pdf( s, zValues( i ) ) * 2.;
				pValues( i ) = alpha;
			}
			return pValues;
		}

		/**
		 * The z statistics for individual coefficients.
		 */
		VectorType ZStatistic( const VectorType& coefficients, const VectorType& response,
				const MatrixType& covariates )
		{
			VectorType means = Means( coefficients, covariates );
			MatrixType weights = Weights( means, coefficients, covariates );

			MatrixType xwx = covariates * weights * covariates.transpose();

			vnl_svd< double > svd( xwx );

			MatrixType variance = svd.inverse();

			VectorType coefficientSE( variance.rows(), 0.0 );

			for( unsigned int i = 0; i < variance.rows(); i++ )
				coefficientSE( i ) = std::sqrt( variance( i, i ) );

			MatrixType correlation( variance.rows(), variance.rows(), 0.0 );

			for( unsigned int i = 0; i < variance.rows(); i++)
			{
				for ( unsigned int j = i; j < variance.rows(); j++ )
				{
					correlation( i, j ) = variance( i, j ) /
											std::sqrt(variance( i, i ) * variance( j, j ) );

					correlation( j, i ) = correlation( i, j );
				}
			}

			VectorType zValues( coefficients.size(), 0.0 );

			for( unsigned int i = 0; i < zValues.size(); i++ )
				zValues( i ) = coefficients( i ) / coefficientSE( i );

			return zValues;
		}

		/**
		 * Return number of training dimensions.
		 */
		unsigned int GetNumberOfTrainingDims( const std::string& trainingData )
		{
			std::string sep = "\t";
			std::ifstream in( trainingData.c_str() );

			if ( in.fail() )
			{
				std::cerr << "*** ERROR ***: could not read labels from: " << trainingData << std::endl;
				exit( EXIT_FAILURE );
			}

			std::string line;
			getline( in, line );

			TokType tok( line, boost::char_separator< char >( sep.c_str() ) );

			unsigned int results = 0;
			try
			{
				for ( TokType::iterator id = tok.begin(); id != tok.end(); ++id )
					results++;
			}
			catch ( boost::bad_lexical_cast& e )
			{
				std::cout << "*** WARNING ***: bad lexical cast during training data parsing!" << std::endl;
			}
			in.close();
			return results;
		}

		/**
		 * Return number of training data points.
		 */
		unsigned int GetNumberOfTrainingPoints( const std::string& trainingData )
		{
			std::ifstream in( trainingData.c_str() );

			if ( in.fail() )
			{
				std::cerr << "*** ERROR ***: could not read labels from: " << trainingData << std::endl;
				exit( EXIT_FAILURE );
			}
			std::string line;
			unsigned int result = 0;

			while ( getline( in, line ) )
			{
				result++;
			}

			in.close();
			return result;
		}

		/**
		 * Add column with initial intercept values (1.0).
		 */
		MatrixType AddIntercept( const MatrixType& M )
		{
			MatrixType result( M.rows() + 1, M.cols() );

			for( unsigned int i = 0; i < result.rows(); i++ )
			{
				for( unsigned int j = 0; j < result.cols(); j++ )
				{
					if( i == 0 )
						result( i, j ) = 1.0;
					else
						result( i, j ) = M( i - 1, j );
				}
			}
			return result;
		}

		/**
		 * Read data from text file.
		 */
		void ReadData( const std::string& sep, const std::string& inputFileName, MatrixType& covariates, VectorType& binaryResponse, PixelType percentage )
		{
			unsigned int dims = GetNumberOfTrainingDims( inputFileName );
			unsigned int points = GetNumberOfTrainingPoints( inputFileName );

			covariates = MatrixType( dims - 1, points, 0.0 );
			binaryResponse = VectorType( points, 0.0 );

			// open training data ...
			std::ifstream in( inputFileName.c_str() );
			if ( in.fail() )
			{
				std::cerr << "*** ERROR ***: could not read data from: " << inputFileName << std::endl;
				exit( EXIT_FAILURE );
			}

			// insert all values into matrix, except the last one (responses) which is inserted in
			// the respose vector ...
			std::string line;
			unsigned int rowIndex = 0;
			while ( getline( in, line ) )
			{
				TokType tok( line, boost::char_separator< char >( sep.c_str() ) );
				try
				{
					unsigned int colIndex = 0;
					for ( TokType::iterator id = tok.begin(); id != tok.end(); ++id )
					{
						if ( colIndex == dims - 1 ) // last column ...
							binaryResponse( rowIndex ) = boost::lexical_cast< PixelType >( *id );
						else
							covariates( colIndex, rowIndex ) = boost::lexical_cast< PixelType >( *id );

						colIndex++;
					}
					rowIndex++;
				} catch ( boost::bad_lexical_cast& e )
				{
					std::cout << "*** WARNING ***: could not parse data! (is it in column format?)" << std::endl;
					e.what();
					exit( EXIT_FAILURE );
				}
			}
			in.close();

			if ( ( percentage > 0 ) && ( percentage < 100 ) )
			{
				ResizeTrainingData( covariates, binaryResponse, percentage );
			}
		}

		/**
		 * Reduce number of training-points to given percentage.
		 */

		void ResizeTrainingData( MatrixType& trainingData, VectorType& trainingClasses,
				PixelType percentage )
		{
			unsigned int pointsToKeep = ( trainingClasses.size() * percentage ) / 100.0;

			// initialize vector ...
			VectorType subClasses( pointsToKeep, 0.0 );

			// initialize matrix ...
			MatrixType subData( trainingData.rows(), pointsToKeep, 0.0 );

			// create generator ...
			random_number_type generator( time( 0 ) );

			VectorType indices = GetRandomValues( trainingClasses, generator, pointsToKeep );

			// insert random samples ...
			for ( unsigned int i = 0; i < indices.size(); i++ )
			{
				subClasses( i ) = trainingClasses( indices( i ) );

				for ( unsigned int j = 0; j < subData.rows(); j++ )
					subData( j, i ) = trainingData( j, indices( i ) );
			}

			trainingData = subData;
			trainingClasses = subClasses;
		}

		/**
		 * Return uniform random values vector from inputs, with similar size.
		 */
		VectorType GetRandomValues( const VectorType& inputs, random_number_type& generator, unsigned int total )
		{
			// uniform distribution: 0 -> largest index ...
			int_distribution_type int_uni_dist( 0, inputs.size() - 1 );

			// generator ...
			int_generator_type int_distribution( generator, int_uni_dist );

			VectorType results( total, 0.0 );

			for ( unsigned int i = 0; i < total; i++ )
				results( int_distribution() );

			return results;
		}

		/**
		 * Return weight matrix.
		 */
		MatrixType Weights( const VectorType& means, const VectorType& coefficients, const MatrixType& covariate )
		{
			MatrixType weights( means.size(), means.size(), 0 );

			for ( unsigned int i = 0; i < means.size(); i++ )
				weights( i, i ) = means( i ) * ( 1. - ( means( i ) ) );

			return weights;
		}

		/**
		 * Return means vector.
		 */
		VectorType Means( const VectorType& coefficients, const MatrixType& covariate )
		{
			VectorType linearPredictors = GetColumnPackedCopy( covariate.transpose() * Vector2Matrix( coefficients ) );

			VectorType means( linearPredictors.size() );

			for ( unsigned int i = 0; i < means.size(); i++ )
				means( i) = std::exp( linearPredictors( i ) ) / ( static_cast< PixelType > ( 1.0 ) + std::exp( linearPredictors( i ) ) );

			return means;
		}

		/**
		 * Construct matrix from vector.
		 */
		MatrixType Vector2Matrix( const VectorType& V )
		{
			MatrixType A( V.size(), 1 );
			A.set_column( 0, V );

			return A;
		}

		/**
		 * Convert all matrix columns to vector.
		 */
		VectorType GetColumnPackedCopy( const MatrixType& M )
		{
			VectorType V( M.rows() * M.cols() );

			for ( unsigned int i = 0; i < M.rows(); i++ )
				for ( unsigned int j = 0; j < M.cols(); j++ )
					V( i + j * M.rows() ) = M( i, j );

			return V;
		}

		/**
		 * Set initial values for IRLS estimation.
		 */
		VectorType SetInit( const MatrixType& covariate )
		{
			VectorType V( covariate.rows() );

			PixelType a = 0;

			for ( unsigned int i = 0; i < V.size(); i++ )
			{
				a = 0;
				for ( unsigned int j = 0; j < covariate.get_row( i ).size(); j++ )
				{
					a += covariate( i, j );
				}

				V( i) = covariate.get_row( i ).size() / ( static_cast< PixelType > ( 100 ) * a );
			}
			return V;
		}

		/**
		 * Reweighted Least Squares ( IRLS ) estimation, by finding the
		 * maximum likelihood estimates of a generalized linear model( GLM ).
		 */
		VectorType IRLS( const VectorType& response, const MatrixType& covariate, unsigned int max_iter, bool verbose )
		{
			if ( response.size() != covariate.cols() )
			{
				std::cerr << "*** ERROR ***: The response vector and rows of the "
					"covariate matrix must have the same length." << std::endl;
				exit( EXIT_FAILURE );
			}

			VectorType coefficients = SetInit( covariate );

			MatrixType responseMatrix = Vector2Matrix( response );

			PixelType error = 1.0;

			MatrixType covariateMatrix( covariate );

			if( verbose )
				std::cout << "Starting iterative solving..." << std::endl;

			unsigned int iter = 0;
			while ( error > 0.000001 )
			{
				if( iter > max_iter )
				{
					std::cerr << "*** ERROR ***: maximum iteration reached. No convergence."<< std::endl;
					exit( EXIT_FAILURE );
				}

				if( verbose )
					std::cout << "Iteration: " << iter << std::endl;

				MatrixType coefficientMatrix = Vector2Matrix( coefficients );

				VectorType means = Means( coefficients, covariate );
				MatrixType weights = Weights( means, coefficients, covariate );

				MatrixType inversedWeights( weights.rows(), weights.cols() );
				MatrixType weight = MatrixType( weights );

				for ( unsigned int i = 0; i < weights.rows(); i++ )
				{
					if ( weights( i, i ) == 0. )
						inversedWeights( i, i ) = 0.;
					else
						inversedWeights( i, i ) = static_cast< PixelType > ( 1. ) / weights( i, i );
				}

				MatrixType linearPredictor = covariateMatrix.transpose() * coefficientMatrix;
				MatrixType z = linearPredictor + ( inversedWeights ) * ( responseMatrix - ( Vector2Matrix( means ) ) );
				MatrixType xwx = covariateMatrix * ( weight * covariateMatrix.transpose() );

				// Correct for rows with all values close to zero, by adding 0.1 to diagonal ...
				if ( std::abs( vnl_determinant< PixelType > ( xwx ) ) <= 1e-8 )
					for ( unsigned int i = 0; i < xwx.rows(); i++ )
						xwx( i, i ) = xwx( i, i ) + 0.1;

				// inverse...
				vnl_svd< PixelType > svd( xwx );

				MatrixType updatedCoefficient = svd.inverse() * ( ( covariateMatrix * weight ) * z );

				coefficients = GetColumnPackedCopy( updatedCoefficient );
				error = std::pow( ( updatedCoefficient - coefficientMatrix ).frobenius_norm(), 2.0 );

				iter++;
			}

			return coefficients;
		}

	};
} // end namespace generalized_linear_model

/**
 * Main.
 */
int main( int argc, char ** argv )
{
	tkd::CmdParser p( argv[0], "Generalized linear model" );

	parameters list;

	list.iterations = 100000;
	list.link = "logistic";
	list.separation = "\t";
	list.percentage = 100.0;
	list.verbose = false;
	list.printPValues = false;
	list.printZValues = false;

	p.AddArgument( list.inputFileName, "input" ) ->AddAlias( "i" ) ->SetInput( "filename" ) ->SetDescription(
			"Input file: list of covariate(s) and response function (column format)" ) ->SetRequired( true );

	p.AddArgument( list.link, "link" ) ->AddAlias( "l" ) ->SetInput( "string" ) ->SetDescription( "Link function (default: \"logistic\")" );

	p.AddArgument( list.separation, "separation" ) ->AddAlias( "s" ) ->SetInput( "string" ) ->SetDescription( "Data separator string (default: \\t" );

	p.AddArgument( list.printZValues, "print-z-values" ) ->AddAlias( "pz" ) ->SetInput( "bool" ) ->SetDescription( "Print Z-values for coefficients (default: false" );

	p.AddArgument( list.printPValues, "print-p-values" ) ->AddAlias( "pp" ) ->SetInput( "bool" ) ->SetDescription( "Print P-values for coefficients (default: false" );

	p.AddArgument( list.percentage, "percentage" ) ->AddAlias( "p" ) ->SetInput( "float" ) ->SetDescription(
			"Percentage of covariates to select randomly (default: 100)" );

	p.AddArgument( list.verbose, "verbose" ) ->AddAlias( "v" ) ->SetInput( "bool" ) ->SetDescription( "Verbose (default: false" );

	if ( !p.Parse( argc, argv ) )
	{
		p.PrintUsage( std::cout );
		return EXIT_FAILURE;
	}

	generalized_linear_model::GLM glm;

	glm.Run( list );

	return EXIT_SUCCESS;
}

max_stars_repo_name: wmotte/toolkid

max_issues_repo_name: wmotte/toolkid

max_forks_repo_name: wmotte/toolkid