diff options
author | Alexander Barkov <bar@mariadb.org> | 2016-12-01 11:57:01 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2016-12-16 18:33:54 +0400 |
commit | 69f80e5ecf8b2685a598e60320d4f0f05f492c22 (patch) | |
tree | 89d1b057a0d94a0beca81295c9fd3784ffa173e1 /sql/sql_string.cc | |
parent | 9185f8d4a72e7e2001c29bf1502ce7dd4e782e98 (diff) | |
download | mariadb-git-69f80e5ecf8b2685a598e60320d4f0f05f492c22.tar.gz |
MDEV-11298 Split Item_func_hex::val_str_ascii() into virtual methods in Type_handler
Diffstat (limited to 'sql/sql_string.cc')
-rw-r--r-- | sql/sql_string.cc | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 62473e082c3..b12f0332035 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -130,6 +130,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]; @@ -960,8 +1015,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; } @@ -1146,8 +1200,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; |