⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
Loader::Loader() : QObject(){    m_requestsPending.setAutoDelete( true );    m_requestsLoading.setAutoDelete( true );    connect(&m_timer, SIGNAL(timeout()), this, SLOT( servePendingRequests() ) );}void Loader::load(DocLoader* dl, CachedObject *object, bool incremental){    Request *req = new Request(dl, object, incremental);    m_requestsPending.append(req);    emit requestStarted( req->m_docLoader, req->object );    m_timer.start(0, true);}void Loader::servePendingRequests(){    while ( (m_requestsPending.count() != 0) && (m_requestsLoading.count() < MAX_JOB_COUNT) )    {        // get the first pending request        Request *req = m_requestsPending.take(0);#ifdef LOADER_DEBUG  kdDebug( 6060 ) << "starting Loader url=" << req->object->url().string() << endl;#endif        KURL u(req->object->url().string());        KIO::TransferJob* job = KIO::get( u, false, false /*no GUI*/);        job->addMetaData("cache", KIO::getCacheControlString(req->object->cachePolicy()));        if (!req->object->accept().isEmpty())            job->addMetaData("accept", req->object->accept());        if ( req->m_docLoader )        {            job->addMetaData( "referrer",  req->m_docLoader->doc()->URL().url() );            KHTMLPart *part = req->m_docLoader->part();            if (part )            {                job->addMetaData( "cross-domain", part->toplevelURL().url() );                if (part->widget())                    job->setWindow (part->widget()->topLevelWidget());            }        }        connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotFinished( KIO::Job * ) ) );        connect( job, SIGNAL( data( KIO::Job*, const QByteArray &)),                 SLOT( slotData( KIO::Job*, const QByteArray &)));        if ( req->object->schedule() )            KIO::Scheduler::scheduleJob( job );        m_requestsLoading.insert(job, req);    }}void Loader::slotFinished( KIO::Job* job ){  Request *r = m_requestsLoading.take( job );  KIO::TransferJob* j = static_cast<KIO::TransferJob*>(job);  if ( !r )    return;  if (j->error() || j->isErrorPage())  {#ifdef LOADER_DEBUG      kdDebug(6060) << "Loader::slotFinished, with error. job->error()= " << j->error() << " job->isErrorPage()=" << j->isErrorPage() << endl;#endif      r->object->error( job->error(), job->errorText().ascii() );      emit requestFailed( r->m_docLoader, r->object );  }  else  {      r->object->data(r->m_buffer, true);      emit requestDone( r->m_docLoader, r->object );      time_t expireDate = j->queryMetaData("expire-date").toLong();#ifdef LOADER_DEBUG      kdDebug(6060) << "Loader::slotFinished, url = " << j->url().url() << endl;#endif      r->object->setExpireDate( expireDate );      if ( r->object->type() == CachedObject::Image ) {          QString fn = j->queryMetaData("content-disposition");          static_cast<CachedImage*>( r->object )->setSuggestedFilename(fn);#ifdef IMAGE_TITLES          static_cast<CachedImage*>( r->object )->setSuggestedTitle(fn);          KTempFile tf;          tf.setAutoDelete(true);          tf.file()->writeBlock((const char*)r->m_buffer.buffer().data(), r->m_buffer.size());          tf.sync();          KFileMetaInfo kfmi(tf.name());          if (!kfmi.isEmpty()) {              KFileMetaInfoItem i = kfmi.item("Name");              if (i.isValid()) {                  static_cast<CachedImage*>(r->object)->setSuggestedTitle(i.string());              } else {                  i = kfmi.item("Title");                  if (i.isValid()) {                      static_cast<CachedImage*>(r->object)->setSuggestedTitle(i.string());                  }              }          }#endif      }  }  r->object->finish();#ifdef LOADER_DEBUG  kdDebug( 6060 ) << "Loader:: JOB FINISHED " << r->object << ": " << r->object->url().string() << endl;#endif  delete r;  if ( (m_requestsPending.count() != 0) && (m_requestsLoading.count() < MAX_JOB_COUNT / 2) )      m_timer.start(0, true);}void Loader::slotData( KIO::Job*job, const QByteArray &data ){    Request *r = m_requestsLoading[job];    if(!r) {        kdDebug( 6060 ) << "got data for unknown request!" << endl;        return;    }    if ( !r->m_buffer.isOpen() )        r->m_buffer.open( IO_WriteOnly );    r->m_buffer.writeBlock( data.data(), data.size() );    if(r->incremental)        r->object->data( r->m_buffer, false );}int Loader::numRequests( DocLoader* dl ) const{    int res = 0;    QPtrListIterator<Request> pIt( m_requestsPending );    for (; pIt.current(); ++pIt )        if ( pIt.current()->m_docLoader == dl )            res++;    QPtrDictIterator<Request> lIt( m_requestsLoading );    for (; lIt.current(); ++lIt )        if ( lIt.current()->m_docLoader == dl )            res++;    return res;}void Loader::cancelRequests( DocLoader* dl ){    QPtrListIterator<Request> pIt( m_requestsPending );    while ( pIt.current() ) {        if ( pIt.current()->m_docLoader == dl )        {            CDEBUG << "canceling pending request for " << pIt.current()->object->url().string() << endl;            Cache::removeCacheEntry( pIt.current()->object );            m_requestsPending.remove( pIt );        }        else            ++pIt;    }    //kdDebug( 6060 ) << "got " << m_requestsLoading.count() << "loading requests" << endl;    QPtrDictIterator<Request> lIt( m_requestsLoading );    while ( lIt.current() )    {        if ( lIt.current()->m_docLoader == dl )        {            //kdDebug( 6060 ) << "canceling loading request for " << lIt.current()->object->url().string() << endl;            KIO::Job *job = static_cast<KIO::Job *>( lIt.currentKey() );            Cache::removeCacheEntry( lIt.current()->object );            m_requestsLoading.remove( lIt.currentKey() );            job->kill();            //emit requestFailed( dl, pIt.current()->object );        }        else            ++lIt;    }}KIO::Job *Loader::jobForRequest( const DOM::DOMString &url ) const{    QPtrDictIterator<Request> it( m_requestsLoading );    for (; it.current(); ++it )    {        CachedObject *obj = it.current()->object;        if ( obj && obj->url() == url )            return static_cast<KIO::Job *>( it.currentKey() );    }    return 0;}// ----------------------------------------------------------------------------QDict<CachedObject> *Cache::cache;QPtrList<DocLoader>* Cache::docloader;QPtrList<CachedObject> *Cache::freeList;Loader *Cache::m_loader;int Cache::maxSize = DEFCACHESIZE;int Cache::totalSizeOfLRU;QPixmap *Cache::nullPixmap;QPixmap *Cache::brokenPixmap;QPixmap *Cache::blockedPixmap;void Cache::init(){    if ( !cache )        cache = new QDict<CachedObject>(401, true);    if ( !docloader )        docloader = new QPtrList<DocLoader>;    if ( !nullPixmap )        nullPixmap = new QPixmap;    if ( !brokenPixmap )        brokenPixmap = new QPixmap(KHTMLFactory::instance()->iconLoader()->loadIcon("file_broken", KIcon::Desktop, 16, KIcon::DisabledState));            if ( !blockedPixmap ) {        blockedPixmap = new QPixmap();        blockedPixmap->loadFromData(blocked_icon_data, blocked_icon_len);    }    if ( !m_loader )        m_loader = new Loader();    if ( !freeList ) {        freeList = new QPtrList<CachedObject>;        freeList->setAutoDelete(true);    }}void Cache::clear(){    if ( !cache ) return;#ifdef CACHE_DEBUG    kdDebug( 6060 ) << "Cache: CLEAR!" << endl;    statistics();#endif    cache->setAutoDelete( true );#ifndef NDEBUG    for (QDictIterator<CachedObject> it(*cache); it.current(); ++it)        assert(it.current()->canDelete());    for (QPtrListIterator<CachedObject> it(*freeList); it.current(); ++it)        assert(it.current()->canDelete());#endif    delete cache; cache = 0;    delete nullPixmap; nullPixmap = 0;    delete brokenPixmap; brokenPixmap = 0;    delete blockedPixmap; blockedPixmap = 0;    delete m_loader;  m_loader = 0;    delete docloader; docloader = 0;    delete freeList; freeList = 0;}template<typename CachedObjectType, enum CachedObject::Type CachedType>CachedObjectType* Cache::requestObject( DocLoader* dl, const KURL& kurl, const char* accept ){    KIO::CacheControl cachePolicy = dl ? dl->cachePolicy() : KIO::CC_Verify;    QString url = kurl.url();    CachedObject* o = cache->find(url);    if ( o && o->type() != CachedType ) {        removeCacheEntry( o );        o = 0;    }    if ( o && dl->needReload( o, url ) ) {        o = 0;        assert( cache->find( url ) == 0 );    }    if(!o)    {#ifdef CACHE_DEBUG        kdDebug( 6060 ) << "Cache: new: " << kurl.url() << endl;#endif        CachedObjectType* cot = new CachedObjectType(dl, url, cachePolicy, accept);        cache->insert( url, cot );        if ( cot->allowInLRUList() )            insertInLRUList( cot );        o = cot;    }#ifdef CACHE_DEBUG    else {    kdDebug( 6060 ) << "Cache: using pending/cached: " << kurl.url() << endl;    }#endif    dl->insertCachedObject( o );    return static_cast<CachedObjectType *>(o);}void Cache::preloadStyleSheet( const QString &url, const QString &stylesheet_data){    CachedObject *o = cache->find(url);    if(o)        removeCacheEntry(o);    CachedCSSStyleSheet *stylesheet = new CachedCSSStyleSheet(url, stylesheet_data);    cache->insert( url, stylesheet );}void Cache::preloadScript( const QString &url, const QString &script_data){    CachedObject *o = cache->find(url);    if(o)        removeCacheEntry(o);    CachedScript *script = new CachedScript(url, script_data);    cache->insert( url, script );}void Cache::flush(bool force){    init();    if ( force || totalSizeOfLRU > maxSize + maxSize/4) {        for ( int i = MAX_LRU_LISTS-1; i >= 0 && totalSizeOfLRU > maxSize; --i )            while ( totalSizeOfLRU > maxSize && m_LRULists[i].m_tail )                removeCacheEntry( m_LRULists[i].m_tail );#ifdef CACHE_DEBUG        statistics();#endif    }    for ( CachedObject* p = freeList->first(); p; p = freeList->next() ) {        if ( p->canDelete() )            freeList->remove();    }}void Cache::setSize( int bytes ){    maxSize = bytes;    flush(true /* force */);}void Cache::statistics(){    CachedObject *o;    // this function is for debugging purposes only    init();    int size = 0;    int msize = 0;    int movie = 0;    int images = 0;    int scripts = 0;    int stylesheets = 0;    QDictIterator<CachedObject> it(*cache);    for(it.toFirst(); it.current(); ++it)    {        o = it.current();        switch(o->type()) {        case CachedObject::Image:        {            CachedImage *im = static_cast<CachedImage *>(o);            images++;            if(im->m != 0)            {                movie++;                msize += im->size();            }            break;        }        case CachedObject::CSSStyleSheet:            stylesheets++;            break;        case CachedObject::Script:            scripts++;            break;        }        size += o->size();    }    size /= 1024;    kdDebug( 6060 ) << "------------------------- image cache statistics -------------------" << endl;    kdDebug( 6060 ) << "Number of items in cache: " << cache->count() << endl;    kdDebug( 6060 ) << "Number of cached images: " << images << endl;    kdDebug( 6060 ) << "Number of cached movies: " << movie << endl;    kdDebug( 6060 ) << "Number of cached scripts: " << scripts << endl;    kdDebug( 6060 ) << "Number of cached stylesheets: " << stylesheets << endl;    kdDebug( 6060 ) << "pixmaps:   allocated space approx. " << size << " kB" << endl;    kdDebug( 6060 ) << "movies :   allocated space approx. " << msize/1024 << " kB" << endl;    kdDebug( 6060 ) << "--------------------------------------------------------------------" << endl;}void Cache::removeCacheEntry( CachedObject *object ){    QString key = object->url().string();    cache->remove( key );    removeFromLRUList( object );    for (const DocLoader* dl=docloader->first(); dl; dl=docloader->next() )        dl->removeCachedObject( object );    if ( !object->free() ) {        Cache::freeList->append( object );        object->m_free = true;    }}static inline int FastLog2(unsigned int j){   unsigned int log2;   log2 = 0;   if (j & (j-1))       log2 += 1;   if (j >> 16)       log2 += 16, j >>= 16;   if (j >> 8)       log2 += 8, j >>= 8;   if (j >> 4)       log2 += 4, j >>= 4;   if (j >> 2)       log2 += 2, j >>= 2;   if (j >> 1)       log2 += 1;   return log2;}static LRUList* getLRUListFor(CachedObject* o){    int accessCount = o->accessCount();    int queueIndex;    if (accessCount == 0) {        queueIndex = 0;   } else {        int sizeLog = FastLog2(o->size());        queueIndex = sizeLog/o->accessCount() - 1;        if (queueIndex < 0)            queueIndex = 0;        if (queueIndex >= MAX_LRU_LISTS)            queueIndex = MAX_LRU_LISTS-1;    }   return &m_LRULists[queueIndex];}void Cache::removeFromLRUList(CachedObject *object){    CachedObject *next = object->m_next;    CachedObject *prev = object->m_prev;    LRUList* list = getLRUListFor(object);    CachedObject *&head = getLRUListFor(object)->m_head;    if (next == 0 && prev == 0 && head != object) {        return;    }    object->m_next = 0;    object->m_prev = 0;    if (next)        next->m_prev = prev;    else if (list->m_tail == object)       list->m_tail = prev;    if (prev)        prev->m_next = next;    else if (head == object)        head = next;    totalSizeOfLRU -= object->size();}void Cache::insertInLRUList(CachedObject *object){    removeFromLRUList(object);    assert( object );    assert( !object->free() );    assert( object->canDelete() );    assert( object->allowInLRUList() );    LRUList* list = getLRUListFor(object);    CachedObject *&head = list->m_head;    object->m_next = head;    if (head)        head->m_prev = object;    head = object;    if (object->m_next == 0)        list->m_tail = object;    totalSizeOfLRU += object->size();}// --------------------------------------void CachedObjectClient::setPixmap(const QPixmap &, const QRect&, CachedImage *) {}void CachedObjectClient::setStyleSheet(const DOM::DOMString &/*url*/, const DOM::DOMString &/*sheet*/) {}void CachedObjectClient::notifyFinished(CachedObject * /*finishedObj*/) {}void CachedObjectClient::error(int /*err*/, const QString &/*text*/) {}#undef CDEBUG#include "loader.moc"

⌨️ 快捷键说明

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