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