diff -r 5cc91383ab1e -r 7333d7932ef7 secureswitools/swisistools/source/dbmanager/dbprocessor.cpp --- a/secureswitools/swisistools/source/dbmanager/dbprocessor.cpp Thu Aug 19 10:02:49 2010 +0300 +++ b/secureswitools/swisistools/source/dbmanager/dbprocessor.cpp Tue Aug 31 15:21:33 2010 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of the License "Eclipse Public License v1.0" @@ -30,10 +30,130 @@ #include "logs.h" #include "util.h" #include "symbiantypes.h" - +#include "utf8_wrapper.h" +#include "../sisxlibrary/utility.h" #include #include +#ifdef __linux__ +#include + + +void* GetProcAddress(HINSTANCE aHandle, const char* aSymbol) + { + return dlsym(aHandle, aSymbol); + } + +HINSTANCE LoadLibraryA(const char* aLibraryName) + { + HINSTANCE handleUsingDefaultSearchPath = dlopen(aLibraryName, RTLD_LAZY); + + if( handleUsingDefaultSearchPath == NULL ) + { + // Once the dlopen() fails by not finding the aLibraryName in the default + // path specified by LD_LIBRARY_PATH, we will look in the epoc32/tools + // path as the second option. + + const char* epocRoot = getenv("EPOCROOT"); + if(NULL == epocRoot) + { + throw CException("EPOCROOT environment variable not specified.", ExceptionCodes::EEnvNotSpecified); + } + std::string epocRootStr(epocRoot); + + std::string absPathToLibrary = epocRootStr + std::string("epoc32/tools/") + std::string(aLibraryName); + HINSTANCE handleUsingAbsSearchPath = dlopen(absPathToLibrary.c_str(), RTLD_LAZY); + + return handleUsingAbsSearchPath; + } + + return handleUsingDefaultSearchPath; + } + +int FreeLibrary(HINSTANCE aHandle) + { + // FreeLibrary returns non-zero value on success whereas + // dlcose returns zero on success. + return (dlclose(aHandle) == 0)? true: false; + } + +std::string GetErrorMessage() + { + return dlerror(); + } + +static utf16WString utf32WString2utf16WString(std::wstring& aParameter) +{ + int strLen = aParameter.length(); + const wchar_t * source = aParameter.c_str(); + unsigned short int* buffer = new unsigned short int[(strLen + 1) * 2]; + + // Using a temp variable in place of buffer as ConvertUTF32toUTF16 modifies the source pointer passed. + unsigned short int* temp = buffer; + + ConvertUTF32toUTF16(&source, source + strLen, &temp, temp + strLen, lenientConversion); + + // Appending NUL to the converted buffer. + *temp = 0; + + utf16WString utf16Ws; + utf16Ws.resize(strLen); + + // The built-in basic_string template class copy operation + // truncates when a NUL is encountered when a c_str() is + // used to construct the required string. + // So, if aParameter is any hashable string having the + // syntax : swtypeName + L'\0' + someId then, we will end + // up returning only part of the converted UTF-16 string. + // Hence, we resort to the explicit copy operation with + // two bytes at a time. + while( strLen-- ) + { + utf16Ws[ strLen ] = buffer[ strLen ]; + } + + delete[] buffer; + + return utf16Ws; +} + +static std::wstring utf16WString2utf32WString(utf16WString& aParameter) +{ + int strLen = aParameter.length(); + const unsigned short int* source = aParameter.c_str(); + wchar_t* buffer = new wchar_t[ strLen + 1 ]; + + // Using a temp variable in place of buffer as ConvertUTF16toUCS4 modifies the source pointer passed. + wchar_t* temp = buffer; + + ConvertUTF16toUCS4(&source, source + strLen, &temp, temp + strLen); + + // Appending NUL to the converted buffer. + *temp = 0; + + std::wstring utf32Ws(buffer); + + delete[] buffer; + + return utf32Ws; +} + +#else +std::string GetErrorMessage() + { + LPCVOID lpMsgBuf; + + DWORD err = GetLastError(); + FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, + 0, NULL + ); + std::wstring wErrMsg((wchar_t*)lpMsgBuf); + return wstring2string(wErrMsg); + } +#endif // __linux__ + TDbLibrary* iLibraryHandler = NULL; TDbLibrary::TDbLibrary(const std::string& aDllPath) @@ -55,18 +175,7 @@ int retCode = FreeLibrary(sqLiteHndl); if(retCode == 0) { - LPCVOID lpMsgBuf; - - DWORD err = GetLastError(); - FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, - 0, NULL - ); - std::wstring wErrMsg((wchar_t*)lpMsgBuf); - std::string errMsg = Util::wstring2string(wErrMsg); - //LOGERROR(errMsg); - + //LOGERROR(GetErrorMessage()); } } @@ -167,16 +276,7 @@ if(aFnPtr != NULL) return; - LPCVOID lpMsgBuf; - - DWORD err = GetLastError(); - FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, - 0, NULL - ); - std::wstring wErrMsg((wchar_t*)lpMsgBuf); - std::string errMsg = Util::wstring2string(wErrMsg); + std::string errMsg = GetErrorMessage(); //LOGERROR(errMsg); throw CException(errMsg,ExceptionCodes::ELibraryLoadError); } @@ -362,9 +462,46 @@ CheckSqlErrCode(err); } + +#ifdef __TOOLS2_LINUX__ +void CStatement::BindStr(TInt aParameterIndex, const std::wstring &aParameterStr, int aConvertSlash=allowSlashConversion) +#else void CStatement::BindStr(TInt aParameterIndex, const std::wstring &aParameterStr) +#endif { + /* + * Under LINUX : Because of the UTF-32 format of wstring, we can't directly use the sqlite3_bind_text16() which + * requires UTF-16 format. So, we convert the UTF-32 data into UTF-16 before using it. + * + * Under WINDOWS : No conversion required since wstring will be in UTF-16 format itself. + */ + + #ifdef __LINUX__ + // Make sure that the wstring passed to this function is not having any trailing + // explicit NUL( Preferably, pass c_str() part of wstring ). + // + // Only case in which you shouldn't pass c_str() is that the wstring has NUL as + // part of its actual string content(like swtypename + L'\0' + someID etc). + + // In order to maintain the consistency of DB contents across the WINDOWS and LINUX platforms, before interacting + // with the DB we convert the local paths into WINDOWS specific paths. + // + // If aParameterStr is not a PATH but contains a forward slash, we should restrain + // from the slash conversion. One such instance is MimeType. + // + std::wstring temp = aParameterStr; + if( aConvertSlash == allowSlashConversion ) + { + ConvertToWindowsSpecificPaths(temp); + } + + utf16WString utf16s = utf32WString2utf16WString(temp); + + TInt err = iLibraryHandler.sqlite3_bind_text16(iStmtHandle, aParameterIndex, utf16s.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT); + + #else TInt err = iLibraryHandler.sqlite3_bind_text16(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT); + #endif // The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately CheckSqlErrCode(err); } @@ -376,6 +513,25 @@ CheckSqlErrCode(err); } +void CStatement::BindBinary(TInt aParameterIndex, const std::wstring &aParameterStr) + { + #ifdef __LINUX__ + // To maintain consistency of the binary equivalent of the wstring + // being binded, we convert the wstring with UTF-32 encoding under LINUX + // to UTF-16 encoding which is same as that of wstring under WINDOWS. + + std::wstring temp = aParameterStr; + utf16WString utf16s = utf32WString2utf16WString(temp); + + TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, utf16s.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT); + #else + TInt err = iLibraryHandler.sqlite3_bind_blob(iStmtHandle, aParameterIndex, aParameterStr.c_str(), aParameterStr.size()*2, SQLITE_TRANSIENT); + #endif + + // The fifth argument has the value SQLITE_TRANSIENT, it means that SQLite makes its own private copy of the data immediately + CheckSqlErrCode(err); + } + void CStatement::Reset() { TInt err = iLibraryHandler.sqlite3_reset(iStmtHandle); @@ -404,8 +560,28 @@ std::wstring CStatement::StrColumn(int aColumnId ) const { - std::wstring columnValue(static_cast(iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId))); - return columnValue; + /* + * Under LINUX : While writing onto DB, we bind the wstring after converting it into UTF-16 from + * UTF-32 format. So, now while reading we need to convert the UTF-16 data back to UTF-32 + * format so that we can return the required UTF-32 wstring. + * + * Under WINDOWS : No conversion required since wstring will be in UTF-16 format itself. + */ + #ifdef __LINUX__ + + utf16WString utf16S = iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId); + std::wstring utf32S = utf16WString2utf32WString(utf16S); + + // The DB will have WINDOWS specific paths to maintain the consistency of DB contents across WINDOWS and LINUX platforms. + // So, after reading under LINUX we will convert them into local paths. + + ConvertToLinuxSpecificPaths(utf32S); + + #else + std::wstring utf32S(static_cast(iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId))); + #endif + + return utf32S; } TInt64 CStatement::Int64Column(int aColumnId ) const