~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

  • Committer: Brian Aker
  • Date: 2009-05-15 17:06:35 UTC
  • mto: This revision was merged to the branch mainline in revision 1023.
  • Revision ID: brian@gaz-20090515170635-croy1u63a3gqdn9n
Dead convert functions for character sets.

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*) my_malloc(arg_length,MYF(MY_WME))))
 
45
    if (!(Ptr=(char*) malloc(arg_length)))
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*) my_realloc(Ptr,len,MYF(MY_WME))))
 
68
      if ((new_ptr= (char*) ::realloc(Ptr,len)))
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*) my_malloc(len,MYF(MY_WME))))
 
76
    else if ((new_ptr= (char*) malloc(len)))
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
 
}
243
194
 
244
195
 
245
196
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
246
197
                                 const CHARSET_INFO * const cs)
247
198
{
248
199
  /* How many bytes are in incomplete character */
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);
 
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;
257
206
}
258
207
 
259
208
        /* Copy with charset conversion */
260
209
 
261
210
bool String::copy(const char *str, uint32_t arg_length,
262
 
                          const CHARSET_INFO * const from_cs,
 
211
                          const CHARSET_INFO * const,
263
212
                                  const CHARSET_INFO * const to_cs, uint32_t *errors)
264
213
{
265
 
  uint32_t offset;
266
 
  if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
267
 
  {
268
 
    *errors= 0;
269
 
    return copy(str, arg_length, to_cs);
270
 
  }
271
 
  if ((from_cs == &my_charset_bin) && offset)
272
 
  {
273
 
    *errors= 0;
274
 
    return copy_aligned(str, arg_length, offset, to_cs);
275
 
  }
276
 
  uint32_t new_length= to_cs->mbmaxlen*arg_length;
277
 
  if (alloc(new_length))
278
 
    return true;
279
 
  str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
280
 
                              str, arg_length, from_cs, errors);
281
 
  str_charset=to_cs;
282
 
  return false;
 
214
  *errors= 0;
 
215
  return copy(str, arg_length, to_cs);
283
216
}
284
217
 
285
218
 
286
219
/*
287
220
  Set a string to the value of a latin1-string, keeping the original charset
288
 
  
 
221
 
289
222
  SYNOPSIS
290
223
    copy_or_set()
291
224
    str                 String of a simple charset (latin1)
313
246
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
314
247
}
315
248
 
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
 
 
333
249
bool String::append(const String &s)
334
250
{
335
251
  if (s.length())
393
309
  with character set recoding
394
310
*/
395
311
 
396
 
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs)
397
 
{
398
 
  uint32_t dummy_offset;
399
 
  
400
 
  if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
401
 
  {
402
 
    uint32_t add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
403
 
    uint32_t dummy_errors;
404
 
    if (realloc(str_length + add_length)) 
405
 
      return true;
406
 
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
407
 
                                  s, arg_length, cs, &dummy_errors);
408
 
  }
409
 
  else
410
 
  {
411
 
    if (realloc(str_length + arg_length)) 
412
 
      return true;
413
 
    memcpy(Ptr + str_length, s, arg_length);
414
 
    str_length+= arg_length;
415
 
  }
416
 
  return false;
417
 
}
418
 
 
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
 
}
 
312
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const)
 
313
{
 
314
  if (realloc(str_length + arg_length))
 
315
    return true;
 
316
  memcpy(Ptr + str_length, s, arg_length);
 
317
  str_length+= arg_length;
 
318
 
 
319
  return false;
 
320
}
 
321
 
432
322
 
433
323
bool String::append_with_prefill(const char *s,uint32_t arg_length,
434
324
                 uint32_t full_length, char fill_char)
537
427
    {
538
428
      if (to_length)
539
429
        memcpy(Ptr+offset,to,to_length);
540
 
      memcpy(Ptr+offset+to_length, Ptr+offset+arg_length,
541
 
             str_length-offset-arg_length);
 
430
      memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
 
431
              str_length-offset-arg_length);
542
432
    }
543
433
    else
544
434
    {
558
448
}
559
449
 
560
450
 
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
 
}
604
451
 
605
452
/*
606
453
  Compare strings according to collation, without end space.
679
526
 
680
527
/*
681
528
  copy a string from one character set to another
682
 
  
 
529
 
683
530
  SYNOPSIS
684
531
    copy_and_convert()
685
532
    to                  Store result here
698
545
 
699
546
static uint32_t
700
547
copy_and_convert_extended(char *to, uint32_t to_length,
701
 
                          const CHARSET_INFO * const to_cs, 
 
548
                          const CHARSET_INFO * const to_cs,
702
549
                          const char *from, uint32_t from_length,
703
550
                          const CHARSET_INFO * const from_cs,
704
551
                          uint32_t *errors)
757
604
  Optimized for quick copying of ASCII characters in the range 0x00..0x7F.
758
605
*/
759
606
uint32_t
760
 
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs, 
 
607
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs,
761
608
                 const char *from, uint32_t from_length,
762
609
                                 const CHARSET_INFO * const from_cs, uint32_t *errors)
763
610
{
807
654
    }
808
655
  }
809
656
 
810
 
  assert(false); // Should never get to here
 
657
#ifndef __sun
811
658
  return 0;           // Make compiler happy
 
659
#endif
812
660
}
813
661
 
814
662
 
820
668
  are read from "src". Any sequences of bytes representing
821
669
  a not-well-formed substring (according to cs) are hex-encoded,
822
670
  and all well-formed substrings (according to cs) are copied as is.
823
 
  Not more than "dstlen" bytes are written to "dst". The number 
 
671
  Not more than "dstlen" bytes are written to "dst". The number
824
672
  of bytes written to "dst" is returned.
825
 
  
 
673
 
826
674
   @param      cs       character set pointer of the destination string
827
675
   @param[out] dst      destination string
828
676
   @param      dstlen   size of dst
878
726
  copy a string,
879
727
  with optional character set conversion,
880
728
  with optional left padding (for binary -> UCS2 conversion)
881
 
  
 
729
 
882
730
  SYNOPSIS
883
731
    well_formed_copy_nchars()
884
732
    to                       Store result here
913
761
{
914
762
  uint32_t res;
915
763
 
916
 
  if ((to_cs == &my_charset_bin) || 
 
764
  if ((to_cs == &my_charset_bin) ||
917
765
      (from_cs == &my_charset_bin) ||
918
766
      (to_cs == from_cs) ||
919
767
      my_charset_same(from_cs, to_cs))
1040
888
    switch (c)
1041
889
    {
1042
890
    case '\\':
1043
 
      str->append(STRING_WITH_LEN("\\\\"));
 
891
      str->append("\\\\", sizeof("\\\\")-1);
1044
892
      break;
1045
893
    case '\0':
1046
 
      str->append(STRING_WITH_LEN("\\0"));
 
894
      str->append("\\0", sizeof("\\0")-1);
1047
895
      break;
1048
896
    case '\'':
1049
 
      str->append(STRING_WITH_LEN("\\'"));
 
897
      str->append("\\'", sizeof("\\'")-1);
1050
898
      break;
1051
899
    case '\n':
1052
 
      str->append(STRING_WITH_LEN("\\n"));
 
900
      str->append("\\n", sizeof("\\n")-1);
1053
901
      break;
1054
902
    case '\r':
1055
 
      str->append(STRING_WITH_LEN("\\r"));
 
903
      str->append("\\r", sizeof("\\r")-1);
1056
904
      break;
1057
905
    case '\032': // Ctrl-Z
1058
 
      str->append(STRING_WITH_LEN("\\Z"));
 
906
      str->append("\\Z", sizeof("\\Z")-1);
1059
907
      break;
1060
908
    default:
1061
909
      str->append(c);
1063
911
  }
1064
912
}
1065
913
 
 
914
/*
 
915
  Quote the given identifier.
 
916
  If the given identifier is empty, it will be quoted.
 
917
 
 
918
  SYNOPSIS
 
919
  append_identifier()
 
920
  name                  the identifier to be appended
 
921
  name_length           length of the appending identifier
 
922
*/
 
923
 
 
924
/* Factor the extern out */
 
925
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
 
926
 
 
927
void String::append_identifier(const char *name, uint32_t in_length)
 
928
{
 
929
  const char *name_end;
 
930
  char quote_char;
 
931
  int q= '`';
 
932
 
 
933
  /*
 
934
    The identifier must be quoted as it includes a quote character or
 
935
   it's a keyword
 
936
  */
 
937
 
 
938
  reserve(in_length*2 + 2);
 
939
  quote_char= (char) q;
 
940
  append(&quote_char, 1, system_charset_info);
 
941
 
 
942
  for (name_end= name+in_length ; name < name_end ; name+= in_length)
 
943
  {
 
944
    unsigned char chr= (unsigned char) *name;
 
945
    in_length= my_mbcharlen(system_charset_info, chr);
 
946
    /*
 
947
      my_mbcharlen can return 0 on a wrong multibyte
 
948
      sequence. It is possible when upgrading from 4.0,
 
949
      and identifier contains some accented characters.
 
950
      The manual says it does not work. So we'll just
 
951
      change length to 1 not to hang in the endless loop.
 
952
    */
 
953
    if (!in_length)
 
954
      in_length= 1;
 
955
    if (in_length == 1 && chr == (unsigned char) quote_char)
 
956
      append(&quote_char, 1, system_charset_info);
 
957
    append(name, in_length, system_charset_info);
 
958
  }
 
959
  append(&quote_char, 1, system_charset_info);
 
960
}
 
961
 
1066
962
 
1067
963
/*
1068
964
  Exchange state of this object and argument.
1082
978
  std::swap(alloced, s.alloced);
1083
979
  std::swap(str_charset, s.str_charset);
1084
980
}
 
981
 
 
982
 
 
983
bool operator==(const String &s1, const String &s2)
 
984
{
 
985
  return stringcmp(&s1,&s2) == 0;
 
986
}
 
987
 
 
988
bool operator!=(const String &s1, const String &s2)
 
989
{
 
990
  return !(s1 == s2);
 
991
}
 
992