<commit_before>/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
** Copyright (C) 2001 by Waldo Bastian (code in questionYesNo)
**
*/

/*
** This program 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 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
static const char *syncAction_id =
	"$Id$";

#include "options.h"

#include <time.h>

#include <pi-socket.h>
#include <pi-dlp.h>

#include <qtimer.h>
#include <qvbox.h>
#include <qlayout.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qmessagebox.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qtl.h>
#include <qstyle.h>

#include <kdialogbase.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include <kmessagebox.h>

#include "syncAction.moc"
#include "kpilotlibSettings.h"

SyncAction::SyncAction(KPilotDeviceLink  *p,
	const char *name) :
	QObject(p, name),
	fHandle(p),
	fParent(0L)
{
	FUNCTIONSETUP;
	(void) syncAction_id;
}

SyncAction::SyncAction(KPilotDeviceLink *p,
	QWidget * visibleparent,
	const char *name) :
	QObject(p, name),
	fHandle(p),
	fParent(visibleparent)
{
	FUNCTIONSETUP;
}

SyncAction::~SyncAction()
{
}

/* virtual */ QString SyncAction::statusString() const
{
	FUNCTIONSETUP;
	QString s = CSL1("status=");

	s.append(QString::number(status()));
	return s;
}

/* slot */ void SyncAction::execConduit()
{
	FUNCTIONSETUP;

#ifdef DEBUG
	DEBUGCONDUIT << fname
		<< ": Running conduit " << name() << endl;
#endif

	bool r = this->exec();

#ifdef DEBUG
	DEBUGCONDUIT << fname << ": Exec returned " << r << endl;
#endif

	if (!r)
	{
		emit logError(i18n("The conduit %1 could not be executed.")
			.arg(QString::fromLatin1(name())));
		delayDone();
	}
}

/* slot */ void SyncAction::delayedDoneSlot()
{
	emit syncDone(this);
}

bool SyncAction::delayDone()
{
	QTimer::singleShot(0,this,SLOT(delayedDoneSlot()));
	return true;
}

static struct
{
	SyncAction::SyncMode::Mode mode;
	const char *name;
} maps[] =
{
	{ SyncAction::SyncMode::eHotSync, "--hotsync" },
	{ SyncAction::SyncMode::eFastSync, "--fast" },
	{ SyncAction::SyncMode::eFullSync, "--full" },
	{ SyncAction::SyncMode::eCopyPCToHH, "--copyPCToHH" },
	{ SyncAction::SyncMode::eCopyHHToPC, "--copyHHToPC" },
	{ SyncAction::SyncMode::eBackup, "--backup" },
	{ SyncAction::SyncMode::eRestore, "--restore" },
	{ SyncAction::SyncMode::eFastSync, "--fastsync" },
	{ SyncAction::SyncMode::eFullSync, "--fullsync" },
	{ SyncAction::SyncMode::eHotSync, (const char *)0 }
}
;

SyncAction::SyncMode::SyncMode(const QStringList &args) :
	fMode(eFastSync),
	fTest(args.contains("--test")),
	fLocal(args.contains("--local"))
{
	int i = 0;
	while(maps[i].name)
	{
		if (args.contains(QString::fromLatin1(maps[i].name)))
		{
			fMode = maps[i].mode;
			break;
		}
		i++;
	}

	if (!maps[i].name)
	{
		kdError() << k_funcinfo << "No mode set by arguments "
			<< args << ", defaulting to FastSync." << endl;
	}
}

SyncAction::SyncMode::SyncMode(Mode m, bool test, bool local) :
	fMode(m),
	fTest(test),
	fLocal(local)
{
	if ( ((int)m<(int)eFastSync) || ((int)m>(int)eRestore) )
	{
		kdError() << k_funcinfo << "Mode value " << (int)m << " is illegal"
			", defaulting to FastSync." << endl;
		fMode = eFastSync;
	}
}

QStringList SyncAction::SyncMode::list() const
{
	FUNCTIONSETUPL(3);

	QStringList l;
	int i=0;

	while(maps[i].name)
	{
		if ( fMode == maps[i].mode )
		{
			l.append(QString::fromLatin1(maps[i].name));
			break;
		}
		i++;
	}
	if ( !maps[i].name )
	{
		kdError() << k_funcinfo << "Mode " << fMode << " does not have a name." << endl;
		l.append(QString::fromLatin1(maps[0].name));
	}

	if (isTest()) l.append(CSL1("--test"));
	if (isLocal()) l.append(CSL1("--local"));
	return l;
}

/* static */ QString SyncAction::SyncMode::name(SyncAction::SyncMode::Mode e)
{
	switch(e)
	{
	case eFastSync : return i18n("FastSync");
	case eHotSync : return i18n("HotSync");
	case eFullSync : return i18n("Full Synchronization");
	case eCopyPCToHH : return i18n("Copy PC to Handheld");
	case eCopyHHToPC : return i18n("Copy Handheld to PC");
	case eBackup : return i18n("Backup");
	case eRestore : return i18n("Restore From Backup");
	}
	return CSL1("<unknown>");
}

QString SyncAction::SyncMode::name() const
{
	QString s = name(fMode);
	if (isTest())
	{

		s.append(CSL1(" [%1]").arg(i18n("Test Sync")));
	}
	if (isLocal())
	{
		s.append(CSL1(" [%1]").arg(i18n("Local Sync")));
	}
	return s;
}

bool SyncAction::SyncMode::setMode(int mode)
{
	// Resets test and local flags too
	fTest = fLocal = false;

	if ( (mode>0) && (mode<=eRestore) )
	{
		fMode = (SyncAction::SyncMode::Mode) mode;
		return true;
	}
	else
	{
		kdWarning() << k_funcinfo << ": Bad sync mode " << mode << " requested." << endl ;
		fMode = eHotSync;
		return false;
	}
}

bool SyncAction::SyncMode::setMode(SyncAction::SyncMode::Mode m)
{
	int i=0;
	while ( maps[i].name )
	{
		if ( maps[i].mode == m )
		{
			fMode = m;
			return true;
		}
		i++;
	}

	kdWarning() << k_funcinfo << ": Bad sync mode " << m << " requested." << endl ;
	fMode = eHotSync;
	return false;
}

void SyncAction::startTickle(unsigned timeout)
{
	FUNCTIONSETUP;
	connect(fHandle,SIGNAL(timeout()),this,SIGNAL(timeout()));
	fHandle->startTickle(timeout);
}

void SyncAction::stopTickle()
{
	FUNCTIONSETUP;
	disconnect(fHandle,SIGNAL(timeout()),this,SIGNAL(timeout()));
	fHandle->stopTickle();
}

int SyncAction::questionYesNo(const QString & text,
	const QString & caption,
	const QString & key,
	unsigned timeout,
	const QString & yes,
	const QString &no )
{
	FUNCTIONSETUP;

	bool checkboxReturn = false;
	int r;
	KMessageBox::ButtonCode result;
	if (!key.isEmpty())
	{
		if (!KMessageBox::shouldBeShownYesNo(key,result))
		{
			return result;
		}
	}

#if !KDE_IS_VERSION(3,3,0)
	return KMessageBox::Cancel;
#else
	KDialogBase *dialog =
		new KDialogBase(caption.isNull()? i18n("Question") : caption,
		KDialogBase::Yes | KDialogBase::No,
		KDialogBase::Yes, KDialogBase::No,
		fParent, "questionYesNo", true, true,
		yes.isEmpty() ? KStdGuiItem::yes() : yes,
		no.isEmpty() ? KStdGuiItem::no() : no);

	if (timeout > 0)
	{
		QObject::connect(fHandle, SIGNAL(timeout()),
			dialog, SLOT(slotCancel()));
		startTickle(timeout);
	}

	r = (KMessageBox::ButtonCode) KMessageBox::createKMessageBox(dialog,
		QMessageBox::Question,
		text,
		QStringList(),
		(key.isEmpty() ? QString::null : i18n("&Do not ask again")),
		&checkboxReturn,
		0);

	switch(r)
	{
	case KDialogBase::Yes : result=KMessageBox::Yes ; break;
	case KDialogBase::No  : result=KMessageBox::No; break;
	case KDialogBase::Cancel : result=KMessageBox::Cancel; break;
	default : break;
	}

	stopTickle();

	if (!key.isEmpty() && checkboxReturn)
	{
		KMessageBox::saveDontShowAgainYesNo(key,result);
	}

	return result;
#endif
}

int SyncAction::questionYesNoCancel(const QString & text,
	const QString & caption,
	const QString & key,
	unsigned timeout,
	const QString &yes,
	const QString &no)
{
	FUNCTIONSETUP;

	bool checkboxReturn = false;
	int r;
	KMessageBox::ButtonCode result;

	if (!key.isEmpty())
	{
		if (!KMessageBox::shouldBeShownYesNo(key,result))
		{
			if (result != KMessageBox::Cancel)
			{
				return result;
			}
		}
	}

	KDialogBase *dialog =
		new KDialogBase(caption.isNull()? i18n("Question") : caption,
		KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel,
		KDialogBase::Yes, KDialogBase::Cancel,
		fParent, "questionYesNoCancel", true, true,
		(yes.isEmpty() ? KStdGuiItem::yes() : yes),
		(no.isEmpty() ? KStdGuiItem::no() : no),
		KStdGuiItem::cancel());

	if (timeout > 0)
	{
		QObject::connect(fHandle, SIGNAL(timeout()),
			dialog, SLOT(slotCancel()));
		startTickle(timeout);
	}

#if KDE_IS_VERSION(3,3,0)
	r = KMessageBox::createKMessageBox(dialog,
		QMessageBox::Question,
		text,
		QStringList(),
		(key.isEmpty() ? QString::null : i18n("&Do not ask again")),
		&checkboxReturn,
		0);
#else
	r = KDialogBase::Cancel;
#endif

	switch(r)
	{
	case KDialogBase::Yes : result=KMessageBox::Yes ; break;
	case KDialogBase::No  : result=KMessageBox::No; break;
	case KDialogBase::Cancel : result=KMessageBox::Cancel; break;
	default : break;
	}
	stopTickle();

	if (!key.isEmpty() && checkboxReturn)
	{
		KMessageBox::saveDontShowAgainYesNo(key,result);
	}

	return result;
}

<commit_msg>Reintroduce backwards-compatibility code for KDE 3.2 that had been removed -- this is needed for proko2. Minor changes from a patch David sent, since that was missing the don't-save-again code.<commit_after>/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
** Copyright (C) 2001 by Waldo Bastian (code in questionYesNo)
**
*/

/*
** This program 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 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
static const char *syncAction_id =
	"$Id$";

#include "options.h"

#include <time.h>

#include <pi-socket.h>
#include <pi-dlp.h>

#include <qtimer.h>
#include <qvbox.h>
#include <qlayout.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qmessagebox.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qtl.h>
#include <qstyle.h>

#include <kdialogbase.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include <kmessagebox.h>

#include "syncAction.moc"
#include "kpilotlibSettings.h"

SyncAction::SyncAction(KPilotDeviceLink  *p,
	const char *name) :
	QObject(p, name),
	fHandle(p),
	fParent(0L)
{
	FUNCTIONSETUP;
	(void) syncAction_id;
}

SyncAction::SyncAction(KPilotDeviceLink *p,
	QWidget * visibleparent,
	const char *name) :
	QObject(p, name),
	fHandle(p),
	fParent(visibleparent)
{
	FUNCTIONSETUP;
}

SyncAction::~SyncAction()
{
}

/* virtual */ QString SyncAction::statusString() const
{
	FUNCTIONSETUP;
	QString s = CSL1("status=");

	s.append(QString::number(status()));
	return s;
}

/* slot */ void SyncAction::execConduit()
{
	FUNCTIONSETUP;

#ifdef DEBUG
	DEBUGCONDUIT << fname
		<< ": Running conduit " << name() << endl;
#endif

	bool r = this->exec();

#ifdef DEBUG
	DEBUGCONDUIT << fname << ": Exec returned " << r << endl;
#endif

	if (!r)
	{
		emit logError(i18n("The conduit %1 could not be executed.")
			.arg(QString::fromLatin1(name())));
		delayDone();
	}
}

/* slot */ void SyncAction::delayedDoneSlot()
{
	emit syncDone(this);
}

bool SyncAction::delayDone()
{
	QTimer::singleShot(0,this,SLOT(delayedDoneSlot()));
	return true;
}

static struct
{
	SyncAction::SyncMode::Mode mode;
	const char *name;
} maps[] =
{
	{ SyncAction::SyncMode::eHotSync, "--hotsync" },
	{ SyncAction::SyncMode::eFastSync, "--fast" },
	{ SyncAction::SyncMode::eFullSync, "--full" },
	{ SyncAction::SyncMode::eCopyPCToHH, "--copyPCToHH" },
	{ SyncAction::SyncMode::eCopyHHToPC, "--copyHHToPC" },
	{ SyncAction::SyncMode::eBackup, "--backup" },
	{ SyncAction::SyncMode::eRestore, "--restore" },
	{ SyncAction::SyncMode::eFastSync, "--fastsync" },
	{ SyncAction::SyncMode::eFullSync, "--fullsync" },
	{ SyncAction::SyncMode::eHotSync, (const char *)0 }
}
;

SyncAction::SyncMode::SyncMode(const QStringList &args) :
	fMode(eFastSync),
	fTest(args.contains("--test")),
	fLocal(args.contains("--local"))
{
	int i = 0;
	while(maps[i].name)
	{
		if (args.contains(QString::fromLatin1(maps[i].name)))
		{
			fMode = maps[i].mode;
			break;
		}
		i++;
	}

	if (!maps[i].name)
	{
		kdError() << k_funcinfo << "No mode set by arguments "
			<< args << ", defaulting to FastSync." << endl;
	}
}

SyncAction::SyncMode::SyncMode(Mode m, bool test, bool local) :
	fMode(m),
	fTest(test),
	fLocal(local)
{
	if ( ((int)m<(int)eFastSync) || ((int)m>(int)eRestore) )
	{
		kdError() << k_funcinfo << "Mode value " << (int)m << " is illegal"
			", defaulting to FastSync." << endl;
		fMode = eFastSync;
	}
}

QStringList SyncAction::SyncMode::list() const
{
	FUNCTIONSETUPL(3);

	QStringList l;
	int i=0;

	while(maps[i].name)
	{
		if ( fMode == maps[i].mode )
		{
			l.append(QString::fromLatin1(maps[i].name));
			break;
		}
		i++;
	}
	if ( !maps[i].name )
	{
		kdError() << k_funcinfo << "Mode " << fMode << " does not have a name." << endl;
		l.append(QString::fromLatin1(maps[0].name));
	}

	if (isTest()) l.append(CSL1("--test"));
	if (isLocal()) l.append(CSL1("--local"));
	return l;
}

/* static */ QString SyncAction::SyncMode::name(SyncAction::SyncMode::Mode e)
{
	switch(e)
	{
	case eFastSync : return i18n("FastSync");
	case eHotSync : return i18n("HotSync");
	case eFullSync : return i18n("Full Synchronization");
	case eCopyPCToHH : return i18n("Copy PC to Handheld");
	case eCopyHHToPC : return i18n("Copy Handheld to PC");
	case eBackup : return i18n("Backup");
	case eRestore : return i18n("Restore From Backup");
	}
	return CSL1("<unknown>");
}

QString SyncAction::SyncMode::name() const
{
	QString s = name(fMode);
	if (isTest())
	{

		s.append(CSL1(" [%1]").arg(i18n("Test Sync")));
	}
	if (isLocal())
	{
		s.append(CSL1(" [%1]").arg(i18n("Local Sync")));
	}
	return s;
}

bool SyncAction::SyncMode::setMode(int mode)
{
	// Resets test and local flags too
	fTest = fLocal = false;

	if ( (mode>0) && (mode<=eRestore) )
	{
		fMode = (SyncAction::SyncMode::Mode) mode;
		return true;
	}
	else
	{
		kdWarning() << k_funcinfo << ": Bad sync mode " << mode << " requested." << endl ;
		fMode = eHotSync;
		return false;
	}
}

bool SyncAction::SyncMode::setMode(SyncAction::SyncMode::Mode m)
{
	int i=0;
	while ( maps[i].name )
	{
		if ( maps[i].mode == m )
		{
			fMode = m;
			return true;
		}
		i++;
	}

	kdWarning() << k_funcinfo << ": Bad sync mode " << m << " requested." << endl ;
	fMode = eHotSync;
	return false;
}

void SyncAction::startTickle(unsigned timeout)
{
	FUNCTIONSETUP;
	connect(fHandle,SIGNAL(timeout()),this,SIGNAL(timeout()));
	fHandle->startTickle(timeout);
}

void SyncAction::stopTickle()
{
	FUNCTIONSETUP;
	disconnect(fHandle,SIGNAL(timeout()),this,SIGNAL(timeout()));
	fHandle->stopTickle();
}

int SyncAction::questionYesNo(const QString & text,
	const QString & caption,
	const QString & key,
	unsigned timeout,
	const QString & yes,
	const QString &no )
{
	FUNCTIONSETUP;

	bool checkboxReturn = false;
	int r;
	KMessageBox::ButtonCode result;
	if (!key.isEmpty())
	{
		if (!KMessageBox::shouldBeShownYesNo(key,result))
		{
			return result;
		}
	}

	KDialogBase *dialog =
		new KDialogBase(caption.isNull()? i18n("Question") : caption,
		KDialogBase::Yes | KDialogBase::No,
		KDialogBase::Yes, KDialogBase::No,
		fParent, "questionYesNo", true, true,
		yes.isEmpty() ? KStdGuiItem::yes() : yes,
		no.isEmpty() ? KStdGuiItem::no() : no);

	if (timeout > 0)
	{
		QObject::connect(fHandle, SIGNAL(timeout()),
			dialog, SLOT(slotCancel()));
		startTickle(timeout);
	}

#if KDE_IS_VERSION(3,3,0)
	r = (KMessageBox::ButtonCode) KMessageBox::createKMessageBox(dialog,
		QMessageBox::Question,
		text,
		QStringList(),
		(key.isEmpty() ? QString::null : i18n("&Do not ask again")),
		&checkboxReturn,
		0);

#else
	// The following code is taken from KDialogBase.cc,
	// part of the KDE 2.2 libraries. Copyright 2001
	// by Waldo Bastian.
	//
	//
	QVBox *topcontents = new QVBox(dialog);

	topcontents->setSpacing(KDialog::spacingHint() * 2);
	topcontents->setMargin(KDialog::marginHint() * 2);

	QWidget *contents = new QWidget(topcontents);
	QHBoxLayout *lay = new QHBoxLayout(contents);

	lay->setSpacing(KDialog::spacingHint() * 2);

	lay->addStretch(1);
	QLabel *label1 = new QLabel( contents);
	label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Information));
	lay->add( label1 );
	QLabel *label2 = new QLabel( text, contents);
	label2->setMinimumSize(label2->sizeHint());
	lay->add(label2);
	lay->addStretch(1);

	QSize extraSize = QSize(50, 30);

	QCheckBox *checkbox = 0L;
	if (!key.isEmpty())
	{
		checkbox = new QCheckBox(i18n("Do not ask again"),topcontents);
		extraSize = QSize(50,0);
	}

	dialog->setMainWidget(topcontents);
	dialog->enableButtonSeparator(false);
	dialog->incInitialSize(extraSize);

	r = dialog->exec();
	if (checkbox)
	{
		checkboxReturn = checkbox->isChecked();
	}
#endif

	switch(r)
	{
	case KDialogBase::Yes : result=KMessageBox::Yes ; break;
	case KDialogBase::No  : result=KMessageBox::No; break;
	case KDialogBase::Cancel : result=KMessageBox::Cancel; break;
	default : break;
	}

	stopTickle();

	if (!key.isEmpty() && checkboxReturn)
	{
		KMessageBox::saveDontShowAgainYesNo(key,result);
	}

	return result;
}

int SyncAction::questionYesNoCancel(const QString & text,
	const QString & caption,
	const QString & key,
	unsigned timeout,
	const QString &yes,
	const QString &no)
{
	FUNCTIONSETUP;

	bool checkboxReturn = false;
	int r;
	KMessageBox::ButtonCode result;

	if (!key.isEmpty())
	{
		if (!KMessageBox::shouldBeShownYesNo(key,result))
		{
			if (result != KMessageBox::Cancel)
			{
				return result;
			}
		}
	}

	KDialogBase *dialog =
		new KDialogBase(caption.isNull()? i18n("Question") : caption,
		KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel,
		KDialogBase::Yes, KDialogBase::Cancel,
		fParent, "questionYesNoCancel", true, true,
		(yes.isEmpty() ? KStdGuiItem::yes() : yes),
		(no.isEmpty() ? KStdGuiItem::no() : no),
		KStdGuiItem::cancel());

	if (timeout > 0)
	{
		QObject::connect(fHandle, SIGNAL(timeout()),
			dialog, SLOT(slotCancel()));
		startTickle(timeout);
	}

#if KDE_IS_VERSION(3,3,0)
	r = KMessageBox::createKMessageBox(dialog,
		QMessageBox::Question,
		text,
		QStringList(),
		(key.isEmpty() ? QString::null : i18n("&Do not ask again")),
		&checkboxReturn,
		0);
#else
	// The following code is taken from KDialogBase.cc,
	// part of the KDE 2.2 libraries. Copyright 2001
	// by Waldo Bastian.
	//
	//
	QVBox *topcontents = new QVBox(dialog);

	topcontents->setSpacing(KDialog::spacingHint() * 2);
	topcontents->setMargin(KDialog::marginHint() * 2);

	QWidget *contents = new QWidget(topcontents);
	QHBoxLayout *lay = new QHBoxLayout(contents);

	lay->setSpacing(KDialog::spacingHint() * 2);

	lay->addStretch(1);
	QLabel *label1 = new QLabel( contents);
	label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Information));
	lay->add( label1 );
	QLabel *label2 = new QLabel( text, contents);
	label2->setMinimumSize(label2->sizeHint());
	lay->add(label2);
	lay->addStretch(1);

	QSize extraSize = QSize(50, 30);

	QCheckBox *checkbox = 0L;
	if (!key.isEmpty())
	{
		checkbox = new QCheckBox(i18n("Do not ask again"),topcontents);
		extraSize = QSize(50,0);
	}

	dialog->setMainWidget(topcontents);
	dialog->enableButtonSeparator(false);
	dialog->incInitialSize(extraSize);

	r = dialog->exec();
	if (checkbox)
	{
		checkboxReturn = checkbox->isChecked();
	}
#endif

	switch(r)
	{
	case KDialogBase::Yes : result=KMessageBox::Yes ; break;
	case KDialogBase::No  : result=KMessageBox::No; break;
	case KDialogBase::Cancel : result=KMessageBox::Cancel; break;
	default : break;
	}
	stopTickle();

	if (!key.isEmpty() && checkboxReturn)
	{
		KMessageBox::saveDontShowAgainYesNo(key,result);
	}

	return result;
}

<|endoftext|>


<commit_before>/*
 * PointProbe.cpp
 *
 *  Created on: Mar 10, 2009
 *      Author: Craig Rasmussen
 */

#include "PointProbe.hpp"
#include "../layers/HyPerLayer.hpp"
// #include "../layers/LIF.hpp" // Commented out May 18, 2011.  LIF-specific code moved to PointLIFProbe back in March.
#include <string.h>

namespace PV {

/**
 * @filename
 * @xLoc
 * @yLoc
 * @fLoc
 * @msg
 */
PointProbe::PointProbe(const char * filename, HyPerCol * hc, int xLoc, int yLoc, int fLoc,
      const char * msg) :
   LayerProbe(filename, hc)
{
   this->xLoc = xLoc;
   this->yLoc = yLoc;
   this->fLoc = fLoc;
   this->msg = strdup(msg);
   this->sparseOutput = false;
}

/**
 * @xLoc
 * @yLoc
 * @fLoc
 * @msg
 */
PointProbe::PointProbe(int xLoc, int yLoc, int fLoc, const char * msg) :
   LayerProbe()
{
   this->xLoc = xLoc;
   this->yLoc = yLoc;
   this->fLoc = fLoc;
   this->msg = strdup(msg);
   this->sparseOutput = false;
}

PointProbe::~PointProbe()
{
   free(msg);
}

/**
 * @time
 * @l
 * NOTES:
 *     - Only the activity buffer covers the extended frame - this is the frame that
 * includes boundaries.
 *     - The other dynamic variables (G_E, G_I, V, Vth) cover the "real" or "restricted"
 *     frame.
 *     - sparseOutput was introduced to deal with ConditionalProbes.
 *     - In MPI runs, xLoc and yLoc refer to global coordinates.
 *     writeState is only called by the processor with (xLoc,yLoc) in its
 *     non-extended region.
 */
int PointProbe::outputState(float time, HyPerLayer * l)
{
   // LIF * lif = dynamic_cast<LIF*>(l);  // Commented out May 18, 2011.  LIF-specific code moved to PointLIFProbe back in March.

   const PVLayerLoc * loc = l->getLayerLoc();

   const int kx0 = loc->kx0;
   const int ky0 = loc->ky0;
   const int nx = loc->nx;
   const int ny = loc->ny;
   const int xLocLocal = xLoc - kx0;
   const int yLocLocal = yLoc - ky0;
   if( xLocLocal < 0 || xLocLocal >= nx ||
       yLocLocal < 0 || yLocLocal >= ny) return PV_SUCCESS;
   const int nf = loc->nf;

   const int k = kIndex(xLocLocal, yLocLocal, fLoc, nx, ny, nf);
   const int kex = kIndexExtended(k, nx, ny, nf, loc->nb);

   return writeState(time, l, k, kex);
}

/**
 * @time
 * @l
 * @k
 * @kex
 */
int PointProbe::writeState(float time, HyPerLayer * l, int k, int kex) {

   const pvdata_t * V = l->getV();
   const pvdata_t * activity = l->getLayerData();

   if (sparseOutput) {
      fprintf(fp, " (%d %d %3.1f) \n", xLoc, yLoc, activity[kex]);
   }
   else if (activity[kex] != 0.0) {
      fprintf(fp, "%s t=%.1f", msg, time);
      fprintf(fp, " V=%6.5f", V[k]);
      fprintf(fp, " a=%.5f", activity[kex]);
      fprintf(fp, "\n");
      fflush(fp);
   }

   return PV_SUCCESS;
}

} // namespace PV
<commit_msg>Fix to PointProbe: if the V layer is not used, output zero instead of trying to reference the nonexistent layer and crashing<commit_after>/*
 * PointProbe.cpp
 *
 *  Created on: Mar 10, 2009
 *      Author: Craig Rasmussen
 */

#include "PointProbe.hpp"
#include "../layers/HyPerLayer.hpp"
// #include "../layers/LIF.hpp" // Commented out May 18, 2011.  LIF-specific code moved to PointLIFProbe back in March.
#include <string.h>

namespace PV {

/**
 * @filename
 * @xLoc
 * @yLoc
 * @fLoc
 * @msg
 */
PointProbe::PointProbe(const char * filename, HyPerCol * hc, int xLoc, int yLoc, int fLoc,
      const char * msg) :
   LayerProbe(filename, hc)
{
   this->xLoc = xLoc;
   this->yLoc = yLoc;
   this->fLoc = fLoc;
   this->msg = strdup(msg);
   this->sparseOutput = false;
}

/**
 * @xLoc
 * @yLoc
 * @fLoc
 * @msg
 */
PointProbe::PointProbe(int xLoc, int yLoc, int fLoc, const char * msg) :
   LayerProbe()
{
   this->xLoc = xLoc;
   this->yLoc = yLoc;
   this->fLoc = fLoc;
   this->msg = strdup(msg);
   this->sparseOutput = false;
}

PointProbe::~PointProbe()
{
   free(msg);
}

/**
 * @time
 * @l
 * NOTES:
 *     - Only the activity buffer covers the extended frame - this is the frame that
 * includes boundaries.
 *     - The other dynamic variables (G_E, G_I, V, Vth) cover the "real" or "restricted"
 *     frame.
 *     - sparseOutput was introduced to deal with ConditionalProbes.
 *     - In MPI runs, xLoc and yLoc refer to global coordinates.
 *     writeState is only called by the processor with (xLoc,yLoc) in its
 *     non-extended region.
 */
int PointProbe::outputState(float time, HyPerLayer * l)
{
   // LIF * lif = dynamic_cast<LIF*>(l);  // Commented out May 18, 2011.  LIF-specific code moved to PointLIFProbe back in March.

   const PVLayerLoc * loc = l->getLayerLoc();

   const int kx0 = loc->kx0;
   const int ky0 = loc->ky0;
   const int nx = loc->nx;
   const int ny = loc->ny;
   const int xLocLocal = xLoc - kx0;
   const int yLocLocal = yLoc - ky0;
   if( xLocLocal < 0 || xLocLocal >= nx ||
       yLocLocal < 0 || yLocLocal >= ny) return PV_SUCCESS;
   const int nf = loc->nf;

   const int k = kIndex(xLocLocal, yLocLocal, fLoc, nx, ny, nf);
   const int kex = kIndexExtended(k, nx, ny, nf, loc->nb);

   return writeState(time, l, k, kex);
}

/**
 * @time
 * @l
 * @k
 * @kex
 */
int PointProbe::writeState(float time, HyPerLayer * l, int k, int kex) {

   const pvdata_t * V = l->getV();
   const pvdata_t * activity = l->getLayerData();

   if (sparseOutput) {
      fprintf(fp, " (%d %d %3.1f) \n", xLoc, yLoc, activity[kex]);
   }
   else if (activity[kex] != 0.0) {
      fprintf(fp, "%s t=%.1f", msg, time);
      fprintf(fp, " V=%6.5f", V != NULL ? V[k] : 0.0f);
      fprintf(fp, " a=%.5f", activity[kex]);
      fprintf(fp, "\n");
      fflush(fp);
   }

   return PV_SUCCESS;
}

} // namespace PV
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2004-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "factory.h"
#include "factory_p.h"

#include "backendinterface.h"
#include "base_p.h"
#include "audiooutput.h"
#include "audiooutput_p.h"
#include "pluginfactory.h"

#include <QFile>
#include <QList>
#include <QCoreApplication>
#include <QtDBus/QtDBus>
#include <QPluginLoader>

#include <klocale.h>
#include <kmimetype.h>
#include "phononnamespace_p.h"
#include <kglobal.h>
#include <kservicetypetrader.h>
#include <klibloader.h>
#include <kmessage.h>
#include <QDir>
#include <QLibrary>
#include <QIcon>

#define PHONON_LOAD_BACKEND_GLOBAL 0

namespace Phonon
{

K_GLOBAL_STATIC(Phonon::FactoryPrivate, globalFactory)

void Factory::createBackend(const QString &library, const QString &version)
{
    Q_ASSERT(!globalFactory->m_backendObject);

    QString additionalConstraints = QLatin1String(" and Library == '") + library + QLatin1Char('\'');
    if (!version.isEmpty()) {
        additionalConstraints += QLatin1String(" and [X-KDE-PhononBackendInfo-Version] == '")
            + version + QLatin1Char('\'');
    }
    const KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("PhononBackend"),
            QString("Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1%1")
            .arg(additionalConstraints));
    if (offers.isEmpty()) {
        KMessage::message(KMessage::Error, i18n("Unable to find the requested Multimedia Backend"));
        return;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end && !globalFactory->createBackend(*it)) {
        ++it;
    }
}

bool FactoryPrivate::createBackend(KService::Ptr newService)
{
    KLibFactory *factory = 0;
#ifdef PHONON_LOAD_BACKEND_GLOBAL
    // This code is in here temporarily until NMM gets fixed.
    // Currently the NMM backend will fail with undefined symbols if
    // the backend is not loaded with global symbol resolution
    KLibrary *library = KLibLoader::self()->library(QFile::encodeName(newService->library()), QLibrary::ExportExternalSymbolsHint);
    if (library) {
        factory = library->factory();
    }
    //factory = KLibLoader::self()->factory(QFile::encodeName(newService->library()), QLibrary::ExportExternalSymbolsHint);
#else
    factory = KLibLoader::self()->factory(QFile::encodeName(newService->library()));
#endif
    if (!factory) {
        QString errorReason = KLibLoader::self()->lastErrorMessage();
        pError() << "Can not create factory for " << newService->name() <<
            ":\n" << errorReason << endl;

        KMessage::message(KMessage::Error,
                QLatin1String("<qt>")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String("<qt>"));
        return false;
    }

    m_backendObject = factory->create();
    if (0 == m_backendObject) {
        QString errorReason = i18n("create method returned 0");
        pError() << "Can not create backend object from factory for " <<
            newService->name() << ", " << newService->library() << ":\n" << errorReason << endl;

        KMessage::message(KMessage::Error,
                QLatin1String("<qt>")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String("<qt>"));
        return false;
    }

    service = newService;
    pDebug() << "using backend: " << newService->name();

    connect(m_backendObject, SIGNAL(objectDescriptionChanged(ObjectDescriptionType)),
            SLOT(objectDescriptionChanged(ObjectDescriptionType)));

    return true;
}

void FactoryPrivate::createBackend()
{
    const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
            "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
    if (offers.isEmpty()) {
        KMessage::message(KMessage::Error, i18n("Unable to find a Multimedia Backend"));
        return;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end && !createBackend(*it)) {
        ++it;
    }
}

FactoryPrivate::FactoryPrivate()
    : m_backendObject(0),
    m_pluginFactory(0)
{
    // Add the post routine to make sure that all other global statics (especially the ones from Qt)
    // are still available. If the FactoryPrivate dtor is called too late many bad things can happen
    // as the whole backend might still be alive.
    qAddPostRoutine(globalFactory.destroy);
    QDBusConnection::sessionBus().connect(QString(), QString(), "org.kde.Phonon.Factory",
            "phononBackendChanged", this, SLOT(phononBackendChanged()));
}

FactoryPrivate::~FactoryPrivate()
{
    emit aboutToBeDestroyed();

    foreach (BasePrivate *bp, basePrivateList) {
        bp->deleteBackendObject();
    }
    if (objects.size() > 0) {
        pError() << "The backend objects are not deleted as was requested." << endl;
        qDeleteAll(objects);
    }
    delete m_backendObject;
}

void FactoryPrivate::objectDescriptionChanged(ObjectDescriptionType type)
{
#ifdef PHONON_METHODTEST
    Q_UNUSED(type);
#else
    pDebug() << Q_FUNC_INFO << type;
    switch (type) {
    case AudioOutputDeviceType:
        // tell all AudioOutput objects to check their output device preference
        foreach (BasePrivate *obj, globalFactory->basePrivateList) {
            AudioOutputPrivate *output = AudioOutputPrivate::cast(obj);
            if (output) {
                output->deviceListChanged();
            }
        }
        break;
    default:
        break;
    }
    //emit capabilitiesChanged();
#endif // PHONON_METHODTEST
}

Factory::Sender *Factory::sender()
{
    return globalFactory;
}

void Factory::registerFrontendObject(BasePrivate *bp)
{
    globalFactory->basePrivateList.prepend(bp); // inserted last => deleted first
}

void Factory::deregisterFrontendObject(BasePrivate *bp)
{
    // The Factory can already be cleaned up while there are other frontend objects still alive.
    // When those are deleted they'll call deregisterFrontendObject through ~BasePrivate
    if (!globalFactory.isDestroyed()) {
        globalFactory->basePrivateList.removeAll(bp);
    }
}

void FactoryPrivate::phononBackendChanged()
{
    if (m_backendObject) {
        foreach (BasePrivate *bp, basePrivateList) {
            bp->deleteBackendObject();
        }
        if (objects.size() > 0) {
            pDebug() << "WARNING: we were asked to change the backend but the application did\n"
                "not free all references to objects created by the factory. Therefore we can not\n"
                "change the backend without crashing. Now we have to wait for a restart to make\n"
                "backendswitching possible.";
            // in case there were objects deleted give 'em a chance to recreate
            // them now
            foreach (BasePrivate *bp, basePrivateList) {
                bp->createBackendObject();
            }
            return;
        }
        delete m_backendObject;
        m_backendObject = 0;
    }
    createBackend();
    foreach (BasePrivate *bp, basePrivateList) {
        bp->createBackendObject();
    }
    emit backendChanged();
}

//X void Factory::freeSoundcardDevices()
//X {
//X     if (globalFactory->backend) {
//X         globalFactory->backend->freeSoundcardDevices();
//X     }
//X }

void FactoryPrivate::objectDestroyed(QObject * obj)
{
    //pDebug() << Q_FUNC_INFO << obj;
    objects.removeAll(obj);
}

#define FACTORY_IMPL(classname) \
QObject *Factory::create ## classname(QObject *parent) \
{ \
    if (backend()) { \
        return registerQObject(qobject_cast<BackendInterface *>(backend())->createObject(BackendInterface::classname##Class, parent)); \
    } \
    return 0; \
}
#define FACTORY_IMPL_1ARG(classname) \
QObject *Factory::create ## classname(int arg1, QObject *parent) \
{ \
    if (backend()) { \
        return registerQObject(qobject_cast<BackendInterface *>(backend())->createObject(BackendInterface::classname##Class, parent, QList<QVariant>() << arg1)); \
    } \
    return 0; \
}

FACTORY_IMPL(MediaObject)
FACTORY_IMPL(AudioPath)
FACTORY_IMPL_1ARG(AudioEffect)
FACTORY_IMPL(VolumeFaderEffect)
FACTORY_IMPL(AudioOutput)
FACTORY_IMPL(AudioDataOutput)
FACTORY_IMPL(Visualization)
FACTORY_IMPL(VideoPath)
FACTORY_IMPL_1ARG(VideoEffect)
FACTORY_IMPL(BrightnessControl)
FACTORY_IMPL(DeinterlaceFilter)
FACTORY_IMPL(VideoDataOutput)
FACTORY_IMPL(VideoWidget)

#undef FACTORY_IMPL

PluginFactory *FactoryPrivate::pluginFactory()
{
    if (!m_pluginFactory) {
        const QString suffix("/phonon_platform");
        foreach (QString libPath, QCoreApplication::libraryPaths()) {
            libPath += suffix;
            const QDir dir(libPath);
            if (!dir.exists()) {
                pDebug() << Q_FUNC_INFO << dir << "does not exist";
                continue;
            }
            QLibrary pluginLib(libPath + QLatin1String("/kde"));
            pluginLib.load();
            pDebug() << Q_FUNC_INFO << "trying to load " << pluginLib.fileName();
            QPluginLoader pluginLoader(pluginLib.fileName());
            Q_ASSERT(pluginLoader.load());
            pDebug() << pluginLoader.instance();
            m_pluginFactory = qobject_cast<PluginFactory *>(pluginLoader.instance());
            pDebug() << m_pluginFactory;
            if (m_pluginFactory) {
                return m_pluginFactory;
            }
        }
        if (!m_pluginFactory) {
            pDebug() << Q_FUNC_INFO << "phonon_platform/kde plugin could not be loaded";
        }
    }
    return m_pluginFactory;
}

AbstractMediaStream *Factory::createKioMediaStream(const QUrl &url, QObject *parent)
{
    PluginFactory *f = globalFactory->pluginFactory();
    if (!f) {
        return 0;
    }
    return f->createKioMediaStream(url, parent);
}

QIcon Factory::icon(const QString &name)
{
    PluginFactory *f = globalFactory->pluginFactory();
    if (!f) {
        return QIcon();
    }
    return f->icon(name);
}

void Factory::notification(const char *notificationName, const QString &text,
        const QStringList &actions, QObject *receiver,
        const char *actionSlot)
{
    PluginFactory *f = globalFactory->pluginFactory();
    if (f) {
        f->notification(notificationName, text, actions, receiver, actionSlot);
    }
}

QString Factory::applicationName()
{
    const PluginFactory *f = globalFactory->pluginFactory();
    if (f) {
        return f->applicationName();
    }
    return QCoreApplication::applicationName();
}

QObject *Factory::backend(bool createWhenNull)
{
    if (createWhenNull && globalFactory->m_backendObject == 0) {
        globalFactory->createBackend();
        // XXX: might create "reentrancy" problems:
        // a method calls this method and is called again because the
        // backendChanged signal is emitted
        emit globalFactory->backendChanged();
    }
    return globalFactory->m_backendObject;
}

QString Factory::identifier()
{
    if (globalFactory->service) {
        return globalFactory->service->library();
    }
    return QString();
}

QString Factory::backendName()
{
    if (globalFactory->service)
        return globalFactory->service->name();
    else
        return QString();
}

QString Factory::backendComment()
{
    if (globalFactory->service)
        return globalFactory->service->comment();
    else
        return QString();
}

QString Factory::backendVersion()
{
    if (globalFactory->service)
        return globalFactory->service->property("X-KDE-PhononBackendInfo-Version").toString();
    else
        return QString();
}

QString Factory::backendIcon()
{
    if (globalFactory->service)
        return globalFactory->service->icon();
    else
        return QString();
}

QString Factory::backendWebsite()
{
    if (globalFactory->service)
        return globalFactory->service->property("X-KDE-PhononBackendInfo-Website").toString();
    else
        return QString();
}

QObject *Factory::registerQObject(QObject *o)
{
    if (o) {
        QObject::connect(o, SIGNAL(destroyed(QObject *)), globalFactory, SLOT(objectDestroyed(QObject *)), Qt::DirectConnection);
        globalFactory->objects.append(o);
    }
    return o;
}

} //namespace Phonon

#include "factory.moc"
#include "factory_p.moc"

// vim: sw=4 ts=4
<commit_msg>apparently qDebug() << QDir() only works for debug builds<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2004-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "factory.h"
#include "factory_p.h"

#include "backendinterface.h"
#include "base_p.h"
#include "audiooutput.h"
#include "audiooutput_p.h"
#include "pluginfactory.h"

#include <QFile>
#include <QList>
#include <QCoreApplication>
#include <QtDBus/QtDBus>
#include <QPluginLoader>

#include <klocale.h>
#include <kmimetype.h>
#include "phononnamespace_p.h"
#include <kglobal.h>
#include <kservicetypetrader.h>
#include <klibloader.h>
#include <kmessage.h>
#include <QDir>
#include <QLibrary>
#include <QIcon>

#define PHONON_LOAD_BACKEND_GLOBAL 0

namespace Phonon
{

K_GLOBAL_STATIC(Phonon::FactoryPrivate, globalFactory)

void Factory::createBackend(const QString &library, const QString &version)
{
    Q_ASSERT(!globalFactory->m_backendObject);

    QString additionalConstraints = QLatin1String(" and Library == '") + library + QLatin1Char('\'');
    if (!version.isEmpty()) {
        additionalConstraints += QLatin1String(" and [X-KDE-PhononBackendInfo-Version] == '")
            + version + QLatin1Char('\'');
    }
    const KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("PhononBackend"),
            QString("Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1%1")
            .arg(additionalConstraints));
    if (offers.isEmpty()) {
        KMessage::message(KMessage::Error, i18n("Unable to find the requested Multimedia Backend"));
        return;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end && !globalFactory->createBackend(*it)) {
        ++it;
    }
}

bool FactoryPrivate::createBackend(KService::Ptr newService)
{
    KLibFactory *factory = 0;
#ifdef PHONON_LOAD_BACKEND_GLOBAL
    // This code is in here temporarily until NMM gets fixed.
    // Currently the NMM backend will fail with undefined symbols if
    // the backend is not loaded with global symbol resolution
    KLibrary *library = KLibLoader::self()->library(QFile::encodeName(newService->library()), QLibrary::ExportExternalSymbolsHint);
    if (library) {
        factory = library->factory();
    }
    //factory = KLibLoader::self()->factory(QFile::encodeName(newService->library()), QLibrary::ExportExternalSymbolsHint);
#else
    factory = KLibLoader::self()->factory(QFile::encodeName(newService->library()));
#endif
    if (!factory) {
        QString errorReason = KLibLoader::self()->lastErrorMessage();
        pError() << "Can not create factory for " << newService->name() <<
            ":\n" << errorReason << endl;

        KMessage::message(KMessage::Error,
                QLatin1String("<qt>")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String("<qt>"));
        return false;
    }

    m_backendObject = factory->create();
    if (0 == m_backendObject) {
        QString errorReason = i18n("create method returned 0");
        pError() << "Can not create backend object from factory for " <<
            newService->name() << ", " << newService->library() << ":\n" << errorReason << endl;

        KMessage::message(KMessage::Error,
                QLatin1String("<qt>")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String("<qt>"));
        return false;
    }

    service = newService;
    pDebug() << "using backend: " << newService->name();

    connect(m_backendObject, SIGNAL(objectDescriptionChanged(ObjectDescriptionType)),
            SLOT(objectDescriptionChanged(ObjectDescriptionType)));

    return true;
}

void FactoryPrivate::createBackend()
{
    const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
            "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
    if (offers.isEmpty()) {
        KMessage::message(KMessage::Error, i18n("Unable to find a Multimedia Backend"));
        return;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end && !createBackend(*it)) {
        ++it;
    }
}

FactoryPrivate::FactoryPrivate()
    : m_backendObject(0),
    m_pluginFactory(0)
{
    // Add the post routine to make sure that all other global statics (especially the ones from Qt)
    // are still available. If the FactoryPrivate dtor is called too late many bad things can happen
    // as the whole backend might still be alive.
    qAddPostRoutine(globalFactory.destroy);
    QDBusConnection::sessionBus().connect(QString(), QString(), "org.kde.Phonon.Factory",
            "phononBackendChanged", this, SLOT(phononBackendChanged()));
}

FactoryPrivate::~FactoryPrivate()
{
    emit aboutToBeDestroyed();

    foreach (BasePrivate *bp, basePrivateList) {
        bp->deleteBackendObject();
    }
    if (objects.size() > 0) {
        pError() << "The backend objects are not deleted as was requested." << endl;
        qDeleteAll(objects);
    }
    delete m_backendObject;
}

void FactoryPrivate::objectDescriptionChanged(ObjectDescriptionType type)
{
#ifdef PHONON_METHODTEST
    Q_UNUSED(type);
#else
    pDebug() << Q_FUNC_INFO << type;
    switch (type) {
    case AudioOutputDeviceType:
        // tell all AudioOutput objects to check their output device preference
        foreach (BasePrivate *obj, globalFactory->basePrivateList) {
            AudioOutputPrivate *output = AudioOutputPrivate::cast(obj);
            if (output) {
                output->deviceListChanged();
            }
        }
        break;
    default:
        break;
    }
    //emit capabilitiesChanged();
#endif // PHONON_METHODTEST
}

Factory::Sender *Factory::sender()
{
    return globalFactory;
}

void Factory::registerFrontendObject(BasePrivate *bp)
{
    globalFactory->basePrivateList.prepend(bp); // inserted last => deleted first
}

void Factory::deregisterFrontendObject(BasePrivate *bp)
{
    // The Factory can already be cleaned up while there are other frontend objects still alive.
    // When those are deleted they'll call deregisterFrontendObject through ~BasePrivate
    if (!globalFactory.isDestroyed()) {
        globalFactory->basePrivateList.removeAll(bp);
    }
}

void FactoryPrivate::phononBackendChanged()
{
    if (m_backendObject) {
        foreach (BasePrivate *bp, basePrivateList) {
            bp->deleteBackendObject();
        }
        if (objects.size() > 0) {
            pDebug() << "WARNING: we were asked to change the backend but the application did\n"
                "not free all references to objects created by the factory. Therefore we can not\n"
                "change the backend without crashing. Now we have to wait for a restart to make\n"
                "backendswitching possible.";
            // in case there were objects deleted give 'em a chance to recreate
            // them now
            foreach (BasePrivate *bp, basePrivateList) {
                bp->createBackendObject();
            }
            return;
        }
        delete m_backendObject;
        m_backendObject = 0;
    }
    createBackend();
    foreach (BasePrivate *bp, basePrivateList) {
        bp->createBackendObject();
    }
    emit backendChanged();
}

//X void Factory::freeSoundcardDevices()
//X {
//X     if (globalFactory->backend) {
//X         globalFactory->backend->freeSoundcardDevices();
//X     }
//X }

void FactoryPrivate::objectDestroyed(QObject * obj)
{
    //pDebug() << Q_FUNC_INFO << obj;
    objects.removeAll(obj);
}

#define FACTORY_IMPL(classname) \
QObject *Factory::create ## classname(QObject *parent) \
{ \
    if (backend()) { \
        return registerQObject(qobject_cast<BackendInterface *>(backend())->createObject(BackendInterface::classname##Class, parent)); \
    } \
    return 0; \
}
#define FACTORY_IMPL_1ARG(classname) \
QObject *Factory::create ## classname(int arg1, QObject *parent) \
{ \
    if (backend()) { \
        return registerQObject(qobject_cast<BackendInterface *>(backend())->createObject(BackendInterface::classname##Class, parent, QList<QVariant>() << arg1)); \
    } \
    return 0; \
}

FACTORY_IMPL(MediaObject)
FACTORY_IMPL(AudioPath)
FACTORY_IMPL_1ARG(AudioEffect)
FACTORY_IMPL(VolumeFaderEffect)
FACTORY_IMPL(AudioOutput)
FACTORY_IMPL(AudioDataOutput)
FACTORY_IMPL(Visualization)
FACTORY_IMPL(VideoPath)
FACTORY_IMPL_1ARG(VideoEffect)
FACTORY_IMPL(BrightnessControl)
FACTORY_IMPL(DeinterlaceFilter)
FACTORY_IMPL(VideoDataOutput)
FACTORY_IMPL(VideoWidget)

#undef FACTORY_IMPL

PluginFactory *FactoryPrivate::pluginFactory()
{
    if (!m_pluginFactory) {
        const QString suffix("/phonon_platform");
        foreach (QString libPath, QCoreApplication::libraryPaths()) {
            libPath += suffix;
            const QDir dir(libPath);
            if (!dir.exists()) {
                pDebug() << Q_FUNC_INFO << dir.canonicalPath() << "does not exist";
                continue;
            }
            QLibrary pluginLib(libPath + QLatin1String("/kde"));
            pluginLib.load();
            pDebug() << Q_FUNC_INFO << "trying to load " << pluginLib.fileName();
            QPluginLoader pluginLoader(pluginLib.fileName());
            Q_ASSERT(pluginLoader.load());
            pDebug() << pluginLoader.instance();
            m_pluginFactory = qobject_cast<PluginFactory *>(pluginLoader.instance());
            pDebug() << m_pluginFactory;
            if (m_pluginFactory) {
                return m_pluginFactory;
            }
        }
        if (!m_pluginFactory) {
            pDebug() << Q_FUNC_INFO << "phonon_platform/kde plugin could not be loaded";
        }
    }
    return m_pluginFactory;
}

AbstractMediaStream *Factory::createKioMediaStream(const QUrl &url, QObject *parent)
{
    PluginFactory *f = globalFactory->pluginFactory();
    if (!f) {
        return 0;
    }
    return f->createKioMediaStream(url, parent);
}

QIcon Factory::icon(const QString &name)
{
    PluginFactory *f = globalFactory->pluginFactory();
    if (!f) {
        return QIcon();
    }
    return f->icon(name);
}

void Factory::notification(const char *notificationName, const QString &text,
        const QStringList &actions, QObject *receiver,
        const char *actionSlot)
{
    PluginFactory *f = globalFactory->pluginFactory();
    if (f) {
        f->notification(notificationName, text, actions, receiver, actionSlot);
    }
}

QString Factory::applicationName()
{
    const PluginFactory *f = globalFactory->pluginFactory();
    if (f) {
        return f->applicationName();
    }
    return QCoreApplication::applicationName();
}

QObject *Factory::backend(bool createWhenNull)
{
    if (createWhenNull && globalFactory->m_backendObject == 0) {
        globalFactory->createBackend();
        // XXX: might create "reentrancy" problems:
        // a method calls this method and is called again because the
        // backendChanged signal is emitted
        emit globalFactory->backendChanged();
    }
    return globalFactory->m_backendObject;
}

QString Factory::identifier()
{
    if (globalFactory->service) {
        return globalFactory->service->library();
    }
    return QString();
}

QString Factory::backendName()
{
    if (globalFactory->service)
        return globalFactory->service->name();
    else
        return QString();
}

QString Factory::backendComment()
{
    if (globalFactory->service)
        return globalFactory->service->comment();
    else
        return QString();
}

QString Factory::backendVersion()
{
    if (globalFactory->service)
        return globalFactory->service->property("X-KDE-PhononBackendInfo-Version").toString();
    else
        return QString();
}

QString Factory::backendIcon()
{
    if (globalFactory->service)
        return globalFactory->service->icon();
    else
        return QString();
}

QString Factory::backendWebsite()
{
    if (globalFactory->service)
        return globalFactory->service->property("X-KDE-PhononBackendInfo-Website").toString();
    else
        return QString();
}

QObject *Factory::registerQObject(QObject *o)
{
    if (o) {
        QObject::connect(o, SIGNAL(destroyed(QObject *)), globalFactory, SLOT(objectDestroyed(QObject *)), Qt::DirectConnection);
        globalFactory->objects.append(o);
    }
    return o;
}

} //namespace Phonon

#include "factory.moc"
#include "factory_p.moc"

// vim: sw=4 ts=4
<|endoftext|>


<commit_before><commit_msg>mrcalc: fix a few minor issues in individual operators<commit_after><|endoftext|>


<commit_before>/**
 * Non-metric Space Library
 *
 * Authors: Bilegsaikhan Naidan (https://github.com/bileg), Leonid Boytsov (http://boytsov.info).
 * With contributions from Lawrence Cayton (http://lcayton.com/) and others.
 *
 * For the complete list of contributors and further details see:
 * https://github.com/searchivarius/NonMetricSpaceLib
 *
 * Copyright (c) 2014
 *
 * This code is released under the
 * Apache License Version 2.0 http://www.apache.org/licenses/.
 *
 */
#include <string>
#include <fstream>

#include <boost/program_options.hpp>

#include "knnquery.h"
#include "knnqueue.h"
#include "space.h"
#include "params.h"
#include "projection.h"
#include "spacefactory.h"
#include "init.h"

using namespace similarity;
using namespace std;

namespace po = boost::program_options;

static void Usage(const char *prog,
                  const po::options_description& desc) {
    std::cout << prog << std::endl
              << desc << std::endl;
}

template <class dist_t>
void benchProjection(string spaceType,
                     string inFile, string outFile,
                     string projType, unsigned knn, string projSpaceType,
                     unsigned nIntermDim,
                     unsigned nDstDim,
                     unsigned binThreshold,
                     unsigned maxNumData,
                     unsigned sampleRandPairQty, unsigned sampleKNNQueryQty, unsigned sampleKNNTotalQty) {
  ToLower(spaceType);
  vector<string> spaceDesc;

  const string descStr = spaceType;
  ParseSpaceArg(descStr, spaceType, spaceDesc);
  unique_ptr<AnyParams> spaceParams =
            unique_ptr<AnyParams>(new AnyParams(spaceDesc));

  unique_ptr<Space<dist_t>> space(SpaceFactoryRegistry<dist_t>::
                                Instance().CreateSpace(spaceType, *spaceParams));

  if (NULL == space.get()) {
    LOG(LIB_FATAL) << "Cannot create the space: '" << spaceType
                   << "' (desc: '" << descStr << "')";
  }

  ToLower(projSpaceType);
  vector<string> projSpaceDesc;

  const string projDescStr = projSpaceType;
  ParseSpaceArg(projDescStr, projSpaceType, projSpaceDesc);
  unique_ptr<AnyParams> projSpaceParams =
            unique_ptr<AnyParams>(new AnyParams(projSpaceDesc));

  unique_ptr<Space<float>> projSpace(SpaceFactoryRegistry<dist_t>::
                                Instance().CreateSpace(projSpaceType, *projSpaceParams));

  if (NULL == projSpace.get()) {
    LOG(LIB_FATAL) << "Cannot create the projection space: '" << projSpaceType
                   << "' (desc: '" << projDescStr << "')";
  }

  const VectorSpaceSimpleStorage<float>*  ps =
      dynamic_cast<const VectorSpaceSimpleStorage<float>*>(projSpace.get());

  if (NULL == ps) {
    LOG(LIB_FATAL) << "The target projection space: '" << projDescStr << "' "
                   << " should be a simple-storage dense vector space, e.g., l2";
  }

  ObjectVector data;
  LOG(LIB_INFO) << "maxNumData=" << maxNumData;
  space->ReadDataset(data, NULL, inFile.c_str(), maxNumData);

  size_t N = data.size();

  unique_ptr<Projection<dist_t> > projObj(
      Projection<dist_t>::createProjection(
                        space.get(),
                        data,
                        projType,
                        nIntermDim,
                        nDstDim,
                        binThreshold));

  ofstream out(outFile);

  if (N > 0) {
    vector<float>   v1(nDstDim), v2(nDstDim);

    vector<IdType>  vId1, vId2;
    vector<dist_t>  vOrigDist;

    for (size_t i = 0; i < sampleRandPairQty; ++i) {
      IdType id1 = RandomInt() % N;
      IdType id2 = RandomInt() % N;
      vId1.push_back(id1);
      vId2.push_back(id2);
      vOrigDist.push_back(space->IndexTimeDistance(data[id1], data[id2]));
    }

    CHECK(vId1.size() == vId2.size());
    CHECK(vId1.size() == vOrigDist.size());

    size_t iter = 0;
    size_t startId = vOrigDist.size();

    LOG(LIB_INFO) << "sampleRandPairQty=" << sampleRandPairQty;
    LOG(LIB_INFO) << "sampleKNNQueryQty=" << sampleKNNQueryQty;
    LOG(LIB_INFO) << "sampleKNNTotalQty=" << sampleKNNTotalQty;

    for (size_t i = 0; i < sampleKNNQueryQty; ++i) {
      IdType id1 = RandomInt() % N;

      KNNQuery<dist_t> query(space.get(), data[id1], knn);

      // Brute force search
      for (size_t i = 0; i < N; ++i) {
        query.CheckAndAddToResult(data[i]);
      }

      unique_ptr<KNNQueue<dist_t>> knnQ(query.Result()->Clone());

      // Extracting results
      while (!knnQ->Empty()) {
        // Reservoir sampling
        int selectIndex = -1;
        ++iter;
        if (iter > sampleKNNTotalQty) {
          selectIndex = RandomInt() % iter; // from 0 to iter
        } else {
          vOrigDist.push_back(-1);
          vId1.push_back(-1);
          vId2.push_back(-1);
          selectIndex = vOrigDist.size() - 1 - startId;
        }

        if (selectIndex >= 0 && selectIndex < vOrigDist.size() - startId) {
          size_t replIndex = selectIndex + startId;
          vOrigDist[replIndex] = knnQ->TopDistance();
          vId1[replIndex] = id1;
          vId2[replIndex] = knnQ->TopObject()->id();
        }

        knnQ->Pop();
      }
    }

    for (size_t i = 0; i < vOrigDist.size(); ++i) {
      projObj->compProj(NULL, data[vId1[i]], &v1[0]);
      projObj->compProj(NULL, data[vId2[i]], &v2[0]);

      CHECK(vId1[i] >= 0);
      CHECK(vId2[i] >= 0);

      unique_ptr<Object> obj1(ps->CreateObjFromVect(-1, -1, v1));
      unique_ptr<Object> obj2(ps->CreateObjFromVect(-1, -1, v2));

      float projDist = ps->IndexTimeDistance(obj1.get(), obj2.get());

      out << vOrigDist[i] << "\t" << projDist << endl;
    }
  }
}

int main(int argc, char *argv[]) {
  string      spaceType, distType, projSpaceType;
  string      inFile, outFile;
  string      projType;
  string      logFile;
  unsigned    maxNumData = 0;
  unsigned    sampleRandPairQty = 0;
  unsigned    sampleKNNQueryQty = 0;
  unsigned    sampleKNNTotalQty = 0;
  unsigned    nIntermDim   = 0;
  unsigned    binThreshold = 0;
  unsigned    nDstDim;
  unsigned    knn = 0;

  po::options_description ProgOptDesc("Allowed options");
  ProgOptDesc.add_options()
    ("help,h", "produce help message")
    ("spaceType,s",     po::value<string>(&spaceType)->required(),
                        "space type, e.g., l1, l2, lp:p=0.5")
    ("projSpaceType",   po::value<string>(&projSpaceType)->default_value("l2"),
                        "space type in the projection space, e.g., l1, l2, lp:p=0.5. "
                        "should be a dense vector space!")
    ("distType",        po::value<string>(&distType)->default_value("float"),
                        "distance value type: int, float, double")
    ("inFile,i",        po::value<string>(&inFile)->required(),
                        "input data file")
    ("outFile,o",       po::value<string>(&outFile)->required(),
                        "output data file")
    ("projType,p",      po::value<string>(&projType)->required(),
                        "projection type")
    ("sampleRandPairQty",po::value<unsigned>(&sampleRandPairQty)->default_value(0),
                        "number of randomly selected pairs")
    ("sampleKNNQueryQty",po::value<unsigned>(&sampleKNNQueryQty)->default_value(0),
                        "number of randomly selected queries")
    ("sampleKNNTotalQty",po::value<unsigned>(&sampleKNNTotalQty)->default_value(0),
                        "a total number of randomly selected queries' nearest neighbors (should be >= sampleKNNQueryQty)")
    ("knn,k",           po::value<unsigned>(&knn)->default_value(0),
                        "use this number of nearest neighbors (should be > 0 if sampleKNNQueryQty > 0)")
    ("intermDim",       po::value<unsigned>(&nIntermDim)->default_value(0),
                        "intermediate dimensionality, used only for sparse vector spaces")
    ("projDim",          po::value<unsigned>(&nDstDim)->required(),
                        "dimensionality in the target space (where we project to)")
    ("binThreshold",    po::value<unsigned>(&binThreshold)->default_value(0),
                        "binarization threshold, used only for permutations")
    ("maxNumData",      po::value<unsigned>(&maxNumData)->default_value(0),
                        "if non-zero, only the first maxNumData elements are used")
    ("logFile,l",       po::value<string>(&logFile)->default_value(""),
                        "log file")
     ;

  po::variables_map vm;

  try {
    po::store(po::parse_command_line(argc, argv, ProgOptDesc), vm);
    po::notify(vm);
  } catch (const exception& e) {
    Usage(argv[0], ProgOptDesc);
    LOG(LIB_FATAL) << e.what();
  }

  if (vm.count("help")  ) {
    Usage(argv[0], ProgOptDesc);
    exit(0);
  }

  initLibrary(logFile.empty() ? LIB_LOGSTDERR:LIB_LOGFILE, logFile.c_str());

  LOG(LIB_INFO) << "Program arguments are processed";

  ToLower(distType);

  try {
    if (sampleKNNQueryQty) {
      if (!knn) LOG(LIB_FATAL) << "Please, specify knn > 0";
      if (sampleKNNTotalQty < sampleKNNQueryQty) {
        LOG(LIB_FATAL) << "sampleKNNTotalQty should be at least as large as sampleKNNQueryQty";
      }
    }
    if (distType == "float") {
      benchProjection<float>(spaceType, inFile, outFile,
                             projType, knn, projSpaceType,
                             nIntermDim, nDstDim, binThreshold,
                             maxNumData,
                             sampleRandPairQty, sampleKNNQueryQty, sampleKNNTotalQty);
    } else if (distType == "double") {
      benchProjection<float>(spaceType, inFile, outFile,
                             projType, knn, projSpaceType,
                             nIntermDim, nDstDim, binThreshold,
                             maxNumData,
                             sampleRandPairQty, sampleKNNQueryQty, sampleKNNTotalQty);
    } else {
      LOG(LIB_FATAL) << "Unsupported distance type: '" << distType << "'";
    }
  } catch (const exception& e) {
    Usage(argv[0], ProgOptDesc);
    LOG(LIB_FATAL) << "Exception: " << e.what();
  }

  return 0;
};
<commit_msg>repeating for projection recreation<commit_after>/**
 * Non-metric Space Library
 *
 * Authors: Bilegsaikhan Naidan (https://github.com/bileg), Leonid Boytsov (http://boytsov.info).
 * With contributions from Lawrence Cayton (http://lcayton.com/) and others.
 *
 * For the complete list of contributors and further details see:
 * https://github.com/searchivarius/NonMetricSpaceLib
 *
 * Copyright (c) 2014
 *
 * This code is released under the
 * Apache License Version 2.0 http://www.apache.org/licenses/.
 *
 */
#include <string>
#include <fstream>

#include <boost/program_options.hpp>

#include "knnquery.h"
#include "knnqueue.h"
#include "space.h"
#include "params.h"
#include "projection.h"
#include "spacefactory.h"
#include "init.h"

using namespace similarity;
using namespace std;

namespace po = boost::program_options;

static void Usage(const char *prog,
                  const po::options_description& desc) {
    std::cout << prog << std::endl
              << desc << std::endl;
}

template <class dist_t>
void benchProjection(size_t repeatQty,
                     string spaceType,
                     string inFile, string outFile,
                     string projType, unsigned knn, string projSpaceType,
                     unsigned nIntermDim,
                     unsigned nDstDim,
                     unsigned binThreshold,
                     unsigned maxNumData,
                     unsigned sampleRandPairQty, unsigned sampleKNNQueryQty, unsigned sampleKNNTotalQty) {
  ToLower(spaceType);
  vector<string> spaceDesc;

  const string descStr = spaceType;
  ParseSpaceArg(descStr, spaceType, spaceDesc);
  unique_ptr<AnyParams> spaceParams =
            unique_ptr<AnyParams>(new AnyParams(spaceDesc));

  unique_ptr<Space<dist_t>> space(SpaceFactoryRegistry<dist_t>::
                                Instance().CreateSpace(spaceType, *spaceParams));

  if (NULL == space.get()) {
    LOG(LIB_FATAL) << "Cannot create the space: '" << spaceType
                   << "' (desc: '" << descStr << "')";
  }

  ToLower(projSpaceType);
  vector<string> projSpaceDesc;

  const string projDescStr = projSpaceType;
  ParseSpaceArg(projDescStr, projSpaceType, projSpaceDesc);
  unique_ptr<AnyParams> projSpaceParams =
            unique_ptr<AnyParams>(new AnyParams(projSpaceDesc));

  unique_ptr<Space<float>> projSpace(SpaceFactoryRegistry<dist_t>::
                                Instance().CreateSpace(projSpaceType, *projSpaceParams));

  if (NULL == projSpace.get()) {
    LOG(LIB_FATAL) << "Cannot create the projection space: '" << projSpaceType
                   << "' (desc: '" << projDescStr << "')";
  }

  const VectorSpaceSimpleStorage<float>*  ps =
      dynamic_cast<const VectorSpaceSimpleStorage<float>*>(projSpace.get());

  if (NULL == ps) {
    LOG(LIB_FATAL) << "The target projection space: '" << projDescStr << "' "
                   << " should be a simple-storage dense vector space, e.g., l2";
  }

  ObjectVector data;
  LOG(LIB_INFO) << "maxNumData=" << maxNumData;
  space->ReadDataset(data, NULL, inFile.c_str(), maxNumData);

  size_t N = data.size();

  unique_ptr<Projection<dist_t> > projObj;

  ofstream out(outFile);

  LOG(LIB_INFO) << "sampleRandPairQty=" << sampleRandPairQty;
  LOG(LIB_INFO) << "sampleKNNQueryQty=" << sampleKNNQueryQty;
  LOG(LIB_INFO) << "sampleKNNTotalQty=" << sampleKNNTotalQty;
  LOG(LIB_INFO) << "recreating projections #times=" << repeatQty;

  if (N > 0)
  for (size_t rr = 0; rr < repeatQty; ++rr) {
    probObj.reset(
      Projection<dist_t>::createProjection(
                        space.get(),
                        data,
                        projType,
                        nIntermDim,
                        nDstDim,
                        binThreshold));

    vector<float>   v1(nDstDim), v2(nDstDim);

    vector<IdType>  vId1, vId2;
    vector<dist_t>  vOrigDist;

    for (size_t i = 0; i < sampleRandPairQty; ++i) {
      IdType id1 = RandomInt() % N;
      IdType id2 = RandomInt() % N;
      vId1.push_back(id1);
      vId2.push_back(id2);
      vOrigDist.push_back(space->IndexTimeDistance(data[id1], data[id2]));
    }

    CHECK(vId1.size() == vId2.size());
    CHECK(vId1.size() == vOrigDist.size());

    size_t iter = 0;
    size_t startId = vOrigDist.size();

    for (size_t i = 0; i < sampleKNNQueryQty; ++i) {
      IdType id1 = RandomInt() % N;

      KNNQuery<dist_t> query(space.get(), data[id1], knn);

      // Brute force search
      for (size_t i = 0; i < N; ++i) {
        query.CheckAndAddToResult(data[i]);
      }

      unique_ptr<KNNQueue<dist_t>> knnQ(query.Result()->Clone());

      // Extracting results
      while (!knnQ->Empty()) {
        // Reservoir sampling
        int selectIndex = -1;
        ++iter;
        if (iter > sampleKNNTotalQty) {
          selectIndex = RandomInt() % iter; // from 0 to iter
        } else {
          vOrigDist.push_back(-1);
          vId1.push_back(-1);
          vId2.push_back(-1);
          selectIndex = vOrigDist.size() - 1 - startId;
        }

        if (selectIndex >= 0 && selectIndex < vOrigDist.size() - startId) {
          size_t replIndex = selectIndex + startId;
          vOrigDist[replIndex] = knnQ->TopDistance();
          vId1[replIndex] = id1;
          vId2[replIndex] = knnQ->TopObject()->id();
        }

        knnQ->Pop();
      }
    }

    for (size_t i = 0; i < vOrigDist.size(); ++i) {
      projObj->compProj(NULL, data[vId1[i]], &v1[0]);
      projObj->compProj(NULL, data[vId2[i]], &v2[0]);

      CHECK(vId1[i] >= 0);
      CHECK(vId2[i] >= 0);

      unique_ptr<Object> obj1(ps->CreateObjFromVect(-1, -1, v1));
      unique_ptr<Object> obj2(ps->CreateObjFromVect(-1, -1, v2));

      float projDist = ps->IndexTimeDistance(obj1.get(), obj2.get());

      out << vOrigDist[i] << "\t" << projDist << endl;
    }
  }
}

int main(int argc, char *argv[]) {
  string      spaceType, distType, projSpaceType;
  string      inFile, outFile;
  string      projType;
  string      logFile;
  unsigned    maxNumData = 0;
  unsigned    sampleRandPairQty = 0;
  unsigned    sampleKNNQueryQty = 0;
  unsigned    sampleKNNTotalQty = 0;
  unsigned    nIntermDim   = 0;
  unsigned    binThreshold = 0;
  unsigned    nDstDim;
  unsigned    knn = 0;
  unsigned    repeatQty = 1;

  po::options_description ProgOptDesc("Allowed options");
  ProgOptDesc.add_options()
    ("help,h", "produce help message")
    ("spaceType,s",     po::value<string>(&spaceType)->required(),
                        "space type, e.g., l1, l2, lp:p=0.5")
    ("projSpaceType",   po::value<string>(&projSpaceType)->default_value("l2"),
                        "space type in the projection space, e.g., l1, l2, lp:p=0.5. "
                        "should be a dense vector space!")
    ("distType",        po::value<string>(&distType)->default_value("float"),
                        "distance value type: int, float, double")
    ("inFile,i",        po::value<string>(&inFile)->required(),
                        "input data file")
    ("outFile,o",       po::value<string>(&outFile)->required(),
                        "output data file")
    ("projType,p",      po::value<string>(&projType)->required(),
                        "projection type")
    ("sampleRandPairQty",po::value<unsigned>(&sampleRandPairQty)->default_value(0),
                        "number of randomly selected pairs")
    ("sampleKNNQueryQty",po::value<unsigned>(&sampleKNNQueryQty)->default_value(0),
                        "number of randomly selected queries")
    ("sampleKNNTotalQty",po::value<unsigned>(&sampleKNNTotalQty)->default_value(0),
                        "a total number of randomly selected queries' nearest neighbors (should be >= sampleKNNQueryQty)")
    ("knn,k",           po::value<unsigned>(&knn)->default_value(0),
                        "use this number of nearest neighbors (should be > 0 if sampleKNNQueryQty > 0)")
    ("repeat,r",        po::value<unsigned>(&repeatQty)->default_value(10),
                        "recreate projections this number of times")
    ("intermDim",       po::value<unsigned>(&nIntermDim)->default_value(0),
                        "intermediate dimensionality, used only for sparse vector spaces")
    ("projDim",          po::value<unsigned>(&nDstDim)->required(),
                        "dimensionality in the target space (where we project to)")
    ("binThreshold",    po::value<unsigned>(&binThreshold)->default_value(0),
                        "binarization threshold, used only for permutations")
    ("maxNumData",      po::value<unsigned>(&maxNumData)->default_value(0),
                        "if non-zero, only the first maxNumData elements are used")
    ("logFile,l",       po::value<string>(&logFile)->default_value(""),
                        "log file")
     ;

  po::variables_map vm;

  try {
    po::store(po::parse_command_line(argc, argv, ProgOptDesc), vm);
    po::notify(vm);
  } catch (const exception& e) {
    Usage(argv[0], ProgOptDesc);
    LOG(LIB_FATAL) << e.what();
  }

  if (vm.count("help")  ) {
    Usage(argv[0], ProgOptDesc);
    exit(0);
  }

  initLibrary(logFile.empty() ? LIB_LOGSTDERR:LIB_LOGFILE, logFile.c_str());

  LOG(LIB_INFO) << "Program arguments are processed";

  ToLower(distType);

  try {
    if (sampleKNNQueryQty) {
      if (!knn) LOG(LIB_FATAL) << "Please, specify knn > 0";
      if (sampleKNNTotalQty < sampleKNNQueryQty) {
        LOG(LIB_FATAL) << "sampleKNNTotalQty should be at least as large as sampleKNNQueryQty";
      }
    }
    if (distType == "float") {
      benchProjection<float>(repeatQty, spaceType, inFile, outFile,
                             projType, knn, projSpaceType,
                             nIntermDim, nDstDim, binThreshold,
                             maxNumData,
                             sampleRandPairQty, sampleKNNQueryQty, sampleKNNTotalQty);
    } else if (distType == "double") {
      benchProjection<float>(repeatQty, spaceType, inFile, outFile,
                             projType, knn, projSpaceType,
                             nIntermDim, nDstDim, binThreshold,
                             maxNumData,
                             sampleRandPairQty, sampleKNNQueryQty, sampleKNNTotalQty);
    } else {
      LOG(LIB_FATAL) << "Unsupported distance type: '" << distType << "'";
    }
  } catch (const exception& e) {
    Usage(argv[0], ProgOptDesc);
    LOG(LIB_FATAL) << "Exception: " << e.what();
  }

  return 0;
};
<|endoftext|>


<commit_before>/*
   +----------------------------------------------------------------------+
   | HipHop for PHP                                                       |
   +----------------------------------------------------------------------+
   | Copyright (c) 2015 Alexandre Kalendarev                              |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+

	 part this code was derived from tarantool/msgpuck, author Roman Tsisyk

	 for HHVM version 3.13
*/

/*
  KindOfUninit          = 0x00,  //  00000000    0
  KindOfNull            = 0x01,  //  00000001    1
  KindOfBoolean         = 0x09,  //  00001001    9
  KindOfInt64           = 0x11,  //  00010001   17
  KindOfDouble          = 0x19,  //  00011001   25
  KindOfPersistentString = 0x1b, //  00011011   27
  KindOfPersistentArray = 0x1d,  //  00011101   29
  KindOfString          = 0x22,  //  00100010   34
  KindOfArray           = 0x34,  //  00110100   52
  KindOfObject          = 0x40,  //  01000000   64
  KindOfResource        = 0x50,  //  01010000
  KindOfRef             = 0x60,  //  01100000
*/

#include "hphp/runtime/ext/extension.h"
#include "hphp/runtime/base/execution-context.h"  // g_context

#define MP_SOURCE 1
#include "msgpuck.h"
#include "msgpack.h"

namespace HPHP {

#define BUFFSIZE 1024

static void printVariant(const Variant& data);
static void packVariant(const Variant& el);

static void test(const Array& el);

/**
* return true if PHP Array as map
*/
static bool checkIsMap(const Array& data) {
	int i =0;
	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
        pos = data->iter_advance(pos)) {
		const Variant key = data->getKey(pos);
		if (!key.isInteger()) {
 			return true;
		}
		if ( key.toInt64() != i) {
			return true;
		}

		i++;
	}

	return false;
}

static int sizeof_pack( const Array& data ) {

	int size = 0;

	for (int i=0; i < data.length(); i++) {
		Variant el(data[i]);
		switch(el.getType()) {

			case KindOfInt64 : {
				size += mp_sizeof_int( el.toInt64() );
				break;
			}

			case KindOfNull : {
				size += mp_sizeof_nil();
				break;
			}

			case KindOfPersistentString:
			case KindOfString : {

				size += mp_sizeof_str( el.toString().length());
				break;
			}

			case KindOfPersistentArray :
			case KindOfArray : {

				size += mp_sizeof_array( el.toArray().size() );
				int arr_size = sizeof_pack( el.toArray() );
				size += arr_size;
				break;
			}

			case KindOfDouble :
				size += mp_sizeof_float(el.toDouble());
				break;

			case KindOfBoolean :
				size += mp_sizeof_bool(el.toBoolean());
				break;

			default : g_context->write( "wrong\n");
		}
	}

	return size;
}

static void mapIteration(ArrayData* data, void  (mapIterationCb) (const Variant& , const Variant&)) {

	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
	       pos = data->iter_advance(pos)) {
	       const Variant key = data->getKey(pos);
	   	   const Variant val = data->getValue(pos);
	   	   mapIterationCb(key, val);
	}
}

static void arrayIteration(ArrayData* data, void  (arrayIterationCb) (const Variant&)) {

	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
	       pos = data->iter_advance(pos)) {
	   	   const Variant val = data->getValue(pos);
	   	   arrayIterationCb(val);
	}
}

static void encodeMapElement(const Variant& key, const Variant& val) {
	packVariant(key);
	packVariant(val);
}

static void encodeArrayElement(const Variant& val) {
	packVariant(val);
}

static void test(const Array& data) {
	printf( "call %s:%d\n", __FUNCTION__, __LINE__);

	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
       pos = data->iter_advance(pos)) {
       const Variant key = data->getKey(pos);

   	   if (key.isString())
   	   		printf("key : [%s]\t", key.toString().c_str());
   	   else if (key.isInteger())
   	    		printf("key : [%ld]\t", key.toInt64());
   	    else
   	    	printf("unknow type: %d",  (int)key.getType());

   	    const Variant val = data->getValue(pos);

   	   if (val.isString())
   	   		printf(" => [%s]\n", val.toString().c_str());
   	   else if (val.isInteger())
   	    		printf(" => [%ld]\n", val.toInt64());
   	   else if (val.isDouble())
   	    		printf(" => [%f]\n", val.toDouble());
   	   else if (val.isBoolean())
   	    		printf(" => %s\n" , val.toBoolean() ? "true" : "false");
   	   else if (val.isArray())
   	    		printf(" => Array\n");
   	   else if (val.isNull())
   	    		printf(" => NULL\n");
   	    else
   	    	printf("unknow type: %d\r",  (int)val.getType());

   	    if (val.isArray()) {
   	    	test(val.toArray());
   	    }

	}

}

static void packVariant(const Variant& el) {

printf("packVariant type: %d\n", (int)el.getType());

	switch(el.getType()) {
		case KindOfInt64 : {
			int64_t int_val = el.toInt64();
			if (int_val >= 0)
				MsgpackExtension::BufferPtr = mp_encode_uint(MsgpackExtension::BufferPtr,  int_val );
			else
				MsgpackExtension::BufferPtr = mp_encode_int(MsgpackExtension::BufferPtr,  int_val );
			break; }

		case KindOfNull : {
			MsgpackExtension::BufferPtr = mp_encode_nil(MsgpackExtension::BufferPtr);
			break; }

		case KindOfBoolean : {
			MsgpackExtension::BufferPtr = mp_encode_bool(MsgpackExtension::BufferPtr, el.toBoolean());
			break;
		}

		case KindOfPersistentString :
		case KindOfString : {
			MsgpackExtension::BufferPtr = mp_encode_str(MsgpackExtension::BufferPtr, el.toString().c_str(), el.toString().length());
			break;
		}

		case KindOfPersistentArray :
		case KindOfArray : {

				bool isMap = checkIsMap(el.toArray());
				ArrayData* ad = el.toArray().get();
				if (isMap) {
					MsgpackExtension::BufferPtr = mp_encode_map(MsgpackExtension::BufferPtr, el.toArray().length());
					mapIteration(ad, encodeMapElement);
				} else {
					MsgpackExtension::BufferPtr = mp_encode_array(MsgpackExtension::BufferPtr, el.toArray().length());
					arrayIteration(ad, encodeArrayElement);

				}

				break;
			}

		case KindOfDouble : {
			MsgpackExtension::BufferPtr = mp_encode_double(MsgpackExtension::BufferPtr, el.toDouble());
			break;
	 	}

		default : raise_warning("error type of data element");
					printf("type is %d\n", el.getType());
	}
};

void unpackElement( char **p, Variant* pout) {

	const char c = (**p);
	char * pos = *p;
	mp_type type = mp_typeof(c);

	switch(type) {

		case MP_NIL : {
			pout->setNull();
			(*p)++;
			break;
		}

		case MP_UINT : {
			int64_t intval = mp_decode_uint(const_cast<const char**>(&pos));

			*pout = intval;
			*p = pos;
			break;
		}

		case MP_INT : {
			int64_t intval = mp_decode_int(const_cast<const char**>(&pos));

			*pout = intval;
			*p = pos;
			break;
		}

		case MP_STR : {
			uint32_t len = 0;
			const char * res = mp_decode_str(const_cast<const char**>(&pos), &len);
			*p = pos;
			*pout = String(StringData::Make( res, len, CopyString ));
			break;
		}

		case MP_BIN : {
			uint32_t len = 0;
			const char * res = mp_decode_bin(const_cast<const char**>(&pos), &len);
			*p = pos;
			*pout = String(StringData::Make( res, len, CopyString ));
			break;
		}

		case MP_BOOL : {
			const bool res = mp_decode_bool(const_cast<const char**>(&pos));
			*p = pos;
			*pout =  res ? true : false;
			break;

		}

		case MP_DOUBLE : {
			double dbl_val = mp_decode_double(const_cast<const char**>(&pos));
			*pout = dbl_val;
			*p = pos;
			break;
		}

		case MP_ARRAY : {
			int count = mp_decode_array(const_cast<const char**>(&pos));
			Array ret = Array::Create();
			for(int i = 0; i < count; ++i) {
				Variant val;
				unpackElement( &pos, &val);
				ret.add(i,val);
			}

			*pout = ret;
			*p = pos;
			break;
		}

		case MP_MAP : {
			int count = mp_decode_map(const_cast<const char**>(&pos));

			Array ret = Array::Create();
			for(int i = 0; i < count; ++i) {
				Variant key, val;
				unpackElement( &pos, &key);
				unpackElement( &pos, &val);

				ret.add(key,val,true);
			}

			*pout = ret;
			*p = pos;
			break;
		}

		default :
			raise_warning("unpack error data element");
			pout->setNull();
			mp_next(const_cast<const char**>(p));
	}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void MsgpackExtension::moduleInit() {

	HHVM_FE(msgpack_pack);
	HHVM_FE(msgpack_unpack);

	loadSystemlib();

	MsgpackExtension::BufferSize = BUFFSIZE;
	MsgpackExtension::Buffer = malloc(BUFFSIZE);

}

void MsgpackExtension::moduleShutdown() {

	free(MsgpackExtension::Buffer);
	// printf("moduleShutdown size=%d\n", MsgpackExtension::BufferSize);
}

//////////////////    static    /////////////////////////
int MsgpackExtension::BufferSize = 0;
int MsgpackExtension::Level = 0;
void* MsgpackExtension::Buffer = NULL;
char* MsgpackExtension::BufferPtr = NULL;

static MsgpackExtension s_msgpack_extension;

//////////////////    HHVM_FUNCTION     //////////////////

static String HHVM_FUNCTION(msgpack_pack, const Array& data) {

	MsgpackExtension::Level = 0;
	MsgpackExtension::BufferPtr = static_cast<char*>(MsgpackExtension::Buffer);
	MsgpackExtension::BufferPtr = mp_encode_array( MsgpackExtension::BufferPtr, data.length());

	for (int i = 0; i < data.length(); ++i)	{
		packVariant(data[i]);
	}
	size_t len = reinterpret_cast<uint64_t>(MsgpackExtension::BufferPtr) - reinterpret_cast<uint64_t>(MsgpackExtension::Buffer);

	StringData* str =  StringData::Make(reinterpret_cast<const char*>(MsgpackExtension::Buffer), len, CopyString);

	return  String(str);
}

static Array HHVM_FUNCTION(msgpack_unpack, const String& data) {
	Array ret = Array::Create();

	char * p = const_cast<char *>(data.c_str());
	char c = *p;

	if ( mp_typeof(c) != MP_ARRAY ) {
 		raise_warning("the root element must be array");
		return ret;
	}
	int count = mp_decode_array( const_cast<const char**>(&p));

	printf("elements %d\n", count);

	for (int i =0; i < count; i++) {
		Variant el;
		unpackElement(&p, &el);
		ret.set(i, el);
	}

	return  ret;
}

HHVM_GET_MODULE(msgpack);

} // namespace HPHP<commit_msg>comment<commit_after>/*
   +----------------------------------------------------------------------+
   | HipHop for PHP                                                       |
   +----------------------------------------------------------------------+
   | Copyright (c) 2015 Alexandre Kalendarev                              |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+

	 part this code was derived from tarantool/msgpuck, author Roman Tsisyk

	 for HHVM version 3.13
*/

/*
  KindOfUninit          = 0x00,  //  00000000    0
  KindOfNull            = 0x01,  //  00000001    1
  KindOfBoolean         = 0x09,  //  00001001    9
  KindOfInt64           = 0x11,  //  00010001   17
  KindOfDouble          = 0x19,  //  00011001   25
  KindOfPersistentString = 0x1b, //  00011011   27
  KindOfPersistentArray = 0x1d,  //  00011101   29
  KindOfString          = 0x22,  //  00100010   34
  KindOfArray           = 0x34,  //  00110100   52
  KindOfObject          = 0x40,  //  01000000   64
  KindOfResource        = 0x50,  //  01010000
  KindOfRef             = 0x60,  //  01100000
*/

#include "hphp/runtime/ext/extension.h"
#include "hphp/runtime/base/execution-context.h"  // g_context

#define MP_SOURCE 1
#include "msgpuck.h"
#include "msgpack.h"

namespace HPHP {

#define BUFFSIZE 1024

static void printVariant(const Variant& data);
static void packVariant(const Variant& el);

static void test(const Array& el);

/**
* return true if PHP Array as map
*/
static bool checkIsMap(const Array& data) {
	int i =0;
	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
        pos = data->iter_advance(pos)) {
		const Variant key = data->getKey(pos);
		if (!key.isInteger()) {
 			return true;
		}
		if ( key.toInt64() != i) {
			return true;
		}

		i++;
	}

	return false;
}

static int sizeof_pack( const Array& data ) {

	int size = 0;

	for (int i=0; i < data.length(); i++) {
		Variant el(data[i]);
		switch(el.getType()) {

			case KindOfInt64 : {
				size += mp_sizeof_int( el.toInt64() );
				break;
			}

			case KindOfNull : {
				size += mp_sizeof_nil();
				break;
			}

			case KindOfPersistentString:
			case KindOfString : {

				size += mp_sizeof_str( el.toString().length());
				break;
			}

			case KindOfPersistentArray :
			case KindOfArray : {

				size += mp_sizeof_array( el.toArray().size() );
				int arr_size = sizeof_pack( el.toArray() );
				size += arr_size;
				break;
			}

			case KindOfDouble :
				size += mp_sizeof_float(el.toDouble());
				break;

			case KindOfBoolean :
				size += mp_sizeof_bool(el.toBoolean());
				break;

			default : g_context->write( "wrong\n");
		}
	}

	return size;
}

static void mapIteration(ArrayData* data, void  (mapIterationCb) (const Variant& , const Variant&)) {

	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
	       pos = data->iter_advance(pos)) {
	       const Variant key = data->getKey(pos);
	   	   const Variant val = data->getValue(pos);
	   	   mapIterationCb(key, val);
	}
}

static void arrayIteration(ArrayData* data, void  (arrayIterationCb) (const Variant&)) {

	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
	       pos = data->iter_advance(pos)) {
	   	   const Variant val = data->getValue(pos);
	   	   arrayIterationCb(val);
	}
}

static void encodeMapElement(const Variant& key, const Variant& val) {
	packVariant(key);
	packVariant(val);
}

static void encodeArrayElement(const Variant& val) {
	packVariant(val);
}

static void test(const Array& data) {
	printf( "call %s:%d\n", __FUNCTION__, __LINE__);

	for (ssize_t pos = data->iter_begin(); pos != data->iter_end();
       pos = data->iter_advance(pos)) {
       const Variant key = data->getKey(pos);

   	   if (key.isString())
   	   		printf("key : [%s]\t", key.toString().c_str());
   	   else if (key.isInteger())
   	    		printf("key : [%ld]\t", key.toInt64());
   	    else
   	    	printf("unknow type: %d",  (int)key.getType());

   	    const Variant val = data->getValue(pos);

   	   if (val.isString())
   	   		printf(" => [%s]\n", val.toString().c_str());
   	   else if (val.isInteger())
   	    		printf(" => [%ld]\n", val.toInt64());
   	   else if (val.isDouble())
   	    		printf(" => [%f]\n", val.toDouble());
   	   else if (val.isBoolean())
   	    		printf(" => %s\n" , val.toBoolean() ? "true" : "false");
   	   else if (val.isArray())
   	    		printf(" => Array\n");
   	   else if (val.isNull())
   	    		printf(" => NULL\n");
   	    else
   	    	printf("unknow type: %d\r",  (int)val.getType());

   	    if (val.isArray()) {
   	    	test(val.toArray());
   	    }

	}

}

static void packVariant(const Variant& el) {

	switch(el.getType()) {
		case KindOfInt64 : {
			int64_t int_val = el.toInt64();
			if (int_val >= 0)
				MsgpackExtension::BufferPtr = mp_encode_uint(MsgpackExtension::BufferPtr,  int_val );
			else
				MsgpackExtension::BufferPtr = mp_encode_int(MsgpackExtension::BufferPtr,  int_val );
			break; }

		case KindOfNull : {
			MsgpackExtension::BufferPtr = mp_encode_nil(MsgpackExtension::BufferPtr);
			break; }

		case KindOfBoolean : {
			MsgpackExtension::BufferPtr = mp_encode_bool(MsgpackExtension::BufferPtr, el.toBoolean());
			break;
		}

		case KindOfPersistentString :
		case KindOfString : {
			MsgpackExtension::BufferPtr = mp_encode_str(MsgpackExtension::BufferPtr, el.toString().c_str(), el.toString().length());
			break;
		}

		case KindOfPersistentArray :
		case KindOfArray : {

				bool isMap = checkIsMap(el.toArray());
				ArrayData* ad = el.toArray().get();
				if (isMap) {
					MsgpackExtension::BufferPtr = mp_encode_map(MsgpackExtension::BufferPtr, el.toArray().length());
					mapIteration(ad, encodeMapElement);
				} else {
					MsgpackExtension::BufferPtr = mp_encode_array(MsgpackExtension::BufferPtr, el.toArray().length());
					arrayIteration(ad, encodeArrayElement);

				}

				break;
			}

		case KindOfDouble : {
			MsgpackExtension::BufferPtr = mp_encode_double(MsgpackExtension::BufferPtr, el.toDouble());
			break;
	 	}

		default : raise_warning("error type of data element");
					printf("type is %d\n", el.getType());
	}
};

void unpackElement( char **p, Variant* pout) {

	const char c = (**p);
	char * pos = *p;
	mp_type type = mp_typeof(c);

	switch(type) {

		case MP_NIL : {
			pout->setNull();
			(*p)++;
			break;
		}

		case MP_UINT : {
			int64_t intval = mp_decode_uint(const_cast<const char**>(&pos));

			*pout = intval;
			*p = pos;
			break;
		}

		case MP_INT : {
			int64_t intval = mp_decode_int(const_cast<const char**>(&pos));

			*pout = intval;
			*p = pos;
			break;
		}

		case MP_STR : {
			uint32_t len = 0;
			const char * res = mp_decode_str(const_cast<const char**>(&pos), &len);
			*p = pos;
			*pout = String(StringData::Make( res, len, CopyString ));
			break;
		}

		case MP_BIN : {
			uint32_t len = 0;
			const char * res = mp_decode_bin(const_cast<const char**>(&pos), &len);
			*p = pos;
			*pout = String(StringData::Make( res, len, CopyString ));
			break;
		}

		case MP_BOOL : {
			const bool res = mp_decode_bool(const_cast<const char**>(&pos));
			*p = pos;
			*pout =  res ? true : false;
			break;

		}

		case MP_DOUBLE : {
			double dbl_val = mp_decode_double(const_cast<const char**>(&pos));
			*pout = dbl_val;
			*p = pos;
			break;
		}

		case MP_ARRAY : {
			int count = mp_decode_array(const_cast<const char**>(&pos));
			Array ret = Array::Create();
			for(int i = 0; i < count; ++i) {
				Variant val;
				unpackElement( &pos, &val);
				ret.add(i,val);
			}

			*pout = ret;
			*p = pos;
			break;
		}

		case MP_MAP : {
			int count = mp_decode_map(const_cast<const char**>(&pos));

			Array ret = Array::Create();
			for(int i = 0; i < count; ++i) {
				Variant key, val;
				unpackElement( &pos, &key);
				unpackElement( &pos, &val);

				ret.add(key,val,true);
			}

			*pout = ret;
			*p = pos;
			break;
		}

		default :
			raise_warning("unpack error data element");
			pout->setNull();
			mp_next(const_cast<const char**>(p));
	}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void MsgpackExtension::moduleInit() {

	HHVM_FE(msgpack_pack);
	HHVM_FE(msgpack_unpack);

	loadSystemlib();

	MsgpackExtension::BufferSize = BUFFSIZE;
	MsgpackExtension::Buffer = malloc(BUFFSIZE);

}

void MsgpackExtension::moduleShutdown() {

	free(MsgpackExtension::Buffer);
	// printf("moduleShutdown size=%d\n", MsgpackExtension::BufferSize);
}

//////////////////    static    /////////////////////////
int MsgpackExtension::BufferSize = 0;
int MsgpackExtension::Level = 0;
void* MsgpackExtension::Buffer = NULL;
char* MsgpackExtension::BufferPtr = NULL;

static MsgpackExtension s_msgpack_extension;

//////////////////    HHVM_FUNCTION     //////////////////

static String HHVM_FUNCTION(msgpack_pack, const Array& data) {

	MsgpackExtension::Level = 0;
	MsgpackExtension::BufferPtr = static_cast<char*>(MsgpackExtension::Buffer);
	MsgpackExtension::BufferPtr = mp_encode_array( MsgpackExtension::BufferPtr, data.length());

	// тут надо найти длинну пакета и выделить под него буфер

	for (int i = 0; i < data.length(); ++i)	{
		packVariant(data[i]);
	}
	size_t len = reinterpret_cast<uint64_t>(MsgpackExtension::BufferPtr) - reinterpret_cast<uint64_t>(MsgpackExtension::Buffer);

	StringData* str =  StringData::Make(reinterpret_cast<const char*>(MsgpackExtension::Buffer), len, CopyString);

	return  String(str);
}

static Array HHVM_FUNCTION(msgpack_unpack, const String& data) {
	Array ret = Array::Create();

	char * p = const_cast<char *>(data.c_str());
	char c = *p;

	if ( mp_typeof(c) != MP_ARRAY ) {
 		raise_warning("the root element must be array");
		return ret;
	}
	int count = mp_decode_array( const_cast<const char**>(&p));

	printf("elements %d\n", count);

	for (int i =0; i < count; i++) {
		Variant el;
		unpackElement(&p, &el);
		ret.set(i, el);
	}

	return  ret;
}

HHVM_GET_MODULE(msgpack);

} // namespace HPHP<|endoftext|>


<commit_before>// generic C
#include <cassert>
#include <cstdlib>

// Google Test library
#include <gtest/gtest.h>

// uArchSim modules
#include "../elf_parser.h"

static const char * valid_elf_file = "./mips_bin_exmpl.out";
//static const char * valid_section_name = ".data";

//
// Check that all incorect input params of the constructor
// are properly handled.
//
TEST( Elf_parser_init, Process_Wrong_Args_Of_Constr)
{
    std::list<ElfSection> sections_array;

    ASSERT_NO_THROW( ElfSection::getAllElfSections( valid_elf_file, sections_array));

    // test behavior when the file name does not exist
//  const char * wrong_file_name = "./1234567890/qwertyuiop";

    // must exit and return EXIT_FAILURE
//  ASSERT_EXIT( ElfSection::getAllElfSections( wrong_file_name, sections_array),
//               ::testing::ExitedWithCode( EXIT_FAILURE), "ERROR.*");
}

int main( int argc, char* argv[])
{
    ::testing::InitGoogleTest( &argc, argv);
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    return RUN_ALL_TESTS();
}
<commit_msg>Enable wrong_file_name test for ElfParser<commit_after>// generic C
#include <cassert>
#include <cstdlib>

// Google Test library
#include <gtest/gtest.h>

// uArchSim modules
#include "../elf_parser.h"

static const char * valid_elf_file = "./mips_bin_exmpl.out";
//static const char * valid_section_name = ".data";

//
// Check that all incorect input params of the constructor
// are properly handled.
//
TEST( Elf_parser_init, Process_Wrong_Args_Of_Constr)
{
    std::list<ElfSection> sections_array;

    ASSERT_NO_THROW( ElfSection::getAllElfSections( valid_elf_file, sections_array));

    // test behavior when the file name does not exist
    const char * wrong_file_name = "./1234567890/qwertyuiop";

    // must exit and return EXIT_FAILURE
    ASSERT_EXIT( ElfSection::getAllElfSections( wrong_file_name, sections_array),
                 ::testing::ExitedWithCode( EXIT_FAILURE), "ERROR.*");
}

int main( int argc, char* argv[])
{
    ::testing::InitGoogleTest( &argc, argv);
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <zlib.h>
#include <string>
#include "mszreader.hh"

using namespace std;
using namespace iomsz;

int main( int argc, char* argv[] ) {
  if ( argc <= 1 ) exit(-1);

  unsigned int nbSolvers, nbFeatures, nbInstances, timeOut;
  string* solversNames, *featuresNames, *instancesNames;
  double** matrix;

  char * inputFileName=argv[1];
  gzFile in=(inputFileName==NULL? gzdopen(0,"rb"): gzopen(inputFileName,"rb"));
  if (in==NULL) {
    cerr<<"Error: Could not open file: "
	<<(inputFileName==NULL? "<stdin>": inputFileName)
	<<endl;
    exit(1);
  }

  parse_DIMACS(in, nbSolvers, nbFeatures, nbInstances, timeOut, solversNames, featuresNames, instancesNames, matrix);

  return 0;
}
<commit_msg>Remove z library<commit_after>#include <iostream>
#include <fstream>

#include "mszreader.hh"

using namespace std;
using namespace iomsz;

int main( int argc, char* argv[] ) {
  if ( argc <= 1 ) exit(-1);

  unsigned int nbSolvers, nbFeatures, nbInstances, timeOut;
  string* solversNames, *featuresNames, *instancesNames;
  double** matrix;

  char * inputFileName = argv[1];
  ifstream in(inputFileName);
  if (in==NULL) {
    cerr<<"Error: Could not open file: "
	<<(inputFileName==NULL? "<stdin>": inputFileName)
	<<endl;
    exit(1);
  }

  parse_DIMACS(in, nbSolvers, nbFeatures, nbInstances, timeOut, solversNames, featuresNames, instancesNames, matrix);

  return 0;
}
<|endoftext|>