a174a3c5 |
1 | // Created on: 2013-01-28 |
2 | // Created by: Kirill GAVRILOV |
3 | // Copyright (c) 2013 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
20 | // ======================================================================= |
21 | // function : strGetAdvance |
22 | // purpose : Compute advance for specified string. |
23 | // ======================================================================= |
24 | template<typename TypeTo> template<typename TypeFrom> inline |
25 | void NCollection_UtfString<TypeTo>::strGetAdvance (const TypeFrom* theStringUtf, |
26 | const Standard_Integer theLengthMax, |
27 | Standard_Integer& theSizeBytes, |
28 | Standard_Integer& theLength) |
29 | { |
30 | theSizeBytes = 0; |
31 | theLength = 0; |
32 | NCollection_UtfIterator<TypeFrom> anIter (theStringUtf); |
33 | const Standard_Integer aLengthMax = (theLengthMax > 0) ? theLengthMax : IntegerLast(); |
34 | switch (sizeof(TypeTo)) |
35 | { |
36 | case sizeof(Standard_Utf8Char): |
37 | { |
38 | for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter) |
39 | { |
40 | theSizeBytes += anIter.AdvanceBytesUtf8(); |
41 | } |
42 | theLength = anIter.Index(); |
43 | return; |
44 | } |
45 | case sizeof(Standard_Utf16Char): |
46 | { |
47 | for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter) |
48 | { |
49 | theSizeBytes += anIter.AdvanceBytesUtf16(); |
50 | } |
51 | theLength = anIter.Index(); |
52 | return; |
53 | } |
54 | case sizeof(Standard_Utf32Char): |
55 | { |
56 | for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter) |
57 | { |
58 | theSizeBytes += anIter.AdvanceBytesUtf32(); |
59 | } |
60 | theLength = anIter.Index(); |
61 | return; |
62 | } |
63 | default: return; |
64 | } |
65 | } |
66 | |
67 | // ======================================================================= |
68 | // function : GetChar |
69 | // purpose : |
70 | // ======================================================================= |
71 | template<typename Type> |
72 | Standard_Utf32Char NCollection_UtfString<Type>::GetChar (const Standard_Integer theCharIndex) const |
73 | { |
74 | //Standard_ASSERT_SKIP (theCharIndex < myLength, "Out of range"); |
75 | NCollection_UtfIterator<Type> anIter (myString); |
76 | for (; *anIter != 0; ++anIter) |
77 | { |
78 | if (anIter.Index() == theCharIndex) |
79 | { |
80 | return *anIter; |
81 | } |
82 | } |
83 | return 0; |
84 | } |
85 | |
86 | // ======================================================================= |
87 | // function : GetCharBuffer |
88 | // purpose : |
89 | // ======================================================================= |
90 | template<typename Type> |
91 | const Type* NCollection_UtfString<Type>::GetCharBuffer (const Standard_Integer theCharIndex) const |
92 | { |
93 | //Standard_ASSERT_SKIP(theCharIndex < myLength); |
94 | NCollection_UtfIterator<Type> anIter (myString); |
95 | for (; *anIter != 0; ++anIter) |
96 | { |
97 | if (anIter.Index() == theCharIndex) |
98 | { |
99 | return anIter.BufferHere(); |
100 | } |
101 | } |
102 | return NULL; |
103 | } |
104 | |
105 | // ======================================================================= |
106 | // function : Clear |
107 | // purpose : |
108 | // ======================================================================= |
109 | template<typename Type> inline |
110 | void NCollection_UtfString<Type>::Clear() |
111 | { |
112 | strFree (myString); |
113 | mySize = 0; |
114 | myLength = 0; |
115 | myString = strAlloc (mySize); |
116 | } |
117 | |
118 | // ======================================================================= |
119 | // function : NCollection_UtfString |
120 | // purpose : |
121 | // ======================================================================= |
122 | template<typename Type> inline |
123 | NCollection_UtfString<Type>::NCollection_UtfString() |
124 | : myString (strAlloc(0)), |
125 | mySize (0), |
126 | myLength (0) |
127 | { |
128 | // |
129 | } |
130 | |
131 | // ======================================================================= |
132 | // function : NCollection_UtfString |
133 | // purpose : |
134 | // ======================================================================= |
135 | template<typename Type> inline |
136 | NCollection_UtfString<Type>::NCollection_UtfString (const NCollection_UtfString& theCopy) |
137 | : myString (strAlloc (theCopy.mySize)), |
138 | mySize (theCopy.mySize), |
139 | myLength (theCopy.myLength) |
140 | { |
141 | strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theCopy.myString, mySize); |
142 | } |
143 | |
144 | // ======================================================================= |
145 | // function : NCollection_UtfString |
146 | // purpose : |
147 | // ======================================================================= |
148 | template<typename Type> inline |
149 | NCollection_UtfString<Type>::NCollection_UtfString (const char* theCopyUtf8, |
150 | const Standard_Integer theLength) |
151 | : myString (NULL), |
152 | mySize (0), |
153 | myLength (0) |
154 | { |
155 | FromUnicode (theCopyUtf8, theLength); |
156 | } |
157 | |
158 | // ======================================================================= |
159 | // function : NCollection_UtfString |
160 | // purpose : |
161 | // ======================================================================= |
162 | template<typename Type> inline |
163 | NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16, |
164 | const Standard_Integer theLength) |
165 | : myString (NULL), |
166 | mySize (0), |
167 | myLength (0) |
168 | { |
169 | FromUnicode (theCopyUtf16, theLength); |
170 | } |
171 | |
172 | // ======================================================================= |
173 | // function : NCollection_UtfString |
174 | // purpose : |
175 | // ======================================================================= |
176 | template<typename Type> inline |
177 | NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32, |
178 | const Standard_Integer theLength) |
179 | : myString (NULL), |
180 | mySize (0), |
181 | myLength (0) |
182 | { |
183 | FromUnicode (theCopyUtf32, theLength); |
184 | } |
185 | |
186 | // ======================================================================= |
187 | // function : NCollection_UtfString |
188 | // purpose : |
189 | // ======================================================================= |
190 | template<typename Type> inline |
191 | NCollection_UtfString<Type>::NCollection_UtfString (const Standard_WideChar* theCopyUtfWide, |
192 | const Standard_Integer theLength) |
193 | : myString (NULL), |
194 | mySize (0), |
195 | myLength (0) |
196 | { |
197 | FromUnicode (theCopyUtfWide, theLength); |
198 | } |
199 | |
200 | // ======================================================================= |
201 | // function : ~NCollection_UtfString |
202 | // purpose : |
203 | // ======================================================================= |
204 | template<typename Type> inline |
205 | NCollection_UtfString<Type>::~NCollection_UtfString() |
206 | { |
207 | strFree (myString); |
208 | } |
209 | |
210 | // ======================================================================= |
211 | // function : operator= |
212 | // purpose : |
213 | // ======================================================================= |
214 | template<typename Type> inline |
215 | const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const NCollection_UtfString<Type>& theOther) |
216 | { |
217 | if (this == &theOther) |
218 | { |
219 | return (*this); |
220 | } |
221 | |
222 | strFree (myString); |
223 | mySize = theOther.mySize; |
224 | myLength = theOther.myLength; |
225 | myString = strAlloc (mySize); |
226 | strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theOther.myString, mySize); |
227 | return (*this); |
228 | } |
229 | |
230 | // ======================================================================= |
231 | // function : FromUnicode |
232 | // purpose : |
233 | // ======================================================================= |
234 | template<typename Type> template<typename TypeFrom> |
235 | void NCollection_UtfString<Type>::FromUnicode (const TypeFrom* theStringUtf, |
236 | const Standard_Integer theLength) |
237 | { |
238 | Type* anOldBuffer = myString; // necessary in case of self-copying |
239 | NCollection_UtfIterator<TypeFrom> anIterRead (theStringUtf); |
240 | if (*anIterRead == 0) |
241 | { |
242 | // special case |
243 | Clear(); |
244 | return; |
245 | } |
246 | |
247 | switch (sizeof(TypeFrom)) // use switch() rather than if() to shut up msvc compiler |
248 | { |
249 | case sizeof(Type): |
250 | { |
251 | if (theLength > 0) |
252 | { |
253 | // optimized copy |
254 | for(; *anIterRead != 0 && anIterRead.Index() < theLength; ++anIterRead) {} |
255 | |
256 | mySize = Standard_Integer((Standard_Byte* )anIterRead.BufferHere() - (Standard_Byte* )theStringUtf); |
257 | myLength = anIterRead.Index(); |
258 | myString = strAlloc (mySize); |
259 | strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theStringUtf, mySize); |
260 | strFree (anOldBuffer); |
261 | return; |
262 | } |
263 | } |
264 | default: break; |
265 | } |
266 | |
267 | strGetAdvance (theStringUtf, theLength, mySize, myLength); |
268 | myString = strAlloc (mySize); |
269 | // reset iterator |
270 | anIterRead.Init (theStringUtf); |
271 | Type* anIterWrite = myString; |
272 | for (; *anIterRead != 0 && anIterRead.Index() < myLength; ++anIterRead) |
273 | { |
274 | anIterWrite = anIterRead.GetUtf (anIterWrite); |
275 | } |
276 | strFree (anOldBuffer); |
277 | } |
278 | |
279 | // ======================================================================= |
280 | // function : FromLocale |
281 | // purpose : |
282 | // ======================================================================= |
283 | template<typename Type> inline |
284 | void NCollection_UtfString<Type>::FromLocale (const char* theString, |
285 | const Standard_Integer theLength) |
286 | { |
287 | #if(defined(_WIN32) || defined(__WIN32__)) |
288 | // use WinAPI |
289 | int aWideSize = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, theString, -1, NULL, 0); |
290 | if (aWideSize <= 0) |
291 | { |
292 | Clear(); |
293 | return; |
294 | } |
295 | wchar_t* aWideBuffer = new wchar_t[aWideSize + 1]; |
296 | MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, theString, -1, aWideBuffer, aWideSize); |
297 | aWideBuffer[aWideSize] = L'\0'; |
298 | FromUnicode (aWideBuffer, theLength); |
299 | delete[] aWideBuffer; |
300 | #else |
301 | // this is size in bytes but should probably be enough to store string in wide chars |
302 | // notice that these functions are sensitive to locale set by application! |
303 | int aMbLen = mblen (theString, MB_CUR_MAX); |
304 | if (aMbLen <= 0) |
305 | { |
306 | Clear(); |
307 | return; |
308 | } |
309 | wchar_t* aWideBuffer = new wchar_t[aMbLen + 1]; |
310 | mbstowcs (aWideBuffer, theString, aMbLen); |
311 | aWideBuffer[aMbLen] = L'\0'; |
312 | FromUnicode (aWideBuffer, theLength); |
313 | delete[] aWideBuffer; |
314 | #endif |
315 | } |
316 | |
317 | // ======================================================================= |
318 | // function : ToLocale |
319 | // purpose : |
320 | // ======================================================================= |
321 | template<typename Type> inline |
322 | bool NCollection_UtfString<Type>::ToLocale (char* theBuffer, |
323 | const Standard_Integer theSizeBytes) const |
324 | { |
325 | NCollection_UtfString<wchar_t> aWideCopy (myString, myLength); |
326 | #if(defined(_WIN32) || defined(__WIN32__)) |
327 | int aMbBytes = WideCharToMultiByte (CP_ACP, 0, aWideCopy.ToCString(), -1, theBuffer, theSizeBytes, NULL, NULL); |
328 | #else |
329 | std::size_t aMbBytes = std::wcstombs (theBuffer, aWideCopy.ToCString(), theSizeBytes); |
330 | #endif |
331 | if (aMbBytes <= 0) |
332 | { |
333 | *theBuffer = '\0'; |
334 | return false; |
335 | } |
336 | return true; |
337 | } |
338 | |
339 | // ======================================================================= |
340 | // function : operator= |
341 | // purpose : |
342 | // ======================================================================= |
343 | template<typename Type> inline |
344 | const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const char* theStringUtf8) |
345 | { |
346 | FromUnicode (theStringUtf8); |
347 | return (*this); |
348 | } |
349 | |
350 | // ======================================================================= |
351 | // function : operator= |
352 | // purpose : |
353 | // ======================================================================= |
354 | template<typename Type> inline |
355 | const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const Standard_WideChar* theStringUtfWide) |
356 | { |
357 | FromUnicode (theStringUtfWide); |
358 | return (*this); |
359 | } |
360 | |
361 | // ======================================================================= |
362 | // function : IsEqual |
363 | // purpose : |
364 | // ======================================================================= |
365 | template<typename Type> inline |
366 | bool NCollection_UtfString<Type>::IsEqual (const NCollection_UtfString& theCompare) const |
367 | { |
368 | return this == &theCompare |
369 | || strAreEqual (myString, mySize, theCompare.myString, theCompare.mySize); |
370 | } |
371 | |
372 | // ======================================================================= |
373 | // function : operator!= |
374 | // purpose : |
375 | // ======================================================================= |
376 | template<typename Type> inline |
377 | bool NCollection_UtfString<Type>::operator!= (const NCollection_UtfString& theCompare) const |
378 | { |
379 | return (!NCollection_UtfString::operator== (theCompare)); |
380 | } |
381 | |
382 | // ======================================================================= |
383 | // function : operator+= |
384 | // purpose : |
385 | // ======================================================================= |
386 | template<typename Type> inline |
387 | NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator+= (const NCollection_UtfString<Type>& theAppend) |
388 | { |
389 | if (theAppend.IsEmpty()) |
390 | { |
391 | return (*this); |
392 | } |
393 | |
394 | // create new string |
395 | Standard_Integer aSize = mySize + theAppend.mySize; |
396 | Type* aString = strAlloc (aSize); |
397 | strCopy ((Standard_Byte* )aString, (const Standard_Byte* )myString, mySize); |
398 | strCopy ((Standard_Byte* )aString + mySize, (const Standard_Byte* )theAppend.myString, theAppend.mySize); |
399 | |
400 | strFree (myString); |
401 | mySize = aSize; |
402 | myString = aString; |
403 | myLength += theAppend.myLength; |
404 | return (*this); |
405 | } |
406 | |
407 | // ======================================================================= |
408 | // function : SubString |
409 | // purpose : |
410 | // ======================================================================= |
411 | template<typename Type> inline |
412 | NCollection_UtfString<Type> NCollection_UtfString<Type>::SubString (const Standard_Integer theStart, |
413 | const Standard_Integer theEnd) const |
414 | { |
415 | if (theStart >= theEnd) |
416 | { |
417 | return NCollection_UtfString<Type>(); |
418 | } |
419 | for (NCollection_UtfIterator<Type> anIter(myString); *anIter != 0; ++anIter) |
420 | { |
421 | if (anIter.Index() >= theStart) |
422 | { |
423 | return NCollection_UtfString<Type> (anIter.BufferHere(), theEnd - theStart); |
424 | } |
425 | } |
426 | return NCollection_UtfString<Type>(); |
427 | } |
428 | |
429 | // ======================================================================= |
430 | // function : ToUtf8 |
431 | // purpose : |
432 | // ======================================================================= |
433 | template<typename Type> inline |
434 | const NCollection_UtfString<Standard_Utf8Char> NCollection_UtfString<Type>::ToUtf8() const |
435 | { |
436 | NCollection_UtfString<Standard_Utf8Char> aCopy; |
437 | aCopy.FromUnicode (myString); |
438 | return aCopy; |
439 | } |
440 | |
441 | // ======================================================================= |
442 | // function : ToUtf16 |
443 | // purpose : |
444 | // ======================================================================= |
445 | template<typename Type> inline |
446 | const NCollection_UtfString<Standard_Utf16Char> NCollection_UtfString<Type>::ToUtf16() const |
447 | { |
448 | NCollection_UtfString<Standard_Utf16Char> aCopy; |
449 | aCopy.FromUnicode (myString); |
450 | return aCopy; |
451 | } |
452 | |
453 | // ======================================================================= |
454 | // function : ToUtf32 |
455 | // purpose : |
456 | // ======================================================================= |
457 | template<typename Type> inline |
458 | const NCollection_UtfString<Standard_Utf32Char> NCollection_UtfString<Type>::ToUtf32() const |
459 | { |
460 | NCollection_UtfString<Standard_Utf32Char> aCopy; |
461 | aCopy.FromUnicode (myString); |
462 | return aCopy; |
463 | } |
464 | |
465 | // ======================================================================= |
466 | // function : ToUtfWide |
467 | // purpose : |
468 | // ======================================================================= |
469 | template<typename Type> inline |
470 | const NCollection_UtfString<Standard_WideChar> NCollection_UtfString<Type>::ToUtfWide() const |
471 | { |
472 | NCollection_UtfString<Standard_WideChar> aCopy; |
473 | aCopy.FromUnicode (myString); |
474 | return aCopy; |
475 | } |