securityanddataprivacytools/securitytools/certapp/utils/utils.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/securityanddataprivacytools/securitytools/certapp/utils/utils.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,176 @@
+/*
+* Copyright (c) 2008-2009 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include <fstream>
+#include "utils.h"
+#include "logger.h"
+
+#ifndef __LINUX__
+#include <windows.h>
+#endif
+
+typedef unsigned char TUint8;
+typedef unsigned int TUint;
+
+#ifdef __LINUX__
+void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
+{
+	aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::in);
+}
+
+void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
+{
+	aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
+}
+
+#else
+
+WCHAR *WindowsUtf8ToUtf16(const char *aUtf8)
+{
+	int utf8Len = strlen(aUtf8) + 1; // We want to copy the terminator to the new string
+	int utf16Space = MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, 0, 0);
+	if(utf16Space <= 0)
+		{
+		dbg << Log::Indent() << "Failed to convert UTF-8 '" << aUtf8 << "' to UTF16" << Log::Endl();
+		FatalError();
+		return 0;
+		}
+	// prog << Log::Indent() << "utf16Space " << utf16Space << Log::Endl();
+	WCHAR *utf16 = new WCHAR[utf16Space];
+	(void) MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, utf16, utf16Space);
+#if 0
+	prog << Log::Indent() << "Raw UTF16 name is (chars " << utf16Space << ")" << Log::Endl();
+	for(int i=0; i<utf16Space*2; ++i)
+		{
+		prog << TUint(((TUint8 *)utf16)[i]) << Log::Endl();
+		}
+#endif
+	return utf16;
+}
+
+CHAR *WindowsUtf16ToUtf8(const WCHAR *aUtf16)
+{
+	int utf16Len = wcslen(aUtf16) + 1; // We want to copy the terminator to the new string
+	int utf8Space = WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, 0, 0, 0, 0);
+	if(utf8Space <= 0)
+		{
+		dbg << Log::Indent() << "Failed to convert UTF16 string to UTF8" << Log::Endl();
+		FatalError();
+		return 0;
+		}
+	//prog << Log::Indent() << "utf8Space " << utf8Space << Log::Endl();
+	CHAR *utf8 = new CHAR[utf8Space];
+	(void) WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, utf8, utf8Space, 0, 0);
+
+#if 0
+	prog << Log::Indent() << "Raw UTF8 name is (chars " << utf8Space << ")" << Log::Endl();
+	for(int i=0; i<utf8Space; ++i)
+		{
+		prog << TUint(((TUint8 *)utf8)[i]) << Log::Endl();
+		}
+#endif
+	return utf8;
+}
+
+WCHAR *WindowsRetrieveDosName(const WCHAR *aLongName)
+{
+	// Convert to a short DOS file name. File MUST already exist!
+	// len will be space required for string and terminator
+	DWORD len = GetShortPathNameW((WCHAR *)aLongName, 0, 0);
+	if( len <= 0 )
+		{
+		prog << Log::Indent() << "Failed to find existing file and retrieve short name" << Log::Endl();
+		return 0;
+		}
+	
+	//prog << Log::Indent() << "space required for short name is " << len << Log::Endl();
+	WCHAR *shortName = new WCHAR[len];
+	(void) GetShortPathNameW(aLongName, shortName, len);
+	return shortName;
+}
+
+void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
+{
+	// Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename.
+	// The workaround is to convert the UTF-8 name to the short DOS compatible name and open that instead
+
+	// First convert the UTF-8 name to UTF-16 for use with the windows APIs
+	WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
+
+	// Obtain short DOS compatible name for file
+	WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
+	if(utf16NameDos == 0)
+		{
+		aFStream.setstate(std::ios_base::badbit);
+		delete [] utf16Name;
+		return;
+		}
+
+	char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
+
+	aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::in);
+
+	delete [] utf8NameDos;
+	delete [] utf16NameDos;
+	delete [] utf16Name;
+	return;
+}
+
+void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
+{
+	// Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename.
+	// The workaround is to make sure the file already exists and then convert the UTF-8 name to the short DOS compatible name 
+	// and open that instead
+
+	// First convert the UTF-8 name to UTF-16 for use with the windows APIs
+	WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
+
+	// Make sure the file exists
+	HANDLE fh = CreateFileW((WCHAR *)utf16Name, GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,  CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
+	if(fh == INVALID_HANDLE_VALUE)
+		{
+		dbg << Log::Indent() << "Failed to create file '" << aUtf8FileName << "'" << Log::Endl();
+		aFStream.setstate(std::ios_base::badbit);
+		delete [] utf16Name;
+		return;
+		}
+	// Close handle
+	CloseHandle(fh);
+
+
+	// Obtain short DOS compatible name for file
+	WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
+	if(utf16NameDos == 0)
+		{
+		aFStream.setstate(std::ios_base::badbit);
+		delete [] utf16Name;
+		return;
+		}
+
+	char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
+
+	aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
+
+	delete [] utf8NameDos;
+	delete [] utf16NameDos;
+	delete [] utf16Name;
+	return;
+}
+#endif
+
+// End of file