KDECore
k3socketbase.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * Copyright (C) 2003-2005 Thiago Macieira <thiago@kde.org> 00003 * 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining 00006 * a copy of this software and associated documentation files (the 00007 * "Software"), to deal in the Software without restriction, including 00008 * without limitation the rights to use, copy, modify, merge, publish, 00009 * distribute, sublicense, and/or sell copies of the Software, and to 00010 * permit persons to whom the Software is furnished to do so, subject to 00011 * the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 #include "k3socketbase.h" 00026 00027 #include <config.h> 00028 #include <config-network.h> 00029 #include <QMutex> 00030 #include <klocale.h> 00031 00032 #include "k3socketdevice.h" 00033 00034 #ifdef Q_WS_WIN 00035 #include <winsock2.h> 00036 00037 void KNetwork_initSocket() 00038 { 00039 static bool hasStarted = false; 00040 if (!hasStarted) 00041 { 00042 WSADATA wsaData; 00043 WORD wVersionRequested = MAKEWORD( 2, 2 ); 00044 WSAStartup( wVersionRequested, &wsaData ); 00045 hasStarted = true; 00046 } 00047 } 00048 #endif 00049 00050 using namespace KNetwork; 00051 00052 class KNetwork::KSocketBasePrivate 00053 { 00054 public: 00055 int socketOptions; 00056 int socketError; 00057 int capabilities; 00058 00059 mutable KSocketDevice* device; 00060 00061 QMutex mutex; 00062 00063 KSocketBasePrivate() 00064 : mutex(QMutex::Recursive) // create recursive 00065 { } 00066 }; 00067 00068 KSocketBase::KSocketBase() 00069 : d(new KSocketBasePrivate) 00070 { 00071 d->socketOptions = Blocking; 00072 d->socketError = 0; 00073 d->device = 0L; 00074 d->capabilities = 0; 00075 #ifdef Q_WS_WIN 00076 KNetwork_initSocket(); 00077 #endif 00078 } 00079 00080 KSocketBase::~KSocketBase() 00081 { 00082 delete d->device; 00083 delete d; 00084 } 00085 00086 bool KSocketBase::setSocketOptions(int opts) 00087 { 00088 d->socketOptions = opts; 00089 return true; 00090 } 00091 00092 int KSocketBase::socketOptions() const 00093 { 00094 return d->socketOptions; 00095 } 00096 00097 bool KSocketBase::setBlocking(bool enable) 00098 { 00099 return setSocketOptions((socketOptions() & ~Blocking) | (enable ? Blocking : 0)); 00100 } 00101 00102 bool KSocketBase::blocking() const 00103 { 00104 return socketOptions() & Blocking; 00105 } 00106 00107 bool KSocketBase::setAddressReuseable(bool enable) 00108 { 00109 return setSocketOptions((socketOptions() & ~AddressReuseable) | (enable ? AddressReuseable : 0)); 00110 } 00111 00112 bool KSocketBase::addressReuseable() const 00113 { 00114 return socketOptions() & AddressReuseable; 00115 } 00116 00117 bool KSocketBase::setIPv6Only(bool enable) 00118 { 00119 return setSocketOptions((socketOptions() & ~IPv6Only) | (enable ? IPv6Only : 0)); 00120 } 00121 00122 bool KSocketBase::isIPv6Only() const 00123 { 00124 return socketOptions() & IPv6Only; 00125 } 00126 00127 bool KSocketBase::setBroadcast(bool enable) 00128 { 00129 return setSocketOptions((socketOptions() & ~Broadcast) | (enable ? Broadcast : 0)); 00130 } 00131 00132 bool KSocketBase::broadcast() const 00133 { 00134 return socketOptions() & Broadcast; 00135 } 00136 00137 bool KSocketBase::setNoDelay(bool enable) 00138 { 00139 return setSocketOptions((socketOptions() & ~NoDelay) | (enable ? NoDelay : 0)); 00140 } 00141 00142 bool KSocketBase::noDelay() const 00143 { 00144 return socketOptions() & NoDelay; 00145 } 00146 00147 00148 KSocketDevice* KSocketBase::socketDevice() const 00149 { 00150 if (d->device) 00151 return d->device; 00152 00153 // it doesn't exist, so create it 00154 QMutexLocker locker(mutex()); 00155 if (d->device) 00156 return d->device; 00157 00158 KSocketBase* that = const_cast<KSocketBase*>(this); 00159 KSocketDevice* dev = 0; 00160 if (d->capabilities) 00161 dev = KSocketDevice::createDefault(that, d->capabilities); 00162 if (!dev) 00163 dev = KSocketDevice::createDefault(that); 00164 that->setSocketDevice(dev); 00165 return d->device; 00166 } 00167 00168 void KSocketBase::setSocketDevice(KSocketDevice* device) 00169 { 00170 QMutexLocker locker(mutex()); 00171 if (d->device == 0L) 00172 d->device = device; 00173 } 00174 00175 int KSocketBase::setRequestedCapabilities(int add, int remove) 00176 { 00177 d->capabilities |= add; 00178 d->capabilities &= ~remove; 00179 return d->capabilities; 00180 } 00181 00182 bool KSocketBase::hasDevice() const 00183 { 00184 return d->device != 0L; 00185 } 00186 00187 void KSocketBase::setError(SocketError error) 00188 { 00189 d->socketError = error; 00190 } 00191 00192 void KSocketBase::resetError() 00193 { 00194 d->socketError = NoError; 00195 } 00196 00197 KSocketBase::SocketError KSocketBase::error() const 00198 { 00199 return static_cast<KSocketBase::SocketError>(d->socketError); 00200 } 00201 00202 QString KSocketBase::errorString() const 00203 { 00204 return errorString(error()); 00205 } 00206 00207 // static 00208 QString KSocketBase::errorString(KSocketBase::SocketError code) 00209 { 00210 QString reason; 00211 switch (code) 00212 { 00213 case NoError: 00214 reason = i18nc("Socket error code NoError", "no error"); 00215 break; 00216 00217 case LookupFailure: 00218 reason = i18nc("Socket error code LookupFailure", 00219 "name lookup has failed"); 00220 break; 00221 00222 case AddressInUse: 00223 reason = i18nc("Socket error code AddressInUse", 00224 "address already in use"); 00225 break; 00226 00227 case AlreadyBound: 00228 reason = i18nc("Socket error code AlreadyBound", 00229 "socket is already bound"); 00230 break; 00231 00232 case AlreadyCreated: 00233 reason = i18nc("Socket error code AlreadyCreated", 00234 "socket is already created"); 00235 break; 00236 00237 case NotBound: 00238 reason = i18nc("Socket error code NotBound", 00239 "socket is not bound"); 00240 break; 00241 00242 case NotCreated: 00243 reason = i18nc("Socket error code NotCreated", 00244 "socket has not been created"); 00245 break; 00246 00247 case WouldBlock: 00248 reason = i18nc("Socket error code WouldBlock", 00249 "operation would block"); 00250 break; 00251 00252 case ConnectionRefused: 00253 reason = i18nc("Socket error code ConnectionRefused", 00254 "connection actively refused"); 00255 break; 00256 00257 case ConnectionTimedOut: 00258 reason = i18nc("Socket error code ConnectionTimedOut", 00259 "connection timed out"); 00260 break; 00261 00262 case InProgress: 00263 reason = i18nc("Socket error code InProgress", 00264 "operation is already in progress"); 00265 break; 00266 00267 case NetFailure: 00268 reason = i18nc("Socket error code NetFailure", 00269 "network failure occurred"); 00270 break; 00271 00272 case NotSupported: 00273 reason = i18nc("Socket error code NotSupported", 00274 "operation is not supported"); 00275 break; 00276 00277 case Timeout: 00278 reason = i18nc("Socket error code Timeout", 00279 "timed operation timed out"); 00280 break; 00281 00282 case UnknownError: 00283 reason = i18nc("Socket error code UnknownError", 00284 "an unknown/unexpected error has happened"); 00285 break; 00286 00287 case RemotelyDisconnected: 00288 reason = i18nc("Socket error code RemotelyDisconnected", 00289 "remote host closed connection"); 00290 break; 00291 00292 default: 00293 reason.clear(); 00294 break; 00295 } 00296 00297 return reason; 00298 } 00299 00300 // static 00301 bool KSocketBase::isFatalError(int code) 00302 { 00303 switch (code) 00304 { 00305 case WouldBlock: 00306 case InProgress: 00307 case NoError: 00308 case RemotelyDisconnected: 00309 return false; 00310 } 00311 00312 return true; 00313 } 00314 00315 void KSocketBase::unsetSocketDevice() 00316 { 00317 d->device = 0L; 00318 } 00319 00320 QMutex* KSocketBase::mutex() const 00321 { 00322 return &d->mutex; 00323 } 00324 00325 KActiveSocketBase::KActiveSocketBase(QObject* parent) 00326 : QIODevice(parent) 00327 { 00328 } 00329 00330 KActiveSocketBase::~KActiveSocketBase() 00331 { 00332 } 00333 00334 QString KActiveSocketBase::errorString() const 00335 { 00336 return QIODevice::errorString(); 00337 } 00338 00339 bool KActiveSocketBase::open(OpenMode mode) 00340 { 00341 QIODevice::open(mode); 00342 if ( mode != QIODevice::NotOpen ) 00343 QIODevice::seek(0); // clear unget buffers 00344 return true; 00345 } 00346 00347 void KActiveSocketBase::setSocketDevice(KSocketDevice* dev) 00348 { 00349 KSocketBase::setSocketDevice(dev); 00350 KActiveSocketBase::open(dev->openMode()); 00351 } 00352 00353 bool KActiveSocketBase::isSequential() const 00354 { 00355 return true; 00356 } 00357 00358 qint64 KActiveSocketBase::size() const 00359 { 00360 return 0; 00361 } 00362 00363 qint64 KActiveSocketBase::pos() const 00364 { 00365 return 0; 00366 } 00367 00368 bool KActiveSocketBase::seek(qint64) 00369 { 00370 return false; 00371 } 00372 00373 bool KActiveSocketBase::atEnd() const 00374 { 00375 return true; 00376 } 00377 00378 qint64 KActiveSocketBase::read(char *data, qint64 maxlen) 00379 { 00380 return QIODevice::read(data, maxlen); 00381 } 00382 00383 QByteArray KActiveSocketBase::read(qint64 len) 00384 { 00385 return QIODevice::read(len); 00386 } 00387 00388 qint64 KActiveSocketBase::read(char *data, qint64 len, KSocketAddress& from) 00389 { 00390 // FIXME TODO: implement unget buffers 00391 return readData(data, len, &from); 00392 } 00393 00394 qint64 KActiveSocketBase::peek(char *data, qint64 len) 00395 { 00396 return peekData(data, len, 0L); 00397 } 00398 00399 qint64 KActiveSocketBase::peek(char *data, qint64 len, KSocketAddress& from) 00400 { 00401 return peekData(data, len, &from); 00402 } 00403 00404 qint64 KActiveSocketBase::write(const char *data, qint64 len) 00405 { 00406 return QIODevice::write(data, len); 00407 } 00408 00409 qint64 KActiveSocketBase::write(const QByteArray& data) 00410 { 00411 return QIODevice::write(data); 00412 } 00413 00414 qint64 KActiveSocketBase::write(const char *data, qint64 len, 00415 const KSocketAddress& to) 00416 { 00417 return writeData(data, len, &to); 00418 } 00419 00420 void KActiveSocketBase::ungetChar(char) 00421 { 00422 return; 00423 } 00424 00425 qint64 KActiveSocketBase::readData(char *data, qint64 len) 00426 { 00427 return readData(data, len, 0L); 00428 } 00429 00430 qint64 KActiveSocketBase::writeData(const char *data, qint64 len) 00431 { 00432 return writeData(data, len, 0L); 00433 } 00434 00435 void KActiveSocketBase::setError(SocketError error) 00436 { 00437 KSocketBase::setError(error); 00438 setErrorString(KSocketBase::errorString()); 00439 } 00440 00441 void KActiveSocketBase::resetError() 00442 { 00443 KSocketBase::setError(NoError); 00444 setErrorString(QString()); 00445 } 00446 00447 KPassiveSocketBase::KPassiveSocketBase() 00448 { 00449 } 00450 00451 KPassiveSocketBase::~KPassiveSocketBase() 00452 { 00453 } 00454 00455 #include "k3socketbase.moc" 00456
KDE 4.6 API Reference