securityanddataprivacytools/securitytools/certapp/utils/utils.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <fstream>
       
    20 #include "utils.h"
       
    21 #include "logger.h"
       
    22 
       
    23 #ifndef __LINUX__
       
    24 #include <windows.h>
       
    25 #endif
       
    26 
       
    27 typedef unsigned char TUint8;
       
    28 typedef unsigned int TUint;
       
    29 
       
    30 #ifdef __LINUX__
       
    31 void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
       
    32 {
       
    33 	aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::in);
       
    34 }
       
    35 
       
    36 void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
       
    37 {
       
    38 	aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
       
    39 }
       
    40 
       
    41 #else
       
    42 
       
    43 WCHAR *WindowsUtf8ToUtf16(const char *aUtf8)
       
    44 {
       
    45 	int utf8Len = strlen(aUtf8) + 1; // We want to copy the terminator to the new string
       
    46 	int utf16Space = MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, 0, 0);
       
    47 	if(utf16Space <= 0)
       
    48 		{
       
    49 		dbg << Log::Indent() << "Failed to convert UTF-8 '" << aUtf8 << "' to UTF16" << Log::Endl();
       
    50 		FatalError();
       
    51 		return 0;
       
    52 		}
       
    53 	// prog << Log::Indent() << "utf16Space " << utf16Space << Log::Endl();
       
    54 	WCHAR *utf16 = new WCHAR[utf16Space];
       
    55 	(void) MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, utf16, utf16Space);
       
    56 #if 0
       
    57 	prog << Log::Indent() << "Raw UTF16 name is (chars " << utf16Space << ")" << Log::Endl();
       
    58 	for(int i=0; i<utf16Space*2; ++i)
       
    59 		{
       
    60 		prog << TUint(((TUint8 *)utf16)[i]) << Log::Endl();
       
    61 		}
       
    62 #endif
       
    63 	return utf16;
       
    64 }
       
    65 
       
    66 CHAR *WindowsUtf16ToUtf8(const WCHAR *aUtf16)
       
    67 {
       
    68 	int utf16Len = wcslen(aUtf16) + 1; // We want to copy the terminator to the new string
       
    69 	int utf8Space = WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, 0, 0, 0, 0);
       
    70 	if(utf8Space <= 0)
       
    71 		{
       
    72 		dbg << Log::Indent() << "Failed to convert UTF16 string to UTF8" << Log::Endl();
       
    73 		FatalError();
       
    74 		return 0;
       
    75 		}
       
    76 	//prog << Log::Indent() << "utf8Space " << utf8Space << Log::Endl();
       
    77 	CHAR *utf8 = new CHAR[utf8Space];
       
    78 	(void) WideCharToMultiByte(CP_UTF8, 0, aUtf16, utf16Len, utf8, utf8Space, 0, 0);
       
    79 
       
    80 #if 0
       
    81 	prog << Log::Indent() << "Raw UTF8 name is (chars " << utf8Space << ")" << Log::Endl();
       
    82 	for(int i=0; i<utf8Space; ++i)
       
    83 		{
       
    84 		prog << TUint(((TUint8 *)utf8)[i]) << Log::Endl();
       
    85 		}
       
    86 #endif
       
    87 	return utf8;
       
    88 }
       
    89 
       
    90 WCHAR *WindowsRetrieveDosName(const WCHAR *aLongName)
       
    91 {
       
    92 	// Convert to a short DOS file name. File MUST already exist!
       
    93 	// len will be space required for string and terminator
       
    94 	DWORD len = GetShortPathNameW((WCHAR *)aLongName, 0, 0);
       
    95 	if( len <= 0 )
       
    96 		{
       
    97 		prog << Log::Indent() << "Failed to find existing file and retrieve short name" << Log::Endl();
       
    98 		return 0;
       
    99 		}
       
   100 	
       
   101 	//prog << Log::Indent() << "space required for short name is " << len << Log::Endl();
       
   102 	WCHAR *shortName = new WCHAR[len];
       
   103 	(void) GetShortPathNameW(aLongName, shortName, len);
       
   104 	return shortName;
       
   105 }
       
   106 
       
   107 void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
       
   108 {
       
   109 	// Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename.
       
   110 	// The workaround is to convert the UTF-8 name to the short DOS compatible name and open that instead
       
   111 
       
   112 	// First convert the UTF-8 name to UTF-16 for use with the windows APIs
       
   113 	WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
       
   114 
       
   115 	// Obtain short DOS compatible name for file
       
   116 	WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
       
   117 	if(utf16NameDos == 0)
       
   118 		{
       
   119 		aFStream.setstate(std::ios_base::badbit);
       
   120 		delete [] utf16Name;
       
   121 		return;
       
   122 		}
       
   123 
       
   124 	char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
       
   125 
       
   126 	aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::in);
       
   127 
       
   128 	delete [] utf8NameDos;
       
   129 	delete [] utf16NameDos;
       
   130 	delete [] utf16Name;
       
   131 	return;
       
   132 }
       
   133 
       
   134 void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
       
   135 {
       
   136 	// Unfortunately the windows C++ STL library will not open files specified via a UTF-8 filename.
       
   137 	// The workaround is to make sure the file already exists and then convert the UTF-8 name to the short DOS compatible name 
       
   138 	// and open that instead
       
   139 
       
   140 	// First convert the UTF-8 name to UTF-16 for use with the windows APIs
       
   141 	WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
       
   142 
       
   143 	// Make sure the file exists
       
   144 	HANDLE fh = CreateFileW((WCHAR *)utf16Name, GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,  CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
       
   145 	if(fh == INVALID_HANDLE_VALUE)
       
   146 		{
       
   147 		dbg << Log::Indent() << "Failed to create file '" << aUtf8FileName << "'" << Log::Endl();
       
   148 		aFStream.setstate(std::ios_base::badbit);
       
   149 		delete [] utf16Name;
       
   150 		return;
       
   151 		}
       
   152 	// Close handle
       
   153 	CloseHandle(fh);
       
   154 
       
   155 
       
   156 	// Obtain short DOS compatible name for file
       
   157 	WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
       
   158 	if(utf16NameDos == 0)
       
   159 		{
       
   160 		aFStream.setstate(std::ios_base::badbit);
       
   161 		delete [] utf16Name;
       
   162 		return;
       
   163 		}
       
   164 
       
   165 	char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
       
   166 
       
   167 	aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
       
   168 
       
   169 	delete [] utf8NameDos;
       
   170 	delete [] utf16NameDos;
       
   171 	delete [] utf16Name;
       
   172 	return;
       
   173 }
       
   174 #endif
       
   175 
       
   176 // End of file