~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

Moved the last of the libdrizzleclient calls into Protocol.

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 */
271
220
  if ((from_cs == &my_charset_bin) && offset)
272
221
  {
273
222
    *errors= 0;
274
 
    return copy_aligned(str, arg_length, offset, to_cs);
 
223
    assert((from_cs == &my_charset_bin) && offset);
 
224
    return false; //copy_aligned(str, arg_length, offset, to_cs);
275
225
  }
276
226
  uint32_t new_length= to_cs->mbmaxlen*arg_length;
277
227
  if (alloc(new_length))
285
235
 
286
236
/*
287
237
  Set a string to the value of a latin1-string, keeping the original charset
288
 
  
 
238
 
289
239
  SYNOPSIS
290
240
    copy_or_set()
291
241
    str                 String of a simple charset (latin1)
313
263
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
314
264
}
315
265
 
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
266
bool String::append(const String &s)
334
267
{
335
268
  if (s.length())
396
329
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs)
397
330
{
398
331
  uint32_t dummy_offset;
399
 
  
 
332
 
400
333
  if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
401
334
  {
402
335
    uint32_t add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
403
336
    uint32_t dummy_errors;
404
 
    if (realloc(str_length + add_length)) 
 
337
    if (realloc(str_length + add_length))
405
338
      return true;
406
339
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
407
340
                                  s, arg_length, cs, &dummy_errors);
408
341
  }
409
342
  else
410
343
  {
411
 
    if (realloc(str_length + arg_length)) 
 
344
    if (realloc(str_length + arg_length))
412
345
      return true;
413
346
    memcpy(Ptr + str_length, s, arg_length);
414
347
    str_length+= arg_length;
417
350
}
418
351
 
419
352
 
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
 
 
433
353
bool String::append_with_prefill(const char *s,uint32_t arg_length,
434
354
                 uint32_t full_length, char fill_char)
435
355
{
537
457
    {
538
458
      if (to_length)
539
459
        memcpy(Ptr+offset,to,to_length);
540
 
      memcpy(Ptr+offset+to_length, Ptr+offset+arg_length,
541
 
             str_length-offset-arg_length);
 
460
      memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
 
461
              str_length-offset-arg_length);
542
462
    }
543
463
    else
544
464
    {
558
478
}
559
479
 
560
480
 
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
481
 
605
482
/*
606
483
  Compare strings according to collation, without end space.
679
556
 
680
557
/*
681
558
  copy a string from one character set to another
682
 
  
 
559
 
683
560
  SYNOPSIS
684
561
    copy_and_convert()
685
562
    to                  Store result here
698
575
 
699
576
static uint32_t
700
577
copy_and_convert_extended(char *to, uint32_t to_length,
701
 
                          const CHARSET_INFO * const to_cs, 
 
578
                          const CHARSET_INFO * const to_cs,
702
579
                          const char *from, uint32_t from_length,
703
580
                          const CHARSET_INFO * const from_cs,
704
581
                          uint32_t *errors)
757
634
  Optimized for quick copying of ASCII characters in the range 0x00..0x7F.
758
635
*/
759
636
uint32_t
760
 
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs, 
 
637
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs,
761
638
                 const char *from, uint32_t from_length,
762
639
                                 const CHARSET_INFO * const from_cs, uint32_t *errors)
763
640
{
807
684
    }
808
685
  }
809
686
 
810
 
  assert(false); // Should never get to here
 
687
#ifndef __sun
811
688
  return 0;           // Make compiler happy
 
689
#endif
812
690
}
813
691
 
814
692
 
820
698
  are read from "src". Any sequences of bytes representing
821
699
  a not-well-formed substring (according to cs) are hex-encoded,
822
700
  and all well-formed substrings (according to cs) are copied as is.
823
 
  Not more than "dstlen" bytes are written to "dst". The number 
 
701
  Not more than "dstlen" bytes are written to "dst". The number
824
702
  of bytes written to "dst" is returned.
825
 
  
 
703
 
826
704
   @param      cs       character set pointer of the destination string
827
705
   @param[out] dst      destination string
828
706
   @param      dstlen   size of dst
878
756
  copy a string,
879
757
  with optional character set conversion,
880
758
  with optional left padding (for binary -> UCS2 conversion)
881
 
  
 
759
 
882
760
  SYNOPSIS
883
761
    well_formed_copy_nchars()
884
762
    to                       Store result here
913
791
{
914
792
  uint32_t res;
915
793
 
916
 
  if ((to_cs == &my_charset_bin) || 
 
794
  if ((to_cs == &my_charset_bin) ||
917
795
      (from_cs == &my_charset_bin) ||
918
796
      (to_cs == from_cs) ||
919
797
      my_charset_same(from_cs, to_cs))
1040
918
    switch (c)
1041
919
    {
1042
920
    case '\\':
1043
 
      str->append(STRING_WITH_LEN("\\\\"));
 
921
      str->append("\\\\", sizeof("\\\\")-1);
1044
922
      break;
1045
923
    case '\0':
1046
 
      str->append(STRING_WITH_LEN("\\0"));
 
924
      str->append("\\0", sizeof("\\0")-1);
1047
925
      break;
1048
926
    case '\'':
1049
 
      str->append(STRING_WITH_LEN("\\'"));
 
927
      str->append("\\'", sizeof("\\'")-1);
1050
928
      break;
1051
929
    case '\n':
1052
 
      str->append(STRING_WITH_LEN("\\n"));
 
930
      str->append("\\n", sizeof("\\n")-1);
1053
931
      break;
1054
932
    case '\r':
1055
 
      str->append(STRING_WITH_LEN("\\r"));
 
933
      str->append("\\r", sizeof("\\r")-1);
1056
934
      break;
1057
935
    case '\032': // Ctrl-Z
1058
 
      str->append(STRING_WITH_LEN("\\Z"));
 
936
      str->append("\\Z", sizeof("\\Z")-1);
1059
937
      break;
1060
938
    default:
1061
939
      str->append(c);
1063
941
  }
1064
942
}
1065
943
 
 
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
 
1066
992
 
1067
993
/*
1068
994
  Exchange state of this object and argument.
1082
1008
  std::swap(alloced, s.alloced);
1083
1009
  std::swap(str_charset, s.str_charset);
1084
1010
}
 
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