0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[occt.git] / src / NCollection / NCollection_UtfString.lxx
CommitLineData
a174a3c5 1// Created on: 2013-01-28
2// Created by: Kirill GAVRILOV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
a174a3c5 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
a174a3c5 6//
d5f74e42 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
973c2be1 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.
a174a3c5 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
a174a3c5 15
16// =======================================================================
17// function : strGetAdvance
18// purpose : Compute advance for specified string.
19// =======================================================================
20template<typename TypeTo> template<typename TypeFrom> inline
21void NCollection_UtfString<TypeTo>::strGetAdvance (const TypeFrom* theStringUtf,
22 const Standard_Integer theLengthMax,
23 Standard_Integer& theSizeBytes,
24 Standard_Integer& theLength)
25{
26 theSizeBytes = 0;
27 theLength = 0;
28 NCollection_UtfIterator<TypeFrom> anIter (theStringUtf);
29 const Standard_Integer aLengthMax = (theLengthMax > 0) ? theLengthMax : IntegerLast();
30 switch (sizeof(TypeTo))
31 {
32 case sizeof(Standard_Utf8Char):
33 {
34 for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
35 {
36 theSizeBytes += anIter.AdvanceBytesUtf8();
37 }
38 theLength = anIter.Index();
39 return;
40 }
41 case sizeof(Standard_Utf16Char):
42 {
43 for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
44 {
45 theSizeBytes += anIter.AdvanceBytesUtf16();
46 }
47 theLength = anIter.Index();
48 return;
49 }
50 case sizeof(Standard_Utf32Char):
51 {
52 for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
53 {
54 theSizeBytes += anIter.AdvanceBytesUtf32();
55 }
56 theLength = anIter.Index();
57 return;
58 }
59 default: return;
60 }
61}
62
63// =======================================================================
64// function : GetChar
65// purpose :
66// =======================================================================
67template<typename Type>
68Standard_Utf32Char NCollection_UtfString<Type>::GetChar (const Standard_Integer theCharIndex) const
69{
70 //Standard_ASSERT_SKIP (theCharIndex < myLength, "Out of range");
71 NCollection_UtfIterator<Type> anIter (myString);
72 for (; *anIter != 0; ++anIter)
73 {
74 if (anIter.Index() == theCharIndex)
75 {
76 return *anIter;
77 }
78 }
79 return 0;
80}
81
82// =======================================================================
83// function : GetCharBuffer
84// purpose :
85// =======================================================================
86template<typename Type>
87const Type* NCollection_UtfString<Type>::GetCharBuffer (const Standard_Integer theCharIndex) const
88{
89 //Standard_ASSERT_SKIP(theCharIndex < myLength);
90 NCollection_UtfIterator<Type> anIter (myString);
91 for (; *anIter != 0; ++anIter)
92 {
93 if (anIter.Index() == theCharIndex)
94 {
95 return anIter.BufferHere();
96 }
97 }
98 return NULL;
99}
100
101// =======================================================================
102// function : Clear
103// purpose :
104// =======================================================================
105template<typename Type> inline
106void NCollection_UtfString<Type>::Clear()
107{
108 strFree (myString);
109 mySize = 0;
110 myLength = 0;
111 myString = strAlloc (mySize);
112}
113
114// =======================================================================
115// function : NCollection_UtfString
116// purpose :
117// =======================================================================
118template<typename Type> inline
119NCollection_UtfString<Type>::NCollection_UtfString()
120: myString (strAlloc(0)),
121 mySize (0),
122 myLength (0)
123{
124 //
125}
126
127// =======================================================================
128// function : NCollection_UtfString
129// purpose :
130// =======================================================================
131template<typename Type> inline
132NCollection_UtfString<Type>::NCollection_UtfString (const NCollection_UtfString& theCopy)
133: myString (strAlloc (theCopy.mySize)),
134 mySize (theCopy.mySize),
135 myLength (theCopy.myLength)
136{
137 strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theCopy.myString, mySize);
138}
139
140// =======================================================================
141// function : NCollection_UtfString
142// purpose :
143// =======================================================================
144template<typename Type> inline
145NCollection_UtfString<Type>::NCollection_UtfString (const char* theCopyUtf8,
146 const Standard_Integer theLength)
147: myString (NULL),
148 mySize (0),
149 myLength (0)
150{
151 FromUnicode (theCopyUtf8, theLength);
152}
153
154// =======================================================================
155// function : NCollection_UtfString
156// purpose :
157// =======================================================================
158template<typename Type> inline
159NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16,
160 const Standard_Integer theLength)
161: myString (NULL),
162 mySize (0),
163 myLength (0)
164{
165 FromUnicode (theCopyUtf16, theLength);
166}
167
168// =======================================================================
169// function : NCollection_UtfString
170// purpose :
171// =======================================================================
172template<typename Type> inline
173NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
174 const Standard_Integer theLength)
175: myString (NULL),
176 mySize (0),
177 myLength (0)
178{
179 FromUnicode (theCopyUtf32, theLength);
180}
181
15173be5 182#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) || (defined(_MSC_VER) && _MSC_VER >= 1900)
a174a3c5 183// =======================================================================
184// function : NCollection_UtfString
185// purpose :
186// =======================================================================
187template<typename Type> inline
188NCollection_UtfString<Type>::NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
189 const Standard_Integer theLength)
190: myString (NULL),
191 mySize (0),
192 myLength (0)
193{
194 FromUnicode (theCopyUtfWide, theLength);
195}
fb0b0531 196#endif
a174a3c5 197
198// =======================================================================
199// function : ~NCollection_UtfString
200// purpose :
201// =======================================================================
202template<typename Type> inline
203NCollection_UtfString<Type>::~NCollection_UtfString()
204{
205 strFree (myString);
206}
207
208// =======================================================================
209// function : operator=
210// purpose :
211// =======================================================================
212template<typename Type> inline
213const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const NCollection_UtfString<Type>& theOther)
214{
215 if (this == &theOther)
216 {
217 return (*this);
218 }
219
220 strFree (myString);
221 mySize = theOther.mySize;
222 myLength = theOther.myLength;
223 myString = strAlloc (mySize);
224 strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theOther.myString, mySize);
225 return (*this);
226}
227
228// =======================================================================
229// function : FromUnicode
230// purpose :
231// =======================================================================
232template<typename Type> template<typename TypeFrom>
233void NCollection_UtfString<Type>::FromUnicode (const TypeFrom* theStringUtf,
234 const Standard_Integer theLength)
235{
236 Type* anOldBuffer = myString; // necessary in case of self-copying
237 NCollection_UtfIterator<TypeFrom> anIterRead (theStringUtf);
238 if (*anIterRead == 0)
239 {
240 // special case
241 Clear();
242 return;
243 }
244
245 switch (sizeof(TypeFrom)) // use switch() rather than if() to shut up msvc compiler
246 {
247 case sizeof(Type):
248 {
249 if (theLength > 0)
250 {
251 // optimized copy
252 for(; *anIterRead != 0 && anIterRead.Index() < theLength; ++anIterRead) {}
253
254 mySize = Standard_Integer((Standard_Byte* )anIterRead.BufferHere() - (Standard_Byte* )theStringUtf);
255 myLength = anIterRead.Index();
256 myString = strAlloc (mySize);
257 strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theStringUtf, mySize);
258 strFree (anOldBuffer);
259 return;
260 }
261 }
262 default: break;
263 }
264
265 strGetAdvance (theStringUtf, theLength, mySize, myLength);
266 myString = strAlloc (mySize);
267 // reset iterator
268 anIterRead.Init (theStringUtf);
269 Type* anIterWrite = myString;
270 for (; *anIterRead != 0 && anIterRead.Index() < myLength; ++anIterRead)
271 {
272 anIterWrite = anIterRead.GetUtf (anIterWrite);
273 }
274 strFree (anOldBuffer);
275}
276
ab2335ae 277#if !defined(__ANDROID__)
7c65581d 278//! Auxiliary convertion tool.
279class NCollection_UtfStringTool
280{
281public:
282 //! Empty constructor.
283 NCollection_UtfStringTool() : myWideBuffer (NULL) {}
284
285 //! Destructor for temporary resources.
286 Standard_EXPORT ~NCollection_UtfStringTool();
287
288 //! Convert the string from current locale into UNICODE (wide characters) using system APIs.
289 //! Returned pointer will be released by this tool.
290 Standard_EXPORT wchar_t* FromLocale (const char* theString);
291
292 //! Convert the UNICODE (wide characters) string into locale using system APIs.
293 Standard_EXPORT static bool ToLocale (const wchar_t* theWideString,
294 char* theBuffer,
295 const Standard_Integer theSizeBytes);
296private:
297 wchar_t* myWideBuffer; //!< temporary variable
298};
ab2335ae 299#endif
7c65581d 300
a174a3c5 301// =======================================================================
302// function : FromLocale
303// purpose :
304// =======================================================================
305template<typename Type> inline
306void NCollection_UtfString<Type>::FromLocale (const char* theString,
307 const Standard_Integer theLength)
308{
ab2335ae 309#if defined(__ANDROID__)
310 // no locales on Android
311 FromUnicode (theString, theLength);
312#else
7c65581d 313 NCollection_UtfStringTool aConvertor;
314 wchar_t* aWideBuffer = aConvertor.FromLocale (theString);
315 if (aWideBuffer == NULL)
a174a3c5 316 {
317 Clear();
318 return;
319 }
a174a3c5 320 FromUnicode (aWideBuffer, theLength);
ab2335ae 321#endif
a174a3c5 322}
323
324// =======================================================================
325// function : ToLocale
326// purpose :
327// =======================================================================
328template<typename Type> inline
329bool NCollection_UtfString<Type>::ToLocale (char* theBuffer,
330 const Standard_Integer theSizeBytes) const
331{
ab2335ae 332#if defined(__ANDROID__)
333 // no locales on Android
334 NCollection_UtfString<Standard_Utf8Char> anUtf8Copy (myString, myLength);
335 const Standard_Integer aSize = anUtf8Copy.Size() + 1;
336 if (theSizeBytes < aSize)
337 {
338 return false;
339 }
340 std::memcpy (theBuffer, anUtf8Copy.ToCString(), (Standard_Size )aSize);
341 return true;
342#else
a174a3c5 343 NCollection_UtfString<wchar_t> aWideCopy (myString, myLength);
7c65581d 344 return NCollection_UtfStringTool::ToLocale (aWideCopy.ToCString(), theBuffer, theSizeBytes);
ab2335ae 345#endif
a174a3c5 346}
347
348// =======================================================================
349// function : operator=
350// purpose :
351// =======================================================================
352template<typename Type> inline
353const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const char* theStringUtf8)
354{
355 FromUnicode (theStringUtf8);
356 return (*this);
357}
358
359// =======================================================================
360// function : operator=
361// purpose :
362// =======================================================================
363template<typename Type> inline
364const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const Standard_WideChar* theStringUtfWide)
365{
366 FromUnicode (theStringUtfWide);
367 return (*this);
368}
369
370// =======================================================================
371// function : IsEqual
372// purpose :
373// =======================================================================
374template<typename Type> inline
375bool NCollection_UtfString<Type>::IsEqual (const NCollection_UtfString& theCompare) const
376{
377 return this == &theCompare
378 || strAreEqual (myString, mySize, theCompare.myString, theCompare.mySize);
379}
380
381// =======================================================================
382// function : operator!=
383// purpose :
384// =======================================================================
385template<typename Type> inline
386bool NCollection_UtfString<Type>::operator!= (const NCollection_UtfString& theCompare) const
387{
388 return (!NCollection_UtfString::operator== (theCompare));
389}
390
391// =======================================================================
392// function : operator+=
393// purpose :
394// =======================================================================
395template<typename Type> inline
396NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator+= (const NCollection_UtfString<Type>& theAppend)
397{
398 if (theAppend.IsEmpty())
399 {
400 return (*this);
401 }
402
403 // create new string
404 Standard_Integer aSize = mySize + theAppend.mySize;
405 Type* aString = strAlloc (aSize);
406 strCopy ((Standard_Byte* )aString, (const Standard_Byte* )myString, mySize);
407 strCopy ((Standard_Byte* )aString + mySize, (const Standard_Byte* )theAppend.myString, theAppend.mySize);
408
409 strFree (myString);
410 mySize = aSize;
411 myString = aString;
412 myLength += theAppend.myLength;
413 return (*this);
414}
415
416// =======================================================================
417// function : SubString
418// purpose :
419// =======================================================================
420template<typename Type> inline
421NCollection_UtfString<Type> NCollection_UtfString<Type>::SubString (const Standard_Integer theStart,
422 const Standard_Integer theEnd) const
423{
424 if (theStart >= theEnd)
425 {
426 return NCollection_UtfString<Type>();
427 }
428 for (NCollection_UtfIterator<Type> anIter(myString); *anIter != 0; ++anIter)
429 {
430 if (anIter.Index() >= theStart)
431 {
432 return NCollection_UtfString<Type> (anIter.BufferHere(), theEnd - theStart);
433 }
434 }
435 return NCollection_UtfString<Type>();
436}
437
438// =======================================================================
439// function : ToUtf8
440// purpose :
441// =======================================================================
442template<typename Type> inline
443const NCollection_UtfString<Standard_Utf8Char> NCollection_UtfString<Type>::ToUtf8() const
444{
445 NCollection_UtfString<Standard_Utf8Char> aCopy;
446 aCopy.FromUnicode (myString);
447 return aCopy;
448}
449
450// =======================================================================
451// function : ToUtf16
452// purpose :
453// =======================================================================
454template<typename Type> inline
455const NCollection_UtfString<Standard_Utf16Char> NCollection_UtfString<Type>::ToUtf16() const
456{
457 NCollection_UtfString<Standard_Utf16Char> aCopy;
458 aCopy.FromUnicode (myString);
459 return aCopy;
460}
461
462// =======================================================================
463// function : ToUtf32
464// purpose :
465// =======================================================================
466template<typename Type> inline
467const NCollection_UtfString<Standard_Utf32Char> NCollection_UtfString<Type>::ToUtf32() const
468{
469 NCollection_UtfString<Standard_Utf32Char> aCopy;
470 aCopy.FromUnicode (myString);
471 return aCopy;
472}
473
474// =======================================================================
475// function : ToUtfWide
476// purpose :
477// =======================================================================
478template<typename Type> inline
479const NCollection_UtfString<Standard_WideChar> NCollection_UtfString<Type>::ToUtfWide() const
480{
481 NCollection_UtfString<Standard_WideChar> aCopy;
482 aCopy.FromUnicode (myString);
483 return aCopy;
484}