kio Library API Documentation

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.48 2003/02/12 00:43:35 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"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:55:24 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003