chm.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <qcstring.h>
00018 #include <qbitarray.h>
00019 #include <qfile.h>
00020 #include <qregexp.h>
00021
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <sys/stat.h>
00025
00026 #include <kapp.h>
00027 #include <kdebug.h>
00028 #include <kinstance.h>
00029 #include <kglobal.h>
00030 #include <kurl.h>
00031 #include <kmimemagic.h>
00032
00033 #include "chm.h"
00034
00035
00036 using namespace KIO;
00037
00038 extern "C"
00039 {
00040 int kdemain( int argc, char **argv )
00041 {
00042 KInstance instance( "kio_chm" );
00043
00044 kdDebug() << "*** Starting kio_chm " << endl;
00045
00046 if (argc != 4) {
00047 kdDebug() << "Usage: kio_chm protocol domain-socket1 domain-socket2" << endl;
00048 exit(-1);
00049 }
00050
00051 ChmProtocol slave(argv[2], argv[3]);
00052 slave.dispatchLoop();
00053
00054 kdDebug() << "*** kio_chm Done" << endl;
00055 return 0;
00056 }
00057 }
00058
00059 ChmProtocol::ChmProtocol(const QCString &pool_socket, const QCString &app_socket)
00060 : SlaveBase("kio_chm", pool_socket, app_socket)
00061 {
00062 kdDebug() << "ChmProtocol::ChmProtocol()" << endl;
00063 }
00064
00065
00066
00067 ChmProtocol::~ChmProtocol()
00068 {
00069 kdDebug() << "ChmProtocol::~ChmProtocol()" << endl;
00070 }
00071
00072
00073
00074 void ChmProtocol::get( const KURL& url )
00075 {
00076 kdDebug() << "kio_chm::get(const KURL& url) " << url.path() << endl;
00077
00078 QString path;
00079 if ( !checkNewFile( url.path(), path ) ) {
00080 error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
00081 return;
00082 }
00083
00084 if (m_dirMap.find(path) == m_dirMap.end()) {
00085 error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
00086 return;
00087 }
00088
00089 QByteArray theData;
00090
00091 if (path == "/") {
00092 int offset = m_dirMap["/@contents"].offset;
00093 int length = m_dirMap["/@contents"].length;
00094 theData.setRawData(&m_contents[offset], length);
00095 QString s(theData);
00096 QString output;
00097
00098 QRegExp object("<OBJECT type=\"text/sitemap\">(.*)</OBJECT>", false);
00099 object.setMinimal(true);
00100
00101 QRegExp nameParam("<param name=\"Name\" value=\"(.*)\">", false);
00102 nameParam.setMinimal(true);
00103
00104 QRegExp localParam("<param name=\"Local\" value=\"(.*)\">", false);
00105 localParam.setMinimal(true);
00106
00107 QRegExp mergeParam("<param name=\"Merge\" value=\"(.*)\">", false);
00108 localParam.setMinimal(true);
00109
00110 int old = 0, pos = 0;
00111 while ((pos = s.find(object, pos)) != -1) {
00112 output += s.mid(old, pos - old);
00113 pos += object.matchedLength();
00114 old = pos;
00115 QString obj = object.cap(1);
00116 QString name, local;
00117 if (obj.find(nameParam) != -1) {
00118 name = nameParam.cap(1);
00119 if (obj.find(localParam) != -1) {
00120 local = localParam.cap(1);
00121 output += "<a href=\"" + local + "\">" + name + "</a>";
00122 } else {
00123 output += name;
00124 }
00125 }
00126 if (obj.find(mergeParam) != -1) {
00127 QString link = mergeParam.cap(1);
00128 QString href = link.left(link.find("::"));
00129 QString path = m_chmFile.left(m_chmFile.findRev("/") + 1);
00130 output += " (<a href=\"" + path + href + "\">link</a>)";
00131 }
00132 }
00133 output += s.mid(old);
00134 theData.resetRawData(&m_contents[offset], length);
00135
00136
00137
00138 QCString output1 = (QCString)(output.latin1());
00139 data(output1);
00140 processedSize(output1.length());
00141 } else {
00142 int offset = m_dirMap[path].offset;
00143 int length = m_dirMap[path].length;
00144 totalSize(length);
00145 theData.setRawData(&m_contents[offset], length);
00146
00147 KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( theData, path );
00148 kdDebug() << "Emitting mimetype " << result->mimeType() << endl;
00149 mimeType( result->mimeType() );
00150 data(theData);
00151 theData.resetRawData(&m_contents[offset], length);
00152 processedSize(length);
00153 }
00154
00155 finished();
00156 }
00157
00158
00159 bool ChmProtocol::checkNewFile( QString fullPath, QString& path )
00160 {
00161
00162
00163 fullPath = fullPath.replace(QRegExp("::"), "");
00164
00165
00166 if ( !m_chmFile.isEmpty() && fullPath.startsWith(m_chmFile) )
00167 {
00168 path = fullPath.mid(m_chmFile.length()).lower();
00169 return true;
00170 }
00171
00172 kdDebug() << "Need to open a new file" << endl;
00173
00174 m_chmFile = "";
00175
00176
00177 int pos = 0;
00178 QString chmFile;
00179 path = "";
00180
00181 int len = fullPath.length();
00182 if ( len != 0 && fullPath[ len - 1 ] != '/' )
00183 fullPath += '/';
00184
00185
00186 while ( (pos=fullPath.find( '/', pos+1 )) != -1 )
00187 {
00188 QString tryPath = fullPath.left( pos );
00189
00190 struct stat statbuf;
00191 if ( ::stat( QFile::encodeName(tryPath), &statbuf ) == 0 && !S_ISDIR(statbuf.st_mode) )
00192 {
00193 chmFile = tryPath;
00194 path = fullPath.mid( pos ).lower();
00195 kdDebug() << "fullPath=" << fullPath << " path=" << path << endl;
00196 len = path.length();
00197 if ( len > 2 )
00198 {
00199 if ( path[ len - 1 ] == '/' )
00200 path.truncate( len - 1 );
00201 }
00202 else
00203 {
00204 path = QString::fromLatin1("/");
00205 }
00206 kdDebug() << "Found. chmFile=" << chmFile << " path=" << path << endl;
00207 break;
00208 }
00209 }
00210 if ( chmFile.isEmpty() )
00211 {
00212 kdDebug() << "ChmProtocol::checkNewFile: not found" << endl;
00213 return false;
00214 }
00215
00216 m_chmFile = chmFile;
00217
00218
00219
00220 return m_chm.read(chmFile, m_dirMap, m_contents);
00221 }
This file is part of the documentation for KDevelop Version 3.1.2.