diff options
Diffstat (limited to 'sql/sql_string.cc')
-rw-r--r-- | sql/sql_string.cc | 117 |
1 files changed, 84 insertions, 33 deletions
diff --git a/sql/sql_string.cc b/sql/sql_string.cc index ff6b2163630..3195f797e25 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -20,8 +20,7 @@ #pragma implementation // gcc: Class implementation #endif -#include <my_global.h> -#include <my_sys.h> +#include "mariadb.h" #include <m_string.h> #include <m_ctype.h> #include <mysql_com.h> @@ -132,6 +131,61 @@ bool String::set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs) return FALSE; } + +// Convert a number into its HEX representation +bool String::set_hex(ulonglong num) +{ + char *n_end; + if (alloc(65) || !(n_end= longlong2str(num, Ptr, 16))) + return true; + length((uint32) (n_end - Ptr)); + set_charset(&my_charset_latin1); + return false; +} + + +/** + Append a hex representation of the byte "value" into "to". + Note: + "to" is incremented for the caller by two bytes. It's passed by reference! + So it resembles a macros, hence capital letters in the name. +*/ +static inline void APPEND_HEX(char *&to, uchar value) +{ + *to++= _dig_vec_upper[((uchar) value) >> 4]; + *to++= _dig_vec_upper[((uchar) value) & 0x0F]; +} + + +void String::qs_append_hex(const char *str, uint32 len) +{ + const char *str_end= str + len; + for (char *to= Ptr + str_length ; str < str_end; str++) + APPEND_HEX(to, (uchar) *str); + str_length+= len * 2; +} + + +// Convert a string to its HEX representation +bool String::set_hex(const char *str, uint32 len) +{ + /* + Safety: cut the source string if "len" is too large. + Note, alloc() can allocate some more space than requested, due to: + - ALIGN_SIZE + - one extra byte for a null terminator + So cut the source string to 0x7FFFFFF0 rather than 0x7FFFFFFE. + */ + set_if_smaller(len, 0x7FFFFFF0); + if (alloc(len * 2)) + return true; + length(0); + qs_append_hex(str, len); + set_charset(&my_charset_latin1); + return false; +} + + bool String::set_real(double num,uint decimals, CHARSET_INFO *cs) { char buff[FLOATING_POINT_BUFFER]; @@ -244,7 +298,7 @@ bool String::copy_or_move(const char *str,size_t arg_length, CHARSET_INFO *cs) character_set_results is NULL. */ -bool String::needs_conversion(uint32 arg_length, +bool String::needs_conversion(size_t arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint32 *offset) @@ -255,7 +309,7 @@ bool String::needs_conversion(uint32 arg_length, (to_cs == from_cs) || my_charset_same(from_cs, to_cs) || ((from_cs == &my_charset_bin) && - (!(*offset=(arg_length % to_cs->mbminlen))))) + (!(*offset=(uint32)(arg_length % to_cs->mbminlen))))) return FALSE; return TRUE; } @@ -273,7 +327,7 @@ bool String::needs_conversion(uint32 arg_length, @return conversion needed */ -bool String::needs_conversion_on_storage(uint32 arg_length, +bool String::needs_conversion_on_storage(size_t arg_length, CHARSET_INFO *cs_from, CHARSET_INFO *cs_to) { @@ -322,14 +376,14 @@ bool String::needs_conversion_on_storage(uint32 arg_length, 1 error */ -bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset, +bool String::copy_aligned(const char *str, size_t arg_length, size_t offset, CHARSET_INFO *cs) { /* How many bytes are in incomplete character */ offset= cs->mbminlen - offset; /* How many zeros we should prepend */ DBUG_ASSERT(offset && offset != cs->mbminlen); - uint32 aligned_length= arg_length + offset; + size_t aligned_length= arg_length + offset; if (alloc(aligned_length)) return TRUE; @@ -342,17 +396,17 @@ bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset, memcpy(Ptr + offset, str, arg_length); Ptr[aligned_length]=0; /* str_length is always >= 0 as arg_length is != 0 */ - str_length= aligned_length; + str_length= (uint32)aligned_length; str_charset= cs; return FALSE; } -bool String::set_or_copy_aligned(const char *str,uint32 arg_length, +bool String::set_or_copy_aligned(const char *str, size_t arg_length, CHARSET_INFO *cs) { /* How many bytes are in incomplete character */ - uint32 offset= (arg_length % cs->mbminlen); + size_t offset= (arg_length % cs->mbminlen); if (!offset) { @@ -374,7 +428,7 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length, */ -bool String::copy(const char *str, uint32 arg_length, +bool String::copy(const char *str, size_t arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors) { uint32 offset; @@ -391,7 +445,7 @@ bool String::copy(const char *str, uint32 arg_length, *errors= 0; return copy_aligned(str, arg_length, offset, to_cs); } - uint32 new_length= to_cs->mbmaxlen*arg_length; + size_t new_length= to_cs->mbmaxlen*arg_length; if (alloc(new_length)) return TRUE; str_length=copy_and_convert((char*) Ptr, new_length, to_cs, @@ -420,7 +474,7 @@ bool String::copy(const char *str, uint32 arg_length, */ -bool String::set_ascii(const char *str, uint32 arg_length) +bool String::set_ascii(const char *str, size_t arg_length) { if (str_charset->mbminlen == 1) { @@ -428,7 +482,7 @@ bool String::set_ascii(const char *str, uint32 arg_length) return 0; } uint dummy_errors; - return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors); + return copy(str, (uint32)arg_length, &my_charset_latin1, str_charset, &dummy_errors); } @@ -537,16 +591,16 @@ bool String::append_ulonglong(ulonglong val) with character set recoding */ -bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) +bool String::append(const char *s, size_t arg_length, CHARSET_INFO *cs) { if (!arg_length) return false; uint32 offset; - if (needs_conversion(arg_length, cs, str_charset, &offset)) + if (needs_conversion((uint32)arg_length, cs, str_charset, &offset)) { - uint32 add_length; + size_t add_length; if ((cs == &my_charset_bin) && offset) { DBUG_ASSERT(str_charset->mbminlen > offset); @@ -556,7 +610,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) return TRUE; bzero((char*) Ptr + str_length, offset); memcpy(Ptr + str_length + offset, s, arg_length); - str_length+= add_length; + str_length+= (uint32)add_length; return FALSE; } @@ -564,15 +618,15 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) uint dummy_errors; if (realloc_with_extra_if_needed(str_length + add_length)) return TRUE; - str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, - s, arg_length, cs, &dummy_errors); + str_length+= copy_and_convert(Ptr+str_length, (uint32)add_length, str_charset, + s, (uint32)arg_length, cs, &dummy_errors); } else { if (realloc_with_extra_if_needed(str_length + arg_length)) return TRUE; memcpy(Ptr + str_length, s, arg_length); - str_length+= arg_length; + str_length+= (uint32)arg_length; } return FALSE; } @@ -583,7 +637,7 @@ bool String::append(IO_CACHE* file, uint32 arg_length) return TRUE; if (my_b_read(file, (uchar*) Ptr + str_length, arg_length)) { - shrink(str_length); + shrink(str_length ? str_length : 1); return TRUE; } str_length+=arg_length; @@ -737,7 +791,7 @@ bool String::replace(uint32 offset,uint32 arg_length, // added by Holyfoot for "geometry" needs -int String::reserve(uint32 space_needed, uint32 grow_by) +int String::reserve(size_t space_needed, size_t grow_by) { if (Alloced_length < str_length + space_needed) { @@ -747,10 +801,10 @@ int String::reserve(uint32 space_needed, uint32 grow_by) return FALSE; } -void String::qs_append(const char *str, uint32 len) +void String::qs_append(const char *str, size_t len) { memcpy(Ptr + str_length, str, len + 1); - str_length += len; + str_length += (uint32)len; } void String::qs_append(double d) @@ -1025,8 +1079,7 @@ my_copy_with_hex_escaping(CHARSET_INFO *cs, break; /* purecov: inspected */ *dst++= '\\'; *dst++= 'x'; - *dst++= _dig_vec_upper[((unsigned char) *src) >> 4]; - *dst++= _dig_vec_upper[((unsigned char) *src) & 15]; + APPEND_HEX(dst, (uchar) *src); src++; dstlen-= 4; } @@ -1071,10 +1124,9 @@ my_copy_with_hex_escaping(CHARSET_INFO *cs, */ uint String_copier::well_formed_copy(CHARSET_INFO *to_cs, - char *to, uint to_length, + char *to, size_t to_length, CHARSET_INFO *from_cs, - const char *from, uint from_length, - uint nchars) + const char *from, size_t from_length, size_t nchars) { if ((to_cs == &my_charset_bin) || (from_cs == &my_charset_bin) || @@ -1097,7 +1149,7 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs, Does not add the enclosing quotes, this is left up to caller. */ #define APPEND(X) if (append(X)) return 1; else break -bool String::append_for_single_quote(const char *st, uint len) +bool String::append_for_single_quote(const char *st, size_t len) { const char *end= st+len; for (; st < end; st++) @@ -1211,8 +1263,7 @@ uint convert_to_printable(char *to, size_t to_len, break; *t++= '\\'; *t++= 'x'; - *t++= _dig_vec_upper[((unsigned char) *f) >> 4]; - *t++= _dig_vec_upper[((unsigned char) *f) & 0x0F]; + APPEND_HEX(t, *f); } if (t_end - t >= 3) // '...' dots= t; |