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

#include "renderer.h"
#include "keyareaitem.h"
#include "keyitem.h"
#include "wordribbonitem.h"
#include "utils.h"

#include "models/keyarea.h"
#include "models/wordribbon.h"

#ifdef MALIIT_KEYBOARD_HAVE_OPENGL
#include <QGLWidget>
#endif

#include <maliit/plugins/abstractwidgetssurface.h>

using Maliit::Plugins::AbstractGraphicsViewSurface;
using Maliit::Plugins::AbstractSurface;
using Maliit::Plugins::AbstractSurfaceFactory;

namespace MaliitKeyboard {

namespace {

const qreal WordRibbonZIndex = 0.0f;
const qreal CenterPanelZIndex = 1.0f;
const qreal ExtendedPanelZIndex = 20.0f;
const qreal ActiveKeyZIndex = 0.0f;

void recycleKeyItem(QVector<KeyItem *> *key_items,
                    int index,
                    const Key &key,
                    QGraphicsItem *parent)
{
    KeyItem *item = 0;

    if (index >= key_items->count()) {
        item = new KeyItem;
        item->setZValue(ActiveKeyZIndex);
        key_items->append(item);
    } else {
        item = key_items->at(index);
    }

    item->setParentItem(parent);
    item->setKey(key);
    item->show();
}

void updateActiveKeys(const QVector<Key> &active_keys,
                      QVector<KeyItem *> *key_items,
                      QGraphicsItem *parent,
                      const Logic::KeyOverrides& overrides)
{
    int index = 0;

    for (; index < active_keys.count(); ++index) {
        Key key(Utils::applyOverride(active_keys.at(index), overrides));

        recycleKeyItem(key_items, index, key, parent);
    }

    // Hide remaining, currently unneeded key items:
    for (; index < key_items->count(); ++index) {
        key_items->at(index)->hide();
    }
}

} // namespace

class RendererPrivate
{
public:
    Maliit::Plugins::AbstractSurfaceFactory *factory;
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> surface;
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> extended_surface;
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> magnifier_surface;
    SharedStyle style;
    KeyAreaItem *center_item;
    KeyAreaItem *extended_item;
    WordRibbonItem *ribbon_item;
    QVector<KeyItem *> key_items;
    QVector<KeyItem *> extended_key_items;
    QVector<KeyItem *> magnifier_key_items;
    QString images_directory_path;

    explicit RendererPrivate()
        : factory(0)
        , surface()
        , extended_surface()
        , magnifier_surface()
        , center_item(new KeyAreaItem)
        , extended_item(new KeyAreaItem)
        , ribbon_item(new WordRibbonItem)
        , key_items()
        , extended_key_items()
        , magnifier_key_items()
    {
        center_item->setZValue(CenterPanelZIndex);
        extended_item->setZValue(ExtendedPanelZIndex);
        ribbon_item->setZValue(WordRibbonZIndex);
    }
};

Renderer::Renderer(QObject *parent)
    : QObject(parent)
    , d_ptr(new RendererPrivate)
{}

Renderer::~Renderer()
{}

void Renderer::setSurfaceFactory(AbstractSurfaceFactory *factory)
{
    Q_D(Renderer);
    d->factory = factory;

    // Assuming that factory == 0 means reset:
    if (not d->factory) {
        // Drop references => shared surface instances are eventually deleted:
        d->surface.clear();
        d->extended_surface.clear();
        d->magnifier_surface.clear();
        return;
    }

    d->surface = qSharedPointerDynamicCast<AbstractGraphicsViewSurface>(
        factory->create(AbstractSurface::PositionCenterBottom | AbstractSurface::TypeGraphicsView));

    d->extended_surface = qSharedPointerDynamicCast<AbstractGraphicsViewSurface>(
        factory->create(AbstractSurface::PositionOverlay | AbstractSurface::TypeGraphicsView, d->surface));

    d->magnifier_surface = qSharedPointerDynamicCast<AbstractGraphicsViewSurface>(
        factory->create(AbstractSurface::PositionOverlay | AbstractSurface::TypeGraphicsView, d->surface));
}

const QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> Renderer::surface() const
{
    Q_D(const Renderer);

    return d->surface;
}

const QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> Renderer::extendedSurface() const
{
    Q_D(const Renderer);

    return d->extended_surface;
}

void Renderer::setStyle(const SharedStyle &style)
{
    Q_D(Renderer);
    if (d->style != style) {
        if (d->style) {
            disconnect(d->style.data(), SIGNAL(profileChanged()),
                       this,            SLOT(applyProfile()));
        }
        d->style = style;
        connect(d->style.data(), SIGNAL(profileChanged()),
                this,            SLOT(applyProfile()));
        applyProfile();
    }
}

void Renderer::show()
{
    Q_D(Renderer);

    if (d->surface.isNull()
        || d->extended_surface.isNull()
        || d->magnifier_surface.isNull()) {
        qCritical() << __PRETTY_FUNCTION__
                    << "Some surfaces not available, cannot show keyboard!"
                    << "Discarding show request.";
        return;
    }

    d->surface->show();
    d->extended_surface->show();

    // The root item of a surface only becomes valid after being shown (for
    // the first time):
    d->center_item->setParentItem(d->surface->root());
    d->extended_item->setParentItem(d->extended_surface->root());
    d->ribbon_item->setParentItem(d->surface->root());
}

void Renderer::hide()
{
    Q_D(Renderer);

    if (d->surface.isNull()
        || d->extended_surface.isNull()
        || d->magnifier_surface.isNull()) {
        qCritical() << __PRETTY_FUNCTION__
                    << "Some surfaces not available, cannot hide keyboard!"
                    << "Discarding hide request.";
        return;
    }

    d->surface->hide();
    d->extended_surface->hide();
    d->magnifier_surface->hide();
}

void Renderer::onActiveKeysChanged(const QVector<Key> &active_keys,
                                   const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);
    updateActiveKeys(active_keys, &d->key_items, d->center_item, overrides);
}

void Renderer::onActiveExtendedKeysChanged(const QVector<Key> &active_keys,
                                           const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);
    updateActiveKeys(active_keys, &d->extended_key_items, d->extended_item, overrides);
}

void Renderer::onMagnifierKeyChanged(const Key &key,
                                     const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);

    if (key.valid()) {
        Key magnifier_key(Utils::applyOverride(key, overrides));
        d->magnifier_surface->setSize(magnifier_key.area().size());
        d->magnifier_surface->setRelativePosition(magnifier_key.origin());
        magnifier_key.setOrigin(QPoint());
        d->magnifier_surface->show();
        recycleKeyItem(&d->magnifier_key_items, 0, magnifier_key, d->magnifier_surface->root());
    } else {
        d->magnifier_surface->hide();
    }
}

void Renderer::onCenterPanelChanged(const KeyArea &key_area,
                                    const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);

    const QSize &ka_size(key_area.area().size());
    const QPoint &origin(key_area.origin());

    d->center_item->setKeyArea(key_area);
    d->center_item->setKeyOverrides(overrides);
    d->center_item->setVisible(ka_size.isValid());

    if (d->center_item->isVisible()) {
        d->surface->setSize(QSize(ka_size.width() + origin.x(),
                                  ka_size.height() + origin.y()));
        d->surface->show();
    } else {
        d->surface->hide();
    }
}

void Renderer::onExtendedPanelChanged(const KeyArea &key_area,
                                      const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);

    const QSize &ka_size(key_area.area().size());
    const QPoint &origin(key_area.origin());

    // For extended keys, we move the surface itself, not the key area:
    KeyArea extended_key_area(key_area);
    extended_key_area.setOrigin(QPoint());

    d->extended_item->setKeyArea(extended_key_area);
    d->extended_item->setKeyOverrides(overrides);
    d->extended_item->setVisible(ka_size.isValid());

    if (d->extended_item->isVisible()) {
        d->extended_surface->setSize(ka_size);
        d->extended_surface->setRelativePosition(origin);
        d->extended_surface->show();
    } else {
        d->extended_surface->hide();
    }
}

void Renderer::onWordRibbonChanged(const WordRibbon &ribbon)
{
    Q_D(Renderer);

    d->ribbon_item->setWordRibbon(ribbon);
    d->ribbon_item->setVisible(ribbon.rect().isValid());
}

void Renderer::applyProfile()
{
    Q_D(Renderer);
    Utils::setImagesDirectoryPath(d->style->directoryPath(Style::Images));
}

} // namespace MaliitKeyboard
<commit_msg>Load font files on every style change.<commit_after>/*
 * This file is part of Maliit Plugins
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
 * Copyright (C) 2012 Openismus GmbH
 *
 * Contact: Mohammad Anwari <Mohammad.Anwari@nokia.com>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * Neither the name of Nokia Corporation nor the names of its contributors may be
 * used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "renderer.h"
#include "keyareaitem.h"
#include "keyitem.h"
#include "wordribbonitem.h"
#include "utils.h"

#include "models/keyarea.h"
#include "models/wordribbon.h"

#ifdef MALIIT_KEYBOARD_HAVE_OPENGL
#include <QGLWidget>
#endif

#include <maliit/plugins/abstractwidgetssurface.h>

using Maliit::Plugins::AbstractGraphicsViewSurface;
using Maliit::Plugins::AbstractSurface;
using Maliit::Plugins::AbstractSurfaceFactory;

namespace MaliitKeyboard {

namespace {

const qreal WordRibbonZIndex = 0.0f;
const qreal CenterPanelZIndex = 1.0f;
const qreal ExtendedPanelZIndex = 20.0f;
const qreal ActiveKeyZIndex = 0.0f;

void recycleKeyItem(QVector<KeyItem *> *key_items,
                    int index,
                    const Key &key,
                    QGraphicsItem *parent)
{
    KeyItem *item = 0;

    if (index >= key_items->count()) {
        item = new KeyItem;
        item->setZValue(ActiveKeyZIndex);
        key_items->append(item);
    } else {
        item = key_items->at(index);
    }

    item->setParentItem(parent);
    item->setKey(key);
    item->show();
}

void updateActiveKeys(const QVector<Key> &active_keys,
                      QVector<KeyItem *> *key_items,
                      QGraphicsItem *parent,
                      const Logic::KeyOverrides& overrides)
{
    int index = 0;

    for (; index < active_keys.count(); ++index) {
        Key key(Utils::applyOverride(active_keys.at(index), overrides));

        recycleKeyItem(key_items, index, key, parent);
    }

    // Hide remaining, currently unneeded key items:
    for (; index < key_items->count(); ++index) {
        key_items->at(index)->hide();
    }
}

void loadFontFiles(const QString &fonts_dir,
                   const QStringList &font_files)
{
    Q_FOREACH (const QString &font_file, font_files) {
        const QString full_font_path(fonts_dir + "/" + font_file);

        if (QFontDatabase::addApplicationFont(full_font_path) < 0) {
            qCritical() << __PRETTY_FUNCTION__
                        << "Could not load a font file" << full_font_path;
        }
    }
}

} // namespace

class RendererPrivate
{
public:
    Maliit::Plugins::AbstractSurfaceFactory *factory;
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> surface;
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> extended_surface;
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> magnifier_surface;
    SharedStyle style;
    KeyAreaItem *center_item;
    KeyAreaItem *extended_item;
    WordRibbonItem *ribbon_item;
    QVector<KeyItem *> key_items;
    QVector<KeyItem *> extended_key_items;
    QVector<KeyItem *> magnifier_key_items;
    QString images_directory_path;

    explicit RendererPrivate()
        : factory(0)
        , surface()
        , extended_surface()
        , magnifier_surface()
        , center_item(new KeyAreaItem)
        , extended_item(new KeyAreaItem)
        , ribbon_item(new WordRibbonItem)
        , key_items()
        , extended_key_items()
        , magnifier_key_items()
    {
        center_item->setZValue(CenterPanelZIndex);
        extended_item->setZValue(ExtendedPanelZIndex);
        ribbon_item->setZValue(WordRibbonZIndex);
    }
};

Renderer::Renderer(QObject *parent)
    : QObject(parent)
    , d_ptr(new RendererPrivate)
{}

Renderer::~Renderer()
{}

void Renderer::setSurfaceFactory(AbstractSurfaceFactory *factory)
{
    Q_D(Renderer);
    d->factory = factory;

    // Assuming that factory == 0 means reset:
    if (not d->factory) {
        // Drop references => shared surface instances are eventually deleted:
        d->surface.clear();
        d->extended_surface.clear();
        d->magnifier_surface.clear();
        return;
    }

    d->surface = qSharedPointerDynamicCast<AbstractGraphicsViewSurface>(
        factory->create(AbstractSurface::PositionCenterBottom | AbstractSurface::TypeGraphicsView));

    d->extended_surface = qSharedPointerDynamicCast<AbstractGraphicsViewSurface>(
        factory->create(AbstractSurface::PositionOverlay | AbstractSurface::TypeGraphicsView, d->surface));

    d->magnifier_surface = qSharedPointerDynamicCast<AbstractGraphicsViewSurface>(
        factory->create(AbstractSurface::PositionOverlay | AbstractSurface::TypeGraphicsView, d->surface));
}

const QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> Renderer::surface() const
{
    Q_D(const Renderer);

    return d->surface;
}

const QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> Renderer::extendedSurface() const
{
    Q_D(const Renderer);

    return d->extended_surface;
}

void Renderer::setStyle(const SharedStyle &style)
{
    Q_D(Renderer);
    if (d->style != style) {
        if (d->style) {
            disconnect(d->style.data(), SIGNAL(profileChanged()),
                       this,            SLOT(applyProfile()));
        }
        d->style = style;
        connect(d->style.data(), SIGNAL(profileChanged()),
                this,            SLOT(applyProfile()));
        applyProfile();
    }
}

void Renderer::show()
{
    Q_D(Renderer);

    if (d->surface.isNull()
        || d->extended_surface.isNull()
        || d->magnifier_surface.isNull()) {
        qCritical() << __PRETTY_FUNCTION__
                    << "Some surfaces not available, cannot show keyboard!"
                    << "Discarding show request.";
        return;
    }

    d->surface->show();
    d->extended_surface->show();

    // The root item of a surface only becomes valid after being shown (for
    // the first time):
    d->center_item->setParentItem(d->surface->root());
    d->extended_item->setParentItem(d->extended_surface->root());
    d->ribbon_item->setParentItem(d->surface->root());
}

void Renderer::hide()
{
    Q_D(Renderer);

    if (d->surface.isNull()
        || d->extended_surface.isNull()
        || d->magnifier_surface.isNull()) {
        qCritical() << __PRETTY_FUNCTION__
                    << "Some surfaces not available, cannot hide keyboard!"
                    << "Discarding hide request.";
        return;
    }

    d->surface->hide();
    d->extended_surface->hide();
    d->magnifier_surface->hide();
}

void Renderer::onActiveKeysChanged(const QVector<Key> &active_keys,
                                   const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);
    updateActiveKeys(active_keys, &d->key_items, d->center_item, overrides);
}

void Renderer::onActiveExtendedKeysChanged(const QVector<Key> &active_keys,
                                           const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);
    updateActiveKeys(active_keys, &d->extended_key_items, d->extended_item, overrides);
}

void Renderer::onMagnifierKeyChanged(const Key &key,
                                     const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);

    if (key.valid()) {
        Key magnifier_key(Utils::applyOverride(key, overrides));
        d->magnifier_surface->setSize(magnifier_key.area().size());
        d->magnifier_surface->setRelativePosition(magnifier_key.origin());
        magnifier_key.setOrigin(QPoint());
        d->magnifier_surface->show();
        recycleKeyItem(&d->magnifier_key_items, 0, magnifier_key, d->magnifier_surface->root());
    } else {
        d->magnifier_surface->hide();
    }
}

void Renderer::onCenterPanelChanged(const KeyArea &key_area,
                                    const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);

    const QSize &ka_size(key_area.area().size());
    const QPoint &origin(key_area.origin());

    d->center_item->setKeyArea(key_area);
    d->center_item->setKeyOverrides(overrides);
    d->center_item->setVisible(ka_size.isValid());

    if (d->center_item->isVisible()) {
        d->surface->setSize(QSize(ka_size.width() + origin.x(),
                                  ka_size.height() + origin.y()));
        d->surface->show();
    } else {
        d->surface->hide();
    }
}

void Renderer::onExtendedPanelChanged(const KeyArea &key_area,
                                      const Logic::KeyOverrides &overrides)
{
    Q_D(Renderer);

    const QSize &ka_size(key_area.area().size());
    const QPoint &origin(key_area.origin());

    // For extended keys, we move the surface itself, not the key area:
    KeyArea extended_key_area(key_area);
    extended_key_area.setOrigin(QPoint());

    d->extended_item->setKeyArea(extended_key_area);
    d->extended_item->setKeyOverrides(overrides);
    d->extended_item->setVisible(ka_size.isValid());

    if (d->extended_item->isVisible()) {
        d->extended_surface->setSize(ka_size);
        d->extended_surface->setRelativePosition(origin);
        d->extended_surface->show();
    } else {
        d->extended_surface->hide();
    }
}

void Renderer::onWordRibbonChanged(const WordRibbon &ribbon)
{
    Q_D(Renderer);

    d->ribbon_item->setWordRibbon(ribbon);
    d->ribbon_item->setVisible(ribbon.rect().isValid());
}

void Renderer::applyProfile()
{
    Q_D(Renderer);
    Utils::setImagesDirectoryPath(d->style->directoryPath(Style::Images));

    const QStringList font_files(d->style->attributes()->fontFiles());
    const QString fonts_dir(d->style->directoryPath(Style::Fonts));

    loadFontFiles(fonts_dir, d->style->attributes()->fontFiles());
    loadFontFiles(fonts_dir, d->style->extendedKeysAttributes()->fontFiles());
}

} // namespace MaliitKeyboard
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <cstring>
#include <pwd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include "agfs-server.hpp"
#include "constants.hpp"
#include "agfsio.hpp"

ClientConnection::ClientConnection(int connfd) {

	//Set timeout
	struct timeval tv;
	tv.tv_sec = SERVER_BLOCK_SEC;
	tv.tv_usec = SERVER_BLOCK_USEC;
	setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)(&tv), sizeof(struct timeval));
	int iMode = 0;
	ioctl(connfd, FIONBIO, &iMode);

	//Verify server key
	std::string clientKey;
	char key[ASCII_KEY_LEN+1];
	memset(key, 0, ASCII_KEY_LEN+1);
	//read(connfd, key, ASCII_KEY_LEN);
	agfs_read_string(connfd, clientKey);

	std::fstream authkeys;
	authkeys.open(KEY_LIST_PATH, std::fstream::in);

	std::string mountPath, user, serverKey;
	bool validKey = false;

	while(!authkeys.eof()) {
		authkeys >> mountPath >> user >> serverKey;
		std::cout << "CLIENT: " << clientKey << std::endl;
		std::cout << "SERVER: " << serverKey << std::endl;
		std::cout << serverKey.length() << " " << clientKey.length() << std::endl;
		if(serverKey.compare(clientKey) == 0) {
			validKey = true;
			break;
		}
	}

	if(validKey == false) {
		agfs_write_cmd(connfd, cmd::INVALID_KEY);
		close(connfd);
		socket_ = -1;
		return;
	}

	//Change user
	struct passwd* userPwd = getpwnam(user.c_str());
	if(userPwd == NULL) {
		agfs_write_cmd(connfd, cmd::USER_NOT_FOUND);
		close(connfd);
		socket_ = -1;
		return;
	} else {
		setuid(userPwd->pw_uid);
		setgid(userPwd->pw_gid);
	}

	//Check that mount point exists
	if(!boost::filesystem::exists(mountPath)) {
		agfs_write_cmd(connfd, cmd::MOUNT_NOT_FOUND);
		close(connfd);
		socket_ = -1;
		return;
	}

	socket_ = connfd;
	mountPoint_ = mountPath;
	beatsMissed_ = 0;
}

bool ClientConnection::connected() {
	return socket_ > -1;
}

void ClientConnection::processCommands() {
	//Passed all checks accept connection and keep alive until heartbeat
	//failure or explicit stop
	agfs_write_cmd(socket_, cmd::ACCEPT);
	while(1) {
		cmd_t cmd = cmd::GETATTR;
		int respVal = agfs_read_cmd(socket_, cmd);
		if(respVal <= 0) {
			std::cout << "Missed heartbeat" << std::endl;
			beatsMissed_ += 1;
			if (beatsMissed_ > 5) {
				close(socket_);
				socket_ = -1;
				return;
			}
		} else {
			switch(cmd) {
			case cmd::STOP:
				std::cerr << "STOP called" << std::endl;
				close(socket_);
				socket_ = -1;
				return;
			case cmd::HEARTBEAT:
				std::cerr << "Received heartbeat" << std::endl;
				processHeartbeat();
				break;
			case cmd::GETATTR:
				std::cerr << "GETATTR called" << std::endl;
				processGetAttr();
				break;
			case cmd::READDIR:
				std::cerr << "READDIR called" << std::endl;
				processReaddir();
				break;
			case cmd::ACCESS:
				std::cerr << "ACCESS called" << std::endl;
				processAccess();
				break;
			case cmd::READ:
				std::cerr << "READ called" << std::endl;
				processRead();
				break;
			case cmd::WRITE:
				std::cerr << "WRITE called"  << std::endl;
				processWrite();
				break;
			case cmd::OPEN:
				std::cerr << "OPEN called" << std::endl;
				processOpen();
				break;
			default:
				std::cerr << "Unknown command" << std::endl;
			}
		}
		//Do stuff here
	}
}

void ClientConnection::processHeartbeat() {
	agfs_write_cmd(socket_, cmd::HEARTBEAT);
}

/*
 * Incoming stack looks like:
 *
 *      STRING
 *
 * Outgoing stack looks like:
 *
 *      ERROR [STAT]
 */
void ClientConnection::processGetAttr() {
	std::string path;
	agfs_read_string(socket_, path);
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	struct stat retValue;
	memset(&retValue, 0, sizeof(struct stat));
	agerr_t error;
	if ((error = lstat(file.c_str(), &retValue)) < 0) {
		error = -errno;
	}

	agfs_write_error(socket_, error);
	if (error >= 0) {
		agfs_write_stat(socket_, retValue);
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING MASK
 *
 * Outgoing stack looks like:
 *
 *      ERROR
 */
void ClientConnection::processAccess() {
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	//Grab the access mask.
	agmask_t mask;
	agfs_read_mask(socket_, mask);

	//Attempt to access the file.
	agerr_t result = access(file.c_str(), mask);

	//Write our result
	agfs_write_error(socket_, result);
}

/*
 * Incoming stack looks like:
 *
 *      STRING
 *
 * Outgoing stack looks like:
 *
 *      ERROR [SIZE [STRING STAT]*]
 */
void ClientConnection::processReaddir() {
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	agerr_t error = 0;
	if (!boost::filesystem::exists(file)) {
		error = -ENOENT;
	}

	if (!boost::filesystem::is_directory(file)) {
		error = -ENOTDIR;
	}
	agfs_write_error(socket_, error);

	//Short circuit if we have an error.
	if (error >= 0) {
		//Write the number of entries in the directory to the pipe.
		agsize_t count = 0;
		boost::filesystem::directory_iterator end_itr{};
		for (boost::filesystem::directory_iterator dir_itr(file);
			dir_itr != end_itr; dir_itr++) {
			count++;
		}
		agfs_write_size(socket_, count);

		//Write the filenames and associated stat's to the pipe.
		struct stat stbuf;
		for (boost::filesystem::directory_iterator dir_itr(file);
			dir_itr != end_itr; dir_itr++) {

			//Write the relative name here
			agfs_write_string(socket_, dir_itr->path().filename().string());

			//We need to stat the absolute name here
			memset(&stbuf, 0, sizeof(struct stat));
			lstat(dir_itr->path().c_str(), &stbuf);
			agfs_write_stat(socket_, stbuf);
		}
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING SIZE OFFSET
 *
 * Outgoing stack looks like:
 *
 *      ERROR [SIZE [DATA]*]
 */
void ClientConnection::processRead()
{
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	agsize_t size = 0;
	agfs_read_size(socket_, size);

	agsize_t offset = 0;
	agfs_read_size(socket_, offset);

	//Process the request
	agerr_t error = 0;

	int fd;
	if ((fd = open(file.c_str(), O_RDONLY)) < 0)
	{
		error = -errno;
		agfs_write_error(socket_, error);
		return;
	}

	lseek(fd, offset, SEEK_SET);

	//Read the file data into the buffer until we have either hit an error,
	//or we have satisfied the read request.
	agsize_t total_read = 0;
	std::vector<unsigned char> buf;
	buf.resize(size);
	while (total_read != size &&
			(error = read(fd, &buf[0] + total_read, size - total_read)) > 0) {
		total_read += error;
	}
	//Write the total number of bytes sent to the error value,
	//unless there was a legitimate error.
	error = error >= 0 ? total_read : error;
	agfs_write_error(socket_, error);

	if (error >= 0) {
		agfs_write_size(socket_, total_read);
		write(socket_, &buf[0], total_read);
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING [SIZE OFFSET DATA]
 *
 * Outgoing stack looks like:
 *
 *      ERROR [ERROR [SIZE]]
 *
 * The incoming stack will only contain parameters if the first error we return
 * indicates that that the file is on our machine.
 *
 * A quick note on the above outgoing stack. Although it may look like we can
 * get away with using the error value as the size, this is not true because
 * an error type is signed, whereas a size type is unsigned. If we were to use
 * the error to hold the total number of bytes written, we would have a very
 * rare bug that would occur when we tried to write large buffers to files.
 */
void ClientConnection::processWrite() {
	std::string path;
	agfs_read_string(fd_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	//Open the file to the correct location.
	int fd;
	agerr_t error = 0;
	if ((fd = open(file.c_str(), O_WRONLY)) < 0)
	{
		error = -errno;
	}

	agfs_write_error(fd_, error);
	if (error < 0) {
		return;
	}

	agsize_t size = 0;
	agfs_read_size(fd_, size);

	agsize_t offset = 0;
	agfs_read_size(fd_, offset);

	lseek(fd, offset, SEEK_SET);

	//Read data into buffer and write data into the file at the same time.
	std::vector<unsigned char> data{};
	data.resize(size);
	agsize_t total_read = 0, total_written = 0;
	error = 0;
	while (total_read != size &&
			(error = read(fd_, &data[0] + total_read, size - total_read)) > 0) {
		total_read += error;

		//We should be okay to use error here, since we are guaranteed that
		//it is positive.
		if ((error = write(fd, &data[0] + total_read - error, error)) > 0) {
			total_written += error;
		}
		else {
			agfs_write_error(fd_, -errno);
			return;
		}
	}
	close(fd);

	agfs_write_error(fd_, error);
	if (error >= 0) {
		agfs_write_size(fd_, total_written);
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING MASK
 *
 * Outgoing stack looks like:
 *
 *      ERROR
 */
void ClientConnection::processOpen() {
	//Read in the path
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the local filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	//Read in the mask
	agmask_t mask = 0;
	agfs_read_mask(socket_, mask);

	//Open the file and write the error
	agerr_t error = 0;
	int fd = -1;
	if ((fd = open(file.c_str(), mask)) < 0) {
		error = -errno;
	}

	//We might want to consider sending the file descriptor to the
	//client in a later iteration.
	close(fd);

	agfs_write_error(socket_, error);
}

void ClientConnection::processRelease()
{

}
<commit_msg>Forgot to change fd_ references to socket_ references when adding back in the process write function.<commit_after>#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <cstring>
#include <pwd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include "agfs-server.hpp"
#include "constants.hpp"
#include "agfsio.hpp"

ClientConnection::ClientConnection(int connfd) {

	//Set timeout
	struct timeval tv;
	tv.tv_sec = SERVER_BLOCK_SEC;
	tv.tv_usec = SERVER_BLOCK_USEC;
	setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)(&tv), sizeof(struct timeval));
	int iMode = 0;
	ioctl(connfd, FIONBIO, &iMode);

	//Verify server key
	std::string clientKey;
	char key[ASCII_KEY_LEN+1];
	memset(key, 0, ASCII_KEY_LEN+1);
	//read(connfd, key, ASCII_KEY_LEN);
	agfs_read_string(connfd, clientKey);

	std::fstream authkeys;
	authkeys.open(KEY_LIST_PATH, std::fstream::in);

	std::string mountPath, user, serverKey;
	bool validKey = false;

	while(!authkeys.eof()) {
		authkeys >> mountPath >> user >> serverKey;
		std::cout << "CLIENT: " << clientKey << std::endl;
		std::cout << "SERVER: " << serverKey << std::endl;
		std::cout << serverKey.length() << " " << clientKey.length() << std::endl;
		if(serverKey.compare(clientKey) == 0) {
			validKey = true;
			break;
		}
	}

	if(validKey == false) {
		agfs_write_cmd(connfd, cmd::INVALID_KEY);
		close(connfd);
		socket_ = -1;
		return;
	}

	//Change user
	struct passwd* userPwd = getpwnam(user.c_str());
	if(userPwd == NULL) {
		agfs_write_cmd(connfd, cmd::USER_NOT_FOUND);
		close(connfd);
		socket_ = -1;
		return;
	} else {
		setuid(userPwd->pw_uid);
		setgid(userPwd->pw_gid);
	}

	//Check that mount point exists
	if(!boost::filesystem::exists(mountPath)) {
		agfs_write_cmd(connfd, cmd::MOUNT_NOT_FOUND);
		close(connfd);
		socket_ = -1;
		return;
	}

	socket_ = connfd;
	mountPoint_ = mountPath;
	beatsMissed_ = 0;
}

bool ClientConnection::connected() {
	return socket_ > -1;
}

void ClientConnection::processCommands() {
	//Passed all checks accept connection and keep alive until heartbeat
	//failure or explicit stop
	agfs_write_cmd(socket_, cmd::ACCEPT);
	while(1) {
		cmd_t cmd = cmd::GETATTR;
		int respVal = agfs_read_cmd(socket_, cmd);
		if(respVal <= 0) {
			std::cout << "Missed heartbeat" << std::endl;
			beatsMissed_ += 1;
			if (beatsMissed_ > 5) {
				close(socket_);
				socket_ = -1;
				return;
			}
		} else {
			switch(cmd) {
			case cmd::STOP:
				std::cerr << "STOP called" << std::endl;
				close(socket_);
				socket_ = -1;
				return;
			case cmd::HEARTBEAT:
				std::cerr << "Received heartbeat" << std::endl;
				processHeartbeat();
				break;
			case cmd::GETATTR:
				std::cerr << "GETATTR called" << std::endl;
				processGetAttr();
				break;
			case cmd::READDIR:
				std::cerr << "READDIR called" << std::endl;
				processReaddir();
				break;
			case cmd::ACCESS:
				std::cerr << "ACCESS called" << std::endl;
				processAccess();
				break;
			case cmd::READ:
				std::cerr << "READ called" << std::endl;
				processRead();
				break;
			case cmd::WRITE:
				std::cerr << "WRITE called"  << std::endl;
				processWrite();
				break;
			case cmd::OPEN:
				std::cerr << "OPEN called" << std::endl;
				processOpen();
				break;
			default:
				std::cerr << "Unknown command" << std::endl;
			}
		}
		//Do stuff here
	}
}

void ClientConnection::processHeartbeat() {
	agfs_write_cmd(socket_, cmd::HEARTBEAT);
}

/*
 * Incoming stack looks like:
 *
 *      STRING
 *
 * Outgoing stack looks like:
 *
 *      ERROR [STAT]
 */
void ClientConnection::processGetAttr() {
	std::string path;
	agfs_read_string(socket_, path);
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	struct stat retValue;
	memset(&retValue, 0, sizeof(struct stat));
	agerr_t error;
	if ((error = lstat(file.c_str(), &retValue)) < 0) {
		error = -errno;
	}

	agfs_write_error(socket_, error);
	if (error >= 0) {
		agfs_write_stat(socket_, retValue);
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING MASK
 *
 * Outgoing stack looks like:
 *
 *      ERROR
 */
void ClientConnection::processAccess() {
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	//Grab the access mask.
	agmask_t mask;
	agfs_read_mask(socket_, mask);

	//Attempt to access the file.
	agerr_t result = access(file.c_str(), mask);

	//Write our result
	agfs_write_error(socket_, result);
}

/*
 * Incoming stack looks like:
 *
 *      STRING
 *
 * Outgoing stack looks like:
 *
 *      ERROR [SIZE [STRING STAT]*]
 */
void ClientConnection::processReaddir() {
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	agerr_t error = 0;
	if (!boost::filesystem::exists(file)) {
		error = -ENOENT;
	}

	if (!boost::filesystem::is_directory(file)) {
		error = -ENOTDIR;
	}
	agfs_write_error(socket_, error);

	//Short circuit if we have an error.
	if (error >= 0) {
		//Write the number of entries in the directory to the pipe.
		agsize_t count = 0;
		boost::filesystem::directory_iterator end_itr{};
		for (boost::filesystem::directory_iterator dir_itr(file);
			dir_itr != end_itr; dir_itr++) {
			count++;
		}
		agfs_write_size(socket_, count);

		//Write the filenames and associated stat's to the pipe.
		struct stat stbuf;
		for (boost::filesystem::directory_iterator dir_itr(file);
			dir_itr != end_itr; dir_itr++) {

			//Write the relative name here
			agfs_write_string(socket_, dir_itr->path().filename().string());

			//We need to stat the absolute name here
			memset(&stbuf, 0, sizeof(struct stat));
			lstat(dir_itr->path().c_str(), &stbuf);
			agfs_write_stat(socket_, stbuf);
		}
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING SIZE OFFSET
 *
 * Outgoing stack looks like:
 *
 *      ERROR [SIZE [DATA]*]
 */
void ClientConnection::processRead()
{
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	agsize_t size = 0;
	agfs_read_size(socket_, size);

	agsize_t offset = 0;
	agfs_read_size(socket_, offset);

	//Process the request
	agerr_t error = 0;

	int fd;
	if ((fd = open(file.c_str(), O_RDONLY)) < 0)
	{
		error = -errno;
		agfs_write_error(socket_, error);
		return;
	}

	lseek(fd, offset, SEEK_SET);

	//Read the file data into the buffer until we have either hit an error,
	//or we have satisfied the read request.
	agsize_t total_read = 0;
	std::vector<unsigned char> buf;
	buf.resize(size);
	while (total_read != size &&
			(error = read(fd, &buf[0] + total_read, size - total_read)) > 0) {
		total_read += error;
	}
	//Write the total number of bytes sent to the error value,
	//unless there was a legitimate error.
	error = error >= 0 ? total_read : error;
	agfs_write_error(socket_, error);

	if (error >= 0) {
		agfs_write_size(socket_, total_read);
		write(socket_, &buf[0], total_read);
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING [SIZE OFFSET DATA]
 *
 * Outgoing stack looks like:
 *
 *      ERROR [ERROR [SIZE]]
 *
 * The incoming stack will only contain parameters if the first error we return
 * indicates that that the file is on our machine.
 *
 * A quick note on the above outgoing stack. Although it may look like we can
 * get away with using the error value as the size, this is not true because
 * an error type is signed, whereas a size type is unsigned. If we were to use
 * the error to hold the total number of bytes written, we would have a very
 * rare bug that would occur when we tried to write large buffers to files.
 */
void ClientConnection::processWrite() {
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	//Open the file to the correct location.
	int fd;
	agerr_t error = 0;
	if ((fd = open(file.c_str(), O_WRONLY)) < 0)
	{
		error = -errno;
	}

	agfs_write_error(socket_, error);
	if (error < 0) {
		return;
	}

	agsize_t size = 0;
	agfs_read_size(socket_, size);

	agsize_t offset = 0;
	agfs_read_size(socket_, offset);

	lseek(fd, offset, SEEK_SET);

	//Read data into buffer and write data into the file at the same time.
	std::vector<unsigned char> data{};
	data.resize(size);
	agsize_t total_read = 0, total_written = 0;
	error = 0;
	while (total_read != size &&
			(error = read(socket_, &data[0] + total_read, size - total_read)) > 0) {
		total_read += error;

		//We should be okay to use error here, since we are guaranteed that
		//it is positive.
		if ((error = write(fd, &data[0] + total_read - error, error)) > 0) {
			total_written += error;
		}
		else {
			agfs_write_error(socket_, -errno);
			return;
		}
	}
	close(fd);

	agfs_write_error(socket_, error);
	if (error >= 0) {
		agfs_write_size(socket_, total_written);
	}
}

/*
 * Incoming stack looks like:
 *
 *      STRING MASK
 *
 * Outgoing stack looks like:
 *
 *      ERROR
 */
void ClientConnection::processOpen() {
	//Read in the path
	std::string path;
	agfs_read_string(socket_, path);

	//Cosntruct the local filepath
	boost::filesystem::path fusePath{path};
	boost::filesystem::path file{mountPoint_};
	file /= fusePath;

	//Read in the mask
	agmask_t mask = 0;
	agfs_read_mask(socket_, mask);

	//Open the file and write the error
	agerr_t error = 0;
	int fd = -1;
	if ((fd = open(file.c_str(), mask)) < 0) {
		error = -errno;
	}

	//We might want to consider sending the file descriptor to the
	//client in a later iteration.
	close(fd);

	agfs_write_error(socket_, error);
}

void ClientConnection::processRelease()
{

}
<|endoftext|>


<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_OPENAL

#include <sstream>
#if OUZEL_PLATFORM_IOS || OUZEL_PLATFORM_TVOS
#include <objc/message.h>
extern "C" id const AVAudioSessionCategoryAmbient;
#endif

#include "AudioDeviceAL.hpp"
#include "core/Engine.hpp"
#include "utils/Errors.hpp"
#include "utils/Log.hpp"
#include "utils/Utils.hpp"

#ifndef AL_FORMAT_MONO_FLOAT32
#  define AL_FORMAT_MONO_FLOAT32                      0x10010
#endif

#ifndef AL_FORMAT_STEREO_FLOAT32
#  define AL_FORMAT_STEREO_FLOAT32                    0x10011
#endif

namespace ouzel
{
    namespace audio
    {
        AudioDeviceAL::AudioDeviceAL():
            AudioDevice(Audio::Driver::OPENAL)
        {
#if OUZEL_PLATFORM_IOS || OUZEL_PLATFORM_TVOS
            id audioSession = reinterpret_cast<id (*)(Class, SEL)>(&objc_msgSend)(objc_getClass("AVAudioSession"), sel_getUid("sharedInstance"));
            reinterpret_cast<BOOL (*)(id, SEL, id, id)>(&objc_msgSend)(audioSession, sel_getUid("setCategory:error:"), AVAudioSessionCategoryAmbient, nil);
#endif

            std::fill(std::begin(bufferIds), std::end(bufferIds), 0);

            const ALCchar* deviceName = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);

            engine->log(Log::Level::INFO) << "Using " << reinterpret_cast<const char*>(deviceName) << " for audio";

            device = alcOpenDevice(deviceName);

            if (!device)
                throw SystemError("Failed to create OpenAL device");

            ALCenum alcError;

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to create OpenAL device, error: " + std::to_string(alcError));

            context = alcCreateContext(device, nullptr);

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to create OpenAL context, error: " + std::to_string(alcError));

            if (!context)
                throw SystemError("Failed to create OpenAL context");

            alcMakeContextCurrent(context);

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to make OpenAL context current, error: " + std::to_string(alcError));

            const ALchar* audioRenderer = alGetString(AL_RENDERER);

            ALenum error;

            if ((error = alGetError()) != AL_NO_ERROR || !audioRenderer)
                engine->log(Log::Level::WARN) << "Failed to get OpenAL renderer, error: " + std::to_string(error);
            else
                engine->log(Log::Level::INFO) << "Using " << reinterpret_cast<const char*>(audioRenderer) << " audio renderer";

            std::vector<std::string> extensions;
            const ALchar* extensionPtr = alGetString(AL_EXTENSIONS);

            if ((error = alGetError()) != AL_NO_ERROR || !extensionPtr)
                engine->log(Log::Level::WARN) << "Failed to get OpenGL extensions";
            else
            {
                std::istringstream extensionStringStream(reinterpret_cast<const char*>(extensionPtr));

                for (std::string extension; extensionStringStream >> extension;)
                    extensions.push_back(extension);
            }

            engine->log(Log::Level::ALL) << "Supported OpenAL extensions: " << extensions;

            bool floatSupported = false;
            for (const std::string& extension : extensions)
            {
                if (extension == "AL_EXT_float32")
                    floatSupported = true;
            }

#if !OUZEL_PLATFORM_EMSCRIPTEN
            format40 = alGetEnumValue("AL_FORMAT_QUAD16");
            format51 = alGetEnumValue("AL_FORMAT_51CHN16");
            format61 = alGetEnumValue("AL_FORMAT_61CHN16");
            format71 = alGetEnumValue("AL_FORMAT_71CHN16");

            if ((error = alGetError()) != AL_NO_ERROR)
                engine->log(Log::Level::WARN) << "Failed to get OpenAL enum values";
#endif

            alGenSources(1, &sourceId);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to create OpenAL source, error: " + std::to_string(error));

            alGenBuffers(2, bufferIds);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to create OpenAL buffers, error: " + std::to_string(error));

            switch (channels)
            {
                case 1:
                {
                    if (floatSupported)
                    {
                        format = AL_FORMAT_MONO_FLOAT32;
                        sampleFormat = Audio::SampleFormat::FLOAT32;
                        sampleSize = sizeof(float);
                    }
                    else
                    {
                        format = AL_FORMAT_MONO16;
                        sampleFormat = Audio::SampleFormat::SINT16;
                        sampleSize = sizeof(uint16_t);
                    }
                    break;
                }
                case 2:
                {
                    if (floatSupported)
                    {
                        format = AL_FORMAT_STEREO_FLOAT32;
                        sampleFormat = Audio::SampleFormat::FLOAT32;
                        sampleSize = sizeof(float);
                    }
                    else
                    {
                        format = AL_FORMAT_STEREO16;
                        sampleFormat = Audio::SampleFormat::SINT16;
                        sampleSize = sizeof(int16_t);
                    }
                    break;
                }
                case 4:
                {
                    format = format40;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                case 6:
                {
                    format = format51;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                case 7:
                {
                    format = format61;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                case 8:
                {
                    format = format71;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                default:
                    throw SystemError("Invalid channel count");
            }

            getData(bufferSize / (channels * sampleSize), data);

            alBufferData(bufferIds[0], format,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            getData(bufferSize / (channels * sampleSize), data);

            alBufferData(bufferIds[1], format,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            nextBuffer = 0;

            alSourceQueueBuffers(sourceId, 2, bufferIds);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to queue OpenAL buffers, error: " + std::to_string(error));

            alSourcePlay(sourceId);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to play OpenAL source, error: " + std::to_string(error));

#if OUZEL_MULTITHREADED
            running = true;
            audioThread = std::thread(&AudioDeviceAL::run, this);
#endif
        }

        AudioDeviceAL::~AudioDeviceAL()
        {
#if OUZEL_MULTITHREADED
            running = false;
            if (audioThread.joinable()) audioThread.join();
#endif

            if (sourceId)
            {
                alSourceStop(sourceId);
                alSourcei(sourceId, AL_BUFFER, 0);
                alDeleteSources(1, &sourceId);
                alGetError();
            }

            for (ALuint bufferId : bufferIds)
            {
                if (bufferId)
                {
                    alDeleteBuffers(1, &bufferId);
                    alGetError();
                }
            }

            if (context)
            {
                alcMakeContextCurrent(nullptr);
                alcDestroyContext(context);
            }

            if (device)
                alcCloseDevice(device);
        }

        void AudioDeviceAL::process()
        {
            AudioDevice::process();

            alcMakeContextCurrent(context);

            ALCenum alcError;

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to make OpenAL context current, error: " + std::to_string(alcError));

            ALint buffersProcessed;
            alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &buffersProcessed);

            ALenum error;

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to get processed buffer count, error: " + std::to_string(error));

            // requeue all processed buffers
            for (; buffersProcessed > 0; --buffersProcessed)
            {
                alSourceUnqueueBuffers(sourceId, 1, &bufferIds[nextBuffer]);

                if ((error = alGetError()) != AL_NO_ERROR)
                    throw SystemError("Failed to unqueue OpenAL buffer, error: " + std::to_string(error));

                getData(bufferSize / (channels * sampleSize), data);

                alBufferData(bufferIds[nextBuffer], format,
                             data.data(),
                             static_cast<ALsizei>(data.size()),
                             static_cast<ALsizei>(sampleRate));

                alSourceQueueBuffers(sourceId, 1, &bufferIds[nextBuffer]);

                if ((error = alGetError()) != AL_NO_ERROR)
                    throw SystemError("Failed to queue OpenAL buffer, error: " + std::to_string(error));

                ALint state;
                alGetSourcei(sourceId, AL_SOURCE_STATE, &state);
                if (state != AL_PLAYING)
                {
                    alSourcePlay(sourceId);

                    if ((error = alGetError()) != AL_NO_ERROR)
                        throw SystemError("Failed to play OpenAL source, error: " + std::to_string(error));
                }

                // swap the buffer
                nextBuffer = (nextBuffer + 1) % 2;
            }
        }

        void AudioDeviceAL::run()
        {
            setCurrentThreadName("Audio");

#if OUZEL_MULTITHREADED
            while (running)
            {
                try
                {
                    process();
                }
                catch (const std::exception& e)
                {
                    ouzel::engine->log(ouzel::Log::Level::ERR) << e.what();
                }
                catch (...)
                {
                    ouzel::engine->log(ouzel::Log::Level::ERR) << "Unknown error occurred";
                }
            }
#endif
        }
    } // namespace audio
} // namespace ouzel

#endif
<commit_msg>Rename floatSupported to float32Supported<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_OPENAL

#include <sstream>
#if OUZEL_PLATFORM_IOS || OUZEL_PLATFORM_TVOS
#include <objc/message.h>
extern "C" id const AVAudioSessionCategoryAmbient;
#endif

#include "AudioDeviceAL.hpp"
#include "core/Engine.hpp"
#include "utils/Errors.hpp"
#include "utils/Log.hpp"
#include "utils/Utils.hpp"

#ifndef AL_FORMAT_MONO_FLOAT32
#  define AL_FORMAT_MONO_FLOAT32                      0x10010
#endif

#ifndef AL_FORMAT_STEREO_FLOAT32
#  define AL_FORMAT_STEREO_FLOAT32                    0x10011
#endif

namespace ouzel
{
    namespace audio
    {
        AudioDeviceAL::AudioDeviceAL():
            AudioDevice(Audio::Driver::OPENAL)
        {
#if OUZEL_PLATFORM_IOS || OUZEL_PLATFORM_TVOS
            id audioSession = reinterpret_cast<id (*)(Class, SEL)>(&objc_msgSend)(objc_getClass("AVAudioSession"), sel_getUid("sharedInstance"));
            reinterpret_cast<BOOL (*)(id, SEL, id, id)>(&objc_msgSend)(audioSession, sel_getUid("setCategory:error:"), AVAudioSessionCategoryAmbient, nil);
#endif

            std::fill(std::begin(bufferIds), std::end(bufferIds), 0);

            const ALCchar* deviceName = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);

            engine->log(Log::Level::INFO) << "Using " << reinterpret_cast<const char*>(deviceName) << " for audio";

            device = alcOpenDevice(deviceName);

            if (!device)
                throw SystemError("Failed to create OpenAL device");

            ALCenum alcError;

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to create OpenAL device, error: " + std::to_string(alcError));

            context = alcCreateContext(device, nullptr);

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to create OpenAL context, error: " + std::to_string(alcError));

            if (!context)
                throw SystemError("Failed to create OpenAL context");

            alcMakeContextCurrent(context);

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to make OpenAL context current, error: " + std::to_string(alcError));

            const ALchar* audioRenderer = alGetString(AL_RENDERER);

            ALenum error;

            if ((error = alGetError()) != AL_NO_ERROR || !audioRenderer)
                engine->log(Log::Level::WARN) << "Failed to get OpenAL renderer, error: " + std::to_string(error);
            else
                engine->log(Log::Level::INFO) << "Using " << reinterpret_cast<const char*>(audioRenderer) << " audio renderer";

            std::vector<std::string> extensions;
            const ALchar* extensionPtr = alGetString(AL_EXTENSIONS);

            if ((error = alGetError()) != AL_NO_ERROR || !extensionPtr)
                engine->log(Log::Level::WARN) << "Failed to get OpenGL extensions";
            else
            {
                std::istringstream extensionStringStream(reinterpret_cast<const char*>(extensionPtr));

                for (std::string extension; extensionStringStream >> extension;)
                    extensions.push_back(extension);
            }

            engine->log(Log::Level::ALL) << "Supported OpenAL extensions: " << extensions;

            bool float32Supported = false;
            for (const std::string& extension : extensions)
            {
                if (extension == "AL_EXT_float32")
                    float32Supported = true;
            }

#if !OUZEL_PLATFORM_EMSCRIPTEN
            format40 = alGetEnumValue("AL_FORMAT_QUAD16");
            format51 = alGetEnumValue("AL_FORMAT_51CHN16");
            format61 = alGetEnumValue("AL_FORMAT_61CHN16");
            format71 = alGetEnumValue("AL_FORMAT_71CHN16");

            if ((error = alGetError()) != AL_NO_ERROR)
                engine->log(Log::Level::WARN) << "Failed to get OpenAL enum values";
#endif

            alGenSources(1, &sourceId);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to create OpenAL source, error: " + std::to_string(error));

            alGenBuffers(2, bufferIds);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to create OpenAL buffers, error: " + std::to_string(error));

            switch (channels)
            {
                case 1:
                {
                    if (float32Supported)
                    {
                        format = AL_FORMAT_MONO_FLOAT32;
                        sampleFormat = Audio::SampleFormat::FLOAT32;
                        sampleSize = sizeof(float);
                    }
                    else
                    {
                        format = AL_FORMAT_MONO16;
                        sampleFormat = Audio::SampleFormat::SINT16;
                        sampleSize = sizeof(uint16_t);
                    }
                    break;
                }
                case 2:
                {
                    if (float32Supported)
                    {
                        format = AL_FORMAT_STEREO_FLOAT32;
                        sampleFormat = Audio::SampleFormat::FLOAT32;
                        sampleSize = sizeof(float);
                    }
                    else
                    {
                        format = AL_FORMAT_STEREO16;
                        sampleFormat = Audio::SampleFormat::SINT16;
                        sampleSize = sizeof(int16_t);
                    }
                    break;
                }
                case 4:
                {
                    format = format40;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                case 6:
                {
                    format = format51;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                case 7:
                {
                    format = format61;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                case 8:
                {
                    format = format71;
                    sampleFormat = Audio::SampleFormat::SINT16;
                    sampleSize = sizeof(int16_t);
                    break;
                }
                default:
                    throw SystemError("Invalid channel count");
            }

            getData(bufferSize / (channels * sampleSize), data);

            alBufferData(bufferIds[0], format,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            getData(bufferSize / (channels * sampleSize), data);

            alBufferData(bufferIds[1], format,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            nextBuffer = 0;

            alSourceQueueBuffers(sourceId, 2, bufferIds);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to queue OpenAL buffers, error: " + std::to_string(error));

            alSourcePlay(sourceId);

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to play OpenAL source, error: " + std::to_string(error));

#if OUZEL_MULTITHREADED
            running = true;
            audioThread = std::thread(&AudioDeviceAL::run, this);
#endif
        }

        AudioDeviceAL::~AudioDeviceAL()
        {
#if OUZEL_MULTITHREADED
            running = false;
            if (audioThread.joinable()) audioThread.join();
#endif

            if (sourceId)
            {
                alSourceStop(sourceId);
                alSourcei(sourceId, AL_BUFFER, 0);
                alDeleteSources(1, &sourceId);
                alGetError();
            }

            for (ALuint bufferId : bufferIds)
            {
                if (bufferId)
                {
                    alDeleteBuffers(1, &bufferId);
                    alGetError();
                }
            }

            if (context)
            {
                alcMakeContextCurrent(nullptr);
                alcDestroyContext(context);
            }

            if (device)
                alcCloseDevice(device);
        }

        void AudioDeviceAL::process()
        {
            AudioDevice::process();

            alcMakeContextCurrent(context);

            ALCenum alcError;

            if ((alcError = alcGetError(device)) != ALC_NO_ERROR)
                throw SystemError("Failed to make OpenAL context current, error: " + std::to_string(alcError));

            ALint buffersProcessed;
            alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &buffersProcessed);

            ALenum error;

            if ((error = alGetError()) != AL_NO_ERROR)
                throw SystemError("Failed to get processed buffer count, error: " + std::to_string(error));

            // requeue all processed buffers
            for (; buffersProcessed > 0; --buffersProcessed)
            {
                alSourceUnqueueBuffers(sourceId, 1, &bufferIds[nextBuffer]);

                if ((error = alGetError()) != AL_NO_ERROR)
                    throw SystemError("Failed to unqueue OpenAL buffer, error: " + std::to_string(error));

                getData(bufferSize / (channels * sampleSize), data);

                alBufferData(bufferIds[nextBuffer], format,
                             data.data(),
                             static_cast<ALsizei>(data.size()),
                             static_cast<ALsizei>(sampleRate));

                alSourceQueueBuffers(sourceId, 1, &bufferIds[nextBuffer]);

                if ((error = alGetError()) != AL_NO_ERROR)
                    throw SystemError("Failed to queue OpenAL buffer, error: " + std::to_string(error));

                ALint state;
                alGetSourcei(sourceId, AL_SOURCE_STATE, &state);
                if (state != AL_PLAYING)
                {
                    alSourcePlay(sourceId);

                    if ((error = alGetError()) != AL_NO_ERROR)
                        throw SystemError("Failed to play OpenAL source, error: " + std::to_string(error));
                }

                // swap the buffer
                nextBuffer = (nextBuffer + 1) % 2;
            }
        }

        void AudioDeviceAL::run()
        {
            setCurrentThreadName("Audio");

#if OUZEL_MULTITHREADED
            while (running)
            {
                try
                {
                    process();
                }
                catch (const std::exception& e)
                {
                    ouzel::engine->log(ouzel::Log::Level::ERR) << e.what();
                }
                catch (...)
                {
                    ouzel::engine->log(ouzel::Log::Level::ERR) << "Unknown error occurred";
                }
            }
#endif
        }
    } // namespace audio
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>// Copyright 2010-2012 RethinkDB, all rights reserved.
#include "arch/address.hpp"

#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "errors.hpp"
#include <boost/bind.hpp>

#include "arch/arch.hpp"

/* Get our hostname as an std::string. */
std::string str_gethostname() {
    char name[HOST_NAME_MAX+1];
    int res = gethostname(name, sizeof(name));
    guarantee(res == 0, "gethostname() failed: %s\n", strerror(errno));
    return std::string(name);
}

void do_getaddrinfo(const char *node,
                    const char *service,
                    const struct addrinfo *hints,
                    struct addrinfo **res,
                    int *retval,
                    int *errno_res) {
    *errno_res = 0;
    *retval = getaddrinfo(node, service, hints, res);
    if (*retval < 0) {
        *errno_res = errno;
    }
}

/* Format an `in_addr` in dotted deciaml notation. */
std::string addr_as_dotted_decimal(struct in_addr addr) {
    char buffer[INET_ADDRSTRLEN + 1] = { 0 };
    const char *result = inet_ntop(AF_INET, reinterpret_cast<const void*>(&addr),
        buffer, INET_ADDRSTRLEN);
    guarantee(result == buffer, "Could not format IP address");
    return std::string(buffer);
}

std::set<ip_address_t> ip_address_t::from_hostname(const std::string &host) {
    std::set<ip_address_t> ips;
    struct addrinfo hint;
    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;

    int res;
    int errno_res;
    struct addrinfo *addrs;
    boost::function<void ()> fn =
        boost::bind(do_getaddrinfo, host.c_str(), static_cast<const char*>(NULL),
                    &hint, &addrs, &res, &errno_res);
    thread_pool_t::run_in_blocker_pool(fn);

    if (res != 0) {
        throw host_lookup_exc_t(host, errno_res);
    }

    guarantee(addrs);
    for (struct addrinfo *ai = addrs; ai; ai = ai->ai_next) {
        ips.insert(ip_address_t(ai));
    }

    freeaddrinfo(addrs);
    return ips;
}

std::set<ip_address_t> ip_address_t::us() {
    std::set<ip_address_t> ips;

    try {
        ips = from_hostname(str_gethostname());
    } catch (const host_lookup_exc_t &ex) {
        // Continue on, this probably means there's no DNS entry for this host
    }

    struct ifaddrs *addrs;
    int res = getifaddrs(&addrs);
    guarantee_err(res == 0, "getifaddrs() failed");

    for (struct ifaddrs *current_addr = addrs; current_addr != NULL; current_addr = current_addr->ifa_next) {
        struct sockaddr *addr_data = current_addr->ifa_addr;
        if (addr_data == NULL) {
            continue;
        } else if (addr_data->sa_family == AF_INET) {
            ips.insert(ip_address_t(addr_data));
        }
    }

    freeifaddrs(addrs);
    return ips;
}

std::string ip_address_t::as_dotted_decimal() const {
    return addr_as_dotted_decimal(get_addr());
}

void debug_print(append_only_printf_buffer_t *buf, const ip_address_t &addr) {
    buf->appendf("%s", addr.as_dotted_decimal().c_str());
}
<commit_msg>Made str_gethostname use sysconf(_SC_HOST_NAME_MAX) on OS X.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#include "arch/address.hpp"

#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "errors.hpp"
#include <boost/bind.hpp>

#include "arch/arch.hpp"

/* Get our hostname as an std::string. */
std::string str_gethostname() {
    // TODO(OSX) reconsider how to detect OS X
    // TODO(OSX) see if sysconf works on linux.  On older Linuxes?
#if __APPLE__
    const int namelen = sysconf(_SC_HOST_NAME_MAX);
#else
    const int namelen = HOST_NAME_MAX;
#endif
    std::vector<char> bytes(namelen + 1);
    bytes[namelen] = '0';

    int res = gethostname(bytes.data(), namelen);
    guarantee_err(res == 0, "gethostname() failed");
    return std::string(bytes.data());
}

void do_getaddrinfo(const char *node,
                    const char *service,
                    const struct addrinfo *hints,
                    struct addrinfo **res,
                    int *retval,
                    int *errno_res) {
    *errno_res = 0;
    *retval = getaddrinfo(node, service, hints, res);
    if (*retval < 0) {
        *errno_res = errno;
    }
}

/* Format an `in_addr` in dotted deciaml notation. */
std::string addr_as_dotted_decimal(struct in_addr addr) {
    char buffer[INET_ADDRSTRLEN + 1] = { 0 };
    const char *result = inet_ntop(AF_INET, reinterpret_cast<const void*>(&addr),
        buffer, INET_ADDRSTRLEN);
    guarantee(result == buffer, "Could not format IP address");
    return std::string(buffer);
}

std::set<ip_address_t> ip_address_t::from_hostname(const std::string &host) {
    std::set<ip_address_t> ips;
    struct addrinfo hint;
    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;

    int res;
    int errno_res;
    struct addrinfo *addrs;
    boost::function<void ()> fn =
        boost::bind(do_getaddrinfo, host.c_str(), static_cast<const char*>(NULL),
                    &hint, &addrs, &res, &errno_res);
    thread_pool_t::run_in_blocker_pool(fn);

    if (res != 0) {
        throw host_lookup_exc_t(host, errno_res);
    }

    guarantee(addrs);
    for (struct addrinfo *ai = addrs; ai; ai = ai->ai_next) {
        ips.insert(ip_address_t(ai));
    }

    freeaddrinfo(addrs);
    return ips;
}

std::set<ip_address_t> ip_address_t::us() {
    std::set<ip_address_t> ips;

    try {
        ips = from_hostname(str_gethostname());
    } catch (const host_lookup_exc_t &ex) {
        // Continue on, this probably means there's no DNS entry for this host
    }

    struct ifaddrs *addrs;
    int res = getifaddrs(&addrs);
    guarantee_err(res == 0, "getifaddrs() failed");

    for (struct ifaddrs *current_addr = addrs; current_addr != NULL; current_addr = current_addr->ifa_next) {
        struct sockaddr *addr_data = current_addr->ifa_addr;
        if (addr_data == NULL) {
            continue;
        } else if (addr_data->sa_family == AF_INET) {
            ips.insert(ip_address_t(addr_data));
        }
    }

    freeifaddrs(addrs);
    return ips;
}

std::string ip_address_t::as_dotted_decimal() const {
    return addr_as_dotted_decimal(get_addr());
}

void debug_print(append_only_printf_buffer_t *buf, const ip_address_t &addr) {
    buf->appendf("%s", addr.as_dotted_decimal().c_str());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Legend.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-09-18 15:02:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef CHART_LEGEND_HXX
#define CHART_LEGEND_HXX

#include "ServiceMacros.hxx"
#include "ModifyListenerHelper.hxx"

#ifndef CHART_OPROPERTYSET_HXX
#include "OPropertySet.hxx"
#endif
#ifndef CHART_MUTEXCONTAINER_HXX
#include "MutexContainer.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE5_HXX_
#include <cppuhelper/implbase5.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#ifndef _COM_SUN_STAR_CHART2_XLEGEND_HPP_
#include <com/sun/star/chart2/XLegend.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLONEABLE_HPP_
#include <com/sun/star/util/XCloneable.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYBROADCASTER_HPP_
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYLISTENER_HPP_
#include <com/sun/star/util/XModifyListener.hpp>
#endif

namespace chart
{

namespace impl
{
typedef ::cppu::WeakImplHelper5<
        ::com::sun::star::chart2::XLegend,
        ::com::sun::star::lang::XServiceInfo,
        ::com::sun::star::util::XCloneable,
        ::com::sun::star::util::XModifyBroadcaster,
        ::com::sun::star::util::XModifyListener >
    Legend_Base;
}

class Legend :
    public MutexContainer,
    public impl::Legend_Base,
    public ::property::OPropertySet
{
public:
    Legend( ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > const & xContext );
    virtual ~Legend();

    /// establish methods for factory instatiation
    APPHELPER_SERVICE_FACTORY_HELPER( Legend )

    /// XServiceInfo declarations
    APPHELPER_XSERVICEINFO_DECL()

    /// merge XInterface implementations
     DECLARE_XINTERFACE()
    /// merge XTypeProvider implementations
     DECLARE_XTYPEPROVIDER()

protected:
    explicit Legend( const Legend & rOther );

    // ____ OPropertySet ____
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException);

    // ____ OPropertySet ____
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

    // ____ XPropertySet ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException);

//  virtual sal_Bool SAL_CALL convertFastPropertyValue
//         ( ::com::sun::star::uno::Any & rConvertedValue,
//           ::com::sun::star::uno::Any & rOldValue,
//           sal_Int32 nHandle,
//           const ::com::sun::star::uno::Any& rValue )
//      throw (::com::sun::star::lang::IllegalArgumentException);

    // ____ XLegend ____
    virtual void SAL_CALL registerEntry( const ::com::sun::star::uno::Reference<
                                         ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL revokeEntry( const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::container::NoSuchElementException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XLegendEntry > > SAL_CALL getEntries()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XCloneable ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XModifyBroadcaster ____
    virtual void SAL_CALL addModifyListener(
        const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeModifyListener(
        const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XModifyListener ____
    virtual void SAL_CALL modified(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XEventListener (base of XModifyListener) ____
    virtual void SAL_CALL disposing(
        const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ OPropertySet ____
    virtual void firePropertyChangeEvent();
    using OPropertySet::disposing;

    void fireModifyEvent();

private:
    typedef ::std::vector<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XLegendEntry > > tLegendEntries;

    tLegendEntries                                    m_aLegendEntries;
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xModifyEventForwarder;
};

} //  namespace chart

// CHART_LEGEND_HXX
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.7.70); FILE MERGED 2008/04/01 15:04:18 thb 1.7.70.3: #i85898# Stripping all external header guards 2008/04/01 10:50:33 thb 1.7.70.2: #i85898# Stripping all external header guards 2008/03/28 16:44:08 rt 1.7.70.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: Legend.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CHART_LEGEND_HXX
#define CHART_LEGEND_HXX

#include "ServiceMacros.hxx"
#include "ModifyListenerHelper.hxx"
#include "OPropertySet.hxx"
#include "MutexContainer.hxx"
#include <cppuhelper/implbase5.hxx>
#include <comphelper/uno3.hxx>
#include <com/sun/star/chart2/XLegend.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <com/sun/star/util/XModifyListener.hpp>

namespace chart
{

namespace impl
{
typedef ::cppu::WeakImplHelper5<
        ::com::sun::star::chart2::XLegend,
        ::com::sun::star::lang::XServiceInfo,
        ::com::sun::star::util::XCloneable,
        ::com::sun::star::util::XModifyBroadcaster,
        ::com::sun::star::util::XModifyListener >
    Legend_Base;
}

class Legend :
    public MutexContainer,
    public impl::Legend_Base,
    public ::property::OPropertySet
{
public:
    Legend( ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > const & xContext );
    virtual ~Legend();

    /// establish methods for factory instatiation
    APPHELPER_SERVICE_FACTORY_HELPER( Legend )

    /// XServiceInfo declarations
    APPHELPER_XSERVICEINFO_DECL()

    /// merge XInterface implementations
     DECLARE_XINTERFACE()
    /// merge XTypeProvider implementations
     DECLARE_XTYPEPROVIDER()

protected:
    explicit Legend( const Legend & rOther );

    // ____ OPropertySet ____
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException);

    // ____ OPropertySet ____
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

    // ____ XPropertySet ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException);

//  virtual sal_Bool SAL_CALL convertFastPropertyValue
//         ( ::com::sun::star::uno::Any & rConvertedValue,
//           ::com::sun::star::uno::Any & rOldValue,
//           sal_Int32 nHandle,
//           const ::com::sun::star::uno::Any& rValue )
//      throw (::com::sun::star::lang::IllegalArgumentException);

    // ____ XLegend ____
    virtual void SAL_CALL registerEntry( const ::com::sun::star::uno::Reference<
                                         ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL revokeEntry( const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::container::NoSuchElementException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XLegendEntry > > SAL_CALL getEntries()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XCloneable ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XModifyBroadcaster ____
    virtual void SAL_CALL addModifyListener(
        const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeModifyListener(
        const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XModifyListener ____
    virtual void SAL_CALL modified(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XEventListener (base of XModifyListener) ____
    virtual void SAL_CALL disposing(
        const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ OPropertySet ____
    virtual void firePropertyChangeEvent();
    using OPropertySet::disposing;

    void fireModifyEvent();

private:
    typedef ::std::vector<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XLegendEntry > > tLegendEntries;

    tLegendEntries                                    m_aLegendEntries;
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xModifyEventForwarder;
};

} //  namespace chart

// CHART_LEGEND_HXX
#endif
<|endoftext|>


<commit_before>
//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

/*!
 @file OptimizeProblem.cpp

 HPCG routine
 */

#include "OptimizeProblem.hpp"
/*!
  Optimizes the data structures used for CG iteration to increase the
  performance of the benchmark version of the preconditioned CG algorithm.

  @param[inout] A      The known system matrix, also contains the MG hierarchy in attributes Ac and mgData.
  @param[inout] data   The data structure with all necessary CG vectors preallocated
  @param[inout] b      The known right hand side vector
  @param[inout] x      The solution vector to be computed in future CG iteration
  @param[inout] xexact The exact solution vector

  @return returns 0 upon success and non-zero otherwise

  @see GenerateGeometry
  @see GenerateProblem
*/
int OptimizeProblem(SparseMatrix & A, CGData & data, Vector & b, Vector & x, Vector & xexact) {

  // This function can be used to completely transform any part of the data structures.
  // Right now it does nothing, so compiling with a check for unused variables results in complaints

#if defined(HPCG_USE_MULTICOLORING)
  const local_int_t nrow = A.localNumberOfRows;
  std::vector<local_int_t> colors(nrow, nrow); // value `nrow' means `uninitialized'; initialized colors go from 0 to nrow-1
  int totalColors = 1;
  colors[0] = 0; // first point gets color 0

  // Finds colors in a greedy (a likely non-optimal) fashion.

  for (local_int_t i=1; i < nrow; ++i) {
    if (colors[i] == nrow) { // if color not assigned
      std::vector<int> assigned(totalColors, 0);
      int currentlyAssigned = 0;
      const local_int_t * const currentColIndices = A.mtxIndL[i];
      const int currentNumberOfNonzeros = A.nonzerosInRow[i];

      for (int j=0; j< currentNumberOfNonzeros; j++) { // scan neighbors
        local_int_t curCol = currentColIndices[j];
        if (curCol < i) { // if this point has an assigned color (points beyond `i' are unassigned)
          if (assigned[colors[curCol]] == 0)
            currentlyAssigned += 1;
          assigned[colors[curCol]] = 1; // this color has been used before by `curCol' point
        } // else // could take advantage of indices being sorted
      }

      if (currentlyAssigned < totalColors) { // if there is at least one color left to use
        for (int j=0; j < totalColors; ++j)  // try all current colors
          if (assigned[j] == 0) { // if no neighbor with this color
            colors[i] = j;
            break;
          }
      } else {
        if (colors[i] == nrow) {
          colors[i] = totalColors;
          totalColors += 1;
        }
      }
    }
  }
#endif

  return 0;
}
<commit_msg>Code to generate multicolor permutation.<commit_after>
//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

/*!
 @file OptimizeProblem.cpp

 HPCG routine
 */

#include "OptimizeProblem.hpp"
/*!
  Optimizes the data structures used for CG iteration to increase the
  performance of the benchmark version of the preconditioned CG algorithm.

  @param[inout] A      The known system matrix, also contains the MG hierarchy in attributes Ac and mgData.
  @param[inout] data   The data structure with all necessary CG vectors preallocated
  @param[inout] b      The known right hand side vector
  @param[inout] x      The solution vector to be computed in future CG iteration
  @param[inout] xexact The exact solution vector

  @return returns 0 upon success and non-zero otherwise

  @see GenerateGeometry
  @see GenerateProblem
*/
int OptimizeProblem(SparseMatrix & A, CGData & data, Vector & b, Vector & x, Vector & xexact) {

  // This function can be used to completely transform any part of the data structures.
  // Right now it does nothing, so compiling with a check for unused variables results in complaints

#if defined(HPCG_USE_MULTICOLORING)
  const local_int_t nrow = A.localNumberOfRows;
  std::vector<local_int_t> colors(nrow, nrow); // value `nrow' means `uninitialized'; initialized colors go from 0 to nrow-1
  int totalColors = 1;
  colors[0] = 0; // first point gets color 0

  // Finds colors in a greedy (a likely non-optimal) fashion.

  for (local_int_t i=1; i < nrow; ++i) {
    if (colors[i] == nrow) { // if color not assigned
      std::vector<int> assigned(totalColors, 0);
      int currentlyAssigned = 0;
      const local_int_t * const currentColIndices = A.mtxIndL[i];
      const int currentNumberOfNonzeros = A.nonzerosInRow[i];

      for (int j=0; j< currentNumberOfNonzeros; j++) { // scan neighbors
        local_int_t curCol = currentColIndices[j];
        if (curCol < i) { // if this point has an assigned color (points beyond `i' are unassigned)
          if (assigned[colors[curCol]] == 0)
            currentlyAssigned += 1;
          assigned[colors[curCol]] = 1; // this color has been used before by `curCol' point
        } // else // could take advantage of indices being sorted
      }

      if (currentlyAssigned < totalColors) { // if there is at least one color left to use
        for (int j=0; j < totalColors; ++j)  // try all current colors
          if (assigned[j] == 0) { // if no neighbor with this color
            colors[i] = j;
            break;
          }
      } else {
        if (colors[i] == nrow) {
          colors[i] = totalColors;
          totalColors += 1;
        }
      }
    }
  }

  std::vector<local_int_t> counters(totalColors);
  for (local_int_t i=0; i<nrow; ++i)
    counters[colors[i]]++;

  local_int_t old, old0;
  for (int i=1; i < totalColors; ++i) {
    old0 = counters[i];
    counters[i] = counters[i-1] + old;
    old = old0;
  }
  counters[0] = 0;

  // translate `colors' into a permutation
  for (local_int_t i=0; i<nrow; ++i) // for each color `c'
    colors[i] = counters[colors[i]]++;
#endif

  return 0;
}
<|endoftext|>