/*************************************************************************** * Copyright (C) 2013 by Volker Krause * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library 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 Library 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. * ***************************************************************************/ #include "session.h" #include #include #include #include #include #include #include #include #include #include #include Session::Session( const QString &input, QObject *parent ) : QObject( parent ) , m_input( 0 ) , m_session( 0 ) , m_notifier( 0 ) , m_receivedBytes( 0 ) , m_sentBytes( 0 ) { QFile *file = new QFile( this ); if ( input != QLatin1String( "-" ) ) { file->setFileName( input ); if ( !file->open( QFile::ReadOnly ) ) { akFatal() << "Failed to open" << input; } } else { // ### does that work on Windows? const int flags = fcntl( 0, F_GETFL ); fcntl( 0, F_SETFL, flags | O_NONBLOCK ); if ( !file->open( stdin, QFile::ReadOnly|QFile::Unbuffered ) ) { akFatal() << "Failed to open stdin!"; } m_notifier = new QSocketNotifier( 0, QSocketNotifier::Read, this ); connect( m_notifier, SIGNAL(activated(int)), SLOT(inputAvailable()) ); } m_input = file; } Session::~Session() { } void Session::connectToHost() { const QSettings connectionSettings( AkStandardDirs::connectionConfigFile(), QSettings::IniFormat ); QString serverAddress; #ifdef Q_OS_WIN serverAddress = connectionSettings.value( QLatin1String( "Data/NamedPipe" ), QString() ).toString(); #else serverAddress = connectionSettings.value( QLatin1String( "Data/UnixPath" ), QString() ).toString(); #endif if ( serverAddress.isEmpty() ) { akFatal() << "Unable to determine server address."; } QLocalSocket *socket = new QLocalSocket( this ); connect( socket, SIGNAL(error(QLocalSocket::LocalSocketError)), SLOT(serverError(QLocalSocket::LocalSocketError)) ); connect( socket, SIGNAL(disconnected()), SLOT(serverDisconnected()) ); connect( socket, SIGNAL(readyRead()), SLOT(serverRead()) ); connect( socket, SIGNAL(connected()), SLOT(inputAvailable()) ); m_session = socket; socket->connectToServer( serverAddress ); m_connectionTime.start(); } void Session::inputAvailable() { if ( !m_session->isOpen() ) { return; } if ( m_notifier ) { m_notifier->setEnabled( false ); } if ( m_input->atEnd() ) { return; } QByteArray buffer( 1024, Qt::Uninitialized ); qint64 readSize = 0; while ( ( readSize = m_input->read( buffer.data(), buffer.size() ) ) > 0 ) { m_session->write( buffer.constData(), readSize ); m_sentBytes += readSize; } if ( m_notifier ) { m_notifier->setEnabled( true ); } } void Session::serverDisconnected() { QCoreApplication::exit( 0 ); } void Session::serverError( QLocalSocket::LocalSocketError socketError ) { if ( socketError == QLocalSocket::PeerClosedError ) { QCoreApplication::exit( 0 ); return; } std::cerr << qPrintable( m_session->errorString() ); QCoreApplication::exit( 1 ); } void Session::serverRead() { QByteArray buffer( 1024, Qt::Uninitialized ); qint64 readSize = 0; while ( ( readSize = m_session->read( buffer.data(), buffer.size() ) ) > 0 ) { write( 1, buffer.data(), readSize ); m_receivedBytes += readSize; } } void Session::printStats() const { std::cerr << "Connection time: " << m_connectionTime.elapsed() << " ms" << std::endl; std::cerr << "Sent: " << m_sentBytes << " bytes" << std::endl; std::cerr << "Received: " << m_receivedBytes << " bytes" << std::endl; }