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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 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. /* Some useful string utility functions used by the MySQL server */
  14. #include "mysql_priv.h"
  15. /*
  16.   Return bitmap for strings used in a set
  17.   SYNOPSIS
  18.   find_set()
  19.   lib Strings in set
  20.   str Strings of set-strings separated by ','
  21.   err_pos If error, set to point to start of wrong set string
  22.   err_len If error, set to the length of wrong set string
  23.   set_warning Set to 1 if some string in set couldn't be used
  24.   NOTE
  25.     We delete all end space from str before comparison
  26.   RETURN
  27.     bitmap of all sets found in x.
  28.     set_warning is set to 1 if there was any sets that couldn't be set
  29. */
  30. static const char field_separator=',';
  31. ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
  32.                    char **err_pos, uint *err_len, bool *set_warning)
  33. {
  34.   CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
  35.   const char *end= str + strip->cset->lengthsp(strip, str, length);
  36.   ulonglong found= 0;
  37.   *err_pos= 0;                  // No error yet
  38.   if (str != end)
  39.   {
  40.     const char *start= str;    
  41.     for (;;)
  42.     {
  43.       const char *pos= start;
  44.       uint var_len;
  45.       int mblen= 1;
  46.       if (cs && cs->mbminlen > 1)
  47.       {
  48.         for ( ; pos < end; pos+= mblen)
  49.         {
  50.           my_wc_t wc;
  51.           if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) pos, 
  52.                                                (const uchar *) end)) < 1)
  53.             mblen= 1; // Not to hang on a wrong multibyte sequence
  54.           if (wc == (my_wc_t) field_separator)
  55.             break;
  56.         }
  57.       }
  58.       else
  59.         for (; pos != end && *pos != field_separator; pos++) ;
  60.       var_len= (uint) (pos - start);
  61.       uint find= cs ? find_type2(lib, start, var_len, cs) :
  62.                       find_type(lib, start, var_len, (bool) 0);
  63.       if (!find)
  64.       {
  65.         *err_pos= (char*) start;
  66.         *err_len= var_len;
  67.         *set_warning= 1;
  68.       }
  69.       else
  70.         found|= ((longlong) 1 << (find - 1));
  71.       if (pos >= end)
  72.         break;
  73.       start= pos + mblen;
  74.     }
  75.   }
  76.   return found;
  77. }
  78. /*
  79.   Function to find a string in a TYPELIB
  80.   (Same format as mysys/typelib.c)
  81.   SYNOPSIS
  82.    find_type()
  83.    lib TYPELIB (struct of pointer to values + count)
  84.    find String to find
  85.    length Length of string to find
  86.    part_match Allow part matching of value
  87.  RETURN
  88.   0 error
  89.   > 0 position in TYPELIB->type_names +1
  90. */
  91. uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match)
  92. {
  93.   uint found_count=0, found_pos=0;
  94.   const char *end= find+length;
  95.   const char *i;
  96.   const char *j;
  97.   for (uint pos=0 ; (j=lib->type_names[pos++]) ; )
  98.   {
  99.     for (i=find ; i != end && 
  100.    my_toupper(system_charset_info,*i) == 
  101.    my_toupper(system_charset_info,*j) ; i++, j++) ;
  102.     if (i == end)
  103.     {
  104.       if (! *j)
  105. return(pos);
  106.       found_count++;
  107.       found_pos= pos;
  108.     }
  109.   }
  110.   return(found_count == 1 && part_match ? found_pos : 0);
  111. }
  112. /*
  113.   Find a string in a list of strings according to collation
  114.   SYNOPSIS
  115.    find_type2()
  116.    lib TYPELIB (struct of pointer to values + count)
  117.    x String to find
  118.    length               String length
  119.    cs Character set + collation to use for comparison
  120.   NOTES
  121.   RETURN
  122.     0 No matching value
  123.     >0  Offset+1 in typelib for matched string
  124. */
  125. uint find_type2(TYPELIB *typelib, const char *x, uint length, CHARSET_INFO *cs)
  126. {
  127.   int find,pos;
  128.   const char *j;
  129.   DBUG_ENTER("find_type2");
  130.   DBUG_PRINT("enter",("x: '%s'  lib: 0x%lx",x,typelib));
  131.   if (!typelib->count)
  132.   {
  133.     DBUG_PRINT("exit",("no count"));
  134.     DBUG_RETURN(0);
  135.   }
  136.   for (find=0, pos=0 ; (j=typelib->type_names[pos]) ; pos++)
  137.   {
  138.     if (!my_strnncoll(cs, (const uchar*) x, length,
  139.                           (const uchar*) j, typelib->type_lengths[pos]))
  140.       DBUG_RETURN(pos+1);
  141.   }
  142.   DBUG_PRINT("exit",("Couldn't find type"));
  143.   DBUG_RETURN(0);
  144. } /* find_type */
  145. /*
  146.   Un-hex all elements in a typelib
  147.   SYNOPSIS
  148.    unhex_type2()
  149.    interval       TYPELIB (struct of pointer to values + lengths + count)
  150.   NOTES
  151.   RETURN
  152.     N/A
  153. */
  154. void unhex_type2(TYPELIB *interval)
  155. {
  156.   for (uint pos= 0; pos < interval->count; pos++)
  157.   {
  158.     char *from, *to;
  159.     for (from= to= (char*) interval->type_names[pos]; *from; )
  160.     {
  161.       /*
  162.         Note, hexchar_to_int(*from++) doesn't work
  163.         one some compilers, e.g. IRIX. Looks like a compiler
  164.         bug in inline functions in combination with arguments
  165.         that have a side effect. So, let's use from[0] and from[1]
  166.         and increment 'from' by two later.
  167.       */
  168.       *to++= (char) (hexchar_to_int(from[0]) << 4) +
  169.                      hexchar_to_int(from[1]);
  170.       from+= 2;
  171.     }
  172.     interval->type_lengths[pos] /= 2;
  173.   }
  174. }
  175. /*
  176.   Check if the first word in a string is one of the ones in TYPELIB
  177.   SYNOPSIS
  178.     check_word()
  179.     lib TYPELIB
  180.     val String to check
  181.     end End of input
  182.     end_of_word Store value of last used byte here if we found word
  183.   RETURN
  184.     0  No matching value
  185.     > 1  lib->type_names[#-1] matched
  186.  end_of_word will point to separator character/end in 'val'
  187. */
  188. uint check_word(TYPELIB *lib, const char *val, const char *end,
  189. const char **end_of_word)
  190. {
  191.   int res;
  192.   const char *ptr;
  193.   /* Fiend end of word */
  194.   for (ptr= val ; ptr < end && my_isalpha(&my_charset_latin1, *ptr) ; ptr++)
  195.     ;
  196.   if ((res=find_type(lib, val, (uint) (ptr - val), 1)) > 0)
  197.     *end_of_word= ptr;
  198.   return res;
  199. }