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