#include "qplatformdefs.h"
#include "qlibrary.h"
#include "qlibrary_p.h"
#include <qstringlist.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qmutex.h>
#include <qmap.h>
#include <qsettings.h>
#include <qdatetime.h>
#include <errno.h>
#include <qdebug.h>
#include <qvector.h>
Include dependency graph for qlibrary.cpp:

Go to the source code of this file.
Classes | |
| struct | qt_token_info |
Defines | |
| #define | QLIBRARY_AS_DEBUG true |
| #define | QT_NO_DEBUG_PLUGIN_CHECK |
Typedefs | |
| typedef QMap< QString, QLibraryPrivate * > | LibraryMap |
Functions | |
| static int | qt_tokenize (const char *s, ulong s_len, ulong *advance, qt_token_info &token_info) |
| static bool | qt_parse_pattern (const char *s, uint *version, bool *debug, QByteArray *key) |
| static long | qt_find_pattern (const char *s, ulong s_len, const char *pattern, ulong p_len) |
| static bool | qt_unix_query (const QString &library, uint *version, bool *debug, QByteArray *key, QLibraryPrivate *lib=0) |
| bool | qt_debug_component () |
| #define QLIBRARY_AS_DEBUG true |
| #define QT_NO_DEBUG_PLUGIN_CHECK |
Definition at line 57 of file qlibrary.cpp.
| typedef QMap<QString, QLibraryPrivate*> LibraryMap |
Definition at line 401 of file qlibrary.cpp.
| bool qt_debug_component | ( | ) |
Definition at line 985 of file qlibrary.cpp.
References qgetenv().
Referenced by QLibraryPrivate::isPlugin(), QFactoryLoader::QFactoryLoader(), qt_unix_query(), and QPluginLoader::setFileName().
00986 { 00987 #if defined(QT_DEBUG_COMPONENT) 00988 return true; //compatibility? 00989 #else 00990 static int debug_env = -1; 00991 if (debug_env == -1) 00992 debug_env = ::qgetenv("QT_DEBUG_PLUGINS").toInt(); 00993 00994 return debug_env != 0; 00995 #endif 00996 }
Here is the call graph for this function:

| static long qt_find_pattern | ( | const char * | s, | |
| ulong | s_len, | |||
| const char * | pattern, | |||
| ulong | p_len | |||
| ) | [static] |
Definition at line 284 of file qlibrary.cpp.
References i, and QByteArray::qstrncmp().
Referenced by qt_unix_query().
00286 { 00287 /* 00288 we search from the end of the file because on the supported 00289 systems, the read-only data/text segments are placed at the end 00290 of the file. HOWEVER, when building with debugging enabled, all 00291 the debug symbols are placed AFTER the data/text segments. 00292 00293 what does this mean? when building in release mode, the search 00294 is fast because the data we are looking for is at the end of the 00295 file... when building in debug mode, the search is slower 00296 because we have to skip over all the debugging symbols first 00297 */ 00298 00299 if (! s || ! pattern || p_len > s_len) return -1; 00300 ulong i, hs = 0, hp = 0, delta = s_len - p_len; 00301 00302 for (i = 0; i < p_len; ++i) { 00303 hs += s[delta + i]; 00304 hp += pattern[i]; 00305 } 00306 i = delta; 00307 for (;;) { 00308 if (hs == hp && qstrncmp(s + i, pattern, p_len) == 0) 00309 return i; 00310 if (i == 0) 00311 break; 00312 --i; 00313 hs -= s[i + p_len]; 00314 hs += s[i]; 00315 } 00316 00317 return -1; 00318 }
Here is the call graph for this function:

| static bool qt_parse_pattern | ( | const char * | s, | |
| uint * | version, | |||
| bool * | debug, | |||
| QByteArray * | key | |||
| ) | [static] |
Definition at line 234 of file qlibrary.cpp.
References key, qt_token_info::lengths, m, n, p, parse(), QByteArray::qstrlen(), QByteArray::qstrncmp(), qt_tokenize(), and qt_token_info::results.
Referenced by QLibraryPrivate::isPlugin(), and qt_unix_query().
00235 { 00236 bool ret = true; 00237 00238 qt_token_info pinfo("=\n", 2); 00239 int parse; 00240 ulong at = 0, advance, parselen = qstrlen(s); 00241 do { 00242 parse = qt_tokenize(s + at, parselen, &advance, pinfo); 00243 if (parse == -1) { 00244 ret = false; 00245 break; 00246 } 00247 00248 at += advance; 00249 parselen -= advance; 00250 00251 if (qstrncmp("version", pinfo.results[0], pinfo.lengths[0]) == 0) { 00252 // parse version string 00253 qt_token_info pinfo2("..-", 3); 00254 if (qt_tokenize(pinfo.results[1], pinfo.lengths[1], 00255 &advance, pinfo2) != -1) { 00256 QByteArray m(pinfo2.results[0], pinfo2.lengths[0]); 00257 QByteArray n(pinfo2.results[1], pinfo2.lengths[1]); 00258 QByteArray p(pinfo2.results[2], pinfo2.lengths[2]); 00259 *version = (m.toUInt() << 16) | (n.toUInt() << 8) | p.toUInt(); 00260 } else { 00261 ret = false; 00262 break; 00263 } 00264 } else if (qstrncmp("debug", pinfo.results[0], pinfo.lengths[0]) == 0) { 00265 *debug = qstrncmp("true", pinfo.results[1], pinfo.lengths[1]) == 0; 00266 } else if (qstrncmp("buildkey", pinfo.results[0], 00267 pinfo.lengths[0]) == 0){ 00268 // save buildkey 00269 *key = QByteArray(pinfo.results[1], pinfo.lengths[1] + 1); 00270 } 00271 } while (parse == 1 && parselen > 0); 00272 00273 return ret; 00274 }
Here is the call graph for this function:

| static int qt_tokenize | ( | const char * | s, | |
| ulong | s_len, | |||
| ulong * | advance, | |||
| qt_token_info & | token_info | |||
| ) | [static] |
Definition at line 179 of file qlibrary.cpp.
References qt_token_info::field_count, qt_token_info::fields, qt_token_info::lengths, and qt_token_info::results.
Referenced by qt_parse_pattern().
00181 { 00182 ulong pos = 0, field = 0, fieldlen = 0; 00183 char current; 00184 int ret = -1; 00185 *advance = 0; 00186 for (;;) { 00187 current = s[pos]; 00188 00189 // next char 00190 ++pos; 00191 ++fieldlen; 00192 ++*advance; 00193 00194 if (! current || pos == s_len + 1) { 00195 // save result 00196 token_info.results[(int)field] = s; 00197 token_info.lengths[(int)field] = fieldlen - 1; 00198 00199 // end of string 00200 ret = 0; 00201 break; 00202 } 00203 00204 if (current == token_info.fields[field]) { 00205 // save result 00206 token_info.results[(int)field] = s; 00207 token_info.lengths[(int)field] = fieldlen - 1; 00208 00209 // end of field 00210 fieldlen = 0; 00211 ++field; 00212 if (field == token_info.field_count - 1) { 00213 // parse ok 00214 ret = 1; 00215 } 00216 if (field == token_info.field_count) { 00217 // done parsing 00218 break; 00219 } 00220 00221 // reset string and its length 00222 s = s + pos; 00223 s_len -= pos; 00224 pos = 0; 00225 } 00226 } 00227 00228 return ret; 00229 }
| static bool qt_unix_query | ( | const QString & | library, | |
| uint * | version, | |||
| bool * | debug, | |||
| QByteArray * | key, | |||
| QLibraryPrivate * | lib = 0 | |||
| ) | [static] |
Definition at line 330 of file qlibrary.cpp.
References QFile::close(), data, QFile::encodeName(), QIODevice::errorString(), QFile::handle(), key, library, MAP_FAILED, QFile::open(), QByteArray::qstrlen(), qt_debug_component(), qt_error_string(), qt_find_pattern(), qt_parse_pattern(), qWarning(), QIODevice::readAll(), QIODevice::ReadOnly, and QFile::size().
Referenced by QLibraryPrivate::isPlugin().
00331 { 00332 QFile file(library); 00333 if (!file.open(QIODevice::ReadOnly)) { 00334 if (lib) 00335 lib->errorString = file.errorString(); 00336 if (qt_debug_component()) { 00337 qWarning("%s: %s", (const char*) QFile::encodeName(library), 00338 qPrintable(qt_error_string(errno))); 00339 } 00340 return false; 00341 } 00342 00343 QByteArray data; 00344 char *filedata = 0; 00345 ulong fdlen = 0; 00346 00347 #ifdef USE_MMAP 00348 char *mapaddr = 0; 00349 size_t maplen = file.size(); 00350 mapaddr = (char *) mmap(mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0); 00351 if (mapaddr != MAP_FAILED) { 00352 // mmap succeeded 00353 filedata = mapaddr; 00354 fdlen = maplen; 00355 } else { 00356 // mmap failed 00357 if (qt_debug_component()) { 00358 qWarning("mmap: %s", qPrintable(qt_error_string(errno))); 00359 } 00360 if (lib) 00361 lib->errorString = QLibrary::tr("Could not mmap '%1': %2") 00362 .arg(library) 00363 .arg(qt_error_string()); 00364 #endif // USE_MMAP 00365 // try reading the data into memory instead 00366 data = file.readAll(); 00367 filedata = data.data(); 00368 fdlen = data.size(); 00369 #ifdef USE_MMAP 00370 } 00371 #endif // USE_MMAP 00372 00373 // verify that the pattern is present in the plugin 00374 const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA"; 00375 const ulong plen = qstrlen(pattern); 00376 long pos = qt_find_pattern(filedata, fdlen, pattern, plen); 00377 00378 bool ret = false; 00379 if (pos >= 0) 00380 ret = qt_parse_pattern(filedata + pos, version, debug, key); 00381 00382 if (!ret && lib) 00383 lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library); 00384 #ifdef USE_MMAP 00385 if (mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0) { 00386 if (qt_debug_component()) 00387 qWarning("munmap: %s", qPrintable(qt_error_string(errno))); 00388 if (lib) 00389 lib->errorString = QLibrary::tr("Could not unmap '%1': %2") 00390 .arg(library) 00391 .arg( qt_error_string() ); 00392 } 00393 #endif // USE_MMAP 00394 00395 file.close(); 00396 return ret; 00397 }
Here is the call graph for this function:

1.5.1