ctype.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <my_global.h>
  14. #include <m_ctype.h>
  15. #include <my_xml.h>
  16. #ifndef SCO
  17. #include <m_string.h>
  18. #endif
  19. /*
  20.   This files implements routines which parse XML based
  21.   character set and collation description files.
  22.   
  23.   Unicode collations are encoded according to
  24.   
  25.     Unicode Technical Standard #35
  26.     Locale Data Markup Language (LDML)
  27.     http://www.unicode.org/reports/tr35/
  28.   
  29.   and converted into ICU string according to
  30.   
  31.     Collation Customization
  32.     http://oss.software.ibm.com/icu/userguide/Collate_Customization.html
  33.   
  34. */
  35. static char *mstr(char *str,const char *src,uint l1,uint l2)
  36. {
  37.   l1= l1<l2 ? l1 : l2;
  38.   memcpy(str,src,l1);
  39.   str[l1]='';
  40.   return str;
  41. }
  42. struct my_cs_file_section_st
  43. {
  44.   int        state;
  45.   const char *str;
  46. };
  47. #define _CS_MISC 1
  48. #define _CS_ID 2
  49. #define _CS_CSNAME 3
  50. #define _CS_FAMILY 4
  51. #define _CS_ORDER 5
  52. #define _CS_COLNAME 6
  53. #define _CS_FLAG 7
  54. #define _CS_CHARSET 8
  55. #define _CS_COLLATION 9
  56. #define _CS_UPPERMAP 10
  57. #define _CS_LOWERMAP 11
  58. #define _CS_UNIMAP 12
  59. #define _CS_COLLMAP 13
  60. #define _CS_CTYPEMAP 14
  61. #define _CS_PRIMARY_ID 15
  62. #define _CS_BINARY_ID 16
  63. #define _CS_CSDESCRIPT 17
  64. #define _CS_RESET 18
  65. #define _CS_DIFF1 19
  66. #define _CS_DIFF2 20
  67. #define _CS_DIFF3 21
  68. static struct my_cs_file_section_st sec[] =
  69. {
  70.   {_CS_MISC, "xml"},
  71.   {_CS_MISC, "xml.version"},
  72.   {_CS_MISC, "xml.encoding"},
  73.   {_CS_MISC, "charsets"},
  74.   {_CS_MISC, "charsets.max-id"},
  75.   {_CS_CHARSET, "charsets.charset"},
  76.   {_CS_PRIMARY_ID, "charsets.charset.primary-id"},
  77.   {_CS_BINARY_ID, "charsets.charset.binary-id"},
  78.   {_CS_CSNAME, "charsets.charset.name"},
  79.   {_CS_FAMILY, "charsets.charset.family"},
  80.   {_CS_CSDESCRIPT, "charsets.charset.description"},
  81.   {_CS_MISC, "charsets.charset.alias"},
  82.   {_CS_MISC, "charsets.charset.ctype"},
  83.   {_CS_CTYPEMAP, "charsets.charset.ctype.map"},
  84.   {_CS_MISC, "charsets.charset.upper"},
  85.   {_CS_UPPERMAP, "charsets.charset.upper.map"},
  86.   {_CS_MISC, "charsets.charset.lower"},
  87.   {_CS_LOWERMAP, "charsets.charset.lower.map"},
  88.   {_CS_MISC, "charsets.charset.unicode"},
  89.   {_CS_UNIMAP, "charsets.charset.unicode.map"},
  90.   {_CS_COLLATION, "charsets.charset.collation"},
  91.   {_CS_COLNAME, "charsets.charset.collation.name"},
  92.   {_CS_ID, "charsets.charset.collation.id"},
  93.   {_CS_ORDER, "charsets.charset.collation.order"},
  94.   {_CS_FLAG, "charsets.charset.collation.flag"},
  95.   {_CS_COLLMAP, "charsets.charset.collation.map"},
  96.   {_CS_RESET, "charsets.charset.collation.rules.reset"},
  97.   {_CS_DIFF1, "charsets.charset.collation.rules.p"},
  98.   {_CS_DIFF2, "charsets.charset.collation.rules.s"},
  99.   {_CS_DIFF3, "charsets.charset.collation.rules.t"},
  100.   {0, NULL}
  101. };
  102. static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len)
  103. {
  104.   struct my_cs_file_section_st *s;
  105.   for (s=sec; s->str; s++)
  106.   {
  107.     if (!strncmp(attr,s->str,len))
  108.       return s;
  109.   }
  110.   return NULL;
  111. }
  112. #define MY_CS_CSDESCR_SIZE 64
  113. #define MY_CS_TAILORING_SIZE 128
  114. typedef struct my_cs_file_info
  115. {
  116.   char   csname[MY_CS_NAME_SIZE];
  117.   char   name[MY_CS_NAME_SIZE];
  118.   uchar  ctype[MY_CS_CTYPE_TABLE_SIZE];
  119.   uchar  to_lower[MY_CS_TO_LOWER_TABLE_SIZE];
  120.   uchar  to_upper[MY_CS_TO_UPPER_TABLE_SIZE];
  121.   uchar  sort_order[MY_CS_SORT_ORDER_TABLE_SIZE];
  122.   uint16 tab_to_uni[MY_CS_TO_UNI_TABLE_SIZE];
  123.   char   comment[MY_CS_CSDESCR_SIZE];
  124.   char   tailoring[MY_CS_TAILORING_SIZE];
  125.   size_t tailoring_length;
  126.   CHARSET_INFO cs;
  127.   int (*add_collation)(CHARSET_INFO *cs);
  128. } MY_CHARSET_LOADER;
  129. static int fill_uchar(uchar *a,uint size,const char *str, uint len)
  130. {
  131.   uint i= 0;
  132.   const char *s, *b, *e=str+len;
  133.   
  134.   for (s=str ; s < e ; i++)
  135.   { 
  136.     for ( ; (s < e) && strchr(" trn",s[0]); s++) ;
  137.     b=s;
  138.     for ( ; (s < e) && !strchr(" trn",s[0]); s++) ;
  139.     if (s == b || i > size)
  140.       break;
  141.     a[i]= (uchar) strtoul(b,NULL,16);
  142.   }
  143.   return 0;
  144. }
  145. static int fill_uint16(uint16 *a,uint size,const char *str, uint len)
  146. {
  147.   uint i= 0;
  148.   
  149.   const char *s, *b, *e=str+len;
  150.   for (s=str ; s < e ; i++)
  151.   { 
  152.     for ( ; (s < e) && strchr(" trn",s[0]); s++) ;
  153.     b=s;
  154.     for ( ; (s < e) && !strchr(" trn",s[0]); s++) ;
  155.     if (s == b || i > size)
  156.       break;
  157.     a[i]= (uint16) strtol(b,NULL,16);
  158.   }
  159.   return 0;
  160. }
  161. static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len)
  162. {
  163.   struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
  164.   struct my_cs_file_section_st *s= cs_file_sec(attr,len);
  165.   
  166.   if ( s && (s->state == _CS_CHARSET))
  167.     bzero(&i->cs,sizeof(i->cs));
  168.   
  169.   if (s && (s->state == _CS_COLLATION))
  170.     i->tailoring_length= 0;
  171.   return MY_XML_OK;
  172. }
  173. static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len)
  174. {
  175.   struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
  176.   struct my_cs_file_section_st *s= cs_file_sec(attr,len);
  177.   int    state= s ? s->state : 0;
  178.   int    rc;
  179.   
  180.   switch(state){
  181.   case _CS_COLLATION:
  182.     rc= i->add_collation ? i->add_collation(&i->cs) : MY_XML_OK;
  183.     break;
  184.   default:
  185.     rc=MY_XML_OK;
  186.   }
  187.   return rc;
  188. }
  189. static int cs_value(MY_XML_PARSER *st,const char *attr, uint len)
  190. {
  191.   struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
  192.   struct my_cs_file_section_st *s;
  193.   int    state= (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0;
  194.   
  195. #ifndef DBUG_OFF
  196.   if(0){
  197.     char   str[1024];
  198.     mstr(str,attr,len,sizeof(str)-1);
  199.     printf("VALUE %d %s='%s'n",state,st->attr,str);
  200.   }
  201. #endif
  202.   
  203.   switch (state) {
  204.   case _CS_ID:
  205.     i->cs.number= strtol(attr,(char**)NULL,10);
  206.     break;
  207.   case _CS_BINARY_ID:
  208.     i->cs.binary_number= strtol(attr,(char**)NULL,10);
  209.     break;
  210.   case _CS_PRIMARY_ID:
  211.     i->cs.primary_number= strtol(attr,(char**)NULL,10);
  212.     break;
  213.   case _CS_COLNAME:
  214.     i->cs.name=mstr(i->name,attr,len,MY_CS_NAME_SIZE-1);
  215.     break;
  216.   case _CS_CSNAME:
  217.     i->cs.csname=mstr(i->csname,attr,len,MY_CS_NAME_SIZE-1);
  218.     break;
  219.   case _CS_CSDESCRIPT:
  220.     i->cs.comment=mstr(i->comment,attr,len,MY_CS_CSDESCR_SIZE-1);
  221.     break;
  222.   case _CS_FLAG:
  223.     if (!strncmp("primary",attr,len))
  224.       i->cs.state|= MY_CS_PRIMARY;
  225.     else if (!strncmp("binary",attr,len))
  226.       i->cs.state|= MY_CS_BINSORT;
  227.     else if (!strncmp("compiled",attr,len))
  228.       i->cs.state|= MY_CS_COMPILED;
  229.     break;
  230.   case _CS_UPPERMAP:
  231.     fill_uchar(i->to_upper,MY_CS_TO_UPPER_TABLE_SIZE,attr,len);
  232.     i->cs.to_upper=i->to_upper;
  233.     break;
  234.   case _CS_LOWERMAP:
  235.     fill_uchar(i->to_lower,MY_CS_TO_LOWER_TABLE_SIZE,attr,len);
  236.     i->cs.to_lower=i->to_lower;
  237.     break;
  238.   case _CS_UNIMAP:
  239.     fill_uint16(i->tab_to_uni,MY_CS_TO_UNI_TABLE_SIZE,attr,len);
  240.     i->cs.tab_to_uni=i->tab_to_uni;
  241.     break;
  242.   case _CS_COLLMAP:
  243.     fill_uchar(i->sort_order,MY_CS_SORT_ORDER_TABLE_SIZE,attr,len);
  244.     i->cs.sort_order=i->sort_order;
  245.     break;
  246.   case _CS_CTYPEMAP:
  247.     fill_uchar(i->ctype,MY_CS_CTYPE_TABLE_SIZE,attr,len);
  248.     i->cs.ctype=i->ctype;
  249.     break;
  250.   case _CS_RESET:
  251.   case _CS_DIFF1:
  252.   case _CS_DIFF2:
  253.   case _CS_DIFF3:
  254.     {
  255.       /*
  256.         Convert collation description from
  257.         Locale Data Markup Language (LDML)
  258.         into ICU Collation Customization expression.
  259.       */
  260.       char arg[16];
  261.       const char *cmd[]= {"&","<","<<","<<<"};
  262.       i->cs.tailoring= i->tailoring;
  263.       mstr(arg,attr,len,sizeof(arg)-1);
  264.       if (i->tailoring_length + 20 < sizeof(i->tailoring))
  265.       {
  266.         char *dst= i->tailoring_length + i->tailoring;
  267.         i->tailoring_length+= sprintf(dst," %s %s",cmd[state-_CS_RESET],arg);
  268.       }
  269.     }
  270.   }
  271.   return MY_XML_OK;
  272. }
  273. my_bool my_parse_charset_xml(const char *buf, uint len, 
  274.     int (*add_collation)(CHARSET_INFO *cs))
  275. {
  276.   MY_XML_PARSER p;
  277.   struct my_cs_file_info i;
  278.   my_bool rc;
  279.   
  280.   my_xml_parser_create(&p);
  281.   my_xml_set_enter_handler(&p,cs_enter);
  282.   my_xml_set_value_handler(&p,cs_value);
  283.   my_xml_set_leave_handler(&p,cs_leave);
  284.   i.add_collation= add_collation;
  285.   my_xml_set_user_data(&p,(void*)&i);
  286.   rc= (my_xml_parse(&p,buf,len) == MY_XML_OK) ? FALSE : TRUE;
  287.   my_xml_parser_free(&p);
  288.   return rc;
  289. }