~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

Fixed the clock_gettime test.

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 */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/* This file is originally from the mysql distribution. Coded by monty */
17
17
 
20
20
#include "drizzled/internal/my_sys.h"
21
21
#include "drizzled/internal/m_string.h"
22
22
#include "drizzled/charset.h"
23
 
#include "drizzled/global_charset_info.h"
24
23
 
25
24
#include <algorithm>
26
25
 
27
26
#include "drizzled/sql_string.h"
28
27
 
 
28
using namespace drizzled;
29
29
using namespace std;
30
30
 
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
 
}
47
 
 
48
31
/*****************************************************************************
49
32
** String functions
50
33
*****************************************************************************/
58
41
{ }
59
42
 
60
43
 
61
 
String::String(size_t length_arg)
 
44
String::String(uint32_t length_arg)
62
45
  : Ptr(NULL),
63
46
    str_length(0),
64
47
    Alloced_length(0),
70
53
 
71
54
String::String(const char *str, const CHARSET_INFO * const cs)
72
55
  : Ptr(const_cast<char *>(str)),
73
 
    str_length(static_cast<size_t>(strlen(str))),
 
56
    str_length(static_cast<uint32_t>(strlen(str))),
74
57
    Alloced_length(0),
75
58
    alloced(false),
76
59
    str_charset(cs)
77
60
{ }
78
61
 
79
62
 
80
 
String::String(const char *str, size_t len, const CHARSET_INFO * const cs)
 
63
String::String(const char *str, uint32_t len, const CHARSET_INFO * const cs)
81
64
  : Ptr(const_cast<char *>(str)),
82
65
    str_length(len),
83
66
    Alloced_length(0),
86
69
{ }
87
70
 
88
71
 
89
 
String::String(char *str, size_t len, const CHARSET_INFO * const cs)
 
72
String::String(char *str, uint32_t len, const CHARSET_INFO * const cs)
90
73
  : Ptr(str),
91
74
    str_length(len),
92
75
    Alloced_length(len),
106
89
 
107
90
void *String::operator new(size_t size, memory::Root *mem_root)
108
91
{
109
 
  return mem_root->alloc_root(static_cast<size_t>(size));
 
92
  return alloc_root(mem_root, static_cast<uint32_t>(size));
110
93
}
111
94
 
112
95
String::~String() { free(); }
113
96
 
114
 
bool String::real_alloc(size_t arg_length)
 
97
bool String::real_alloc(uint32_t arg_length)
115
98
{
116
99
  arg_length=ALIGN_SIZE(arg_length+1);
117
100
  str_length=0;
118
101
  if (Alloced_length < arg_length)
119
102
  {
120
 
    if (Alloced_length > 0)
121
 
      free();
 
103
    free();
122
104
    if (!(Ptr=(char*) malloc(arg_length)))
123
105
      return true;
124
106
    Alloced_length=arg_length;
134
116
** (for C functions)
135
117
*/
136
118
 
137
 
bool String::realloc(size_t alloc_length)
 
119
bool String::realloc(uint32_t alloc_length)
138
120
{
139
 
  size_t len=ALIGN_SIZE(alloc_length+1);
 
121
  uint32_t len=ALIGN_SIZE(alloc_length+1);
140
122
  if (Alloced_length < len)
141
123
  {
142
124
    char *new_ptr;
168
150
 
169
151
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
170
152
{
171
 
  size_t l=20*cs->mbmaxlen+1;
 
153
  uint32_t l=20*cs->mbmaxlen+1;
172
154
  int base= unsigned_flag ? 10 : -10;
173
155
 
174
156
  if (alloc(l))
175
157
    return true;
176
 
  str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
 
158
  str_length=(uint32_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
177
159
  str_charset=cs;
178
160
  return false;
179
161
}
180
162
 
181
 
bool String::set_real(double num,size_t decimals, const CHARSET_INFO * const cs)
 
163
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
182
164
{
183
165
  char buff[FLOATING_POINT_BUFFER];
184
 
  size_t dummy_errors;
 
166
  uint32_t dummy_errors;
185
167
  size_t len;
186
168
 
187
169
  str_charset=cs;
188
170
  if (decimals >= NOT_FIXED_DEC)
189
171
  {
190
 
    len= internal::my_gcvt(num,
191
 
                           internal::MY_GCVT_ARG_DOUBLE,
192
 
                           sizeof(buff) - 1, buff, NULL);
 
172
    len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
193
173
    return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
194
174
  }
195
 
  len= internal::my_fcvt(num, decimals, buff, NULL);
196
 
  return copy(buff, (size_t) len, &my_charset_utf8_general_ci, cs,
 
175
  len= my_fcvt(num, decimals, buff, NULL);
 
176
  return copy(buff, (uint32_t) len, &my_charset_utf8_general_ci, cs,
197
177
              &dummy_errors);
198
178
}
199
179
 
219
199
  return false;
220
200
}
221
201
 
222
 
bool String::copy(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
 
202
bool String::copy(const char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
223
203
{
224
204
  if (alloc(arg_length))
225
205
    return true;
230
210
  return false;
231
211
}
232
212
 
 
213
 
233
214
/*
234
215
  Checks that the source string can be just copied to the destination string
235
216
  without conversion.
240
221
  arg_length            Length of string to copy.
241
222
  from_cs               Character set to copy from
242
223
  to_cs                 Character set to copy to
243
 
  size_t *offset        Returns number of unaligned characters.
 
224
  uint32_t *offset      Returns number of unaligned characters.
244
225
 
245
226
  RETURN
246
227
   0  No conversion needed
252
233
  character_set_results is NULL.
253
234
*/
254
235
 
255
 
bool String::needs_conversion(size_t arg_length,
 
236
bool String::needs_conversion(uint32_t arg_length,
256
237
                              const CHARSET_INFO * const from_cs,
257
238
                              const CHARSET_INFO * const to_cs,
258
 
                              size_t *offset)
 
239
                              uint32_t *offset)
259
240
{
260
241
  *offset= 0;
261
242
  if (!to_cs ||
271
252
 
272
253
 
273
254
 
274
 
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
 
255
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
275
256
                                 const CHARSET_INFO * const cs)
276
257
{
277
258
  /* How many bytes are in incomplete character */
278
 
  size_t offset= (arg_length % cs->mbminlen);
 
259
  uint32_t offset= (arg_length % cs->mbminlen);
279
260
 
280
261
  assert(!offset); /* All characters are complete, just copy */
281
262
 
285
266
 
286
267
        /* Copy with charset conversion */
287
268
 
288
 
bool String::copy(const char *str, size_t arg_length,
 
269
bool String::copy(const char *str, uint32_t arg_length,
289
270
                          const CHARSET_INFO * const,
290
 
                                  const CHARSET_INFO * const to_cs, size_t *errors)
 
271
                                  const CHARSET_INFO * const to_cs, uint32_t *errors)
291
272
{
292
273
  *errors= 0;
293
274
  return copy(str, arg_length, to_cs);
313
294
 
314
295
*/
315
296
 
316
 
bool String::set_ascii(const char *str, size_t arg_length)
 
297
bool String::set_ascii(const char *str, uint32_t arg_length)
317
298
{
318
299
  if (str_charset->mbminlen == 1)
319
300
  {
320
301
    set(str, arg_length, str_charset);
321
302
    return 0;
322
303
  }
323
 
  size_t dummy_errors;
 
304
  uint32_t dummy_errors;
324
305
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
325
306
}
326
307
 
341
322
  Append an ASCII string to the a string of the current character set
342
323
*/
343
324
 
344
 
bool String::append(const char *s,size_t arg_length)
 
325
bool String::append(const char *s,uint32_t arg_length)
345
326
{
346
327
  if (!arg_length)
347
328
    return false;
372
353
  with character set recoding
373
354
*/
374
355
 
375
 
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
 
356
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const)
376
357
{
377
358
  if (realloc(str_length + arg_length))
378
359
    return true;
383
364
}
384
365
 
385
366
 
386
 
bool String::append_with_prefill(const char *s,size_t arg_length,
387
 
                 size_t full_length, char fill_char)
 
367
bool String::append_with_prefill(const char *s,uint32_t arg_length,
 
368
                 uint32_t full_length, char fill_char)
388
369
{
389
370
  int t_length= arg_length > full_length ? arg_length : full_length;
390
371
 
400
381
  return false;
401
382
}
402
383
 
403
 
size_t String::numchars()
 
384
uint32_t String::numchars()
404
385
{
405
386
  return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
406
387
}
407
388
 
408
 
int String::charpos(int i,size_t offset)
 
389
int String::charpos(int i,uint32_t offset)
409
390
{
410
391
  if (i <= 0)
411
392
    return i;
412
393
  return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
413
394
}
414
395
 
415
 
int String::strstr(const String &s,size_t offset)
 
396
int String::strstr(const String &s,uint32_t offset)
416
397
{
417
398
  if (s.length()+offset <= str_length)
418
399
  {
443
424
** Search string from end. Offset is offset to the end of string
444
425
*/
445
426
 
446
 
int String::strrstr(const String &s,size_t offset)
 
427
int String::strrstr(const String &s,uint32_t offset)
447
428
{
448
429
  if (s.length() <= offset && offset <= str_length)
449
430
  {
475
456
  If wrong parameter or not enough memory, do nothing
476
457
*/
477
458
 
478
 
bool String::replace(size_t offset,size_t arg_length,const String &to)
 
459
bool String::replace(uint32_t offset,uint32_t arg_length,const String &to)
479
460
{
480
461
  return replace(offset,arg_length,to.ptr(),to.length());
481
462
}
482
463
 
483
 
bool String::replace(size_t offset,size_t arg_length,
484
 
                     const char *to, size_t to_length)
 
464
bool String::replace(uint32_t offset,uint32_t arg_length,
 
465
                     const char *to, uint32_t to_length)
485
466
{
486
467
  long diff = (long) to_length-(long) arg_length;
487
468
  if (offset+arg_length <= str_length)
497
478
    {
498
479
      if (diff)
499
480
      {
500
 
        if (realloc(str_length+(size_t) diff))
 
481
        if (realloc(str_length+(uint32_t) diff))
501
482
          return true;
502
 
        internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
503
 
                            (unsigned char*) Ptr+str_length,
504
 
                            str_length-offset-arg_length);
 
483
        bmove_upp((unsigned char*) Ptr+str_length+diff, (unsigned char*) Ptr+str_length,
 
484
                  str_length-offset-arg_length);
505
485
      }
506
486
      if (to_length)
507
487
        memcpy(Ptr+offset,to,to_length);
508
488
    }
509
 
    str_length+=(size_t) diff;
 
489
    str_length+=(uint32_t) diff;
510
490
  }
511
491
  return false;
512
492
}
560
540
 
561
541
int stringcmp(const String *s,const String *t)
562
542
{
563
 
  size_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
 
543
  uint32_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
564
544
  int cmp= memcmp(s->ptr(), t->ptr(), len);
565
545
  return (cmp) ? cmp : (int) (s_len - t_len);
566
546
}
567
547
 
568
548
 
569
 
String *copy_if_not_alloced(String *to,String *from,size_t from_length)
 
549
String *copy_if_not_alloced(String *to,String *from,uint32_t from_length)
570
550
{
571
551
  if (from->Alloced_length >= from_length)
572
552
    return from;
615
595
*/
616
596
 
617
597
 
618
 
size_t
 
598
uint32_t
619
599
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
620
 
                        char *to, size_t to_length,
 
600
                        char *to, uint32_t to_length,
621
601
                        const CHARSET_INFO * const from_cs,
622
 
                        const char *from, size_t from_length,
623
 
                        size_t nchars,
 
602
                        const char *from, uint32_t from_length,
 
603
                        uint32_t nchars,
624
604
                        const char **well_formed_error_pos,
625
605
                        const char **cannot_convert_error_pos,
626
606
                        const char **from_end_pos)
627
607
{
628
 
  size_t res;
 
608
  uint32_t res;
629
609
 
630
610
  assert((to_cs == &my_charset_bin) ||
631
611
         (from_cs == &my_charset_bin) ||
651
631
  else
652
632
  {
653
633
    int well_formed_error;
654
 
    size_t from_offset;
 
634
    uint32_t from_offset;
655
635
 
656
636
    if ((from_offset= (from_length % to_cs->mbminlen)) &&
657
637
        (from_cs == &my_charset_bin))
661
641
        INSERT INTO t1 (ucs2_column) VALUES (0x01);
662
642
        0x01 -> 0x0001
663
643
      */
664
 
      size_t pad_length= to_cs->mbminlen - from_offset;
 
644
      uint32_t pad_length= to_cs->mbminlen - from_offset;
665
645
      memset(to, 0, pad_length);
666
646
      memmove(to + pad_length, from, from_offset);
667
647
      nchars--;
733
713
/* Factor the extern out */
734
714
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
735
715
 
736
 
void String::append_identifier(const char *name, size_t in_length)
 
716
void String::append_identifier(const char *name, uint32_t in_length)
737
717
{
738
718
  const char *name_end;
739
719
  char quote_char;
788
768
  std::swap(str_charset, s.str_charset);
789
769
}
790
770
 
791
 
void String::q_append(const size_t n)
792
 
{
793
 
  int8store(Ptr + str_length, n);
794
 
  str_length += 4;
795
 
}
796
 
void String::q_append(double d)
797
 
{
798
 
  float8store(Ptr + str_length, d);
799
 
  str_length += 8;
800
 
}
801
 
void String::q_append(double *d)
802
 
{
803
 
  float8store(Ptr + str_length, *d);
804
 
  str_length += 8;
805
 
}
806
 
void String::q_append(const char *data, size_t data_len)
807
 
{
808
 
  memcpy(Ptr + str_length, data, data_len);
809
 
  str_length += data_len;
810
 
}
811
 
 
812
 
void String::write_at_position(int position, size_t value)
813
 
{
814
 
  int8store(Ptr + position,value);
815
 
}
 
771
 
 
772
bool operator==(const String &s1, const String &s2)
 
773
{
 
774
  return stringcmp(&s1,&s2) == 0;
 
775
}
 
776
 
 
777
bool operator!=(const String &s1, const String &s2)
 
778
{
 
779
  return !(s1 == s2);
 
780
}
 
781
 
816
782
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
817
783
                             char *end)
818
784
{
819
785
  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
820
786
}
821
 
 
822
 
} /* namespace drizzled */
823
 
 
824
 
bool operator==(const drizzled::String &s1, const drizzled::String &s2)
825
 
{
826
 
  return stringcmp(&s1,&s2) == 0;
827
 
}
828
 
 
829
 
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
830
 
{
831
 
  return !(s1 == s2);
832
 
}
833