1 #include "stdafx.h"
2 #include "MASTER.h"
3 #define TECPLOTENGINEMODULE
4 /*
5 *****************************************************************
6 *****************************************************************
7 ******* ********
8 ****** Copyright (C) 1988-2010 Tecplot, Inc. *******
9 ******* ********
10 *****************************************************************
11 *****************************************************************
12 */
13
14 #include "GLOBAL.h"
15 #include "TASSERT.h"
16 #include "Q_UNICODE.h"
17
18
19 using namespace std;
20
21 namespace tecplot
22 {
23 namespace strutil
24 {
25
26 #if defined MSWIN && !defined TECPLOTKERNEL
27 /**
28 * Stub function for non-TECPLOTKERNEL
29 */
LookUpTranslation(string & str)30 string LookUpTranslation(string& str)
31 {
32 return string(str);
33 }
34 #endif
35
36 /**
37 * Convenience function for creating Utf8 string translations.
38 *
39 * @param str
40 * String to translate.
41 *
42 * @return
43 * A new Utf8 translated string.
44 */
createUtf8StringTranslation(string & str)45 static inline string* createUtf8StringTranslation(string& str)
46 {
47 #if defined MSWIN
48 string *result = new string(LookUpTranslation(str));
49 #else
50 string *result = new string(str);
51 #endif
52 ENSURE(VALID_REF(result));
53 return result;
54 }
55
56 #if defined MSWIN
57 /**
58 * Convenience function for creating wide string translations.
59 *
60 * @param str
61 * String to translate.
62 *
63 * @return
64 * A new wide translated string.
65 */
createWideStringTranslation(string & str)66 static inline wstring* createWideStringTranslation(string& str)
67 {
68 wstring *result = new wstring;
69 *result = StringToWString(LookUpTranslation(str));
70
71 ENSURE(VALID_REF(result));
72 return result;
73 }
74 #endif
75
76 #if defined MSWIN
77 /**
78 * Convenience function for creating wide string with the given mode.
79 *
80 * @param mode
81 * Indicates if this string is to be translated or not.
82 * @param str
83 * String to translate.
84 *
85 * @return
86 * A new wide translated string.
87 */
createWideString(TranslatedString::Mode mode,string & str)88 static inline wstring* createWideString(TranslatedString::Mode mode,
89 string& str)
90 {
91 REQUIRE(mode == TranslatedString::DoTranslate || mode == TranslatedString::DontTranslate);
92
93 wstring* result;
94 if (mode == TranslatedString::DoTranslate)
95 result = createWideStringTranslation(str);
96 else
97 result = new wstring(StringToWString(str));
98
99 return result;
100 }
101 #endif
102
103 /**
104 */
init(TranslatedString::Mode mode,const char * str,const char * translatorNotes)105 void TranslatedString::init(TranslatedString::Mode mode,
106 const char* str,
107 const char* translatorNotes)
108 {
109 REQUIRE(mode == DoTranslate || mode == DontTranslate);
110 REQUIRE(VALID_REF_OR_NULL(str));
111 REQUIRE(VALID_REF_OR_NULL(translatorNotes));
112
113 m_mode = mode;
114 m_isNull = (str == NULL);
115 if (!m_isNull)
116 m_string = str;
117 m_utf8String = NULL; // ...on demand resource
118 #if defined MSWIN
119 m_wideString = NULL; // ...on demand resource
120 #endif
121 }
122
123 /**
124 */
TranslatedString()125 TranslatedString::TranslatedString()
126 {
127 init(DontTranslate, (const char*)NULL, (const char*)NULL);
128 ENSURE(this->isValid());
129 }
130
131 /**
132 */
null()133 TranslatedString TranslatedString::null()
134 {
135 return dontTranslate(NULL);
136 }
137
138 /**
139 */
TranslatedString(TranslatedString::Mode mode,const char * str,const char * translatorNotes)140 TranslatedString::TranslatedString(TranslatedString::Mode mode,
141 const char* str,
142 const char* translatorNotes)
143 {
144
145 REQUIRE(mode == DoTranslate || mode == DontTranslate);
146 REQUIRE(VALID_REF_OR_NULL(str));
147 REQUIRE(VALID_REF_OR_NULL(translatorNotes));
148
149 init(mode, str, translatorNotes);
150 ENSURE(this->isValid());
151 }
152
153 /**
154 */
~TranslatedString()155 TranslatedString::~TranslatedString()
156 {
157 delete m_utf8String;
158 #if defined MSWIN
159 delete m_wideString;
160 #endif
161 }
162
163 #if !defined NO_ASSERTS
164 /**
165 */
isValid() const166 bool TranslatedString::isValid() const
167 {
168 CHECK(IMPLICATION(m_isNull, m_string.length() == 0));
169 #if 0
170 /* TODO(DTO/RMS/CAM): 11/2/2007
171 * Code currently exists in Tecplot where we call translate() on a
172 * variable. This seems wrong and at times (PleaseWait() in
173 * particular) the variable passed is a NULL pointer which causes
174 * this assertion to fail. There is not enough time before v11.2
175 * release to remove all translate() calls to non-literal strings so
176 * we'll have to do this as a post release cleanup. For now just
177 * deactivate this assertion.
178 */
179 CHECK(IMPLICATION(m_isNull, m_mode == DontTranslate));
180 #endif
181
182 return true;
183 }
184 #endif
185
186 /**
187 */
isNull() const188 bool TranslatedString::isNull() const
189 {
190 INVARIANT(this->isValid());
191 return m_isNull;
192 }
193
194 /**
195 */
isNullOrZeroLength() const196 bool TranslatedString::isNullOrZeroLength() const
197 {
198 INVARIANT(this->isValid());
199 return m_isNull || m_string.length() == 0;
200 }
201
202 /**
203 */
c_str()204 const char* TranslatedString::c_str()
205 {
206 INVARIANT(this->isValid());
207
208 const char* result = NULL;
209 if (!isNull())
210 {
211 if (m_mode == DoTranslate)
212 {
213 if (m_utf8String == NULL)
214 m_utf8String = createUtf8StringTranslation(m_string);
215 result = m_utf8String->c_str();
216 }
217 else // ...if we aren't translating don't bother creating another Utf8 copy just use m_string
218 result = m_string.c_str();
219 }
220
221 ENSURE(result == NULL || VALID_REF(result));
222 return result;
223 }
224
225 #if defined MSWIN
226 /**
227 */
c_wstr()228 const wchar_t *TranslatedString::c_wstr()
229 {
230 INVARIANT(this->isValid());
231
232 const wchar_t *result = NULL;
233 if (!isNull())
234 {
235 if (m_wideString == NULL)
236 m_wideString = createWideString(m_mode, m_string);
237 result = m_wideString->c_str();
238 }
239
240 ENSURE(result == NULL || VALID_REF(result));
241 return result;
242 }
243 #endif
244
245 /**
246 */
operator string()247 TranslatedString::operator string()
248 {
249 INVARIANT(this->isValid());
250 REQUIRE(!isNull());
251
252 string* result;
253 if (m_mode == DoTranslate)
254 {
255 if (m_utf8String == NULL)
256 m_utf8String = createUtf8StringTranslation(m_string);
257 result = m_utf8String;
258 }
259 else // ...if we aren't translating don't bother creating another Utf8 copy just use m_string
260 result = &m_string;
261
262 return *result;
263 }
264
265 #if defined MSWIN
266 /**
267 */
operator wstring()268 TranslatedString::operator wstring()
269 {
270 INVARIANT(this->isValid());
271 REQUIRE(!isNull());
272
273 if (m_wideString == NULL)
274 m_wideString = createWideString(m_mode, m_string);
275
276 return *m_wideString;
277 }
278 #endif
279
280 /**
281 */
operator =(const TranslatedString & other)282 TranslatedString& TranslatedString::operator =(const TranslatedString& other)
283 {
284 REQUIRE(other.isValid());
285
286 if (this != &other) // ...only perform if not self assignment
287 {
288 m_mode = other.m_mode;
289 m_isNull = other.m_isNull;
290 m_string = other.m_string;
291 m_utf8String = (other.m_utf8String != NULL ? new string(*other.m_utf8String) : NULL);
292 #if defined MSWIN
293 m_wideString = (other.m_wideString != NULL ? new wstring(*other.m_wideString) : NULL);
294 #endif
295 }
296
297 ENSURE(this->isValid());
298 return *this;
299 }
300
301 /**
302 */
TranslatedString(const TranslatedString & other)303 TranslatedString::TranslatedString(const TranslatedString& other)
304 {
305 REQUIRE(other.isValid());
306
307 m_mode = other.m_mode;
308 m_isNull = other.m_isNull;
309 m_string = other.m_string;
310 m_utf8String = (other.m_utf8String != NULL ? new string(*other.m_utf8String) : NULL);
311 #if defined MSWIN
312 m_wideString = (other.m_wideString != NULL ? new wstring(*other.m_wideString) : NULL);
313 #endif
314
315 ENSURE(this->isValid());
316 }
317
318 /**
319 */
translate(const char * str,const char * translatorNotes)320 TranslatedString TranslatedString::translate(const char* str,
321 const char* translatorNotes)
322 {
323 REQUIRE(VALID_REF_OR_NULL(str));
324 REQUIRE(VALID_REF_OR_NULL(translatorNotes));
325
326 return TranslatedString(DoTranslate, str, translatorNotes);
327 }
328
329 /**
330 */
dontTranslate(const char * str)331 TranslatedString TranslatedString::dontTranslate(const char* str)
332 {
333 REQUIRE(VALID_REF_OR_NULL(str));
334
335 return TranslatedString(DontTranslate, str, NULL);
336 }
337
338 }
339 }
340