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