~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

  • Committer: Olaf van der Spek
  • Date: 2011-07-04 19:11:47 UTC
  • mto: This revision was merged to the branch mainline in revision 2367.
  • Revision ID: olafvdspek@gmail.com-20110704191147-s99ojek811zi1fzj
Remove unused Name_resolution_context::error_reporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* This file is originally from the mysql distribution. Coded by monty */
17
17
 
18
 
#include "config.h"
 
18
#include <config.h>
19
19
 
20
 
#include "drizzled/internal/my_sys.h"
21
 
#include "drizzled/internal/m_string.h"
22
 
#include "drizzled/charset.h"
23
 
#include "drizzled/global_charset_info.h"
 
20
#include <drizzled/definitions.h>
 
21
#include <drizzled/internal/my_sys.h>
 
22
#include <drizzled/internal/m_string.h>
 
23
#include <drizzled/memory/root.h>
 
24
#include <drizzled/charset.h>
24
25
 
25
26
#include <algorithm>
26
27
 
27
 
#include "drizzled/sql_string.h"
 
28
#include <drizzled/sql_string.h>
28
29
 
29
30
using namespace std;
30
31
 
31
 
namespace drizzled
32
 
{
33
 
 
34
 
// Converstion functions to and from std::string.
35
 
 
36
 
std::string String_to_std_string(String const& s)
37
 
{
38
 
   return std::string(s.ptr(), s.length());
39
 
}
40
 
 
41
 
String* set_String_from_std_string(String* s, std::string const& cs)
42
 
{
43
 
   s->set_ascii(cs.c_str(), cs.length());
44
 
   s->copy();
45
 
   return s;
46
 
}
 
32
namespace drizzled {
47
33
 
48
34
/*****************************************************************************
49
35
** String functions
68
54
  (void) real_alloc(length_arg);
69
55
}
70
56
 
71
 
String::String(const char *str, const CHARSET_INFO * const cs)
 
57
String::String(const char *str, const charset_info_st * const cs)
72
58
  : Ptr(const_cast<char *>(str)),
73
59
    str_length(static_cast<size_t>(strlen(str))),
74
60
    Alloced_length(0),
77
63
{ }
78
64
 
79
65
 
80
 
String::String(const char *str, size_t len, const CHARSET_INFO * const cs)
 
66
String::String(const char *str, size_t len, const charset_info_st * const cs)
81
67
  : Ptr(const_cast<char *>(str)),
82
68
    str_length(len),
83
69
    Alloced_length(0),
86
72
{ }
87
73
 
88
74
 
89
 
String::String(char *str, size_t len, const CHARSET_INFO * const cs)
 
75
String::String(char *str, size_t len, const charset_info_st * const cs)
90
76
  : Ptr(str),
91
77
    str_length(len),
92
78
    Alloced_length(len),
106
92
 
107
93
void *String::operator new(size_t size, memory::Root *mem_root)
108
94
{
109
 
  return mem_root->alloc_root(static_cast<size_t>(size));
 
95
  return mem_root->alloc(size);
110
96
}
111
97
 
112
98
String::~String() { free(); }
113
99
 
114
 
bool String::real_alloc(size_t arg_length)
 
100
void String::real_alloc(size_t arg_length)
115
101
{
116
102
  arg_length=ALIGN_SIZE(arg_length+1);
117
103
  str_length=0;
119
105
  {
120
106
    if (Alloced_length > 0)
121
107
      free();
122
 
    if (!(Ptr=(char*) malloc(arg_length)))
123
 
      return true;
 
108
    Ptr=(char*) malloc(arg_length);
124
109
    Alloced_length=arg_length;
125
110
    alloced=1;
126
111
  }
127
112
  Ptr[0]=0;
128
 
  return false;
129
113
}
130
114
 
131
115
 
134
118
** (for C functions)
135
119
*/
136
120
 
137
 
bool String::realloc(size_t alloc_length)
 
121
void String::realloc(size_t alloc_length)
138
122
{
139
123
  size_t len=ALIGN_SIZE(alloc_length+1);
140
124
  if (Alloced_length < len)
142
126
    char *new_ptr;
143
127
    if (alloced)
144
128
    {
145
 
      if ((new_ptr= (char*) ::realloc(Ptr,len)))
146
 
      {
147
 
        Ptr=new_ptr;
148
 
        Alloced_length=len;
149
 
      }
150
 
      else
151
 
        return true;                            // Signal error
 
129
      new_ptr= (char*) ::realloc(Ptr,len);
 
130
      Ptr=new_ptr;
 
131
      Alloced_length=len;
152
132
    }
153
 
    else if ((new_ptr= (char*) malloc(len)))
 
133
    else 
154
134
    {
 
135
      new_ptr= (char*) malloc(len);
155
136
      if (str_length)                           // Avoid bugs in memcpy on AIX
156
 
        memcpy(new_ptr,Ptr,str_length);
 
137
        memcpy(new_ptr,Ptr,str_length);
157
138
      new_ptr[str_length]=0;
158
139
      Ptr=new_ptr;
159
140
      Alloced_length=len;
160
141
      alloced=1;
161
142
    }
162
 
    else
163
 
      return true;                      // Signal error
164
143
  }
165
144
  Ptr[alloc_length]=0;                  // This make other funcs shorter
166
 
  return false;
167
145
}
168
146
 
169
 
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
 
147
void String::set_int(int64_t num, bool unsigned_flag, const charset_info_st * const cs)
170
148
{
171
 
  size_t l=20*cs->mbmaxlen+1;
172
 
  int base= unsigned_flag ? 10 : -10;
173
 
 
174
 
  if (alloc(l))
175
 
    return true;
176
 
  str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
 
149
  size_t l= 20 * cs->mbmaxlen + 1;
 
150
  alloc(l);
 
151
  str_length=(size_t) (cs->cset->int64_t10_to_str)(cs, Ptr, l, unsigned_flag ? 10 : -10,num);
177
152
  str_charset=cs;
178
 
  return false;
179
153
}
180
154
 
181
 
bool String::set_real(double num,size_t decimals, const CHARSET_INFO * const cs)
 
155
void String::set_real(double num,size_t decimals, const charset_info_st * const cs)
182
156
{
183
157
  char buff[FLOATING_POINT_BUFFER];
184
 
  size_t dummy_errors;
185
158
  size_t len;
186
159
 
187
160
  str_charset=cs;
188
161
  if (decimals >= NOT_FIXED_DEC)
189
162
  {
190
 
    len= internal::my_gcvt(num,
191
 
                           internal::MY_GCVT_ARG_DOUBLE,
192
 
                           sizeof(buff) - 1, buff, NULL);
193
 
    return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
 
163
    len= internal::my_gcvt(num, internal::MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
 
164
    copy(buff, len, cs);
 
165
    return;
194
166
  }
195
167
  len= internal::my_fcvt(num, decimals, buff, NULL);
196
 
  return copy(buff, (size_t) len, &my_charset_utf8_general_ci, cs,
197
 
              &dummy_errors);
 
168
  copy(buff, len, cs);
198
169
}
199
170
 
200
171
 
201
 
bool String::copy()
 
172
void String::copy()
202
173
{
203
174
  if (!alloced)
204
175
  {
205
176
    Alloced_length=0;                           // Force realloc
206
 
    return realloc(str_length);
 
177
    realloc(str_length);
207
178
  }
208
 
  return false;
209
179
}
210
180
 
211
 
bool String::copy(const String &str)
 
181
void String::copy(const String &str)
212
182
{
213
 
  if (alloc(str.str_length))
214
 
    return true;
 
183
  alloc(str.str_length);
215
184
  str_length=str.str_length;
216
185
  memmove(Ptr, str.Ptr, str_length);            // May be overlapping
217
186
  Ptr[str_length]=0;
218
187
  str_charset=str.str_charset;
219
 
  return false;
220
188
}
221
189
 
222
 
bool String::copy(const std::string& arg, const CHARSET_INFO * const cs)        // Allocate new string
 
190
void String::copy(const std::string& arg, const charset_info_st * const cs)     // Allocate new string
223
191
{
224
 
  if (alloc(arg.size()))
225
 
    return true;
 
192
  alloc(arg.size());
226
193
 
227
194
  if ((str_length= arg.size()))
228
195
    memcpy(Ptr, arg.c_str(), arg.size());
229
196
 
230
197
  Ptr[arg.size()]= 0;
231
198
  str_charset= cs;
232
 
 
233
 
  return false;
234
199
}
235
200
 
236
 
bool String::copy(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
 
201
void String::copy(const char *str,size_t arg_length, const charset_info_st* cs)
237
202
{
238
 
  if (alloc(arg_length))
239
 
    return true;
 
203
  alloc(arg_length);
240
204
  if ((str_length=arg_length))
241
205
    memcpy(Ptr,str,arg_length);
242
206
  Ptr[arg_length]=0;
243
207
  str_charset=cs;
244
 
  return false;
245
208
}
246
209
 
247
210
/*
266
229
  character_set_results is NULL.
267
230
*/
268
231
 
269
 
bool String::needs_conversion(size_t arg_length,
270
 
                              const CHARSET_INFO * const from_cs,
271
 
                              const CHARSET_INFO * const to_cs,
272
 
                              size_t *offset)
 
232
bool String::needs_conversion(size_t arg_length, const charset_info_st* from_cs, const charset_info_st* to_cs)
273
233
{
274
 
  *offset= 0;
275
234
  if (!to_cs ||
276
 
      (to_cs == &my_charset_bin) ||
277
 
      (to_cs == from_cs) ||
 
235
      to_cs == &my_charset_bin ||
 
236
      to_cs == from_cs ||
278
237
      my_charset_same(from_cs, to_cs) ||
279
 
      ((from_cs == &my_charset_bin) &&
280
 
       (!(*offset=(arg_length % to_cs->mbminlen)))))
 
238
      (from_cs == &my_charset_bin && not (arg_length % to_cs->mbminlen)))
281
239
    return false;
282
240
  return true;
283
241
}
284
242
 
285
 
 
286
 
 
287
 
 
288
 
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
289
 
                                 const CHARSET_INFO * const cs)
290
 
{
291
 
  /* How many bytes are in incomplete character */
292
 
  size_t offset= (arg_length % cs->mbminlen);
293
 
 
294
 
  assert(!offset); /* All characters are complete, just copy */
295
 
 
296
 
  set(str, arg_length, cs);
297
 
  return false;
298
 
}
299
 
 
300
 
        /* Copy with charset conversion */
301
 
 
302
 
bool String::copy(const char *str, size_t arg_length,
303
 
                          const CHARSET_INFO * const,
304
 
                                  const CHARSET_INFO * const to_cs, size_t *errors)
305
 
{
306
 
  *errors= 0;
307
 
  return copy(str, arg_length, to_cs);
308
 
}
309
 
 
310
 
 
311
243
/*
312
244
  Set a string to the value of a latin1-string, keeping the original charset
313
245
 
327
259
 
328
260
*/
329
261
 
330
 
bool String::set_ascii(const char *str, size_t arg_length)
 
262
void String::set_ascii(const char *str, size_t arg_length)
331
263
{
332
264
  if (str_charset->mbminlen == 1)
333
265
  {
334
266
    set(str, arg_length, str_charset);
335
 
    return 0;
 
267
    return;
336
268
  }
337
 
  size_t dummy_errors;
338
 
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
 
269
  copy(str, arg_length, str_charset);
339
270
}
340
271
 
341
 
bool String::append(const String &s)
 
272
void String::append(const String &s)
342
273
{
343
274
  if (s.length())
344
275
  {
345
 
    if (realloc(str_length+s.length()))
346
 
      return true;
 
276
    realloc(str_length+s.length());
347
277
    memcpy(Ptr+str_length,s.ptr(),s.length());
348
278
    str_length+=s.length();
349
279
  }
350
 
  return false;
351
280
}
352
281
 
353
282
 
355
284
  Append an ASCII string to the a string of the current character set
356
285
*/
357
286
 
358
 
bool String::append(const char *s,size_t arg_length)
 
287
void String::append(const char *s,size_t arg_length)
359
288
{
360
289
  if (!arg_length)
361
 
    return false;
 
290
    return;
362
291
 
363
292
  /*
364
293
    For an ASCII compatinble string we can just append.
365
294
  */
366
 
  if (realloc(str_length+arg_length))
367
 
    return true;
 
295
  realloc(str_length+arg_length);
368
296
  memcpy(Ptr+str_length,s,arg_length);
369
297
  str_length+=arg_length;
370
 
  return false;
371
298
}
372
299
 
373
300
 
375
302
  Append a 0-terminated ASCII string
376
303
*/
377
304
 
378
 
bool String::append(const char *s)
379
 
{
380
 
  return append(s, strlen(s));
381
 
}
382
 
 
383
 
 
384
 
/*
385
 
  Append a string in the given charset to the string
386
 
  with character set recoding
387
 
*/
388
 
 
389
 
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
390
 
{
391
 
  if (realloc(str_length + arg_length))
392
 
    return true;
393
 
  memcpy(Ptr + str_length, s, arg_length);
394
 
  str_length+= arg_length;
395
 
 
396
 
  return false;
397
 
}
398
 
 
399
 
 
400
 
bool String::append_with_prefill(const char *s,size_t arg_length,
401
 
                 size_t full_length, char fill_char)
 
305
void String::append(const char *s)
 
306
{
 
307
  append(s, strlen(s));
 
308
}
 
309
 
 
310
void String::append_with_prefill(const char *s,size_t arg_length, size_t full_length, char fill_char)
402
311
{
403
312
  int t_length= arg_length > full_length ? arg_length : full_length;
404
313
 
405
 
  if (realloc(str_length + t_length))
406
 
    return true;
 
314
  realloc(str_length + t_length);
407
315
  t_length= full_length - arg_length;
408
316
  if (t_length > 0)
409
317
  {
411
319
    str_length=str_length + t_length;
412
320
  }
413
321
  append(s, arg_length);
414
 
  return false;
415
322
}
416
323
 
417
324
size_t String::numchars()
428
335
 
429
336
int String::strstr(const String &s,size_t offset)
430
337
{
431
 
  if (s.length()+offset <= str_length)
 
338
  if (s.length() + offset <= str_length)
432
339
  {
433
340
    if (!s.length())
434
341
      return ((int) offset);    // Empty string is always found
435
342
 
436
 
    register const char *str = Ptr+offset;
437
 
    register const char *search=s.ptr();
438
 
    const char *end=Ptr+str_length-s.length()+1;
 
343
    const char *str = Ptr+offset;
 
344
    const char *search=s.ptr();
 
345
    const char *last=Ptr+str_length-s.length()+1;
439
346
    const char *search_end=s.ptr()+s.length();
440
347
skip:
441
 
    while (str != end)
 
348
    while (str != last)
442
349
    {
443
350
      if (*str++ == *search)
444
351
      {
445
 
        register char *i,*j;
446
 
        i=(char*) str; j=(char*) search+1;
447
 
        while (j != search_end)
448
 
          if (*i++ != *j++) goto skip;
449
 
        return (int) (str-Ptr) -1;
 
352
        const char* i= str; 
 
353
        const char* j= search + 1;
 
354
        while (j != search_end)
 
355
          if (*i++ != *j++) goto skip;
 
356
        return (int) (str - Ptr) - 1;
450
357
      }
451
358
    }
452
359
  }
463
370
  {
464
371
    if (!s.length())
465
372
      return offset;                            // Empty string is always found
466
 
    register const char *str = Ptr+offset-1;
467
 
    register const char *search=s.ptr()+s.length()-1;
 
373
    const char *str = Ptr+offset-1;
 
374
    const char *search=s.ptr()+s.length()-1;
468
375
 
469
 
    const char *end=Ptr+s.length()-2;
 
376
    const char *last=Ptr+s.length()-2;
470
377
    const char *search_end=s.ptr()-1;
471
378
skip:
472
 
    while (str != end)
 
379
    while (str != last)
473
380
    {
474
381
      if (*str-- == *search)
475
382
      {
476
 
        register char *i,*j;
477
 
        i=(char*) str; j=(char*) search-1;
478
 
        while (j != search_end)
479
 
          if (*i-- != *j--) goto skip;
480
 
        return (int) (i-Ptr) +1;
 
383
        const char* i= str; 
 
384
        const char* j= search-1;
 
385
        while (j != search_end)
 
386
          if (*i-- != *j--) goto skip;
 
387
        return (int) (i-Ptr) + 1;
481
388
      }
482
389
    }
483
390
  }
489
396
  If wrong parameter or not enough memory, do nothing
490
397
*/
491
398
 
492
 
bool String::replace(size_t offset,size_t arg_length,const String &to)
 
399
void String::replace(size_t offset,size_t arg_length,const String &to)
493
400
{
494
 
  return replace(offset,arg_length,to.ptr(),to.length());
 
401
  replace(offset,arg_length,to.ptr(),to.length());
495
402
}
496
403
 
497
 
bool String::replace(size_t offset,size_t arg_length,
 
404
void String::replace(size_t offset,size_t arg_length,
498
405
                     const char *to, size_t to_length)
499
406
{
500
407
  long diff = (long) to_length-(long) arg_length;
511
418
    {
512
419
      if (diff)
513
420
      {
514
 
        if (realloc(str_length+(size_t) diff))
515
 
          return true;
 
421
        realloc(str_length+(size_t) diff);
516
422
        internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
517
423
                            (unsigned char*) Ptr+str_length,
518
424
                            str_length-offset-arg_length);
522
428
    }
523
429
    str_length+=(size_t) diff;
524
430
  }
525
 
  return false;
526
431
}
527
432
 
528
433
 
546
451
*/
547
452
 
548
453
 
549
 
int sortcmp(const String *s,const String *t, const CHARSET_INFO * const cs)
 
454
int sortcmp(const String *s,const String *t, const charset_info_st * const cs)
550
455
{
551
456
 return cs->coll->strnncollsp(cs,
552
457
                              (unsigned char *) s->ptr(),s->length(),
589
494
    (void) from->realloc(from_length);
590
495
    return from;
591
496
  }
592
 
  if (to->realloc(from_length))
593
 
    return from;                                // Actually an error
 
497
  to->realloc(from_length);
594
498
  if ((to->str_length= min(from->str_length,from_length)))
595
499
    memcpy(to->Ptr,from->Ptr,to->str_length);
596
500
  to->str_charset=from->str_charset;
630
534
 
631
535
 
632
536
size_t
633
 
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
 
537
well_formed_copy_nchars(const charset_info_st * const to_cs,
634
538
                        char *to, size_t to_length,
635
 
                        const CHARSET_INFO * const from_cs,
 
539
                        const charset_info_st * const from_cs,
636
540
                        const char *from, size_t from_length,
637
541
                        size_t nchars,
638
542
                        const char **well_formed_error_pos,
699
603
  return res;
700
604
}
701
605
 
702
 
 
703
 
 
704
 
 
705
 
void String::print(String *str)
 
606
void String::print(String& str) const
706
607
{
707
 
  char *st= (char*)Ptr, *end= st+str_length;
708
 
  for (; st < end; st++)
 
608
  const char* last= Ptr + str_length;
 
609
  for (const char* st= Ptr; st < last; st++)
709
610
  {
710
611
    unsigned char c= *st;
711
612
    switch (c)
712
613
    {
713
614
    case '\\':
714
 
      str->append("\\\\", sizeof("\\\\")-1);
 
615
      str.append("\\\\", sizeof("\\\\")-1);
715
616
      break;
716
617
    case '\0':
717
 
      str->append("\\0", sizeof("\\0")-1);
 
618
      str.append("\\0", sizeof("\\0")-1);
718
619
      break;
719
620
    case '\'':
720
 
      str->append("\\'", sizeof("\\'")-1);
 
621
      str.append("\\'", sizeof("\\'")-1);
721
622
      break;
722
623
    case '\n':
723
 
      str->append("\\n", sizeof("\\n")-1);
 
624
      str.append("\\n", sizeof("\\n")-1);
724
625
      break;
725
626
    case '\r':
726
 
      str->append("\\r", sizeof("\\r")-1);
 
627
      str.append("\\r", sizeof("\\r")-1);
727
628
      break;
728
629
    case '\032': // Ctrl-Z
729
 
      str->append("\\Z", sizeof("\\Z")-1);
 
630
      str.append("\\Z", sizeof("\\Z")-1);
730
631
      break;
731
632
    default:
732
 
      str->append(c);
 
633
      str.append(c);
733
634
    }
734
635
  }
735
636
}
745
646
*/
746
647
 
747
648
/* Factor the extern out */
748
 
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
 
649
extern const charset_info_st *system_charset_info;
749
650
 
750
651
void String::append_identifier(const char *name, size_t in_length)
751
652
{
752
 
  const char *name_end;
753
 
  char quote_char;
754
 
  int q= '`';
755
 
 
756
 
  /*
757
 
    The identifier must be quoted as it includes a quote character or
758
 
   it's a keyword
759
 
  */
760
 
 
761
 
  reserve(in_length*2 + 2);
762
 
  quote_char= (char) q;
763
 
  append(&quote_char, 1, system_charset_info);
764
 
 
765
 
  for (name_end= name+in_length ; name < name_end ; name+= in_length)
 
653
  // The identifier must be quoted as it includes a quote character or it's a keyword
 
654
 
 
655
  reserve(in_length * 2 + 2);
 
656
  const char quote_char= '`';
 
657
  append(&quote_char, 1);
 
658
 
 
659
  for (const char* name_end= name+in_length ; name < name_end ; name+= in_length)
766
660
  {
767
661
    unsigned char chr= (unsigned char) *name;
768
662
    in_length= my_mbcharlen(system_charset_info, chr);
776
670
    if (!in_length)
777
671
      in_length= 1;
778
672
    if (in_length == 1 && chr == (unsigned char) quote_char)
779
 
      append(&quote_char, 1, system_charset_info);
780
 
    append(name, in_length, system_charset_info);
 
673
      append(&quote_char, 1);
 
674
    append(name, in_length);
781
675
  }
782
 
  append(&quote_char, 1, system_charset_info);
783
 
}
784
 
 
785
 
 
786
 
/*
787
 
  Exchange state of this object and argument.
788
 
 
789
 
  SYNOPSIS
790
 
    String::swap()
791
 
 
792
 
  RETURN
793
 
    Target string will contain state of this object and vice versa.
794
 
*/
795
 
 
796
 
void String::swap(String &s)
797
 
{
798
 
  std::swap(Ptr, s.Ptr);
799
 
  std::swap(str_length, s.str_length);
800
 
  std::swap(Alloced_length, s.Alloced_length);
801
 
  std::swap(alloced, s.alloced);
802
 
  std::swap(str_charset, s.str_charset);
803
 
}
804
 
 
805
 
void String::q_append(const size_t n)
806
 
{
807
 
  int8store(Ptr + str_length, n);
808
 
  str_length += 4;
809
 
}
810
 
void String::q_append(double d)
811
 
{
812
 
  float8store(Ptr + str_length, d);
813
 
  str_length += 8;
814
 
}
815
 
void String::q_append(double *d)
816
 
{
817
 
  float8store(Ptr + str_length, *d);
818
 
  str_length += 8;
819
 
}
820
 
void String::q_append(const char *data, size_t data_len)
821
 
{
822
 
  memcpy(Ptr + str_length, data, data_len);
823
 
  str_length += data_len;
824
 
}
825
 
 
826
 
void String::write_at_position(int position, size_t value)
827
 
{
828
 
  int8store(Ptr + position,value);
829
 
}
830
 
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
 
676
  append(&quote_char, 1);
 
677
}
 
678
 
 
679
bool check_if_only_end_space(const charset_info_st * const cs, char *str,
831
680
                             char *end)
832
681
{
833
682
  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;