0023457: Slow text rendering
[occt.git] / src / NCollection / NCollection_UtfString.hxx
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 #ifndef _NCollection_UtfString_H__
21 #define _NCollection_UtfString_H__
22
23 #include "NCollection_UtfIterator.hxx"
24
25 #include <Standard.hxx>
26
27 #include <string>
28 #include <cstdlib>
29
30 //! This template class represent constant UTF-* string.
31 //! String stored in memory continuously, always NULL-terminated
32 //! and can be used as standard C-string using ToCString() method.
33 //!
34 //! Notice that changing the string is not allowed
35 //! and any modifications should produce new string.
36 template<typename Type>
37 class NCollection_UtfString
38 {
39
40 public:
41
42   NCollection_UtfIterator<Type> Iterator() const
43   {
44     return NCollection_UtfIterator<Type> (myString);
45   }
46
47   //! @return the size of the buffer, excluding NULL-termination symbol
48   Standard_Integer Size() const
49   {
50     return mySize;
51   }
52
53   //! @return the length of the string in Unicode symbols
54   Standard_Integer Length() const
55   {
56     return myLength;
57   }
58
59   //! Retrieve Unicode symbol at specified position.
60   //! Warning! This is a slow access. Iterator should be used for consecutive parsing.
61   //! @param theCharIndex the index of the symbol, should be lesser than Length()
62   //! @return the Unicode symbol value
63   Standard_Utf32Char GetChar (const Standard_Integer theCharIndex) const;
64
65   //! Retrieve string buffer at specified position.
66   //! Warning! This is a slow access. Iterator should be used for consecutive parsing.
67   //! @param theCharIndex the index of the symbol, should be lesser than Length()
68   //! @return the pointer to the symbol
69   const Type* GetCharBuffer (const Standard_Integer theCharIndex) const;
70
71   //! Retrieve Unicode symbol at specified position.
72   //! Warning! This is a slow access. Iterator should be used for consecutive parsing.
73   Standard_Utf32Char operator[] (const Standard_Integer theCharIndex) const
74   {
75     return GetChar (theCharIndex);
76   }
77
78   //! Initialize empty string.
79   NCollection_UtfString();
80
81   //! Copy constructor.
82   //! @param theCopy string to copy.
83   NCollection_UtfString (const NCollection_UtfString& theCopy);
84
85   //! Copy constructor from NULL-terminated UTF-8 string.
86   //! @param theCopyUtf8 NULL-terminated UTF-8 string to copy
87   //! @param theLength   the length limit in Unicode symbols (NOT bytes!)
88   NCollection_UtfString (const char*            theCopyUtf8,
89                          const Standard_Integer theLength = -1);
90
91   //! Copy constructor from NULL-terminated UTF-16 string.
92   //! @param theCopyUtf16 NULL-terminated UTF-16 string to copy
93   //! @param theLength    the length limit in Unicode symbols (NOT bytes!)
94   NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16,
95                          const Standard_Integer    theLength = -1);
96
97   //! Copy constructor from NULL-terminated UTF-32 string.
98   //! @param theCopyUtf32 NULL-terminated UTF-32 string to copy
99   //! @param theLength    the length limit in Unicode symbols (NOT bytes!)
100   NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
101                          const Standard_Integer    theLength = -1);
102
103   //! Copy constructor from NULL-terminated wide UTF string.
104   //! @param theCopyUtfWide NULL-terminated wide UTF string to copy
105   //! @param theLength      the length limit in Unicode symbols (NOT bytes!)
106   NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
107                          const Standard_Integer   theLength = -1);
108
109   //! Copy from NULL-terminated Unicode string.
110   //! @param theStringUtf NULL-terminated Unicode string
111   //! @param theLength    the length limit in Unicode symbols
112   template <typename TypeFrom>
113   void FromUnicode (const TypeFrom*        theStringUtf,
114                     const Standard_Integer theLength = -1);
115
116   //! Copy from NULL-terminated multibyte string in system locale.
117   //! You should avoid this function unless extreme necessity.
118   //! @param theString NULL-terminated multibyte string
119   //! @param theLength the length limit in Unicode symbols
120   void FromLocale (const char*            theString,
121                    const Standard_Integer theLength = -1);
122
123   //! Destructor.
124   ~NCollection_UtfString();
125
126   //! Compares this string with another one.
127   bool IsEqual (const NCollection_UtfString& theCompare) const;
128
129   //! Returns the substring.
130   //! @param theStart start index (inclusive) of subString
131   //! @param theEnd   end index   (exclusive) of subString
132   //! @return the substring
133   NCollection_UtfString SubString (const Standard_Integer theStart,
134                                    const Standard_Integer theEnd) const;
135
136   //! Returns NULL-terminated Unicode string.
137   //! Should not be modifed or deleted!
138   //! @return (const Type* ) pointer to string
139   const Type* ToCString() const
140   {
141     return myString;
142   }
143
144   //! @return copy in UTF-8 format
145   const NCollection_UtfString<Standard_Utf8Char> ToUtf8() const;
146
147   //! @return copy in UTF-16 format
148   const NCollection_UtfString<Standard_Utf16Char> ToUtf16() const;
149
150   //! @return copy in UTF-32 format
151   const NCollection_UtfString<Standard_Utf32Char> ToUtf32() const;
152
153   //! @return copy in wide format (UTF-16 on Windows and UTF-32 on Linux)
154   const NCollection_UtfString<Standard_WideChar> ToUtfWide() const;
155
156   //! Converts the string into multibyte string.
157   //! You should avoid this function unless extreme necessity.
158   //! @param theBuffer    output buffer
159   //! @param theSizeBytes buffer size in bytes
160   //! @return true on success
161   bool ToLocale (char*                  theBuffer,
162                  const Standard_Integer theSizeBytes) const;
163
164   //! @return true if string is empty
165   bool IsEmpty() const
166   {
167     return myString[0] == Type(0);
168   }
169
170   //! Zero string.
171   void Clear();
172
173 public: //! @name assign operators
174
175   //! Copy from another string.
176   const NCollection_UtfString& operator= (const NCollection_UtfString& theOther);
177
178   //! Copy from UTF-8 NULL-terminated string.
179   const NCollection_UtfString& operator= (const char* theStringUtf8);
180
181   //! Copy from wchar_t UTF NULL-terminated string.
182   const NCollection_UtfString& operator= (const Standard_WideChar* theStringUtfWide);
183
184   //! Join strings.
185   NCollection_UtfString& operator+= (const NCollection_UtfString& theAppend);
186
187   //! Join two strings.
188   friend NCollection_UtfString operator+ (const NCollection_UtfString& theLeft,
189                                           const NCollection_UtfString& theRight)
190   {
191     NCollection_UtfString aSumm;
192     strFree (aSumm.myString);
193     aSumm.mySize   = theLeft.mySize   + theRight.mySize;
194     aSumm.myLength = theLeft.myLength + theRight.myLength;
195     aSumm.myString = strAlloc (aSumm.mySize);
196
197     // copy bytes
198     strCopy ((Standard_Byte* )aSumm.myString,                  (const Standard_Byte* )theLeft.myString,  theLeft.mySize);
199     strCopy ((Standard_Byte* )aSumm.myString + theLeft.mySize, (const Standard_Byte* )theRight.myString, theRight.mySize);
200     return aSumm;
201   }
202
203 public: //! @name compare operators
204
205   bool operator== (const NCollection_UtfString& theCompare) const
206   {
207     return IsEqual (theCompare);
208   }
209   bool operator!= (const NCollection_UtfString& theCompare) const;
210
211 private: //! @name low-level methods
212
213   //! Compute advance for specified string.
214   //! @param theStringUtf pointer to the NULL-terminated Unicode string
215   //! @param theLengthMax length limit (to cut the string), set to -1 to compute up to NULL-termination symbol
216   //! @param theSizeBytes advance in bytes (out)
217   //! @param theLength    string length (out)
218   template<typename TypeFrom>
219   static void strGetAdvance (const TypeFrom*        theStringUtf,
220                              const Standard_Integer theLengthMax,
221                              Standard_Integer&      theSizeBytes,
222                              Standard_Integer&      theLength);
223
224   //! Allocate NULL-terminated string buffer.
225   static Type* strAlloc (const Standard_Size theSizeBytes)
226   {
227     Type* aPtr = (Type* )Standard::Allocate (theSizeBytes + sizeof(Type));
228     if (aPtr != NULL)
229     {
230       // always NULL-terminate the string
231       aPtr[theSizeBytes / sizeof(Type)] = Type(0);
232     }
233     return aPtr;
234   }
235
236   //! Release string buffer and nullify the pointer.
237   static void strFree (Type*& thePtr)
238   {
239     void* aPtr = thePtr;
240     Standard::Free (aPtr);
241     thePtr = NULL;
242   }
243
244   //! Provides bytes interface to avoid incorrect pointer arithmetics.
245   static void strCopy (Standard_Byte*         theStrDst,
246                        const Standard_Byte*   theStrSrc,
247                        const Standard_Integer theSizeBytes)
248   {
249     ::memcpy (theStrDst, theStrSrc, (Standard_Size )theSizeBytes);
250   }
251
252   //! Compare two Unicode strings per-byte.
253   static bool strAreEqual (const Type*            theString1,
254                            const Standard_Integer theSizeBytes1,
255                            const Type*            theString2,
256                            const Standard_Integer theSizeBytes2)
257   {
258     return (theSizeBytes1 == theSizeBytes2)
259         && (::memcmp (theString1, theString2, (Standard_Size )theSizeBytes1) == 0);
260   }
261
262 private: //! @name private fields
263
264   Type*            myString; //!< string buffer
265   Standard_Integer mySize;   //!< buffer size in bytes, excluding NULL-termination symbol
266   Standard_Integer myLength; //!< length of the string in Unicode symbols (cached value, excluding NULL-termination symbol)
267
268 };
269
270 typedef NCollection_UtfString<Standard_Utf8Char>  NCollection_Utf8String;
271 typedef NCollection_UtfString<Standard_Utf16Char> NCollection_Utf16String;
272 typedef NCollection_UtfString<Standard_Utf32Char> NCollection_Utf32String;
273 typedef NCollection_UtfString<Standard_WideChar>  NCollection_UtfWideString;
274
275 // template implementation (inline methods)
276 #include "NCollection_UtfString.lxx"
277
278 #endif // _NCollection_UtfString_H__