1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 /*
24 * This file is based on WME Lite.
25 * http://dead-code.org/redir.php?target=wmelite
26 * Copyright (c) 2011 Jan Nedoma
27 */
28
29 #include "common/language.h"
30 #include "common/tokenizer.h"
31 #include "engines/wintermute/base/base_engine.h"
32 #include "engines/wintermute/utils/string_util.h"
33 #include "engines/wintermute/utils/convert_utf.h"
34
35 namespace Wintermute {
36
37 //////////////////////////////////////////////////////////////////////////
compareNoCase(const AnsiString & str1,const AnsiString & str2)38 bool StringUtil::compareNoCase(const AnsiString &str1, const AnsiString &str2) {
39 return (str1.compareToIgnoreCase(str2) == 0);
40 }
41
42 //////////////////////////////////////////////////////////////////////////
43 /*bool StringUtil::CompareNoCase(const WideString &str1, const WideString &str2) {
44 WideString str1lc = str1;
45 WideString str2lc = str2;
46
47 ToLowerCase(str1lc);
48 ToLowerCase(str2lc);
49
50 return (str1lc == str2lc);
51 }*/
52
53 //////////////////////////////////////////////////////////////////////////
utf8ToWide(const Utf8String & Utf8Str)54 WideString StringUtil::utf8ToWide(const Utf8String &Utf8Str) {
55 size_t wideSize = Utf8Str.size();
56
57 uint32 *wideStringNative = new uint32[wideSize + 1];
58
59 const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
60 const UTF8 *sourceEnd = sourceStart + wideSize;
61
62 UTF32 *targetStart = reinterpret_cast<UTF32 *>(wideStringNative);
63 UTF32 *targetEnd = targetStart + wideSize;
64
65 ConversionResult res = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
66 if (res != conversionOK) {
67 delete[] wideStringNative;
68 return WideString();
69 }
70 *targetStart = 0;
71 WideString resultString(wideStringNative);
72 delete[] wideStringNative;
73 return resultString;
74 }
75
76 //////////////////////////////////////////////////////////////////////////
wideToUtf8(const WideString & WideStr)77 Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
78 size_t wideSize = WideStr.size();
79
80 size_t utf8Size = 4 * wideSize + 1;
81 char *utf8StringNative = new char[utf8Size];
82
83 const UTF32 *sourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
84 const UTF32 *sourceEnd = sourceStart + wideSize;
85
86 UTF8 *targetStart = reinterpret_cast<UTF8 *>(utf8StringNative);
87 UTF8 *targetEnd = targetStart + utf8Size;
88
89 ConversionResult res = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
90 if (res != conversionOK) {
91 delete[] utf8StringNative;
92 return Utf8String();
93 }
94 *targetStart = 0;
95 Utf8String resultString(utf8StringNative);
96 delete[] utf8StringNative;
97 return resultString;
98 }
99
100 //////////////////////////////////////////////////////////////////////////
mapCodePage(TTextCharset charset)101 Common::CodePage StringUtil::mapCodePage(TTextCharset charset) {
102 switch (charset) {
103 case CHARSET_EASTEUROPE:
104 return Common::kWindows1250;
105
106 case CHARSET_RUSSIAN:
107 return Common::kWindows1251;
108
109 case CHARSET_ANSI:
110 return Common::kWindows1252;
111
112 case CHARSET_GREEK:
113 return Common::kWindows1253;
114
115 case CHARSET_TURKISH:
116 return Common::kWindows1254;
117
118 case CHARSET_HEBREW:
119 return Common::kWindows1255;
120
121 case CHARSET_BALTIC:
122 return Common::kWindows1257;
123
124 case CHARSET_DEFAULT:
125 switch (BaseEngine::instance().getLanguage()) {
126
127 //cp1250: Central Europe
128 case Common::CZ_CZE:
129 case Common::HR_HRV:
130 case Common::HU_HUN:
131 case Common::PL_POL:
132 case Common::SK_SVK:
133 return Common::kWindows1250;
134
135 //cp1251: Cyrillic
136 case Common::RU_RUS:
137 case Common::UA_UKR:
138 return Common::kWindows1251;
139
140 //cp1252: Western Europe
141 case Common::DA_DAN:
142 case Common::DE_DEU:
143 case Common::EN_ANY:
144 case Common::EN_GRB:
145 case Common::EN_USA:
146 case Common::ES_ESP:
147 case Common::FI_FIN:
148 case Common::FR_FRA:
149 case Common::IT_ITA:
150 case Common::NB_NOR:
151 case Common::NL_NLD:
152 case Common::PT_BRA:
153 case Common::PT_POR:
154 case Common::SE_SWE:
155 case Common::UNK_LANG:
156 return Common::kWindows1252;
157
158 //cp1253: Greek
159 case Common::GR_GRE:
160 return Common::kWindows1253;
161
162 //cp1254: Turkish
163 case Common::TR_TUR:
164 return Common::kWindows1254;
165
166 //cp1255: Hebrew
167 case Common::HE_ISR:
168 return Common::kWindows1255;
169
170 //cp1257: Baltic
171 case Common::ET_EST:
172 case Common::LV_LAT:
173 return Common::kWindows1257;
174
175 case Common::JA_JPN:
176 case Common::KO_KOR:
177 case Common::ZH_CNA:
178 case Common::ZH_TWN:
179 default:
180 warning("Unsupported charset: %d", charset);
181 return Common::kWindows1252;
182 }
183
184 case CHARSET_OEM:
185 case CHARSET_CHINESEBIG5:
186 case CHARSET_GB2312:
187 case CHARSET_HANGUL:
188 case CHARSET_MAC:
189 case CHARSET_SHIFTJIS:
190 case CHARSET_SYMBOL:
191 case CHARSET_VIETNAMESE:
192 case CHARSET_JOHAB:
193 case CHARSET_ARABIC:
194 case CHARSET_THAI:
195 default:
196 warning("Unsupported charset: %d", charset);
197 return Common::kWindows1252;
198 }
199 }
200
201 //////////////////////////////////////////////////////////////////////////
ansiToWide(const AnsiString & str,TTextCharset charset)202 WideString StringUtil::ansiToWide(const AnsiString &str, TTextCharset charset) {
203 return Common::convertToU32String(str.c_str(), mapCodePage(charset));
204 }
205
206 //////////////////////////////////////////////////////////////////////////
wideToAnsi(const WideString & wstr,TTextCharset charset)207 AnsiString StringUtil::wideToAnsi(const WideString &wstr, TTextCharset charset) {
208 return Common::convertFromU32String(wstr, mapCodePage(charset));
209 }
210
211 //////////////////////////////////////////////////////////////////////////
isUtf8BOM(const byte * buffer,uint32 bufferSize)212 bool StringUtil::isUtf8BOM(const byte *buffer, uint32 bufferSize) {
213 if (bufferSize > 3 && buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF) {
214 return true;
215 } else {
216 return false;
217 }
218 }
219
220 //////////////////////////////////////////////////////////////////////////
indexOf(const WideString & str,const WideString & toFind,size_t startFrom)221 int StringUtil::indexOf(const WideString &str, const WideString &toFind, size_t startFrom) {
222 return str.find(toFind, startFrom);
223 }
224
encodeSetting(const Common::String & str)225 Common::String StringUtil::encodeSetting(const Common::String &str) {
226 for (uint32 i = 0; i < str.size(); i++) {
227 if ((str[i] < 33) || (str[i] == '=') || (str[i] > 126)) {
228 error("Setting contains illegal characters: %s", str.c_str());
229 }
230 }
231 return str;
232 }
233
decodeSetting(const Common::String & str)234 Common::String StringUtil::decodeSetting(const Common::String &str) {
235 return str;
236 }
237
238 //////////////////////////////////////////////////////////////////////////
toString(int val)239 AnsiString StringUtil::toString(int val) {
240 return Common::String::format("%d", val);
241 }
242
243 } // End of namespace Wintermute
244