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

KHTML

  • 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
43template class QList<KHTMLPageCacheDelivery*>;
44class KHTMLPageCacheEntry
45{
46 friend class KHTMLPageCache;
47public:
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);
59private:
60 long m_id;
61 bool m_complete;
62 QByteArray m_buffer;
63 QIODevice* m_file;
64 QString m_fileName;
65};
66
67class KHTMLPageCachePrivate
68{
69public:
70 long newId;
71 bool deliveryActive;
72 QHash<int, KHTMLPageCacheEntry*> dict;
73 QList<KHTMLPageCacheDelivery*> delivery;
74 QQueue<long> expireQueue;
75};
76
77KHTMLPageCacheEntry::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
92KHTMLPageCacheEntry::~KHTMLPageCacheEntry()
93{
94 delete m_file;
95 QFile::remove(m_fileName);
96}
97
98
99void
100KHTMLPageCacheEntry::addData(const QByteArray &data)
101{
102 m_buffer+=data;
103}
104
105void
106KHTMLPageCacheEntry::endData()
107{
108 m_complete = true;
109 m_file->write(m_buffer);
110 m_buffer.clear();
111 m_file->close();
112}
113
114
115KHTMLPageCacheDelivery *
116KHTMLPageCacheEntry::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
129KHTMLPageCache *
130KHTMLPageCache::self()
131{
132 K_GLOBAL_STATIC(KHTMLPageCache, _self)
133 return _self;
134}
135
136KHTMLPageCache::KHTMLPageCache()
137 :d( new KHTMLPageCachePrivate)
138{
139 d->newId = 1;
140 d->deliveryActive = false;
141}
142
143KHTMLPageCache::~KHTMLPageCache()
144{
145 qDeleteAll(d->dict);
146 qDeleteAll(d->delivery);
147 delete d;
148}
149
150long
151KHTMLPageCache::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
162void
163KHTMLPageCache::addData(long id, const QByteArray &data)
164{
165
166 KHTMLPageCacheEntry *entry = d->dict.value( id );
167 if (entry)
168 entry->addData(data);
169}
170
171void
172KHTMLPageCache::endData(long id)
173{
174 KHTMLPageCacheEntry *entry = d->dict.value( id );
175 if (entry)
176 entry->endData();
177}
178
179void
180KHTMLPageCache::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
190bool
191KHTMLPageCache::isValid(long id)
192{
193 return d->dict.contains(id);
194}
195
196bool
197KHTMLPageCache::isComplete(long id)
198{
199 KHTMLPageCacheEntry *entry = d->dict.value( id );
200 if (entry)
201 return entry->isComplete();
202 return false;
203}
204
205void
206KHTMLPageCache::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
223void
224KHTMLPageCache::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
237void
238KHTMLPageCache::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
266void
267KHTMLPageCache::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
289KHTMLPageCacheDelivery::~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)
KHTMLPageCacheDelivery
Definition: khtml_pagecache.h:114
KHTMLPageCacheDelivery::emitData
void emitData(const QByteArray &data)
KHTMLPageCacheDelivery::file
QIODevice * file
Definition: khtml_pagecache.h:126
KHTMLPageCacheDelivery::recvObj
QObject * recvObj
Definition: khtml_pagecache.h:125
KHTMLPageCacheDelivery::~KHTMLPageCacheDelivery
~KHTMLPageCacheDelivery()
Definition: khtml_pagecache.cpp:289
KHTMLPageCache
Singleton Object that handles a binary cache on top of the http cache management of kio.
Definition: khtml_pagecache.h:39
KHTMLPageCache::saveData
void saveData(long id, QDataStream *str)
Save the data of cache entry id to the datastream str.
Definition: khtml_pagecache.cpp:267
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
KHTMLPageCache::endData
void endData(long id)
Signal end of data for the cache entry with id id.
Definition: khtml_pagecache.cpp:172
KHTMLPageCache::addData
void addData(long id, const QByteArray &data)
Add data to the cache entry with id id.
Definition: khtml_pagecache.cpp:163
KHTMLPageCache::self
static KHTMLPageCache * self()
static "constructor".
Definition: khtml_pagecache.cpp:130
KHTMLPageCache::createCacheEntry
long createCacheEntry()
Create a new cache entry.
Definition: khtml_pagecache.cpp:151
KHTMLPageCache::cancelEntry
void cancelEntry(long id)
Cancel the entry.
Definition: khtml_pagecache.cpp:180
KHTMLPageCache::~KHTMLPageCache
~KHTMLPageCache()
Definition: khtml_pagecache.cpp:143
KHTMLPageCache::isComplete
bool isComplete(long id)
Definition: khtml_pagecache.cpp:197
KHTMLPageCache::isValid
bool isValid(long id)
Definition: khtml_pagecache.cpp:191
KHTMLPageCache::cancelFetch
void cancelFetch(QObject *recvObj)
Cancel sending data to recvObj.
Definition: khtml_pagecache.cpp:224
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, bool createDir, const KComponentData &cData=KGlobal::mainComponent())
QHash
QIODevice
QList
QObject
QTemporaryFile
assert
#define assert(x)
Definition: editor.cpp:43
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
kfilterdev.h
KHTML_PAGE_CACHE_SIZE
#define KHTML_PAGE_CACHE_SIZE
Definition: khtml_pagecache.cpp:40
khtml_pagecache.h
d
#define d
Definition: khtmlfind.cpp:42
kstandarddirs.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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