<commit_before>
#include <Python.h>

#include "module_lock.h"

#include "classad/classad.h"

using namespace condor;

#if !defined(WIN32)
pthread_mutex_t ModuleLock::m_mutex = PTHREAD_MUTEX_INITIALIZER;

ModuleLock::ModuleLock()
    : m_release_gil(!classad::ClassAdGetExpressionCaching()),
      m_owned(false), m_save(0)
{
    acquire();
}

void
ModuleLock::acquire()
{
    if (m_release_gil && !m_owned)
    {
        m_save = PyEval_SaveThread();
        pthread_mutex_lock(&m_mutex);
        m_owned = true;
    }
}

ModuleLock::~ModuleLock()
{
    release();
}

void
ModuleLock::release()
{
    if (m_release_gil && m_owned)
    {
        pthread_mutex_unlock(&m_mutex);
        PyEval_RestoreThread(m_save);
    }
}
#else
ModuleLock::ModuleLock()
{
    acquire();
}

void
ModuleLock::acquire()
{

}

ModuleLock::~ModuleLock()
{
    release();
}

void
ModuleLock::release()
{
}
#endif
<commit_msg>Reset lock ownership on release. #5000<commit_after>
#include <Python.h>

#include "module_lock.h"

#include "classad/classad.h"

using namespace condor;

#if !defined(WIN32)
pthread_mutex_t ModuleLock::m_mutex = PTHREAD_MUTEX_INITIALIZER;

ModuleLock::ModuleLock()
    : m_release_gil(!classad::ClassAdGetExpressionCaching()),
      m_owned(false), m_save(0)
{
    acquire();
}

void
ModuleLock::acquire()
{
    if (m_release_gil && !m_owned)
    {
        m_save = PyEval_SaveThread();
        pthread_mutex_lock(&m_mutex);
        m_owned = true;
    }
}

ModuleLock::~ModuleLock()
{
    release();
}

void
ModuleLock::release()
{
    if (m_release_gil && m_owned)
    {
        pthread_mutex_unlock(&m_mutex);
        PyEval_RestoreThread(m_save);
        m_owned = false;
    }
}
#else
ModuleLock::ModuleLock()
{
    acquire();
}

void
ModuleLock::acquire()
{

}

ModuleLock::~ModuleLock()
{
    release();
}

void
ModuleLock::release()
{
}
#endif
<|endoftext|>


<commit_before>#include "offerwhitelisttablemodel.h"

#include "guiutil.h"
#include "walletmodel.h"

#include "wallet/wallet.h"
#include "base58.h"

#include <QFont>
using namespace std;

struct OfferWhitelistTableEntry
{

    QString alias;
	QString expires;
	QString discount;

    OfferWhitelistTableEntry() {}
    OfferWhitelistTableEntry(const QString &alias, const QString &expires,const QString &discount):
        alias(alias), expires(expires),discount(discount) {}
};

struct OfferWhitelistTableEntryLessThan
{
    bool operator()(const OfferWhitelistTableEntry &a, const OfferWhitelistTableEntry &b) const
    {
        return a.alias < b.alias;
    }
    bool operator()(const OfferWhitelistTableEntry &a, const QString &b) const
    {
        return a.alias < b;
    }
    bool operator()(const QString &a, const OfferWhitelistTableEntry &b) const
    {
        return a < b.alias;
    }
};

// Private implementation
class OfferWhitelistTablePriv
{
public:
    QList<OfferWhitelistTableEntry> cachedEntryTable;
    OfferWhitelistTableModel *parent;

    OfferWhitelistTablePriv(OfferWhitelistTableModel *parent):
        parent(parent) {}

    void updateEntry(const QString &alias, const QString &expires,const QString &discount, int status)
    {
		if(!parent)
		{
			return;
		}
        // Find offer / value in model
        QList<OfferWhitelistTableEntry>::iterator lower = qLowerBound(
            cachedEntryTable.begin(), cachedEntryTable.end(), alias, OfferWhitelistTableEntryLessThan());
        QList<OfferWhitelistTableEntry>::iterator upper = qUpperBound(
            cachedEntryTable.begin(), cachedEntryTable.end(), alias, OfferWhitelistTableEntryLessThan());
        int lowerIndex = (lower - cachedEntryTable.begin());
        int upperIndex = (upper - cachedEntryTable.begin());
        bool inModel = (lower != upper);

        switch(status)
        {
        case CT_NEW:
            if(inModel)
            {
                break;
            }
            parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
            cachedEntryTable.insert(lowerIndex, OfferWhitelistTableEntry(alias, expires, discount));
            parent->endInsertRows();
            break;
        case CT_UPDATED:
            if(!inModel)
            {
                break;
            }
			lower->alias = alias;
			lower->expires = expires;
			lower->discount = discount;
            parent->emitDataChanged(lowerIndex);
            break;
        case CT_DELETED:
            if(!inModel)
            {
                break;
            }
            parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
            cachedEntryTable.erase(lower, upper);
            parent->endRemoveRows();
            break;
        }
    }

    int size()
    {
        return cachedEntryTable.size();
    }

    OfferWhitelistTableEntry *index(int idx)
    {
        if(idx >= 0 && idx < cachedEntryTable.size())
        {
            return &cachedEntryTable[idx];
        }
        else
        {
            return 0;
        }
    }
};

OfferWhitelistTableModel::OfferWhitelistTableModel(WalletModel *parent) :
    QAbstractTableModel(parent)
{
    columns << tr("Alias") << << tr("Discount") << tr("Expires In");
    priv = new OfferWhitelistTablePriv(this);

}

OfferWhitelistTableModel::~OfferWhitelistTableModel()
{
    delete priv;
}
int OfferWhitelistTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return priv->size();
}

int OfferWhitelistTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return columns.length();
}

QVariant OfferWhitelistTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();

    OfferWhitelistTableEntry *rec = static_cast<OfferWhitelistTableEntry*>(index.internalPointer());

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        switch(index.column())
        {
        case Alias:
            return rec->alias;
        case Discount:
            return rec->discount;
        case Expires:
            return rec->expires;
        }
    }
    else if (role == AliasRole)
    {
        return rec->alias;
    }
    return QVariant();
}

bool OfferWhitelistTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;
    OfferWhitelistTableEntry *rec = static_cast<OfferWhitelistTableEntry*>(index.internalPointer());

    editStatus = OK;

    if(role == Qt::EditRole)
    {
        switch(index.column())
        {
        case Alias:
            // Do nothing, if old value == new value
            if(rec->alias == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }
             // Check for duplicates
            else if(lookupEntry(rec->alias) != -1)
            {
                editStatus = DUPLICATE_ENTRY;
                return false;
            }
            break;
        case Discount:
            // Do nothing, if old value == new value
            if(rec->discount == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }

            break;
       case Expires:
            // Do nothing, if old value == new value
            if(rec->expires == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }
            break;
        return true;
    }
    return false;
}

QVariant OfferWhitelistTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole)
        {
            return columns[section];
        }
    }
    return QVariant();
}

Qt::ItemFlags OfferWhitelistTableModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return 0;
    Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    return retval;
}

QModelIndex OfferWhitelistTableModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    OfferWhitelistTableEntry *data = priv->index(row);
    if(data)
    {
        return createIndex(row, column, priv->index(row));
    }
    else
    {
        return QModelIndex();
    }
}

void OfferWhitelistTableModel::updateEntry(const QString &alias, const QString &expires,const QString &discount, int status)
{
    priv->updateEntry(alias, expires, discount, status);
}

QString OfferWhitelistTableModel::addRow(const QString &alias, const QString &expires,const QString &discount)
{
    std::string strAlias = alias.toStdString();
    editStatus = OK;
    // Check for duplicate
    {
        if(lookupEntry(alias) != -1)
        {
            editStatus = DUPLICATE_ENTRY;
            return QString();
        }
    }

    // Add entry

    return QString::fromStdString(strAlias);
}
void OfferWhitelistTableModel::clear()
{
	beginResetModel();
    priv->cachedEntryTable.clear();
	endResetModel();
}

int OfferWhitelistTableModel::lookupEntry(const QString &alias) const
{
    QModelIndexList lst = match(index(0, Alias, QModelIndex()),
                                Qt::EditRole, alias, 1, Qt::MatchExactly);
    if(lst.isEmpty())
    {
        return -1;
    }
    else
    {
        return lst.at(0).row();
    }
}

void OfferWhitelistTableModel::emitDataChanged(int idx)
{
    Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
}
<commit_msg>typo<commit_after>#include "offerwhitelisttablemodel.h"

#include "guiutil.h"
#include "walletmodel.h"

#include "wallet/wallet.h"
#include "base58.h"

#include <QFont>
using namespace std;

struct OfferWhitelistTableEntry
{

    QString alias;
	QString expires;
	QString discount;

    OfferWhitelistTableEntry() {}
    OfferWhitelistTableEntry(const QString &alias, const QString &expires,const QString &discount):
        alias(alias), expires(expires),discount(discount) {}
};

struct OfferWhitelistTableEntryLessThan
{
    bool operator()(const OfferWhitelistTableEntry &a, const OfferWhitelistTableEntry &b) const
    {
        return a.alias < b.alias;
    }
    bool operator()(const OfferWhitelistTableEntry &a, const QString &b) const
    {
        return a.alias < b;
    }
    bool operator()(const QString &a, const OfferWhitelistTableEntry &b) const
    {
        return a < b.alias;
    }
};

// Private implementation
class OfferWhitelistTablePriv
{
public:
    QList<OfferWhitelistTableEntry> cachedEntryTable;
    OfferWhitelistTableModel *parent;

    OfferWhitelistTablePriv(OfferWhitelistTableModel *parent):
        parent(parent) {}

    void updateEntry(const QString &alias, const QString &expires,const QString &discount, int status)
    {
		if(!parent)
		{
			return;
		}
        // Find offer / value in model
        QList<OfferWhitelistTableEntry>::iterator lower = qLowerBound(
            cachedEntryTable.begin(), cachedEntryTable.end(), alias, OfferWhitelistTableEntryLessThan());
        QList<OfferWhitelistTableEntry>::iterator upper = qUpperBound(
            cachedEntryTable.begin(), cachedEntryTable.end(), alias, OfferWhitelistTableEntryLessThan());
        int lowerIndex = (lower - cachedEntryTable.begin());
        int upperIndex = (upper - cachedEntryTable.begin());
        bool inModel = (lower != upper);

        switch(status)
        {
        case CT_NEW:
            if(inModel)
            {
                break;
            }
            parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
            cachedEntryTable.insert(lowerIndex, OfferWhitelistTableEntry(alias, expires, discount));
            parent->endInsertRows();
            break;
        case CT_UPDATED:
            if(!inModel)
            {
                break;
            }
			lower->alias = alias;
			lower->expires = expires;
			lower->discount = discount;
            parent->emitDataChanged(lowerIndex);
            break;
        case CT_DELETED:
            if(!inModel)
            {
                break;
            }
            parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
            cachedEntryTable.erase(lower, upper);
            parent->endRemoveRows();
            break;
        }
    }

    int size()
    {
        return cachedEntryTable.size();
    }

    OfferWhitelistTableEntry *index(int idx)
    {
        if(idx >= 0 && idx < cachedEntryTable.size())
        {
            return &cachedEntryTable[idx];
        }
        else
        {
            return 0;
        }
    }
};

OfferWhitelistTableModel::OfferWhitelistTableModel(WalletModel *parent) :
    QAbstractTableModel(parent)
{
    columns << tr("Alias") << tr("Discount") << tr("Expires In");
    priv = new OfferWhitelistTablePriv(this);

}

OfferWhitelistTableModel::~OfferWhitelistTableModel()
{
    delete priv;
}
int OfferWhitelistTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return priv->size();
}

int OfferWhitelistTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return columns.length();
}

QVariant OfferWhitelistTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();

    OfferWhitelistTableEntry *rec = static_cast<OfferWhitelistTableEntry*>(index.internalPointer());

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        switch(index.column())
        {
        case Alias:
            return rec->alias;
        case Discount:
            return rec->discount;
        case Expires:
            return rec->expires;
        }
    }
    else if (role == AliasRole)
    {
        return rec->alias;
    }
    return QVariant();
}

bool OfferWhitelistTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;
    OfferWhitelistTableEntry *rec = static_cast<OfferWhitelistTableEntry*>(index.internalPointer());

    editStatus = OK;

    if(role == Qt::EditRole)
    {
        switch(index.column())
        {
        case Alias:
            // Do nothing, if old value == new value
            if(rec->alias == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }
             // Check for duplicates
            else if(lookupEntry(rec->alias) != -1)
            {
                editStatus = DUPLICATE_ENTRY;
                return false;
            }
            break;
        case Discount:
            // Do nothing, if old value == new value
            if(rec->discount == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }

            break;
       case Expires:
            // Do nothing, if old value == new value
            if(rec->expires == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }
            break;
        return true;
		}
    }
    return false;
}

QVariant OfferWhitelistTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole)
        {
            return columns[section];
        }
    }
    return QVariant();
}

Qt::ItemFlags OfferWhitelistTableModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return 0;
    Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    return retval;
}

QModelIndex OfferWhitelistTableModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    OfferWhitelistTableEntry *data = priv->index(row);
    if(data)
    {
        return createIndex(row, column, priv->index(row));
    }
    else
    {
        return QModelIndex();
    }
}

void OfferWhitelistTableModel::updateEntry(const QString &alias, const QString &expires,const QString &discount, int status)
{
    priv->updateEntry(alias, expires, discount, status);
}

QString OfferWhitelistTableModel::addRow(const QString &alias, const QString &expires,const QString &discount)
{
    std::string strAlias = alias.toStdString();
    editStatus = OK;
    // Check for duplicate
    {
        if(lookupEntry(alias) != -1)
        {
            editStatus = DUPLICATE_ENTRY;
            return QString();
        }
    }

    // Add entry

    return QString::fromStdString(strAlias);
}
void OfferWhitelistTableModel::clear()
{
	beginResetModel();
    priv->cachedEntryTable.clear();
	endResetModel();
}

int OfferWhitelistTableModel::lookupEntry(const QString &alias) const
{
    QModelIndexList lst = match(index(0, Alias, QModelIndex()),
                                Qt::EditRole, alias, 1, Qt::MatchExactly);
    if(lst.isEmpty())
    {
        return -1;
    }
    else
    {
        return lst.at(0).row();
    }
}

void OfferWhitelistTableModel::emitDataChanged(int idx)
{
    Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
}
<|endoftext|>


<commit_before><commit_msg>Fixed converseion from double to float.<commit_after><|endoftext|>


<commit_before>/* pilotAddress.cc			KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
**
** This is a C++ wrapper for the pilot's address database structures.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
** MA 02139, USA.
*/

/*
** Bug reports and questions can be sent to adridg@cs.kun.nl
*/

static const char *pilotadress_id="$Id$";

#include "options.h"

#include <stdlib.h>
#include <assert.h>

#ifndef _KPILOT_PILOTADDRESS_H
#include "pilotAddress.h"
#endif

const int PilotAddress::APP_BUFFER_SIZE = 0xffff;

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo,
			   PilotRecord* rec)
      : PilotAppCategory(rec), fAppInfo(appInfo), fAddressInfo()
    {
    unpack_Address(&fAddressInfo, (unsigned char*)rec->getData(), rec->getLen());
    (void)pilotadress_id;
    }

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo) :
      PilotAppCategory(), fAppInfo(appInfo)
    {
    reset();
    }

PilotAddress::PilotAddress(const PilotAddress &copyFrom) :
      PilotAppCategory(copyFrom), fAppInfo(copyFrom.fAppInfo),
      fAddressInfo()
    {
    _copyAddressInfo(copyFrom.fAddressInfo);
    }

PilotAddress& PilotAddress::operator=( const PilotAddress &copyFrom )
    {
    PilotAppCategory::operator=(copyFrom);
    _copyAddressInfo(copyFrom.fAddressInfo);
    return *this;
    }

void PilotAddress::_copyAddressInfo(const struct Address &copyFrom)
    {
    fAddressInfo.showPhone = copyFrom.showPhone;
    for (int labelLp=0;labelLp < 5;labelLp++)
	fAddressInfo.phoneLabel[labelLp] =
	    copyFrom.phoneLabel[labelLp];
    for (int entryLp=0;entryLp < 19;entryLp++)
	{
	if (copyFrom.entry[entryLp])
	    fAddressInfo.entry[entryLp] =
		qstrdup(copyFrom.entry[entryLp]);
	else
	    fAddressInfo.entry[entryLp] = 0L;
	}
    return;
    }

PilotAddress::~PilotAddress()
    {
    free_Address(&fAddressInfo);
    }

QString PilotAddress::_typeToStr(EPhoneType type) const
    {
    QString s;
    switch(type)
	{
	case eWork : s = "Work"; break;
	case eHome : s = "Home"; break;
	case eFax : s = "Fax"; break;
	case eOther : s = "Other"; break;
	case ePager : s = "Pager"; break;
	case eMobile : s = "Mobile"; break;
	case eEmail : s = "E-mail"; break;
	case eMain :
	default : s = "Main"; break;
	}
    return s;
    }

bool PilotAddress::setCategory(const char *label)
    {
    for (int catId=0;catId < 16;catId++)
	{
	QString aCat = fAppInfo.category.name[catId];
	if (label == aCat)
	    {
	    setCat(catId);
	    return true;
	    }
	else
	    // if empty, then no more labels; add it
	    if (aCat.isEmpty())
		{
		qstrncpy(fAppInfo.category.name[catId], label, 16);
		setCat(catId);
		return true;
		}
	}
    // if got here, the category slots were full
    return false;
    }

int PilotAddress::_getNextEmptyPhoneSlot() const
    {
    for (int phoneSlot = entryPhone1;phoneSlot <= entryPhone5;phoneSlot++)
	{
	QString phoneField = getField(phoneSlot);
	if (phoneField.isEmpty())
	    return phoneSlot;
	}
    return entryCustom4;
    }

void PilotAddress::setPhoneField(EPhoneType type, const char *field,
				 bool overflowCustom)
    {
    // first look to see if the type is already assigned to a fieldSlot
    QString fieldStr(field);
    QString typeStr(_typeToStr(type));
    int appPhoneLabelNum = _getAppPhoneLabelNum(typeStr);
    int fieldSlot = _findPhoneFieldSlot(appPhoneLabelNum);
    if (fieldSlot == -1)
	fieldSlot = _getNextEmptyPhoneSlot();

    // store the overflow phone
    if (fieldSlot == entryCustom4)
	{
	if (!fieldStr.isEmpty() && overflowCustom)
	    {
	    QString custom4Field = getField(entryCustom4);
	    custom4Field += typeStr + " " + fieldStr;
	    setField(entryCustom4, custom4Field.latin1());
	    }
	}
    else // phone field 1 - 5; straight forward storage
	{
	setField(fieldSlot, field);
	int labelIndex = fieldSlot - entryPhone1;
	fAddressInfo.phoneLabel[labelIndex] = appPhoneLabelNum;
	}
    }

int PilotAddress::_findPhoneFieldSlot(int appTypeNum) const
    {
    for (int index=0;index < 5;index++)
	if (fAddressInfo.phoneLabel[index] == appTypeNum)
	    return index+entryPhone1;
    return -1;
    }

const char *PilotAddress::getPhoneField(EPhoneType type,
					bool checkCustom4) const
    {
    // given the type, need to find which slot is associated with it
    QString typeToStr(_typeToStr(type));
    int appTypeNum = _getAppPhoneLabelNum(typeToStr);
    int fieldSlot = _findPhoneFieldSlot(appTypeNum);
    if (fieldSlot != -1)
	return getField(fieldSlot);

    // look through custom 4 for the field
    if (!checkCustom4)
	return 0L;

    // look for the phone type str
    QString customField(getField(entryCustom4));
    int foundField = customField.find(typeToStr);
    if (foundField == -1)
	return 0L;

    // parse out the next token
    int startPos = foundField+typeToStr.length()+1;
    int endPos = customField.find(' ', startPos);
    if (endPos == -1)
	endPos = customField.length();
    QString field = customField.mid(startPos, endPos);
    field = field.simplifyWhiteSpace();

    // return the token
    return field.latin1();
    }

int PilotAddress::_getAppPhoneLabelNum(const QString &phoneType) const
    {
    for (int index=0;index < 8;index++)
	if (phoneType == fAppInfo.phoneLabels[index])
	    return index;
    qDebug("PilotAddress::getAppPhoneLabelNum can't find index for phoneType = %s", phoneType.latin1());
    assert(0);
    return -1;
    }

void
PilotAddress::setField(int field, const char* text)
    {
    // This will have either been created with unpack_Address, and/or will
    // be released with free_Address, so use malloc/free here:
    if(fAddressInfo.entry[field])
	{
	free(fAddressInfo.entry[field]);
	}
    if (text)
      {
	fAddressInfo.entry[field] = (char*)malloc(strlen(text) + 1);
	strcpy(fAddressInfo.entry[field], text);
      }
    else
      fAddressInfo.entry[field] = 0L;
    }

void*
PilotAddress::pack(void *buf, int *len)
    {
    int i;
    i = pack_Address(&fAddressInfo, (unsigned char*)buf, *len);
    *len = i;
    return buf;
    }

// $Log$
// Revision 1.14  2001/04/04 21:20:32  stern
// Added support for category information and copy constructors
//
// Revision 1.13  2001/04/02 21:56:22  stern
// Fixed bugs in getPhoneField and setPhoneField methods
//
// Revision 1.12  2001/03/29 21:40:55  stern
// Added APP_BUFFER_SIZE to pilotAddress
//
// Revision 1.11  2001/03/19 23:12:39  stern
// Made changes necessary for upcoming abbrowser conduit.
//
// Mainly, I added two public methods to PilotAddress that allow for easier
// setting and getting of phone fields.
//
// I also have added some documentation throughout as I have tried to figure
// out how everything works.
//
// Revision 1.10  2001/03/09 09:46:15  adridg
// Large-scale #include cleanup
//
// Revision 1.9  2001/02/08 08:13:44  habenich
// exchanged the common identifier "id" with source unique <sourcename>_id for --enable-final build
//
// Revision 1.8  2001/02/05 20:58:48  adridg
// Fixed copyright headers for source releases. No code changed
//
<commit_msg>Fixed bug in copying an address<commit_after>/* pilotAddress.cc			KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
**
** This is a C++ wrapper for the pilot's address database structures.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
** MA 02139, USA.
*/

/*
** Bug reports and questions can be sent to adridg@cs.kun.nl
*/

static const char *pilotadress_id="$Id$";

#include "options.h"

#include <stdlib.h>
#include <assert.h>

#ifndef _KPILOT_PILOTADDRESS_H
#include "pilotAddress.h"
#endif

const int PilotAddress::APP_BUFFER_SIZE = 0xffff;

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo,
			   PilotRecord* rec)
      : PilotAppCategory(rec), fAppInfo(appInfo), fAddressInfo()
    {
    unpack_Address(&fAddressInfo, (unsigned char*)rec->getData(), rec->getLen());
    (void)pilotadress_id;
    }

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo) :
      PilotAppCategory(), fAppInfo(appInfo)
    {
    reset();
    }

PilotAddress::PilotAddress(const PilotAddress &copyFrom) :
      PilotAppCategory(copyFrom), fAppInfo(copyFrom.fAppInfo),
      fAddressInfo()
    {
    _copyAddressInfo(copyFrom.fAddressInfo);
    }

PilotAddress& PilotAddress::operator=( const PilotAddress &copyFrom )
    {
    PilotAppCategory::operator=(copyFrom);
    _copyAddressInfo(copyFrom.fAddressInfo);
    return *this;
    }

void PilotAddress::_copyAddressInfo(const struct Address &copyFrom)
    {
    fAddressInfo.showPhone = copyFrom.showPhone;
    for (int labelLp=0;labelLp < 5;labelLp++)
	fAddressInfo.phoneLabel[labelLp] =
	    copyFrom.phoneLabel[labelLp];
    for (int entryLp=0;entryLp < 19;entryLp++)
	{
	if (copyFrom.entry[entryLp])
	    fAddressInfo.entry[entryLp] =
		qstrdup(copyFrom.entry[entryLp]);
	else
	    fAddressInfo.entry[entryLp] = 0L;
	}
    }

PilotAddress::~PilotAddress()
    {
    free_Address(&fAddressInfo);
    }

QString PilotAddress::_typeToStr(EPhoneType type) const
    {
    QString s;
    switch(type)
	{
	case eWork : s = "Work"; break;
	case eHome : s = "Home"; break;
	case eFax : s = "Fax"; break;
	case eOther : s = "Other"; break;
	case ePager : s = "Pager"; break;
	case eMobile : s = "Mobile"; break;
	case eEmail : s = "E-mail"; break;
	case eMain :
	default : s = "Main"; break;
	}
    return s;
    }

bool PilotAddress::setCategory(const char *label)
    {
    for (int catId=0;catId < 16;catId++)
	{
	QString aCat = fAppInfo.category.name[catId];
	if (label == aCat)
	    {
	    setCat(catId);
	    return true;
	    }
	else
	    // if empty, then no more labels; add it
	    if (aCat.isEmpty())
		{
		qstrncpy(fAppInfo.category.name[catId], label, 16);
		setCat(catId);
		return true;
		}
	}
    // if got here, the category slots were full
    return false;
    }

int PilotAddress::_getNextEmptyPhoneSlot() const
    {
    for (int phoneSlot = entryPhone1;phoneSlot <= entryPhone5;phoneSlot++)
	{
	QString phoneField = getField(phoneSlot);
	if (phoneField.isEmpty())
	    return phoneSlot;
	}
    return entryCustom4;
    }

void PilotAddress::setPhoneField(EPhoneType type, const char *field,
				 bool overflowCustom)
    {
    // first look to see if the type is already assigned to a fieldSlot
    QString fieldStr(field);
    QString typeStr(_typeToStr(type));
    int appPhoneLabelNum = _getAppPhoneLabelNum(typeStr);
    int fieldSlot = _findPhoneFieldSlot(appPhoneLabelNum);
    if (fieldSlot == -1)
	fieldSlot = _getNextEmptyPhoneSlot();

    // store the overflow phone
    if (fieldSlot == entryCustom4)
	{
	if (!fieldStr.isEmpty() && overflowCustom)
	    {
	    QString custom4Field = getField(entryCustom4);
	    custom4Field += typeStr + " " + fieldStr;
	    setField(entryCustom4, custom4Field.latin1());
	    }
	}
    else // phone field 1 - 5; straight forward storage
	{
	setField(fieldSlot, field);
	int labelIndex = fieldSlot - entryPhone1;
	fAddressInfo.phoneLabel[labelIndex] = appPhoneLabelNum;
	}
    }

int PilotAddress::_findPhoneFieldSlot(int appTypeNum) const
    {
    for (int index=0;index < 5;index++)
	if (fAddressInfo.phoneLabel[index] == appTypeNum)
	    return index+entryPhone1;
    return -1;
    }

const char *PilotAddress::getPhoneField(EPhoneType type,
					bool checkCustom4) const
    {
    // given the type, need to find which slot is associated with it
    QString typeToStr(_typeToStr(type));
    int appTypeNum = _getAppPhoneLabelNum(typeToStr);
    int fieldSlot = _findPhoneFieldSlot(appTypeNum);
    if (fieldSlot != -1)
	return getField(fieldSlot);

    // look through custom 4 for the field
    if (!checkCustom4)
	return 0L;

    // look for the phone type str
    QString customField(getField(entryCustom4));
    int foundField = customField.find(typeToStr);
    if (foundField == -1)
	return 0L;

    // parse out the next token
    int startPos = foundField+typeToStr.length()+1;
    int endPos = customField.find(' ', startPos);
    if (endPos == -1)
	endPos = customField.length();
    QString field = customField.mid(startPos, endPos);
    field = field.simplifyWhiteSpace();

    // return the token
    return field.latin1();
    }

int PilotAddress::_getAppPhoneLabelNum(const QString &phoneType) const
    {
    for (int index=0;index < 8;index++)
	if (phoneType == fAppInfo.phoneLabels[index])
	    return index;
    qDebug("PilotAddress::getAppPhoneLabelNum can't find index for phoneType = %s", phoneType.latin1());
    assert(0);
    return -1;
    }

void
PilotAddress::setField(int field, const char* text)
    {
    // This will have either been created with unpack_Address, and/or will
    // be released with free_Address, so use malloc/free here:
    if(fAddressInfo.entry[field])
	{
	free(fAddressInfo.entry[field]);
	}
    if (text)
      {
	fAddressInfo.entry[field] = (char*)malloc(strlen(text) + 1);
	strcpy(fAddressInfo.entry[field], text);
      }
    else
      fAddressInfo.entry[field] = 0L;
    }

void*
PilotAddress::pack(void *buf, int *len)
    {
    int i;
    i = pack_Address(&fAddressInfo, (unsigned char*)buf, *len);
    *len = i;
    return buf;
    }

// $Log$
// Revision 1.15  2001/04/11 11:02:37  leitner
// A void function must not return anything. Also there was an uninitialize
// variable being used.
//
// Revision 1.14  2001/04/04 21:20:32  stern
// Added support for category information and copy constructors
//
// Revision 1.13  2001/04/02 21:56:22  stern
// Fixed bugs in getPhoneField and setPhoneField methods
//
// Revision 1.12  2001/03/29 21:40:55  stern
// Added APP_BUFFER_SIZE to pilotAddress
//
// Revision 1.11  2001/03/19 23:12:39  stern
// Made changes necessary for upcoming abbrowser conduit.
//
// Mainly, I added two public methods to PilotAddress that allow for easier
// setting and getting of phone fields.
//
// I also have added some documentation throughout as I have tried to figure
// out how everything works.
//
// Revision 1.10  2001/03/09 09:46:15  adridg
// Large-scale #include cleanup
//
// Revision 1.9  2001/02/08 08:13:44  habenich
// exchanged the common identifier "id" with source unique <sourcename>_id for --enable-final build
//
// Revision 1.8  2001/02/05 20:58:48  adridg
// Fixed copyright headers for source releases. No code changed
//
<|endoftext|>


<commit_before>#include "AliPHOSDA2.h"
#include "TString.h"

ClassImp(AliPHOSDA2)

//----------------------------------------------------------------
AliPHOSDA2::AliPHOSDA2(int module) : TNamed(),
 fHistoFile(0),fMod(module)

{
  // Create AliPHOSDA2 ("Bad channels finder") object.
  // module is the PHOS module number (0..4).
  // Quality histogram names: module_iX_iZ_gain.
  // Root file name: PHOS_ModuleX_BCM.root, where X - module number.

  char name[128];
  sprintf(name,"PHOS_Module%d_BCM",fMod);
  SetName(name);

  SetTitle("Detector Algorithm to check for PHOS channels quality");

  char rootname[128];
  sprintf(rootname,"%s.root",GetName());

  fHistoFile =  new TFile(rootname,"recreate"); // new file!

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {
      for(Int_t iGain=0; iGain<2; iGain++) {
	fHQuality[iX][iZ][iGain] = 0;
      }
    }
  }

  fMaps[0]=0;
  fMaps[1]=0;

}

//-------------------------------------------------------------------
AliPHOSDA2::AliPHOSDA2(const AliPHOSDA2& da) : TNamed(da),
  fHistoFile(0),fMod(da.fMod)
{
  // Copy constructor.

  char hname[128];
  TH1F* hist1=0;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {
      for(Int_t iGain=0; iGain<2; iGain++) {

	sprintf(hname,"%d_%d_%d_%d",fMod,iX,iZ,iGain);
	hist1 = (TH1F*)da.fHistoFile->Get(hname);
	if(hist1) fHQuality[iX][iZ][iGain] = new TH1F(*hist1);
	else
	  fHQuality[iX][iZ][iGain] = 0;
      }
    }
  }

  if(da.fMaps[0])
    fMaps[0] = new TH2F(*da.fMaps[0]);
  else
    fMaps[0] = 0;

  if(da.fMaps[1])
    fMaps[1] = new TH2F(*da.fMaps[1]);
  else
    fMaps[1] = 0;

  fHistoFile = new TFile(da.GetName(),"recreate");

}

//-------------------------------------------------------------------
AliPHOSDA2& AliPHOSDA2::operator= (const AliPHOSDA2& da)
{
  //Assignment operator.

  if(this != &da) {

    TString oldname(fHistoFile->GetName());
    TString newname(da.fHistoFile->GetName());

    if(oldname != newname) {
      delete fHistoFile;
      fHistoFile = new TFile(da.fHistoFile->GetName(),"update");
    }

    fMod = da.fMod;

    SetName(da.GetName());
    SetTitle(da.GetTitle());

    for(Int_t iX=0; iX<64; iX++) {
      for(Int_t iZ=0; iZ<56; iZ++) {
	for(Int_t iGain=0; iGain<2; iGain++) {
	  if (fHQuality[iX][iZ][iGain]) delete fHQuality[iX][iZ][iGain];
	  fHQuality[iX][iZ][iGain] = da.fHQuality[iX][iZ][iGain];
	}
      }
    }

    if(fMaps[0]) {
      delete fMaps[0];
      fMaps[0] = da.fMaps[0];
    }

    if(fMaps[1]) {
      delete fMaps[1];
      fMaps[1] = da.fMaps[1];
    }

  }

  return *this;
}

//-------------------------------------------------------------------
AliPHOSDA2::~AliPHOSDA2()
{
  // Destructor

  UpdateHistoFile();
  if(fHistoFile) delete fHistoFile;

}

//-------------------------------------------------------------------
void AliPHOSDA2::FillQualityHistograms(Float_t quality[64][56][2])
{
  // Fills quality histograms.
  // _By definition_, qood quality is 0<quality<1,
  // all outside that is a bad quality.
  // If no quality value read for particular channel,
  // the correspondent array entry should be filled by zero.
  // WARNING: this function should be called once per event!

  char hname[128];
  char htitl[128];

  for(Int_t iX=0; iX<64; iX++) {
    for (Int_t iZ=0; iZ<56; iZ++) {

      for(Int_t iGain=0; iGain<2; iGain++) {
	if(!quality[iX][iZ][iGain]) continue;

	if(fHQuality[iX][iZ][iGain])
	  fHQuality[iX][iZ][iGain]->Fill(quality[iX][iZ][iGain]);
	else {
	  sprintf(hname,"%d_%d_%d_%d",fMod,iX,iZ,iGain);
	  sprintf(htitl,"Quality for crystal %d_%d_%d and gain %d",fMod,iX,iZ,iGain);
	  fHQuality[iX][iZ][iGain] = new TH1F(hname,htitl,100,1.e-6,10.);
	  fHQuality[iX][iZ][iGain]->Fill(quality[iX][iZ][iGain]);
	}
      }

    }
  }

}

//-------------------------------------------------------------------
void AliPHOSDA2::UpdateHistoFile()
{
  // Write histograms to file

  if(!fHistoFile) return;
  if(!fHistoFile->IsOpen()) return;

  char titl[128];

  if(fMaps[0])
    fMaps[0]->Reset();
  else {
    sprintf(titl,"Quality map for Low gain");
    fMaps[0] = new TH2F("gmaplow",  titl, 64,0.,64.,56,0.,56.);
  }

  if(fMaps[1])
    fMaps[1]->Reset();
  else {
    sprintf(titl,"Quality map for High gain");
    fMaps[1] = new TH2F("gmaphigh", titl, 64,0.,64.,56,0.,56.);
  }

  TH1F* hist1=0;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {

      for(Int_t iGain=0; iGain<2; iGain++) {
	hist1 = fHQuality[iX][iZ][iGain];
	if(hist1) {
	  hist1->Write(hist1->GetName(),TObject::kWriteDelete);
	  Double_t mean = hist1->GetMean();
	  fMaps[iGain]->Fill(iX,iZ,mean);
	}
      }

    }
  }

  fMaps[0]->Write(fMaps[0]->GetName(),TObject::kWriteDelete);
  fMaps[1]->Write(fMaps[1]->GetName(),TObject::kWriteDelete);

}

<commit_msg>Wrong bin enumeration fixed.<commit_after>#include "AliPHOSDA2.h"
#include "TString.h"

ClassImp(AliPHOSDA2)

//----------------------------------------------------------------
AliPHOSDA2::AliPHOSDA2(int module) : TNamed(),
 fHistoFile(0),fMod(module)

{
  // Create AliPHOSDA2 ("Bad channels finder") object.
  // module is the PHOS module number (0..4).
  // Quality histogram names: module_iX_iZ_gain.
  // Root file name: PHOS_ModuleX_BCM.root, where X - module number.

  char name[128];
  sprintf(name,"PHOS_Module%d_BCM",fMod);
  SetName(name);

  SetTitle("Detector Algorithm to check for PHOS channels quality");

  char rootname[128];
  sprintf(rootname,"%s.root",GetName());

  fHistoFile =  new TFile(rootname,"recreate"); // new file!

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {
      for(Int_t iGain=0; iGain<2; iGain++) {
	fHQuality[iX][iZ][iGain] = 0;
      }
    }
  }

  fMaps[0]=0;
  fMaps[1]=0;

}

//-------------------------------------------------------------------
AliPHOSDA2::AliPHOSDA2(const AliPHOSDA2& da) : TNamed(da),
  fHistoFile(0),fMod(da.fMod)
{
  // Copy constructor.

  char hname[128];
  TH1F* hist1=0;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {
      for(Int_t iGain=0; iGain<2; iGain++) {

	sprintf(hname,"%d_%d_%d_%d",fMod,iX,iZ,iGain);
	hist1 = (TH1F*)da.fHistoFile->Get(hname);
	if(hist1) fHQuality[iX][iZ][iGain] = new TH1F(*hist1);
	else
	  fHQuality[iX][iZ][iGain] = 0;
      }
    }
  }

  if(da.fMaps[0])
    fMaps[0] = new TH2F(*da.fMaps[0]);
  else
    fMaps[0] = 0;

  if(da.fMaps[1])
    fMaps[1] = new TH2F(*da.fMaps[1]);
  else
    fMaps[1] = 0;

  fHistoFile = new TFile(da.GetName(),"recreate");

}

//-------------------------------------------------------------------
AliPHOSDA2& AliPHOSDA2::operator= (const AliPHOSDA2& da)
{
  //Assignment operator.

  if(this != &da) {

    TString oldname(fHistoFile->GetName());
    TString newname(da.fHistoFile->GetName());

    if(oldname != newname) {
      delete fHistoFile;
      fHistoFile = new TFile(da.fHistoFile->GetName(),"update");
    }

    fMod = da.fMod;

    SetName(da.GetName());
    SetTitle(da.GetTitle());

    for(Int_t iX=0; iX<64; iX++) {
      for(Int_t iZ=0; iZ<56; iZ++) {
	for(Int_t iGain=0; iGain<2; iGain++) {
	  if (fHQuality[iX][iZ][iGain]) delete fHQuality[iX][iZ][iGain];
	  fHQuality[iX][iZ][iGain] = da.fHQuality[iX][iZ][iGain];
	}
      }
    }

    if(fMaps[0]) {
      delete fMaps[0];
      fMaps[0] = da.fMaps[0];
    }

    if(fMaps[1]) {
      delete fMaps[1];
      fMaps[1] = da.fMaps[1];
    }

  }

  return *this;
}

//-------------------------------------------------------------------
AliPHOSDA2::~AliPHOSDA2()
{
  // Destructor

  UpdateHistoFile();
  if(fHistoFile) delete fHistoFile;

}

//-------------------------------------------------------------------
void AliPHOSDA2::FillQualityHistograms(Float_t quality[64][56][2])
{
  // Fills quality histograms.
  // _By definition_, qood quality is 0<quality<1,
  // all outside that is a bad quality.
  // If no quality value read for particular channel,
  // the correspondent array entry should be filled by zero.
  // WARNING: this function should be called once per event!

  char hname[128];
  char htitl[128];

  for(Int_t iX=0; iX<64; iX++) {
    for (Int_t iZ=0; iZ<56; iZ++) {

      for(Int_t iGain=0; iGain<2; iGain++) {
	if(!quality[iX][iZ][iGain]) continue;

	if(fHQuality[iX][iZ][iGain])
	  fHQuality[iX][iZ][iGain]->Fill(quality[iX][iZ][iGain]);
	else {
	  sprintf(hname,"%d_%d_%d_%d",fMod,iX,iZ,iGain);
	  sprintf(htitl,"Quality for crystal %d_%d_%d and gain %d",fMod,iX,iZ,iGain);
	  fHQuality[iX][iZ][iGain] = new TH1F(hname,htitl,100,1.e-6,10.);
	  fHQuality[iX][iZ][iGain]->Fill(quality[iX][iZ][iGain]);
	}
      }

    }
  }

}

//-------------------------------------------------------------------
void AliPHOSDA2::UpdateHistoFile()
{
  // Write histograms to file

  if(!fHistoFile) return;
  if(!fHistoFile->IsOpen()) return;

  char titl[128];

  if(fMaps[0])
    fMaps[0]->Reset();
  else {
    sprintf(titl,"Quality map for Low gain");
    fMaps[0] = new TH2F("gmaplow",  titl, 64,0.,64.,56,0.,56.);
  }

  if(fMaps[1])
    fMaps[1]->Reset();
  else {
    sprintf(titl,"Quality map for High gain");
    fMaps[1] = new TH2F("gmaphigh", titl, 64,0.,64.,56,0.,56.);
  }

  TH1F* hist1=0;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {

      for(Int_t iGain=0; iGain<2; iGain++) {
	hist1 = fHQuality[iX][iZ][iGain];
	if(hist1) {
	  hist1->Write(hist1->GetName(),TObject::kWriteDelete);
	  Double_t mean = hist1->GetMean();
	  fMaps[iGain]->SetBinContent(iX+1,iZ+1,mean);
	}
      }

    }
  }

  fMaps[0]->Write(fMaps[0]->GetName(),TObject::kWriteDelete);
  fMaps[1]->Write(fMaps[1]->GetName(),TObject::kWriteDelete);

}

<|endoftext|>


<commit_before>/**
 * Copyright (c) <2016> Web App SDK granada <afernandez@cookinapps.io>
 *
 * This source code is licensed under the MIT license.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 *
 * Tests for granada::util::string
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 **/
#include "stdafx.h"
#include <vector>
#include "granada/util/time.h"
#include "granada/cache/shared_map_cache_driver.h"

namespace granada { namespace test { namespace cache {

SUITE(shared_map_cache_driver)
{

	TEST(write_read)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello"),"world");

		cache_driver.Write("hello","world","!!!");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello","world"),"!!!");
	}

	TEST(exist)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");

		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_FALSE(cache_driver.Exists("none"));

		cache_driver.Write("hello","world","!!!");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_TRUE(cache_driver.Exists("hello","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("none","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("hello","none"));
	}

	TEST(match)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");
		cache_driver.Write("session:6464","token","6464");
		cache_driver.Write("session:6464","update.time","123456789");
		cache_driver.Write("session:roles:6464","ROLES_6464");
		cache_driver.Write("session:777","token","777");
		cache_driver.Write("session:777","update.time","987654321");
		cache_driver.Write("session:roles:777","ROLES_777");

		std::vector<std::string> keys;

		cache_driver.Match("",keys);
		VERIFY_IS_TRUE(keys.size()==0);

		cache_driver.Match("*",keys);
		VERIFY_IS_TRUE(keys.size()==5);

		cache_driver.Match("session:",keys);
		VERIFY_IS_TRUE(keys.size()==0);

		cache_driver.Match("session:*",keys);
		VERIFY_IS_TRUE(keys.size()==4);

		cache_driver.Match("session:*:",keys);
		VERIFY_IS_TRUE(keys.size()==0);

		cache_driver.Match("session:*:*",keys);
		VERIFY_IS_TRUE(keys.size()==2);

		cache_driver.Match("session:6464*",keys);
		VERIFY_IS_TRUE(keys.size()==1);

		cache_driver.Match("session:*6464*",keys);
		VERIFY_IS_TRUE(keys.size()==2);
	}

	TEST(destroy)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");

		VERIFY_ARE_EQUAL(cache_driver.Read("hello"),"world");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_FALSE(cache_driver.Exists("none"));
		cache_driver.Destroy("hello");
		VERIFY_ARE_NOT_EQUAL(cache_driver.Read("hello"),"world");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello"),"");
		VERIFY_IS_FALSE(cache_driver.Exists("hello"));

		cache_driver.Write("hello","world","!!!");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello","world"),"!!!");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_TRUE(cache_driver.Exists("hello","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("none","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("hello","none"));
		cache_driver.Destroy("hello","world");
		VERIFY_ARE_NOT_EQUAL(cache_driver.Read("hello","world"),"!!!");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello","world"),"");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_FALSE(cache_driver.Exists("hello","world"));

	}

	TEST(iterator)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");
		cache_driver.Write("session:6464","token","6464");
		cache_driver.Write("session:6464","update.time","123456789");
		cache_driver.Write("session:roles:6464","ROLES_6464");
		cache_driver.Write("session:777","token","777");
		cache_driver.Write("session:777","update.time","987654321");
		cache_driver.Write("session:roles:777","ROLES_777");

		std::shared_ptr<granada::cache::CacheHandlerIterator> cache_iterator = cache_driver.make_iterator("");
		VERIFY_IS_TRUE(!cache_iterator->has_next());
		for (int i = 0; i < 5; i++){
			VERIFY_IS_TRUE(cache_iterator->next()=="");
		}

		cache_iterator = cache_driver.make_iterator("*");
		int i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==5);

		cache_iterator = cache_driver.make_iterator("session:");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==0);

		cache_iterator = cache_driver.make_iterator("session:*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==4);

		cache_iterator = cache_driver.make_iterator("session:*:");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==0);

		cache_iterator = cache_driver.make_iterator("session:*:*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==2);

		cache_iterator = cache_driver.make_iterator("session:6464*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==1);

		cache_iterator = cache_driver.make_iterator("session:*6464*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==2);
	}

}

}}} //namespaces
<commit_msg>comment correction.<commit_after>/**
 * Copyright (c) <2016> Web App SDK granada <afernandez@cookinapps.io>
 *
 * This source code is licensed under the MIT license.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 *
 * Tests for granada::cache::SharedMapCacheDriver
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 **/
#include "stdafx.h"
#include <vector>
#include "granada/util/time.h"
#include "granada/cache/shared_map_cache_driver.h"

namespace granada { namespace test { namespace cache {

SUITE(shared_map_cache_driver)
{

	TEST(write_read)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello"),"world");

		cache_driver.Write("hello","world","!!!");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello","world"),"!!!");
	}

	TEST(exist)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");

		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_FALSE(cache_driver.Exists("none"));

		cache_driver.Write("hello","world","!!!");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_TRUE(cache_driver.Exists("hello","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("none","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("hello","none"));
	}

	TEST(match)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");
		cache_driver.Write("session:6464","token","6464");
		cache_driver.Write("session:6464","update.time","123456789");
		cache_driver.Write("session:roles:6464","ROLES_6464");
		cache_driver.Write("session:777","token","777");
		cache_driver.Write("session:777","update.time","987654321");
		cache_driver.Write("session:roles:777","ROLES_777");

		std::vector<std::string> keys;

		cache_driver.Match("",keys);
		VERIFY_IS_TRUE(keys.size()==0);

		cache_driver.Match("*",keys);
		VERIFY_IS_TRUE(keys.size()==5);

		cache_driver.Match("session:",keys);
		VERIFY_IS_TRUE(keys.size()==0);

		cache_driver.Match("session:*",keys);
		VERIFY_IS_TRUE(keys.size()==4);

		cache_driver.Match("session:*:",keys);
		VERIFY_IS_TRUE(keys.size()==0);

		cache_driver.Match("session:*:*",keys);
		VERIFY_IS_TRUE(keys.size()==2);

		cache_driver.Match("session:6464*",keys);
		VERIFY_IS_TRUE(keys.size()==1);

		cache_driver.Match("session:*6464*",keys);
		VERIFY_IS_TRUE(keys.size()==2);
	}

	TEST(destroy)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");

		VERIFY_ARE_EQUAL(cache_driver.Read("hello"),"world");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_FALSE(cache_driver.Exists("none"));
		cache_driver.Destroy("hello");
		VERIFY_ARE_NOT_EQUAL(cache_driver.Read("hello"),"world");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello"),"");
		VERIFY_IS_FALSE(cache_driver.Exists("hello"));

		cache_driver.Write("hello","world","!!!");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello","world"),"!!!");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_TRUE(cache_driver.Exists("hello","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("none","world"));
		VERIFY_IS_FALSE(cache_driver.Exists("hello","none"));
		cache_driver.Destroy("hello","world");
		VERIFY_ARE_NOT_EQUAL(cache_driver.Read("hello","world"),"!!!");
		VERIFY_ARE_EQUAL(cache_driver.Read("hello","world"),"");
		VERIFY_IS_TRUE(cache_driver.Exists("hello"));
		VERIFY_IS_FALSE(cache_driver.Exists("hello","world"));

	}

	TEST(iterator)
	{
		granada::cache::SharedMapCacheDriver cache_driver;
		cache_driver.Write("hello","world");
		cache_driver.Write("session:6464","token","6464");
		cache_driver.Write("session:6464","update.time","123456789");
		cache_driver.Write("session:roles:6464","ROLES_6464");
		cache_driver.Write("session:777","token","777");
		cache_driver.Write("session:777","update.time","987654321");
		cache_driver.Write("session:roles:777","ROLES_777");

		std::shared_ptr<granada::cache::CacheHandlerIterator> cache_iterator = cache_driver.make_iterator("");
		VERIFY_IS_TRUE(!cache_iterator->has_next());
		for (int i = 0; i < 5; i++){
			VERIFY_IS_TRUE(cache_iterator->next()=="");
		}

		cache_iterator = cache_driver.make_iterator("*");
		int i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==5);

		cache_iterator = cache_driver.make_iterator("session:");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==0);

		cache_iterator = cache_driver.make_iterator("session:*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==4);

		cache_iterator = cache_driver.make_iterator("session:*:");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==0);

		cache_iterator = cache_driver.make_iterator("session:*:*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==2);

		cache_iterator = cache_driver.make_iterator("session:6464*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==1);

		cache_iterator = cache_driver.make_iterator("session:*6464*");
		i = 0;
		while(cache_iterator->has_next()){
			i++;
			cache_iterator->next();
		}
		VERIFY_IS_TRUE(i==2);
	}

}

}}} //namespaces
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2006 Ulrich von Zadow
//
//  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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//
//  Original author of this file is Nick Hebner (hebnern@gmail.com).
//

#include "SDLAudioEngine.h"
#include "Dynamics.h"

#include "../base/Exception.h"
#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/Profiler.h"

#include <iostream>

namespace avg {

using namespace std;
using namespace boost;

SDLAudioEngine::SDLAudioEngine()
    : m_pTempBuffer(),
      m_pMixBuffer(0),
      m_pLimiter(0)
{
    if (SDL_InitSubSystem(SDL_INIT_AUDIO)==-1) {
        AVG_TRACE(Logger::ERROR, "Can't init SDL audio subsystem.");
        exit(-1);
    }
}

SDLAudioEngine::~SDLAudioEngine()
{
    if (m_pMixBuffer) {
        delete[] m_pMixBuffer;
    }
    SDL_QuitSubSystem(SDL_INIT_AUDIO);
}

int SDLAudioEngine::getChannels()
{
    return m_AP.m_Channels;
}

int SDLAudioEngine::getSampleRate()
{
    return m_AP.m_SampleRate;
}

const AudioParams & SDLAudioEngine::getParams()
{
    return m_AP;
}

void SDLAudioEngine::init(const AudioParams& AP, double volume)
{
    AudioEngine::init(AP, volume);
    m_AP = AP;
    Dynamics<double, 2>* pLimiter = new Dynamics<double, 2>(m_AP.m_SampleRate);
    pLimiter->setThreshold(0.); // in dB
    pLimiter->setAttackTime(0.); // in seconds
    pLimiter->setReleaseTime(0.05); // in seconds
    pLimiter->setRmsTime(0.); // in seconds
    pLimiter->setRatio(std::numeric_limits<double>::infinity());
    pLimiter->setMakeupGain(0.); // in dB
    m_pLimiter = pLimiter;

    SDL_AudioSpec desired;
    desired.freq = m_AP.m_SampleRate;
    desired.format = AUDIO_S16SYS;
    desired.channels = m_AP.m_Channels;
    desired.silence = 0;
    desired.samples = m_AP.m_OutputBufferSamples;
    desired.callback = audioCallback;
    desired.userdata = this;

    if (SDL_OpenAudio(&desired, 0) < 0) {
      //throw new Exception("Cannot open audio device");
    }
}

void SDLAudioEngine::teardown()
{
    mutex::scoped_lock Lock(m_Mutex);
    SDL_PauseAudio(1);
    SDL_CloseAudio();

    getSources().clear();
    if (m_pLimiter) {
        delete m_pLimiter;
        m_pLimiter = 0;
    }
}

void SDLAudioEngine::setAudioEnabled(bool bEnabled)
{
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::setAudioEnabled(bEnabled);
}

void SDLAudioEngine::play()
{
    SDL_PauseAudio(0);
}

void SDLAudioEngine::pause()
{
    SDL_PauseAudio(1);
}

void SDLAudioEngine::addSource(IAudioSource* pSource)
{
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::addSource(pSource);
}

void SDLAudioEngine::removeSource(IAudioSource* pSource)
{
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::removeSource(pSource);
}

void SDLAudioEngine::setVolume(double volume)
{
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::setVolume(volume);
}

void SDLAudioEngine::mixAudio(Uint8 *pDestBuffer, int destBufferLen)
{
    mutex::scoped_lock Lock(m_Mutex);
    int numFrames = destBufferLen/(2*getChannels()); // 16 bit samples.

    if (getSources().size() == 0) {
        return;
    }
    if (!m_pTempBuffer || m_pTempBuffer->getNumFrames() < numFrames) {
        if (m_pTempBuffer) {
            delete[] m_pMixBuffer;
        }
        m_pTempBuffer = AudioBufferPtr(new AudioBuffer(numFrames, m_AP));
        m_pMixBuffer = new double[getChannels()*numFrames];
    }

    for (int i=0; i<getChannels()*numFrames; ++i) {
        m_pMixBuffer[i]=0;
    }
    AudioSourceList::iterator it;
    for(it = getSources().begin(); it != getSources().end(); it++) {
        m_pTempBuffer->clear();
        (*it)->fillAudioBuffer(m_pTempBuffer);
        addBuffers(m_pMixBuffer, m_pTempBuffer);
    }
    calcVolume(m_pMixBuffer, numFrames*getChannels(), getVolume());
    for (int i=0; i<numFrames; ++i) {
        m_pLimiter->process(m_pMixBuffer+i*getChannels());
        for (int j=0; j<getChannels(); ++j) {
            ((short*)pDestBuffer)[i*2+j]=short(m_pMixBuffer[i*2+j]*32768);
        }
    }
}

void SDLAudioEngine::audioCallback(void *userData, Uint8 *audioBuffer, int audioBufferLen)
{
    SDLAudioEngine *pThis = (SDLAudioEngine*)userData;
    pThis->mixAudio(audioBuffer, audioBufferLen);
}

void SDLAudioEngine::addBuffers(double *pDest, AudioBufferPtr pSrc)
{
    int numFrames = pSrc->getNumFrames();
    short * pData = pSrc->getData();
    for(int i = 0; i < numFrames*getChannels(); ++i) {
        pDest[i] += pData[i]/32768.0;
    }
}

void SDLAudioEngine::calcVolume(double *pBuffer, int numSamples, double volume)
{
    // TODO: We need a VolumeFader class that keeps state.
    for(int i = 0; i < numSamples; ++i) {
        pBuffer[i] *= volume;
    }
}

}
<commit_msg>More Audio locking fixes.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2006 Ulrich von Zadow
//
//  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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//
//  Original author of this file is Nick Hebner (hebnern@gmail.com).
//

#include "SDLAudioEngine.h"
#include "Dynamics.h"

#include "../base/Exception.h"
#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/Profiler.h"

#include <iostream>

namespace avg {

using namespace std;
using namespace boost;

SDLAudioEngine::SDLAudioEngine()
    : m_pTempBuffer(),
      m_pMixBuffer(0),
      m_pLimiter(0)
{
    if (SDL_InitSubSystem(SDL_INIT_AUDIO)==-1) {
        AVG_TRACE(Logger::ERROR, "Can't init SDL audio subsystem.");
        exit(-1);
    }
}

SDLAudioEngine::~SDLAudioEngine()
{
    if (m_pMixBuffer) {
        delete[] m_pMixBuffer;
    }
    SDL_QuitSubSystem(SDL_INIT_AUDIO);
}

int SDLAudioEngine::getChannels()
{
    return m_AP.m_Channels;
}

int SDLAudioEngine::getSampleRate()
{
    return m_AP.m_SampleRate;
}

const AudioParams & SDLAudioEngine::getParams()
{
    return m_AP;
}

void SDLAudioEngine::init(const AudioParams& AP, double volume)
{
    AudioEngine::init(AP, volume);
    m_AP = AP;
    Dynamics<double, 2>* pLimiter = new Dynamics<double, 2>(m_AP.m_SampleRate);
    pLimiter->setThreshold(0.); // in dB
    pLimiter->setAttackTime(0.); // in seconds
    pLimiter->setReleaseTime(0.05); // in seconds
    pLimiter->setRmsTime(0.); // in seconds
    pLimiter->setRatio(std::numeric_limits<double>::infinity());
    pLimiter->setMakeupGain(0.); // in dB
    m_pLimiter = pLimiter;

    SDL_AudioSpec desired;
    desired.freq = m_AP.m_SampleRate;
    desired.format = AUDIO_S16SYS;
    desired.channels = m_AP.m_Channels;
    desired.silence = 0;
    desired.samples = m_AP.m_OutputBufferSamples;
    desired.callback = audioCallback;
    desired.userdata = this;

    if (SDL_OpenAudio(&desired, 0) < 0) {
      //throw new Exception("Cannot open audio device");
    }
}

void SDLAudioEngine::teardown()
{
    mutex::scoped_lock Lock(m_Mutex);
    SDL_LockAudio();
    SDL_PauseAudio(1);
    SDL_CloseAudio();
    SDL_UnlockAudio();

    getSources().clear();
    if (m_pLimiter) {
        delete m_pLimiter;
        m_pLimiter = 0;
    }
}

void SDLAudioEngine::setAudioEnabled(bool bEnabled)
{
    SDL_LockAudio();
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::setAudioEnabled(bEnabled);
    SDL_UnlockAudio();
}

void SDLAudioEngine::play()
{
    SDL_PauseAudio(0);
}

void SDLAudioEngine::pause()
{
    SDL_PauseAudio(1);
}

void SDLAudioEngine::addSource(IAudioSource* pSource)
{
    SDL_LockAudio();
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::addSource(pSource);
    SDL_UnlockAudio();
}

void SDLAudioEngine::removeSource(IAudioSource* pSource)
{
    SDL_LockAudio();
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::removeSource(pSource);
    SDL_UnlockAudio();
}

void SDLAudioEngine::setVolume(double volume)
{
    SDL_LockAudio();
    mutex::scoped_lock Lock(m_Mutex);
    AudioEngine::setVolume(volume);
    SDL_UnlockAudio();
}

void SDLAudioEngine::mixAudio(Uint8 *pDestBuffer, int destBufferLen)
{
    int numFrames = destBufferLen/(2*getChannels()); // 16 bit samples.

    if (getSources().size() == 0) {
        return;
    }
    if (!m_pTempBuffer || m_pTempBuffer->getNumFrames() < numFrames) {
        if (m_pTempBuffer) {
            delete[] m_pMixBuffer;
        }
        m_pTempBuffer = AudioBufferPtr(new AudioBuffer(numFrames, m_AP));
        m_pMixBuffer = new double[getChannels()*numFrames];
    }

    for (int i=0; i<getChannels()*numFrames; ++i) {
        m_pMixBuffer[i]=0;
    }
    {
        mutex::scoped_lock Lock(m_Mutex);
        AudioSourceList::iterator it;
        for(it = getSources().begin(); it != getSources().end(); it++) {
            m_pTempBuffer->clear();
            (*it)->fillAudioBuffer(m_pTempBuffer);
            addBuffers(m_pMixBuffer, m_pTempBuffer);
        }
    }
    calcVolume(m_pMixBuffer, numFrames*getChannels(), getVolume());
    for (int i=0; i<numFrames; ++i) {
        m_pLimiter->process(m_pMixBuffer+i*getChannels());
        for (int j=0; j<getChannels(); ++j) {
            ((short*)pDestBuffer)[i*2+j]=short(m_pMixBuffer[i*2+j]*32768);
        }
    }
}

void SDLAudioEngine::audioCallback(void *userData, Uint8 *audioBuffer, int audioBufferLen)
{
    SDLAudioEngine *pThis = (SDLAudioEngine*)userData;
    pThis->mixAudio(audioBuffer, audioBufferLen);
}

void SDLAudioEngine::addBuffers(double *pDest, AudioBufferPtr pSrc)
{
    int numFrames = pSrc->getNumFrames();
    short * pData = pSrc->getData();
    for(int i = 0; i < numFrames*getChannels(); ++i) {
        pDest[i] += pData[i]/32768.0;
    }
}

void SDLAudioEngine::calcVolume(double *pBuffer, int numSamples, double volume)
{
    // TODO: We need a VolumeFader class that keeps state.
    for(int i = 0; i < numSamples; ++i) {
        pBuffer[i] *= volume;
    }
}

}
<|endoftext|>


<commit_before><commit_msg>Update thermostat.cpp<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: salgdiutils.cxx,v $
 * $Revision: 1.17 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "salgdi.h"
#include "salframe.h"

#include "basebmp/scanlineformats.hxx"
#include "basebmp/color.hxx"
#include "basegfx/range/b2drectangle.hxx"
#include "basegfx/range/b2irange.hxx"
#include "basegfx/vector/b2ivector.hxx"
#include "basegfx/polygon/b2dpolygon.hxx"
#include "basegfx/polygon/b2dpolygontools.hxx"
#include <boost/bind.hpp>

#include "vcl/svapp.hxx"
#include "saldata.hxx"

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

void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame )
{
    mpFrame     = pFrame;

    mbWindow    = true;
    mbPrinter   = false;
    mbVirDev    = false;
}

void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY, double fScale )
{
    mbWindow    = false;
    mbPrinter   = true;
    mbVirDev    = false;

    mrContext   = xContext;
    mfFakeDPIScale = fScale;
    mnRealDPIX  = nDPIX;
    mnRealDPIY  = nDPIY;

    if( mrContext )
    {
        CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSaveGState( mrContext );
        SetState();
    }
}

void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContext,
    int nBitmapDepth )
{
    mbWindow    = false;
    mbPrinter   = false;
    mbVirDev    = true;

    // set graphics properties
    mxLayer = xLayer;
    mrContext = xContext;
    mnBitmapDepth = nBitmapDepth;

    if( !mxLayer )
    {
        if( !xContext )
            return;
        mnWidth = CGBitmapContextGetWidth( xContext );
        mnHeight = CGBitmapContextGetHeight( xContext );
    }
    else
    {
        const CGSize aSize = CGLayerGetSize( mxLayer );
        mnWidth = aSize.width;
        mnHeight = aSize.height;
    }

    // prepare graphics for drawing
    DBG_ASSERT( mrContext, "AquaSalVirtualDevice has no drawing context?" );
    if( !mrContext )
        return;
    const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
    CGContextSetFillColorSpace( mrContext, aCGColorSpace );
    CGContextSetStrokeColorSpace( mrContext, aCGColorSpace );
    CGContextSaveGState( mrContext );
    SetState();
}

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

void AquaSalGraphics::SetState()
{
    CGContextRestoreGState( mrContext );
    CGContextSaveGState( mrContext );

    // setup standard clipping (unions of non-intersecting rectangles)
    if( mxClipRectsPath )
    {
        CGContextBeginPath( mrContext );                // discard any existing path
        CGContextAddPath( mrContext, mxClipRectsPath );  // set the current path to the clipping path
        CGContextClip( mrContext );                     // use it for clipping
    }

    // intersect with complex clipping
    if( mxClipPolysPath )
    {
        CGContextBeginPath( mrContext );
        CGContextAddPath( mrContext, mxClipPolysPath );
        CGContextEOClip( mrContext );
    }

    // set RGB colorspace and line and fill colors
    CGContextSetFillColor( mrContext, maFillColor.AsArray() );
    CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
    CGContextSetShouldAntialias( mrContext, false );
}

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

bool AquaSalGraphics::CheckContext()
{
    if( mpFrame != NULL )
    {
        const unsigned int nWidth = mpFrame->maGeometry.nWidth;
        const unsigned int nHeight = mpFrame->maGeometry.nHeight;

        CGContextRef rReleaseContext = 0;
        CGLayerRef   rReleaseLayer = NULL;
        const bool bXorEnabled = (mpXorEmulation && mpXorEmulation->IsEnabled());

        // check if a new drawing context is needed (e.g. after a resize)
        if( (mnWidth != nWidth) || (mnHeight != nHeight) )
        {
            mnWidth = nWidth;
            mnHeight = nHeight;
            // prepare to release the corresponding resources
            rReleaseContext = mrContext;
            rReleaseLayer   = mxLayer;
            mrContext = NULL;
            mxLayer = NULL;
            delete mpXorEmulation;
            mpXorEmulation = NULL;
        }

        if( !mrContext )
        {
            const CGSize aLayerSize = {nWidth,nHeight};
            NSGraphicsContext* pNSGContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getWindow()];
            CGContextRef xCGContext = reinterpret_cast<CGContextRef>([pNSGContext graphicsPort]);
            mxLayer = CGLayerCreateWithContext( xCGContext, aLayerSize, NULL );
            if( mxLayer )
                mrContext = CGLayerGetContext( mxLayer );

            if( mrContext )
            {
                // copy original layer to resized layer
                if( rReleaseLayer )
                    CGContextDrawLayerAtPoint( mrContext, CGPointZero, rReleaseLayer );

                CGContextTranslateCTM( mrContext, 0, nHeight );
                CGContextScaleCTM( mrContext, 1.0, -1.0 );
                CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
                CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
                CGContextSaveGState( mrContext );
                SetState();

                // re-enable XOR emulation for the new context
                if( bXorEnabled )
                {
                    mpXorEmulation = new XorEmulation( nWidth, nHeight, 0 );
                    mrContext = mpXorEmulation->Enable( mrContext, mxLayer );
                }
            }
        }

        if( rReleaseLayer )
            CGLayerRelease( rReleaseLayer );
        else if( rReleaseContext )
            CGContextRelease( rReleaseContext );
    }

    DBG_ASSERT( mrContext, "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
    return (mrContext != NULL);
}

void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeight)
{
    if( ! mbWindow ) // view only on Window graphics
        return;

    if( mpFrame )
    {
        // update a little more around the designated rectangle
        // this helps with antialiased rendering
        const Rectangle aVclRect( Point( lX-1, lY-1 ), Size( lWidth+2, lHeight+2) );
        mpFrame->maInvalidRect.Union( aVclRect );
    }
}

CGPoint* AquaSalGraphics::makeCGptArray(ULONG nPoints, const SalPoint*  pPtAry)
{
    CGPoint *CGpoints = new (CGPoint[nPoints]);
    if ( CGpoints )
      {
        for(ULONG i=0;i<nPoints;i++)
          {
            CGpoints[i].x = (float)(pPtAry[i].mnX);
            CGpoints[i].y = (float)(pPtAry[i].mnY);
          }
      }
    return CGpoints;
}

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

void AquaSalGraphics::UpdateWindow( NSRect& rRect )
{
    if( !mpFrame )
        return;
    NSGraphicsContext* pContext = [NSGraphicsContext currentContext];
    // NSGraphicsContext* pContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getWindow()];
    if( (mxLayer != NULL) && (pContext != NULL) )
    {
        CGContextRef rCGContext = reinterpret_cast<CGContextRef>([pContext graphicsPort]);

        CGMutablePathRef rClip = mpFrame->getClipPath();
        if( rClip )
        {
            CGContextSaveGState( rCGContext );
            CGContextBeginPath( rCGContext );
            CGContextAddPath( rCGContext, rClip );
            CGContextClip( rCGContext );
        }

        if( mxLayer )
            CGContextDrawLayerAtPoint( rCGContext, CGPointZero, mxLayer );
        CGContextFlush( rCGContext );
        if( rClip ) // cleanup clipping
            CGContextRestoreGState( rCGContext );
    }
    else
        DBG_ERROR( "UpdateWindow called on uneligible graphics" );
}

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

<commit_msg>#i10000# compare signed unsigned warning<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: salgdiutils.cxx,v $
 * $Revision: 1.18 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "salgdi.h"
#include "salframe.h"

#include "basebmp/scanlineformats.hxx"
#include "basebmp/color.hxx"
#include "basegfx/range/b2drectangle.hxx"
#include "basegfx/range/b2irange.hxx"
#include "basegfx/vector/b2ivector.hxx"
#include "basegfx/polygon/b2dpolygon.hxx"
#include "basegfx/polygon/b2dpolygontools.hxx"
#include <boost/bind.hpp>

#include "vcl/svapp.hxx"
#include "saldata.hxx"

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

void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame )
{
    mpFrame     = pFrame;

    mbWindow    = true;
    mbPrinter   = false;
    mbVirDev    = false;
}

void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY, double fScale )
{
    mbWindow    = false;
    mbPrinter   = true;
    mbVirDev    = false;

    mrContext   = xContext;
    mfFakeDPIScale = fScale;
    mnRealDPIX  = nDPIX;
    mnRealDPIY  = nDPIY;

    if( mrContext )
    {
        CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSaveGState( mrContext );
        SetState();
    }
}

void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContext,
    int nBitmapDepth )
{
    mbWindow    = false;
    mbPrinter   = false;
    mbVirDev    = true;

    // set graphics properties
    mxLayer = xLayer;
    mrContext = xContext;
    mnBitmapDepth = nBitmapDepth;

    if( !mxLayer )
    {
        if( !xContext )
            return;
        mnWidth = CGBitmapContextGetWidth( xContext );
        mnHeight = CGBitmapContextGetHeight( xContext );
    }
    else
    {
        const CGSize aSize = CGLayerGetSize( mxLayer );
        mnWidth = aSize.width;
        mnHeight = aSize.height;
    }

    // prepare graphics for drawing
    DBG_ASSERT( mrContext, "AquaSalVirtualDevice has no drawing context?" );
    if( !mrContext )
        return;
    const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
    CGContextSetFillColorSpace( mrContext, aCGColorSpace );
    CGContextSetStrokeColorSpace( mrContext, aCGColorSpace );
    CGContextSaveGState( mrContext );
    SetState();
}

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

void AquaSalGraphics::SetState()
{
    CGContextRestoreGState( mrContext );
    CGContextSaveGState( mrContext );

    // setup standard clipping (unions of non-intersecting rectangles)
    if( mxClipRectsPath )
    {
        CGContextBeginPath( mrContext );                // discard any existing path
        CGContextAddPath( mrContext, mxClipRectsPath );  // set the current path to the clipping path
        CGContextClip( mrContext );                     // use it for clipping
    }

    // intersect with complex clipping
    if( mxClipPolysPath )
    {
        CGContextBeginPath( mrContext );
        CGContextAddPath( mrContext, mxClipPolysPath );
        CGContextEOClip( mrContext );
    }

    // set RGB colorspace and line and fill colors
    CGContextSetFillColor( mrContext, maFillColor.AsArray() );
    CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
    CGContextSetShouldAntialias( mrContext, false );
}

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

bool AquaSalGraphics::CheckContext()
{
    if( mpFrame != NULL )
    {
        const unsigned int nWidth = mpFrame->maGeometry.nWidth;
        const unsigned int nHeight = mpFrame->maGeometry.nHeight;

        CGContextRef rReleaseContext = 0;
        CGLayerRef   rReleaseLayer = NULL;
        const bool bXorEnabled = (mpXorEmulation && mpXorEmulation->IsEnabled());

        // check if a new drawing context is needed (e.g. after a resize)
        if( (unsigned(mnWidth) != nWidth) || (unsigned(mnHeight) != nHeight) )
        {
            mnWidth = nWidth;
            mnHeight = nHeight;
            // prepare to release the corresponding resources
            rReleaseContext = mrContext;
            rReleaseLayer   = mxLayer;
            mrContext = NULL;
            mxLayer = NULL;
            delete mpXorEmulation;
            mpXorEmulation = NULL;
        }

        if( !mrContext )
        {
            const CGSize aLayerSize = {nWidth,nHeight};
            NSGraphicsContext* pNSGContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getWindow()];
            CGContextRef xCGContext = reinterpret_cast<CGContextRef>([pNSGContext graphicsPort]);
            mxLayer = CGLayerCreateWithContext( xCGContext, aLayerSize, NULL );
            if( mxLayer )
                mrContext = CGLayerGetContext( mxLayer );

            if( mrContext )
            {
                // copy original layer to resized layer
                if( rReleaseLayer )
                    CGContextDrawLayerAtPoint( mrContext, CGPointZero, rReleaseLayer );

                CGContextTranslateCTM( mrContext, 0, nHeight );
                CGContextScaleCTM( mrContext, 1.0, -1.0 );
                CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
                CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
                CGContextSaveGState( mrContext );
                SetState();

                // re-enable XOR emulation for the new context
                if( bXorEnabled )
                {
                    mpXorEmulation = new XorEmulation( nWidth, nHeight, 0 );
                    mrContext = mpXorEmulation->Enable( mrContext, mxLayer );
                }
            }
        }

        if( rReleaseLayer )
            CGLayerRelease( rReleaseLayer );
        else if( rReleaseContext )
            CGContextRelease( rReleaseContext );
    }

    DBG_ASSERT( mrContext, "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
    return (mrContext != NULL);
}

void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeight)
{
    if( ! mbWindow ) // view only on Window graphics
        return;

    if( mpFrame )
    {
        // update a little more around the designated rectangle
        // this helps with antialiased rendering
        const Rectangle aVclRect( Point( lX-1, lY-1 ), Size( lWidth+2, lHeight+2) );
        mpFrame->maInvalidRect.Union( aVclRect );
    }
}

CGPoint* AquaSalGraphics::makeCGptArray(ULONG nPoints, const SalPoint*  pPtAry)
{
    CGPoint *CGpoints = new (CGPoint[nPoints]);
    if ( CGpoints )
      {
        for(ULONG i=0;i<nPoints;i++)
          {
            CGpoints[i].x = (float)(pPtAry[i].mnX);
            CGpoints[i].y = (float)(pPtAry[i].mnY);
          }
      }
    return CGpoints;
}

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

void AquaSalGraphics::UpdateWindow( NSRect& rRect )
{
    if( !mpFrame )
        return;
    NSGraphicsContext* pContext = [NSGraphicsContext currentContext];
    // NSGraphicsContext* pContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getWindow()];
    if( (mxLayer != NULL) && (pContext != NULL) )
    {
        CGContextRef rCGContext = reinterpret_cast<CGContextRef>([pContext graphicsPort]);

        CGMutablePathRef rClip = mpFrame->getClipPath();
        if( rClip )
        {
            CGContextSaveGState( rCGContext );
            CGContextBeginPath( rCGContext );
            CGContextAddPath( rCGContext, rClip );
            CGContextClip( rCGContext );
        }

        if( mxLayer )
            CGContextDrawLayerAtPoint( rCGContext, CGPointZero, mxLayer );
        CGContextFlush( rCGContext );
        if( rClip ) // cleanup clipping
            CGContextRestoreGState( rCGContext );
    }
    else
        DBG_ERROR( "UpdateWindow called on uneligible graphics" );
}

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

<|endoftext|>


<commit_before>/*
	sudo cpufreq-set -c 0 -g performance
	mycl karatsuba.cpp -DMCL_USE_LLVM=1 ../lib/libmcl.a && ./a.out
*/
#include <stdio.h>
#include <mcl/fp.hpp>
#include <cybozu/xorshift.hpp>
#include "../src/fp_proto.hpp"
#ifdef MCL_USE_LLVM
#include "../src/fp_llvm.hpp"
#endif
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>

typedef mcl::FpT<> Fp;

using namespace mcl::fp;

void dump(const Unit *x, size_t N)
{
	for (size_t i = 0; i < N; i++) {
		printf("%016llx ", (long long)x[N - 1 - i]);
	}
	printf("\n");
}

void gggKara(uint64_t *z, const uint64_t *x, const uint64_t *)
{
	SqrPre<8, Gtag>::f(z, x);
}
void gggLLVM(uint64_t *z, const uint64_t *x, const uint64_t *y)
{
	MulPre<8, Ltag>::f(z, x, y);
}

template<size_t N>
void benchKaratsuba()
{
	cybozu::XorShift rg;
	printf("N=%d\n", (int)N);
	Unit x[N], z[N * 2];
	rg.read(x, N);
	rg.read(z, N);
	CYBOZU_BENCH("g:mulPre ", (MulPreCore<N, Gtag>::f), z, z, x);
	CYBOZU_BENCH("g:mulKara", (MulPre<N, Gtag>::karatsuba), z, z, x);
	CYBOZU_BENCH("g:sqrPre ", (SqrPreCore<N, Gtag>::f), z, z);
	CYBOZU_BENCH("g:sqrKara", (SqrPre<N, Gtag>::karatsuba), z, z);

#ifdef MCL_USE_LLVM
	CYBOZU_BENCH("l:mulPre ", (MulPreCore<N, Ltag>::f), z, z, x);
	CYBOZU_BENCH("l:mulKara", (MulPre<N, Ltag>::karatsuba), z, z, x);
	CYBOZU_BENCH("l:sqrPre ", (SqrPreCore<N, Ltag>::f), z, z);
	CYBOZU_BENCH("l:sqrKara", (SqrPre<N, Ltag>::karatsuba), z, z);
#endif
}

CYBOZU_TEST_AUTO(karatsuba)
{
	benchKaratsuba<4>();
	benchKaratsuba<6>();
	benchKaratsuba<8>();
#if MCL_MAX_BIT_SIZE == 768
	benchKaratsuba<10>();
	benchKaratsuba<12>();
#endif
}

<commit_msg>remove x in benchmark<commit_after>/*
	sudo cpufreq-set -c 0 -g performance
	mycl karatsuba.cpp -DMCL_USE_LLVM=1 ../lib/libmcl.a && ./a.out
*/
#include <stdio.h>
#include <mcl/fp.hpp>
#include <cybozu/xorshift.hpp>
#include "../src/fp_proto.hpp"
#ifdef MCL_USE_LLVM
#include "../src/fp_llvm.hpp"
#endif
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>

typedef mcl::FpT<> Fp;

using namespace mcl::fp;

void dump(const Unit *x, size_t N)
{
	for (size_t i = 0; i < N; i++) {
		printf("%016llx ", (long long)x[N - 1 - i]);
	}
	printf("\n");
}

void gggKara(uint64_t *z, const uint64_t *x, const uint64_t *)
{
	SqrPre<8, Gtag>::f(z, x);
}
void gggLLVM(uint64_t *z, const uint64_t *x, const uint64_t *y)
{
	MulPre<8, Ltag>::f(z, x, y);
}

template<size_t N>
void benchKaratsuba()
{
	cybozu::XorShift rg;
	printf("N=%d\n", (int)N);
	Unit z[N * 2];
	rg.read(z, N);
	CYBOZU_BENCH("g:mulPre ", (MulPreCore<N, Gtag>::f), z, z, z);
	CYBOZU_BENCH("g:mulKara", (MulPre<N, Gtag>::karatsuba), z, z, z);
	CYBOZU_BENCH("g:sqrPre ", (SqrPreCore<N, Gtag>::f), z, z);
	CYBOZU_BENCH("g:sqrKara", (SqrPre<N, Gtag>::karatsuba), z, z);

#ifdef MCL_USE_LLVM
	CYBOZU_BENCH("l:mulPre ", (MulPreCore<N, Ltag>::f), z, z, z);
	CYBOZU_BENCH("l:mulKara", (MulPre<N, Ltag>::karatsuba), z, z, z);
	CYBOZU_BENCH("l:sqrPre ", (SqrPreCore<N, Ltag>::f), z, z);
	CYBOZU_BENCH("l:sqrKara", (SqrPre<N, Ltag>::karatsuba), z, z);
#endif
}

CYBOZU_TEST_AUTO(karatsuba)
{
	benchKaratsuba<4>();
	benchKaratsuba<6>();
	benchKaratsuba<8>();
#if MCL_MAX_BIT_SIZE == 768
	benchKaratsuba<10>();
	benchKaratsuba<12>();
#endif
}

<|endoftext|>