<commit_before>/*
(c) Matthew Slocum 2015

msgComponent.cpp

msgComponent is resbonaible for sending and revieving messages
    upon creation it spins off a thread to listen for incoming messages.
    the parent process takes input from the user and executes commands or sends messages.

*/

#include <iostream>
#include <stdlib.h>
#include <boost/asio.hpp>
#include <pthread.h>
#include <string>
#include "msgComponent.h"
#include "regComponent.h"
#include "secComponent.h"

using namespace std;
using boost::asio::ip::tcp;

msgComponent::msgComponent() {

}

//Code derived from:
// daytime_server.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// at http://www.boost.org/LICENSE_1_0.txt)

//Function for listener thread
//This fucntion listens for incoming connections, recieves a message, decrypts it and displays it.
void* listen(void *threadid) {
    try
      {
        extern regComponent* reg;
        extern secComponent* sec;
        boost::asio::io_service io_service;
        tcp::endpoint endpoint(tcp::v4(), 6283);
        tcp::acceptor acceptor(io_service, endpoint);
        for (;;)
        {
          tcp::iostream stream;
          boost::system::error_code ec;
          acceptor.accept(*stream.rdbuf(), ec);
          //if the is an incomming connection
          if (!ec)
          {
            string message = "";
            string line;
            char c;
            char msg [1034];
            int msg_count=0;
            //get message
            while(stream.get(c)) {
                msg[msg_count++]=c;
            }
            //make holder for plaintext
            char plaintext[msg_count];
            //decrypt message and store in plaintext
            sec->decrypt(msg, msg_count, reg->key, 20, plaintext);
            //display plaintext message
            cout << endl << endl;
            for(int i=0; i<msg_count-10; i++) {
                cout << plaintext[i];
            }
            cout << endl;
            //redraw user input prompt
            cout.clear();cout.flush();
            cout << endl << "TauNet [TO: " << reg->name_list[reg->dest] << "]> "; cout.clear(); cout.flush();
          }
        }

      }
      //catch any std exceptions
      catch (std::exception& e)
      {
        std::cerr << e.what() << std::endl;
      }
    pthread_exit(NULL);
}

void msgComponent::run() {
    //spin off thread for listener
    pthread_t thread;
    int rc;
    rc = pthread_create(&thread, NULL, listen, NULL);
    if (rc){
        cout << "Error:unable to create thread," << rc << endl;
        exit(-1);
    }
    command="";
    //draw some ui
    draw_header();
    draw_dest();
    //c&c loop
    while(command!=":q") {
        //get input
        get_input();
        //parse special commands
        //list destinations
        if(command==":dlist") {
            reg->printDest();
        }
        //set destination
        else if (command.find(":dset")==0) {
            //cout << command.substr(6) << endl;
            int d = atoi((command.substr(6)).c_str());
            d--;
            if(d>=0 && d<reg->dest_count) {
                reg->setDest(d);
                draw_dest();
            } else {
                cout << "Destination out of range." << endl;
            }
        }
        //else, its a message, send it!
        //CODE derived from daytime_client.cpp (Boost::asio)
        //Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
        //Distributed under the Boost Software License, Version 1.0 at http://www.boost.org/LICENSE_1_0.txt)
        else {
            try {
                boost::asio::io_service io_service;
                boost::asio::ip::tcp::resolver resolver(io_service);
                boost::asio::ip::tcp::resolver::query query(reg->dest_list[reg->dest], "6283");
                //attempt to open connection
                tcp::iostream stream(reg->dest_list[reg->dest], "6283");
                if (!stream)
                {
                  std::cout << "Unable to connect: " << stream.error().message() << std::endl;
                }
                //build message
                string message;
                message = string("version: 0.2\r\n")
                        + "from: " + reg->username + "\r\n"
                        + "to: " + reg->name_list[reg->dest] + "\r\n"
                        + "\r\n"
                        + command + "\r\n";

                //init holder for ciphertext
                char ciphertext [message.length()+10];
                //encrypt the message
                sec->encrypt(message,reg->key,20, ciphertext);
                //send the message
                for(unsigned int i=0; i<message.length()+10; i++) {
                    stream << ciphertext[i];
                }
                //close the connection
                stream.close();
            }
            catch (std::exception& e) {
                std::cout << "Exception: " << e.what() << std::endl;
            }
        }

    }
}

//let the msgComponent know about the regComponent
void msgComponent::bind_regComponent(regComponent * in) {
    reg = in;
}

//let the msgComponent know about the secComponent
void msgComponent::bind_secComponent(secComponent * in) {
    sec = in;
}

void msgComponent::draw_header() {
    system("clear");
    cout << "|------------TauNet Messenger------------|" << endl;
    cout << "|  Commands" << endl;
    cout << "|   :q        - quit" << endl;
    cout << "|   :dlist    - list destinations" << endl;
    cout << "|   :dset #   - set destination" << endl;
    cout << "|------------TauNet Messenger------------|" << endl;
}

void msgComponent::draw_dest() {
    cout << "***     DESTINATION: [" << reg->name_list[reg->dest] << "]" << reg->dest_list[reg->dest] << "     ***" << endl;
}

void msgComponent::get_input() {
    cout << endl;
    cin.clear();
    cout << "TauNet [TO: " << reg->name_list[reg->dest] << "]> ";
    getline(cin,command);
}

void msgComponent::draw_get_input() {
    cout << "TauNet [TO: " << reg->name_list[reg->dest] << "]> ";
}
<commit_msg>added code to discard messages of length zero<commit_after>/*
(c) Matthew Slocum 2015

msgComponent.cpp

msgComponent is resbonaible for sending and revieving messages
    upon creation it spins off a thread to listen for incoming messages.
    the parent process takes input from the user and executes commands or sends messages.

*/

#include <iostream>
#include <stdlib.h>
#include <boost/asio.hpp>
#include <pthread.h>
#include <string>
#include "msgComponent.h"
#include "regComponent.h"
#include "secComponent.h"

using namespace std;
using boost::asio::ip::tcp;

msgComponent::msgComponent() {

}

//Code derived from:
// daytime_server.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// at http://www.boost.org/LICENSE_1_0.txt)

//Function for listener thread
//This fucntion listens for incoming connections, recieves a message, decrypts it and displays it.
void* listen(void *threadid) {
    try
      {
        extern regComponent* reg;
        extern secComponent* sec;
        boost::asio::io_service io_service;
        tcp::endpoint endpoint(tcp::v4(), 6283);
        tcp::acceptor acceptor(io_service, endpoint);
        for (;;)
        {
          tcp::iostream stream;
          boost::system::error_code ec;
          acceptor.accept(*stream.rdbuf(), ec);
          //if the is an incomming connection
          if (!ec)
          {
            string message = "";
            string line;
            char c;
            char msg [1034];
            int msg_count=0;
            //get message
            while(stream.get(c)) {
                msg[msg_count++]=c;
            }
            //make holder for plaintext
            char plaintext[msg_count];
            //decrypt message and store in plaintext
            sec->decrypt(msg, msg_count, reg->key, 20, plaintext);
            //display plaintext message if it exists
            if(msg_count>0) {
                cout << endl << endl;
                for(int i=0; i<msg_count-10; i++) {
                    cout << plaintext[i];
                }
                cout << endl;
            }
            //redraw user input prompt
            cout.clear();cout.flush();
            cout << endl << "TauNet [TO: " << reg->name_list[reg->dest] << "]> "; cout.clear(); cout.flush();
          }
        }

      }
      //catch any std exceptions
      catch (std::exception& e)
      {
        std::cerr << e.what() << std::endl;
      }
    pthread_exit(NULL);
}

void msgComponent::run() {
    //spin off thread for listener
    pthread_t thread;
    int rc;
    rc = pthread_create(&thread, NULL, listen, NULL);
    if (rc){
        cout << "Error:unable to create thread," << rc << endl;
        exit(-1);
    }
    command="";
    //draw some ui
    draw_header();
    draw_dest();
    //c&c loop
    while(command!=":q") {
        //get input
        get_input();
        //parse special commands
        //list destinations
        if(command==":dlist") {
            reg->printDest();
        }
        //set destination
        else if (command.find(":dset")==0) {
            //cout << command.substr(6) << endl;
            int d = atoi((command.substr(6)).c_str());
            d--;
            if(d>=0 && d<reg->dest_count) {
                reg->setDest(d);
                draw_dest();
            } else {
                cout << "Destination out of range." << endl;
            }
        }
        //else, its a message, send it!
        //CODE derived from daytime_client.cpp (Boost::asio)
        //Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
        //Distributed under the Boost Software License, Version 1.0 at http://www.boost.org/LICENSE_1_0.txt)
        else {
            try {
                boost::asio::io_service io_service;
                boost::asio::ip::tcp::resolver resolver(io_service);
                boost::asio::ip::tcp::resolver::query query(reg->dest_list[reg->dest], "6283");
                //attempt to open connection
                tcp::iostream stream(reg->dest_list[reg->dest], "6283");
                if (!stream)
                {
                  std::cout << "Unable to connect: " << stream.error().message() << std::endl;
                }
                //build message
                string message;
                message = string("version: 0.2\r\n")
                        + "from: " + reg->username + "\r\n"
                        + "to: " + reg->name_list[reg->dest] + "\r\n"
                        + "\r\n"
                        + command + "\r\n";

                //init holder for ciphertext
                char ciphertext [message.length()+10];
                //encrypt the message
                sec->encrypt(message,reg->key,20, ciphertext);
                //send the message
                for(unsigned int i=0; i<message.length()+10; i++) {
                    stream << ciphertext[i];
                }
                //close the connection
                stream.close();
            }
            catch (std::exception& e) {
                std::cout << "Exception: " << e.what() << std::endl;
            }
        }

    }
}

//let the msgComponent know about the regComponent
void msgComponent::bind_regComponent(regComponent * in) {
    reg = in;
}

//let the msgComponent know about the secComponent
void msgComponent::bind_secComponent(secComponent * in) {
    sec = in;
}

void msgComponent::draw_header() {
    system("clear");
    cout << "|------------TauNet Messenger------------|" << endl;
    cout << "|  Commands" << endl;
    cout << "|   :q        - quit" << endl;
    cout << "|   :dlist    - list destinations" << endl;
    cout << "|   :dset #   - set destination" << endl;
    cout << "|------------TauNet Messenger------------|" << endl;
}

void msgComponent::draw_dest() {
    cout << "***     DESTINATION: [" << reg->name_list[reg->dest] << "]" << reg->dest_list[reg->dest] << "     ***" << endl;
}

void msgComponent::get_input() {
    cout << endl;
    cin.clear();
    cout << "TauNet [TO: " << reg->name_list[reg->dest] << "]> ";
    getline(cin,command);
}

void msgComponent::draw_get_input() {
    cout << "TauNet [TO: " << reg->name_list[reg->dest] << "]> ";
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

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, see <http://www.gnu.org/licenses/>.

*/

#include "utils.h"
#include "videooutput.h"
#include "videooutputobserver.h"

#ifdef _DEBUG
#include "objectdump.h"
#endif

#include <QPaintEvent>
#include <QPainter>
#include <QMoveEvent>
#include <QResizeEvent>

// Required for implementation of transparentFill
#include <QtGui/private/qwidget_p.h>
#include <QtGui/private/qdrawhelper_p.h>
#include <QtGui/private/qwindowsurface_p.h>
#include <QImage>

QT_BEGIN_NAMESPACE

using namespace Phonon;
using namespace Phonon::MMF;

//-----------------------------------------------------------------------------
// Constructor / destructor
//-----------------------------------------------------------------------------

MMF::VideoOutput::VideoOutput(QWidget* parent)
        :   QWidget(parent)
        ,   m_observer(NULL)
{
    TRACE_CONTEXT(VideoOutput::VideoOutput, EVideoInternal);
    TRACE_ENTRY("parent 0x%08x", parent);

#ifndef PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
    setPalette(QPalette(Qt::black));
	setAttribute(Qt::WA_OpaquePaintEvent, true);
	setAttribute(Qt::WA_NoSystemBackground, true);
	setAutoFillBackground(false);
#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET

    dump();

    TRACE_EXIT_0();
}

MMF::VideoOutput::~VideoOutput()
{
    TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal);
    TRACE_ENTRY_0();

    TRACE_EXIT_0();
}

void MMF::VideoOutput::setFrameSize(const QSize& frameSize)
{
#ifdef PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
    Q_UNUSED(frameSize);
#else
    TRACE_CONTEXT(VideoOutput::setFrameSize, EVideoInternal);
    TRACE("oldSize %d %d newSize %d %d",
          m_frameSize.width(), m_frameSize.height(),
          frameSize.width(), frameSize.height());

    if (frameSize != m_frameSize) {
        m_frameSize = frameSize;
        updateGeometry();
    }
#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
}

void MMF::VideoOutput::setObserver(VideoOutputObserver* observer)
{
    TRACE_CONTEXT(VideoOutput::setObserver, EVideoInternal);
    TRACE("observer 0x%08x", observer);

    m_observer = observer;
}

//-----------------------------------------------------------------------------
// QWidget
//-----------------------------------------------------------------------------

#ifndef PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET

QSize MMF::VideoOutput::sizeHint() const
{
    // TODO: replace this with a more sensible default
    QSize result(320, 240);

    if (!m_frameSize.isNull()) {
        result = m_frameSize;
    }

    return result;
}

void MMF::VideoOutput::paintEvent(QPaintEvent* event)
{
    TRACE_CONTEXT(VideoOutput::paintEvent, EVideoInternal);
    TRACE("rect %d %d - %d %d",
          event->rect().left(), event->rect().top(),
          event->rect().right(), event->rect().bottom());
    TRACE("regions %d", event->region().numRects());
    TRACE("type %d", event->type());

    dump();

#ifdef PHONON_MMF_DIRECT_WRITE_ALPHA
    transparentFill(event->region().rects());
#else
    // Note: composition mode code was a failed attempt to get transparent
    // alpha values to be propagated to the (EColor16MU) window surface.

    QPainter painter;
    //const QPainter::CompositionMode compositionMode = painter.compositionMode();
    //painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.begin(this);
    painter.setBrush(QColor(0, 0, 0, 0));
    painter.drawRects(event->region().rects());
    painter.end();
    //painter.setCompositionMode(compositionMode);
#endif
}

void MMF::VideoOutput::transparentFill(const QVector<QRect>& rects)
{
	TRACE_CONTEXT(VideoOutput::transparentFill, EVideoInternal);
	TRACE_ENTRY_0();

	QImage *image = window()->windowSurface()->buffer(window());
	QRgb *data = reinterpret_cast<QRgb *>(image->bits());
	const int row_stride = image->bytesPerLine() / 4;

	for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {

		const QRect& rect = *it;

		TRACE("%d %d size %d x %d", rect.x(), rect.y(), rect.width(), rect.height());

		const int x_start = rect.x();
		const int width = rect.width();

		const int y_start = rect.y();
		const int height = rect.height();

		QRgb *row = data + row_stride * y_start;
		for (int y = 0; y < height; ++y) {

			// Note: not using the optimised qt_memfill function implemented in
			// gui/painting/qdrawhelper.cpp - can we somehow link against this?

			//qt_memfill(row + x_start, 0U, width);
			memset(row + x_start, 0, width*4);
			row += row_stride;
		}
	}

	TRACE_EXIT_0();
}

void MMF::VideoOutput::resizeEvent(QResizeEvent* event)
{
    TRACE_CONTEXT(VideoOutput::resizeEvent, EVideoInternal);
    TRACE("%d %d -> %d %d",
          event->oldSize().width(), event->oldSize().height(),
          event->size().width(), event->size().height());

    QWidget::resizeEvent(event);

    if (m_observer)
        m_observer->videoOutputRegionChanged();
}

void MMF::VideoOutput::moveEvent(QMoveEvent* event)
{
    TRACE_CONTEXT(VideoOutput::moveEvent, EVideoInternal);
    TRACE("%d %d -> %d %d",
          event->oldPos().x(), event->oldPos().y(),
          event->pos().x(), event->pos().y());

    QWidget::moveEvent(event);

    if (m_observer)
        m_observer->videoOutputRegionChanged();
}

#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET

//-----------------------------------------------------------------------------
// Private functions
//-----------------------------------------------------------------------------

void VideoOutput::dump() const
{
#ifdef _DEBUG
    TRACE_CONTEXT(VideoOutput::dump, EVideoInternal);
    QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor);
    visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs
    ObjectDump::addDefaultAnnotators(*visitor);
    TRACE("Dumping tree from leaf 0x%08x:", this);
    //ObjectDump::dumpAncestors(*this, *visitor);
    ObjectDump::dumpTreeFromLeaf(*this, *visitor);
#endif
}

QT_END_NAMESPACE

<commit_msg>Modified transparentFill to allow RGBA color to be specified more easily, for testing<commit_after>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

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, see <http://www.gnu.org/licenses/>.

*/

#include "utils.h"
#include "videooutput.h"
#include "videooutputobserver.h"

#ifdef _DEBUG
#include "objectdump.h"
#endif

#include <QPaintEvent>
#include <QPainter>
#include <QMoveEvent>
#include <QResizeEvent>

// Required for implementation of transparentFill
#include <QtGui/private/qwidget_p.h>
#include <QtGui/private/qdrawhelper_p.h>
#include <QtGui/private/qwindowsurface_p.h>
#include <QImage>

QT_BEGIN_NAMESPACE

using namespace Phonon;
using namespace Phonon::MMF;

//-----------------------------------------------------------------------------
// Constructor / destructor
//-----------------------------------------------------------------------------

MMF::VideoOutput::VideoOutput(QWidget* parent)
        :   QWidget(parent)
        ,   m_observer(NULL)
{
    TRACE_CONTEXT(VideoOutput::VideoOutput, EVideoInternal);
    TRACE_ENTRY("parent 0x%08x", parent);

#ifndef PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
    setPalette(QPalette(Qt::black));
	setAttribute(Qt::WA_OpaquePaintEvent, true);
	setAttribute(Qt::WA_NoSystemBackground, true);
	setAutoFillBackground(false);
#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET

    dump();

    TRACE_EXIT_0();
}

MMF::VideoOutput::~VideoOutput()
{
    TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal);
    TRACE_ENTRY_0();

    TRACE_EXIT_0();
}

void MMF::VideoOutput::setFrameSize(const QSize& frameSize)
{
#ifdef PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
    Q_UNUSED(frameSize);
#else
    TRACE_CONTEXT(VideoOutput::setFrameSize, EVideoInternal);
    TRACE("oldSize %d %d newSize %d %d",
          m_frameSize.width(), m_frameSize.height(),
          frameSize.width(), frameSize.height());

    if (frameSize != m_frameSize) {
        m_frameSize = frameSize;
        updateGeometry();
    }
#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
}

void MMF::VideoOutput::setObserver(VideoOutputObserver* observer)
{
    TRACE_CONTEXT(VideoOutput::setObserver, EVideoInternal);
    TRACE("observer 0x%08x", observer);

    m_observer = observer;
}

//-----------------------------------------------------------------------------
// QWidget
//-----------------------------------------------------------------------------

#ifndef PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET

QSize MMF::VideoOutput::sizeHint() const
{
    // TODO: replace this with a more sensible default
    QSize result(320, 240);

    if (!m_frameSize.isNull()) {
        result = m_frameSize;
    }

    return result;
}

void MMF::VideoOutput::paintEvent(QPaintEvent* event)
{
    TRACE_CONTEXT(VideoOutput::paintEvent, EVideoInternal);
    TRACE("rect %d %d - %d %d",
          event->rect().left(), event->rect().top(),
          event->rect().right(), event->rect().bottom());
    TRACE("regions %d", event->region().numRects());
    TRACE("type %d", event->type());

    dump();

#ifdef PHONON_MMF_DIRECT_WRITE_ALPHA
    transparentFill(event->region().rects());
#else
    // Note: composition mode code was a failed attempt to get transparent
    // alpha values to be propagated to the (EColor16MU) window surface.

    QPainter painter;
    //const QPainter::CompositionMode compositionMode = painter.compositionMode();
    //painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.begin(this);
    painter.setBrush(QColor(0, 0, 0, 0));
    painter.drawRects(event->region().rects());
    painter.end();
    //painter.setCompositionMode(compositionMode);
#endif
}

void MMF::VideoOutput::transparentFill(const QVector<QRect>& rects)
{
	TRACE_CONTEXT(VideoOutput::transparentFill, EVideoInternal);
	TRACE_ENTRY_0();

	QImage *image = window()->windowSurface()->buffer(window());
	QRgb *data = reinterpret_cast<QRgb *>(image->bits());
	const int row_stride = image->bytesPerLine() / 4;

	for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {

		const QRect& rect = *it;

		TRACE("%d %d size %d x %d", rect.x(), rect.y(), rect.width(), rect.height());

		const int x_start = rect.x();
		const int width = rect.width();

		const int y_start = rect.y();
		const int height = rect.height();

		QRgb *row = data + row_stride * y_start;
		for (int y = 0; y < height; ++y) {

			// Note: not using the optimised qt_memfill function implemented in
			// gui/painting/qdrawhelper.cpp - can we somehow link against this?

			QRgb *ptr = row + x_start;
			for(int x = 0; x < width; ++x)
				*ptr++ = 0x00000000;

			row += row_stride;
		}
	}

	TRACE_EXIT_0();
}

void MMF::VideoOutput::resizeEvent(QResizeEvent* event)
{
    TRACE_CONTEXT(VideoOutput::resizeEvent, EVideoInternal);
    TRACE("%d %d -> %d %d",
          event->oldSize().width(), event->oldSize().height(),
          event->size().width(), event->size().height());

    QWidget::resizeEvent(event);

    if (m_observer)
        m_observer->videoOutputRegionChanged();
}

void MMF::VideoOutput::moveEvent(QMoveEvent* event)
{
    TRACE_CONTEXT(VideoOutput::moveEvent, EVideoInternal);
    TRACE("%d %d -> %d %d",
          event->oldPos().x(), event->oldPos().y(),
          event->pos().x(), event->pos().y());

    QWidget::moveEvent(event);

    if (m_observer)
        m_observer->videoOutputRegionChanged();
}

#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET

//-----------------------------------------------------------------------------
// Private functions
//-----------------------------------------------------------------------------

void VideoOutput::dump() const
{
#ifdef _DEBUG
    TRACE_CONTEXT(VideoOutput::dump, EVideoInternal);
    QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor);
    visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs
    ObjectDump::addDefaultAnnotators(*visitor);
    TRACE("Dumping tree from leaf 0x%08x:", this);
    //ObjectDump::dumpAncestors(*this, *visitor);
    ObjectDump::dumpTreeFromLeaf(*this, *visitor);
#endif
}

QT_END_NAMESPACE

<|endoftext|>


<commit_before>#include "SDBPConnection.h"
#include "SDBPServer.h"
#include "SDBPContext.h"
#include "SDBPRequestMessage.h"
#include "SDBPResponseMessage.h"
#include "Application/Common/ClientRequestCache.h"
#include "System/Config.h"

static const unsigned keepAliveTimeout = 60*1000; // msec

SDBPConnection::SDBPConnection()
{
    server = NULL;
    context = NULL;
    numPending = 0;
    autoFlush = false;
    onKeepAlive.SetCallable(MFUNC(SDBPConnection, OnKeepAlive));
    onKeepAlive.SetDelay(0);
}

SDBPConnection::~SDBPConnection()
{
    EventLoop::Remove(&onKeepAlive);
}

void SDBPConnection::Init(SDBPServer* server_)
{
    ClientResponse      resp;
    SDBPResponseMessage sdbpResponse;

    MessageConnection::InitConnected();

    numCompleted = 0;
    connectTimestamp = NowClock();
    server = server_;

    socket.GetEndpoint(remoteEndpoint);
    Log_Message("[%s] Client connected", remoteEndpoint.ToString());

    resp.Hello();
    sdbpResponse.response = &resp;
    Write(sdbpResponse);
    Flush();

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Add(&onKeepAlive);
}

void SDBPConnection::SetContext(SDBPContext* context_)
{
    context = context_;
}

bool SDBPConnection::OnMessage(ReadBuffer& msg)
{
    SDBPRequestMessage  sdbpRequest;
    ClientRequest*      request;

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Reset(&onKeepAlive);

    request = REQUEST_CACHE->CreateRequest();
    request->session = this;
    sdbpRequest.request = request;
    if (!sdbpRequest.Read(msg) || !context->IsValidClientRequest(request))
    {
        REQUEST_CACHE->DeleteRequest(request);
        OnClose();
        return true;
    }

    numPending++;
    context->OnClientRequest(request);
    return false;
}

void SDBPConnection::OnWrite()
{
    Log_Trace();

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Reset(&onKeepAlive);

    MessageConnection::OnWrite();
}

void SDBPConnection::OnClose()
{
    uint64_t    elapsed;

    EventLoop::Remove(&onKeepAlive);
    elapsed = NowClock() - connectTimestamp;

    Log_Message("[%s] Client disconnected (active: %u seconds, served: %u requests)",
     remoteEndpoint.ToString(), (unsigned)(elapsed / 1000.0 + 0.5), numCompleted);

    context->OnClientClose(this);
    MessageConnection::Close();

    if (numPending == 0)
    {
        Log_Debug("[%s] Connection deleted", remoteEndpoint.ToString());
        server->DeleteConn(this);
    }
}

void SDBPConnection::OnComplete(ClientRequest* request, bool last)
{
    SDBPResponseMessage sdbpResponse;

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Reset(&onKeepAlive);

    if (last)
        numPending--;

//    if (request->response.type == CLIENTRESPONSE_OK)
//        Log_Debug("OK, commandID: %U", request->commandID);

    if (state == TCPConnection::CONNECTED &&
     request->response.type != CLIENTRESPONSE_NORESPONSE &&
     !(request->response.type == CLIENTRESPONSE_CONFIG_STATE &&
      TCPConnection::GetWriteBuffer().GetLength() > SDBP_MAX_QUEUED_BYTES))
    {
        sdbpResponse.response = &request->response;
        Write(sdbpResponse);
        // TODO: HACK
        if (TCPConnection::GetWriteBuffer().GetLength() >= MESSAGING_BUFFER_THRESHOLD || last ||
         request->type == CLIENTREQUEST_GET_CONFIG_STATE)
            Flush();
    }

    if (last)
    {
        REQUEST_CACHE->DeleteRequest(request);
        numCompleted++;
    }

    if (numPending == 0 && state == DISCONNECTED)
    {
        Log_Debug("[%s] Connection deleted", remoteEndpoint.ToString());
        server->DeleteConn(this);
    }
}

bool SDBPConnection::IsActive()
{
    if (state == DISCONNECTED)
        return false;

    return true;
}

void SDBPConnection::UseKeepAlive(bool useKeepAlive_)
{
    onKeepAlive.SetDelay(configFile.GetIntValue("sdbp.keepAliveTimeout", keepAliveTimeout));
}

void SDBPConnection::OnKeepAlive()
{
    Log_Debug("Keep alive timeout occured");
    OnClose();
}
<commit_msg>Fixed bug in KeepAlive in SDBP connections.<commit_after>#include "SDBPConnection.h"
#include "SDBPServer.h"
#include "SDBPContext.h"
#include "SDBPRequestMessage.h"
#include "SDBPResponseMessage.h"
#include "Application/Common/ClientRequestCache.h"
#include "System/Config.h"

static const unsigned keepAliveTimeout = 60*1000; // msec

SDBPConnection::SDBPConnection()
{
    server = NULL;
    context = NULL;
    numPending = 0;
    autoFlush = false;
    onKeepAlive.SetCallable(MFUNC(SDBPConnection, OnKeepAlive));
    onKeepAlive.SetDelay(0);
}

SDBPConnection::~SDBPConnection()
{
    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Remove(&onKeepAlive);
}

void SDBPConnection::Init(SDBPServer* server_)
{
    ClientResponse      resp;
    SDBPResponseMessage sdbpResponse;

    MessageConnection::InitConnected();

    numCompleted = 0;
    connectTimestamp = NowClock();
    server = server_;

    socket.GetEndpoint(remoteEndpoint);
    Log_Message("[%s] Client connected", remoteEndpoint.ToString());

    resp.Hello();
    sdbpResponse.response = &resp;
    Write(sdbpResponse);
    Flush();

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Reset(&onKeepAlive);
}

void SDBPConnection::SetContext(SDBPContext* context_)
{
    context = context_;
}

bool SDBPConnection::OnMessage(ReadBuffer& msg)
{
    SDBPRequestMessage  sdbpRequest;
    ClientRequest*      request;

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Reset(&onKeepAlive);

    request = REQUEST_CACHE->CreateRequest();
    request->session = this;
    sdbpRequest.request = request;
    if (!sdbpRequest.Read(msg) || !context->IsValidClientRequest(request))
    {
        REQUEST_CACHE->DeleteRequest(request);
        OnClose();
        return true;
    }

    numPending++;
    context->OnClientRequest(request);
    return false;
}

void SDBPConnection::OnWrite()
{
    Log_Trace();

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Reset(&onKeepAlive);

    MessageConnection::OnWrite();
}

void SDBPConnection::OnClose()
{
    uint64_t    elapsed;

    if (onKeepAlive.GetDelay() > 0)
        EventLoop::Remove(&onKeepAlive);

    elapsed = NowClock() - connectTimestamp;

    Log_Message("[%s] Client disconnected (active: %u seconds, served: %u requests)",
     remoteEndpoint.ToString(), (unsigned)(elapsed / 1000.0 + 0.5), numCompleted);

    context->OnClientClose(this);
    MessageConnection::Close();

    if (numPending == 0)
    {
        Log_Debug("[%s] Connection deleted", remoteEndpoint.ToString());
        server->DeleteConn(this);
    }
}

void SDBPConnection::OnComplete(ClientRequest* request, bool last)
{
    SDBPResponseMessage sdbpResponse;

    if (last)
        numPending--;

//    if (request->response.type == CLIENTRESPONSE_OK)
//        Log_Debug("OK, commandID: %U", request->commandID);

    if (state == TCPConnection::CONNECTED &&
     request->response.type != CLIENTRESPONSE_NORESPONSE &&
     !(request->response.type == CLIENTRESPONSE_CONFIG_STATE &&
      TCPConnection::GetWriteBuffer().GetLength() > SDBP_MAX_QUEUED_BYTES))
    {
        sdbpResponse.response = &request->response;
        Write(sdbpResponse);
        // TODO: HACK
        if (TCPConnection::GetWriteBuffer().GetLength() >= MESSAGING_BUFFER_THRESHOLD || last ||
         request->type == CLIENTREQUEST_GET_CONFIG_STATE)
            Flush();
    }

    if (last)
    {
        REQUEST_CACHE->DeleteRequest(request);
        numCompleted++;
    }

    if (numPending == 0 && state == DISCONNECTED)
    {
        Log_Debug("[%s] Connection deleted", remoteEndpoint.ToString());
        server->DeleteConn(this);
    }
}

bool SDBPConnection::IsActive()
{
    if (state == DISCONNECTED)
        return false;

    return true;
}

void SDBPConnection::UseKeepAlive(bool useKeepAlive)
{
    if (useKeepAlive)
    {
        onKeepAlive.SetDelay(configFile.GetIntValue("sdbp.keepAliveTimeout", keepAliveTimeout));
        EventLoop::Reset(&onKeepAlive);
    }
    else
    {
        EventLoop::Remove(&onKeepAlive);
        onKeepAlive.SetDelay(0);
    }
}

void SDBPConnection::OnKeepAlive()
{
    Log_Debug("Keep alive timeout occured");
    OnClose();
}
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 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

#ifndef JUBATUS_CORE_COMMON_UNORDERED_MAP_HPP_
#define JUBATUS_CORE_COMMON_UNORDERED_MAP_HPP_

#include <msgpack.hpp>
#include <pficommon/data/unordered_map.h>

// to make pfi::data::unordered_map serializable

namespace msgpack {

template<typename K, typename V>
inline pfi::data::unordered_map<K, V> operator>>(
    object o,
    pfi::data::unordered_map<K, V>& v) {
  if (o.type != type::MAP) {
    throw type_error();
  }
  object_kv* const p_end = o.via.map.ptr + o.via.map.size;
  for (object_kv* p = o.via.map.ptr; p != p_end; ++p) {
    K key;
    p->key.convert(&key);
    p->val.convert(&v[key]);
  }
  return v;
}

template<typename Stream, typename K, typename V>
inline packer<Stream>& operator<<(
    packer<Stream>& o,
    const pfi::data::unordered_map<K, V>& v) {
  o.pack_map(v.size());
  for (typename std::tr1::unordered_map<K, V>::const_iterator it = v.begin();
      it != v.end(); ++it) {
    o.pack(it->first);
    o.pack(it->second);
  }
  return o;
}

}  // namespace msgpack

#endif  // JUBATUS_CORE_COMMON_UNORDERED_MAP_HPP_
<commit_msg>Fixed a bad typename.<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 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

#ifndef JUBATUS_CORE_COMMON_UNORDERED_MAP_HPP_
#define JUBATUS_CORE_COMMON_UNORDERED_MAP_HPP_

#include <msgpack.hpp>
#include <pficommon/data/unordered_map.h>

// to make pfi::data::unordered_map serializable

namespace msgpack {

template<typename K, typename V>
inline pfi::data::unordered_map<K, V> operator>>(
    object o,
    pfi::data::unordered_map<K, V>& v) {
  if (o.type != type::MAP) {
    throw type_error();
  }
  object_kv* const p_end = o.via.map.ptr + o.via.map.size;
  for (object_kv* p = o.via.map.ptr; p != p_end; ++p) {
    K key;
    p->key.convert(&key);
    p->val.convert(&v[key]);
  }
  return v;
}

template<typename Stream, typename K, typename V>
inline packer<Stream>& operator<<(
    packer<Stream>& o,
    const pfi::data::unordered_map<K, V>& v) {
  o.pack_map(v.size());
  for (typename pfi::data::unordered_map<K, V>::const_iterator it = v.begin();
      it != v.end(); ++it) {
    o.pack(it->first);
    o.pack(it->second);
  }
  return o;
}

}  // namespace msgpack

#endif  // JUBATUS_CORE_COMMON_UNORDERED_MAP_HPP_
<|endoftext|>


<commit_before>/*
    This file is part of KAddressbook.
    Copyright (c) 2003 Tobias Koenig <tokoe@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.

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

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

	As a special exception, permission is given to link this program
	with any edition of Qt, and distribute the resulting executable,
	without including the source code for Qt in the source distribution.
 */

#include <qfile.h>

#include <kfiledialog.h>
#include <kio/netaccess.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ktempfile.h>
#include <kurl.h>

#include <kdebug.h>

#include "importdialog.h"

#include "eudora_xxport.h"

#define CTRL_C 3

class EudoraXXPortFactory : public XXPortFactory
{
  public:
    XXPortObject *xxportObject( KABCore *core, QObject *parent, const char *name )
    {
      return new EudoraXXPort( core, parent, name );
    }
};

extern "C"
{
  void *init_libkaddrbk_eudora_xxport()
  {
    return ( new EudoraXXPortFactory() );
  }
}

  EudoraXXPort::EudoraXXPort( KABCore *core, QObject *parent, const char *name )
: XXPortObject( core, parent, name )
{
  createImportAction( i18n( "Import Eudora Addressbook .." ) );
  //createExportAction( i18n( "Export Eudora Addressbook .." ) );
}

bool EudoraXXPort::exportContacts( const KABC::AddresseeList &, const QString& )
{
  // ### implement me
  return false;
}

KABC::AddresseeList EudoraXXPort::importContacts( const QString& ) const
{

  QString file=KFileDialog::getOpenFileName(QDir::homeDirPath() ,"*.txt *.TXT",0);
  if (file.isEmpty())
    return KABC::AddresseeList();

  QFile f(file);
  if (!f.open(IO_ReadOnly))
    return KABC::AddresseeList();

  QString line;
  QTextStream stream(&f);
  KABC::Addressee *a = 0;
  int bytesRead = 0;

  KABC::AddresseeList list;

  while(!stream.eof()) {
    line = stream.readLine();
    bytesRead += line.length();
    QString tmp;

    if (line.startsWith("alias")) {
      if (a) { // Write it out
        list << *a;
        delete a;
        a = 0;
        a = new KABC::Addressee();
      } else a = new KABC::Addressee();
      tmp = key(line);
      if (!tmp.isEmpty()) a->setFormattedName(tmp);
      tmp = email(line);
      if (!tmp.isEmpty()) a->insertEmail(tmp);
    }
    else if (line.startsWith("note")) {
      if (!a) break; // Must have an alias before a note

      tmp = comment(line);
      if (!tmp.isEmpty()) a->setNote(tmp);

      tmp = get(line, "name");
      if (!tmp.isEmpty()) a->setFamilyName(tmp);

      tmp =  get(line, "address");
      if (!tmp.isEmpty()){
        KABC::Address addr;
        kdDebug() << tmp << endl; // dump complete address
        addr.setLabel(tmp);
        a->insertAddress(addr);
      }

      tmp = get(line,"phone");
      if (tmp.isEmpty())
         a->insertPhoneNumber( KABC::PhoneNumber( tmp, KABC::PhoneNumber::Voice ));
    }
  }

  if (a) { // Write out address
    list << *a;
    delete a;
    a = 0;
  }

  f.close();

  return list;
}

void EudoraXXPort::doExport( QFile *fp, const KABC::AddresseeList &list )
{
  QTextStream t( fp );

  KABC::AddresseeList::ConstIterator iter;
  KABC::Field::List fields = core()->addressBook()->fields();
  KABC::Field::List::Iterator fieldIter;
  bool first = true;

  // First output the column headings
  for ( fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) {
    if ( !first )
      t << ",";

    t << "\"" << (*fieldIter)->label() << "\"";
    first = false;
  }
  t << "\n";

  // Then all the addressee objects
  KABC::Addressee addr;
  for ( iter = list.begin(); iter != list.end(); ++iter ) {
    addr = *iter;
    first = true;

    for ( fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) {
      if ( !first )
        t << ",";

      t << "\"" << (*fieldIter)->value( addr ).replace( "\n", "\\n" ) << "\"";
      first = false;
    }

    t << "\n";
  }
}

QString EudoraXXPort::key(const QString& line) const
{
  int e;
  QString result;
  int b=line.find('\"',0);
  if (b==-1) {
    b=line.find(' ');
    if (b==-1) { return result; }
    b+=1;
    e=line.find(' ',b);
    result=line.mid(b,e-b);
    return result;
  }
  b+=1;
  e=line.find('\"',b);if (e==-1) { return result; }
  result=line.mid(b,e-b);
  return result;
}

QString EudoraXXPort::email(const QString& line) const
{
  int b;
  QString result;
  b=line.findRev('\"');if (b==-1) {
    b=line.findRev(' ');if(b==-1) { return result; }
  }
  result=line.mid(b+1);
  return result;
}

QString EudoraXXPort::comment(const QString& line) const
{
  int b;
  QString result;
  uint i;
  b=line.findRev('>');if (b==-1) {
    b=line.findRev('\"');if (b==-1) { return result; }
  }
  result=line.mid(b+1);
  for(i=0;i<result.length();i++) {
    if (result[i]==CTRL_C) { result[i]='\n'; }
  }
  return result;
}

QString EudoraXXPort::get(const QString& line,const QString& key) const
{
  QString fd="<"+key+":";
  int b,e;
  uint i;

  // Find formatted key, return on error
  b=line.find(fd);
  if (b==-1) { return QString::null; }

  b+=fd.length();
  e=line.find('>',b);
  if (e==-1) { return QString::null; }

  e--;
  QString result=line.mid(b,e-b+1);
  for(i=0;i<result.length();i++) {
    if (result[i]==CTRL_C) { result[i]='\n'; }
  }
  return result;
}

#include "eudora_xxport.moc"

// vim: ts=2 sw=2 et
<commit_msg>better<commit_after>/*
    This file is part of KAddressbook.
    Copyright (c) 2003 Tobias Koenig <tokoe@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.

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

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

	As a special exception, permission is given to link this program
	with any edition of Qt, and distribute the resulting executable,
	without including the source code for Qt in the source distribution.
 */

#include <qfile.h>

#include <kfiledialog.h>
#include <kio/netaccess.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ktempfile.h>
#include <kurl.h>

#include <kdebug.h>

#include "importdialog.h"

#include "eudora_xxport.h"

#define CTRL_C 3

class EudoraXXPortFactory : public XXPortFactory
{
  public:
    XXPortObject *xxportObject( KABCore *core, QObject *parent, const char *name )
    {
      return new EudoraXXPort( core, parent, name );
    }
};

extern "C"
{
  void *init_libkaddrbk_eudora_xxport()
  {
    return ( new EudoraXXPortFactory() );
  }
}

  EudoraXXPort::EudoraXXPort( KABCore *core, QObject *parent, const char *name )
: XXPortObject( core, parent, name )
{
  createImportAction( i18n( "Import Eudora Addressbook .." ) );
  //createExportAction( i18n( "Export Eudora Addressbook .." ) );
}

bool EudoraXXPort::exportContacts( const KABC::AddresseeList &, const QString& )
{
  // ### implement me
  return false;
}

KABC::AddresseeList EudoraXXPort::importContacts( const QString& ) const
{

  QString file=KFileDialog::getOpenFileName(QDir::homeDirPath() ,"*.txt *.TXT",0);
  if (file.isEmpty())
    return KABC::AddresseeList();

  QFile f(file);
  if (!f.open(IO_ReadOnly))
    return KABC::AddresseeList();

  QString line;
  QTextStream stream(&f);
  KABC::Addressee *a = 0;
  int bytesRead = 0;

  KABC::AddresseeList list;

  while(!stream.eof()) {
    line = stream.readLine();
    bytesRead += line.length();
    QString tmp;

    if (line.startsWith("alias")) {
      if (a) { // Write it out
        list << *a;
        delete a;
        a = 0;
        a = new KABC::Addressee();
      } else a = new KABC::Addressee();
      tmp = key(line).stripWhiteSpace();
      if (!tmp.isEmpty()) a->setFormattedName(tmp);
      tmp = email(line).stripWhiteSpace();
      if (!tmp.isEmpty()) a->insertEmail(tmp);
    }
    else if (line.startsWith("note")) {
      if (!a) break; // Must have an alias before a note

      tmp = comment(line).stripWhiteSpace();
      if (!tmp.isEmpty()) a->setNote(tmp);

      tmp = get(line, "name").stripWhiteSpace();
      if (!tmp.isEmpty()) a->setFamilyName(tmp);

      tmp =  get(line, "address").stripWhiteSpace();
      if (!tmp.isEmpty()){
        KABC::Address addr;
        kdDebug() << tmp << endl; // dump complete address
        addr.setLabel(tmp);
        a->insertAddress(addr);
      }

      tmp = get(line,"phone").stripWhiteSpace();
      if (tmp.isEmpty())
         a->insertPhoneNumber( KABC::PhoneNumber( tmp, KABC::PhoneNumber::Voice ));
    }
  }

  if (a) { // Write out address
    list << *a;
    delete a;
    a = 0;
  }

  f.close();

  return list;
}

void EudoraXXPort::doExport( QFile *fp, const KABC::AddresseeList &list )
{
  QTextStream t( fp );

  KABC::AddresseeList::ConstIterator iter;
  KABC::Field::List fields = core()->addressBook()->fields();
  KABC::Field::List::Iterator fieldIter;
  bool first = true;

  // First output the column headings
  for ( fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) {
    if ( !first )
      t << ",";

    t << "\"" << (*fieldIter)->label() << "\"";
    first = false;
  }
  t << "\n";

  // Then all the addressee objects
  KABC::Addressee addr;
  for ( iter = list.begin(); iter != list.end(); ++iter ) {
    addr = *iter;
    first = true;

    for ( fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) {
      if ( !first )
        t << ",";

      t << "\"" << (*fieldIter)->value( addr ).replace( "\n", "\\n" ) << "\"";
      first = false;
    }

    t << "\n";
  }
}

QString EudoraXXPort::key(const QString& line) const
{
  int e;
  QString result;
  int b=line.find('\"',0);
  if (b==-1) {
    b=line.find(' ');
    if (b==-1) { return result; }
    b+=1;
    e=line.find(' ',b);
    result=line.mid(b,e-b);
    return result;
  }
  b+=1;
  e=line.find('\"',b);if (e==-1) { return result; }
  result=line.mid(b,e-b);
  return result;
}

QString EudoraXXPort::email(const QString& line) const
{
  int b;
  QString result;
  b=line.findRev('\"');if (b==-1) {
    b=line.findRev(' ');if(b==-1) { return result; }
  }
  result=line.mid(b+1);
  return result;
}

QString EudoraXXPort::comment(const QString& line) const
{
  int b;
  QString result;
  uint i;
  b=line.findRev('>');if (b==-1) {
    b=line.findRev('\"');if (b==-1) { return result; }
  }
  result=line.mid(b+1);
  for(i=0;i<result.length();i++) {
    if (result[i]==CTRL_C) { result[i]='\n'; }
  }
  return result;
}

QString EudoraXXPort::get(const QString& line,const QString& key) const
{
  QString fd="<"+key+":";
  int b,e;
  uint i;

  // Find formatted key, return on error
  b=line.find(fd);
  if (b==-1) { return QString::null; }

  b+=fd.length();
  e=line.find('>',b);
  if (e==-1) { return QString::null; }

  e--;
  QString result=line.mid(b,e-b+1);
  for(i=0;i<result.length();i++) {
    if (result[i]==CTRL_C) { result[i]='\n'; }
  }
  return result;
}

#include "eudora_xxport.moc"

// vim: ts=2 sw=2 et
<|endoftext|>


<commit_before>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "date_time_parser.h"

namespace You {
namespace NLP {

using ptime = boost::posix_time::ptime;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;

ptime DateTimeParser::parse(const StringType& string) {
	ptime result;
	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool DateTimeParser::parse(const StringType& string, ptime& result) {
	return qi::parse(
		begin(string),
		end(string),
		DateTimeParser(),
		result);
}

DateTimeParser::DateTimeParser() : DateTimeParser::base_type(start) {
	start %= (
		date[qi::_val = phoenix::construct<DateTime>(
			qi::_1,
			boost::posix_time::hours(0))
		]
	) >> qi::eoi;
	BOOST_SPIRIT_DEBUG_NODE(start);

	#pragma region Primitive date component parsers
	year = (
		+ParserCharTraits::digit
	)[qi::_val = phoenix::bind(&DateTimeParser::parseFuzzyYear, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(year);

	monthNames.add
		(L"jan", boost::gregorian::Jan)
		(L"feb", boost::gregorian::Feb)
		(L"mar", boost::gregorian::Mar)
		(L"apr", boost::gregorian::Apr)
		(L"may", boost::gregorian::May)
		(L"jun", boost::gregorian::Jun)
		(L"jul", boost::gregorian::Jul)
		(L"aug", boost::gregorian::Aug)
		(L"sep", boost::gregorian::Sep)
		(L"oct", boost::gregorian::Oct)
		(L"nov", boost::gregorian::Nov)
		(L"dec", boost::gregorian::Dec);
	monthNames.name("monthNames");

	month %= (
		qi::int_ |
		ParserCharTraits::no_case[monthNames]
	);
	month.name("month");

	weekDays.add
		(L"mon", boost::gregorian::Monday)
		(L"monday", boost::gregorian::Monday)
		(L"tue", boost::gregorian::Tuesday)
		(L"tuesday", boost::gregorian::Tuesday)
		(L"wed", boost::gregorian::Wednesday)
		(L"wednesday", boost::gregorian::Wednesday)
		(L"thu", boost::gregorian::Thursday)
		(L"thursday", boost::gregorian::Thursday)
		(L"fri", boost::gregorian::Friday)
		(L"friday", boost::gregorian::Friday)
		(L"sat", boost::gregorian::Saturday)
		(L"saturday", boost::gregorian::Saturday)
		(L"sun", boost::gregorian::Sunday)
		(L"sunday", boost::gregorian::Sunday);
	weekDays.name("weekDays");

	day %= (
		qi::int_
	);
	BOOST_SPIRIT_DEBUG_NODE(day);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	#pragma region Supported Date Formats
	dateYearMonthDay = (
		year >> (space | '-') >> month >> (space | '-') >> day
	)[qi::_val = phoenix::construct<Date>(qi::_1, qi::_2, qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(dateYearMonthDay);

	dateYearMonth = (
		year >> '-' >> month
	)[qi::_val = phoenix::construct<Date>(qi::_1, qi::_2, 1)];
	BOOST_SPIRIT_DEBUG_NODE(dateYearMonth);

	dateYear = (
		year
	)[qi::_val = phoenix::construct<Date>(qi::_1, boost::gregorian::Jan, 1)];
	BOOST_SPIRIT_DEBUG_NODE(dateYear);

	dateMonthYear = (
		month >> space  >> year
	)[qi::_val = phoenix::construct<Date>(qi::_2, qi::_1, 1)];
	BOOST_SPIRIT_DEBUG_NODE(dateMonthYear);

	dateDayMonth = (
		day >> space >> month
	)[qi::_val = phoenix::bind(&constructDayMonthDate, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(dateDayMonth);

	date %= (
		relativeDate |
		dateYearMonthDay |
		dateYearMonth |
		dateMonthYear |
		dateDayMonth |
		dateYear
	);
	BOOST_SPIRIT_DEBUG_NODE(date);
	#pragma endregion

	relativeDate %= (
		ParserCharTraits::no_case[(
			qi::lit(L"next") |
			qi::lit(L"coming"))] >> space >>
		relativeDateInDirection(1) |

		ParserCharTraits::no_case[(
			qi::lit(L"this"))] >> space >>
		relativeDateInDirection(0) |

		ParserCharTraits::no_case[(
			qi::lit(L"last") |
			qi::lit(L"previous"))] >> space >>
		relativeDateInDirection(-1) |

		relativeDateInDays
	);
	relativeDate.name("relativeDate");

	relativeDateInDirection = ParserCharTraits::no_case[(
		(
			monthNames
			[qi::_val = phoenix::bind(&
				constructRelativeMonthDate, qi::_r1, qi::_1)] |

			weekDays
			[qi::_val = phoenix::bind(&
				constructRelativeWeekDayDate, qi::_r1, qi::_1)]
		)
	)];
	relativeDateInDirection.name("relativeDateInDirection");

	relativeDateInDays = (
		ParserCharTraits::no_case[qi::lit(L"tomorrow")][
			qi::_val = phoenix::bind(&constructRelativeDate, 1)
		] |

		ParserCharTraits::no_case[qi::lit(L"yesterday")][
			qi::_val = phoenix::bind(&constructRelativeDate, -1)
		] |

		((qi::int_ >> space >> ParserCharTraits::no_case[qi::lit("days")])[
			qi::_val = phoenix::bind(&constructRelativeDate, qi::_1)
		]) |

		((qi::int_ >> space >> ParserCharTraits::no_case[qi::lit("weeks")])[
			qi::_val = phoenix::bind(&constructRelativeDate,
				qi::_1 * 7)
		])
	);
	relativeDateInDays.name("relativeDateInDays");
	#pragma endregion

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void DateTimeParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const boost::spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<commit_msg>Our date parser might not parse a complete string.<commit_after>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "date_time_parser.h"

namespace You {
namespace NLP {

using ptime = boost::posix_time::ptime;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;

ptime DateTimeParser::parse(const StringType& string) {
	ptime result;
	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool DateTimeParser::parse(const StringType& string, ptime& result) {
	return qi::parse(
		begin(string),
		end(string),
		DateTimeParser(),
		result);
}

DateTimeParser::DateTimeParser() : DateTimeParser::base_type(start) {
	start %= (
		date[qi::_val = phoenix::construct<DateTime>(
			qi::_1,
			boost::posix_time::hours(0))
		]
	);
	BOOST_SPIRIT_DEBUG_NODE(start);

	#pragma region Primitive date component parsers
	year = (
		+ParserCharTraits::digit
	)[qi::_val = phoenix::bind(&DateTimeParser::parseFuzzyYear, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(year);

	monthNames.add
		(L"jan", boost::gregorian::Jan)
		(L"feb", boost::gregorian::Feb)
		(L"mar", boost::gregorian::Mar)
		(L"apr", boost::gregorian::Apr)
		(L"may", boost::gregorian::May)
		(L"jun", boost::gregorian::Jun)
		(L"jul", boost::gregorian::Jul)
		(L"aug", boost::gregorian::Aug)
		(L"sep", boost::gregorian::Sep)
		(L"oct", boost::gregorian::Oct)
		(L"nov", boost::gregorian::Nov)
		(L"dec", boost::gregorian::Dec);
	monthNames.name("monthNames");

	month %= (
		qi::int_ |
		ParserCharTraits::no_case[monthNames]
	);
	month.name("month");

	weekDays.add
		(L"mon", boost::gregorian::Monday)
		(L"monday", boost::gregorian::Monday)
		(L"tue", boost::gregorian::Tuesday)
		(L"tuesday", boost::gregorian::Tuesday)
		(L"wed", boost::gregorian::Wednesday)
		(L"wednesday", boost::gregorian::Wednesday)
		(L"thu", boost::gregorian::Thursday)
		(L"thursday", boost::gregorian::Thursday)
		(L"fri", boost::gregorian::Friday)
		(L"friday", boost::gregorian::Friday)
		(L"sat", boost::gregorian::Saturday)
		(L"saturday", boost::gregorian::Saturday)
		(L"sun", boost::gregorian::Sunday)
		(L"sunday", boost::gregorian::Sunday);
	weekDays.name("weekDays");

	day %= (
		qi::int_
	);
	BOOST_SPIRIT_DEBUG_NODE(day);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	#pragma region Supported Date Formats
	dateYearMonthDay = (
		year >> (space | '-') >> month >> (space | '-') >> day
	)[qi::_val = phoenix::construct<Date>(qi::_1, qi::_2, qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(dateYearMonthDay);

	dateYearMonth = (
		year >> '-' >> month
	)[qi::_val = phoenix::construct<Date>(qi::_1, qi::_2, 1)];
	BOOST_SPIRIT_DEBUG_NODE(dateYearMonth);

	dateYear = (
		year
	)[qi::_val = phoenix::construct<Date>(qi::_1, boost::gregorian::Jan, 1)];
	BOOST_SPIRIT_DEBUG_NODE(dateYear);

	dateMonthYear = (
		month >> space  >> year
	)[qi::_val = phoenix::construct<Date>(qi::_2, qi::_1, 1)];
	BOOST_SPIRIT_DEBUG_NODE(dateMonthYear);

	dateDayMonth = (
		day >> space >> month
	)[qi::_val = phoenix::bind(&constructDayMonthDate, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(dateDayMonth);

	date %= (
		relativeDate |
		dateYearMonthDay |
		dateYearMonth |
		dateMonthYear |
		dateDayMonth |
		dateYear
	);
	BOOST_SPIRIT_DEBUG_NODE(date);
	#pragma endregion

	relativeDate %= (
		ParserCharTraits::no_case[(
			qi::lit(L"next") |
			qi::lit(L"coming"))] >> space >>
		relativeDateInDirection(1) |

		ParserCharTraits::no_case[(
			qi::lit(L"this"))] >> space >>
		relativeDateInDirection(0) |

		ParserCharTraits::no_case[(
			qi::lit(L"last") |
			qi::lit(L"previous"))] >> space >>
		relativeDateInDirection(-1) |

		relativeDateInDays
	);
	relativeDate.name("relativeDate");

	relativeDateInDirection = ParserCharTraits::no_case[(
		(
			monthNames
			[qi::_val = phoenix::bind(&
				constructRelativeMonthDate, qi::_r1, qi::_1)] |

			weekDays
			[qi::_val = phoenix::bind(&
				constructRelativeWeekDayDate, qi::_r1, qi::_1)]
		)
	)];
	relativeDateInDirection.name("relativeDateInDirection");

	relativeDateInDays = (
		ParserCharTraits::no_case[qi::lit(L"tomorrow")][
			qi::_val = phoenix::bind(&constructRelativeDate, 1)
		] |

		ParserCharTraits::no_case[qi::lit(L"yesterday")][
			qi::_val = phoenix::bind(&constructRelativeDate, -1)
		] |

		((qi::int_ >> space >> ParserCharTraits::no_case[qi::lit("days")])[
			qi::_val = phoenix::bind(&constructRelativeDate, qi::_1)
		]) |

		((qi::int_ >> space >> ParserCharTraits::no_case[qi::lit("weeks")])[
			qi::_val = phoenix::bind(&constructRelativeDate,
				qi::_1 * 7)
		])
	);
	relativeDateInDays.name("relativeDateInDays");
	#pragma endregion

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void DateTimeParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const boost::spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<|endoftext|>


<commit_before>/*******************************
Copyright (c) 2016-2021 Grégoire Angerand

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 "utils.h"

#include <y/utils/log.h>
#include <y/utils/format.h>
#include <y/core/String.h>

#include <y/concurrent/concurrent.h>

#ifdef Y_OS_WIN
#include <windows.h>
#endif

#ifdef Y_GCC
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
#endif

namespace y {

#ifdef Y_DEBUG
namespace core::result {
bool break_on_error = false;
}
#endif

void break_in_debugger() {
#ifdef Y_OS_WIN
    if(IsDebuggerPresent()) {
        DebugBreak();
    }
#endif
}

void fatal(const char* msg, const char* file, int line) {
    core::String msg_str(msg);
    if(file) {
        fmt_into(msg_str, " in file \"%\"", file);
    }
    if(line) {
        fmt_into(msg_str, " at line %", line);
    }

    if(const char* thread_name = concurrent::thread_name()) {
        fmt_into(msg_str, " on thread \"%\"", thread_name);
    }

    log_msg(msg_str, Log::Error);
    y_breakpoint;
    std::abort();
}

}

<commit_msg>Fixed potential stack overflow in fatal<commit_after>/*******************************
Copyright (c) 2016-2021 Grégoire Angerand

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 "utils.h"

#include <y/utils/log.h>
#include <y/concurrent/concurrent.h>

#include <array>

#ifdef Y_OS_WIN
#include <windows.h>
#endif

#ifdef Y_GCC
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
#endif

namespace y {

#ifdef Y_DEBUG
namespace core::result {
bool break_on_error = false;
}
#endif

void break_in_debugger() {
#ifdef Y_OS_WIN
    if(IsDebuggerPresent()) {
        DebugBreak();
    }
#endif
}

void fatal(const char* msg, const char* file, int line) {
    // Don't use fmt since it can assert
    std::array<char, 1024> buffer = {};
    std::snprintf(buffer.data(), buffer.size(), "%s", msg);

    if(file) {
        const auto tmp_buffer = buffer;
        std::snprintf(buffer.data(), buffer.size(), "%s in file \"%s\"", tmp_buffer.data(), file);
    }
    if(line) {
        const auto tmp_buffer = buffer;
        std::snprintf(buffer.data(), buffer.size(), "%s at line %i", tmp_buffer.data(), line);
    }

    if(const char* thread_name = concurrent::thread_name()) {
        const auto tmp_buffer = buffer;
        std::snprintf(buffer.data(), buffer.size(), "%s on thread \"%s\"", tmp_buffer.data(), thread_name);
    }

    log_msg(buffer.data(), Log::Error);
    y_breakpoint;
    std::abort();
}

}

<|endoftext|>


<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    utils/archivedefinition.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2009 Klarälvdalens Datakonsult AB

    Kleopatra 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.

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

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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "archivedefinition.h"

#include <utils/exception.h>
#include <utils/input.h>
#include <utils/path-helper.h>

#include <KConfigGroup>
#include <KLocalizedString>
#include <KGlobal>
#include <KConfig>

#include <QProcess>
#include <QString>
#include <QStringList>
#include <QDir>
#include <QDebug>

#include <boost/shared_ptr.hpp>

using namespace Kleo;
using namespace boost;

static const QLatin1String ID_ENTRY( "id" );
static const QLatin1String NAME_ENTRY( "name" );
static const QLatin1String COMMAND_ENTRY( "pack-command" );
static const QLatin1String EXTENSIONS_ENTRY( "extensions" );
static const QLatin1String FILE_PLACEHOLDER( "%f" );

namespace {

    class ArchiveDefinitionError : Kleo::Exception {
        const QString m_id;
    public:
        ArchiveDefinitionError( const QString & id, const QString & message )
            : Kleo::Exception( GPG_ERR_INV_PARAMETER, i18n("Error in archive definition %1: %2").arg( id, message ) ),
              m_id( id )
        {

        }
        ~ArchiveDefinitionError() throw() {}

        const QString & archiveDefinitionId() const { return m_id; }
    };

    class KConfigBasedArchiveDefinition : public ArchiveDefinition {
    public:
        explicit KConfigBasedArchiveDefinition( const KConfigGroup & group )
            : ArchiveDefinition( group.readEntryUntranslated( ID_ENTRY ),
                                 group.readEntry( NAME_ENTRY ),
                                 group.readEntry( EXTENSIONS_ENTRY, QStringList() ) )
        {
            if ( extensions().empty() )
                throw ArchiveDefinitionError( id(), i18n("'extensions' entry is empty/missing") );
            const QStringList l = group.readEntry( COMMAND_ENTRY ).split( QLatin1Char(' '), QString::SkipEmptyParts );
            qDebug() << "ArchiveDefinition[" << id() << ']' << l;
            if ( l.empty() )
                throw ArchiveDefinitionError( id(), i18n("'command' entry is empty/missing") );
            m_command = l.front();
            const int idx = l.indexOf( FILE_PLACEHOLDER );
            if ( idx < 0 ) {
                // none -> append
                m_prefixArguments = l.mid( 1 );
            } else {
                m_prefixArguments = l.mid( 1, idx-1 );
                m_postfixArguments = l.mid( idx+1 );
            }
            qDebug() << "ArchiveDefinition[" << id() << ']' << m_command << m_prefixArguments << FILE_PLACEHOLDER << m_postfixArguments;
        }

    private:
        /* reimp */ QString doGetCommand() const { return m_command; }
        /* reimp */ QStringList doGetArguments( const QStringList & files ) const {
            return m_prefixArguments + files + m_postfixArguments;
        }

    private:
        QString m_command;
        QStringList m_prefixArguments, m_postfixArguments;
    };

}

ArchiveDefinition::ArchiveDefinition( const QString & id, const QString & label, const QStringList & extensions )
    : m_id( id ), m_label( label ), m_extensions( extensions )
{

}

ArchiveDefinition::~ArchiveDefinition() {}

shared_ptr<Input> ArchiveDefinition::createInput( const QStringList & files ) const {
    const QString base = heuristicBaseDirectory( files );
    if ( base.isEmpty() )
        throw Kleo::Exception( GPG_ERR_CONFLICT, i18n("Cannot find common base directory for these files:\n%1", files.join( "\n" ) ) );
    qDebug() << "heuristicBaseDirectory(" << files << ") ->" << base;
    const QStringList relative = makeRelativeTo( base, files );
    qDebug() << "relative" << relative;
    return Input::createFromProcessStdOut( doGetCommand(),
                                           doGetArguments( relative ),
                                           QDir( base ) );
}

// static
std::vector< shared_ptr<ArchiveDefinition> > ArchiveDefinition::getArchiveDefinitions() {
    std::vector< shared_ptr<ArchiveDefinition> > result;
    if ( const KSharedConfigPtr config = KGlobal::config() ) {
        const QStringList groups = config->groupList().filter( QRegExp(QLatin1String("^Archive Definition #")) );
        result.reserve( groups.size() );
        Q_FOREACH( const QString & group, groups )
            try {
                const shared_ptr<ArchiveDefinition> ad( new KConfigBasedArchiveDefinition( KConfigGroup( config, group ) ) );
                result.push_back( ad );
            } catch ( const std::exception & e ) {
                qDebug() << e.what();
            }
    }
    return result;
}
<commit_msg>ArchiveDefiniton: read config from libkleopatrarc, not kleopatrarc<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    utils/archivedefinition.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2009 Klarälvdalens Datakonsult AB

    Kleopatra 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.

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

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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "archivedefinition.h"

#include <utils/exception.h>
#include <utils/input.h>
#include <utils/path-helper.h>

#include <kleo/cryptobackendfactory.h>

#include <KConfigGroup>
#include <KLocalizedString>
#include <KGlobal>
#include <KConfig>

#include <QProcess>
#include <QString>
#include <QStringList>
#include <QDir>
#include <QDebug>

#include <boost/shared_ptr.hpp>

using namespace Kleo;
using namespace boost;

static const QLatin1String ID_ENTRY( "id" );
static const QLatin1String NAME_ENTRY( "name" );
static const QLatin1String COMMAND_ENTRY( "pack-command" );
static const QLatin1String EXTENSIONS_ENTRY( "extensions" );
static const QLatin1String FILE_PLACEHOLDER( "%f" );

namespace {

    class ArchiveDefinitionError : Kleo::Exception {
        const QString m_id;
    public:
        ArchiveDefinitionError( const QString & id, const QString & message )
            : Kleo::Exception( GPG_ERR_INV_PARAMETER, i18n("Error in archive definition %1: %2").arg( id, message ) ),
              m_id( id )
        {

        }
        ~ArchiveDefinitionError() throw() {}

        const QString & archiveDefinitionId() const { return m_id; }
    };

    class KConfigBasedArchiveDefinition : public ArchiveDefinition {
    public:
        explicit KConfigBasedArchiveDefinition( const KConfigGroup & group )
            : ArchiveDefinition( group.readEntryUntranslated( ID_ENTRY ),
                                 group.readEntry( NAME_ENTRY ),
                                 group.readEntry( EXTENSIONS_ENTRY, QStringList() ) )
        {
            if ( extensions().empty() )
                throw ArchiveDefinitionError( id(), i18n("'extensions' entry is empty/missing") );
            const QStringList l = group.readEntry( COMMAND_ENTRY ).split( QLatin1Char(' '), QString::SkipEmptyParts );
            qDebug() << "ArchiveDefinition[" << id() << ']' << l;
            if ( l.empty() )
                throw ArchiveDefinitionError( id(), i18n("'command' entry is empty/missing") );
            m_command = l.front();
            const int idx = l.indexOf( FILE_PLACEHOLDER );
            if ( idx < 0 ) {
                // none -> append
                m_prefixArguments = l.mid( 1 );
            } else {
                m_prefixArguments = l.mid( 1, idx-1 );
                m_postfixArguments = l.mid( idx+1 );
            }
            qDebug() << "ArchiveDefinition[" << id() << ']' << m_command << m_prefixArguments << FILE_PLACEHOLDER << m_postfixArguments;
        }

    private:
        /* reimp */ QString doGetCommand() const { return m_command; }
        /* reimp */ QStringList doGetArguments( const QStringList & files ) const {
            return m_prefixArguments + files + m_postfixArguments;
        }

    private:
        QString m_command;
        QStringList m_prefixArguments, m_postfixArguments;
    };

}

ArchiveDefinition::ArchiveDefinition( const QString & id, const QString & label, const QStringList & extensions )
    : m_id( id ), m_label( label ), m_extensions( extensions )
{

}

ArchiveDefinition::~ArchiveDefinition() {}

shared_ptr<Input> ArchiveDefinition::createInput( const QStringList & files ) const {
    const QString base = heuristicBaseDirectory( files );
    if ( base.isEmpty() )
        throw Kleo::Exception( GPG_ERR_CONFLICT, i18n("Cannot find common base directory for these files:\n%1", files.join( "\n" ) ) );
    qDebug() << "heuristicBaseDirectory(" << files << ") ->" << base;
    const QStringList relative = makeRelativeTo( base, files );
    qDebug() << "relative" << relative;
    return Input::createFromProcessStdOut( doGetCommand(),
                                           doGetArguments( relative ),
                                           QDir( base ) );
}

// static
std::vector< shared_ptr<ArchiveDefinition> > ArchiveDefinition::getArchiveDefinitions() {
    std::vector< shared_ptr<ArchiveDefinition> > result;
    if ( KConfig * config = CryptoBackendFactory::instance()->configObject() ) {
        const QStringList groups = config->groupList().filter( QRegExp(QLatin1String("^Archive Definition #")) );
        result.reserve( groups.size() );
        Q_FOREACH( const QString & group, groups )
            try {
                const shared_ptr<ArchiveDefinition> ad( new KConfigBasedArchiveDefinition( KConfigGroup( config, group ) ) );
                result.push_back( ad );
            } catch ( const std::exception & e ) {
                qDebug() << e.what();
            }
    }
    return result;
}
<|endoftext|>