diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-03-16 12:14:31 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-03-16 12:14:31 +0400 |
commit | f48dc5ccc7246c5ca9ebad2acc2d1d56a3470f9d (patch) | |
tree | dad0c76c6303556b7a92431957b08dec4ff8c559 /strings | |
parent | c4b268add0475c6633f35eaf8cf4c7fbcad298f6 (diff) | |
download | mariadb-git-f48dc5ccc7246c5ca9ebad2acc2d1d56a3470f9d.tar.gz |
Moving the conversion code from String::well_formed_copy()
to my_convert_fix() - a new function in /strings.
Diffstat (limited to 'strings')
-rw-r--r-- | strings/ctype.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/strings/ctype.c b/strings/ctype.c index 048fbe3d368..aa40e2b338c 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -1161,3 +1161,76 @@ my_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, DBUG_ASSERT(FALSE); // Should never get to here return 0; // Make compiler happy } + + +size_t +my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, + CHARSET_INFO *from_cs, const char *from, size_t from_length, + size_t nchars, MY_STRCONV_STATUS *status) +{ + int cnvres; + my_wc_t wc; + my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc; + my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb; + const uchar *from_end= (const uchar*) from + from_length; + uchar *to_end= (uchar*) to + to_length; + char *to_start= to; + + DBUG_ASSERT(to_cs != &my_charset_bin); + DBUG_ASSERT(from_cs != &my_charset_bin); + + status->m_native_copy_status.m_well_formed_error_pos= NULL; + status->m_cannot_convert_error_pos= NULL; + + for ( ; nchars; nchars--) + { + const char *from_prev= from; + if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from, from_end)) > 0) + from+= cnvres; + else if (cnvres == MY_CS_ILSEQ) + { + if (!status->m_native_copy_status.m_well_formed_error_pos) + status->m_native_copy_status.m_well_formed_error_pos= from; + from++; + wc= '?'; + } + else if (cnvres > MY_CS_TOOSMALL) + { + /* + A correct multibyte sequence detected + But it doesn't have Unicode mapping. + */ + if (!status->m_cannot_convert_error_pos) + status->m_cannot_convert_error_pos= from; + from+= (-cnvres); + wc= '?'; + } + else + { + if ((uchar *) from >= from_end) + break; // End of line + // Incomplete byte sequence + if (!status->m_native_copy_status.m_well_formed_error_pos) + status->m_native_copy_status.m_well_formed_error_pos= from; + from++; + wc= '?'; + } +outp: + if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0) + to+= cnvres; + else if (cnvres == MY_CS_ILUNI && wc != '?') + { + if (!status->m_cannot_convert_error_pos) + status->m_cannot_convert_error_pos= from_prev; + wc= '?'; + goto outp; + } + else + { + from= from_prev; + break; + } + } + status->m_native_copy_status.m_source_end_pos= from; + return to - to_start; +} |