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

#include "chrome/browser/ui/views/extensions/extension_dialog.h"

#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
#include "chrome/browser/ui/views/window.h"  // CreateViewsWindow
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "googleurl/src/gurl.h"
#include "views/widget/widget.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/frame/bubble_window.h"
#endif

namespace {

views::Widget* CreateWindow(gfx::NativeWindow parent,
                            views::WidgetDelegate* delegate) {
#if defined(OS_CHROMEOS)
  // On Chrome OS we need to override the style to suppress padding around
  // the borders.
  return chromeos::BubbleWindow::Create(parent,
      chromeos::STYLE_FLUSH, delegate);
#else
  return browser::CreateViewsWindow(parent, delegate);
#endif
}

}  // namespace

ExtensionDialog::ExtensionDialog(ExtensionHost* host,
                                 ExtensionDialogObserver* observer)
    : window_(NULL),
      extension_host_(host),
      observer_(observer) {
  AddRef();  // Balanced in DeleteDelegate();

  // Listen for the containing view calling window.close();
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 Source<Profile>(host->profile()));
}

ExtensionDialog::~ExtensionDialog() {
}

// static
ExtensionDialog* ExtensionDialog::Show(
    const GURL& url,
    Browser* browser,
    TabContents* tab_contents,
    int width,
    int height,
    ExtensionDialogObserver* observer) {
  CHECK(browser);
  ExtensionHost* host = CreateExtensionHost(url, browser);
  if (!host)
    return NULL;
  host->set_associated_tab_contents(tab_contents);

  ExtensionDialog* dialog = new ExtensionDialog(host, observer);
  dialog->InitWindow(browser, width, height);
  // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
  host->render_view_host()->view()->Focus();
  return dialog;
}

// static
ExtensionHost* ExtensionDialog::CreateExtensionHost(const GURL& url,
                                                    Browser* browser) {
  ExtensionProcessManager* manager =
      browser->profile()->GetExtensionProcessManager();
  DCHECK(manager);
  if (!manager)
    return NULL;
  return manager->CreateDialogHost(url, browser);
}

void ExtensionDialog::InitWindow(Browser* browser, int width, int height) {
  gfx::NativeWindow parent = browser->window()->GetNativeHandle();
  window_ = CreateWindow(parent, this /* views::WidgetDelegate */);

  // Center the window over the browser.
  gfx::Point center = browser->window()->GetBounds().CenterPoint();
  int x = center.x() - width / 2;
  int y = center.y() - height / 2;
  window_->SetBounds(gfx::Rect(x, y, width, height));

  window_->Show();
  window_->Activate();
}

void ExtensionDialog::ObserverDestroyed() {
  observer_ = NULL;
}

void ExtensionDialog::Close() {
  if (!window_)
    return;

  if (observer_)
    observer_->ExtensionDialogIsClosing(this);

  window_->Close();
  window_ = NULL;
}

/////////////////////////////////////////////////////////////////////////////
// views::WidgetDelegate overrides.

bool ExtensionDialog::CanResize() const {
  return false;
}

bool ExtensionDialog::IsModal() const {
  return true;
}

bool ExtensionDialog::ShouldShowWindowTitle() const {
  return false;
}

void ExtensionDialog::DeleteDelegate() {
  // The window has finished closing.  Allow ourself to be deleted.
  Release();
}

views::Widget* ExtensionDialog::GetWidget() {
  return extension_host_->view()->GetWidget();
}

const views::Widget* ExtensionDialog::GetWidget() const {
  return extension_host_->view()->GetWidget();
}

views::View* ExtensionDialog::GetContentsView() {
  return extension_host_->view();
}

/////////////////////////////////////////////////////////////////////////////
// NotificationObserver overrides.

void ExtensionDialog::Observe(int type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
      // If we aren't the host of the popup, then disregard the notification.
      if (Details<ExtensionHost>(host()) != details)
        return;
      Close();
      break;
    default:
      NOTREACHED() << L"Received unexpected notification";
      break;
  }
}
<commit_msg>Aura: Fix crash when opening CrOS file picker<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/extensions/extension_dialog.h"

#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
#include "chrome/browser/ui/views/window.h"  // CreateViewsWindow
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "googleurl/src/gurl.h"
#include "views/widget/widget.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/frame/bubble_window.h"
#endif

namespace {

views::Widget* CreateWindow(gfx::NativeWindow parent,
                            views::WidgetDelegate* delegate) {
#if defined(OS_CHROMEOS) && defined(TOOLKIT_USES_GTK)
  // TODO(msw): revert to BubbleWindow for all ChromeOS cases when CL
  // for crbug.com/98322 is landed.
  // On Chrome OS we need to override the style to suppress padding around
  // the borders.
  return chromeos::BubbleWindow::Create(parent,
      chromeos::STYLE_FLUSH, delegate);
#else
  return browser::CreateViewsWindow(parent, delegate);
#endif
}

}  // namespace

ExtensionDialog::ExtensionDialog(ExtensionHost* host,
                                 ExtensionDialogObserver* observer)
    : window_(NULL),
      extension_host_(host),
      observer_(observer) {
  AddRef();  // Balanced in DeleteDelegate();

  // Listen for the containing view calling window.close();
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 Source<Profile>(host->profile()));
}

ExtensionDialog::~ExtensionDialog() {
}

// static
ExtensionDialog* ExtensionDialog::Show(
    const GURL& url,
    Browser* browser,
    TabContents* tab_contents,
    int width,
    int height,
    ExtensionDialogObserver* observer) {
  CHECK(browser);
  ExtensionHost* host = CreateExtensionHost(url, browser);
  if (!host)
    return NULL;
  host->set_associated_tab_contents(tab_contents);

  ExtensionDialog* dialog = new ExtensionDialog(host, observer);
  dialog->InitWindow(browser, width, height);
  // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
  host->render_view_host()->view()->Focus();
  return dialog;
}

// static
ExtensionHost* ExtensionDialog::CreateExtensionHost(const GURL& url,
                                                    Browser* browser) {
  ExtensionProcessManager* manager =
      browser->profile()->GetExtensionProcessManager();
  DCHECK(manager);
  if (!manager)
    return NULL;
  return manager->CreateDialogHost(url, browser);
}

void ExtensionDialog::InitWindow(Browser* browser, int width, int height) {
  gfx::NativeWindow parent = browser->window()->GetNativeHandle();
  window_ = CreateWindow(parent, this /* views::WidgetDelegate */);

  // Center the window over the browser.
  gfx::Point center = browser->window()->GetBounds().CenterPoint();
  int x = center.x() - width / 2;
  int y = center.y() - height / 2;
  window_->SetBounds(gfx::Rect(x, y, width, height));

  window_->Show();
  window_->Activate();
}

void ExtensionDialog::ObserverDestroyed() {
  observer_ = NULL;
}

void ExtensionDialog::Close() {
  if (!window_)
    return;

  if (observer_)
    observer_->ExtensionDialogIsClosing(this);

  window_->Close();
  window_ = NULL;
}

/////////////////////////////////////////////////////////////////////////////
// views::WidgetDelegate overrides.

bool ExtensionDialog::CanResize() const {
  return false;
}

bool ExtensionDialog::IsModal() const {
  return true;
}

bool ExtensionDialog::ShouldShowWindowTitle() const {
  return false;
}

void ExtensionDialog::DeleteDelegate() {
  // The window has finished closing.  Allow ourself to be deleted.
  Release();
}

views::Widget* ExtensionDialog::GetWidget() {
  return extension_host_->view()->GetWidget();
}

const views::Widget* ExtensionDialog::GetWidget() const {
  return extension_host_->view()->GetWidget();
}

views::View* ExtensionDialog::GetContentsView() {
  return extension_host_->view();
}

/////////////////////////////////////////////////////////////////////////////
// NotificationObserver overrides.

void ExtensionDialog::Observe(int type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
      // If we aren't the host of the popup, then disregard the notification.
      if (Details<ExtensionHost>(host()) != details)
        return;
      Close();
      break;
    default:
      NOTREACHED() << L"Received unexpected notification";
      break;
  }
}
<|endoftext|>


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

#include "chromecast/browser/devtools/remote_debugging_server.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/strings/stringprintf.h"
#include "chromecast/browser/devtools/cast_dev_tools_delegate.h"
#include "chromecast/common/chromecast_config.h"
#include "chromecast/common/pref_names.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/user_agent.h"
#include "net/socket/tcp_server_socket.h"

#if defined(OS_ANDROID)
#include "content/public/browser/android/devtools_auth.h"
#include "net/socket/unix_domain_server_socket_posix.h"
#endif  // defined(OS_ANDROID)

namespace chromecast {
namespace shell {

namespace {

const char kFrontEndURL[] =
    "https://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
const int kDefaultRemoteDebuggingPort = 9222;

#if defined(OS_ANDROID)
class UnixDomainServerSocketFactory
    : public content::DevToolsHttpHandler::ServerSocketFactory {
 public:
  explicit UnixDomainServerSocketFactory(const std::string& socket_name)
      : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1) {}

 private:
  // content::DevToolsHttpHandler::ServerSocketFactory.
  virtual scoped_ptr<net::ServerSocket> Create() const override {
    return scoped_ptr<net::ServerSocket>(
        new net::UnixDomainServerSocket(
            base::Bind(&content::CanUserConnectToDevTools),
            true /* use_abstract_namespace */));
  }

  DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
};
#else
class TCPServerSocketFactory
    : public content::DevToolsHttpHandler::ServerSocketFactory {
 public:
  TCPServerSocketFactory(const std::string& address, int port, int backlog)
      : content::DevToolsHttpHandler::ServerSocketFactory(
            address, port, backlog) {}

 private:
  // content::DevToolsHttpHandler::ServerSocketFactory.
  virtual scoped_ptr<net::ServerSocket> Create() const override {
    return scoped_ptr<net::ServerSocket>(
        new net::TCPServerSocket(NULL, net::NetLog::Source()));
  }

  DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
};
#endif

scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>
CreateSocketFactory(int port) {
#if defined(OS_ANDROID)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  std::string socket_name = "cast_shell_devtools_remote";
  if (command_line->HasSwitch(switches::kRemoteDebuggingSocketName)) {
    socket_name = command_line->GetSwitchValueASCII(
        switches::kRemoteDebuggingSocketName);
  }
  return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
      new UnixDomainServerSocketFactory(socket_name));
#else
  return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
      new TCPServerSocketFactory("0.0.0.0", port, 1));
#endif
}

std::string GetFrontendUrl() {
  return base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str());
}

}  // namespace

RemoteDebuggingServer::RemoteDebuggingServer()
    : devtools_http_handler_(NULL),
      port_(0) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  pref_port_.Init(prefs::kRemoteDebuggingPort,
                  ChromecastConfig::GetInstance()->pref_service(),
                  base::Bind(&RemoteDebuggingServer::OnPortChanged,
                             base::Unretained(this)));

  // Starts new dev tools, clearing port number saved in config.
  // Remote debugging in production must be triggered only by config server.
  pref_port_.SetValue(ShouldStartImmediately() ?
                      kDefaultRemoteDebuggingPort : 0);
  OnPortChanged();
}

RemoteDebuggingServer::~RemoteDebuggingServer() {
  pref_port_.SetValue(0);
  OnPortChanged();
}

void RemoteDebuggingServer::OnPortChanged() {
  int new_port = *pref_port_;
  if (new_port < 0) {
    new_port = 0;
  }
  VLOG(1) << "OnPortChanged called: old_port=" << port_
          << ", new_port=" << new_port;

  if (new_port == port_) {
    VLOG(1) << "Port has not been changed. Ignore silently.";
    return;
  }

  if (devtools_http_handler_) {
    LOG(INFO) << "Stop old devtools: port=" << port_;
    devtools_http_handler_.reset();
  }

  port_ = new_port;
  if (port_ > 0) {
    devtools_http_handler_.reset(content::DevToolsHttpHandler::Start(
        CreateSocketFactory(port_),
        GetFrontendUrl(),
        new CastDevToolsDelegate(),
        base::FilePath()));
    LOG(INFO) << "Devtools started: port=" << port_;
  }
}

}  // namespace shell
}  // namespace chromecast
<commit_msg>Chromecast buildfix: scoped_ptr cannot be initialized with NULL.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromecast/browser/devtools/remote_debugging_server.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/strings/stringprintf.h"
#include "chromecast/browser/devtools/cast_dev_tools_delegate.h"
#include "chromecast/common/chromecast_config.h"
#include "chromecast/common/pref_names.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/user_agent.h"
#include "net/socket/tcp_server_socket.h"

#if defined(OS_ANDROID)
#include "content/public/browser/android/devtools_auth.h"
#include "net/socket/unix_domain_server_socket_posix.h"
#endif  // defined(OS_ANDROID)

namespace chromecast {
namespace shell {

namespace {

const char kFrontEndURL[] =
    "https://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
const int kDefaultRemoteDebuggingPort = 9222;

#if defined(OS_ANDROID)
class UnixDomainServerSocketFactory
    : public content::DevToolsHttpHandler::ServerSocketFactory {
 public:
  explicit UnixDomainServerSocketFactory(const std::string& socket_name)
      : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1) {}

 private:
  // content::DevToolsHttpHandler::ServerSocketFactory.
  virtual scoped_ptr<net::ServerSocket> Create() const override {
    return scoped_ptr<net::ServerSocket>(
        new net::UnixDomainServerSocket(
            base::Bind(&content::CanUserConnectToDevTools),
            true /* use_abstract_namespace */));
  }

  DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
};
#else
class TCPServerSocketFactory
    : public content::DevToolsHttpHandler::ServerSocketFactory {
 public:
  TCPServerSocketFactory(const std::string& address, int port, int backlog)
      : content::DevToolsHttpHandler::ServerSocketFactory(
            address, port, backlog) {}

 private:
  // content::DevToolsHttpHandler::ServerSocketFactory.
  virtual scoped_ptr<net::ServerSocket> Create() const override {
    return scoped_ptr<net::ServerSocket>(
        new net::TCPServerSocket(NULL, net::NetLog::Source()));
  }

  DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
};
#endif

scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>
CreateSocketFactory(int port) {
#if defined(OS_ANDROID)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  std::string socket_name = "cast_shell_devtools_remote";
  if (command_line->HasSwitch(switches::kRemoteDebuggingSocketName)) {
    socket_name = command_line->GetSwitchValueASCII(
        switches::kRemoteDebuggingSocketName);
  }
  return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
      new UnixDomainServerSocketFactory(socket_name));
#else
  return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
      new TCPServerSocketFactory("0.0.0.0", port, 1));
#endif
}

std::string GetFrontendUrl() {
  return base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str());
}

}  // namespace

RemoteDebuggingServer::RemoteDebuggingServer() : port_(0) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  pref_port_.Init(prefs::kRemoteDebuggingPort,
                  ChromecastConfig::GetInstance()->pref_service(),
                  base::Bind(&RemoteDebuggingServer::OnPortChanged,
                             base::Unretained(this)));

  // Starts new dev tools, clearing port number saved in config.
  // Remote debugging in production must be triggered only by config server.
  pref_port_.SetValue(ShouldStartImmediately() ?
                      kDefaultRemoteDebuggingPort : 0);
  OnPortChanged();
}

RemoteDebuggingServer::~RemoteDebuggingServer() {
  pref_port_.SetValue(0);
  OnPortChanged();
}

void RemoteDebuggingServer::OnPortChanged() {
  int new_port = *pref_port_;
  if (new_port < 0) {
    new_port = 0;
  }
  VLOG(1) << "OnPortChanged called: old_port=" << port_
          << ", new_port=" << new_port;

  if (new_port == port_) {
    VLOG(1) << "Port has not been changed. Ignore silently.";
    return;
  }

  if (devtools_http_handler_) {
    LOG(INFO) << "Stop old devtools: port=" << port_;
    devtools_http_handler_.reset();
  }

  port_ = new_port;
  if (port_ > 0) {
    devtools_http_handler_.reset(content::DevToolsHttpHandler::Start(
        CreateSocketFactory(port_),
        GetFrontendUrl(),
        new CastDevToolsDelegate(),
        base::FilePath()));
    LOG(INFO) << "Devtools started: port=" << port_;
  }
}

}  // namespace shell
}  // namespace chromecast
<|endoftext|>


<commit_before>#ifndef WF_SAFE_LIST_HPP
#define WF_SAFE_LIST_HPP

#include <list>
#include <memory>
#include <algorithm>
#include <functional>

#include <wayland-server.h>

#include "reverse.hpp"

/* This is a trimmed-down wrapper of std::list<T>.
 *
 * It supports safe iteration over all elements in the collection, where any
 * element can be deleted from the list at any given time (i.e even in a
 * for-each-like loop) */
namespace wf
{
    /* The object type depends on the safe list type, and the safe list type
     * needs access to the event loop. However, the event loop is typically
     * available from core.hpp. Because we can't resolve this circular dependency,
     * we provide a link to the event loop specially for the safe list */
    namespace _safe_list_detail
    {
        /* In main.cpp, and initialized there */
        extern wl_event_loop* event_loop;
        void idle_cleanup_func(void *data);
    }

    template<class T>
    class safe_list_t
    {
        std::list<std::unique_ptr<T>> list;
        wl_event_source *idle_cleanup_source = NULL;

        /* Remove all invalidated elements in the list */
        std::function<void()> do_cleanup = [&] ()
        {
            auto it = list.begin();
            while (it != list.end())
            {
                if (*it) {
                    ++it;
                } else {
                    it = list.erase(it);
                }
            }

            idle_cleanup_source = NULL;
        };

        /* Return whether the list has invalidated elements */
        bool is_dirty() const
        {
            return idle_cleanup_source;
        }

        public:
        safe_list_t() {};

        /* Copy the not-erased elements from other, but do not copy the idle source */
        safe_list_t(const safe_list_t& other) { *this = other; }
        safe_list_t& operator = (const safe_list_t& other)
        {
            this->idle_cleanup_source = NULL;
            other.for_each([&] (auto& el) {
                this->push_back(el);
            });
        }

        safe_list_t(safe_list_t&& other) = default;
        safe_list_t& operator = (safe_list_t&& other) = default;

        ~safe_list_t()
        {
            if (idle_cleanup_source)
                wl_event_source_remove(idle_cleanup_source);
        }

        T& back()
        {
            /* No invalidated elements */
            if (!is_dirty())
                return *list.back();

            auto it = list.rbegin();
            while (it != list.rend() && (*it) == nullptr)
                ++it;

            if (it == list.rend())
                throw std::out_of_range("back() called on an empty list!");

            return **it;
        }

        size_t size() const
        {
            if (!is_dirty())
                return list.size();

            /* Count non-null elements, because that's the real size */
            size_t sz = 0;
            for (auto& it : list)
                sz += (it != nullptr);

            return sz;
        }

        /* Push back by copying */
        void push_back(T value)
        {
            list.push_back(std::make_unique<T> (std::move(value)));
        }

        /* Push back by moving */
        void emplace_back(T&& value)
        {
            list.push_back(std::make_unique<T> (value));
        }

        enum insert_place_t
        {
            INSERT_BEFORE,
            INSERT_AFTER,
            INSERT_NONE,
        };

        /* Insert the given value at a position in the list, determined by the
         * check function. The value is inserted at the first position that
         * check indicates, or at the end of the list otherwise */
        void emplace_at(T&& value, std::function<insert_place_t(T&)> check)
        {
            auto it = list.begin();
            while (it != list.end())
            {
                /* Skip empty elements */
                if (*it == nullptr)
                {
                    ++it;
                    continue;
                }

                auto place = check(**it);
                switch (place)
                {
                    case INSERT_AFTER:
                        /* We can safely increment it, because it points to an
                         * element in the list */
                        ++it;
                        // fall through
                    case INSERT_BEFORE:
                        list.emplace(it, std::make_unique<T>(value));
                        return;

                    default:
                        break;
                }

                ++it;
            }

            /* If no place found, insert at the end */
            emplace_back(std::move(value));
        }

        void insert_at(T value, std::function<insert_place_t(T&)> check)
        {
            emplace_at(std::move(value), check);
        }

        /* Call func for each non-erased element of the list */
        void for_each(std::function<void(T&)> func) const
        {
            for (auto& el : list)
            {
                /* The for-each loop here is safe, because no elements will be
                 * erased util the event loop goes idle */
                if (el)
                    func(*el);
            }
        }

        /* Call func for each non-erased element of the list in reversed order */
        void for_each_reverse(std::function<void(T&)> func) const
        {
            for (auto& el : wf::reverse(list))
            {
                /* The loop here is safe, because no elements will be erased
                 * util the event loop goes idle */
                if (el)
                    func(*el);
            }
        }

        /* Safely remove all elements equal to value */
        void remove_all(const T& value)
        {
            remove_if([=] (const T& el) { return el == value; });
        }

        /* Remove all elements satisfying a given condition.
         * This function resets their pointers and scheduling a cleanup operation */
        void remove_if(std::function<bool(const T&)> predicate)
        {
            bool actually_removed = false;
            for (auto& it : list)
            {
                if (it && predicate(*it))
                {
                    actually_removed = true;
                    /* First reset the element in the list, and then free resources */
                    auto copy = std::move(it);
                    it = nullptr;
                    /* Now copy goes out of scope */
                }
            }

            /* Schedule a clean-up, but be careful to not schedule it twice */
            if (!idle_cleanup_source && actually_removed)
            {
                idle_cleanup_source = wl_event_loop_add_idle(_safe_list_detail::event_loop,
                    _safe_list_detail::idle_cleanup_func, &do_cleanup);
            }
        }
    };
}

#endif /* end of include guard: WF_SAFE_LIST_HPP */
<commit_msg>safe-list: iterate only on already-available elements in for_each<commit_after>#ifndef WF_SAFE_LIST_HPP
#define WF_SAFE_LIST_HPP

#include <list>
#include <memory>
#include <algorithm>
#include <functional>

#include <wayland-server.h>

#include "reverse.hpp"

/* This is a trimmed-down wrapper of std::list<T>.
 *
 * It supports safe iteration over all elements in the collection, where any
 * element can be deleted from the list at any given time (i.e even in a
 * for-each-like loop) */
namespace wf
{
    /* The object type depends on the safe list type, and the safe list type
     * needs access to the event loop. However, the event loop is typically
     * available from core.hpp. Because we can't resolve this circular dependency,
     * we provide a link to the event loop specially for the safe list */
    namespace _safe_list_detail
    {
        /* In main.cpp, and initialized there */
        extern wl_event_loop* event_loop;
        void idle_cleanup_func(void *data);
    }

    template<class T>
    class safe_list_t
    {
        std::list<std::unique_ptr<T>> list;
        wl_event_source *idle_cleanup_source = NULL;

        /* Remove all invalidated elements in the list */
        std::function<void()> do_cleanup = [&] ()
        {
            auto it = list.begin();
            while (it != list.end())
            {
                if (*it) {
                    ++it;
                } else {
                    it = list.erase(it);
                }
            }

            idle_cleanup_source = NULL;
        };

        /* Return whether the list has invalidated elements */
        bool is_dirty() const
        {
            return idle_cleanup_source;
        }

        public:
        safe_list_t() {};

        /* Copy the not-erased elements from other, but do not copy the idle source */
        safe_list_t(const safe_list_t& other) { *this = other; }
        safe_list_t& operator = (const safe_list_t& other)
        {
            this->idle_cleanup_source = NULL;
            other.for_each([&] (auto& el) {
                this->push_back(el);
            });
        }

        safe_list_t(safe_list_t&& other) = default;
        safe_list_t& operator = (safe_list_t&& other) = default;

        ~safe_list_t()
        {
            if (idle_cleanup_source)
                wl_event_source_remove(idle_cleanup_source);
        }

        T& back()
        {
            /* No invalidated elements */
            if (!is_dirty())
                return *list.back();

            auto it = list.rbegin();
            while (it != list.rend() && (*it) == nullptr)
                ++it;

            if (it == list.rend())
                throw std::out_of_range("back() called on an empty list!");

            return **it;
        }

        size_t size() const
        {
            if (!is_dirty())
                return list.size();

            /* Count non-null elements, because that's the real size */
            size_t sz = 0;
            for (auto& it : list)
                sz += (it != nullptr);

            return sz;
        }

        /* Push back by copying */
        void push_back(T value)
        {
            list.push_back(std::make_unique<T> (std::move(value)));
        }

        /* Push back by moving */
        void emplace_back(T&& value)
        {
            list.push_back(std::make_unique<T> (value));
        }

        enum insert_place_t
        {
            INSERT_BEFORE,
            INSERT_AFTER,
            INSERT_NONE,
        };

        /* Insert the given value at a position in the list, determined by the
         * check function. The value is inserted at the first position that
         * check indicates, or at the end of the list otherwise */
        void emplace_at(T&& value, std::function<insert_place_t(T&)> check)
        {
            auto it = list.begin();
            while (it != list.end())
            {
                /* Skip empty elements */
                if (*it == nullptr)
                {
                    ++it;
                    continue;
                }

                auto place = check(**it);
                switch (place)
                {
                    case INSERT_AFTER:
                        /* We can safely increment it, because it points to an
                         * element in the list */
                        ++it;
                        // fall through
                    case INSERT_BEFORE:
                        list.emplace(it, std::make_unique<T>(value));
                        return;

                    default:
                        break;
                }

                ++it;
            }

            /* If no place found, insert at the end */
            emplace_back(std::move(value));
        }

        void insert_at(T value, std::function<insert_place_t(T&)> check)
        {
            emplace_at(std::move(value), check);
        }

        /* Call func for each non-erased element of the list */
        void for_each(std::function<void(T&)> func) const
        {
            /* Go through all elements currently in the list */
            auto it = list.begin();
            for (int size = list.size(); size > 0; size--, it++)
            {
                if (*it)
                    func(**it);
            }
        }

        /* Call func for each non-erased element of the list in reversed order */
        void for_each_reverse(std::function<void(T&)> func) const
        {
            auto it = list.rbegin();
            for (int size = list.size(); size > 0; size--, it++)
            {
                if (*it)
                    func(**it);
            }
        }

        /* Safely remove all elements equal to value */
        void remove_all(const T& value)
        {
            remove_if([=] (const T& el) { return el == value; });
        }

        /* Remove all elements satisfying a given condition.
         * This function resets their pointers and scheduling a cleanup operation */
        void remove_if(std::function<bool(const T&)> predicate)
        {
            bool actually_removed = false;
            for (auto& it : list)
            {
                if (it && predicate(*it))
                {
                    actually_removed = true;
                    /* First reset the element in the list, and then free resources */
                    auto copy = std::move(it);
                    it = nullptr;
                    /* Now copy goes out of scope */
                }
            }

            /* Schedule a clean-up, but be careful to not schedule it twice */
            if (!idle_cleanup_source && actually_removed)
            {
                idle_cleanup_source = wl_event_loop_add_idle(_safe_list_detail::event_loop,
                    _safe_list_detail::idle_cleanup_func, &do_cleanup);
            }
        }
    };
}

#endif /* end of include guard: WF_SAFE_LIST_HPP */
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Ford Motor Company
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of the Ford Motor Company nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/ssl.h>
#include <fcntl.h>
#include <unistd.h>
#include <fstream>

#include "gtest/gtest.h"
#include "security_manager/crypto_manager.h"
#include "security_manager/crypto_manager_impl.h"
#include "security_manager/ssl_context.h"
#include "utils/custom_string.h"

#ifdef __QNXNTO__
#define FORD_CIPHER SSL3_TXT_RSA_DES_192_CBC3_SHA
#else
// Used cipher from ford protocol requirement
#define FORD_CIPHER TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384
#endif

#define ALL_CIPHERS "ALL"

namespace {
const size_t updates_before_hour = 24;
}

namespace test {
namespace components {
namespace ssl_context_test {
namespace custom_str = utils::custom_string;

class SSLTest : public testing::Test {
 protected:
  static void SetUpTestCase() {
    std::ifstream file("server/spt_credential.p12.enc");
    std::stringstream ss;
    ss << file.rdbuf();
    file.close();
    crypto_manager = new security_manager::CryptoManagerImpl();
    const bool crypto_manager_initialization = crypto_manager->Init(
        security_manager::SERVER, security_manager::TLSv1_2, ss.str(),
        FORD_CIPHER, false, "", updates_before_hour);
    EXPECT_TRUE(crypto_manager_initialization);

    client_manager = new security_manager::CryptoManagerImpl();
    const bool client_manager_initialization = client_manager->Init(
        security_manager::CLIENT, security_manager::TLSv1_2, "", FORD_CIPHER,
        false, "", updates_before_hour);
    EXPECT_TRUE(client_manager_initialization);
  }

  static void TearDownTestCase() {
    delete crypto_manager;
    delete client_manager;
  }

  virtual void SetUp() {
    server_ctx = crypto_manager->CreateSSLContext();
    client_ctx = client_manager->CreateSSLContext();

    security_manager::SSLContext::HandshakeContext ctx;
    ctx.make_context("SPT", "client");
    server_ctx->SetHandshakeContext(ctx);

    ctx.expected_cn = "server";
    client_ctx->SetHandshakeContext(ctx);
  }

  virtual void TearDown() {
    crypto_manager->ReleaseSSLContext(server_ctx);
    client_manager->ReleaseSSLContext(client_ctx);
  }

  static security_manager::CryptoManager* crypto_manager;
  static security_manager::CryptoManager* client_manager;
  security_manager::SSLContext* server_ctx;
  security_manager::SSLContext* client_ctx;
};

security_manager::CryptoManager* SSLTest::crypto_manager;
security_manager::CryptoManager* SSLTest::client_manager;

// TODO(EZAMAKHOV): Split to SSL/TLS1/TLS1_1/TLS1_2 tests

TEST_F(SSLTest, BrokenHandshake) {
  const uint8_t* server_buf;
  const uint8_t* client_buf;
  size_t server_buf_len;
  size_t client_buf_len;
  ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
            client_ctx->StartHandshake(&client_buf, &client_buf_len));
  ASSERT_FALSE(client_buf == NULL);
  ASSERT_GT(client_buf_len, 0u);
  // Broke 3 bytes for get abnormal fail of handshake
  const_cast<uint8_t*>(client_buf)[0] ^= 0xFF;
  const_cast<uint8_t*>(client_buf)[client_buf_len / 2] ^= 0xFF;
  const_cast<uint8_t*>(client_buf)[client_buf_len - 1] ^= 0xFF;
  ASSERT_EQ(security_manager::SSLContext::Handshake_Result_AbnormalFail,
            server_ctx->DoHandshakeStep(client_buf, client_buf_len, &server_buf,
                                        &server_buf_len));
}

TEST_F(SSLTest, Positive) {
  const uint8_t* server_buf;
  const uint8_t* client_buf;
  size_t server_buf_len;
  size_t client_buf_len;

  ASSERT_EQ(client_ctx->StartHandshake(&client_buf, &client_buf_len),
            security_manager::SSLContext::Handshake_Result_Success);
  ASSERT_FALSE(client_buf == NULL);
  ASSERT_GT(client_buf_len, 0u);

  for (;;) {
    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              server_ctx->DoHandshakeStep(client_buf, client_buf_len,
                                          &server_buf, &server_buf_len));
    ASSERT_FALSE(server_buf == NULL);
    ASSERT_GT(server_buf_len, 0u);

    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              client_ctx->DoHandshakeStep(server_buf, server_buf_len,
                                          &client_buf, &client_buf_len));
    if (server_ctx->IsInitCompleted()) {
      break;
    }

    ASSERT_FALSE(client_buf == NULL);
    ASSERT_GT(client_buf_len, 0u);
  }
  // Expect empty buffers after init complete
  ASSERT_TRUE(client_buf == NULL);
  ASSERT_EQ(client_buf_len, 0u);
  // expect both side initialization complete
  EXPECT_TRUE(client_ctx->IsInitCompleted());
  EXPECT_TRUE(server_ctx->IsInitCompleted());

  // Encrypt text on client side
  const uint8_t* text = reinterpret_cast<const uint8_t*>("abra");
  const uint8_t* encrypted_text = 0;
  size_t text_len = 4;
  size_t encrypted_text_len;
  EXPECT_TRUE(client_ctx->Encrypt(text, text_len, &encrypted_text,
                                  &encrypted_text_len));

  ASSERT_NE(encrypted_text, reinterpret_cast<void*>(NULL));
  ASSERT_GT(encrypted_text_len, 0u);

  // Decrypt text on server side
  EXPECT_TRUE(server_ctx->Decrypt(encrypted_text, encrypted_text_len, &text,
                                  &text_len));
  ASSERT_NE(text, reinterpret_cast<void*>(NULL));
  ASSERT_GT(text_len, 0u);

  ASSERT_EQ(strncmp(reinterpret_cast<const char*>(text), "abra", 4), 0);
}

TEST_F(SSLTest, EcncryptionFail) {
  const uint8_t* server_buf;
  const uint8_t* client_buf;
  size_t server_buf_len;
  size_t client_buf_len;
  ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
            client_ctx->StartHandshake(&client_buf, &client_buf_len));

  while (!server_ctx->IsInitCompleted()) {
    ASSERT_FALSE(client_buf == NULL);
    ASSERT_GT(client_buf_len, 0u);
    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              server_ctx->DoHandshakeStep(client_buf, client_buf_len,
                                          &server_buf, &server_buf_len));
    ASSERT_FALSE(server_buf == NULL);
    ASSERT_GT(server_buf_len, 0u);

    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              client_ctx->DoHandshakeStep(server_buf, server_buf_len,
                                          &client_buf, &client_buf_len));
  }
  // expect empty buffers after init complete
  ASSERT_TRUE(client_buf == NULL);
  ASSERT_EQ(client_buf_len, 0u);
  // expect both side initialization complete
  EXPECT_TRUE(client_ctx->IsInitCompleted());
  EXPECT_TRUE(server_ctx->IsInitCompleted());

  // Encrypt text on client side
  const uint8_t* text = reinterpret_cast<const uint8_t*>("abra");
  const uint8_t* encrypted_text = 0;
  size_t text_len = 4;
  size_t encrypted_text_len;
  EXPECT_TRUE(client_ctx->Encrypt(text, text_len, &encrypted_text,
                                  &encrypted_text_len));
  ASSERT_NE(encrypted_text, reinterpret_cast<void*>(NULL));
  ASSERT_GT(encrypted_text_len, 0u);

  std::vector<uint8_t> broken(encrypted_text,
                              encrypted_text + encrypted_text_len);
  // Broke message
  broken[encrypted_text_len / 2] ^= 0xFF;

  const uint8_t* out_text;
  size_t out_text_size;
  // Decrypt broken text on server side
  EXPECT_FALSE(server_ctx->Decrypt(&broken[0], broken.size(), &out_text,
                                   &out_text_size));

  // Check after broken message that server encryption and decryption fail
  // Encrypte message on server side
  EXPECT_FALSE(server_ctx->Decrypt(encrypted_text, encrypted_text_len,
                                   &out_text, &out_text_size));
  EXPECT_FALSE(server_ctx->Encrypt(text, text_len, &encrypted_text,
                                   &encrypted_text_len));
}

}  // namespace ssl_context_test
}  // namespace components
}  // namespace test
<commit_msg>Add macro OVERRIDE for virtual methods<commit_after>/*
 * Copyright (c) 2015, Ford Motor Company
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of the Ford Motor Company nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/ssl.h>
#include <fcntl.h>
#include <unistd.h>
#include <fstream>

#include "gtest/gtest.h"
#include "security_manager/crypto_manager.h"
#include "security_manager/crypto_manager_impl.h"
#include "security_manager/ssl_context.h"
#include "utils/custom_string.h"

#ifdef __QNXNTO__
#define FORD_CIPHER SSL3_TXT_RSA_DES_192_CBC3_SHA
#else
// Used cipher from ford protocol requirement
#define FORD_CIPHER TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384
#endif

#define ALL_CIPHERS "ALL"

namespace {
const size_t updates_before_hour = 24;
}

namespace test {
namespace components {
namespace ssl_context_test {
namespace custom_str = utils::custom_string;

class SSLTest : public testing::Test {
 protected:
  static void SetUpTestCase() {
    std::ifstream file("server/spt_credential.p12.enc");
    std::stringstream ss;
    ss << file.rdbuf();
    file.close();
    crypto_manager = new security_manager::CryptoManagerImpl();
    const bool crypto_manager_initialization = crypto_manager->Init(
        security_manager::SERVER, security_manager::TLSv1_2, ss.str(),
        FORD_CIPHER, false, "", updates_before_hour);
    EXPECT_TRUE(crypto_manager_initialization);

    client_manager = new security_manager::CryptoManagerImpl();
    const bool client_manager_initialization = client_manager->Init(
        security_manager::CLIENT, security_manager::TLSv1_2, "", FORD_CIPHER,
        false, "", updates_before_hour);
    EXPECT_TRUE(client_manager_initialization);
  }

  static void TearDownTestCase() {
    delete crypto_manager;
    delete client_manager;
  }

  virtual void SetUp() OVERRIDE {
    server_ctx = crypto_manager->CreateSSLContext();
    client_ctx = client_manager->CreateSSLContext();

    security_manager::SSLContext::HandshakeContext ctx;
    ctx.make_context("SPT", "client");
    server_ctx->SetHandshakeContext(ctx);

    ctx.expected_cn = "server";
    client_ctx->SetHandshakeContext(ctx);
  }

  virtual void TearDown() OVERRIDE {
    crypto_manager->ReleaseSSLContext(server_ctx);
    client_manager->ReleaseSSLContext(client_ctx);
  }

  static security_manager::CryptoManager* crypto_manager;
  static security_manager::CryptoManager* client_manager;
  security_manager::SSLContext* server_ctx;
  security_manager::SSLContext* client_ctx;
};

security_manager::CryptoManager* SSLTest::crypto_manager;
security_manager::CryptoManager* SSLTest::client_manager;

// TODO(EZAMAKHOV): Split to SSL/TLS1/TLS1_1/TLS1_2 tests

TEST_F(SSLTest, BrokenHandshake) {
  const uint8_t* server_buf;
  const uint8_t* client_buf;
  size_t server_buf_len;
  size_t client_buf_len;
  ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
            client_ctx->StartHandshake(&client_buf, &client_buf_len));
  ASSERT_FALSE(client_buf == NULL);
  ASSERT_GT(client_buf_len, 0u);
  // Broke 3 bytes for get abnormal fail of handshake
  const_cast<uint8_t*>(client_buf)[0] ^= 0xFF;
  const_cast<uint8_t*>(client_buf)[client_buf_len / 2] ^= 0xFF;
  const_cast<uint8_t*>(client_buf)[client_buf_len - 1] ^= 0xFF;
  ASSERT_EQ(security_manager::SSLContext::Handshake_Result_AbnormalFail,
            server_ctx->DoHandshakeStep(client_buf, client_buf_len, &server_buf,
                                        &server_buf_len));
}

TEST_F(SSLTest, Positive) {
  const uint8_t* server_buf;
  const uint8_t* client_buf;
  size_t server_buf_len;
  size_t client_buf_len;

  ASSERT_EQ(client_ctx->StartHandshake(&client_buf, &client_buf_len),
            security_manager::SSLContext::Handshake_Result_Success);
  ASSERT_FALSE(client_buf == NULL);
  ASSERT_GT(client_buf_len, 0u);

  for (;;) {
    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              server_ctx->DoHandshakeStep(client_buf, client_buf_len,
                                          &server_buf, &server_buf_len));
    ASSERT_FALSE(server_buf == NULL);
    ASSERT_GT(server_buf_len, 0u);

    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              client_ctx->DoHandshakeStep(server_buf, server_buf_len,
                                          &client_buf, &client_buf_len));
    if (server_ctx->IsInitCompleted()) {
      break;
    }

    ASSERT_FALSE(client_buf == NULL);
    ASSERT_GT(client_buf_len, 0u);
  }
  // Expect empty buffers after init complete
  ASSERT_TRUE(client_buf == NULL);
  ASSERT_EQ(client_buf_len, 0u);
  // expect both side initialization complete
  EXPECT_TRUE(client_ctx->IsInitCompleted());
  EXPECT_TRUE(server_ctx->IsInitCompleted());

  // Encrypt text on client side
  const uint8_t* text = reinterpret_cast<const uint8_t*>("abra");
  const uint8_t* encrypted_text = 0;
  size_t text_len = 4;
  size_t encrypted_text_len;
  EXPECT_TRUE(client_ctx->Encrypt(text, text_len, &encrypted_text,
                                  &encrypted_text_len));

  ASSERT_NE(encrypted_text, reinterpret_cast<void*>(NULL));
  ASSERT_GT(encrypted_text_len, 0u);

  // Decrypt text on server side
  EXPECT_TRUE(server_ctx->Decrypt(encrypted_text, encrypted_text_len, &text,
                                  &text_len));
  ASSERT_NE(text, reinterpret_cast<void*>(NULL));
  ASSERT_GT(text_len, 0u);

  ASSERT_EQ(strncmp(reinterpret_cast<const char*>(text), "abra", 4), 0);
}

TEST_F(SSLTest, EcncryptionFail) {
  const uint8_t* server_buf;
  const uint8_t* client_buf;
  size_t server_buf_len;
  size_t client_buf_len;
  ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
            client_ctx->StartHandshake(&client_buf, &client_buf_len));

  while (!server_ctx->IsInitCompleted()) {
    ASSERT_FALSE(client_buf == NULL);
    ASSERT_GT(client_buf_len, 0u);
    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              server_ctx->DoHandshakeStep(client_buf, client_buf_len,
                                          &server_buf, &server_buf_len));
    ASSERT_FALSE(server_buf == NULL);
    ASSERT_GT(server_buf_len, 0u);

    ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
              client_ctx->DoHandshakeStep(server_buf, server_buf_len,
                                          &client_buf, &client_buf_len));
  }
  // expect empty buffers after init complete
  ASSERT_TRUE(client_buf == NULL);
  ASSERT_EQ(client_buf_len, 0u);
  // expect both side initialization complete
  EXPECT_TRUE(client_ctx->IsInitCompleted());
  EXPECT_TRUE(server_ctx->IsInitCompleted());

  // Encrypt text on client side
  const uint8_t* text = reinterpret_cast<const uint8_t*>("abra");
  const uint8_t* encrypted_text = 0;
  size_t text_len = 4;
  size_t encrypted_text_len;
  EXPECT_TRUE(client_ctx->Encrypt(text, text_len, &encrypted_text,
                                  &encrypted_text_len));
  ASSERT_NE(encrypted_text, reinterpret_cast<void*>(NULL));
  ASSERT_GT(encrypted_text_len, 0u);

  std::vector<uint8_t> broken(encrypted_text,
                              encrypted_text + encrypted_text_len);
  // Broke message
  broken[encrypted_text_len / 2] ^= 0xFF;

  const uint8_t* out_text;
  size_t out_text_size;
  // Decrypt broken text on server side
  EXPECT_FALSE(server_ctx->Decrypt(&broken[0], broken.size(), &out_text,
                                   &out_text_size));

  // Check after broken message that server encryption and decryption fail
  // Encrypte message on server side
  EXPECT_FALSE(server_ctx->Decrypt(encrypted_text, encrypted_text_len,
                                   &out_text, &out_text_size));
  EXPECT_FALSE(server_ctx->Encrypt(text, text_len, &encrypted_text,
                                   &encrypted_text_len));
}

}  // namespace ssl_context_test
}  // namespace components
}  // namespace test
<|endoftext|>


<commit_before>/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/gpu/GrContext.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrSkSLFPFactoryCache.h"

/**
 * The DDL Context is the one in effect during DDL Recording. It isn't backed by a GrGPU and
 * cannot allocate any GPU resources.
 */
class GrDDLContext : public GrContext {
public:
    GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy)
            : INHERITED(proxy->backend(), proxy->priv().options(), proxy->priv().contextID()) {
        fThreadSafeProxy = std::move(proxy);
    }

    ~GrDDLContext() final { }

    void abandonContext() final {
        SkASSERT(0); // abandoning in a DDL Recorder doesn't make a whole lot of sense
        INHERITED::abandonContext();
    }

    void releaseResourcesAndAbandonContext() final {
        SkASSERT(0); // abandoning in a DDL Recorder doesn't make a whole lot of sense
        INHERITED::releaseResourcesAndAbandonContext();
    }

    void freeGpuResources() final {
        SkASSERT(0); // freeing resources in a DDL Recorder doesn't make a whole lot of sense
        INHERITED::freeGpuResources();
    }

private:
    // TODO: Here we're pretending this isn't derived from GrContext. Switch this to be derived from
    // GrRecordingContext!
    GrContext* asDirectContext() final { return nullptr; }

    bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) final {
        SkASSERT(caps && FPFactoryCache);
        SkASSERT(fThreadSafeProxy); // should've been set in the ctor

        if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
            return false;
        }

        // DDL contexts/drawing managers always sort the oplists and attempt to reduce opsTask
        // splitting.
        this->setupDrawingManager(true, true);

        SkASSERT(this->caps());

        return true;
    }

    GrAtlasManager* onGetAtlasManager() final {
        SkASSERT(0);   // the DDL Recorders should never invoke this
        return nullptr;
    }

    typedef GrContext INHERITED;
};

sk_sp<GrContext> GrContextPriv::MakeDDL(const sk_sp<GrContextThreadSafeProxy>& proxy) {
    sk_sp<GrContext> context(new GrDDLContext(proxy));

    if (!context->init(proxy->priv().refCaps(), proxy->priv().fpFactoryCache())) {
        return nullptr;
    }
    return context;
}
<commit_msg>Fix warning in Fuchsia build<commit_after>/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/gpu/GrContext.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrSkSLFPFactoryCache.h"

/**
 * The DDL Context is the one in effect during DDL Recording. It isn't backed by a GrGPU and
 * cannot allocate any GPU resources.
 */
class GrDDLContext final : public GrContext {
public:
    GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy)
            : INHERITED(proxy->backend(), proxy->priv().options(), proxy->priv().contextID()) {
        fThreadSafeProxy = std::move(proxy);
    }

    ~GrDDLContext() final { }

    void abandonContext() final {
        SkASSERT(0); // abandoning in a DDL Recorder doesn't make a whole lot of sense
        INHERITED::abandonContext();
    }

    void releaseResourcesAndAbandonContext() final {
        SkASSERT(0); // abandoning in a DDL Recorder doesn't make a whole lot of sense
        INHERITED::releaseResourcesAndAbandonContext();
    }

    void freeGpuResources() final {
        SkASSERT(0); // freeing resources in a DDL Recorder doesn't make a whole lot of sense
        INHERITED::freeGpuResources();
    }

private:
    // TODO: Here we're pretending this isn't derived from GrContext. Switch this to be derived from
    // GrRecordingContext!
    GrContext* asDirectContext() final { return nullptr; }

    bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) final {
        SkASSERT(caps && FPFactoryCache);
        SkASSERT(fThreadSafeProxy); // should've been set in the ctor

        if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
            return false;
        }

        // DDL contexts/drawing managers always sort the oplists and attempt to reduce opsTask
        // splitting.
        this->setupDrawingManager(true, true);

        SkASSERT(this->caps());

        return true;
    }

    GrAtlasManager* onGetAtlasManager() final {
        SkASSERT(0);   // the DDL Recorders should never invoke this
        return nullptr;
    }

    typedef GrContext INHERITED;
};

sk_sp<GrContext> GrContextPriv::MakeDDL(const sk_sp<GrContextThreadSafeProxy>& proxy) {
    sk_sp<GrContext> context(new GrDDLContext(proxy));

    if (!context->init(proxy->priv().refCaps(), proxy->priv().fpFactoryCache())) {
        return nullptr;
    }
    return context;
}
<|endoftext|>


<commit_before>// ========================================================================== //
// This file is part of DO-CV, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2021-present David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#include <DO/Shakti/Cuda/VideoIO/VideoStream.hpp>

#include "nvidia-video-codec-sdk-9.1.23/NvCodec/NvDecoder/NvDecoder.h"
#include "nvidia-video-codec-sdk-9.1.23/Utils/ColorSpace.h"
#include "nvidia-video-codec-sdk-9.1.23/Utils/FFmpegDemuxer.h"
#include "nvidia-video-codec-sdk-9.1.23/Utils/NvCodecUtils.h"

namespace DriverApi {

  auto init() -> void
  {
    ck(cuInit(0));
  }

  auto get_device_count() -> int
  {
    auto num_gpus = 0;
    ck(cuDeviceGetCount(&num_gpus));
    return num_gpus;
  }

  CudaContext::CudaContext(int gpu_id_)
    : gpu_id{gpu_id_}
  {
    ck(cuDeviceGet(&cuda_device, gpu_id));

    std::array<char, 80> device_name;
    ck(cuDeviceGetName(device_name.data(), device_name.size(), cuda_device));
    std::cout << "GPU in use: " << device_name.data() << std::endl;

    ck(cuCtxCreate(&cuda_context, CU_CTX_BLOCKING_SYNC, cuda_device));
  }

  CudaContext::CudaContext(CudaContext&& other)
  {
    std::swap(gpu_id, other.gpu_id);
    std::swap(cuda_context, other.cuda_context);
    std::swap(cuda_device, other.cuda_device);
  }

  CudaContext::~CudaContext()
  {
    if (cuda_context)
    {
      ck(cuCtxDestroy(cuda_context));
      cuda_context = 0;
      cuda_device = 0;
      gpu_id = -1;
    }
  }

  auto CudaContext::make_current() -> void
  {
    ck(cuCtxSetCurrent(cuda_context));
  }

  DeviceBgraBuffer::DeviceBgraBuffer(int width_, int height_)
    : width{width_}
    , height{height_}
  {
    ck(cuMemAlloc(&data, width * height * 4));
    ck(cuMemsetD8(data, 0, width * height * 4));
  }

  DeviceBgraBuffer::~DeviceBgraBuffer()
  {
    if (data)
      ck(cuMemFree(data));
  }

  auto
  DeviceBgraBuffer::to_host(DO::Sara::ImageView<DO::Sara::Bgra8>& image) const
      -> void
  {
    ck(cudaMemcpy(reinterpret_cast<void*>(image.data()),
                  reinterpret_cast<const void*>(data), width * height * 4,
                  cudaMemcpyDeviceToHost));
  }

}  // namespace DriverApi

simplelogger::Logger* logger =
    simplelogger::LoggerFactory::CreateConsoleLogger();

namespace DO { namespace Shakti {

  struct VideoStream::Impl
  {
    Impl(const std::string& video_filepath,
         const DriverApi::CudaContext& context)
      : demuxer{video_filepath.c_str()}
      , decoder{context.cuda_context, true,
                FFmpeg2NvCodecId(demuxer.GetVideoCodec())}
    {
    }

    auto
    read_decoded_frame_packet(DriverApi::DeviceBgraBuffer& bgra_frame_buffer)
        -> void
    {
      // Launch CUDA kernels for colorspace conversion from raw video to raw
      // image formats which OpenGL textures can work with
      if (decoder.GetBitDepth() == 8)
      {
        if (decoder.GetOutputFormat() == cudaVideoSurfaceFormat_YUV444)
          YUV444ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
        else  // default assumed NV12
          Nv12ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
      }
      else
      {
        if (decoder.GetOutputFormat() == cudaVideoSurfaceFormat_YUV444)
          YUV444P16ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], 2 * decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
        else  // default assumed P016
          P016ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], 2 * decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
      }

      ++frame_index;

      if (frame_index == num_frames_decoded)
        num_frames_decoded = frame_index = 0;
    }

    auto decode() -> bool
    {
      // Initialize the video stream.
      do
      {
        if (not demuxer.Demux(&frame_data_compressed.data,
                              &frame_data_compressed.size))
          return false;

        decoder.Decode(frame_data_compressed.data, frame_data_compressed.size,
                       &raw_frame_packet, &num_frames_decoded);
      } while (num_frames_decoded <= 0);
      return true;
    }

    auto read(DriverApi::DeviceBgraBuffer& bgra_frame_buffer) -> bool
    {
      if (num_frames_decoded == 0 and !decode())
        return false;

#ifdef DEBUG
      LOG(INFO) << decoder.GetVideoInfo();
#endif

      if (frame_index < num_frames_decoded)
        read_decoded_frame_packet(bgra_frame_buffer);

      return true;
    }

    mutable FFmpegDemuxer demuxer;
    NvDecoder decoder;

    std::uint8_t** raw_frame_packet{nullptr};
    std::int32_t num_frames_decoded{};
    std::int32_t frame_index{};

    struct EncodedVideoBuffer
    {
      std::uint8_t* data{nullptr};
      std::int32_t size{};
    } frame_data_compressed;
  };

  auto VideoStream::ImplDeleter::operator()(const VideoStream::Impl* p) const
      -> void
  {
    delete p;
  }

  VideoStream::VideoStream(const std::string& video_filepath,
                           const DriverApi::CudaContext& context)
    : _impl{new VideoStream::Impl{video_filepath, context}}
  {
  }

  auto VideoStream::width() const -> int
  {
    return _impl->demuxer.GetWidth();
  }

  auto VideoStream::height() const -> int
  {
    return _impl->demuxer.GetHeight();
  }

  auto VideoStream::decode() -> bool
  {
    return _impl->decode();
  }

  auto VideoStream::read(DriverApi::DeviceBgraBuffer& bgra_frame_buffer) -> bool
  {
    return _impl->read(bgra_frame_buffer);
  }

}}  // namespace DO::Shakti

static auto get_output_format_names(unsigned short output_format_mask,
                                    char* OutputFormats) -> void
{
  if (output_format_mask == 0)
  {
    strcpy(OutputFormats, "N/A");
    return;
  }

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_NV12))
    strcat(OutputFormats, "NV12 ");

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_P016))
    strcat(OutputFormats, "P016 ");

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_YUV444))
    strcat(OutputFormats, "YUV444 ");

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_YUV444_16Bit))
    strcat(OutputFormats, "YUV444P16 ");
}

auto show_decoder_capability() -> void
{
  ck(cuInit(0));
  int num_gpus = 0;
  ck(cuDeviceGetCount(&num_gpus));
  std::cout << "Decoder Capability" << std::endl << std::endl;
  const char* codec_names[] = {
      "JPEG", "MPEG1", "MPEG2", "MPEG4", "H264", "HEVC", "HEVC", "HEVC",
      "HEVC", "HEVC",  "HEVC",  "VC1",   "VP8",  "VP9",  "VP9",  "VP9"};
  const char* chroma_format_strings[] = {"4:0:0", "4:2:0", "4:2:2", "4:4:4"};
  char output_formats[64];
  cudaVideoCodec codecs[] = {
      cudaVideoCodec_JPEG,  cudaVideoCodec_MPEG1, cudaVideoCodec_MPEG2,
      cudaVideoCodec_MPEG4, cudaVideoCodec_H264,  cudaVideoCodec_HEVC,
      cudaVideoCodec_HEVC,  cudaVideoCodec_HEVC,  cudaVideoCodec_HEVC,
      cudaVideoCodec_HEVC,  cudaVideoCodec_HEVC,  cudaVideoCodec_VC1,
      cudaVideoCodec_VP8,   cudaVideoCodec_VP9,   cudaVideoCodec_VP9,
      cudaVideoCodec_VP9};
  int bit_depth_minus_8[] = {0, 0, 0, 0, 0, 0, 2, 4, 0, 2, 4, 0, 0, 0, 2, 4};

  cudaVideoChromaFormat chroma_formats[] = {
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_444, cudaVideoChromaFormat_444,
      cudaVideoChromaFormat_444, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420};

  for (int gpu_id = 0; gpu_id < num_gpus; ++gpu_id)
  {
    auto cuda_context = DriverApi::CudaContext{gpu_id};

    for (auto i = 0u; i < sizeof(codecs) / sizeof(codecs[0]); ++i)
    {
      CUVIDDECODECAPS decode_caps = {};
      decode_caps.eCodecType = codecs[i];
      decode_caps.eChromaFormat = chroma_formats[i];
      decode_caps.nBitDepthMinus8 = bit_depth_minus_8[i];

      cuvidGetDecoderCaps(&decode_caps);

      output_formats[0] = '\0';
      get_output_format_names(decode_caps.nOutputFormatMask, output_formats);

      // setw() width = maximum_width_of_string + 2 spaces
      std::cout << "Codec  " << std::left << std::setw(7) << codec_names[i]
                << "BitDepth  " << std::setw(4)
                << decode_caps.nBitDepthMinus8 + 8 << "ChromaFormat  "
                << std::setw(7)
                << chroma_format_strings[decode_caps.eChromaFormat]
                << "Supported  " << std::setw(3)
                << (int) decode_caps.bIsSupported << "MaxWidth  "
                << std::setw(7) << decode_caps.nMaxWidth << "MaxHeight  "
                << std::setw(7) << decode_caps.nMaxHeight << "MaxMBCount  "
                << std::setw(10) << decode_caps.nMaxMBCount << "MinWidth  "
                << std::setw(5) << decode_caps.nMinWidth << "MinHeight  "
                << std::setw(5) << decode_caps.nMinHeight << "SurfaceFormat  "
                << std::setw(11) << output_formats << std::endl;
    }

    std::cout << std::endl;
  }
}
<commit_msg>MAINT: fix compile error.<commit_after>// ========================================================================== //
// This file is part of DO-CV, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2021-present David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#include <DO/Shakti/Cuda/VideoIO/VideoStream.hpp>

#include "nvidia-video-codec-sdk-9.1.23/NvCodec/NvDecoder/NvDecoder.h"
#include "nvidia-video-codec-sdk-9.1.23/Utils/ColorSpace.h"
#include "nvidia-video-codec-sdk-9.1.23/Utils/FFmpegDemuxer.h"
#include "nvidia-video-codec-sdk-9.1.23/Utils/NvCodecUtils.h"

#include <array>

namespace DriverApi {

  auto init() -> void
  {
    ck(cuInit(0));
  }

  auto get_device_count() -> int
  {
    auto num_gpus = 0;
    ck(cuDeviceGetCount(&num_gpus));
    return num_gpus;
  }

  CudaContext::CudaContext(int gpu_id_)
    : gpu_id{gpu_id_}
  {
    ck(cuDeviceGet(&cuda_device, gpu_id));

    std::array<char, 80> device_name;
    ck(cuDeviceGetName(device_name.data(), static_cast<int>(device_name.size()),
                       cuda_device));
    std::cout << "GPU in use: " << device_name.data() << std::endl;

    ck(cuCtxCreate(&cuda_context, CU_CTX_BLOCKING_SYNC, cuda_device));
  }

  CudaContext::CudaContext(CudaContext&& other)
  {
    std::swap(gpu_id, other.gpu_id);
    std::swap(cuda_context, other.cuda_context);
    std::swap(cuda_device, other.cuda_device);
  }

  CudaContext::~CudaContext()
  {
    if (cuda_context)
    {
      ck(cuCtxDestroy(cuda_context));
      cuda_context = 0;
      cuda_device = 0;
      gpu_id = -1;
    }
  }

  auto CudaContext::make_current() -> void
  {
    ck(cuCtxSetCurrent(cuda_context));
  }

  DeviceBgraBuffer::DeviceBgraBuffer(int width_, int height_)
    : width{width_}
    , height{height_}
  {
    ck(cuMemAlloc(&data, width * height * 4));
    ck(cuMemsetD8(data, 0, width * height * 4));
  }

  DeviceBgraBuffer::~DeviceBgraBuffer()
  {
    if (data)
      ck(cuMemFree(data));
  }

  auto
  DeviceBgraBuffer::to_host(DO::Sara::ImageView<DO::Sara::Bgra8>& image) const
      -> void
  {
    ck(cudaMemcpy(reinterpret_cast<void*>(image.data()),
                  reinterpret_cast<const void*>(data), width * height * 4,
                  cudaMemcpyDeviceToHost));
  }

}  // namespace DriverApi

simplelogger::Logger* logger =
    simplelogger::LoggerFactory::CreateConsoleLogger();

namespace DO { namespace Shakti {

  struct VideoStream::Impl
  {
    Impl(const std::string& video_filepath,
         const DriverApi::CudaContext& context)
      : demuxer{video_filepath.c_str()}
      , decoder{context.cuda_context, true,
                FFmpeg2NvCodecId(demuxer.GetVideoCodec())}
    {
    }

    auto
    read_decoded_frame_packet(DriverApi::DeviceBgraBuffer& bgra_frame_buffer)
        -> void
    {
      // Launch CUDA kernels for colorspace conversion from raw video to raw
      // image formats which OpenGL textures can work with
      if (decoder.GetBitDepth() == 8)
      {
        if (decoder.GetOutputFormat() == cudaVideoSurfaceFormat_YUV444)
          YUV444ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
        else  // default assumed NV12
          Nv12ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
      }
      else
      {
        if (decoder.GetOutputFormat() == cudaVideoSurfaceFormat_YUV444)
          YUV444P16ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], 2 * decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
        else  // default assumed P016
          P016ToColor32<BGRA32>(
              (uint8_t*) raw_frame_packet[frame_index], 2 * decoder.GetWidth(),
              (uint8_t*) bgra_frame_buffer.data, bgra_frame_buffer.width * 4,
              decoder.GetWidth(), decoder.GetHeight());
      }

      ++frame_index;

      if (frame_index == num_frames_decoded)
        num_frames_decoded = frame_index = 0;
    }

    auto decode() -> bool
    {
      // Initialize the video stream.
      do
      {
        if (!demuxer.Demux(&frame_data_compressed.data,
                           &frame_data_compressed.size))
          return false;

        decoder.Decode(frame_data_compressed.data, frame_data_compressed.size,
                       &raw_frame_packet, &num_frames_decoded);
      } while (num_frames_decoded <= 0);
      return true;
    }

    auto read(DriverApi::DeviceBgraBuffer& bgra_frame_buffer) -> bool
    {
      if (num_frames_decoded == 0 && !decode())
        return false;

#ifdef DEBUG
      LOG(INFO) << decoder.GetVideoInfo();
#endif

      if (frame_index < num_frames_decoded)
        read_decoded_frame_packet(bgra_frame_buffer);

      return true;
    }

    mutable FFmpegDemuxer demuxer;
    NvDecoder decoder;

    std::uint8_t** raw_frame_packet{nullptr};
    std::int32_t num_frames_decoded{};
    std::int32_t frame_index{};

    struct EncodedVideoBuffer
    {
      std::uint8_t* data{nullptr};
      std::int32_t size{};
    } frame_data_compressed;
  };

  auto VideoStream::ImplDeleter::operator()(const VideoStream::Impl* p) const
      -> void
  {
    delete p;
  }

  VideoStream::VideoStream(const std::string& video_filepath,
                           const DriverApi::CudaContext& context)
    : _impl{new VideoStream::Impl{video_filepath, context}}
  {
  }

  auto VideoStream::width() const -> int
  {
    return _impl->demuxer.GetWidth();
  }

  auto VideoStream::height() const -> int
  {
    return _impl->demuxer.GetHeight();
  }

  auto VideoStream::decode() -> bool
  {
    return _impl->decode();
  }

  auto VideoStream::read(DriverApi::DeviceBgraBuffer& bgra_frame_buffer) -> bool
  {
    return _impl->read(bgra_frame_buffer);
  }

}}  // namespace DO::Shakti

static auto get_output_format_names(unsigned short output_format_mask,
                                    char* OutputFormats) -> void
{
  if (output_format_mask == 0)
  {
    strcpy(OutputFormats, "N/A");
    return;
  }

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_NV12))
    strcat(OutputFormats, "NV12 ");

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_P016))
    strcat(OutputFormats, "P016 ");

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_YUV444))
    strcat(OutputFormats, "YUV444 ");

  if (output_format_mask & (1U << cudaVideoSurfaceFormat_YUV444_16Bit))
    strcat(OutputFormats, "YUV444P16 ");
}

auto show_decoder_capability() -> void
{
  ck(cuInit(0));
  int num_gpus = 0;
  ck(cuDeviceGetCount(&num_gpus));
  std::cout << "Decoder Capability" << std::endl << std::endl;
  const char* codec_names[] = {
      "JPEG", "MPEG1", "MPEG2", "MPEG4", "H264", "HEVC", "HEVC", "HEVC",
      "HEVC", "HEVC",  "HEVC",  "VC1",   "VP8",  "VP9",  "VP9",  "VP9"};
  const char* chroma_format_strings[] = {"4:0:0", "4:2:0", "4:2:2", "4:4:4"};
  char output_formats[64];
  cudaVideoCodec codecs[] = {
      cudaVideoCodec_JPEG,  cudaVideoCodec_MPEG1, cudaVideoCodec_MPEG2,
      cudaVideoCodec_MPEG4, cudaVideoCodec_H264,  cudaVideoCodec_HEVC,
      cudaVideoCodec_HEVC,  cudaVideoCodec_HEVC,  cudaVideoCodec_HEVC,
      cudaVideoCodec_HEVC,  cudaVideoCodec_HEVC,  cudaVideoCodec_VC1,
      cudaVideoCodec_VP8,   cudaVideoCodec_VP9,   cudaVideoCodec_VP9,
      cudaVideoCodec_VP9};
  int bit_depth_minus_8[] = {0, 0, 0, 0, 0, 0, 2, 4, 0, 2, 4, 0, 0, 0, 2, 4};

  cudaVideoChromaFormat chroma_formats[] = {
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_444, cudaVideoChromaFormat_444,
      cudaVideoChromaFormat_444, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420,
      cudaVideoChromaFormat_420, cudaVideoChromaFormat_420};

  for (int gpu_id = 0; gpu_id < num_gpus; ++gpu_id)
  {
    auto cuda_context = DriverApi::CudaContext{gpu_id};

    for (auto i = 0u; i < sizeof(codecs) / sizeof(codecs[0]); ++i)
    {
      CUVIDDECODECAPS decode_caps = {};
      decode_caps.eCodecType = codecs[i];
      decode_caps.eChromaFormat = chroma_formats[i];
      decode_caps.nBitDepthMinus8 = bit_depth_minus_8[i];

      cuvidGetDecoderCaps(&decode_caps);

      output_formats[0] = '\0';
      get_output_format_names(decode_caps.nOutputFormatMask, output_formats);

      // setw() width = maximum_width_of_string + 2 spaces
      std::cout << "Codec  " << std::left << std::setw(7) << codec_names[i]
                << "BitDepth  " << std::setw(4)
                << decode_caps.nBitDepthMinus8 + 8 << "ChromaFormat  "
                << std::setw(7)
                << chroma_format_strings[decode_caps.eChromaFormat]
                << "Supported  " << std::setw(3)
                << (int) decode_caps.bIsSupported << "MaxWidth  "
                << std::setw(7) << decode_caps.nMaxWidth << "MaxHeight  "
                << std::setw(7) << decode_caps.nMaxHeight << "MaxMBCount  "
                << std::setw(10) << decode_caps.nMaxMBCount << "MinWidth  "
                << std::setw(5) << decode_caps.nMinWidth << "MinHeight  "
                << std::setw(5) << decode_caps.nMinHeight << "SurfaceFormat  "
                << std::setw(11) << output_formats << std::endl;
    }

    std::cout << std::endl;
  }
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osg/GraphicsContext>
#include <osg/Notify>
#include <map>

using namespace osg;

static ref_ptr<GraphicsContext::CreateGraphicContextCallback> s_createGraphicsContextCallback;

void GraphicsContext::setCreateGraphicsContextCallback(CreateGraphicContextCallback* callback)
{
    s_createGraphicsContextCallback = callback;
}

GraphicsContext::CreateGraphicContextCallback* GraphicsContext::getCreateGraphicsContextCallback()
{
    return s_createGraphicsContextCallback.get();
}

GraphicsContext* GraphicsContext::createGraphicsContext(Traits* traits)
{
    if (s_createGraphicsContextCallback.valid())
        return s_createGraphicsContextCallback->createGraphicsContext(traits);
    else
        return 0;
}

typedef std::map<unsigned int, unsigned int>  ContextIDMap;
static ContextIDMap s_contextIDMap;
static OpenThreads::Mutex s_contextIDMapMutex;

unsigned int GraphicsContext::createNewContextID()
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);

    // first check to see if we can reuse contextID;
    for(ContextIDMap::iterator itr = s_contextIDMap.begin();
        itr != s_contextIDMap.end();
        ++itr)
    {
        if (itr->second == 0)
        {

            // reuse contextID;
            itr->second = 1;

            osg::notify(osg::NOTICE)<<"GraphicsContext::createNewContextID() reusing contextID="<<itr->first<<std::endl;

            return itr->first;
        }
    }

    unsigned int contextID = s_contextIDMap.size();
    s_contextIDMap[contextID] = 1;

    osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() creating contextID="<<contextID<<std::endl;

    if ( (contextID+1) > osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts() )
    {
        osg::notify(osg::INFO)<<"Updating the MaxNumberOfGraphicsContexts to "<<contextID+1<<std::endl;

        // update the the maximum number of graphics contexts,
        // to ensure that texture objects and display buffers are configured to the correct size.
        osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( contextID + 1 );
    }

    return contextID;
}

void GraphicsContext::incrementContextIDUsageCount(unsigned int contextID)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);

    osg::notify(osg::INFO)<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]<<std::endl;

    ++s_contextIDMap[contextID];
}

void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
{

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);

    if (s_contextIDMap[contextID]!=0)
    {
        --s_contextIDMap[contextID];
    }
    else
    {
        osg::notify(osg::NOTICE)<<"Warning: decrementContextIDUsageCount("<<contextID<<") called on expired contextID."<<std::endl;
    }

    osg::notify(osg::INFO)<<"GraphicsContext::decrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]<<std::endl;

}

GraphicsContext::GraphicsContext():
    _threadOfLastMakeCurrent(0)
{
}

GraphicsContext::~GraphicsContext()
{
    close(false);
}

/** Realise the GraphicsContext.*/
bool GraphicsContext::realize()
{
    if (realizeImplementation())
    {
        if (_graphicsThread.valid() && !_graphicsThread->isRunning())
        {
            _graphicsThread->startThread();
        }
        return true;
    }
    else
    {
        return false;
    }
}

void GraphicsContext::close(bool callCloseImplementation)
{
    // switch off the graphics thread...
    setGraphicsThread(0);

    if (callCloseImplementation) closeImplementation();

    if (_state.valid())
    {
        decrementContextIDUsageCount(_state->getContextID());

        _state = 0;
    }
}

void GraphicsContext::makeCurrent()
{
    ReleaseContext_Block_MakeCurrentOperation* rcbmco = 0;

    if (_graphicsThread.valid() &&
        _threadOfLastMakeCurrent == _graphicsThread.get() &&
        _threadOfLastMakeCurrent != OpenThreads::Thread::CurrentThread())
    {
        // create a relase contex, block and make current operation to stop the graphics thread while we use the graphics context for ourselves
        rcbmco = new ReleaseContext_Block_MakeCurrentOperation;
        _graphicsThread->add(rcbmco);
    }

    if (!isCurrent()) _mutex.lock();

    makeCurrentImplementation();

    _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();

    if (rcbmco)
    {
        // Let the "relase contex, block and make current operation" proceed, which will now move on to trying to aquire the graphics
        // contex itself with a makeCurrent(), this will then block on the GraphicsContext mutex till releaseContext() releases it.
        rcbmco->release();
    }
}

void GraphicsContext::makeContextCurrent(GraphicsContext* readContext)
{
    if (!isCurrent()) _mutex.lock();

    makeContextCurrentImplementation(readContext);

    _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
}

void GraphicsContext::releaseContext()
{
    _mutex.unlock();
}

void GraphicsContext::swapBuffers()
{
    if (isCurrent())
    {
        swapBuffersImplementation();
    }
    else if (_graphicsThread.valid() &&
             _threadOfLastMakeCurrent == _graphicsThread.get())
    {
        _graphicsThread->add(new SwapBuffersOperation);
    }
    else
    {
        makeCurrent();
        swapBuffersImplementation();
        releaseContext();
    }
}

void GraphicsContext::createGraphicsThread()
{
    if (!_graphicsThread)
    {
        setGraphicsThread(new GraphicsThread);
    }
}

void GraphicsContext::setGraphicsThread(GraphicsThread* gt)
{
    if (_graphicsThread==gt) return;

    if (_graphicsThread.valid())
    {
        // need to kill the thread in some way...
        _graphicsThread->cancel();
        _graphicsThread->_graphicsContext = 0;
    }

    _graphicsThread = gt;

    if (_graphicsThread.valid())
    {
        _graphicsThread->_graphicsContext = this;

        if (!_graphicsThread->isRunning())
        {
            _graphicsThread->startThread();
        }
    }
}
<commit_msg>Changed debug message to INFO.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osg/GraphicsContext>
#include <osg/Notify>
#include <map>

using namespace osg;

static ref_ptr<GraphicsContext::CreateGraphicContextCallback> s_createGraphicsContextCallback;

void GraphicsContext::setCreateGraphicsContextCallback(CreateGraphicContextCallback* callback)
{
    s_createGraphicsContextCallback = callback;
}

GraphicsContext::CreateGraphicContextCallback* GraphicsContext::getCreateGraphicsContextCallback()
{
    return s_createGraphicsContextCallback.get();
}

GraphicsContext* GraphicsContext::createGraphicsContext(Traits* traits)
{
    if (s_createGraphicsContextCallback.valid())
        return s_createGraphicsContextCallback->createGraphicsContext(traits);
    else
        return 0;
}

typedef std::map<unsigned int, unsigned int>  ContextIDMap;
static ContextIDMap s_contextIDMap;
static OpenThreads::Mutex s_contextIDMapMutex;

unsigned int GraphicsContext::createNewContextID()
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);

    // first check to see if we can reuse contextID;
    for(ContextIDMap::iterator itr = s_contextIDMap.begin();
        itr != s_contextIDMap.end();
        ++itr)
    {
        if (itr->second == 0)
        {

            // reuse contextID;
            itr->second = 1;

            osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() reusing contextID="<<itr->first<<std::endl;

            return itr->first;
        }
    }

    unsigned int contextID = s_contextIDMap.size();
    s_contextIDMap[contextID] = 1;

    osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() creating contextID="<<contextID<<std::endl;

    if ( (contextID+1) > osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts() )
    {
        osg::notify(osg::INFO)<<"Updating the MaxNumberOfGraphicsContexts to "<<contextID+1<<std::endl;

        // update the the maximum number of graphics contexts,
        // to ensure that texture objects and display buffers are configured to the correct size.
        osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( contextID + 1 );
    }

    return contextID;
}

void GraphicsContext::incrementContextIDUsageCount(unsigned int contextID)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);

    osg::notify(osg::INFO)<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]<<std::endl;

    ++s_contextIDMap[contextID];
}

void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
{

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);

    if (s_contextIDMap[contextID]!=0)
    {
        --s_contextIDMap[contextID];
    }
    else
    {
        osg::notify(osg::NOTICE)<<"Warning: decrementContextIDUsageCount("<<contextID<<") called on expired contextID."<<std::endl;
    }

    osg::notify(osg::INFO)<<"GraphicsContext::decrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]<<std::endl;

}

GraphicsContext::GraphicsContext():
    _threadOfLastMakeCurrent(0)
{
}

GraphicsContext::~GraphicsContext()
{
    close(false);
}

/** Realise the GraphicsContext.*/
bool GraphicsContext::realize()
{
    if (realizeImplementation())
    {
        if (_graphicsThread.valid() && !_graphicsThread->isRunning())
        {
            _graphicsThread->startThread();
        }
        return true;
    }
    else
    {
        return false;
    }
}

void GraphicsContext::close(bool callCloseImplementation)
{
    // switch off the graphics thread...
    setGraphicsThread(0);

    if (callCloseImplementation) closeImplementation();

    if (_state.valid())
    {
        decrementContextIDUsageCount(_state->getContextID());

        _state = 0;
    }
}

void GraphicsContext::makeCurrent()
{
    ReleaseContext_Block_MakeCurrentOperation* rcbmco = 0;

    if (_graphicsThread.valid() &&
        _threadOfLastMakeCurrent == _graphicsThread.get() &&
        _threadOfLastMakeCurrent != OpenThreads::Thread::CurrentThread())
    {
        // create a relase contex, block and make current operation to stop the graphics thread while we use the graphics context for ourselves
        rcbmco = new ReleaseContext_Block_MakeCurrentOperation;
        _graphicsThread->add(rcbmco);
    }

    if (!isCurrent()) _mutex.lock();

    makeCurrentImplementation();

    _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();

    if (rcbmco)
    {
        // Let the "relase contex, block and make current operation" proceed, which will now move on to trying to aquire the graphics
        // contex itself with a makeCurrent(), this will then block on the GraphicsContext mutex till releaseContext() releases it.
        rcbmco->release();
    }
}

void GraphicsContext::makeContextCurrent(GraphicsContext* readContext)
{
    if (!isCurrent()) _mutex.lock();

    makeContextCurrentImplementation(readContext);

    _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
}

void GraphicsContext::releaseContext()
{
    _mutex.unlock();
}

void GraphicsContext::swapBuffers()
{
    if (isCurrent())
    {
        swapBuffersImplementation();
    }
    else if (_graphicsThread.valid() &&
             _threadOfLastMakeCurrent == _graphicsThread.get())
    {
        _graphicsThread->add(new SwapBuffersOperation);
    }
    else
    {
        makeCurrent();
        swapBuffersImplementation();
        releaseContext();
    }
}

void GraphicsContext::createGraphicsThread()
{
    if (!_graphicsThread)
    {
        setGraphicsThread(new GraphicsThread);
    }
}

void GraphicsContext::setGraphicsThread(GraphicsThread* gt)
{
    if (_graphicsThread==gt) return;

    if (_graphicsThread.valid())
    {
        // need to kill the thread in some way...
        _graphicsThread->cancel();
        _graphicsThread->_graphicsContext = 0;
    }

    _graphicsThread = gt;

    if (_graphicsThread.valid())
    {
        _graphicsThread->_graphicsContext = this;

        if (!_graphicsThread->isRunning())
        {
            _graphicsThread->startThread();
        }
    }
}
<|endoftext|>


<commit_before>/// HEADER
#include "optimization_dummy.h"

/// PROJECT
#include <csapex/msg/io.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/msg/generic_value_message.hpp>

CSAPEX_REGISTER_CLASS(csapex::OptimizationDummy, csapex::Node)

using namespace csapex;
using namespace csapex::connection_types;

OptimizationDummy::OptimizationDummy()
{
}

void OptimizationDummy::setupParameters(Parameterizable& parameters)
{
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("a", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("b", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("c", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("d", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("e", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("f", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("g", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("h", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("i", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("j", -10.0, 10.0, 0.0, 0.1));
}

void OptimizationDummy::setup(NodeModifier& node_modifier)
{
    in_ = node_modifier.addInput<double>("argument");
    out_ = node_modifier.addOutput<double>("Fitness");
}

void OptimizationDummy::process()
{
    double a = readParameter<double>("a");
    double b = readParameter<double>("b");
    double c = readParameter<double>("c");
    double d = readParameter<double>("d");
    double e = readParameter<double>("e");
    double f = readParameter<double>("f");
    double g = readParameter<double>("g");
    double h = readParameter<double>("h");
    double i = readParameter<double>("i");
    double j = readParameter<double>("j");

    double x = msg::getValue<double>(in_);

    double fitness = -std::pow((a - 4), 2)
            + std::pow(x + 1.0 - b, 2)
            + std::pow(x + 2.0 - c, 2)
            + std::pow(x + 3.0 - d, 2)
            + std::pow(x + 4.0 - e, 2)
            + std::pow(x + 5.0 - f, 2)
            + std::pow(x + 6.0 - g, 2)
            + std::pow(x + 7.0 - h, 2)
            + std::pow(x + 8.0 - i, 2)
            + std::pow(x + 9.0 - j, 2)
            ;

    msg::publish(out_, fitness);
}
<commit_msg>changed optimization dummy for minimization<commit_after>/// HEADER
#include "optimization_dummy.h"

/// PROJECT
#include <csapex/msg/io.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/msg/generic_value_message.hpp>

CSAPEX_REGISTER_CLASS(csapex::OptimizationDummy, csapex::Node)

using namespace csapex;
using namespace csapex::connection_types;

OptimizationDummy::OptimizationDummy()
{
}

void OptimizationDummy::setupParameters(Parameterizable& parameters)
{
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("a", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("b", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("c", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("d", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("e", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("f", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("g", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("h", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("i", -10.0, 10.0, 0.0, 0.1));
    parameters.addParameter(csapex::param::ParameterFactory::declareRange("j", -10.0, 10.0, 0.0, 0.1));
}

void OptimizationDummy::setup(NodeModifier& node_modifier)
{
    in_ = node_modifier.addInput<double>("argument");
    out_ = node_modifier.addOutput<double>("Fitness");
}

void OptimizationDummy::process()
{
    double a = readParameter<double>("a");
    double b = readParameter<double>("b");
    double c = readParameter<double>("c");
    double d = readParameter<double>("d");
    double e = readParameter<double>("e");
    double f = readParameter<double>("f");
    double g = readParameter<double>("g");
    double h = readParameter<double>("h");
    double i = readParameter<double>("i");
    double j = readParameter<double>("j");

    double x = msg::getValue<double>(in_);

    double fitness = std::abs(a - 4)
            + std::pow(x - 5.0 - b, 2)
            + std::pow(x - 2.0 - c, 2)
            + std::pow(x - 3.0 - d, 2)
            + std::pow(x - 4.0 - e, 2)
            + std::pow(x - 5.0 - f, 2)
            + std::pow(x - 6.0 - g, 2)
            + std::pow(x - 7.0 - h, 2)
            + std::pow(x - 8.0 - i, 2)
            + std::pow(x - 9.0 - j, 2)
            ;

    msg::publish(out_, fitness);
}
<|endoftext|>