secureswitools/swisistools/source/dbmanager/dbprocessor.cpp
branchRCL_3
changeset 25 7333d7932ef7
parent 0 ba25891c3a9e
child 26 8b7f4e561641
--- 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 <string>
 #include <cassert>
 
+#ifdef __linux__
+#include <dlfcn.h>
+
+
+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<const wchar_t*>(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<const wchar_t*>(iLibraryHandler.sqlite3_column_text16(iStmtHandle, aColumnId)));
+	#endif
+
+	return utf32S;
 	}
 
 TInt64 CStatement::Int64Column(int aColumnId ) const