VR-Forces 4.3 Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DtUnicodeChar.h
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright (c) 2010 MAK Technologies, Inc.
3 ** All rights reserved.
4 ******************************************************************************/
5 /*********************************************************************
6 ** $RCSfile: DtUnicodeChar.h,v $ $Revision: $ $State: $
7 *********************************************************************/
8 
11 
12 #ifndef DtUnicodeChar_H
13 #define DtUnicodeChar_H
14 
15 #include <stdexcept>
16 
17 namespace makVrv
18 {
21  {
22  public:
23 
24  //A Unicode Code Point, is a unique Unicode Character.
25  typedef unsigned int CodePoint;
26 
27  //A Unicode Surrogate code point, is a 16bit code point, used in UTF-16 encoding.
28  typedef unsigned short Surrogate;
29 
31  typedef unsigned char Octet;
32 
33  inline DtUnicodeChar()
34  : myCodePoint(0)
35  {
36  }
37 
40  inline explicit DtUnicodeChar(const char c)
41  : myCodePoint(c)
42  {
43  }
44 
45 
49  inline explicit DtUnicodeChar(const wchar_t c)
50  : myCodePoint(c)
51  {
52  }
53 
56  inline explicit DtUnicodeChar(const unsigned short s,const unsigned short c)
58  {
59  if(!(isSurrogate(s) && isSurrogate(c)))
60  {
61  throw std::invalid_argument("UTF-16 characters are not a surrogate pair.");
62  }
63  }
64 
65  inline DtUnicodeChar(const DtUnicodeChar& other)
66  : myCodePoint(other.myCodePoint)
67  {
68  }
69 
70  template <int sizeof_wchar_t>
71  inline static CodePoint widechar(const wchar_t c);
72 
73  inline DtUnicodeChar& operator=(const DtUnicodeChar& other)
74  {
75  //No need to check for equality.
76  myCodePoint = other.myCodePoint;
77  return *this;
78  }
79 
80  inline bool operator==(const DtUnicodeChar& other) const
81  {
82  return myCodePoint == other.myCodePoint;
83  }
84 
85  inline bool operator!=(const DtUnicodeChar& other) const
86  {
87  return myCodePoint != other.myCodePoint;
88  }
89 
90  // Maximum valid value for a Unicode code point
91  static const CodePoint CodePointMax = 0x0010ffff;
92  static const Surrogate LeadSurrogateMin = 0xd800;
93  static const Surrogate LeadSurrogateMax = 0xdbff;
94  static const Surrogate TrailSurrogateMin = 0xdc00;
95  static const Surrogate TrailSurrogateMax = 0xdfff;
96 
97  static inline bool isCodePointValid(CodePoint codePoint)
98  {
99  return (codePoint <= CodePointMax && !isSurrogate((Surrogate)codePoint) &&
100  codePoint != 0xfffe && codePoint != 0xffff);
101  }
102 
103  static inline bool isSurrogateSubstringValid(const Surrogate* start,
104  const Surrogate* end, const Surrogate* substringStart,
105  const Surrogate* substringEnd)
106  {
107  // Test to see if beginning in middle of surrogate pair.
108  if(TrailSurrogateMin == ((*substringStart)&0xfffffc00) &&
109  start != substringStart &&
110  LeadSurrogateMin == ((*(substringStart - 1))&0xfffffc00))
111  {
112 
113  return false;
114  }
115 
116  //Test to see if end is middle of pair.
117  if((LeadSurrogateMin == ((*(substringEnd - 1 ))&0xfffffc00)) &&
118  substringStart != end &&
119  (TrailSurrogateMin == ((*substringEnd)&0xfffffc00)))
120  {
121  return false;
122  }
123 
124  //Not at middle of surrogate pair.
125  return true;
126  }
127 
128 
129  static inline bool isSurrogate(Surrogate cp)
130  {
131  return (cp >= LeadSurrogateMin && cp <= TrailSurrogateMax);
132  }
133 
135  static inline DtUnicodeChar fromUtf32(unsigned int character)
136  {
137  if(!isCodePointValid(character)) throw std::invalid_argument("Not a valid UTF 32 code point");
138  return DtUnicodeChar(character);
139  }
140 
142  inline unsigned int utf8Length() const
143  {
144  if (myCodePoint < 0x80) // one octet
145  {
146  return 1;
147  }
148  else if (myCodePoint < 0x800) // two octets
149  {
150  return 2;
151  }
152  else if (myCodePoint < 0x10000) // three octets
153  {
154  return 3;
155  }
156  else // four octets
157  {
158  return 4;
159  }
160  }
161 
162  template <int sizeofWChar_t>
163  inline unsigned int wchartLength() const;
164 
165  inline unsigned int wideStringLength() const;
166 
167  inline unsigned int utf16Length() const
168  {
169  if(myCodePoint > 0xFFFF) return 4; else return 2;
170  }
171 
172  inline unsigned int utf32Length() const
173  {
174  return 4;
175  }
176 
178  {
179  //Get bits 10 - 15 bits from hi, and get bits 0-9 bits from lo
180  CodePoint X = (hi & 0x3F) << 10 | (lo & 0x3FF);
181  //Get bits 16-21 from hi, and offset.
182  CodePoint U = ((hi >> 6) & (0x1F)) + 1;
183  //Recombine.
184  return (U << 16) | X;
185  }
186 
187  static inline void encodeSurrogatePair(CodePoint cp, Surrogate& hi,Surrogate& lo)
188  {
189  // TAG Top 17-22 bits minus 1,
190  hi = LeadSurrogateMin | ((unsigned short)((cp >> 16) & 0x1F) - 1)
191  // bits 10-16 bits.
192  | (unsigned short)((cp >> 10) & 0x3F);
193  //Has bottom 10 bits + Trail Tag.
194  lo = TrailSurrogateMin | (unsigned short)(cp & 0x3FF);
195  }
196 
197  inline unsigned int utf16CodeUnits() const
198  {
199  if(myCodePoint >= 0x10000)
200  {
201  return 2;
202  }
203  else
204  {
205  return 1;
206  }
207  }
208 
211  inline unsigned int readUtf16(const Surrogate* memory)
212  {
213  if(isSurrogate(*memory))
214  {
215  Surrogate hiPair = *memory;
216  Surrogate loPair = *(memory + 1);
217  myCodePoint = decodeSurrogatePair(hiPair,loPair);
218  return 2;
219  }
220  else
221  {
222  myCodePoint = *memory;
223  return 1;
224  }
225  }
226 
227  inline void writeUtf16(Surrogate* memory) const
228  {
229  if(myCodePoint >= 0x10000)
230  {
231  encodeSurrogatePair(myCodePoint,*memory,*(memory + 1));
232  }
233  else
234  {
235  *memory = static_cast<Surrogate>(myCodePoint);
236  }
237  }
238 
239  inline void readUtf32(const unsigned int* memory)
240  {
241  myCodePoint = *memory;
242  }
243 
244  inline void writeUtf32(unsigned int* memory) const
245  {
246  *memory = myCodePoint;
247  }
248 
250  static inline unsigned int utf8Length(const unsigned char c)
251  {
252  if(c < 0x80)
253  {
254  return 1;
255  }
256  else if(c < 0xE0)
257  {
258  return 2;
259  }
260  else if(c < 0xF0)
261  {
262  return 3;
263  }
264  else if(c < 0xF8)
265  {
266  return 4;
267  }
268  else
269  {
270  throw std::invalid_argument("Not a valid UTF8 string.");
271  }
272  }
273 
274  inline unsigned int readUtf8(const unsigned char* memory)
275  {
276  unsigned char c = *memory;
277  if(c < 0x80)
278  {
279  myCodePoint = c;
280  return 1;
281  }
282  else if(c < 0xE0)
283  {
284  myCodePoint = ((c & 0x1F) << 6) |
285  (*(memory + 1) & 0x3F);
286  return 2;
287  }
288  else if(c < 0xF0)
289  {
290  myCodePoint = ((c & 0xF) << 12) |
291  ((*(memory + 1) & 0x3F) << 6) |
292  (*(memory + 2) & 0x3F);
293  return 3;
294  }
295  else if(c < 0xF8)
296  {
297  myCodePoint = ((c & 0x7) << 18) |
298  ((*(memory + 1) & 0x3F) << 12) |
299  ((*(memory + 2) & 0x3F) << 6) |
300  (*(memory + 3) & 0x3F);
301  return 4;
302  }
303  else
304  {
305  throw std::invalid_argument("Not a valid UTF8 string.");
306  }
307  }
308 
309  inline void writeUtf8(char* memory) const
310  {
311  if (myCodePoint < 0x80) // one octet
312  {
313  *memory = (unsigned char)(myCodePoint & 0x7F);
314  }
315  else if (myCodePoint < 0x800) // two octets
316  {
317  *memory = (unsigned char)((myCodePoint >> 6) & 0x1F) | 0xC0;
318  *(memory+1) = (unsigned char)((myCodePoint ) & 0x3F) | 0x80;
319 
320  }
321  else if (myCodePoint < 0x10000) // three octets
322  {
323  *memory = (unsigned char)((myCodePoint >> 12) & 0xF ) | 0xE0;
324  *(memory+1) = (unsigned char)((myCodePoint >> 6) & 0x3F) | 0x80;
325  *(memory+2) = (unsigned char)((myCodePoint ) & 0x3F) | 0x80;
326  }
327  else // four octets
328  {
329  *memory = (unsigned char)((myCodePoint >> 18) & 0x7 ) | 0xF0;
330  *(memory+1) = (unsigned char)((myCodePoint >> 12) & 0x3F) | 0x80;
331  *(memory+2) = (unsigned char)((myCodePoint >> 6 ) & 0x3F) | 0x80;
332  *(memory+3) = (unsigned char)((myCodePoint ) & 0x3F) | 0x80;
333  }
334  }
335 
336  template <int sizeofWchart>
337  inline void writeWCharT(wchar_t* memory) const;
338 
339 
340  inline void writeWChar(wchar_t* memory) const;
341 
342  inline CodePoint codePoint() const
343  {
344  return myCodePoint;
345  }
346 
347  protected:
348 
349  inline DtUnicodeChar(unsigned int utf32c)
350  : myCodePoint(utf32c)
351  {
352  }
353 
354  private:
356  };
357 
358  template <>
359  inline unsigned int DtUnicodeChar::wchartLength<2>() const
360  {
361  return utf16CodeUnits() << 1;
362  }
363 
364  template <>
365  inline unsigned int DtUnicodeChar::wchartLength<4>() const
366  {
367  return utf32Length();
368  }
369 
370 
371 
372  template <int sizeof_wchar_t>
374  {
375  return c;
376  }
377 
378  template <>
379  inline DtUnicodeChar::CodePoint DtUnicodeChar::widechar<2>(const wchar_t c)
380  {
381  if(isSurrogate(c))
382  {
383  throw std::invalid_argument("Invalid UTF-16 character");
384  }
385  return c;
386  }
387 
388  template <>
389  inline void DtUnicodeChar::writeWCharT<2>(wchar_t* memory) const
390  {
391  writeUtf16(reinterpret_cast<Surrogate*>(memory));
392  }
393 
394  template <>
395  inline void DtUnicodeChar::writeWCharT<4>(wchar_t* memory) const
396  {
397  writeUtf32(reinterpret_cast<unsigned int*>(memory));
398  }
399 
400  inline unsigned int DtUnicodeChar::wideStringLength() const
401  {
402  return wchartLength<sizeof(wchar_t)>();
403  }
404 
405  inline void DtUnicodeChar::writeWChar(wchar_t* memory) const
406  {
407  writeWCharT<sizeof(wchar_t)>(memory);
408  }
409 }
410 
411 #endif

Document ID: Generated on Wed Mar 11 21:20:57 EDT 2015 from SVN revision 150940
Copyright © 2005-2014 VT MÄK. All Rights Reserved (www.mak.com)