00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _khtml_loader_h
00026 #define _khtml_loader_h
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032 #include <time.h>
00033
00034 #include "loader_client.h"
00035 #ifdef HAVE_LIBJPEG
00036 #include "loader_jpeg.h"
00037 #endif
00038
00039 #include <stdlib.h>
00040 #include <qptrlist.h>
00041 #include <qobject.h>
00042 #include <qptrdict.h>
00043 #include <qdict.h>
00044 #include <qpixmap.h>
00045 #include <qbuffer.h>
00046 #include <qstringlist.h>
00047 #include <qtextcodec.h>
00048
00049 #include <kurl.h>
00050 #include <kio/global.h>
00051
00052 #include <khtml_settings.h>
00053 #include <dom/dom_string.h>
00054
00055 class QMovie;
00056 class KHTMLPart;
00057
00058 namespace KIO {
00059 class Job;
00060 class TransferJob;
00061 }
00062
00063 namespace DOM
00064 {
00065 class CSSStyleSheetImpl;
00066 class DocumentImpl;
00067 }
00068
00069 namespace khtml
00070 {
00071 class CachedObject;
00072 class Request;
00073 class DocLoader;
00074
00083 class CachedObject
00084 {
00085 public:
00086 enum Type {
00087 Image,
00088 CSSStyleSheet,
00089 Script
00090 };
00091
00092 enum Status {
00093 NotCached,
00094 Unknown,
00095 New,
00096 Pending,
00097 Persistent,
00098 Cached,
00099 Uncacheable
00100 };
00101
00102 CachedObject(const DOM::DOMString &url, Type type, KIO::CacheControl _cachePolicy, time_t _expireDate)
00103 {
00104 m_url = url;
00105 m_type = type;
00106 m_status = Pending;
00107 m_size = 0;
00108 m_cachePolicy = _cachePolicy;
00109 m_request = 0;
00110 m_expireDate = _expireDate;
00111 m_deleted = false;
00112 m_expireDateChanged = false;
00113 m_free = false;
00114 }
00115 virtual ~CachedObject() {
00116 if(m_deleted) abort();
00117 m_deleted = true;
00118 }
00119
00120 virtual void data( QBuffer &buffer, bool eof) = 0;
00121 virtual void error( int err, const char *text ) = 0;
00122
00123 const DOM::DOMString &url() const { return m_url; }
00124 Type type() const { return m_type; }
00125
00126 virtual void ref(CachedObjectClient *consumer) = 0;
00127 virtual void deref(CachedObjectClient *consumer) = 0;
00128
00129 int count() const { return m_clients.count(); }
00130
00131 void setStatus(Status s) { m_status = s; }
00132 Status status() const { return m_status; }
00133
00134 int size() const { return m_size; }
00135
00141 virtual void finish();
00142
00143 void setFree();
00144
00145 KIO::CacheControl cachePolicy() const { return m_cachePolicy; }
00146
00147 void setRequest(Request *_request);
00148
00149 bool canDelete() const { return (m_clients.count() == 0 && !m_request); }
00150
00151 void setExpireDate(time_t _expireDate, bool changeHttpCache);
00152
00153 bool isExpired() const;
00154
00155 virtual bool schedule() const { return false; }
00156
00160
00161 QString accept() const { return m_accept; }
00162 void setAccept(const QString &_accept) { m_accept = _accept; }
00163
00164 protected:
00165 QPtrList<CachedObjectClient> m_clients;
00166
00167 DOM::DOMString m_url;
00168 QString m_accept;
00169 Request *m_request;
00170 Type m_type;
00171 Status m_status;
00172 int m_size;
00173 time_t m_expireDate;
00174 KIO::CacheControl m_cachePolicy;
00175 bool m_deleted : 1;
00176 bool m_loading : 1;
00177 bool m_expireDateChanged : 1;
00178 bool m_free : 1;
00179 };
00180
00181
00185 class CachedCSSStyleSheet : public CachedObject
00186 {
00187 public:
00188 CachedCSSStyleSheet(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, time_t _expireDate, const QString& charset);
00189 CachedCSSStyleSheet(const DOM::DOMString &url, const QString &stylesheet_data);
00190 virtual ~CachedCSSStyleSheet();
00191
00192 const DOM::DOMString &sheet() const { return m_sheet; }
00193
00194 virtual void ref(CachedObjectClient *consumer);
00195 virtual void deref(CachedObjectClient *consumer);
00196
00197 virtual void data( QBuffer &buffer, bool eof );
00198 virtual void error( int err, const char *text );
00199
00200 virtual bool schedule() const { return true; }
00201
00202 void checkNotify();
00203
00204 protected:
00205 DOM::DOMString m_sheet;
00206 QTextCodec* m_codec;
00207 };
00208
00212 class CachedScript : public CachedObject
00213 {
00214 public:
00215 CachedScript(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, time_t _expireDate, const QString& charset);
00216 CachedScript(const DOM::DOMString &url, const QString &script_data);
00217 virtual ~CachedScript();
00218
00219 const DOM::DOMString &script() const { return m_script; }
00220
00221 virtual void ref(CachedObjectClient *consumer);
00222 virtual void deref(CachedObjectClient *consumer);
00223
00224 virtual void data( QBuffer &buffer, bool eof );
00225 virtual void error( int err, const char *text );
00226
00227 virtual bool schedule() const { return false; }
00228
00229 void checkNotify();
00230
00231 bool isLoaded() const { return !m_loading; }
00232
00233 protected:
00234 DOM::DOMString m_script;
00235 QTextCodec* m_codec;
00236 };
00237
00238 class ImageSource;
00239
00243 class CachedImage : public QObject, public CachedObject
00244 {
00245 Q_OBJECT
00246 public:
00247 CachedImage(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, time_t _expireDate);
00248 virtual ~CachedImage();
00249
00250 const QPixmap &pixmap() const;
00251 const QPixmap &tiled_pixmap(const QColor& bg);
00252
00253 QSize pixmap_size() const;
00254 QRect valid_rect() const;
00255
00256 void ref(CachedObjectClient *consumer);
00257 virtual void deref(CachedObjectClient *consumer);
00258
00259 virtual void data( QBuffer &buffer, bool eof );
00260 virtual void error( int err, const char *text );
00261
00262 bool isTransparent() const { return isFullyTransparent; }
00263 bool isErrorImage() const { return errorOccured; }
00264
00265 void setShowAnimations( KHTMLSettings::KAnimationAdvice );
00266
00267 virtual bool schedule() const { return true; }
00268
00269 virtual void finish();
00270
00271 protected:
00272 void clear();
00273
00274 private slots:
00278 void movieUpdated( const QRect &rect );
00279 void movieStatus(int);
00280 void movieResize(const QSize&);
00281 void deleteMovie();
00282
00283 private:
00284 void do_notify(const QPixmap& p, const QRect& r);
00285
00286 QMovie* m;
00287 QPixmap* p;
00288 QPixmap* bg;
00289 QRgb bgColor;
00290 mutable QPixmap* pixPart;
00291
00292 ImageSource* imgSource;
00293 const char* formatType;
00294
00295 int width;
00296 int height;
00297
00298
00299 bool typeChecked : 1;
00300 bool isFullyTransparent : 1;
00301 bool errorOccured : 1;
00302 bool monochrome : 1;
00303 KHTMLSettings::KAnimationAdvice m_showAnimations : 2;
00304
00305 friend class Cache;
00306 };
00307
00313 class DocLoader
00314 {
00315 public:
00316 DocLoader(KHTMLPart*, DOM::DocumentImpl*);
00317 ~DocLoader();
00318
00319 CachedImage *requestImage( const DOM::DOMString &url);
00320 CachedCSSStyleSheet *requestStyleSheet( const DOM::DOMString &url, const QString& charset);
00321 CachedScript *requestScript( const DOM::DOMString &url, const QString& charset);
00322
00323 bool autoloadImages() const { return m_bautoloadImages; }
00324 KIO::CacheControl cachePolicy() const { return m_cachePolicy; }
00325 KHTMLSettings::KAnimationAdvice showAnimations() const { return m_showAnimations; }
00326 time_t expireDate() const { return m_expireDate; }
00327 KHTMLPart* part() const { return m_part; }
00328 DOM::DocumentImpl* doc() const { return m_doc; }
00329
00330 void setCacheCreationDate( time_t );
00331 void setExpireDate( time_t, bool relative );
00332 void setAutoloadImages( bool );
00333 void setCachePolicy( KIO::CacheControl cachePolicy );
00334 void setShowAnimations( KHTMLSettings::KAnimationAdvice );
00335 void removeCachedObject( CachedObject*) const;
00336
00337 private:
00338 bool needReload(const KURL &fullUrl);
00339
00340 friend class Cache;
00341 friend class DOM::DocumentImpl;
00342
00343 QStringList m_reloadedURLs;
00344 mutable QPtrList<CachedObject> m_docObjects;
00345 time_t m_expireDate;
00346 time_t m_creationDate;
00347 KIO::CacheControl m_cachePolicy;
00348 bool m_bautoloadImages : 1;
00349 KHTMLSettings::KAnimationAdvice m_showAnimations : 2;
00350 KHTMLPart* m_part;
00351 DOM::DocumentImpl* m_doc;
00352 };
00353
00357 class Request
00358 {
00359 public:
00360 Request(DocLoader* dl, CachedObject *_object, bool _incremental);
00361 ~Request();
00362 bool incremental;
00363 QBuffer m_buffer;
00364 CachedObject *object;
00365 DocLoader* m_docLoader;
00366 };
00367
00371 class Loader : public QObject
00372 {
00373 Q_OBJECT
00374
00375 public:
00376 Loader();
00377 ~Loader();
00378
00379 void load(DocLoader* dl, CachedObject *object, bool incremental = true);
00380
00381 int numRequests( DocLoader* dl ) const;
00382 void cancelRequests( DocLoader* dl );
00383
00384
00385 KIO::Job *jobForRequest( const DOM::DOMString &url ) const;
00386
00387 signals:
00388 void requestStarted( khtml::DocLoader* dl, khtml::CachedObject* obj );
00389 void requestDone( khtml::DocLoader* dl, khtml::CachedObject *obj );
00390 void requestFailed( khtml::DocLoader* dl, khtml::CachedObject *obj );
00391
00392 protected slots:
00393 void slotFinished( KIO::Job * );
00394 void slotData( KIO::Job *, const QByteArray & );
00395 void servePendingRequests();
00396
00397 protected:
00398 QPtrList<Request> m_requestsPending;
00399 QPtrDict<Request> m_requestsLoading;
00400 #ifdef HAVE_LIBJPEG
00401 KJPEGFormatType m_jpegloader;
00402 #endif
00403 };
00404
00411 class Cache
00412 {
00413 friend class DocLoader;
00414 public:
00419 static void init();
00420
00427 static CachedImage *requestImage( DocLoader* l, const DOM::DOMString &url, bool reload=false, time_t _expireDate=0);
00428
00433 static CachedCSSStyleSheet *requestStyleSheet( DocLoader* l, const DOM::DOMString &url, bool reload=false, time_t _expireDate=0, const QString& charset = QString::null);
00434
00438 static void preloadStyleSheet(const QString &url, const QString &stylesheet_data);
00439
00444 static CachedScript *requestScript( DocLoader* l, const DOM::DOMString &url, bool reload=false, time_t _expireDate=0, const QString& charset=QString::null);
00445
00449 static void preloadScript(const QString &url, const QString &script_data);
00450
00455 static void setSize( int bytes );
00459 static int size() { return maxSize; };
00460
00464 static void statistics();
00465
00469 static void flush(bool force=false);
00470
00476 static void clear();
00477
00478 static Loader *loader() { return m_loader; }
00479
00480 static QPixmap *nullPixmap;
00481 static QPixmap *brokenPixmap;
00482 static int cacheSize;
00483
00484 static void removeCacheEntry( CachedObject *object );
00485
00486 protected:
00487
00488
00489
00490 class LRUList : public QStringList
00491 {
00492 public:
00497 void touch( const QString &url )
00498 {
00499 remove( url );
00500 prepend( url );
00501 }
00502 };
00503 private:
00504 friend class CachedObject;
00505 static void flushFreeList();
00506 static QPtrList<CachedObject> *freeList;
00507 static QDict<CachedObject> *cache;
00508 static LRUList *lru;
00509 static QPtrList<DocLoader>* docloader;
00510
00511 static int maxSize;
00512 static int flushCount;
00513
00514 static Loader *m_loader;
00515
00516 static unsigned long s_ulRefCnt;
00517 };
00518
00519 inline void CachedObject::setFree() {
00520 if ( !m_free ) {
00521 Cache::freeList->append(this);
00522 m_free = true;
00523 }
00524 }
00525
00526 }
00527
00528 #endif