<commit_before>/***************************************************************************
**
** Copyright (C) 2012 Jolla Ltd.
** Contact: Robin Burchell <robin.burchell@jollamobile.com>
**
** This file is part of lipstick.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <dbus/dbus.h>
#include <policy/resource-set.h>
#include <linux/input.h>
#include <QGuiApplication>
#include "homewindow.h"
#include <QQmlContext>
#include <QScreen>
#include <QKeyEvent>
#include <MGConfItem>
#include "utilities/closeeventeater.h"
#include "pulseaudiocontrol.h"
#include "volumecontrol.h"
#include "lipstickqmlpath.h"

VolumeControl::VolumeControl(QObject *parent) :
    QObject(parent),
    window(0),
    pulseAudioControl(new PulseAudioControl(this)),
    hwKeyResource(new ResourcePolicy::ResourceSet("event")),
    hwKeysAcquired(false),
    volume_(0),
    maximumVolume_(0),
    audioWarning(new MGConfItem("/desktop/nemo/audiowarning", this)),
    safeVolume_(0),
    callActive_(false)
{
    hwKeyResource->setAlwaysReply();
    hwKeyResource->addResourceObject(new ResourcePolicy::ScaleButtonResource);
    connect(hwKeyResource, SIGNAL(resourcesGranted(QList<ResourcePolicy::ResourceType>)), this, SLOT(hwKeyResourceAcquired()));
    connect(hwKeyResource, SIGNAL(lostResources()), this, SLOT(hwKeyResourceLost()));

    // Set up key repeat: initial delay and per-repeat delay
    keyRepeatDelayTimer.setSingleShot(true);
    keyRepeatDelayTimer.setInterval(600);
    keyRepeatTimer.setInterval(75);
    connect(&keyRepeatDelayTimer, SIGNAL(timeout()), &keyRepeatTimer, SLOT(start()));
    connect(&keyRepeatTimer, SIGNAL(timeout()), this, SLOT(changeVolume()));

    connect(pulseAudioControl, SIGNAL(volumeChanged(int,int)), this, SLOT(setVolume(int,int)));
    connect(pulseAudioControl, SIGNAL(highVolume(int)), SLOT(handleHighVolume(int)));
    connect(pulseAudioControl, SIGNAL(longListeningTime(int)), SLOT(handleLongListeningTime(int)));
    connect(pulseAudioControl, SIGNAL(callActiveChanged(bool)), SLOT(handleCallActive(bool)));
    pulseAudioControl->update();

    qApp->installEventFilter(this);

    acquireKeys();
}

VolumeControl::~VolumeControl()
{
    hwKeyResource->deleteResource(ResourcePolicy::ScaleButtonType);
    delete window;
}

int VolumeControl::volume() const
{
    return volume_;
}

int VolumeControl::maximumVolume() const
{
    return maximumVolume_;
}

int VolumeControl::safeVolume() const
{
    return safeVolume_ == 0 ? maximumVolume() : safeVolume_;
}

void VolumeControl::setWindowVisible(bool visible)
{
    if (visible) {
        if (window == 0) {
            window = new HomeWindow();
            window->setGeometry(QRect(QPoint(), QGuiApplication::primaryScreen()->size()));
            window->setCategory(QLatin1String("notification"));
            window->setWindowTitle("Volume");
            window->setContextProperty("initialSize", QGuiApplication::primaryScreen()->size());
            window->setContextProperty("volumeControl", this);
            window->setSource(QmlPath::to("volumecontrol/VolumeControl.qml"));
            window->installEventFilter(new CloseEventEater(this));
        }

        if (!window->isVisible()) {
            window->show();
            emit windowVisibleChanged();
        }
    } else if (window != 0 && window->isVisible()) {
        window->hide();
        emit windowVisibleChanged();
    }
}

bool VolumeControl::windowVisible() const
{
    return window != 0 && window->isVisible();
}

bool VolumeControl::warningAcknowledged() const
{
    return audioWarning->value(false).toBool();
}

void VolumeControl::setWarningAcknowledged(bool acknowledged)
{
    if (audioWarning->value(false).toBool() != acknowledged) {
        audioWarning->set(acknowledged);
    }
}

bool VolumeControl::callActive() const
{
    return callActive_;
}

void VolumeControl::setVolume(int volume, int maximumVolume)
{
    int clampedMaxVolume = maximumVolume < 0 ? 0 : maximumVolume;
    int clampedVolume = qBound(0, volume, maximumVolume);

    bool volumeUpdated = false;
    bool maxVolumeUpdated = false;

    if (maximumVolume_ != clampedMaxVolume) {
        maximumVolume_ = clampedMaxVolume;
        maxVolumeUpdated = true;
    }

    if (volume_ != clampedVolume) {
        volume_ = clampedVolume;
        volumeUpdated = true;
    }

    if (maxVolumeUpdated) {
        emit maximumVolumeChanged();
    }

    if (volumeUpdated) {
        emit volumeChanged();
    }
}

void VolumeControl::hwKeyResourceAcquired()
{
    hwKeysAcquired = true;
}

void VolumeControl::hwKeyResourceLost()
{
    hwKeysAcquired = false;
    stopKeyRepeat();
}

void VolumeControl::releaseKeys()
{
    hwKeyResource->release();
    stopKeyRepeat();
}

void VolumeControl::acquireKeys()
{
    hwKeyResource->acquire();
}

void VolumeControl::changeVolume()
{
    int newVolume = qBound(0, volume_ + volumeChange, warningAcknowledged() ? maximumVolume() : safeVolume());
    if (newVolume != volume_) {
        volume_ = newVolume;
        pulseAudioControl->setVolume(volume_);
        emit volumeChanged();
    }

    setWindowVisible(true);

    if (!warningAcknowledged() && safeVolume_ != 0 && volume_ >= safeVolume_) {
        emit showAudioWarning(false);
    }

    emit volumeKeyPressed();
}

void VolumeControl::stopKeyRepeat()
{
    keyRepeatDelayTimer.stop();
    keyRepeatTimer.stop();
}

void VolumeControl::handleHighVolume(int safeLevel)
{
    if (safeVolume_ != safeLevel) {
        safeVolume_ = safeLevel;
        emit safeVolumeChanged();
    }
}

void VolumeControl::handleLongListeningTime(int listeningTime)
{
    setWarningAcknowledged(false);
    setWindowVisible(true);

    int newVolume = qBound(0, volume_, listeningTime == 0 ? maximumVolume() : safeVolume());
    if (newVolume != volume_) {
        volume_ = newVolume;
        pulseAudioControl->setVolume(volume_);
        emit volumeChanged();
    }

    emit showAudioWarning(listeningTime == 0);
}

void VolumeControl::handleCallActive(bool callActive)
{
    if (callActive_ != callActive) {
        callActive_ = callActive;
        emit callActiveChanged();
    }
}

bool VolumeControl::eventFilter(QObject *, QEvent *event)
{
    if (hwKeysAcquired && (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_VolumeUp || keyEvent->key() == Qt::Key_VolumeDown) {
            if (event->type() == QEvent::KeyPress) {
                // Key down: set which way to change the volume on each repeat, start the repeat delay timer and change the volume once
                volumeChange = keyEvent->key() == Qt::Key_VolumeUp ? 1 : -1;
                if (!keyRepeatDelayTimer.isActive() && !keyRepeatTimer.isActive()) {
                    keyRepeatDelayTimer.start();
                    changeVolume();
                }
            } else {
                // Key up: stop any key repeating in progress and the repeat delay timer
                stopKeyRepeat();
            }
            return true;
        }
    }
    return false;
}
<commit_msg>[volumecontrol] Be more strict about volume warning dialogs.<commit_after>/***************************************************************************
**
** Copyright (C) 2012 Jolla Ltd.
** Contact: Robin Burchell <robin.burchell@jollamobile.com>
**
** This file is part of lipstick.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <dbus/dbus.h>
#include <policy/resource-set.h>
#include <linux/input.h>
#include <QGuiApplication>
#include "homewindow.h"
#include <QQmlContext>
#include <QScreen>
#include <QKeyEvent>
#include <MGConfItem>
#include "utilities/closeeventeater.h"
#include "pulseaudiocontrol.h"
#include "volumecontrol.h"
#include "lipstickqmlpath.h"

VolumeControl::VolumeControl(QObject *parent) :
    QObject(parent),
    window(0),
    pulseAudioControl(new PulseAudioControl(this)),
    hwKeyResource(new ResourcePolicy::ResourceSet("event")),
    hwKeysAcquired(false),
    volume_(0),
    maximumVolume_(0),
    audioWarning(new MGConfItem("/desktop/nemo/audiowarning", this)),
    safeVolume_(0),
    callActive_(false)
{
    hwKeyResource->setAlwaysReply();
    hwKeyResource->addResourceObject(new ResourcePolicy::ScaleButtonResource);
    connect(hwKeyResource, SIGNAL(resourcesGranted(QList<ResourcePolicy::ResourceType>)), this, SLOT(hwKeyResourceAcquired()));
    connect(hwKeyResource, SIGNAL(lostResources()), this, SLOT(hwKeyResourceLost()));

    // Set up key repeat: initial delay and per-repeat delay
    keyRepeatDelayTimer.setSingleShot(true);
    keyRepeatDelayTimer.setInterval(600);
    keyRepeatTimer.setInterval(75);
    connect(&keyRepeatDelayTimer, SIGNAL(timeout()), &keyRepeatTimer, SLOT(start()));
    connect(&keyRepeatTimer, SIGNAL(timeout()), this, SLOT(changeVolume()));

    setWarningAcknowledged(false);
    connect(pulseAudioControl, SIGNAL(volumeChanged(int,int)), this, SLOT(setVolume(int,int)));
    connect(pulseAudioControl, SIGNAL(highVolume(int)), SLOT(handleHighVolume(int)));
    connect(pulseAudioControl, SIGNAL(longListeningTime(int)), SLOT(handleLongListeningTime(int)));
    connect(pulseAudioControl, SIGNAL(callActiveChanged(bool)), SLOT(handleCallActive(bool)));
    pulseAudioControl->update();

    qApp->installEventFilter(this);

    acquireKeys();
}

VolumeControl::~VolumeControl()
{
    hwKeyResource->deleteResource(ResourcePolicy::ScaleButtonType);
    delete window;
}

int VolumeControl::volume() const
{
    return volume_;
}

int VolumeControl::maximumVolume() const
{
    return maximumVolume_;
}

int VolumeControl::safeVolume() const
{
    return safeVolume_ == 0 ? maximumVolume() : safeVolume_;
}

void VolumeControl::setWindowVisible(bool visible)
{
    if (visible) {
        if (window == 0) {
            window = new HomeWindow();
            window->setGeometry(QRect(QPoint(), QGuiApplication::primaryScreen()->size()));
            window->setCategory(QLatin1String("notification"));
            window->setWindowTitle("Volume");
            window->setContextProperty("initialSize", QGuiApplication::primaryScreen()->size());
            window->setContextProperty("volumeControl", this);
            window->setSource(QmlPath::to("volumecontrol/VolumeControl.qml"));
            window->installEventFilter(new CloseEventEater(this));
        }

        if (!window->isVisible()) {
            window->show();
            emit windowVisibleChanged();
        }
    } else if (window != 0 && window->isVisible()) {
        window->hide();
        emit windowVisibleChanged();
    }
}

bool VolumeControl::windowVisible() const
{
    return window != 0 && window->isVisible();
}

bool VolumeControl::warningAcknowledged() const
{
    return audioWarning->value(false).toBool();
}

void VolumeControl::setWarningAcknowledged(bool acknowledged)
{
    if (audioWarning->value(false).toBool() != acknowledged) {
        audioWarning->set(acknowledged);
    }
}

bool VolumeControl::callActive() const
{
    return callActive_;
}

void VolumeControl::setVolume(int volume, int maximumVolume)
{
    int clampedMaxVolume = maximumVolume < 0 ? 0 : maximumVolume;
    int clampedVolume = qBound(0, volume, maximumVolume);

    bool volumeUpdated = false;
    bool maxVolumeUpdated = false;

    if (maximumVolume_ != clampedMaxVolume) {
        maximumVolume_ = clampedMaxVolume;
        maxVolumeUpdated = true;
    }

    if (volume_ != clampedVolume) {
        volume_ = clampedVolume;
        volumeUpdated = true;
    }

    if (maxVolumeUpdated) {
        emit maximumVolumeChanged();
    }

    if (volumeUpdated) {
        emit volumeChanged();
    }
}

void VolumeControl::hwKeyResourceAcquired()
{
    hwKeysAcquired = true;
}

void VolumeControl::hwKeyResourceLost()
{
    hwKeysAcquired = false;
    stopKeyRepeat();
}

void VolumeControl::releaseKeys()
{
    hwKeyResource->release();
    stopKeyRepeat();
}

void VolumeControl::acquireKeys()
{
    hwKeyResource->acquire();
}

void VolumeControl::changeVolume()
{
    int newVolume = qBound(0, volume_ + volumeChange, maximumVolume());

    if (!warningAcknowledged() && safeVolume_ != 0 && newVolume > safeVolume_) {
        emit showAudioWarning(false);
        newVolume = safeVolume();
    }

    if (newVolume != volume_) {
        volume_ = newVolume;
        pulseAudioControl->setVolume(volume_);
        emit volumeChanged();
    }

    setWindowVisible(true);
    emit volumeKeyPressed();
}

void VolumeControl::stopKeyRepeat()
{
    keyRepeatDelayTimer.stop();
    keyRepeatTimer.stop();
}

void VolumeControl::handleHighVolume(int safeLevel)
{
    if (safeVolume_ != safeLevel) {
        safeVolume_ = safeLevel;
        emit safeVolumeChanged();
    }
}

void VolumeControl::handleLongListeningTime(int listeningTime)
{
    // Ignore initial listening time signal, which is sent the first time
    // media audio starts playing after reboot.
    if (listeningTime == 0)
        return;

    setWarningAcknowledged(false);
    setWindowVisible(true);

    // If safe volume step is not defined for this route (safeVolume() returns 0), use
    // maximum volume as the upper bound, otherwise use safe volume step as the upper
    // bound.
    int newVolume = qBound(0, volume_, safeVolume() == 0 ? maximumVolume() : safeVolume());
    if (newVolume != volume_) {
        volume_ = newVolume;
        pulseAudioControl->setVolume(volume_);
        emit volumeChanged();
    }

    emit showAudioWarning(false);
}

void VolumeControl::handleCallActive(bool callActive)
{
    if (callActive_ != callActive) {
        callActive_ = callActive;
        emit callActiveChanged();
    }
}

bool VolumeControl::eventFilter(QObject *, QEvent *event)
{
    if (hwKeysAcquired && (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_VolumeUp || keyEvent->key() == Qt::Key_VolumeDown) {
            if (event->type() == QEvent::KeyPress) {
                // Key down: set which way to change the volume on each repeat, start the repeat delay timer and change the volume once
                volumeChange = keyEvent->key() == Qt::Key_VolumeUp ? 1 : -1;
                if (!keyRepeatDelayTimer.isActive() && !keyRepeatTimer.isActive()) {
                    keyRepeatDelayTimer.start();
                    changeVolume();
                }
            } else {
                // Key up: stop any key repeating in progress and the repeat delay timer
                stopKeyRepeat();
            }
            return true;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "test/test_syscoin_services.h"
#include "utiltime.h"
#include "util.h"
#include "rpc/server.h"
#include "alias.h"
#include "cert.h"
#include "asset.h"
#include "base58.h"
#include "chainparams.h"
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <iterator>
#include <chrono>
#include "ranges.h"
using namespace boost::chrono;
using namespace std;
BOOST_GLOBAL_FIXTURE( SyscoinTestingSetup );

BOOST_FIXTURE_TEST_SUITE(syscoin_asset_allocation_tests, BasicSyscoinTestingSetup)
BOOST_AUTO_TEST_CASE(generate_asset_allocation_send)
{
	UniValue r;
	printf("Running generate_asset_allocation_send...\n");
	GenerateBlocks(5);
	AliasNew("node1", "jagassetallocationsend1", "data");
	AliasNew("node2", "jagassetallocationsend2", "data");
	string guid = AssetNew("node1", "usd", "jagassetallocationsend1", "data", "8", "false", "1", "-1");

	AssetSend("node1", guid, "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend1\\\",\\\"amount\\\":1}]\"", "assetallocationsend");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend1 false"));
	UniValue balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false), 1 * COIN);

	string txid0 = AssetAllocationTransfer(false, "node1", guid, "jagassetallocationsend1", "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend2\\\",\\\"amount\\\":0.11}]\"", "allocationsendmemo");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend2 false"));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false),0.11 * COIN);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// send using zdag
	string txid1 = AssetAllocationTransfer(true, "node1", guid, "jagassetallocationsend1", "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend2\\\",\\\"amount\\\":0.12}]\"", "allocationsendmemo");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend2 false"));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false), 0.23 * COIN);

	// non zdag cannot be found since it was already mined, but ends up briefly in conflict state because sender is conflicted
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// first tx should have to wait 1 sec for good status
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid +  " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// wait for 1 second as required by unit test
	MilliSleep(1000);

	// second send
	string txid2 = AssetAllocationTransfer(true, "node1", guid, "jagassetallocationsend1", "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend2\\\",\\\"amount\\\":0.13}]\"", "allocationsendmemo");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend2 false"));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false), 0.36 * COIN);

	// sender is conflicted so txid0 is conflicted by extension even if its not found
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// first ones now OK because it was found explicitely
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// second one hasn't waited enough time yet
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// wait for 1.5 second to clear minor warning status
	MilliSleep(1500);
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// after pow, should get not found on all of them
	GenerateBlocks(1);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

}
BOOST_AUTO_TEST_CASE(generate_asset_allocation_througput)
{
	UniValue r;
	printf("Running generate_asset_allocation_througputlkoi...\n");
	GenerateBlocks(5);
	vector<string> assetVec;
	// create 1000 aliases and assets for each asset
	for (int i = 0; i < 1000; i++) {
		string aliasname = "jagthroughput-" + boost::lexical_cast<string>(i);
		string aliasnameto = "jagthroughput3-" + boost::lexical_cast<string>(i);
		AliasNew("node1",aliasname, "data");
		AliasNew("node3", aliasnameto, "data");
		string guid = AssetNew("node1", "usd", aliasname, "data", "8", "false", "1", "-1");
		assetVec.push_back(guid);
	}
	vector<string> assetSendTxVec;
	for (auto& guid : assetVec) {
		string hex_str = AssetSend("node1", guid, "\"[{\\\"aliasto\\\":\\\"" + aliasnameto "\\\",\\\"amount\\\":1}]\"", "assetallocationsend", "''", false);
		assetSendTxVec.push_back(hex_str);
	}
	map<string, int64_t> sendTimes;
	for (auto& hex_str : assetSendTxVec) {
		BOOST_CHECK_NO_THROW(r = CallRPC("node1", "syscoinsendrawtransaction " + hex_str));
		string txid = find_value(r.get_obj(), "txid").get_str();
		sendTimes[txid] = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
	}
	float totalTime = 0;
	// wait 10 seconds
	MilliSleep(10000);
	BOOST_CHECK_NO_THROW(r = CallRPC("node3", "tpstestinfo"));
	UniValue tpsresponse = r.get_array();
	for (int i = 0; i < tpsresponse.size();i++) {
		UniValue responesObj = tpsresponse[i].get_obj();
		string txid = find_value(responesObj, "txid").get_str();
		int64_t timeRecv = find_value(responesObj, "time").get_int64();
		if (sendTimes.find(txid) == sendTimes.end())
			continue;
		totalTime += timeRecv - sendTimes[txid];
	}
	totalTime /= tpsresponse.size();
	printf("totalTime %.2f, num responses %d\n", totalTime, tpsresponse.size());
}
BOOST_AUTO_TEST_SUITE_END ()
<commit_msg>compile<commit_after>// Copyright (c) 2016-2017 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "test/test_syscoin_services.h"
#include "utiltime.h"
#include "util.h"
#include "rpc/server.h"
#include "alias.h"
#include "cert.h"
#include "asset.h"
#include "base58.h"
#include "chainparams.h"
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <iterator>
#include <chrono>
#include "ranges.h"
using namespace boost::chrono;
using namespace std;
BOOST_GLOBAL_FIXTURE( SyscoinTestingSetup );

BOOST_FIXTURE_TEST_SUITE(syscoin_asset_allocation_tests, BasicSyscoinTestingSetup)
BOOST_AUTO_TEST_CASE(generate_asset_allocation_send)
{
	UniValue r;
	printf("Running generate_asset_allocation_send...\n");
	GenerateBlocks(5);
	AliasNew("node1", "jagassetallocationsend1", "data");
	AliasNew("node2", "jagassetallocationsend2", "data");
	string guid = AssetNew("node1", "usd", "jagassetallocationsend1", "data", "8", "false", "1", "-1");

	AssetSend("node1", guid, "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend1\\\",\\\"amount\\\":1}]\"", "assetallocationsend");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend1 false"));
	UniValue balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false), 1 * COIN);

	string txid0 = AssetAllocationTransfer(false, "node1", guid, "jagassetallocationsend1", "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend2\\\",\\\"amount\\\":0.11}]\"", "allocationsendmemo");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend2 false"));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false),0.11 * COIN);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// send using zdag
	string txid1 = AssetAllocationTransfer(true, "node1", guid, "jagassetallocationsend1", "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend2\\\",\\\"amount\\\":0.12}]\"", "allocationsendmemo");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend2 false"));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false), 0.23 * COIN);

	// non zdag cannot be found since it was already mined, but ends up briefly in conflict state because sender is conflicted
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// first tx should have to wait 1 sec for good status
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid +  " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// wait for 1 second as required by unit test
	MilliSleep(1000);

	// second send
	string txid2 = AssetAllocationTransfer(true, "node1", guid, "jagassetallocationsend1", "\"[{\\\"aliasto\\\":\\\"jagassetallocationsend2\\\",\\\"amount\\\":0.13}]\"", "allocationsendmemo");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " jagassetallocationsend2 false"));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8, false), 0.36 * COIN);

	// sender is conflicted so txid0 is conflicted by extension even if its not found
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// first ones now OK because it was found explicitely
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// second one hasn't waited enough time yet
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT_OK);

	// wait for 1.5 second to clear minor warning status
	MilliSleep(1500);
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// after pow, should get not found on all of them
	GenerateBlocks(1);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " jagassetallocationsend1 ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

}
BOOST_AUTO_TEST_CASE(generate_asset_allocation_througput)
{
	UniValue r;
	printf("Running generate_asset_allocation_througputlkoi...\n");
	GenerateBlocks(5);
	map<string, string> assetMap;
	// create 1000 aliases and assets for each asset
	for (int i = 0; i < 1000; i++) {
		string aliasname = "jagthroughput-" + boost::lexical_cast<string>(i);
		string aliasnameto = "jagthroughput3-" + boost::lexical_cast<string>(i);
		AliasNew("node1",aliasname, "data");
		AliasNew("node3", aliasnameto, "data");
		string guid = AssetNew("node1", "usd", aliasname, "data", "8", "false", "1", "-1");
		assetMap[guid] = aliasnameto;
	}
	vector<string> assetSendTxVec;
	for (auto& assetTuple : assetMap) {
		string hex_str = AssetSend("node1", assetTuple.first, "\"[{\\\"aliasto\\\":\\\"" + assetTuple.second "\\\",\\\"amount\\\":1}]\"", "assetallocationsend", "''", false);
		assetSendTxVec.push_back(hex_str);
	}
	map<string, int64_t> sendTimes;
	for (auto& hex_str : assetSendTxVec) {
		BOOST_CHECK_NO_THROW(r = CallRPC("node1", "syscoinsendrawtransaction " + hex_str));
		string txid = find_value(r.get_obj(), "txid").get_str();
		sendTimes[txid] = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
	}
	float totalTime = 0;
	// wait 10 seconds
	MilliSleep(10000);
	BOOST_CHECK_NO_THROW(r = CallRPC("node3", "tpstestinfo"));
	UniValue tpsresponse = r.get_array();
	for (int i = 0; i < tpsresponse.size();i++) {
		UniValue responesObj = tpsresponse[i].get_obj();
		string txid = find_value(responesObj, "txid").get_str();
		int64_t timeRecv = find_value(responesObj, "time").get_int64();
		if (sendTimes.find(txid) == sendTimes.end())
			continue;
		totalTime += timeRecv - sendTimes[txid];
	}
	totalTime /= tpsresponse.size();
	printf("totalTime %.2f, num responses %d\n", totalTime, tpsresponse.size());
}
BOOST_AUTO_TEST_SUITE_END ()
<|endoftext|>


<commit_before>/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 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
    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

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#include <assert.h>

#include "SDL_naclvideo.h"
#include "SDL_naclevents_c.h"
#include "SDL_naclmouse_c.h"

extern NPDevice* NPN_AcquireDevice(NPP instance, NPDeviceID device);

extern "C" {

#include "SDL_video.h"
#include "SDL_mouse.h"
#include "SDL_nacl.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"

#define NACLVID_DRIVER_NAME "nacl"

static NPP global_npp;

void SDL_NACL_SetNPP(NPP npp) {
  global_npp = npp;
}

/* Initialization/Query functions */
static int NACL_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **NACL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *NACL_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int NACL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
static void NACL_VideoQuit(_THIS);

/* Hardware surface functions */
static int NACL_AllocHWSurface(_THIS, SDL_Surface *surface);
static int NACL_LockHWSurface(_THIS, SDL_Surface *surface);
static void NACL_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void NACL_FreeHWSurface(_THIS, SDL_Surface *surface);

/* etc. */
static void NACL_SetCaption(_THIS, const char* title, const char* icon);
static void NACL_UpdateRects(_THIS, int numrects, SDL_Rect *rects);

/* NACL driver bootstrap functions */

static int NACL_Available(void)
{
	const char *envr = SDL_getenv("SDL_VIDEODRIVER");
	assert(global_npp);
	printf("yes, nacl is available\n");
	return 1; // HACK
	if ((envr) && (SDL_strcmp(envr, NACLVID_DRIVER_NAME) == 0)) {
		return(1);
	}

	return(0);
}

static void NACL_DeleteDevice(SDL_VideoDevice *device)
{
	SDL_free(device->hidden);
	SDL_free(device);
}

static SDL_VideoDevice *NACL_CreateDevice(int devindex)
{
	SDL_VideoDevice *device;

	printf("Creating a NaCl device\n");
	/* Initialize all variables that we clean on shutdown */
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
	if ( device ) {
		SDL_memset(device, 0, (sizeof *device));
		device->hidden = (struct SDL_PrivateVideoData *)
				SDL_malloc((sizeof *device->hidden));
	}
	if ( (device == NULL) || (device->hidden == NULL) ) {
		SDL_OutOfMemory();
		if ( device ) {
			SDL_free(device);
		}
		return(0);
	}
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));

	printf("NPN_AcquireDevice...\n");
	assert(global_npp);
	device->hidden->device2d_ = NPN_AcquireDevice(global_npp, NPPepper2DDevice);
	assert(device->hidden->device2d_);

	memset(&device->hidden->context2d_, 0, sizeof(device->hidden->context2d_));
	NPDeviceContext2DConfig config;
	printf("device->initializeContext...\n");
	NPError init_err = device->hidden->device2d_->initializeContext(global_npp, &config, &device->hidden->context2d_);
	printf("error code %d\n", init_err);
	assert(NPERR_NO_ERROR == init_err);
	printf("NP magic successful\n");

	/* Set the function pointers */
	device->VideoInit = NACL_VideoInit;
	device->ListModes = NACL_ListModes;
	device->SetVideoMode = NACL_SetVideoMode;
	device->CreateYUVOverlay = NULL;
	device->SetColors = NACL_SetColors;
	device->UpdateRects = NACL_UpdateRects;
	device->VideoQuit = NACL_VideoQuit;
	device->AllocHWSurface = NACL_AllocHWSurface;
	device->CheckHWBlit = NULL;
	device->FillHWRect = NULL;
	device->SetHWColorKey = NULL;
	device->SetHWAlpha = NULL;
	device->LockHWSurface = NACL_LockHWSurface;
	device->UnlockHWSurface = NACL_UnlockHWSurface;
	device->FlipHWSurface = NULL;
	device->FreeHWSurface = NACL_FreeHWSurface;
	device->SetCaption = NACL_SetCaption;
	device->SetIcon = NULL;
	device->IconifyWindow = NULL;
	device->GrabInput = NULL;
	device->GetWMInfo = NULL;
	device->InitOSKeymap = NACL_InitOSKeymap;
	device->PumpEvents = NACL_PumpEvents;

	device->free = NACL_DeleteDevice;

	return device;
}

VideoBootStrap NACL_bootstrap = {
	NACLVID_DRIVER_NAME, "SDL Native Client video driver",
	NACL_Available, NACL_CreateDevice
};

int NACL_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
	fprintf(stderr, "CONGRATULATIONS: You are using the SDL nacl video driver!\n");

	/* Determine the screen depth (use default 8-bit depth) */
	/* we change this during the SDL_SetVideoMode implementation... */
	vformat->BitsPerPixel = 8;
	vformat->BytesPerPixel = 1;

	/* We're done! */
	return(0);
}

SDL_Rect **NACL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
   	 return (SDL_Rect **) -1;
}

SDL_Surface *NACL_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
  printf("SetVideoMode: %dx%dx%d, flags %u\n", width, height, bpp, (unsigned)flags);
	if ( _this->hidden->buffer ) {
		SDL_free( _this->hidden->buffer );
	}

	_this->hidden->buffer = SDL_malloc(width * height * (bpp / 8));
	if ( ! _this->hidden->buffer ) {
		SDL_SetError("Couldn't allocate buffer for requested mode");
		return(NULL);
	}

	if (bpp == 8) {
	  _this->hidden->palette = (SDL_Color*)SDL_malloc(256 * sizeof(SDL_Color));
	  if ( ! _this->hidden->palette ) {
	    SDL_SetError("Couldn't allocate palette for requested 8-bit mode");
	    return(NULL);
	  }
	}

/* 	printf("Setting mode %dx%d\n", width, height); */

	SDL_memset(_this->hidden->buffer, 0, width * height * (bpp / 8));
	if (_this->hidden->palette) {
	  SDL_memset(_this->hidden->palette, 0, 256 * sizeof(SDL_Color));
	}

	/* Allocate the new pixel format for the screen */
	if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
		SDL_free(_this->hidden->buffer);
		_this->hidden->buffer = NULL;
		SDL_SetError("Couldn't allocate new pixel format for requested mode");
		return(NULL);
	}

	/* Set up the new mode framebuffer */
	current->flags = flags & SDL_FULLSCREEN;
	_this->hidden->bpp = bpp;
	_this->hidden->w = current->w = width;
	_this->hidden->h = current->h = height;
	_this->hidden->pitch = current->pitch = current->w * (bpp / 8);
	current->pixels = _this->hidden->buffer;

	/* We're done */
	return(current);
}

/* We don't actually allow hardware surfaces other than the main one */
static int NACL_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	return(-1);
}
static void NACL_FreeHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

/* We need to wait for vertical retrace on page flipped displays */
static int NACL_LockHWSurface(_THIS, SDL_Surface *surface)
{
	return(0);
}

static void NACL_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static void write_ppm(_THIS, char* fname) {
  FILE* fp = fopen(fname, "w");
  int x, y;
  assert(_this->hidden->bpp == 8);
  fprintf(fp, "P3\n%d %d\n255\n", _this->hidden->w, _this->hidden->h);
  for (y = 0; y < _this->hidden->h; ++y) {
    unsigned char* pixels = ((unsigned char*)_this->hidden->buffer) + _this->hidden->pitch * y;
    for (x = 0; x < _this->hidden->w; ++x) {
      SDL_Color pixel = _this->hidden->palette[pixels[x]];
      fprintf(fp, "%d %d %d  ", pixel.r, pixel.g, pixel.b);
    }
    fprintf(fp, "\n");
  }
  fclose(fp);
}

// This is called by the brower when the 2D context has been flushed to the
// browser window.
// static void FlushCallback(NPP instance, NPDeviceContext* context,
//   NPError err, void* user_data) {
// }

static void flush(_THIS) {
  // NPDeviceFlushContextCallbackPtr callback =
  //   reinterpret_cast<NPDeviceFlushContextCallbackPtr>(&FlushCallback);
  // _this->hidden->device2d_->flushContext(global_npp, &_this->hidden->context2d_, callback, NULL);
  _this->hidden->device2d_->flushContext(global_npp, &_this->hidden->context2d_, NULL, NULL);
}

static void NACL_SetCaption(_THIS, const char* title, const char* icon) {
  if (title && strcmp(title, "Dear SDL, this is your chance to flush the NPDevice context.") == 0) {
    // Do what we are told.
    flush(_this);
  }
}

static void flip(_THIS) {
  // printf("flip: this %p\n", _this);
  // printf("flip: h %d w %d bpp %d\n", _this->hidden->h, _this->hidden->w, _this->hidden->bpp);
  assert(_this->hidden->bpp == 8);
  uint32_t* pixel_bits = static_cast<uint32_t*>(_this->hidden->context2d_.region);
  for (int y = 0; y < _this->hidden->h; ++y) {
    unsigned char* pixels = ((unsigned char*)_this->hidden->buffer) + _this->hidden->pitch * y;
    for (int x = 0; x < _this->hidden->w; ++x) {
      SDL_Color color = _this->hidden->palette[pixels[x]];
      uint32_t val = 0xFF000000 + ((uint32_t)color.r << 16) + ((uint32_t)color.g << 8) +
	((uint32_t)color.b);
      pixel_bits[_this->hidden->w * y + x] = val;
    }
  }
  // flush(_this);
}

static void NACL_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
{
  /* static int frameno; */
  /* char fname[100]; */
  /* if (_this->hidden->bpp == 0) // not initialized yet */
  /*   return; */
  /* snprintf(fname, 100, "frame%05d.ppm", frameno++); */
  /* write_ppm(_this, fname); */

  if (_this->hidden->bpp == 0) // not initialized yet
    return;
  flip(_this);
}

int NACL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
  int i;
  assert(_this->hidden->bpp == 8);
  assert(_this->hidden->palette);
  for (i = 0; i < ncolors; ++i)
    _this->hidden->palette[firstcolor + i] = colors[i];
  return(1);
}

/* Note:  If we are terminated, this could be called in the middle of
   another SDL video routine -- notably UpdateRects.
*/
void NACL_VideoQuit(_THIS)
{
	if (_this->screen->pixels != NULL)
	{
		SDL_free(_this->screen->pixels);
		_this->screen->pixels = NULL;
	}
}
} // extern "C"
<commit_msg>Call flush() in the main thread instead of waiting for application callback.<commit_after>/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 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
    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

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#include <assert.h>

#include "SDL_naclvideo.h"
#include "SDL_naclevents_c.h"
#include "SDL_naclmouse_c.h"

extern NPDevice* NPN_AcquireDevice(NPP instance, NPDeviceID device);

extern "C" {

#include "SDL_video.h"
#include "SDL_mouse.h"
#include "SDL_nacl.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"

#define NACLVID_DRIVER_NAME "nacl"

static NPP global_npp;

void SDL_NACL_SetNPP(NPP npp) {
  global_npp = npp;
}

/* Initialization/Query functions */
static int NACL_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **NACL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *NACL_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int NACL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
static void NACL_VideoQuit(_THIS);

/* Hardware surface functions */
static int NACL_AllocHWSurface(_THIS, SDL_Surface *surface);
static int NACL_LockHWSurface(_THIS, SDL_Surface *surface);
static void NACL_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void NACL_FreeHWSurface(_THIS, SDL_Surface *surface);

/* etc. */
static void NACL_SetCaption(_THIS, const char* title, const char* icon);
static void NACL_UpdateRects(_THIS, int numrects, SDL_Rect *rects);

/* NACL driver bootstrap functions */

static int NACL_Available(void)
{
  const char *envr = SDL_getenv("SDL_VIDEODRIVER");
  // Available if NPP is set and SDL_VIDEODRIVER is either unset, empty, or "nacl".
  if (global_npp &&
      (!envr || !*envr || SDL_strcmp(envr, NACLVID_DRIVER_NAME) == 0)) {
    printf("nacl video is available\n");
    return 1;
  }
  return 0;
}

static void NACL_DeleteDevice(SDL_VideoDevice *device)
{
	SDL_free(device->hidden);
	SDL_free(device);
}

static SDL_VideoDevice *NACL_CreateDevice(int devindex)
{
	SDL_VideoDevice *device;

	printf("Creating a NaCl device\n");
	/* Initialize all variables that we clean on shutdown */
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
	if ( device ) {
		SDL_memset(device, 0, (sizeof *device));
		device->hidden = (struct SDL_PrivateVideoData *)
				SDL_malloc((sizeof *device->hidden));
	}
	if ( (device == NULL) || (device->hidden == NULL) ) {
		SDL_OutOfMemory();
		if ( device ) {
			SDL_free(device);
		}
		return(0);
	}
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));

	printf("NPN_AcquireDevice...\n");
	assert(global_npp);
	device->hidden->device2d_ = NPN_AcquireDevice(global_npp, NPPepper2DDevice);
	assert(device->hidden->device2d_);

	memset(&device->hidden->context2d_, 0, sizeof(device->hidden->context2d_));
	NPDeviceContext2DConfig config;
	printf("device->initializeContext...\n");
	NPError init_err = device->hidden->device2d_->initializeContext(global_npp, &config, &device->hidden->context2d_);
	printf("error code %d\n", init_err);
	assert(NPERR_NO_ERROR == init_err);
	printf("NP magic successful\n");

	/* Set the function pointers */
	device->VideoInit = NACL_VideoInit;
	device->ListModes = NACL_ListModes;
	device->SetVideoMode = NACL_SetVideoMode;
	device->CreateYUVOverlay = NULL;
	device->SetColors = NACL_SetColors;
	device->UpdateRects = NACL_UpdateRects;
	device->VideoQuit = NACL_VideoQuit;
	device->AllocHWSurface = NACL_AllocHWSurface;
	device->CheckHWBlit = NULL;
	device->FillHWRect = NULL;
	device->SetHWColorKey = NULL;
	device->SetHWAlpha = NULL;
	device->LockHWSurface = NACL_LockHWSurface;
	device->UnlockHWSurface = NACL_UnlockHWSurface;
	device->FlipHWSurface = NULL;
	device->FreeHWSurface = NACL_FreeHWSurface;
	device->SetCaption = NACL_SetCaption;
	device->SetIcon = NULL;
	device->IconifyWindow = NULL;
	device->GrabInput = NULL;
	device->GetWMInfo = NULL;
	device->InitOSKeymap = NACL_InitOSKeymap;
	device->PumpEvents = NACL_PumpEvents;

	device->free = NACL_DeleteDevice;

	return device;
}

VideoBootStrap NACL_bootstrap = {
	NACLVID_DRIVER_NAME, "SDL Native Client video driver",
	NACL_Available, NACL_CreateDevice
};

int NACL_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
	fprintf(stderr, "CONGRATULATIONS: You are using the SDL nacl video driver!\n");

	/* Determine the screen depth (use default 8-bit depth) */
	/* we change this during the SDL_SetVideoMode implementation... */
	vformat->BitsPerPixel = 8;
	vformat->BytesPerPixel = 1;

	/* We're done! */
	return(0);
}

SDL_Rect **NACL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
   	 return (SDL_Rect **) -1;
}

SDL_Surface *NACL_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
  printf("SetVideoMode: %dx%dx%d, flags %u\n", width, height, bpp, (unsigned)flags);
	if ( _this->hidden->buffer ) {
		SDL_free( _this->hidden->buffer );
	}

	_this->hidden->buffer = SDL_malloc(width * height * (bpp / 8));
	if ( ! _this->hidden->buffer ) {
		SDL_SetError("Couldn't allocate buffer for requested mode");
		return(NULL);
	}

	if (bpp == 8) {
	  _this->hidden->palette = (SDL_Color*)SDL_malloc(256 * sizeof(SDL_Color));
	  if ( ! _this->hidden->palette ) {
	    SDL_SetError("Couldn't allocate palette for requested 8-bit mode");
	    return(NULL);
	  }
	}

/* 	printf("Setting mode %dx%d\n", width, height); */

	SDL_memset(_this->hidden->buffer, 0, width * height * (bpp / 8));
	if (_this->hidden->palette) {
	  SDL_memset(_this->hidden->palette, 0, 256 * sizeof(SDL_Color));
	}

	/* Allocate the new pixel format for the screen */
	if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
		SDL_free(_this->hidden->buffer);
		_this->hidden->buffer = NULL;
		SDL_SetError("Couldn't allocate new pixel format for requested mode");
		return(NULL);
	}

	/* Set up the new mode framebuffer */
	current->flags = flags & SDL_FULLSCREEN;
	_this->hidden->bpp = bpp;
	_this->hidden->w = current->w = width;
	_this->hidden->h = current->h = height;
	_this->hidden->pitch = current->pitch = current->w * (bpp / 8);
	current->pixels = _this->hidden->buffer;

	/* We're done */
	return(current);
}

/* We don't actually allow hardware surfaces other than the main one */
static int NACL_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	return(-1);
}
static void NACL_FreeHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

/* We need to wait for vertical retrace on page flipped displays */
static int NACL_LockHWSurface(_THIS, SDL_Surface *surface)
{
	return(0);
}

static void NACL_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static void write_ppm(_THIS, char* fname) {
  FILE* fp = fopen(fname, "w");
  int x, y;
  assert(_this->hidden->bpp == 8);
  fprintf(fp, "P3\n%d %d\n255\n", _this->hidden->w, _this->hidden->h);
  for (y = 0; y < _this->hidden->h; ++y) {
    unsigned char* pixels = ((unsigned char*)_this->hidden->buffer) + _this->hidden->pitch * y;
    for (x = 0; x < _this->hidden->w; ++x) {
      SDL_Color pixel = _this->hidden->palette[pixels[x]];
      fprintf(fp, "%d %d %d  ", pixel.r, pixel.g, pixel.b);
    }
    fprintf(fp, "\n");
  }
  fclose(fp);
}

// This is called by the brower when the 2D context has been flushed to the
// browser window.
// static void FlushCallback(NPP instance, NPDeviceContext* context,
//   NPError err, void* user_data) {
// }

static void flush(_THIS) {
  // NPDeviceFlushContextCallbackPtr callback =
  //   reinterpret_cast<NPDeviceFlushContextCallbackPtr>(&FlushCallback);
  // _this->hidden->device2d_->flushContext(global_npp, &_this->hidden->context2d_, callback, NULL);
  _this->hidden->device2d_->flushContext(global_npp, &_this->hidden->context2d_, NULL, NULL);
}

static void NACL_SetCaption(_THIS, const char* title, const char* icon) {
}

static void flip(_THIS) {
  // printf("flip: this %p\n", _this);
  // printf("flip: h %d w %d bpp %d\n", _this->hidden->h, _this->hidden->w, _this->hidden->bpp);
  assert(_this->hidden->bpp == 8);
  uint32_t* pixel_bits = static_cast<uint32_t*>(_this->hidden->context2d_.region);
  for (int y = 0; y < _this->hidden->h; ++y) {
    unsigned char* pixels = ((unsigned char*)_this->hidden->buffer) + _this->hidden->pitch * y;
    for (int x = 0; x < _this->hidden->w; ++x) {
      SDL_Color color = _this->hidden->palette[pixels[x]];
      uint32_t val = 0xFF000000 + ((uint32_t)color.r << 16) + ((uint32_t)color.g << 8) +
	((uint32_t)color.b);
      pixel_bits[_this->hidden->w * y + x] = val;
    }
  }
  NPN_PluginThreadAsyncCall(global_npp, (void (*)(void*))&flush, _this);
}

static void NACL_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
{
  /* static int frameno; */
  /* char fname[100]; */
  /* if (_this->hidden->bpp == 0) // not initialized yet */
  /*   return; */
  /* snprintf(fname, 100, "frame%05d.ppm", frameno++); */
  /* write_ppm(_this, fname); */

  if (_this->hidden->bpp == 0) // not initialized yet
    return;
  flip(_this);
}

int NACL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
  int i;
  assert(_this->hidden->bpp == 8);
  assert(_this->hidden->palette);
  for (i = 0; i < ncolors; ++i)
    _this->hidden->palette[firstcolor + i] = colors[i];
  return(1);
}

/* Note:  If we are terminated, this could be called in the middle of
   another SDL video routine -- notably UpdateRects.
*/
void NACL_VideoQuit(_THIS)
{
	if (_this->screen->pixels != NULL)
	{
		SDL_free(_this->screen->pixels);
		_this->screen->pixels = NULL;
	}
}
} // extern "C"
<|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include <exception>
#include <sstream>

#include <fcntl.h>
#include <sys/stat.h>

#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

#include <glog/logging.h>

#include "osquery/filesystem.h"

using osquery::Status;

namespace pt = boost::property_tree;
namespace fs = boost::filesystem;

namespace osquery {

Status writeTextFile(const boost::filesystem::path& path,
                     const std::string& content,
                     int permissions,
                     bool force_permissions) {
  // Open the file with the request permissions.
  int output_fd =
      open(path.c_str(), O_CREAT | O_APPEND | O_WRONLY, permissions);
  if (output_fd <= 0) {
    return Status(1, "Could not create file");
  }

  // If the file existed with different permissions before our open
  // they must be restricted.
  if (chmod(path.c_str(), permissions) != 0) {
    // Could not change the file to the requested permissions.
    return Status(1, "Failed to change permissions");
  }

  auto bytes = write(output_fd, content.c_str(), content.size());
  if (bytes != content.size()) {
    close(output_fd);
    return Status(1, "Failed to write contents");
  }

  close(output_fd);
  return Status(0, "OK");
}

Status readFile(const boost::filesystem::path& path, std::string& content) {
  auto path_exists = pathExists(path);
  if (!path_exists.ok()) {
    return path_exists;
  }

  int statusCode = 0;
  std::string statusMessage = "OK";
  char* buffer;

  fs::ifstream file_h(path);
  if (file_h) {
    file_h.seekg(0, file_h.end);
    int len = file_h.tellg();
    file_h.seekg(0, file_h.beg);
    buffer = new char[len];
    file_h.read(buffer, len);
    if (!file_h) {
      statusCode = 1;
      statusMessage = "Could not read file";
      goto cleanup_buffer;
    }
    content.assign(buffer, len);
  } else {
    statusCode = 1;
    statusMessage = "Could not open file for reading";
    goto cleanup;
  }

cleanup_buffer:
  delete[] buffer;
cleanup:
  if (file_h) {
    file_h.close();
  }
  return Status(statusCode, statusMessage);
}

Status isWritable(const boost::filesystem::path& path) {
  auto path_exists = pathExists(path);
  if (!path_exists.ok()) {
    return path_exists;
  }

  if (access(path.c_str(), W_OK) == 0) {
    return Status(0, "OK");
  }
  return Status(1, "Path is not writable.");
}

Status isReadable(const boost::filesystem::path& path) {
  auto path_exists = pathExists(path);
  if (!path_exists.ok()) {
    return path_exists;
  }

  if (access(path.c_str(), R_OK) == 0) {
    return Status(0, "OK");
  }
  return Status(1, "Path is not readable.");
}

Status pathExists(const boost::filesystem::path& path) {
  if (path.empty()) {
    return Status(1, "-1");
  }

  // A tri-state determination of presence
  if (!boost::filesystem::exists(path)) {
    return Status(1, "0");
  }
  return Status(0, "1");
}

Status listFilesInDirectory(const boost::filesystem::path& path,
                            std::vector<std::string>& results) {
  try {
    if (!boost::filesystem::exists(path)) {
      return Status(1, "Directory not found");
    }

    if (!boost::filesystem::is_directory(path)) {
      return Status(1, "Supplied path is not a directory");
    }

    boost::filesystem::directory_iterator begin_iter(path);
    boost::filesystem::directory_iterator end_iter;
    for (; begin_iter != end_iter; begin_iter++) {
      results.push_back(begin_iter->path().string());
    }

    return Status(0, "OK");
  } catch (const boost::filesystem::filesystem_error& e) {
    return Status(1, e.what());
  }
}

Status getDirectory(const boost::filesystem::path& path,
                    boost::filesystem::path& dirpath) {
  if (!isDirectory(path).ok()) {
    dirpath = boost::filesystem::path(path).parent_path().string();
    return Status(0, "OK");
  }
  dirpath = path;
  return Status(1, "Path is a directory");
}

Status isDirectory(const boost::filesystem::path& path) {
  if (boost::filesystem::is_directory(path)) {
    return Status(0, "OK");
  }
  return Status(1, "Path is not a directory");
}

Status parseTomcatUserConfigFromDisk(
    const boost::filesystem::path& path,
    std::vector<std::pair<std::string, std::string> >& credentials) {
  std::string content;
  auto s = readFile(path, content);
  if (s.ok()) {
    return parseTomcatUserConfig(content, credentials);
  } else {
    return s;
  }
}

Status parseTomcatUserConfig(
    const std::string& content,
    std::vector<std::pair<std::string, std::string> >& credentials) {
  std::stringstream ss;
  ss << content;
  pt::ptree tree;
  try {
    pt::xml_parser::read_xml(ss, tree);
  } catch (const pt::xml_parser_error& e) {
    return Status(1, e.what());
  }
  try {
    for (const auto& i : tree.get_child("tomcat-users")) {
      if (i.first == "user") {
        try {
          std::pair<std::string, std::string> user;
          user.first = i.second.get<std::string>("<xmlattr>.username");
          user.second = i.second.get<std::string>("<xmlattr>.password");
          credentials.push_back(user);
        } catch (const std::exception& e) {
          LOG(ERROR)
              << "An error occured parsing the tomcat users xml: " << e.what();
          return Status(1, e.what());
        }
      }
    }
  } catch (const std::exception& e) {
    LOG(ERROR) << "An error occured while trying to access the tomcat-users"
               << " key in the XML content: " << e.what();
    return Status(1, e.what());
  }
  return Status(0, "OK");
}
}
<commit_msg>Catch exception in pathExists<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include <exception>
#include <sstream>

#include <fcntl.h>
#include <sys/stat.h>

#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

#include <glog/logging.h>

#include "osquery/filesystem.h"

using osquery::Status;

namespace pt = boost::property_tree;
namespace fs = boost::filesystem;

namespace osquery {

Status writeTextFile(const boost::filesystem::path& path,
                     const std::string& content,
                     int permissions,
                     bool force_permissions) {
  // Open the file with the request permissions.
  int output_fd =
      open(path.c_str(), O_CREAT | O_APPEND | O_WRONLY, permissions);
  if (output_fd <= 0) {
    return Status(1, "Could not create file");
  }

  // If the file existed with different permissions before our open
  // they must be restricted.
  if (chmod(path.c_str(), permissions) != 0) {
    // Could not change the file to the requested permissions.
    return Status(1, "Failed to change permissions");
  }

  auto bytes = write(output_fd, content.c_str(), content.size());
  if (bytes != content.size()) {
    close(output_fd);
    return Status(1, "Failed to write contents");
  }

  close(output_fd);
  return Status(0, "OK");
}

Status readFile(const boost::filesystem::path& path, std::string& content) {
  auto path_exists = pathExists(path);
  if (!path_exists.ok()) {
    return path_exists;
  }

  int statusCode = 0;
  std::string statusMessage = "OK";
  char* buffer;

  fs::ifstream file_h(path);
  if (file_h) {
    file_h.seekg(0, file_h.end);
    int len = file_h.tellg();
    file_h.seekg(0, file_h.beg);
    buffer = new char[len];
    file_h.read(buffer, len);
    if (!file_h) {
      statusCode = 1;
      statusMessage = "Could not read file";
      goto cleanup_buffer;
    }
    content.assign(buffer, len);
  } else {
    statusCode = 1;
    statusMessage = "Could not open file for reading";
    goto cleanup;
  }

cleanup_buffer:
  delete[] buffer;
cleanup:
  if (file_h) {
    file_h.close();
  }
  return Status(statusCode, statusMessage);
}

Status isWritable(const boost::filesystem::path& path) {
  auto path_exists = pathExists(path);
  if (!path_exists.ok()) {
    return path_exists;
  }

  if (access(path.c_str(), W_OK) == 0) {
    return Status(0, "OK");
  }
  return Status(1, "Path is not writable.");
}

Status isReadable(const boost::filesystem::path& path) {
  auto path_exists = pathExists(path);
  if (!path_exists.ok()) {
    return path_exists;
  }

  if (access(path.c_str(), R_OK) == 0) {
    return Status(0, "OK");
  }
  return Status(1, "Path is not readable.");
}

Status pathExists(const boost::filesystem::path& path) {
  if (path.empty()) {
    return Status(1, "-1");
  }

  // A tri-state determination of presence
  try {
    if (!boost::filesystem::exists(path)) {
      return Status(1, "0");
    }
  }
  catch (boost::filesystem::filesystem_error e) {
    return Status(1, e.what());
  }
  return Status(0, "1");
}

Status listFilesInDirectory(const boost::filesystem::path& path,
                            std::vector<std::string>& results) {
  try {
    if (!boost::filesystem::exists(path)) {
      return Status(1, "Directory not found");
    }

    if (!boost::filesystem::is_directory(path)) {
      return Status(1, "Supplied path is not a directory");
    }

    boost::filesystem::directory_iterator begin_iter(path);
    boost::filesystem::directory_iterator end_iter;
    for (; begin_iter != end_iter; begin_iter++) {
      results.push_back(begin_iter->path().string());
    }

    return Status(0, "OK");
  } catch (const boost::filesystem::filesystem_error& e) {
    return Status(1, e.what());
  }
}

Status getDirectory(const boost::filesystem::path& path,
                    boost::filesystem::path& dirpath) {
  if (!isDirectory(path).ok()) {
    dirpath = boost::filesystem::path(path).parent_path().string();
    return Status(0, "OK");
  }
  dirpath = path;
  return Status(1, "Path is a directory");
}

Status isDirectory(const boost::filesystem::path& path) {
  if (boost::filesystem::is_directory(path)) {
    return Status(0, "OK");
  }
  return Status(1, "Path is not a directory");
}

Status parseTomcatUserConfigFromDisk(
    const boost::filesystem::path& path,
    std::vector<std::pair<std::string, std::string> >& credentials) {
  std::string content;
  auto s = readFile(path, content);
  if (s.ok()) {
    return parseTomcatUserConfig(content, credentials);
  } else {
    return s;
  }
}

Status parseTomcatUserConfig(
    const std::string& content,
    std::vector<std::pair<std::string, std::string> >& credentials) {
  std::stringstream ss;
  ss << content;
  pt::ptree tree;
  try {
    pt::xml_parser::read_xml(ss, tree);
  } catch (const pt::xml_parser_error& e) {
    return Status(1, e.what());
  }
  try {
    for (const auto& i : tree.get_child("tomcat-users")) {
      if (i.first == "user") {
        try {
          std::pair<std::string, std::string> user;
          user.first = i.second.get<std::string>("<xmlattr>.username");
          user.second = i.second.get<std::string>("<xmlattr>.password");
          credentials.push_back(user);
        } catch (const std::exception& e) {
          LOG(ERROR)
              << "An error occured parsing the tomcat users xml: " << e.what();
          return Status(1, e.what());
        }
      }
    }
  } catch (const std::exception& e) {
    LOG(ERROR) << "An error occured while trying to access the tomcat-users"
               << " key in the XML content: " << e.what();
    return Status(1, e.what());
  }
  return Status(0, "OK");
}
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//                       Copyright (c) 2011 - 2012 by                        //
//                                Simon Pratt                                //
//                           (All rights reserved)                           //
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// FILE:    PersistentSkipList.cpp                                           //
//                                                                           //
// MODULE:  Persistent Skip List                                             //
//                                                                           //
// NOTES:   None.                                                            //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////
#ifndef PERSISTENTSKIPLIST_CPP
#define PERSISTENTSKIPLIST_CPP

#include "PersistentSkipList.hpp"

using namespace persistent_skip_list;

///////////////////////////////////////////////////////////////////////////////
// PersistentSkipList Implementation                                         //
///////////////////////////////////////////////////////////////////////////////

template <class T>
PersistentSkipList<T>::PersistentSkipList(int nodeSize)
  : node_size(nodeSize), present(0), head(), tail(), data_set()
{
  SmartPointer<ListNode<T> > negInf(new ListNode<T>(1,false));
  SmartPointer<ListNode<T> > posInf(new ListNode<T>(1,true));
  head.insert( pair<int,SmartPointer<ListNode<T> > >(0,negInf) );
  tail.insert( pair<int,SmartPointer<ListNode<T> > >(0,posInf) );
  // set next on negInf to posInf
  TSA* newNext = new TSA(0,1);
  newNext->setElement(0,posInf);
  negInf->addNext(newNext);
}

template <class T>
PersistentSkipList<T>::~PersistentSkipList() {
}

template <class T>
int PersistentSkipList<T>::getPresent() const {
  assert(this != NULL);
  return present;
}

template <class T>
PersistentSkipList<T>& PersistentSkipList<T>::operator++() {
  incTime();
  return this;
}

template <class T>
void PersistentSkipList<T>::incTime() {
  assert(this != NULL);
  ++present;
}

template <class T>
void PersistentSkipList<T>::drawPresent() {
  assert(this != NULL);
  draw(getPresent());
}

template <class T>
void PersistentSkipList<T>::draw(int t) {
  assert(this != NULL);
  assert(t >= 0);
  cout << "Drawing skip list at time " << t << "..." << endl;
  if(empty(t)) {
    cout << "NULL" << endl;
    return;
  }
  for(int i = 0; i < getHeight(t); ++i) {
    PSLIterator<T> next = begin(t,i);

    cout << "Height: " << i+1 << endl;

    while(next != end(t)) {
      cout << "Node(data=" << *next
	   << ",height=" << next.getHeight() << ")" << endl;
      ++next;
    }
  }
}

template <class T>
int PersistentSkipList<T>::addHead(SmartPointer<ListNode<T> > new_head) {
  assert(this != NULL);
  assert(new_head != NULL);
  // delete old head if exists
  if(head.count(present) > 0)
    head.erase(present); // shouldn't leak using smart pointer
  // save the new head
  head.insert( pair< int, SmartPointer<ListNode<T> > >(present,new_head) );
  // success
  return 0;
}

template <class T>
SmartPointer<ListNode<T> >& PersistentSkipList<T>::getHead(int t) {
  // reverse linear search from starting time
  while(head.count(t) == 0)
    --t;
  return head[t];
}

template <class T>
int PersistentSkipList<T>::addTail(SmartPointer<ListNode<T> > new_tail) {
  assert(this != NULL);
  assert(new_tail != NULL);
  // delete old head if exists
  if(tail.count(present) > 0)
    tail.erase(present); // shouldn't leak using smart pointer
  // save the new head
  tail.insert( pair< int, SmartPointer<ListNode<T> > >(present,new_tail) );
  // success
  return 0;
}

template <class T>
SmartPointer<ListNode<T> >& PersistentSkipList<T>::getTail(int t) {
  // reverse linear search from starting time
  while(tail.count(t) == 0)
    --t;
  return tail[t];
}

template <class T>
void PersistentSkipList<T>::buildHeadAndTail(int new_height) {
  assert(new_height > getHeight(getPresent()));
  int present = getPresent();
  SmartPointer<ListNode<T> > old_head = getHead(present);
  SmartPointer<ListNode<T> > old_tail = getTail(present);
  int old_height = old_head->getHeight();
  assert(new_height > old_height);
  assert(old_height == old_tail->getHeight());
  SmartPointer<ListNode<T> > new_head(new ListNode<T>(new_height,false));
  SmartPointer<ListNode<T> > new_tail(new ListNode<T>(new_height,true));
  assert(new_head->getHeight() == new_tail->getHeight());
  TSA* new_next = new TSA(present,new_height);
  // make the tail the new next above the old height
  while(--new_height >= old_height) {
    new_next->setElement(new_height,new_tail);
  }
  while(new_height >= 0) {
    SmartPointer<ListNode<T> > next_node =
      old_head->getNext(present)->getElement(new_height);
    if(next_node == old_tail)
      new_next->setElement(new_height,new_tail);
    else
      new_next->setElement(new_height,next_node);
    --new_height;
  }
  new_head->addNext(new_next);
  addHead(new_head);
  // make all the nodes which pointed to the old tail point to the new tail
  --old_height;
  while(old_height >= 0) {
    int end = old_height;
    while(end > 0 &&
	  old_tail->getIncoming(end-1) == old_tail->getIncoming(old_height))
      --end;
    ListNode<T>* toChange = old_tail->getIncoming(old_height);
    if(old_head == toChange) {
      old_height = end-1;
      continue;
    }
    new_next = new TSA(present,
		       toChange->getHeight(),
		       *(toChange->getNext(present)));
    while(old_height >= end) {
      new_next->setElement(old_height,new_tail);
      new_tail->setIncoming(old_height,toChange);
      --old_height;
    }
    toChange->addNext(new_next);
  }
  addTail(new_tail);
}

template < class T >
PSLIterator<T> PersistentSkipList<T>::begin(int t, int h) {
  return ++(PSLIterator<T>(getHead(t),t,h));
}

template < class T >
PSLIterator<T> PersistentSkipList<T>::end(int t) {
  return PSLIterator<T>(getTail(t),t);
}

template < class T >
PSLIterator<T> PersistentSkipList<T>::find(const T& toFind, int t) {
  PSLIterator<T> iter = PSLIterator<T>(getHead(t),t,getHeight(t)-1);
  PSLIterator<T> next = iter.getNext();
  const PSLIterator<T> end = this->end(t);
  while( iter.getSearchHeight() > 0 || next != end ) {
    // loop invariant: we have already determined the value of iter
    //                 precedes the data for which we are searching.
    if(next <= toFind && next != end) {
      assert(iter.getSearchHeight() < next.getHeight());
      iter.next();
    } else if(next > toFind && iter.getSearchHeight() > 0) {
      iter.down();
    } else {
      return iter;
    }
    next = iter.getNext();
  }
  return iter;
}

template < class T >
int PersistentSkipList<T>::getHeight(int t) {
  return (getHead(t))->getHeight();
}

template < class T >
bool PersistentSkipList<T>::empty(void) {
  return empty(getPresent());
}

template < class T >
bool PersistentSkipList<T>::empty(int t) {
  return begin(t) == end(t);
}

/////////////////////////////////////////////////////////////////////////////
// INSERT METHOD                                                           //
/////////////////////////////////////////////////////////////////////////////

template <class T>
const PersistentSkipList<T>& PersistentSkipList<T>::operator+=(const T& data) {
  if(insert(data) != 0) // error
    throw "Unable to insert data!";
  return this;
}

template <class T>
int PersistentSkipList<T>::insert(const T& data) {
  assert(this != NULL);
  // check if data exists already
  if(data_set.count(data)>0)
    return 1;
  int present = getPresent();
  // otherwise, create node
  SmartPointer<ListNode<T> > new_ln(new ListNode<T>(data));
  int height = new_ln->getHeight();
  // add node to list
  int start = height-1;
  // Taller than old head
  if(height > getHeight(getPresent()))
    buildHeadAndTail(height);
  // Add new node to list
  SmartPointer<ListNode<T> > old_ln = getHead(present);
  TSA* new_node_next = new TSA(present,height);
  while(start >= 0) {
    SmartPointer<ListNode<T> > next_ln =
      old_ln->getNext(present)->getElement(start);
    // find the elements between which we should insert the new node
    while(*new_ln > *next_ln) {
      old_ln = next_ln;
      next_ln = old_ln->getNext(present)->getElement(start);
    }
    TSA* old_ln_next = new TSA(present,
			       old_ln->getHeight(),
			       *(old_ln->getNext(present)));
    while(*new_ln < *next_ln) {
      new_node_next->setElement(start,next_ln);
      // point the old node to the new node
      old_ln_next->setElement(start,new_ln);
      // move to the next height
      --start;
      if(start < 0)
	break;
      next_ln = old_ln_next->getElement(start);
    }
    old_ln->addNext(old_ln_next);
    // move to next search height
    if(start < 0)
      break;
    // get node at new height
    old_ln = next_ln;
  }
  new_ln->addNext(new_node_next);
  // prevent duplicates by registering this datum
  data_set.insert(data);
  // success
  return 0;
}

#endif
<commit_msg>Fixed search error<commit_after>///////////////////////////////////////////////////////////////////////////////
//                       Copyright (c) 2011 - 2012 by                        //
//                                Simon Pratt                                //
//                           (All rights reserved)                           //
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// FILE:    PersistentSkipList.cpp                                           //
//                                                                           //
// MODULE:  Persistent Skip List                                             //
//                                                                           //
// NOTES:   None.                                                            //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////
#ifndef PERSISTENTSKIPLIST_CPP
#define PERSISTENTSKIPLIST_CPP

#include "PersistentSkipList.hpp"

using namespace persistent_skip_list;

///////////////////////////////////////////////////////////////////////////////
// PersistentSkipList Implementation                                         //
///////////////////////////////////////////////////////////////////////////////

template <class T>
PersistentSkipList<T>::PersistentSkipList(int nodeSize)
  : node_size(nodeSize), present(0), head(), tail(), data_set()
{
  SmartPointer<ListNode<T> > negInf(new ListNode<T>(1,false));
  SmartPointer<ListNode<T> > posInf(new ListNode<T>(1,true));
  head.insert( pair<int,SmartPointer<ListNode<T> > >(0,negInf) );
  tail.insert( pair<int,SmartPointer<ListNode<T> > >(0,posInf) );
  // set next on negInf to posInf
  TSA* newNext = new TSA(0,1);
  newNext->setElement(0,posInf);
  negInf->addNext(newNext);
}

template <class T>
PersistentSkipList<T>::~PersistentSkipList() {
}

template <class T>
int PersistentSkipList<T>::getPresent() const {
  assert(this != NULL);
  return present;
}

template <class T>
PersistentSkipList<T>& PersistentSkipList<T>::operator++() {
  incTime();
  return this;
}

template <class T>
void PersistentSkipList<T>::incTime() {
  assert(this != NULL);
  ++present;
}

template <class T>
void PersistentSkipList<T>::drawPresent() {
  assert(this != NULL);
  draw(getPresent());
}

template <class T>
void PersistentSkipList<T>::draw(int t) {
  assert(this != NULL);
  assert(t >= 0);
  cout << "Drawing skip list at time " << t << "..." << endl;
  if(empty(t)) {
    cout << "NULL" << endl;
    return;
  }
  for(int i = 0; i < getHeight(t); ++i) {
    PSLIterator<T> next = begin(t,i);

    cout << "Height: " << i+1 << endl;

    while(next != end(t)) {
      cout << "Node(data=" << *next
	   << ",height=" << next.getHeight() << ")" << endl;
      ++next;
    }
  }
}

template <class T>
int PersistentSkipList<T>::addHead(SmartPointer<ListNode<T> > new_head) {
  assert(this != NULL);
  assert(new_head != NULL);
  // delete old head if exists
  if(head.count(present) > 0)
    head.erase(present); // shouldn't leak using smart pointer
  // save the new head
  head.insert( pair< int, SmartPointer<ListNode<T> > >(present,new_head) );
  // success
  return 0;
}

template <class T>
SmartPointer<ListNode<T> >& PersistentSkipList<T>::getHead(int t) {
  // reverse linear search from starting time
  while(head.count(t) == 0)
    --t;
  return head[t];
}

template <class T>
int PersistentSkipList<T>::addTail(SmartPointer<ListNode<T> > new_tail) {
  assert(this != NULL);
  assert(new_tail != NULL);
  // delete old head if exists
  if(tail.count(present) > 0)
    tail.erase(present); // shouldn't leak using smart pointer
  // save the new head
  tail.insert( pair< int, SmartPointer<ListNode<T> > >(present,new_tail) );
  // success
  return 0;
}

template <class T>
SmartPointer<ListNode<T> >& PersistentSkipList<T>::getTail(int t) {
  // reverse linear search from starting time
  while(tail.count(t) == 0)
    --t;
  return tail[t];
}

template <class T>
void PersistentSkipList<T>::buildHeadAndTail(int new_height) {
  assert(new_height > getHeight(getPresent()));
  int present = getPresent();
  SmartPointer<ListNode<T> > old_head = getHead(present);
  SmartPointer<ListNode<T> > old_tail = getTail(present);
  int old_height = old_head->getHeight();
  assert(new_height > old_height);
  assert(old_height == old_tail->getHeight());
  SmartPointer<ListNode<T> > new_head(new ListNode<T>(new_height,false));
  SmartPointer<ListNode<T> > new_tail(new ListNode<T>(new_height,true));
  assert(new_head->getHeight() == new_tail->getHeight());
  TSA* new_next = new TSA(present,new_height);
  // make the tail the new next above the old height
  while(--new_height >= old_height) {
    new_next->setElement(new_height,new_tail);
  }
  while(new_height >= 0) {
    SmartPointer<ListNode<T> > next_node =
      old_head->getNext(present)->getElement(new_height);
    if(next_node == old_tail)
      new_next->setElement(new_height,new_tail);
    else
      new_next->setElement(new_height,next_node);
    --new_height;
  }
  new_head->addNext(new_next);
  addHead(new_head);
  // make all the nodes which pointed to the old tail point to the new tail
  --old_height;
  while(old_height >= 0) {
    int end = old_height;
    while(end > 0 &&
	  old_tail->getIncoming(end-1) == old_tail->getIncoming(old_height))
      --end;
    ListNode<T>* toChange = old_tail->getIncoming(old_height);
    if(old_head == toChange) {
      old_height = end-1;
      continue;
    }
    new_next = new TSA(present,
		       toChange->getHeight(),
		       *(toChange->getNext(present)));
    while(old_height >= end) {
      new_next->setElement(old_height,new_tail);
      new_tail->setIncoming(old_height,toChange);
      --old_height;
    }
    toChange->addNext(new_next);
  }
  addTail(new_tail);
}

template < class T >
PSLIterator<T> PersistentSkipList<T>::begin(int t, int h) {
  return ++(PSLIterator<T>(getHead(t),t,h));
}

template < class T >
PSLIterator<T> PersistentSkipList<T>::end(int t) {
  return PSLIterator<T>(getTail(t),t);
}

template < class T >
PSLIterator<T> PersistentSkipList<T>::find(const T& toFind, int t) {
  PSLIterator<T> iter = PSLIterator<T>(getHead(t),t,getHeight(t)-1);
  PSLIterator<T> next = iter.getNext();
  const PSLIterator<T> end = this->end(t);
  while( iter.getSearchHeight() >= 0 || next != end ) {
    // loop invariant: we have already determined the value of iter
    //                 precedes the data for which we are searching.
    if(next <= toFind && next != end) {
      assert(iter.getSearchHeight() < next.getHeight());
      iter.next();
    } else if(next > toFind && iter.getSearchHeight() > 0) {
      iter.down();
    } else {
      return iter;
    }
    next = iter.getNext();
  }
  return iter;
}

template < class T >
int PersistentSkipList<T>::getHeight(int t) {
  return (getHead(t))->getHeight();
}

template < class T >
bool PersistentSkipList<T>::empty(void) {
  return empty(getPresent());
}

template < class T >
bool PersistentSkipList<T>::empty(int t) {
  return begin(t) == end(t);
}

/////////////////////////////////////////////////////////////////////////////
// INSERT METHOD                                                           //
/////////////////////////////////////////////////////////////////////////////

template <class T>
const PersistentSkipList<T>& PersistentSkipList<T>::operator+=(const T& data) {
  if(insert(data) != 0) // error
    throw "Unable to insert data!";
  return this;
}

template <class T>
int PersistentSkipList<T>::insert(const T& data) {
  assert(this != NULL);
  // check if data exists already
  if(data_set.count(data)>0)
    return 1;
  int present = getPresent();
  // otherwise, create node
  SmartPointer<ListNode<T> > new_ln(new ListNode<T>(data));
  int height = new_ln->getHeight();
  // add node to list
  int start = height-1;
  // Taller than old head
  if(height > getHeight(getPresent()))
    buildHeadAndTail(height);
  // Add new node to list
  SmartPointer<ListNode<T> > old_ln = getHead(present);
  TSA* new_node_next = new TSA(present,height);
  while(start >= 0) {
    SmartPointer<ListNode<T> > next_ln =
      old_ln->getNext(present)->getElement(start);
    // find the elements between which we should insert the new node
    while(*new_ln > *next_ln) {
      old_ln = next_ln;
      next_ln = old_ln->getNext(present)->getElement(start);
    }
    TSA* old_ln_next = new TSA(present,
			       old_ln->getHeight(),
			       *(old_ln->getNext(present)));
    while(*new_ln < *next_ln) {
      new_node_next->setElement(start,next_ln);
      // point the old node to the new node
      old_ln_next->setElement(start,new_ln);
      // move to the next height
      --start;
      if(start < 0)
	break;
      next_ln = old_ln_next->getElement(start);
    }
    old_ln->addNext(old_ln_next);
    // move to next search height
    if(start < 0)
      break;
    // get node at new height
    old_ln = next_ln;
  }
  new_ln->addNext(new_node_next);
  // prevent duplicates by registering this datum
  data_set.insert(data);
  // success
  return 0;
}

#endif
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "SettingsUI.h"
#include "Display.h"
#include "afxdialogex.h"

IMPLEMENT_DYNAMIC(Display, CPropertyPage)

Display::Display() :
CPropertyPage(Display::IDD) {
}

Display::~Display() {

}

void Display::DoDataExchange(CDataExchange* pDX) {
    CPropertyPage::DoDataExchange(pDX);
    DDX_Control(pDX, CHK_ONTOP, _onTop);
    DDX_Control(pDX, SP_DELAY, _spinDelay);
    DDX_Control(pDX, SP_SPEED, _spinSpeed);
    DDX_Control(pDX, CHK_FULLSCREEN, _fullscreen);
    DDX_Control(pDX, CMB_POSITION, _position);
    DDX_Control(pDX, LBL_CUSTOMX, _lbX);
    DDX_Control(pDX, LBL_CUSTOMY, _lbY);
    DDX_Control(pDX, ED_CUSTOMX, _customX);
    DDX_Control(pDX, ED_CUSTOMY, _customY);
}

BOOL Display::OnApply() {
    return CPropertyPage::OnApply();
}

BOOL Display::OnCommand(WPARAM wParam, LPARAM lParam) {
    SetModified();
    return CPropertyPage::OnCommand(wParam, lParam);
}

BOOL Display::OnInitDialog() {
    CPropertyPage::OnInitDialog();
    return TRUE;
}

BEGIN_MESSAGE_MAP(Display, CPropertyPage)
END_MESSAGE_MAP()void Display::OnCbnSelchangePosition() {
void Display::OnDeltaposDelay(NMHDR *pNMHDR, LRESULT *pResult) {
    LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
    pNMUpDown->iDelta *= 100;
    *pResult = 0;
}

void Display::OnDeltaposSpeed(NMHDR *pNMHDR, LRESULT *pResult) {
    LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
    pNMUpDown->iDelta *= 100;
    *pResult = 0;
}
    int selIdx = _position.GetCurSel();
    CString selected;
    _position.GetLBText(selIdx, selected);
    BOOL isCustom = (selected == L"Custom");
    _lbX.EnableWindow(isCustom);
    _lbY.EnableWindow(isCustom);
    _customX.EnableWindow(isCustom);
    _customY.EnableWindow(isCustom);
}
<commit_msg>Initialize controls<commit_after>#include "stdafx.h"
#include "SettingsUI.h"
#include "Display.h"
#include "afxdialogex.h"

IMPLEMENT_DYNAMIC(Display, CPropertyPage)

Display::Display() :
CPropertyPage(Display::IDD) {
}

Display::~Display() {

}

void Display::DoDataExchange(CDataExchange* pDX) {
    CPropertyPage::DoDataExchange(pDX);
    DDX_Control(pDX, CHK_ONTOP, _onTop);
    DDX_Control(pDX, SP_DELAY, _spinDelay);
    DDX_Control(pDX, SP_SPEED, _spinSpeed);
    DDX_Control(pDX, CHK_FULLSCREEN, _fullscreen);
    DDX_Control(pDX, CMB_POSITION, _position);
    DDX_Control(pDX, LBL_CUSTOMX, _lbX);
    DDX_Control(pDX, LBL_CUSTOMY, _lbY);
    DDX_Control(pDX, ED_CUSTOMX, _customX);
    DDX_Control(pDX, ED_CUSTOMY, _customY);
}

BOOL Display::OnApply() {
    return CPropertyPage::OnApply();
}

BOOL Display::OnCommand(WPARAM wParam, LPARAM lParam) {
    SetModified();
    return CPropertyPage::OnCommand(wParam, lParam);
}

BOOL Display::OnInitDialog() {
    CPropertyPage::OnInitDialog();

    _position.AddString(L"Top");
    _position.AddString(L"Left");
    _position.AddString(L"Right");
    _position.AddString(L"Bottom");
    _position.AddString(L"Center");
    _position.AddString(L"Custom");

    _spinDelay.SetRange32(MIN_MS, MAX_MS);
    _spinSpeed.SetRange32(MIN_MS, MAX_MS);
    return TRUE;
}

BEGIN_MESSAGE_MAP(Display, CPropertyPage)
END_MESSAGE_MAP()void Display::OnCbnSelchangePosition() {
void Display::OnDeltaposDelay(NMHDR *pNMHDR, LRESULT *pResult) {
    LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
    pNMUpDown->iDelta *= 100;
    *pResult = 0;
}

void Display::OnDeltaposSpeed(NMHDR *pNMHDR, LRESULT *pResult) {
    LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
    pNMUpDown->iDelta *= 100;
    *pResult = 0;
}
    int selIdx = _position.GetCurSel();
    CString selected;
    _position.GetLBText(selIdx, selected);
    BOOL isCustom = (selected == L"Custom");
    _lbX.EnableWindow(isCustom);
    _lbY.EnableWindow(isCustom);
    _customX.EnableWindow(isCustom);
    _customY.EnableWindow(isCustom);
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMemory.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/MemoryManager.hpp>
#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN

void* XMemory::operator new(size_t size)
{
	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));

    void* const block = XMLPlatformUtils::fgMemoryManager->allocate
        (
	        headerSize + size
        );
    *(MemoryManager**)block = XMLPlatformUtils::fgMemoryManager;

    return (char*)block + headerSize;
}

#if defined(XML_VISUALCPP)

void* XMemory::operator new(size_t size, const char* file, int line)
{
		 return operator new(size);
}

void XMemory::operator delete(void* p, const char* file, int line)
{
		 operator delete(p);
}

#endif

void* XMemory::operator new(size_t size, MemoryManager* manager)
{
    assert(manager != 0);

	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));
    void* const block = manager->allocate(headerSize + size);
    *(MemoryManager**)block = manager;

    return (char*)block + headerSize;
}

void XMemory::operator delete(void* p)
{
    if (p != 0)
    {
		size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
											sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;

        MemoryManager* const manager = *(MemoryManager**)block;
        assert(manager != 0);
        manager->deallocate(block);
    }
}

//The HP compiler is complaining about duplicate overloading of delete
#if !defined(XML_HPUX) && !defined(XML_BORLAND)

void XMemory::operator delete(void* p, MemoryManager* manager)
{
    assert(manager != 0);

    if (p != 0)
    {
        size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;
        assert(*(MemoryManager**)block == manager);
        /***
         * NOTE: for compiler which can't properly trace the memory manager used in the
         *       placement new, we use the memory manager embedded in the memory rather
         *       than the one passed in
         */
        MemoryManager* pM = *(MemoryManager**)block;
        pM->deallocate(block);
    }
}

#endif

XERCES_CPP_NAMESPACE_END

<commit_msg>do not assert memorymanager in placement delete.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMemory.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/MemoryManager.hpp>
#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN

void* XMemory::operator new(size_t size)
{
	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));

    void* const block = XMLPlatformUtils::fgMemoryManager->allocate
        (
	        headerSize + size
        );
    *(MemoryManager**)block = XMLPlatformUtils::fgMemoryManager;

    return (char*)block + headerSize;
}

#if defined(XML_VISUALCPP)

void* XMemory::operator new(size_t size, const char* file, int line)
{
		 return operator new(size);
}

void XMemory::operator delete(void* p, const char* file, int line)
{
		 operator delete(p);
}

#endif

void* XMemory::operator new(size_t size, MemoryManager* manager)
{
    assert(manager != 0);

	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));
    void* const block = manager->allocate(headerSize + size);
    *(MemoryManager**)block = manager;

    return (char*)block + headerSize;
}

void XMemory::operator delete(void* p)
{
    if (p != 0)
    {
		size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
											sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;

        MemoryManager* const manager = *(MemoryManager**)block;
        assert(manager != 0);
        manager->deallocate(block);
    }
}

//The HP compiler is complaining about duplicate overloading of delete
#if !defined(XML_HPUX) && !defined(XML_BORLAND)

void XMemory::operator delete(void* p, MemoryManager* manager)
{
    assert(manager != 0);

    if (p != 0)
    {
        size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;

        /***
         * assert(*(MemoryManager**)block == manager);
         *
         * NOTE: for compiler which can't properly trace the memory manager used in the
         *       placement new, we use the memory manager embedded in the memory rather
         *       than the one passed in
         */
        MemoryManager* pM = *(MemoryManager**)block;
        pM->deallocate(block);
    }
}

#endif

XERCES_CPP_NAMESPACE_END

<|endoftext|>