summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/CHM.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/CHM.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/CHM.cpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/CHM.cpp b/noncore/apps/opie-reader/CHM.cpp
new file mode 100644
index 0000000..9d1eb87
--- a/dev/null
+++ b/noncore/apps/opie-reader/CHM.cpp
@@ -0,0 +1,380 @@
1#include "CHM.h"
2#include "chm_lib.h"
3#include "static.h"
4#include <qstring.h>
5#include <qstringlist.h>
6#include <stdio.h>
7#include <qimage.h>
8#include <qpixmap.h>
9
10#ifndef __STATIC
11extern "C"
12{
13 CExpander* newcodec() { return new CHM; }
14}
15#endif
16
17static int _print_ui_index(struct chmFile *h, struct chmUnitInfo *ui,
18 void *context)
19{
20 CHM *chm = (CHM *)context;
21 QString temp = "<tr>";
22 char buff[1024];
23 sprintf( buff,"<td align=right>%8d\n</td><td><a href=\"%s\">%s</a></td></tr>",(int)ui->length, ui->path, ui->path);
24 temp += buff;
25 chm->addContent(temp);
26 return CHM_ENUMERATOR_CONTINUE;
27}
28
29static int _get_hhc (struct chmFile *h, struct chmUnitInfo *ui,
30 void *context)
31{
32 CHM *chm = (CHM *)context;
33 QString PathName = ui->path;
34 if (PathName.find(".hhc") > -1) {
35 chm->setPath(PathName);
36 }
37 return CHM_ENUMERATOR_CONTINUE;
38}
39
40CHM::CHM() {
41 chmFile = NULL;
42 chmPath = "";
43 chmHHCPath = "";
44 chmBuffer = "";
45 bufpos = 0;
46}
47
48CHM::~CHM() {
49 if (chmFile != NULL)
50 chm_close(chmFile);
51}
52
53void CHM::suspend() {
54#ifdef USEQPE
55 bSuspended = true;
56 //suspos = gztell(file);
57 chm_close(chmFile);
58 chmFile = NULL;
59 sustime = time(NULL);
60#endif
61}
62
63void CHM::unsuspend() {
64#ifdef USEQPE
65 if (bSuspended)
66 {
67 bSuspended = false;
68 int delay = time(NULL) - sustime;
69 if (delay < 10)
70 sleep(10-delay);
71 chmFile = chm_open(fname);
72 for (int i = 0; chmFile == NULL && i < 5; i++) {
73 sleep(5);
74 chmFile = chm_open(fname);
75 }
76 if (chmFile == NULL) {
77 QMessageBox::warning(NULL, PROGNAME, "Couldn't reopen file");
78 exit(0);
79 }
80 //suspos = gzseek(file, suspos, SEEK_SET);
81 }
82#endif
83}
84
85void CHM::addContent(QString content) {
86 chmBuffer += content;
87}
88
89void CHM::FillHomeContent() {
90 if (chmHHCPath != "") {
91 const char *ext;
92 char buffer[65536];
93 unsigned int swath, offset;
94 QString tmp="";
95 QString HTML="";
96 /* try to find the file */
97 const char *filename = (const char *)chmHHCPath;
98 if (chm_resolve_object(chmFile, filename, &m_ui) != CHM_RESOLVE_SUCCESS)
99 {
100 chmBuffer = "HELP";
101 fsize = chmBuffer.length();
102 return;
103 }
104 m_homestart = m_ui.start;
105 m_homeend = m_homestart + m_ui.length;
106 swath = 65536;
107 offset = 0;
108 fsize = m_ui.length;
109 while (offset < m_ui.length)
110 {
111 if ((m_ui.length - offset) < 65536)
112 swath = m_ui.length - offset;
113 else
114 swath = 65536;
115 swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath);
116 tmp += buffer;
117 offset += swath;
118 }
119 HTML +="<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN>\r\n";
120 HTML +="<HTML>\r\n";
121 HTML +="<BODY>\r\n";
122 HTML +="<h2>Home Page</h2>\r\n";
123 HTML +="<h3>\r\n";
124 QStringList qsl = QStringList::split("\r\n",tmp);
125 QString NameFind ="<param name=\"Name\" value=\"";
126 QString LocalFind = "<param name=\"Local\" value=\"";
127 QString ULOpenFind = "<UL>";
128 QString LIOpenFind = "<LI>";
129 QString ULCloseFind = "</UL>";
130 QString Name = "";
131 QString Local = "";
132 for ( QStringList::Iterator it = qsl.begin(); it != qsl.end(); ++it ) {
133 QString Line = (*it);
134 int NamePos = Line.find( NameFind);
135 int LocalPos = Line.find( LocalFind);
136 if (NamePos > -1) {
137 Name = Line.mid(NamePos+NameFind.length(),Line.length());
138 Name = Name.left(Name.length() - 2);
139 }
140 if (LocalPos > -1) {
141 Local = Line.mid(LocalPos+LocalFind.length(),Line.length());
142 Local = Local.left(Local.length() - 2);
143 if (Name != "") {
144 HTML += "<br>\r\n<a href=";
145 HTML += Local;
146 HTML += ">";
147 HTML += Name;
148 HTML += "</a>\r\n";
149 Name = "";
150 }
151 }
152 }
153 HTML +="</h3>";
154 HTML +="</BODY>\r\n";
155 HTML +="</HTML>\r\n";
156 chmHomeBuffer = HTML;
157 chmBuffer = HTML;
158 fsize = chmBuffer.length();
159 m_currentstart = m_ui.start;
160 m_currentend = m_currentstart+chmBuffer.length();
161 }
162}
163
164bool CHM::FillBuffer()
165{
166 bool bRetVal = false;
167 char buffer[65536];
168 int swath, offset;
169 chmBuffer = "";
170 swath = 65536;
171 offset = 0;
172 fsize = m_ui.length;
173 while (offset < m_ui.length)
174 {
175 if ((m_ui.length - offset) < 65536)
176 swath = m_ui.length - offset;
177 else
178 swath = 65536;
179 swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath);
180 chmBuffer += buffer;
181 offset += swath;
182 }
183 //There seems to be a ton of gobbledygook at the end that is reminiscent of the hhc file - remove it
184 QString temp = chmBuffer.lower();
185 int lpos = temp.find("</html");
186 if (lpos > -1) {
187 chmBuffer.truncate(lpos);
188 chmBuffer = chmBuffer+"</HTML>";
189 }
190 fsize = chmBuffer.length();
191
192 bufpos = 0;
193 bRetVal = true;
194 m_currentstart = m_ui.start;
195 m_currentend = m_currentstart+chmBuffer.length();
196 return bRetVal;
197}
198
199bool CHM::FillContent() {
200 bool bRetVal = false;
201 if (chmPath != "") {
202 /* try to find the file */
203 const char *filename = (const char *)chmPath;
204 if (chm_resolve_object(chmFile, filename, &m_ui) != CHM_RESOLVE_SUCCESS)
205 {
206 fsize = chmBuffer.length();
207 return bRetVal;
208 }
209
210 char buffer[65536];
211 int swath, offset;
212 chmBuffer = "";
213 swath = 65536;
214 offset = 0;
215 fsize = m_ui.length;
216 while (offset < m_ui.length)
217 {
218 if ((m_ui.length - offset) < 65536)
219 swath = m_ui.length - offset;
220 else
221 swath = 65536;
222 swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath);
223 chmBuffer += buffer;
224 offset += swath;
225 }
226 //There seems to be a ton of gobbledygook at the end that is reminiscent of the hhc file - remove it
227 QString temp = chmBuffer.lower();
228 int lpos = temp.find("</html");
229 if (lpos > -1) {
230 chmBuffer.truncate(lpos);
231 chmBuffer = chmBuffer+"</HTML>";
232 }
233 fsize = chmBuffer.length();
234
235 bufpos = 0;
236 m_currentstart = m_ui.start;
237 m_currentend = m_currentstart+chmBuffer.length();
238 bRetVal = true;
239 }
240 return bRetVal;
241}
242
243bool CHM::getFile(const QString& href) {
244 qDebug("Got:%s", (const char*)href);
245 bool bRetVal = false;
246 QString temp = chmPath;
247 chmPath = href;
248 if (FillContent()) {
249 qDebug("Got it");
250 bRetVal = true;
251 } else {
252 qDebug("Missed");
253 chmPath = temp;
254 FillContent();
255 }
256 return bRetVal;
257}
258
259QImage *CHM::getPicture(const QString& href) {
260 QImage *img = NULL;
261 QString PicRef = "/"+href;
262 struct chmUnitInfo ui;
263 const char *ext;
264 /* try to find the file */
265 const char *filename = (const char *)PicRef;
266 if (chm_resolve_object(chmFile, filename, &ui) != CHM_RESOLVE_SUCCESS)
267 {
268 qDebug ("Could not resolve image");
269 return img;
270 }
271 if (ui.length > 0) {
272 char *temp = new char[ui.length];
273 char buffer[65536];
274 int swath, offset;
275 swath = 65536;
276 offset = 0;
277
278 while (offset < ui.length)
279 {
280 if ((ui.length - offset) < 65536)
281 swath = ui.length - offset;
282 else
283 swath = 65536;
284 swath = (int)chm_retrieve_object(chmFile, &ui, (unsigned char *) buffer, offset, swath);
285 memcpy( (void *) (temp + offset), (void *)&buffer, swath );
286 offset += swath;
287 }
288 QByteArray qba;
289 qba.setRawData( (const char *)temp, ui.length);
290 QPixmap qpm(qba);
291 img = new QImage(qpm.convertToImage());
292 qba.resetRawData((const char *)temp, ui.length);
293 delete[] temp;
294 }
295
296 return img;
297}
298
299int CHM::OpenFile(const char *src) {
300 if (chmFile != NULL) chm_close(chmFile);
301 struct stat _stat;
302 stat(src,&_stat);
303 fsize = _stat.st_size;
304 chmFile = chm_open(src);
305 if (chmFile != NULL) {
306 chm_enumerate(chmFile,
307 CHM_ENUMERATE_ALL,
308 _get_hhc,
309 (void *)this);
310 if ( chmPath != "") {
311 setHomePath(chmPath);
312 FillHomeContent();
313 }
314 }
315 m_homepos = locate();
316 qDebug("Home:%u", m_homepos);
317 return (chmFile==NULL);
318}
319
320int CHM::getch() {
321 if ( (bufpos+1) >= chmBuffer.length() )
322 return EOF;
323#ifdef _WINDOWS
324 QChar letter = chmBuffer.at(bufpos++);
325#else
326 QChar letter = chmBuffer[bufpos++];
327#endif
328 return (int)(char)letter;
329}
330
331void CHM::getch(tchar& ch, CStyle& sty)
332{
333 int ich = getch();
334 ch = (ich == EOF) ? UEOF : ich;
335}
336
337void CHM::start2endSection()
338{
339 m_currentstart = m_ui.start;
340 m_currentend = m_currentstart+chmBuffer.length();
341}
342
343unsigned int CHM::locate() {
344 return m_currentstart+bufpos;
345}
346
347void CHM::locate(unsigned int n) {
348 if (n == 0) n = m_homepos;
349 if (n >= m_homestart && n < m_homeend)
350 {
351 FillHomeContent();
352 bufpos = n - m_homestart;
353 start2endSection();
354 qDebug("Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend);
355 }
356 else if (n >= m_currentstart && n < m_currentend)
357 {
358 bufpos = n - m_currentstart;
359 }
360 else if (CHM_RESOLVE_FAILURE == chm_resolve_location(chmFile, n/4, &m_ui))
361 {
362 qDebug("Resolve failure");
363 FillHomeContent();
364 bufpos = 0;
365 start2endSection();
366 qDebug("Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend);
367 }
368 else
369 {
370 qDebug("Resolve success");
371 FillBuffer();
372 start2endSection();
373 bufpos=n-m_currentstart;
374 qDebug("Not Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend);
375 }
376}
377
378void CHM::sizes(unsigned long& _file, unsigned long& _text) {
379 _text = _file = fsize;
380}