~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/charset.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
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"
 
16
#include "mysys_priv.h"
 
17
#include "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
 
using namespace std;
26
 
 
27
 
namespace drizzled
28
 
{
29
 
 
30
 
/*
31
 
  We collect memory in this vector that we free on delete.
32
 
*/
33
 
static vector<void *>memory_vector;
 
21
 
34
22
 
35
23
/*
36
24
  The code below implements this functionality:
70
58
  unsigned char *state_map;
71
59
  unsigned char *ident_map;
72
60
 
73
 
  if (!(cs->state_map= (unsigned char*) cs_alloc(256)))
 
61
  if (!(cs->state_map= (unsigned char*) malloc(256)))
74
62
    return 1;
75
63
    
76
 
  if (!(cs->ident_map= (unsigned char*) cs_alloc(256)))
 
64
  if (!(cs->ident_map= (unsigned char*) malloc(256)))
77
65
    return 1;
78
66
 
79
67
  state_map= cs->state_map;
86
74
      state_map[i]=(unsigned char) MY_LEX_IDENT;
87
75
    else if (my_isdigit(cs,i))
88
76
      state_map[i]=(unsigned char) MY_LEX_NUMBER_IDENT;
 
77
#if defined(USE_MB) && defined(USE_MB_IDENT)
89
78
    else if (my_mbcharlen(cs, i)>1)
90
79
      state_map[i]=(unsigned char) MY_LEX_IDENT;
 
80
#endif
91
81
    else if (my_isspace(cs,i))
92
82
      state_map[i]=(unsigned char) MY_LEX_SKIP;
93
83
    else
139
129
 
140
130
void *cs_alloc(size_t size)
141
131
{
142
 
  void *ptr= malloc(size);
143
 
 
144
 
  memory_vector.push_back(ptr);
145
 
 
146
 
  return ptr;
 
132
  return malloc(size);
147
133
}
148
134
 
149
135
 
150
 
 
151
136
static bool init_available_charsets(myf myflags)
152
137
{
153
138
  bool error= false;
185
170
void free_charsets(void)
186
171
{
187
172
  charset_initialized= true;
188
 
 
189
 
  while (memory_vector.empty() == false)
190
 
  {
191
 
    void *ptr= memory_vector.back();
192
 
    memory_vector.pop_back();
193
 
    free(ptr);
194
 
  }
195
 
  memory_vector.clear();
196
 
 
197
173
}
198
174
 
199
175
 
284
260
  const CHARSET_INFO *cs;
285
261
  (void) init_available_charsets(MYF(0));       /* If it isn't initialized */
286
262
 
287
 
  cs_number= get_collation_number(cs_name);
 
263
  cs_number=get_collation_number(cs_name);
288
264
  cs= cs_number ? get_internal_charset(cs_number) : NULL;
289
265
 
290
266
  return cs;
305
281
}
306
282
 
307
283
 
 
284
/**
 
285
  Resolve character set by the character set name (utf8, latin1, ...).
 
286
 
 
287
  The function tries to resolve character set by the specified name. If
 
288
  there is character set with the given name, it is assigned to the "cs"
 
289
  parameter and false is returned. If there is no such character set,
 
290
  "default_cs" is assigned to the "cs" and true is returned.
 
291
 
 
292
  @param[in] cs_name    Character set name.
 
293
  @param[in] default_cs Default character set.
 
294
  @param[out] cs        Variable to store character set.
 
295
 
 
296
  @return false if character set was resolved successfully; true if there
 
297
  is no character set with given name.
 
298
*/
 
299
 
 
300
bool resolve_charset(const char *cs_name,
 
301
                     const CHARSET_INFO *default_cs,
 
302
                     const CHARSET_INFO **cs)
 
303
{
 
304
  *cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY);
 
305
 
 
306
  if (*cs == NULL)
 
307
  {
 
308
    *cs= default_cs;
 
309
    return true;
 
310
  }
 
311
 
 
312
  return false;
 
313
}
 
314
 
 
315
 
 
316
/**
 
317
  Resolve collation by the collation name (utf8_general_ci, ...).
 
318
 
 
319
  The function tries to resolve collation by the specified name. If there
 
320
  is collation with the given name, it is assigned to the "cl" parameter
 
321
  and false is returned. If there is no such collation, "default_cl" is
 
322
  assigned to the "cl" and true is returned.
 
323
 
 
324
  @param[out] cl        Variable to store collation.
 
325
  @param[in] cl_name    Collation name.
 
326
  @param[in] default_cl Default collation.
 
327
 
 
328
  @return false if collation was resolved successfully; true if there is no
 
329
  collation with given name.
 
330
*/
 
331
 
 
332
bool resolve_collation(const char *cl_name,
 
333
                       const CHARSET_INFO *default_cl,
 
334
                       const CHARSET_INFO **cl)
 
335
{
 
336
  *cl= get_charset_by_name(cl_name);
 
337
 
 
338
  if (*cl == NULL)
 
339
  {
 
340
    *cl= default_cl;
 
341
    return true;
 
342
  }
 
343
 
 
344
  return false;
 
345
}
 
346
 
 
347
 
 
348
#ifdef BACKSLASH_MBTAIL
 
349
static CHARSET_INFO *fs_cset_cache= NULL;
 
350
 
 
351
CHARSET_INFO *fs_character_set()
 
352
{
 
353
  if (!fs_cset_cache)
 
354
  {
 
355
    char buf[10]= "cp";
 
356
    GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
 
357
                  buf+2, sizeof(buf)-3);
 
358
    /*
 
359
      We cannot call get_charset_by_name here
 
360
      because fs_character_set() is executed before
 
361
      LOCK_THD_charset mutex initialization, which
 
362
      is used inside get_charset_by_name.
 
363
      As we're now interested in cp932 only,
 
364
      let's just detect it using strcmp().
 
365
    */
 
366
    fs_cset_cache= !strcmp(buf, "cp932") ?
 
367
                   &my_charset_cp932_japanese_ci : &my_charset_bin;
 
368
  }
 
369
  return fs_cset_cache;
 
370
}
 
371
#endif
 
372
 
308
373
/*
309
374
  Escape apostrophes by doubling them up
310
375
 
337
402
  const char *to_start= to;
338
403
  const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
339
404
  bool overflow= false;
 
405
#ifdef USE_MB
340
406
  bool use_mb_flag= use_mb(charset_info);
 
407
#endif
341
408
  for (end= from + length; from < end; from++)
342
409
  {
 
410
#ifdef USE_MB
343
411
    int tmp_length;
344
412
    if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
345
413
    {
358
426
      turned into a multi-byte character by the addition of an escaping
359
427
      character, because we are only escaping the ' character with itself.
360
428
     */
 
429
#endif
361
430
    if (*from == '\'')
362
431
    {
363
432
      if (to + 2 > to_end)
381
450
  *to= 0;
382
451
  return overflow ? UINT32_MAX : (uint32_t) (to - to_start);
383
452
}
384
 
 
385
 
} /* namespace drizzled */