<commit_before>#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QFile>
#include <QMenu>
#include <QTreeWidget>
#include <QDateTime>

#include "about.h"
#include "settings.h"
#include "ipobjects.h"
#include "messenger.h"
#include "messagedialog.h"
#include "fileutils.h"
#include "sendfileprogressdialog.h"
#include "recvfileprogressdialog.h"
#include "qommunicate.h"

Qommunicate::Qommunicate(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    createTrayIcon();

    memberCountLabel.setText("0");
    statusBar()->addPermanentWidget(&memberCountLabel);

    MemberUtils::init();
    populateTree();
    firstRun();
    messenger()->login();

    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));

    connect(messenger(), SIGNAL(msg_ansEntry(Message)), this, SLOT(addMember(Message)));
    connect(messenger(), SIGNAL(msg_entry(Message)), this, SLOT(addMemberAndAnswer(Message)));
    connect(messenger(), SIGNAL(msg_exit(Message)), this, SLOT(removeMember(Message)));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(openDialog(Message)));
    connect(messenger(), SIGNAL(msg_readConfirmMsg(Message)), this, SLOT(confirmRead(Message)));
    connect(messenger(), SIGNAL(msg_fileRecvRequest(Message)), this, SLOT(fileRecvRequested(Message)));
    connect(messenger(), SIGNAL(msg_getAbsenceInfo(Message)), this, SLOT(sendAbsenceInfo(Message)));
    connect(messenger(), SIGNAL(msg_absence(Message)), this, SLOT(absenceChanged(Message)));

    connect(fileUtils(), SIGNAL(newFileSendSocket(QTcpSocket*)), this, SLOT(fileSendRequested(QTcpSocket*)));
}

void Qommunicate::on_searchEdit_textChanged(const QString &text)
{
    filterModel->setFilterFixedString(text);
    ui.memberTree->expandAll();
}

void Qommunicate::on_action_About_triggered()
{
    AboutDialog(this).exec();
}

void Qommunicate::on_action_Settings_triggered()
{
    SettingsDialog sd(this);
    connect(&sd, SIGNAL(settingsChanged()), messenger(), SLOT(nickChanged()));
    sd.exec();
}

void Qommunicate::on_actionMulticast_triggered()
{
    MessageDialog dlg(this);
    dlg.exec();
}

void Qommunicate::on_actionQuit_triggered()
{
    qApp->quit();
}

void Qommunicate::closeEvent(QCloseEvent * event)
{
    setVisible(false);
    event->ignore();
}

void Qommunicate::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if( reason == QSystemTrayIcon::Trigger )
        setVisible(!isVisible());
}

void Qommunicate::createTrayIcon()
{
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(windowIcon());

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    QMenu *menu = new QMenu;
    menu->addAction(ui.actionMulticast);
    menu->addAction(ui.actionQuit);
    trayIcon->setContextMenu(menu);

    trayIcon->show();
}

void Qommunicate::populateTree()
{
    model = new MemberModel(this);
    filterModel = new MemberFilter(this);

    filterModel->setSourceModel(model);
    filterModel->setDynamicSortFilter(true);
    filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    ui.memberTree->setSelectionMode(ui.memberTree->ExtendedSelection);
    ui.memberTree->setModel(filterModel);
    ui.memberTree->setHeaderHidden(true);
    ui.memberTree->setAcceptDrops(true);
    ui.memberTree->setExpandsOnDoubleClick(false);
    ui.memberTree->expandAll();
}

/*
If item is a group, adds all submembers to receivers and returns true.
otherwise assumes item is a member, inserts in receivers and returns false
*/
bool Qommunicate::createGroupMemberList(QStandardItem* item, QSet<Member*>& receivers)
{
    if(item->type() == TYPE_GROUP)
    {
        if(!item->hasChildren())
            return true;

        for(int i = 0; i < item->rowCount(); i++)
        {
            receivers << (Member*)item->child(i, 0);
        }
        return true;
    }
    receivers << (Member*)item;
    return false;
}

void Qommunicate::on_memberTree_doubleClicked(const QModelIndex& proxyIndex)
{

    MessageDialog* dlg;
    QSet<Member*> receivers;

    MemberModel* model = (MemberModel*) ( (MemberFilter*) ui.memberTree->model() )->sourceModel();
    QModelIndex index = ((MemberFilter*)ui.memberTree->model())->mapToSource(proxyIndex);

    if(index.isValid())
    {
        // only single item clicked
        createGroupMemberList(model->itemFromIndex(index), receivers);
    }
    else
    {
        QModelIndex i;
        foreach(i, ui.memberTree->selectionModel()->selectedRows())
        {
            QStandardItem* item = model->itemFromIndex(((MemberFilter*)ui.memberTree->model())->mapToSource(i));
            createGroupMemberList(item, receivers);
        }
    }

    if(receivers.isEmpty())
        return;

    QList<Member*> toDialog = receivers.toList();
    if(toDialog.size() == 1 && MemberUtils::contains("open_conversations", toDialog[0]))
        return;

    if(toDialog.size() == 1)
    {
        if(!MemberUtils::contains("open_conversations", toDialog[0]))
            dlg = new MessageDialog( new Member(*toDialog[0]), this );
    }
    else
        dlg = new MessageDialog( toDialog, this );

    dlg->setModal(false);
    dlg->show();
}

void Qommunicate::on_statusCombo_currentIndexChanged(const QString& text)
{
    messenger()->multicast(QOM_BR_ABSENCE, me().name().toAscii()+'\0'+myGroup().name().toAscii());
}

void Qommunicate::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return && ui.memberTree->hasFocus()) {
        event->accept();
        on_memberTree_doubleClicked(QModelIndex());
        return;
    }
    event->ignore();
}

void Qommunicate::firstRun()
{
    QSettings s;
    if( ! s.contains(tr("nick")) )
        ui.action_Settings->trigger();
}

void Qommunicate::dialogOpened(Member* m)
{
    MemberUtils::insert("open_conversations", m);
}

void Qommunicate::dialogClosed(Member *m)
{
    MemberUtils::remove("open_conversations", m);
}

void Qommunicate::cleanup()
{
    messenger()->logout();
    delete messenger();
}

// Message handling slots
void Qommunicate::addMember(Message msg)
{
    if(MemberUtils::contains("members_list", msg.sender()))
        return;

    QList<QByteArray> tokens = msg.payload().split('\a');
    msg.sender()->setName(tokens[0]);

    Member* sender = new Member(*msg.sender());

    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    if(groupName.isEmpty())
    {
        model->appendRow(sender);
    }
    else
    {
        QList<QStandardItem*> matches = model->findItems(groupName);
        if(!matches.isEmpty() && matches[0]->type() == TYPE_GROUP)
        {
            matches[0]->appendRow(sender);
        }
        else
        {
            Group * group = new Group(groupName);
            group->appendRow(sender);
            model->appendRow(group);
        }
    }

    MemberUtils::insert("members_list", sender);
    memberCountLabel.setText(QString::number(memberCountLabel.text().toInt() + 1));
    ui.memberTree->expandAll();
}

void Qommunicate::addMemberAndAnswer(Message msg)
{
    addMember(msg);
    messenger()->sendMessage(QOM_ANSENTRY, (me().name()+'\0'+myGroup().name()).toAscii(), msg.sender());
}

void Qommunicate::removeMember(Message msg)
{
    qDebug() << "removeMember: called with" << msg.sender()->name();
    QList<QByteArray> tokens = msg.payload().split('\a');
    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    Member* sender = new Member(*msg.sender());

    for(int i = 0; i < model->rowCount(); i++)
    {
        QStandardItem* it = model->item(i, 0);
        if(it->type() == TYPE_MEMBER && ((Member*)it)->name() == sender->addressString())
        {
            qDebug() << "removeMember: Deleting" << ((Member*)it->row())->name();
            model->removeRow(it->row());
        }
        else
        {
            for(int j = 0; j < it->rowCount(); j++)
            {
                if(((Member*)it->child(j))->addressString() == sender->addressString())
                {
                    qDebug() << "removeMember: Deleting" << ((Member*)it->child(j))->name();
                    it->removeRow(j);
                }
            }
            //remove empty group
            if(it->rowCount() == 0)
            {
                model->removeRow(it->row());
            }
        }
    }
    qDebug() << "Now deleting" << sender->name() << "from members_list";
    MemberUtils::remove("members_list", sender->addressString());
    memberCountLabel.setText(QString::number(memberCountLabel.text().toInt() - 1));
}

void Qommunicate::openDialog(Message msg)
{
    if(MemberUtils::contains("open_conversations", msg.sender()))
        return;

    // if set to ignore received messages
    QSettings s;
    if(s.value(tr("no_receive")).toBool() && (msg.command() & QOM_MULTICASTOPT))
    {
        notify(tr("Multicast"), tr("Multicast from %1 ignored").arg(MemberUtils::get("members_list", msg.sender())->name()));
        if(msg.command() & QOM_SENDCHECKOPT)
            messenger()->sendMessage(QOM_RECVMSG, QByteArray::number(msg.packetNo()), msg.sender());
        return;
    }

    Member* with = MemberUtils::get("members_list", msg.sender());
    if(!with->isValid())
        with = msg.sender();
    MessageDialog *dlg = new MessageDialog(new Member(*with));
    dlg->setModal(false);
    dlg->show();
    dlg->incomingMessage(msg);
}

void Qommunicate::sendAbsenceInfo(Message msg)
{
    QString payload = ui.statusCombo->currentText();
    if(payload == tr("Available"))
        payload = "Not absence mode";
    messenger()->multicast(QOM_SENDABSENCEINFO, payload.toAscii());
}

void Qommunicate::fileSendRequested(QTcpSocket* sock)
{
    qDebug() << "\n\nReceived new connection";
    new FileSendProgressDialog(sock);
}

void Qommunicate::fileRecvRequested(Message msg)
{
    qDebug() << "\n\nRequest for file receiving";
    if(msg.command() & QOM_SENDCHECKOPT)
        messenger()->sendMessage(QOM_RECVMSG, QByteArray::number(msg.packetNo()), msg.sender());
    RecvFileProgressDialog* dlg = new RecvFileProgressDialog(msg);
    connect(dlg, SIGNAL(downloadDone(QString)), this, SLOT(fileRecvDone(QString)));
    connect(dlg, SIGNAL(allDownloadsDone(QString)), this, SLOT(fileRecvDone(QString)));
}

void Qommunicate::fileRecvDone(QString message)
{
    notify(tr("Download done"), message, true);
}

void Qommunicate::notify(const QString& title, const QString& message, bool dialog)
{
    if(trayIcon->supportsMessages())
        trayIcon->showMessage(title, message);
    statusBar()->showMessage(message, 10000);

    if(dialog)
        QMessageBox::information(this, title, message);
}

void Qommunicate::confirmRead(Message msg)
{
    QString time = QDateTime::currentDateTime().toString("h:mm:ss");

    QString message = QString("%1\n%2 read message").arg(time).arg(MemberUtils::get("members_list", msg.sender())->name());

    messenger()->sendMessage(QOM_ANSREADMSG, QByteArray::number(msg.packetNo()), msg.sender());
    notify(tr("Message Read"), message, true);
}

void Qommunicate::absenceChanged(Message msg)
{
//     QString name = MemberUtils::get("members_list", msg.sender())->name();
//     qDebug() << "absenceChanged "<<name;
//     QString status = msg.payload().mid(name.length());
//     MemberUtils::get("members_list", msg.sender())->setStatus(status);
}<commit_msg>Sealed messages are ignored if ignore multicasts is set<commit_after>#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QFile>
#include <QMenu>
#include <QTreeWidget>
#include <QDateTime>

#include "about.h"
#include "settings.h"
#include "ipobjects.h"
#include "messenger.h"
#include "messagedialog.h"
#include "fileutils.h"
#include "sendfileprogressdialog.h"
#include "recvfileprogressdialog.h"
#include "qommunicate.h"

Qommunicate::Qommunicate(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    createTrayIcon();

    memberCountLabel.setText("0");
    statusBar()->addPermanentWidget(&memberCountLabel);

    MemberUtils::init();
    populateTree();
    firstRun();
    messenger()->login();

    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));

    connect(messenger(), SIGNAL(msg_ansEntry(Message)), this, SLOT(addMember(Message)));
    connect(messenger(), SIGNAL(msg_entry(Message)), this, SLOT(addMemberAndAnswer(Message)));
    connect(messenger(), SIGNAL(msg_exit(Message)), this, SLOT(removeMember(Message)));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(openDialog(Message)));
    connect(messenger(), SIGNAL(msg_readConfirmMsg(Message)), this, SLOT(confirmRead(Message)));
    connect(messenger(), SIGNAL(msg_fileRecvRequest(Message)), this, SLOT(fileRecvRequested(Message)));
    connect(messenger(), SIGNAL(msg_getAbsenceInfo(Message)), this, SLOT(sendAbsenceInfo(Message)));
    connect(messenger(), SIGNAL(msg_absence(Message)), this, SLOT(absenceChanged(Message)));

    connect(fileUtils(), SIGNAL(newFileSendSocket(QTcpSocket*)), this, SLOT(fileSendRequested(QTcpSocket*)));
}

void Qommunicate::on_searchEdit_textChanged(const QString &text)
{
    filterModel->setFilterFixedString(text);
    ui.memberTree->expandAll();
}

void Qommunicate::on_action_About_triggered()
{
    AboutDialog(this).exec();
}

void Qommunicate::on_action_Settings_triggered()
{
    SettingsDialog sd(this);
    connect(&sd, SIGNAL(settingsChanged()), messenger(), SLOT(nickChanged()));
    sd.exec();
}

void Qommunicate::on_actionMulticast_triggered()
{
    MessageDialog dlg(this);
    dlg.exec();
}

void Qommunicate::on_actionQuit_triggered()
{
    qApp->quit();
}

void Qommunicate::closeEvent(QCloseEvent * event)
{
    setVisible(false);
    event->ignore();
}

void Qommunicate::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if( reason == QSystemTrayIcon::Trigger )
        setVisible(!isVisible());
}

void Qommunicate::createTrayIcon()
{
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(windowIcon());

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    QMenu *menu = new QMenu;
    menu->addAction(ui.actionMulticast);
    menu->addAction(ui.actionQuit);
    trayIcon->setContextMenu(menu);

    trayIcon->show();
}

void Qommunicate::populateTree()
{
    model = new MemberModel(this);
    filterModel = new MemberFilter(this);

    filterModel->setSourceModel(model);
    filterModel->setDynamicSortFilter(true);
    filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    ui.memberTree->setSelectionMode(ui.memberTree->ExtendedSelection);
    ui.memberTree->setModel(filterModel);
    ui.memberTree->setHeaderHidden(true);
    ui.memberTree->setAcceptDrops(true);
    ui.memberTree->setExpandsOnDoubleClick(false);
    ui.memberTree->expandAll();
}

/*
If item is a group, adds all submembers to receivers and returns true.
otherwise assumes item is a member, inserts in receivers and returns false
*/
bool Qommunicate::createGroupMemberList(QStandardItem* item, QSet<Member*>& receivers)
{
    if(item->type() == TYPE_GROUP)
    {
        if(!item->hasChildren())
            return true;

        for(int i = 0; i < item->rowCount(); i++)
        {
            receivers << (Member*)item->child(i, 0);
        }
        return true;
    }
    receivers << (Member*)item;
    return false;
}

void Qommunicate::on_memberTree_doubleClicked(const QModelIndex& proxyIndex)
{

    MessageDialog* dlg;
    QSet<Member*> receivers;

    MemberModel* model = (MemberModel*) ( (MemberFilter*) ui.memberTree->model() )->sourceModel();
    QModelIndex index = ((MemberFilter*)ui.memberTree->model())->mapToSource(proxyIndex);

    if(index.isValid())
    {
        // only single item clicked
        createGroupMemberList(model->itemFromIndex(index), receivers);
    }
    else
    {
        QModelIndex i;
        foreach(i, ui.memberTree->selectionModel()->selectedRows())
        {
            QStandardItem* item = model->itemFromIndex(((MemberFilter*)ui.memberTree->model())->mapToSource(i));
            createGroupMemberList(item, receivers);
        }
    }

    if(receivers.isEmpty())
        return;

    QList<Member*> toDialog = receivers.toList();
    if(toDialog.size() == 1 && MemberUtils::contains("open_conversations", toDialog[0]))
        return;

    if(toDialog.size() == 1)
    {
        if(!MemberUtils::contains("open_conversations", toDialog[0]))
            dlg = new MessageDialog( new Member(*toDialog[0]), this );
    }
    else
        dlg = new MessageDialog( toDialog, this );

    dlg->setModal(false);
    dlg->show();
}

void Qommunicate::on_statusCombo_currentIndexChanged(const QString& text)
{
    messenger()->multicast(QOM_BR_ABSENCE, me().name().toAscii()+'\0'+myGroup().name().toAscii());
}

void Qommunicate::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return && ui.memberTree->hasFocus()) {
        event->accept();
        on_memberTree_doubleClicked(QModelIndex());
        return;
    }
    event->ignore();
}

void Qommunicate::firstRun()
{
    QSettings s;
    if( ! s.contains(tr("nick")) )
        ui.action_Settings->trigger();
}

void Qommunicate::dialogOpened(Member* m)
{
    MemberUtils::insert("open_conversations", m);
}

void Qommunicate::dialogClosed(Member *m)
{
    MemberUtils::remove("open_conversations", m);
}

void Qommunicate::cleanup()
{
    messenger()->logout();
    delete messenger();
}

// Message handling slots
void Qommunicate::addMember(Message msg)
{
    if(MemberUtils::contains("members_list", msg.sender()))
        return;

    QList<QByteArray> tokens = msg.payload().split('\a');
    msg.sender()->setName(tokens[0]);

    Member* sender = new Member(*msg.sender());

    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    if(groupName.isEmpty())
    {
        model->appendRow(sender);
    }
    else
    {
        QList<QStandardItem*> matches = model->findItems(groupName);
        if(!matches.isEmpty() && matches[0]->type() == TYPE_GROUP)
        {
            matches[0]->appendRow(sender);
        }
        else
        {
            Group * group = new Group(groupName);
            group->appendRow(sender);
            model->appendRow(group);
        }
    }

    MemberUtils::insert("members_list", sender);
    memberCountLabel.setText(QString::number(memberCountLabel.text().toInt() + 1));
    ui.memberTree->expandAll();
}

void Qommunicate::addMemberAndAnswer(Message msg)
{
    addMember(msg);
    messenger()->sendMessage(QOM_ANSENTRY, (me().name()+'\0'+myGroup().name()).toAscii(), msg.sender());
}

void Qommunicate::removeMember(Message msg)
{
    qDebug() << "removeMember: called with" << msg.sender()->name();
    QList<QByteArray> tokens = msg.payload().split('\a');
    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    Member* sender = new Member(*msg.sender());

    for(int i = 0; i < model->rowCount(); i++)
    {
        QStandardItem* it = model->item(i, 0);
        if(it->type() == TYPE_MEMBER && ((Member*)it)->name() == sender->addressString())
        {
            qDebug() << "removeMember: Deleting" << ((Member*)it->row())->name();
            model->removeRow(it->row());
        }
        else
        {
            for(int j = 0; j < it->rowCount(); j++)
            {
                if(((Member*)it->child(j))->addressString() == sender->addressString())
                {
                    qDebug() << "removeMember: Deleting" << ((Member*)it->child(j))->name();
                    it->removeRow(j);
                }
            }
            //remove empty group
            if(it->rowCount() == 0)
            {
                model->removeRow(it->row());
            }
        }
    }
    qDebug() << "Now deleting" << sender->name() << "from members_list";
    MemberUtils::remove("members_list", sender->addressString());
    memberCountLabel.setText(QString::number(memberCountLabel.text().toInt() - 1));
}

void Qommunicate::openDialog(Message msg)
{
    if(MemberUtils::contains("open_conversations", msg.sender()))
        return;

    // if set to ignore received messages
    QSettings s;
    if(s.value(tr("no_receive")).toBool() && (msg.command() & QOM_MULTICASTOPT))
    {
        notify(tr("Multicast"), tr("Multicast from %1 ignored").arg(MemberUtils::get("members_list", msg.sender())->name()));
        if(msg.command() & QOM_SENDCHECKOPT)
            messenger()->sendMessage(QOM_RECVMSG, QByteArray::number(msg.packetNo()), msg.sender());
        return;
    }

    Member* with = MemberUtils::get("members_list", msg.sender());
    if(!with->isValid())
        with = msg.sender();
    MessageDialog *dlg = new MessageDialog(new Member(*with));
    dlg->setModal(false);
    dlg->show();
    dlg->incomingMessage(msg);
}

void Qommunicate::sendAbsenceInfo(Message msg)
{
    QString payload = ui.statusCombo->currentText();
    if(payload == tr("Available"))
        payload = "Not absence mode";
    messenger()->multicast(QOM_SENDABSENCEINFO, payload.toAscii());
}

void Qommunicate::fileSendRequested(QTcpSocket* sock)
{
    qDebug() << "\n\nReceived new connection";
    new FileSendProgressDialog(sock);
}

void Qommunicate::fileRecvRequested(Message msg)
{
    qDebug() << "\n\nRequest for file receiving";
    if(msg.command() & QOM_SENDCHECKOPT)
        messenger()->sendMessage(QOM_RECVMSG, QByteArray::number(msg.packetNo()), msg.sender());
    RecvFileProgressDialog* dlg = new RecvFileProgressDialog(msg);
    connect(dlg, SIGNAL(downloadDone(QString)), this, SLOT(fileRecvDone(QString)));
    connect(dlg, SIGNAL(allDownloadsDone(QString)), this, SLOT(fileRecvDone(QString)));
}

void Qommunicate::fileRecvDone(QString message)
{
    notify(tr("Download done"), message, true);
}

void Qommunicate::notify(const QString& title, const QString& message, bool dialog)
{
    if(trayIcon->supportsMessages())
        trayIcon->showMessage(title, message);
    statusBar()->showMessage(message, 10000);

    if(dialog)
        QMessageBox::information(this, title, message);
}

void Qommunicate::confirmRead(Message msg)
{
    //if ignoring multicasts, then we aren't gonna reply to the sealed message
    QSettings s;
    if(s.value("no_receive").toBool())
        return;

    QString time = QDateTime::currentDateTime().toString("h:mm:ss");

    QString message = QString("%1\n%2 read message").arg(time).arg(MemberUtils::get("members_list", msg.sender())->name());

    messenger()->sendMessage(QOM_ANSREADMSG, QByteArray::number(msg.packetNo()), msg.sender());
    notify(tr("Message Read"), message, true);
}

void Qommunicate::absenceChanged(Message msg)
{
//     QString name = MemberUtils::get("members_list", msg.sender())->name();
//     qDebug() << "absenceChanged "<<name;
//     QString status = msg.payload().mid(name.length());
//     MemberUtils::get("members_list", msg.sender())->setStatus(status);
}<|endoftext|>


<commit_before>//---------------------------------*-C++-*-----------------------------------//
/*!
 * \file   Utils/comm/OMP.hh
 * \author Thomas M. Evans
 * \date   Thu Aug 20 10:18:57 2015
 * \brief  OMP class declaration.
 * \note   Copyright (c) 2015 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#ifndef Utils_comm_OMP_hh
#define Utils_comm_OMP_hh

#ifdef _OPENMP
#include <omp.h>
#endif

namespace profugus
{

//---------------------------------------------------------------------------//
// OpenMP FUNCTIONS
//---------------------------------------------------------------------------//

inline bool multithreading_available()
{
#ifdef _OPENMP
    return true;
#endif
    return false;
}

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

inline void set_num_threads(int nt)
{
#ifdef _OPENMP
    omp_set_num_threads(nt);
#endif
}

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

inline int num_current_threads()
{
#ifdef _OPENMP
    return omp_get_num_threads();
#endif
    return 1;
}

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

inline int thread_id()
{
#ifdef _OPENMP
    return omp_get_thread_num();
#endif
    return 0;
}

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

inline int num_available_threads()
{
#ifdef _OPENMP
    return omp_get_max_threads();
#endif
    return 1;
}

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

inline void turn_off_dynamic_threading()
{
#ifdef _OPENMP
    omp_set_dynamic(0);
#endif
}

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

inline void turn_on_dynamic_threading()
{
#ifdef _OPENMP
    omp_set_dynamic(1);
#endif
}

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

inline bool is_threading_dynamic()
{
#ifdef _OPENMP
    return omp_get_dynamic();
#endif
    return false;
}

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

inline bool in_thread_parallel_region()
{
#ifdef _OPENMP
    return omp_in_parallel();
#endif
    return false;
}

} // end namespace profugus

#endif // Utils_comm_OMP_hh

//---------------------------------------------------------------------------//
// end of Utils/comm/OMP.hh
//---------------------------------------------------------------------------//
<commit_msg>Added timing function.<commit_after>//---------------------------------*-C++-*-----------------------------------//
/*!
 * \file   Utils/comm/OMP.hh
 * \author Thomas M. Evans
 * \date   Thu Aug 20 10:18:57 2015
 * \brief  OMP class declaration.
 * \note   Copyright (c) 2015 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#ifndef Utils_comm_OMP_hh
#define Utils_comm_OMP_hh

#ifdef _OPENMP
#include <omp.h>
#endif

namespace profugus
{

//---------------------------------------------------------------------------//
// OpenMP FUNCTIONS
//---------------------------------------------------------------------------//

inline bool multithreading_available()
{
#ifdef _OPENMP
    return true;
#endif
    return false;
}

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

inline void set_num_threads(int nt)
{
#ifdef _OPENMP
    omp_set_num_threads(nt);
#endif
}

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

inline int num_current_threads()
{
#ifdef _OPENMP
    return omp_get_num_threads();
#endif
    return 1;
}

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

inline int thread_id()
{
#ifdef _OPENMP
    return omp_get_thread_num();
#endif
    return 0;
}

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

inline int num_available_threads()
{
#ifdef _OPENMP
    return omp_get_max_threads();
#endif
    return 1;
}

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

inline void turn_off_dynamic_threading()
{
#ifdef _OPENMP
    omp_set_dynamic(0);
#endif
}

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

inline void turn_on_dynamic_threading()
{
#ifdef _OPENMP
    omp_set_dynamic(1);
#endif
}

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

inline bool is_threading_dynamic()
{
#ifdef _OPENMP
    return omp_get_dynamic();
#endif
    return false;
}

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

inline bool in_thread_parallel_region()
{
#ifdef _OPENMP
    return omp_in_parallel();
#endif
    return false;
}

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

inline double thread_time()
{
#ifdef _OPENMP
    return omp_get_wtime();
#endif
    return 0.0;
}

} // end namespace profugus

#endif // Utils_comm_OMP_hh

//---------------------------------------------------------------------------//
// end of Utils/comm/OMP.hh
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>#include <signal.h>

#include "gen/wsdd.nsmap"
#include "wsddapi.h"

const char* host = "239.255.255.250";
int port = 3702;
const int _metadataVersion = 1;
const char* _xaddr="http://localhost/service";
const char* _type="\"http://schemas.xmlsoap.org/ws/2006/02/devprof\":device";
const char* _endpoint="urn";

bool stop = false;
void sighandler(int sig)
{
	std::cout<< "Signal caught..." << std::endl;
	stop = true;
}

int mainloop(soap* serv)
{
	return soap_wsdd_listen(serv, -1000000);
}

void sendHello()
{
	struct soap* soap = soap_new1(SOAP_IO_UDP);
	printf("call soap_wsdd_Hello\n");
	int res = soap_wsdd_Hello(soap,
	  SOAP_WSDD_ADHOC,      // mode
	  "soap.udp://239.255.255.250:3702",         // address of TS
	  soap_wsa_rand_uuid(soap),                   // message ID
	  NULL,
	  _endpoint,
	  NULL,
	  _type,
	  NULL,
	  _xaddr,
          _metadataVersion);
	if (res != SOAP_OK)
	{
		soap_print_fault(soap, stderr);
	}
	soap_end(soap);
}

void sendBye()
{
	struct soap* soap = soap_new1(SOAP_IO_UDP);
	printf("call soap_wsdd_Bye\n");
	int res = soap_wsdd_Bye(soap,
	  SOAP_WSDD_ADHOC,      // mode
	  "soap.udp://239.255.255.250:3702",         // address of TS
	  soap_wsa_rand_uuid(soap),                   // message ID
	  _endpoint,
	  NULL,
	  _type,
	  NULL,
	  _xaddr,
          _metadataVersion);
	if (res != SOAP_OK)
	{
		soap_print_fault(soap, stderr);
	}
	soap_end(soap);
}

int main(int argc, char** argv)
{
	struct soap* serv = soap_new1(SOAP_IO_UDP | SOAP_IO_KEEPALIVE);
	serv->bind_flags=SO_REUSEADDR;
	if (!soap_valid_socket(soap_bind(serv, NULL, port, 1000)))
	{
		soap_print_fault(serv, stderr);
		exit(1);
	}

	ip_mreq mcast;
	mcast.imr_multiaddr.s_addr = inet_addr(host);
	mcast.imr_interface.s_addr = htonl(INADDR_ANY);
	if (setsockopt(serv->master, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))<0)
	{
		std::cout << "group membership failed:" << strerror(errno) << std::endl;
	}

	sendHello();
	mainloop(serv);

	signal(SIGINT, &sighandler);
	while (!stop)
	{
		mainloop(serv);
	}

	sendBye();
	mainloop(serv);

	return 0;
}

soap_wsdd_mode wsdd_event_Resolve(struct soap *soap, const char *MessageID, const char *ReplyTo, const char *EndpointReference, struct wsdd__ResolveMatchType *match)
{
	printf("wsdd_event_Resolve  id=%s replyTo=%s\n", MessageID, ReplyTo);
	return SOAP_WSDD_ADHOC;
}

soap_wsdd_mode wsdd_event_Probe(struct soap *soap, const char *MessageID, const char *ReplyTo, const char *Types, const char *Scopes, const char *MatchBy, struct wsdd__ProbeMatchesType *matches)
{
	printf("wsdd_event_Probe id=%s replyTo=%s types=%s scopes=%s\n", MessageID, ReplyTo, Types, Scopes);
	soap_wsdd_init_ProbeMatches(soap,matches);
	soap_wsdd_add_ProbeMatch(soap, matches, "soap.udp://239.255.255.250:3702", _type, NULL, NULL, _xaddr, _metadataVersion);
	soap_wsdd_ProbeMatches(soap, "soap.udp://239.255.255.250:3702", soap_wsa_rand_uuid(soap) , MessageID, ReplyTo, matches);
	return SOAP_WSDD_ADHOC;
}

<commit_msg>fix probematch answer<commit_after>#include <signal.h>

#include "gen/wsdd.nsmap"
#include "wsddapi.h"

const char* host = "239.255.255.250";
int port = 3702;
const int _metadataVersion = 1;
const char* _xaddr="http://localhost/service";
const char* _type="\"http://schemas.xmlsoap.org/ws/2006/02/devprof\":device";
const char* _endpoint="urn";

bool stop = false;
void sighandler(int sig)
{
	std::cout<< "Signal caught..." << std::endl;
	stop = true;
}

int mainloop(soap* serv)
{
	return soap_wsdd_listen(serv, -1000000);
}

void sendHello()
{
	struct soap* soap = soap_new1(SOAP_IO_UDP);
	printf("call soap_wsdd_Hello\n");
	int res = soap_wsdd_Hello(soap,
	  SOAP_WSDD_ADHOC,      // mode
	  "soap.udp://239.255.255.250:3702",         // address of TS
	  soap_wsa_rand_uuid(soap),                   // message ID
	  NULL,
	  _endpoint,
	  NULL,
	  _type,
	  NULL,
	  _xaddr,
          _metadataVersion);
	if (res != SOAP_OK)
	{
		soap_print_fault(soap, stderr);
	}
	soap_end(soap);
}

void sendBye()
{
	struct soap* soap = soap_new1(SOAP_IO_UDP);
	printf("call soap_wsdd_Bye\n");
	int res = soap_wsdd_Bye(soap,
	  SOAP_WSDD_ADHOC,      // mode
	  "soap.udp://239.255.255.250:3702",         // address of TS
	  soap_wsa_rand_uuid(soap),                   // message ID
	  _endpoint,
	  NULL,
	  _type,
	  NULL,
	  _xaddr,
          _metadataVersion);
	if (res != SOAP_OK)
	{
		soap_print_fault(soap, stderr);
	}
	soap_end(soap);
}

int main(int argc, char** argv)
{
	struct soap* serv = soap_new1(SOAP_IO_UDP | SOAP_IO_KEEPALIVE);
	serv->bind_flags=SO_REUSEADDR;
	if (!soap_valid_socket(soap_bind(serv, NULL, port, 1000)))
	{
		soap_print_fault(serv, stderr);
		exit(1);
	}

	ip_mreq mcast;
	mcast.imr_multiaddr.s_addr = inet_addr(host);
	mcast.imr_interface.s_addr = htonl(INADDR_ANY);
	if (setsockopt(serv->master, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))<0)
	{
		std::cout << "group membership failed:" << strerror(errno) << std::endl;
	}

	sendHello();
	mainloop(serv);

	signal(SIGINT, &sighandler);
	while (!stop)
	{
		mainloop(serv);
	}

	sendBye();
	mainloop(serv);

	return 0;
}

soap_wsdd_mode wsdd_event_Resolve(struct soap *soap, const char *MessageID, const char *ReplyTo, const char *EndpointReference, struct wsdd__ResolveMatchType *match)
{
	printf("wsdd_event_Resolve  id=%s replyTo=%s\n", MessageID, ReplyTo);
	return SOAP_WSDD_ADHOC;
}

soap_wsdd_mode wsdd_event_Probe(struct soap *soap, const char *MessageID, const char *ReplyTo, const char *Types, const char *Scopes, const char *MatchBy, struct wsdd__ProbeMatchesType *matches)
{
	printf("wsdd_event_Probe id=%s replyTo=%s types=%s scopes=%s\n", MessageID, ReplyTo, Types, Scopes);
	soap_wsdd_init_ProbeMatches(soap,matches);
	soap_wsdd_add_ProbeMatch(soap, matches, _endpoint, _type, NULL, NULL, _xaddr, _metadataVersion);
	soap_wsdd_ProbeMatches(soap, NULL, soap_wsa_rand_uuid(soap) , MessageID, ReplyTo, matches);
	return SOAP_WSDD_ADHOC;
}

<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "gmm_clustering_method.hpp"

#include <utility>
#include <vector>
#include "../common/exception.hpp"
#include "util.hpp"

using std::vector;

namespace jubatus {
namespace core {
namespace clustering {

gmm_clustering_method::gmm_clustering_method(size_t k) : k_(k) {
}

gmm_clustering_method::~gmm_clustering_method() {
}

void gmm_clustering_method::batch_update(wplist points) {
  mapper_.clear();
  eigen_wsvec_list_t data = mapper_.convert(points, true);
  gmm_.batch(data, mapper_.get_dimension(), k_);
  kcenters_ = mapper_.revert(gmm_.get_centers());
}

void gmm_clustering_method::online_update(wplist points) {
}

std::vector<common::sfv_t> gmm_clustering_method::get_k_center() const {
  return kcenters_;
}

int64_t gmm_clustering_method::get_nearest_center_index(
    const common::sfv_t& point) const {
  return gmm_.get_nearest_center_index(mapper_.convertc(point));
}

common::sfv_t gmm_clustering_method::get_nearest_center(
    const common::sfv_t& point) const {
  return mapper_.revert(gmm_.get_nearest_center(mapper_.convertc(point)));
}

wplist gmm_clustering_method::get_cluster(
    size_t cluster_id,
    const wplist& points) const {
  return get_clusters(points)[cluster_id];
}

std::vector<wplist> gmm_clustering_method::get_clusters(
    const wplist& points) const {
  std::vector<wplist> ret(k_);
  for (wplist::const_iterator it = points.begin(); it != points.end(); ++it) {
    int64_t c = get_nearest_center_index(it->data);
    ret[c].push_back(*it);
  }
  return ret;
}

}  // namespace clustering
}  // namespace core
}  // namespace jubatus
<commit_msg>Fix gmm_clustering_method's ctor<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "gmm_clustering_method.hpp"

#include <utility>
#include <vector>
#include "../common/exception.hpp"
#include "util.hpp"

using std::vector;

namespace jubatus {
namespace core {
namespace clustering {

gmm_clustering_method::gmm_clustering_method(size_t k)
    : k_(k), kcenters_(), mapper_(), gmm_() {
}

gmm_clustering_method::~gmm_clustering_method() {
}

void gmm_clustering_method::batch_update(wplist points) {
  mapper_.clear();
  eigen_wsvec_list_t data = mapper_.convert(points, true);
  gmm_.batch(data, mapper_.get_dimension(), k_);
  kcenters_ = mapper_.revert(gmm_.get_centers());
}

void gmm_clustering_method::online_update(wplist points) {
}

std::vector<common::sfv_t> gmm_clustering_method::get_k_center() const {
  return kcenters_;
}

int64_t gmm_clustering_method::get_nearest_center_index(
    const common::sfv_t& point) const {
  return gmm_.get_nearest_center_index(mapper_.convertc(point));
}

common::sfv_t gmm_clustering_method::get_nearest_center(
    const common::sfv_t& point) const {
  return mapper_.revert(gmm_.get_nearest_center(mapper_.convertc(point)));
}

wplist gmm_clustering_method::get_cluster(
    size_t cluster_id,
    const wplist& points) const {
  return get_clusters(points)[cluster_id];
}

std::vector<wplist> gmm_clustering_method::get_clusters(
    const wplist& points) const {
  std::vector<wplist> ret(k_);
  for (wplist::const_iterator it = points.begin(); it != points.end(); ++it) {
    int64_t c = get_nearest_center_index(it->data);
    ret[c].push_back(*it);
  }
  return ret;
}

}  // namespace clustering
}  // namespace core
}  // namespace jubatus
<|endoftext|>


<commit_before>/***************************************************************************
                          plugin_katetextfilter.cpp  -  description
                             -------------------
    begin                : FRE Feb 23 2001
    copyright            : (C) 2001 by Joseph Wenninger
    email                : jowenn@bigfoot.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "plugin_katetextfilter.h"
#include "plugin_katetextfilter.moc"

#include <ktexteditor/editor.h>

#include <kaction.h>
#include <kcomponentdata.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <cassert>
#include <kdebug.h>
#include <qstring.h>
#include <klineedit.h>
#include <kinputdialog.h>
#include <k3process.h>
#define POP_(x) kDebug(13000) << #x " = " << flush << x << endl

#include <kgenericfactory.h>
#include <kauthorized.h>
#include <kactioncollection.h>
K_EXPORT_COMPONENT_FACTORY( katetextfilterplugin, KGenericFactory<PluginKateTextFilter>( "katetextfilter" ) )

PluginViewKateTextFilter::PluginViewKateTextFilter(PluginKateTextFilter *plugin,Kate::MainWindow *mainwindow)
  : Kate::PluginView(mainwindow),KXMLGUIClient()
{
    setComponentData (KComponentData("kate"));

    KAction *a = actionCollection()->addAction("edit_filter");
    a->setText(i18n("Filter Te&xt..."));
    a->setShortcut( Qt::CTRL + Qt::Key_Backslash );
    connect( a, SIGNAL(triggered(bool)), plugin, SLOT(slotEditFilter()) );

    setXMLFile( "plugins/katetextfilter/ui.rc" );
    mainwindow->guiFactory()->addClient (this);
}

PluginViewKateTextFilter::~PluginViewKateTextFilter()
{
      mainWindow()->guiFactory()->removeClient (this);
}

PluginKateTextFilter::PluginKateTextFilter( QObject* parent, const QStringList& )
  : Kate::Plugin ( (Kate::Application *)parent, "kate-text-filter-plugin" ),
    KTextEditor::Command(),
    m_pFilterShellProcess (NULL)
{
  KTextEditor::CommandInterface* cmdIface = qobject_cast<KTextEditor::CommandInterface*>(application()->editor());
  if( cmdIface ) cmdIface->registerCommand( this );
}

PluginKateTextFilter::~PluginKateTextFilter()
{
  delete m_pFilterShellProcess;
  KTextEditor::CommandInterface* cmdIface = qobject_cast<KTextEditor::CommandInterface*>(application()->editor());
  if( cmdIface ) cmdIface->unregisterCommand( this );
}

Kate::PluginView *PluginKateTextFilter::createView (Kate::MainWindow *mainWindow)
{
    return new PluginViewKateTextFilter(this,mainWindow);
}

	void
PluginKateTextFilter::slotFilterReceivedStdout (K3Process * pProcess, char * got, int len)
{

	assert (pProcess == m_pFilterShellProcess);

	if (got && len)
		{
		m_strFilterOutput += QString::fromLocal8Bit( got, len );
//		POP_(m_strFilterOutput);
		}

}

	void
PluginKateTextFilter::slotFilterReceivedStderr (K3Process * pProcess, char * got, int len)
	{
	slotFilterReceivedStdout (pProcess, got, len);
	}

	void
PluginKateTextFilter::slotFilterProcessExited (K3Process * pProcess)
{

	assert (pProcess == m_pFilterShellProcess);
	KTextEditor::View * kv (application()->activeMainWindow()->activeView());
	if (!kv) return;
	kv->document()->startEditing();
	if( kv->selection () )
	  kv->removeSelectionText();
	kv -> insertText (m_strFilterOutput);
	kv->document()->endEditing();
	m_strFilterOutput = "";

}

        static void  //  PCP
slipInFilter (K3ShellProcess & shell, KTextEditor::View & view, QString command)
{
  if( !view.selection() ) return;
  QString marked = view.selectionText ();
  if( marked.isEmpty())
      return;
//  POP_(command.latin1 ());
  shell.clearArguments ();
  shell << command;

  shell.start (K3Process::NotifyOnExit, K3Process::All);
  QByteArray encoded = marked.toLocal8Bit ();
  shell.writeStdin (encoded, encoded.length ());
  //  TODO: Put up a modal dialog to defend the text from further
  //  keystrokes while the command is out. With a cancel button...

}

	void
PluginKateTextFilter::slotFilterCloseStdin (K3Process * pProcess)
	{
	assert (pProcess == m_pFilterShellProcess);
	pProcess -> closeStdin ();
	}

                 void
PluginKateTextFilter::slotEditFilter ()  //  PCP
{
  if (!KAuthorized::authorizeKAction("shell_access")) {
      KMessageBox::sorry(0,i18n(
          "You are not allowed to execute arbitrary external applications. If "
          "you want to be able to do this, contact your system administrator."),
          i18n("Access Restrictions"));
      return;
  }
  if (!application()->activeMainWindow())
    return;

  KTextEditor::View * kv (application()->activeMainWindow()->activeView());
  if (!kv) return;

  bool ok(false);
  QString text ( KInputDialog::getText(i18n("Filter"),"",i18n("Enter command to pipe selected text through:"),&ok));
  if ( ok && (!text.isEmpty () ))
    runFilter( kv, text );
}

void PluginKateTextFilter::runFilter( KTextEditor::View *kv, const QString &filter )
{
  m_strFilterOutput = "";

  if (!m_pFilterShellProcess)
  {
    m_pFilterShellProcess = new K3ShellProcess;

    connect ( m_pFilterShellProcess, SIGNAL(wroteStdin(K3Process *)),
              this, SLOT(slotFilterCloseStdin (K3Process *)));

    connect ( m_pFilterShellProcess, SIGNAL(receivedStdout(K3Process*,char*,int)),
              this, SLOT(slotFilterReceivedStdout(K3Process*,char*,int)) );

    connect ( m_pFilterShellProcess, SIGNAL(receivedStderr(K3Process*,char*,int)),
              this, SLOT(slotFilterReceivedStderr(K3Process*,char*,int)) );

    connect ( m_pFilterShellProcess, SIGNAL(processExited(K3Process*)),
              this, SLOT(slotFilterProcessExited(K3Process*) ) ) ;
  }

  slipInFilter (*m_pFilterShellProcess, *kv, filter);
}

//BEGIN Kate::Command methods
const QStringList &PluginKateTextFilter::cmds()
{
  static QStringList dummy("textfilter");
  return dummy;
}

bool PluginKateTextFilter::help( KTextEditor::View *, const QString&, QString &msg )
{
  msg = i18n(
      "<qt>
Usage: textfilter COMMAND
"
      "
Replace the selection with the output of the specified shell command.
</qt>");
  return true;
}

bool PluginKateTextFilter::exec( KTextEditor::View *v, const QString &cmd, QString &msg )
{
  if (! v->selection() )
  {
    msg = i18n("You need to have a selection to use textfilter");
    return false;
  }

  QString filter = cmd.section( " ", 1 ).trimmed();

  if ( filter.isEmpty() )
  {
    msg = i18n("Usage: textfilter COMMAND");
    return false;
  }

  runFilter( v, filter );
  return true;
}
//END
// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;
<commit_msg>Fixed wrong order of arguments in input dialog, was causing input field label to show as default value.<commit_after>/***************************************************************************
                          plugin_katetextfilter.cpp  -  description
                             -------------------
    begin                : FRE Feb 23 2001
    copyright            : (C) 2001 by Joseph Wenninger
    email                : jowenn@bigfoot.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "plugin_katetextfilter.h"
#include "plugin_katetextfilter.moc"

#include <ktexteditor/editor.h>

#include <kaction.h>
#include <kcomponentdata.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <cassert>
#include <kdebug.h>
#include <qstring.h>
#include <klineedit.h>
#include <kinputdialog.h>
#include <k3process.h>
#define POP_(x) kDebug(13000) << #x " = " << flush << x << endl

#include <kgenericfactory.h>
#include <kauthorized.h>
#include <kactioncollection.h>
K_EXPORT_COMPONENT_FACTORY( katetextfilterplugin, KGenericFactory<PluginKateTextFilter>( "katetextfilter" ) )

PluginViewKateTextFilter::PluginViewKateTextFilter(PluginKateTextFilter *plugin,Kate::MainWindow *mainwindow)
  : Kate::PluginView(mainwindow),KXMLGUIClient()
{
    setComponentData (KComponentData("kate"));

    KAction *a = actionCollection()->addAction("edit_filter");
    a->setText(i18n("Filter Te&xt..."));
    a->setShortcut( Qt::CTRL + Qt::Key_Backslash );
    connect( a, SIGNAL(triggered(bool)), plugin, SLOT(slotEditFilter()) );

    setXMLFile( "plugins/katetextfilter/ui.rc" );
    mainwindow->guiFactory()->addClient (this);
}

PluginViewKateTextFilter::~PluginViewKateTextFilter()
{
      mainWindow()->guiFactory()->removeClient (this);
}

PluginKateTextFilter::PluginKateTextFilter( QObject* parent, const QStringList& )
  : Kate::Plugin ( (Kate::Application *)parent, "kate-text-filter-plugin" ),
    KTextEditor::Command(),
    m_pFilterShellProcess (NULL)
{
  KTextEditor::CommandInterface* cmdIface = qobject_cast<KTextEditor::CommandInterface*>(application()->editor());
  if( cmdIface ) cmdIface->registerCommand( this );
}

PluginKateTextFilter::~PluginKateTextFilter()
{
  delete m_pFilterShellProcess;
  KTextEditor::CommandInterface* cmdIface = qobject_cast<KTextEditor::CommandInterface*>(application()->editor());
  if( cmdIface ) cmdIface->unregisterCommand( this );
}

Kate::PluginView *PluginKateTextFilter::createView (Kate::MainWindow *mainWindow)
{
    return new PluginViewKateTextFilter(this,mainWindow);
}

	void
PluginKateTextFilter::slotFilterReceivedStdout (K3Process * pProcess, char * got, int len)
{

	assert (pProcess == m_pFilterShellProcess);

	if (got && len)
		{
		m_strFilterOutput += QString::fromLocal8Bit( got, len );
//		POP_(m_strFilterOutput);
		}

}

	void
PluginKateTextFilter::slotFilterReceivedStderr (K3Process * pProcess, char * got, int len)
	{
	slotFilterReceivedStdout (pProcess, got, len);
	}

	void
PluginKateTextFilter::slotFilterProcessExited (K3Process * pProcess)
{

	assert (pProcess == m_pFilterShellProcess);
	KTextEditor::View * kv (application()->activeMainWindow()->activeView());
	if (!kv) return;
	kv->document()->startEditing();
	if( kv->selection () )
	  kv->removeSelectionText();
	kv -> insertText (m_strFilterOutput);
	kv->document()->endEditing();
	m_strFilterOutput = "";

}

        static void  //  PCP
slipInFilter (K3ShellProcess & shell, KTextEditor::View & view, QString command)
{
  if( !view.selection() ) return;
  QString marked = view.selectionText ();
  if( marked.isEmpty())
      return;
//  POP_(command.latin1 ());
  shell.clearArguments ();
  shell << command;

  shell.start (K3Process::NotifyOnExit, K3Process::All);
  QByteArray encoded = marked.toLocal8Bit ();
  shell.writeStdin (encoded, encoded.length ());
  //  TODO: Put up a modal dialog to defend the text from further
  //  keystrokes while the command is out. With a cancel button...

}

	void
PluginKateTextFilter::slotFilterCloseStdin (K3Process * pProcess)
	{
	assert (pProcess == m_pFilterShellProcess);
	pProcess -> closeStdin ();
	}

                 void
PluginKateTextFilter::slotEditFilter ()  //  PCP
{
  if (!KAuthorized::authorizeKAction("shell_access")) {
      KMessageBox::sorry(0,i18n(
          "You are not allowed to execute arbitrary external applications. If "
          "you want to be able to do this, contact your system administrator."),
          i18n("Access Restrictions"));
      return;
  }
  if (!application()->activeMainWindow())
    return;

  KTextEditor::View * kv (application()->activeMainWindow()->activeView());
  if (!kv) return;

  bool ok(false);
  QString text ( KInputDialog::getText(i18n("Filter"),i18n("Enter command to pipe selected text through:"),"",&ok));
  if ( ok && (!text.isEmpty () ))
    runFilter( kv, text );
}

void PluginKateTextFilter::runFilter( KTextEditor::View *kv, const QString &filter )
{
  m_strFilterOutput = "";

  if (!m_pFilterShellProcess)
  {
    m_pFilterShellProcess = new K3ShellProcess;

    connect ( m_pFilterShellProcess, SIGNAL(wroteStdin(K3Process *)),
              this, SLOT(slotFilterCloseStdin (K3Process *)));

    connect ( m_pFilterShellProcess, SIGNAL(receivedStdout(K3Process*,char*,int)),
              this, SLOT(slotFilterReceivedStdout(K3Process*,char*,int)) );

    connect ( m_pFilterShellProcess, SIGNAL(receivedStderr(K3Process*,char*,int)),
              this, SLOT(slotFilterReceivedStderr(K3Process*,char*,int)) );

    connect ( m_pFilterShellProcess, SIGNAL(processExited(K3Process*)),
              this, SLOT(slotFilterProcessExited(K3Process*) ) ) ;
  }

  slipInFilter (*m_pFilterShellProcess, *kv, filter);
}

//BEGIN Kate::Command methods
const QStringList &PluginKateTextFilter::cmds()
{
  static QStringList dummy("textfilter");
  return dummy;
}

bool PluginKateTextFilter::help( KTextEditor::View *, const QString&, QString &msg )
{
  msg = i18n(
      "<qt>
Usage: textfilter COMMAND
"
      "
Replace the selection with the output of the specified shell command.
</qt>");
  return true;
}

bool PluginKateTextFilter::exec( KTextEditor::View *v, const QString &cmd, QString &msg )
{
  if (! v->selection() )
  {
    msg = i18n("You need to have a selection to use textfilter");
    return false;
  }

  QString filter = cmd.section( " ", 1 ).trimmed();

  if ( filter.isEmpty() )
  {
    msg = i18n("Usage: textfilter COMMAND");
    return false;
  }

  runFilter( v, filter );
  return true;
}
//END
// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;
<|endoftext|>


<commit_before>/* -*- MODE: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2017 Couchbase, Inc
 *
 *   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 "config.h"

#include "custom_rotating_file_sink.h"

#include "logger.h"

#include <memcached/engine.h>
#include <memcached/extension.h>
#include <phosphor/phosphor.h>
#include <platform/processclock.h>
#include <spdlog/sinks/dist_sink.h>
#include <spdlog/sinks/null_sink.h>
#include <spdlog/sinks/stdout_sinks.h>
#include <spdlog/spdlog.h>
#include <chrono>
#include <cstdio>

#ifndef WIN32
#include <spdlog/sinks/ansicolor_sink.h>
#endif

static const std::string logger_name{"spdlog_file_logger"};

static EXTENSION_LOGGER_DESCRIPTOR descriptor;

/**
 * Custom log pattern which the loggers will use.
 * This pattern is duplicated for some test cases. If you need to update it,
 * please also update in all relevant places.
 * TODO: Remove the duplication in the future, by (maybe) moving
 *       the const to a header file.
 */
static const std::string log_pattern{"%Y-%m-%dT%T.%fZ %l %v"};

spdlog::level::level_enum cb::logger::convertToSpdSeverity(
        EXTENSION_LOG_LEVEL sev) {
    using namespace spdlog::level;
    switch (sev) {
    case EXTENSION_LOG_DEBUG:
        return level_enum::debug;
    case EXTENSION_LOG_INFO:
        return level_enum::info;
    case EXTENSION_LOG_NOTICE:
        return level_enum::info;
    case EXTENSION_LOG_WARNING:
        return level_enum::warn;
    case EXTENSION_LOG_FATAL:
        return level_enum::critical;
    }
    throw std::invalid_argument("Unknown severity level");
}

/**
 * Instances of spdlog (async) file logger.
 * The files logger requires a rotating file sink which is manually configured
 * from the parsed settings.
 * The loggers act as a handle to the sinks. They do the processing of log
 * messages and send them to the sinks, which do the actual writing (to file,
 * to stream etc.) or further processing.
 */
static std::shared_ptr<spdlog::logger> file_logger;

/**
 * Retrieves a message, applies formatting and then logs it to stderr and
 * to file, according to the severity.
 */
static void log(EXTENSION_LOG_LEVEL mcd_severity,
                const void* client_cookie,
                const char* fmt,
                ...) {
    const auto severity = cb::logger::convertToSpdSeverity(mcd_severity);

    // Retrieve formatted log message
    char msg[2048];
    int len;
    va_list va;
    va_start(va, fmt);
    len = vsnprintf(msg, 2048, fmt, va);
    va_end(va);

    // Something went wrong during formatting, so return
    if (len < 0) {
        return;
    }
    // len does not include '\0', hence >= and not >
    if (len >= int(sizeof(msg))) {
        // Crop message for logging
        const char cropped[] = " [cut]";
        snprintf(msg + (sizeof(msg) - sizeof(cropped)),
                 sizeof(cropped),
                 "%s",
                 cropped);
    } else {
        msg[len] = '\0';
    }

    file_logger->log(severity, msg);
}

LOGGER_PUBLIC_API
void cb::logger::flush() {
    if (file_logger) {
        file_logger->flush();
    }
}

LOGGER_PUBLIC_API
void cb::logger::shutdown() {
    flush();
    file_logger.reset();
    spdlog::drop_all();
}

/**
 * Initialises the loggers. Called if the logger configuration is
 * specified in a separate settings object.
 */
boost::optional<std::string> cb::logger::initialize(
        const Config& logger_settings) {
    auto fname = logger_settings.filename;
    auto buffersz = logger_settings.buffersize;
    auto cyclesz = logger_settings.cyclesize;

    if (getenv("CB_MAXIMIZE_LOGGER_CYCLE_SIZE") != nullptr) {
        cyclesz = 1024 * 1024 * 1024; // use up to 1 GB log file size
    }

    if (getenv("CB_MAXIMIZE_LOGGER_BUFFER_SIZE") != nullptr) {
        buffersz = 8 * 1024 * 1024; // use an 8MB log buffer
    }

    try {
        // Initialise the loggers.
        //
        // The structure is as follows:
        //
        // file_logger = sends log messages to sink
        //   |__dist_sink_mt = Distribute log messages to multiple sinks
        //       |     |__custom_rotating_file_sink_mt = adds opening & closing
        //       |                                       hooks to the file
        //       |__ (color)__stderr_sink_mt = Send log messages to consloe
        //
        // When a new log message is being submitted to the file_logger it
        // is subject to the log level specified on the file_logger. If it
        // is to be included it is passed down to the dist_sink which will
        // evaluate if the message should be passed on based on its log level.
        // It'll then try to pass the message to the file sink and the
        // console sink and they will evaluate if the message should be
        // logged or not. This means that we should set the file sink
        // loglevel to TRACE so that all messages which goes all the way
        // will end up in the file. Due to the fact that ns_server can't
        // keep up with the rate we might produce log we want the console
        // sink to drop everything below WARNING (unless we're running
        // unit tests (through testapp).
        //
        // When the user change the verbosity level we'll modify the
        // level for the file_logger object causing it to allow more
        // messages to go down to the various sinks.

        auto sink = std::make_shared<spdlog::sinks::dist_sink_mt>();
        sink->set_level(spdlog::level::trace);

        if (!fname.empty()) {
            auto fsink = std::make_shared<custom_rotating_file_sink_mt>(
                    fname, cyclesz, log_pattern);
            fsink->set_level(spdlog::level::trace);
            sink->add_sink(fsink);
        }

        if (logger_settings.console) {
#ifdef WIN32
            auto stderrsink = std::make_shared<spdlog::sinks::stderr_sink_mt>();
#else
            auto stderrsink =
                    std::make_shared<spdlog::sinks::ansicolor_stderr_sink_mt>();
#endif
            if (logger_settings.unit_test) {
                stderrsink->set_level(spdlog::level::trace);
            } else {
                stderrsink->set_level(spdlog::level::warn);
            }
            sink->add_sink(stderrsink);
        }

        spdlog::drop(logger_name);
        file_logger =
                spdlog::create_async(logger_name,
                                     sink,
                                     buffersz,
                                     spdlog::async_overflow_policy::block_retry,
                                     nullptr,
                                     std::chrono::milliseconds(200));
    } catch (const spdlog::spdlog_ex& ex) {
        std::string msg =
                std::string{"Log initialization failed: "} + ex.what();
        return boost::optional<std::string>{msg};
    }

    file_logger->set_pattern(log_pattern);
    file_logger->set_level(spdlog::level::level_enum::info);
    return {};
}

std::shared_ptr<spdlog::logger> cb::logger::get() {
    return file_logger;
}

void cb::logger::createBlackholeLogger() {
    // delete if already exists
    spdlog::drop(logger_name);

    file_logger = spdlog::create(
            logger_name, std::make_shared<spdlog::sinks::null_sink_mt>());

    file_logger->set_level(spdlog::level::off);
    file_logger->set_pattern(log_pattern);
}

void cb::logger::createConsoleLogger() {
    // delete if already exists
    spdlog::drop(logger_name);
    file_logger = spdlog::stderr_color_mt(logger_name);
    file_logger->set_level(spdlog::level::info);
    file_logger->set_pattern(log_pattern);
}

LOGGER_PUBLIC_API
EXTENSION_LOGGER_DESCRIPTOR& cb::logger::getLoggerDescriptor() {
    descriptor.log = log;
    return descriptor;
}
<commit_msg>spdlogger: Remove unused headers<commit_after>/* -*- MODE: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2017 Couchbase, Inc
 *
 *   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 "config.h"

#include "custom_rotating_file_sink.h"

#include "logger.h"

#include <memcached/engine.h>
#include <memcached/extension.h>
#include <spdlog/sinks/dist_sink.h>
#include <spdlog/sinks/null_sink.h>
#include <spdlog/sinks/stdout_sinks.h>
#include <spdlog/spdlog.h>
#include <chrono>
#include <cstdio>

#ifndef WIN32
#include <spdlog/sinks/ansicolor_sink.h>
#endif

static const std::string logger_name{"spdlog_file_logger"};

static EXTENSION_LOGGER_DESCRIPTOR descriptor;

/**
 * Custom log pattern which the loggers will use.
 * This pattern is duplicated for some test cases. If you need to update it,
 * please also update in all relevant places.
 * TODO: Remove the duplication in the future, by (maybe) moving
 *       the const to a header file.
 */
static const std::string log_pattern{"%Y-%m-%dT%T.%fZ %l %v"};

spdlog::level::level_enum cb::logger::convertToSpdSeverity(
        EXTENSION_LOG_LEVEL sev) {
    using namespace spdlog::level;
    switch (sev) {
    case EXTENSION_LOG_DEBUG:
        return level_enum::debug;
    case EXTENSION_LOG_INFO:
        return level_enum::info;
    case EXTENSION_LOG_NOTICE:
        return level_enum::info;
    case EXTENSION_LOG_WARNING:
        return level_enum::warn;
    case EXTENSION_LOG_FATAL:
        return level_enum::critical;
    }
    throw std::invalid_argument("Unknown severity level");
}

/**
 * Instances of spdlog (async) file logger.
 * The files logger requires a rotating file sink which is manually configured
 * from the parsed settings.
 * The loggers act as a handle to the sinks. They do the processing of log
 * messages and send them to the sinks, which do the actual writing (to file,
 * to stream etc.) or further processing.
 */
static std::shared_ptr<spdlog::logger> file_logger;

/**
 * Retrieves a message, applies formatting and then logs it to stderr and
 * to file, according to the severity.
 */
static void log(EXTENSION_LOG_LEVEL mcd_severity,
                const void* client_cookie,
                const char* fmt,
                ...) {
    const auto severity = cb::logger::convertToSpdSeverity(mcd_severity);

    // Retrieve formatted log message
    char msg[2048];
    int len;
    va_list va;
    va_start(va, fmt);
    len = vsnprintf(msg, 2048, fmt, va);
    va_end(va);

    // Something went wrong during formatting, so return
    if (len < 0) {
        return;
    }
    // len does not include '\0', hence >= and not >
    if (len >= int(sizeof(msg))) {
        // Crop message for logging
        const char cropped[] = " [cut]";
        snprintf(msg + (sizeof(msg) - sizeof(cropped)),
                 sizeof(cropped),
                 "%s",
                 cropped);
    } else {
        msg[len] = '\0';
    }

    file_logger->log(severity, msg);
}

LOGGER_PUBLIC_API
void cb::logger::flush() {
    if (file_logger) {
        file_logger->flush();
    }
}

LOGGER_PUBLIC_API
void cb::logger::shutdown() {
    flush();
    file_logger.reset();
    spdlog::drop_all();
}

/**
 * Initialises the loggers. Called if the logger configuration is
 * specified in a separate settings object.
 */
boost::optional<std::string> cb::logger::initialize(
        const Config& logger_settings) {
    auto fname = logger_settings.filename;
    auto buffersz = logger_settings.buffersize;
    auto cyclesz = logger_settings.cyclesize;

    if (getenv("CB_MAXIMIZE_LOGGER_CYCLE_SIZE") != nullptr) {
        cyclesz = 1024 * 1024 * 1024; // use up to 1 GB log file size
    }

    if (getenv("CB_MAXIMIZE_LOGGER_BUFFER_SIZE") != nullptr) {
        buffersz = 8 * 1024 * 1024; // use an 8MB log buffer
    }

    try {
        // Initialise the loggers.
        //
        // The structure is as follows:
        //
        // file_logger = sends log messages to sink
        //   |__dist_sink_mt = Distribute log messages to multiple sinks
        //       |     |__custom_rotating_file_sink_mt = adds opening & closing
        //       |                                       hooks to the file
        //       |__ (color)__stderr_sink_mt = Send log messages to consloe
        //
        // When a new log message is being submitted to the file_logger it
        // is subject to the log level specified on the file_logger. If it
        // is to be included it is passed down to the dist_sink which will
        // evaluate if the message should be passed on based on its log level.
        // It'll then try to pass the message to the file sink and the
        // console sink and they will evaluate if the message should be
        // logged or not. This means that we should set the file sink
        // loglevel to TRACE so that all messages which goes all the way
        // will end up in the file. Due to the fact that ns_server can't
        // keep up with the rate we might produce log we want the console
        // sink to drop everything below WARNING (unless we're running
        // unit tests (through testapp).
        //
        // When the user change the verbosity level we'll modify the
        // level for the file_logger object causing it to allow more
        // messages to go down to the various sinks.

        auto sink = std::make_shared<spdlog::sinks::dist_sink_mt>();
        sink->set_level(spdlog::level::trace);

        if (!fname.empty()) {
            auto fsink = std::make_shared<custom_rotating_file_sink_mt>(
                    fname, cyclesz, log_pattern);
            fsink->set_level(spdlog::level::trace);
            sink->add_sink(fsink);
        }

        if (logger_settings.console) {
#ifdef WIN32
            auto stderrsink = std::make_shared<spdlog::sinks::stderr_sink_mt>();
#else
            auto stderrsink =
                    std::make_shared<spdlog::sinks::ansicolor_stderr_sink_mt>();
#endif
            if (logger_settings.unit_test) {
                stderrsink->set_level(spdlog::level::trace);
            } else {
                stderrsink->set_level(spdlog::level::warn);
            }
            sink->add_sink(stderrsink);
        }

        spdlog::drop(logger_name);
        file_logger =
                spdlog::create_async(logger_name,
                                     sink,
                                     buffersz,
                                     spdlog::async_overflow_policy::block_retry,
                                     nullptr,
                                     std::chrono::milliseconds(200));
    } catch (const spdlog::spdlog_ex& ex) {
        std::string msg =
                std::string{"Log initialization failed: "} + ex.what();
        return boost::optional<std::string>{msg};
    }

    file_logger->set_pattern(log_pattern);
    file_logger->set_level(spdlog::level::level_enum::info);
    return {};
}

std::shared_ptr<spdlog::logger> cb::logger::get() {
    return file_logger;
}

void cb::logger::createBlackholeLogger() {
    // delete if already exists
    spdlog::drop(logger_name);

    file_logger = spdlog::create(
            logger_name, std::make_shared<spdlog::sinks::null_sink_mt>());

    file_logger->set_level(spdlog::level::off);
    file_logger->set_pattern(log_pattern);
}

void cb::logger::createConsoleLogger() {
    // delete if already exists
    spdlog::drop(logger_name);
    file_logger = spdlog::stderr_color_mt(logger_name);
    file_logger->set_level(spdlog::level::info);
    file_logger->set_pattern(log_pattern);
}

LOGGER_PUBLIC_API
EXTENSION_LOGGER_DESCRIPTOR& cb::logger::getLoggerDescriptor() {
    descriptor.log = log;
    return descriptor;
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Adam Grandquist

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.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#ifndef REQL_REQL_STREAM_HPP_
#define REQL_REQL_STREAM_HPP_

#include "./reql/string.hpp"

#include <algorithm>
#include <deque>
#include <string>

namespace _ReQL {

template <class str_t>
class Stream {
public:
  typedef str_t string_type;

  Stream &operator <<(const Stream &other) {
    p_stream.insert(p_stream.cend(), other.p_stream.cbegin(), other.p_stream.cend());
    return *this;
  }

  Stream &operator <<(const int value) {
    p_stream.push_back(std::to_string(value));
    return *this;
  }

  Stream &operator <<(const typename string_type::value_type *value) {
    p_stream.push_back(string_type(value));
    return *this;
  }

  Stream &operator <<(const string_type &value) {
    p_stream.push_back(value);
    return *this;
  }

  Stream &operator <<(const double value) {
    p_stream.push_back(std::to_string(value));
    return *this;
  }

  string_type str() const {
    auto size = std::accumulate(p_stream.cbegin(), p_stream.cend(), 0, [](const size_t size, const string_type &s) {
      return size + s.size();
    });
    const std::unique_ptr<typename string_type::value_type> value(new typename string_type::value_type[size]);
    std::accumulate(p_stream.cbegin(), p_stream.cend(), value.get(), [](typename string_type::value_type *value, const string_type &s) {
      memcpy(value, s.c_str(), s.size());
      return value + s.size();
    });
    return string_type(value.get(), size);
  }

  std::deque<string_type> p_stream;
};

typedef _ReQL::Stream<ImmutableString> _Stream;

}  // namespace _ReQL

#endif  // REQL_REQL_STREAM_HPP_
<commit_msg>Remove redundant namespace.<commit_after>/*
Copyright 2015 Adam Grandquist

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.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#ifndef REQL_REQL_STREAM_HPP_
#define REQL_REQL_STREAM_HPP_

#include "./reql/string.hpp"

#include <algorithm>
#include <deque>
#include <string>

namespace _ReQL {

template <class str_t>
class Stream {
public:
  typedef str_t string_type;

  Stream &operator <<(const Stream &other) {
    p_stream.insert(p_stream.cend(), other.p_stream.cbegin(), other.p_stream.cend());
    return *this;
  }

  Stream &operator <<(const int value) {
    p_stream.push_back(std::to_string(value));
    return *this;
  }

  Stream &operator <<(const typename string_type::value_type *value) {
    p_stream.push_back(string_type(value));
    return *this;
  }

  Stream &operator <<(const string_type &value) {
    p_stream.push_back(value);
    return *this;
  }

  Stream &operator <<(const double value) {
    p_stream.push_back(std::to_string(value));
    return *this;
  }

  string_type str() const {
    auto size = std::accumulate(p_stream.cbegin(), p_stream.cend(), 0, [](const size_t size, const string_type &s) {
      return size + s.size();
    });
    const std::unique_ptr<typename string_type::value_type> value(new typename string_type::value_type[size]);
    std::accumulate(p_stream.cbegin(), p_stream.cend(), value.get(), [](typename string_type::value_type *value, const string_type &s) {
      memcpy(value, s.c_str(), s.size());
      return value + s.size();
    });
    return string_type(value.get(), size);
  }

  std::deque<string_type> p_stream;
};

typedef Stream<ImmutableString> _Stream;

}  // namespace _ReQL

#endif  // REQL_REQL_STREAM_HPP_
<|endoftext|>


<commit_before>#include <Eigen/Core>       // Cholesky decomposition + solving
#include <Eigen/Cholesky>   // of system of linear equations.

#include "nao_igm.h"
#include "maple_functions.h"

/**
 * @brief Get feet positions.
 *
 * @param[out] left_foot_expected 3x1 expected position vector
 * @param[out] right_foot_expected 3x1 expected position vector
 * @param[out] left_foot_computed 3x1 position vector determined using sensor data
 * @param[out] right_foot_computed 3x1 position vector determined using sensor data
 *
 * @note Support foot position is assumed to be correct and there is no difference
 * between the expected and 'real' positions.
 *
 * @note swing_foot_posture member is updated.
 */
void nao_igm::getFeetPositions (
        double *left_foot_expected,
        double *right_foot_expected,
        double *left_foot_computed,
        double *right_foot_computed)
{
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        Vector3d::Map(left_foot_expected) = Vector3d::Map(left_foot_computed) = left_foot_posture.translation();
        Vector3d::Map(right_foot_expected) = right_foot_posture.translation();
        getSwingFootPosition (state_sensor, right_foot_computed);
    }
    else
    {
        Vector3d::Map(right_foot_expected) = Vector3d::Map(right_foot_computed) = right_foot_posture.translation();
        Vector3d::Map(left_foot_expected) = right_foot_posture.translation();
        getSwingFootPosition (state_sensor, left_foot_computed);
    }
}

/**
 * @brief Set coordinates of center of mass.
 *
 * @param[in] x coordinate
 * @param[in] y coordinate
 * @param[in] z coordinate
 */
void nao_igm::setCoM (const double x, const double y, const double z)
{
    CoM_position[0] = x;
    CoM_position[1] = y;
    CoM_position[2] = z;
}

/** @brief Initialize model.

    @param[in] support_foot_ current support foot.
    @param[in] x x-position
    @param[in] y y-position
    @param[in] z z-position
    @param[in] roll x-rotation
    @param[in] pitch y-rotation
    @param[in] yaw z-rotation

    @attention Joint angles in state_sensor must be set.
*/
void nao_igm::init(
        const igmSupportFoot support_foot_,
        const double x,
        const double y,
        const double z,
        const double roll,
        const double pitch,
        const double yaw)
{
    Transform <double, 3> support_foot_posture =
            Translation<double,3>(x, y, z) *
            AngleAxisd(roll, Vector3d::UnitX()) *
            AngleAxisd(pitch, Vector3d::UnitY()) *
            AngleAxisd(yaw, Vector3d::UnitZ());
    support_foot = support_foot_;
    state_model = state_sensor;

    Transform<double,3> torso_posture;
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        left_foot_posture = support_foot_posture;
        LLeg2Torso(state_sensor.q, left_foot_posture.data(), torso_posture.data());
        LLeg2RLeg(state_sensor.q, left_foot_posture.data(), right_foot_posture.data());
        swing_foot_posture = right_foot_posture;
    }
    else
    {
        right_foot_posture = support_foot_posture;
        RLeg2Torso(state_sensor.q, right_foot_posture.data(), torso_posture.data());
        RLeg2LLeg(state_sensor.q, right_foot_posture.data(), left_foot_posture.data());
        swing_foot_posture = left_foot_posture;
    }
    Matrix3d::Map (torso_orientation) = torso_posture.matrix().corner(TopLeft,3,3);

    getCoM (state_sensor, CoM_position);
}

/**
 * @brief Switch support foot.
 *
 * @return A 4x4 homogeneous matrix, which contains position and orientation
 * (computed using sensor data) of the new support foot.
 *
 * @note swing_foot_posture member is updated.
 */
double* nao_igm::switchSupportFoot()
{
    getSwingFootPosture (state_sensor);
    state_model = state_sensor;

    if (support_foot == IGM_SUPPORT_LEFT)
    {
        support_foot = IGM_SUPPORT_RIGHT;
    }
    else
    {
        support_foot = IGM_SUPPORT_LEFT;
    }

    return (swing_foot_posture.data());
}

/**
 * @brief Compute position of the CoM from joint angles.
 *
 * @param[in] joints state of the joints.
 * @param[in,out] CoM_pos 3x1 vector of coordinates.
 */
void nao_igm::getCoM (jointState& joints, double *CoM_pos)
{
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        LLeg2CoM(joints.q, left_foot_posture.data(), CoM_pos);
    }
    else
    {
        RLeg2CoM(joints.q, right_foot_posture.data(), CoM_pos);
    }
}

/**
 * @brief Compute position of the swing foot from joint angles.
 *
 * @param[in] joints state of the joints.
 * @param[in,out] swing_foot_position  3x1 vector of coordinates.
 *
 * @note swing_foot_posture member is updated.
 */
void nao_igm::getSwingFootPosition (jointState& joints, double * swing_foot_position)
{
    getSwingFootPosture(joints);
    Vector3d::Map(swing_foot_position) = swing_foot_posture.translation();
}

/**
 * @brief Compute position of the swing foot from joint angles.
 *
 * @param[in] joints state of the joints.
 *
 * @note swing_foot_posture member is updated.
 */
void nao_igm::getSwingFootPosture (jointState& joints)
{
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        LLeg2RLeg(joints.q, left_foot_posture.data(), swing_foot_posture.data());
    }
    else
    {
        RLeg2LLeg(joints.q, right_foot_posture.data(), swing_foot_posture.data());
    }
}

/** \brief Solves the Inverse Geometric Problem (IGM). Constraints for (x, y, z, X(alpha), Y(beta),
    Z(gamma)) of the foot not in support as well as (x, y, z) position of the CoM, and X(alpha),
    Y(beta) rotation of the torso can be imposed.

    \return int iter - the number of iterations performed until convergence, or -1 if the algorithm
    did not converge within max_iter number of iterations.

    \note It is assumed that the leading matrix of the constraints is nonsingular.

    @note On input, the entries of q are the joint angles from where to start the
    search for a solution (i.e., the initial guess). On output q contains a solution of the
    inverse kinematics problem (if iter != -1). Only q[0]...q[11] are altered.
*/
int nao_igm::igm()
{
    const int num_constraints = LOWER_JOINTS_NUM-1; // one is skipped

    Matrix<double, num_constraints, num_constraints> AAT;
    Matrix<double, LOWER_JOINTS_NUM, 1> dq;

    double out[num_constraints*LOWER_JOINTS_NUM + num_constraints];
    Map<MatrixXd> A(out,num_constraints,LOWER_JOINTS_NUM);
    Map<VectorXd> err(out+num_constraints*LOWER_JOINTS_NUM,num_constraints);

    double tol = 0.0005;
    int max_iter = 20;
    int iter;
    double norm_dq = 1.0;

    for (iter = 0; (norm_dq > tol) && (iter <= max_iter); ++iter)
    {
        // Form data
        if (support_foot == IGM_SUPPORT_LEFT)
        {
            from_LLeg_3 (
                    state_model.q,
                    left_foot_posture.data(),
                    right_foot_posture.data(),
                    CoM_position,
                    torso_orientation,
                    out);
        }
        else
        {
            from_RLeg_3 (
                    state_model.q,
                    right_foot_posture.data(),
                    left_foot_posture.data(),
                    CoM_position,
                    torso_orientation,
                    out);
        }

        // Solve KKT system
        AAT = A*A.transpose();
        AAT.llt().solveInPlace(err);
        dq = A.transpose()*err;

        // Update angles (of legs)
        VectorXd::Map (state_model.q, LOWER_JOINTS_NUM) += dq;

        // Compute the norm of dq
        norm_dq = dq.norm();
    }

    if (iter > max_iter)
    {
        iter = -1;
    }

    return(iter);
}
<commit_msg>Fixed wrong position of the left foot in getFeetPositions().<commit_after>#include <Eigen/Core>       // Cholesky decomposition + solving
#include <Eigen/Cholesky>   // of system of linear equations.

#include "nao_igm.h"
#include "maple_functions.h"

/**
 * @brief Get feet positions.
 *
 * @param[out] left_foot_expected 3x1 expected position vector
 * @param[out] right_foot_expected 3x1 expected position vector
 * @param[out] left_foot_computed 3x1 position vector determined using sensor data
 * @param[out] right_foot_computed 3x1 position vector determined using sensor data
 *
 * @note Support foot position is assumed to be correct and there is no difference
 * between the expected and 'real' positions.
 *
 * @note swing_foot_posture member is updated.
 */
void nao_igm::getFeetPositions (
        double *left_foot_expected,
        double *right_foot_expected,
        double *left_foot_computed,
        double *right_foot_computed)
{
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        Vector3d::Map(left_foot_expected) = Vector3d::Map(left_foot_computed) = left_foot_posture.translation();
        Vector3d::Map(right_foot_expected) = right_foot_posture.translation();
        getSwingFootPosition (state_sensor, right_foot_computed);
    }
    else
    {
        Vector3d::Map(right_foot_expected) = Vector3d::Map(right_foot_computed) = right_foot_posture.translation();
        Vector3d::Map(left_foot_expected) = left_foot_posture.translation();
        getSwingFootPosition (state_sensor, left_foot_computed);
    }
}

/**
 * @brief Set coordinates of center of mass.
 *
 * @param[in] x coordinate
 * @param[in] y coordinate
 * @param[in] z coordinate
 */
void nao_igm::setCoM (const double x, const double y, const double z)
{
    CoM_position[0] = x;
    CoM_position[1] = y;
    CoM_position[2] = z;
}

/** @brief Initialize model.

    @param[in] support_foot_ current support foot.
    @param[in] x x-position
    @param[in] y y-position
    @param[in] z z-position
    @param[in] roll x-rotation
    @param[in] pitch y-rotation
    @param[in] yaw z-rotation

    @attention Joint angles in state_sensor must be set.
*/
void nao_igm::init(
        const igmSupportFoot support_foot_,
        const double x,
        const double y,
        const double z,
        const double roll,
        const double pitch,
        const double yaw)
{
    Transform <double, 3> support_foot_posture =
            Translation<double,3>(x, y, z) *
            AngleAxisd(roll, Vector3d::UnitX()) *
            AngleAxisd(pitch, Vector3d::UnitY()) *
            AngleAxisd(yaw, Vector3d::UnitZ());
    support_foot = support_foot_;
    state_model = state_sensor;

    Transform<double,3> torso_posture;
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        left_foot_posture = support_foot_posture;
        LLeg2Torso(state_sensor.q, left_foot_posture.data(), torso_posture.data());
        LLeg2RLeg(state_sensor.q, left_foot_posture.data(), right_foot_posture.data());
        swing_foot_posture = right_foot_posture;
    }
    else
    {
        right_foot_posture = support_foot_posture;
        RLeg2Torso(state_sensor.q, right_foot_posture.data(), torso_posture.data());
        RLeg2LLeg(state_sensor.q, right_foot_posture.data(), left_foot_posture.data());
        swing_foot_posture = left_foot_posture;
    }
    Matrix3d::Map (torso_orientation) = torso_posture.matrix().corner(TopLeft,3,3);

    getCoM (state_sensor, CoM_position);
}

/**
 * @brief Switch support foot.
 *
 * @return A 4x4 homogeneous matrix, which contains position and orientation
 * (computed using sensor data) of the new support foot.
 *
 * @note swing_foot_posture member is updated.
 */
double* nao_igm::switchSupportFoot()
{
    getSwingFootPosture (state_sensor);
    state_model = state_sensor;

    if (support_foot == IGM_SUPPORT_LEFT)
    {
        support_foot = IGM_SUPPORT_RIGHT;
    }
    else
    {
        support_foot = IGM_SUPPORT_LEFT;
    }

    return (swing_foot_posture.data());
}

/**
 * @brief Compute position of the CoM from joint angles.
 *
 * @param[in] joints state of the joints.
 * @param[in,out] CoM_pos 3x1 vector of coordinates.
 */
void nao_igm::getCoM (jointState& joints, double *CoM_pos)
{
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        LLeg2CoM(joints.q, left_foot_posture.data(), CoM_pos);
    }
    else
    {
        RLeg2CoM(joints.q, right_foot_posture.data(), CoM_pos);
    }
}

/**
 * @brief Compute position of the swing foot from joint angles.
 *
 * @param[in] joints state of the joints.
 * @param[in,out] swing_foot_position  3x1 vector of coordinates.
 *
 * @note swing_foot_posture member is updated.
 */
void nao_igm::getSwingFootPosition (jointState& joints, double * swing_foot_position)
{
    getSwingFootPosture(joints);
    Vector3d::Map(swing_foot_position) = swing_foot_posture.translation();
}

/**
 * @brief Compute position of the swing foot from joint angles.
 *
 * @param[in] joints state of the joints.
 *
 * @note swing_foot_posture member is updated.
 */
void nao_igm::getSwingFootPosture (jointState& joints)
{
    if (support_foot == IGM_SUPPORT_LEFT)
    {
        LLeg2RLeg(joints.q, left_foot_posture.data(), swing_foot_posture.data());
    }
    else
    {
        RLeg2LLeg(joints.q, right_foot_posture.data(), swing_foot_posture.data());
    }
}

/** \brief Solves the Inverse Geometric Problem (IGM). Constraints for (x, y, z, X(alpha), Y(beta),
    Z(gamma)) of the foot not in support as well as (x, y, z) position of the CoM, and X(alpha),
    Y(beta) rotation of the torso can be imposed.

    \return int iter - the number of iterations performed until convergence, or -1 if the algorithm
    did not converge within max_iter number of iterations.

    \note It is assumed that the leading matrix of the constraints is nonsingular.

    @note On input, the entries of q are the joint angles from where to start the
    search for a solution (i.e., the initial guess). On output q contains a solution of the
    inverse kinematics problem (if iter != -1). Only q[0]...q[11] are altered.
*/
int nao_igm::igm()
{
    const int num_constraints = LOWER_JOINTS_NUM-1; // one is skipped

    Matrix<double, num_constraints, num_constraints> AAT;
    Matrix<double, LOWER_JOINTS_NUM, 1> dq;

    double out[num_constraints*LOWER_JOINTS_NUM + num_constraints];
    Map<MatrixXd> A(out,num_constraints,LOWER_JOINTS_NUM);
    Map<VectorXd> err(out+num_constraints*LOWER_JOINTS_NUM,num_constraints);

    double tol = 0.0005;
    int max_iter = 20;
    int iter;
    double norm_dq = 1.0;

    for (iter = 0; (norm_dq > tol) && (iter <= max_iter); ++iter)
    {
        // Form data
        if (support_foot == IGM_SUPPORT_LEFT)
        {
            from_LLeg_3 (
                    state_model.q,
                    left_foot_posture.data(),
                    right_foot_posture.data(),
                    CoM_position,
                    torso_orientation,
                    out);
        }
        else
        {
            from_RLeg_3 (
                    state_model.q,
                    right_foot_posture.data(),
                    left_foot_posture.data(),
                    CoM_position,
                    torso_orientation,
                    out);
        }

        // Solve KKT system
        AAT = A*A.transpose();
        AAT.llt().solveInPlace(err);
        dq = A.transpose()*err;

        // Update angles (of legs)
        VectorXd::Map (state_model.q, LOWER_JOINTS_NUM) += dq;

        // Compute the norm of dq
        norm_dq = dq.norm();
    }

    if (iter > max_iter)
    {
        iter = -1;
    }

    return(iter);
}
<|endoftext|>