<commit_before>/*****************************************************************************\

Name:   simple_frontend.cxx
Author: Matthias W. Smith
Email:  mwsmith2@uw.edu

About:  A simple example frontend that generates a random point.

\*****************************************************************************/

//--- std includes ----------------------------------------------------------//
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <random>
#include <sys/time.h>
using std::string;

//--- other includes --------------------------------------------------------//
#include "midas.h"

//--- project includes ------------------------------------------------------//
#include "frontend_utils.hh"
#include "field_structs.hh"

//--- globals ---------------------------------------------------------------//

// @EXAMPLE BEGIN
#define FRONTEND_NAME "Simple Frontend" // Prefer capitalize with spaces
const char * const bank_name = "SMFE"; // 4 letters, try to make sensible

// Any structs need to be defined.
BANK_LIST trigger_bank_list[] = {
  {bank_name, TID_STRUCT, sizeof(g2::point_t), g2::point_str_midas}
  ,
  {""}
};
// @EXAMPLE END

extern "C" {

  // The frontend name (client name) as seen by other MIDAS clients
  char *frontend_name = (char*)FRONTEND_NAME;

  // The frontend file name, don't change it.
  char *frontend_file_name = (char*)__FILE__;

  // frontend_loop is called periodically if this variable is TRUE
  BOOL frontend_call_loop = FALSE;

  // A frontend status page is displayed with this frequency in ms.
  INT display_period = 1000;

  // maximum event size produced by this frontend
  INT max_event_size = 0x8000; // 32 kB @EXAMPLE - adjust if neeeded

  // maximum event size for fragmented events (EQ_FRAGMENTED)
  INT max_event_size_frag = 0x800000; // DEPRECATED

  // buffer size to hold events
  INT event_buffer_size = 0x800000;

  // Function declarations
  INT frontend_init();
  INT frontend_exit();
  INT begin_of_run(INT run_number, char *error);
  INT end_of_run(INT run_number, char *error);
  INT pause_run(INT run_number, char *error);
  INT resume_run(INT run_number, char *error);

  INT frontend_loop();
  INT read_trigger_event(char *pevent, INT off);
  INT poll_event(INT source, INT count, BOOL test);
  INT interrupt_configure(INT cmd, INT source, PTYPE adr);

  // Equipment list @EXAMPLE BEGIN

  EQUIPMENT equipment[] =
    {
      {FRONTEND_NAME,   // equipment name
       { 10, 0,         // event ID, trigger mask
         "SYSTEM",      // event buffer (used to be SYSTEM)
         EQ_POLLED,     // equipment type
         0,             // not used
         "MIDAS",       // format
         TRUE,          // enabled
         RO_RUNNING,    // read only when running
         5,           // poll for 5 ms
         0,             // stop run after this event limit
         0,             // number of sub events
         1,             // don't log history
         "", "", "",
       },
       read_trigger_event,      // readout routine
      },

      {""}
    };

} //extern C

// Put necessary globals in an anonomous namespace here.
namespace {
boost::property_tree::ptree conf;
boost::property_tree::ptree global_conf;
double point_min = 0.0;
double point_max = 1.0;
long long last_event;
long long next_event;
}

//--- Frontend Init ---------------------------------------------------------//
INT frontend_init()
{
  return SUCCESS;
}

//--- Frontend Exit ---------------------------------------------------------//
INT frontend_exit()
{
  return SUCCESS;
}

//--- Begin of Run ----------------------------------------------------------//
INT begin_of_run(INT run_number, char *error)
{

  int rc = load_global_settings(global_conf);
  if (rc != 0) {
    cm_msg(MERROR, "begin_of_run", "could not load global settings");
    return rc;
  }

  rc = load_settings(frontend_name, global_conf);
  if (rc != 0) {
    cm_msg(MERROR, "begin_of_run", "could not load equipment settings");
    return rc;
  }

  point_min = conf.get<double>("min");
  point_max = conf.get<double>("max");

  return SUCCESS;
}

//--- End of Run ------------------------------------------------------------//
INT end_of_run(INT run_number, char *error)
{
  return SUCCESS;
}

//--- Pause Run -------------------------------------------------------------//
INT pause_run(INT run_number, char *error)
{
  return SUCCESS;
}

//--- Resume Run ------------------------------------------------------------//
INT resume_run(INT run_number, char *error)
{
  return SUCCESS;
}

//--- Frontend Loop ---------------------------------------------------------//

INT frontend_loop()
{
  // If frontend_call_loop is true, this routine gets called when
  // the frontend is idle or once between every event
  return SUCCESS;
}

//---------------------------------------------------------------------------//

/****************************************************************************\

  Readout routines for different events

\*****************************************************************************/

//--- Trigger event routines ------------------------------------------------//

INT poll_event(INT source, INT count, BOOL test) {

  static unsigned int i;

  // fake calibration
  if (test) {
    for (i = 0; i < count; i++) {
      usleep(10);
    }

    last_event = steadyclock_us();

    return 0;
  }

  next_event = steadyclock_us();

  // Check hardware for events, just random here.
  if (next_event - last_event > 100000) {
    return 1;
  } else {
    return 0;
  }
}

//--- Interrupt configuration ---------------------------------------*/

INT interrupt_configure(INT cmd, INT source, PTYPE adr)
{
  switch (cmd) {
  case CMD_INTERRUPT_ENABLE:
    break;
  case CMD_INTERRUPT_DISABLE:
    break;
  case CMD_INTERRUPT_ATTACH:
    break;
  case CMD_INTERRUPT_DETACH:
    break;
  }
  return SUCCESS;
}

//--- Event readout -------------------------------------------------*/

INT read_trigger_event(char *pevent, INT off)
{
  g2::point_t *point;

  // And MIDAS output.
  bk_init32(pevent);

  // Let MIDAS allocate the struct.
  bk_create(pevent, bank_name, TID_STRUCT, &point);

  // Grab a timestamp.
  last_event = steadyclock_us();

  // Fill the struct.
  point->timestamp = last_event;
  point->x = (double)rand() / RAND_MAX * (point_max - point_min) + point_min;
  point->y = (double)rand() / RAND_MAX * (point_max - point_min) + point_min;
  point->z = (double)rand() / RAND_MAX * (point_max - point_min) + point_min;

  // Need to increment pointer and close.
  bk_close(pevent, ++point);

  return bk_size(pevent);
}
<commit_msg>Reverting banks back to casting bytes to structs.<commit_after>/*****************************************************************************\

Name:   simple_frontend.cxx
Author: Matthias W. Smith
Email:  mwsmith2@uw.edu

About:  A simple example frontend that generates a random point.

\*****************************************************************************/

//--- std includes ----------------------------------------------------------//
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <random>
#include <sys/time.h>
using std::string;

//--- other includes --------------------------------------------------------//
#include "midas.h"

//--- project includes ------------------------------------------------------//
#include "frontend_utils.hh"
#include "field_structs.hh"

//--- globals ---------------------------------------------------------------//

// @EXAMPLE BEGIN
#define FRONTEND_NAME "Simple Frontend" // Prefer capitalize with spaces
const char * const bank_name = "SMFE"; // 4 letters, try to make sensible

// Any structs need to be defined.
BANK_LIST trigger_bank_list[] = {
  {bank_name, TID_CHAR, sizeof(g2::point_t), NULL},
  {""}
};
// @EXAMPLE END

extern "C" {

  // The frontend name (client name) as seen by other MIDAS clients
  char *frontend_name = (char*)FRONTEND_NAME;

  // The frontend file name, don't change it.
  char *frontend_file_name = (char*)__FILE__;

  // frontend_loop is called periodically if this variable is TRUE
  BOOL frontend_call_loop = FALSE;

  // A frontend status page is displayed with this frequency in ms.
  INT display_period = 1000;

  // maximum event size produced by this frontend
  INT max_event_size = 0x8000; // 32 kB @EXAMPLE - adjust if neeeded

  // maximum event size for fragmented events (EQ_FRAGMENTED)
  INT max_event_size_frag = 0x800000; // DEPRECATED

  // buffer size to hold events
  INT event_buffer_size = 0x800000;

  // Function declarations
  INT frontend_init();
  INT frontend_exit();
  INT begin_of_run(INT run_number, char *error);
  INT end_of_run(INT run_number, char *error);
  INT pause_run(INT run_number, char *error);
  INT resume_run(INT run_number, char *error);

  INT frontend_loop();
  INT read_trigger_event(char *pevent, INT off);
  INT poll_event(INT source, INT count, BOOL test);
  INT interrupt_configure(INT cmd, INT source, PTYPE adr);

  // Equipment list @EXAMPLE BEGIN

  EQUIPMENT equipment[] =
    {
      {FRONTEND_NAME,   // equipment name
       { 10, 0,         // event ID, trigger mask
         "SYSTEM",      // event buffer (used to be SYSTEM)
         EQ_POLLED,     // equipment type
         0,             // not used
         "MIDAS",       // format
         TRUE,          // enabled
         RO_RUNNING,    // read only when running
         5,           // poll for 5 ms
         0,             // stop run after this event limit
         0,             // number of sub events
         1,             // don't log history
         "", "", "",
       },
       read_trigger_event,      // readout routine
       NULL,
       NULL,
       NULL,
      },

      {""}
    };

} //extern C

// Put necessary globals in an anonomous namespace here.
namespace {
boost::property_tree::ptree conf;
boost::property_tree::ptree global_conf;
double point_min = 0.0;
double point_max = 1.0;
long long last_event;
long long next_event;
}

//--- Frontend Init ---------------------------------------------------------//
INT frontend_init()
{
  return SUCCESS;
}

//--- Frontend Exit ---------------------------------------------------------//
INT frontend_exit()
{
  return SUCCESS;
}

//--- Begin of Run ----------------------------------------------------------//
INT begin_of_run(INT run_number, char *error)
{

  int rc = load_global_settings(global_conf);
  if (rc != 0) {
    cm_msg(MERROR, "begin_of_run", "could not load global settings");
    return rc;
  }

  rc = load_settings(frontend_name, global_conf);
  if (rc != 0) {
    cm_msg(MERROR, "begin_of_run", "could not load equipment settings");
    return rc;
  }

  point_min = conf.get<double>("min");
  point_max = conf.get<double>("max");

  return SUCCESS;
}

//--- End of Run ------------------------------------------------------------//
INT end_of_run(INT run_number, char *error)
{
  return SUCCESS;
}

//--- Pause Run -------------------------------------------------------------//
INT pause_run(INT run_number, char *error)
{
  return SUCCESS;
}

//--- Resume Run ------------------------------------------------------------//
INT resume_run(INT run_number, char *error)
{
  return SUCCESS;
}

//--- Frontend Loop ---------------------------------------------------------//

INT frontend_loop()
{
  // If frontend_call_loop is true, this routine gets called when
  // the frontend is idle or once between every event
  return SUCCESS;
}

//---------------------------------------------------------------------------//

/****************************************************************************\

  Readout routines for different events

\*****************************************************************************/

//--- Trigger event routines ------------------------------------------------//

INT poll_event(INT source, INT count, BOOL test) {

  static unsigned int i;

  // fake calibration
  if (test) {
    for (i = 0; i < count; i++) {
      usleep(10);
    }

    last_event = steadyclock_us();

    return 0;
  }

  next_event = steadyclock_us();

  // Check hardware for events, just random here.
  if (next_event - last_event > 100000) {
    return 1;
  } else {
    return 0;
  }
}

//--- Interrupt configuration ---------------------------------------*/

INT interrupt_configure(INT cmd, INT source, PTYPE adr)
{
  switch (cmd) {
  case CMD_INTERRUPT_ENABLE:
    break;
  case CMD_INTERRUPT_DISABLE:
    break;
  case CMD_INTERRUPT_ATTACH:
    break;
  case CMD_INTERRUPT_DETACH:
    break;
  }
  return SUCCESS;
}

//--- Event readout -------------------------------------------------*/

INT read_trigger_event(char *pevent, INT off)
{
  BYTE *pdata;
  g2::point_t point;

  // And MIDAS output.
  bk_init32(pevent);

  // Let MIDAS allocate the struct.
  bk_create(pevent, bank_name, TID_BYTE, &pdata);

  // Grab a timestamp.
  last_event = steadyclock_us();

  // Fill the struct.
  point.timestamp = last_event;
  point.x = (double)rand() / RAND_MAX * (point_max - point_min) + point_min;
  point.y = (double)rand() / RAND_MAX * (point_max - point_min) + point_min;
  point.z = (double)rand() / RAND_MAX * (point_max - point_min) + point_min;

  // Copy the struct
  memcpy(pdata, &point.timestamp, sizeof(point));
  pdata += sizeof(point);

  // Need to increment pointer and close.
  bk_close(pevent, pdata);

  return bk_size(pevent);
}
<|endoftext|>


<commit_before>/*
	Copyright (c) 2014, Madd Games.
	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.

	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 <Apoc/Thread/Thread.h>
#include <stdlib.h>

struct ThreadInfo
{
	ThreadHandler *handler;
	Thread *thread;
};

#ifdef _WIN32
DWORD ApocThreadProc(LPVOID pHandler)
#else
void* ApocThreadProc(void *pHandler)
#endif
{
	ThreadInfo *info = reinterpret_cast<ThreadInfo*>(pHandler);
	ThreadHandler *handler = info->handler;
	Thread *thread = info->thread;
	delete info;
	handler->startThread(thread);

#ifdef _WIN32
	return 0;
#else
	return NULL;
#endif
};

Thread::Thread(ThreadHandler *handler)
{
	threadHandler = handler;

	ThreadInfo *info = new ThreadInfo;
	info->handler = handler;
	info->thread = this;

#ifdef _WIN32
	sysThread = CreateThread(NULL, 0, ApocThreadProc, reinterpret_cast<LPVOID>(info), 0, NULL);
#else
	pthread_create(&sysThread, NULL, ApocThreadProc, reinterpret_cast<LPVOID>(info));
#endif
};

Thread::~Thread()
{
#ifdef _WIN32
	CloseHandle(sysThread);
#else

};
<commit_msg>Update Thread.cpp<commit_after>/*
	Copyright (c) 2014, Madd Games.
	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.

	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 <Apoc/Thread/Thread.h>
#include <stdlib.h>

#ifndef _WIN32
#include <signal.h>
#endif

struct ThreadInfo
{
	ThreadHandler *handler;
	Thread *thread;
};

#ifdef _WIN32
DWORD ApocThreadProc(LPVOID pHandler)
#else
void* ApocThreadProc(void *pHandler)
#endif
{
	ThreadInfo *info = reinterpret_cast<ThreadInfo*>(pHandler);
	ThreadHandler *handler = info->handler;
	Thread *thread = info->thread;
	delete info;
	handler->startThread(thread);

#ifdef _WIN32
	return 0;
#else
	return NULL;
#endif
};

Thread::Thread(ThreadHandler *handler)
{
	threadHandler = handler;

	ThreadInfo *info = new ThreadInfo;
	info->handler = handler;
	info->thread = this;

#ifdef _WIN32
	sysThread = CreateThread(NULL, 0, ApocThreadProc, reinterpret_cast<LPVOID>(info), 0, NULL);
#else
	pthread_create(&sysThread, NULL, ApocThreadProc, reinterpret_cast<LPVOID>(info));
#endif
};

Thread::~Thread()
{
#ifdef _WIN32
	TerminateThread(sysThread, 0);
#else
	pthread_kill(sysThread, SIGKILL);
#endif

	join();
	delete threadHandler;
};

void Thread::join()
{
#ifdef _WIN32
	WaitForSingleObject(sysThread, INFINITE);
	CloseHandler(sysThread);
#else
	pthread_join(sysThread, NULL);
#endif
};
<|endoftext|>


<commit_before>#include "iorequest.h"
#include <QtDebug>
#include "event.h"
#include "actions/action.h"

IORequest::IORequest(Player* source, IORequest::RequestType type, int refCount) :
    QObject(NULL),
    mRefCount(refCount),
    m_source(source),
    m_type(type),
    m_response(NULL)
{
}

IORequest::~IORequest()
{
}

IORequest::RequestType IORequest::type() const
{
    return m_type;
}

void IORequest::putExtra(const QString& key, const QVariant& value)
{
    m_extras.insert(key, value);
}

QVariant IORequest::extra(const QString& key) const
{
    Q_ASSERT(m_extras.contains(key));
    return m_extras.value(key);
}

void IORequest::setResponse(void* r)
{
    m_response = r;
}

void* IORequest::response() const
{
    return m_response;
}

void IORequest::clearRef()
{
    if (mRefCount-- <= 0)
        delete this;
}

<commit_msg>Fix memory leak: IORequest needed 3 calls (instead of 2) to deRef to delete itself<commit_after>#include "iorequest.h"
#include <QtDebug>
#include "event.h"
#include "actions/action.h"

IORequest::IORequest(Player* source, IORequest::RequestType type, int refCount) :
    QObject(NULL),
    mRefCount(refCount),
    m_source(source),
    m_type(type),
    m_response(NULL)
{
}

IORequest::~IORequest()
{
}

IORequest::RequestType IORequest::type() const
{
    return m_type;
}

void IORequest::putExtra(const QString& key, const QVariant& value)
{
    m_extras.insert(key, value);
}

QVariant IORequest::extra(const QString& key) const
{
    Q_ASSERT(m_extras.contains(key));
    return m_extras.value(key);
}

void IORequest::setResponse(void* r)
{
    m_response = r;
}

void* IORequest::response() const
{
    return m_response;
}

void IORequest::clearRef()
{
    if (--mRefCount <= 0)
        delete this;
}

<|endoftext|>


<commit_before>// [WriteFile Name=SearchForWebmap, Category=CloudAndPortal]
// [Legal]
// Copyright 2016 ESRI
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
//
// See the Sample code usage restrictions document for further information.
//

#include "AuthenticationManager.h"
#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "Portal.h"
#include "PortalItem.h"
#include "PortalItemListModel.h"
#include "PortalQueryParametersForItems.h"
#include "SearchForWebmap.h"

using namespace Esri::ArcGISRuntime;

SearchForWebmap::SearchForWebmap(QQuickItem* parent /* = nullptr */):
    QQuickItem(parent),
    m_map(nullptr),
    m_mapView(nullptr),
    m_portal(new Portal(new Credential(OAuthClientInfo("W3hPKzPbeJ0tr8aj", OAuthMode::User), this), this)),
    m_webmapResults(nullptr),
    m_webmaps(nullptr),
    m_selectedItem(nullptr),
    m_portalLoaded(false)
{
    AuthenticationManager::instance()->setCredentialCacheEnabled(false);
}

SearchForWebmap::~SearchForWebmap()
{
}

void SearchForWebmap::componentComplete()
{
    QQuickItem::componentComplete();
    emit authManagerChanged();

    connect(m_portal, &Portal::loadStatusChanged, this, [this](){
        m_portalLoaded = m_portal->loadStatus() == LoadStatus::Loaded;
        emit portalLoadedChanged();
    });

    connect(m_portal, &Portal::findItemsCompleted, this, [this](PortalQueryResultSetForItems *webmapResults){
        m_webmapResults = webmapResults;
        m_webmaps = m_webmapResults->itemResults();
        emit webmapsChanged();
        emit hasMoreResultsChanged();
    });

    m_portal->load();

    // find QML MapView component
    m_mapView = findChild<MapQuickView*>("mapView");
    m_mapView->setWrapAroundMode(WrapAroundMode::Disabled);
}

bool SearchForWebmap::portalLoaded() const
{
    return m_portalLoaded;
}

QAbstractListModel* SearchForWebmap::webmaps() const
{
    return m_webmaps;
}

bool SearchForWebmap::hasMoreResults() const
{
    return m_webmapResults && m_webmapResults->nextQueryParameters().startIndex() > -1;
}

QString SearchForWebmap::mapLoadError() const
{
    return m_mapLoadeError;
}

void SearchForWebmap::search(const QString keyword)
{
    PortalQueryParametersForItems query;
    query.setSearchString(QString("tags:\"%1\"").arg(keyword));
    query.setTypes(QList<PortalItemType>() << PortalItemType::WebMap);
    m_portal->findItems(query);

    m_mapView->setVisible(false);
}

void SearchForWebmap::searchNext()
{
    if (!m_webmapResults || m_webmapResults->nextQueryParameters().startIndex() == -1)
        return;

    m_portal->findItems(m_webmapResults->nextQueryParameters());
}

void SearchForWebmap::loadSelectedWebmap(int index)
{
    if (!m_webmaps)
        return;

    PortalItem* selectedItem = m_webmaps->at(index);
    if (!selectedItem)
        return;

    if (m_selectedItem)
        m_selectedItem->disconnect();

    m_selectedItem = selectedItem;

    connect(m_selectedItem, &PortalItem::loadStatusChanged, this, [this]{
        if (!m_selectedItem || m_selectedItem->loadStatus() != LoadStatus::Loaded)
            return;

        if (m_map)
            m_map->disconnect();

        m_mapLoadeError.clear();
        emit mapLoadErrorChanged();

        m_map = new Map(m_selectedItem, this);

        connect(m_map, &Map::errorOccurred, this, [this](){
            m_mapLoadeError = m_map->loadError().message();
            emit mapLoadErrorChanged();
        });

        connect(m_map, &Map::loadStatusChanged, this, [this](){
            if (!m_map || m_map->loadStatus() != LoadStatus::Loaded)
                return;

            m_mapView->setMap(m_map);
            m_mapView->setVisible(true);
        });

        m_map->load();
    });
    m_selectedItem->load();
}

void SearchForWebmap::errorAccepted()
{
    m_mapLoadeError.clear();
    emit mapLoadErrorChanged();
}

AuthenticationManager *SearchForWebmap::authManager() const
{
    return AuthenticationManager::instance();
}
<commit_msg>add snippet tags<commit_after>// [WriteFile Name=SearchForWebmap, Category=CloudAndPortal]
// [Legal]
// Copyright 2016 ESRI
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
//
// See the Sample code usage restrictions document for further information.
//

#include "AuthenticationManager.h"
#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "Portal.h"
#include "PortalItem.h"
#include "PortalItemListModel.h"
#include "PortalQueryParametersForItems.h"
#include "SearchForWebmap.h"

using namespace Esri::ArcGISRuntime;

SearchForWebmap::SearchForWebmap(QQuickItem* parent /* = nullptr */):
    QQuickItem(parent),
    m_map(nullptr),
    m_mapView(nullptr),
    m_portal(new Portal(new Credential(OAuthClientInfo("W3hPKzPbeJ0tr8aj", OAuthMode::User), this), this)),
    m_webmapResults(nullptr),
    m_webmaps(nullptr),
    m_selectedItem(nullptr),
    m_portalLoaded(false)
{
    AuthenticationManager::instance()->setCredentialCacheEnabled(false);
}

SearchForWebmap::~SearchForWebmap()
{
}

void SearchForWebmap::componentComplete()
{
    QQuickItem::componentComplete();
    emit authManagerChanged();

    connect(m_portal, &Portal::loadStatusChanged, this, [this](){
        m_portalLoaded = m_portal->loadStatus() == LoadStatus::Loaded;
        emit portalLoadedChanged();
    });

    //! [SearchForWebmap CPP Portal find items completed]
    connect(m_portal, &Portal::findItemsCompleted, this, [this](PortalQueryResultSetForItems *webmapResults){
        m_webmapResults = webmapResults;
        m_webmaps = m_webmapResults->itemResults();
        emit webmapsChanged();
        emit hasMoreResultsChanged();
    });
    //! [SearchForWebmap CPP Portal find items completed]

    m_portal->load();

    // find QML MapView component
    m_mapView = findChild<MapQuickView*>("mapView");
    m_mapView->setWrapAroundMode(WrapAroundMode::Disabled);
}

bool SearchForWebmap::portalLoaded() const
{
    return m_portalLoaded;
}

QAbstractListModel* SearchForWebmap::webmaps() const
{
    return m_webmaps;
}

bool SearchForWebmap::hasMoreResults() const
{
    return m_webmapResults && m_webmapResults->nextQueryParameters().startIndex() > -1;
}

QString SearchForWebmap::mapLoadError() const
{
    return m_mapLoadeError;
}

void SearchForWebmap::search(const QString keyword)
{
    //! [SearchForWebmap CPP Portal find items]
    PortalQueryParametersForItems query;
    query.setSearchString(QString("tags:\"%1\"").arg(keyword));
    query.setTypes(QList<PortalItemType>() << PortalItemType::WebMap);
    m_portal->findItems(query);
    //! [SearchForWebmap CPP Portal find items]

    m_mapView->setVisible(false);
}

void SearchForWebmap::searchNext()
{
    if (!m_webmapResults || m_webmapResults->nextQueryParameters().startIndex() == -1)
        return;

    m_portal->findItems(m_webmapResults->nextQueryParameters());
}

void SearchForWebmap::loadSelectedWebmap(int index)
{
    if (!m_webmaps)
        return;

    PortalItem* selectedItem = m_webmaps->at(index);
    if (!selectedItem)
        return;

    if (m_selectedItem)
        m_selectedItem->disconnect();

    m_selectedItem = selectedItem;

    connect(m_selectedItem, &PortalItem::loadStatusChanged, this, [this]{
        if (!m_selectedItem || m_selectedItem->loadStatus() != LoadStatus::Loaded)
            return;

        if (m_map)
            m_map->disconnect();

        m_mapLoadeError.clear();
        emit mapLoadErrorChanged();

        m_map = new Map(m_selectedItem, this);

        connect(m_map, &Map::errorOccurred, this, [this](){
            m_mapLoadeError = m_map->loadError().message();
            emit mapLoadErrorChanged();
        });

        connect(m_map, &Map::loadStatusChanged, this, [this](){
            if (!m_map || m_map->loadStatus() != LoadStatus::Loaded)
                return;

            m_mapView->setMap(m_map);
            m_mapView->setVisible(true);
        });

        m_map->load();
    });
    m_selectedItem->load();
}

void SearchForWebmap::errorAccepted()
{
    m_mapLoadeError.clear();
    emit mapLoadErrorChanged();
}

AuthenticationManager *SearchForWebmap::authManager() const
{
    return AuthenticationManager::instance();
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    CheckglXGetProcAddressARB.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

  Copyright 2005 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
  license for use of this work by or on behalf of the
  U.S. Government. Redistribution and use in source and binary forms, with
  or without modification, are permitted provided that this Notice and any
  statement of authorship are reproduced on all copies.

=========================================================================*/

// This is just a test program so that CMake can determine if
// glXGetProcAddressARB needs to be declared.

#include <GL/gl.h>
#include <GL/glx.h>

int main(int, char **)
{
  void (*FuncPointer)(void);

  FuncPointer = glXGetProcAddressARB((const GLubyte *)"glHelloWorldEXT");

  return 0;
}

<commit_msg>BUG:Speculative fix for SunOS 5.8, Sun Studio 11 and Mesa 6.4.2.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    CheckglXGetProcAddressARB.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

  Copyright 2005 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
  license for use of this work by or on behalf of the
  U.S. Government. Redistribution and use in source and binary forms, with
  or without modification, are permitted provided that this Notice and any
  statement of authorship are reproduced on all copies.

=========================================================================*/

// This is just a test program so that CMake can determine if
// glXGetProcAddressARB needs to be declared.

#define GLX_GLXEXT_LEGACY
#define GL_GLEXT_LEGACY
#include <GL/gl.h>
#include <GL/glx.h>

int main(int, char **)
{
  void (*FuncPointer)(void);

  FuncPointer = glXGetProcAddressARB((const GLubyte *)"glHelloWorldEXT");

  return 0;
}

<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkSymmetricEllipsoidInteriorExteriorSpatialFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
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.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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 AUTHORS 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 "itkSymmetricEllipsoidInteriorExteriorSpatialFunction.h"

int main()
{
  std::cout << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction test start" << std::endl;

  // Test will create an ellipsoid (3-dimensional)
  const unsigned int dimension = 3;

  // Symmetric Ellipsoid spatial function typedef
  typedef itk::SymmetricEllipsoidInteriorExteriorSpatialFunction<double, 3> TSymEllipsoidFunctionType;

  // Point position typedef
  typedef TSymEllipsoidFunctionType::TPositionType TSymEllipsoidFunctionVectorType;

  // Create an ellipsoid spatial function for the source image
  TSymEllipsoidFunctionType::Pointer spatialFunc = TSymEllipsoidFunctionType::New();

  // Define function domain, which encapsulates ellipsoid.
  int xExtent = 50;
  int yExtent = 50;
  int zExtent = 50;

  // Define and set the center of the ellipsoid in the center of
  // the function domain
  TSymEllipsoidFunctionVectorType center;
  center[0] = xExtent/2;
  center[1] = yExtent/2;
  center[2] = zExtent/2;
  spatialFunc->SetCenter(center);

  // Define and set the orientation and axes lengths of the ellipsoid
  // NOTE: Orienation vector must be normalized!!!!
  itk::Vector<double, 3> orientation;
  orientation[0] = 1/sqrt(2);
  orientation[1] = 1/sqrt(2);
  orientation[2] = 0;

  double uniqueAxisLength = 45;
  double symmetricAxesLength = 30;

  spatialFunc->SetOrientation(orientation, uniqueAxisLength, symmetricAxesLength);

  // Evaluate all points in the spatial function and count the number of
  // pixels that are inside the sphere.
  double testPosition[dimension];  // position of a pixel in the function domain

  bool functionValue;  // Value of pixel at a given position
  int interiorPixelCounter = 0;  // Count pixels inside ellipsoid

  for(int x = 0; x < xExtent; x++)
    {
    for(int y = 0; y < yExtent; y++)
      {
      for(int z =0; z < zExtent; z++)
        {
        testPosition[0] = x;
        testPosition[1] = y;
        testPosition[2] = z;
        functionValue = spatialFunc->Evaluate(testPosition);
        if(functionValue == 1)
          interiorPixelCounter++;
        }
      }
    }

  // Evaluate the center of the ellipsoid, which is inside the ellipsoid and
  // should equal 1.
  testPosition[0] = center[0];
  testPosition[1] = center[1];
  testPosition[2] = center[2];
  functionValue = spatialFunc->Evaluate(testPosition);

  // Volume of ellipsoid using V=(4/3)*pi*(a/2)*(b/2)*(c/2)
  double volume = 4.18879013333*(uniqueAxisLength/2)*(symmetricAxesLength/2)*(symmetricAxesLength/2);

  // Percent difference in volume measurement and calculation
  double volumeError = (fabs(volume - interiorPixelCounter)/volume)*100;

  // 5% error was randomly chosen as a successful ellipsoid fill.
  // This should actually be some function of the image/ellipsoid size.
  if(volumeError <= 5 || functionValue == 1)
    {
    // With testing settings, results should yield:
    // calculated ellipsoid volume = 21205.8 pixels
    // measured ellipsoid volume = 21197 pixels
    // volume error = 0.04126%
    // function value = 1
    std::cout << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << interiorPixelCounter << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidSpatialFunction ended successfully!" << std::endl;
    return EXIT_SUCCESS;
    }
  else
    {
    std::cerr << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << interiorPixelCounter << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidSpatialFunction failed :(" << std::endl;
    return EXIT_FAILURE;
    }
}
<commit_msg>ERR: sqrt(2) -> sqrt(2.0).<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkSymmetricEllipsoidInteriorExteriorSpatialFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
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.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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 AUTHORS 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 "itkSymmetricEllipsoidInteriorExteriorSpatialFunction.h"

int main()
{
  std::cout << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction test start" << std::endl;

  // Test will create an ellipsoid (3-dimensional)
  const unsigned int dimension = 3;

  // Symmetric Ellipsoid spatial function typedef
  typedef itk::SymmetricEllipsoidInteriorExteriorSpatialFunction<double, 3> TSymEllipsoidFunctionType;

  // Point position typedef
  typedef TSymEllipsoidFunctionType::TPositionType TSymEllipsoidFunctionVectorType;

  // Create an ellipsoid spatial function for the source image
  TSymEllipsoidFunctionType::Pointer spatialFunc = TSymEllipsoidFunctionType::New();

  // Define function domain, which encapsulates ellipsoid.
  int xExtent = 50;
  int yExtent = 50;
  int zExtent = 50;

  // Define and set the center of the ellipsoid in the center of
  // the function domain
  TSymEllipsoidFunctionVectorType center;
  center[0] = xExtent/2;
  center[1] = yExtent/2;
  center[2] = zExtent/2;
  spatialFunc->SetCenter(center);

  // Define and set the orientation and axes lengths of the ellipsoid
  // NOTE: Orienation vector must be normalized!!!!
  itk::Vector<double, 3> orientation;
  orientation[0] = 1/sqrt(2.0);
  orientation[1] = 1/sqrt(2.0);
  orientation[2] = 0;

  double uniqueAxisLength = 45;
  double symmetricAxesLength = 30;

  spatialFunc->SetOrientation(orientation, uniqueAxisLength, symmetricAxesLength);

  // Evaluate all points in the spatial function and count the number of
  // pixels that are inside the sphere.
  double testPosition[dimension];  // position of a pixel in the function domain

  bool functionValue;  // Value of pixel at a given position
  int interiorPixelCounter = 0;  // Count pixels inside ellipsoid

  for(int x = 0; x < xExtent; x++)
    {
    for(int y = 0; y < yExtent; y++)
      {
      for(int z =0; z < zExtent; z++)
        {
        testPosition[0] = x;
        testPosition[1] = y;
        testPosition[2] = z;
        functionValue = spatialFunc->Evaluate(testPosition);
        if(functionValue == 1)
          interiorPixelCounter++;
        }
      }
    }

  // Evaluate the center of the ellipsoid, which is inside the ellipsoid and
  // should equal 1.
  testPosition[0] = center[0];
  testPosition[1] = center[1];
  testPosition[2] = center[2];
  functionValue = spatialFunc->Evaluate(testPosition);

  // Volume of ellipsoid using V=(4/3)*pi*(a/2)*(b/2)*(c/2)
  double volume = 4.18879013333*(uniqueAxisLength/2)*(symmetricAxesLength/2)*(symmetricAxesLength/2);

  // Percent difference in volume measurement and calculation
  double volumeError = (fabs(volume - interiorPixelCounter)/volume)*100;

  // 5% error was randomly chosen as a successful ellipsoid fill.
  // This should actually be some function of the image/ellipsoid size.
  if(volumeError <= 5 || functionValue == 1)
    {
    // With testing settings, results should yield:
    // calculated ellipsoid volume = 21205.8 pixels
    // measured ellipsoid volume = 21197 pixels
    // volume error = 0.04126%
    // function value = 1
    std::cout << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << interiorPixelCounter << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidSpatialFunction ended successfully!" << std::endl;
    return EXIT_SUCCESS;
    }
  else
    {
    std::cerr << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << interiorPixelCounter << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidSpatialFunction failed :(" << std::endl;
    return EXIT_FAILURE;
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <QUrl>
#include <QFileInfo>
#include "kernel.h"
#include "ilwisdata.h"
#include "resource.h"
#include "identity.h"
#include "symboltable.h"
#include "operationExpression.h"
#include "operationmetadata.h"
#include "commandhandler.h"
#include "operation.h"
#include "script.h"
#include "parserlexer/IlwisScriptLexer.h"
#include "parserlexer/ilwisscriptParser.h"

using namespace Ilwis;
OperationImplementation *Script::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Script(metaid, expr);
}

Script::Script()
{
}

Script::Script(quint64 metaid,const Ilwis::OperationExpression &expr) : OperationImplementation(metaid, expr)
{
}

bool Script::detectKey(const std::string& line, const std::string& key) {
    int index = line.find(key);
    if ( index == std::string::npos)
        return false;
    if ( index == 0)
        return true;

    int index1 = line.find('"');
    int index2 = line.find_last_of('"');
    bool ok = index < index1 || index > index2;
    if (!ok)
        return false;

    if ( index != 0 && line[index -1] == ' ')
        return true;
    return false;
}

OperationImplementation::State Script::prepare(ExecutionContext *, const SymbolTable&) {
    QString txt = _expression.parm(0).value();
    QUrl url(txt);
    if ( url.isValid() && url.scheme() == "file") {
        QFileInfo inf( url.toLocalFile());
        bool exists = inf.exists();
        if (exists && inf.suffix() == "isf") {
            std::string text;
            std::ifstream in(inf.absoluteFilePath().toLatin1(), std::ios_base::in);
            int ignorenCount=0;
            if(in.is_open() && in.good()) {
                while(!in.eof()) {
                    std::string line;
                    std::getline(in, line);
                    if ( line == "") // skip empty lines
                        continue;
                    if (detectKey(line, "if") || detectKey(line, "while") ){
                        ignorenCount++;
                    }
                    if (detectKey(line, "endif") || detectKey(line, "endwhile")) {
                        ignorenCount--;
                    }
                    text += line + (ignorenCount != 0 ? " " : ";");
                }
                char *buf = new char[text.size()];
                memcpy(buf,text.c_str(), text.size());
                _buffer.reset( buf );
                _bufferSize = text.size();
                return sPREPARED;
            }
        } else {
            return sPREPAREFAILED;
        }
    } else {
        QString text = txt.trimmed();
        if ( text[text.size() - 1] != ';')
            text += ';';
        char *buf = new char[text.size()];
        memcpy(buf,text.toLatin1(), text.size());
        _buffer.reset( buf );
        _bufferSize = text.size();
        return sPREPARED;
    }

    return sNOTPREPARED;
}

bool Script::execute(ExecutionContext *ctx, SymbolTable& symbols )
{
    try{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx, symbols)) != sPREPARED)
            return false;

    ANTLR3_UINT8 * bufferData = (ANTLR3_UINT8 *) _buffer.get();

    pANTLR3_INPUT_STREAM input = antlr3StringStreamNew(bufferData,  ANTLR3_ENC_8BIT,  _bufferSize, (pANTLR3_UINT8)"ScriptText");
    if(input == NULL)
        return false;

    pilwisscriptLexer lxr = ilwisscriptLexerNew(input);
    if(lxr == NULL)
        return false;

    //Creates an empty token stream.
    pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lxr));
    if(tstream == NULL)
        return false;

    //Creates a parser.
    pilwisscriptParser psr = ilwisscriptParserNew(tstream);
    if(psr == NULL)
        return false;

    //Run the parser rule. This also runs the lexer to create the token stream.
    ASTNode *scr = psr->script(psr);

    bool ok = scr->evaluate(symbols, 1000, ctx);
    return ok;
    }
    catch(Ilwis::ScriptError& err) {
        kernel()->issues()->log(err.message());
    }
    return false;

}

quint64 Script::createMetadata()
{
    QString urlTxt = QString("ilwis://operations/script");
    QUrl url(urlTxt);
    Resource resource(url, itOPERATIONMETADATA);
    resource.addProperty("namespace","ilwis");
    resource.addProperty("longname","ilwisscript");
    resource.addProperty("syntax","script file|script scriptline(,scriptline)*");
    resource.addProperty("inparameters","1");
    resource.addProperty("pin_1_type", itFILE | itSTRING);
    resource.addProperty("pin_1_name", TR("input script file"));
    resource.addProperty("pin_1_domain","none");
    resource.addProperty("pin_1_desc",TR("input file containing script commands"));
    resource.addProperty("outparameters",1);
    resource.addProperty("pout_1_type", itBOOL);
    resource.addProperty("pout_1_name", TR("succes"));
    resource.addProperty("pout_1_domain","bool");
    resource.addProperty("pout_1_desc",TR("returns the succes of the execution of the script"));

    resource.prepare();
    urlTxt += "=" + QString::number(resource.id());
    resource.setUrl(QUrl(urlTxt));
//    IOperationMetaData md;
//    if(!md.prepare(resource)) {
//        return i64UNDEF;
//    }
    mastercatalog()->addItems({resource});
    return resource.id();
}
<commit_msg>Give error message for empty command line<commit_after>#include <iostream>
#include <fstream>
#include <QUrl>
#include <QFileInfo>
#include "kernel.h"
#include "ilwisdata.h"
#include "resource.h"
#include "identity.h"
#include "symboltable.h"
#include "operationExpression.h"
#include "operationmetadata.h"
#include "commandhandler.h"
#include "operation.h"
#include "script.h"
#include "parserlexer/IlwisScriptLexer.h"
#include "parserlexer/ilwisscriptParser.h"

using namespace Ilwis;
OperationImplementation *Script::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Script(metaid, expr);
}

Script::Script()
{
}

Script::Script(quint64 metaid,const Ilwis::OperationExpression &expr) : OperationImplementation(metaid, expr)
{
}

bool Script::detectKey(const std::string& line, const std::string& key) {
    int index = line.find(key);
    if ( index == std::string::npos)
        return false;
    if ( index == 0)
        return true;

    int index1 = line.find('"');
    int index2 = line.find_last_of('"');
    bool ok = index < index1 || index > index2;
    if (!ok)
        return false;

    if ( index != 0 && line[index -1] == ' ')
        return true;
    return false;
}

OperationImplementation::State Script::prepare(ExecutionContext *, const SymbolTable&) {
    QString txt = _expression.parm(0).value();
    if ( txt == "") {
        ERROR2(ERR_NOT_FOUND2, TR("valid expression"), _expression.toString());
        return sPREPAREFAILED;
    }
    QUrl url(txt);
    if ( url.isValid() && url.scheme() == "file") {
        QFileInfo inf( url.toLocalFile());
        bool exists = inf.exists();
        if (exists && inf.suffix() == "isf") {
            std::string text;
            std::ifstream in(inf.absoluteFilePath().toLatin1(), std::ios_base::in);
            int ignorenCount=0;
            if(in.is_open() && in.good()) {
                while(!in.eof()) {
                    std::string line;
                    std::getline(in, line);
                    if ( line == "") // skip empty lines
                        continue;
                    if (detectKey(line, "if") || detectKey(line, "while") ){
                        ignorenCount++;
                    }
                    if (detectKey(line, "endif") || detectKey(line, "endwhile")) {
                        ignorenCount--;
                    }
                    text += line + (ignorenCount != 0 ? " " : ";");
                }
                char *buf = new char[text.size()];
                memcpy(buf,text.c_str(), text.size());
                _buffer.reset( buf );
                _bufferSize = text.size();
                return sPREPARED;
            }
        } else {
            return sPREPAREFAILED;
        }
    } else {
        QString text = txt.trimmed();
        if ( text[text.size() - 1] != ';')
            text += ';';
        char *buf = new char[text.size()];
        memcpy(buf,text.toLatin1(), text.size());
        _buffer.reset( buf );
        _bufferSize = text.size();
        return sPREPARED;
    }

    return sNOTPREPARED;
}

bool Script::execute(ExecutionContext *ctx, SymbolTable& symbols )
{
    try{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx, symbols)) != sPREPARED)
            return false;

    ANTLR3_UINT8 * bufferData = (ANTLR3_UINT8 *) _buffer.get();

    pANTLR3_INPUT_STREAM input = antlr3StringStreamNew(bufferData,  ANTLR3_ENC_8BIT,  _bufferSize, (pANTLR3_UINT8)"ScriptText");
    if(input == NULL)
        return false;

    pilwisscriptLexer lxr = ilwisscriptLexerNew(input);
    if(lxr == NULL)
        return false;

    //Creates an empty token stream.
    pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lxr));
    if(tstream == NULL)
        return false;

    //Creates a parser.
    pilwisscriptParser psr = ilwisscriptParserNew(tstream);
    if(psr == NULL)
        return false;

    //Run the parser rule. This also runs the lexer to create the token stream.
    ASTNode *scr = psr->script(psr);

    bool ok = scr->evaluate(symbols, 1000, ctx);
    return ok;
    }
    catch(Ilwis::ScriptError& err) {
        kernel()->issues()->log(err.message());
    }
    return false;

}

quint64 Script::createMetadata()
{
    QString urlTxt = QString("ilwis://operations/script");
    QUrl url(urlTxt);
    Resource resource(url, itOPERATIONMETADATA);
    resource.addProperty("namespace","ilwis");
    resource.addProperty("longname","ilwisscript");
    resource.addProperty("syntax","script file|script scriptline(,scriptline)*");
    resource.addProperty("inparameters","1");
    resource.addProperty("pin_1_type", itFILE | itSTRING);
    resource.addProperty("pin_1_name", TR("input script file"));
    resource.addProperty("pin_1_domain","none");
    resource.addProperty("pin_1_desc",TR("input file containing script commands"));
    resource.addProperty("outparameters",1);
    resource.addProperty("pout_1_type", itBOOL);
    resource.addProperty("pout_1_name", TR("succes"));
    resource.addProperty("pout_1_domain","bool");
    resource.addProperty("pout_1_desc",TR("returns the succes of the execution of the script"));

    resource.prepare();
    urlTxt += "=" + QString::number(resource.id());
    resource.setUrl(QUrl(urlTxt));
//    IOperationMetaData md;
//    if(!md.prepare(resource)) {
//        return i64UNDEF;
//    }
    mastercatalog()->addItems({resource});
    return resource.id();
}
<|endoftext|>


<commit_before>// mpi
#include <mpi.h>

// std
#include <string>

// cstd
#include <cstdio>

int main(int argc, char *argv[]){
	// Initialize the MPI environment
	if(MPI_Init( &argc, &argv ) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 1 );
	}

	// Get the number of processes
	int world_size;
	if(MPI_Comm_size(MPI_COMM_WORLD, &world_size) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 2 );
	}

	// Get the rank of the process
	int world_rank;
	if(MPI_Comm_rank(MPI_COMM_WORLD, &world_rank) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 3 );
	}

	// Get the name of the processor
	std::string processor_name(MPI_MAX_PROCESSOR_NAME, '\0');
	int name_len = processor_name.size();
	if(MPI_Get_processor_name(&processor_name[0], &name_len) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 4 );
	}
	processor_name.resize(name_len);

	// Print off a hello world message from every process -> normally you would send all message to the first process and print them from there
	printf("Hello world from processor \"%s\", rank %d out of %d processors\n", processor_name.c_str(), world_rank, world_size);

	// Finalize the MPI environment. No more MPI calls can be made after this
	if(MPI_Finalize() != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 6 );
	}

	return 0;
}
<commit_msg>added empty newline at the end of the file<commit_after>// mpi
#include <mpi.h>

// std
#include <string>

// cstd
#include <cstdio>

int main(int argc, char *argv[]){
	// Initialize the MPI environment
	if(MPI_Init( &argc, &argv ) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 1 );
	}

	// Get the number of processes
	int world_size;
	if(MPI_Comm_size(MPI_COMM_WORLD, &world_size) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 2 );
	}

	// Get the rank of the process
	int world_rank;
	if(MPI_Comm_rank(MPI_COMM_WORLD, &world_rank) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 3 );
	}

	// Get the name of the processor
	std::string processor_name(MPI_MAX_PROCESSOR_NAME, '\0');
	int name_len = processor_name.size();
	if(MPI_Get_processor_name(&processor_name[0], &name_len) != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 4 );
	}
	processor_name.resize(name_len);

	// Print off a hello world message from every process -> normally you would send all message to the first process and print them from there
	printf("Hello world from processor \"%s\", rank %d out of %d processors\n", processor_name.c_str(), world_rank, world_size);

	// Finalize the MPI environment. No more MPI calls can be made after this
	if(MPI_Finalize() != MPI_SUCCESS){
		MPI_Abort( MPI_COMM_WORLD, 6 );
	}

	return 0;
}

<|endoftext|>


<commit_before>#pragma once

#include "conv2d_toe.hpp"

namespace ncv
{
        namespace tensor
        {
                ///
                /// \brief 3D convolution output: odata(o) = sum(i, idata(i) @ kdata(i, o))
                ///
                template
                <
                        typename ttensori,
                        typename ttensork,
                        typename ttensoro
                >
                void conv3d_output(const ttensori& idata, const ttensork& kdata, ttensoro&& odata)
                {
                        odata.setZero();

                        for (decltype(idata.dims()) i = 0, k = 0; i < idata.dims(); i ++)
                        {
                                const auto imap = idata.matrix(i);
                                const auto tmap = tensor::make_toeplitz(imap, kdata);

                                for (decltype(odata.dims()) o = 0; o < odata.dims(); o ++, k ++)
                                {
                                        auto omap = odata.matrix(o);
                                        auto kmap = kdata.matrix(k);

                                        conv2d_toe_buffered(imap, kmap, tmap, omap);
                                }
                        }
                }

//                ///
//                /// \brief gradient wrt the input
//                ///
//                template
//                <
//                        typename ttensori,
//                        typename ttensork,
//                        typename ttensoro
//                >
//                void conv3d_ginput(ttensori&& gidata, const ttensork& kdata, const ttensoro& odata)
//                {
//                        gidata.setZero();

//                        for (decltype(odata.dims()) o = 0, k = 0; o < odata.dims(); o ++)
//                        {
//                                auto omap = odata.matrix(o);

//                                for (decltype(gidata.dims()) i = 0; i < gidata.dims(); i ++, k ++)
//                                {
//                                        auto gimap = gidata.matrix(i);
//                                        auto kmap = kdata.matrix(k);

//                                        math::corr2d_dyn(omap, kmap, gimap);
//                                }
//                        }
//                }

//                ///
//                /// \brief gradient wrt the parameters
//                ///
//                template
//                <
//                        typename ttensori,
//                        typename ttensork,
//                        typename ttensoro
//                >
//                void conv3d_gparam(const ttensori& idata, ttensork&& gkdata, const ttensoro& odata)
//                {
//                        for (decltype(odata.dims()) o = 0, k = 0; o < odata.dims(); o ++)
//                        {
//                                auto omap = odata.matrix(o);

//                                for (decltype(idata.dims()) i = 0; i < idata.dims(); i ++, k ++)
//                                {
//                                        auto imap = idata.matrix(i);
//                                        auto gkmap = gkdata.matrix(k);

//                                        gkmap.setZero();
//                                        math::conv2d_dyn(imap, omap, gkmap);
//                                }
//                        }
//                }
        }
}

<commit_msg>simplify 3D convolution as a linear matrix operation<commit_after>#pragma once

#include "conv2d_toe.hpp"

namespace ncv
{
        namespace tensor
        {
                ///
                /// \brief 3D convolution output: odata(o) = sum(i, idata(i) @ kdata(i, o))
                ///
                template
                <
                        typename ttensori,
                        typename ttensork,
                        typename ttensoro
                >
                void conv3d_output(const ttensori& idata, const ttensork& kdata, ttensoro&& odata)
                {
                        odata.setZero();

                        for (decltype(idata.dims()) i = 0, k = 0; i < idata.dims(); i ++)
                        {
                                const auto imap = idata.matrix(i);
                                const auto tmap = tensor::make_toeplitz(imap, kdata);

                                const auto osize = odata.rows() * odata.cols();
                                const auto ksize = kdata.rows() * kdata.cols();

                                const auto odims = odata.dims();

                                tensor::map_matrix(odata.data(), odims, osize).transpose() +=
                                tmap *
                                tensor::map_matrix(kdata.planeData(i * odims), odims, ksize).transpose();

//                                for (decltype(odata.dims()) o = 0; o < odata.dims(); o ++, k ++)
//                                {
//                                        auto omap = odata.matrix(o);
//                                        auto kmap = kdata.matrix(k);

//                                        conv2d_toe_buffered(imap, kmap, tmap, omap);
//                                }
                        }
                }

//                ///
//                /// \brief gradient wrt the input
//                ///
//                template
//                <
//                        typename ttensori,
//                        typename ttensork,
//                        typename ttensoro
//                >
//                void conv3d_ginput(ttensori&& gidata, const ttensork& kdata, const ttensoro& odata)
//                {
//                        gidata.setZero();

//                        for (decltype(odata.dims()) o = 0, k = 0; o < odata.dims(); o ++)
//                        {
//                                auto omap = odata.matrix(o);

//                                for (decltype(gidata.dims()) i = 0; i < gidata.dims(); i ++, k ++)
//                                {
//                                        auto gimap = gidata.matrix(i);
//                                        auto kmap = kdata.matrix(k);

//                                        math::corr2d_dyn(omap, kmap, gimap);
//                                }
//                        }
//                }

//                ///
//                /// \brief gradient wrt the parameters
//                ///
//                template
//                <
//                        typename ttensori,
//                        typename ttensork,
//                        typename ttensoro
//                >
//                void conv3d_gparam(const ttensori& idata, ttensork&& gkdata, const ttensoro& odata)
//                {
//                        for (decltype(odata.dims()) o = 0, k = 0; o < odata.dims(); o ++)
//                        {
//                                auto omap = odata.matrix(o);

//                                for (decltype(idata.dims()) i = 0; i < idata.dims(); i ++, k ++)
//                                {
//                                        auto imap = idata.matrix(i);
//                                        auto gkmap = gkdata.matrix(k);

//                                        gkmap.setZero();
//                                        math::conv2d_dyn(imap, omap, gkmap);
//                                }
//                        }
//                }
        }
}

<|endoftext|>


<commit_before><commit_msg>remove block_production_condition_enum consecutive<commit_after><|endoftext|>


<commit_before>#include <gbBase/Allocator.hpp>

#include <catch.hpp>

#include <algorithm>
#include <vector>

TEST_CASE("Allocator integration test")
{
    using namespace GHULBUS_BASE_NAMESPACE;

    Allocator::Storage::Dynamic storage(1024);
    Allocator::LinearMemoryResource<Allocator::Storage::Dynamic> resource(storage);
    Allocator::StatefulAllocator<double, decltype(resource)> allocator(resource);

    std::vector<double, decltype(allocator)> my_vector(allocator);
    my_vector.resize(100, 42.5);
    CHECK(resource.getFreeMemory() <= 1024 - (100 * sizeof(double)));
    CHECK(reinterpret_cast<std::byte*>(my_vector.data()) - storage.get() < resource.getFreeMemory());
    CHECK(std::all_of(begin(my_vector), end(my_vector), [](double d) { return d == 42.5; }));
}
<commit_msg>fixed signed/unsigned warning<commit_after>#include <gbBase/Allocator.hpp>

#include <catch.hpp>

#include <algorithm>
#include <vector>

TEST_CASE("Allocator integration test")
{
    using namespace GHULBUS_BASE_NAMESPACE;

    Allocator::Storage::Dynamic storage(1024);
    Allocator::LinearMemoryResource<Allocator::Storage::Dynamic> resource(storage);
    Allocator::StatefulAllocator<double, decltype(resource)> allocator(resource);

    std::vector<double, decltype(allocator)> my_vector(allocator);
    my_vector.resize(100, 42.5);
    CHECK(resource.getFreeMemory() <= 1024 - (100 * sizeof(double)));
    CHECK(reinterpret_cast<std::byte*>(my_vector.data()) - storage.get() < static_cast<int>(resource.getFreeMemory()));
    CHECK(std::all_of(begin(my_vector), end(my_vector), [](double d) { return d == 42.5; }));
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is [Open Source Virtual Machine.].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2004-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#include "MMgc.h"

#ifdef MMGC_MEMORY_PROFILER

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/un.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>

const char* spy_socket_channel = "/tmp/MMgc_Spy"; //name of unix domain for spy connections

bool spy_connected  = false;
bool spy_running = false;

pthread_cond_t spy_cond; //condition variable for synchronizing spy signalling and socket communication
pthread_mutex_t spy_mutex; //mutex for spy_signal and spy_cond condition variable
pthread_t spy_thread;

int serverSocket = -1; //fd for spy server socket
int clientSocket = -1; //fd for spy socket connection (one at a time)

void* SpyConnectionLoop(void*)
{
    struct sockaddr_un sockAddr;

    socklen_t len = sizeof(sockAddr.sun_family) + strlen(sockAddr.sun_path)+1;
    while(spy_running)
    {
        //wait for spy socket connection
        if((clientSocket = accept(serverSocket, (struct sockaddr*)&sockAddr, &len)) >= 0)
        {
            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(clientSocket, &fds);

            select(clientSocket+1, NULL, &fds, NULL, NULL);

            if(FD_ISSET(clientSocket, &fds))
            {
                pthread_cond_signal(&spy_cond);

                pthread_mutex_lock(&spy_mutex);
                spy_connected = true; //set the

                //wait until we are woken up my the main program thread
                //we do this to avoid processing any new incoming spy request
                pthread_cond_wait(&spy_cond, &spy_mutex);
                pthread_mutex_unlock(&spy_mutex);
            }
            close(clientSocket); //we are done, close this connection
        }
    }

    return NULL;
}

bool SetupSpyServer()
{
    //clear remnants of previous execution
    unlink(spy_socket_channel);

    struct sockaddr_un sockAddr;

    //open a server socket
    if((serverSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        return false;

    memset(&sockAddr, 0, sizeof(struct sockaddr_un));

    sockAddr.sun_family = AF_UNIX;
    strcpy(sockAddr.sun_path, spy_socket_channel);

    //bind and listen
    socklen_t len = sizeof(sockAddr.sun_family) + strlen(sockAddr.sun_path) + 1;
    if( (bind(serverSocket, (struct sockaddr*)&sockAddr, len) < 0) || (listen(serverSocket, 5) < 0))
    {
        close(serverSocket);
        return false;
    }

    //initialize synchronization variables
    pthread_mutex_init(&spy_mutex, NULL);
    pthread_cond_init(&spy_cond, NULL);

    //wait for spy connections on a separate thread
    if(pthread_create(&spy_thread, NULL, SpyConnectionLoop, NULL))
    {
        close(serverSocket);
        return false;
    }

    return true;
}

//log redirector function for outputting log messages to the spy
void SpyLog(const char* message)
{
    send(clientSocket, message, VMPI_strlen(message)+1, 0);
}

extern void RedirectLogOutput(void (*)(const char*));

void VMPI_spyCallback()
{
    if(spy_connected)
    {
        pthread_mutex_lock(&spy_mutex);
        if(spy_connected)
        {
            spy_connected = false;

            RedirectLogOutput(SpyLog);
            MMgc::GCHeap::GetGCHeap()->DumpMemoryInfo();
            RedirectLogOutput(NULL);

            //we are done dumping memory info to the spy
            //signal the condition variable to
            //wake up SpyConnectionLoop thread
            pthread_cond_signal(&spy_cond);
        }
        pthread_mutex_unlock(&spy_mutex);
    }
}

bool VMPI_spySetup()
{
    //setup server socket for spy connections
    return SetupSpyServer();
}

void VMPI_spyTeardown()
{
    spy_running = false;

    if(spy_connected)
    {
        spy_connected = false;
        pthread_cond_signal(&spy_cond);
    }
}

bool VMPI_hasSymbols()
{
    return true;
}

#endif //MMGC_MEMORY_PROFILER
<commit_msg>Spy on mac didn't start the spy thread properly, fixes memory profiler (r=lhansen)<commit_after>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is [Open Source Virtual Machine.].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2004-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#include "MMgc.h"

#ifdef MMGC_MEMORY_PROFILER

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/un.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>

const char* spy_socket_channel = "/tmp/MMgc_Spy"; //name of unix domain for spy connections

bool spy_connected  = false;
bool spy_running = false;

pthread_cond_t spy_cond; //condition variable for synchronizing spy signalling and socket communication
pthread_mutex_t spy_mutex; //mutex for spy_signal and spy_cond condition variable
pthread_t spy_thread;

int serverSocket = -1; //fd for spy server socket
int clientSocket = -1; //fd for spy socket connection (one at a time)

void* SpyConnectionLoop(void*)
{
    struct sockaddr_un sockAddr;

    socklen_t len = sizeof(sockAddr.sun_family) + strlen(sockAddr.sun_path)+1;
    while(spy_running)
    {
        //wait for spy socket connection
        if((clientSocket = accept(serverSocket, (struct sockaddr*)&sockAddr, &len)) >= 0)
        {
            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(clientSocket, &fds);

            select(clientSocket+1, NULL, &fds, NULL, NULL);

            if(FD_ISSET(clientSocket, &fds))
            {
                pthread_cond_signal(&spy_cond);

                pthread_mutex_lock(&spy_mutex);
                spy_connected = true; //set the

                //wait until we are woken up my the main program thread
                //we do this to avoid processing any new incoming spy request
                pthread_cond_wait(&spy_cond, &spy_mutex);
                pthread_mutex_unlock(&spy_mutex);
            }
            close(clientSocket); //we are done, close this connection
        }
    }

    return NULL;
}

bool SetupSpyServer()
{
    //clear remnants of previous execution
    unlink(spy_socket_channel);

    struct sockaddr_un sockAddr;

    //open a server socket
    if((serverSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        return false;

    memset(&sockAddr, 0, sizeof(struct sockaddr_un));

    sockAddr.sun_family = AF_UNIX;
    strcpy(sockAddr.sun_path, spy_socket_channel);

    //bind and listen
    socklen_t len = sizeof(sockAddr.sun_family) + strlen(sockAddr.sun_path) + 1;
    if( (bind(serverSocket, (struct sockaddr*)&sockAddr, len) < 0) || (listen(serverSocket, 5) < 0))
    {
        close(serverSocket);
        return false;
    }

    //initialize synchronization variables
    pthread_mutex_init(&spy_mutex, NULL);
    pthread_cond_init(&spy_cond, NULL);

    spy_running = true;

    //wait for spy connections on a separate thread
    if(pthread_create(&spy_thread, NULL, SpyConnectionLoop, NULL))
    {
        close(serverSocket);
        return false;
    }

    return true;
}

//log redirector function for outputting log messages to the spy
void SpyLog(const char* message)
{
    send(clientSocket, message, VMPI_strlen(message)+1, 0);
}

extern void RedirectLogOutput(void (*)(const char*));

void VMPI_spyCallback()
{
    if(spy_connected)
    {
        pthread_mutex_lock(&spy_mutex);
        if(spy_connected)
        {
            spy_connected = false;

            RedirectLogOutput(SpyLog);
            MMgc::GCHeap::GetGCHeap()->DumpMemoryInfo();
            RedirectLogOutput(NULL);

            //we are done dumping memory info to the spy
            //signal the condition variable to
            //wake up SpyConnectionLoop thread
            pthread_cond_signal(&spy_cond);
        }
        pthread_mutex_unlock(&spy_mutex);
    }
}

bool VMPI_spySetup()
{
    //setup server socket for spy connections
    return SetupSpyServer();
}

void VMPI_spyTeardown()
{
    spy_running = false;

    if(spy_connected)
    {
        spy_connected = false;
        pthread_cond_signal(&spy_cond);
    }
}

bool VMPI_hasSymbols()
{
    return true;
}

#endif //MMGC_MEMORY_PROFILER
<|endoftext|>