~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/charset.cc

  • Committer: patrick crews
  • Date: 2011-06-08 03:02:27 UTC
  • mto: This revision was merged to the branch mainline in revision 2329.
  • Revision ID: gleebix@gmail.com-20110608030227-updkyv2652zvfajc
Initial voodoo worked to give us a crashme mode.  Need docs still

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
 
#include "config.h"
 
16
#include <config.h>
17
17
 
18
 
#include "drizzled/charset.h"
19
 
#include "drizzled/error.h"
20
 
#include "drizzled/charset_info.h"
21
 
#include "drizzled/internal/m_string.h"
 
18
#include <drizzled/charset.h>
 
19
#include <drizzled/error.h>
 
20
#include <drizzled/internal/m_string.h>
22
21
#include <drizzled/configmake.h>
23
22
#include <vector>
24
23
 
 
24
#include <drizzled/visibility.h>
 
25
 
25
26
using namespace std;
26
27
 
27
28
namespace drizzled
30
31
/*
31
32
  We collect memory in this vector that we free on delete.
32
33
*/
33
 
static vector<void *>memory_vector;
 
34
static vector<unsigned char*> memory_vector;
34
35
 
35
36
/*
36
37
  The code below implements this functionality:
37
38
 
38
39
    - Initializing charset related structures
39
40
    - Loading dynamic charsets
40
 
    - Searching for a proper CHARSET_INFO
 
41
    - Searching for a proper charset_info_st
41
42
      using charset name, collation name or collation ID
42
43
    - Setting server default character set
43
44
*/
44
45
 
45
 
bool my_charset_same(const CHARSET_INFO *cs1, const CHARSET_INFO *cs2)
 
46
bool my_charset_same(const charset_info_st *cs1, const charset_info_st *cs2)
46
47
{
47
48
  return ((cs1 == cs2) || !strcmp(cs1->csname,cs2->csname));
48
49
}
51
52
static uint
52
53
get_collation_number_internal(const char *name)
53
54
{
54
 
  CHARSET_INFO **cs;
55
 
  for (cs= all_charsets;
56
 
       cs < all_charsets+array_elements(all_charsets)-1 ;
 
55
  for (charset_info_st **cs= all_charsets;
 
56
       cs < all_charsets+array_elements(all_charsets)-1;
57
57
       cs++)
58
58
  {
59
 
    if ( cs[0] && cs[0]->name &&
60
 
         !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
 
59
    if ( cs[0] && cs[0]->name && !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
 
60
    {
61
61
      return cs[0]->number;
 
62
    }
62
63
  }
63
64
  return 0;
64
65
}
65
66
 
66
 
 
67
 
static bool init_state_maps(CHARSET_INFO *cs)
68
 
{
69
 
  uint32_t i;
70
 
  unsigned char *state_map;
71
 
  unsigned char *ident_map;
72
 
 
73
 
  if (!(cs->state_map= (unsigned char*) cs_alloc(256)))
 
67
static unsigned char *cs_alloc(size_t size)
 
68
{
 
69
  memory_vector.push_back(new unsigned char[size]);
 
70
  return memory_vector.back();
 
71
}
 
72
 
 
73
static bool init_state_maps(charset_info_st *cs)
 
74
{
 
75
  if (!(cs->state_map= cs_alloc(256)))
74
76
    return 1;
75
77
    
76
 
  if (!(cs->ident_map= (unsigned char*) cs_alloc(256)))
 
78
  if (!(cs->ident_map= cs_alloc(256)))
77
79
    return 1;
78
80
 
79
 
  state_map= cs->state_map;
80
 
  ident_map= cs->ident_map;
 
81
  unsigned char *state_map= cs->state_map;
 
82
  unsigned char *ident_map= cs->ident_map;
81
83
 
82
84
  /* Fill state_map with states to get a faster parser */
83
 
  for (i=0; i < 256 ; i++)
 
85
  for (int i= 0; i < 256; i++)
84
86
  {
85
87
    if (my_isalpha(cs,i))
86
 
      state_map[i]=(unsigned char) MY_LEX_IDENT;
 
88
      state_map[i]= MY_LEX_IDENT;
87
89
    else if (my_isdigit(cs,i))
88
 
      state_map[i]=(unsigned char) MY_LEX_NUMBER_IDENT;
 
90
      state_map[i]= MY_LEX_NUMBER_IDENT;
89
91
    else if (my_mbcharlen(cs, i)>1)
90
 
      state_map[i]=(unsigned char) MY_LEX_IDENT;
 
92
      state_map[i]= MY_LEX_IDENT;
91
93
    else if (my_isspace(cs,i))
92
 
      state_map[i]=(unsigned char) MY_LEX_SKIP;
 
94
      state_map[i]= MY_LEX_SKIP;
93
95
    else
94
 
      state_map[i]=(unsigned char) MY_LEX_CHAR;
 
96
      state_map[i]= MY_LEX_CHAR;
95
97
  }
96
 
  state_map[(unsigned char)'_']=state_map[(unsigned char)'$']=(unsigned char) MY_LEX_IDENT;
97
 
  state_map[(unsigned char)'\'']=(unsigned char) MY_LEX_STRING;
98
 
  state_map[(unsigned char)'.']=(unsigned char) MY_LEX_REAL_OR_POINT;
99
 
  state_map[(unsigned char)'>']=state_map[(unsigned char)'=']=state_map[(unsigned char)'!']= (unsigned char) MY_LEX_CMP_OP;
100
 
  state_map[(unsigned char)'<']= (unsigned char) MY_LEX_LONG_CMP_OP;
101
 
  state_map[(unsigned char)'&']=state_map[(unsigned char)'|']=(unsigned char) MY_LEX_BOOL;
102
 
  state_map[(unsigned char)'#']=(unsigned char) MY_LEX_COMMENT;
103
 
  state_map[(unsigned char)';']=(unsigned char) MY_LEX_SEMICOLON;
104
 
  state_map[(unsigned char)':']=(unsigned char) MY_LEX_SET_VAR;
105
 
  state_map[0]=(unsigned char) MY_LEX_EOL;
106
 
  state_map[(unsigned char)'\\']= (unsigned char) MY_LEX_ESCAPE;
107
 
  state_map[(unsigned char)'/']= (unsigned char) MY_LEX_LONG_COMMENT;
108
 
  state_map[(unsigned char)'*']= (unsigned char) MY_LEX_END_LONG_COMMENT;
109
 
  state_map[(unsigned char)'@']= (unsigned char) MY_LEX_USER_END;
110
 
  state_map[(unsigned char) '`']= (unsigned char) MY_LEX_USER_VARIABLE_DELIMITER;
111
 
  state_map[(unsigned char)'"']= (unsigned char) MY_LEX_STRING_OR_DELIMITER;
 
98
  state_map['_']=state_map['$']= MY_LEX_IDENT;
 
99
  state_map['\'']= MY_LEX_STRING;
 
100
  state_map['.']= MY_LEX_REAL_OR_POINT;
 
101
  state_map['>']=state_map['=']=state_map['!']=  MY_LEX_CMP_OP;
 
102
  state_map['<']=  MY_LEX_LONG_CMP_OP;
 
103
  state_map['&']=state_map['|']= MY_LEX_BOOL;
 
104
  state_map['#']= MY_LEX_COMMENT;
 
105
  state_map[';']= MY_LEX_SEMICOLON;
 
106
  state_map[':']= MY_LEX_SET_VAR;
 
107
  state_map[0]= MY_LEX_EOL;
 
108
  state_map['\\']=  MY_LEX_ESCAPE;
 
109
  state_map['/']=  MY_LEX_LONG_COMMENT;
 
110
  state_map['*']=  MY_LEX_END_LONG_COMMENT;
 
111
  state_map['@']=  MY_LEX_USER_END;
 
112
  state_map['`']=  MY_LEX_USER_VARIABLE_DELIMITER;
 
113
  state_map['"']=  MY_LEX_STRING_OR_DELIMITER;
112
114
 
113
115
  /*
114
116
    Create a second map to make it faster to find identifiers
115
117
  */
116
 
  for (i=0; i < 256 ; i++)
 
118
  for (int i= 0; i < 256; i++)
117
119
  {
118
 
    ident_map[i]= (unsigned char) (state_map[i] == MY_LEX_IDENT ||
119
 
                           state_map[i] == MY_LEX_NUMBER_IDENT);
 
120
    ident_map[i]= state_map[i] == MY_LEX_IDENT || state_map[i] == MY_LEX_NUMBER_IDENT;
120
121
  }
121
122
 
122
123
  /* Special handling of hex and binary strings */
123
 
  state_map[(unsigned char)'x']= state_map[(unsigned char)'X']= (unsigned char) MY_LEX_IDENT_OR_HEX;
124
 
  state_map[(unsigned char)'b']= state_map[(unsigned char)'B']= (unsigned char) MY_LEX_IDENT_OR_BIN;
 
124
  state_map['x']= state_map['X']=  MY_LEX_IDENT_OR_HEX;
 
125
  state_map['b']= state_map['B']=  MY_LEX_IDENT_OR_BIN;
125
126
  return 0;
126
127
}
127
128
 
128
 
 
129
129
static bool charset_initialized= false;
130
130
 
131
 
CHARSET_INFO *all_charsets[256];
132
 
const CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
 
131
DRIZZLED_API charset_info_st *all_charsets[256];
 
132
const DRIZZLED_API charset_info_st *default_charset_info = &my_charset_utf8_general_ci;
133
133
 
134
 
void add_compiled_collation(CHARSET_INFO * cs)
 
134
void add_compiled_collation(charset_info_st * cs)
135
135
{
136
136
  all_charsets[cs->number]= cs;
137
137
  cs->state|= MY_CS_AVAILABLE;
138
138
}
139
139
 
140
 
void *cs_alloc(size_t size)
141
 
{
142
 
  void *ptr= malloc(size);
143
 
 
144
 
  memory_vector.push_back(ptr);
145
 
 
146
 
  return ptr;
147
 
}
148
 
 
149
 
 
150
 
 
151
140
static bool init_available_charsets(myf myflags)
152
141
{
153
142
  bool error= false;
157
146
  */
158
147
  if (charset_initialized == false)
159
148
  {
160
 
    CHARSET_INFO **cs;
 
149
    charset_info_st **cs;
161
150
    memset(&all_charsets, 0, sizeof(all_charsets));
162
151
    init_compiled_charsets(myflags);
163
152
 
182
171
}
183
172
 
184
173
 
185
 
void free_charsets(void)
 
174
void free_charsets()
186
175
{
187
 
  charset_initialized= true;
 
176
  charset_initialized= false;
188
177
 
189
 
  while (memory_vector.empty() == false)
 
178
  while (not memory_vector.empty())
190
179
  {
191
 
    void *ptr= memory_vector.back();
 
180
    delete[] memory_vector.back();
192
181
    memory_vector.pop_back();
193
 
    free(ptr);
194
182
  }
195
 
  memory_vector.clear();
196
 
 
197
183
}
198
184
 
199
185
 
206
192
 
207
193
uint32_t get_charset_number(const char *charset_name, uint32_t cs_flags)
208
194
{
209
 
  CHARSET_INFO **cs;
 
195
  charset_info_st **cs;
210
196
  init_available_charsets(MYF(0));
211
197
 
212
198
  for (cs= all_charsets;
213
199
       cs < all_charsets+array_elements(all_charsets)-1 ;
214
200
       cs++)
215
201
  {
216
 
    if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
217
 
         !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
 
202
    if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) && !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
218
203
      return cs[0]->number;
219
204
  }
220
205
  return 0;
223
208
 
224
209
const char *get_charset_name(uint32_t charset_number)
225
210
{
226
 
  const CHARSET_INFO *cs;
227
211
  init_available_charsets(MYF(0));
228
212
 
229
 
  cs=all_charsets[charset_number];
 
213
  const charset_info_st *cs= all_charsets[charset_number];
230
214
  if (cs && (cs->number == charset_number) && cs->name )
231
 
    return (char*) cs->name;
 
215
    return cs->name;
232
216
 
233
 
  return (char*) "?";   /* this mimics find_type() */
 
217
  return "?";   /* this mimics find_type() */
234
218
}
235
219
 
236
220
 
237
 
static const CHARSET_INFO *get_internal_charset(uint32_t cs_number)
 
221
static const charset_info_st *get_internal_charset(uint32_t cs_number)
238
222
{
239
 
  CHARSET_INFO *cs;
 
223
  charset_info_st *cs;
240
224
  /*
241
225
    To make things thread safe we are not allowing other threads to interfere
242
226
    while we may changing the cs_info_table
262
246
}
263
247
 
264
248
 
265
 
const CHARSET_INFO *get_charset(uint32_t cs_number)
 
249
const charset_info_st *get_charset(uint32_t cs_number)
266
250
{
267
 
  const CHARSET_INFO *cs;
 
251
  const charset_info_st *cs;
268
252
  if (cs_number == default_charset_info->number)
269
253
    return default_charset_info;
270
254
 
278
262
  return cs;
279
263
}
280
264
 
281
 
const CHARSET_INFO *get_charset_by_name(const char *cs_name)
 
265
const charset_info_st *get_charset_by_name(const char *cs_name)
282
266
{
283
267
  uint32_t cs_number;
284
 
  const CHARSET_INFO *cs;
 
268
  const charset_info_st *cs;
285
269
  (void) init_available_charsets(MYF(0));       /* If it isn't initialized */
286
270
 
287
271
  cs_number= get_collation_number(cs_name);
291
275
}
292
276
 
293
277
 
294
 
const CHARSET_INFO *get_charset_by_csname(const char *cs_name, uint32_t cs_flags)
 
278
const charset_info_st *get_charset_by_csname(const char *cs_name, uint32_t cs_flags)
295
279
{
296
280
  uint32_t cs_number;
297
 
  const CHARSET_INFO *cs;
 
281
  const charset_info_st *cs;
298
282
 
299
283
  (void) init_available_charsets(MYF(0));       /* If it isn't initialized */
300
284
 
330
314
    >=0         The length of the escaped string
331
315
*/
332
316
 
333
 
size_t escape_quotes_for_drizzle(const CHARSET_INFO *charset_info,
 
317
size_t escape_quotes_for_drizzle(const charset_info_st *charset_info,
334
318
                                 char *to, size_t to_length,
335
319
                                 const char *from, size_t length)
336
320
{
379
363
    }
380
364
  }
381
365
  *to= 0;
382
 
  return overflow ? UINT32_MAX : (uint32_t) (to - to_start);
 
366
  return overflow ? UINT32_MAX : to - to_start;
383
367
}
384
368
 
385
369
} /* namespace drizzled */