kresolver.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,159 行 · 第 1/2 页
CPP
1,159 行
/* -*- C++ -*- * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net> * * * 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 "config.h"// System includes#include <sys/types.h>#include <sys/socket.h>#include <sys/param.h>#include <errno.h>#include <netdb.h>#include <time.h>#include <arpa/inet.h>#include <netinet/in.h>#include <stdlib.h>#include <unistd.h>// Qt includes#include <qapplication.h>#include <qstring.h>#include <qcstring.h>#include <qstrlist.h>#include <qstringlist.h>#include <qshared.h>#include <qdatetime.h>#include <qtimer.h>#include <qmutex.h>#include <qguardedptr.h>// IDN#ifdef HAVE_IDNA_H# include <idna.h>#endif// KDE#include <klocale.h>// Us#include "kresolver.h"#include "kresolver_p.h"#include "ksocketaddress.h"#ifdef NEED_MUTEX#warning "mutex"QMutex getXXbyYYmutex;#endifusing namespace KNetwork;using namespace KNetwork::Internal;/////////////////////////////////////////////// class KResolverEntryclass KNetwork::KResolverEntryPrivate: public QShared{public: KSocketAddress addr; int socktype; int protocol; QString canonName; QCString encodedName; inline KResolverEntryPrivate() : socktype(0), protocol(0) { }};// default constructorKResolverEntry::KResolverEntry() : d(0L){}// constructor with stuffKResolverEntry::KResolverEntry(const KSocketAddress& addr, int socktype, int protocol, const QString& canonName, const QCString& encodedName) : d(new KResolverEntryPrivate){ d->addr = addr; d->socktype = socktype; d->protocol = protocol; d->canonName = canonName; d->encodedName = encodedName;}// constructor with even more stuffKResolverEntry::KResolverEntry(const struct sockaddr* sa, Q_UINT16 salen, int socktype, int protocol, const QString& canonName, const QCString& encodedName) : d(new KResolverEntryPrivate){ d->addr = KSocketAddress(sa, salen); d->socktype = socktype; d->protocol = protocol; d->canonName = canonName; d->encodedName = encodedName;}// copy constructorKResolverEntry::KResolverEntry(const KResolverEntry& that) : d(0L){ *this = that;}// destructorKResolverEntry::~KResolverEntry(){ if (d == 0L) return; if (d->deref()) delete d;}// returns the socket addressKSocketAddress KResolverEntry::address() const{ return d ? d->addr : KSocketAddress();}// returns the lengthQ_UINT16 KResolverEntry::length() const{ return d ? d->addr.length() : 0;}// returns the familyint KResolverEntry::family() const{ return d ? d->addr.family() : AF_UNSPEC;}// returns the canonical nameQString KResolverEntry::canonicalName() const{ return d ? d->canonName : QString::null;}// returns the encoded nameQCString KResolverEntry::encodedName() const{ return d ? d->encodedName : QCString();}// returns the socket typeint KResolverEntry::socketType() const{ return d ? d->socktype : 0;}// returns the protocolint KResolverEntry::protocol() const{ return d ? d->protocol : 0;}// assignment operatorKResolverEntry& KResolverEntry::operator= (const KResolverEntry& that){ // copy the data if (that.d) that.d->ref(); if (d && d->deref()) delete d; d = that.d; return *this;}/////////////////////////////////////////////// class KResolverResultsclass KNetwork::KResolverResultsPrivate{public: QString node, service; int errorcode, syserror; KResolverResultsPrivate() : errorcode(0), syserror(0) { }};// default constructorKResolverResults::KResolverResults() : d(new KResolverResultsPrivate){}// copy constructorKResolverResults::KResolverResults(const KResolverResults& other) : QValueList<KResolverEntry>(other), d(new KResolverResultsPrivate){ *d = *other.d;}// destructorKResolverResults::~KResolverResults(){ delete d;}// assignment operatorKResolverResults&KResolverResults::operator= (const KResolverResults& other){ if (this == &other) return *this; // copy over the other data *d = *other.d; // now let QValueList do the rest of the work QValueList<KResolverEntry>::operator =(other); return *this;}// gets the error codeint KResolverResults::error() const{ return d->errorcode;}// gets the system errnoint KResolverResults::systemError() const{ return d->syserror;}// sets the error codesvoid KResolverResults::setError(int errorcode, int systemerror){ d->errorcode = errorcode; d->syserror = systemerror;}// gets the hostnameQString KResolverResults::nodeName() const{ return d->node;}// gets the service nameQString KResolverResults::serviceName() const{ return d->service;}// sets the addressvoid KResolverResults::setAddress(const QString& node, const QString& service){ d->node = node; d->service = service;}void KResolverResults::virtual_hook( int, void* ){ /*BASE::virtual_hook( id, data );*/ }///////////////////////// class KResolverQStringList *KResolver::idnDomains = 0;// default constructorKResolver::KResolver(QObject *parent, const char *name) : QObject(parent, name), d(new KResolverPrivate(this)){}// constructor with host and serviceKResolver::KResolver(const QString& nodename, const QString& servicename, QObject *parent, const char *name) : QObject(parent, name), d(new KResolverPrivate(this, nodename, servicename)){}// destructorKResolver::~KResolver(){ cancel(false); delete d;}// get the statusint KResolver::status() const{ return d->status;}// get the error codeint KResolver::error() const{ return d->errorcode;}// get the errnoint KResolver::systemError() const{ return d->syserror;}// are we running?bool KResolver::isRunning() const{ return d->status > 0 && d->status < Success;}// get the hostnameQString KResolver::nodeName() const{ return d->input.node;}// get the serviceQString KResolver::serviceName() const{ return d->input.service;}// sets the hostnamevoid KResolver::setNodeName(const QString& nodename){ // don't touch those values if we're working! if (!isRunning()) { d->input.node = nodename; d->status = Idle; d->results.setAddress(nodename, d->input.service); }}// sets the servicevoid KResolver::setServiceName(const QString& service){ // don't change if running if (!isRunning()) { d->input.service = service; d->status = Idle; d->results.setAddress(d->input.node, service); }}// sets the addressvoid KResolver::setAddress(const QString& nodename, const QString& service){ setNodeName(nodename); setServiceName(service);}// get the flagsint KResolver::flags() const{ return d->input.flags;}// sets the flagsint KResolver::setFlags(int flags){ int oldflags = d->input.flags; if (!isRunning()) { d->input.flags = flags; d->status = Idle; } return oldflags;}// sets the family maskvoid KResolver::setFamily(int families){ if (!isRunning()) { d->input.familyMask = families; d->status = Idle; }}// sets the socket typevoid KResolver::setSocketType(int type){ if (!isRunning()) { d->input.socktype = type; d->status = Idle; }}// sets the protocolvoid KResolver::setProtocol(int protonum, const char *name){ if (isRunning()) return; // can't change now // we copy the given protocol name. If it isn't an empty string // and the protocol number was 0, we will look it up in /etc/protocols // we also leave the error reporting to the actual lookup routines, in // case the given protocol name doesn't exist d->input.protocolName = name; if (protonum == 0 && name != 0L && *name != '\0') { // must look up the protocol number d->input.protocol = KResolver::protocolNumber(name); } else d->input.protocol = protonum; d->status = Idle;}bool KResolver::start(){ if (!isRunning()) { d->results.empty(); // is there anything to be queued? if (d->input.node.isEmpty() && d->input.service.isEmpty()) { d->status = KResolver::Success; emitFinished(); } else KResolverManager::manager()->enqueue(this, 0L); } return true;}bool KResolver::wait(int msec){ if (!isRunning()) { emitFinished(); return true; } QMutexLocker locker(&d->mutex); if (!isRunning()) { // it was running and no longer is? // That means the manager has finished its processing and has posted // an event for the signal to be emitted already. This means the signal // will be emitted twice! emitFinished(); return true; } else { QTime t; t.start(); while (!msec || t.elapsed() < msec) { // wait on the manager to broadcast completion d->waiting = true; if (msec) KResolverManager::manager()->notifyWaiters.wait(&d->mutex, msec - t.elapsed()); else KResolverManager::manager()->notifyWaiters.wait(&d->mutex); // the manager has processed // see if this object is done if (!isRunning()) { // it's done d->waiting = false; emitFinished(); return true; } } // if we've got here, we've timed out d->waiting = false; return false; }}void KResolver::cancel(bool emitSignal){ KResolverManager::manager()->dequeue(this); if (emitSignal) emitFinished();}KResolverResultsKResolver::results() const{ if (!isRunning()) return d->results; // return a dummy, empty result KResolverResults r; r.setAddress(d->input.node, d->input.service); r.setError(d->errorcode, d->syserror); return r;}bool KResolver::event(QEvent* e){ if (static_cast<int>(e->type()) == KResolverManager::ResolutionCompleted) { emitFinished(); return true; } return false;}void KResolver::emitFinished(){ if (isRunning()) d->status = KResolver::Success; QGuardedPtr<QObject> p = this; // guard against deletion emit finished(d->results); if (p && d->deleteWhenDone) deleteLater(); // in QObject}QString KResolver::errorString(int errorcode, int syserror){ // no i18n now... static const char * const messages[] = { I18N_NOOP("no error"), // NoError I18N_NOOP("requested family not supported for this host name"), // AddrFamily I18N_NOOP("temporary failure in name resolution"), // TryAgain I18N_NOOP("non-recoverable failure in name resolution"), // NonRecoverable I18N_NOOP("invalid flags"), // BadFlags I18N_NOOP("memory allocation failure"), // Memory I18N_NOOP("name or service not known"), // NoName I18N_NOOP("requested family not supported"), // UnsupportedFamily I18N_NOOP("requested service not supported for this socket type"), // UnsupportedService I18N_NOOP("requested socket type not supported"), // UnsupportedSocketType I18N_NOOP("unknown error"), // UnknownError I18N_NOOP2("1: the i18n'ed system error code, from errno", "system error: %1") // SystemError }; // handle the special value if (errorcode == Canceled) return i18n("request was canceled"); if (errorcode > 0 || errorcode < SystemError) return QString::null; QString msg = i18n(messages[-errorcode]); if (errorcode == SystemError)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?