<commit_before>/*
    bonjouraccount.cpp - Kopete Bonjour Protocol

    Copyright (c) 2007      by Tejas Dinkar	<tejas@gja.in>
    Copyright (c) 2003      by Will Stephenson		 <will@stevello.free-online.co.uk>
    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU General Public                   *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include <QtDBus>

#include <kaction.h>
#include <kdebug.h>
#include <klocale.h>
#include <kactionmenu.h>
#include <kmenu.h>
#include <kicon.h>

#include <dnssd/publicservice.h>

#include "kopetemetacontact.h"
#include "kopetecontactlist.h"
#include "kopetedeletecontacttask.h"

#include "bonjouraccount.h"
#include "bonjourcontact.h"
#include "bonjourfakeserver.h"
#include "bonjourprotocol.h"
#include "bonjourcontactconnection.h"

BonjourAccount::BonjourAccount( BonjourProtocol *parent, const QString& accountID )
: Kopete::Account ( parent, accountID )
{
	// Init the myself contact
	setMyself( new BonjourContact( this, accountId(), accountId(), Kopete::ContactList::self()->myself() ) );
	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOffline );
	m_server = new BonjourFakeServer();;

	service = NULL;
	localServer = NULL;
	listeningPort = 0;
	browser = NULL;

	// All Contacts Go To The Bonjour Group
	bonjourGroup = Kopete::ContactList::self()->findGroup("Bonjour");

	// Clean out Contacts from last time when kopete starts up
	wipeOutAllContacts();
}

BonjourAccount::~BonjourAccount()
{
	if (isConnected())
		disconnect();
	delete m_server;
}

KActionMenu* BonjourAccount::actionMenu()
{
	KActionMenu *mActionMenu = Kopete::Account::actionMenu();

	mActionMenu->addSeparator();

	KAction *action;

	action = new KAction (KIcon("bonjour_showvideo"), i18n ("Show my own video..."), mActionMenu );
        //, "actionShowVideo");
	QObject::connect( action, SIGNAL(triggered(bool)), this, SLOT(slotShowVideo()) );
	mActionMenu->addAction(action);
	action->setEnabled( isConnected() );

	return mActionMenu;
}

bool BonjourAccount::createContact(const QString& contactId, Kopete::MetaContact* parentContact)
{
	BonjourContact* newContact = new BonjourContact( this, contactId, parentContact->displayName(), parentContact );
	return newContact != 0L;
}

void BonjourAccount::setAway( bool away, const QString & /* reason */ )
{
	if ( away )
		slotGoAway();
	else
		slotGoOnline();
}

void BonjourAccount::setOnlineStatus(const Kopete::OnlineStatus& status, const Kopete::StatusMessage &reason )
{
	if ( status.status() == Kopete::OnlineStatus::Online &&
			myself()->onlineStatus().status() == Kopete::OnlineStatus::Offline )
		slotGoOnline();
	else if (status.status() == Kopete::OnlineStatus::Online &&
			myself()->onlineStatus().status() == Kopete::OnlineStatus::Away )
		setAway( false, reason.message() );
	else if ( status.status() == Kopete::OnlineStatus::Offline )
		slotGoOffline();
	else if ( status.status() == Kopete::OnlineStatus::Away )
		slotGoAway( /* reason */ );
}

void BonjourAccount::setStatusMessage(const Kopete::StatusMessage& statusMessage)
{
	Q_UNUSED(statusMessage);
	/* Not used in bonjour */
}

// This Function Starts a new Local Server
// It runs on local port listeningPort
// Make Sure IP Tables lets this port through!!
bool BonjourAccount::startLocalServer()
{
        int port = 5298;

        localServer = new QTcpServer();

        while (port < 5305)             // No of Attempts
                if (localServer->listen(QHostAddress::Any, port)) {
			QObject::connect(localServer, SIGNAL(newConnection()),
					this, SLOT(newIncomingConnection()));
			listeningPort = port;
                        break;
		}
                else
                        port++;

        return localServer->isListening();
}

void BonjourAccount::startBrowse()
{
	// Delete All Contacts Before we start looking for new ones
	wipeOutAllContacts();

	browser = new DNSSD::ServiceBrowser("_presence._tcp");

	QObject::connect(browser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),
			this,SLOT(comingOnline(DNSSD::RemoteService::Ptr)));
	QObject::connect(browser,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)),
			this,SLOT(goingOffline(DNSSD::RemoteService::Ptr)));

	browser->startBrowse();
}

void BonjourAccount::startPublish()
{
	if (! fullName.contains('@')) {
		fullName.append("@");
		fullName.append(getLocalHostName().toUtf8());
	}

	service = new DNSSD::PublicService(fullName, "_presence._tcp", listeningPort);

        QMap <QString, QByteArray> map;
        map.insert("1st",  firstName);
        map.insert("email", emailAddress);
        map.insert("last", lastName);
        map.insert("node", "kopete");
        map.insert("port.p2pj", QByteArray::number(listeningPort));	// This Number Actuall Ignored
        map.insert("status", "avail");
        map.insert("txtvers", "1");
        map.insert("vc", "!");
        map.insert("ver", "0.0.1");

        service->setTextData(map);

        service->publish();
}

void BonjourAccount::connect( const Kopete::OnlineStatus& /* initialStatus */ )
{
	if (fullName.isEmpty())
		fullName = accountId().toUtf8();

	if (! startLocalServer())
		return;

	startPublish();

	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOnline );

	startBrowse();

	QObject::connect ( m_server, SIGNAL ( messageReceived( const QString & ) ),
			this, SLOT ( receivedMessage( const QString & ) ) );
}

void BonjourAccount::comingOnline(DNSSD::RemoteService::Ptr pointer)
{
	pointer->resolve();

	kDebug()<<"\nComing Online\n";

	if (pointer->serviceName() == fullName)			// Don't Add Ourselves
		return;

	QString display = pointer->serviceName().split("@")[0];

	Kopete::MetaContact *mc;

	// FIXME: The Standard Has Specifications on What To Do in case of a clash
	// We Ignore them over here.
	mc = addContact(pointer->serviceName(), display, bonjourGroup);

	Kopete::Contact *c = mc->contacts()[0];

	//FIXME: QObject is needed to be called here as there is a conflict fo setproperty
	c->QObject::setProperty("remoteHostName", pointer->hostName());
	c->QObject::setProperty("remotePort", pointer->port());
	c->setOnlineStatus(Kopete::OnlineStatus::Online);
}

void BonjourAccount::goingOffline(DNSSD::RemoteService::Ptr pointer)
{
	pointer->resolve();

	Kopete::Contact *c = contacts()[pointer->serviceName()];
	wipeOutContact(c);
}

void BonjourAccount::wipeOutContact(Kopete::Contact *c)
{
	if (c == myself())
		return;

	Kopete::MetaContact *mc = c->metaContact();

	c->setOnlineStatus(Kopete::OnlineStatus::Offline);
	mc->removeContact(c);

	// FIXME: DeleteContact task should be extended and used
	Kopete::DeleteContactTask task(c);
	task.start();

	if (mc->contacts().isEmpty())
		Kopete::ContactList::self()->removeMetaContact(mc);
}

void BonjourAccount::wipeOutAllContacts()
{
	QList <Kopete::Contact *> list = contacts().values();

	for (QList <Kopete::Contact *>::Iterator i = list.begin(); i != list.end(); i++)
		wipeOutContact(*i);
}

void BonjourAccount::disconnect()
{
	wipeOutAllContacts();

	localServer->close();
	service->stop();

	delete browser;
	browser = NULL;

	delete localServer;
	localServer = NULL;
	listeningPort = 0;

	delete service;
	service = NULL;

	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOffline );
	QObject::disconnect ( m_server, 0, 0, 0 );
}

BonjourFakeServer * BonjourAccount::server()
{
	return m_server;
}

void BonjourAccount::slotGoOnline ()
{
	kDebug ( 14210 ) ;

	if (!isConnected ())
		connect ();
	else
		myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOnline );
	updateContactStatus();
}

void BonjourAccount::slotGoAway ()
{
	kDebug ( 14210 ) ;

	if (!isConnected ())
		connect();

	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourAway );
	updateContactStatus();
}

void BonjourAccount::slotGoOffline ()
{
	kDebug ( 14210 ) ;

	if (isConnected ())
		disconnect ();
	updateContactStatus();
}

void BonjourAccount::slotShowVideo ()
{
	kDebug ( 14210 ) ;

	if (isConnected ())
	{
		BonjourWebcamDialog *bonjourWebcamDialog = new BonjourWebcamDialog(0, 0);
		Q_UNUSED(bonjourWebcamDialog);
	}
	updateContactStatus();
}

void BonjourAccount::receivedMessage( const QString &message )
{
	// Look up the contact the message is from
	QString from;
	BonjourContact* messageSender;

	from = message.section( ':', 0, 0 );
	Kopete::Contact* contact = contacts()[from];
	messageSender = dynamic_cast<BonjourContact *>( contact );

	kDebug( 14210 ) << " got a message from " << from << ", " << messageSender << ", is: " << message;
	// Pass it on to the contact to process and display via a KMM
	if ( messageSender )
		messageSender->receivedMessage( message );
	else
		kWarning(14210) << "unable to look up contact for delivery";
}

void BonjourAccount::updateContactStatus()
{
	QHashIterator<QString, Kopete::Contact*>itr( contacts() );
	for ( ; itr.hasNext(); ) {
		itr.next();
		itr.value()->setOnlineStatus( myself()->onlineStatus() );
	}
}

void BonjourAccount::setfullName(const QByteArray &n_fullName)
{
	fullName = n_fullName;
}

void BonjourAccount::setfirstName(const QByteArray &n_firstName)
{
	firstName = n_firstName;
}

void BonjourAccount::setlastName(const QByteArray &n_lastName)
{
	lastName = n_lastName;
}

void BonjourAccount::setemailAddress(const QByteArray &n_emailAddress)
{
	emailAddress = n_emailAddress;
}

const QByteArray BonjourAccount::getfullName() const
{
	return fullName;
}

const QByteArray BonjourAccount::getfirstName() const
{
	return firstName;
}

const QByteArray BonjourAccount::getlastName() const
{
	return lastName;
}

const QByteArray BonjourAccount::getemailAddress() const
{
	return emailAddress;
}

QList <BonjourContact *> BonjourAccount::getContactsByAddress(const QHostAddress &addr)
{
	QList <BonjourContact *> list;

	QList <Kopete::Contact *> c = contacts().values();

	for (QList <Kopete::Contact *>::iterator i = c.begin(); i != c.end(); i++) {
		BonjourContact *c = (BonjourContact *) *i;
		if (c->isRemoteAddress(addr))
			list<<c;
	}

	return list;
}

void BonjourAccount::newIncomingConnection()
{
	// Get Next Connection
	QTcpSocket *sock = localServer->nextPendingConnection();

	BonjourContactConnection *bcc = new BonjourContactConnection(sock);
	QObject::connect(bcc, SIGNAL(discoveredUserName(BonjourContactConnection *, QString)),
			this, SLOT(discoveredUserName(BonjourContactConnection *, QString)));;

	unknownConnections << bcc;
}

void BonjourAccount::discoveredUserName(BonjourContactConnection *conn, QString user)
{
	kDebug()<<"User Making Contact (unverified): "<<user;

	BonjourContact *c;

	if (! (c = verifyUser(conn, user))) {
		kDebug()<<"Ignoring Unverified User: "<<user;
		return;
	}

	kDebug()<<"User Verified: "<<user;

	unknownConnections.remove(conn);

	c->setConnection(conn);
}

BonjourContact *BonjourAccount::verifyUser(BonjourContactConnection *conn, QString user)
{
	// First Check the User Exists
	if (! contacts().keys().contains(user))
		return NULL;

	BonjourContact *c = (BonjourContact *) contacts()[user];

	if (c->getremoteAddress() != conn->getHostAddress())
		return NULL;

	return c;
}

#include "bonjouraccount.moc"
<commit_msg>Changed Display name so that it shows <firstname> <lastname> and not 'nickname'<commit_after>/*
    bonjouraccount.cpp - Kopete Bonjour Protocol

    Copyright (c) 2007      by Tejas Dinkar	<tejas@gja.in>
    Copyright (c) 2003      by Will Stephenson		 <will@stevello.free-online.co.uk>
    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU General Public                   *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include <QtDBus>

#include <kaction.h>
#include <kdebug.h>
#include <klocale.h>
#include <kactionmenu.h>
#include <kmenu.h>
#include <kicon.h>

#include <dnssd/publicservice.h>

#include "kopetemetacontact.h"
#include "kopetecontactlist.h"
#include "kopetedeletecontacttask.h"

#include "bonjouraccount.h"
#include "bonjourcontact.h"
#include "bonjourfakeserver.h"
#include "bonjourprotocol.h"
#include "bonjourcontactconnection.h"

BonjourAccount::BonjourAccount( BonjourProtocol *parent, const QString& accountID )
: Kopete::Account ( parent, accountID )
{
	// Init the myself contact
	setMyself( new BonjourContact( this, accountId(), accountId(), Kopete::ContactList::self()->myself() ) );
	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOffline );
	m_server = new BonjourFakeServer();;

	service = NULL;
	localServer = NULL;
	listeningPort = 0;
	browser = NULL;

	// All Contacts Go To The Bonjour Group
	bonjourGroup = Kopete::ContactList::self()->findGroup("Bonjour");

	// Clean out Contacts from last time when kopete starts up
	wipeOutAllContacts();
}

BonjourAccount::~BonjourAccount()
{
	if (isConnected())
		disconnect();
	delete m_server;
}

KActionMenu* BonjourAccount::actionMenu()
{
	KActionMenu *mActionMenu = Kopete::Account::actionMenu();

	mActionMenu->addSeparator();

	KAction *action;

	action = new KAction (KIcon("bonjour_showvideo"), i18n ("Show my own video..."), mActionMenu );
        //, "actionShowVideo");
	QObject::connect( action, SIGNAL(triggered(bool)), this, SLOT(slotShowVideo()) );
	mActionMenu->addAction(action);
	action->setEnabled( isConnected() );

	return mActionMenu;
}

bool BonjourAccount::createContact(const QString& contactId, Kopete::MetaContact* parentContact)
{
	BonjourContact* newContact = new BonjourContact( this, contactId, parentContact->displayName(), parentContact );
	return newContact != 0L;
}

void BonjourAccount::setAway( bool away, const QString & /* reason */ )
{
	if ( away )
		slotGoAway();
	else
		slotGoOnline();
}

void BonjourAccount::setOnlineStatus(const Kopete::OnlineStatus& status, const Kopete::StatusMessage &reason )
{
	if ( status.status() == Kopete::OnlineStatus::Online &&
			myself()->onlineStatus().status() == Kopete::OnlineStatus::Offline )
		slotGoOnline();
	else if (status.status() == Kopete::OnlineStatus::Online &&
			myself()->onlineStatus().status() == Kopete::OnlineStatus::Away )
		setAway( false, reason.message() );
	else if ( status.status() == Kopete::OnlineStatus::Offline )
		slotGoOffline();
	else if ( status.status() == Kopete::OnlineStatus::Away )
		slotGoAway( /* reason */ );
}

void BonjourAccount::setStatusMessage(const Kopete::StatusMessage& statusMessage)
{
	Q_UNUSED(statusMessage);
	/* Not used in bonjour */
}

// This Function Starts a new Local Server
// It runs on local port listeningPort
// Make Sure IP Tables lets this port through!!
bool BonjourAccount::startLocalServer()
{
        int port = 5298;

        localServer = new QTcpServer();

        while (port < 5305)             // No of Attempts
                if (localServer->listen(QHostAddress::Any, port)) {
			QObject::connect(localServer, SIGNAL(newConnection()),
					this, SLOT(newIncomingConnection()));
			listeningPort = port;
                        break;
		}
                else
                        port++;

	kDebug()<<"Listening On Port: "<<listeningPort;
        return localServer->isListening();
}

void BonjourAccount::startBrowse()
{
	// Delete All Contacts Before we start looking for new ones
	wipeOutAllContacts();

	browser = new DNSSD::ServiceBrowser("_presence._tcp");

	QObject::connect(browser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),
			this,SLOT(comingOnline(DNSSD::RemoteService::Ptr)));
	QObject::connect(browser,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)),
			this,SLOT(goingOffline(DNSSD::RemoteService::Ptr)));

	kDebug()<<"Starting Browser";
	browser->startBrowse();
}

void BonjourAccount::startPublish()
{
	if (! fullName.contains('@')) {
		fullName.append("@");
		fullName.append(getLocalHostName().toUtf8());
	}

	service = new DNSSD::PublicService(fullName, "_presence._tcp", listeningPort);

        QMap <QString, QByteArray> map;
        map.insert("1st",  firstName);
        map.insert("email", emailAddress);
        map.insert("last", lastName);
        map.insert("node", "kopete");
        map.insert("port.p2pj", QByteArray::number(listeningPort));	// This Number Actuall Ignored
        map.insert("status", "avail");
        map.insert("txtvers", "1");
        map.insert("vc", "!");
        map.insert("ver", "0.0.1");

        service->setTextData(map);

	kDebug()<<"Starting Publish";
        service->publish();
}

void BonjourAccount::connect( const Kopete::OnlineStatus& /* initialStatus */ )
{
	if (fullName.isEmpty())
		fullName = accountId().toUtf8();

	if (! startLocalServer())
		return;

	startPublish();

	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOnline );

	startBrowse();

	QObject::connect ( m_server, SIGNAL ( messageReceived( const QString & ) ),
			this, SLOT ( receivedMessage( const QString & ) ) );
}

void BonjourAccount::comingOnline(DNSSD::RemoteService::Ptr pointer)
{
	pointer->resolve();

	kDebug()<<"\nComing Online\n";

	if (pointer->serviceName() == fullName)			// Don't Add Ourselves
		return;

        QMap <QString, QByteArray> map = pointer->textData();
	QString cfirst = map["1st"];
	QString clast = map["last"];

	QString display;
	if (cfirst != "" && clast != "")
		display = cfirst + " " + clast;
	else if (cfirst != "")
		display = cfirst;
	else if (clast != "")
		display = clast;
	else
		display = pointer->serviceName().split("@")[0];

	Kopete::MetaContact *mc;

	// FIXME: The Standard Has Specifications on What To Do in case of a clash
	// We Ignore them over here.
	mc = addContact(pointer->serviceName(), display, bonjourGroup);

	Kopete::Contact *c = mc->contacts()[0];

	//FIXME: QObject is needed to be called here as there is a conflict fo setproperty
	c->QObject::setProperty("remoteHostName", pointer->hostName());
	c->QObject::setProperty("remotePort", pointer->port());
	c->setOnlineStatus(Kopete::OnlineStatus::Online);
}

void BonjourAccount::goingOffline(DNSSD::RemoteService::Ptr pointer)
{
	pointer->resolve();

	Kopete::Contact *c = contacts()[pointer->serviceName()];
	wipeOutContact(c);
}

void BonjourAccount::wipeOutContact(Kopete::Contact *c)
{
	if (c == myself())
		return;

	Kopete::MetaContact *mc = c->metaContact();

	c->setOnlineStatus(Kopete::OnlineStatus::Offline);
	mc->removeContact(c);

	// FIXME: DeleteContact task should be extended and used
	Kopete::DeleteContactTask task(c);
	task.start();

	if (mc->contacts().isEmpty())
		Kopete::ContactList::self()->removeMetaContact(mc);
}

void BonjourAccount::wipeOutAllContacts()
{
	QList <Kopete::Contact *> list = contacts().values();

	for (QList <Kopete::Contact *>::Iterator i = list.begin(); i != list.end(); i++)
		wipeOutContact(*i);
}

void BonjourAccount::disconnect()
{
	wipeOutAllContacts();

	localServer->close();
	service->stop();

	delete browser;
	browser = NULL;

	delete localServer;
	localServer = NULL;
	listeningPort = 0;

	delete service;
	service = NULL;

	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOffline );
	QObject::disconnect ( m_server, 0, 0, 0 );
}

BonjourFakeServer * BonjourAccount::server()
{
	return m_server;
}

void BonjourAccount::slotGoOnline ()
{
	kDebug ( 14210 ) ;

	if (!isConnected ())
		connect ();
	else
		myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourOnline );
	updateContactStatus();
}

void BonjourAccount::slotGoAway ()
{
	kDebug ( 14210 ) ;

	if (!isConnected ())
		connect();

	myself()->setOnlineStatus( BonjourProtocol::protocol()->bonjourAway );
	updateContactStatus();
}

void BonjourAccount::slotGoOffline ()
{
	kDebug ( 14210 ) ;

	if (isConnected ())
		disconnect ();
	updateContactStatus();
}

void BonjourAccount::slotShowVideo ()
{
	kDebug ( 14210 ) ;

	if (isConnected ())
	{
		BonjourWebcamDialog *bonjourWebcamDialog = new BonjourWebcamDialog(0, 0);
		Q_UNUSED(bonjourWebcamDialog);
	}
	updateContactStatus();
}

void BonjourAccount::receivedMessage( const QString &message )
{
	// Look up the contact the message is from
	QString from;
	BonjourContact* messageSender;

	from = message.section( ':', 0, 0 );
	Kopete::Contact* contact = contacts()[from];
	messageSender = dynamic_cast<BonjourContact *>( contact );

	kDebug( 14210 ) << " got a message from " << from << ", " << messageSender << ", is: " << message;
	// Pass it on to the contact to process and display via a KMM
	if ( messageSender )
		messageSender->receivedMessage( message );
	else
		kWarning(14210) << "unable to look up contact for delivery";
}

void BonjourAccount::updateContactStatus()
{
	QHashIterator<QString, Kopete::Contact*>itr( contacts() );
	for ( ; itr.hasNext(); ) {
		itr.next();
		itr.value()->setOnlineStatus( myself()->onlineStatus() );
	}
}

void BonjourAccount::setfullName(const QByteArray &n_fullName)
{
	fullName = n_fullName;
}

void BonjourAccount::setfirstName(const QByteArray &n_firstName)
{
	firstName = n_firstName;
}

void BonjourAccount::setlastName(const QByteArray &n_lastName)
{
	lastName = n_lastName;
}

void BonjourAccount::setemailAddress(const QByteArray &n_emailAddress)
{
	emailAddress = n_emailAddress;
}

const QByteArray BonjourAccount::getfullName() const
{
	return fullName;
}

const QByteArray BonjourAccount::getfirstName() const
{
	return firstName;
}

const QByteArray BonjourAccount::getlastName() const
{
	return lastName;
}

const QByteArray BonjourAccount::getemailAddress() const
{
	return emailAddress;
}

QList <BonjourContact *> BonjourAccount::getContactsByAddress(const QHostAddress &addr)
{
	QList <BonjourContact *> list;

	QList <Kopete::Contact *> c = contacts().values();

	for (QList <Kopete::Contact *>::iterator i = c.begin(); i != c.end(); i++) {
		BonjourContact *c = (BonjourContact *) *i;
		if (c->isRemoteAddress(addr))
			list<<c;
	}

	return list;
}

void BonjourAccount::newIncomingConnection()
{
	// Get Next Connection
	QTcpSocket *sock = localServer->nextPendingConnection();

	BonjourContactConnection *bcc = new BonjourContactConnection(sock);
	QObject::connect(bcc, SIGNAL(discoveredUserName(BonjourContactConnection *, QString)),
			this, SLOT(discoveredUserName(BonjourContactConnection *, QString)));;

	unknownConnections << bcc;
}

void BonjourAccount::discoveredUserName(BonjourContactConnection *conn, QString user)
{
	kDebug()<<"User Making Contact (unverified): "<<user;

	BonjourContact *c;

	if (! (c = verifyUser(conn, user))) {
		kDebug()<<"Ignoring Unverified User: "<<user;
		return;
	}

	kDebug()<<"User Verified: "<<user;

	unknownConnections.removeAll(conn);

	c->setConnection(conn);
}

BonjourContact *BonjourAccount::verifyUser(BonjourContactConnection *conn, QString user)
{
	// First Check the User Exists
	if (! contacts().keys().contains(user))
		return NULL;

	BonjourContact *c = (BonjourContact *) contacts()[user];

	if (c->getremoteAddress() != conn->getHostAddress())
		return NULL;

	return c;
}

#include "bonjouraccount.moc"
<|endoftext|>


<commit_before> /*

    Copyright (c) 2006      by Olivier Goffart  <ogoffart at kde.org>

    Kopete    (c) 2006 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
 */

#include "jabbertransport.h"
#include "jabbercontact.h"
#include "jabberaccount.h"
#include "jabberprotocol.h"
#include "jabbercontactpool.h"

#include <kopeteaccountmanager.h>
#include <kopetecontact.h>
#include <kopetecontactlist.h>

#include <kopeteversion.h>

#include <qpixmap.h>
#include <qtimer.h>
#include <kaction.h>
#include <kdebug.h>
#include <klocale.h>
#include <kconfig.h>

#include "xmpp_tasks.h"

JabberTransport::JabberTransport (JabberAccount * parentAccount, const QString & myselfContactId, const QString& gateway_type)
	:Kopete::Account ( parentAccount->protocol(), myselfContactId+"/"+parentAccount->accountId())
{
	m_status=Creating;
	m_account = parentAccount;
	m_account->addTransport( this, myselfContactId );

	JabberContact *myContact = m_account->contactPool()->addContact ( XMPP::RosterItem ( myselfContactId ), Kopete::ContactList::self()->myself(), false );
	setMyself( myContact );

	//we have to know if the account get loaded from the config, or newly created
	bool exist=configGroup()->readBoolEntry("exist",false);

	if(!exist)
	{
		setColor( account()->color() );
#if KOPETE_IS_VERSION(0,11,51)
		QString cIcon;
		if(gateway_type=="msn")
			cIcon="msn_protocol";
		else if(gateway_type=="icq")
			cIcon="icq_protocol";
		else if(gateway_type=="aim")
			cIcon="aim_protocol";
		else if(gateway_type=="yahoo")
			cIcon="yahoo_protocol";
		else if(gateway_type=="sms")
			cIcon="sms_protocol";
		else if(gateway_type=="gadu-gadu")
			cIcon="gadu_protocol";
		else if(gateway_type=="smtp")
			cIcon="mail_generic";
		//TODO: theses gateway are referenced in http://www.jabber.org/registrar/disco-categories.html#gateway
		//      but i don't have icon now
/*		else if(gateway_type=="http-ws")
			cIcon="";
		else if(gateway_type=="qq")
			cIcon="";
		else if(gateway_type=="tlen")
			cIcon="";*/
		else if(gateway_type=="irc")  //NOTE: this is not official
			cIcon="irc_protocol";

		if( !cIcon.isEmpty() )
			setCustomIcon( cIcon );
		configGroup()->writeEntry("exist",true);
#endif
		QTimer::singleShot(0, this, SLOT(eatContacts()));
	}

	m_status=Normal;
}

JabberTransport::~JabberTransport ()
{
	m_account->removeTransport( myself()->contactId() );
}

KActionMenu *JabberTransport::actionMenu ()
{
	KActionMenu *menu = new KActionMenu( accountId(), myself()->onlineStatus().iconFor( this ),  this );
	QString nick = myself()->property( Kopete::Global::Properties::self()->nickName()).value().toString();

	menu->popupMenu()->insertTitle( myself()->onlineStatus().iconFor( myself() ),
	nick.isNull() ? accountLabel() : i18n( "%2 <%1>" ).arg( accountLabel(), nick )
								  );

	QPtrList<KAction> *customActions = myself()->customContextMenuActions(  );
	if( customActions && !customActions->isEmpty() )
	{
		menu->popupMenu()->insertSeparator();

		for( KAction *a = customActions->first(); a; a = customActions->next() )
			a->plug( menu->popupMenu() );
	}
	delete customActions;

	return menu;

/*	KActionMenu *m_actionMenu = Kopete::Account::actionMenu();

	m_actionMenu->popupMenu()->insertSeparator();

	m_actionMenu->insert(new KAction (i18n ("Join Groupchat..."), "jabber_group", 0,
		this, SLOT (slotJoinNewChat ()), this, "actionJoinChat"));

	m_actionMenu->popupMenu()->insertSeparator();

	m_actionMenu->insert ( new KAction ( i18n ("Services..."), "jabber_serv_on", 0,
										 this, SLOT ( slotGetServices () ), this, "actionJabberServices") );

	m_actionMenu->insert ( new KAction ( i18n ("Send Raw Packet to Server..."), "mail_new", 0,
										 this, SLOT ( slotSendRaw () ), this, "actionJabberSendRaw") );

	m_actionMenu->insert ( new KAction ( i18n ("Edit User Info..."), "identity", 0,
										 this, SLOT ( slotEditVCard () ), this, "actionEditVCard") );

	return m_actionMenu;*/
}

bool JabberTransport::createContact (const QString & contactId,  Kopete::MetaContact * metaContact)
{
#if 0 //TODO
	// collect all group names
	QStringList groupNames;
	Kopete::GroupList groupList = metaContact->groups();
	for(Kopete::Group *group = groupList.first(); group; group = groupList.next())
		groupNames += group->displayName();

	XMPP::Jid jid ( contactId );
	XMPP::RosterItem item ( jid );
	item.setName ( metaContact->displayName () );
	item.setGroups ( groupNames );

	// this contact will be created with the "dirty" flag set
	// (it will get reset if the contact appears in the roster during connect)
	JabberContact *contact = contactPool()->addContact ( item, metaContact, true );

	return ( contact != 0 );
#endif
	return false;
}

void JabberTransport::setOnlineStatus( const Kopete::OnlineStatus& status  , const QString &reason)
{
#if 0
	if( status.status() == Kopete::OnlineStatus::Offline )
	{
		disconnect( Kopete::Account::Manual );
		return;
	}

	if( isConnecting () )
	{
		errorConnectionInProgress ();
		return;
	}

	XMPP::Status xmppStatus ( "", reason );

	switch ( status.internalStatus () )
	{
		case JabberProtocol::JabberFreeForChat:
			xmppStatus.setShow ( "chat" );
			break;

		case JabberProtocol::JabberOnline:
			xmppStatus.setShow ( "" );
			break;

		case JabberProtocol::JabberAway:
			xmppStatus.setShow ( "away" );
			break;

		case JabberProtocol::JabberXA:
			xmppStatus.setShow ( "xa" );
			break;

		case JabberProtocol::JabberDND:
			xmppStatus.setShow ( "dnd" );
			break;

		case JabberProtocol::JabberInvisible:
			xmppStatus.setIsInvisible ( true );
			break;
	}

	if ( !isConnected () )
	{
		// we are not connected yet, so connect now
		m_initialPresence = xmppStatus;
		connect ();
	}
	else
	{
		setPresence ( xmppStatus );
	}
#endif
}

JabberProtocol * JabberTransport::protocol( ) const
{
	return m_account->protocol();
}

bool JabberTransport::removeAccount( )
{
	if(m_status == Removing  ||  m_status == AccountRemoved)
		return true; //so it can be deleted

	if (!account()->isConnected())
	{
		account()->errorConnectFirst ();
		return false;
	}

	m_status = Removing;
	XMPP::JT_Register *task = new XMPP::JT_Register ( m_account->client()->rootTask () );
	QObject::connect ( task, SIGNAL ( finished () ), this, SLOT ( removeAllContacts() ) );

	//JabberContact *my=static_cast<JabberContact*>(myself());
	task->unreg ( myself()->contactId() );
	task->go ( true );
	return false; //delay the removal
}

void JabberTransport::removeAllContacts( )
{
//	XMPP::JT_Register * task = (XMPP::JT_Register *) sender ();

/*	if ( ! task->success ())
	KMessageBox::queuedMessageBox ( 0L, KMessageBox::Error,
									i18n ("An error occured when trying to remove the transport:\n%1").arg(task->statusString()),
									i18n ("Jabber Service Unregistration"));
	*/ //we don't really care, we remove everithing anyway.

	kdDebug() << k_funcinfo << "delete all contacts of the transport"<< endl;
	QDictIterator<Kopete::Contact> it( contacts() );
	for( ; it.current(); ++it )
	{
		XMPP::JT_Roster * rosterTask = new XMPP::JT_Roster ( account()->client()->rootTask () );
		rosterTask->remove ( static_cast<JabberBaseContact*>(it.current())->rosterItem().jid() );
		rosterTask->go ( true );
	}
	m_status = Removing; //in theory that's already our status
	Kopete::AccountManager::self()->removeAccount( this ); //this will delete this
}

QString JabberTransport::legacyId( const XMPP::Jid & jid )
{
	if(jid.node().isEmpty())
		return QString();
	QString node = jid.node();
	return node.replace("%","@");
}

void JabberTransport::jabberAccountRemoved( )
{
	m_status = AccountRemoved;
	Kopete::AccountManager::self()->removeAccount( this ); //this will delete this
}

void JabberTransport::eatContacts( )
{
	/*
	* "Gateway Contact Eating" (c)(r)(tm)(g)(o)(f)
	* this comes directly from my mind into the kopete code.
	* principe: - the transport is ungry
	*           - it will eat contacts which belong to him
	*           - the contact will die
	*           - a new contact will born, with the same caracteristic, but owned by the transport
	* - Olivier 2006-01-17 -
	*/

	QDict<Kopete::Contact> cts=account()->contacts();
	QDictIterator<Kopete::Contact> it( cts );
	for( ; it.current(); ++it )
	{
		JabberContact *contact=dynamic_cast<JabberContact*>(it.current());
		if( contact && !contact->transport() && contact->rosterItem().jid().domain() == myself()->contactId() && contact != account()->myself())
		{
			XMPP::RosterItem item=contact->rosterItem();
			Kopete::MetaContact *mc=contact->metaContact();
			delete *it;
			account()->contactPool()->addContact( item , mc , false ); //not sure this is false;
		}
	}
}

#include "jabbertransport.moc"

// vim: set noet ts=4 sts=4 sw=4:
<commit_msg>SVN_SILENT spell fixors<commit_after> /*

    Copyright (c) 2006      by Olivier Goffart  <ogoffart at kde.org>

    Kopete    (c) 2006 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
 */

#include "jabbertransport.h"
#include "jabbercontact.h"
#include "jabberaccount.h"
#include "jabberprotocol.h"
#include "jabbercontactpool.h"

#include <kopeteaccountmanager.h>
#include <kopetecontact.h>
#include <kopetecontactlist.h>

#include <kopeteversion.h>

#include <qpixmap.h>
#include <qtimer.h>
#include <kaction.h>
#include <kdebug.h>
#include <klocale.h>
#include <kconfig.h>

#include "xmpp_tasks.h"

JabberTransport::JabberTransport (JabberAccount * parentAccount, const QString & myselfContactId, const QString& gateway_type)
	:Kopete::Account ( parentAccount->protocol(), myselfContactId+"/"+parentAccount->accountId())
{
	m_status=Creating;
	m_account = parentAccount;
	m_account->addTransport( this, myselfContactId );

	JabberContact *myContact = m_account->contactPool()->addContact ( XMPP::RosterItem ( myselfContactId ), Kopete::ContactList::self()->myself(), false );
	setMyself( myContact );

	//we have to know if the account get loaded from the config, or newly created
	bool exist=configGroup()->readBoolEntry("exist",false);

	if(!exist)
	{
		setColor( account()->color() );
#if KOPETE_IS_VERSION(0,11,51)
		QString cIcon;
		if(gateway_type=="msn")
			cIcon="msn_protocol";
		else if(gateway_type=="icq")
			cIcon="icq_protocol";
		else if(gateway_type=="aim")
			cIcon="aim_protocol";
		else if(gateway_type=="yahoo")
			cIcon="yahoo_protocol";
		else if(gateway_type=="sms")
			cIcon="sms_protocol";
		else if(gateway_type=="gadu-gadu")
			cIcon="gadu_protocol";
		else if(gateway_type=="smtp")
			cIcon="mail_generic";
		//TODO: theses gateway are referenced in http://www.jabber.org/registrar/disco-categories.html#gateway
		//      but i don't have icon now
/*		else if(gateway_type=="http-ws")
			cIcon="";
		else if(gateway_type=="qq")
			cIcon="";
		else if(gateway_type=="tlen")
			cIcon="";*/
		else if(gateway_type=="irc")  //NOTE: this is not official
			cIcon="irc_protocol";

		if( !cIcon.isEmpty() )
			setCustomIcon( cIcon );
		configGroup()->writeEntry("exist",true);
#endif
		QTimer::singleShot(0, this, SLOT(eatContacts()));
	}

	m_status=Normal;
}

JabberTransport::~JabberTransport ()
{
	m_account->removeTransport( myself()->contactId() );
}

KActionMenu *JabberTransport::actionMenu ()
{
	KActionMenu *menu = new KActionMenu( accountId(), myself()->onlineStatus().iconFor( this ),  this );
	QString nick = myself()->property( Kopete::Global::Properties::self()->nickName()).value().toString();

	menu->popupMenu()->insertTitle( myself()->onlineStatus().iconFor( myself() ),
	nick.isNull() ? accountLabel() : i18n( "%2 <%1>" ).arg( accountLabel(), nick )
								  );

	QPtrList<KAction> *customActions = myself()->customContextMenuActions(  );
	if( customActions && !customActions->isEmpty() )
	{
		menu->popupMenu()->insertSeparator();

		for( KAction *a = customActions->first(); a; a = customActions->next() )
			a->plug( menu->popupMenu() );
	}
	delete customActions;

	return menu;

/*	KActionMenu *m_actionMenu = Kopete::Account::actionMenu();

	m_actionMenu->popupMenu()->insertSeparator();

	m_actionMenu->insert(new KAction (i18n ("Join Groupchat..."), "jabber_group", 0,
		this, SLOT (slotJoinNewChat ()), this, "actionJoinChat"));

	m_actionMenu->popupMenu()->insertSeparator();

	m_actionMenu->insert ( new KAction ( i18n ("Services..."), "jabber_serv_on", 0,
										 this, SLOT ( slotGetServices () ), this, "actionJabberServices") );

	m_actionMenu->insert ( new KAction ( i18n ("Send Raw Packet to Server..."), "mail_new", 0,
										 this, SLOT ( slotSendRaw () ), this, "actionJabberSendRaw") );

	m_actionMenu->insert ( new KAction ( i18n ("Edit User Info..."), "identity", 0,
										 this, SLOT ( slotEditVCard () ), this, "actionEditVCard") );

	return m_actionMenu;*/
}

bool JabberTransport::createContact (const QString & contactId,  Kopete::MetaContact * metaContact)
{
#if 0 //TODO
	// collect all group names
	QStringList groupNames;
	Kopete::GroupList groupList = metaContact->groups();
	for(Kopete::Group *group = groupList.first(); group; group = groupList.next())
		groupNames += group->displayName();

	XMPP::Jid jid ( contactId );
	XMPP::RosterItem item ( jid );
	item.setName ( metaContact->displayName () );
	item.setGroups ( groupNames );

	// this contact will be created with the "dirty" flag set
	// (it will get reset if the contact appears in the roster during connect)
	JabberContact *contact = contactPool()->addContact ( item, metaContact, true );

	return ( contact != 0 );
#endif
	return false;
}

void JabberTransport::setOnlineStatus( const Kopete::OnlineStatus& status  , const QString &reason)
{
#if 0
	if( status.status() == Kopete::OnlineStatus::Offline )
	{
		disconnect( Kopete::Account::Manual );
		return;
	}

	if( isConnecting () )
	{
		errorConnectionInProgress ();
		return;
	}

	XMPP::Status xmppStatus ( "", reason );

	switch ( status.internalStatus () )
	{
		case JabberProtocol::JabberFreeForChat:
			xmppStatus.setShow ( "chat" );
			break;

		case JabberProtocol::JabberOnline:
			xmppStatus.setShow ( "" );
			break;

		case JabberProtocol::JabberAway:
			xmppStatus.setShow ( "away" );
			break;

		case JabberProtocol::JabberXA:
			xmppStatus.setShow ( "xa" );
			break;

		case JabberProtocol::JabberDND:
			xmppStatus.setShow ( "dnd" );
			break;

		case JabberProtocol::JabberInvisible:
			xmppStatus.setIsInvisible ( true );
			break;
	}

	if ( !isConnected () )
	{
		// we are not connected yet, so connect now
		m_initialPresence = xmppStatus;
		connect ();
	}
	else
	{
		setPresence ( xmppStatus );
	}
#endif
}

JabberProtocol * JabberTransport::protocol( ) const
{
	return m_account->protocol();
}

bool JabberTransport::removeAccount( )
{
	if(m_status == Removing  ||  m_status == AccountRemoved)
		return true; //so it can be deleted

	if (!account()->isConnected())
	{
		account()->errorConnectFirst ();
		return false;
	}

	m_status = Removing;
	XMPP::JT_Register *task = new XMPP::JT_Register ( m_account->client()->rootTask () );
	QObject::connect ( task, SIGNAL ( finished () ), this, SLOT ( removeAllContacts() ) );

	//JabberContact *my=static_cast<JabberContact*>(myself());
	task->unreg ( myself()->contactId() );
	task->go ( true );
	return false; //delay the removal
}

void JabberTransport::removeAllContacts( )
{
//	XMPP::JT_Register * task = (XMPP::JT_Register *) sender ();

/*	if ( ! task->success ())
	KMessageBox::queuedMessageBox ( 0L, KMessageBox::Error,
									i18n ("An error occured when trying to remove the transport:\n%1").arg(task->statusString()),
									i18n ("Jabber Service Unregistration"));
	*/ //we don't really care, we remove everithing anyway.

	kdDebug() << k_funcinfo << "delete all contacts of the transport"<< endl;
	QDictIterator<Kopete::Contact> it( contacts() );
	for( ; it.current(); ++it )
	{
		XMPP::JT_Roster * rosterTask = new XMPP::JT_Roster ( account()->client()->rootTask () );
		rosterTask->remove ( static_cast<JabberBaseContact*>(it.current())->rosterItem().jid() );
		rosterTask->go ( true );
	}
	m_status = Removing; //in theory that's already our status
	Kopete::AccountManager::self()->removeAccount( this ); //this will delete this
}

QString JabberTransport::legacyId( const XMPP::Jid & jid )
{
	if(jid.node().isEmpty())
		return QString();
	QString node = jid.node();
	return node.replace("%","@");
}

void JabberTransport::jabberAccountRemoved( )
{
	m_status = AccountRemoved;
	Kopete::AccountManager::self()->removeAccount( this ); //this will delete this
}

void JabberTransport::eatContacts( )
{
	/*
	* "Gateway Contact Eating" (c)(r)(tm)(g)(o)(f)
	* this comes directly from my mind into the kopete code.
	* principle: - the transport is hungry
	*            - it will eat contacts which belong to him
	*            - the contact will die
	*            - a new contact will born, with the same characteristics, but owned by the transport
	* - Olivier 2006-01-17 -
	*/

	QDict<Kopete::Contact> cts=account()->contacts();
	QDictIterator<Kopete::Contact> it( cts );
	for( ; it.current(); ++it )
	{
		JabberContact *contact=dynamic_cast<JabberContact*>(it.current());
		if( contact && !contact->transport() && contact->rosterItem().jid().domain() == myself()->contactId() && contact != account()->myself())
		{
			XMPP::RosterItem item=contact->rosterItem();
			Kopete::MetaContact *mc=contact->metaContact();
			delete *it;
			account()->contactPool()->addContact( item , mc , false ); //not sure this is false;
		}
	}
}

#include "jabbertransport.moc"

// vim: set noet ts=4 sts=4 sw=4:
<|endoftext|>


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

#include <string>

#include "gtest/gtest.h"

#include "modules/common/configs/config_gflags.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/integration_tests/planning_test_base.h"
#include "modules/planning/planning.h"

namespace apollo {
namespace planning {

/**
 * @class SunnyvaleLoopTest
 * @brief This is an integration test that uses the sunnyvale_loop map.
 */

class SunnyvaleLoopTest : public PlanningTestBase {
 public:
  virtual void SetUp() {
    FLAGS_map_dir = "modules/map/data/sunnyvale_loop";
    FLAGS_test_data_dir = "modules/planning/testdata/sunnyvale_loop_test";
    FLAGS_test_routing_response_file = "1_routing.pb.txt";
  }
};

/*
 * test stop for not-nudgable obstacle
 * A cruise test case
 */
TEST_F(SunnyvaleLoopTest, cruise) {
  std::string seq_num = "1";
  FLAGS_test_prediction_file = seq_num + "_prediction.pb.txt";
  FLAGS_test_localization_file = seq_num + "_localization.pb.txt";
  FLAGS_test_chassis_file = seq_num + "_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * stop case to trigger QP ST failed to solve
 */
TEST_F(SunnyvaleLoopTest, stop) {
  std::string seq_num = "2";
  FLAGS_test_prediction_file = seq_num + "_prediction.pb.txt";
  FLAGS_test_localization_file = seq_num + "_localization.pb.txt";
  FLAGS_test_chassis_file = seq_num + "_chassis.pb.txt";
  FLAGS_test_routing_response_file = seq_num + "_routing.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: fixed a bug in integration test..<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <string>

#include "gtest/gtest.h"

#include "modules/common/configs/config_gflags.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/integration_tests/planning_test_base.h"
#include "modules/planning/planning.h"

namespace apollo {
namespace planning {

/**
 * @class SunnyvaleLoopTest
 * @brief This is an integration test that uses the sunnyvale_loop map.
 */

class SunnyvaleLoopTest : public PlanningTestBase {
 public:
  virtual void SetUp() {
    FLAGS_map_dir = "modules/map/data/sunnyvale_loop";
    FLAGS_test_data_dir = "modules/planning/testdata/sunnyvale_loop_test";
    FLAGS_test_routing_response_file = "1_routing.pb.txt";
  }
};

/*
 * test stop for not-nudgable obstacle
 * A cruise test case
 */
TEST_F(SunnyvaleLoopTest, cruise) {
  std::string seq_num = "1";
  FLAGS_test_prediction_file = seq_num + "_prediction.pb.txt";
  FLAGS_test_localization_file = seq_num + "_localization.pb.txt";
  FLAGS_test_chassis_file = seq_num + "_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * stop case to trigger QP ST failed to solve
 */
// TODO: fix this test.
TEST_F(SunnyvaleLoopTest, stop) {
  std::string seq_num = "2";
  FLAGS_test_prediction_file = seq_num + "_prediction.pb.txt";
  FLAGS_test_localization_file = seq_num + "_localization.pb.txt";
  FLAGS_test_chassis_file = seq_num + "_chassis.pb.txt";
  FLAGS_test_routing_response_file = seq_num + "_routing.pb.txt";
  PlanningTestBase::SetUp();
  bool run_planning_success = RunPlanning("sunnyvale_stop", 0);
  EXPECT_FALSE(run_planning_success);
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Cloudius Systems
 */

#ifndef SSTRING_HH_
#define SSTRING_HH_

#include <stdint.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <stdexcept>
#include <initializer_list>
#include <iostream>
#include <functional>
#include <cstdio>
#include <experimental/string_view>

template <typename char_type, typename size_type, size_type max_size>
class basic_sstring {
    union contents {
        struct external_type {
            char* str;
            size_type size;
            int8_t pad;
        } external;
        struct internal_type {
            char str[max_size];
            int8_t size;
        } internal;
        static_assert(sizeof(external_type) <= sizeof(internal_type), "max_size too small");
        static_assert(max_size <= 127, "max_size too large");
    } u;
    bool is_internal() const noexcept {
        return u.internal.size >= 0;
    }
    bool is_external() const noexcept {
        return !is_internal();
    }
    const char* str() const {
        return is_internal() ? u.internal.str : u.external.str;
    }
    char* str() {
        return is_internal() ? u.internal.str : u.external.str;
    }
public:
    struct initialized_later {};

    basic_sstring() noexcept {
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    basic_sstring(const basic_sstring& x) {
        if (x.is_internal()) {
            u.internal = x.u.internal;
        } else {
            u.internal.size = -1;
            u.external.str = new char[x.u.external.size + 1];
            std::copy(x.u.external.str, x.u.external.str + x.u.external.size + 1, u.external.str);
            u.external.size = x.u.external.size;
        }
    }
    basic_sstring(basic_sstring&& x) noexcept {
        u = x.u;
        x.u.internal.size = 0;
        x.u.internal.str[0] = '\0';
    }
    basic_sstring(initialized_later, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            std::copy(x, x + size, u.internal.str);
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            std::copy(x, x + size, u.external.str);
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x) : basic_sstring(x, std::strlen(x)) {}
    basic_sstring(std::basic_string<char_type>& x) : basic_sstring(x.c_str(), x.size()) {}
    basic_sstring(std::initializer_list<char_type> x) : basic_sstring(x.begin(), x.end() - x.begin()) {}
    basic_sstring(const char_type* b, const char_type* e) : basic_sstring(b, e - b) {}
    basic_sstring(const std::basic_string<char_type>& s)
        : basic_sstring(s.data(), s.size()) {}
    ~basic_sstring() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
    }
    basic_sstring& operator=(const basic_sstring& x) {
        basic_sstring tmp(x);
        swap(tmp);
        return *this;
    }
    basic_sstring& operator=(basic_sstring&& x) noexcept {
        if (this != &x) {
            swap(x);
            x.reset();
        }
        return *this;
    }
    operator std::string() const {
        return str();
    }
    size_t size() const noexcept {
        return is_internal() ? u.internal.size : u.external.size;
    }
    bool empty() const noexcept {
        return u.internal.size == 0;
    }
    void reset() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    void swap(basic_sstring& x) noexcept {
        contents tmp;
        tmp = x.u;
        x.u = u;
        u = tmp;
    }
    const char* c_str() const {
        return str();
    }
    const char_type* begin() const { return str(); }
    const char_type* end() const { return str() + size(); }
    char_type* begin() { return str(); }
    char_type* end() { return str() + size(); }
    bool operator==(const basic_sstring& x) const {
        return size() == x.size() && std::equal(begin(), end(), x.begin());
    }
    bool operator!=(const basic_sstring& x) const {
        return !operator==(x);
    }
    basic_sstring operator+(const basic_sstring& x) const {
        basic_sstring ret(initialized_later(), size() + x.size());
        std::copy(begin(), end(), ret.begin());
        std::copy(x.begin(), x.end(), ret.begin() + size());
        return ret;
    }
    basic_sstring& operator+=(const basic_sstring& x) {
        return *this = *this + x;
    }

    operator std::experimental::string_view() const {
        return std::experimental::string_view(str(), size());
    }
};

template <typename char_type, typename size_type, size_type max_size>
inline
void swap(basic_sstring<char_type, size_type, max_size>& x,
          basic_sstring<char_type, size_type, max_size>& y) noexcept
{
    return x.swap(y);
}

template <typename char_type, typename size_type, size_type max_size, typename char_traits>
inline
std::basic_ostream<char_type, char_traits>&
operator<<(std::basic_ostream<char_type, char_traits>& os,
        const basic_sstring<char_type, size_type, max_size>& s) {
    return os.write(s.begin(), s.size());
}

namespace std {

template <typename char_type, typename size_type, size_type max_size>
struct hash<basic_sstring<char_type, size_type, max_size>> {
    size_t operator()(const basic_sstring<char_type, size_type, max_size>& s) const {
        return std::hash<std::experimental::string_view>()(s);
    }
};

}

using sstring = basic_sstring<char, uint32_t, 15>;

template <typename T, typename String = sstring, typename for_enable_if = void*>
String to_sstring(T value, for_enable_if);

template <typename T>
inline
sstring to_sstring_sprintf(T value, const char* fmt) {
    char tmp[sizeof(value) * 3 + 3];
    auto len = std::sprintf(tmp, fmt, value);
    return sstring(tmp, len);
}

template <typename string_type = sstring>
inline
string_type to_sstring(int value, void* = nullptr) {
    return to_sstring_sprintf(value, "%d");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned value, void* = nullptr) {
    return to_sstring_sprintf(value, "%u");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%ld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lu");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%llu");
}

template <typename string_type = sstring>
inline
string_type to_sstring(const char* value, void* = nullptr) {
    return string_type(value);
}

template <typename string_type = sstring>
inline
string_type to_sstring(sstring value, void* = nullptr) {
    return value;
}

template <typename T>
inline
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    bool first = true;
    os << "{";
    for (auto&& elem : v) {
        if (!first) {
            os << ", ";
        } else {
            first = false;
        }
        os << elem;
    }
    os << "}";
    return os;
}

#endif /* SSTRING_HH_ */
<commit_msg>sstring: introduce make_sstring()<commit_after>/*
 * Copyright 2014 Cloudius Systems
 */

#ifndef SSTRING_HH_
#define SSTRING_HH_

#include <stdint.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <stdexcept>
#include <initializer_list>
#include <iostream>
#include <functional>
#include <cstdio>
#include <experimental/string_view>

template <typename char_type, typename size_type, size_type max_size>
class basic_sstring {
    union contents {
        struct external_type {
            char* str;
            size_type size;
            int8_t pad;
        } external;
        struct internal_type {
            char str[max_size];
            int8_t size;
        } internal;
        static_assert(sizeof(external_type) <= sizeof(internal_type), "max_size too small");
        static_assert(max_size <= 127, "max_size too large");
    } u;
    bool is_internal() const noexcept {
        return u.internal.size >= 0;
    }
    bool is_external() const noexcept {
        return !is_internal();
    }
    const char* str() const {
        return is_internal() ? u.internal.str : u.external.str;
    }
    char* str() {
        return is_internal() ? u.internal.str : u.external.str;
    }
public:
    struct initialized_later {};

    basic_sstring() noexcept {
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    basic_sstring(const basic_sstring& x) {
        if (x.is_internal()) {
            u.internal = x.u.internal;
        } else {
            u.internal.size = -1;
            u.external.str = new char[x.u.external.size + 1];
            std::copy(x.u.external.str, x.u.external.str + x.u.external.size + 1, u.external.str);
            u.external.size = x.u.external.size;
        }
    }
    basic_sstring(basic_sstring&& x) noexcept {
        u = x.u;
        x.u.internal.size = 0;
        x.u.internal.str[0] = '\0';
    }
    basic_sstring(initialized_later, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            std::copy(x, x + size, u.internal.str);
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            std::copy(x, x + size, u.external.str);
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x) : basic_sstring(x, std::strlen(x)) {}
    basic_sstring(std::basic_string<char_type>& x) : basic_sstring(x.c_str(), x.size()) {}
    basic_sstring(std::initializer_list<char_type> x) : basic_sstring(x.begin(), x.end() - x.begin()) {}
    basic_sstring(const char_type* b, const char_type* e) : basic_sstring(b, e - b) {}
    basic_sstring(const std::basic_string<char_type>& s)
        : basic_sstring(s.data(), s.size()) {}
    ~basic_sstring() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
    }
    basic_sstring& operator=(const basic_sstring& x) {
        basic_sstring tmp(x);
        swap(tmp);
        return *this;
    }
    basic_sstring& operator=(basic_sstring&& x) noexcept {
        if (this != &x) {
            swap(x);
            x.reset();
        }
        return *this;
    }
    operator std::string() const {
        return str();
    }
    size_t size() const noexcept {
        return is_internal() ? u.internal.size : u.external.size;
    }
    bool empty() const noexcept {
        return u.internal.size == 0;
    }
    void reset() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    void swap(basic_sstring& x) noexcept {
        contents tmp;
        tmp = x.u;
        x.u = u;
        u = tmp;
    }
    const char* c_str() const {
        return str();
    }
    const char_type* begin() const { return str(); }
    const char_type* end() const { return str() + size(); }
    char_type* begin() { return str(); }
    char_type* end() { return str() + size(); }
    bool operator==(const basic_sstring& x) const {
        return size() == x.size() && std::equal(begin(), end(), x.begin());
    }
    bool operator!=(const basic_sstring& x) const {
        return !operator==(x);
    }
    basic_sstring operator+(const basic_sstring& x) const {
        basic_sstring ret(initialized_later(), size() + x.size());
        std::copy(begin(), end(), ret.begin());
        std::copy(x.begin(), x.end(), ret.begin() + size());
        return ret;
    }
    basic_sstring& operator+=(const basic_sstring& x) {
        return *this = *this + x;
    }

    operator std::experimental::string_view() const {
        return std::experimental::string_view(str(), size());
    }
};

template <size_t N>
static inline
size_t str_len(const char(&s)[N]) { return N - 1; }

template <size_t N>
static inline
const char* str_begin(const char(&s)[N]) { return s; }

template <size_t N>
static inline
const char* str_end(const char(&s)[N]) { return str_begin(s) + str_len(s); }

template <typename char_type, typename size_type, size_type max_size>
static inline
const char_type* str_begin(const basic_sstring<char_type, size_type, max_size>& s) { return s.begin(); }

template <typename char_type, typename size_type, size_type max_size>
static inline
const char_type* str_end(const basic_sstring<char_type, size_type, max_size>& s) { return s.end(); }

template <typename char_type, typename size_type, size_type max_size>
static inline
size_type str_len(const basic_sstring<char_type, size_type, max_size>& s) { return s.size(); }

template <typename First, typename Second, typename... Tail>
static inline
const size_t str_len(const First& first, const Second& second, const Tail&... tail) {
    return str_len(first) + str_len(second, tail...);
}

template <typename char_type, typename size_type, size_type max_size>
inline
void swap(basic_sstring<char_type, size_type, max_size>& x,
          basic_sstring<char_type, size_type, max_size>& y) noexcept
{
    return x.swap(y);
}

template <typename char_type, typename size_type, size_type max_size, typename char_traits>
inline
std::basic_ostream<char_type, char_traits>&
operator<<(std::basic_ostream<char_type, char_traits>& os,
        const basic_sstring<char_type, size_type, max_size>& s) {
    return os.write(s.begin(), s.size());
}

namespace std {

template <typename char_type, typename size_type, size_type max_size>
struct hash<basic_sstring<char_type, size_type, max_size>> {
    size_t operator()(const basic_sstring<char_type, size_type, max_size>& s) const {
        return std::hash<std::experimental::string_view>()(s);
    }
};

}

using sstring = basic_sstring<char, uint32_t, 15>;

static inline
char* copy_str_to(char* dst) {
    return dst;
}

template <typename Head, typename... Tail>
static inline
char* copy_str_to(char* dst, const Head& head, const Tail&... tail) {
    return copy_str_to(std::copy(str_begin(head), str_end(head), dst), tail...);
}

template <typename String = sstring, typename... Args>
static String make_sstring(Args&&... args)
{
    String ret(sstring::initialized_later(), str_len(args...));
    copy_str_to(ret.begin(), args...);
    return ret;
}

template <typename T, typename String = sstring, typename for_enable_if = void*>
String to_sstring(T value, for_enable_if);

template <typename T>
inline
sstring to_sstring_sprintf(T value, const char* fmt) {
    char tmp[sizeof(value) * 3 + 3];
    auto len = std::sprintf(tmp, fmt, value);
    return sstring(tmp, len);
}

template <typename string_type = sstring>
inline
string_type to_sstring(int value, void* = nullptr) {
    return to_sstring_sprintf(value, "%d");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned value, void* = nullptr) {
    return to_sstring_sprintf(value, "%u");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%ld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lu");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%llu");
}

template <typename string_type = sstring>
inline
string_type to_sstring(const char* value, void* = nullptr) {
    return string_type(value);
}

template <typename string_type = sstring>
inline
string_type to_sstring(sstring value, void* = nullptr) {
    return value;
}

template <typename T>
inline
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    bool first = true;
    os << "{";
    for (auto&& elem : v) {
        if (!first) {
            os << ", ";
        } else {
            first = false;
        }
        os << elem;
    }
    os << "}";
    return os;
}

#endif /* SSTRING_HH_ */
<|endoftext|>


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

#include <boost/test/unit_test.hpp>

#include <APL/Log.h>
#include <APLTestTools/LogTester.h>
#include <APLTestTools/MockPhysicalLayerAsync.h>
#include <APLTestTools/MockTimerSource.h>
#include <APLTestTools/TestHelpers.h>

#include <DNP3/VtoRouter.h>
#include <DNP3/VtoWriter.h>

using namespace std;
using namespace apl;
using namespace apl::dnp;

class RouterTestClass : LogTester
{
	public:
	RouterTestClass() :
		LogTester(false),
		phys(mLog.GetLogger(LEV_DEBUG, "phys")),
		writer(100),
		mts(),
		router(mLog.GetLogger(LEV_DEBUG, "router"), 8, &writer, &phys, &mts)
	{}

	MockPhysicalLayerAsync phys;
	VtoWriter writer;
	MockTimerSource mts;
	VtoRouter router;
};

BOOST_AUTO_TEST_SUITE(VtoRouterTests)

	BOOST_AUTO_TEST_CASE(Construction)
	{
		RouterTestClass rtc;
	}

	BOOST_AUTO_TEST_CASE(StartsReadingAfterOpen)
	{
		RouterTestClass rtc;
		rtc.router.Start();
		BOOST_REQUIRE(rtc.phys.IsOpening());
		rtc.phys.SignalOpenSuccess();
		BOOST_REQUIRE(rtc.phys.IsReading());
	}

BOOST_AUTO_TEST_SUITE_END()

/* vim: set ts=4 sw=4: */
<commit_msg>Fixed file permissions on TestVtoRouter.cpp.  Bless you, Windows.<commit_after>//
// Licensed to Green Energy Corp (www.greenenergycorp.com) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Green Enery Corp licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//

#include <boost/test/unit_test.hpp>

#include <APL/Log.h>
#include <APLTestTools/LogTester.h>
#include <APLTestTools/MockPhysicalLayerAsync.h>
#include <APLTestTools/MockTimerSource.h>
#include <APLTestTools/TestHelpers.h>

#include <DNP3/VtoRouter.h>
#include <DNP3/VtoWriter.h>

using namespace std;
using namespace apl;
using namespace apl::dnp;

class RouterTestClass : LogTester
{
	public:
	RouterTestClass() :
		LogTester(false),
		phys(mLog.GetLogger(LEV_DEBUG, "phys")),
		writer(100),
		mts(),
		router(mLog.GetLogger(LEV_DEBUG, "router"), 8, &writer, &phys, &mts)
	{}

	MockPhysicalLayerAsync phys;
	VtoWriter writer;
	MockTimerSource mts;
	VtoRouter router;
};

BOOST_AUTO_TEST_SUITE(VtoRouterTests)

	BOOST_AUTO_TEST_CASE(Construction)
	{
		RouterTestClass rtc;
	}

	BOOST_AUTO_TEST_CASE(StartsReadingAfterOpen)
	{
		RouterTestClass rtc;
		rtc.router.Start();
		BOOST_REQUIRE(rtc.phys.IsOpening());
		rtc.phys.SignalOpenSuccess();
		BOOST_REQUIRE(rtc.phys.IsReading());
	}

BOOST_AUTO_TEST_SUITE_END()

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


<commit_before>#ifndef __SIMFQT_SIMFQT_TYPES_HPP
#define __SIMFQT_SIMFQT_TYPES_HPP

// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <vector>
#include <string>
// StdAir
#include <stdair/stdair_exceptions.hpp>

namespace SIMFQT {

  // ///////// Exceptions ///////////
  class FareFileParsingFailedException : public stdair::ParsingFileFailedException {
  public:
    /** Constructor. */
    FareFileParsingFailedException (const std::string& iWhat)
      : stdair::ParsingFileFailedException (iWhat) {}
  };

  class AirportPairNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /** Constructor. */
    AirportPairNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  class PosOrChannelNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /** Constructor. */
    PosOrChannelNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  class FlightDateNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /** Constructor. */
    FlightDateNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  class FlightTimeNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /** Constructor. */
    FlightTimeNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  class FeaturesNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /** Constructor. */
    FeaturesNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  class AirlineNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /** Constructor. */
    AirlineNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  class FareInputFileNotFoundException : public stdair::FileNotFoundException {
  public:
    /** Constructor. */
    FareInputFileNotFoundException (const std::string& iWhat)
      : stdair::FileNotFoundException (iWhat) {}
  };

  class QuotingException : public stdair::RootException {
  };

  // //////// Type definitions specific to SimFQT /////////
  /** ID for the Fare Quote system. */
  typedef unsigned int FareQuoteID_T;

}
#endif // __SIMFQT_SIMFQT_TYPES_HPP
<commit_msg>[Dev] Implemented, for DSim and SimCRS, the option of building the BOM tree either from parsing input files or from built-in samples.<commit_after>#ifndef __SIMFQT_SIMFQT_TYPES_HPP
#define __SIMFQT_SIMFQT_TYPES_HPP

// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <vector>
#include <string>
// Boost
#include <boost/shared_ptr.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>

namespace SIMFQT {

  // Forward declarations
  class SIMFQT_Service;

  // ///////// Exceptions ///////////
  /**
   * The fare input file can not be parsed.
   */
  class FareFileParsingFailedException
    : public stdair::ParsingFileFailedException {
  public:
    /**
     * Constructor.
     */
    FareFileParsingFailedException (const std::string& iWhat)
      : stdair::ParsingFileFailedException (iWhat) {}
  };

  /**
   * The given airport pair can not be found.
   */
  class AirportPairNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /**
     * Constructor.
     */
    AirportPairNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  /**
   * The given POS/channel can not be found.
   */
  class PosOrChannelNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /**
     * Constructor.
     */
    PosOrChannelNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  /**
   * The departure date of the flight can not be found.
   */
  class FlightDateNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /**
     * Constructor.
     */
    FlightDateNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  /**
   * The departure time of the flight can not be found.
   */
  class FlightTimeNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /**
     * Constructor.
     */
    FlightTimeNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  /**
   * The fare features can not be found.
   */
  class FeaturesNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /**
     * Constructor.
     */
    FeaturesNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  /**
   * The airline can not be found.
   */
  class AirlineNotFoundException : public stdair::ObjectNotFoundException {
  public:
    /**
     * Constructor.
     */
    AirlineNotFoundException (const std::string& iWhat)
      : stdair::ObjectNotFoundException (iWhat) {}
  };

  /**
   * The fare input file can not be found.
   */
  class FareInputFileNotFoundException : public stdair::FileNotFoundException {
  public:
    /**
     * Constructor.
     */
    FareInputFileNotFoundException (const std::string& iWhat)
      : stdair::FileNotFoundException (iWhat) {}
  };

  /**
   * The pricing operation fails.
   */
  class QuotingException : public stdair::RootException {
  };

  // //////// Type definitions specific to SimFQT /////////
  /**
   * ID for the Fare Quote system.
   */
  typedef unsigned int FareQuoteID_T;

  /**
   * (Smart) Pointer on the SimFQT service handler.
   */
  typedef boost::shared_ptr<SIMFQT_Service> SIMFQT_ServicePtr_T;
}
#endif // __SIMFQT_SIMFQT_TYPES_HPP
<|endoftext|>


<commit_before>#include <cassert>
#include <fstream>
#include <iostream>
#include <iterator>
#include <limits>
#include <mutex>
#include <sstream>
#include <string>
#include <thread>
#include <vector>

#include <boost/heap/fibonacci_heap.hpp>

struct Edge {
    const int target;
    const int cost;
    Edge(int target, int cost) : target(target), cost(cost) {}
};

struct Vertex {
    std::mutex mutex;
    std::vector<Edge> edges;
    void add_edge(int target, int cost) {
        std::lock_guard<std::mutex> lock(mutex);
        edges.emplace_back(target, cost);
    }
};

struct DistInfo {
    int v;
    int cost = std::numeric_limits<int>::max();
    int parent = -1;
    bool operator<(const DistInfo& that) const {
        return this->cost > that.cost;
    }
};

struct FilePartition {
    const int threads;
    const ssize_t start, stop, diff, div, mod;
    FilePartition(int threads, ssize_t start, ssize_t stop)
        : threads(threads),
          start(start),
          stop(stop),
          diff(stop - start),
          div(diff / threads),
          mod(diff % threads) {}
    ssize_t operator[](ssize_t tid) const {
        return start + div * tid + std::min(mod, tid);
    }
};

struct IntFile {
    std::ifstream ifs;
    int c = ' ';
    ssize_t g = 0;
    IntFile(const char* filename) : ifs(filename) {}
    operator bool() { return (bool)ifs; }
    IntFile& operator>>(int& other) {
        other = 0;
        while (c == ' ' or c == '\n' or c == '\t') {
            c = ifs.get();
            ++g;
        }
        while ('0' <= c and c <= '9') {
            other *= 10;
            other += c - '0';
            c = ifs.get();
            ++g;
        }
        return *this;
    }
    void seekg(ssize_t pos) {
        ifs.seekg(pos);
        g = pos;
    }
    ssize_t tellg() { return g; }
    void ignore(ssize_t, int chr) {
        while (c != '\n' and c != EOF) {
            ++g;
            c = ifs.get();
        }
    }
};

char* infile;
std::vector<Vertex> vertices;

void read_file(ssize_t from, ssize_t to) {
    // printf("%ld %ld %ld %s\n", from, to, vertices.size(), infile);
    IntFile fin(infile);
    assert(fin);
    fin.seekg(from);
    fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    while (fin.tellg() < to) {
        int u, v, cost;
        fin >> u >> v >> cost;
        fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        --u;
        --v;
        // printf("%d %d %d\n", u, v, cost);
        vertices.at(u).add_edge(v, cost);
        vertices.at(v).add_edge(u, cost);
    }
}

void sincelast(const char* message = 0) {
    static auto last = std::chrono::high_resolution_clock::now();
    auto now = std::chrono::high_resolution_clock::now();
    std::cout << message
              << ((std::chrono::duration<double>)(now - last)).count()
              << std::endl;
    last = now;
}

int main(int argc, char** argv) {
    std::ios_base::sync_with_stdio(false);
    assert(argc == 5);
    auto num_threads = std::stoi(argv[1]);
    assert(num_threads > 0);
    infile = argv[2];
    std::ifstream fin(argv[2]);
    std::ofstream fout(argv[3]);
    auto origin = std::stoi(argv[4]) - 1;
    if (not fin) {
        throw std::runtime_error("bad input file");
    }
    if (not fout) {
        throw std::runtime_error("bad output file");
    }
    int num_vertices, num_edges;
    fin >> num_vertices >> num_edges;
    auto file_start = fin.tellg();
    fin.seekg(0, std::ios_base::end);
    auto file_end = fin.tellg();
    FilePartition fp(num_threads, file_start, file_end);
    vertices = std::vector<Vertex>(num_vertices);
    std::vector<std::thread> rfthreads;
    sincelast("init ");
    for (int i = 0; i < num_threads; ++i) {
        rfthreads.emplace_back(read_file, fp[i], fp[i + 1]);
    }
    for (auto& thread : rfthreads) {
        thread.join();
    }
    sincelast("input ");
    std::vector<DistInfo> distinfo(num_vertices);
    distinfo[origin].cost = 0;
    distinfo[origin].parent = origin;
    using heap_t = boost::heap::fibonacci_heap<DistInfo>;
    heap_t heap;
    std::vector<heap_t::handle_type> handles;
    handles.reserve(num_vertices);
    for (int v = 0; v < num_vertices; ++v) {
        distinfo[v].v = v;
        handles.emplace_back(heap.push(distinfo[v]));
    }
    while (not heap.empty()) {
        int v = heap.top().v;
        heap.pop();
        const auto& vertex = vertices[v];
        const auto& di = distinfo[v];
        for (const auto& edge : vertex.edges) {
            auto& dst = distinfo[edge.target];
            auto off = di.cost + edge.cost;
            if (dst.cost > off) {
                dst.cost = off;
                dst.parent = v;
                heap.increase(handles[edge.target], dst);
            }
        }
    }
    sincelast("compute ");
    for (int i = 0; i < num_vertices; ++i) {
        std::vector<int> path;
        int cur = i;
        path.push_back(cur + 1);
        do {
            cur = distinfo[cur].parent;
            path.push_back(cur + 1);
        } while (cur != origin);
        std::copy(path.crbegin(), path.crend(),
                  std::ostream_iterator<int>(fout, " "));
        fout << '\n';
    }
    sincelast("output ");
}
<commit_msg>fix a bug<commit_after>#include <cassert>
#include <fstream>
#include <iostream>
#include <iterator>
#include <limits>
#include <mutex>
#include <sstream>
#include <string>
#include <thread>
#include <vector>

#include <boost/heap/fibonacci_heap.hpp>

struct Edge {
    const int target;
    const int cost;
    Edge(int target, int cost) : target(target), cost(cost) {}
};

struct Vertex {
    std::mutex mutex;
    std::vector<Edge> edges;
    void add_edge(int target, int cost) {
        std::lock_guard<std::mutex> lock(mutex);
        edges.emplace_back(target, cost);
    }
};

struct DistInfo {
    int v;
    int cost = std::numeric_limits<int>::max();
    int parent = -1;
    bool operator<(const DistInfo& that) const {
        return this->cost > that.cost;
    }
};

struct FilePartition {
    const int threads;
    const ssize_t start, stop, diff, div, mod;
    FilePartition(int threads, ssize_t start, ssize_t stop)
        : threads(threads),
          start(start),
          stop(stop),
          diff(stop - start),
          div(diff / threads),
          mod(diff % threads) {}
    ssize_t operator[](ssize_t tid) const {
        return start + div * tid + std::min(mod, tid);
    }
};

struct IntFile {
    std::ifstream ifs;
    int c = ' ';
    ssize_t g = 0;
    IntFile(const char* filename) : ifs(filename) {}
    operator bool() { return (bool)ifs; }
    IntFile& operator>>(int& other) {
        other = 0;
        while (c == ' ' or c == '\n' or c == '\t') {
            c = ifs.get();
            ++g;
        }
        while ('0' <= c and c <= '9') {
            other *= 10;
            other += c - '0';
            c = ifs.get();
            ++g;
        }
        return *this;
    }
    void seekg(ssize_t pos) {
        ifs.seekg(pos);
        g = pos;
    }
    ssize_t tellg() { return g; }
    void ignore(ssize_t, int chr) {
        while (c != '\n' and c != EOF) {
            ++g;
            c = ifs.get();
        }
    }
};

char* infile;
std::vector<Vertex> vertices;

void read_file(ssize_t from, ssize_t to) {
    // printf("%ld %ld %ld %s\n", from, to, vertices.size(), infile);
    IntFile fin(infile);
    assert(fin);
    fin.seekg(from);
    fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    while (fin.tellg() < to) {
        int u, v, cost;
        fin >> u >> v >> cost;
        fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        --u;
        --v;
        // printf("%d %d %d\n", u, v, cost);
        vertices.at(u).add_edge(v, cost);
        vertices.at(v).add_edge(u, cost);
    }
}

void sincelast(const char* message = 0) {
    static auto last = std::chrono::high_resolution_clock::now();
    auto now = std::chrono::high_resolution_clock::now();
    std::cout << message
              << ((std::chrono::duration<double>)(now - last)).count()
              << std::endl;
    last = now;
}

int main(int argc, char** argv) {
    std::ios_base::sync_with_stdio(false);
    assert(argc == 5);
    auto num_threads = std::stoi(argv[1]);
    assert(num_threads > 0);
    infile = argv[2];
    std::ifstream fin(argv[2]);
    std::ofstream fout(argv[3]);
    auto origin = std::stoi(argv[4]) - 1;
    if (not fin) {
        throw std::runtime_error("bad input file");
    }
    if (not fout) {
        throw std::runtime_error("bad output file");
    }
    int num_vertices, num_edges;
    fin >> num_vertices >> num_edges;
    auto file_start = fin.tellg();
    fin.seekg(0, std::ios_base::end);
    auto file_end = fin.tellg();
    FilePartition fp(num_threads, file_start, file_end);
    vertices = std::vector<Vertex>(num_vertices);
    std::vector<std::thread> rfthreads;
    sincelast("init ");
    for (int i = 0; i < num_threads; ++i) {
        rfthreads.emplace_back(read_file, fp[i] - 1, fp[i + 1]);
    }
    for (auto& thread : rfthreads) {
        thread.join();
    }
    sincelast("input ");
    std::vector<DistInfo> distinfo(num_vertices);
    distinfo[origin].cost = 0;
    distinfo[origin].parent = origin;
    using heap_t = boost::heap::fibonacci_heap<DistInfo>;
    heap_t heap;
    std::vector<heap_t::handle_type> handles;
    handles.reserve(num_vertices);
    for (int v = 0; v < num_vertices; ++v) {
        distinfo[v].v = v;
        handles.emplace_back(heap.push(distinfo[v]));
    }
    while (not heap.empty()) {
        int v = heap.top().v;
        heap.pop();
        const auto& vertex = vertices[v];
        const auto& di = distinfo[v];
        for (const auto& edge : vertex.edges) {
            auto& dst = distinfo[edge.target];
            auto off = di.cost + edge.cost;
            if (dst.cost > off) {
                dst.cost = off;
                dst.parent = v;
                heap.increase(handles[edge.target], dst);
            }
        }
    }
    sincelast("compute ");
    for (int i = 0; i < num_vertices; ++i) {
        std::vector<int> path;
        int cur = i;
        path.push_back(cur + 1);
        do {
            cur = distinfo[cur].parent;
            path.push_back(cur + 1);
        } while (cur != origin);
        std::copy(path.crbegin(), path.crend(),
                  std::ostream_iterator<int>(fout, " "));
        fout << '\n';
    }
    sincelast("output ");
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-present Advanced Micro Devices, Inc.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE. */

#include "top.hpp"
#include "utils/flags.hpp"

#include <unordered_map>
#include <string>
#include <cstdlib>
#include <cstring>

#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#else
#include <unistd.h>
#endif  // !_WIN32

namespace {

const char* removeQuotes(const char* Value) {
  const char *b, *e, *p;
  if (Value == NULL) {
    return Value;
  }

  // skip the leading blank
  for (p = Value; *p == ' '; ++p)
    ;
  if (*p != '"') {
    return Value;
  }
  b = p;
  e = NULL;
  for (++p; *p != '\0'; ++p) {
    if (*p == '"') {
      // e points to the last '"'
      e = p;
    } else if ((e != NULL) && (*p != ' ')) {
      // e isn't last '"' if there is any non-blank following e
      e = NULL;
    }
  }

  if (e == NULL) {
    return Value;
  }
  // Found a valid quoted string "<str>" with b=1st '"' and e=the last '"'
  size_t len = (e - b - 1) > 0 ? (e - b - 1) : 0;
#ifdef _WIN32
  char* p1 = _strdup(b + 1);
  p1[len] = '\0';
  p = p1;
#else
  p = strndup(b + 1, len);
#endif
  return p;
}
}

namespace amd {

#ifdef __APPLE__
#include <crt_externs.h>
#endif  // __APPLE__

bool IS_HIP = false;
std::atomic_bool IS_PROFILER_ON(false);

#if defined(WITH_GPU_DEVICE)
bool IS_LEGACY = true;
#else
bool IS_LEGACY = false;
#endif

// static
char* Flag::envstr_;

void Flag::tearDown() {
#ifdef _WIN32
  FreeEnvironmentStringsA(envstr_);
#endif
}

bool Flag::init() {
  typedef std::unordered_map<std::string, const char*> vars_type;
  vars_type vars;

#ifdef _WIN32
  char* str = GetEnvironmentStringsA();
  envstr_ = str;

  for (; *str != '\0'; str += strlen(str) + 1) {
    // For all environment variables:
    std::string var = str;
    size_t pos = var.find('=');
    if ((pos == std::string::npos) || ((pos + 1) >= var.size())) {
      continue;
    }

    std::string name = var.substr(0, pos);
    vars.insert(std::make_pair(name, &str[pos + 1]));
  }
#else  // !_WIN32
#ifdef __APPLE__
  char** environ = *_NSGetEnviron();
  if (environ == NULL) {
    return false;
  }
#endif  // __APPLE__

  for (const char** p = const_cast<const char**>(environ); *p != NULL; ++p) {
    std::string var = *p;
    size_t pos = var.find('=');
    if ((pos == std::string::npos) || ((pos + 1) >= var.size())) {
      continue;
    }

    std::string name = var.substr(0, pos);
    vars.insert(std::make_pair(name, &(*p)[pos + 1]));
  }
#endif  // !_WIN32

  for (size_t i = 0; i < numFlags_; ++i) {
    Flag& flag = flags_[i];

    const auto it = vars.find(flag.name_);
    if (it != vars.cend()) {
      flag.setValue(it->second);
    }
  }
  if (!flagIsDefault(AMD_LOG_LEVEL)) {
    if (!flagIsDefault(AMD_LOG_LEVEL_FILE)) {
      std::string fileName = AMD_LOG_LEVEL_FILE;
      outFile = fopen(fileName.c_str(), "w");
    }
  }

  return true;
}

bool Flag::setValue(const char* value) {
  if (value_ == NULL) {
    return false;  // flag is constant.
  }

  isDefault_ = false;

  switch (type_) {
    case Tbool:
      *(bool*)value_ = (strcmp(value, "true") == 0 || atoi(value) != 0) ? true : false;
      return true;

    case Tint:
    case Tuint:
      *(int*)value_ = atoi(value);
      return true;

    case Tsize_t:
      *(size_t*)value_ = atol(value);
      return true;

    case Tcstring:
      *(const char**)value_ = removeQuotes(value);
      return true;

    default:
      break;
  }
  ShouldNotReachHere();
  return false;
}

#define DEFINE_RELEASE_FLAG_STRUCT(type, name, value, help) {#name, &name, T##type, true},
#define DEFINE_DEBUG_FLAG_STRUCT(type, name, value, help)                                          \
  {#name, RELEASE_ONLY(NULL) DEBUG_ONLY(&name), T##type, true},

Flag Flag::flags_[] = {
    RUNTIME_FLAGS(DEFINE_DEBUG_FLAG_STRUCT, DEFINE_RELEASE_FLAG_STRUCT, DEFINE_DEBUG_FLAG_STRUCT)
        {NULL, NULL, Tinvalid, true}};

#undef DEFINE_DEBUG_FLAG_STRUCT
#undef DEFINE_RELEASE_FLAG_STRUCT

}  // namespace amd

#define DEFINE_RELEASE_FLAG_VALUE(type, name, value, help) type name = value;
#define DEFINE_DEBUG_FLAG_VALUE(type, name, value, help) DEBUG_ONLY(type name = value);

RUNTIME_FLAGS(DEFINE_DEBUG_FLAG_VALUE, DEFINE_RELEASE_FLAG_VALUE, DEFINE_DEBUG_FLAG_VALUE);

#undef DEFINE_DEBUG_FLAG_VALUE
#undef DEFINE_RELEASE_FLAG_VALUE
<commit_msg>SWDEV-86035 - Make sure the legacy lib is loaded with PAL backend<commit_after>/* Copyright (c) 2008-present Advanced Micro Devices, Inc.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE. */

#include "top.hpp"
#include "utils/flags.hpp"

#include <unordered_map>
#include <string>
#include <cstdlib>
#include <cstring>

#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#else
#include <unistd.h>
#endif  // !_WIN32

namespace {

const char* removeQuotes(const char* Value) {
  const char *b, *e, *p;
  if (Value == NULL) {
    return Value;
  }

  // skip the leading blank
  for (p = Value; *p == ' '; ++p)
    ;
  if (*p != '"') {
    return Value;
  }
  b = p;
  e = NULL;
  for (++p; *p != '\0'; ++p) {
    if (*p == '"') {
      // e points to the last '"'
      e = p;
    } else if ((e != NULL) && (*p != ' ')) {
      // e isn't last '"' if there is any non-blank following e
      e = NULL;
    }
  }

  if (e == NULL) {
    return Value;
  }
  // Found a valid quoted string "<str>" with b=1st '"' and e=the last '"'
  size_t len = (e - b - 1) > 0 ? (e - b - 1) : 0;
#ifdef _WIN32
  char* p1 = _strdup(b + 1);
  p1[len] = '\0';
  p = p1;
#else
  p = strndup(b + 1, len);
#endif
  return p;
}
}

namespace amd {

#ifdef __APPLE__
#include <crt_externs.h>
#endif  // __APPLE__

bool IS_HIP = false;
std::atomic_bool IS_PROFILER_ON(false);

#if defined(WITH_GPU_DEVICE)
bool IS_LEGACY = true;
#else
#if !defined(_WIN32) && defined(WITH_PAL_DEVICE)
bool IS_LEGACY = true;
#else
bool IS_LEGACY = false;
#endif
#endif

// static
char* Flag::envstr_;

void Flag::tearDown() {
#ifdef _WIN32
  FreeEnvironmentStringsA(envstr_);
#endif
}

bool Flag::init() {
  typedef std::unordered_map<std::string, const char*> vars_type;
  vars_type vars;

#ifdef _WIN32
  char* str = GetEnvironmentStringsA();
  envstr_ = str;

  for (; *str != '\0'; str += strlen(str) + 1) {
    // For all environment variables:
    std::string var = str;
    size_t pos = var.find('=');
    if ((pos == std::string::npos) || ((pos + 1) >= var.size())) {
      continue;
    }

    std::string name = var.substr(0, pos);
    vars.insert(std::make_pair(name, &str[pos + 1]));
  }
#else  // !_WIN32
#ifdef __APPLE__
  char** environ = *_NSGetEnviron();
  if (environ == NULL) {
    return false;
  }
#endif  // __APPLE__

  for (const char** p = const_cast<const char**>(environ); *p != NULL; ++p) {
    std::string var = *p;
    size_t pos = var.find('=');
    if ((pos == std::string::npos) || ((pos + 1) >= var.size())) {
      continue;
    }

    std::string name = var.substr(0, pos);
    vars.insert(std::make_pair(name, &(*p)[pos + 1]));
  }
#endif  // !_WIN32

  for (size_t i = 0; i < numFlags_; ++i) {
    Flag& flag = flags_[i];

    const auto it = vars.find(flag.name_);
    if (it != vars.cend()) {
      flag.setValue(it->second);
    }
  }
  if (!flagIsDefault(AMD_LOG_LEVEL)) {
    if (!flagIsDefault(AMD_LOG_LEVEL_FILE)) {
      std::string fileName = AMD_LOG_LEVEL_FILE;
      outFile = fopen(fileName.c_str(), "w");
    }
  }

  return true;
}

bool Flag::setValue(const char* value) {
  if (value_ == NULL) {
    return false;  // flag is constant.
  }

  isDefault_ = false;

  switch (type_) {
    case Tbool:
      *(bool*)value_ = (strcmp(value, "true") == 0 || atoi(value) != 0) ? true : false;
      return true;

    case Tint:
    case Tuint:
      *(int*)value_ = atoi(value);
      return true;

    case Tsize_t:
      *(size_t*)value_ = atol(value);
      return true;

    case Tcstring:
      *(const char**)value_ = removeQuotes(value);
      return true;

    default:
      break;
  }
  ShouldNotReachHere();
  return false;
}

#define DEFINE_RELEASE_FLAG_STRUCT(type, name, value, help) {#name, &name, T##type, true},
#define DEFINE_DEBUG_FLAG_STRUCT(type, name, value, help)                                          \
  {#name, RELEASE_ONLY(NULL) DEBUG_ONLY(&name), T##type, true},

Flag Flag::flags_[] = {
    RUNTIME_FLAGS(DEFINE_DEBUG_FLAG_STRUCT, DEFINE_RELEASE_FLAG_STRUCT, DEFINE_DEBUG_FLAG_STRUCT)
        {NULL, NULL, Tinvalid, true}};

#undef DEFINE_DEBUG_FLAG_STRUCT
#undef DEFINE_RELEASE_FLAG_STRUCT

}  // namespace amd

#define DEFINE_RELEASE_FLAG_VALUE(type, name, value, help) type name = value;
#define DEFINE_DEBUG_FLAG_VALUE(type, name, value, help) DEBUG_ONLY(type name = value);

RUNTIME_FLAGS(DEFINE_DEBUG_FLAG_VALUE, DEFINE_RELEASE_FLAG_VALUE, DEFINE_DEBUG_FLAG_VALUE);

#undef DEFINE_DEBUG_FLAG_VALUE
#undef DEFINE_RELEASE_FLAG_VALUE
<|endoftext|>