diff options
author | unknown <bar@bar.intranet.mysql.r18.ru> | 2004-01-21 14:15:19 +0400 |
---|---|---|
committer | unknown <bar@bar.intranet.mysql.r18.ru> | 2004-01-21 14:15:19 +0400 |
commit | cf240e4ee83b39fbbccf92a35f394cb2793437a5 (patch) | |
tree | 058a7d4f2f63504db9bb954a87f85a755f802179 /sql/sql_string.cc | |
parent | 53d6a088bcbab1777e32777e80a548b46f1140af (diff) | |
download | mariadb-git-cf240e4ee83b39fbbccf92a35f394cb2793437a5.tar.gz |
Further fixes for 2390: ucs2 alignment
Diffstat (limited to 'sql/sql_string.cc')
-rw-r--r-- | sql/sql_string.cc | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 9534c5605fe..225076bc555 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -228,6 +228,32 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) return FALSE; } + +/* + Checks that the source string can be just copied + to the destination string without conversion. + If either character set conversion or adding leading + zeros (e.g. for UCS-2) must be done then return + value is TRUE else FALSE. +*/ +bool String::needs_conversion(const char *str, uint32 arg_length, + CHARSET_INFO *from_cs, + CHARSET_INFO *to_cs) +{ + if (to_cs == &my_charset_bin) + return FALSE; + if (to_cs == from_cs) + return FALSE; + if (my_charset_same(from_cs, to_cs)) + return FALSE; + if ((from_cs == &my_charset_bin)) + { + if (!(arg_length % to_cs->mbminlen)) + return FALSE; + } + return TRUE; +} + /* ** For real multi-byte, ascii incompatible charactser sets, ** like UCS-2, add leading zeros if we have an incomplete character. @@ -237,15 +263,15 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) ** SELECT _ucs2 0x00AA */ -bool String::set_or_copy_aligned(const char *str,uint32 arg_length, - CHARSET_INFO *cs) +bool String::copy_aligned(const char *str,uint32 arg_length, + CHARSET_INFO *cs) { /* How many bytes are in incomplete character */ uint32 offs= (arg_length % cs->mbminlen); if (!offs) /* All characters are complete, just copy */ { - set(str, arg_length, cs); + copy(str, arg_length, cs); return FALSE; } @@ -274,15 +300,35 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length, return FALSE; } + +bool String::set_or_copy_aligned(const char *str,uint32 arg_length, + CHARSET_INFO *cs) +{ + /* How many bytes are in incomplete character */ + uint32 offs= (arg_length % cs->mbminlen); + + if (!offs) /* All characters are complete, just copy */ + { + set(str, arg_length, cs); + return FALSE; + } + return copy_aligned(str, arg_length, cs); +} + /* Copy with charset convertion */ bool String::copy(const char *str, uint32 arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) { - if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin)) + if (!needs_conversion(str, arg_length, from_cs, to_cs)) { return copy(str, arg_length, to_cs); } + if ((from_cs == &my_charset_bin) && (arg_length % to_cs->mbminlen)) + { + return copy_aligned(str, arg_length, to_cs); + } + uint32 new_length= to_cs->mbmaxlen*arg_length; if (alloc(new_length)) return TRUE; |