~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/charset.cc

  • Committer: devananda
  • Date: 2009-07-01 17:38:47 UTC
  • mto: (1093.1.7 captain)
  • mto: This revision was merged to the branch mainline in revision 1095.
  • Revision ID: devananda.vdv@gmail.com-20090701173847-3n3mbtessg5ff35e
refactored function/benchmark into plugin/benchmark

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
#include <config.h>
17
 
 
18
 
#include <drizzled/charset.h>
19
 
#include <drizzled/error.h>
20
 
#include <drizzled/charset_info.h>
21
 
#include <drizzled/internal/m_string.h>
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include "mysys/mysys_priv.h"
 
17
#include "mysys/mysys_err.h"
 
18
#include <mystrings/m_ctype.h>
 
19
#include <mystrings/m_string.h>
22
20
#include <drizzled/configmake.h>
23
 
#include <vector>
24
 
 
25
 
#include <drizzled/visibility.h>
26
 
 
27
 
using namespace std;
28
 
 
29
 
namespace drizzled
30
 
{
31
 
 
32
 
/*
33
 
  We collect memory in this vector that we free on delete.
34
 
*/
35
 
static vector<unsigned char*> memory_vector;
 
21
 
36
22
 
37
23
/*
38
24
  The code below implements this functionality:
53
39
static uint
54
40
get_collation_number_internal(const char *name)
55
41
{
56
 
  for (CHARSET_INFO **cs= all_charsets;
57
 
       cs < all_charsets+array_elements(all_charsets)-1;
 
42
  CHARSET_INFO **cs;
 
43
  for (cs= all_charsets;
 
44
       cs < all_charsets+array_elements(all_charsets)-1 ;
58
45
       cs++)
59
46
  {
60
 
    if ( cs[0] && cs[0]->name && !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
61
 
    {
 
47
    if ( cs[0] && cs[0]->name &&
 
48
         !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
62
49
      return cs[0]->number;
63
 
    }
64
50
  }
65
51
  return 0;
66
52
}
67
53
 
68
 
static unsigned char *cs_alloc(size_t size)
69
 
{
70
 
  memory_vector.push_back(new unsigned char[size]);
71
 
  return memory_vector.back();
72
 
}
73
54
 
74
55
static bool init_state_maps(CHARSET_INFO *cs)
75
56
{
76
 
  if (!(cs->state_map= cs_alloc(256)))
 
57
  uint32_t i;
 
58
  unsigned char *state_map;
 
59
  unsigned char *ident_map;
 
60
 
 
61
  if (!(cs->state_map= (unsigned char*) malloc(256)))
77
62
    return 1;
78
63
    
79
 
  if (!(cs->ident_map= cs_alloc(256)))
 
64
  if (!(cs->ident_map= (unsigned char*) malloc(256)))
80
65
    return 1;
81
66
 
82
 
  unsigned char *state_map= cs->state_map;
83
 
  unsigned char *ident_map= cs->ident_map;
 
67
  state_map= cs->state_map;
 
68
  ident_map= cs->ident_map;
84
69
 
85
70
  /* Fill state_map with states to get a faster parser */
86
 
  for (int i= 0; i < 256; i++)
 
71
  for (i=0; i < 256 ; i++)
87
72
  {
88
73
    if (my_isalpha(cs,i))
89
 
      state_map[i]= MY_LEX_IDENT;
 
74
      state_map[i]=(unsigned char) MY_LEX_IDENT;
90
75
    else if (my_isdigit(cs,i))
91
 
      state_map[i]= MY_LEX_NUMBER_IDENT;
 
76
      state_map[i]=(unsigned char) MY_LEX_NUMBER_IDENT;
 
77
#if defined(USE_MB) && defined(USE_MB_IDENT)
92
78
    else if (my_mbcharlen(cs, i)>1)
93
 
      state_map[i]= MY_LEX_IDENT;
 
79
      state_map[i]=(unsigned char) MY_LEX_IDENT;
 
80
#endif
94
81
    else if (my_isspace(cs,i))
95
 
      state_map[i]= MY_LEX_SKIP;
 
82
      state_map[i]=(unsigned char) MY_LEX_SKIP;
96
83
    else
97
 
      state_map[i]= MY_LEX_CHAR;
 
84
      state_map[i]=(unsigned char) MY_LEX_CHAR;
98
85
  }
99
 
  state_map['_']=state_map['$']= MY_LEX_IDENT;
100
 
  state_map['\'']= MY_LEX_STRING;
101
 
  state_map['.']= MY_LEX_REAL_OR_POINT;
102
 
  state_map['>']=state_map['=']=state_map['!']=  MY_LEX_CMP_OP;
103
 
  state_map['<']=  MY_LEX_LONG_CMP_OP;
104
 
  state_map['&']=state_map['|']= MY_LEX_BOOL;
105
 
  state_map['#']= MY_LEX_COMMENT;
106
 
  state_map[';']= MY_LEX_SEMICOLON;
107
 
  state_map[':']= MY_LEX_SET_VAR;
108
 
  state_map[0]= MY_LEX_EOL;
109
 
  state_map['\\']=  MY_LEX_ESCAPE;
110
 
  state_map['/']=  MY_LEX_LONG_COMMENT;
111
 
  state_map['*']=  MY_LEX_END_LONG_COMMENT;
112
 
  state_map['@']=  MY_LEX_USER_END;
113
 
  state_map['`']=  MY_LEX_USER_VARIABLE_DELIMITER;
114
 
  state_map['"']=  MY_LEX_STRING_OR_DELIMITER;
 
86
  state_map[(unsigned char)'_']=state_map[(unsigned char)'$']=(unsigned char) MY_LEX_IDENT;
 
87
  state_map[(unsigned char)'\'']=(unsigned char) MY_LEX_STRING;
 
88
  state_map[(unsigned char)'.']=(unsigned char) MY_LEX_REAL_OR_POINT;
 
89
  state_map[(unsigned char)'>']=state_map[(unsigned char)'=']=state_map[(unsigned char)'!']= (unsigned char) MY_LEX_CMP_OP;
 
90
  state_map[(unsigned char)'<']= (unsigned char) MY_LEX_LONG_CMP_OP;
 
91
  state_map[(unsigned char)'&']=state_map[(unsigned char)'|']=(unsigned char) MY_LEX_BOOL;
 
92
  state_map[(unsigned char)'#']=(unsigned char) MY_LEX_COMMENT;
 
93
  state_map[(unsigned char)';']=(unsigned char) MY_LEX_SEMICOLON;
 
94
  state_map[(unsigned char)':']=(unsigned char) MY_LEX_SET_VAR;
 
95
  state_map[0]=(unsigned char) MY_LEX_EOL;
 
96
  state_map[(unsigned char)'\\']= (unsigned char) MY_LEX_ESCAPE;
 
97
  state_map[(unsigned char)'/']= (unsigned char) MY_LEX_LONG_COMMENT;
 
98
  state_map[(unsigned char)'*']= (unsigned char) MY_LEX_END_LONG_COMMENT;
 
99
  state_map[(unsigned char)'@']= (unsigned char) MY_LEX_USER_END;
 
100
  state_map[(unsigned char) '`']= (unsigned char) MY_LEX_USER_VARIABLE_DELIMITER;
 
101
  state_map[(unsigned char)'"']= (unsigned char) MY_LEX_STRING_OR_DELIMITER;
115
102
 
116
103
  /*
117
104
    Create a second map to make it faster to find identifiers
118
105
  */
119
 
  for (int i= 0; i < 256; i++)
 
106
  for (i=0; i < 256 ; i++)
120
107
  {
121
 
    ident_map[i]= state_map[i] == MY_LEX_IDENT || state_map[i] == MY_LEX_NUMBER_IDENT;
 
108
    ident_map[i]= (unsigned char) (state_map[i] == MY_LEX_IDENT ||
 
109
                           state_map[i] == MY_LEX_NUMBER_IDENT);
122
110
  }
123
111
 
124
112
  /* Special handling of hex and binary strings */
125
 
  state_map['x']= state_map['X']=  MY_LEX_IDENT_OR_HEX;
126
 
  state_map['b']= state_map['B']=  MY_LEX_IDENT_OR_BIN;
 
113
  state_map[(unsigned char)'x']= state_map[(unsigned char)'X']= (unsigned char) MY_LEX_IDENT_OR_HEX;
 
114
  state_map[(unsigned char)'b']= state_map[(unsigned char)'B']= (unsigned char) MY_LEX_IDENT_OR_BIN;
127
115
  return 0;
128
116
}
129
117
 
 
118
 
130
119
static bool charset_initialized= false;
131
120
 
132
 
DRIZZLED_API CHARSET_INFO *all_charsets[256];
133
 
const DRIZZLED_API CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
 
121
CHARSET_INFO *all_charsets[256];
 
122
const CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
134
123
 
135
124
void add_compiled_collation(CHARSET_INFO * cs)
136
125
{
138
127
  cs->state|= MY_CS_AVAILABLE;
139
128
}
140
129
 
 
130
void *cs_alloc(size_t size)
 
131
{
 
132
  return malloc(size);
 
133
}
 
134
 
 
135
 
141
136
static bool init_available_charsets(myf myflags)
142
137
{
143
138
  bool error= false;
172
167
}
173
168
 
174
169
 
175
 
void free_charsets()
 
170
void free_charsets(void)
176
171
{
177
 
  charset_initialized= false;
178
 
 
179
 
  while (not memory_vector.empty())
180
 
  {
181
 
    delete[] memory_vector.back();
182
 
    memory_vector.pop_back();
183
 
  }
 
172
  charset_initialized= true;
184
173
}
185
174
 
186
175
 
200
189
       cs < all_charsets+array_elements(all_charsets)-1 ;
201
190
       cs++)
202
191
  {
203
 
    if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) && !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
 
192
    if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
 
193
         !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
204
194
      return cs[0]->number;
205
195
  }
206
196
  return 0;
209
199
 
210
200
const char *get_charset_name(uint32_t charset_number)
211
201
{
 
202
  const CHARSET_INFO *cs;
212
203
  init_available_charsets(MYF(0));
213
204
 
214
 
  const CHARSET_INFO *cs= all_charsets[charset_number];
 
205
  cs=all_charsets[charset_number];
215
206
  if (cs && (cs->number == charset_number) && cs->name )
216
 
    return cs->name;
 
207
    return (char*) cs->name;
217
208
 
218
 
  return "?";   /* this mimics find_type() */
 
209
  return (char*) "?";   /* this mimics find_type() */
219
210
}
220
211
 
221
212
 
322
313
  const char *to_start= to;
323
314
  const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
324
315
  bool overflow= false;
 
316
#ifdef USE_MB
325
317
  bool use_mb_flag= use_mb(charset_info);
 
318
#endif
326
319
  for (end= from + length; from < end; from++)
327
320
  {
 
321
#ifdef USE_MB
328
322
    int tmp_length;
329
323
    if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
330
324
    {
343
337
      turned into a multi-byte character by the addition of an escaping
344
338
      character, because we are only escaping the ' character with itself.
345
339
     */
 
340
#endif
346
341
    if (*from == '\'')
347
342
    {
348
343
      if (to + 2 > to_end)
364
359
    }
365
360
  }
366
361
  *to= 0;
367
 
  return overflow ? UINT32_MAX : to - to_start;
 
362
  return overflow ? UINT32_MAX : (uint32_t) (to - to_start);
368
363
}
369
 
 
370
 
} /* namespace drizzled */