slaveinterface.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 544 行

CPP
544
字号
/* This file is part of the KDE libraries   Copyright (C) 2000 David Faure <faure@kde.org>   This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public   License version 2 as published by the Free Software Foundation.   This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public License   along with this library; see the file COPYING.LIB.  If not, write to   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,   Boston, MA 02110-1301, USA.*/#include "kio/slaveinterface.h"#include "kio/slavebase.h"#include "kio/connection.h"#include <errno.h>#include <assert.h>#include <kdebug.h>#include <stdlib.h>#include <sys/time.h>#include <unistd.h>#include <signal.h>#include <kio/observer.h>#include <kapplication.h>#include <dcopclient.h>#include <time.h>#include <qtimer.h>using namespace KIO;QDataStream &operator <<(QDataStream &s, const KIO::UDSEntry &e ){    // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front    // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because    // that would break the compatibility of the wire-protocol with KDE 2.    // We do the same on 64-bit platforms in case we run in a mixed 32/64bit    // environment.    Q_UINT32 size = 0;    KIO::UDSEntry::ConstIterator it = e.begin();    for( ; it != e.end(); ++it )    {       size++;       if ((*it).m_uds == KIO::UDS_SIZE)          size++;    }    s << size;    it = e.begin();    for( ; it != e.end(); ++it )    {       if ((*it).m_uds == KIO::UDS_SIZE)       {          KIO::UDSAtom a;          a.m_uds = KIO::UDS_SIZE_LARGE;          a.m_long = (*it).m_long >> 32;          s << a;       }       s << *it;    }    return s;}QDataStream &operator >>(QDataStream &s, KIO::UDSEntry &e ){    e.clear();    Q_UINT32 size;    s >> size;    // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front    // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because    // that would break the compatibility of the wire-protocol with KDE 2.    // We do the same on 64-bit platforms in case we run in a mixed 32/64bit    // environment.    Q_LLONG msb = 0;    for(Q_UINT32 i = 0; i < size; i++)    {       KIO::UDSAtom a;       s >> a;       if (a.m_uds == KIO::UDS_SIZE_LARGE)       {          msb = a.m_long;       }       else       {          if (a.m_uds == KIO::UDS_SIZE)          {             if (a.m_long < 0)                a.m_long += (Q_LLONG) 1 << 32;             a.m_long += msb << 32;          }          e.append(a);          msb = 0;       }    }    return s;}static const unsigned int max_nums = 8;class KIO::SlaveInterfacePrivate{public:  SlaveInterfacePrivate() {    slave_calcs_speed = false;    start_time.tv_sec = 0;    start_time.tv_usec = 0;    last_time = 0;    nums = 0;    filesize = 0;    offset = 0;  }  bool slave_calcs_speed;  struct timeval start_time;  uint nums;  long times[max_nums];  KIO::filesize_t sizes[max_nums];  size_t last_time;  KIO::filesize_t filesize, offset;  QTimer speed_timer;};//////////////SlaveInterface::SlaveInterface( Connection * connection ){    m_pConnection = connection;    m_progressId = 0;    d = new SlaveInterfacePrivate;    connect(&d->speed_timer, SIGNAL(timeout()), SLOT(calcSpeed()));}SlaveInterface::~SlaveInterface(){    // Note: no kdDebug() here (scheduler is deleted very late)    m_pConnection = 0; // a bit like the "wasDeleted" of QObject...    delete d;}static KIO::filesize_t readFilesize_t(QDataStream &stream){   KIO::filesize_t result;   unsigned long ul;   stream >> ul;   result = ul;   if (stream.atEnd())      return result;   stream >> ul;   result += ((KIO::filesize_t)ul) << 32;   return result;}bool SlaveInterface::dispatch(){    assert( m_pConnection );    int cmd;    QByteArray data;    if (m_pConnection->read( &cmd, data ) == -1)      return false;    return dispatch( cmd, data );}void SlaveInterface::calcSpeed(){  if (d->slave_calcs_speed) {    d->speed_timer.stop();    return;  }  struct timeval tv;  gettimeofday(&tv, 0);  long diff = ((tv.tv_sec - d->start_time.tv_sec) * 1000000 +	       tv.tv_usec - d->start_time.tv_usec) / 1000;  if (diff - d->last_time >= 900) {    d->last_time = diff;    if (d->nums == max_nums) {      // let's hope gcc can optimize that well enough      // otherwise I'd try memcpy :)      for (unsigned int i = 1; i < max_nums; ++i) {	d->times[i-1] = d->times[i];	d->sizes[i-1] = d->sizes[i];      }      d->nums--;    }    d->times[d->nums] = diff;    d->sizes[d->nums++] = d->filesize - d->offset;    KIO::filesize_t lspeed = 1000 * (d->sizes[d->nums-1] - d->sizes[0]) / (d->times[d->nums-1] - d->times[0]);//     kdDebug() << "proceeed " << (long)d->filesize << " " << diff << " " // 	      << long(d->sizes[d->nums-1] - d->sizes[0]) << " " // 	      <<  d->times[d->nums-1] - d->times[0] << " " // 	      << long(lspeed) << " " << double(d->filesize) / diff // 	      << " " << convertSize(lspeed) << " " // 	      << convertSize(long(double(d->filesize) / diff) * 1000) << " " // 	      <<  endl ;    if (!lspeed) {      d->nums = 1;      d->times[0] = diff;      d->sizes[0] = d->filesize - d->offset;    }    emit speed(lspeed);  }}bool SlaveInterface::dispatch( int _cmd, const QByteArray &rawdata ){    //kdDebug(7007) << "dispatch " << _cmd << endl;    QDataStream stream( rawdata, IO_ReadOnly );    QString str1;    Q_INT32 i;    Q_INT8 b;    Q_UINT32 ul;    switch( _cmd ) {    case MSG_DATA:	emit data( rawdata );	break;    case MSG_DATA_REQ:        emit dataReq();	break;    case MSG_FINISHED:	//kdDebug(7007) << "Finished [this = " << this << "]" << endl;        d->offset = 0;        d->speed_timer.stop();	emit finished();	break;    case MSG_STAT_ENTRY:	{	    UDSEntry entry;	    stream >> entry;	    emit statEntry(entry);	}	break;    case MSG_LIST_ENTRIES:	{	    Q_UINT32 count;	    stream >> count;	    UDSEntryList list;	    UDSEntry entry;	    for (uint i = 0; i < count; i++) {		stream >> entry;		list.append(entry);	    }	    emit listEntries(list);	}	break;    case MSG_RESUME: // From the put job	{	    d->offset = readFilesize_t(stream);	    emit canResume( d->offset );	}	break;    case MSG_CANRESUME: // From the get job        d->filesize = d->offset;        emit canResume(0); // the arg doesn't matter        break;    case MSG_ERROR:	stream >> i >> str1;	kdDebug(7007) << "error " << i << " " << str1 << endl;	emit error( i, str1 );	break;    case MSG_SLAVE_STATUS:        {           pid_t pid;           QCString protocol;           stream >> pid >> protocol >> str1 >> b;           emit slaveStatus(pid, protocol, str1, (b != 0));        }        break;    case MSG_CONNECTED:	emit connected();	break;    case INF_TOTAL_SIZE:	{	    KIO::filesize_t size = readFilesize_t(stream);	    gettimeofday(&d->start_time, 0);	    d->last_time = 0;	    d->filesize = d->offset;	    d->sizes[0] = d->filesize - d->offset;	    d->times[0] = 0;	    d->nums = 1;	    d->speed_timer.start(1000);	    d->slave_calcs_speed = false;	    emit totalSize( size );	}	break;    case INF_PROCESSED_SIZE:	{	    KIO::filesize_t size = readFilesize_t(stream);	    emit processedSize( size );	    d->filesize = size;	}	break;    case INF_SPEED:	stream >> ul;	d->slave_calcs_speed = true;	d->speed_timer.stop();	emit speed( ul );	break;    case INF_GETTING_FILE:	break;    case INF_ERROR_PAGE:	emit errorPage();	break;    case INF_REDIRECTION:      {	KURL url;	stream >> url;	emit redirection( url );      }      break;    case INF_MIME_TYPE:	stream >> str1;	emit mimeType( str1 );        if (!m_pConnection->suspended())            m_pConnection->sendnow( CMD_NONE, QByteArray() );	break;    case INF_WARNING:	stream >> str1;	emit warning( str1 );	break;    case INF_NEED_PASSWD: {        AuthInfo info;       	stream >> info;	openPassDlg( info );	break;    }    case INF_MESSAGEBOX: {	kdDebug(7007) << "needs a msg box" << endl;	QString text, caption, buttonYes, buttonNo, dontAskAgainName;        int type;	stream >> type >> text >> caption >> buttonYes >> buttonNo;	if (stream.atEnd())	messageBox(type, text, caption, buttonYes, buttonNo);	else {	    stream >> dontAskAgainName;	    messageBox(type, text, caption, buttonYes, buttonNo, dontAskAgainName);	}	break;    }    case INF_INFOMESSAGE: {        QString msg;        stream >> msg;        infoMessage(msg);        break;    }    case INF_META_DATA: {        MetaData meta_data;        stream >> meta_data;        metaData(meta_data);        break;    }    case MSG_NET_REQUEST: {        QString host;	QString slaveid;        stream >> host >> slaveid;        requestNetwork(host, slaveid);        break;    }    case MSG_NET_DROP: {        QString host;	QString slaveid;        stream >> host >> slaveid;        dropNetwork(host, slaveid);        break;    }    case MSG_NEED_SUBURL_DATA: {        emit needSubURLData();        break;    }    case MSG_AUTH_KEY: {        bool keep;        QCString key, group;        stream >> key >> group >> keep;        kdDebug(7007) << "Got auth-key:      " << key << endl                      << "    group-key:     " << group << endl                      << "    keep password: " << keep << endl;        emit authorizationKey( key, group, keep );        break;    }    case MSG_DEL_AUTH_KEY: {        QCString key;        stream >> key;        kdDebug(7007) << "Delete auth-key: " << key << endl;        emit delAuthorization( key );    }    default:        kdWarning(7007) << "Slave sends unknown command (" << _cmd << "), dropping slave" << endl;	return false;    }    return true;}void SlaveInterface::setOffset( KIO::filesize_t o){    d->offset = o;}KIO::filesize_t SlaveInterface::offset() const { return d->offset; }void SlaveInterface::requestNetwork(const QString &host, const QString &slaveid){    kdDebug(7007) << "requestNetwork " << host << slaveid << endl;    QByteArray packedArgs;    QDataStream stream( packedArgs, IO_WriteOnly );    stream << true;    m_pConnection->sendnow( INF_NETWORK_STATUS, packedArgs );}void SlaveInterface::dropNetwork(const QString &host, const QString &slaveid){    kdDebug(7007) << "dropNetwork " << host << slaveid << endl;}void SlaveInterface::sendResumeAnswer( bool resume ){    kdDebug(7007) << "SlaveInterface::sendResumeAnswer ok for resuming :" << resume << endl;    m_pConnection->sendnow( resume ? CMD_RESUMEANSWER : CMD_NONE, QByteArray() );}void SlaveInterface::openPassDlg( const QString& prompt, const QString& user, bool readOnly ){    AuthInfo info;    info.prompt = prompt;    info.username = user;    info.readOnly = readOnly;    openPassDlg( info );}void SlaveInterface::openPassDlg( const QString& prompt, const QString& user,                                  const QString& caption, const QString& comment,                                  const QString& label, bool readOnly ){    AuthInfo info;    info.prompt = prompt;    info.username = user;    info.caption = caption;    info.comment = comment;    info.commentLabel = label;    info.readOnly = readOnly;    openPassDlg( info );}void SlaveInterface::openPassDlg( AuthInfo& info ){    kdDebug(7007) << "SlaveInterface::openPassDlg: "                  << "User= " << info.username                  << ", Message= " << info.prompt << endl;    bool result = Observer::self()->openPassDlg( info );    if ( m_pConnection )    {        QByteArray data;        QDataStream stream( data, IO_WriteOnly );        if ( result )        {            stream << info;            kdDebug(7007) << "SlaveInterface:::openPassDlg got: "                          << "User= " << info.username                          << ", Password= [hidden]" << endl;            m_pConnection->sendnow( CMD_USERPASS, data );        }        else            m_pConnection->sendnow( CMD_NONE, data );    }}void SlaveInterface::messageBox( int type, const QString &text, const QString &_caption,                                 const QString &buttonYes, const QString &buttonNo ){    messageBox( type, text, _caption, buttonYes, buttonNo, QString::null );}void SlaveInterface::messageBox( int type, const QString &text, const QString &_caption,                                 const QString &buttonYes, const QString &buttonNo, const QString &dontAskAgainName ){    kdDebug(7007) << "messageBox " << type << " " << text << " - " << _caption << " " << dontAskAgainName << endl;    QByteArray packedArgs;    QDataStream stream( packedArgs, IO_WriteOnly );    QString caption( _caption );    if ( type == KIO::SlaveBase::SSLMessageBox )        caption = QString::fromUtf8(kapp->dcopClient()->appId()); // hack, see observer.cpp    emit needProgressId();    kdDebug(7007) << "SlaveInterface::messageBox m_progressId=" << m_progressId << endl;    QGuardedPtr<SlaveInterface> me = this;    m_pConnection->suspend();    int result = Observer::/*self()->*/messageBox( m_progressId, type, text, caption, buttonYes, buttonNo, dontAskAgainName );    if ( me && m_pConnection ) // Don't do anything if deleted meanwhile    {        m_pConnection->resume();        kdDebug(7007) << this << " SlaveInterface result=" << result << endl;        stream << result;        m_pConnection->sendnow( CMD_MESSAGEBOXANSWER, packedArgs );    }}// No longer used.// Remove in KDE 4.0void SlaveInterface::sigpipe_handler(int){    int saved_errno = errno;    // Using kdDebug from a signal handler is not a good idea.#ifndef NDEBUG        char msg[1000];    sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid());    write(2, msg, strlen(msg));#endif        // Do nothing.    // dispatch will return false and that will trigger ERR_SLAVE_DIED in slave.cpp    errno = saved_errno;}void SlaveInterface::virtual_hook( int, void* ){ /*BASE::virtual_hook( id, data );*/ }#include "slaveinterface.moc"

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?