• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdehtml
 

tdehtml

  • tdehtml
tdehtml_pagecache.cpp
1/* This file is part of the KDE project
2 *
3 * Copyright (C) 2000 Waldo Bastian <bastian@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "tdehtml_pagecache.h"
22
23#include <kstaticdeleter.h>
24#include <tdetempfile.h>
25#include <tdestandarddirs.h>
26
27#include <tqintdict.h>
28#include <tqtimer.h>
29
30#include <sys/types.h>
31#include <unistd.h>
32#include <assert.h>
33
34// We keep 12 pages in memory.
35#ifndef TDEHTML_PAGE_CACHE_SIZE
36#define TDEHTML_PAGE_CACHE_SIZE 12
37#endif
38
39template class TQPtrList<TDEHTMLPageCacheDelivery>;
40class TDEHTMLPageCacheEntry
41{
42 friend class TDEHTMLPageCache;
43public:
44 TDEHTMLPageCacheEntry(long id);
45
46 ~TDEHTMLPageCacheEntry();
47
48 void addData(const TQByteArray &data);
49
50 void endData();
51
52 bool isComplete()
53 { return m_complete; }
54
55 TDEHTMLPageCacheDelivery *fetchData(TQObject *recvObj, const char *recvSlot);
56private:
57 long m_id;
58 bool m_complete;
59 TQValueList<TQByteArray> m_data;
60 KTempFile *m_file;
61};
62
63class TDEHTMLPageCachePrivate
64{
65public:
66 long newId;
67 TQIntDict<TDEHTMLPageCacheEntry> dict;
68 TQPtrList<TDEHTMLPageCacheDelivery> delivery;
69 TQPtrList<TDEHTMLPageCacheEntry> expireQueue;
70 bool deliveryActive;
71};
72
73TDEHTMLPageCacheEntry::TDEHTMLPageCacheEntry(long id) : m_id(id), m_complete(false)
74{
75 TQString path = locateLocal("tmp", "tdehtmlcache");
76 m_file = new KTempFile(path);
77 m_file->unlink();
78}
79
80TDEHTMLPageCacheEntry::~TDEHTMLPageCacheEntry()
81{
82 delete m_file;
83}
84
85
86void
87TDEHTMLPageCacheEntry::addData(const TQByteArray &data)
88{
89 if (m_file->status() == 0)
90 m_file->dataStream()->writeRawBytes(data.data(), data.size());
91}
92
93void
94TDEHTMLPageCacheEntry::endData()
95{
96 m_complete = true;
97 if ( m_file->status() == 0) {
98 m_file->dataStream()->device()->flush();
99 m_file->dataStream()->device()->at(0);
100 }
101}
102
103
104TDEHTMLPageCacheDelivery *
105TDEHTMLPageCacheEntry::fetchData(TQObject *recvObj, const char *recvSlot)
106{
107 // Duplicate fd so that entry can be safely deleted while delivering the data.
108 int fd = dup(m_file->handle());
109 lseek(fd, 0, SEEK_SET);
110 TDEHTMLPageCacheDelivery *delivery = new TDEHTMLPageCacheDelivery(fd);
111 recvObj->connect(delivery, TQ_SIGNAL(emitData(const TQByteArray&)), recvSlot);
112 delivery->recvObj = recvObj;
113 return delivery;
114}
115
116static KStaticDeleter<TDEHTMLPageCache> pageCacheDeleter;
117
118TDEHTMLPageCache *TDEHTMLPageCache::_self = 0;
119
120TDEHTMLPageCache *
121TDEHTMLPageCache::self()
122{
123 if (!_self)
124 _self = pageCacheDeleter.setObject(_self, new TDEHTMLPageCache);
125 return _self;
126}
127
128TDEHTMLPageCache::TDEHTMLPageCache()
129{
130 d = new TDEHTMLPageCachePrivate;
131 d->newId = 1;
132 d->deliveryActive = false;
133}
134
135TDEHTMLPageCache::~TDEHTMLPageCache()
136{
137 d->delivery.setAutoDelete(true);
138 d->dict.setAutoDelete(true);
139 delete d;
140}
141
142long
143TDEHTMLPageCache::createCacheEntry()
144{
145 TDEHTMLPageCacheEntry *entry = new TDEHTMLPageCacheEntry(d->newId);
146 d->dict.insert(d->newId, entry);
147 d->expireQueue.append(entry);
148 if (d->expireQueue.count() > TDEHTML_PAGE_CACHE_SIZE)
149 {
150 TDEHTMLPageCacheEntry *entry = d->expireQueue.take(0);
151 d->dict.remove(entry->m_id);
152 delete entry;
153 }
154 return (d->newId++);
155}
156
157void
158TDEHTMLPageCache::addData(long id, const TQByteArray &data)
159{
160 TDEHTMLPageCacheEntry *entry = d->dict.find(id);
161 if (entry)
162 entry->addData(data);
163}
164
165void
166TDEHTMLPageCache::endData(long id)
167{
168 TDEHTMLPageCacheEntry *entry = d->dict.find(id);
169 if (entry)
170 entry->endData();
171}
172
173void
174TDEHTMLPageCache::cancelEntry(long id)
175{
176 TDEHTMLPageCacheEntry *entry = d->dict.take(id);
177 if (entry)
178 {
179 d->expireQueue.removeRef(entry);
180 delete entry;
181 }
182}
183
184bool
185TDEHTMLPageCache::isValid(long id)
186{
187 return (d->dict.find(id) != 0);
188}
189
190bool
191TDEHTMLPageCache::isComplete(long id)
192{
193 TDEHTMLPageCacheEntry *entry = d->dict.find(id);
194 if (entry)
195 return entry->isComplete();
196 return false;
197}
198
199void
200TDEHTMLPageCache::fetchData(long id, TQObject *recvObj, const char *recvSlot)
201{
202 TDEHTMLPageCacheEntry *entry = d->dict.find(id);
203 if (!entry || !entry->isComplete()) return;
204
205 // Make this entry the most recent entry.
206 d->expireQueue.removeRef(entry);
207 d->expireQueue.append(entry);
208
209 d->delivery.append( entry->fetchData(recvObj, recvSlot) );
210 if (!d->deliveryActive)
211 {
212 d->deliveryActive = true;
213 TQTimer::singleShot(20, this, TQ_SLOT(sendData()));
214 }
215}
216
217void
218TDEHTMLPageCache::cancelFetch(TQObject *recvObj)
219{
220 TDEHTMLPageCacheDelivery *next;
221 for(TDEHTMLPageCacheDelivery* delivery = d->delivery.first();
222 delivery;
223 delivery = next)
224 {
225 next = d->delivery.next();
226 if (delivery->recvObj == recvObj)
227 {
228 d->delivery.removeRef(delivery);
229 delete delivery;
230 }
231 }
232}
233
234void
235TDEHTMLPageCache::sendData()
236{
237 if (d->delivery.isEmpty())
238 {
239 d->deliveryActive = false;
240 return;
241 }
242 TDEHTMLPageCacheDelivery *delivery = d->delivery.take(0);
243 assert(delivery);
244
245 char buf[8192];
246 TQByteArray byteArray;
247
248 int n = read(delivery->fd, buf, 8192);
249
250 if ((n < 0) && (errno == EINTR))
251 {
252 // try again later
253 d->delivery.append( delivery );
254 }
255 else if (n <= 0)
256 {
257 // done.
258 delivery->emitData(byteArray); // Empty array
259 delete delivery;
260 }
261 else
262 {
263 byteArray.setRawData(buf, n);
264 delivery->emitData(byteArray);
265 byteArray.resetRawData(buf, n);
266 d->delivery.append( delivery );
267 }
268 TQTimer::singleShot(0, this, TQ_SLOT(sendData()));
269}
270
271void
272TDEHTMLPageCache::saveData(long id, TQDataStream *str)
273{
274 TDEHTMLPageCacheEntry *entry = d->dict.find(id);
275 assert(entry);
276
277 int fd = entry->m_file->handle();
278 if ( fd < 0 ) return;
279
280 off_t pos = lseek(fd, 0, SEEK_CUR);
281 lseek(fd, 0, SEEK_SET);
282
283 char buf[8192];
284
285 while(true)
286 {
287 int n = read(fd, buf, 8192);
288 if ((n < 0) && (errno == EINTR))
289 {
290 // try again
291 continue;
292 }
293 else if (n <= 0)
294 {
295 // done.
296 break;
297 }
298 else
299 {
300 str->writeRawBytes(buf, n);
301 }
302 }
303
304 if (pos != (off_t)-1)
305 lseek(fd, pos, SEEK_SET);
306}
307
308TDEHTMLPageCacheDelivery::~TDEHTMLPageCacheDelivery()
309{
310 close(fd);
311}
312
313#include "tdehtml_pagecache.moc"
KStaticDeleter
KTempFile
TDEHTMLPageCache
Singleton Object that handles a binary cache on top of the http cache management of tdeio.
Definition: tdehtml_pagecache.h:42
TDEHTMLPageCache::createCacheEntry
long createCacheEntry()
Create a new cache entry.
Definition: tdehtml_pagecache.cpp:143
TDEHTMLPageCache::isValid
bool isValid(long id)
Definition: tdehtml_pagecache.cpp:185
TDEHTMLPageCache::addData
void addData(long id, const TQByteArray &data)
Add data to the cache entry with id id.
Definition: tdehtml_pagecache.cpp:158
TDEHTMLPageCache::endData
void endData(long id)
Signal end of data for the cache entry with id id.
Definition: tdehtml_pagecache.cpp:166
TDEHTMLPageCache::saveData
void saveData(long id, TQDataStream *str)
Save the data of cache entry id to the datastream str.
Definition: tdehtml_pagecache.cpp:272
TDEHTMLPageCache::isComplete
bool isComplete(long id)
Definition: tdehtml_pagecache.cpp:191
TDEHTMLPageCache::self
static TDEHTMLPageCache * self()
static "constructor".
Definition: tdehtml_pagecache.cpp:121
TDEHTMLPageCache::fetchData
void fetchData(long id, TQObject *recvObj, const char *recvSlot)
Fetch data for cache entry id and send it to slot recvSlot in the object recvObj.
Definition: tdehtml_pagecache.cpp:200
TDEHTMLPageCache::cancelEntry
void cancelEntry(long id)
Cancel the entry.
Definition: tdehtml_pagecache.cpp:174
TDEHTMLPageCache::cancelFetch
void cancelFetch(TQObject *recvObj)
Cancel sending data to recvObj.
Definition: tdehtml_pagecache.cpp:218
locateLocal
TQString locateLocal(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())

tdehtml

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

tdehtml

Skip menu "tdehtml"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdehtml by doxygen 1.9.4
This website is maintained by Timothy Pearson.