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

khtml

  • khtml
khtml_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 "khtml_pagecache.h"
22 
23 #include <kstaticdeleter.h>
24 #include <ktempfile.h>
25 #include <kstandarddirs.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 KHTML_PAGE_CACHE_SIZE
36 #define KHTML_PAGE_CACHE_SIZE 12
37 #endif
38 
39 template class TQPtrList<KHTMLPageCacheDelivery>;
40 class KHTMLPageCacheEntry
41 {
42  friend class KHTMLPageCache;
43 public:
44  KHTMLPageCacheEntry(long id);
45 
46  ~KHTMLPageCacheEntry();
47 
48  void addData(const TQByteArray &data);
49 
50  void endData();
51 
52  bool isComplete()
53  { return m_complete; }
54 
55  KHTMLPageCacheDelivery *fetchData(TQObject *recvObj, const char *recvSlot);
56 private:
57  long m_id;
58  bool m_complete;
59  TQValueList<TQByteArray> m_data;
60  KTempFile *m_file;
61 };
62 
63 class KHTMLPageCachePrivate
64 {
65 public:
66  long newId;
67  TQIntDict<KHTMLPageCacheEntry> dict;
68  TQPtrList<KHTMLPageCacheDelivery> delivery;
69  TQPtrList<KHTMLPageCacheEntry> expireQueue;
70  bool deliveryActive;
71 };
72 
73 KHTMLPageCacheEntry::KHTMLPageCacheEntry(long id) : m_id(id), m_complete(false)
74 {
75  TQString path = locateLocal("tmp", "khtmlcache");
76  m_file = new KTempFile(path);
77  m_file->unlink();
78 }
79 
80 KHTMLPageCacheEntry::~KHTMLPageCacheEntry()
81 {
82  delete m_file;
83 }
84 
85 
86 void
87 KHTMLPageCacheEntry::addData(const TQByteArray &data)
88 {
89  if (m_file->status() == 0)
90  m_file->dataStream()->writeRawBytes(data.data(), data.size());
91 }
92 
93 void
94 KHTMLPageCacheEntry::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 
104 KHTMLPageCacheDelivery *
105 KHTMLPageCacheEntry::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  KHTMLPageCacheDelivery *delivery = new KHTMLPageCacheDelivery(fd);
111  recvObj->connect(delivery, TQT_SIGNAL(emitData(const TQByteArray&)), recvSlot);
112  delivery->recvObj = recvObj;
113  return delivery;
114 }
115 
116 static KStaticDeleter<KHTMLPageCache> pageCacheDeleter;
117 
118 KHTMLPageCache *KHTMLPageCache::_self = 0;
119 
120 KHTMLPageCache *
121 KHTMLPageCache::self()
122 {
123  if (!_self)
124  _self = pageCacheDeleter.setObject(_self, new KHTMLPageCache);
125  return _self;
126 }
127 
128 KHTMLPageCache::KHTMLPageCache()
129 {
130  d = new KHTMLPageCachePrivate;
131  d->newId = 1;
132  d->deliveryActive = false;
133 }
134 
135 KHTMLPageCache::~KHTMLPageCache()
136 {
137  d->delivery.setAutoDelete(true);
138  d->dict.setAutoDelete(true);
139  delete d;
140 }
141 
142 long
143 KHTMLPageCache::createCacheEntry()
144 {
145  KHTMLPageCacheEntry *entry = new KHTMLPageCacheEntry(d->newId);
146  d->dict.insert(d->newId, entry);
147  d->expireQueue.append(entry);
148  if (d->expireQueue.count() > KHTML_PAGE_CACHE_SIZE)
149  {
150  KHTMLPageCacheEntry *entry = d->expireQueue.take(0);
151  d->dict.remove(entry->m_id);
152  delete entry;
153  }
154  return (d->newId++);
155 }
156 
157 void
158 KHTMLPageCache::addData(long id, const TQByteArray &data)
159 {
160  KHTMLPageCacheEntry *entry = d->dict.find(id);
161  if (entry)
162  entry->addData(data);
163 }
164 
165 void
166 KHTMLPageCache::endData(long id)
167 {
168  KHTMLPageCacheEntry *entry = d->dict.find(id);
169  if (entry)
170  entry->endData();
171 }
172 
173 void
174 KHTMLPageCache::cancelEntry(long id)
175 {
176  KHTMLPageCacheEntry *entry = d->dict.take(id);
177  if (entry)
178  {
179  d->expireQueue.removeRef(entry);
180  delete entry;
181  }
182 }
183 
184 bool
185 KHTMLPageCache::isValid(long id)
186 {
187  return (d->dict.find(id) != 0);
188 }
189 
190 bool
191 KHTMLPageCache::isComplete(long id)
192 {
193  KHTMLPageCacheEntry *entry = d->dict.find(id);
194  if (entry)
195  return entry->isComplete();
196  return false;
197 }
198 
199 void
200 KHTMLPageCache::fetchData(long id, TQObject *recvObj, const char *recvSlot)
201 {
202  KHTMLPageCacheEntry *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, TQT_SLOT(sendData()));
214  }
215 }
216 
217 void
218 KHTMLPageCache::cancelFetch(TQObject *recvObj)
219 {
220  KHTMLPageCacheDelivery *next;
221  for(KHTMLPageCacheDelivery* 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 
234 void
235 KHTMLPageCache::sendData()
236 {
237  if (d->delivery.isEmpty())
238  {
239  d->deliveryActive = false;
240  return;
241  }
242  KHTMLPageCacheDelivery *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, TQT_SLOT(sendData()));
269 }
270 
271 void
272 KHTMLPageCache::saveData(long id, TQDataStream *str)
273 {
274  KHTMLPageCacheEntry *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 
308 KHTMLPageCacheDelivery::~KHTMLPageCacheDelivery()
309 {
310  close(fd);
311 }
312 
313 #include "khtml_pagecache.moc"

khtml

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

khtml

Skip menu "khtml"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for khtml by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |