<commit_before>#include "../../../shared/generated/cpp/WebViewBase.h"
#include "../../../shared/System.h"
#include "common/RhodesApp.h"
#include "common/RhoConf.h"
#include "rubyext/WebView.h"

//extern "C" HWND getMainWnd();

namespace rho {

using namespace apiGenerator;
using namespace common;

class CWebViewImpl: public CWebViewSingletonBase
{
    int m_nNavigationTimeout;
    double m_dZoomPage;
    int m_nTextZoom;
public:

    CWebViewImpl(): CWebViewSingletonBase(), m_nNavigationTimeout(0), m_dZoomPage(1.0), m_nTextZoom(1) {}

    virtual void getFramework(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(System::getWebviewFramework());
    }

    virtual void getFullScreen(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(rho_webview_get_full_screen() != 0 ? true : false );
    }

    virtual void setFullScreen( bool value, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_full_screen_mode(value ? 1 : 0);
    }

    virtual void getNativeMenu(rho::apiGenerator::CMethodResult& oResult)
    {
        rho::Vector< Hashtable<String, String> > arRes;
        RHODESAPP().getAppMenu().getMenuItemsEx(arRes);

        oResult.set(arRes);
    }

    virtual void setNativeMenu( const rho::Vector<rho::String>& value, rho::apiGenerator::CMethodResult& oResult)
    {
        RHODESAPP().getAppMenu().setAppMenuJSONItemsEx(value);
    }

    //Android only
    virtual void getEnableZoom(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(true);
    }

    virtual void setEnableZoom( bool value, rho::apiGenerator::CMethodResult& oResult){}
    virtual void getEnablePageLoadingIndication(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(false);
    }

    virtual void getEnableMediaPlaybackWithoutGesture(rho::apiGenerator::CMethodResult& oResult) {
        oResult.set(false);
    }

    virtual void setEnablePageLoadingIndication( bool value, rho::apiGenerator::CMethodResult& oResult){}
    virtual void getEnableWebPlugins(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(true);
    }

    virtual void setEnableWebPlugins( bool value, rho::apiGenerator::CMethodResult& oResult){}
    //

    virtual void getNavigationTimeout(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(m_nNavigationTimeout);
    }

    virtual void setNavigationTimeout( int value, rho::apiGenerator::CMethodResult& oResult)
    {
        //m_nNavigationTimeout = value;
        //rho_webview_setNavigationTimeout(m_nNavigationTimeout);
        //TODO: implement rho_webview_setNavigationTimeout
    }

    virtual void getScrollTechnique(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getString("WebView.scrollTechnique") );
    }

    virtual void getFontFamily(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getString("WebView.fontFamily") );
    }

    virtual void getUserAgent(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getString("WebView.userAgent") );
    }

    virtual void getViewportEnabled(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getBool("WebView.viewportEnabled") );
    }

    virtual void getViewportWidth(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getInt("WebView.viewportWidth") );
    }

    virtual void getCacheSize(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getInt("WebView.cacheSize") );
    }

    //TODO: EnableCache - does it supported by Webkit ?
    virtual void getEnableCache(rho::apiGenerator::CMethodResult& oResult){}
    virtual void setEnableCache( bool value, rho::apiGenerator::CMethodResult& oResult){}

    //TODO: AcceptLanguage - does it supported by Webkit ?
    virtual void getAcceptLanguage(rho::apiGenerator::CMethodResult& oResult){}
    virtual void setAcceptLanguage( const rho::String& value, rho::apiGenerator::CMethodResult& oResult){}

    virtual void getZoomPage(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(m_dZoomPage);
    }

    virtual void setZoomPage( double value, rho::apiGenerator::CMethodResult& oResult)
    {
        //m_dZoomPage = value;
        //RHODESAPP().getExtManager().zoomPage( (float)m_dZoomPage);
        // TODO: implement webview zoom
    }

    virtual void getTextZoomLevel(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( 1. );//m_nTextZoom
    }

    virtual void setTextZoomLevel( int value, rho::apiGenerator::CMethodResult& oResult)
    {
        //m_nTextZoom = value;
        //RHODESAPP().getExtManager().zoomText( m_nTextZoom );
        // TODO: implement webview zoom
    }

    virtual void refresh( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_refresh(tabIndex);
    }

    virtual void navigate( const rho::String& url,  int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_navigate(url.c_str(), tabIndex);
    }

    virtual void navigateBack( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        //rho_webview_navigate_back();
        //commented because every time it is navigating with default -1 instead of user defined tab index.
        rho_webview_navigate_back_with_tab(tabIndex);
    }

    virtual void currentLocation( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_current_location(tabIndex) );
    }

    virtual void currentURL( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_current_location(tabIndex) );
    }

    virtual void executeJavascript( const rho::String& javascriptText,  int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_execute_js( javascriptText.c_str(), tabIndex );
    }

    virtual void active_tab(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_active_tab() );
    }

    virtual void getActiveTab(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_active_tab() );
    }

    virtual void full_screen_mode( bool enable, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_full_screen_mode(enable ? 1 : 0);
    }

    virtual void setCookie( const rho::String& url,  const rho::String& cookie, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_set_cookie( strdup(url.c_str()), strdup(cookie.c_str()) );
    }

    //Android only
    virtual void save( const rho::String& format,  const rho::String& path,  int tabIndex, rho::apiGenerator::CMethodResult& oResult){}
    //
};

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

class CWebViewFactory: public CWebViewFactoryBase
{
public:
    ~CWebViewFactory(){}

    IWebViewSingleton* createModuleSingleton()
    {
        return new CWebViewImpl();
    }
};

}

extern "C" void Init_WebView()
{
    rho::CWebViewFactory::setInstance( new rho::CWebViewFactory() );
    rho::Init_WebView_API();

    RHODESAPP().getExtManager().requireRubyFile("RhoWebViewApi");

}
<commit_msg>FIXed KeyboardDisplayRequiresUserAction on CWebViewImpl<commit_after>#include "../../../shared/generated/cpp/WebViewBase.h"
#include "../../../shared/System.h"
#include "common/RhodesApp.h"
#include "common/RhoConf.h"
#include "rubyext/WebView.h"

//extern "C" HWND getMainWnd();

namespace rho {

using namespace apiGenerator;
using namespace common;

class CWebViewImpl: public CWebViewSingletonBase
{
    int m_nNavigationTimeout;
    double m_dZoomPage;
    int m_nTextZoom;
public:

    CWebViewImpl(): CWebViewSingletonBase(), m_nNavigationTimeout(0), m_dZoomPage(1.0), m_nTextZoom(1) {}

    virtual void getFramework(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(System::getWebviewFramework());
    }

    virtual void getFullScreen(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(rho_webview_get_full_screen() != 0 ? true : false );
    }

    virtual void setFullScreen( bool value, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_full_screen_mode(value ? 1 : 0);
    }

    virtual void getNativeMenu(rho::apiGenerator::CMethodResult& oResult)
    {
        rho::Vector< Hashtable<String, String> > arRes;
        RHODESAPP().getAppMenu().getMenuItemsEx(arRes);

        oResult.set(arRes);
    }

    virtual void setNativeMenu( const rho::Vector<rho::String>& value, rho::apiGenerator::CMethodResult& oResult)
    {
        RHODESAPP().getAppMenu().setAppMenuJSONItemsEx(value);
    }

    //Android only
    virtual void getEnableZoom(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(true);
    }

    virtual void setEnableZoom( bool value, rho::apiGenerator::CMethodResult& oResult){}
    virtual void getEnablePageLoadingIndication(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(false);
    }

    virtual void getEnableMediaPlaybackWithoutGesture(rho::apiGenerator::CMethodResult& oResult) {
        oResult.set(false);
    }

    virtual void setEnablePageLoadingIndication( bool value, rho::apiGenerator::CMethodResult& oResult){}
    virtual void getEnableWebPlugins(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(true);
    }

    virtual void setEnableWebPlugins( bool value, rho::apiGenerator::CMethodResult& oResult){}
    //

    virtual void getNavigationTimeout(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(m_nNavigationTimeout);
    }

    virtual void setNavigationTimeout( int value, rho::apiGenerator::CMethodResult& oResult)
    {
        //m_nNavigationTimeout = value;
        //rho_webview_setNavigationTimeout(m_nNavigationTimeout);
        //TODO: implement rho_webview_setNavigationTimeout
    }

    virtual void getScrollTechnique(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getString("WebView.scrollTechnique") );
    }

    virtual void getFontFamily(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getString("WebView.fontFamily") );
    }

    virtual void getUserAgent(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getString("WebView.userAgent") );
    }

    virtual void getViewportEnabled(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getBool("WebView.viewportEnabled") );
    }

    virtual void getViewportWidth(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getInt("WebView.viewportWidth") );
    }

    virtual void getCacheSize(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( RHOCONF().getInt("WebView.cacheSize") );
    }

    //TODO: EnableCache - does it supported by Webkit ?
    virtual void getEnableCache(rho::apiGenerator::CMethodResult& oResult){}
    virtual void setEnableCache( bool value, rho::apiGenerator::CMethodResult& oResult){}

    //TODO: AcceptLanguage - does it supported by Webkit ?
    virtual void getAcceptLanguage(rho::apiGenerator::CMethodResult& oResult){}
    virtual void setAcceptLanguage( const rho::String& value, rho::apiGenerator::CMethodResult& oResult){}

    virtual void getZoomPage(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set(m_dZoomPage);
    }

    virtual void setZoomPage( double value, rho::apiGenerator::CMethodResult& oResult)
    {
        //m_dZoomPage = value;
        //RHODESAPP().getExtManager().zoomPage( (float)m_dZoomPage);
        // TODO: implement webview zoom
    }

    virtual void getTextZoomLevel(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( 1. );//m_nTextZoom
    }

    virtual void setTextZoomLevel( int value, rho::apiGenerator::CMethodResult& oResult)
    {
        //m_nTextZoom = value;
        //RHODESAPP().getExtManager().zoomText( m_nTextZoom );
        // TODO: implement webview zoom
    }

    virtual void refresh( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_refresh(tabIndex);
    }

    virtual void navigate( const rho::String& url,  int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_navigate(url.c_str(), tabIndex);
    }

    virtual void navigateBack( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        //rho_webview_navigate_back();
        //commented because every time it is navigating with default -1 instead of user defined tab index.
        rho_webview_navigate_back_with_tab(tabIndex);
    }

    virtual void currentLocation( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_current_location(tabIndex) );
    }

    virtual void currentURL( int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_current_location(tabIndex) );
    }

    virtual void executeJavascript( const rho::String& javascriptText,  int tabIndex, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_execute_js( javascriptText.c_str(), tabIndex );
    }

    virtual void active_tab(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_active_tab() );
    }

    virtual void getActiveTab(rho::apiGenerator::CMethodResult& oResult)
    {
        oResult.set( rho_webview_active_tab() );
    }

    virtual void full_screen_mode( bool enable, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_full_screen_mode(enable ? 1 : 0);
    }

    virtual void setCookie( const rho::String& url,  const rho::String& cookie, rho::apiGenerator::CMethodResult& oResult)
    {
        rho_webview_set_cookie( strdup(url.c_str()), strdup(cookie.c_str()) );
    }

    //Android only
    virtual void save( const rho::String& format,  const rho::String& path,  int tabIndex, rho::apiGenerator::CMethodResult& oResult){}
    //

    void getKeyboardDisplayRequiresUserAction(rho::apiGenerator::CMethodResult& oResult){}
    void setKeyboardDisplayRequiresUserAction( bool keyboardDisplayRequiresUserAction, rho::apiGenerator::CMethodResult& oResult){}
};

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

class CWebViewFactory: public CWebViewFactoryBase
{
public:
    ~CWebViewFactory(){}

    IWebViewSingleton* createModuleSingleton()
    {
        return new CWebViewImpl();
    }
};

}

extern "C" void Init_WebView()
{
    rho::CWebViewFactory::setInstance( new rho::CWebViewFactory() );
    rho::Init_WebView_API();

    RHODESAPP().getExtManager().requireRubyFile("RhoWebViewApi");

}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2020 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Dataflow/Serialization/Network/NetworkDescriptionSerialization.h>
#include <Dataflow/Serialization/Network/XMLSerializer.h>
#include <boost/filesystem/operations.hpp>
#include <Dataflow/Serialization/Network/NetworkXMLSerializer.h>

using namespace SCIRun::Dataflow::Networks;

void ToolkitFile::load(std::istream& istr)
{
  auto xmlPtr = XMLSerializer::load_xml<ToolkitFile>(istr);
  if (xmlPtr)
    (*this) = *xmlPtr;
}

void ToolkitFile::save(std::ostream& ostr) const
{
  XMLSerializer::save_xml(*this, ostr, "toolkit");
}

namespace
{
  namespace fs = boost::filesystem;

  fs::path addSlash(const fs::path& p)
  {
    auto fullBasePath(p);
    if ("." != fullBasePath.filename())
      fullBasePath += fs::path::preferred_separator;
    return fullBasePath;
  }

  fs::path diffPath(const fs::path& basePath, const fs::path& newPath)
  {
    auto fullBasePath = addSlash(basePath);
    auto tmpPath = newPath;
    fs::path diffpath;
    while (addSlash(tmpPath) != fullBasePath)
    {
      diffpath = tmpPath.stem() / diffpath;
      tmpPath = tmpPath.parent_path();
    }

    auto filename = diffpath.leaf().string() + newPath.extension().string();
    diffpath.remove_leaf() /= filename;
    return diffpath;
  }
}

ToolkitFile SCIRun::Dataflow::Networks::makeToolkitFromDirectory(const boost::filesystem::path& toolkitPath)
{
  ToolkitFile toolkit;

  for (const auto& p : boost::filesystem::recursive_directory_iterator(toolkitPath))
  {
    if (p.path().extension() == ".srn5")
    {
      auto path = diffPath(toolkitPath, p.path()).string();
      std::replace(path.begin(), path.end(), '\\', '/');
      toolkit.networks[path] = *XMLSerializer::load_xml<NetworkFile>(p.path().string());
    }
  }
  return toolkit;
}

class NetworkSerializationWrapper : public NetworkSerializationInterface
{
public:
  explicit NetworkSerializationWrapper(const NetworkXML* ) {}
  std::map<std::string, std::pair<ModuleLookupInfo, ModuleStateHandle>> modules() const override
  {
    return {};
  }
  std::vector<ConnectionDescription> sortedConnections() const override
  {
    return {};
  }
private:
};

NetworkSerializationInterfaceHandle NetworkXML::data() const
{
  return makeShared<NetworkSerializationWrapper>(this);
}
<commit_msg>Green<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2020 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Dataflow/Serialization/Network/NetworkDescriptionSerialization.h>
#include <Dataflow/Serialization/Network/XMLSerializer.h>
#include <boost/filesystem/operations.hpp>
#include <Dataflow/Serialization/Network/NetworkXMLSerializer.h>

using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Dataflow::State;

void ToolkitFile::load(std::istream& istr)
{
  auto xmlPtr = XMLSerializer::load_xml<ToolkitFile>(istr);
  if (xmlPtr)
    (*this) = *xmlPtr;
}

void ToolkitFile::save(std::ostream& ostr) const
{
  XMLSerializer::save_xml(*this, ostr, "toolkit");
}

namespace
{
  namespace fs = boost::filesystem;

  fs::path addSlash(const fs::path& p)
  {
    auto fullBasePath(p);
    if ("." != fullBasePath.filename())
      fullBasePath += fs::path::preferred_separator;
    return fullBasePath;
  }

  fs::path diffPath(const fs::path& basePath, const fs::path& newPath)
  {
    auto fullBasePath = addSlash(basePath);
    auto tmpPath = newPath;
    fs::path diffpath;
    while (addSlash(tmpPath) != fullBasePath)
    {
      diffpath = tmpPath.stem() / diffpath;
      tmpPath = tmpPath.parent_path();
    }

    auto filename = diffpath.leaf().string() + newPath.extension().string();
    diffpath.remove_leaf() /= filename;
    return diffpath;
  }
}

ToolkitFile SCIRun::Dataflow::Networks::makeToolkitFromDirectory(const boost::filesystem::path& toolkitPath)
{
  ToolkitFile toolkit;

  for (const auto& p : boost::filesystem::recursive_directory_iterator(toolkitPath))
  {
    if (p.path().extension() == ".srn5")
    {
      auto path = diffPath(toolkitPath, p.path()).string();
      std::replace(path.begin(), path.end(), '\\', '/');
      toolkit.networks[path] = *XMLSerializer::load_xml<NetworkFile>(p.path().string());
    }
  }
  return toolkit;
}

class NetworkSerializationWrapper : public NetworkSerializationInterface
{
public:
  explicit NetworkSerializationWrapper(const NetworkXML* xml)
  {
    if (!xml)
      return;

    for (const auto& mod : xml->modules)
    {
      moduleMap_[mod.first] = { mod.second.module, makeShared<SimpleMapModuleState>(mod.second.state) };
    }
    for (const auto& conn : xml->connections)
    {
      sortedConnections_.push_back(conn);
    }
    std::sort(sortedConnections_.begin(), sortedConnections_.end());
  }

  std::map<std::string, std::pair<ModuleLookupInfo, ModuleStateHandle>> modules() const override
  {
    return moduleMap_;
  }

  std::vector<ConnectionDescription> sortedConnections() const override
  {
    return sortedConnections_;
  }
private:
  std::map<std::string, std::pair<ModuleLookupInfo, ModuleStateHandle>> moduleMap_;
  std::vector<ConnectionDescription> sortedConnections_;
};

NetworkSerializationInterfaceHandle NetworkXML::data() const
{
  return makeShared<NetworkSerializationWrapper>(this);
}
<|endoftext|>


<commit_before>#pragma once

#include <cstddef>
#include <cstring>
#include <limits>
#include <system_error>
#include <vector>

#include <rdma/rdma_cma.h>

namespace crossbow {
namespace infinio {

class MmapRegion;
class ProtectionDomain;

/**
 * @brief Buffer class pointing to a buffer space registered with an Infiniband device
 *
 * Each buffer has an unique ID associated with itself.
 */
class InfinibandBuffer {
public:
    static constexpr uint16_t INVALID_ID = std::numeric_limits<uint16_t>::max();

    InfinibandBuffer(uint16_t id)
            : mId(id) {
        memset(&mHandle, 0, sizeof(mHandle));
    }

    uint16_t id() const {
        return mId;
    }

    /**
     * @brief The number of buffers
     */
    size_t count() const {
        return 1;
    }

    /**
     * @brief The total data length of all buffers
     */
    uint32_t length() const {
        return mHandle.length;
    }

    /**
     * @brief Whether the buffer is valid
     */
    bool valid() const {
        return (mId != INVALID_ID);
    }

    /**
     * @brief Shrinks the buffer space to the given length
     *
     * The new buffer length has to be smaller than the current length.
     *
     * @param length The new length of the buffer
     */
    void shrink(uint32_t length) {
        if (mHandle.length <= length) {
            return;
        }
        mHandle.length = length;
    }

    void* data() {
        return const_cast<void*>(const_cast<const InfinibandBuffer*>(this)->data());
    }

    const void* data() const {
        return reinterpret_cast<void*>(mHandle.addr);
    }

    struct ibv_sge* handle() {
        return &mHandle;
    }

private:
    friend class ScatterGatherBuffer;

    uint32_t lkey() const {
        return mHandle.lkey;
    }

    struct ibv_sge mHandle;

    uint16_t mId;
};

/**
 * @brief The LocalMemoryRegion class provides access to a memory region on the local host
 *
 * Can be used to let a remote host read and write to the memory region or read/write data from this region to a remote
 * memory region.
 */
class LocalMemoryRegion {
public:
    LocalMemoryRegion()
            : mDataRegion(nullptr) {
    }

    /**
     * @brief Registers the memory region
     *
     * @param domain The protection domain to register this region with
     * @param data The start pointer of the memory region
     * @param length The length of the memory region
     * @param access Access flags for the Infiniband Adapter
     */
    LocalMemoryRegion(const ProtectionDomain& domain, void* data, size_t length, int access);

    LocalMemoryRegion(const ProtectionDomain& domain, MmapRegion& region, int access);

    /**
     * @brief Deregisters the memory region
     *
     * The data referenced by this memory region should not be used in any further RDMA operations.
     */
    ~LocalMemoryRegion();

    LocalMemoryRegion(const LocalMemoryRegion&) = delete;
    LocalMemoryRegion& operator=(const LocalMemoryRegion&) = delete;

    LocalMemoryRegion(LocalMemoryRegion&& other)
            : mDataRegion(other.mDataRegion) {
        other.mDataRegion = nullptr;
    }

    LocalMemoryRegion& operator=(LocalMemoryRegion&& other);

    uintptr_t address() const {
        return reinterpret_cast<uintptr_t>(mDataRegion->addr);
    }

    size_t length() const {
        return mDataRegion->length;
    }

    uint32_t rkey() const {
        return mDataRegion->rkey;
    }

    /**
     * @brief Acquire a buffer from the memory region for use in RDMA read and write requests
     *
     * The user has to take care that buffers do not overlap or read/writes are serialized.
     *
     * @param id User specified buffer ID
     * @param offset Offset into the memory region the buffer should start
     * @param length Length of the buffer
     * @return A newly acquired buffer or a buffer with invalid ID in case of an error
     */
    InfinibandBuffer acquireBuffer(uint16_t id, size_t offset, uint32_t length);

    /**
     * @brief Whether the buffer was acquired from this memory region
     */
    bool belongsToRegion(InfinibandBuffer& buffer) {
        return buffer.handle()->lkey == mDataRegion->lkey;
    }

private:
    friend class ScatterGatherBuffer;

    uint32_t lkey() const {
        return mDataRegion->lkey;
    }

    struct ibv_mr* mDataRegion;
};

/**
 * @brief The RemoteMemoryRegion class provides access to a memory region on a remote host
 *
 * Can be used to read and write from/to the remote memory.
 */
class RemoteMemoryRegion {
public:
    RemoteMemoryRegion()
            : mAddress(0x0u),
              mLength(0x0u),
              mKey(0x0u) {
    }

    RemoteMemoryRegion(uintptr_t address, size_t length, uint32_t key)
            : mAddress(address),
              mLength(length),
              mKey(key) {
    }

    uintptr_t address() const {
        return mAddress;
    }

    size_t length() const {
        return mLength;
    }

    uint32_t key() const {
        return mKey;
    }

private:
    uintptr_t mAddress;
    size_t mLength;
    uint32_t mKey;
};

/**
 * @brief Buffer class wrapping many buffers into a single one to be used in scatter / gather operations
 */
class ScatterGatherBuffer {
public:
    ScatterGatherBuffer(uint16_t id)
            : mId(id),
              mLength(0) {
    }

    uint16_t id() const {
        return mId;
    }

    /**
     * @brief The number of buffers
     */
    size_t count() const {
        return mHandle.size();
    }

    /**
     * @brief The total data length of all buffers
     */
    size_t length() const {
        return mLength;
    }

    void add(const LocalMemoryRegion& region, const void* addr, uint32_t length);

    void add(const LocalMemoryRegion& region, size_t offset, uint32_t length) {
        add(region, reinterpret_cast<const void*>(region.address() + offset), length);
    }

    void add(const InfinibandBuffer& buffer, size_t offset, uint32_t length);

    void* data(size_t index) {
        return const_cast<void*>(const_cast<const ScatterGatherBuffer*>(this)->data(index));
    }

    const void* data(size_t index) const {
        return reinterpret_cast<const void*>(mHandle.at(index).addr);
    }

    struct ibv_sge* handle() {
        return mHandle.data();
    }

    /**
     * @brief Clears all buffers
     */
    void reset() {
        mHandle.clear();
        mLength = 0;
    }

private:
    std::vector<struct ibv_sge> mHandle;
    uint64_t mLength;

    uint16_t mId;
};

} // namespace infinio
} // namespace crossbow
<commit_msg>Fix member variable initialization order<commit_after>#pragma once

#include <cstddef>
#include <cstring>
#include <limits>
#include <system_error>
#include <vector>

#include <rdma/rdma_cma.h>

namespace crossbow {
namespace infinio {

class MmapRegion;
class ProtectionDomain;

/**
 * @brief Buffer class pointing to a buffer space registered with an Infiniband device
 *
 * Each buffer has an unique ID associated with itself.
 */
class InfinibandBuffer {
public:
    static constexpr uint16_t INVALID_ID = std::numeric_limits<uint16_t>::max();

    InfinibandBuffer(uint16_t id)
            : mId(id) {
        memset(&mHandle, 0, sizeof(mHandle));
    }

    uint16_t id() const {
        return mId;
    }

    /**
     * @brief The number of buffers
     */
    size_t count() const {
        return 1;
    }

    /**
     * @brief The total data length of all buffers
     */
    uint32_t length() const {
        return mHandle.length;
    }

    /**
     * @brief Whether the buffer is valid
     */
    bool valid() const {
        return (mId != INVALID_ID);
    }

    /**
     * @brief Shrinks the buffer space to the given length
     *
     * The new buffer length has to be smaller than the current length.
     *
     * @param length The new length of the buffer
     */
    void shrink(uint32_t length) {
        if (mHandle.length <= length) {
            return;
        }
        mHandle.length = length;
    }

    void* data() {
        return const_cast<void*>(const_cast<const InfinibandBuffer*>(this)->data());
    }

    const void* data() const {
        return reinterpret_cast<void*>(mHandle.addr);
    }

    struct ibv_sge* handle() {
        return &mHandle;
    }

private:
    friend class ScatterGatherBuffer;

    uint32_t lkey() const {
        return mHandle.lkey;
    }

    struct ibv_sge mHandle;

    uint16_t mId;
};

/**
 * @brief The LocalMemoryRegion class provides access to a memory region on the local host
 *
 * Can be used to let a remote host read and write to the memory region or read/write data from this region to a remote
 * memory region.
 */
class LocalMemoryRegion {
public:
    LocalMemoryRegion()
            : mDataRegion(nullptr) {
    }

    /**
     * @brief Registers the memory region
     *
     * @param domain The protection domain to register this region with
     * @param data The start pointer of the memory region
     * @param length The length of the memory region
     * @param access Access flags for the Infiniband Adapter
     */
    LocalMemoryRegion(const ProtectionDomain& domain, void* data, size_t length, int access);

    LocalMemoryRegion(const ProtectionDomain& domain, MmapRegion& region, int access);

    /**
     * @brief Deregisters the memory region
     *
     * The data referenced by this memory region should not be used in any further RDMA operations.
     */
    ~LocalMemoryRegion();

    LocalMemoryRegion(const LocalMemoryRegion&) = delete;
    LocalMemoryRegion& operator=(const LocalMemoryRegion&) = delete;

    LocalMemoryRegion(LocalMemoryRegion&& other)
            : mDataRegion(other.mDataRegion) {
        other.mDataRegion = nullptr;
    }

    LocalMemoryRegion& operator=(LocalMemoryRegion&& other);

    uintptr_t address() const {
        return reinterpret_cast<uintptr_t>(mDataRegion->addr);
    }

    size_t length() const {
        return mDataRegion->length;
    }

    uint32_t rkey() const {
        return mDataRegion->rkey;
    }

    /**
     * @brief Acquire a buffer from the memory region for use in RDMA read and write requests
     *
     * The user has to take care that buffers do not overlap or read/writes are serialized.
     *
     * @param id User specified buffer ID
     * @param offset Offset into the memory region the buffer should start
     * @param length Length of the buffer
     * @return A newly acquired buffer or a buffer with invalid ID in case of an error
     */
    InfinibandBuffer acquireBuffer(uint16_t id, size_t offset, uint32_t length);

    /**
     * @brief Whether the buffer was acquired from this memory region
     */
    bool belongsToRegion(InfinibandBuffer& buffer) {
        return buffer.handle()->lkey == mDataRegion->lkey;
    }

private:
    friend class ScatterGatherBuffer;

    uint32_t lkey() const {
        return mDataRegion->lkey;
    }

    struct ibv_mr* mDataRegion;
};

/**
 * @brief The RemoteMemoryRegion class provides access to a memory region on a remote host
 *
 * Can be used to read and write from/to the remote memory.
 */
class RemoteMemoryRegion {
public:
    RemoteMemoryRegion()
            : mAddress(0x0u),
              mLength(0x0u),
              mKey(0x0u) {
    }

    RemoteMemoryRegion(uintptr_t address, size_t length, uint32_t key)
            : mAddress(address),
              mLength(length),
              mKey(key) {
    }

    uintptr_t address() const {
        return mAddress;
    }

    size_t length() const {
        return mLength;
    }

    uint32_t key() const {
        return mKey;
    }

private:
    uintptr_t mAddress;
    size_t mLength;
    uint32_t mKey;
};

/**
 * @brief Buffer class wrapping many buffers into a single one to be used in scatter / gather operations
 */
class ScatterGatherBuffer {
public:
    ScatterGatherBuffer(uint16_t id)
            : mLength(0),
              mId(id) {
    }

    uint16_t id() const {
        return mId;
    }

    /**
     * @brief The number of buffers
     */
    size_t count() const {
        return mHandle.size();
    }

    /**
     * @brief The total data length of all buffers
     */
    size_t length() const {
        return mLength;
    }

    void add(const LocalMemoryRegion& region, const void* addr, uint32_t length);

    void add(const LocalMemoryRegion& region, size_t offset, uint32_t length) {
        add(region, reinterpret_cast<const void*>(region.address() + offset), length);
    }

    void add(const InfinibandBuffer& buffer, size_t offset, uint32_t length);

    void* data(size_t index) {
        return const_cast<void*>(const_cast<const ScatterGatherBuffer*>(this)->data(index));
    }

    const void* data(size_t index) const {
        return reinterpret_cast<const void*>(mHandle.at(index).addr);
    }

    struct ibv_sge* handle() {
        return mHandle.data();
    }

    /**
     * @brief Clears all buffers
     */
    void reset() {
        mHandle.clear();
        mLength = 0;
    }

private:
    std::vector<struct ibv_sge> mHandle;
    uint64_t mLength;

    uint16_t mId;
};

} // namespace infinio
} // namespace crossbow
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "deployconfiguration.h"

#include "buildmanager.h"
#include "buildsteplist.h"
#include "buildstepspage.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "target.h"

using namespace ProjectExplorer;

namespace {

const char * const BUILD_STEP_LIST_COUNT("ProjectExplorer.BuildConfiguration.BuildStepListCount");
const char * const BUILD_STEP_LIST_PREFIX("ProjectExplorer.BuildConfiguration.BuildStepList.");

} // namespace

DeployConfiguration::DeployConfiguration(Target *target, const QString &id) :
    ProjectConfiguration(target, id),
    m_stepList(0)
{
    Q_ASSERT(target);
    m_stepList = new BuildStepList(this, QLatin1String(Constants::BUILDSTEPS_DEPLOY));
    //: Display name of the deploy build step list. Used as part of the labels in the project window.
    m_stepList->setDisplayName(tr("Deploy"));
    setDisplayName(tr("No deployment"));
}

DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) :
    ProjectConfiguration(target, source)
{
    Q_ASSERT(target);
    // Do not clone stepLists here, do that in the derived constructor instead
    // otherwise BuildStepFactories might reject to set up a BuildStep for us
    // since we are not yet the derived class!
}

DeployConfiguration::~DeployConfiguration()
{
    delete m_stepList;
}

BuildStepList *DeployConfiguration::stepList() const
{
    return m_stepList;
}

QVariantMap DeployConfiguration::toMap() const
{
    QVariantMap map(ProjectConfiguration::toMap());
    map.insert(QLatin1String(BUILD_STEP_LIST_COUNT), 1);
    map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) % QLatin1String("0"), m_stepList->toMap());

    return map;
}

DeployConfigurationWidget *DeployConfiguration::configurationWidget() const
{
    return 0;
}

bool DeployConfiguration::fromMap(const QVariantMap &map)
{
    if (!ProjectConfiguration::fromMap(map))
        return false;

    int maxI = map.value(QLatin1String(BUILD_STEP_LIST_COUNT), 0).toInt();
    Q_ASSERT(maxI == 1);
    QVariantMap data = map.value(QLatin1String(BUILD_STEP_LIST_PREFIX) % QLatin1String("0")).toMap();
    if (!data.isEmpty()) {
        m_stepList = new BuildStepList(this, data);
        if (m_stepList->isNull()) {
            qWarning() << "Failed to restore deploy step list";
            delete m_stepList;
            m_stepList = 0;
            return false;
        }
    } else {
        qWarning() << "No data for deploy step list found!";
    }

    // TODO: We assume that we have hold the deploy list
    Q_ASSERT(m_stepList && m_stepList->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY));

    return true;
}

Target *DeployConfiguration::target() const
{
    return static_cast<Target *>(parent());
}

void DeployConfiguration::cloneSteps(DeployConfiguration *source)
{
    if (source == this)
        return;
    delete m_stepList;
    m_stepList = new BuildStepList(this, source->stepList());
}

///
// DeployConfigurationFactory
///

DeployConfigurationFactory::DeployConfigurationFactory(QObject *parent) :
    QObject(parent)
{ }

DeployConfigurationFactory::~DeployConfigurationFactory()
{ }

QStringList DeployConfigurationFactory::availableCreationIds(Target *parent) const
{
    Q_UNUSED(parent);
    return QStringList() << QLatin1String(Constants::DEFAULT_DEPLOYCONFIGURATION_ID);
}

QString DeployConfigurationFactory::displayNameForId(const QString &id) const
{
    if (id == QLatin1String(Constants::DEFAULT_DEPLOYCONFIGURATION_ID))
        //: Display name of the default deploy configuration
        return tr("Deploy Configuration");
    return QString();
}

bool DeployConfigurationFactory::canCreate(Target *parent, const QString &id) const
{
    Q_UNUSED(parent);
    return id == QLatin1String(Constants::DEFAULT_DEPLOYCONFIGURATION_ID);
}

DeployConfiguration *DeployConfigurationFactory::create(Target *parent, const QString &id)
{
    if (!canCreate(parent, id))
        return 0;
    return new DeployConfiguration(parent, id);
}

bool DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
{
    return canCreate(parent, idFromMap(map));
}

DeployConfiguration *DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;
    DeployConfiguration *dc = new DeployConfiguration(parent, idFromMap(map));
    if (!dc->fromMap(map)) {
        delete dc;
        return 0;
    }
    return dc;
}

bool DeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *product) const
{
    return canCreate(parent, product->id());
}

DeployConfiguration *DeployConfigurationFactory::clone(Target *parent, DeployConfiguration *product)
{
    if (!canClone(parent, product))
        return 0;
    return new DeployConfiguration(parent, product);
}

///
// DeployConfigurationWidget
///

DeployConfigurationWidget::DeployConfigurationWidget(QWidget *parent) : NamedWidget(parent)
{ }
<commit_msg>Compile fix on mac<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "deployconfiguration.h"

#include "buildmanager.h"
#include "buildsteplist.h"
#include "buildstepspage.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "target.h"

using namespace ProjectExplorer;

namespace {

const char * const BUILD_STEP_LIST_COUNT("ProjectExplorer.BuildConfiguration.BuildStepListCount");
const char * const BUILD_STEP_LIST_PREFIX("ProjectExplorer.BuildConfiguration.BuildStepList.");

} // namespace

DeployConfiguration::DeployConfiguration(Target *target, const QString &id) :
    ProjectConfiguration(target, id),
    m_stepList(0)
{
    Q_ASSERT(target);
    m_stepList = new BuildStepList(this, QLatin1String(Constants::BUILDSTEPS_DEPLOY));
    //: Display name of the deploy build step list. Used as part of the labels in the project window.
    m_stepList->setDisplayName(tr("Deploy"));
    setDisplayName(tr("No deployment"));
}

DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) :
    ProjectConfiguration(target, source)
{
    Q_ASSERT(target);
    // Do not clone stepLists here, do that in the derived constructor instead
    // otherwise BuildStepFactories might reject to set up a BuildStep for us
    // since we are not yet the derived class!
}

DeployConfiguration::~DeployConfiguration()
{
    delete m_stepList;
}

BuildStepList *DeployConfiguration::stepList() const
{
    return m_stepList;
}

QVariantMap DeployConfiguration::toMap() const
{
    QVariantMap map(ProjectConfiguration::toMap());
    map.insert(QLatin1String(BUILD_STEP_LIST_COUNT), 1);
    map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QLatin1String("0"), m_stepList->toMap());

    return map;
}

DeployConfigurationWidget *DeployConfiguration::configurationWidget() const
{
    return 0;
}

bool DeployConfiguration::fromMap(const QVariantMap &map)
{
    if (!ProjectConfiguration::fromMap(map))
        return false;

    int maxI = map.value(QLatin1String(BUILD_STEP_LIST_COUNT), 0).toInt();
    Q_ASSERT(maxI == 1);
    QVariantMap data = map.value(QLatin1String(BUILD_STEP_LIST_PREFIX) + QLatin1String("0")).toMap();
    if (!data.isEmpty()) {
        m_stepList = new BuildStepList(this, data);
        if (m_stepList->isNull()) {
            qWarning() << "Failed to restore deploy step list";
            delete m_stepList;
            m_stepList = 0;
            return false;
        }
    } else {
        qWarning() << "No data for deploy step list found!";
    }

    // TODO: We assume that we have hold the deploy list
    Q_ASSERT(m_stepList && m_stepList->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY));

    return true;
}

Target *DeployConfiguration::target() const
{
    return static_cast<Target *>(parent());
}

void DeployConfiguration::cloneSteps(DeployConfiguration *source)
{
    if (source == this)
        return;
    delete m_stepList;
    m_stepList = new BuildStepList(this, source->stepList());
}

///
// DeployConfigurationFactory
///

DeployConfigurationFactory::DeployConfigurationFactory(QObject *parent) :
    QObject(parent)
{ }

DeployConfigurationFactory::~DeployConfigurationFactory()
{ }

QStringList DeployConfigurationFactory::availableCreationIds(Target *parent) const
{
    Q_UNUSED(parent);
    return QStringList() << QLatin1String(Constants::DEFAULT_DEPLOYCONFIGURATION_ID);
}

QString DeployConfigurationFactory::displayNameForId(const QString &id) const
{
    if (id == QLatin1String(Constants::DEFAULT_DEPLOYCONFIGURATION_ID))
        //: Display name of the default deploy configuration
        return tr("Deploy Configuration");
    return QString();
}

bool DeployConfigurationFactory::canCreate(Target *parent, const QString &id) const
{
    Q_UNUSED(parent);
    return id == QLatin1String(Constants::DEFAULT_DEPLOYCONFIGURATION_ID);
}

DeployConfiguration *DeployConfigurationFactory::create(Target *parent, const QString &id)
{
    if (!canCreate(parent, id))
        return 0;
    return new DeployConfiguration(parent, id);
}

bool DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
{
    return canCreate(parent, idFromMap(map));
}

DeployConfiguration *DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;
    DeployConfiguration *dc = new DeployConfiguration(parent, idFromMap(map));
    if (!dc->fromMap(map)) {
        delete dc;
        return 0;
    }
    return dc;
}

bool DeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *product) const
{
    return canCreate(parent, product->id());
}

DeployConfiguration *DeployConfigurationFactory::clone(Target *parent, DeployConfiguration *product)
{
    if (!canClone(parent, product))
        return 0;
    return new DeployConfiguration(parent, product);
}

///
// DeployConfigurationWidget
///

DeployConfigurationWidget::DeployConfigurationWidget(QWidget *parent) : NamedWidget(parent)
{ }
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <algorithm>
#include <cmath>
#include <iostream>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "modules/planning/proto/dp_st_speed_config.pb.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/file.h"
#include "modules/planning/common/path_decision.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/integration_tests/planning_test_base.h"
#include "modules/planning/optimizer/dp_st_speed/dp_st_graph.h"

namespace apollo {
namespace planning {

using common::adapter::AdapterManager;

class DpStSpeedTest : public PlanningTestBase {
 public:
  void SetPathDataWithStraightLine() {
    double l = 0.0;
    const double ds = 1.0;

    std::vector<common::FrenetFramePoint> points;
    for (double s = 0.0; s < 100.0; s += ds) {
      common::FrenetFramePoint ffp;
      ffp.set_s(s);
      ffp.set_l(l);
      points.push_back(ffp);
    }

    FrenetFramePath path(points);
    path_data_.SetReferenceLine(reference_line_);
    path_data_.SetFrenetPath(path);
  }

  virtual void SetUp() {
    google::InitGoogleLogging("DpStSpeedTest");
    PlanningTestBase::SetUp();
    const auto* frame = planning_.GetFrame();
    reference_line_ = &(frame->reference_line());
    SetPathDataWithStraightLine();
  }

 protected:
  const ReferenceLine* reference_line_ = nullptr;
  common::TrajectoryPoint init_point_;
  SpeedData speed_data_;  // output
  PathData path_data_;    // input
};

TEST_F(DpStSpeedTest, dp_st_graph_test) {
  DpStSpeedConfig dp_st_speed_config;
  DpStGraph dp_st_graph(dp_st_speed_config, path_data_);
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: fixed dp_st_graph_test<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <algorithm>
#include <cmath>
#include <iostream>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "modules/planning/proto/dp_st_speed_config.pb.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/file.h"
#include "modules/planning/common/path_decision.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/integration_tests/planning_test_base.h"
#include "modules/planning/optimizer/dp_st_speed/dp_st_graph.h"

namespace apollo {
namespace planning {

using common::adapter::AdapterManager;

class DpStSpeedTest : public PlanningTestBase {
 public:
  void SetPathDataWithStraightLine() {
    double l = 0.0;
    const double ds = 1.0;

    std::vector<common::FrenetFramePoint> points;
    for (double s = 0.0; s < 50.0; s += ds) {
      common::FrenetFramePoint ffp;
      ffp.set_s(s);
      ffp.set_l(l);
      points.push_back(ffp);
    }

    FrenetFramePath path(points);
    path_data_.SetReferenceLine(reference_line_);
    path_data_.SetFrenetPath(path);
  }

  virtual void SetUp() {
    google::InitGoogleLogging("DpStSpeedTest");
    PlanningTestBase::SetUp();
    RunPlanning();
    const auto* frame = planning_.GetFrame();
    reference_line_ = &(frame->reference_line());
    SetPathDataWithStraightLine();
  }

 protected:
  const ReferenceLine* reference_line_ = nullptr;
  common::TrajectoryPoint init_point_;
  SpeedData speed_data_;  // output
  PathData path_data_;    // input
};

TEST_F(DpStSpeedTest, dp_st_graph_test) {
  DpStSpeedConfig dp_st_speed_config;
  DpStGraph dp_st_graph(dp_st_speed_config, path_data_);
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Jolla Ltd.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qcontinuinganimationgroupjob_p.h"
#include "private/qanimationjobutil_p.h"

QT_BEGIN_NAMESPACE

QContinuingAnimationGroupJob::QContinuingAnimationGroupJob()
    : QAnimationGroupJob()
{
}

QContinuingAnimationGroupJob::~QContinuingAnimationGroupJob()
{
}

void QContinuingAnimationGroupJob::updateCurrentTime(int /*currentTime*/)
{
    if (!firstChild())
        return;

    for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
        if (animation->state() == state()) {
            RETURN_IF_DELETED(animation->setCurrentTime(m_currentTime));
        }
    }
}

void QContinuingAnimationGroupJob::updateState(QAbstractAnimationJob::State newState,
                                          QAbstractAnimationJob::State oldState)
{
    QAnimationGroupJob::updateState(newState, oldState);

    switch (newState) {
    case Stopped:
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling())
            animation->stop();
        break;
    case Paused:
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling())
            if (animation->isRunning())
                animation->pause();
        break;
    case Running:
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
            resetUncontrolledAnimationFinishTime(animation);
            animation->setDirection(m_direction);
            animation->start();
        }
        break;
    }
}

void QContinuingAnimationGroupJob::updateDirection(QAbstractAnimationJob::Direction direction)
{
    if (!isStopped()) {
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
            animation->setDirection(direction);
        }
    }
}

void QContinuingAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimationJob *animation)
{
    Q_ASSERT(animation && (animation->duration() == -1));
    int uncontrolledRunningCount = 0;

    for (QAbstractAnimationJob *child = firstChild(); child; child = child->nextSibling()) {
        if (child == animation)
            setUncontrolledAnimationFinishTime(animation, animation->currentTime());
        else if (uncontrolledAnimationFinishTime(child) == -1)
            ++uncontrolledRunningCount;
    }

    if (uncontrolledRunningCount > 0)
        return;

    setUncontrolledAnimationFinishTime(this, currentTime());
    stop();
}

QT_END_NAMESPACE

<commit_msg>Don't start continuing animation when it doesn't have children.<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Jolla Ltd.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qcontinuinganimationgroupjob_p.h"
#include "private/qanimationjobutil_p.h"

QT_BEGIN_NAMESPACE

QContinuingAnimationGroupJob::QContinuingAnimationGroupJob()
    : QAnimationGroupJob()
{
}

QContinuingAnimationGroupJob::~QContinuingAnimationGroupJob()
{
}

void QContinuingAnimationGroupJob::updateCurrentTime(int /*currentTime*/)
{
    Q_ASSERT(firstChild());

    for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
        if (animation->state() == state()) {
            RETURN_IF_DELETED(animation->setCurrentTime(m_currentTime));
        }
    }
}

void QContinuingAnimationGroupJob::updateState(QAbstractAnimationJob::State newState,
                                          QAbstractAnimationJob::State oldState)
{
    QAnimationGroupJob::updateState(newState, oldState);

    switch (newState) {
    case Stopped:
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling())
            animation->stop();
        break;
    case Paused:
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling())
            if (animation->isRunning())
                animation->pause();
        break;
    case Running:
        if (!firstChild()) {
            stop();
            return;
        }
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
            resetUncontrolledAnimationFinishTime(animation);
            animation->setDirection(m_direction);
            animation->start();
        }
        break;
    }
}

void QContinuingAnimationGroupJob::updateDirection(QAbstractAnimationJob::Direction direction)
{
    if (!isStopped()) {
        for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
            animation->setDirection(direction);
        }
    }
}

void QContinuingAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimationJob *animation)
{
    Q_ASSERT(animation && (animation->duration() == -1));
    int uncontrolledRunningCount = 0;

    for (QAbstractAnimationJob *child = firstChild(); child; child = child->nextSibling()) {
        if (child == animation)
            setUncontrolledAnimationFinishTime(animation, animation->currentTime());
        else if (uncontrolledAnimationFinishTime(child) == -1)
            ++uncontrolledRunningCount;
    }

    if (uncontrolledRunningCount > 0)
        return;

    setUncontrolledAnimationFinishTime(this, currentTime());
    stop();
}

QT_END_NAMESPACE

<|endoftext|>


<commit_before>#ifndef LOGGER_HH
#define LOGGER_HH

#include <iostream>
#include <fstream>
#include <sstream>

///just a LOGINDENT value to be defined at build time. this way you have indent levels depending on built libraries
#ifndef LOGINDENTLVL
#define LOGINDENTLVL 0
#endif

///the default tab width for the indent...
#ifndef LOGINDENTWIDTH
#define LOGINDENTWIDTH 2
#endif

///just a LOGPREFIX value to be defined at build time. this way you can have a prefix for the whole project binary (library or executable)
#ifndef LOGPREFIX
#define LOGPREFIX "Default Log"
#endif

/**
 * \class Logger
 *
 * \brief This class defines loglevel on top of clog
 *
 * This Logger use indentation levels, usually defined on build time.
 * TODO : Add LogLevels to filter the console output as well as the file output (3 loglevel : quiet / normal / verbose)
 *
 * \author Alex
 *
 * \date 2005/10/05
 *
 * Contact: asmodehn@gna.org
 *
 */

typedef enum {quiet,normal,verbose} Loglevel;

class Logger //: public std::ostream
{
	int _indentlvl,_indentwidth;
	std::string _logprefix;

	std::ofstream _ofstr;
	bool _consoleLog;
	bool _fileLog;

	bool setLogfile( const std::string & filename);

  public :

    ///Default Constructor that defines how to write the log
    Logger(const std::string & LogPrefix = LOGPREFIX, int indentlevel = LOGINDENTLVL, int indentwidth = LOGINDENTWIDTH );

    ///Default Destructor that flush the Log Buffer
    ~Logger();

    void toggleConsoleLog() { _consoleLog = !_consoleLog ; }
    void enableConsoleLog() { _consoleLog= true ; }
    void disableConsoleLog() { _consoleLog = false ; }

    bool enableFileLog( const std::string & filename) { _fileLog= true ; return setLogfile(filename);}
    void disableFileLog() { _fileLog = false ; _ofstr.close();}

    //void add(const std::string & message); // not const because of initial '\n' in string from streams...
		template<typename M> Logger& operator << (const M & msg);
		//to enable manipulators on Logger
		Logger& operator << (std::ostream& (*manip)(std::ostream&));
		Logger& operator << (std::ios_base& (*manip)(std::ios_base&));
		Logger& operator << (Logger& (*manip)(Logger&));//to enable specific manipulators on Logger

		friend Logger& nl (Logger& log); // adds a prefix
		friend Logger& endl (Logger& log); // adds a prefix

		Logger & flush(void);

  //TODO : handle operator<< and
  //http://www.mactech.com/articles/mactech/Vol.16/16.04/StreamforAllSeasons/
  //http://www.horstmann.com/cpp/iostreams.html
  //http://spec.winprog.org/streams/

};

template<typename M> Logger& Logger::operator<< ( const M & msg)
{
	if (_consoleLog) std::clog << msg;
	if (_fileLog) _ofstr << msg;
	return *this;
}

#endif
<commit_msg>moved logger from Common to SDLwrap, since it might depend on some SDL library feature to be thread safe or to write to a file...<commit_after><|endoftext|>


<commit_before>/*****************************************************************************
 * Licensed to Qualys, Inc. (QUALYS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * QUALYS 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.
 ****************************************************************************/

/**
 * @file
 * @brief IronBee Modules --- XRule Exception
 *
 * @author Sam Baskinger <sbaskinger@qualys.com>
 */

#include "xrules_exception.hpp"
#include "xrules.hpp"
#include "xrules_acls.hpp"

#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>

#include <strings.h>

namespace {

/**
 * Utility function to parse an argument for XRuleException configurations.
 *
 * This takes an XRuleException argument, checks the provided prefix,
 * and if it matches returns IB_OK and assigns the `char *` following the
 * prefix in @a arg to @a rest. Thus, the caller is provided with
 * the value following the prefix and may continue parsing it.
 *
 * @param[in] expected The expected value. A case insensitive comparison
 *            is done between @a expected and @a arg.
 * @param[in] arg The argument to check.
 * @param[in] rest The rest of @a arg following the prefix @a expected.
 *
 * @returns
 * - IB_OK On success and a match.
 * - IB_ENOENT If @a expected does not match @a arg.
 */
ib_status_t parse_arg(
    const char  *expected,
    const char  *arg,
    const char **rest
)
{
    size_t len = strlen(expected);
    if (strncasecmp(expected, arg, len) == 0) {
        (*rest) = arg+len;
        return IB_OK;
    }
    else {
        return IB_ENOENT;
    }
}

/**
 * Use ib_uuid_create_v4() to generate a name.
 *
 * This is used to name Actions when the name is not important.
 */
std::string random_name()
{
    std::vector<char> uuid(IB_UUID_LENGTH);

    IronBee::throw_if_error(ib_uuid_create_v4(&(uuid[0])));

    return std::string(&(uuid[0]));
}

/**
 * A ConclusionAction is an action that conditionally fires when it is applied.
 *
 * To implement an XRuleException we actually wire together many
 * FactActions which, after each is called, attempts to apply the
 * ConclusionAction.
 *
 * The ConclusionAction will only fire if all its facts are true (results=1).
 */
class ConclusionAction : public Action
{
public:
    /**
     * Construct a conclusion action that depends on @a results.
     *
     * @param[in] action The user's action to execute when all FactAction s
     *            are true.
     * @param[in] results The number of results this ConclusionAction should
     *            create to be given to FactActions.
     */
    ConclusionAction(action_ptr action, int results);

    /**
     * Return a reference to the boolean that denotes a particular result.
     *
     * @param[in] mdata Module data.
     * @param[in] i The index of the result to fetch. This must be in
     * the range 0 through the number of results specified when this
     * object was created.
     *
     * @returns The int reference to assign to.
     */
    int& result(
        XRulesModuleTxData& mdata,
        int i
    );

private:
    //! The action that is applied if all results are true.
    action_ptr m_action;

    /**
     * A vector of results (0=failed/not executed, 1=success).
     *
     * Only when all of these are equal to 1 will ConclusionAction::m_action
     * be executed.
     */
    size_t m_results;

    /**
     * Apply this action to the transaction if all results are non-zero.
     *
     * @param[in] config Module configuration.
     * @param[in] mdata The module.
     * @param[in] tx The current transaction.
     */
    virtual void apply_impl(
        const XRulesModuleConfig& config,
        xrules_module_tx_data_ptr mdata,
        IronBee::Transaction      tx
    ) const;
};

ConclusionAction::ConclusionAction(action_ptr action, int results):
    Action(random_name(), 10),
    m_action(action),
    m_results(results)
{}

int& ConclusionAction::result(
    XRulesModuleTxData& mdata,
    int i
)
{
    std::vector<int>& v = mdata.exception_facts[this];

    if (v.size() <= m_results) {
        v.resize(m_results);
    }

    return v[i];
}

void ConclusionAction::apply_impl(
    const XRulesModuleConfig& config,
    xrules_module_tx_data_ptr mdata,
    IronBee::Transaction      tx
) const
{
    std::vector<int>& v = (*mdata).exception_facts[this];

    BOOST_FOREACH(int r, v) {
        if (r != 1) {
            return;
        }
    }

    /* If we reach this code, all results were = 1. Execute. */
    (*m_action)(config, mdata, tx);
}

/**
 * This action initializes facts to false (0) and sets them to true (1).
 *
 * To implement an XRuleException we must collect various facts, such as
 * is a Path equal to some prefix, is a source IP in a subnet, etc.
 * To collect these facts XRules are created and given FactActions
 * which record that a given XRule was true and fired its action.
 *
 * When any FactAction fires, as its last action, it calls its
 * associated ConclusionAction. A ConclusionAction will check if all
 * FactActions have set their facts to true (1). Only if all facts are
 * true does the ConclusionAction then fire its own associated Action.
 * The ConclusionAction's Action is the action the user requested
 * in the configuration language.
 */
class FactAction : public Action
{
public:

    /**
     * Construct a new action.
     *
     * @param[in] conclusion The conclusion action that this Fact is
     *            gating the execution of.
     * @param[in] result_idx The index of the result in the result
     *            vector of the ConclusionAction.
     *
     * @note This takes a reference to a boolean because actions may
     *       not modify themselves.
     */
    FactAction(action_ptr conclusion, int result_idx);

private:
    action_ptr  m_conclusion;
    int         m_result_idx;

    /**
     * Apply this action to the transaction.
     *
     * @param[in] config Module configuration.
     * @param[in] mdata The module.
     * @param[in] tx The current transaction.
     */
    virtual void apply_impl(
        const XRulesModuleConfig& config,
        xrules_module_tx_data_ptr mdata,
        IronBee::Transaction      tx
    ) const;
};

FactAction::FactAction(action_ptr conclusion, int result_idx) :
    Action(random_name(), 10),
    m_conclusion(conclusion),
    m_result_idx(result_idx)
{}

void FactAction::apply_impl(
    const XRulesModuleConfig& config,
    xrules_module_tx_data_ptr mdata,
    IronBee::Transaction      tx
) const
{
    /* Update the results. */
    static_cast<ConclusionAction&>(*m_conclusion).
        result(*mdata, m_result_idx) = 1;

    /* Having updated the results, try the conclusion. */
    (*m_conclusion)(config, mdata, tx);
}

} /* Anonymous Namespace */

void XRuleException::xrule_directive(
    XRulesModule                     module,
    IronBee::ConfigurationParser     cp,
    const char *                     name,
    IronBee::ConstList<const char *> all_params
)
{
    IronBee::Context    ctx = cp.current_context();
    XRulesModuleConfig& cfg =
        module.module().configuration_data<XRulesModuleConfig>(ctx);

    /* The unparsed bits from parsing an action out of the params arg. */
    IronBee::List<const char *> params =
        IronBee::List<const char *>::create(cp.memory_manager());

    /* Parse the action and put the remaining tokens in `params`. */
    action_ptr user_action = module.parse_action(cp, all_params, params);

    /* Construct a conclusion action that will fire the user's action. */
    action_ptr conclusion(
        boost::make_shared<ConclusionAction>(
            user_action,
            params.size()));

    /* The conclusion action will log. The user action does not. */
    user_action->logevent_msg() =
        std::string("Exception matched: ") +
        user_action->logevent_msg();
    user_action->logevent_tag() = user_action->logevent_tag();

    conclusion->logevent_msg() = "";
    conclusion->logevent_tag() = "";

    if (params.empty()) {
        BOOST_THROW_EXCEPTION(
            IronBee::einval()
                << IronBee::errinfo_what(
                    "XRuleException require at least 1 argument.")
        );
    }

    int result_idx = 0;
    BOOST_FOREACH(const char* param, params) {
        const char* val;

        /* Build a new FactAction to
         * - Set the result `result_idx` to 1.
         * - Fire the conclusion action. */
        action_ptr action(
            boost::make_shared<FactAction>(
                conclusion,
                result_idx));

        ++result_idx;

        if (IB_OK == parse_arg("EventTag:", param, &val)) {
            IronBee::List<const char *> l =
                IronBee::List<const char *>::create(cp.memory_manager());
            l.push_back(val);
            action->logevent_msg() =
                std::string("EventTag ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/tags";
            cfg.event_xrules.push_back(
                xrule_ptr(
                    new XRuleEventTag(l, action)));
        }
        else if (IB_OK == parse_arg("IPv4:", param, &val)) {
            // Copy in an empty, uninitialized ipset entry.
            ib_ipset4_entry_t entry;

            memset(&entry, 0, sizeof(entry));

            val = XRuleIP::normalize_ipv4(cp.memory_manager(), val);

            IronBee::throw_if_error(
                ib_ip4_str_to_net(val, &(entry.network)),
                (std::string("Failed to get net from string: ")+val).c_str()
            );

            action->logevent_msg() =
                std::string("IPv4 ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/ipv4";

            // Put that action in the ip set.
            entry.data = IronBee::value_to_data<action_ptr>(
                action,
                cp.engine().main_memory_mm().ib());

            cfg.ipv4_list.push_back(entry);
        }
        else if (IB_OK == parse_arg("IPv6:", param, &val)) {
            // Copy in an empty, uninitialized ipset entry.
            ib_ipset6_entry_t entry;

            memset(&entry, 0, sizeof(entry));

            val = XRuleIP::normalize_ipv6(cp.memory_manager(), val);

            IronBee::throw_if_error(
                ib_ip6_str_to_net(val, &(entry.network)),
                (std::string("Failed to get net from string: ")+val).c_str()
            );

            action->logevent_msg() =
                std::string("IPv6 ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/ipv6";

            // Put that action in the ip set.
            entry.data = IronBee::value_to_data<action_ptr>(
                action,
                cp.engine().main_memory_mm().ib());

            cfg.ipv6_list.push_back(entry);
        }
        else if (IB_OK == parse_arg("Geo:", param, &val)) {
            action->logevent_msg() =
                std::string("Geo ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/geo";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleGeo(val, action)));
        }
        else if (IB_OK == parse_arg("Path:", param, &val)) {
            action->logevent_msg() =
                std::string("Path ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/path";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRulePath(val, action)));
        }
        else if (IB_OK == parse_arg("Param:", param, &val)) {
            action->logevent_msg() = std::string("Param ") + val + " matched";
            action->logevent_tag() = "xrule/param";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleParam(val, cp.engine(), action)));
        }
        else if (IB_OK == parse_arg("Cookie:", param, &val)) {
            action->logevent_msg() = std::string("Cookie ") + val + " matched";
            action->logevent_tag() = "xrule/cookie";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleCookie(val, cp.engine(), action)));
        }
        else if (IB_OK == parse_arg("RequestHeader:", param, &val)) {
            action->logevent_msg() =
                std::string("RequestHeader ") + val + " matched";
            action->logevent_tag() = "xrule/requestheader";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleRequestHeader(val, action)));
        }
        else if (IB_OK == parse_arg("Method:", param, &val)) {
            action->logevent_msg() = std::string("Method ") + val + " matched";
            action->logevent_tag() = "xrule/method";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleMethod(val, action)));
        }
        else if (IB_OK == parse_arg("Hostname:", param, &val)) {
            action->logevent_msg() = std::string("Hostname ") + val + " matched";
            action->logevent_tag() = "xrule/hostname";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleHostname(val, action)));
        }
        else {
            BOOST_THROW_EXCEPTION(
                IronBee::enoent()
                    << IronBee::errinfo_what(
                        std::string("Unknown XRuleException: ")+param)
            );
        }
    }
}
<commit_msg>xrule_exceptions.cpp: XRuleException now supports types RequestContentType:... and Time:... RNS-1394.<commit_after>/*****************************************************************************
 * Licensed to Qualys, Inc. (QUALYS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * QUALYS 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.
 ****************************************************************************/

/**
 * @file
 * @brief IronBee Modules --- XRule Exception
 *
 * @author Sam Baskinger <sbaskinger@qualys.com>
 */

#include "xrules_exception.hpp"
#include "xrules.hpp"
#include "xrules_acls.hpp"

#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>

#include <strings.h>

namespace {

/**
 * Utility function to parse an argument for XRuleException configurations.
 *
 * This takes an XRuleException argument, checks the provided prefix,
 * and if it matches returns IB_OK and assigns the `char *` following the
 * prefix in @a arg to @a rest. Thus, the caller is provided with
 * the value following the prefix and may continue parsing it.
 *
 * @param[in] expected The expected value. A case insensitive comparison
 *            is done between @a expected and @a arg.
 * @param[in] arg The argument to check.
 * @param[in] rest The rest of @a arg following the prefix @a expected.
 *
 * @returns
 * - IB_OK On success and a match.
 * - IB_ENOENT If @a expected does not match @a arg.
 */
ib_status_t parse_arg(
    const char  *expected,
    const char  *arg,
    const char **rest
)
{
    size_t len = strlen(expected);
    if (strncasecmp(expected, arg, len) == 0) {
        (*rest) = arg+len;
        return IB_OK;
    }
    else {
        return IB_ENOENT;
    }
}

/**
 * Use ib_uuid_create_v4() to generate a name.
 *
 * This is used to name Actions when the name is not important.
 */
std::string random_name()
{
    std::vector<char> uuid(IB_UUID_LENGTH);

    IronBee::throw_if_error(ib_uuid_create_v4(&(uuid[0])));

    return std::string(&(uuid[0]));
}

/**
 * A ConclusionAction is an action that conditionally fires when it is applied.
 *
 * To implement an XRuleException we actually wire together many
 * FactActions which, after each is called, attempts to apply the
 * ConclusionAction.
 *
 * The ConclusionAction will only fire if all its facts are true (results=1).
 */
class ConclusionAction : public Action
{
public:
    /**
     * Construct a conclusion action that depends on @a results.
     *
     * @param[in] action The user's action to execute when all FactAction s
     *            are true.
     * @param[in] results The number of results this ConclusionAction should
     *            create to be given to FactActions.
     */
    ConclusionAction(action_ptr action, int results);

    /**
     * Return a reference to the boolean that denotes a particular result.
     *
     * @param[in] mdata Module data.
     * @param[in] i The index of the result to fetch. This must be in
     * the range 0 through the number of results specified when this
     * object was created.
     *
     * @returns The int reference to assign to.
     */
    int& result(
        XRulesModuleTxData& mdata,
        int i
    );

private:
    //! The action that is applied if all results are true.
    action_ptr m_action;

    /**
     * A vector of results (0=failed/not executed, 1=success).
     *
     * Only when all of these are equal to 1 will ConclusionAction::m_action
     * be executed.
     */
    size_t m_results;

    /**
     * Apply this action to the transaction if all results are non-zero.
     *
     * @param[in] config Module configuration.
     * @param[in] mdata The module.
     * @param[in] tx The current transaction.
     */
    virtual void apply_impl(
        const XRulesModuleConfig& config,
        xrules_module_tx_data_ptr mdata,
        IronBee::Transaction      tx
    ) const;
};

ConclusionAction::ConclusionAction(action_ptr action, int results):
    Action(random_name(), 10),
    m_action(action),
    m_results(results)
{}

int& ConclusionAction::result(
    XRulesModuleTxData& mdata,
    int i
)
{
    std::vector<int>& v = mdata.exception_facts[this];

    if (v.size() <= m_results) {
        v.resize(m_results);
    }

    return v[i];
}

void ConclusionAction::apply_impl(
    const XRulesModuleConfig& config,
    xrules_module_tx_data_ptr mdata,
    IronBee::Transaction      tx
) const
{
    std::vector<int>& v = (*mdata).exception_facts[this];

    BOOST_FOREACH(int r, v) {
        if (r != 1) {
            return;
        }
    }

    /* If we reach this code, all results were = 1. Execute. */
    (*m_action)(config, mdata, tx);
}

/**
 * This action initializes facts to false (0) and sets them to true (1).
 *
 * To implement an XRuleException we must collect various facts, such as
 * is a Path equal to some prefix, is a source IP in a subnet, etc.
 * To collect these facts XRules are created and given FactActions
 * which record that a given XRule was true and fired its action.
 *
 * When any FactAction fires, as its last action, it calls its
 * associated ConclusionAction. A ConclusionAction will check if all
 * FactActions have set their facts to true (1). Only if all facts are
 * true does the ConclusionAction then fire its own associated Action.
 * The ConclusionAction's Action is the action the user requested
 * in the configuration language.
 */
class FactAction : public Action
{
public:

    /**
     * Construct a new action.
     *
     * @param[in] conclusion The conclusion action that this Fact is
     *            gating the execution of.
     * @param[in] result_idx The index of the result in the result
     *            vector of the ConclusionAction.
     *
     * @note This takes a reference to a boolean because actions may
     *       not modify themselves.
     */
    FactAction(action_ptr conclusion, int result_idx);

private:
    action_ptr  m_conclusion;
    int         m_result_idx;

    /**
     * Apply this action to the transaction.
     *
     * @param[in] config Module configuration.
     * @param[in] mdata The module.
     * @param[in] tx The current transaction.
     */
    virtual void apply_impl(
        const XRulesModuleConfig& config,
        xrules_module_tx_data_ptr mdata,
        IronBee::Transaction      tx
    ) const;
};

FactAction::FactAction(action_ptr conclusion, int result_idx) :
    Action(random_name(), 10),
    m_conclusion(conclusion),
    m_result_idx(result_idx)
{}

void FactAction::apply_impl(
    const XRulesModuleConfig& config,
    xrules_module_tx_data_ptr mdata,
    IronBee::Transaction      tx
) const
{
    /* Update the results. */
    static_cast<ConclusionAction&>(*m_conclusion).
        result(*mdata, m_result_idx) = 1;

    /* Having updated the results, try the conclusion. */
    (*m_conclusion)(config, mdata, tx);
}

} /* Anonymous Namespace */

void XRuleException::xrule_directive(
    XRulesModule                     module,
    IronBee::ConfigurationParser     cp,
    const char *                     name,
    IronBee::ConstList<const char *> all_params
)
{
    IronBee::Context    ctx = cp.current_context();
    XRulesModuleConfig& cfg =
        module.module().configuration_data<XRulesModuleConfig>(ctx);

    /* The unparsed bits from parsing an action out of the params arg. */
    IronBee::List<const char *> params =
        IronBee::List<const char *>::create(cp.memory_manager());

    /* Parse the action and put the remaining tokens in `params`. */
    action_ptr user_action = module.parse_action(cp, all_params, params);

    /* Construct a conclusion action that will fire the user's action. */
    action_ptr conclusion(
        boost::make_shared<ConclusionAction>(
            user_action,
            params.size()));

    /* The conclusion action will log. The user action does not. */
    user_action->logevent_msg() =
        std::string("Exception matched: ") +
        user_action->logevent_msg();
    user_action->logevent_tag() = user_action->logevent_tag();

    conclusion->logevent_msg() = "";
    conclusion->logevent_tag() = "";

    if (params.empty()) {
        BOOST_THROW_EXCEPTION(
            IronBee::einval()
                << IronBee::errinfo_what(
                    "XRuleException require at least 1 argument.")
        );
    }

    int result_idx = 0;
    BOOST_FOREACH(const char* param, params) {
        const char* val;

        /* Build a new FactAction to
         * - Set the result `result_idx` to 1.
         * - Fire the conclusion action. */
        action_ptr action(
            boost::make_shared<FactAction>(
                conclusion,
                result_idx));

        ++result_idx;

        if (IB_OK == parse_arg("EventTag:", param, &val)) {
            IronBee::List<const char *> l =
                IronBee::List<const char *>::create(cp.memory_manager());
            l.push_back(val);
            action->logevent_msg() =
                std::string("EventTag ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/tags";
            cfg.event_xrules.push_back(
                xrule_ptr(
                    new XRuleEventTag(l, action)));
        }
        else if (IB_OK == parse_arg("IPv4:", param, &val)) {
            // Copy in an empty, uninitialized ipset entry.
            ib_ipset4_entry_t entry;

            memset(&entry, 0, sizeof(entry));

            val = XRuleIP::normalize_ipv4(cp.memory_manager(), val);

            IronBee::throw_if_error(
                ib_ip4_str_to_net(val, &(entry.network)),
                (std::string("Failed to get net from string: ")+val).c_str()
            );

            action->logevent_msg() =
                std::string("IPv4 ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/ipv4";

            // Put that action in the ip set.
            entry.data = IronBee::value_to_data<action_ptr>(
                action,
                cp.engine().main_memory_mm().ib());

            cfg.ipv4_list.push_back(entry);
        }
        else if (IB_OK == parse_arg("IPv6:", param, &val)) {
            // Copy in an empty, uninitialized ipset entry.
            ib_ipset6_entry_t entry;

            memset(&entry, 0, sizeof(entry));

            val = XRuleIP::normalize_ipv6(cp.memory_manager(), val);

            IronBee::throw_if_error(
                ib_ip6_str_to_net(val, &(entry.network)),
                (std::string("Failed to get net from string: ")+val).c_str()
            );

            action->logevent_msg() =
                std::string("IPv6 ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/ipv6";

            // Put that action in the ip set.
            entry.data = IronBee::value_to_data<action_ptr>(
                action,
                cp.engine().main_memory_mm().ib());

            cfg.ipv6_list.push_back(entry);
        }
        else if (IB_OK == parse_arg("Geo:", param, &val)) {
            action->logevent_msg() =
                std::string("Geo ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/geo";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleGeo(val, action)));
        }
        else if (IB_OK == parse_arg("Path:", param, &val)) {
            action->logevent_msg() =
                std::string("Path ") +
                val +
                " matched";
            action->logevent_tag() = "xrules/path";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRulePath(val, action)));
        }
        else if (IB_OK == parse_arg("Param:", param, &val)) {
            action->logevent_msg() = std::string("Param ") + val + " matched";
            action->logevent_tag() = "xrule/param";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleParam(val, cp.engine(), action)));
        }
        else if (IB_OK == parse_arg("Cookie:", param, &val)) {
            action->logevent_msg() = std::string("Cookie ") + val + " matched";
            action->logevent_tag() = "xrule/cookie";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleCookie(val, cp.engine(), action)));
        }
        else if (IB_OK == parse_arg("RequestHeader:", param, &val)) {
            action->logevent_msg() =
                std::string("RequestHeader ") + val + " matched";
            action->logevent_tag() = "xrule/requestheader";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleRequestHeader(val, action)));
        }
        else if (IB_OK == parse_arg("Method:", param, &val)) {
            action->logevent_msg() = std::string("Method ") + val + " matched";
            action->logevent_tag() = "xrule/method";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleMethod(val, action)));
        }
        else if (IB_OK == parse_arg("Hostname:", param, &val)) {
            action->logevent_msg() = std::string("Hostname ") + val + " matched";
            action->logevent_tag() = "xrule/hostname";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleHostname(val, action)));
        }
        else if (IB_OK == parse_arg("RequestContentType", param, &val)) {
            action->logevent_msg() =
                std::string("RequestContentType ") + val + " matched";
            action->logevent_tag() = "xrule/content_type/request";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleContentType(val, action,
                        "request_headers:Content-Type",
                        "request_headers:Content-Length",
                        "request_headers:Transport-Encoding")));
        }
        else if (IB_OK == parse_arg("Time", param, &val)) {
            action->logevent_msg() = std::string("Time ") + val + " matched";
            action->logevent_tag() = "xrule/time";
            cfg.req_xrules.push_back(
                xrule_ptr(
                    new XRuleTime(cp, val, action)));
        }
        else {
            BOOST_THROW_EXCEPTION(
                IronBee::enoent()
                    << IronBee::errinfo_what(
                        std::string("Unknown XRuleException: ")+param)
            );
        }
    }
}
<|endoftext|>