~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
  if (Alloced_length < arg_length)
43
43
  {
44
44
    free();
45
 
    if (!(Ptr=(char*) malloc(arg_length)))
 
45
    if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))
46
46
      return true;
47
47
    Alloced_length=arg_length;
48
48
    alloced=1;
65
65
    char *new_ptr;
66
66
    if (alloced)
67
67
    {
68
 
      if ((new_ptr= (char*) ::realloc(Ptr,len)))
 
68
      if ((new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME))))
69
69
      {
70
70
        Ptr=new_ptr;
71
71
        Alloced_length=len;
73
73
      else
74
74
        return true;                            // Signal error
75
75
    }
76
 
    else if ((new_ptr= (char*) malloc(len)))
 
76
    else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME))))
77
77
    {
78
78
      if (str_length)                           // Avoid bugs in memcpy on AIX
79
79
        memcpy(new_ptr,Ptr,str_length);
181
181
{
182
182
  *offset= 0;
183
183
  if (!to_cs ||
184
 
      (to_cs == &my_charset_bin) ||
 
184
      (to_cs == &my_charset_bin) || 
185
185
      (to_cs == from_cs) ||
186
186
      my_charset_same(from_cs, to_cs) ||
187
187
      ((from_cs == &my_charset_bin) &&
191
191
}
192
192
 
193
193
 
 
194
/*
 
195
  Copy a multi-byte character sets with adding leading zeros.
 
196
 
 
197
  SYNOPSIS
 
198
 
 
199
  copy_aligned()
 
200
  str                   String to copy
 
201
  arg_length            Length of string. This should NOT be dividable with
 
202
                        cs->mbminlen.
 
203
  offset                arg_length % cs->mb_minlength
 
204
  cs                    Character set for 'str'
 
205
 
 
206
  NOTES
 
207
    For real multi-byte, ascii incompatible charactser sets,
 
208
    like UCS-2, add leading zeros if we have an incomplete character.
 
209
    Thus, 
 
210
      SELECT _ucs2 0xAA 
 
211
    will automatically be converted into
 
212
      SELECT _ucs2 0x00AA
 
213
 
 
214
  RETURN
 
215
    0  ok
 
216
    1  error
 
217
*/
 
218
 
 
219
bool String::copy_aligned(const char *str,uint32_t arg_length, uint32_t offset,
 
220
                          const CHARSET_INFO * const cs)
 
221
{
 
222
  /* How many bytes are in incomplete character */
 
223
  offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */
 
224
  assert(offset && offset != cs->mbmaxlen);
 
225
 
 
226
  uint32_t aligned_length= arg_length + offset;
 
227
  if (alloc(aligned_length))
 
228
    return true;
 
229
  
 
230
  /*
 
231
    Note, this is only safe for big-endian UCS-2.
 
232
    If we add little-endian UCS-2 sometimes, this code
 
233
    will be more complicated. But it's OK for now.
 
234
  */
 
235
  memset(Ptr, 0, offset);
 
236
  memcpy(Ptr + offset, str, arg_length);
 
237
  Ptr[aligned_length]=0;
 
238
  /* str_length is always >= 0 as arg_length is != 0 */
 
239
  str_length= aligned_length;
 
240
  str_charset= cs;
 
241
  return false;
 
242
}
194
243
 
195
244
 
196
245
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
197
246
                                 const CHARSET_INFO * const cs)
198
247
{
199
248
  /* How many bytes are in incomplete character */
200
 
  uint32_t offset= (arg_length % cs->mbminlen);
201
 
 
202
 
  assert(!offset); /* All characters are complete, just copy */
203
 
 
204
 
  set(str, arg_length, cs);
205
 
  return false;
 
249
  uint32_t offset= (arg_length % cs->mbminlen); 
 
250
  
 
251
  if (!offset) /* All characters are complete, just copy */
 
252
  {
 
253
    set(str, arg_length, cs);
 
254
    return false;
 
255
  }
 
256
  return copy_aligned(str, arg_length, offset, cs);
206
257
}
207
258
 
208
259
        /* Copy with charset conversion */
220
271
  if ((from_cs == &my_charset_bin) && offset)
221
272
  {
222
273
    *errors= 0;
223
 
    assert((from_cs == &my_charset_bin) && offset);
224
 
    return false; //copy_aligned(str, arg_length, offset, to_cs);
 
274
    return copy_aligned(str, arg_length, offset, to_cs);
225
275
  }
226
276
  uint32_t new_length= to_cs->mbmaxlen*arg_length;
227
277
  if (alloc(new_length))
235
285
 
236
286
/*
237
287
  Set a string to the value of a latin1-string, keeping the original charset
238
 
 
 
288
  
239
289
  SYNOPSIS
240
290
    copy_or_set()
241
291
    str                 String of a simple charset (latin1)
263
313
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
264
314
}
265
315
 
 
316
 
 
317
/* This is used by mysql.cc */
 
318
 
 
319
bool String::fill(uint32_t max_length,char fill_char)
 
320
{
 
321
  if (str_length > max_length)
 
322
    Ptr[str_length=max_length]=0;
 
323
  else
 
324
  {
 
325
    if (realloc(max_length))
 
326
      return true;
 
327
    memset(Ptr+str_length, fill_char, max_length-str_length);
 
328
    str_length=max_length;
 
329
  }
 
330
  return false;
 
331
}
 
332
 
266
333
bool String::append(const String &s)
267
334
{
268
335
  if (s.length())
329
396
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs)
330
397
{
331
398
  uint32_t dummy_offset;
332
 
 
 
399
  
333
400
  if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
334
401
  {
335
402
    uint32_t add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
336
403
    uint32_t dummy_errors;
337
 
    if (realloc(str_length + add_length))
 
404
    if (realloc(str_length + add_length)) 
338
405
      return true;
339
406
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
340
407
                                  s, arg_length, cs, &dummy_errors);
341
408
  }
342
409
  else
343
410
  {
344
 
    if (realloc(str_length + arg_length))
 
411
    if (realloc(str_length + arg_length)) 
345
412
      return true;
346
413
    memcpy(Ptr + str_length, s, arg_length);
347
414
    str_length+= arg_length;
350
417
}
351
418
 
352
419
 
 
420
bool String::append(IO_CACHE* file, uint32_t arg_length)
 
421
{
 
422
  if (realloc(str_length+arg_length))
 
423
    return true;
 
424
  if (my_b_read(file, (unsigned char*) Ptr + str_length, arg_length))
 
425
  {
 
426
    shrink(str_length);
 
427
    return true;
 
428
  }
 
429
  str_length+=arg_length;
 
430
  return false;
 
431
}
 
432
 
353
433
bool String::append_with_prefill(const char *s,uint32_t arg_length,
354
434
                 uint32_t full_length, char fill_char)
355
435
{
457
537
    {
458
538
      if (to_length)
459
539
        memcpy(Ptr+offset,to,to_length);
460
 
      memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
461
 
              str_length-offset-arg_length);
 
540
      memcpy(Ptr+offset+to_length, Ptr+offset+arg_length,
 
541
             str_length-offset-arg_length);
462
542
    }
463
543
    else
464
544
    {
478
558
}
479
559
 
480
560
 
 
561
// added by Holyfoot for "geometry" needs
 
562
int String::reserve(uint32_t space_needed, uint32_t grow_by)
 
563
{
 
564
  if (Alloced_length < str_length + space_needed)
 
565
  {
 
566
    if (realloc(Alloced_length + cmax(space_needed, grow_by) - 1))
 
567
      return true;
 
568
  }
 
569
  return false;
 
570
}
 
571
 
 
572
void String::qs_append(const char *str, uint32_t len)
 
573
{
 
574
  memcpy(Ptr + str_length, str, len + 1);
 
575
  str_length += len;
 
576
}
 
577
 
 
578
void String::qs_append(double d)
 
579
{
 
580
  char *buff = Ptr + str_length;
 
581
  str_length+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff, NULL);
 
582
}
 
583
 
 
584
void String::qs_append(double *d)
 
585
{
 
586
  double ld;
 
587
  float8get(ld, (char*) d);
 
588
  qs_append(ld);
 
589
}
 
590
 
 
591
void String::qs_append(int i)
 
592
{
 
593
  char *buff= Ptr + str_length;
 
594
  char *end= int10_to_str(i, buff, -10);
 
595
  str_length+= (int) (end-buff);
 
596
}
 
597
 
 
598
void String::qs_append(uint32_t i)
 
599
{
 
600
  char *buff= Ptr + str_length;
 
601
  char *end= int10_to_str(i, buff, 10);
 
602
  str_length+= (int) (end-buff);
 
603
}
481
604
 
482
605
/*
483
606
  Compare strings according to collation, without end space.
556
679
 
557
680
/*
558
681
  copy a string from one character set to another
559
 
 
 
682
  
560
683
  SYNOPSIS
561
684
    copy_and_convert()
562
685
    to                  Store result here
575
698
 
576
699
static uint32_t
577
700
copy_and_convert_extended(char *to, uint32_t to_length,
578
 
                          const CHARSET_INFO * const to_cs,
 
701
                          const CHARSET_INFO * const to_cs, 
579
702
                          const char *from, uint32_t from_length,
580
703
                          const CHARSET_INFO * const from_cs,
581
704
                          uint32_t *errors)
634
757
  Optimized for quick copying of ASCII characters in the range 0x00..0x7F.
635
758
*/
636
759
uint32_t
637
 
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs,
 
760
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs, 
638
761
                 const char *from, uint32_t from_length,
639
762
                                 const CHARSET_INFO * const from_cs, uint32_t *errors)
640
763
{
684
807
    }
685
808
  }
686
809
 
687
 
#ifndef __sun
 
810
  assert(false); // Should never get to here
688
811
  return 0;           // Make compiler happy
689
 
#endif
690
812
}
691
813
 
692
814
 
698
820
  are read from "src". Any sequences of bytes representing
699
821
  a not-well-formed substring (according to cs) are hex-encoded,
700
822
  and all well-formed substrings (according to cs) are copied as is.
701
 
  Not more than "dstlen" bytes are written to "dst". The number
 
823
  Not more than "dstlen" bytes are written to "dst". The number 
702
824
  of bytes written to "dst" is returned.
703
 
 
 
825
  
704
826
   @param      cs       character set pointer of the destination string
705
827
   @param[out] dst      destination string
706
828
   @param      dstlen   size of dst
756
878
  copy a string,
757
879
  with optional character set conversion,
758
880
  with optional left padding (for binary -> UCS2 conversion)
759
 
 
 
881
  
760
882
  SYNOPSIS
761
883
    well_formed_copy_nchars()
762
884
    to                       Store result here
791
913
{
792
914
  uint32_t res;
793
915
 
794
 
  if ((to_cs == &my_charset_bin) ||
 
916
  if ((to_cs == &my_charset_bin) || 
795
917
      (from_cs == &my_charset_bin) ||
796
918
      (to_cs == from_cs) ||
797
919
      my_charset_same(from_cs, to_cs))
918
1040
    switch (c)
919
1041
    {
920
1042
    case '\\':
921
 
      str->append("\\\\", sizeof("\\\\")-1);
 
1043
      str->append(STRING_WITH_LEN("\\\\"));
922
1044
      break;
923
1045
    case '\0':
924
 
      str->append("\\0", sizeof("\\0")-1);
 
1046
      str->append(STRING_WITH_LEN("\\0"));
925
1047
      break;
926
1048
    case '\'':
927
 
      str->append("\\'", sizeof("\\'")-1);
 
1049
      str->append(STRING_WITH_LEN("\\'"));
928
1050
      break;
929
1051
    case '\n':
930
 
      str->append("\\n", sizeof("\\n")-1);
 
1052
      str->append(STRING_WITH_LEN("\\n"));
931
1053
      break;
932
1054
    case '\r':
933
 
      str->append("\\r", sizeof("\\r")-1);
 
1055
      str->append(STRING_WITH_LEN("\\r"));
934
1056
      break;
935
1057
    case '\032': // Ctrl-Z
936
 
      str->append("\\Z", sizeof("\\Z")-1);
 
1058
      str->append(STRING_WITH_LEN("\\Z"));
937
1059
      break;
938
1060
    default:
939
1061
      str->append(c);
941
1063
  }
942
1064
}
943
1065
 
944
 
/*
945
 
  Quote the given identifier.
946
 
  If the given identifier is empty, it will be quoted.
947
 
 
948
 
  SYNOPSIS
949
 
  append_identifier()
950
 
  name                  the identifier to be appended
951
 
  name_length           length of the appending identifier
952
 
*/
953
 
 
954
 
/* Factor the extern out */
955
 
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
956
 
 
957
 
void String::append_identifier(const char *name, uint32_t in_length)
958
 
{
959
 
  const char *name_end;
960
 
  char quote_char;
961
 
  int q= '`';
962
 
 
963
 
  /*
964
 
    The identifier must be quoted as it includes a quote character or
965
 
   it's a keyword
966
 
  */
967
 
 
968
 
  reserve(in_length*2 + 2);
969
 
  quote_char= (char) q;
970
 
  append(&quote_char, 1, system_charset_info);
971
 
 
972
 
  for (name_end= name+in_length ; name < name_end ; name+= in_length)
973
 
  {
974
 
    unsigned char chr= (unsigned char) *name;
975
 
    in_length= my_mbcharlen(system_charset_info, chr);
976
 
    /*
977
 
      my_mbcharlen can return 0 on a wrong multibyte
978
 
      sequence. It is possible when upgrading from 4.0,
979
 
      and identifier contains some accented characters.
980
 
      The manual says it does not work. So we'll just
981
 
      change length to 1 not to hang in the endless loop.
982
 
    */
983
 
    if (!in_length)
984
 
      in_length= 1;
985
 
    if (in_length == 1 && chr == (unsigned char) quote_char)
986
 
      append(&quote_char, 1, system_charset_info);
987
 
    append(name, in_length, system_charset_info);
988
 
  }
989
 
  append(&quote_char, 1, system_charset_info);
990
 
}
991
 
 
992
1066
 
993
1067
/*
994
1068
  Exchange state of this object and argument.
1008
1082
  std::swap(alloced, s.alloced);
1009
1083
  std::swap(str_charset, s.str_charset);
1010
1084
}
1011
 
 
1012
 
 
1013
 
bool operator==(const String &s1, const String &s2)
1014
 
{
1015
 
  return stringcmp(&s1,&s2) == 0;
1016
 
}
1017
 
 
1018
 
bool operator!=(const String &s1, const String &s2)
1019
 
{
1020
 
  return !(s1 == s2);
1021
 
}
1022