00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "avmplus.h"
00039
00040 namespace avmplus
00041 {
00042 using namespace MMgc;
00043
00044 int String::Length(const wchar *str)
00045 {
00046 if (!str)
00047 return 0;
00048
00049 int len = 0;
00050 while (*str) {
00051 len++;
00052 str++;
00053 }
00054 return len;
00055 }
00056
00057 int String::Length(const char *str)
00058 {
00059 if (!str)
00060 return 0;
00061
00062 int len = 0;
00063 while (*str) {
00064 len++;
00065 str++;
00066 }
00067 return len;
00068 }
00069
00070
00071 String::String(int len)
00072 #ifdef DEBUGGER
00073 : AvmPlusScriptableObject(kStringType)
00074 #endif // DEBUGGER
00075 {
00076 AvmAssert(len >= 0);
00077 MMGC_MEM_TYPE(this);
00078 setBuf(allocBuf(len));
00079 m_length = len;
00080 }
00081
00082
00083 String::String(const char *str, int utf8len, int utf16len)
00084 #ifdef DEBUGGER
00085 : AvmPlusScriptableObject(kStringType)
00086 #endif // DEBUGGER
00087 {
00088 AvmAssert(utf8len >= 0);
00089 AvmAssert(utf16len >= 0);
00090
00091 MMGC_MEM_TYPE(this);
00092 setBuf(allocBuf(utf16len));
00093 m_length = UnicodeUtils::Utf8ToUtf16((const uint8 *)str, utf8len,
00094 getData(), utf16len);
00095 AvmAssert(m_length >= 0);
00096 getData()[m_length] = 0;
00097 }
00098
00099
00100 String::String(const wchar *str, int len)
00101 #ifdef DEBUGGER
00102 : AvmPlusScriptableObject(kStringType)
00103 #endif // DEBUGGER
00104 {
00105 AvmAssert(len >= 0);
00106 m_length = len;
00107 MMGC_MEM_TYPE(this);
00108 setBuf(allocBuf(m_length));
00109 memcpy (getData(), str, m_length * sizeof(wchar));
00110 getData()[m_length] = 0;
00111 }
00112
00113
00114 String::String(Stringp s1, Stringp s2)
00115 #ifdef DEBUGGER
00116 : AvmPlusScriptableObject(kStringType)
00117 #endif // DEBUGGER
00118 {
00119 m_length = s1->length() + s2->length();
00120 AvmAssert(m_length >= 0);
00121 setPrefixOrOffsetOrNumber(uintptr(s1) | PREFIXFLAG);
00122 if (s2->needsNormalization()) s2->normalize();
00123 setBuf(s2->m_buf);
00124 }
00125
00126
00127 String::String(Stringp s, int pos, int len)
00128 #ifdef DEBUGGER
00129 : AvmPlusScriptableObject(kStringType)
00130 #endif // DEBUGGER
00131 {
00132
00133 if (pos < 0) {
00134 pos = 0;
00135 }
00136 if (len < 0) {
00137 len = 0;
00138 }
00139
00140 int s_len = s->length();
00141 if (pos + len > s_len) {
00142 len = s_len - pos;
00143 }
00144 if (pos > s_len) {
00145 len = 0;
00146 }
00147
00148 AvmAssert(pos >= 0);
00149 AvmAssert(len == 0 || pos + len <= s_len);
00150
00151 #if 0 // old way
00152 if (s->hasPrefix()) s->normalize();
00153
00154 m_length = len;
00155 GC* gc = GC::GetGC(this);
00156 MMGC_MEM_TYPE(this);
00157 m_buf = (wchar *) gc->Alloc (sizeof(wchar)*(m_length+1), 0);
00158 memcpy (m_buf, s->m_buf+pos, m_length * sizeof(wchar));
00159 m_buf[m_length] = 0;
00160 m_prefixOrOffsetOrNumber = 0;
00161 #endif
00162
00163 if (s->hasOffset())
00164 {
00165 m_length = len;
00166 setBuf(s->m_buf);
00167 m_prefixOrOffsetOrNumber = int(((s->getOffset() + pos) << 2) | OFFSETFLAG);
00168 return;
00169 }
00170 else if (s->hasPrefix())
00171 {
00172 Stringp news = s;
00173 while (news->getPrefix() && pos < news->getPrefix()->length())
00174 news = news->getPrefix();
00175
00176 int newpos = pos;
00177 int segmentLen = news->length();
00178 if (news->getPrefix())
00179 {
00180 int prefixLen = news->getPrefix()->length();
00181 newpos -= prefixLen;
00182 segmentLen -= prefixLen;
00183 }
00184
00185
00186
00187
00188
00189 if ((newpos + len) <= segmentLen)
00190 {
00191 m_length = len;
00192 setBuf(news->m_buf);
00193 int offset = news->getOffset() + newpos;
00194 m_prefixOrOffsetOrNumber = int((offset << 2) | OFFSETFLAG);
00195 return;
00196 }
00197
00198 s->normalize();
00199 }
00200
00201 m_length = len;
00202 setBuf(s->m_buf);
00203 m_prefixOrOffsetOrNumber = int((pos << 2) | OFFSETFLAG);
00204 }
00205
00206
00207 int String::Compare(const wchar *dst, int dstLen, const wchar *src, int srcLen)
00208 {
00209 int ret = 0;
00210 int count = (dstLen < srcLen) ? dstLen : srcLen;
00211 const wchar *dstend = dst + count;
00212
00213 while(dst < dstend && 0 == (ret = (int)(*src - *dst)))
00214 {
00215 ++src, ++dst;
00216 }
00217
00218
00219 if (ret == 0)
00220 {
00221 if (srcLen < dstLen)
00222 ret = -1;
00223 else if (srcLen > dstLen)
00224 ret = 1;
00225 else
00226 ;
00227 }
00228 return ret;
00229 }
00230
00231
00232 int String::Compare(const wchar *dst, const char *src, int len)
00233 {
00234 int ret = 0;
00235 const wchar *dstend = dst + len;
00236
00237 while(dst < dstend && *src && 0 == (ret = (int)(((wchar)*src) - *dst)) )
00238 {
00239 ++src, ++dst;
00240 }
00241
00242 if (ret == 0)
00243 {
00244
00245 if (dst < dstend)
00246 {
00247
00248 AvmAssert(*src == 0);
00249 ret = -1;
00250 }
00251 else if (*src)
00252 {
00253
00254 AvmAssert(dst == dstend);
00255 ret = 1;
00256 }
00257 else
00258 {
00259
00260 AvmAssert(dst == dstend);
00261 AvmAssert(*src == 0);
00262 }
00263 }
00264
00265 return ret;
00266 }
00267
00268 bool String::Contains(wchar c)
00269 {
00270 if (hasPrefix()) normalize();
00271
00272 const wchar *p = getData() + getOffset();
00273
00274 while (*p && (*p != c)) {
00275 p++;
00276 }
00277
00278 return (*p == c);
00279 }
00280
00281
00282 void String::normalize()
00283 {
00284 AvmAssert(needsNormalization() == true);
00285 MMGC_MEM_TYPE(this);
00286 StringBuf *newData = allocBuf(length());
00287 if (newData == NULL)
00288 return;
00289 wchar *new_buf = newData->m_buf;
00290 new_buf[length()] = 0;
00291
00292 if (hasPrefix())
00293 {
00294
00295 Stringp p = this;
00296 for (; p->getPrefix() != 0; p = p->getPrefix())
00297 {
00298 memcpy(new_buf + p->getPrefix()->length(), p->getData(), sizeof(wchar)*(p->length()-p->getPrefix()->length()));
00299 }
00300
00301 memcpy(new_buf, p->getData() + p->getOffset(), sizeof(wchar) * p->length());
00302 setBuf(newData);
00303 }
00304 else
00305 {
00306 AvmAssert(hasOffset());
00307 memcpy(new_buf, getData() + getOffset(), sizeof(wchar) * length());
00308 setBuf(newData);
00309 }
00310
00311
00312 setPrefixOrOffsetOrNumber(0);
00313 }
00314
00315
00316 UTF8String* String::toUTF8String()
00317 {
00318 if (hasPrefix()) normalize();
00319 int utf8len = UnicodeUtils::Utf16ToUtf8(getData() + getOffset(), length(), NULL, 0);
00320
00321 if( utf8len < 0 )
00322 {
00323 utf8len = 0;
00324 }
00325
00326 UTF8String* out = new (GC::GetGC(this), utf8len) UTF8String(utf8len);
00327
00328 if (out) {
00329 char *dst = out->lockBuffer();
00330 UnicodeUtils::Utf16ToUtf8(getData() + getOffset(), length(), (uint8*)dst, utf8len);
00331 dst[utf8len] = 0;
00332 out->unlockBuffer();
00333 }
00334 return out;
00335 }
00336
00337
00338
00339
00340
00341 const wchar String::lowerCaseBase[] =
00342 {
00343 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A,
00344 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
00345 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00B5, 0x00E0, 0x00E1, 0x00E2,
00346 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC,
00347 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6,
00348 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x0101, 0x0103,
00349 0x0105, 0x0107, 0x0109, 0x010B, 0x010D, 0x010F, 0x0111, 0x0113, 0x0115, 0x0117,
00350 0x0119, 0x011B, 0x011D, 0x011F, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x012B,
00351 0x012D, 0x012F, 0x0131, 0x0133, 0x0135, 0x0137, 0x013A, 0x013C, 0x013E, 0x0140,
00352 0x0142, 0x0144, 0x0146, 0x0148, 0x014B, 0x014D, 0x014F, 0x0151, 0x0153, 0x0155,
00353 0x0157, 0x0159, 0x015B, 0x015D, 0x015F, 0x0161, 0x0163, 0x0165, 0x0167, 0x0169,
00354 0x016B, 0x016D, 0x016F, 0x0171, 0x0173, 0x0175, 0x0177, 0x017A, 0x017C, 0x017E,
00355 0x017F, 0x0183, 0x0185, 0x0188, 0x018C, 0x0192, 0x0195, 0x0199, 0x01A1, 0x01A3,
00356 0x01A5, 0x01A8, 0x01AD, 0x01B0, 0x01B4, 0x01B6, 0x01B9, 0x01BD, 0x01BF, 0x01C5,
00357 0x01C6, 0x01C8, 0x01C9, 0x01CB, 0x01CC, 0x01CE, 0x01D0, 0x01D2, 0x01D4, 0x01D6,
00358 0x01D8, 0x01DA, 0x01DC, 0x01DD, 0x01DF, 0x01E1, 0x01E3, 0x01E5, 0x01E7, 0x01E9,
00359 0x01EB, 0x01ED, 0x01EF, 0x01F2, 0x01F3, 0x01F5, 0x01F9, 0x01FB, 0x01FD, 0x01FF,
00360 0x0201, 0x0203, 0x0205, 0x0207, 0x0209, 0x020B, 0x020D, 0x020F, 0x0211, 0x0213,
00361 0x0215, 0x0217, 0x0219, 0x021B, 0x021D, 0x021F, 0x0223, 0x0225, 0x0227, 0x0229,
00362 0x022B, 0x022D, 0x022F, 0x0231, 0x0233, 0x0253, 0x0254, 0x0256, 0x0257, 0x0259,
00363 0x025B, 0x0260, 0x0263, 0x0268, 0x0269, 0x026F, 0x0272, 0x0275, 0x0280, 0x0283,
00364 0x0288, 0x028A, 0x028B, 0x0292, 0x0345, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B1,
00365 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
00366 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5,
00367 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03D0,
00368 0x03D1, 0x03D5, 0x03D6, 0x03DB, 0x03DD, 0x03DF, 0x03E1, 0x03E3, 0x03E5, 0x03E7,
00369 0x03E9, 0x03EB, 0x03ED, 0x03EF, 0x03F0, 0x03F1, 0x03F2, 0x03F5, 0x0430, 0x0431,
00370 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
00371 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
00372 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
00373 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459,
00374 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F, 0x0461, 0x0463, 0x0465, 0x0467,
00375 0x0469, 0x046B, 0x046D, 0x046F, 0x0471, 0x0473, 0x0475, 0x0477, 0x0479, 0x047B,
00376 0x047D, 0x047F, 0x0481, 0x048D, 0x048F, 0x0491, 0x0493, 0x0495, 0x0497, 0x0499,
00377 0x049B, 0x049D, 0x049F, 0x04A1, 0x04A3, 0x04A5, 0x04A7, 0x04A9, 0x04AB, 0x04AD,
00378 0x04AF, 0x04B1, 0x04B3, 0x04B5, 0x04B7, 0x04B9, 0x04BB, 0x04BD, 0x04BF, 0x04C2,
00379 0x04C4, 0x04C8, 0x04CC, 0x04D1, 0x04D3, 0x04D5, 0x04D7, 0x04D9, 0x04DB, 0x04DD,
00380 0x04DF, 0x04E1, 0x04E3, 0x04E5, 0x04E7, 0x04E9, 0x04EB, 0x04ED, 0x04EF, 0x04F1,
00381 0x04F3, 0x04F5, 0x04F9, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
00382 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, 0x0570, 0x0571,
00383 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B,
00384 0x057C, 0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585,
00385 0x0586, 0x1E01, 0x1E03, 0x1E05, 0x1E07, 0x1E09, 0x1E0B, 0x1E0D, 0x1E0F, 0x1E11,
00386 0x1E13, 0x1E15, 0x1E17, 0x1E19, 0x1E1B, 0x1E1D, 0x1E1F, 0x1E21, 0x1E23, 0x1E25,
00387 0x1E27, 0x1E29, 0x1E2B, 0x1E2D, 0x1E2F, 0x1E31, 0x1E33, 0x1E35, 0x1E37, 0x1E39,
00388 0x1E3B, 0x1E3D, 0x1E3F, 0x1E41, 0x1E43, 0x1E45, 0x1E47, 0x1E49, 0x1E4B, 0x1E4D,
00389 0x1E4F, 0x1E51, 0x1E53, 0x1E55, 0x1E57, 0x1E59, 0x1E5B, 0x1E5D, 0x1E5F, 0x1E61,
00390 0x1E63, 0x1E65, 0x1E67, 0x1E69, 0x1E6B, 0x1E6D, 0x1E6F, 0x1E71, 0x1E73, 0x1E75,
00391 0x1E77, 0x1E79, 0x1E7B, 0x1E7D, 0x1E7F, 0x1E81, 0x1E83, 0x1E85, 0x1E87, 0x1E89,
00392 0x1E8B, 0x1E8D, 0x1E8F, 0x1E91, 0x1E93, 0x1E95, 0x1E9B, 0x1EA1, 0x1EA3, 0x1EA5,
00393 0x1EA7, 0x1EA9, 0x1EAB, 0x1EAD, 0x1EAF, 0x1EB1, 0x1EB3, 0x1EB5, 0x1EB7, 0x1EB9,
00394 0x1EBB, 0x1EBD, 0x1EBF, 0x1EC1, 0x1EC3, 0x1EC5, 0x1EC7, 0x1EC9, 0x1ECB, 0x1ECD,
00395 0x1ECF, 0x1ED1, 0x1ED3, 0x1ED5, 0x1ED7, 0x1ED9, 0x1EDB, 0x1EDD, 0x1EDF, 0x1EE1,
00396 0x1EE3, 0x1EE5, 0x1EE7, 0x1EE9, 0x1EEB, 0x1EED, 0x1EEF, 0x1EF1, 0x1EF3, 0x1EF5,
00397 0x1EF7, 0x1EF9, 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
00398 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x1F20, 0x1F21, 0x1F22, 0x1F23,
00399 0x1F24, 0x1F25, 0x1F26, 0x1F27, 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35,
00400 0x1F36, 0x1F37, 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x1F51, 0x1F53,
00401 0x1F55, 0x1F57, 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
00402 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, 0x1F78, 0x1F79,
00403 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85,
00404 0x1F86, 0x1F87, 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
00405 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, 0x1FB0, 0x1FB1,
00406 0x1FB3, 0x1FBE, 0x1FC3, 0x1FD0, 0x1FD1, 0x1FE0, 0x1FE1, 0x1FE5, 0x1FF3, 0x2170,
00407 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A,
00408 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4,
00409 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE,
00410 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8,
00411 0x24E9, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49,
00412 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53,
00413 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A
00414 };
00415
00416 const wchar String::upperCaseConversion[] =
00417 {
00418 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A,
00419 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054,
00420 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x039C, 0x00C0, 0x00C1, 0x00C2,
00421 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC,
00422 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6,
00423 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x0178, 0x0100, 0x0102,
00424 0x0104, 0x0106, 0x0108, 0x010A, 0x010C, 0x010E, 0x0110, 0x0112, 0x0114, 0x0116,
00425 0x0118, 0x011A, 0x011C, 0x011E, 0x0120, 0x0122, 0x0124, 0x0126, 0x0128, 0x012A,
00426 0x012C, 0x012E, 0x0049, 0x0132, 0x0134, 0x0136, 0x0139, 0x013B, 0x013D, 0x013F,
00427 0x0141, 0x0143, 0x0145, 0x0147, 0x014A, 0x014C, 0x014E, 0x0150, 0x0152, 0x0154,
00428 0x0156, 0x0158, 0x015A, 0x015C, 0x015E, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168,
00429 0x016A, 0x016C, 0x016E, 0x0170, 0x0172, 0x0174, 0x0176, 0x0179, 0x017B, 0x017D,
00430 0x0053, 0x0182, 0x0184, 0x0187, 0x018B, 0x0191, 0x01F6, 0x0198, 0x01A0, 0x01A2,
00431 0x01A4, 0x01A7, 0x01AC, 0x01AF, 0x01B3, 0x01B5, 0x01B8, 0x01BC, 0x01F7, 0x01C4,
00432 0x01C4, 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CD, 0x01CF, 0x01D1, 0x01D3, 0x01D5,
00433 0x01D7, 0x01D9, 0x01DB, 0x018E, 0x01DE, 0x01E0, 0x01E2, 0x01E4, 0x01E6, 0x01E8,
00434 0x01EA, 0x01EC, 0x01EE, 0x01F1, 0x01F1, 0x01F4, 0x01F8, 0x01FA, 0x01FC, 0x01FE,
00435 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020A, 0x020C, 0x020E, 0x0210, 0x0212,
00436 0x0214, 0x0216, 0x0218, 0x021A, 0x021C, 0x021E, 0x0222, 0x0224, 0x0226, 0x0228,
00437 0x022A, 0x022C, 0x022E, 0x0230, 0x0232, 0x0181, 0x0186, 0x0189, 0x018A, 0x018F,
00438 0x0190, 0x0193, 0x0194, 0x0197, 0x0196, 0x019C, 0x019D, 0x019F, 0x01A6, 0x01A9,
00439 0x01AE, 0x01B1, 0x01B2, 0x01B7, 0x0399, 0x0386, 0x0388, 0x0389, 0x038A, 0x0391,
00440 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B,
00441 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5,
00442 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0392,
00443 0x0398, 0x03A6, 0x03A0, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x03E2, 0x03E4, 0x03E6,
00444 0x03E8, 0x03EA, 0x03EC, 0x03EE, 0x039A, 0x03A1, 0x03A3, 0x0395, 0x0410, 0x0411,
00445 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B,
00446 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425,
00447 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
00448 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409,
00449 0x040A, 0x040B, 0x040C, 0x040D, 0x040E, 0x040F, 0x0460, 0x0462, 0x0464, 0x0466,
00450 0x0468, 0x046A, 0x046C, 0x046E, 0x0470, 0x0472, 0x0474, 0x0476, 0x0478, 0x047A,
00451 0x047C, 0x047E, 0x0480, 0x048C, 0x048E, 0x0490, 0x0492, 0x0494, 0x0496, 0x0498,
00452 0x049A, 0x049C, 0x049E, 0x04A0, 0x04A2, 0x04A4, 0x04A6, 0x04A8, 0x04AA, 0x04AC,
00453 0x04AE, 0x04B0, 0x04B2, 0x04B4, 0x04B6, 0x04B8, 0x04BA, 0x04BC, 0x04BE, 0x04C1,
00454 0x04C3, 0x04C7, 0x04CB, 0x04D0, 0x04D2, 0x04D4, 0x04D6, 0x04D8, 0x04DA, 0x04DC,
00455 0x04DE, 0x04E0, 0x04E2, 0x04E4, 0x04E6, 0x04E8, 0x04EA, 0x04EC, 0x04EE, 0x04F0,
00456 0x04F2, 0x04F4, 0x04F8, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537,
00457 0x0538, 0x0539, 0x053A, 0x053B, 0x053C, 0x053D, 0x053E, 0x053F, 0x0540, 0x0541,
00458 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054A, 0x054B,
00459 0x054C, 0x054D, 0x054E, 0x054F, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555,
00460 0x0556, 0x1E00, 0x1E02, 0x1E04, 0x1E06, 0x1E08, 0x1E0A, 0x1E0C, 0x1E0E, 0x1E10,
00461 0x1E12, 0x1E14, 0x1E16, 0x1E18, 0x1E1A, 0x1E1C, 0x1E1E, 0x1E20, 0x1E22, 0x1E24,
00462 0x1E26, 0x1E28, 0x1E2A, 0x1E2C, 0x1E2E, 0x1E30, 0x1E32, 0x1E34, 0x1E36, 0x1E38,
00463 0x1E3A, 0x1E3C, 0x1E3E, 0x1E40, 0x1E42, 0x1E44, 0x1E46, 0x1E48, 0x1E4A, 0x1E4C,
00464 0x1E4E, 0x1E50, 0x1E52, 0x1E54, 0x1E56, 0x1E58, 0x1E5A, 0x1E5C, 0x1E5E, 0x1E60,
00465 0x1E62, 0x1E64, 0x1E66, 0x1E68, 0x1E6A, 0x1E6C, 0x1E6E, 0x1E70, 0x1E72, 0x1E74,
00466 0x1E76, 0x1E78, 0x1E7A, 0x1E7C, 0x1E7E, 0x1E80, 0x1E82, 0x1E84, 0x1E86, 0x1E88,
00467 0x1E8A, 0x1E8C, 0x1E8E, 0x1E90, 0x1E92, 0x1E94, 0x1E60, 0x1EA0, 0x1EA2, 0x1EA4,
00468 0x1EA6, 0x1EA8, 0x1EAA, 0x1EAC, 0x1EAE, 0x1EB0, 0x1EB2, 0x1EB4, 0x1EB6, 0x1EB8,
00469 0x1EBA, 0x1EBC, 0x1EBE, 0x1EC0, 0x1EC2, 0x1EC4, 0x1EC6, 0x1EC8, 0x1ECA, 0x1ECC,
00470 0x1ECE, 0x1ED0, 0x1ED2, 0x1ED4, 0x1ED6, 0x1ED8, 0x1EDA, 0x1EDC, 0x1EDE, 0x1EE0,
00471 0x1EE2, 0x1EE4, 0x1EE6, 0x1EE8, 0x1EEA, 0x1EEC, 0x1EEE, 0x1EF0, 0x1EF2, 0x1EF4,
00472 0x1EF6, 0x1EF8, 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
00473 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x1F28, 0x1F29, 0x1F2A, 0x1F2B,
00474 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D,
00475 0x1F3E, 0x1F3F, 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x1F59, 0x1F5B,
00476 0x1F5D, 0x1F5F, 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
00477 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, 0x1FF8, 0x1FF9,
00478 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D,
00479 0x1F8E, 0x1F8F, 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
00480 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, 0x1FB8, 0x1FB9,
00481 0x1FBC, 0x0399, 0x1FCC, 0x1FD8, 0x1FD9, 0x1FE8, 0x1FE9, 0x1FEC, 0x1FFC, 0x2160,
00482 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A,
00483 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0x24B6, 0x24B7, 0x24B8, 0x24B9, 0x24BA,
00484 0x24BB, 0x24BC, 0x24BD, 0x24BE, 0x24BF, 0x24C0, 0x24C1, 0x24C2, 0x24C3, 0x24C4,
00485 0x24C5, 0x24C6, 0x24C7, 0x24C8, 0x24C9, 0x24CA, 0x24CB, 0x24CC, 0x24CD, 0x24CE,
00486 0x24CF, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29,
00487 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33,
00488 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A
00489 };
00490
00491
00492
00493 wchar String::wCharToUpper (wchar ch)
00494 {
00495 AvmAssert (sizeof (lowerCaseBase) == sizeof (upperCaseConversion));
00496
00497 wchar result = ch;
00498
00499 int lo = 0;
00500 int hi = (sizeof (lowerCaseBase) / sizeof (lowerCaseBase[0])) - 1;
00501
00502 while (lo <= hi)
00503 {
00504 int pivot = (lo+hi)>>1;
00505 int testChar = lowerCaseBase[pivot];
00506
00507 if (ch == testChar)
00508 {
00509
00510 result = upperCaseConversion[pivot];
00511 break;
00512 }
00513 else if (ch < testChar)
00514 {
00515 hi = pivot-1;
00516 }
00517 else
00518 {
00519 lo = pivot+1;
00520 }
00521 }
00522
00523 return result;
00524 }
00525
00526
00527
00528
00529 const unsigned char String::tolower_map[] = {
00530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00534 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
00535 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
00536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00542 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
00543 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
00544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00546 };
00547
00548 const unsigned char String::toupper_map[] = {
00549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00555 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
00556 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
00557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
00563 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
00564 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
00565 };
00566
00567 const wchar String::upperCaseBase[] = {
00568 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A,
00569 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054,
00570 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C0, 0x00C1, 0x00C2, 0x00C3,
00571 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD,
00572 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D8,
00573 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x0100, 0x0102, 0x0104, 0x0106,
00574 0x0108, 0x010A, 0x010C, 0x010E, 0x0110, 0x0112, 0x0114, 0x0116, 0x0118, 0x011A,
00575 0x011C, 0x011E, 0x0120, 0x0122, 0x0124, 0x0126, 0x0128, 0x012A, 0x012C, 0x012E,
00576 0x0130, 0x0132, 0x0134, 0x0136, 0x0139, 0x013B, 0x013D, 0x013F, 0x0141, 0x0143,
00577 0x0145, 0x0147, 0x014A, 0x014C, 0x014E, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158,
00578 0x015A, 0x015C, 0x015E, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016A, 0x016C,
00579 0x016E, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0179, 0x017B, 0x017D, 0x0181,
00580 0x0182, 0x0184, 0x0186, 0x0187, 0x0189, 0x018A, 0x018B, 0x018E, 0x018F, 0x0190,
00581 0x0191, 0x0193, 0x0194, 0x0196, 0x0197, 0x0198, 0x019C, 0x019D, 0x019F, 0x01A0,
00582 0x01A2, 0x01A4, 0x01A6, 0x01A7, 0x01A9, 0x01AC, 0x01AE, 0x01AF, 0x01B1, 0x01B2,
00583 0x01B3, 0x01B5, 0x01B7, 0x01B8, 0x01BC, 0x01C4, 0x01C5, 0x01C7, 0x01C8, 0x01CA,
00584 0x01CB, 0x01CD, 0x01CF, 0x01D1, 0x01D3, 0x01D5, 0x01D7, 0x01D9, 0x01DB, 0x01DE,
00585 0x01E0, 0x01E2, 0x01E4, 0x01E6, 0x01E8, 0x01EA, 0x01EC, 0x01EE, 0x01F1, 0x01F2,
00586 0x01F4, 0x01F6, 0x01F7, 0x01F8, 0x01FA, 0x01FC, 0x01FE, 0x0200, 0x0202, 0x0204,
00587 0x0206, 0x0208, 0x020A, 0x020C, 0x020E, 0x0210, 0x0212, 0x0214, 0x0216, 0x0218,
00588 0x021A, 0x021C, 0x021E, 0x0222, 0x0224, 0x0226, 0x0228, 0x022A, 0x022C, 0x022E,
00589 0x0230, 0x0232, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, 0x038F, 0x0391,
00590 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B,
00591 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6,
00592 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x03E2,
00593 0x03E4, 0x03E6, 0x03E8, 0x03EA, 0x03EC, 0x03EE, 0x03F4, 0x0400, 0x0401, 0x0402,
00594 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, 0x040C,
00595 0x040D, 0x040E, 0x040F, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416,
00596 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
00597 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A,
00598 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0460, 0x0462, 0x0464, 0x0466, 0x0468,
00599 0x046A, 0x046C, 0x046E, 0x0470, 0x0472, 0x0474, 0x0476, 0x0478, 0x047A, 0x047C,
00600 0x047E, 0x0480, 0x048C, 0x048E, 0x0490, 0x0492, 0x0494, 0x0496, 0x0498, 0x049A,
00601 0x049C, 0x049E, 0x04A0, 0x04A2, 0x04A4, 0x04A6, 0x04A8, 0x04AA, 0x04AC, 0x04AE,
00602 0x04B0, 0x04B2, 0x04B4, 0x04B6, 0x04B8, 0x04BA, 0x04BC, 0x04BE, 0x04C1, 0x04C3,
00603 0x04C7, 0x04CB, 0x04D0, 0x04D2, 0x04D4, 0x04D6, 0x04D8, 0x04DA, 0x04DC, 0x04DE,
00604 0x04E0, 0x04E2, 0x04E4, 0x04E6, 0x04E8, 0x04EA, 0x04EC, 0x04EE, 0x04F0, 0x04F2,
00605 0x04F4, 0x04F8, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538,
00606 0x0539, 0x053A, 0x053B, 0x053C, 0x053D, 0x053E, 0x053F, 0x0540, 0x0541, 0x0542,
00607 0x0543, 0x0544, 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054A, 0x054B, 0x054C,
00608 0x054D, 0x054E, 0x054F, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556,
00609
00610 0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, 0x10a9,
00611 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, 0x10b1, 0x10b2, 0x10b3,
00612 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd,
00613 0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5,
00614
00615 0x1E00, 0x1E02, 0x1E04, 0x1E06, 0x1E08, 0x1E0A, 0x1E0C, 0x1E0E, 0x1E10, 0x1E12,
00616 0x1E14, 0x1E16, 0x1E18, 0x1E1A, 0x1E1C, 0x1E1E, 0x1E20, 0x1E22, 0x1E24, 0x1E26,
00617 0x1E28, 0x1E2A, 0x1E2C, 0x1E2E, 0x1E30, 0x1E32, 0x1E34, 0x1E36, 0x1E38, 0x1E3A,
00618 0x1E3C, 0x1E3E, 0x1E40, 0x1E42, 0x1E44, 0x1E46, 0x1E48, 0x1E4A, 0x1E4C, 0x1E4E,
00619 0x1E50, 0x1E52, 0x1E54, 0x1E56, 0x1E58, 0x1E5A, 0x1E5C, 0x1E5E, 0x1E60, 0x1E62,
00620 0x1E64, 0x1E66, 0x1E68, 0x1E6A, 0x1E6C, 0x1E6E, 0x1E70, 0x1E72, 0x1E74, 0x1E76,
00621 0x1E78, 0x1E7A, 0x1E7C, 0x1E7E, 0x1E80, 0x1E82, 0x1E84, 0x1E86, 0x1E88, 0x1E8A,
00622 0x1E8C, 0x1E8E, 0x1E90, 0x1E92, 0x1E94, 0x1EA0, 0x1EA2, 0x1EA4, 0x1EA6, 0x1EA8,
00623 0x1EAA, 0x1EAC, 0x1EAE, 0x1EB0, 0x1EB2, 0x1EB4, 0x1EB6, 0x1EB8, 0x1EBA, 0x1EBC,
00624 0x1EBE, 0x1EC0, 0x1EC2, 0x1EC4, 0x1EC6, 0x1EC8, 0x1ECA, 0x1ECC, 0x1ECE, 0x1ED0,
00625 0x1ED2, 0x1ED4, 0x1ED6, 0x1ED8, 0x1EDA, 0x1EDC, 0x1EDE, 0x1EE0, 0x1EE2, 0x1EE4,
00626 0x1EE6, 0x1EE8, 0x1EEA, 0x1EEC, 0x1EEE, 0x1EF0, 0x1EF2, 0x1EF4, 0x1EF6, 0x1EF8,
00627 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, 0x1F18, 0x1F19,
00628 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D,
00629 0x1F2E, 0x1F2F, 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
00630 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x1F59, 0x1F5B, 0x1F5D, 0x1F5F,
00631 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, 0x1F88, 0x1F89,
00632 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, 0x1F98, 0x1F99, 0x1F9A, 0x1F9B,
00633 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD,
00634 0x1FAE, 0x1FAF, 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FC8, 0x1FC9, 0x1FCA,
00635 0x1FCB, 0x1FCC, 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB,
00636 0x1FEC, 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x2126, 0x212A, 0x212B, 0x2160,
00637 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A,
00638 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0x24B6, 0x24B7, 0x24B8, 0x24B9, 0x24BA,
00639 0x24BB, 0x24BC, 0x24BD, 0x24BE, 0x24BF, 0x24C0, 0x24C1, 0x24C2, 0x24C3, 0x24C4,
00640 0x24C5, 0x24C6, 0x24C7, 0x24C8, 0x24C9, 0x24CA, 0x24CB, 0x24CC, 0x24CD, 0x24CE,
00641 0x24CF, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29,
00642 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33,
00643 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A
00644 };
00645
00646 const wchar String::lowerCaseConversion[] = {
00647 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A,
00648 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
00649 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00E0, 0x00E1, 0x00E2, 0x00E3,
00650 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED,
00651 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F8,
00652 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0101, 0x0103, 0x0105, 0x0107,
00653 0x0109, 0x010B, 0x010D, 0x010F, 0x0111, 0x0113, 0x0115, 0x0117, 0x0119, 0x011B,
00654 0x011D, 0x011F, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x012B, 0x012D, 0x012F,
00655 0x0069, 0x0133, 0x0135, 0x0137, 0x013A, 0x013C, 0x013E, 0x0140, 0x0142, 0x0144,
00656 0x0146, 0x0148, 0x014B, 0x014D, 0x014F, 0x0151, 0x0153, 0x0155, 0x0157, 0x0159,
00657 0x015B, 0x015D, 0x015F, 0x0161, 0x0163, 0x0165, 0x0167, 0x0169, 0x016B, 0x016D,
00658 0x016F, 0x0171, 0x0173, 0x0175, 0x0177, 0x00FF, 0x017A, 0x017C, 0x017E, 0x0253,
00659 0x0183, 0x0185, 0x0254, 0x0188, 0x0256, 0x0257, 0x018C, 0x01DD, 0x0259, 0x025B,
00660 0x0192, 0x0260, 0x0263, 0x0269, 0x0268, 0x0199, 0x026F, 0x0272, 0x0275, 0x01A1,
00661 0x01A3, 0x01A5, 0x0280, 0x01A8, 0x0283, 0x01AD, 0x0288, 0x01B0, 0x028A, 0x028B,
00662 0x01B4, 0x01B6, 0x0292, 0x01B9, 0x01BD, 0x01C6, 0x01C6, 0x01C9, 0x01C9, 0x01CC,
00663 0x01CC, 0x01CE, 0x01D0, 0x01D2, 0x01D4, 0x01D6, 0x01D8, 0x01DA, 0x01DC, 0x01DF,
00664 0x01E1, 0x01E3, 0x01E5, 0x01E7, 0x01E9, 0x01EB, 0x01ED, 0x01EF, 0x01F3, 0x01F3,
00665 0x01F5, 0x0195, 0x01BF, 0x01F9, 0x01FB, 0x01FD, 0x01FF, 0x0201, 0x0203, 0x0205,
00666 0x0207, 0x0209, 0x020B, 0x020D, 0x020F, 0x0211, 0x0213, 0x0215, 0x0217, 0x0219,
00667 0x021B, 0x021D, 0x021F, 0x0223, 0x0225, 0x0227, 0x0229, 0x022B, 0x022D, 0x022F,
00668 0x0231, 0x0233, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03CC, 0x03CD, 0x03CE, 0x03B1,
00669 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
00670 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6,
00671 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03DB, 0x03DD, 0x03DF, 0x03E1, 0x03E3,
00672 0x03E5, 0x03E7, 0x03E9, 0x03EB, 0x03ED, 0x03EF, 0x03B8, 0x0450, 0x0451, 0x0452,
00673 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C,
00674 0x045D, 0x045E, 0x045F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436,
00675 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
00676 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A,
00677 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0461, 0x0463, 0x0465, 0x0467, 0x0469,
00678 0x046B, 0x046D, 0x046F, 0x0471, 0x0473, 0x0475, 0x0477, 0x0479, 0x047B, 0x047D,
00679 0x047F, 0x0481, 0x048D, 0x048F, 0x0491, 0x0493, 0x0495, 0x0497, 0x0499, 0x049B,
00680 0x049D, 0x049F, 0x04A1, 0x04A3, 0x04A5, 0x04A7, 0x04A9, 0x04AB, 0x04AD, 0x04AF,
00681 0x04B1, 0x04B3, 0x04B5, 0x04B7, 0x04B9, 0x04BB, 0x04BD, 0x04BF, 0x04C2, 0x04C4,
00682 0x04C8, 0x04CC, 0x04D1, 0x04D3, 0x04D5, 0x04D7, 0x04D9, 0x04DB, 0x04DD, 0x04DF,
00683 0x04E1, 0x04E3, 0x04E5, 0x04E7, 0x04E9, 0x04EB, 0x04ED, 0x04EF, 0x04F1, 0x04F3,
00684 0x04F5, 0x04F9, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568,
00685 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, 0x0570, 0x0571, 0x0572,
00686 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C,
00687 0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586,
00688
00689 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, 0x10d8, 0x10d9,
00690 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, 0x10e0, 0x10e1, 0x10e2, 0x10e3,
00691 0x10e4, 0x10e5, 0x10e6, 0x10e7, 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed,
00692 0x10ee, 0x10ef, 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5,
00693
00694 0x1E01, 0x1E03, 0x1E05, 0x1E07, 0x1E09, 0x1E0B, 0x1E0D, 0x1E0F, 0x1E11, 0x1E13,
00695 0x1E15, 0x1E17, 0x1E19, 0x1E1B, 0x1E1D, 0x1E1F, 0x1E21, 0x1E23, 0x1E25, 0x1E27,
00696 0x1E29, 0x1E2B, 0x1E2D, 0x1E2F, 0x1E31, 0x1E33, 0x1E35, 0x1E37, 0x1E39, 0x1E3B,
00697 0x1E3D, 0x1E3F, 0x1E41, 0x1E43, 0x1E45, 0x1E47, 0x1E49, 0x1E4B, 0x1E4D, 0x1E4F,
00698 0x1E51, 0x1E53, 0x1E55, 0x1E57, 0x1E59, 0x1E5B, 0x1E5D, 0x1E5F, 0x1E61, 0x1E63,
00699 0x1E65, 0x1E67, 0x1E69, 0x1E6B, 0x1E6D, 0x1E6F, 0x1E71, 0x1E73, 0x1E75, 0x1E77,
00700 0x1E79, 0x1E7B, 0x1E7D, 0x1E7F, 0x1E81, 0x1E83, 0x1E85, 0x1E87, 0x1E89, 0x1E8B,
00701 0x1E8D, 0x1E8F, 0x1E91, 0x1E93, 0x1E95, 0x1EA1, 0x1EA3, 0x1EA5, 0x1EA7, 0x1EA9,
00702 0x1EAB, 0x1EAD, 0x1EAF, 0x1EB1, 0x1EB3, 0x1EB5, 0x1EB7, 0x1EB9, 0x1EBB, 0x1EBD,
00703 0x1EBF, 0x1EC1, 0x1EC3, 0x1EC5, 0x1EC7, 0x1EC9, 0x1ECB, 0x1ECD, 0x1ECF, 0x1ED1,
00704 0x1ED3, 0x1ED5, 0x1ED7, 0x1ED9, 0x1EDB, 0x1EDD, 0x1EDF, 0x1EE1, 0x1EE3, 0x1EE5,
00705 0x1EE7, 0x1EE9, 0x1EEB, 0x1EED, 0x1EEF, 0x1EF1, 0x1EF3, 0x1EF5, 0x1EF7, 0x1EF9,
00706 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, 0x1F10, 0x1F11,
00707 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25,
00708 0x1F26, 0x1F27, 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
00709 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x1F51, 0x1F53, 0x1F55, 0x1F57,
00710 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, 0x1F80, 0x1F81,
00711 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, 0x1F90, 0x1F91, 0x1F92, 0x1F93,
00712 0x1F94, 0x1F95, 0x1F96, 0x1F97, 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5,
00713 0x1FA6, 0x1FA7, 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1F72, 0x1F73, 0x1F74,
00714 0x1F75, 0x1FC3, 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B,
00715 0x1FE5, 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x03C9, 0x006B, 0x00E5, 0x2170,
00716 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A,
00717 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4,
00718 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE,
00719 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8,
00720 0x24E9, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49,
00721 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53,
00722 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A
00723 };
00724
00725
00726
00727 wchar String::wCharToLower(wchar ch)
00728 {
00729 AvmAssert (sizeof (upperCaseBase) == sizeof (lowerCaseConversion));
00730
00731 wchar result = ch;
00732
00733 int lo = 0;
00734 int hi = (sizeof (upperCaseBase) / sizeof (upperCaseBase[0])) - 1;
00735
00736 while (lo <= hi)
00737 {
00738 int pivot = (lo+hi)>>1;
00739 int testChar = upperCaseBase[pivot];
00740
00741 if (ch == testChar)
00742 {
00743
00744 result = lowerCaseConversion[pivot];
00745 break;
00746 }
00747 else if (ch < testChar)
00748 {
00749 hi = pivot-1;
00750 }
00751 else
00752 {
00753 lo = pivot+1;
00754 }
00755 }
00756
00757 return result;
00758 }
00759
00760 Stringp String::toUpperCase()
00761 {
00762 GC* gc = GC::GetGC(this);
00763 int len = length();
00764 Stringp out = new (gc) String(len);
00765
00766
00767 bool changed = false;
00768
00769
00770 wchar *dst = out->lockBuffer();
00771 const wchar *src = c_str();
00772 const wchar *end = src + len;
00773 wchar charIn, charOut;
00774 while (src < end)
00775 {
00776 charIn = *src;
00777 if (charIn >= 0xFF)
00778 break;
00779
00780 charOut = String::toupper_map[charIn] ^ charIn;
00781 if (charOut != charIn)
00782 changed = true;
00783
00784 *dst++ = charOut;
00785 src++;
00786 }
00787
00788
00789
00790 while (src < end)
00791 {
00792 charIn = *src;
00793 charOut = wCharToUpper(charIn);
00794 if (charOut != charIn)
00795 changed = true;
00796
00797 *dst++ = charOut;
00798 src++;
00799 }
00800
00801 *dst = 0;
00802 out->unlockBuffer();
00803
00804
00805
00806 return changed ? out : this;
00807 }
00808
00809 Stringp String::toLowerCase()
00810 {
00811 GC* gc = GC::GetGC(this);
00812 int len = length();
00813 Stringp out = new (gc) String(len);
00814
00815
00816 bool changed = false;
00817
00818
00819 wchar *dst = out->lockBuffer();
00820 const wchar *src = c_str();
00821 const wchar *end = src + len;
00822 wchar charIn, charOut;
00823 while (src < end)
00824 {
00825 charIn = *src;
00826 if (charIn >= 0xFF)
00827 break;
00828
00829 charOut = String::tolower_map[charIn] ^ charIn;
00830 if (charOut != charIn)
00831 changed = true;
00832
00833 *dst++ = charOut;
00834 src++;
00835 }
00836
00837
00838
00839 while (src < end)
00840 {
00841 charIn = *src;
00842 charOut = wCharToLower(charIn);
00843 if (charOut != charIn)
00844 changed = true;
00845
00846 *dst++ = charOut;
00847 src++;
00848 }
00849
00850 *dst = 0;
00851 out->unlockBuffer();
00852
00853
00854
00855 return changed ? out : this;
00856 }
00857
00858 int String::indexOf(Stringp substr, int iStartPos)
00859 {
00860 if(!substr)
00861 return -1;
00862
00863 int sublen = substr->length();
00864 if (iStartPos > this->length())
00865 iStartPos = this->length();
00866
00867
00868
00869 const int iRight = this->length() - sublen;
00870
00871
00872
00873
00874
00875
00876
00877
00878 if (iStartPos < 0) {
00879 iStartPos = 0;
00880 }
00881
00882
00883 if (sublen == 1)
00884 {
00885 const wchar substrchar = substr->c_str()[0];
00886 const wchar *selfstr = this->c_str();
00887 for ( ; iStartPos <= iRight; iStartPos++)
00888 {
00889 if (substrchar == selfstr[iStartPos])
00890 {
00891 return iStartPos;
00892 }
00893 }
00894 }
00895 else
00896 {
00897 const wchar *substrstr = substr->c_str();
00898 const wchar *selfstr = this->c_str();
00899 selfstr += iStartPos;
00900 for ( ; iStartPos <= iRight; iStartPos++)
00901 {
00902 int j;
00903 for (j = 0; j < sublen; j++)
00904 {
00905 if (substrstr[j] != selfstr[j])
00906 {
00907 break;
00908 }
00909 }
00910
00911 if (j == sublen)
00912 {
00913 return iStartPos;
00914 }
00915 selfstr++;
00916 }
00917 }
00918
00919 return -1;
00920 }
00921
00922 int String::indexOfDouble(Stringp substr, double dStartPos)
00923 {
00924 dStartPos = MathUtils::toInt(dStartPos);
00925 int iStartPos = (dStartPos > (double)this->length() ? this->length() : (int)dStartPos);
00926 return indexOf (substr, iStartPos);
00927 }
00928
00929 Stringp String::charAt(int iPos)
00930 {
00931 GC *gc = GC::GetGC(this);
00932 AvmCore *core = (AvmCore *) gc->GetGCContextVariable (MMgc::GC::GCV_AVMCORE);
00933 if (iPos >= 0 && iPos < length())
00934 {
00935 wchar ch = !this->needsNormalization() ? getData()[iPos] : ((*this)[iPos]);
00936 if (ch < 128)
00937 {
00938 return core->cachedChars[ch];
00939 }
00940 else
00941 {
00942 return new (gc) String(this, iPos, 1);
00943 }
00944 }
00945 else
00946 {
00947 return core->kEmptyString;
00948 }
00949 }
00950
00951 Stringp String::charAtDouble(double dPos)
00952 {
00953 dPos = MathUtils::toInt(dPos);
00954 int iPos = (dPos > (double)this->length()) ? this->length() : (int)dPos;
00955 return charAt (iPos);
00956 }
00957
00958 double String::charCodeAt(int iPos)
00959 {
00960 if (iPos >= 0 && iPos < length())
00961 return (*this)[iPos];
00962 else
00963 return MathUtils::nan();
00964 }
00965
00966 double String::charCodeAtDouble(double dPos)
00967 {
00968 dPos = MathUtils::toInt(dPos);
00969 int iPos = (dPos > (double)this->length()) ? this->length() : (int)dPos;
00970 return charCodeAt (iPos);
00971 }
00972
00973 const wchar* String::c_str()
00974 {
00975
00976 if (needsNormalization()) normalize();
00977 return getData();
00978 }
00979
00980 wchar String::operator[] (int index)
00981 {
00982 AvmAssert(index >=0 && index < length());
00983 if (!hasPrefix())
00984 {
00985 return getData()[index + getOffset()];
00986 }
00987 else
00988 {
00989 AvmAssert (hasPrefix());
00990 normalize();
00991 return getData()[index];
00992
00993 #if 0 // This is the code if we want to skip the normalizations
00994
00995 Stringp s = this;
00996 while (s->getPrefix() && index < s->getPrefix()->length())
00997 s = s->getPrefix();
00998
00999 if (s->getPrefix())
01000 index -= s->getPrefix()->length();
01001 return s->getData()[s->getOffset() + index];
01002 #endif
01003 }
01004 }
01005
01006 wchar* String::lockBuffer()
01007 {
01008
01009 if (needsNormalization()) normalize();
01010 return (wchar*) getData();
01011 }
01012
01013 bool String::isSpace(wchar ch)
01014 {
01015 return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
01016 }
01017
01018 bool String::isWhitespace()
01019 {
01020 Stringp s = this;
01021 do
01022 {
01023 int base = !s->getPrefix() ? 0 : s->getPrefix()->length();
01024 for (int i = s->length()-base-1; i >= 0; i--)
01025 if (!isSpace(s->getData()[s->getOffset() + i]))
01026 return false;
01027 }
01028 while ( (s = s->getPrefix()) != 0);
01029 return true;
01030 }
01031
01032 int String::lastIndexOf(Stringp substr, int iStartPos)
01033 {
01034 int sublen = substr->length();
01035 iStartPos = (iStartPos > this->length()) ? this->length() : iStartPos;
01036
01037
01038
01039 const int iRight = this->length() - sublen;
01040
01041
01042
01043 if (iStartPos > iRight) {
01044 iStartPos = iRight;
01045 }
01046
01047 if (sublen == 0)
01048 return iStartPos;
01049
01050 const wchar *substrstr = substr->c_str();
01051 const wchar *selfstr = this->c_str() + iStartPos;
01052 for ( ; iStartPos >= 0 ; iStartPos-- )
01053 {
01054 for (int j = 0; j < sublen; j++)
01055 {
01056 if (substrstr[j] != selfstr[j])
01057 {
01058 break;
01059 }
01060
01061 if (j == (sublen - 1))
01062 return iStartPos;
01063 }
01064
01065 selfstr--;
01066 }
01067
01068 return -1;
01069 }
01070
01071 int String::lastIndexOfDouble(Stringp substr, double dStartPos)
01072 {
01073 if (!MathUtils::isNaN(dStartPos))
01074 dStartPos = MathUtils::toInt(dStartPos);
01075 else
01076 dStartPos = this->length();
01077 int iStartPos = (dStartPos > this->length() ? this->length() : (int)dStartPos);
01078 return lastIndexOf (substr, iStartPos);
01079 }
01080
01081 int String::localeCompare(Stringp other)
01082 {
01083 if ( !other )
01084 {
01085 GC *gc = GC::GetGC(this);
01086 AvmCore *core = (AvmCore *) gc->GetGCContextVariable (MMgc::GC::GCV_AVMCORE);
01087 other = core->knull;
01088 }
01089
01090 return other->Compare(*this);
01091 }
01092
01093 void String::generateIntegerEquivalent (AvmCore* core)
01094 {
01095 AvmAssert(this->isInterned());
01096 AvmAssert(!this->hasOffset());
01097 AvmAssert(!this->hasPrefix());
01098 uint32 index;
01099 (void)core;
01100 if (core->getIndexFromString (this, &index))
01101 {
01102 if (!(index & ScriptObject::MAX_INTEGER_MASK))
01103 {
01104 m_prefixOrOffsetOrNumber = index<<3 | NUMBERFLAG;
01105 }
01106 }
01107 }
01108
01109 String::StringBuf *String::allocBuf(int numChars)
01110 {
01111 GC* gc = GC::GetGC(this);
01112 return new (gc, sizeof(wchar)*(numChars+1)) StringBuf();
01113 }
01114
01115 Stringp String::substring(int start, int end)
01116 {
01117 GC *gc = GC::GetGC(this);
01118 NativeObjectHelpers::ClampBInt(start, end, this->length());
01119 return new (gc) String(this, start, (end-start));
01120 }
01121
01122 Stringp String::substringDouble(double d_start, double d_end)
01123 {
01124 GC *gc = GC::GetGC(this);
01125 double start = MathUtils::toInt(d_start);
01126 double end = MathUtils::toInt(d_end);
01127 NativeObjectHelpers::ClampB(start, end, length());
01128 return new (gc) String(this, (int)start, (int)(end-start));
01129 }
01130
01131 Stringp String::slice(int start, int end)
01132 {
01133 GC *gc = GC::GetGC(this);
01134 int len = this->length();
01135 start = (int)NativeObjectHelpers::ClampIndexInt(start, len);
01136 end = (int)NativeObjectHelpers::ClampIndexInt(end, len);
01137 if (end < start)
01138 end = start;
01139
01140 return new (gc) String(this, start, end-start);
01141 }
01142
01143 Stringp String::sliceDouble(double d_start, double d_end)
01144 {
01145 GC *gc = GC::GetGC(this);
01146 int len = this->length();
01147 int start = (int)NativeObjectHelpers::ClampIndex(MathUtils::toInt(d_start), len);
01148 int end = (int)NativeObjectHelpers::ClampIndex(MathUtils::toInt(d_end), len);
01149 if (end < start)
01150 end = start;
01151
01152 return new (gc) String(this, start, end-start);
01153 }
01154
01155 Stringp String::substr(int start, int end)
01156 {
01157 GC *gc = GC::GetGC(this);
01158 int len = this->length();
01159 start = (int)NativeObjectHelpers::ClampIndexInt(start, len);
01160
01161
01162
01163
01164
01165
01166
01167 if (end == 0x7ffffff)
01168 {
01169 end = len;
01170 }
01171 else if ((end > 0xffffff) || (start > 0xffffff))
01172 {
01173 end = (int)NativeObjectHelpers::ClampIndex(double(end) + double(start), len);
01174 }
01175 else
01176 {
01177 end = (int)NativeObjectHelpers::ClampIndexInt(end + start, len);
01178 }
01179
01180 if (end < start)
01181 end = start;
01182
01183 return new (gc) String(this, start, end-start);
01184 }
01185
01186 Stringp String::substrDouble(double d_start, double d_end)
01187 {
01188 GC *gc = GC::GetGC(this);
01189 int len = this->length();
01190 int start = (int)NativeObjectHelpers::ClampIndex(MathUtils::toInt(d_start), len);
01191
01192
01193
01194
01195 int end = (int)NativeObjectHelpers::ClampIndex(MathUtils::toInt(d_end) + (double)start, len);
01196 if (end < start)
01197 end = start;
01198
01199 return new (gc) String(this, start, end-start);
01200 }
01201
01202 void String::setPrefixOrOffsetOrNumber(uintptr value)
01203 {
01204 #ifdef MMGC_DRC
01205
01206 if((m_prefixOrOffsetOrNumber & STRINGFLAGS) == PREFIXFLAG)
01207 getPrefix()->DecrementRef();
01208 #endif
01209 GC::GetGC(this)->WriteBarrierNoSubstitute(this, (void*)value);
01210 m_prefixOrOffsetOrNumber = value;
01211 #ifdef MMGC_DRC
01212 if((value & STRINGFLAGS) == PREFIXFLAG)
01213 getPrefix()->IncrementRef();
01214 #endif
01215 }
01216
01217 #ifdef DEBUGGER
01218 uint64 String::size() const
01219 {
01220 uint64 size = sizeof(String) - sizeof(AvmPlusScriptableObject);
01221 uint64 bufSize = sizeof(StringBuf) + length() * sizeof(wchar);
01222 if(m_buf->RefCount() != 0)
01223 size += bufSize / m_buf->RefCount();
01224 else
01225 size += bufSize;
01226 return size;
01227 }
01228 #endif
01229
01230 StringNullTerminatedUTF8::StringNullTerminatedUTF8(MMgc::GC *gc, Stringp str) :
01231 m_str(str),
01232 m_bufptr(NULL),
01233 gc(gc)
01234 {
01235 MMGC_MEM_TYPE("StringNullTerminatedUTF8");
01236 int len = str->length();
01237 m_bufptr = (char*)gc->Alloc(len + 1);
01238 const wchar *data = str->c_str();
01239 for (int i=0; i < len; i++) {
01240 m_bufptr[i] = (char) data[i];
01241 }
01242 m_bufptr[len] = 0;
01243 }
01244
01245 StringNullTerminatedUTF8::~StringNullTerminatedUTF8()
01246 {
01247 gc->Free(m_bufptr);
01248 m_str = NULL;
01249 m_bufptr = NULL;
01250 }
01251 }