00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <config.h>
00017
00018 #include <drizzled/internal/m_string.h>
00019 #include <drizzled/charset.h>
00020
00021 #include <algorithm>
00022
00023 using namespace std;
00024
00025 namespace drizzled {
00026
00027
00028
00029
00030
00031 int my_strcasecmp_mb(const charset_info_st * const cs,const char *s, const char *t)
00032 {
00033 uint32_t l;
00034 unsigned char *map=cs->to_upper;
00035
00036 while (*s && *t)
00037 {
00038
00039 if ((l=my_ismbchar(cs, s, s + cs->mbmaxlen)))
00040 {
00041 while (l--)
00042 if (*s++ != *t++)
00043 return 1;
00044 }
00045 else if (my_mbcharlen(cs, *t) > 1)
00046 return 1;
00047 else if (map[(unsigned char) *s++] != map[(unsigned char) *t++])
00048 return 1;
00049 }
00050
00051 return (*t != *s);
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 inline static const char* inc_ptr(const charset_info_st *cs, const char *str, const char* str_end)
00062 {
00063 return str + (my_ismbchar(cs, str, str_end) ? my_ismbchar(cs, str, str_end) : 1);
00064 }
00065
00066 inline static int likeconv(const charset_info_st *cs, const char c)
00067 {
00068 return (unsigned char) cs->sort_order[(unsigned char) c];
00069 }
00070
00071 int my_wildcmp_mb(const charset_info_st * const cs,
00072 const char *str,const char *str_end,
00073 const char *wildstr,const char *wildend,
00074 int escape, int w_one, int w_many)
00075 {
00076 int result= -1;
00077
00078 while (wildstr != wildend)
00079 {
00080 while (*wildstr != w_many && *wildstr != w_one)
00081 {
00082 int l;
00083 if (*wildstr == escape && wildstr+1 != wildend)
00084 wildstr++;
00085 if ((l = my_ismbchar(cs, wildstr, wildend)))
00086 {
00087 if (str+l > str_end || memcmp(str, wildstr, l) != 0)
00088 return 1;
00089 str += l;
00090 wildstr += l;
00091 }
00092 else
00093 if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
00094 return 1;
00095 if (wildstr == wildend)
00096 return (str != str_end);
00097 result=1;
00098 }
00099 if (*wildstr == w_one)
00100 {
00101 do
00102 {
00103 if (str == str_end)
00104 return (result);
00105 inc_ptr(cs,str,str_end);
00106 } while (++wildstr < wildend && *wildstr == w_one);
00107 if (wildstr == wildend)
00108 break;
00109 }
00110 if (*wildstr == w_many)
00111 {
00112 unsigned char cmp;
00113 const char* mb = wildstr;
00114 int mb_len=0;
00115
00116 wildstr++;
00117
00118 for (; wildstr != wildend ; wildstr++)
00119 {
00120 if (*wildstr == w_many)
00121 continue;
00122 if (*wildstr == w_one)
00123 {
00124 if (str == str_end)
00125 return (-1);
00126 inc_ptr(cs,str,str_end);
00127 continue;
00128 }
00129 break;
00130 }
00131 if (wildstr == wildend)
00132 return 0;
00133 if (str == str_end)
00134 return -1;
00135
00136 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
00137 cmp= *++wildstr;
00138
00139 mb=wildstr;
00140 mb_len= my_ismbchar(cs, wildstr, wildend);
00141 inc_ptr(cs,wildstr,wildend);
00142 cmp=likeconv(cs,cmp);
00143 do
00144 {
00145 for (;;)
00146 {
00147 if (str >= str_end)
00148 return -1;
00149 if (mb_len)
00150 {
00151 if (str+mb_len <= str_end && memcmp(str, mb, mb_len) == 0)
00152 {
00153 str += mb_len;
00154 break;
00155 }
00156 }
00157 else if (!my_ismbchar(cs, str, str_end) &&
00158 likeconv(cs,*str) == cmp)
00159 {
00160 str++;
00161 break;
00162 }
00163 inc_ptr(cs,str, str_end);
00164 }
00165 {
00166 int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,
00167 w_many);
00168 if (tmp <= 0)
00169 return (tmp);
00170 }
00171 } while (str != str_end && wildstr[0] != w_many);
00172 return(-1);
00173 }
00174 }
00175 return (str != str_end ? 1 : 0);
00176 }
00177
00178
00179 size_t my_numchars_mb(const charset_info_st * const cs,
00180 const char *pos, const char *end)
00181 {
00182 size_t count= 0;
00183 while (pos < end)
00184 {
00185 uint32_t mb_len;
00186 pos+= (mb_len= my_ismbchar(cs,pos,end)) ? mb_len : 1;
00187 count++;
00188 }
00189 return count;
00190 }
00191
00192
00193 size_t my_charpos_mb(const charset_info_st * const cs, const char *pos, const char *end, size_t length)
00194 {
00195 const char *start= pos;
00196
00197 while (length && pos < end)
00198 {
00199 uint32_t mb_len;
00200 pos+= (mb_len= my_ismbchar(cs, pos, end)) ? mb_len : 1;
00201 length--;
00202 }
00203 return (size_t) (length ? end+2-start : pos-start);
00204 }
00205
00206
00207 size_t my_well_formed_len_mb(const charset_info_st& cs, str_ref str, size_t pos, int *error)
00208 {
00209 const char *b= str.begin();
00210 const char *e= str.end();
00211 const char *b_start= b;
00212 *error= 0;
00213 while (pos)
00214 {
00215 my_wc_t wc;
00216 int mb_len= cs.cset->mb_wc(&cs, &wc, (const unsigned char*) b, (const unsigned char*) e);
00217 if (mb_len <= 0)
00218 {
00219 *error= b < e ? 1 : 0;
00220 break;
00221 }
00222 b+= mb_len;
00223 pos--;
00224 }
00225 return (size_t) (b - b_start);
00226 }
00227
00228
00229 uint32_t my_instr_mb(const charset_info_st * const cs,
00230 const char *b, size_t b_length,
00231 const char *s, size_t s_length,
00232 my_match_t *match, uint32_t nmatch)
00233 {
00234 const char *end, *b0;
00235 int res= 0;
00236
00237 if (s_length <= b_length)
00238 {
00239 if (!s_length)
00240 {
00241 if (nmatch)
00242 {
00243 match->beg= 0;
00244 match->end= 0;
00245 match->mb_len= 0;
00246 }
00247 return 1;
00248 }
00249
00250 b0= b;
00251 end= b+b_length-s_length+1;
00252
00253 while (b < end)
00254 {
00255 int mb_len;
00256
00257 if (!cs->coll->strnncoll(cs, (const unsigned char*) b, s_length,
00258 (const unsigned char*) s, s_length, 0))
00259 {
00260 if (nmatch)
00261 {
00262 match[0].beg= 0;
00263 match[0].end= (size_t) (b-b0);
00264 match[0].mb_len= res;
00265 if (nmatch > 1)
00266 {
00267 match[1].beg= match[0].end;
00268 match[1].end= match[0].end+s_length;
00269 match[1].mb_len= 0;
00270 }
00271 }
00272 return 2;
00273 }
00274 mb_len= (mb_len= my_ismbchar(cs, b, end)) ? mb_len : 1;
00275 b+= mb_len;
00276 b_length-= mb_len;
00277 res++;
00278 }
00279 }
00280 return 0;
00281 }
00282
00283
00284
00285
00286 int my_strnncoll_mb_bin(const charset_info_st * const,
00287 const unsigned char *s, size_t slen,
00288 const unsigned char *t, size_t tlen,
00289 bool t_is_prefix)
00290 {
00291 size_t len= min(slen,tlen);
00292 int cmp= memcmp(s,t,len);
00293 return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 int my_strnncollsp_mb_bin(const charset_info_st * const,
00323 const unsigned char *a, size_t a_length,
00324 const unsigned char *b, size_t b_length,
00325 bool diff_if_only_endspace_difference)
00326 {
00327 const unsigned char *end;
00328 size_t length;
00329 int res;
00330
00331 #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
00332 diff_if_only_endspace_difference= 0;
00333 #endif
00334
00335 end= a + (length= min(a_length, b_length));
00336 while (a < end)
00337 {
00338 if (*a++ != *b++)
00339 return ((int) a[-1] - (int) b[-1]);
00340 }
00341 res= 0;
00342 if (a_length != b_length)
00343 {
00344 int swap= 1;
00345 if (diff_if_only_endspace_difference)
00346 res= 1;
00347
00348
00349
00350
00351 if (a_length < b_length)
00352 {
00353
00354 a_length= b_length;
00355 a= b;
00356 swap= -1;
00357 res= -res;
00358 }
00359 for (end= a + a_length-length; a < end ; a++)
00360 {
00361 if (*a != ' ')
00362 return (*a < ' ') ? -swap : swap;
00363 }
00364 }
00365 return res;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 #define my_strnxfrm_mb_non_ascii_char(cs, dst, src, se) \
00378 { \
00379 switch (cs->cset->ismbchar(cs, (const char*) src, (const char*) se)) { \
00380 case 4: \
00381 *dst++= *src++; \
00382 \
00383 case 3: \
00384 *dst++= *src++; \
00385 \
00386 case 2: \
00387 *dst++= *src++; \
00388 \
00389 case 0: \
00390 *dst++= *src++; \
00391 } \
00392 }
00393
00394
00395
00396
00397
00398
00399
00400 size_t
00401 my_strnxfrm_mb(const charset_info_st * const cs,
00402 unsigned char *dst, size_t dstlen, uint32_t nweights,
00403 const unsigned char *src, size_t srclen, uint32_t flags)
00404 {
00405 unsigned char *d0= dst;
00406 unsigned char *de= dst + dstlen;
00407 const unsigned char *se= src + srclen;
00408 const unsigned char *sort_order= cs->sort_order;
00409
00410 assert(cs->mbmaxlen <= 4);
00411
00412
00413
00414
00415
00416
00417 if (dstlen >= srclen && nweights >= srclen)
00418 {
00419 if (sort_order)
00420 {
00421
00422 for (; src < se; nweights--)
00423 {
00424 if (*src < 128)
00425 *dst++= sort_order[*src++];
00426 else
00427 my_strnxfrm_mb_non_ascii_char(cs, dst, src, se);
00428 }
00429 }
00430 else
00431 {
00432
00433 for (; src < se; nweights--)
00434 {
00435 if (*src < 128)
00436 *dst++= *src++;
00437 else
00438 my_strnxfrm_mb_non_ascii_char(cs, dst, src, se);
00439 }
00440 }
00441 goto pad;
00442 }
00443
00444
00445
00446
00447
00448 for (; src < se && nweights; nweights--)
00449 {
00450 int chlen;
00451 if (*src < 128 ||
00452 !(chlen= cs->cset->ismbchar(cs, (const char*) src, (const char*) se)))
00453 {
00454
00455 if (dst >= de)
00456 break;
00457 *dst++= sort_order ? sort_order[*src++] : *src++;
00458 }
00459 else
00460 {
00461
00462 if (dst + chlen > de)
00463 break;
00464 *dst++= *src++;
00465 *dst++= *src++;
00466 if (chlen == 3)
00467 *dst++= *src++;
00468 }
00469 }
00470
00471 pad:
00472 return my_strxfrm_pad_desc_and_reverse(cs, d0, dst, de, nweights, flags, 0);
00473 }
00474
00475
00476 int my_strcasecmp_mb_bin(const charset_info_st * const,
00477 const char *s, const char *t)
00478 {
00479 return strcmp(s,t);
00480 }
00481
00482
00483 void my_hash_sort_mb_bin(const charset_info_st * const,
00484 const unsigned char *key, size_t len,
00485 uint32_t *nr1, uint32_t *nr2)
00486 {
00487 const unsigned char *pos = key;
00488
00489
00490
00491
00492
00493 key= internal::skip_trailing_space(key, len);
00494
00495 for (; pos < (const unsigned char*) key ; pos++)
00496 {
00497 nr1[0]^=(ulong) ((((uint32_t) nr1[0] & 63)+nr2[0]) *
00498 ((uint32_t)*pos)) + (nr1[0] << 8);
00499 nr2[0]+=3;
00500 }
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 static void pad_max_char(const charset_info_st * const cs, char *str, char *end)
00521 {
00522 char buf[10];
00523 char buflen;
00524
00525 if (!(cs->state & MY_CS_UNICODE))
00526 {
00527 memset(str, 255, end - str);
00528 return;
00529 }
00530
00531 buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (unsigned char*) buf,
00532 (unsigned char*) buf + sizeof(buf));
00533
00534 assert(buflen > 0);
00535 do
00536 {
00537 if ((str + buflen) < end)
00538 {
00539
00540 memcpy(str, buf, buflen);
00541 str+= buflen;
00542 }
00543 else
00544 {
00545
00546
00547
00548
00549 *str++= ' ';
00550 }
00551 } while (str < end);
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 bool my_like_range_mb(const charset_info_st * const cs,
00575 const char *ptr,size_t ptr_length,
00576 char escape, char w_one, char w_many,
00577 size_t res_length,
00578 char *min_str,char *max_str,
00579 size_t *min_length,size_t *max_length)
00580 {
00581 uint32_t mb_len;
00582 const char *end= ptr + ptr_length;
00583 char *min_org= min_str;
00584 char *min_end= min_str + res_length;
00585 char *max_end= max_str + res_length;
00586 size_t maxcharlen= res_length / cs->mbmaxlen;
00587 const char *contraction_flags= cs->contractions ?
00588 ((const char*) cs->contractions) + 0x40*0x40 : NULL;
00589
00590 for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
00591 {
00592
00593 if (*ptr == escape && ptr+1 != end)
00594 ptr++;
00595 else if (*ptr == w_one || *ptr == w_many)
00596 {
00597 fill_max_and_min:
00598
00599
00600
00601
00602
00603 *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) :
00604 res_length);
00605 *max_length= res_length;
00606
00607 do
00608 {
00609 *min_str++= (char) cs->min_sort_char;
00610 } while (min_str != min_end);
00611
00612
00613
00614
00615
00616
00617 *max_length= res_length;
00618 pad_max_char(cs, max_str, max_end);
00619 return 0;
00620 }
00621 if ((mb_len= my_ismbchar(cs, ptr, end)) > 1)
00622 {
00623 if (ptr+mb_len > end || min_str+mb_len > min_end)
00624 break;
00625 while (mb_len--)
00626 *min_str++= *max_str++= *ptr++;
00627 }
00628 else
00629 {
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 if (contraction_flags && ptr + 1 < end &&
00657 contraction_flags[(unsigned char) *ptr])
00658 {
00659
00660
00661 if (ptr[1] == w_one || ptr[1] == w_many)
00662 {
00663
00664 goto fill_max_and_min;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 if (contraction_flags[(unsigned char) ptr[1]] &&
00680 cs->contractions[(*ptr-0x40)*0x40 + ptr[1] - 0x40])
00681 {
00682
00683 if (maxcharlen == 1 || min_str + 1 >= min_end)
00684 {
00685
00686 goto fill_max_and_min;
00687 }
00688
00689
00690 *min_str++= *max_str++= *ptr++;
00691 maxcharlen--;
00692 }
00693 }
00694
00695 *min_str++= *max_str++= *ptr++;
00696 }
00697 }
00698
00699 *min_length= *max_length = (size_t) (min_str - min_org);
00700 while (min_str != min_end)
00701 *min_str++= *max_str++= ' ';
00702 return 0;
00703 }
00704
00705
00706 int my_wildcmp_mb_bin(const charset_info_st * const cs,
00707 const char *str,const char *str_end,
00708 const char *wildstr,const char *wildend,
00709 int escape, int w_one, int w_many)
00710 {
00711 int result= -1;
00712
00713 while (wildstr != wildend)
00714 {
00715 while (*wildstr != w_many && *wildstr != w_one)
00716 {
00717 int l;
00718 if (*wildstr == escape && wildstr+1 != wildend)
00719 wildstr++;
00720 if ((l = my_ismbchar(cs, wildstr, wildend)))
00721 {
00722 if (str+l > str_end || memcmp(str, wildstr, l) != 0)
00723 return 1;
00724 str += l;
00725 wildstr += l;
00726 }
00727 else
00728 if (str == str_end || *wildstr++ != *str++)
00729 return 1;
00730 if (wildstr == wildend)
00731 return (str != str_end);
00732 result=1;
00733 }
00734 if (*wildstr == w_one)
00735 {
00736 do
00737 {
00738 if (str == str_end)
00739 return (result);
00740 inc_ptr(cs,str,str_end);
00741 } while (++wildstr < wildend && *wildstr == w_one);
00742 if (wildstr == wildend)
00743 break;
00744 }
00745 if (*wildstr == w_many)
00746 {
00747 unsigned char cmp;
00748 const char* mb = wildstr;
00749 int mb_len=0;
00750
00751 wildstr++;
00752
00753 for (; wildstr != wildend ; wildstr++)
00754 {
00755 if (*wildstr == w_many)
00756 continue;
00757 if (*wildstr == w_one)
00758 {
00759 if (str == str_end)
00760 return (-1);
00761 inc_ptr(cs,str,str_end);
00762 continue;
00763 }
00764 break;
00765 }
00766 if (wildstr == wildend)
00767 return 0;
00768 if (str == str_end)
00769 return -1;
00770
00771 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
00772 cmp= *++wildstr;
00773
00774 mb=wildstr;
00775 mb_len= my_ismbchar(cs, wildstr, wildend);
00776 inc_ptr(cs,wildstr,wildend);
00777 do
00778 {
00779 for (;;)
00780 {
00781 if (str >= str_end)
00782 return -1;
00783 if (mb_len)
00784 {
00785 if (str+mb_len <= str_end && memcmp(str, mb, mb_len) == 0)
00786 {
00787 str += mb_len;
00788 break;
00789 }
00790 }
00791 else if (!my_ismbchar(cs, str, str_end) && *str == cmp)
00792 {
00793 str++;
00794 break;
00795 }
00796 inc_ptr(cs,str, str_end);
00797 }
00798 {
00799 int tmp=my_wildcmp_mb_bin(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
00800 if (tmp <= 0)
00801 return (tmp);
00802 }
00803 } while (str != str_end && wildstr[0] != w_many);
00804 return(-1);
00805 }
00806 }
00807 return (str != str_end ? 1 : 0);
00808 }
00809
00810
00811
00812
00813
00814
00815 static char pg11[256]=
00816 {
00817 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00818 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00819 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,
00820 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00821 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00822 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00823 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00824 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00825 };
00826
00827 static char pg23[256]=
00828 {
00829 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00830 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00831 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00832 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00833 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00834 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00835 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00836 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00837 };
00838
00839 static char pg2E[256]=
00840 {
00841 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00842 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00843 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00844 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00845 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,
00846 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00847 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00848 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
00849 };
00850
00851 static char pg2F[256]=
00852 {
00853 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00854 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00855 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00856 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00857 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00858 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00859 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
00860 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
00861 };
00862
00863 static char pg30[256]=
00864 {
00865 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00866 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
00867 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00868 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00869 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
00870 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00871 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00872 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
00873 };
00874
00875 static char pg31[256]=
00876 {
00877 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00878 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00879 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00880 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00881 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00882 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
00883 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00884 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
00885 };
00886
00887 static char pg32[256]=
00888 {
00889 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
00890 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00891 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00892 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,
00893 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00894 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00895 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00896 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
00897 };
00898
00899 static char pg4D[256]=
00900 {
00901 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00902 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00903 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00904 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00905 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00906 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
00907 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00908 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00909 };
00910
00911 static char pg9F[256]=
00912 {
00913 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00914 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00915 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00916 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00917 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00918 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00919 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00920 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00921 };
00922
00923 static char pgA4[256]=
00924 {
00925 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00926 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00927 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00928 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00929 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00930 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00931 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00932 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00933 };
00934
00935 static char pgD7[256]=
00936 {
00937 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00938 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00939 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00940 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00941 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00942 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00943 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00944 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00945 };
00946
00947 static char pgFA[256]=
00948 {
00949 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00950 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00951 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00952 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00953 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00954 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00955 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00956 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00957 };
00958
00959 static char pgFE[256]=
00960 {
00961 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00962 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00963 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
00964 1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00965 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00966 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00967 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00968 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00969 };
00970
00971 static char pgFF[256]=
00972 {
00973 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00974 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00975 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00976 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00977 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00978 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00979 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00980 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00981 };
00982
00983 static class {
00984 public:
00985 int page;
00986 char *p;
00987 }
00988 utr11_data[256]=
00989 {
00990 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
00991 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
00992 {0,NULL},{0,pg11},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
00993 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
00994 {0,NULL},{0,NULL},{0,NULL},{0,pg23},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
00995 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,pg2E},{0,pg2F},
00996 {0,pg30},{0,pg31},{0,pg32},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
00997 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
00998 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
00999 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pg4D},{1,NULL},{1,NULL},
01000 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01001 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01002 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01003 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01004 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01005 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01006 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01007 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01008 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01009 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pg9F},
01010 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pgA4},{0,NULL},{0,NULL},{0,NULL},
01011 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01012 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01013 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01014 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01015 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
01016 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pgD7},
01017 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
01018 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
01019 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
01020 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
01021 {0,NULL},{1,NULL},{0,pgFA},{0,NULL},{0,NULL},{0,NULL},{0,pgFE},{0,pgFF}
01022 };
01023
01024
01025 size_t my_numcells_mb(const charset_info_st * const cs, const char *b, const char *e)
01026 {
01027 my_wc_t wc;
01028 size_t clen= 0;
01029
01030 while (b < e)
01031 {
01032 int mb_len;
01033 uint32_t pg;
01034 if ((mb_len= cs->cset->mb_wc(cs, &wc, (unsigned char*) b, (unsigned char*) e)) <= 0 ||
01035 wc > 0xFFFF)
01036 {
01037
01038
01039
01040
01041 mb_len= 1;
01042 b++;
01043 continue;
01044 }
01045 b+= mb_len;
01046 pg= (wc >> 8) & 0xFF;
01047 clen+= utr11_data[pg].p ? utr11_data[pg].p[wc & 0xFF] : utr11_data[pg].page;
01048 clen++;
01049 }
01050 return clen;
01051 }
01052
01053
01054
01055 int my_mb_ctype_mb(const charset_info_st * const cs, int *ctype,
01056 const unsigned char *s, const unsigned char *e)
01057 {
01058 my_wc_t wc;
01059 int res= cs->cset->mb_wc(cs, &wc, s, e);
01060 if (res <= 0 || wc > 0xFFFF)
01061 *ctype= 0;
01062 else
01063 *ctype= my_uni_ctype[wc>>8].ctype ? my_uni_ctype[wc>>8].ctype[wc&0xFF] : my_uni_ctype[wc>>8].pctype;
01064 return res;
01065 }
01066
01067 }