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// ======================================================================= 20template<typename Type> 21Standard_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// ======================================================================= 39template<typename Type> 40const 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// ======================================================================= 58template<typename Type> inline 59void 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// ======================================================================= 71template<typename Type> inline 72NCollection_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// ======================================================================= 84template<typename Type> inline 85NCollection_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// ======================================================================= 98template<typename Type> inline 99NCollection_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// ======================================================================= 114template<typename Type> inline 115NCollection_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// ======================================================================= 128template<typename Type> inline 129NCollection_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// ======================================================================= 142template<typename Type> inline 143NCollection_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// ======================================================================= 157template<typename Type> inline 158NCollection_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// ======================================================================= 172template<typename Type> inline 173NCollection_UtfString<Type>::~NCollection_UtfString() 174{ 175 strFree (myString); 176} 177 178// ======================================================================= 179// function : Assign 180// purpose : 181// ======================================================================= 182template<typename Type> inline 183const 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// ======================================================================= 202template<typename Type> inline 203void 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. 220class NCollection_UtfStringTool 221{ 222public: 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); 237private: 238 wchar_t* myWideBuffer; //!< temporary variable 239}; 240#endif 241 242// ======================================================================= 243// function : FromLocale 244// purpose : 245// ======================================================================= 246template<typename Type> inline 247void 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// ======================================================================= 269template<typename Type> inline 270bool 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// ======================================================================= 293template<typename Type> inline 294const 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// ======================================================================= 304template<typename Type> inline 305const 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// ======================================================================= 315template<typename Type> inline 316bool 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// ======================================================================= 326template<typename Type> inline 327bool 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// ======================================================================= 336template<typename Type> inline 337NCollection_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// ======================================================================= 361template<typename Type> inline 362NCollection_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// ======================================================================= 383template<typename Type> inline 384const 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// ======================================================================= 395template<typename Type> inline 396const 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// ======================================================================= 407template<typename Type> inline 408const 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// ======================================================================= 419template<typename Type> inline 420const NCollection_UtfString<Standard_WideChar> NCollection_UtfString<Type>::ToUtfWide() const 421{ 422 NCollection_UtfString<Standard_WideChar> aCopy; 423 aCopy.FromUnicode (myString); 424 return aCopy; 425} 426