• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • sources
  • kde-4.12
  • kdelibs
  • khtml
khtml_pagecache.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2000 Waldo Bastian <bastian@kde.org>
4  * Copyright (C) 2007 Nick Shaforostoff <shafff@ukr.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "khtml_pagecache.h"
23 
24 #include <kfilterdev.h>
25 #include <QTemporaryFile>
26 #include <kstandarddirs.h>
27 
28 #include <QQueue>
29 #include <QHash>
30 #include <QList>
31 #include <QtCore/QTimer>
32 #include <QtCore/QFile>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 #include <assert.h>
37 
38 // We keep 12 pages in memory.
39 #ifndef KHTML_PAGE_CACHE_SIZE
40 #define KHTML_PAGE_CACHE_SIZE 12
41 #endif
42 
43 template class QList<KHTMLPageCacheDelivery*>;
44 class KHTMLPageCacheEntry
45 {
46  friend class KHTMLPageCache;
47 public:
48  KHTMLPageCacheEntry(long id);
49 
50  ~KHTMLPageCacheEntry();
51 
52  void addData(const QByteArray &data);
53  void endData();
54 
55  bool isComplete() const {return m_complete;}
56  QString fileName() const {return m_fileName;}
57 
58  KHTMLPageCacheDelivery *fetchData(QObject *recvObj, const char *recvSlot);
59 private:
60  long m_id;
61  bool m_complete;
62  QByteArray m_buffer;
63  QIODevice* m_file;
64  QString m_fileName;
65 };
66 
67 class KHTMLPageCachePrivate
68 {
69 public:
70  long newId;
71  bool deliveryActive;
72  QHash<int, KHTMLPageCacheEntry*> dict;
73  QList<KHTMLPageCacheDelivery*> delivery;
74  QQueue<long> expireQueue;
75 };
76 
77 KHTMLPageCacheEntry::KHTMLPageCacheEntry(long id)
78  : m_id(id)
79  , m_complete(false)
80 {
81  //get tmp file name
82  QTemporaryFile* f=new QTemporaryFile(KStandardDirs::locateLocal("tmp", "")+"khtmlcacheXXXXXX.tmp");
83  f->open();
84  m_fileName=f->fileName();
85  f->setAutoRemove(false);
86  delete f;
87 
88  m_file = KFilterDev::deviceForFile(m_fileName, "application/x-gzip"/*,false*/);
89  m_file->open(QIODevice::WriteOnly);
90 }
91 
92 KHTMLPageCacheEntry::~KHTMLPageCacheEntry()
93 {
94  delete m_file;
95  QFile::remove(m_fileName);
96 }
97 
98 
99 void
100 KHTMLPageCacheEntry::addData(const QByteArray &data)
101 {
102  m_buffer+=data;
103 }
104 
105 void
106 KHTMLPageCacheEntry::endData()
107 {
108  m_complete = true;
109  m_file->write(m_buffer);
110  m_buffer.clear();
111  m_file->close();
112 }
113 
114 
115 KHTMLPageCacheDelivery *
116 KHTMLPageCacheEntry::fetchData(QObject *recvObj, const char *recvSlot)
117 {
118  // Duplicate fd so that entry can be safely deleted while delivering the data.
119  KHTMLPageCacheDelivery *delivery=new KHTMLPageCacheDelivery(
120  KFilterDev::deviceForFile (m_fileName, "application/x-gzip")
121  );
122  delivery->file->open(QIODevice::ReadOnly);
123 
124  recvObj->connect(delivery, SIGNAL(emitData(QByteArray)), recvSlot);
125  delivery->recvObj = recvObj;
126  return delivery;
127 }
128 
129 KHTMLPageCache *
130 KHTMLPageCache::self()
131 {
132  K_GLOBAL_STATIC(KHTMLPageCache, _self)
133  return _self;
134 }
135 
136 KHTMLPageCache::KHTMLPageCache()
137  :d( new KHTMLPageCachePrivate)
138 {
139  d->newId = 1;
140  d->deliveryActive = false;
141 }
142 
143 KHTMLPageCache::~KHTMLPageCache()
144 {
145  qDeleteAll(d->dict);
146  qDeleteAll(d->delivery);
147  delete d;
148 }
149 
150 long
151 KHTMLPageCache::createCacheEntry()
152 {
153 
154  KHTMLPageCacheEntry *entry = new KHTMLPageCacheEntry(d->newId);
155  d->dict.insert(d->newId, entry);
156  d->expireQueue.append(d->newId);
157  if (d->expireQueue.count() > KHTML_PAGE_CACHE_SIZE)
158  delete d->dict.take(d->expireQueue.dequeue());
159  return (d->newId++);
160 }
161 
162 void
163 KHTMLPageCache::addData(long id, const QByteArray &data)
164 {
165 
166  KHTMLPageCacheEntry *entry = d->dict.value( id );
167  if (entry)
168  entry->addData(data);
169 }
170 
171 void
172 KHTMLPageCache::endData(long id)
173 {
174  KHTMLPageCacheEntry *entry = d->dict.value( id );
175  if (entry)
176  entry->endData();
177 }
178 
179 void
180 KHTMLPageCache::cancelEntry(long id)
181 {
182  KHTMLPageCacheEntry *entry = d->dict.take( id );
183  if (entry)
184  {
185  d->expireQueue.removeAll(entry->m_id);
186  delete entry;
187  }
188 }
189 
190 bool
191 KHTMLPageCache::isValid(long id)
192 {
193  return d->dict.contains(id);
194 }
195 
196 bool
197 KHTMLPageCache::isComplete(long id)
198 {
199  KHTMLPageCacheEntry *entry = d->dict.value( id );
200  if (entry)
201  return entry->isComplete();
202  return false;
203 }
204 
205 void
206 KHTMLPageCache::fetchData(long id, QObject *recvObj, const char *recvSlot)
207 {
208  KHTMLPageCacheEntry *entry = d->dict.value( id );
209  if (!entry || !entry->isComplete()) return;
210 
211  // Make this entry the most recent entry.
212  d->expireQueue.removeAll(entry->m_id);
213  d->expireQueue.enqueue(entry->m_id);
214 
215  d->delivery.append( entry->fetchData(recvObj, recvSlot) );
216  if (!d->deliveryActive)
217  {
218  d->deliveryActive = true;
219  QTimer::singleShot(20, this, SLOT(sendData()));
220  }
221 }
222 
223 void
224 KHTMLPageCache::cancelFetch(QObject *recvObj)
225 {
226  QMutableListIterator<KHTMLPageCacheDelivery*> it( d->delivery );
227  while (it.hasNext()) {
228  KHTMLPageCacheDelivery* delivery = it.next();
229  if (delivery->recvObj == recvObj)
230  {
231  delete delivery;
232  it.remove();
233  }
234  }
235 }
236 
237 void
238 KHTMLPageCache::sendData()
239 {
240  if (d->delivery.isEmpty())
241  {
242  d->deliveryActive = false;
243  return;
244  }
245 
246  KHTMLPageCacheDelivery *delivery = d->delivery.takeFirst();
247  assert(delivery);
248 
249  QByteArray byteArray(delivery->file->read(64*1024));
250  delivery->emitData(byteArray);
251 
252  //put back in queue
253  if (delivery->file->atEnd())
254  {
255  // done.
256  delivery->file->close();
257  delivery->emitData(QByteArray()); // Empty array
258  delete delivery;
259  }
260  else
261  d->delivery.append( delivery );
262 
263  QTimer::singleShot(0, this, SLOT(sendData()));
264 }
265 
266 void
267 KHTMLPageCache::saveData(long id, QDataStream *str)
268 {
269  assert(d->dict.contains( id ));
270  KHTMLPageCacheEntry *entry = d->dict.value( id );
271 
272  if (!entry->isComplete())
273  {
274  QTimer::singleShot(20, this, SLOT(saveData()));
275  return;
276  }
277 
278  QIODevice* file = KFilterDev::deviceForFile (entry->fileName(), "application/x-gzip");
279  if (!file->open(QIODevice::ReadOnly))
280  return;
281 
282  QByteArray byteArray(file->readAll());
283  file->close();
284 
285  str->writeRawData(byteArray.constData(), byteArray.length());
286 
287 }
288 
289 KHTMLPageCacheDelivery::~KHTMLPageCacheDelivery()
290 {
291  file->close();
292  delete file;
293 }
294 
295 #include "khtml_pagecache.moc"
KFilterDev::deviceForFile
static QIODevice * deviceForFile(const QString &fileName, const QString &mimetype=QString(), bool forceFilter=false)
KHTMLPageCache::fetchData
void fetchData(long id, QObject *recvObj, const char *recvSlot)
Fetch data for cache entry id and send it to slot recvSlot in the object recvObj. ...
Definition: khtml_pagecache.cpp:206
khtml_pagecache.h
KHTMLPageCache::self
static KHTMLPageCache * self()
static "constructor".
Definition: khtml_pagecache.cpp:130
kfilterdev.h
assert
#define assert(x)
Definition: editor.cpp:43
d
#define d
Definition: khtmlfind.cpp:42
KHTMLPageCacheDelivery::emitData
void emitData(const QByteArray &data)
QTemporaryFile
KHTMLPageCacheDelivery::file
QIODevice * file
Definition: khtml_pagecache.h:126
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
QString
QHash< int, KHTMLPageCacheEntry * >
QObject
KHTMLPageCache::isComplete
bool isComplete(long id)
Definition: khtml_pagecache.cpp:197
KHTMLPageCache::isValid
bool isValid(long id)
Definition: khtml_pagecache.cpp:191
KHTMLPageCacheDelivery
Definition: khtml_pagecache.h:113
KHTMLPageCache::cancelFetch
void cancelFetch(QObject *recvObj)
Cancel sending data to recvObj.
Definition: khtml_pagecache.cpp:224
KHTMLPageCache::cancelEntry
void cancelEntry(long id)
Cancel the entry.
Definition: khtml_pagecache.cpp:180
KHTMLPageCache::~KHTMLPageCache
~KHTMLPageCache()
Definition: khtml_pagecache.cpp:143
KHTMLPageCache
Singleton Object that handles a binary cache on top of the http cache management of kio...
Definition: khtml_pagecache.h:38
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
kstandarddirs.h
KHTMLPageCache::createCacheEntry
long createCacheEntry()
Create a new cache entry.
Definition: khtml_pagecache.cpp:151
KHTML_PAGE_CACHE_SIZE
#define KHTML_PAGE_CACHE_SIZE
Definition: khtml_pagecache.cpp:40
KHTMLPageCache::saveData
void saveData(long id, QDataStream *str)
Save the data of cache entry id to the datastream str.
Definition: khtml_pagecache.cpp:267
KHTMLPageCacheDelivery::recvObj
QObject * recvObj
Definition: khtml_pagecache.h:125
QIODevice
KHTMLPageCache::addData
void addData(long id, const QByteArray &data)
Add data to the cache entry with id id.
Definition: khtml_pagecache.cpp:163
KHTMLPageCacheDelivery::~KHTMLPageCacheDelivery
~KHTMLPageCacheDelivery()
Definition: khtml_pagecache.cpp:289
KHTMLPageCache::endData
void endData(long id)
Signal end of data for the cache entry with id id.
Definition: khtml_pagecache.cpp:172
QList< KHTMLPageCacheDelivery * >
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:51:21 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal