~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.cc

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include <mysys/my_sys.h>
20
20
#include <mystrings/m_string.h>
21
21
 
22
 
#include <algorithm>
23
 
 
24
22
/*
25
23
  The following extern declarations are ok as these are interface functions
26
24
  required by the string function
27
25
*/
28
26
 
29
 
extern unsigned char* sql_alloc(unsigned size);
 
27
extern uchar* sql_alloc(unsigned size);
30
28
extern void sql_element_free(void *ptr);
31
29
 
32
30
#include "sql_string.h"
91
89
 
92
90
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
93
91
{
94
 
  uint32_t l=20*cs->mbmaxlen+1;
 
92
  uint l=20*cs->mbmaxlen+1;
95
93
  int base= unsigned_flag ? 10 : -10;
96
94
 
97
95
  if (alloc(l))
101
99
  return false;
102
100
}
103
101
 
104
 
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
 
102
bool String::set_real(double num,uint decimals, const CHARSET_INFO * const cs)
105
103
{
106
104
  char buff[FLOATING_POINT_BUFFER];
107
 
  uint32_t dummy_errors;
 
105
  uint dummy_errors;
108
106
  size_t len;
109
107
 
110
108
  str_charset=cs;
260
258
 
261
259
bool String::copy(const char *str, uint32_t arg_length,
262
260
                          const CHARSET_INFO * const from_cs,
263
 
                                  const CHARSET_INFO * const to_cs, uint32_t *errors)
 
261
                                  const CHARSET_INFO * const to_cs, uint *errors)
264
262
{
265
263
  uint32_t offset;
266
264
  if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
309
307
    set(str, arg_length, str_charset);
310
308
    return 0;
311
309
  }
312
 
  uint32_t dummy_errors;
 
310
  uint dummy_errors;
313
311
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
314
312
}
315
313
 
358
356
  if (str_charset->mbminlen > 1)
359
357
  {
360
358
    uint32_t add_length=arg_length * str_charset->mbmaxlen;
361
 
    uint32_t dummy_errors;
 
359
    uint dummy_errors;
362
360
    if (realloc(str_length+ add_length))
363
361
      return true;
364
362
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
400
398
  if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
401
399
  {
402
400
    uint32_t add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
403
 
    uint32_t dummy_errors;
 
401
    uint dummy_errors;
404
402
    if (realloc(str_length + add_length)) 
405
403
      return true;
406
404
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
421
419
{
422
420
  if (realloc(str_length+arg_length))
423
421
    return true;
424
 
  if (my_b_read(file, (unsigned char*) Ptr + str_length, arg_length))
 
422
  if (my_b_read(file, (uchar*) Ptr + str_length, arg_length))
425
423
  {
426
424
    shrink(str_length);
427
425
    return true;
546
544
      {
547
545
        if (realloc(str_length+(uint32_t) diff))
548
546
          return true;
549
 
        bmove_upp((unsigned char*) Ptr+str_length+diff, (unsigned char*) Ptr+str_length,
 
547
        bmove_upp((uchar*) Ptr+str_length+diff, (uchar*) Ptr+str_length,
550
548
                  str_length-offset-arg_length);
551
549
      }
552
550
      if (to_length)
563
561
{
564
562
  if (Alloced_length < str_length + space_needed)
565
563
  {
566
 
    if (realloc(Alloced_length + cmax(space_needed, grow_by) - 1))
 
564
    if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
567
565
      return true;
568
566
  }
569
567
  return false;
595
593
  str_length+= (int) (end-buff);
596
594
}
597
595
 
598
 
void String::qs_append(uint32_t i)
 
596
void String::qs_append(uint i)
599
597
{
600
598
  char *buff= Ptr + str_length;
601
599
  char *end= int10_to_str(i, buff, 10);
624
622
int sortcmp(const String *s,const String *t, const CHARSET_INFO * const cs)
625
623
{
626
624
 return cs->coll->strnncollsp(cs,
627
 
                              (unsigned char *) s->ptr(),s->length(),
628
 
                              (unsigned char *) t->ptr(),t->length(), 0);
 
625
                              (uchar *) s->ptr(),s->length(),
 
626
                              (uchar *) t->ptr(),t->length(), 0);
629
627
}
630
628
 
631
629
 
638
636
    t           Second string
639
637
 
640
638
  NOTE:
641
 
    Strings are compared as a stream of unsigned chars
 
639
    Strings are compared as a stream of uchars
642
640
 
643
641
  RETURN
644
642
  < 0   s < t
649
647
 
650
648
int stringcmp(const String *s,const String *t)
651
649
{
652
 
  uint32_t s_len=s->length(),t_len=t->length(),len=cmin(s_len,t_len);
 
650
  uint32_t s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
653
651
  int cmp= memcmp(s->ptr(), t->ptr(), len);
654
652
  return (cmp) ? cmp : (int) (s_len - t_len);
655
653
}
666
664
  }
667
665
  if (to->realloc(from_length))
668
666
    return from;                                // Actually an error
669
 
  if ((to->str_length=cmin(from->str_length,from_length)))
 
667
  if ((to->str_length=min(from->str_length,from_length)))
670
668
    memcpy(to->Ptr,from->Ptr,to->str_length);
671
669
  to->str_charset=from->str_charset;
672
670
  return to;
701
699
                          const CHARSET_INFO * const to_cs, 
702
700
                          const char *from, uint32_t from_length,
703
701
                          const CHARSET_INFO * const from_cs,
704
 
                          uint32_t *errors)
 
702
                          uint *errors)
705
703
{
706
704
  int         cnvres;
707
705
  my_wc_t     wc;
708
 
  const unsigned char *from_end= (const unsigned char*) from+from_length;
 
706
  const uchar *from_end= (const uchar*) from+from_length;
709
707
  char *to_start= to;
710
 
  unsigned char *to_end= (unsigned char*) to+to_length;
 
708
  uchar *to_end= (uchar*) to+to_length;
711
709
  my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
712
710
  my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
713
 
  uint32_t error_count= 0;
 
711
  uint error_count= 0;
714
712
 
715
713
  while (1)
716
714
  {
717
 
    if ((cnvres= (*mb_wc)(from_cs, &wc, (unsigned char*) from,
 
715
    if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from,
718
716
                                      from_end)) > 0)
719
717
      from+= cnvres;
720
718
    else if (cnvres == MY_CS_ILSEQ)
737
735
      break;  // Not enough characters
738
736
 
739
737
outp:
740
 
    if ((cnvres= (*wc_mb)(to_cs, wc, (unsigned char*) to, to_end)) > 0)
 
738
    if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
741
739
      to+= cnvres;
742
740
    else if (cnvres == MY_CS_ILUNI && wc != '?')
743
741
    {
759
757
uint32_t
760
758
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs, 
761
759
                 const char *from, uint32_t from_length,
762
 
                                 const CHARSET_INFO * const from_cs, uint32_t *errors)
 
760
                                 const CHARSET_INFO * const from_cs, uint *errors)
763
761
{
764
762
  /*
765
763
    If any of the character sets is not ASCII compatible,
769
767
    return copy_and_convert_extended(to, to_length, to_cs,
770
768
                                     from, from_length, from_cs, errors);
771
769
 
772
 
  uint32_t length= cmin(to_length, from_length), length2= length;
 
770
  uint32_t length= min(to_length, from_length), length2= length;
773
771
 
774
772
#if defined(__i386__)
775
773
  /*
903
901
 
904
902
uint32_t
905
903
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
906
 
                        char *to, uint32_t to_length,
 
904
                        char *to, uint to_length,
907
905
                        const CHARSET_INFO * const from_cs,
908
 
                        const char *from, uint32_t from_length,
909
 
                        uint32_t nchars,
 
906
                        const char *from, uint from_length,
 
907
                        uint nchars,
910
908
                        const char **well_formed_error_pos,
911
909
                        const char **cannot_convert_error_pos,
912
910
                        const char **from_end_pos)
913
911
{
914
 
  uint32_t res;
 
912
  uint res;
915
913
 
916
914
  if ((to_cs == &my_charset_bin) || 
917
915
      (from_cs == &my_charset_bin) ||
928
926
 
929
927
    if (to_cs == &my_charset_bin)
930
928
    {
931
 
      res= cmin(cmin(nchars, to_length), from_length);
 
929
      res= min(min(nchars, to_length), from_length);
932
930
      memmove(to, from, res);
933
931
      *from_end_pos= from + res;
934
932
      *well_formed_error_pos= NULL;
937
935
    else
938
936
    {
939
937
      int well_formed_error;
940
 
      uint32_t from_offset;
 
938
      uint from_offset;
941
939
 
942
940
      if ((from_offset= (from_length % to_cs->mbminlen)) &&
943
941
          (from_cs == &my_charset_bin))
947
945
          INSERT INTO t1 (ucs2_column) VALUES (0x01);
948
946
          0x01 -> 0x0001
949
947
        */
950
 
        uint32_t pad_length= to_cs->mbminlen - from_offset;
 
948
        uint pad_length= to_cs->mbminlen - from_offset;
951
949
        memset(to, 0, pad_length);
952
950
        memmove(to + pad_length, from, from_offset);
953
951
        nchars--;
974
972
    my_wc_t wc;
975
973
    my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
976
974
    my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
977
 
    const unsigned char *from_end= (const unsigned char*) from + from_length;
978
 
    unsigned char *to_end= (unsigned char*) to + to_length;
 
975
    const uchar *from_end= (const uchar*) from + from_length;
 
976
    uchar *to_end= (uchar*) to + to_length;
979
977
    char *to_start= to;
980
978
    *well_formed_error_pos= NULL;
981
979
    *cannot_convert_error_pos= NULL;
983
981
    for ( ; nchars; nchars--)
984
982
    {
985
983
      const char *from_prev= from;
986
 
      if ((cnvres= (*mb_wc)(from_cs, &wc, (unsigned char*) from, from_end)) > 0)
 
984
      if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from, from_end)) > 0)
987
985
        from+= cnvres;
988
986
      else if (cnvres == MY_CS_ILSEQ)
989
987
      {
1007
1005
        break;  // Not enough characters
1008
1006
 
1009
1007
outp:
1010
 
      if ((cnvres= (*wc_mb)(to_cs, wc, (unsigned char*) to, to_end)) > 0)
 
1008
      if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
1011
1009
        to+= cnvres;
1012
1010
      else if (cnvres == MY_CS_ILUNI && wc != '?')
1013
1011
      {
1036
1034
  char *st= (char*)Ptr, *end= st+str_length;
1037
1035
  for (; st < end; st++)
1038
1036
  {
1039
 
    unsigned char c= *st;
 
1037
    uchar c= *st;
1040
1038
    switch (c)
1041
1039
    {
1042
1040
    case '\\':
1043
 
      str->append("\\\\", sizeof("\\\\")-1);
 
1041
      str->append(STRING_WITH_LEN("\\\\"));
1044
1042
      break;
1045
1043
    case '\0':
1046
 
      str->append("\\0", sizeof("\\0")-1);
 
1044
      str->append(STRING_WITH_LEN("\\0"));
1047
1045
      break;
1048
1046
    case '\'':
1049
 
      str->append("\\'", sizeof("\\'")-1);
 
1047
      str->append(STRING_WITH_LEN("\\'"));
1050
1048
      break;
1051
1049
    case '\n':
1052
 
      str->append("\\n", sizeof("\\n")-1);
 
1050
      str->append(STRING_WITH_LEN("\\n"));
1053
1051
      break;
1054
1052
    case '\r':
1055
 
      str->append("\\r", sizeof("\\r")-1);
 
1053
      str->append(STRING_WITH_LEN("\\r"));
1056
1054
      break;
1057
1055
    case '\032': // Ctrl-Z
1058
 
      str->append("\\Z", sizeof("\\Z")-1);
 
1056
      str->append(STRING_WITH_LEN("\\Z"));
1059
1057
      break;
1060
1058
    default:
1061
1059
      str->append(c);