00001
00002
00003 #ifndef _GUTF_H_
00004 #define _GUTF_H_
00005
00006
00007 #define IsUtf8_1Byte(c) ( ((uchar)(c) & 0x80) == 0x00 )
00008 #define IsUtf8_2Byte(c) ( ((uchar)(c) & 0xe0) == 0xc0 )
00009 #define IsUtf8_3Byte(c) ( ((uchar)(c) & 0xf0) == 0xe0 )
00010 #define IsUtf8_4Byte(c) ( ((uchar)(c) & 0xf8) == 0xf0 )
00011
00012 #define IsUtf8_Lead(c) ( ((uchar)(c) & 0xc0) == 0xc0 )
00013 #define IsUtf8_Trail(c) ( ((uchar)(c) & 0xc0) == 0x80 )
00014
00015
00016
00018 inline uint32 LgiUtf8To32(uint8 *&i, int &Len)
00019 {
00020 uint32 Out = 0;
00021
00022 #define InvalidUtf() { Len--; i++; return 0xFFFD; }
00023
00024
00025 if (Len > 0)
00026 {
00027 if (!*i)
00028 {
00029 Len = 0;
00030 return 0;
00031 }
00032
00033 if (IsUtf8_1Byte(*i))
00034 {
00035
00036 Len--;
00037 return *i++;
00038 }
00039 else if (IsUtf8_2Byte(*i))
00040 {
00041
00042 if (Len > 1)
00043 {
00044 Out = ((int)(*i++ & 0x1f)) << 6;
00045 Len--;
00046
00047 if (IsUtf8_Trail(*i))
00048 {
00049 Out |= *i++ & 0x3f;
00050 Len--;
00051 }
00052 else InvalidUtf()
00053 }
00054 }
00055 else if (IsUtf8_3Byte(*i))
00056 {
00057
00058 if (Len > 2)
00059 {
00060 Out = ((int)(*i++ & 0x0f)) << 12;
00061 Len--;
00062
00063 if (IsUtf8_Trail(*i))
00064 {
00065 Out |= ((int)(*i++ & 0x3f)) << 6;
00066 Len--;
00067
00068 if (IsUtf8_Trail(*i))
00069 {
00070 Out |= *i++ & 0x3f;
00071 Len--;
00072 }
00073 else InvalidUtf()
00074 }
00075 else InvalidUtf()
00076 }
00077 }
00078 else if (IsUtf8_4Byte(*i))
00079 {
00080
00081 if (Len > 3)
00082 {
00083 Out = ((int)(*i++ & 0x07)) << 18;
00084 Len--;
00085
00086 if (IsUtf8_Trail(*i))
00087 {
00088 Out |= ((int)(*i++ & 0x3f)) << 12;
00089 Len--;
00090
00091 if (IsUtf8_Trail(*i))
00092 {
00093 Out |= ((int)(*i++ & 0x3f)) << 6;
00094 Len--;
00095
00096 if (IsUtf8_Trail(*i))
00097 {
00098 Out |= *i++ & 0x3f;
00099 Len--;
00100 }
00101 else InvalidUtf()
00102 }
00103 else InvalidUtf()
00104 }
00105 else InvalidUtf()
00106 }
00107 }
00108 else
00109 InvalidUtf()
00110 }
00111
00112 return Out;
00113 }
00114
00116 inline bool LgiUtf32To8(uint32 c, uint8 *&i, int &Len)
00117 {
00118 if ((c & ~0x7f) == 0)
00119 {
00120 if (Len > 0)
00121 {
00122 *i++ = c;
00123 Len--;
00124 return true;
00125 }
00126 }
00127 else if ((c & ~0x7ff) == 0)
00128 {
00129 if (Len > 1)
00130 {
00131 *i++ = 0xc0 | (c >> 6);
00132 *i++ = 0x80 | (c & 0x3f);
00133 Len -= 2;
00134 return true;
00135 }
00136 }
00137 else if ((c & 0xffff0000) == 0)
00138 {
00139 if (Len > 2)
00140 {
00141 *i++ = 0xe0 | (c >> 12);
00142 *i++ = 0x80 | ((c & 0x0fc0) >> 6);
00143 *i++ = 0x80 | (c & 0x3f);
00144 Len -= 3;
00145 return true;
00146 }
00147 }
00148 else
00149 {
00150 if (Len > 3)
00151 {
00152 *i++ = 0xf0 | (c >> 18);
00153 *i++ = 0x80 | ((c&0x3f000) >> 12);
00154 *i++ = 0x80 | ((c&0xfc0) >> 6);
00155 *i++ = 0x80 | (c&0x3f);
00156 Len -= 4;
00157 return true;
00158 }
00159 }
00160
00161 return false;
00162 }
00163
00165 inline uint32 LgiUtf16To32(char16 *&i, int &Len)
00166 {
00167 if (Len > 1)
00168 {
00169 if (!*i)
00170 {
00171 Len = 0;
00172 return 0;
00173 }
00174
00175 int n = *i & 0xfc00;
00176 if (n == 0xd800 || n == 0xdc00)
00177 {
00178
00179 if (Len > 3)
00180 {
00181 Len -= sizeof(char16)<<1;
00182 int w = (*i & 0x3c0) >> 6;
00183 int zy = *i++ & 0x3f;
00184 return ((w + 1) << 16) | (zy << 10) | (*i++ & 0x3ff);
00185 }
00186 }
00187
00188
00189 Len -= sizeof(char16);
00190 return *i++;
00191 }
00192
00193 return 0;
00194 }
00195
00197 inline void LgiUtf32To16(uint32 c, char16 *&i, int &Len)
00198 {
00199 if (c & 0xffff0000)
00200 {
00201
00202 if (Len > 3)
00203 {
00204 int w = (c >> 16) - 1;
00205 *i++ = 0xd800 | (w << 6) | ((c & 0xfc00) >> 10);
00206 *i++ = 0xdc00 | (c & 0x3ff);
00207 Len -= sizeof(char16) << 1;
00208 }
00209 }
00210
00211
00212 if (Len > 1)
00213 {
00214 *i++ = c;
00215 Len -= sizeof(char16);
00216 }
00217 }
00218
00220 inline void LgiNextUtf8(char *&p)
00221 {
00222 if (IsUtf8_Lead(*p++))
00223 {
00224 while (IsUtf8_Trail(*p)) p++;
00225 }
00226 }
00227
00229 inline void LgiPrevUtf8(char *&p)
00230 {
00231 p--;
00232 while (IsUtf8_Trail(*p)) p--;
00233 }
00234
00236 class LgiClass GUtf8Ptr
00237 {
00238 protected:
00239 uint8 *Ptr;
00240
00241 public:
00242 GUtf8Ptr(char *p = 0);
00243
00245 GUtf8Ptr &operator =(char *s) { Ptr = (uint8*)s; return *this; }
00247 GUtf8Ptr &operator =(uint8 *s) { Ptr = s; return *this; }
00249 operator uint32();
00251 uint32 operator ++(const int n);
00253 uint32 operator --(const int n);
00255 uint32 operator +=(const int n);
00257 uint32 operator -=(const int n);
00258
00260 int GetBytes();
00262 int GetChars();
00264 uint8 *GetCurrent() { return Ptr; }
00266 void Add(char16 c);
00267
00269 uint8 *GetPtr() { return Ptr; }
00270 };
00271
00273 class LgiClass GUtf8Str : public GUtf8Ptr
00274 {
00275
00276 uint8 *Start;
00277 uint8 *End;
00278 GUtf8Ptr Cur;
00279 bool Own;
00280
00281 void Empty();
00282
00283 public:
00285 GUtf8Str
00286 (
00288 char *utf,
00290 int bytes = -1,
00292 bool Copy = false
00293 );
00295 GUtf8Str
00296 (
00298 char16 *wide,
00300 int chars = -1
00301 );
00302 ~GUtf8Str();
00303
00305 GUtf8Str &operator =(char *s);
00306
00308 char16 *ToWide();
00310 bool Valid();
00312 bool IsStart();
00314 bool IsEnd();
00315 };
00316
00317 #endif