diff options
Diffstat (limited to 'tqtinterface/qt4/src/tools/tqcomlibrary.cpp')
-rw-r--r-- | tqtinterface/qt4/src/tools/tqcomlibrary.cpp | 538 |
1 files changed, 0 insertions, 538 deletions
diff --git a/tqtinterface/qt4/src/tools/tqcomlibrary.cpp b/tqtinterface/qt4/src/tools/tqcomlibrary.cpp deleted file mode 100644 index 4bbeee3..0000000 --- a/tqtinterface/qt4/src/tools/tqcomlibrary.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQComLibrary class -** -** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the tools module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at [email protected]. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include "tqcomlibrary_p.h" - -#ifndef TQT_NO_COMPONENT -#include <tqapplication.h> -#include <tqsettings.h> -#include <tqfileinfo.h> -#include <tqdatetime.h> -#include <tqcleanuphandler.h> -#ifndef NO_ERRNO_H -#include <errno.h> -#endif // NO_ERROR_H - -#ifdef TQT_THREAD_SUPPORT -# include "tqmutexpool_p.h" -#endif // TQT_THREAD_SUPPORT - -#ifndef TQT_DEBUG_COMPONENT -# if defined(TQT_DEBUG) -# define TQT_DEBUG_COMPONENT 1 -# endif -#endif - - -TQComLibrary::TQComLibrary( const TQString &filename ) - : TQLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 ) -{ -} - -TQComLibrary::~TQComLibrary() -{ - if ( autoUnload() ) - unload(); - if ( libiface ) - libiface->release(); - if ( entry ) - entry->release(); -} - -bool TQComLibrary::unload() -{ - int refs = entry ? entry->release() : 0; - entry = 0; - if (refs || !libiface) - return FALSE; - - libiface->cleanup(); - if ( !libiface->canUnload() ) - return FALSE; - libiface->release(); - libiface = 0; - - return TQLibrary::unload(); -} - -static bool qt_verify( const TQString& library, uint version, uint flags, - const TQCString &key, bool warn ) -{ - uint our_flags = 1; -#if defined(TQT_THREAD_SUPPORT) - our_flags |= 2; -#endif - - if ( (flags & 1) == 0 ) { - if ( warn ) - qWarning( "Conflict in %s:\n" - " Plugin cannot be queried successfully! [2]", - (const char*) TQFile::encodeName(library) ); - } else if ( ( version > TQT_VERSION ) || - ( ( TQT_VERSION & 0xff0000 ) > ( version & 0xff0000 ) ) ) { - if ( warn ) - qWarning( "Conflict in %s:\n" - " Plugin uses incompatible TQt library (%d.%d.%d)!", - (const char*) TQFile::encodeName(library), - (version&0xff0000) >> 16, (version&0xff00) >> 8, version&0xff ); - } else if ( (flags & 2) != (our_flags & 2) ) { - if ( warn ) - qWarning( "Conflict in %s:\n" - " Plugin uses %s TQt library!", - (const char*) TQFile::encodeName(library), - (flags & 2) ? "multi threaded" : "single threaded" ); - } else if ( key != TQT_BUILD_KEY ) { - if ( warn ) - qWarning( "Conflict in %s:\n" - " Plugin uses incompatible TQt library!\n" - " expected build key \"%s\", got \"%s\".", - (const char*) TQFile::encodeName(library), - TQT_BUILD_KEY, - key.isEmpty() ? "<null>" : (const char *) key ); - } else { - return TRUE; - } - return FALSE; -} - -struct qt_token_info -{ - qt_token_info( const char *f, const ulong fc ) - : fields( f ), field_count( fc ), results( fc ), lengths( fc ) - { - results.fill( 0 ); - lengths.fill( 0 ); - } - - const char *fields; - const ulong field_count; - - TQMemArray<const char *> results; - TQMemArray<ulong> lengths; -}; - -/* - return values: - 1 parse ok - 0 eos - -1 parse error -*/ -static int qt_tokenize( const char *s, ulong s_len, ulong *advance, - const qt_token_info &token_info ) -{ - ulong pos = 0, field = 0, fieldlen = 0; - char current; - int ret = -1; - *advance = 0; - for (;;) { - current = s[ pos ]; - - // next char - ++pos; - ++fieldlen; - ++*advance; - - if ( ! current || pos == s_len + 1 ) { - // save result - token_info.results[ (int)field ] = s; - token_info.lengths[ (int)field ] = fieldlen - 1; - - // end of string - ret = 0; - break; - } - - if ( current == token_info.fields[ field ] ) { - // save result - token_info.results[ (int)field ] = s; - token_info.lengths[ (int)field ] = fieldlen - 1; - - // end of field - fieldlen = 0; - ++field; - if ( field == token_info.field_count - 1 ) { - // parse ok - ret = 1; - } - if ( field == token_info.field_count ) { - // done parsing - break; - } - - // reset string and its length - s = s + pos; - s_len -= pos; - pos = 0; - } - } - - return ret; -} - -/* - returns TRUE if the string s was correctly parsed, FALSE otherwise. -*/ -static bool tqt_parse_pattern( const char *s, uint *version, uint *flags, - TQCString *key ) -{ - bool ret = TRUE; - - qt_token_info pinfo("=\n", 2); - int parse; - ulong at = 0, advance, parselen = tqstrlen( s ); - do { - parse = qt_tokenize( s + at, parselen, &advance, pinfo ); - if ( parse == -1 ) { - ret = FALSE; - break; - } - - at += advance; - parselen -= advance; - - if ( tqstrncmp( "version", pinfo.results[ 0 ], pinfo.lengths[ 0 ] ) == 0 ) { - // parse version string - qt_token_info pinfo2("..-", 3); - if ( qt_tokenize( pinfo.results[ 1 ], pinfo.lengths[ 1 ], - &advance, pinfo2 ) != -1 ) { - TQCString m( pinfo2.results[ 0 ], pinfo2.lengths[ 0 ] + 1 ); - TQCString n( pinfo2.results[ 1 ], pinfo2.lengths[ 1 ] + 1 ); - TQCString p( pinfo2.results[ 2 ], pinfo2.lengths[ 2 ] + 1 ); - *version = (m.toUInt() << 16) | (n.toUInt() << 8) | p.toUInt(); - } else { - ret = FALSE; - break; - } - } else if ( tqstrncmp( "flags", pinfo.results[ 0 ], pinfo.lengths[ 0 ] ) == 0 ) { - // parse flags string - char ch; - *flags = 0; - ulong p = 0, c = 0, bit = 0; - while ( p < pinfo.lengths[ 1 ] ) { - ch = pinfo.results[ 1 ][ p ]; - bit = pinfo.lengths[ 1 ] - p - 1; - c = 1 << bit; - if ( ch == '1' ) { - *flags |= c; - } else if ( ch != '0' ) { - ret = FALSE; - break; - } - ++p; - } - } else if ( tqstrncmp( "buildkey", pinfo.results[ 0 ], - pinfo.lengths[ 0 ] ) == 0 ){ - // save buildkey - *key = TQCString( pinfo.results[ 1 ], pinfo.lengths[ 1 ] + 1 ); - } - } while ( parse == 1 && parselen > 0 ); - - return ret; -} - -#if defined(TQ_OS_UNIX) - -#if defined(TQ_OS_FREEBSD) || defined(TQ_OS_LINUX) -# define USE_MMAP -# include <sys/types.h> -# include <sys/mman.h> -#endif // TQ_OS_FREEBSD || TQ_OS_LINUX - -static long qt_find_pattern( const char *s, ulong s_len, - const char *pattern, ulong p_len ) -{ - /* - this uses the same algorithm as TQString::findRev... - - we search from the end of the file because on the supported - systems, the read-only data/text segments are placed at the end - of the file. HOWEVER, when building with debugging enabled, all - the debug symbols are placed AFTER the data/text segments. - - what does this mean? when building in release mode, the search - is fast because the data we are looking for is at the end of the - file... when building in debug mode, the search is slower - because we have to skip over all the debugging symbols first - */ - - if ( ! s || ! pattern || p_len > s_len ) return -1; - ulong i, hs = 0, hp = 0, delta = s_len - p_len; - - for (i = 0; i < p_len; ++i ) { - hs += s[delta + i]; - hp += pattern[i]; - } - i = delta; - for (;;) { - if ( hs == hp && tqstrncmp( s + i, pattern, p_len ) == 0 ) - return i; - if ( i == 0 ) - break; - --i; - hs -= s[i + p_len]; - hs += s[i]; - } - - return -1; -} - -/* - This opens the specified library, mmaps it into memory, and searches - for the TQT_UCM_VERIFICATION_DATA. The advantage of this approach is that - we can get the verification data without have to actually load the library. - This lets us detect mismatches more safely. - - Returns FALSE if version/flags/key information is not present, or if the - information could not be read. - Returns TRUE if version/flags/key information is present and succesfully read. -*/ -static bool tqt_unix_query( const TQString &library, uint *version, uint *flags, - TQCString *key ) -{ - TQFile file( library ); - if (! file.open( IO_ReadOnly ) ) { - qWarning( "%s: %s", (const char*) TQFile::encodeName(library), - strerror( errno ) ); - return FALSE; - } - - TQByteArray data; - char *filedata = 0; - ulong fdlen = 0; - -#ifdef USE_MMAP - char *mapaddr = 0; - size_t maplen = file.size(); - mapaddr = (char *) mmap( mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0 ); - if ( mapaddr != MAP_FAILED ) { - // mmap succeeded - filedata = mapaddr; - fdlen = maplen; - } else { - // mmap failed - qWarning( "mmap: %s", strerror( errno ) ); -#endif // USE_MMAP - // try reading the data into memory instead - data = file.readAll(); - filedata = data.data(); - fdlen = data.size(); -#ifdef USE_MMAP - } -#endif // USE_MMAP - - // verify that the pattern is present in the plugin - const char *pattern = "pattern=TQT_UCM_VERIFICATION_DATA"; - const ulong plen = tqstrlen( pattern ); - long pos = qt_find_pattern( filedata, fdlen, pattern, plen ); - - bool ret = FALSE; - if ( pos >= 0 ) { - ret = tqt_parse_pattern( filedata + pos, version, flags, key ); - } - -#ifdef USE_MMAP - if ( mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0 ) { - qWarning( "munmap: %s", strerror( errno ) ); - } -#endif // USE_MMAP - - file.close(); - return ret; -} - -#endif // TQ_OS_UNIX - - -static TQSettings *cache = 0; -static TQSingleCleanupHandler<TQSettings> cleanup_cache; - -void TQComLibrary::createInstanceInternal() -{ - if ( library().isEmpty() ) - return; - - TQFileInfo fileinfo( library() ); - TQString lastModified = fileinfo.lastModified().toString(Qt::ISODate); - TQString regkey = TQString("/TQt Plugins %1.%2/%3") - .arg( ( TQT_VERSION & 0xff0000 ) >> 16 ) - .arg( ( TQT_VERSION & 0xff00 ) >> 8 ) - .arg( library() ); - TQStringList reg; - uint flags = 0; - TQCString key; - bool query_done = FALSE; - bool warn_mismatch = TRUE; - -#ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( tqt_global_mutexpool ? - tqt_global_mutexpool->get( &cache ) : 0 ); -#endif // TQT_THREAD_SUPPORT - - if ( ! cache ) { - cache = new TQSettings; - cache->insertSearchPath( TQSettings::Windows, "/Trolltech" ); - cleanup_cache.set( &cache ); - } - - reg = cache->readListEntry( regkey ); - if ( reg.count() == 4 ) { - // check timestamp - if ( lastModified == reg[3] ) { - qt_version = reg[0].toUInt(0, 16); - flags = reg[1].toUInt(0, 16); - key = reg[2].latin1(); - - query_done = TRUE; - warn_mismatch = FALSE; - } - } - -#if defined(TQ_OS_UNIX) - if ( ! query_done ) { - // get the query information directly from the plugin without loading - if ( tqt_unix_query( library(), &qt_version, &flags, &key ) ) { - // info read succesfully from library - query_done = TRUE; - } - } -#else // !TQ_OS_UNIX - if ( ! query_done ) { - // get the query information by loading the plugin - if ( !isLoaded() ) { - TQ_ASSERT( entry == 0 ); - if ( !load() ) - return; - } - -# ifdef TQ_CC_BOR - typedef const char * __stdcall (*UCMQueryVerificationDataProc)(); -# else - typedef const char * (*UCMQueryVerificationDataProc)(); -# endif - UCMQueryVerificationDataProc ucmQueryVerificationdataProc; - ucmQueryVerificationdataProc = - (UCMQueryVerificationDataProc) resolve( "qt_ucm_query_verification_data" ); - - if ( !ucmQueryVerificationdataProc || - !tqt_parse_pattern( ucmQueryVerificationdataProc(), - &qt_version, &flags, &key ) ) { - qt_version = flags = 0; - key = "unknown"; - } else { - query_done = TRUE; - } - } -#endif // TQ_OS_UNIX - - TQStringList queried; - queried << TQString::number( qt_version,16 ) - << TQString::number( flags, 16 ) - << key - << lastModified; - - if ( queried != reg ) { - cache->writeEntry( regkey, queried ); - // delete the cache, which forces the settings to be written - delete cache; - cache = 0; - } - - if ( ! query_done ) { - if ( warn_mismatch ) { - qWarning( "Conflict in %s:\n Plugin cannot be queried successfully! [1]", - (const char*) TQFile::encodeName( library() ) ); - } - unload(); - return; - } - - if ( ! qt_verify( library(), qt_version, flags, key, warn_mismatch ) ) { - unload(); - return; - } else if ( !isLoaded() ) { - TQ_ASSERT( entry == 0 ); - if ( !load() ) - return; - } - -#ifdef TQ_CC_BOR - typedef TQUnknownInterface* __stdcall (*UCMInstanceProc)(); -#else - typedef TQUnknownInterface* (*UCMInstanceProc)(); -#endif - UCMInstanceProc ucmInstanceProc; - ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" ); -#if defined(TQT_DEBUG_COMPONENT) - if ( !ucmInstanceProc ) - qWarning( "%s: Not a UCOM library.", (const char*) TQFile::encodeName(library()) ); -#endif - entry = ucmInstanceProc ? ucmInstanceProc() : 0; - - if ( entry ) { - if ( entry->queryInterface( IID_TQLibrary, (TQUnknownInterface**)&libiface ) == TQS_OK ) { - if ( libiface && !libiface->init() ) { - libiface->release(); - libiface = 0; - unload(); - return; - } - } - } else { -#if defined(TQT_DEBUG_COMPONENT) - qWarning( "%s: No exported component provided.", (const char*) TQFile::encodeName(library()) ); -#endif - unload(); - } -} - -TQRESULT TQComLibrary::queryInterface( const TQUuid& request, TQUnknownInterface** iface ) -{ - if ( !entry ) - createInstanceInternal(); - return entry ? entry->queryInterface( request, iface ) : TQE_NOCOMPONENT; -} - -uint TQComLibrary::qtVersion() -{ - if ( !entry ) - createInstanceInternal(); - return entry ? qt_version : 0; -} - - -#endif // TQT_NO_COMPONENT |