Commit 95ffd436 authored by bar@bar.mysql.r18.ru's avatar bar@bar.mysql.r18.ru

Fixes for fault about String::copy()

parent 1f5b2898
...@@ -952,7 +952,7 @@ static bool add_line(String &buffer,char *line,char *in_string) ...@@ -952,7 +952,7 @@ static bool add_line(String &buffer,char *line,char *in_string)
} }
if ((com=find_command(NullS,(char) inchar))) if ((com=find_command(NullS,(char) inchar)))
{ {
const String tmp(line,(uint) (out-line)); const String tmp(line,(uint) (out-line), system_charset_info);
buffer.append(tmp); buffer.append(tmp);
if ((*com->func)(&buffer,pos-1) > 0) if ((*com->func)(&buffer,pos-1) > 0)
return 1; // Quit return 1; // Quit
...@@ -1709,7 +1709,7 @@ print_table_data(MYSQL_RES *result) ...@@ -1709,7 +1709,7 @@ print_table_data(MYSQL_RES *result)
print_field_types(result); print_field_types(result);
mysql_field_seek(result,0); mysql_field_seek(result,0);
} }
separator.copy("+",1); separator.copy("+",1,system_charset_info);
while ((field = mysql_fetch_field(result))) while ((field = mysql_fetch_field(result)))
{ {
uint length= column_names ? (uint) strlen(field->name) : 0; uint length= column_names ? (uint) strlen(field->name) : 0;
......
...@@ -40,19 +40,16 @@ extern void sql_element_free(void *ptr); ...@@ -40,19 +40,16 @@ extern void sql_element_free(void *ptr);
bool String::real_alloc(uint32 arg_length) bool String::real_alloc(uint32 arg_length)
{ {
arg_length=ALIGN_SIZE(arg_length+1); arg_length=ALIGN_SIZE(arg_length+1);
str_length=0;
if (Alloced_length < arg_length) if (Alloced_length < arg_length)
{ {
free(); free();
if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME)))) if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))
{
str_length=0;
return TRUE; return TRUE;
}
Alloced_length=arg_length; Alloced_length=arg_length;
alloced=1; alloced=1;
} }
Ptr[0]=0; Ptr[0]=0;
str_length=0;
return FALSE; return FALSE;
} }
...@@ -94,36 +91,40 @@ bool String::realloc(uint32 alloc_length) ...@@ -94,36 +91,40 @@ bool String::realloc(uint32 alloc_length)
return FALSE; return FALSE;
} }
bool String::set(longlong num) bool String::set(longlong num, CHARSET_INFO *cs)
{ {
if (alloc(21)) if (alloc(21))
return TRUE; return TRUE;
str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr); str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr);
str_charset=cs;
return FALSE; return FALSE;
} }
bool String::set(ulonglong num) bool String::set(ulonglong num, CHARSET_INFO *cs)
{ {
if (alloc(21)) if (alloc(21))
return TRUE; return TRUE;
str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr); str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr);
str_charset=cs;
return FALSE; return FALSE;
} }
bool String::set(double num,uint decimals) bool String::set(double num,uint decimals, CHARSET_INFO *cs)
{ {
char buff[331]; char buff[331];
str_charset=cs;
if (decimals >= NOT_FIXED_DEC) if (decimals >= NOT_FIXED_DEC)
{ {
sprintf(buff,"%.14g",num); // Enough for a DATETIME sprintf(buff,"%.14g",num); // Enough for a DATETIME
return copy(buff, (uint32) strlen(buff)); return copy(buff, (uint32) strlen(buff), my_charset_latin1);
} }
#ifdef HAVE_FCONVERT #ifdef HAVE_FCONVERT
int decpt,sign; int decpt,sign;
char *pos,*to; char *pos,*to;
VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1)); VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1));
if (!isdigit(buff[1])) if (!my_isdigit(system_charset_info, buff[1]))
{ // Nan or Inf { // Nan or Inf
pos=buff+1; pos=buff+1;
if (sign) if (sign)
...@@ -181,7 +182,7 @@ end: ...@@ -181,7 +182,7 @@ end:
#else #else
sprintf(buff,"%.*f",(int) decimals,num); sprintf(buff,"%.*f",(int) decimals,num);
#endif #endif
return copy(buff,(uint32) strlen(buff)); return copy(buff,(uint32) strlen(buff), my_charset_latin1);
#endif #endif
} }
...@@ -203,16 +204,18 @@ bool String::copy(const String &str) ...@@ -203,16 +204,18 @@ bool String::copy(const String &str)
str_length=str.str_length; str_length=str.str_length;
bmove(Ptr,str.Ptr,str_length); // May be overlapping bmove(Ptr,str.Ptr,str_length); // May be overlapping
Ptr[str_length]=0; Ptr[str_length]=0;
str_charset=str.str_charset;
return FALSE; return FALSE;
} }
bool String::copy(const char *str,uint32 arg_length) bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
{ {
if (alloc(arg_length)) if (alloc(arg_length))
return TRUE; return TRUE;
if ((str_length=arg_length)) if ((str_length=arg_length))
memcpy(Ptr,str,arg_length); memcpy(Ptr,str,arg_length);
Ptr[arg_length]=0; Ptr[arg_length]=0;
str_charset=cs;
return FALSE; return FALSE;
} }
...@@ -489,7 +492,7 @@ void String::qs_append(double d) ...@@ -489,7 +492,7 @@ void String::qs_append(double d)
void String::qs_append(double *d) void String::qs_append(double *d)
{ {
double ld; double ld;
float8get(ld, d); float8get(ld, (char*) d);
qs_append(ld); qs_append(ld);
} }
...@@ -523,12 +526,23 @@ int sortcmp(const String *x,const String *y) ...@@ -523,12 +526,23 @@ int sortcmp(const String *x,const String *y)
#endif /* USE_STRCOLL */ #endif /* USE_STRCOLL */
x_len-=len; // For easy end space test x_len-=len; // For easy end space test
y_len-=len; y_len-=len;
while (len--) if (x->str_charset->sort_order)
{ {
if (x->str_charset->sort_order[(uchar) *s++] != while (len--)
{
if (x->str_charset->sort_order[(uchar) *s++] !=
x->str_charset->sort_order[(uchar) *t++]) x->str_charset->sort_order[(uchar) *t++])
return ((int) x->str_charset->sort_order[(uchar) s[-1]] - return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
(int) x->str_charset->sort_order[(uchar) t[-1]]); (int) x->str_charset->sort_order[(uchar) t[-1]]);
}
}
else
{
while (len--)
{
if (*s++ != *t++)
return ((int) s[-1] - (int) t[-1]);
}
} }
#ifndef CMP_ENDSPACE #ifndef CMP_ENDSPACE
/* Don't compare end space in strings */ /* Don't compare end space in strings */
...@@ -586,6 +600,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) ...@@ -586,6 +600,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
return from; // Actually an error return from; // Actually an error
if ((to->str_length=min(from->str_length,from_length))) if ((to->str_length=min(from->str_length,from_length)))
memcpy(to->Ptr,from->Ptr,to->str_length); memcpy(to->Ptr,from->Ptr,to->str_length);
to->str_charset=from->str_charset;
return to; return to;
} }
...@@ -658,7 +673,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, ...@@ -658,7 +673,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end,
{ // Found wild_many { // Found wild_many
wildstr++; wildstr++;
/* Remove any '%' and '_' from the wild search string */ /* Remove any '%' and '_' from the wild search string */
for ( ; wildstr != wildend ; wildstr++) for (; wildstr != wildend ; wildstr++)
{ {
if (*wildstr == wild_many) if (*wildstr == wild_many)
continue; continue;
...@@ -787,7 +802,7 @@ int wild_compare(const char *str,const char *str_end, ...@@ -787,7 +802,7 @@ int wild_compare(const char *str,const char *str_end,
{ // Found wild_many { // Found wild_many
wildstr++; wildstr++;
/* Remove any '%' and '_' from the wild search string */ /* Remove any '%' and '_' from the wild search string */
for ( ; wildstr != wildend ; wildstr++) for (; wildstr != wildend ; wildstr++)
{ {
if (*wildstr == wild_many) if (*wildstr == wild_many)
continue; continue;
......
...@@ -46,22 +46,22 @@ public: ...@@ -46,22 +46,22 @@ public:
String(uint32 length_arg) String(uint32 length_arg)
{ {
alloced=0; Alloced_length=0; (void) real_alloc(length_arg); alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
str_charset=default_charset_info; str_charset=default_charset_info;
} }
String(const char *str) String(const char *str, CHARSET_INFO *cs)
{ {
Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
str_charset=default_charset_info; str_charset=cs;
} }
String(const char *str,uint32 len) String(const char *str,uint32 len, CHARSET_INFO *cs)
{ {
Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
str_charset=default_charset_info; str_charset=cs;
} }
String(char *str,uint32 len) String(char *str,uint32 len, CHARSET_INFO *cs)
{ {
Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
str_charset=default_charset_info; str_charset=cs;
} }
String(const String &str) String(const String &str)
{ {
...@@ -74,6 +74,7 @@ public: ...@@ -74,6 +74,7 @@ public:
{ sql_element_free(ptr_arg); } { sql_element_free(ptr_arg); }
~String() { free(); } ~String() { free(); }
inline void set_charset(CHARSET_INFO *charset) { str_charset=charset; }
inline CHARSET_INFO *charset() const { return str_charset; } inline CHARSET_INFO *charset() const { return str_charset; }
inline uint32 length() const { return str_length;} inline uint32 length() const { return str_length;}
inline uint32 alloced_length() const { return Alloced_length;} inline uint32 alloced_length() const { return Alloced_length;}
...@@ -102,28 +103,31 @@ public: ...@@ -102,28 +103,31 @@ public:
Alloced_length=str.Alloced_length-offset; Alloced_length=str.Alloced_length-offset;
else else
Alloced_length=0; Alloced_length=0;
str_charset=str.str_charset;
} }
inline void set(char *str,uint32 arg_length) inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
{ {
free(); free();
Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
str_charset=cs;
} }
inline void set(const char *str,uint32 arg_length) inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs)
{ {
free(); free();
Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
str_charset=cs;
} }
inline void set_quick(char *str,uint32 arg_length) inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
{ {
if (!alloced) if (!alloced)
{ {
Ptr=(char*) str; str_length=Alloced_length=arg_length; Ptr=(char*) str; str_length=Alloced_length=arg_length;
} }
str_charset=cs;
} }
bool set(longlong num); bool set(longlong num, CHARSET_INFO *cs);
/* bool set(long num); */ bool set(ulonglong num, CHARSET_INFO *cs);
bool set(ulonglong num); bool set(double num,uint decimals, CHARSET_INFO *cs);
bool set(double num,uint decimals=2);
inline void free() inline void free()
{ {
if (alloced) if (alloced)
...@@ -174,7 +178,7 @@ public: ...@@ -174,7 +178,7 @@ public:
bool copy(); // Alloc string if not alloced bool copy(); // Alloc string if not alloced
bool copy(const String &s); // Allocate new string bool copy(const String &s); // Allocate new string
bool copy(const char *s,uint32 arg_length); // Allocate new string bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
bool append(const String &s); bool append(const String &s);
bool append(const char *s,uint32 arg_length=0); bool append(const char *s,uint32 arg_length=0);
bool append(IO_CACHE* file, uint32 arg_length); bool append(IO_CACHE* file, uint32 arg_length);
...@@ -208,16 +212,17 @@ public: ...@@ -208,16 +212,17 @@ public:
uint32 numchars(); uint32 numchars();
int charpos(int i,uint32 offset=0); int charpos(int i,uint32 offset=0);
// added by Holyfoot for "geometry" needs
int reserve(uint32 space_needed) int reserve(uint32 space_needed)
{ {
return realloc(str_length + space_needed); return realloc(str_length + space_needed);
} }
int reserve(uint32 space_needed, uint32 grow_by); int reserve(uint32 space_needed, uint32 grow_by);
// these append operations do NOT check alloced memory /*
// q_*** methods writes values of parameters itself The following append operations do NOT check alloced memory
// qs_*** methods writes string representation of value q_*** methods writes values of parameters itself
qs_*** methods writes string representation of value
*/
void q_append(const char &c) void q_append(const char &c)
{ {
Ptr[str_length++] = c; Ptr[str_length++] = c;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment