Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CHM.cpp

Go to the documentation of this file.
00001 #include "CHM.h"
00002 #include "chm_lib.h"
00003 #include <qstring.h>
00004 #include <qstringlist.h>
00005 #include <stdio.h>
00006 #include <qimage.h>
00007 #include <qpixmap.h>
00008 #ifdef USEQPE
00009 #include <qpe/global.h>
00010 #endif
00011 
00012 #ifndef __STATIC
00013 extern "C"
00014 {
00015   CExpander* newcodec() { return new CHM; }
00016 }
00017 #endif
00018 
00019 static int _print_ui_index(struct chmFile *h, struct chmUnitInfo *ui,
00020                         void *context)
00021 {
00022     CHM *chm = (CHM *)context;
00023     QString temp = "<tr>";
00024     char buff[1024];
00025     sprintf( buff,"<td align=right>%8d\n</td><td><a href=\"%s\">%s</a></td></tr>",(int)ui->length, ui->path, ui->path);
00026     temp += buff;
00027     chm->addContent(temp);
00028     return CHM_ENUMERATOR_CONTINUE;
00029 }
00030 
00031 static int _get_hhc (struct chmFile *h, struct chmUnitInfo *ui,
00032                         void *context)
00033 {
00034     CHM *chm = (CHM *)context;
00035     QString PathName = ui->path;
00036     if (PathName.find(".hhc") > -1) {
00037         chm->setPath(PathName);
00038     }
00039     return CHM_ENUMERATOR_CONTINUE;
00040 }
00041 
00042 CHM::CHM() {
00043     chmFile = NULL;
00044     chmPath = "";
00045     chmHHCPath = "";
00046     chmBuffer = "";
00047     bufpos = 0;
00048 }
00049 
00050 CHM::~CHM()  {
00051     if (chmFile != NULL)
00052         chm_close(chmFile);
00053 }
00054 
00055 void CHM::suspend() {
00056 #ifdef USEQPE
00057         bSuspended = true;
00058         //suspos = gztell(file);
00059         chm_close(chmFile);
00060         chmFile = NULL;
00061         sustime = time(NULL);
00062 #endif
00063 }
00064 
00065 void CHM::unsuspend() {
00066 #ifdef USEQPE
00067         if (bSuspended)
00068         {
00069             bSuspended = false;
00070             int delay = time(NULL) - sustime;
00071             if (delay < 10)
00072               {
00073                 Global::statusMessage("Stalling");
00074                 sleep(10-delay);
00075               }
00076             chmFile = chm_open(fname);
00077             for (int i = 0; chmFile == NULL && i < 5; i++) {
00078               Global::statusMessage("Stalling");
00079                 sleep(5);
00080                 chmFile = chm_open(fname);
00081             }
00082             if (chmFile == NULL) {
00083                 QMessageBox::warning(NULL, PROGNAME, "Couldn't reopen file");
00084                 exit(0);
00085             }
00086         //suspos = gzseek(file, suspos, SEEK_SET);
00087         }
00088 #endif
00089 }
00090 
00091 void CHM::addContent(QString content) {
00092     chmBuffer += content;
00093 }
00094 
00095 void CHM::FillHomeContent() {
00096 unsuspend();
00097     if (chmHHCPath != "") {
00098         const char *ext;
00099         char buffer[65536];
00100         unsigned int swath, offset;
00101         QString tmp="";
00102         QString HTML="";
00103         /* try to find the file */
00104         const char *filename = (const char *)chmHHCPath;
00105         if (chm_resolve_object(chmFile, filename, &m_ui) != CHM_RESOLVE_SUCCESS)
00106         {
00107             chmBuffer = "HELP";
00108             fsize = chmBuffer.length();
00109             return;
00110         }
00111         m_homestart = m_ui.start;
00112         m_homeend = m_homestart + m_ui.length;
00113         swath = 65536;
00114         offset = 0;
00115         fsize = m_ui.length;
00116         while (offset < m_ui.length)
00117         {
00118             if ((m_ui.length - offset) < 65536)
00119                 swath = m_ui.length - offset;
00120             else
00121                 swath = 65536;
00122             swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath);
00123             tmp += buffer;
00124             offset += swath;
00125         }
00126         HTML +="<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN>\r\n";
00127         HTML +="<HTML>\r\n";
00128         HTML +="<BODY>\r\n";
00129         HTML +="<h2>Home Page</h2>\r\n";
00130         HTML +="<h3>\r\n";
00131         QStringList qsl = QStringList::split("\r\n",tmp);
00132         QString NameFind ="<param name=\"Name\" value=\"";
00133         QString LocalFind = "<param name=\"Local\" value=\"";
00134         QString ULOpenFind = "<UL>";
00135         QString LIOpenFind = "<LI>";
00136         QString ULCloseFind = "</UL>";
00137         QString Name = "";
00138         QString Local = "";
00139         for ( QStringList::Iterator it = qsl.begin(); it != qsl.end(); ++it ) {
00140             QString Line = (*it);
00141             int NamePos = Line.find( NameFind);
00142             int LocalPos = Line.find( LocalFind);
00143             if (NamePos > -1) {
00144                 Name = Line.mid(NamePos+NameFind.length(),Line.length());
00145                 Name = Name.left(Name.length() - 2);
00146             }
00147             if (LocalPos > -1) {
00148                 Local = Line.mid(LocalPos+LocalFind.length(),Line.length());
00149                 Local = Local.left(Local.length() - 2);
00150                 if (Name != "") {
00151                     HTML += "<br>\r\n<a href=";
00152                     HTML += Local;
00153                     HTML += ">";
00154                     HTML += Name;
00155                     HTML += "</a>\r\n";
00156                     Name = "";
00157                 }
00158             }
00159         }
00160         HTML +="</h3>";
00161         HTML +="</BODY>\r\n";
00162         HTML +="</HTML>\r\n";
00163         chmHomeBuffer = HTML;
00164         chmBuffer = HTML;
00165         fsize = chmBuffer.length();
00166         m_currentstart = m_ui.start;
00167         m_currentend = m_currentstart+chmBuffer.length();
00168     }
00169 }
00170 
00171 bool CHM::FillBuffer()
00172 {
00173 unsuspend();
00174   bool bRetVal = false;
00175   char buffer[65536];
00176   int swath, offset;
00177   chmBuffer = "";
00178   swath = 65536;
00179   offset = 0;
00180   fsize = m_ui.length;
00181   while (offset < m_ui.length)
00182     {
00183       if ((m_ui.length - offset) < 65536)
00184         swath = m_ui.length - offset;
00185       else
00186         swath = 65536;
00187       swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath);
00188       chmBuffer += buffer;
00189       offset += swath;
00190     }
00191   //There seems to be a ton of gobbledygook at the end that is reminiscent of the hhc file - remove it
00192   QString temp = chmBuffer.lower();
00193   int lpos = temp.find("</html");
00194   if (lpos > -1) {
00195     chmBuffer.truncate(lpos);
00196     chmBuffer = chmBuffer+"</HTML>";
00197   }
00198   fsize = chmBuffer.length();
00199   
00200   bufpos = 0;
00201   bRetVal = true;
00202   m_currentstart = m_ui.start;
00203   m_currentend = m_currentstart+chmBuffer.length();
00204   return bRetVal;
00205 }
00206 
00207 bool CHM::FillContent() {
00208 unsuspend();
00209     bool bRetVal = false;
00210     if (chmPath != "") {
00211         /* try to find the file */
00212         const char *filename = (const char *)chmPath;
00213         if (chm_resolve_object(chmFile, filename, &m_ui) != CHM_RESOLVE_SUCCESS)
00214         {
00215             fsize = chmBuffer.length();
00216             return bRetVal;
00217         }
00218 
00219         char buffer[65536];
00220         int swath, offset;
00221         chmBuffer = "";
00222         swath = 65536;
00223         offset = 0;
00224         fsize = m_ui.length;
00225         while (offset < m_ui.length)
00226         {
00227             if ((m_ui.length - offset) < 65536)
00228                 swath = m_ui.length - offset;
00229             else
00230                 swath = 65536;
00231             swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath);
00232             chmBuffer += buffer;
00233             offset += swath;
00234         }
00235         //There seems to be a ton of gobbledygook at the end that is reminiscent of the hhc file - remove it
00236         QString temp = chmBuffer.lower();
00237         int lpos = temp.find("</html");
00238         if (lpos > -1) {
00239             chmBuffer.truncate(lpos);
00240             chmBuffer = chmBuffer+"</HTML>";
00241         }
00242         fsize = chmBuffer.length();
00243 
00244         bufpos = 0;
00245         m_currentstart = m_ui.start;
00246         m_currentend = m_currentstart+chmBuffer.length();
00247         bRetVal = true;
00248     }
00249     return bRetVal;
00250 }
00251 
00252 bool CHM::getFile(const QString& _href, const QString& ) {
00253   QString href = "/" + _href;
00254   qDebug("Got:%s", (const char*)href);
00255     bool bRetVal = false;
00256     QString temp = chmPath;
00257     chmPath = href;
00258     if (FillContent()) {
00259       qDebug("Got it");
00260         bRetVal = true;
00261     } else {
00262       qDebug("Missed");
00263         chmPath = temp;
00264         FillContent();
00265     }
00266     return bRetVal;
00267 }
00268 
00269 QImage *CHM::getPicture(const QString& href) {
00270         QImage *img = NULL;
00271         QString PicRef = "/"+href;
00272         struct chmUnitInfo ui;
00273         const char *ext;
00274         /* try to find the file */
00275         const char *filename = (const char *)PicRef;
00276         if (chm_resolve_object(chmFile, filename, &ui) != CHM_RESOLVE_SUCCESS)
00277         {
00278             qDebug ("Could not resolve image");
00279             return img;
00280         }
00281         if (ui.length > 0) {
00282             char *temp = new char[ui.length];
00283             char buffer[65536];
00284             int swath, offset;
00285             swath = 65536;
00286             offset = 0;
00287 
00288             while (offset < ui.length)
00289             {
00290                 if ((ui.length - offset) < 65536)
00291                     swath = ui.length - offset;
00292                 else
00293                     swath = 65536;
00294                 swath = (int)chm_retrieve_object(chmFile, &ui, (unsigned char *) buffer, offset, swath);
00295                 memcpy( (void *) (temp + offset), (void *)&buffer, swath );
00296                 offset += swath;
00297             }
00298             QByteArray qba;
00299             qba.setRawData( (const char *)temp, ui.length);
00300             QPixmap qpm(qba);
00301             img = new QImage(qpm.convertToImage());
00302             qba.resetRawData((const char *)temp, ui.length);
00303             delete[] temp;
00304         }
00305 
00306         return img;
00307 }
00308 
00309 int CHM::OpenFile(const char *src) {
00310         if (chmFile != NULL) chm_close(chmFile);
00311         struct stat _stat;
00312         stat(src,&_stat);
00313         fsize = _stat.st_size;
00314         chmFile = chm_open(src);
00315         if (chmFile != NULL) {
00316             chm_enumerate(chmFile,
00317                         CHM_ENUMERATE_ALL,
00318                         _get_hhc,
00319                         (void *)this);
00320             if ( chmPath != "") {
00321                 setHomePath(chmPath);
00322                 FillHomeContent();
00323             }
00324         }
00325         m_homepos = locate();
00326         qDebug("Home:%u", m_homepos);
00327         return (chmFile==NULL);
00328 }
00329 
00330 int CHM::getch() {
00331     if ( (bufpos+1) >= chmBuffer.length() )
00332         return EOF;
00333 #ifdef _WINDOWS
00334     QChar letter = chmBuffer.at(bufpos++);
00335 #else
00336     QChar letter = chmBuffer[bufpos++];
00337 #endif
00338     return (int)(char)letter;
00339 }
00340 
00341 void CHM::getch(tchar& ch, CStyle& sty)
00342 {
00343         int ich = getch();
00344         ch = (ich == EOF) ? UEOF : ich;
00345 }
00346 
00347 void CHM::start2endSection()
00348 {
00349   m_currentstart = m_ui.start;
00350   m_currentend = m_currentstart+chmBuffer.length();
00351 }
00352 
00353 unsigned int CHM::locate() {
00354     return m_currentstart+bufpos;
00355 }
00356 
00357 void CHM::locate(unsigned int n) {
00358   if (n == 0) n = m_homepos;
00359   if (n >= m_homestart && n < m_homeend)
00360     {
00361       FillHomeContent();
00362       bufpos = n - m_homestart;
00363       start2endSection();
00364       qDebug("Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend);
00365     }
00366   else if (n >= m_currentstart && n < m_currentend)
00367     {
00368       bufpos = n - m_currentstart;
00369     }
00370   else if (CHM_RESOLVE_FAILURE == chm_resolve_location(chmFile, n/4, &m_ui))
00371     {
00372       qDebug("Resolve failure");
00373       FillHomeContent();
00374       bufpos = 0;
00375       start2endSection();
00376       qDebug("Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend);
00377     }
00378   else
00379     {
00380       qDebug("Resolve success");
00381       FillBuffer();
00382       start2endSection();
00383       bufpos=n-m_currentstart;
00384       qDebug("Not Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend);
00385     }
00386 }
00387 
00388 void CHM::sizes(unsigned long& _file, unsigned long& _text) {
00389     _text = _file = fsize;
00390 }

Generated on Sat Nov 5 16:16:54 2005 for OPIE by  doxygen 1.4.2