mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
Merge MySQL->MariaDB
* Finished Monty and Jani's merge * Some InnoDB tests still fail (because it's old xtradb code run against newer testsuite). They are expected to go after mergning with the latest xtradb.
This commit is contained in:
@@ -322,12 +322,24 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
|
||||
return copy_aligned(str, arg_length, offset, cs);
|
||||
}
|
||||
|
||||
/* Copy with charset conversion */
|
||||
|
||||
/**
|
||||
Copies the character data into this String, with optional character set
|
||||
conversion.
|
||||
|
||||
@return
|
||||
FALSE ok
|
||||
TRUE Could not allocate result buffer
|
||||
|
||||
*/
|
||||
|
||||
bool String::copy(const char *str, uint32 arg_length,
|
||||
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
|
||||
{
|
||||
uint32 offset;
|
||||
|
||||
DBUG_ASSERT(!str || str != Ptr);
|
||||
|
||||
if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
|
||||
{
|
||||
*errors= 0;
|
||||
@@ -1167,3 +1179,76 @@ void String::swap(String &s)
|
||||
swap_variables(bool, alloced, s.alloced);
|
||||
swap_variables(CHARSET_INFO*, str_charset, s.str_charset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Convert string to printable ASCII string
|
||||
|
||||
@details This function converts input string "from" replacing non-ASCII bytes
|
||||
with hexadecimal sequences ("\xXX") optionally appending "..." to the end of
|
||||
the resulting string.
|
||||
This function used in the ER_TRUNCATED_WRONG_VALUE_FOR_FIELD error messages,
|
||||
e.g. when a string cannot be converted to a result charset.
|
||||
|
||||
|
||||
@param to output buffer
|
||||
@param to_len size of the output buffer (8 bytes or greater)
|
||||
@param from input string
|
||||
@param from_len size of the input string
|
||||
@param from_cs input charset
|
||||
@param nbytes maximal number of bytes to convert (from_len if 0)
|
||||
|
||||
@return number of bytes in the output string
|
||||
*/
|
||||
|
||||
uint convert_to_printable(char *to, size_t to_len,
|
||||
const char *from, size_t from_len,
|
||||
CHARSET_INFO *from_cs, size_t nbytes /*= 0*/)
|
||||
{
|
||||
/* needs at least 8 bytes for '\xXX...' and zero byte */
|
||||
DBUG_ASSERT(to_len >= 8);
|
||||
|
||||
char *t= to;
|
||||
char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
|
||||
const char *f= from;
|
||||
const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
|
||||
char *dots= to; // last safe place to append '...'
|
||||
|
||||
if (!f || t == t_end)
|
||||
return 0;
|
||||
|
||||
for (; t < t_end && f < f_end; f++)
|
||||
{
|
||||
/*
|
||||
If the source string is ASCII compatible (mbminlen==1)
|
||||
and the source character is in ASCII printable range (0x20..0x7F),
|
||||
then display the character as is.
|
||||
|
||||
Otherwise, if the source string is not ASCII compatible (e.g. UCS2),
|
||||
or the source character is not in the printable range,
|
||||
then print the character using HEX notation.
|
||||
*/
|
||||
if (((unsigned char) *f) >= 0x20 &&
|
||||
((unsigned char) *f) <= 0x7F &&
|
||||
from_cs->mbminlen == 1)
|
||||
{
|
||||
*t++= *f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t_end - t < 4) // \xXX
|
||||
break;
|
||||
*t++= '\\';
|
||||
*t++= 'x';
|
||||
*t++= _dig_vec_upper[((unsigned char) *f) >> 4];
|
||||
*t++= _dig_vec_upper[((unsigned char) *f) & 0x0F];
|
||||
}
|
||||
if (t_end - t >= 3) // '...'
|
||||
dots= t;
|
||||
}
|
||||
if (f < from + from_len)
|
||||
memcpy(dots, STRING_WITH_LEN("...\0"));
|
||||
else
|
||||
*t= '\0';
|
||||
return t - to;
|
||||
}
|
||||
|
Reference in New Issue
Block a user