| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# connection.cpp

    00001 /* This file is part of the KDE libraries
    00002     Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
    00003                        David Faure <faure@kde.org>
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public License
    00016     along with this library; see the file COPYING.LIB.  If not, write to
    00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00018     Boston, MA 02111-1307, USA.
    00019 */
    00020
    00021 // $Id: connection.cpp,v 1.47.2.1 2003/02/12 00:43:57 pfeiffer Exp $
    00022
    00023 #include <config.h>
    00024
    00025 #include <ksock.h>
    00026 #include <qtimer.h>
    00027
    00028 #include <sys/types.h>
    00029 #include <sys/signal.h>
    00030 #include <sys/time.h>
    00031
    00032 #include <errno.h>
    00033 #include <fcntl.h>
    00034 #include <stdio.h>
    00035 #include <stdlib.h>
    00036 #include <signal.h>
    00037 #include <string.h>
    00038 #include <unistd.h>
    00039
    00040 #include "kio/connection.h"
    00041
    00042 #include <kdebug.h>
    00043 #include <qsocketnotifier.h>
    00044
    00045 using namespace KIO;
    00046
    00047 Connection::Connection()
    00048 {
    00049     f_out = 0;
    00050     fd_in = -1;
    00051     socket = 0;
    00052     notifier = 0;
    00053     receiver = 0;
    00054     member = 0;
    00055     m_suspended = false;
    00056     tasks.setAutoDelete(true);
    00057 }
    00058
    00059 Connection::~Connection()
    00060 {
    00061     close();
    00062 }
    00063
    00064 void Connection::suspend()
    00065 {
    00066     m_suspended = true;
    00067     if (notifier)
    00068        notifier->setEnabled(false);
    00069 }
    00070
    00071 void Connection::resume()
    00072 {
    00073     m_suspended = false;
    00074     if (notifier)
    00075        notifier->setEnabled(true);
    00076 }
    00077
    00078 void Connection::close()
    00079 {
    00080     delete notifier;
    00081     notifier = 0;
    00082     delete socket;
    00083     socket = 0;
    00084 //    if (f_out) // causes double close, as KSocket already closed it for us
    00085 //       fclose(f_out);
    00086     f_out = 0;
    00087     fd_in = -1;
    00088     tasks.clear();
    00089 }
    00090
    00091 void Connection::send(int cmd, const QByteArray& data)
    00092 {
    00093     if (!inited() || tasks.count() > 0) {
    00094         Task *task = new Task();
    00095         task->cmd = cmd;
    00096         task->data = data;
    00097         tasks.append(task);
    00098     } else {
    00099         sendnow( cmd, data );
    00100     }
    00101 }
    00102
    00103 void Connection::dequeue()
    00104 {
    00105     if (!inited())
    00106         return;
    00107
    00108     while (tasks.count())
    00109     {
    00110        tasks.first();
    00111        Task *task = tasks.take();
    00112        sendnow( task->cmd, task->data );
    00113        delete task;
    00114     }
    00115 }
    00116
    00117 void Connection::init(KSocket *sock)
    00118 {
    00119     delete notifier;
    00120     notifier = 0;
    00121     delete socket;
    00122     socket = sock;
    00123     fd_in = socket->socket();
    00124     f_out = fdopen( socket->socket(), "wb" );
    00125     if (receiver && ( fd_in != -1 )) {
    00126         notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
    00127         if ( m_suspended ) {
    00128             suspend();
    00129         }
    00130         QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
    00131     }
    00132     dequeue();
    00133 }
    00134
    00135 void Connection::init(int _fd_in, int fd_out)
    00136 {
    00137     delete notifier;
    00138     notifier = 0;
    00139     fd_in = _fd_in;
    00140     f_out = fdopen( fd_out, "wb" );
    00141     if (receiver && ( fd_in != -1 )) {
    00142         notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
    00143         if ( m_suspended ) {
    00144             suspend();
    00145         }
    00146         QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
    00147     }
    00148     dequeue();
    00149 }
    00150
    00151
    00152 void Connection::connect(QObject *_receiver, const char *_member)
    00153 {
    00154     receiver = _receiver;
    00155     member = _member;
    00156     delete notifier;
    00157     notifier = 0;
    00158     if (receiver && (fd_in != -1 )) {
    00159         notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
    00160         if ( m_suspended )
    00161             suspend();
    00162         QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
    00163     }
    00164 }
    00165
    00166 bool Connection::sendnow( int _cmd, const QByteArray &data )
    00167 {
    00168     if (f_out == 0) {
    00169         return false;
    00170     }
    00171
    00172     if (data.size() > 0xffffff)
    00173         return false;
    00174
    00175     static char buffer[ 64 ];
    00176     sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
    00177
    00178     size_t n = fwrite( buffer, 1, 10, f_out );
    00179
    00180     if ( n != 10 ) {
    00181         kdError(7017) << "Could not send header" << endl;
    00182         return false;
    00183     }
    00184
    00185     n = fwrite( data.data(), 1, data.size(), f_out );
    00186
    00187     if ( n != data.size() ) {
    00188         kdError(7017) << "Could not write data" << endl;
    00189         return false;
    00190     }
    00191
    00192     fflush( f_out );
    00193
    00194     return true;
    00195 }
    00196
    00197 int Connection::read( int* _cmd, QByteArray &data )
    00198 {
    00199     if (fd_in == -1 ) {
    00200         kdError(7017) << "read: not yet inited" << endl;
    00201         return -1;
    00202     }
    00203
    00204     static char buffer[ 10 ];
    00205
    00206  again1:
    00207     ssize_t n = ::read( fd_in, buffer, 10);
    00208     if ( n == -1 && errno == EINTR )
    00209         goto again1;
    00210
    00211     if ( n == -1) {
    00212         kdError(7017) << "Header read failed, errno=" << errno << endl;
    00213     }
    00214
    00215     if ( n != 10 ) {
    00216       if ( n ) // 0 indicates end of file
    00217         kdError(7017) << "Header has invalid size (" << n << ")" << endl;
    00218       return -1;
    00219     }
    00220
    00221     buffer[ 6 ] = 0;
    00222     buffer[ 9 ] = 0;
    00223
    00224     char *p = buffer;
    00225     while( *p == ' ' ) p++;
    00226     long int len = strtol( p, 0L, 16 );
    00227
    00228     p = buffer + 7;
    00229     while( *p == ' ' ) p++;
    00230     long int cmd = strtol( p, 0L, 16 );
    00231
    00232     data.resize( len );
    00233
    00234     if ( len > 0L ) {
    00235         size_t bytesToGo = len;
    00236         size_t bytesRead = 0;
    00237         do {
    00238             n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
    00239             if (n == -1) {
    00240                 if (errno == EINTR)
    00241                     continue;
    00242
    00243                 kdError(7017) << "Data read failed, errno=" << errno << endl;
    00244                 return -1;
    00245             }
    00246
    00247             bytesRead += n;
    00248             bytesToGo -= n;
    00249         }
    00250         while(bytesToGo);
    00251     }
    00252
    00253     *_cmd = cmd;
    00254     return len;
    00255 }
    00256
    00257 #include "connection.moc"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:12:43 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001