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 + -
显示快捷键?