<commit_before>/***
Copyright (C) 2013 Aniket Deole <aniket.deole@gmail.com>
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License version 2.1, as published
by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranties of
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
***/
#include <iostream>
#include "notepaneview.hh"
/*
 * This files contains C Code as I was not able to find a good C++ gtkmm e
 * equivalent wrapper for webkit. Open to suggestions :)
 */

NotePaneView::NotePaneView (bool homogeneous, int spacing, Gtk::PackOptions options, int padding) {
	set_orientation (Gtk::ORIENTATION_VERTICAL);

	noteTitle = Gtk::manage (new Gtk::Entry ());
	noteTitle->set_text ("NoteTitle");
	noteTitle->set_has_frame (false);
	noteTitle->set_editable (true);

	addCss (noteTitle, "noteTitle", ".noteTitle {\n color:#000;\n font: OpenSans light 18; padding-top:10px;padding-bottom:10px; "
								"padding-left:14px; background-image:none; background-color:white;\n}\n"
								".noteTitle:selected {    background-color: #34393D; color:white ; }");

	Gtk::EventBox* ev = Gtk::manage (new Gtk::EventBox ());

	Gtk::Box* noteTitleAndSaveButtonBox = Gtk::manage (new Gtk::Box ());

	saveButton = Gtk::manage (new Gtk::Button ("  Save Note  "));

  	saveButton->signal_clicked().connect(
    sigc::mem_fun(*this, &NotePaneView::saveNote) );

	noteTitleAndSaveButtonBox->pack_start (*noteTitle, true, true, 0);
	noteTitleAndSaveButtonBox->pack_end (*saveButton, false, false, 0);

	ev->add (*noteTitleAndSaveButtonBox);

	addCss (ev, "ev", ".ev { background-image:none; background-color:white;\n}\n");

	pack_start (*ev, false, false, 0);

	Gtk::Separator* sepBot = Gtk::manage (new Gtk::Separator (Gtk::ORIENTATION_HORIZONTAL));
	pack_start (*sepBot, false, false, 0);

	webviewWrapper = Gtk::manage (new Gtk::ScrolledWindow ());

	webview = WEBKIT_WEB_VIEW(webkit_web_view_new());

	GtkScrolledWindow* webviewWrapper_c = webviewWrapper->gobj ();
	gtk_container_add (GTK_CONTAINER (webviewWrapper_c), GTK_WIDGET (webview));

	webkit_web_view_set_editable(webview, true);

	webkit_web_view_load_string (webview, "No Notes :(", "text/html", NULL, NULL);

	WebKitWebSettings* wkws = webkit_web_view_get_settings ( webview);
	g_object_set (G_OBJECT(wkws), "default-font-size", 10, NULL);
	g_object_set (G_OBJECT(wkws), "enable-offline-web-application-cache", true, NULL);
	g_object_set (G_OBJECT(wkws), "tab-key-cycles-through-elements", false, NULL);

	webviewWrapper->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	pack_start (*webviewWrapper);

	show_all ();
}

NotePaneView::~NotePaneView () {}

void NotePaneView::setDatabaseManager (DatabaseManager* d) {
    dbm = d;
}

void NotePaneView::setNote (NoteData n) {
	setWebViewContent (n.getBody ());
	setNoteTitleEntryText (n.getTitle ());
	nd = n;
}

void NotePaneView::setNoteTitleEntryText (std::string content) {
	noteTitle->set_text (content);
}

void NotePaneView::setWebViewContent (std::string content) {
	webkit_web_view_load_string (webview, content.c_str (), "text/html", NULL, NULL);
}

void NotePaneView::newNote () {
	webkit_web_view_load_string (webview, "", "text/html", NULL, NULL);
}

void NotePaneView::disableButtons () {
	saveButton->set_sensitive (false);
}

void NotePaneView::enableButtons () {
	saveButton->set_sensitive (true);
}

std::string
replaceSingleQuote( std::string const& original )
{
    std::string results(
        original.size()
            + std::count( original.begin(), original.end(), '\''),
        '\'' );
    std::string::iterator dest = results.begin();
    for ( std::string::const_iterator current = original.begin();
            current != original.end();
            ++ current ) {
        if ( *current == '\'' ) {
            ++ dest;
        }
        *dest = *current;
        ++ dest;
    }
    return results;
}

template <typename T>
std::string NumberToString(T pNumber)
{
 std::ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

void NotePaneView::saveNote () {

    std::string body = "";
	webkit_web_view_execute_script (webview, "document.title=document.documentElement.innerHTML;");
	body.append (webkit_web_frame_get_title ((webkit_web_view_get_main_frame (webview))));
	body = replaceSingleQuote (body);

	std::string title = replaceSingleQuote (noteTitle->get_text ());
	std::cout << "saved: " << "update notes set title = '" + title + "', body = '" + body + "' where id = " + NumberToString (nd.getPrimaryKey ()) 	<< std::endl;
  	dbm->exec ("update notes set title = '" + title + "', body = '" + body + "', modified_time = strftime('%s','now') where id = " + NumberToString (nd.getPrimaryKey ()), NULL, this);

  	app->nlpv->fetchNotesForNotebook (app->lpv->getSelectedNotebookId ());
}<commit_msg>Styled the save button to a white background.<commit_after>/***
Copyright (C) 2013 Aniket Deole <aniket.deole@gmail.com>
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License version 2.1, as published
by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranties of
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
***/
#include <iostream>
#include "notepaneview.hh"
/*
 * This files contains C Code as I was not able to find a good C++ gtkmm e
 * equivalent wrapper for webkit. Open to suggestions :)
 */

NotePaneView::NotePaneView (bool homogeneous, int spacing, Gtk::PackOptions options, int padding) {
	set_orientation (Gtk::ORIENTATION_VERTICAL);

	noteTitle = Gtk::manage (new Gtk::Entry ());
	noteTitle->set_text ("NoteTitle");
	noteTitle->set_has_frame (false);
	noteTitle->set_editable (true);

	addCss (noteTitle, "noteTitle", ".noteTitle {\n color:#000;\n font: OpenSans light 18; padding-top:10px;padding-bottom:10px; "
								"padding-left:14px; background-image:none; background-color:white;\n}\n"
								".noteTitle:selected {    background-color: #34393D; color:white ; }");

	Gtk::EventBox* ev = Gtk::manage (new Gtk::EventBox ());

	Gtk::Box* noteTitleAndSaveButtonBox = Gtk::manage (new Gtk::Box ());

	Gtk::Separator* sepVert = Gtk::manage (new Gtk::Separator (Gtk::ORIENTATION_VERTICAL));

	saveButton = Gtk::manage (new Gtk::Button ("  Save Note  "));
	addCss (saveButton, "saveButton", ".saveButton { background-image:none; background-color:white;"
		"border-radius: 0px; border: 0px solid; -unico-inner-stroke-width: 0px;	-unico-outer-stroke-width: 0px;-GtkButton-inner-border: 0;\n}\n");

  	saveButton->signal_clicked().connect(
    sigc::mem_fun(*this, &NotePaneView::saveNote) );

	noteTitleAndSaveButtonBox->pack_start (*noteTitle, true, true, 0);
	noteTitleAndSaveButtonBox->pack_start (*sepVert, false, false, 0);
	noteTitleAndSaveButtonBox->pack_end (*saveButton, false, false, 0);

	ev->add (*noteTitleAndSaveButtonBox);

	addCss (ev, "ev", ".ev { background-image:none; background-color:white;\n}\n");

	pack_start (*ev, false, false, 0);

	Gtk::Separator* sepBot = Gtk::manage (new Gtk::Separator (Gtk::ORIENTATION_HORIZONTAL));
	pack_start (*sepBot, false, false, 0);

	webviewWrapper = Gtk::manage (new Gtk::ScrolledWindow ());

	webview = WEBKIT_WEB_VIEW(webkit_web_view_new());

	GtkScrolledWindow* webviewWrapper_c = webviewWrapper->gobj ();
	gtk_container_add (GTK_CONTAINER (webviewWrapper_c), GTK_WIDGET (webview));

	webkit_web_view_set_editable(webview, true);

	webkit_web_view_load_string (webview, "No Notes :(", "text/html", NULL, NULL);

	WebKitWebSettings* wkws = webkit_web_view_get_settings ( webview);
	g_object_set (G_OBJECT(wkws), "default-font-size", 10, NULL);
	g_object_set (G_OBJECT(wkws), "enable-offline-web-application-cache", true, NULL);
	g_object_set (G_OBJECT(wkws), "tab-key-cycles-through-elements", false, NULL);

	webviewWrapper->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	pack_start (*webviewWrapper);

	show_all ();
}

NotePaneView::~NotePaneView () {}

void NotePaneView::setDatabaseManager (DatabaseManager* d) {
    dbm = d;
}

void NotePaneView::setNote (NoteData n) {
	setWebViewContent (n.getBody ());
	setNoteTitleEntryText (n.getTitle ());
	nd = n;
}

void NotePaneView::setNoteTitleEntryText (std::string content) {
	noteTitle->set_text (content);
}

void NotePaneView::setWebViewContent (std::string content) {
	webkit_web_view_load_string (webview, content.c_str (), "text/html", NULL, NULL);
}

void NotePaneView::newNote () {
	webkit_web_view_load_string (webview, "", "text/html", NULL, NULL);
}

void NotePaneView::disableButtons () {
	saveButton->set_sensitive (false);
}

void NotePaneView::enableButtons () {
	saveButton->set_sensitive (true);
}

std::string
replaceSingleQuote( std::string const& original )
{
    std::string results(
        original.size()
            + std::count( original.begin(), original.end(), '\''),
        '\'' );
    std::string::iterator dest = results.begin();
    for ( std::string::const_iterator current = original.begin();
            current != original.end();
            ++ current ) {
        if ( *current == '\'' ) {
            ++ dest;
        }
        *dest = *current;
        ++ dest;
    }
    return results;
}

template <typename T>
std::string NumberToString(T pNumber)
{
 std::ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

void NotePaneView::saveNote () {

    std::string body = "";
	webkit_web_view_execute_script (webview, "document.title=document.documentElement.innerHTML;");
	body.append (webkit_web_frame_get_title ((webkit_web_view_get_main_frame (webview))));
	body = replaceSingleQuote (body);

	std::string title = replaceSingleQuote (noteTitle->get_text ());
	std::cout << "saved: " << "update notes set title = '" + title + "', body = '" + body + "' where id = " + NumberToString (nd.getPrimaryKey ()) 	<< std::endl;
  	dbm->exec ("update notes set title = '" + title + "', body = '" + body + "', modified_time = strftime('%s','now') where id = " + NumberToString (nd.getPrimaryKey ()), NULL, this);

  	app->nlpv->fetchNotesForNotebook (app->lpv->getSelectedNotebookId ());
}<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "content/renderer/pepper/pepper_websocket_host.h"

#include <string>

#include "content/public/renderer/renderer_ppapi_host.h"
#include "net/base/net_util.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_websocket.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebArrayBuffer.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
#include "third_party/WebKit/public/web/WebSocket.h"

using blink::WebArrayBuffer;
using blink::WebDocument;
using blink::WebString;
using blink::WebSocket;
using blink::WebURL;

namespace content {

#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name)                   \
  COMPILE_ASSERT(                                                            \
      static_cast<int>(WebSocket::webkit_name) == static_cast<int>(np_name), \
      mismatching_enums)

COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeNormalClosure,
                             PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeGoingAway,
                             PP_WEBSOCKETSTATUSCODE_GOING_AWAY);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeProtocolError,
                             PP_WEBSOCKETSTATUSCODE_PROTOCOL_ERROR);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeUnsupportedData,
                             PP_WEBSOCKETSTATUSCODE_UNSUPPORTED_DATA);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeNoStatusRcvd,
                             PP_WEBSOCKETSTATUSCODE_NO_STATUS_RECEIVED);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeAbnormalClosure,
                             PP_WEBSOCKETSTATUSCODE_ABNORMAL_CLOSURE);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeInvalidFramePayloadData,
                             PP_WEBSOCKETSTATUSCODE_INVALID_FRAME_PAYLOAD_DATA);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodePolicyViolation,
                             PP_WEBSOCKETSTATUSCODE_POLICY_VIOLATION);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMessageTooBig,
                             PP_WEBSOCKETSTATUSCODE_MESSAGE_TOO_BIG);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMandatoryExt,
                             PP_WEBSOCKETSTATUSCODE_MANDATORY_EXTENSION);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeInternalError,
                             PP_WEBSOCKETSTATUSCODE_INTERNAL_SERVER_ERROR);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeTLSHandshake,
                             PP_WEBSOCKETSTATUSCODE_TLS_HANDSHAKE);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMinimumUserDefined,
                             PP_WEBSOCKETSTATUSCODE_USER_REGISTERED_MIN);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMaximumUserDefined,
                             PP_WEBSOCKETSTATUSCODE_USER_PRIVATE_MAX);

PepperWebSocketHost::PepperWebSocketHost(RendererPpapiHost* host,
                                         PP_Instance instance,
                                         PP_Resource resource)
    : ResourceHost(host->GetPpapiHost(), instance, resource),
      renderer_ppapi_host_(host),
      connecting_(false),
      initiating_close_(false),
      accepting_close_(false),
      error_was_received_(false) {}

PepperWebSocketHost::~PepperWebSocketHost() {
  if (websocket_)
    websocket_->disconnect();
}

int32_t PepperWebSocketHost::OnResourceMessageReceived(
    const IPC::Message& msg,
    ppapi::host::HostMessageContext* context) {
  PPAPI_BEGIN_MESSAGE_MAP(PepperWebSocketHost, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Connect,
                                      OnHostMsgConnect)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Close,
                                      OnHostMsgClose)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_SendText,
                                      OnHostMsgSendText)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_SendBinary,
                                      OnHostMsgSendBinary)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Fail,
                                      OnHostMsgFail)
  PPAPI_END_MESSAGE_MAP()
  return PP_ERROR_FAILED;
}

void PepperWebSocketHost::didConnect() {
  std::string protocol;
  if (websocket_)
    protocol = websocket_->subprotocol().utf8();
  connecting_ = false;
  connect_reply_.params.set_result(PP_OK);
  host()->SendReply(connect_reply_,
                    PpapiPluginMsg_WebSocket_ConnectReply(url_, protocol));
}

void PepperWebSocketHost::didReceiveMessage(const blink::WebString& message) {
  // Dispose packets after receiving an error.
  if (error_was_received_)
    return;

  // Send an IPC to transport received data.
  std::string string_message = message.utf8();
  host()->SendUnsolicitedReply(
      pp_resource(), PpapiPluginMsg_WebSocket_ReceiveTextReply(string_message));
}

void PepperWebSocketHost::didReceiveArrayBuffer(
    const blink::WebArrayBuffer& binaryData) {
  // Dispose packets after receiving an error.
  if (error_was_received_)
    return;

  // Send an IPC to transport received data.
  uint8_t* data = static_cast<uint8_t*>(binaryData.data());
  std::vector<uint8_t> array_message(data, data + binaryData.byteLength());
  host()->SendUnsolicitedReply(
      pp_resource(),
      PpapiPluginMsg_WebSocket_ReceiveBinaryReply(array_message));
}

void PepperWebSocketHost::didReceiveMessageError() {
  // Records the error, then stops receiving any frames after this error.
  // The error must be notified after all queued messages are read.
  error_was_received_ = true;

  // Send an IPC to report the error. After this IPC, ReceiveTextReply and
  // ReceiveBinaryReply IPC are not sent anymore because |error_was_received_|
  // blocks.
  host()->SendUnsolicitedReply(pp_resource(),
                               PpapiPluginMsg_WebSocket_ErrorReply());
}

void PepperWebSocketHost::didUpdateBufferedAmount(
    unsigned long buffered_amount) {
  // Send an IPC to update buffered amount.
  host()->SendUnsolicitedReply(
      pp_resource(),
      PpapiPluginMsg_WebSocket_BufferedAmountReply(buffered_amount));
}

void PepperWebSocketHost::didStartClosingHandshake() {
  accepting_close_ = true;

  // Send an IPC to notice that server starts closing handshake.
  host()->SendUnsolicitedReply(
      pp_resource(),
      PpapiPluginMsg_WebSocket_StateReply(PP_WEBSOCKETREADYSTATE_CLOSING));
}

void PepperWebSocketHost::didClose(unsigned long unhandled_buffered_amount,
                                   ClosingHandshakeCompletionStatus status,
                                   unsigned short code,
                                   const blink::WebString& reason) {
  if (connecting_) {
    connecting_ = false;
    connect_reply_.params.set_result(PP_ERROR_FAILED);
    host()->SendReply(
        connect_reply_,
        PpapiPluginMsg_WebSocket_ConnectReply(url_, std::string()));
  }

  // Set close_was_clean_.
  bool was_clean = (initiating_close_ || accepting_close_) &&
                   !unhandled_buffered_amount &&
                   status == WebSocketClient::ClosingHandshakeComplete;

  if (initiating_close_) {
    initiating_close_ = false;
    close_reply_.params.set_result(PP_OK);
    host()->SendReply(
        close_reply_,
        PpapiPluginMsg_WebSocket_CloseReply(
            unhandled_buffered_amount, was_clean, code, reason.utf8()));
  } else {
    accepting_close_ = false;
    host()->SendUnsolicitedReply(
        pp_resource(),
        PpapiPluginMsg_WebSocket_ClosedReply(
            unhandled_buffered_amount, was_clean, code, reason.utf8()));
  }

  // Disconnect.
  if (websocket_) {
    websocket_->disconnect();
    websocket_.reset();
  }
}

int32_t PepperWebSocketHost::OnHostMsgConnect(
    ppapi::host::HostMessageContext* context,
    const std::string& url,
    const std::vector<std::string>& protocols) {
  // Validate url and convert it to WebURL.
  GURL gurl(url);
  url_ = gurl.spec();
  if (!gurl.is_valid())
    return PP_ERROR_BADARGUMENT;
  if (!gurl.SchemeIs("ws") && !gurl.SchemeIs("wss"))
    return PP_ERROR_BADARGUMENT;
  if (gurl.has_ref())
    return PP_ERROR_BADARGUMENT;
  if (!net::IsPortAllowedByDefault(gurl.IntPort()))
    return PP_ERROR_BADARGUMENT;
  WebURL web_url(gurl);

  // Validate protocols.
  std::string protocol_string;
  for (std::vector<std::string>::const_iterator vector_it = protocols.begin();
       vector_it != protocols.end();
       ++vector_it) {

    // Check containing characters.
    for (std::string::const_iterator string_it = vector_it->begin();
         string_it != vector_it->end();
         ++string_it) {
      uint8_t character = *string_it;
      // WebSocket specification says "(Subprotocol string must consist of)
      // characters in the range U+0021 to U+007E not including separator
      // characters as defined in [RFC2616]."
      const uint8_t minimumProtocolCharacter = '!';  // U+0021.
      const uint8_t maximumProtocolCharacter = '~';  // U+007E.
      if (character < minimumProtocolCharacter ||
          character > maximumProtocolCharacter || character == '"' ||
          character == '(' || character == ')' || character == ',' ||
          character == '/' ||
          (character >= ':' && character <= '@') ||  // U+003A - U+0040
          (character >= '[' && character <= ']') ||  // U+005B - u+005D
          character == '{' ||
          character == '}')
        return PP_ERROR_BADARGUMENT;
    }
    // Join protocols with the comma separator.
    if (vector_it != protocols.begin())
      protocol_string.append(",");
    protocol_string.append(*vector_it);
  }

  // Convert protocols to WebString.
  WebString web_protocols = WebString::fromUTF8(protocol_string);

  // Create blink::WebSocket object and connect.
  blink::WebPluginContainer* container =
      renderer_ppapi_host_->GetContainerForInstance(pp_instance());
  if (!container)
    return PP_ERROR_BADARGUMENT;
  // TODO(toyoshim) Remove following WebDocument object copy.
  WebDocument document = container->element().document();
  websocket_.reset(WebSocket::create(document, this));
  DCHECK(websocket_.get());
  if (!websocket_)
    return PP_ERROR_NOTSUPPORTED;

  // Set receiving binary object type.
  websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer);
  websocket_->connect(web_url, web_protocols);

  connect_reply_ = context->MakeReplyMessageContext();
  connecting_ = true;
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperWebSocketHost::OnHostMsgClose(
    ppapi::host::HostMessageContext* context,
    int32_t code,
    const std::string& reason) {
  if (!websocket_)
    return PP_ERROR_FAILED;
  close_reply_ = context->MakeReplyMessageContext();
  initiating_close_ = true;

  blink::WebSocket::CloseEventCode event_code =
      static_cast<blink::WebSocket::CloseEventCode>(code);
  if (code == PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED) {
    // PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED and CloseEventCodeNotSpecified are
    // assigned to different values. A conversion is needed if
    // PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED is specified.
    event_code = blink::WebSocket::CloseEventCodeNotSpecified;
  }

  WebString web_reason = WebString::fromUTF8(reason);
  websocket_->close(event_code, web_reason);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperWebSocketHost::OnHostMsgSendText(
    ppapi::host::HostMessageContext* context,
    const std::string& message) {
  if (websocket_) {
    WebString web_message = WebString::fromUTF8(message);
    websocket_->sendText(web_message);
  }
  return PP_OK;
}

int32_t PepperWebSocketHost::OnHostMsgSendBinary(
    ppapi::host::HostMessageContext* context,
    const std::vector<uint8_t>& message) {
  if (websocket_.get() && !message.empty()) {
    WebArrayBuffer web_message = WebArrayBuffer::create(message.size(), 1);
    memcpy(web_message.data(), &message.front(), message.size());
    websocket_->sendArrayBuffer(web_message);
  }
  return PP_OK;
}

int32_t PepperWebSocketHost::OnHostMsgFail(
    ppapi::host::HostMessageContext* context,
    const std::string& message) {
  if (websocket_)
    websocket_->fail(WebString::fromUTF8(message));
  return PP_OK;
}

}  // namespace content
<commit_msg>Change pepper websocket port check to use EffectiveIntPort.<commit_after>// Copyright (c) 2012 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 "content/renderer/pepper/pepper_websocket_host.h"

#include <string>

#include "content/public/renderer/renderer_ppapi_host.h"
#include "net/base/net_util.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_websocket.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebArrayBuffer.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
#include "third_party/WebKit/public/web/WebSocket.h"

using blink::WebArrayBuffer;
using blink::WebDocument;
using blink::WebString;
using blink::WebSocket;
using blink::WebURL;

namespace content {

#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name)                   \
  COMPILE_ASSERT(                                                            \
      static_cast<int>(WebSocket::webkit_name) == static_cast<int>(np_name), \
      mismatching_enums)

COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeNormalClosure,
                             PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeGoingAway,
                             PP_WEBSOCKETSTATUSCODE_GOING_AWAY);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeProtocolError,
                             PP_WEBSOCKETSTATUSCODE_PROTOCOL_ERROR);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeUnsupportedData,
                             PP_WEBSOCKETSTATUSCODE_UNSUPPORTED_DATA);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeNoStatusRcvd,
                             PP_WEBSOCKETSTATUSCODE_NO_STATUS_RECEIVED);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeAbnormalClosure,
                             PP_WEBSOCKETSTATUSCODE_ABNORMAL_CLOSURE);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeInvalidFramePayloadData,
                             PP_WEBSOCKETSTATUSCODE_INVALID_FRAME_PAYLOAD_DATA);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodePolicyViolation,
                             PP_WEBSOCKETSTATUSCODE_POLICY_VIOLATION);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMessageTooBig,
                             PP_WEBSOCKETSTATUSCODE_MESSAGE_TOO_BIG);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMandatoryExt,
                             PP_WEBSOCKETSTATUSCODE_MANDATORY_EXTENSION);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeInternalError,
                             PP_WEBSOCKETSTATUSCODE_INTERNAL_SERVER_ERROR);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeTLSHandshake,
                             PP_WEBSOCKETSTATUSCODE_TLS_HANDSHAKE);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMinimumUserDefined,
                             PP_WEBSOCKETSTATUSCODE_USER_REGISTERED_MIN);
COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMaximumUserDefined,
                             PP_WEBSOCKETSTATUSCODE_USER_PRIVATE_MAX);

PepperWebSocketHost::PepperWebSocketHost(RendererPpapiHost* host,
                                         PP_Instance instance,
                                         PP_Resource resource)
    : ResourceHost(host->GetPpapiHost(), instance, resource),
      renderer_ppapi_host_(host),
      connecting_(false),
      initiating_close_(false),
      accepting_close_(false),
      error_was_received_(false) {}

PepperWebSocketHost::~PepperWebSocketHost() {
  if (websocket_)
    websocket_->disconnect();
}

int32_t PepperWebSocketHost::OnResourceMessageReceived(
    const IPC::Message& msg,
    ppapi::host::HostMessageContext* context) {
  PPAPI_BEGIN_MESSAGE_MAP(PepperWebSocketHost, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Connect,
                                      OnHostMsgConnect)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Close,
                                      OnHostMsgClose)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_SendText,
                                      OnHostMsgSendText)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_SendBinary,
                                      OnHostMsgSendBinary)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Fail,
                                      OnHostMsgFail)
  PPAPI_END_MESSAGE_MAP()
  return PP_ERROR_FAILED;
}

void PepperWebSocketHost::didConnect() {
  std::string protocol;
  if (websocket_)
    protocol = websocket_->subprotocol().utf8();
  connecting_ = false;
  connect_reply_.params.set_result(PP_OK);
  host()->SendReply(connect_reply_,
                    PpapiPluginMsg_WebSocket_ConnectReply(url_, protocol));
}

void PepperWebSocketHost::didReceiveMessage(const blink::WebString& message) {
  // Dispose packets after receiving an error.
  if (error_was_received_)
    return;

  // Send an IPC to transport received data.
  std::string string_message = message.utf8();
  host()->SendUnsolicitedReply(
      pp_resource(), PpapiPluginMsg_WebSocket_ReceiveTextReply(string_message));
}

void PepperWebSocketHost::didReceiveArrayBuffer(
    const blink::WebArrayBuffer& binaryData) {
  // Dispose packets after receiving an error.
  if (error_was_received_)
    return;

  // Send an IPC to transport received data.
  uint8_t* data = static_cast<uint8_t*>(binaryData.data());
  std::vector<uint8_t> array_message(data, data + binaryData.byteLength());
  host()->SendUnsolicitedReply(
      pp_resource(),
      PpapiPluginMsg_WebSocket_ReceiveBinaryReply(array_message));
}

void PepperWebSocketHost::didReceiveMessageError() {
  // Records the error, then stops receiving any frames after this error.
  // The error must be notified after all queued messages are read.
  error_was_received_ = true;

  // Send an IPC to report the error. After this IPC, ReceiveTextReply and
  // ReceiveBinaryReply IPC are not sent anymore because |error_was_received_|
  // blocks.
  host()->SendUnsolicitedReply(pp_resource(),
                               PpapiPluginMsg_WebSocket_ErrorReply());
}

void PepperWebSocketHost::didUpdateBufferedAmount(
    unsigned long buffered_amount) {
  // Send an IPC to update buffered amount.
  host()->SendUnsolicitedReply(
      pp_resource(),
      PpapiPluginMsg_WebSocket_BufferedAmountReply(buffered_amount));
}

void PepperWebSocketHost::didStartClosingHandshake() {
  accepting_close_ = true;

  // Send an IPC to notice that server starts closing handshake.
  host()->SendUnsolicitedReply(
      pp_resource(),
      PpapiPluginMsg_WebSocket_StateReply(PP_WEBSOCKETREADYSTATE_CLOSING));
}

void PepperWebSocketHost::didClose(unsigned long unhandled_buffered_amount,
                                   ClosingHandshakeCompletionStatus status,
                                   unsigned short code,
                                   const blink::WebString& reason) {
  if (connecting_) {
    connecting_ = false;
    connect_reply_.params.set_result(PP_ERROR_FAILED);
    host()->SendReply(
        connect_reply_,
        PpapiPluginMsg_WebSocket_ConnectReply(url_, std::string()));
  }

  // Set close_was_clean_.
  bool was_clean = (initiating_close_ || accepting_close_) &&
                   !unhandled_buffered_amount &&
                   status == WebSocketClient::ClosingHandshakeComplete;

  if (initiating_close_) {
    initiating_close_ = false;
    close_reply_.params.set_result(PP_OK);
    host()->SendReply(
        close_reply_,
        PpapiPluginMsg_WebSocket_CloseReply(
            unhandled_buffered_amount, was_clean, code, reason.utf8()));
  } else {
    accepting_close_ = false;
    host()->SendUnsolicitedReply(
        pp_resource(),
        PpapiPluginMsg_WebSocket_ClosedReply(
            unhandled_buffered_amount, was_clean, code, reason.utf8()));
  }

  // Disconnect.
  if (websocket_) {
    websocket_->disconnect();
    websocket_.reset();
  }
}

int32_t PepperWebSocketHost::OnHostMsgConnect(
    ppapi::host::HostMessageContext* context,
    const std::string& url,
    const std::vector<std::string>& protocols) {
  // Validate url and convert it to WebURL.
  GURL gurl(url);
  url_ = gurl.spec();
  if (!gurl.is_valid())
    return PP_ERROR_BADARGUMENT;
  if (!gurl.SchemeIs("ws") && !gurl.SchemeIs("wss"))
    return PP_ERROR_BADARGUMENT;
  if (gurl.has_ref())
    return PP_ERROR_BADARGUMENT;
  if (!net::IsPortAllowedByDefault(gurl.EffectiveIntPort()))
    return PP_ERROR_BADARGUMENT;
  WebURL web_url(gurl);

  // Validate protocols.
  std::string protocol_string;
  for (std::vector<std::string>::const_iterator vector_it = protocols.begin();
       vector_it != protocols.end();
       ++vector_it) {

    // Check containing characters.
    for (std::string::const_iterator string_it = vector_it->begin();
         string_it != vector_it->end();
         ++string_it) {
      uint8_t character = *string_it;
      // WebSocket specification says "(Subprotocol string must consist of)
      // characters in the range U+0021 to U+007E not including separator
      // characters as defined in [RFC2616]."
      const uint8_t minimumProtocolCharacter = '!';  // U+0021.
      const uint8_t maximumProtocolCharacter = '~';  // U+007E.
      if (character < minimumProtocolCharacter ||
          character > maximumProtocolCharacter || character == '"' ||
          character == '(' || character == ')' || character == ',' ||
          character == '/' ||
          (character >= ':' && character <= '@') ||  // U+003A - U+0040
          (character >= '[' && character <= ']') ||  // U+005B - u+005D
          character == '{' ||
          character == '}')
        return PP_ERROR_BADARGUMENT;
    }
    // Join protocols with the comma separator.
    if (vector_it != protocols.begin())
      protocol_string.append(",");
    protocol_string.append(*vector_it);
  }

  // Convert protocols to WebString.
  WebString web_protocols = WebString::fromUTF8(protocol_string);

  // Create blink::WebSocket object and connect.
  blink::WebPluginContainer* container =
      renderer_ppapi_host_->GetContainerForInstance(pp_instance());
  if (!container)
    return PP_ERROR_BADARGUMENT;
  // TODO(toyoshim) Remove following WebDocument object copy.
  WebDocument document = container->element().document();
  websocket_.reset(WebSocket::create(document, this));
  DCHECK(websocket_.get());
  if (!websocket_)
    return PP_ERROR_NOTSUPPORTED;

  // Set receiving binary object type.
  websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer);
  websocket_->connect(web_url, web_protocols);

  connect_reply_ = context->MakeReplyMessageContext();
  connecting_ = true;
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperWebSocketHost::OnHostMsgClose(
    ppapi::host::HostMessageContext* context,
    int32_t code,
    const std::string& reason) {
  if (!websocket_)
    return PP_ERROR_FAILED;
  close_reply_ = context->MakeReplyMessageContext();
  initiating_close_ = true;

  blink::WebSocket::CloseEventCode event_code =
      static_cast<blink::WebSocket::CloseEventCode>(code);
  if (code == PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED) {
    // PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED and CloseEventCodeNotSpecified are
    // assigned to different values. A conversion is needed if
    // PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED is specified.
    event_code = blink::WebSocket::CloseEventCodeNotSpecified;
  }

  WebString web_reason = WebString::fromUTF8(reason);
  websocket_->close(event_code, web_reason);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperWebSocketHost::OnHostMsgSendText(
    ppapi::host::HostMessageContext* context,
    const std::string& message) {
  if (websocket_) {
    WebString web_message = WebString::fromUTF8(message);
    websocket_->sendText(web_message);
  }
  return PP_OK;
}

int32_t PepperWebSocketHost::OnHostMsgSendBinary(
    ppapi::host::HostMessageContext* context,
    const std::vector<uint8_t>& message) {
  if (websocket_.get() && !message.empty()) {
    WebArrayBuffer web_message = WebArrayBuffer::create(message.size(), 1);
    memcpy(web_message.data(), &message.front(), message.size());
    websocket_->sendArrayBuffer(web_message);
  }
  return PP_OK;
}

int32_t PepperWebSocketHost::OnHostMsgFail(
    ppapi::host::HostMessageContext* context,
    const std::string& message) {
  if (websocket_)
    websocket_->fail(WebString::fromUTF8(message));
  return PP_OK;
}

}  // namespace content
<|endoftext|>


<commit_before>/**  Manages the event handling functions in the superloop
 *
 * StageManager.cpp
 * Created 1-28-18 By: Smitty
 *
 * A longer description.
 */

#include "StageManager.hpp"

/**
 * @brief  StageManager constructor
 */
StageManager::StageManager(void)
{
    timerList = new Timer[TIMER_NUM];
    timerList[0].limit = LED_1_POLL;
    timerList[1].limit = LED_2_POLL;

    //initializing the variables in the Timer array
    for(int i = 0; i < TIMER_NUM; i++)
    {
        //creating the individual mask for each timer
        timerList[i].TFmask = 1 << i;
        timerList[i].count = 0;
    }
}

/**
 * @brief  Handles the multiple timers running off of a single 1ms timer from main
 * @note   Might have to be fleshed out more
 * @retval uint32_t with each bit coresponding to which timers went off
 */
uint32_t StageManager::processTimers(Stage currentStage)
{
    //Goes through the array of timers to increment their count and store which ones popped
    for (int i = 0; i < TIMER_NUM; i++)
    {
        timerList[i].count++;
        if(timerList[i].count >= timerList[i].limit)
        {
            //store which timer popped
            timerTF |= timerList[i].TFmask;

            //resetting the count of the timer that just popped
            timerList[i].count = 0;
        }

    }

    return timerTF;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processCan(Stage currentStage)
{
    //do CAN stuff
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processCooling(Stage currentStage)
{
    //do Cooling stuff
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processDash(Stage currentStage)
{
    //do Dash processing

    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processGlcd(Stage currentStage)
{
    //glcd view display updating

    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processImd(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processOrion(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processPedal(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processSdCard(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processUnitek(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processBatlog(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processPrecharge(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processReadyToDrive(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processLaunch(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processShutdown(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note   Entry condition: EVOS finishes subsystem testing
 *         Exit condition:  Driver requests Precharging
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsStandby(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_STANDBY;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:

            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:

            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:

            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

        break;

    } //End switch

    return currentStage;
}

/**
 * @brief
 * @note   Entry condition: Driver requests Precharging
 *         Exit condition:  Precharge done signal recieved from Unitek
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsPrecharge(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_PRECHARGE;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:
            //code here
            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:
            //code here
            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:
            //code here

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:
            //code here
            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

        break;

    } //End switch

    return currentStage;
}

/**
 * @brief
 * @note   Entry condition: Precharge done signal recieved from Unitek
 *         Exit condition:  Driver requests ready to drive
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsEnergized(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_ENERGIZED;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:
            //code here
            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:
            //code here
            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:
            //code here

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:
            //code here
            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

        break;

    } //End switch

    return currentStage;
}

/**
 * @brief
 * @note   Entry condition: Driver requests ready to drive
 *         Exit condition:  Driver requests standby
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsDriving(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_STANDBY;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:
            //code here
            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:
            //code here
            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:
            //code here

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:
            //code here
            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

        break;

    } //End switch

    return currentStage;
}<commit_msg>#25 processPedal function skeleton<commit_after>/**  Manages the event handling functions in the superloop
 *
 * StageManager.cpp
 * Created 1-28-18 By: Smitty
 *
 * A longer description.
 */

#include "StageManager.hpp"

/**
 * @brief  StageManager constructor
 */
StageManager::StageManager(void)
{
    timerList = new Timer[TIMER_NUM];
    timerList[0].limit = LED_1_POLL;
    timerList[1].limit = LED_2_POLL;

    //initializing the variables in the Timer array
    for(int i = 0; i < TIMER_NUM; i++)
    {
        //creating the individual mask for each timer
        timerList[i].TFmask = 1 << i;
        timerList[i].count = 0;
    }
}

/**
 * @brief  Handles the multiple timers running off of a single 1ms timer from main
 * @note   Might have to be fleshed out more
 * @retval uint32_t with each bit coresponding to which timers went off
 */
uint32_t StageManager::processTimers(Stage currentStage)
{
    //Goes through the array of timers to increment their count and store which ones popped
    for (int i = 0; i < TIMER_NUM; i++)
    {
        timerList[i].count++;
        if(timerList[i].count >= timerList[i].limit)
        {
            //store which timer popped
            timerTF |= timerList[i].TFmask;

            //resetting the count of the timer that just popped
            timerList[i].count = 0;
        }

    }

    return timerTF;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processCan(Stage currentStage)
{
    //do CAN stuff
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processCooling(Stage currentStage)
{
    //do Cooling stuff
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processDash(Stage currentStage)
{
    //do Dash processing

    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processGlcd(Stage currentStage)
{
    //glcd view display updating

    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processImd(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processOrion(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processPedal(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processSdCard(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processUnitek(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processBatlog(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processPrecharge(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processReadyToDrive(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processLaunch(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note
 * @retval
 */
uint32_t StageManager::processShutdown(Stage currentStage)
{
    return 0;
}

/**
 * @brief
 * @note   Entry condition: EVOS finishes subsystem testing
 *         Exit condition:  Driver requests Precharging
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsStandby(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_STANDBY;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:

            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:

            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:

            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

        break;

    } //End switch

    return currentStage;
}

/**
 * @brief
 * @note   Entry condition: Driver requests Precharging
 *         Exit condition:  Precharge done signal recieved from Unitek
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsPrecharge(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_PRECHARGE;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:
            //code here
            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:
            //code here
            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:
            //code here

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:
            //code here
            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

        break;

    } //End switch

    return currentStage;
}

/**
 * @brief
 * @note   Entry condition: Precharge done signal recieved from Unitek
 *         Exit condition:  Driver requests ready to drive
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsEnergized(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_ENERGIZED;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:
            //code here
            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:
            //code here
            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:
            //code here

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:
            //code here
            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

        break;

    } //End switch

    return currentStage;
}

/**
 * @brief
 * @note   Entry condition: Driver requests ready to drive
 *         Exit condition:  Driver requests standby
 * @param  &localEventFlags:
 * @param  urgencyLevel:
 * @retval
 */
StageManager::Stage StageManager::processEventsDriving(uint32_t &localEventFlags, Priority urgencyLevel)
{
    Stage currentStage = Stage::STAGE_STANDBY;

    switch(urgencyLevel)
    {
        case PRIORITY_CRITICAL:
            //code here
            if(localEventFlags && EF_SHUTDOWN)
            {
                processShutdown(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_SHUTDOWN;
            }

            if(localEventFlags && EF_IMD)
            {
                processImd(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_IMD;
            }

        break;

        case PRIORITY_HIGH:
            //code here
            if(localEventFlags && EF_CAN)
            {
                processCan(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_CAN;
            }

            if(localEventFlags && EF_UNITEK)
            {
                processUnitek(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_UNITEK;
            }

            if(localEventFlags && EF_ORION)
            {
                processOrion(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_ORION;
            }

        break;

        case PRIORITY_MEDIUM:
            //code here

             if(localEventFlags && EF_COOLING)
            {
                processCooling(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_COOLING;
            }

            if(localEventFlags && EF_BATLOG)
            {
                processBatlog(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_BATLOG;
            }

            if(localEventFlags && EF_DASH)
            {
                processDash(currentStage);

                //clearing the EF so we don't trigger this again
                localEventFlags &= ~EF_DASH;
            }

        break;

        case PRIORITY_LOW:
            //code here
            if(localEventFlags && TF_PEDAL)
            {
                processPedal(currentStage);

                //clearing the Flag so we don't trigger this again
                localEventFlags &= ~TF_PEDAL;
            }

            if(localEventFlags && TF_GLCD)
            {
                processGlcd(currentStage);

                //clearing the Flag so we don't trigger this again
                localEventFlags &= ~TF_GLCD;
            }

            if(localEventFlags && TF_SDCARD)
            {
                processSdCard(currentStage);

                //clearing the Flag so we don't trigger this again
                localEventFlags &= ~TF_SDCARD;
            }

        break;

    } //End switch

    return currentStage;
}<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#ifndef mitkCLVoxeFeatures_cpp
#define mitkCLVoxeFeatures_cpp

#include "time.h"
#include <sstream>
#include <fstream>

#include <mitkIOUtil.h>
#include <mitkImageAccessByItk.h>
#include <mitkImageCast.h>
#include "mitkCommandLineParser.h"

#include <mitkGIFCooccurenceMatrix.h>
#include <mitkGIFGrayLevelRunLength.h>

#include "itkDiscreteGaussianImageFilter.h"
#include <itkLaplacianRecursiveGaussianImageFilter.h>
#include "itkHessianRecursiveGaussianImageFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "vnl/algo/vnl_symmetric_eigensystem.h"
#include <itkSubtractImageFilter.h>

static vector<double> splitDouble(string str, char delimiter) {
  vector<double> internal;
  stringstream ss(str); // Turn the string into a stream.
  string tok;
  double val;
  while(getline(ss, tok, delimiter)) {
    stringstream s2(tok);
    s2 >> val;
    internal.push_back(val);
  }

  return internal;
}

namespace Functor
{
  template <class TInput, class TOutput>
  class MatrixFirstEigenvalue
  {
  public:
    MatrixFirstEigenvalue() {}
    virtual ~MatrixFirstEigenvalue() {}

    int order;

    inline TOutput operator ()(const TInput& input)
    {
      double a,b,c;
      if (input[0] < 0.01 && input[1] < 0.01 &&input[2] < 0.01 &&input[3] < 0.01 &&input[4] < 0.01 &&input[5] < 0.01)
        return 0;
      vnl_symmetric_eigensystem_compute_eigenvals(input[0], input[1],input[2],input[3],input[4],input[5],a,b,c);
      switch (order)
      {
      case 0: return a;
      case 1: return b;
      case 2: return c;
      default: return a;
      }
    }
    bool operator !=(const MatrixFirstEigenvalue) const
    {
      return false;
    }
    bool operator ==(const MatrixFirstEigenvalue& other) const
    {
      return !(*this != other);
    }
  };
}

template<typename TPixel, unsigned int VImageDimension>
void
  GaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType >  GaussFilterType;

  typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New();
  gaussianFilter->SetInput( itkImage );
  gaussianFilter->SetVariance(variance);
  gaussianFilter->Update();
  mitk::CastToMitkImage(gaussianFilter->GetOutput(), output);
}

template<typename TPixel, unsigned int VImageDimension>
void
  DifferenceOfGaussFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType >  GaussFilterType;
  typedef itk::SubtractImageFilter<ImageType, ImageType, ImageType> SubFilterType;

  typename GaussFilterType::Pointer gaussianFilter1 = GaussFilterType::New();
  gaussianFilter1->SetInput( itkImage );
  gaussianFilter1->SetVariance(variance);
  gaussianFilter1->Update();
  typename GaussFilterType::Pointer gaussianFilter2 = GaussFilterType::New();
  gaussianFilter2->SetInput( itkImage );
  gaussianFilter2->SetVariance(variance*0.66*0.66);
  gaussianFilter2->Update();
  typename SubFilterType::Pointer subFilter = SubFilterType::New();
  subFilter->SetInput1(gaussianFilter1->GetOutput());
  subFilter->SetInput2(gaussianFilter2->GetOutput());
  subFilter->Update();
  mitk::CastToMitkImage(subFilter->GetOutput(), output);
}

template<typename TPixel, unsigned int VImageDimension>
void
  LaplacianOfGaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType >  GaussFilterType;
  typedef itk::LaplacianRecursiveGaussianImageFilter<ImageType, ImageType>    LaplacianFilter;

  typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New();
  gaussianFilter->SetInput( itkImage );
  gaussianFilter->SetVariance(variance);
  gaussianFilter->Update();
  typename LaplacianFilter::Pointer laplaceFilter = LaplacianFilter::New();
  laplaceFilter->SetInput(gaussianFilter->GetOutput());
  laplaceFilter->Update();
  mitk::CastToMitkImage(laplaceFilter->GetOutput(), output);
}

template<typename TPixel, unsigned int VImageDimension>
void
  HessianOfGaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, std::vector<mitk::Image::Pointer> &out)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::Image<double, VImageDimension> FloatImageType;
  typedef itk::HessianRecursiveGaussianImageFilter <ImageType> HessianFilterType;
  typedef typename HessianFilterType::OutputImageType VectorImageType;
  typedef Functor::MatrixFirstEigenvalue<VectorImageType::PixelType, double> DeterminantFunctorType;
  typedef itk::UnaryFunctorImageFilter<VectorImageType, FloatImageType, DeterminantFunctorType> DetFilterType;

  typename HessianFilterType::Pointer hessianFilter = HessianFilterType::New();
  hessianFilter->SetInput(itkImage);
  hessianFilter->SetSigma(std::sqrt(variance));
  for (int i = 0; i < VImageDimension; ++i)
  {
    typename DetFilterType::Pointer detFilter = DetFilterType::New();
    detFilter->SetInput(hessianFilter->GetOutput());
    detFilter->GetFunctor().order = i;
    detFilter->Update();
    mitk::CastToMitkImage(detFilter->GetOutput(), out[i]);
  }
}

int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setArgumentPrefix("--", "-");
  // required params
  parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to the input VTK polydata", us::Any(), false);
  parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output text file", "Target file. The output statistic is appended to this file.", us::Any(), false);

  parser.addArgument("gaussian","g",mitkCommandLineParser::String, "Gaussian Filtering of the input images", "Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  parser.addArgument("difference-of-gaussian","dog",mitkCommandLineParser::String, "Difference of Gaussian Filtering of the input images", "Difference of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  parser.addArgument("laplace-of-gauss","log",mitkCommandLineParser::String, "Laplacian of Gaussian Filtering", "Laplacian of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  parser.addArgument("hessian-of-gauss","hog",mitkCommandLineParser::String, "Hessian of Gaussian Filtering", "Hessian of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  // Miniapp Infos
  parser.setCategory("Classification Tools");
  parser.setTitle("Global Image Feature calculator");
  parser.setDescription("Calculates different global statistics for a given segmentation / image combination");
  parser.setContributor("MBI");

  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);

  if (parsedArgs.size()==0)
  {
    return EXIT_FAILURE;
  }
  if ( parsedArgs.count("help") || parsedArgs.count("h"))
  {
    return EXIT_SUCCESS;
  }
  bool useCooc = parsedArgs.count("cooccurence");

  mitk::Image::Pointer image = mitk::IOUtil::LoadImage(parsedArgs["image"].ToString());
  std::string filename=parsedArgs["output"].ToString();

  ////////////////////////////////////////////////////////////////
  // CAlculate Gaussian Features
  ////////////////////////////////////////////////////////////////
  MITK_INFO << "Check for Gaussian...";
  if (parsedArgs.count("gaussian"))
  {
    MITK_INFO << "Calculate Gaussian... " << parsedArgs["gaussian"].ToString();
    auto ranges = splitDouble(parsedArgs["gaussian"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      mitk::Image::Pointer output;
      AccessByItk_2(image, GaussianFilter, ranges[i], output);
      std::string name = filename + "-gaussian-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(output, name);
    }
  }

  ////////////////////////////////////////////////////////////////
  // CAlculate Difference of Gaussian Features
  ////////////////////////////////////////////////////////////////
  MITK_INFO << "Check for DoG...";
  if (parsedArgs.count("difference-of-gaussian"))
  {
    MITK_INFO << "Calculate Difference of Gaussian... " << parsedArgs["difference-of-gaussian"].ToString();
    auto ranges = splitDouble(parsedArgs["difference-of-gaussian"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      mitk::Image::Pointer output;
      AccessByItk_2(image, DifferenceOfGaussFilter, ranges[i], output);
      std::string name = filename + "-dog-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(output, name);
    }
  }

  MITK_INFO << "Check for LoG...";
  ////////////////////////////////////////////////////////////////
  // CAlculate Laplacian Of Gauss Features
  ////////////////////////////////////////////////////////////////
  if (parsedArgs.count("laplace-of-gauss"))
  {
    MITK_INFO << "Calculate LoG... " << parsedArgs["laplace-of-gauss"].ToString();
    auto ranges = splitDouble(parsedArgs["laplace-of-gauss"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      mitk::Image::Pointer output;
      AccessByItk_2(image, LaplacianOfGaussianFilter, ranges[i], output);
      std::string name = filename + "-log-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(output, name);
    }
  }

  MITK_INFO << "Check for HoG...";
  ////////////////////////////////////////////////////////////////
  // CAlculate Hessian Of Gauss Features
  ////////////////////////////////////////////////////////////////
  if (parsedArgs.count("hessian-of-gauss"))
  {
    MITK_INFO << "Calculate HoG... " << parsedArgs["hessian-of-gauss"].ToString();
    auto ranges = splitDouble(parsedArgs["hessian-of-gauss"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      std::vector<mitk::Image::Pointer> outs;
      outs.push_back(mitk::Image::New());
      outs.push_back(mitk::Image::New());
      outs.push_back(mitk::Image::New());
      AccessByItk_2(image, HessianOfGaussianFilter, ranges[i], outs);
      std::string name = filename + "-hog0-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(outs[0], name);
      name = filename + "-hog1-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(outs[1], name);
      name = filename + "-hog2-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(outs[2], name);
    }
  }

  return 0;
}

#endif<commit_msg>COMP: Fixed missing typename<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#ifndef mitkCLVoxeFeatures_cpp
#define mitkCLVoxeFeatures_cpp

#include "time.h"
#include <sstream>
#include <fstream>

#include <mitkIOUtil.h>
#include <mitkImageAccessByItk.h>
#include <mitkImageCast.h>
#include "mitkCommandLineParser.h"

#include <mitkGIFCooccurenceMatrix.h>
#include <mitkGIFGrayLevelRunLength.h>

#include "itkDiscreteGaussianImageFilter.h"
#include <itkLaplacianRecursiveGaussianImageFilter.h>
#include "itkHessianRecursiveGaussianImageFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "vnl/algo/vnl_symmetric_eigensystem.h"
#include <itkSubtractImageFilter.h>

static vector<double> splitDouble(string str, char delimiter) {
  vector<double> internal;
  stringstream ss(str); // Turn the string into a stream.
  string tok;
  double val;
  while(getline(ss, tok, delimiter)) {
    stringstream s2(tok);
    s2 >> val;
    internal.push_back(val);
  }

  return internal;
}

namespace Functor
{
  template <class TInput, class TOutput>
  class MatrixFirstEigenvalue
  {
  public:
    MatrixFirstEigenvalue() {}
    virtual ~MatrixFirstEigenvalue() {}

    int order;

    inline TOutput operator ()(const TInput& input)
    {
      double a,b,c;
      if (input[0] < 0.01 && input[1] < 0.01 &&input[2] < 0.01 &&input[3] < 0.01 &&input[4] < 0.01 &&input[5] < 0.01)
        return 0;
      vnl_symmetric_eigensystem_compute_eigenvals(input[0], input[1],input[2],input[3],input[4],input[5],a,b,c);
      switch (order)
      {
      case 0: return a;
      case 1: return b;
      case 2: return c;
      default: return a;
      }
    }
    bool operator !=(const MatrixFirstEigenvalue) const
    {
      return false;
    }
    bool operator ==(const MatrixFirstEigenvalue& other) const
    {
      return !(*this != other);
    }
  };
}

template<typename TPixel, unsigned int VImageDimension>
void
  GaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType >  GaussFilterType;

  typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New();
  gaussianFilter->SetInput( itkImage );
  gaussianFilter->SetVariance(variance);
  gaussianFilter->Update();
  mitk::CastToMitkImage(gaussianFilter->GetOutput(), output);
}

template<typename TPixel, unsigned int VImageDimension>
void
  DifferenceOfGaussFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType >  GaussFilterType;
  typedef itk::SubtractImageFilter<ImageType, ImageType, ImageType> SubFilterType;

  typename GaussFilterType::Pointer gaussianFilter1 = GaussFilterType::New();
  gaussianFilter1->SetInput( itkImage );
  gaussianFilter1->SetVariance(variance);
  gaussianFilter1->Update();
  typename GaussFilterType::Pointer gaussianFilter2 = GaussFilterType::New();
  gaussianFilter2->SetInput( itkImage );
  gaussianFilter2->SetVariance(variance*0.66*0.66);
  gaussianFilter2->Update();
  typename SubFilterType::Pointer subFilter = SubFilterType::New();
  subFilter->SetInput1(gaussianFilter1->GetOutput());
  subFilter->SetInput2(gaussianFilter2->GetOutput());
  subFilter->Update();
  mitk::CastToMitkImage(subFilter->GetOutput(), output);
}

template<typename TPixel, unsigned int VImageDimension>
void
  LaplacianOfGaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType >  GaussFilterType;
  typedef itk::LaplacianRecursiveGaussianImageFilter<ImageType, ImageType>    LaplacianFilter;

  typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New();
  gaussianFilter->SetInput( itkImage );
  gaussianFilter->SetVariance(variance);
  gaussianFilter->Update();
  typename LaplacianFilter::Pointer laplaceFilter = LaplacianFilter::New();
  laplaceFilter->SetInput(gaussianFilter->GetOutput());
  laplaceFilter->Update();
  mitk::CastToMitkImage(laplaceFilter->GetOutput(), output);
}

template<typename TPixel, unsigned int VImageDimension>
void
  HessianOfGaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, std::vector<mitk::Image::Pointer> &out)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::Image<double, VImageDimension> FloatImageType;
  typedef itk::HessianRecursiveGaussianImageFilter <ImageType> HessianFilterType;
  typedef typename HessianFilterType::OutputImageType VectorImageType;
  typedef Functor::MatrixFirstEigenvalue<typename VectorImageType::PixelType, double> DeterminantFunctorType;
  typedef itk::UnaryFunctorImageFilter<VectorImageType, FloatImageType, DeterminantFunctorType> DetFilterType;

  typename HessianFilterType::Pointer hessianFilter = HessianFilterType::New();
  hessianFilter->SetInput(itkImage);
  hessianFilter->SetSigma(std::sqrt(variance));
  for (int i = 0; i < VImageDimension; ++i)
  {
    typename DetFilterType::Pointer detFilter = DetFilterType::New();
    detFilter->SetInput(hessianFilter->GetOutput());
    detFilter->GetFunctor().order = i;
    detFilter->Update();
    mitk::CastToMitkImage(detFilter->GetOutput(), out[i]);
  }
}

int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setArgumentPrefix("--", "-");
  // required params
  parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to the input VTK polydata", us::Any(), false);
  parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output text file", "Target file. The output statistic is appended to this file.", us::Any(), false);

  parser.addArgument("gaussian","g",mitkCommandLineParser::String, "Gaussian Filtering of the input images", "Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  parser.addArgument("difference-of-gaussian","dog",mitkCommandLineParser::String, "Difference of Gaussian Filtering of the input images", "Difference of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  parser.addArgument("laplace-of-gauss","log",mitkCommandLineParser::String, "Laplacian of Gaussian Filtering", "Laplacian of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  parser.addArgument("hessian-of-gauss","hog",mitkCommandLineParser::String, "Hessian of Gaussian Filtering", "Hessian of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any());
  // Miniapp Infos
  parser.setCategory("Classification Tools");
  parser.setTitle("Global Image Feature calculator");
  parser.setDescription("Calculates different global statistics for a given segmentation / image combination");
  parser.setContributor("MBI");

  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);

  if (parsedArgs.size()==0)
  {
    return EXIT_FAILURE;
  }
  if ( parsedArgs.count("help") || parsedArgs.count("h"))
  {
    return EXIT_SUCCESS;
  }
  bool useCooc = parsedArgs.count("cooccurence");

  mitk::Image::Pointer image = mitk::IOUtil::LoadImage(parsedArgs["image"].ToString());
  std::string filename=parsedArgs["output"].ToString();

  ////////////////////////////////////////////////////////////////
  // CAlculate Gaussian Features
  ////////////////////////////////////////////////////////////////
  MITK_INFO << "Check for Gaussian...";
  if (parsedArgs.count("gaussian"))
  {
    MITK_INFO << "Calculate Gaussian... " << parsedArgs["gaussian"].ToString();
    auto ranges = splitDouble(parsedArgs["gaussian"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      mitk::Image::Pointer output;
      AccessByItk_2(image, GaussianFilter, ranges[i], output);
      std::string name = filename + "-gaussian-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(output, name);
    }
  }

  ////////////////////////////////////////////////////////////////
  // CAlculate Difference of Gaussian Features
  ////////////////////////////////////////////////////////////////
  MITK_INFO << "Check for DoG...";
  if (parsedArgs.count("difference-of-gaussian"))
  {
    MITK_INFO << "Calculate Difference of Gaussian... " << parsedArgs["difference-of-gaussian"].ToString();
    auto ranges = splitDouble(parsedArgs["difference-of-gaussian"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      mitk::Image::Pointer output;
      AccessByItk_2(image, DifferenceOfGaussFilter, ranges[i], output);
      std::string name = filename + "-dog-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(output, name);
    }
  }

  MITK_INFO << "Check for LoG...";
  ////////////////////////////////////////////////////////////////
  // CAlculate Laplacian Of Gauss Features
  ////////////////////////////////////////////////////////////////
  if (parsedArgs.count("laplace-of-gauss"))
  {
    MITK_INFO << "Calculate LoG... " << parsedArgs["laplace-of-gauss"].ToString();
    auto ranges = splitDouble(parsedArgs["laplace-of-gauss"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      mitk::Image::Pointer output;
      AccessByItk_2(image, LaplacianOfGaussianFilter, ranges[i], output);
      std::string name = filename + "-log-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(output, name);
    }
  }

  MITK_INFO << "Check for HoG...";
  ////////////////////////////////////////////////////////////////
  // CAlculate Hessian Of Gauss Features
  ////////////////////////////////////////////////////////////////
  if (parsedArgs.count("hessian-of-gauss"))
  {
    MITK_INFO << "Calculate HoG... " << parsedArgs["hessian-of-gauss"].ToString();
    auto ranges = splitDouble(parsedArgs["hessian-of-gauss"].ToString(),';');

    for (int i = 0; i < ranges.size(); ++i)
    {
      std::vector<mitk::Image::Pointer> outs;
      outs.push_back(mitk::Image::New());
      outs.push_back(mitk::Image::New());
      outs.push_back(mitk::Image::New());
      AccessByItk_2(image, HessianOfGaussianFilter, ranges[i], outs);
      std::string name = filename + "-hog0-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(outs[0], name);
      name = filename + "-hog1-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(outs[1], name);
      name = filename + "-hog2-" + us::any_value_to_string(ranges[i])+".nrrd";
      mitk::IOUtil::SaveImage(outs[2], name);
    }
  }

  return 0;
}

#endif<|endoftext|>