Drizzled Public API Documentation

strfunc.cc

00001 /* Copyright (C) 2003 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 /* Some useful string utility functions used by the MySQL server */
00017 #include <config.h>
00018 
00019 #include <drizzled/typelib.h>
00020 #include <drizzled/charset_info.h>
00021 #include <drizzled/global_charset_info.h>
00022 
00023 namespace drizzled
00024 {
00025 
00026 /*
00027   Return bitmap for strings used in a set
00028 
00029   SYNOPSIS
00030   find_set()
00031   lib     Strings in set
00032   str     Strings of set-strings separated by ','
00033   err_pos   If error, set to point to start of wrong set string
00034   err_len   If error, set to the length of wrong set string
00035   set_warning   Set to 1 if some string in set couldn't be used
00036 
00037   NOTE
00038     We delete all end space from str before comparison
00039 
00040   RETURN
00041     bitmap of all sets found in x.
00042     set_warning is set to 1 if there was any sets that couldn't be set
00043 */
00044 
00045 static const char field_separator=',';
00046 
00047 uint64_t st_typelib::find_set(const char *str, uint32_t length,
00048                   const CHARSET_INFO * const cs,
00049                   char **err_pos, uint32_t *err_len, bool *set_warning) const
00050 {
00051   const CHARSET_INFO * const strip= cs ? cs : &my_charset_utf8_general_ci;
00052   const char *end= str + strip->cset->lengthsp(strip, str, length);
00053   uint64_t found= 0;
00054   *err_pos= 0;                  // No error yet
00055   if (str != end)
00056   {
00057     const char *start= str;
00058     for (;;)
00059     {
00060       const char *pos= start;
00061       uint32_t var_len;
00062       int mblen= 1;
00063 
00064       for (; pos != end && *pos != field_separator; pos++) 
00065       {}
00066       var_len= (uint32_t) (pos - start);
00067       uint32_t find= cs ? find_type2(start, var_len, cs) : find_type(start, var_len, false);
00068       if (!find)
00069       {
00070         *err_pos= (char*) start;
00071         *err_len= var_len;
00072         *set_warning= 1;
00073       }
00074       else
00075         found|= ((int64_t) 1 << (find - 1));
00076       if (pos >= end)
00077         break;
00078       start= pos + mblen;
00079     }
00080   }
00081   return found;
00082 }
00083 
00084 
00085 /*
00086   Function to find a string in a TYPELIB
00087   (Same format as mysys/typelib.c)
00088 
00089   SYNOPSIS
00090    find_type()
00091    lib      TYPELIB (struct of pointer to values + count)
00092    find     String to find
00093    length   Length of string to find
00094    part_match   Allow part matching of value
00095 
00096  RETURN
00097   0 error
00098   > 0 position in TYPELIB->type_names +1
00099 */
00100 
00101 uint32_t st_typelib::find_type(const char *find, uint32_t length, bool part_match) const
00102 {
00103   uint32_t found_count=0, found_pos=0;
00104   const char *end= find+length;
00105   const char *i;
00106   const char *j;
00107   for (uint32_t pos= 0 ; (j= type_names[pos++]) ; )
00108   {
00109     for (i=find ; i != end &&
00110      my_toupper(system_charset_info,*i) ==
00111      my_toupper(system_charset_info,*j) ; i++, j++) ;
00112     if (i == end)
00113     {
00114       if (! *j)
00115   return(pos);
00116       found_count++;
00117       found_pos= pos;
00118     }
00119   }
00120   return(found_count == 1 && part_match ? found_pos : 0);
00121 }
00122 
00123 
00124 /*
00125   Find a string in a list of strings according to collation
00126 
00127   SYNOPSIS
00128    find_type2()
00129    lib      TYPELIB (struct of pointer to values + count)
00130    x      String to find
00131    length               String length
00132    cs     Character set + collation to use for comparison
00133 
00134   NOTES
00135 
00136   RETURN
00137     0 No matching value
00138     >0  Offset+1 in typelib for matched string
00139 */
00140 
00141 uint32_t st_typelib::find_type2(const char *x, uint32_t length, const CHARSET_INFO *cs) const
00142 {
00143   if (!count)
00144     return 0;
00145   const char *j;
00146   for (int pos=0 ; (j= type_names[pos]) ; pos++)
00147   {
00148     if (!my_strnncoll(cs, (const unsigned char*) x, length,
00149                           (const unsigned char*) j, type_lengths[pos]))
00150       return pos + 1;
00151   }
00152   return 0;
00153 } /* find_type */
00154 
00155 } /* namespace drizzled */