summaryrefslogtreecommitdiff
path: root/sql/sql_string.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-12-01 11:57:01 +0400
committerAlexander Barkov <bar@mariadb.org>2016-12-16 18:33:54 +0400
commit69f80e5ecf8b2685a598e60320d4f0f05f492c22 (patch)
tree89d1b057a0d94a0beca81295c9fd3784ffa173e1 /sql/sql_string.cc
parent9185f8d4a72e7e2001c29bf1502ce7dd4e782e98 (diff)
downloadmariadb-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.cc61
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;