First public contribution.
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
27 typedef unsigned char TUint8;
28 typedef unsigned int TUint;
31 void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
33 aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::in);
36 void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
38 aFStream.open(aUtf8FileName, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
43 WCHAR *WindowsUtf8ToUtf16(const char *aUtf8)
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);
49 dbg << Log::Indent() << "Failed to convert UTF-8 '" << aUtf8 << "' to UTF16" << Log::Endl();
53 // prog << Log::Indent() << "utf16Space " << utf16Space << Log::Endl();
54 WCHAR *utf16 = new WCHAR[utf16Space];
55 (void) MultiByteToWideChar(CP_UTF8, 0, aUtf8, utf8Len, utf16, utf16Space);
57 prog << Log::Indent() << "Raw UTF16 name is (chars " << utf16Space << ")" << Log::Endl();
58 for(int i=0; i<utf16Space*2; ++i)
60 prog << TUint(((TUint8 *)utf16)[i]) << Log::Endl();
66 CHAR *WindowsUtf16ToUtf8(const WCHAR *aUtf16)
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);
72 dbg << Log::Indent() << "Failed to convert UTF16 string to UTF8" << Log::Endl();
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);
81 prog << Log::Indent() << "Raw UTF8 name is (chars " << utf8Space << ")" << Log::Endl();
82 for(int i=0; i<utf8Space; ++i)
84 prog << TUint(((TUint8 *)utf8)[i]) << Log::Endl();
90 WCHAR *WindowsRetrieveDosName(const WCHAR *aLongName)
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);
97 prog << Log::Indent() << "Failed to find existing file and retrieve short name" << Log::Endl();
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);
107 void OpenUtf8FStreamForRead(std::fstream &aFStream, const char *aUtf8FileName)
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
112 // First convert the UTF-8 name to UTF-16 for use with the windows APIs
113 WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
115 // Obtain short DOS compatible name for file
116 WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
117 if(utf16NameDos == 0)
119 aFStream.setstate(std::ios_base::badbit);
124 char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
126 aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::in);
128 delete [] utf8NameDos;
129 delete [] utf16NameDos;
134 void OpenUtf8FStreamForWrite(std::fstream &aFStream, const char *aUtf8FileName)
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
140 // First convert the UTF-8 name to UTF-16 for use with the windows APIs
141 WCHAR *utf16Name = WindowsUtf8ToUtf16(aUtf8FileName);
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)
147 dbg << Log::Indent() << "Failed to create file '" << aUtf8FileName << "'" << Log::Endl();
148 aFStream.setstate(std::ios_base::badbit);
156 // Obtain short DOS compatible name for file
157 WCHAR *utf16NameDos = WindowsRetrieveDosName(utf16Name);
158 if(utf16NameDos == 0)
160 aFStream.setstate(std::ios_base::badbit);
165 char *utf8NameDos = WindowsUtf16ToUtf8(utf16NameDos);
167 aFStream.open(utf8NameDos, std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
169 delete [] utf8NameDos;
170 delete [] utf16NameDos;