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

📄 loader.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*    This file is part of the KDE libraries    Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)    Copyright (C) 2001-2003 Dirk Mueller (mueller@kde.org)    Copyright (C) 2002 Waldo Bastian (bastian@kde.org)    Copyright (C) 2003 Apple Computer, Inc.    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    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.    This class provides all functionality needed for loading images, style sheets and html    pages from the web. It has a memory cache for these objects.    // regarding the LRU:    // http://www.is.kyusan-u.ac.jp/~chengk/pub/papers/compsac00_A07-07.pdf*/#undef CACHE_DEBUG//#define CACHE_DEBUG#ifdef CACHE_DEBUG#define CDEBUG kdDebug(6060)#else#define CDEBUG kndDebug()#endif#undef LOADER_DEBUG//#define LOADER_DEBUG#include <assert.h>#include "misc/loader.h"#include "misc/seed.h"// default cache size#define DEFCACHESIZE 2096*1024#define MAX_JOB_COUNT 32#include <qasyncio.h>#include <qasyncimageio.h>#include <qpainter.h>#include <qbitmap.h>#include <qmovie.h>#include <qwidget.h>#include <kapplication.h>#include <kio/job.h>#include <kio/jobclasses.h>#include <kglobal.h>#include <kimageio.h>#include <kcharsets.h>#include <kiconloader.h>#include <scheduler.h>#include <kdebug.h>#include "khtml_factory.h"#include "khtml_part.h"#ifdef IMAGE_TITLES#include <qfile.h>#include <kfilemetainfo.h>#include <ktempfile.h>#endif#include "html/html_documentimpl.h"#include "css/css_stylesheetimpl.h"#include "xml/dom_docimpl.h"#include "blocked_icon.cpp"using namespace khtml;using namespace DOM;#define MAX_LRU_LISTS 20struct LRUList {    CachedObject* m_head;    CachedObject* m_tail;    LRUList() : m_head(0), m_tail(0) {}};static LRUList m_LRULists[MAX_LRU_LISTS];static LRUList* getLRUListFor(CachedObject* o);CachedObjectClient::~CachedObjectClient(){}CachedObject::~CachedObject(){    Cache::removeFromLRUList(this);}void CachedObject::finish(){    m_status = Cached;}bool CachedObject::isExpired() const{    if (!m_expireDate) return false;    time_t now = time(0);    return (difftime(now, m_expireDate) >= 0);}void CachedObject::setRequest(Request *_request){    if ( _request && !m_request )        m_status = Pending;    if ( allowInLRUList() )        Cache::removeFromLRUList( this );    m_request = _request;    if ( allowInLRUList() )        Cache::insertInLRUList( this );}void CachedObject::ref(CachedObjectClient *c){    // unfortunately we can be ref'ed multiple times from the    // same object,  because it uses e.g. the same foreground    // and the same background picture. so deal with it.    m_clients.insert(c,c);    Cache::removeFromLRUList(this);    m_accessCount++;}void CachedObject::deref(CachedObjectClient *c){    assert( c );    assert( m_clients.count() );    assert( !canDelete() );    assert( m_clients.find( c ) );    Cache::flush();    m_clients.remove(c);    if (allowInLRUList())        Cache::insertInLRUList(this);}void CachedObject::setSize(int size){    bool sizeChanged;    if ( !m_next && !m_prev && getLRUListFor(this)->m_head != this )        sizeChanged = false;    else        sizeChanged = ( size - m_size ) != 0;    // The object must now be moved to a different queue,    // since its size has been changed.    if ( sizeChanged  && allowInLRUList())        Cache::removeFromLRUList(this);    m_size = size;    if ( sizeChanged && allowInLRUList())        Cache::insertInLRUList(this);}QTextCodec* CachedObject::codecForBuffer( const QString& charset, const QByteArray& buffer ) const{    // we don't use heuristicContentMatch here since it is a) far too slow and    // b) having too much functionality for our case.    uchar* d = ( uchar* ) buffer.data();    int s = buffer.size();    if ( s >= 3 &&         d[0] == 0xef && d[1] == 0xbb && d[2] == 0xbf)         return QTextCodec::codecForMib( 106 ); // UTF-8    if ( s >= 2 && ((d[0] == 0xff && d[1] == 0xfe) ||                    (d[0] == 0xfe && d[1] == 0xff)))        return QTextCodec::codecForMib( 1000 ); // UCS-2    if(!charset.isEmpty())    {	QTextCodec* c = KGlobal::charsets()->codecForName(charset);        if(c->mibEnum() == 11)  {            // iso8859-8 (visually ordered)            c = QTextCodec::codecForName("iso8859-8-i");        }        return c;    }    return QTextCodec::codecForMib(4); // latin-1}// -------------------------------------------------------------------------------------------CachedCSSStyleSheet::CachedCSSStyleSheet(DocLoader* dl, const DOMString &url, KIO::CacheControl _cachePolicy,					 const char *accept)    : CachedObject(url, CSSStyleSheet, _cachePolicy, 0){    // Set the type we want (probably css or xml)    QString ah = QString::fromLatin1( accept );    if ( !ah.isEmpty() )        ah += ",";    ah += "*/*;q=0.1";    setAccept( ah );    m_hadError = false;    m_wasBlocked = false;    m_err = 0;    // load the file    Cache::loader()->load(dl, this, false);    m_loading = true;}CachedCSSStyleSheet::CachedCSSStyleSheet(const DOMString &url, const QString &stylesheet_data)    : CachedObject(url, CSSStyleSheet, KIO::CC_Verify, stylesheet_data.length()){    m_loading = false;    m_status = Persistent;    m_sheet = DOMString(stylesheet_data);}void CachedCSSStyleSheet::ref(CachedObjectClient *c){    CachedObject::ref(c);    if (!m_loading) {	if (m_hadError)	    c->error( m_err, m_errText );	else	    c->setStyleSheet( m_url, m_sheet );    }}void CachedCSSStyleSheet::data( QBuffer &buffer, bool eof ){    if(!eof) return;    buffer.close();    setSize(buffer.buffer().size());    QTextCodec* c = codecForBuffer( m_charset, buffer.buffer() );    QString data = c->toUnicode( buffer.buffer().data(), m_size );    // workaround Qt bugs    m_sheet = data[0] == QChar::byteOrderMark ? DOMString(data.mid( 1 ) ) : DOMString(data);    m_loading = false;    checkNotify();}void CachedCSSStyleSheet::checkNotify(){    if(m_loading || m_hadError) return;    CDEBUG << "CachedCSSStyleSheet:: finishedLoading " << m_url.string() << endl;    // it() first increments, then returnes the current item.    // this avoids skipping an item when setStyleSheet deletes the "current" one.    for (QPtrDictIterator<CachedObjectClient> it( m_clients ); it.current();)        it()->setStyleSheet( m_url, m_sheet );}void CachedCSSStyleSheet::error( int err, const char* text ){    m_hadError = true;    m_err = err;    m_errText = text;    m_loading = false;    // it() first increments, then returnes the current item.    // this avoids skipping an item when setStyleSheet deletes the "current" one.    for (QPtrDictIterator<CachedObjectClient> it( m_clients ); it.current();)        it()->error( m_err, m_errText );}// -------------------------------------------------------------------------------------------CachedScript::CachedScript(DocLoader* dl, const DOMString &url, KIO::CacheControl _cachePolicy, const char*)    : CachedObject(url, Script, _cachePolicy, 0){    // It's javascript we want.    // But some websites think their scripts are <some wrong mimetype here>    // and refuse to serve them if we only accept application/x-javascript.    setAccept( QString::fromLatin1("*/*") );    // load the file    Cache::loader()->load(dl, this, false);    m_loading = true;}CachedScript::CachedScript(const DOMString &url, const QString &script_data)    : CachedObject(url, Script, KIO::CC_Verify, script_data.length()){    m_loading = false;    m_status = Persistent;    m_script = DOMString(script_data);}void CachedScript::ref(CachedObjectClient *c){    CachedObject::ref(c);    if(!m_loading) c->notifyFinished(this);}void CachedScript::data( QBuffer &buffer, bool eof ){    if(!eof) return;    buffer.close();    setSize(buffer.buffer().size());    QTextCodec* c = codecForBuffer( m_charset, buffer.buffer() );    QString data = c->toUnicode( buffer.buffer().data(), m_size );    m_script = data[0] == QChar::byteOrderMark ? DOMString(data.mid( 1 ) ) : DOMString(data);    m_loading = false;    checkNotify();}void CachedScript::checkNotify(){    if(m_loading) return;    for (QPtrDictIterator<CachedObjectClient> it( m_clients); it.current();)        it()->notifyFinished(this);}void CachedScript::error( int /*err*/, const char* /*text*/ ){    m_loading = false;    checkNotify();}// ------------------------------------------------------------------------------------------namespace khtml{class ImageSource : public QDataSource{public:    ImageSource(QByteArray buf)        : buffer( buf ), pos( 0 ), eof( false ), rew(false ), rewable( true )        {}    int readyToSend()    {       if(eof && pos == buffer.size())           return -1;        return  buffer.size() - pos;    }    void sendTo(QDataSink* sink, int n)    {        sink->receive((const uchar*)&buffer.at(pos), n);        pos += n;        // buffer is no longer needed        if(eof && pos == buffer.size() && !rewable)        {            buffer.resize(0);            pos = 0;        }    }    /**     * Sets the EOF state.     */    void setEOF( bool state ) { eof = state; }    bool rewindable() const { return rewable; }    void enableRewind(bool on) { rew = on; }    /*      Calls reset() on the QIODevice.    */    void rewind()    {        pos = 0;        if (!rew) {            QDataSource::rewind();        } else            ready();    }    /*      Indicates that the buffered data is no longer      needed.    */    void cleanBuffer()    {        // if we need to be able to rewind, buffer is needed        if(rew)            return;        rewable = false;        // buffer is no longer needed        if(eof && pos == buffer.size())        {            buffer.resize(0);            pos = 0;        }    }    QByteArray buffer;    unsigned int pos;private:    bool eof     : 1;    bool rew     : 1;    bool rewable : 1;};} // end namespacestatic QString buildAcceptHeader(){    return "image/png, image/jpeg, video/x-mng, image/jp2, image/gif;q=0.5,*/*;q=0.1";}// -------------------------------------------------------------------------------------CachedImage::CachedImage(DocLoader* dl, const DOMString &url, KIO::CacheControl _cachePolicy, const char*)    : QObject(), CachedObject(url, Image, _cachePolicy, 0){    static const QString &acceptHeader = KGlobal::staticQString( buildAcceptHeader() );    m = 0;    p = 0;    pixPart = 0;    bg = 0;    bgColor = qRgba( 0, 0, 0, 0xFF );    typeChecked = false;    isFullyTransparent = false;    monochrome = false;    formatType = 0;    m_status = Unknown;    imgSource = 0;    setAccept( acceptHeader );    m_showAnimations = dl->showAnimations();    if ( KHTMLFactory::defaultHTMLSettings()->isAdFiltered( url.string() ) ) {        m_wasBlocked = true;        CachedObject::finish();    }}CachedImage::~CachedImage(){    clear();}void CachedImage::ref( CachedObjectClient *c ){    CachedObject::ref(c);    if( m ) {        m->unpause();        if( m->finished() || m_clients.count() == 1 )            m->restart();    }    // for mouseovers, dynamic changes    if ( m_status >= Persistent && !valid_rect().isNull() ) {        c->setPixmap( pixmap(), valid_rect(), this);        c->notifyFinished( this );    }}void CachedImage::deref( CachedObjectClient *c ){    CachedObject::deref(c);    if(m && m_clients.isEmpty() && m->running())        m->pause();}#define BGMINWIDTH      32#define BGMINHEIGHT     32const QPixmap &CachedImage::tiled_pixmap(const QColor& newc){    static QRgb bgTransparant = qRgba( 0, 0, 0, 0xFF );    if ( (bgColor != bgTransparant) && (bgColor != newc.rgb()) ) {        delete bg; bg = 0;    }    if (bg)        return *bg;    const QPixmap &r = pixmap();    if (r.isNull()) return r;    // no error indication for background images    if(m_hadError||m_wasBlocked) return *Cache::nullPixmap;    bool isvalid = newc.isValid();    QSize s(pixmap_size());    int w = r.width();    int h = r.height();    if ( w*h < 8192 )    {        if ( r.width() < BGMINWIDTH )            w = ((BGMINWIDTH  / s.width())+1) * s.width();        if ( r.height() < BGMINHEIGHT )            h = ((BGMINHEIGHT / s.height())+1) * s.height();    }#ifdef Q_WS_X11    if ( r.hasAlphaChannel() &&         ((w != r.width()) || (h != r.height())) )    {        bg = new QPixmap(w, h);        //Tile horizontally on the first stripe

⌨️ 快捷键说明

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