0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / NCollection / NCollection_UtfString.lxx
1 // Created on: 2013-01-28
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 // =======================================================================
17 // function : GetChar
18 // purpose  :
19 // =======================================================================
20 template<typename Type>
21 Standard_Utf32Char NCollection_UtfString<Type>::GetChar (const Standard_Integer theCharIndex) const
22 {
23   //Standard_ASSERT_SKIP (theCharIndex < myLength, "Out of range");
24   NCollection_UtfIterator<Type> anIter (myString);
25   for (; *anIter != 0; ++anIter)
26   {
27     if (anIter.Index() == theCharIndex)
28     {
29       return *anIter;
30     }
31   }
32   return 0;
33 }
34
35 // =======================================================================
36 // function : GetCharBuffer
37 // purpose  :
38 // =======================================================================
39 template<typename Type>
40 const Type* NCollection_UtfString<Type>::GetCharBuffer (const Standard_Integer theCharIndex) const
41 {
42   //Standard_ASSERT_SKIP(theCharIndex < myLength);
43   NCollection_UtfIterator<Type> anIter (myString);
44   for (; *anIter != 0; ++anIter)
45   {
46     if (anIter.Index() == theCharIndex)
47     {
48       return anIter.BufferHere();
49     }
50   }
51   return NULL;
52 }
53
54 // =======================================================================
55 // function : Clear
56 // purpose  :
57 // =======================================================================
58 template<typename Type> inline
59 void NCollection_UtfString<Type>::Clear()
60 {
61   strFree (myString);
62   mySize   = 0;
63   myLength = 0;
64   myString = strAlloc (mySize);
65 }
66
67 // =======================================================================
68 // function : NCollection_UtfString
69 // purpose  :
70 // =======================================================================
71 template<typename Type> inline
72 NCollection_UtfString<Type>::NCollection_UtfString()
73 : myString (strAlloc(0)),
74   mySize   (0),
75   myLength (0)
76 {
77   //
78 }
79
80 // =======================================================================
81 // function : NCollection_UtfString
82 // purpose  :
83 // =======================================================================
84 template<typename Type> inline
85 NCollection_UtfString<Type>::NCollection_UtfString (const NCollection_UtfString& theCopy)
86 : myString (strAlloc (theCopy.mySize)),
87   mySize   (theCopy.mySize),
88   myLength (theCopy.myLength)
89 {
90   strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theCopy.myString, mySize);
91 }
92
93 #ifndef OCCT_NO_RVALUE_REFERENCE
94 // =======================================================================
95 // function : NCollection_UtfString
96 // purpose  :
97 // =======================================================================
98 template<typename Type> inline
99 NCollection_UtfString<Type>::NCollection_UtfString (NCollection_UtfString&& theOther)
100 : myString(theOther.myString),
101   mySize  (theOther.mySize),
102   myLength(theOther.myLength)
103 {
104   theOther.myString = NULL;
105   theOther.mySize   = 0;
106   theOther.myLength = 0;
107 }
108 #endif
109
110 // =======================================================================
111 // function : NCollection_UtfString
112 // purpose  :
113 // =======================================================================
114 template<typename Type> inline
115 NCollection_UtfString<Type>::NCollection_UtfString (const char*            theCopyUtf8,
116                                                     const Standard_Integer theLength)
117 : myString (NULL),
118   mySize   (0),
119   myLength (0)
120 {
121   FromUnicode (theCopyUtf8, theLength);
122 }
123
124 // =======================================================================
125 // function : NCollection_UtfString
126 // purpose  :
127 // =======================================================================
128 template<typename Type> inline
129 NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16,
130                                                     const Standard_Integer    theLength)
131 : myString (NULL),
132   mySize   (0),
133   myLength (0)
134 {
135   FromUnicode (theCopyUtf16, theLength);
136 }
137
138 // =======================================================================
139 // function : NCollection_UtfString
140 // purpose  :
141 // =======================================================================
142 template<typename Type> inline
143 NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
144                                                     const Standard_Integer     theLength)
145 : myString (NULL),
146   mySize   (0),
147   myLength (0)
148 {
149   FromUnicode (theCopyUtf32, theLength);
150 }
151
152 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) || (defined(_MSC_VER) && _MSC_VER >= 1900)
153 // =======================================================================
154 // function : NCollection_UtfString
155 // purpose  :
156 // =======================================================================
157 template<typename Type> inline
158 NCollection_UtfString<Type>::NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
159                                                     const Standard_Integer   theLength)
160 : myString (NULL),
161   mySize   (0),
162   myLength (0)
163 {
164   FromUnicode (theCopyUtfWide, theLength);
165 }
166 #endif
167
168 // =======================================================================
169 // function : ~NCollection_UtfString
170 // purpose  :
171 // =======================================================================
172 template<typename Type> inline
173 NCollection_UtfString<Type>::~NCollection_UtfString()
174 {
175   strFree (myString);
176 }
177
178 // =======================================================================
179 // function : Assign
180 // purpose  :
181 // =======================================================================
182 template<typename Type> inline
183 const NCollection_UtfString<Type>& NCollection_UtfString<Type>::Assign (const NCollection_UtfString<Type>& theOther)
184 {
185   if (this == &theOther)
186   {
187     return (*this);
188   }
189
190   strFree (myString);
191   mySize   = theOther.mySize;
192   myLength = theOther.myLength;
193   myString = strAlloc (mySize);
194   strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theOther.myString, mySize);
195   return (*this);
196 }
197
198 // =======================================================================
199 // function : Swap
200 // purpose  :
201 // =======================================================================
202 template<typename Type> inline
203 void NCollection_UtfString<Type>::Swap (NCollection_UtfString<Type>& theOther)
204 {
205   // Note: we could use std::swap() here, but prefer to not
206   // have dependency on <algorithm> header at that level
207   Type* aString = myString;
208   const Standard_Integer aSize   = mySize;
209   const Standard_Integer aLength = myLength;
210   myString = theOther.myString;
211   mySize   = theOther.mySize;
212   myLength = theOther.myLength;
213   theOther.myString = aString;
214   theOther.mySize   = aSize;
215   theOther.myLength = aLength;
216 }
217
218 #if !defined(__ANDROID__)
219 //! Auxiliary convertion tool.
220 class NCollection_UtfStringTool
221 {
222 public:
223   //! Empty constructor.
224   NCollection_UtfStringTool() : myWideBuffer (NULL) {}
225
226   //! Destructor for temporary resources.
227   Standard_EXPORT ~NCollection_UtfStringTool();
228
229   //! Convert the string from current locale into UNICODE (wide characters) using system APIs.
230   //! Returned pointer will be released by this tool.
231   Standard_EXPORT wchar_t* FromLocale (const char* theString);
232
233   //! Convert the UNICODE (wide characters) string into locale using system APIs.
234   Standard_EXPORT static bool ToLocale (const wchar_t*         theWideString,
235                                         char*                  theBuffer,
236                                         const Standard_Integer theSizeBytes);
237 private:
238   wchar_t* myWideBuffer; //!< temporary variable
239 };
240 #endif
241
242 // =======================================================================
243 // function : FromLocale
244 // purpose  :
245 // =======================================================================
246 template<typename Type> inline
247 void NCollection_UtfString<Type>::FromLocale (const char*            theString,
248                                               const Standard_Integer theLength)
249 {
250 #if defined(__ANDROID__)
251   // no locales on Android
252   FromUnicode (theString, theLength);
253 #else
254   NCollection_UtfStringTool aConvertor;
255   wchar_t* aWideBuffer = aConvertor.FromLocale (theString);
256   if (aWideBuffer == NULL)
257   {
258     Clear();
259     return;
260   }
261   FromUnicode (aWideBuffer, theLength);
262 #endif
263 }
264
265 // =======================================================================
266 // function : ToLocale
267 // purpose  :
268 // =======================================================================
269 template<typename Type> inline
270 bool NCollection_UtfString<Type>::ToLocale (char*                  theBuffer,
271                                             const Standard_Integer theSizeBytes) const
272 {
273 #if defined(__ANDROID__)
274   // no locales on Android
275   NCollection_UtfString<Standard_Utf8Char> anUtf8Copy (myString, myLength);
276   const Standard_Integer aSize = anUtf8Copy.Size() + 1;
277   if (theSizeBytes < aSize)
278   {
279     return false;
280   }
281   std::memcpy (theBuffer, anUtf8Copy.ToCString(), (Standard_Size )aSize);
282   return true;
283 #else
284   NCollection_UtfString<wchar_t> aWideCopy (myString, myLength);
285   return NCollection_UtfStringTool::ToLocale (aWideCopy.ToCString(), theBuffer, theSizeBytes);
286 #endif
287 }
288
289 // =======================================================================
290 // function : operator=
291 // purpose  :
292 // =======================================================================
293 template<typename Type> inline
294 const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const char* theStringUtf8)
295 {
296   FromUnicode (theStringUtf8);
297   return (*this);
298 }
299
300 // =======================================================================
301 // function : operator=
302 // purpose  :
303 // =======================================================================
304 template<typename Type> inline
305 const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const Standard_WideChar* theStringUtfWide)
306 {
307   FromUnicode (theStringUtfWide);
308   return (*this);
309 }
310
311 // =======================================================================
312 // function : IsEqual
313 // purpose  :
314 // =======================================================================
315 template<typename Type> inline
316 bool NCollection_UtfString<Type>::IsEqual (const NCollection_UtfString& theCompare) const
317 {
318   return this == &theCompare
319       || strAreEqual (myString, mySize, theCompare.myString, theCompare.mySize);
320 }
321
322 // =======================================================================
323 // function : operator!=
324 // purpose  :
325 // =======================================================================
326 template<typename Type> inline
327 bool NCollection_UtfString<Type>::operator!= (const NCollection_UtfString& theCompare) const
328 {
329   return (!NCollection_UtfString::operator== (theCompare));
330 }
331
332 // =======================================================================
333 // function : operator+=
334 // purpose  :
335 // =======================================================================
336 template<typename Type> inline
337 NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator+= (const NCollection_UtfString<Type>& theAppend)
338 {
339   if (theAppend.IsEmpty())
340   {
341     return (*this);
342   }
343
344   // create new string
345   Standard_Integer aSize = mySize + theAppend.mySize;
346   Type* aString = strAlloc (aSize);
347   strCopy ((Standard_Byte* )aString,          (const Standard_Byte* )myString,           mySize);
348   strCopy ((Standard_Byte* )aString + mySize, (const Standard_Byte* )theAppend.myString, theAppend.mySize);
349
350   strFree (myString);
351   mySize   = aSize;
352   myString = aString;
353   myLength += theAppend.myLength;
354   return (*this);
355 }
356
357 // =======================================================================
358 // function : SubString
359 // purpose  :
360 // =======================================================================
361 template<typename Type> inline
362 NCollection_UtfString<Type> NCollection_UtfString<Type>::SubString (const Standard_Integer theStart,
363                                                                     const Standard_Integer theEnd) const
364 {
365   if (theStart >= theEnd)
366   {
367     return NCollection_UtfString<Type>();
368   }
369   for (NCollection_UtfIterator<Type> anIter(myString); *anIter != 0; ++anIter)
370   {
371     if (anIter.Index() >= theStart)
372     {
373       return NCollection_UtfString<Type> (anIter.BufferHere(), theEnd - theStart);
374     }
375   }
376   return NCollection_UtfString<Type>();
377 }
378
379 // =======================================================================
380 // function : ToUtf8
381 // purpose  :
382 // =======================================================================
383 template<typename Type> inline
384 const NCollection_UtfString<Standard_Utf8Char> NCollection_UtfString<Type>::ToUtf8() const
385 {
386   NCollection_UtfString<Standard_Utf8Char> aCopy;
387   aCopy.FromUnicode (myString);
388   return aCopy;
389 }
390
391 // =======================================================================
392 // function : ToUtf16
393 // purpose  :
394 // =======================================================================
395 template<typename Type> inline
396 const NCollection_UtfString<Standard_Utf16Char> NCollection_UtfString<Type>::ToUtf16() const
397 {
398   NCollection_UtfString<Standard_Utf16Char> aCopy;
399   aCopy.FromUnicode (myString);
400   return aCopy;
401 }
402
403 // =======================================================================
404 // function : ToUtf32
405 // purpose  :
406 // =======================================================================
407 template<typename Type> inline
408 const NCollection_UtfString<Standard_Utf32Char> NCollection_UtfString<Type>::ToUtf32() const
409 {
410   NCollection_UtfString<Standard_Utf32Char> aCopy;
411   aCopy.FromUnicode (myString);
412   return aCopy;
413 }
414
415 // =======================================================================
416 // function : ToUtfWide
417 // purpose  :
418 // =======================================================================
419 template<typename Type> inline
420 const NCollection_UtfString<Standard_WideChar> NCollection_UtfString<Type>::ToUtfWide() const
421 {
422   NCollection_UtfString<Standard_WideChar> aCopy;
423   aCopy.FromUnicode (myString);
424   return aCopy;
425 }