<commit_before>/*
 * Copyright (C) 2008 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library 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 library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include "contextregistryinfo.h"

ContextRegistryInfo* ContextRegistryInfo::registryInstance = NULL;

QList<QString> ContextRegistryInfo::listKeys() const
{
    return QList<QString> ();
}

QList<QString> ContextRegistryInfo::listKeys(QString providername) const
{
    return QList<QString> ();
}

QList<QString> ContextRegistryInfo::listProviders() const
{
    return QList<QString> ();
}
<commit_msg>Implementation of the stubber ContextRegistryInfo.listKeys() method.<commit_after>/*
 * Copyright (C) 2008 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library 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 library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include "contextregistryinfo.h"
#include "infobackend.h"

ContextRegistryInfo* ContextRegistryInfo::registryInstance = NULL;

QList<QString> ContextRegistryInfo::listKeys() const
{
    return InfoBackend::instance()->listKeys();
}

QList<QString> ContextRegistryInfo::listKeys(QString providername) const
{
    return QList<QString> ();
}

QList<QString> ContextRegistryInfo::listProviders() const
{
    return QList<QString> ();
}
<|endoftext|>


<commit_before>#include "appcontroller.hpp"
#include "window.hpp"
#include "resourcemanager.hpp"
#include <lib/draw/scenemanager.hpp>
#include "utilprovider.hpp"
#include "log.hpp"
#include "exceptionmanager.hpp"
#include "filesystem.hpp"
#include "configuration.hpp"
#include "servicesmanager.hpp"
#include "shareddata.hpp"
#include "input.hpp"

namespace lib
{
	namespace core
	{
		AppController::AppController(uptr<IApp> iapp, sptr<Driver> driverInstance)
			: m_iapp{ std::move(iapp) }, m_driver{ driverInstance }, m_servicesManager{ new ServicesManager{ this } }
		{
			LOG_CONSTRUCT_NOPARAMS;
			LOG_DEBUG("Starting app " << appId() << "...");
			m_state = AppState::ReadyToStart;
		}

		AppController::~AppController()
		{
			LOG_DESTRUCT("Name: " + appId());
		}

		bool AppController::update()
		{
			switch (m_state)
			{
			case AppState::NotInitialized:
				break;
			case AppState::ReadyToStart:
			{
				// Create the scene manager
				LOG_DEBUG_(appId() + ":  Starting initialization...");
				m_state = AppState::Executing;

				//TO DO: Ask via requests
				m_servicesManager->addService(sptr<ExceptionManager>{new ExceptionManager{}});
				m_servicesManager->addService(sptr<FileSystem>{ new FileSystem{} });
				m_servicesManager->addService(sptr<Configuration>{ new Configuration{} });
				m_servicesManager->addService(sptr<Configuration>{ new Configuration{} });
				m_servicesManager->addService(sptr<SharedData>{ new SharedData{} });
				m_servicesManager->addService(sptr<UtilProvider>{new UtilProvider{}});
				m_servicesManager->addService(sptr<ResourceManager>{ new ResourceManager{} });
				m_servicesManager->addService(sptr<draw::SceneManager>{ new draw::SceneManager{} });
				m_servicesManager->addService(sptr<Window>{ new Window{ m_iapp->getAppDescriptor().wcp }});
				m_servicesManager->addService(sptr<Input>{new Input{}});

				m_servicesManager->setupAllServices();
				m_servicesManager->initializeServices();

				m_servicesManager->service<draw::SceneManager>()->addScenes(m_iapp->scenesVector());

				m_iapp->onInit();
				LOG_DEBUG(appId() << ": " << " is now executing");
			}
				break;
			case AppState::Executing:
			{
				if (loopStep())
				{
					m_state = AppState::ReadyToTerminate;
					LOG_DEBUG(appId() << ": " << " is now ready to terminate");
				}
			}
				break;
			case AppController::AppState::ReadyToTerminate:
				LOG_DEBUG(appId() << ": " << " started termination");
				m_state = AppState::Terminated;
//				m_iapp->onFinish();

				m_servicesManager->stopServices();
				LOG_DEBUG_(appId() + ": terminated");
				return true;
				break;
			case AppState::Terminated:
				return true;
				break;
			default:
				break;
			}
			return false;
		}

		bool AppController::loopStep()
		{
			bool windowWants2Close = m_servicesManager->service<Window>()->preLoop();
			m_servicesManager->service<draw::SceneManager>()->update();
			windowWants2Close |= m_servicesManager->service<Window>()->postLoop();
			return windowWants2Close;
		}

		const std::string AppController::appId() const
		{
			if (m_iapp)
			{
				return std::string(m_iapp->getAppDescriptor().Name + ":" + std::to_string(m_iapp->getAppDescriptor().Version) +
					"." + std::to_string(m_iapp->getAppDescriptor().SubVersion) + "."+std::to_string(m_iapp->getAppDescriptor().Patch));
			}
			return "NoApp:0.0.0";
		}

	}
}
<commit_msg>Added RenderManager to application services<commit_after>#include "appcontroller.hpp"
#include "window.hpp"
#include "resourcemanager.hpp"
#include <lib/draw/scenemanager.hpp>
#include <lib/draw/rendermanager.hpp>
#include "utilprovider.hpp"
#include "log.hpp"
#include "exceptionmanager.hpp"
#include "filesystem.hpp"
#include "configuration.hpp"
#include "servicesmanager.hpp"
#include "shareddata.hpp"
#include "input.hpp"

namespace lib
{
	namespace core
	{
		AppController::AppController(uptr<IApp> iapp, sptr<Driver> driverInstance)
			: m_iapp{ std::move(iapp) }, m_driver{ driverInstance }, m_servicesManager{ new ServicesManager{ this } }
		{
			LOG_CONSTRUCT_NOPARAMS;
			LOG_DEBUG("Starting app " << appId() << "...");
			m_state = AppState::ReadyToStart;
		}

		AppController::~AppController()
		{
			LOG_DESTRUCT("Name: " + appId());
		}

		bool AppController::update()
		{
			switch (m_state)
			{
			case AppState::NotInitialized:
				break;
			case AppState::ReadyToStart:
			{
				// Create the scene manager
				LOG_DEBUG_(appId() + ":  Starting initialization...");
				m_state = AppState::Executing;

				//TO DO: Ask via requests
				m_servicesManager->addService(sptr<ExceptionManager>{new ExceptionManager{}});
				m_servicesManager->addService(sptr<FileSystem>{ new FileSystem{} });
				m_servicesManager->addService(sptr<Configuration>{ new Configuration{} });
				m_servicesManager->addService(sptr<Configuration>{ new Configuration{} });
				m_servicesManager->addService(sptr<SharedData>{ new SharedData{} });
				m_servicesManager->addService(sptr<UtilProvider>{new UtilProvider{}});
				m_servicesManager->addService(sptr<ResourceManager>{ new ResourceManager{} });
				m_servicesManager->addService(sptr<draw::SceneManager>{ new draw::SceneManager{} });
				m_servicesManager->addService(sptr<draw::RenderManager>{ new draw::RenderManager{} });
				m_servicesManager->addService(sptr<Window>{ new Window{ m_iapp->getAppDescriptor().wcp }});
				m_servicesManager->addService(sptr<Input>{new Input{}});

				m_servicesManager->setupAllServices();
				m_servicesManager->initializeServices();

				m_servicesManager->service<draw::SceneManager>()->addScenes(m_iapp->scenesVector());

				m_iapp->onInit();
				LOG_DEBUG(appId() << ": " << " is now executing");
			}
				break;
			case AppState::Executing:
			{
				if (loopStep())
				{
					m_state = AppState::ReadyToTerminate;
					LOG_DEBUG(appId() << ": " << " is now ready to terminate");
				}
			}
				break;
			case AppController::AppState::ReadyToTerminate:
				LOG_DEBUG(appId() << ": " << " started termination");
				m_state = AppState::Terminated;
//				m_iapp->onFinish();

				m_servicesManager->stopServices();
				LOG_DEBUG_(appId() + ": terminated");
				return true;
				break;
			case AppState::Terminated:
				return true;
				break;
			default:
				break;
			}
			return false;
		}

		bool AppController::loopStep()
		{
			bool windowWants2Close = m_servicesManager->service<Window>()->preLoop();
			m_servicesManager->service<draw::SceneManager>()->update();
			windowWants2Close |= m_servicesManager->service<Window>()->postLoop();
			return windowWants2Close;
		}

		const std::string AppController::appId() const
		{
			if (m_iapp)
			{
				return std::string(m_iapp->getAppDescriptor().Name + ":" + std::to_string(m_iapp->getAppDescriptor().Version) +
					"." + std::to_string(m_iapp->getAppDescriptor().SubVersion) + "."+std::to_string(m_iapp->getAppDescriptor().Patch));
			}
			return "NoApp:0.0.0";
		}

	}
}
<|endoftext|>


<commit_before>/*
 * D-Bus AT-SPI, Qt Adaptor
 *
 * Copyright 2008, 2009      Nokia.
 * Copyright 2008, 2009      Codethink Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "bridge.h"

#include "adaptor.h"
#include "accessible.h"
#include "application.h"
#include "cache.h"
#include "constant_mappings.h"
#include "dbusconnection.h"
#include "struct_marshallers.h"

#include "generated/dec_proxy.h"
#include "generated/event_adaptor.h"

#include <QEvent>
#include <QKeyEvent>

#define QSPI_DEC_NAME        "/org/a11y/atspi/Registry"
#define QSPI_DEC_OBJECT_PATH "/org/a11y/atspi/registry/deviceeventcontroller"

QSpiAccessibleBridge* QSpiAccessibleBridge::self = 0;

QSpiAccessibleBridge::QSpiAccessibleBridge()
    : cache(0)
{
    Q_ASSERT(self == 0);
    self = this;

    dbusConnection = new DBusConnection();
    if (!dBusConnection().isConnected()) {
        qWarning() << "Could not connect to dbus.";
    }

    qSpiInitializeStructTypes();
    qSpiInitializeConstantMappings();

    /* Create the cache of accessible objects */
    cache = new QSpiDBusCache(this);
    dec = new DeviceEventControllerProxy(this);

    bool reg = dBusConnection().registerObject(QSPI_DEC_OBJECT_PATH, this, QDBusConnection::ExportAdaptors);
    qDebug() << "Registered DEC: " << reg;

    QAccessibleInterface* i = QAccessible::queryAccessibleInterface(qApp);
    QSpiApplication* accessible = new QSpiApplication(i);
    adaptorWithObjectMap.insert(qApp, accessible);
    allAdaptors.append(accessible);
}

QSpiAccessibleBridge::~QSpiAccessibleBridge ()
{
    delete dbusConnection;
} // Qt currently doesn't delete plugins.

QDBusConnection QSpiAccessibleBridge::dBusConnection() const
{
    return dbusConnection->connection();
}

void QSpiAccessibleBridge::setRootObject(QAccessibleInterface *interface)
{
    // the interface we get will be for the QApplication object.
    // we already cache it in the constructor.
    Q_ASSERT(interface->object() == qApp);
}

QSpiObjectReference QSpiAccessibleBridge::getRootReference() const
{
    return QSpiObjectReference(dBusConnection(), QDBusObjectPath(QSPI_OBJECT_PATH_ROOT));
}

void QSpiAccessibleBridge::notifyAccessibilityUpdate(int reason, QAccessibleInterface *interface, int index)
{
    Q_ASSERT(interface && interface->isValid());

    // this gets deleted, so create one if we don't have it yet
    QSpiAdaptor* accessible = interfaceToAccessible(interface, index, false);

    if (reason == QAccessible::Focus) {
        static QSpiAccessible *lastFocused = 0;
        if (lastFocused) {
            QDBusVariant data;
            data.setVariant(QVariant::fromValue(lastFocused->getReference()));
            qDebug() << "last focus: " << lastFocused;
            emit lastFocused->StateChanged("focused", 0, 0, data, getRootReference());
        }
        lastFocused = qobject_cast<QSpiAccessible*>(accessible);
    }
//    qDebug() << "QSpiAccessibleBridge::notifyAccessibilityUpdate" << QString::number(reason, 16)
//             << " obj: " << interface->object()
//             << (interface->isValid() ? interface->object()->objectName() : " invalid interface!")
//             << accessible->interface;
    accessible->accessibleEvent((QAccessible::Event)reason);
}

QSpiAdaptor* QSpiAccessibleBridge::objectToAccessible(QObject *object)
{
    Q_ASSERT(object);
    if (adaptorWithObjectMap.contains(object))
        return adaptorWithObjectMap.value(object);

    QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(object);
    if (!interface) {
        qWarning() << "Create accessible for object which cannot create an accessible interface." << object;
        Q_ASSERT(interface);
        return 0;
    }

    return interfaceToAccessible(interface, 0, true);
}

QSpiAdaptor* QSpiAccessibleBridge::interfaceToAccessible(QAccessibleInterface* interface, int index, bool takeOwnershipOfInterface)
{
    Q_ASSERT(interface && interface->isValid());
    if (interface->object()) {
        QHash<QObject*, QSpiAdaptor*>::const_iterator i = adaptorWithObjectMap.constFind(interface->object());
        while (i != adaptorWithObjectMap.constEnd()) {
            if (i.value()->childIndex() == index)
                return i.value();
            ++i;
        }
    }

    // FIXME maybe cache (QHash<QAccessibleInterface*, QSpiAdaptor*> for things that don't have an object associated?
    if (interface->object() == 0) {
        foreach (QSpiAdaptor* a, adaptorWithoutObjectList) {
            if (a->associatedInterface() == interface && a->childIndex() == index)
                return a;
        }
        qDebug() << "      QSpiAccessibleBridge::interfaceToAccessible new with no object";
    } else {
        qDebug() << "      QSpiAccessibleBridge::interfaceToAccessible new: " << interface->object()
                 << interface->text(QAccessible::Name, index) << qSpiRoleMapping.value(interface->role(index)).name();
    }

    // FIXME look for interfaces with no object or index > 0

    // if we cannot keep the interface around (notifyAccessibility will delete interfaces)
    // we need to ask for one that we can keep
    if (!takeOwnershipOfInterface) {
        interface = QAccessible::queryAccessibleInterface(interface->object());
    }
    QSpiAdaptor *accessible = new QSpiAccessible(interface, index);

    // put ourself in the list of accessibles
    if (interface->object()) {
        adaptorWithObjectMap.insertMulti(interface->object(), accessible);
        connect(interface->object(), SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
    } else {
        adaptorWithoutObjectList.append(accessible);
    }
    allAdaptors.append(accessible);

    // say hello to d-bus
    cache->emitAddAccessible(accessible->getCacheItem());

    // notify about the new child of our parent
    int childCount = 0;
    QSpiAdaptor* parentAdaptor = 0;
    if (index == 0) {
        QAccessibleInterface *parent = 0;
        interface->navigate(QAccessible::Ancestor, 1, &parent);
        if (parent) {
            parentAdaptor = interfaceToAccessible(parent, 0, true);
            childCount = parent->childCount();
        }
    } else {
        parentAdaptor = interfaceToAccessible(interface, 0, true);
        childCount = interface->childCount();
    }

    if (parentAdaptor) {
        QSpiObjectReference r = accessible->getReference();
        QDBusVariant data;
        data.setVariant(QVariant::fromValue(r));
        parentAdaptor->signalChildrenChanged("add", childCount, 0, data);
    }

    return accessible;
}

void QSpiAccessibleBridge::objectDestroyed(QObject* o)
{
    QHash<QObject*, QSpiAdaptor*>::iterator i = adaptorWithObjectMap.find(o);
    if (i != adaptorWithObjectMap.end()) {
        adaptorWithObjectMap.erase(i);
        allAdaptors.removeAll(i.value());
    }
}

void QSpiAccessibleBridge::removeAdaptor(QSpiAdaptor *adaptor)
{
    if (adaptorWithoutObjectList.contains(adaptor)) {
        adaptorWithoutObjectList.removeAll(adaptor);
    } else {
        adaptorWithObjectMap.remove(adaptor->getObject());
    }

    allAdaptors.removeAll(adaptor);
}
<commit_msg>Fix order of interface removal.<commit_after>/*
 * D-Bus AT-SPI, Qt Adaptor
 *
 * Copyright 2008, 2009      Nokia.
 * Copyright 2008, 2009      Codethink Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "bridge.h"

#include "adaptor.h"
#include "accessible.h"
#include "application.h"
#include "cache.h"
#include "constant_mappings.h"
#include "dbusconnection.h"
#include "struct_marshallers.h"

#include "generated/dec_proxy.h"
#include "generated/event_adaptor.h"

#include <QEvent>
#include <QKeyEvent>

#define QSPI_DEC_NAME        "/org/a11y/atspi/Registry"
#define QSPI_DEC_OBJECT_PATH "/org/a11y/atspi/registry/deviceeventcontroller"

QSpiAccessibleBridge* QSpiAccessibleBridge::self = 0;

QSpiAccessibleBridge::QSpiAccessibleBridge()
    : cache(0)
{
    Q_ASSERT(self == 0);
    self = this;

    dbusConnection = new DBusConnection();
    if (!dBusConnection().isConnected()) {
        qWarning() << "Could not connect to dbus.";
    }

    qSpiInitializeStructTypes();
    qSpiInitializeConstantMappings();

    /* Create the cache of accessible objects */
    cache = new QSpiDBusCache(this);
    dec = new DeviceEventControllerProxy(this);

    bool reg = dBusConnection().registerObject(QSPI_DEC_OBJECT_PATH, this, QDBusConnection::ExportAdaptors);
    qDebug() << "Registered DEC: " << reg;

    QAccessibleInterface* i = QAccessible::queryAccessibleInterface(qApp);
    QSpiApplication* accessible = new QSpiApplication(i);
    adaptorWithObjectMap.insert(qApp, accessible);
    allAdaptors.append(accessible);
}

QSpiAccessibleBridge::~QSpiAccessibleBridge ()
{
    delete dbusConnection;
} // Qt currently doesn't delete plugins.

QDBusConnection QSpiAccessibleBridge::dBusConnection() const
{
    return dbusConnection->connection();
}

void QSpiAccessibleBridge::setRootObject(QAccessibleInterface *interface)
{
    // the interface we get will be for the QApplication object.
    // we already cache it in the constructor.
    Q_ASSERT(interface->object() == qApp);
}

QSpiObjectReference QSpiAccessibleBridge::getRootReference() const
{
    return QSpiObjectReference(dBusConnection(), QDBusObjectPath(QSPI_OBJECT_PATH_ROOT));
}

void QSpiAccessibleBridge::notifyAccessibilityUpdate(int reason, QAccessibleInterface *interface, int index)
{
    Q_ASSERT(interface && interface->isValid());

    // this gets deleted, so create one if we don't have it yet
    QSpiAdaptor* accessible = interfaceToAccessible(interface, index, false);

    if (reason == QAccessible::Focus) {
        static QSpiAccessible *lastFocused = 0;
        if (lastFocused) {
            QDBusVariant data;
            data.setVariant(QVariant::fromValue(lastFocused->getReference()));
            qDebug() << "last focus: " << lastFocused;
            emit lastFocused->StateChanged("focused", 0, 0, data, getRootReference());
        }
        lastFocused = qobject_cast<QSpiAccessible*>(accessible);
    }
//    qDebug() << "QSpiAccessibleBridge::notifyAccessibilityUpdate" << QString::number(reason, 16)
//             << " obj: " << interface->object()
//             << (interface->isValid() ? interface->object()->objectName() : " invalid interface!")
//             << accessible->interface;
    accessible->accessibleEvent((QAccessible::Event)reason);
}

QSpiAdaptor* QSpiAccessibleBridge::objectToAccessible(QObject *object)
{
    Q_ASSERT(object);
    if (adaptorWithObjectMap.contains(object))
        return adaptorWithObjectMap.value(object);

    QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(object);
    if (!interface) {
        qWarning() << "Create accessible for object which cannot create an accessible interface." << object;
        Q_ASSERT(interface);
        return 0;
    }

    return interfaceToAccessible(interface, 0, true);
}

QSpiAdaptor* QSpiAccessibleBridge::interfaceToAccessible(QAccessibleInterface* interface, int index, bool takeOwnershipOfInterface)
{
    Q_ASSERT(interface && interface->isValid());
    if (interface->object()) {
        QHash<QObject*, QSpiAdaptor*>::const_iterator i = adaptorWithObjectMap.constFind(interface->object());
        while (i != adaptorWithObjectMap.constEnd()) {
            if (i.value()->childIndex() == index)
                return i.value();
            ++i;
        }
    }

    // FIXME maybe cache (QHash<QAccessibleInterface*, QSpiAdaptor*> for things that don't have an object associated?
    if (interface->object() == 0) {
        foreach (QSpiAdaptor* a, adaptorWithoutObjectList) {
            if (a->associatedInterface() == interface && a->childIndex() == index)
                return a;
        }
        qDebug() << "      QSpiAccessibleBridge::interfaceToAccessible new with no object";
    } else {
        qDebug() << "      QSpiAccessibleBridge::interfaceToAccessible new: " << interface->object()
                 << interface->text(QAccessible::Name, index) << qSpiRoleMapping.value(interface->role(index)).name();
    }

    // FIXME look for interfaces with no object or index > 0

    // if we cannot keep the interface around (notifyAccessibility will delete interfaces)
    // we need to ask for one that we can keep
    if (!takeOwnershipOfInterface) {
        interface = QAccessible::queryAccessibleInterface(interface->object());
    }
    QSpiAdaptor *accessible = new QSpiAccessible(interface, index);

    // put ourself in the list of accessibles
    if (interface->object()) {
        adaptorWithObjectMap.insertMulti(interface->object(), accessible);
        connect(interface->object(), SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
    } else {
        adaptorWithoutObjectList.append(accessible);
    }
    allAdaptors.append(accessible);

    // say hello to d-bus
    cache->emitAddAccessible(accessible->getCacheItem());

    // notify about the new child of our parent
    int childCount = 0;
    QSpiAdaptor* parentAdaptor = 0;
    if (index == 0) {
        QAccessibleInterface *parent = 0;
        interface->navigate(QAccessible::Ancestor, 1, &parent);
        if (parent) {
            parentAdaptor = interfaceToAccessible(parent, 0, true);
            childCount = parent->childCount();
        }
    } else {
        parentAdaptor = interfaceToAccessible(interface, 0, true);
        childCount = interface->childCount();
    }

    if (parentAdaptor) {
        QSpiObjectReference r = accessible->getReference();
        QDBusVariant data;
        data.setVariant(QVariant::fromValue(r));
        parentAdaptor->signalChildrenChanged("add", childCount, 0, data);
    }

    return accessible;
}

void QSpiAccessibleBridge::objectDestroyed(QObject* o)
{
    QHash<QObject*, QSpiAdaptor*>::iterator i = adaptorWithObjectMap.find(o);
    if (i != adaptorWithObjectMap.end()) {
        allAdaptors.removeAll(i.value());
        adaptorWithObjectMap.erase(i);
    }
}

void QSpiAccessibleBridge::removeAdaptor(QSpiAdaptor *adaptor)
{
    if (adaptorWithoutObjectList.contains(adaptor)) {
        adaptorWithoutObjectList.removeAll(adaptor);
    } else {
        adaptorWithObjectMap.remove(adaptor->getObject());
    }

    allAdaptors.removeAll(adaptor);
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/concept/printable/core/printer.hpp"
#include "vast/concept/printable/string/any.hpp"

namespace vast {

struct string_printer : printer<string_printer> {
  using attribute = std::string;

  template <class Iterator>
  static bool print_string(Iterator& out, char c) {
    return printers::any.print(out, c);
  }

  template <class Iterator, class StringIterator>
  static bool print_string(Iterator& out, StringIterator f, StringIterator l) {
    while (f != l)
      if (!printers::any.print(out, *f++))
        return false;
    return true;
  }

  template <class Iterator>
  static bool print_string(Iterator& out, const char* str) {
    while (*str != '\0')
      if (!printers::any.print(out, *str++))
        return false;
    return true;
  }

  template <class Iterator>
  static bool print_string(Iterator& out, const std::string& str) {
    return print_string(out, str.begin(), str.end());
  }

  template <class Iterator, size_t N>
  static bool print(Iterator& out, const char(&str)[N]) {
    return print_string(out, str, str + N - 1); // without the last NUL byte.
  }

  template <class Iterator, class Attribute>
  bool print(Iterator& out, const Attribute& str) const {
    return print_string(out, str);
  }
};

template <size_t N>
struct printer_registry<const char(&)[N]> {
  using type = string_printer;
};

template <size_t N>
struct printer_registry<char[N]> {
  using type = string_printer;
};

template <>
struct printer_registry<const char*> {
  using type = string_printer;
};

template <>
struct printer_registry<char*> {
  using type = string_printer;
};

template <>
struct printer_registry<std::string> {
  using type = string_printer;
};

namespace printers {

auto const str = string_printer{};

} // namespace printers
} // namespace vast

<commit_msg>Simplify string printer implementation<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/concept/printable/core/printer.hpp"
#include "vast/concept/printable/string/any.hpp"

namespace vast {

struct string_printer : printer<string_printer> {
  using attribute = std::string_view;

  template <class Iterator>
  bool print(Iterator& out, std::string_view str) const {
    auto f = str.begin();
    auto l = str.end();
    while (f != l)
      if (!printers::any.print(out, *f++))
        return false;
    return true;
  }
};

template <size_t N>
struct printer_registry<const char(&)[N]> {
  using type = string_printer;
};

template <size_t N>
struct printer_registry<char[N]> {
  using type = string_printer;
};

template <>
struct printer_registry<const char*> {
  using type = string_printer;
};

template <>
struct printer_registry<char*> {
  using type = string_printer;
};

template <>
struct printer_registry<std::string> {
  using type = string_printer;
};

template <>
struct printer_registry<std::string_view> {
  using type = string_printer;
};

namespace printers {

auto const str = string_printer{};

} // namespace printers
} // namespace vast
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library 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 library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <QCoreApplication>
#include <QDir>
#include <stdlib.h>
#include "contextregistryinfo.h"
#include "contextpropertyinfo.h"
#include "contextproviderinfo.h"
#include "cdbwriter.h"
#include "fcntl.h"

/*!
   \page UpdatingContextProviders

   \brief The update tool (\c update-contextkit-providers) is used to regenerate the registry cache database.

   \section Overview

   Information about keys and providers is normally stored in a system directory in
   \b xml format. The xml (being xml) is slow to parse and not efficient as a storage format for
   data that is mostly static.

   It makes sense to store a cached version of the xml registry in a constant-database
   fast-access format and regenerate it when the xml data changes.

   Update tool does exactly that - it reads the xml registry and (re)generates a
   constant \b tiny-cdb database containing the cached version of the data in the registry.

   \section Usage

   The \c update-contextkit-providers binary, when launched without parameters, will by default regenerate
   the database in the default installation prefix. Most likely: \c "/usr/share/contextkit/providers" .
   Obviously, for this to be successful, it needs to be launched with proper privileges.

   It's possible to override the registry directory with first parameter:

   \code
   $> update-contextkit-providers /some/path/to/registry
   \endcode

   In this case the xml will be read from \c "/some/path/to/registry" and the resulting
   database will be written to \c "/some/path/to/registry/cache.cdb" .

   Lastly, the \c "CONTEXT_PROVIDERS" environment variable can be used to specify
   a directory containing the registry.

   \section Implementation

   To ensure the registry consistency the regeneration is done atomically: the
   new database is first written to a temp-named file and then moved over the old one.
*/

/* Make sure the given directory exists, is readable etc.
   If not, bail out with proper error. */
void checkDirectory(const QDir &dir)
{
    QByteArray utf8Data = dir.absolutePath().toUtf8();
    const char *path = utf8Data.constData();

    if (! dir.exists()) {
        printf ("ERROR: Directory '%s' does not exist!\n", path);
        exit (128);
    }

    if (! dir.isReadable()) {
        printf ("ERROR: Directory '%s' is not readable!\n", path);
        exit (128);
    }
}

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QStringList args = app.arguments();

    // Check args etc
    QString path;

    // We first try to use first argument if present, then CONTEXT_PROVIDERS env,
    // lastly -- the compiled-in default path.
    if (args.size() > 1) {
        path = args.at(1);
        setenv("CONTEXT_PROVIDERS", path.toUtf8().constData(), 1);
    } else if (getenv("CONTEXT_PROVIDERS"))
        path = QString(getenv("CONTEXT_PROVIDERS"));
    else
        path = QString(DEFAULT_CONTEXT_PROVIDERS);

    printf("Updating from: '%s'\n", path.toUtf8().constData());

    // Force the xml backend
    ContextRegistryInfo *context = ContextRegistryInfo::instance("xml");

    QDir dir(path);
    checkDirectory(dir);
    QString tmpDbPath = dir.absoluteFilePath("cache-XXXXXX");
    QString finalDbPath = dir.absoluteFilePath("cache.cdb");
    QByteArray templ = tmpDbPath.toUtf8();

    char *tempPath = templ.data();
    CDBWriter writer(mkstemp(tempPath));
    chmod(tempPath, 0644);
    if (writer.isWritable() == false) {
        printf("ERROR: %s is not writable. No permissions?\n", templ.constData());
        exit(128);
    }

    foreach(const QString& key, context->listKeys()) {
        ContextPropertyInfo keyInfo(key);

        // Write value to list key
        writer.add("KEYS", key);

        // Write type
        writer.replace(key + ":KEYTYPE", QVariant(keyInfo.typeInfo()));

        // Write doc
        writer.replace(key + ":KEYDOC", keyInfo.doc());

        // Write the providers
        QVariantList providers;
        foreach(const ContextProviderInfo info, keyInfo.providers()) {
            QHash <QString, QVariant> provider;
            provider.insert("plugin", info.plugin);
            provider.insert("constructionString", info.constructionString);
            providers << QVariant(provider);

        }

        writer.add(key + ":PROVIDERS", QVariant(providers));
    }

    if (fsync(writer.fileDescriptor()) != 0) {
        printf("ERROR: failed to fsync data on writer to %s.\n", templ.constData());
        exit(64);
    }

    writer.close();

    // Atomically rename
    if (rename(templ.constData(), finalDbPath.toUtf8().constData()) != 0) {
        printf("ERROR: failed to rename %s to %s.\n", templ.constData(), finalDbPath.toUtf8().constData());
        exit(64);
    }

    // All ok
    printf("Generated: '%s'\n", finalDbPath.toUtf8().constData());
    return 0;
}

<commit_msg>update-contextkit-providers: updated key type to KEYTYPEINFO<commit_after>/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library 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 library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <QCoreApplication>
#include <QDir>
#include <stdlib.h>
#include "contextregistryinfo.h"
#include "contextpropertyinfo.h"
#include "contextproviderinfo.h"
#include "cdbwriter.h"
#include "fcntl.h"

/*!
   \page UpdatingContextProviders

   \brief The update tool (\c update-contextkit-providers) is used to regenerate the registry cache database.

   \section Overview

   Information about keys and providers is normally stored in a system directory in
   \b xml format. The xml (being xml) is slow to parse and not efficient as a storage format for
   data that is mostly static.

   It makes sense to store a cached version of the xml registry in a constant-database
   fast-access format and regenerate it when the xml data changes.

   Update tool does exactly that - it reads the xml registry and (re)generates a
   constant \b tiny-cdb database containing the cached version of the data in the registry.

   \section Usage

   The \c update-contextkit-providers binary, when launched without parameters, will by default regenerate
   the database in the default installation prefix. Most likely: \c "/usr/share/contextkit/providers" .
   Obviously, for this to be successful, it needs to be launched with proper privileges.

   It's possible to override the registry directory with first parameter:

   \code
   $> update-contextkit-providers /some/path/to/registry
   \endcode

   In this case the xml will be read from \c "/some/path/to/registry" and the resulting
   database will be written to \c "/some/path/to/registry/cache.cdb" .

   Lastly, the \c "CONTEXT_PROVIDERS" environment variable can be used to specify
   a directory containing the registry.

   \section Implementation

   To ensure the registry consistency the regeneration is done atomically: the
   new database is first written to a temp-named file and then moved over the old one.
*/

/* Make sure the given directory exists, is readable etc.
   If not, bail out with proper error. */
void checkDirectory(const QDir &dir)
{
    QByteArray utf8Data = dir.absolutePath().toUtf8();
    const char *path = utf8Data.constData();

    if (! dir.exists()) {
        printf ("ERROR: Directory '%s' does not exist!\n", path);
        exit (128);
    }

    if (! dir.isReadable()) {
        printf ("ERROR: Directory '%s' is not readable!\n", path);
        exit (128);
    }
}

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QStringList args = app.arguments();

    // Check args etc
    QString path;

    // We first try to use first argument if present, then CONTEXT_PROVIDERS env,
    // lastly -- the compiled-in default path.
    if (args.size() > 1) {
        path = args.at(1);
        setenv("CONTEXT_PROVIDERS", path.toUtf8().constData(), 1);
    } else if (getenv("CONTEXT_PROVIDERS"))
        path = QString(getenv("CONTEXT_PROVIDERS"));
    else
        path = QString(DEFAULT_CONTEXT_PROVIDERS);

    printf("Updating from: '%s'\n", path.toUtf8().constData());

    // Force the xml backend
    ContextRegistryInfo *context = ContextRegistryInfo::instance("xml");

    QDir dir(path);
    checkDirectory(dir);
    QString tmpDbPath = dir.absoluteFilePath("cache-XXXXXX");
    QString finalDbPath = dir.absoluteFilePath("cache.cdb");
    QByteArray templ = tmpDbPath.toUtf8();

    char *tempPath = templ.data();
    CDBWriter writer(mkstemp(tempPath));
    chmod(tempPath, 0644);
    if (writer.isWritable() == false) {
        printf("ERROR: %s is not writable. No permissions?\n", templ.constData());
        exit(128);
    }

    foreach(const QString& key, context->listKeys()) {
        ContextPropertyInfo keyInfo(key);

        // Write value to list key
        writer.add("KEYS", key);

        // Write type
        writer.replace(key + ":KEYTYPEINFO", QVariant(keyInfo.typeInfo()));

        // Write doc
        writer.replace(key + ":KEYDOC", keyInfo.doc());

        // Write the providers
        QVariantList providers;
        foreach(const ContextProviderInfo info, keyInfo.providers()) {
            QHash <QString, QVariant> provider;
            provider.insert("plugin", info.plugin);
            provider.insert("constructionString", info.constructionString);
            providers << QVariant(provider);

        }

        writer.add(key + ":PROVIDERS", QVariant(providers));
    }

    if (fsync(writer.fileDescriptor()) != 0) {
        printf("ERROR: failed to fsync data on writer to %s.\n", templ.constData());
        exit(64);
    }

    writer.close();

    // Atomically rename
    if (rename(templ.constData(), finalDbPath.toUtf8().constData()) != 0) {
        printf("ERROR: failed to rename %s to %s.\n", templ.constData(), finalDbPath.toUtf8().constData());
        exit(64);
    }

    // All ok
    printf("Generated: '%s'\n", finalDbPath.toUtf8().constData());
    return 0;
}

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/mss_field.H $             */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mss_field.H
/// @brief API for data fields and operations
///

// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_FIELD_H_
#define _MSS_FIELD_H_

#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/mss_generic_check.H>

namespace mss
{

///
/// @class field_t
/// @brief data structure for byte fields
/// @note holds byte index, start bit, and bit length of a decoded field
///
class field_t
{
    private:

        const size_t iv_byte;
        const size_t iv_start;
        const size_t iv_length;

    public:

        // default ctor deleted
        field_t() = delete;

        ///
        /// @brief ctor
        /// @param[in] i_byte_index
        /// @param[in] i_start_bit
        /// @param[in] i_bit_length
        ///
        constexpr field_t(const size_t i_byte_index,
                          const size_t i_start_bit,
                          const size_t i_bit_length)
            : iv_byte(i_byte_index),
              iv_start(i_start_bit),
              iv_length(i_bit_length)
        {}

        ///
        /// @brief default dtor
        ///
        ~field_t() = default;

        ///
        /// @brief Byte index getter
        /// @return the byte index for this field
        ///
        constexpr size_t get_byte() const
        {
            return iv_byte;
        }

        ///
        /// @brief Starting bit getter
        /// @return the starting bit position for this field
        ///
        constexpr size_t get_start() const
        {
            return iv_start;
        }

        ///
        /// @brief bit length getter
        /// @return the bit length of this field
        ///
        constexpr size_t get_length() const
        {
            return iv_length;
        }

};// field_t

///
/// @brief Checks input field against a custom conditional
/// @tparam T field input type
/// @tparam F Callable object type
/// @param[in] i_field Extracted field
/// @param[in] i_comparison_val value we are comparing against
/// @param[in] i_op comparison operator function object
/// @return boolean true or false
///
template < typename T, typename F >
bool conditional(const T i_field,
                 const size_t i_comparison_val,
                 const F i_op)
{
    return i_op(i_field, i_comparison_val);
}

///
/// @brief Helper function to extract byte information
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the fapi2 target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
                            const std::vector<IT>& i_data,
                            const FFDC i_ffdc_codes,
                            OT& o_value)
{
    constexpr size_t BYTE = F.get_byte();

    FAPI_ASSERT( BYTE < i_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(i_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 i_data.size(),
                 spd::c_str(i_target));

    {
        // Extracting desired bits
        const fapi2::buffer<OT> l_buffer(i_data[BYTE]);
        l_buffer.template extractToRight<F.get_start(), F.get_length()>(o_value);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 i_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 o_value);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function to set byte field information
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the fapi2 target
/// @param[in] i_setting the setting to set
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
                            const IT i_setting,
                            const FFDC i_ffdc_codes,
                            std::vector<OT>& io_data)
{
    constexpr size_t BYTE = F.get_byte();

    FAPI_ASSERT( BYTE < io_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(io_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 io_data.size(),
                 spd::c_str(i_target));

    {
        // Insert desired setting
        fapi2::buffer<OT> l_buffer(io_data[BYTE]);
        l_buffer.template insertFromRight<F.get_start(), F.get_length()>(i_setting);

        io_data[BYTE] = static_cast<OT>(l_buffer);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 io_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 i_setting);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field reader
/// @tparam F the byte field to read
/// @tparam TT traits associated with F - required
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @param[in] i_target the dimm target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
                                    const std::vector<IT>& i_data,
                                    const FFDC i_ffdc_codes,
                                    OT& o_value )
{
    IT l_temp = 0;
    FAPI_TRY( get_field<F>(i_target, i_data, i_ffdc_codes, l_temp),
              "Failed get_field() for %s", spd::c_str(i_target) );

    // Test if retrieved data seems valid
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( l_temp,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   F.get_byte(),
                                   l_temp,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    // Output should only change if data check passes
    o_value = static_cast<OT>(l_temp);

    FAPI_ASSERT( o_value == l_temp,
                 fapi2::MSS_CONVERSION_ERROR()
                 .set_ORIGINAL_VAL(l_temp)
                 .set_CONVERTED_VAL(o_value)
                 .set_TARGET(i_target)
                 .set_FUNCTION(i_ffdc_codes),
                 "Conversion error between original %d to converted %d value for %s",
                 l_temp, o_value, spd::c_str(i_target) );

    FAPI_INF("%s: 0x%02x for %s",
             TT::FIELD_STR,
             o_value,
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field writer
/// @tparam F the byte field to read
/// @tparam TT traits associated with writer
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the dimm target
/// @param[in] i_setting value to set for field
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
                             const IT i_setting,
                             const FFDC i_ffdc_codes,
                             std::vector<OT>& io_data )
{
    constexpr size_t BYTE = F.get_byte();

    // Test if the data we want to set is valid for this field
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( i_setting,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   BYTE,
                                   i_setting,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    FAPI_TRY( set_field<F>(i_target, i_setting, i_ffdc_codes, io_data),
              "Failed set_field() for %s", spd::c_str(i_target) );

    FAPI_INF("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
             TT::FIELD_STR,
             i_setting,
             BYTE,
             io_data[BYTE],
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

}// mss

#endif
<commit_msg>Initial mss_field endian modification<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/mss_field.H $             */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mss_field.H
/// @brief API for data fields and operations
///

// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_FIELD_H_
#define _MSS_FIELD_H_

#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/mss_generic_check.H>

namespace mss
{

///
/// @brief endian fields for use as a template selecor
///
enum class endian
{
    BIG,
    LITTLE,
};

///
/// @class field_t
/// @brief data structure for byte fields
/// @tparam E endian type for this field
/// @note holds byte index, start bit, and bit length of a decoded field
///
template< endian E >
class field_t
{
    private:

        const size_t iv_byte;
        const size_t iv_start;
        const size_t iv_length;

    public:

        // default ctor deleted
        field_t() = delete;

        ///
        /// @brief ctor
        /// @param[in] i_byte_index
        /// @param[in] i_start_bit
        /// @param[in] i_bit_length
        ///
        constexpr field_t(const size_t i_byte_index,
                          const size_t i_start_bit,
                          const size_t i_bit_length)
            : iv_byte(i_byte_index),
              iv_start(i_start_bit),
              iv_length(i_bit_length)
        {}

        ///
        /// @brief default dtor
        ///
        ~field_t() = default;

        ///
        /// @brief Byte index getter
        /// @return the byte index for this field
        ///
        const size_t get_byte(const std::vector<uint8_t>& i_data) const;

        ///
        /// @brief Starting bit getter
        /// @return the starting bit position for this field
        ///
        constexpr size_t get_start() const
        {
            return iv_start;
        }

        ///
        /// @brief bit length getter
        /// @return the bit length of this field
        ///
        constexpr size_t get_length() const
        {
            return iv_length;
        }

};// field_t

///
/// @brief Byte index getter - big endian specialization
/// @return the byte index for this field
///
template<>
inline const size_t field_t<mss::endian::BIG>::get_byte(const std::vector<uint8_t>& i_data) const
{
    return ( i_data.size() - 1 ) - iv_byte;
}

///
/// @brief Byte index getter - big endian specialization
/// @return the byte index for this field
///
template<>
inline const size_t field_t<mss::endian::LITTLE>::get_byte(const std::vector<uint8_t>& i_data) const
{
    return iv_byte;
}

///
/// @brief Checks input field against a custom conditional
/// @tparam T field input type
/// @tparam F Callable object type
/// @param[in] i_field Extracted field
/// @param[in] i_comparison_val value we are comparing against
/// @param[in] i_op comparison operator function object
/// @return boolean true or false
///
template < typename T, typename F >
inline bool conditional(const T i_field,
                        const size_t i_comparison_val,
                        const F i_op)
{
    return i_op(i_field, i_comparison_val);
}

///
/// @brief Helper function to extract byte information
/// @tparam E endian type
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the fapi2 target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< mss::endian E,
          const mss::field_t<E>& F,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
inline fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
                                   const std::vector<IT>& i_data,
                                   const FFDC i_ffdc_codes,
                                   OT& o_value)
{
    const size_t BYTE = F.get_byte(i_data);

    FAPI_ASSERT( BYTE < i_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(i_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 i_data.size(),
                 spd::c_str(i_target));

    {
        // Extracting desired bits
        const fapi2::buffer<OT> l_buffer(i_data[BYTE]);
        l_buffer.template extractToRight<F.get_start(), F.get_length()>(o_value);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 i_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 o_value);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function to set byte field information
/// @tparam E endian type
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the fapi2 target
/// @param[in] i_setting the setting to set
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< mss::endian E,
          const mss::field_t<E>& F,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
                                   const IT i_setting,
                                   const FFDC i_ffdc_codes,
                                   std::vector<OT>& io_data)
{
    const size_t BYTE = F.get_byte(io_data);

    FAPI_ASSERT( BYTE < io_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(io_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 io_data.size(),
                 spd::c_str(i_target));

    {
        // Insert desired setting
        fapi2::buffer<OT> l_buffer(io_data[BYTE]);
        l_buffer.template insertFromRight<F.get_start(), F.get_length()>(i_setting);

        io_data[BYTE] = static_cast<OT>(l_buffer);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 io_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 i_setting);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field reader
/// @tparam E endian type
/// @tparam F the byte field to read
/// @tparam TT traits associated with F - required
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @param[in] i_target the dimm target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< mss::endian E,
          const mss::field_t<E>& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
                                    const std::vector<IT>& i_data,
                                    const FFDC i_ffdc_codes,
                                    OT& o_value )
{
    IT l_temp = 0;
    FAPI_TRY( (get_field<E, F>(i_target, i_data, i_ffdc_codes, l_temp)),
              "Failed get_field() for %s", spd::c_str(i_target) );

    // Test if retrieved data seems valid
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( l_temp,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   F.get_byte(i_data),
                                   l_temp,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    // Output should only change if data check passes
    o_value = static_cast<OT>(l_temp);

    FAPI_ASSERT( o_value == l_temp,
                 fapi2::MSS_CONVERSION_ERROR()
                 .set_ORIGINAL_VAL(l_temp)
                 .set_CONVERTED_VAL(o_value)
                 .set_TARGET(i_target)
                 .set_FUNCTION(i_ffdc_codes),
                 "Conversion error between original %d to converted %d value for %s",
                 l_temp, o_value, spd::c_str(i_target) );

    FAPI_INF("%s: 0x%02x for %s",
             TT::FIELD_STR,
             o_value,
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field writer
/// @tparam E endian type
/// @tparam F the byte field to read
/// @tparam TT traits associated with writer
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the dimm target
/// @param[in] i_setting value to set for field
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< mss::endian E,
          const mss::field_t<E>& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
inline fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
                                    const IT i_setting,
                                    const FFDC i_ffdc_codes,
                                    std::vector<OT>& io_data )
{
    const size_t BYTE = F.get_byte(io_data);

    // Test if the data we want to set is valid for this field
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( i_setting,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   BYTE,
                                   i_setting,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    FAPI_TRY( (set_field<E, F>(i_target, i_setting, i_ffdc_codes, io_data)),
              "Failed set_field() for %s", spd::c_str(i_target) );

    FAPI_INF("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
             TT::FIELD_STR,
             i_setting,
             BYTE,
             io_data[BYTE],
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

}// mss

#endif
<|endoftext|>


<commit_before>#include "linedetector.h"
#include <common/logger/logger.h>
#include <sstream>
#include <iostream>
#include <cstdlib>

using namespace std;
using namespace cv;

LineDetector::LineDetector()
    : max_elem(2),
      max_kernel_size(2),
      gaussian_size(7)
{
    erosion_elem = 2;
    erosion_size = 2;
    dilation_elem = 2;
    dilation_size = 1;
}

void LineDetector::onImageEvent(ImageData imgd){
    src = imgd.mat();
    dst = src.clone();
    /** Total Average of the pixels in the screen. Used to account for brightness variability. */
    float totalAvg = getAvg();

    /** Blurs the picture just a little */
    GaussianBlur(dst, dst, Size(gaussian_size,gaussian_size),2,0);
    /** Separates the pixels into black(not lines) and white (lines) */
    blackAndWhite(totalAvg);

    Erosion();
    Dilation();

    transformPoints();
    toPointCloud();

//    pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");
//    viewer.showCloud(cloud);
//    while (!viewer.wasStopped ())
//    {
//    }

    onNewLines(ImageData(transformDst));
    pcl::io::savePCDFileASCII("line_pcd.pcd", cloud);
}

void LineDetector::transformPoints(){

    int offset = 100;
    int factor = 5;
    //pcam is where the coordinates are in actual space (in inches right now)
    //pcam = (cv::Mat_<float>(4,2) << offset-12,72, offset, 72, offset, 60,offset -12, 60);
    pcam = (cv::Mat_<float>(4,2) << 4,81, -8, 81, -8, 93,4, 93);
    pcam = pcam+offset;
    //p is where they show up as pixels on the camera
    //p = (cv::Mat_<float>(4,2) << 427, 642, 515, 642, 512, 589, 432, 588);
     p= (cv::Mat_<float>(4,2) << 440, 674, 356, 679, 364, 631, 439, 627);
    //pcam = pcam*3+450; //This is just so we can see it on the screen
    //Getting the transform
    transformMat = cv::getPerspectiveTransform(p, pcam);
    //Apply the transform to dst and store result in transformDST
    cv::warpPerspective(dst, transformDst, transformMat, transformDst.size());
}

void LineDetector::toPointCloud(){
    cloud.width = transformDst.rows*transformDst.cols/2; //change later
    cloud.height = 1;
    cloud.points.resize(cloud.width*cloud.height);
    int i =0;

    //Add points to the cloud if they are white (right now only checking the first
    //layer)
    for (int r=0; r<transformDst.rows;r++){
        for (int c=0; c<transformDst.cols; c++){
            if (transformDst.at<cv::Vec3b>(r,c)[0]==255){
                cloud.points[i].x = .0245*(c-100)/2;
                cloud.points[i].y = .0245*(r-100)/2;
                cloud.points[i++].z = 1;
            }
        }
    }

    //Plots one meter long lines on x and y for scale
    for(int r=0; r<21; r++){
        cloud.points[i].x = 0;
        cloud.points[i].y = (float) r/20;
        cloud.points[i++].z = 0;
    }

    for(int r=0; r<21; r++){
        cloud.points[i].x = (float) r/20;
        cloud.points[i].y =0;
        cloud.points[i++].z = 0;
    }

}

void LineDetector::Erosion()
{
  int erosion_type;
  if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }
  else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }
  else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( erosion_type,
                                       Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                       Point( erosion_size, erosion_size ) );
  // Apply the erosion operation
  erode( dst, dst, element );
}

/** Dilation enhances the white lines */
void LineDetector::Dilation()
{
  int dilation_type;
  if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }
  else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }
  else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( dilation_type,
                                       Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       Point( dilation_size, dilation_size ) );
  // Apply the dilation operation
  dilate( dst, dst, element );

}

/**
 *  @brief LineDetector::blackAndWhite converts the image into
 *         black (not lines) and white (lines)
 *  @param totalAvg The average brightness of the picture
 */
void LineDetector::blackAndWhite(float totalAvg){
    Vec3b p;
    int rows = src.rows;
    int cols = src.cols;

    //Turn the top quarter of the screen and bottom sixth of the screen black
    //We can disregard these areas - may extend the bottom of the screen slightly later on
    for (int i = 0; i< rows/3; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
    for (int i = rows*5/6; i< rows; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }

    //Loops through relevant parts of the image and scans for white lines
    //Also tries to detect obstacles
    int tempAvg;
    for (int i = rows/3; i< rows*5/6; i++){
        for(int j=0; j< cols; j++){
            tempAvg = totalAvg*(1.1 - i*.1/768);
            p = dst.at<Vec3b>(i, j); //Current pixel

            //If there is a significant amount of red in the pixel, it's most likely an orange cone
            //Get rid of the obstacle
            if (p[2] > totalAvg*2|| p[2] > 253){
                detectObstacle(i, j);
            }
            //Filters out the white and makes it pure white
            if((p[0]>tempAvg*1.5)&& (p[0] < tempAvg*2.2)&& (p[1] < tempAvg*1.6)&&(p[2]>tempAvg*1.1) &&
                    (p[2]<tempAvg*1.7)&&(p[1]>tempAvg*1.05)&&(abs(p[1] - p[2]) <20)){
                dst.at<Vec3b>(i,j)[0] = 255;
                dst.at<Vec3b>(i,j)[1] = 255;
                dst.at<Vec3b>(i,j)[2] = 255;

            }
            else { //Otherwise, set pixel to black
                dst.at<Vec3b>(i,j)[0] = 0;
                dst.at<Vec3b>(i,j)[1] = 0;
                dst.at<Vec3b>(i,j)[2] = 0;
            }
        }
    }
}

/**
 *  \brief LineDetector::detectObstacle detects orange and bright white obstacles
 *  \param col the column of the left of the obstacle
 */
void LineDetector::detectObstacle(int row, int col){
    Vec3b p = dst.at<Vec3b>(row,col);
    int row2 = row;
    int col2 = col;

    //While the pixel is still orange, turn it black
    //Then on to the next one, by row
    while (p[2]>100){
        dst.at<Vec3b>(row2, col)[0] = 0;
        dst.at<Vec3b>(row2, col)[1] = 0;
        dst.at<Vec3b>(row2, col)[2] = 0;
        p = dst.at<Vec3b>(++row2, col);
    }
    p = dst.at<Vec3b>(row,col);

    //While the pixel is still orange, turn it black
    //Then on to the next one, by column
    while (p[2]>100){
        dst.at<Vec3b>(row, col2)[0] = 0;
        dst.at<Vec3b>(row, col2)[1] = 0;
        dst.at<Vec3b>(row, col2)[2] = 0;
        p = dst.at<Vec3b>(row, ++col2);
    }

    //Turn everything in that block we just found black
    for(int i = row+1; i<row2;i++){
        for (int j = col+1; j<col2; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

/**
 *  \brief LineDetector::getAvg gets the average of the relevant pixels
 *  \return the average as a floating point number
 */
float LineDetector::getAvg(){
    Vec3b p;
    float totalAvg = 0;
    for (int i = src.rows/3; i< 5*src.rows/6; i++){
        for(int j=src.cols/6; j< 5*src.cols/6; j++){
            p = dst.at<Vec3b>(i, j);
            totalAvg += (p[0]+p[1]+p[2])/3;
        }
    }
    totalAvg = (25*totalAvg)/(src.cols*src.rows*8);
    return totalAvg;
}

/**
 *  \brief LineDetector::blackoutSection turns a section of the image black
 *  \param rowl the lower row bound
 *  \param rowu the upper row bound
 *  \param coll the left column bound
 *  \param colu the right column bound
 */
void LineDetector::blackoutSection(int rowl, int rowu, int coll, int colu){

    for (int i=rowl;i<=rowu;i++){
        for (int j = coll; j<=colu; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

<commit_msg>Begin cleanup of line detection code.<commit_after>#include "linedetector.h"
#include <common/logger/logger.h>
#include <sstream>
#include <iostream>
#include <cstdlib>

using namespace std;
using namespace cv;

LineDetector::LineDetector()
    : max_elem(2),
      max_kernel_size(2),
      gaussian_size(7)
{
    erosion_elem = 2;
    erosion_size = 2;
    dilation_elem = 2;
    dilation_size = 1;
}

void LineDetector::onImageEvent(ImageData imgd){
    src = imgd.mat();
    dst = src.clone();
    /** Total Average of the pixels in the screen. Used to account for brightness variability. */
    float totalAvg = getAvg();

    /** Blurs the picture just a little */
    GaussianBlur(dst, dst, Size(gaussian_size,gaussian_size),2,0);
    /** Separates the pixels into black(not lines) and white (lines) */
    blackAndWhite(totalAvg);

    Erosion();
    Dilation();

    transformPoints();
    toPointCloud();

    onNewLines(ImageData(transformDst));
    onNewCloud(cloud);
}

void LineDetector::transformPoints(){

    int offset = 100;
    int factor = 5;
    //pcam is where the coordinates are in actual space (in inches right now)
    //pcam = (cv::Mat_<float>(4,2) << offset-12,72, offset, 72, offset, 60,offset -12, 60);
    pcam = (cv::Mat_<float>(4,2) << 4,81, -8, 81, -8, 93,4, 93);
    pcam = pcam+offset;
    //p is where they show up as pixels on the camera
    //p = (cv::Mat_<float>(4,2) << 427, 642, 515, 642, 512, 589, 432, 588);
     p= (cv::Mat_<float>(4,2) << 440, 674, 356, 679, 364, 631, 439, 627);
    //pcam = pcam*3+450; //This is just so we can see it on the screen
    //Getting the transform
    transformMat = cv::getPerspectiveTransform(p, pcam);
    //Apply the transform to dst and store result in transformDST
    cv::warpPerspective(dst, transformDst, transformMat, transformDst.size());
}

void LineDetector::toPointCloud(){
    cloud.width = transformDst.rows*transformDst.cols/2; //change later
    cloud.height = 1;
    cloud.points.resize(cloud.width*cloud.height);
    int i =0;

    //Add points to the cloud if they are white (right now only checking the first
    //layer)
    for (int r=0; r<transformDst.rows;r++){
        for (int c=0; c<transformDst.cols; c++){
            if (transformDst.at<cv::Vec3b>(r,c)[0]==255){
                cloud.points[i].x = .0245*(c-100)/2;
                cloud.points[i].y = .0245*(r-100)/2;
                cloud.points[i++].z = 1;
            }
        }
    }

    //Plots one meter long lines on x and y for scale
    for(int r=0; r<21; r++){
        cloud.points[i].x = 0;
        cloud.points[i].y = (float) r/20;
        cloud.points[i++].z = 0;
    }

    for(int r=0; r<21; r++){
        cloud.points[i].x = (float) r/20;
        cloud.points[i].y =0;
        cloud.points[i++].z = 0;
    }

}

void LineDetector::Erosion()
{
  int erosion_type;
  if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }
  else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }
  else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( erosion_type,
                                       Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                       Point( erosion_size, erosion_size ) );
  // Apply the erosion operation
  erode( dst, dst, element );
}

/** Dilation enhances the white lines */
void LineDetector::Dilation()
{
  int dilation_type;
  if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }
  else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }
  else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( dilation_type,
                                       Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       Point( dilation_size, dilation_size ) );
  // Apply the dilation operation
  dilate( dst, dst, element );

}

/**
 *  @brief LineDetector::blackAndWhite converts the image into
 *         black (not lines) and white (lines)
 *  @param totalAvg The average brightness of the picture
 */
void LineDetector::blackAndWhite(float totalAvg){
    Vec3b p;
    int rows = src.rows;
    int cols = src.cols;

    //Turn the top quarter of the screen and bottom sixth of the screen black
    //We can disregard these areas - may extend the bottom of the screen slightly later on
    for (int i = 0; i< rows/3; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
    for (int i = rows*5/6; i< rows; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }

    //Loops through relevant parts of the image and scans for white lines
    //Also tries to detect obstacles
    int tempAvg;
    for (int i = rows/3; i< rows*5/6; i++){
        for(int j=0; j< cols; j++){
            tempAvg = totalAvg*(1.1 - i*.1/768);
            p = dst.at<Vec3b>(i, j); //Current pixel

            //If there is a significant amount of red in the pixel, it's most likely an orange cone
            //Get rid of the obstacle
            if (p[2] > totalAvg*2|| p[2] > 253){
                detectObstacle(i, j);
            }
            //Filters out the white and makes it pure white
            if((p[0]>tempAvg*1.5)&& (p[0] < tempAvg*2.2)&& (p[1] < tempAvg*1.6)&&(p[2]>tempAvg*1.1) &&
                    (p[2]<tempAvg*1.7)&&(p[1]>tempAvg*1.05)&&(abs(p[1] - p[2]) <20)){
                dst.at<Vec3b>(i,j)[0] = 255;
                dst.at<Vec3b>(i,j)[1] = 255;
                dst.at<Vec3b>(i,j)[2] = 255;

            }
            else { //Otherwise, set pixel to black
                dst.at<Vec3b>(i,j)[0] = 0;
                dst.at<Vec3b>(i,j)[1] = 0;
                dst.at<Vec3b>(i,j)[2] = 0;
            }
        }
    }
}

/**
 *  \brief LineDetector::detectObstacle detects orange and bright white obstacles
 *  \param col the column of the left of the obstacle
 */
void LineDetector::detectObstacle(int row, int col){
    Vec3b p = dst.at<Vec3b>(row,col);
    int row2 = row;
    int col2 = col;

    //While the pixel is still orange, turn it black
    //Then on to the next one, by row
    while (p[2]>100){
        dst.at<Vec3b>(row2, col)[0] = 0;
        dst.at<Vec3b>(row2, col)[1] = 0;
        dst.at<Vec3b>(row2, col)[2] = 0;
        p = dst.at<Vec3b>(++row2, col);
    }
    p = dst.at<Vec3b>(row,col);

    //While the pixel is still orange, turn it black
    //Then on to the next one, by column
    while (p[2]>100){
        dst.at<Vec3b>(row, col2)[0] = 0;
        dst.at<Vec3b>(row, col2)[1] = 0;
        dst.at<Vec3b>(row, col2)[2] = 0;
        p = dst.at<Vec3b>(row, ++col2);
    }

    //Turn everything in that block we just found black
    for(int i = row+1; i<row2;i++){
        for (int j = col+1; j<col2; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

/**
 *  \brief LineDetector::getAvg gets the average of the relevant pixels
 *  \return the average as a floating point number
 */
float LineDetector::getAvg(){
    Vec3b p;
    float totalAvg = 0;
    for (int i = src.rows/3; i< 5*src.rows/6; i++){
        for(int j=src.cols/6; j< 5*src.cols/6; j++){
            p = dst.at<Vec3b>(i, j);
            totalAvg += (p[0]+p[1]+p[2])/3;
        }
    }
    totalAvg = (25*totalAvg)/(src.cols*src.rows*8);
    return totalAvg;
}

/**
 *  \brief LineDetector::blackoutSection turns a section of the image black
 *  \param rowl the lower row bound
 *  \param rowu the upper row bound
 *  \param coll the left column bound
 *  \param colu the right column bound
 */
void LineDetector::blackoutSection(int rowl, int rowu, int coll, int colu){

    for (int i=rowl;i<=rowu;i++){
        for (int j = coll; j<=colu; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

<|endoftext|>


<commit_before>// bslim_gtestutil.cpp                                                -*-C++-*-

#include <bslim_gtestutil.h>

namespace BloombergLP {
namespace balb {

}  // close package namespace
}  // close enterprise namespace

// ----------------------------------------------------------------------------
// Copyright 2018 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<commit_msg>bslim_gtestutil.cpp: typo<commit_after>// bslim_gtestutil.cpp                                                -*-C++-*-

#include <bslim_gtestutil.h>

namespace BloombergLP {
namespace bslim {

}  // close package namespace
}  // close enterprise namespace

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


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

#include "proton/io/connection_driver.hpp"

#include "proton/event_loop.hpp"
#include "proton/error.hpp"
#include "proton/messaging_handler.hpp"
#include "proton/uuid.hpp"

#include "contexts.hpp"
#include "messaging_adapter.hpp"
#include "msg.hpp"
#include "proton_bits.hpp"
#include "proton_event.hpp"

#include <proton/connection.h>
#include <proton/transport.h>
#include <proton/event.h>

#include <algorithm>

namespace proton {
namespace io {

void connection_driver::init() {
    if (pn_connection_driver_init(&driver_, pn_connection(), pn_transport()) != 0) {
        this->~connection_driver(); // Dtor won't be called on throw from ctor.
        throw proton::error(std::string("connection_driver allocation failed"));
    }
}

connection_driver::connection_driver() : handler_(0), container_(0) { init(); }

connection_driver::connection_driver(class container& cont) : handler_(0), container_(&cont) {
    init();
    connection_context& ctx = connection_context::get(unwrap(connection()));
    ctx.container = container_;
}

#if PN_CPP_HAS_RVALUE_REFERENCES
connection_driver::connection_driver(class container& cont, event_loop&& loop) : handler_(0), container_(&cont) {
    init();
    connection_context& ctx = connection_context::get(unwrap(connection()));
    ctx.container = container_;
    ctx.event_loop_ = loop.impl_.get();
}
#endif

connection_driver::~connection_driver() {
    pn_connection_driver_destroy(&driver_);
}

// FIXME aconway 2016-11-16: rename _engine > _driver
void connection_driver::configure(const connection_options& opts, bool server) {
    proton::connection c(connection());
    opts.apply_unbound(c);
    if (server) pn_transport_set_server(driver_.transport);
    pn_connection_driver_bind(&driver_);
    opts.apply_bound(c);
    handler_ =  opts.handler();
}

void connection_driver::connect(const connection_options& opts) {
    connection_options all;
    if (container_) {
        all.container_id(container_->id());
        all.update(container_->client_connection_options());
    }
    all.update(opts);
    configure(all, false);
    connection().open();
}

void connection_driver::accept(const connection_options& opts) {
    connection_options all;
    if (container_) {
        all.container_id(container_->id());
        all.update(container_->server_connection_options());
    }
    all.update(opts);
    configure(all, true);
}

bool connection_driver::dispatch() {
    pn_event_t* c_event;
    while ((c_event = pn_connection_driver_next_event(&driver_)) != NULL) {
        proton_event cpp_event(c_event, container_);
        try {
            if (handler_ != 0) {
                messaging_adapter adapter(*handler_);
                cpp_event.dispatch(adapter);
            }
        } catch (const std::exception& e) {
            pn_condition_t *cond = pn_transport_condition(driver_.transport);
            if (!pn_condition_is_set(cond)) {
                pn_condition_format(cond, "exception", "%s", e.what());
            }
        }
    }
    return !pn_connection_driver_finished(&driver_);
}

mutable_buffer connection_driver::read_buffer() {
    pn_rwbytes_t buffer = pn_connection_driver_read_buffer(&driver_);
    return mutable_buffer(buffer.start, buffer.size);
}

void connection_driver::read_done(size_t n) {
    return pn_connection_driver_read_done(&driver_, n);
}

void connection_driver::read_close() {
    pn_connection_driver_read_close(&driver_);
}

const_buffer connection_driver::write_buffer() {
    pn_bytes_t buffer = pn_connection_driver_write_buffer(&driver_);
    return const_buffer(buffer.start, buffer.size);
}

void connection_driver::write_done(size_t n) {
    return pn_connection_driver_write_done(&driver_, n);
}

void connection_driver::write_close() {
    pn_connection_driver_write_close(&driver_);
}

void connection_driver::disconnected(const proton::error_condition& err) {
    pn_condition_t* condition = pn_transport_condition(driver_.transport);
    if (!pn_condition_is_set(condition))  {
        set_error_condition(err, condition);
    }
    pn_connection_driver_close(&driver_);
}

proton::connection connection_driver::connection() const {
    return make_wrapper(driver_.connection);
}

proton::transport connection_driver::transport() const {
    return make_wrapper(driver_.transport);
}

proton::container* connection_driver::container() const {
    return container_;
}

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

#include "proton/io/connection_driver.hpp"

#include "proton/event_loop.hpp"
#include "proton/error.hpp"
#include "proton/messaging_handler.hpp"
#include "proton/uuid.hpp"

#include "contexts.hpp"
#include "messaging_adapter.hpp"
#include "msg.hpp"
#include "proton_bits.hpp"
#include "proton_event.hpp"

#include <proton/connection.h>
#include <proton/transport.h>
#include <proton/event.h>

#include <algorithm>

namespace proton {
namespace io {

void connection_driver::init() {
    if (pn_connection_driver_init(&driver_, pn_connection(), pn_transport()) != 0) {
        this->~connection_driver(); // Dtor won't be called on throw from ctor.
        throw proton::error(std::string("connection_driver allocation failed"));
    }
}

connection_driver::connection_driver() : handler_(0), container_(0) { init(); }

connection_driver::connection_driver(class container& cont) : handler_(0), container_(&cont) {
    init();
    connection_context& ctx = connection_context::get(unwrap(connection()));
    ctx.container = container_;
}

#if PN_CPP_HAS_RVALUE_REFERENCES
connection_driver::connection_driver(class container& cont, event_loop&& loop) : handler_(0), container_(&cont) {
    init();
    connection_context& ctx = connection_context::get(unwrap(connection()));
    ctx.container = container_;
    ctx.event_loop_ = loop.impl_.get();
}
#endif

connection_driver::~connection_driver() {
    pn_connection_driver_destroy(&driver_);
}

void connection_driver::configure(const connection_options& opts, bool server) {
    proton::connection c(connection());
    opts.apply_unbound(c);
    if (server) pn_transport_set_server(driver_.transport);
    pn_connection_driver_bind(&driver_);
    opts.apply_bound(c);
    handler_ =  opts.handler();
}

void connection_driver::connect(const connection_options& opts) {
    connection_options all;
    if (container_) {
        all.container_id(container_->id());
        all.update(container_->client_connection_options());
    }
    all.update(opts);
    configure(all, false);
    connection().open();
}

void connection_driver::accept(const connection_options& opts) {
    connection_options all;
    if (container_) {
        all.container_id(container_->id());
        all.update(container_->server_connection_options());
    }
    all.update(opts);
    configure(all, true);
}

bool connection_driver::dispatch() {
    pn_event_t* c_event;
    while ((c_event = pn_connection_driver_next_event(&driver_)) != NULL) {
        proton_event cpp_event(c_event, container_);
        try {
            if (handler_ != 0) {
                messaging_adapter adapter(*handler_);
                cpp_event.dispatch(adapter);
            }
        } catch (const std::exception& e) {
            pn_condition_t *cond = pn_transport_condition(driver_.transport);
            if (!pn_condition_is_set(cond)) {
                pn_condition_format(cond, "exception", "%s", e.what());
            }
        }
    }
    return !pn_connection_driver_finished(&driver_);
}

mutable_buffer connection_driver::read_buffer() {
    pn_rwbytes_t buffer = pn_connection_driver_read_buffer(&driver_);
    return mutable_buffer(buffer.start, buffer.size);
}

void connection_driver::read_done(size_t n) {
    return pn_connection_driver_read_done(&driver_, n);
}

void connection_driver::read_close() {
    pn_connection_driver_read_close(&driver_);
}

const_buffer connection_driver::write_buffer() {
    pn_bytes_t buffer = pn_connection_driver_write_buffer(&driver_);
    return const_buffer(buffer.start, buffer.size);
}

void connection_driver::write_done(size_t n) {
    return pn_connection_driver_write_done(&driver_, n);
}

void connection_driver::write_close() {
    pn_connection_driver_write_close(&driver_);
}

void connection_driver::disconnected(const proton::error_condition& err) {
    pn_condition_t* condition = pn_transport_condition(driver_.transport);
    if (!pn_condition_is_set(condition))  {
        set_error_condition(err, condition);
    }
    pn_connection_driver_close(&driver_);
}

proton::connection connection_driver::connection() const {
    return make_wrapper(driver_.connection);
}

proton::transport connection_driver::transport() const {
    return make_wrapper(driver_.transport);
}

proton::container* connection_driver::container() const {
    return container_;
}

}}
<|endoftext|>