~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

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/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>
 
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"
25
24
 
26
25
#include <algorithm>
27
26
 
28
 
#include <drizzled/sql_string.h>
 
27
#include "drizzled/sql_string.h"
29
28
 
30
29
using namespace std;
31
30
 
32
 
namespace drizzled {
 
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
}
33
47
 
34
48
/*****************************************************************************
35
49
** String functions
54
68
  (void) real_alloc(length_arg);
55
69
}
56
70
 
57
 
String::String(const char *str, const charset_info_st * const cs)
 
71
String::String(const char *str, const CHARSET_INFO * const cs)
58
72
  : Ptr(const_cast<char *>(str)),
59
73
    str_length(static_cast<size_t>(strlen(str))),
60
74
    Alloced_length(0),
63
77
{ }
64
78
 
65
79
 
66
 
String::String(const char *str, size_t len, const charset_info_st * const cs)
 
80
String::String(const char *str, size_t len, const CHARSET_INFO * const cs)
67
81
  : Ptr(const_cast<char *>(str)),
68
82
    str_length(len),
69
83
    Alloced_length(0),
72
86
{ }
73
87
 
74
88
 
75
 
String::String(char *str, size_t len, const charset_info_st * const cs)
 
89
String::String(char *str, size_t len, const CHARSET_INFO * const cs)
76
90
  : Ptr(str),
77
91
    str_length(len),
78
92
    Alloced_length(len),
97
111
 
98
112
String::~String() { free(); }
99
113
 
100
 
void String::real_alloc(size_t arg_length)
 
114
bool String::real_alloc(size_t arg_length)
101
115
{
102
116
  arg_length=ALIGN_SIZE(arg_length+1);
103
117
  str_length=0;
105
119
  {
106
120
    if (Alloced_length > 0)
107
121
      free();
108
 
    Ptr=(char*) malloc(arg_length);
 
122
    if (!(Ptr=(char*) malloc(arg_length)))
 
123
      return true;
109
124
    Alloced_length=arg_length;
110
125
    alloced=1;
111
126
  }
112
127
  Ptr[0]=0;
 
128
  return false;
113
129
}
114
130
 
115
131
 
118
134
** (for C functions)
119
135
*/
120
136
 
121
 
void String::realloc(size_t alloc_length)
 
137
bool String::realloc(size_t alloc_length)
122
138
{
123
139
  size_t len=ALIGN_SIZE(alloc_length+1);
124
140
  if (Alloced_length < len)
126
142
    char *new_ptr;
127
143
    if (alloced)
128
144
    {
129
 
      new_ptr= (char*) ::realloc(Ptr,len);
130
 
      Ptr=new_ptr;
131
 
      Alloced_length=len;
 
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
132
152
    }
133
 
    else 
 
153
    else if ((new_ptr= (char*) malloc(len)))
134
154
    {
135
 
      new_ptr= (char*) malloc(len);
136
155
      if (str_length)                           // Avoid bugs in memcpy on AIX
137
 
        memcpy(new_ptr,Ptr,str_length);
 
156
        memcpy(new_ptr,Ptr,str_length);
138
157
      new_ptr[str_length]=0;
139
158
      Ptr=new_ptr;
140
159
      Alloced_length=len;
141
160
      alloced=1;
142
161
    }
 
162
    else
 
163
      return true;                      // Signal error
143
164
  }
144
165
  Ptr[alloc_length]=0;                  // This make other funcs shorter
 
166
  return false;
145
167
}
146
168
 
147
 
void String::set_int(int64_t num, bool unsigned_flag, const charset_info_st * const cs)
 
169
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
148
170
{
149
171
  size_t l=20*cs->mbmaxlen+1;
150
172
  int base= unsigned_flag ? 10 : -10;
151
173
 
152
 
  alloc(l);
 
174
  if (alloc(l))
 
175
    return true;
153
176
  str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
154
177
  str_charset=cs;
 
178
  return false;
155
179
}
156
180
 
157
 
void String::set_real(double num,size_t decimals, const charset_info_st * const cs)
 
181
bool String::set_real(double num,size_t decimals, const CHARSET_INFO * const cs)
158
182
{
159
183
  char buff[FLOATING_POINT_BUFFER];
 
184
  size_t dummy_errors;
160
185
  size_t len;
161
186
 
162
187
  str_charset=cs;
163
188
  if (decimals >= NOT_FIXED_DEC)
164
189
  {
165
 
    len= internal::my_gcvt(num, internal::MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
166
 
    copy(buff, len, cs);
167
 
    return;
 
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);
168
194
  }
169
195
  len= internal::my_fcvt(num, decimals, buff, NULL);
170
 
  copy(buff, len, cs);
 
196
  return copy(buff, (size_t) len, &my_charset_utf8_general_ci, cs,
 
197
              &dummy_errors);
171
198
}
172
199
 
173
200
 
174
 
void String::copy()
 
201
bool String::copy()
175
202
{
176
203
  if (!alloced)
177
204
  {
178
205
    Alloced_length=0;                           // Force realloc
179
 
    realloc(str_length);
 
206
    return realloc(str_length);
180
207
  }
 
208
  return false;
181
209
}
182
210
 
183
 
void String::copy(const String &str)
 
211
bool String::copy(const String &str)
184
212
{
185
 
  alloc(str.str_length);
 
213
  if (alloc(str.str_length))
 
214
    return true;
186
215
  str_length=str.str_length;
187
216
  memmove(Ptr, str.Ptr, str_length);            // May be overlapping
188
217
  Ptr[str_length]=0;
189
218
  str_charset=str.str_charset;
 
219
  return false;
190
220
}
191
221
 
192
 
void String::copy(const std::string& arg, const charset_info_st * const cs)     // Allocate new string
 
222
bool String::copy(const std::string& arg, const CHARSET_INFO * const cs)        // Allocate new string
193
223
{
194
 
  alloc(arg.size());
 
224
  if (alloc(arg.size()))
 
225
    return true;
195
226
 
196
227
  if ((str_length= arg.size()))
197
228
    memcpy(Ptr, arg.c_str(), arg.size());
198
229
 
199
230
  Ptr[arg.size()]= 0;
200
231
  str_charset= cs;
 
232
 
 
233
  return false;
201
234
}
202
235
 
203
 
void String::copy(const char *str,size_t arg_length, const charset_info_st* cs)
 
236
bool String::copy(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
204
237
{
205
 
  alloc(arg_length);
 
238
  if (alloc(arg_length))
 
239
    return true;
206
240
  if ((str_length=arg_length))
207
241
    memcpy(Ptr,str,arg_length);
208
242
  Ptr[arg_length]=0;
209
243
  str_charset=cs;
 
244
  return false;
210
245
}
211
246
 
212
247
/*
232
267
*/
233
268
 
234
269
bool String::needs_conversion(size_t arg_length,
235
 
                              const charset_info_st * const from_cs,
236
 
                              const charset_info_st * const to_cs,
 
270
                              const CHARSET_INFO * const from_cs,
 
271
                              const CHARSET_INFO * const to_cs,
237
272
                              size_t *offset)
238
273
{
239
274
  *offset= 0;
250
285
 
251
286
 
252
287
 
253
 
void String::set_or_copy_aligned(const char *str,size_t arg_length, const charset_info_st* cs)
 
288
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
 
289
                                 const CHARSET_INFO * const cs)
254
290
{
255
291
  /* How many bytes are in incomplete character */
256
292
  size_t offset= (arg_length % cs->mbminlen);
258
294
  assert(!offset); /* All characters are complete, just copy */
259
295
 
260
296
  set(str, arg_length, cs);
261
 
}
 
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
 
262
310
 
263
311
/*
264
312
  Set a string to the value of a latin1-string, keeping the original charset
279
327
 
280
328
*/
281
329
 
282
 
void String::set_ascii(const char *str, size_t arg_length)
 
330
bool String::set_ascii(const char *str, size_t arg_length)
283
331
{
284
332
  if (str_charset->mbminlen == 1)
285
333
  {
286
334
    set(str, arg_length, str_charset);
287
 
    return;
 
335
    return 0;
288
336
  }
289
 
  copy(str, arg_length, str_charset);
 
337
  size_t dummy_errors;
 
338
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
290
339
}
291
340
 
292
 
void String::append(const String &s)
 
341
bool String::append(const String &s)
293
342
{
294
343
  if (s.length())
295
344
  {
296
 
    realloc(str_length+s.length());
 
345
    if (realloc(str_length+s.length()))
 
346
      return true;
297
347
    memcpy(Ptr+str_length,s.ptr(),s.length());
298
348
    str_length+=s.length();
299
349
  }
 
350
  return false;
300
351
}
301
352
 
302
353
 
304
355
  Append an ASCII string to the a string of the current character set
305
356
*/
306
357
 
307
 
void String::append(const char *s,size_t arg_length)
 
358
bool String::append(const char *s,size_t arg_length)
308
359
{
309
360
  if (!arg_length)
310
 
    return;
 
361
    return false;
311
362
 
312
363
  /*
313
364
    For an ASCII compatinble string we can just append.
314
365
  */
315
 
  realloc(str_length+arg_length);
 
366
  if (realloc(str_length+arg_length))
 
367
    return true;
316
368
  memcpy(Ptr+str_length,s,arg_length);
317
369
  str_length+=arg_length;
 
370
  return false;
318
371
}
319
372
 
320
373
 
322
375
  Append a 0-terminated ASCII string
323
376
*/
324
377
 
325
 
void String::append(const char *s)
 
378
bool String::append(const char *s)
326
379
{
327
 
  append(s, strlen(s));
 
380
  return append(s, strlen(s));
328
381
}
329
382
 
330
383
 
333
386
  with character set recoding
334
387
*/
335
388
 
336
 
void String::append(const char *s,size_t arg_length, const charset_info_st * const)
 
389
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
337
390
{
338
 
  realloc(str_length + arg_length);
 
391
  if (realloc(str_length + arg_length))
 
392
    return true;
339
393
  memcpy(Ptr + str_length, s, arg_length);
340
394
  str_length+= arg_length;
 
395
 
 
396
  return false;
341
397
}
342
398
 
343
399
 
344
 
void String::append_with_prefill(const char *s,size_t arg_length,
 
400
bool String::append_with_prefill(const char *s,size_t arg_length,
345
401
                 size_t full_length, char fill_char)
346
402
{
347
403
  int t_length= arg_length > full_length ? arg_length : full_length;
348
404
 
349
 
  realloc(str_length + t_length);
 
405
  if (realloc(str_length + t_length))
 
406
    return true;
350
407
  t_length= full_length - arg_length;
351
408
  if (t_length > 0)
352
409
  {
354
411
    str_length=str_length + t_length;
355
412
  }
356
413
  append(s, arg_length);
 
414
  return false;
357
415
}
358
416
 
359
417
size_t String::numchars()
375
433
    if (!s.length())
376
434
      return ((int) offset);    // Empty string is always found
377
435
 
378
 
    const char *str = Ptr+offset;
379
 
    const char *search=s.ptr();
 
436
    register const char *str = Ptr+offset;
 
437
    register const char *search=s.ptr();
380
438
    const char *end=Ptr+str_length-s.length()+1;
381
439
    const char *search_end=s.ptr()+s.length();
382
440
skip:
384
442
    {
385
443
      if (*str++ == *search)
386
444
      {
387
 
        char *i,*j;
 
445
        register char *i,*j;
388
446
        i=(char*) str; j=(char*) search+1;
389
447
        while (j != search_end)
390
448
          if (*i++ != *j++) goto skip;
405
463
  {
406
464
    if (!s.length())
407
465
      return offset;                            // Empty string is always found
408
 
    const char *str = Ptr+offset-1;
409
 
    const char *search=s.ptr()+s.length()-1;
 
466
    register const char *str = Ptr+offset-1;
 
467
    register const char *search=s.ptr()+s.length()-1;
410
468
 
411
469
    const char *end=Ptr+s.length()-2;
412
470
    const char *search_end=s.ptr()-1;
415
473
    {
416
474
      if (*str-- == *search)
417
475
      {
418
 
        char *i,*j;
 
476
        register char *i,*j;
419
477
        i=(char*) str; j=(char*) search-1;
420
478
        while (j != search_end)
421
479
          if (*i-- != *j--) goto skip;
431
489
  If wrong parameter or not enough memory, do nothing
432
490
*/
433
491
 
434
 
void String::replace(size_t offset,size_t arg_length,const String &to)
 
492
bool String::replace(size_t offset,size_t arg_length,const String &to)
435
493
{
436
 
  replace(offset,arg_length,to.ptr(),to.length());
 
494
  return replace(offset,arg_length,to.ptr(),to.length());
437
495
}
438
496
 
439
 
void String::replace(size_t offset,size_t arg_length,
 
497
bool String::replace(size_t offset,size_t arg_length,
440
498
                     const char *to, size_t to_length)
441
499
{
442
500
  long diff = (long) to_length-(long) arg_length;
453
511
    {
454
512
      if (diff)
455
513
      {
456
 
        realloc(str_length+(size_t) diff);
 
514
        if (realloc(str_length+(size_t) diff))
 
515
          return true;
457
516
        internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
458
517
                            (unsigned char*) Ptr+str_length,
459
518
                            str_length-offset-arg_length);
463
522
    }
464
523
    str_length+=(size_t) diff;
465
524
  }
 
525
  return false;
466
526
}
467
527
 
468
528
 
486
546
*/
487
547
 
488
548
 
489
 
int sortcmp(const String *s,const String *t, const charset_info_st * const cs)
 
549
int sortcmp(const String *s,const String *t, const CHARSET_INFO * const cs)
490
550
{
491
551
 return cs->coll->strnncollsp(cs,
492
552
                              (unsigned char *) s->ptr(),s->length(),
529
589
    (void) from->realloc(from_length);
530
590
    return from;
531
591
  }
532
 
  to->realloc(from_length);
 
592
  if (to->realloc(from_length))
 
593
    return from;                                // Actually an error
533
594
  if ((to->str_length= min(from->str_length,from_length)))
534
595
    memcpy(to->Ptr,from->Ptr,to->str_length);
535
596
  to->str_charset=from->str_charset;
569
630
 
570
631
 
571
632
size_t
572
 
well_formed_copy_nchars(const charset_info_st * const to_cs,
 
633
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
573
634
                        char *to, size_t to_length,
574
 
                        const charset_info_st * const from_cs,
 
635
                        const CHARSET_INFO * const from_cs,
575
636
                        const char *from, size_t from_length,
576
637
                        size_t nchars,
577
638
                        const char **well_formed_error_pos,
684
745
*/
685
746
 
686
747
/* Factor the extern out */
687
 
extern const charset_info_st *system_charset_info, *files_charset_info;
 
748
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
688
749
 
689
750
void String::append_identifier(const char *name, size_t in_length)
690
751
{
721
782
  append(&quote_char, 1, system_charset_info);
722
783
}
723
784
 
724
 
bool check_if_only_end_space(const charset_info_st * const cs, char *str,
 
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,
725
831
                             char *end)
726
832
{
727
833
  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;