在服务器和客户端设置相同的字符集对程序运行的影响如下:
bool Protocol::net_store_data(const
uchar *from,
size_t length,
CHARSET_INFO *from_cs,
CHARSET_INFO *to_cs)
{
uint dummy_errors;
/* Calculate
maxumum possible result length */
uint conv_length= to_cs->mbmaxlen * length
/ from_cs->mbminlen;
if (conv_length > 250)
{
/*
For strings with conv_length greater than
250 bytes
we don't know how many bytes we will need
to store length: one or two,
because we don't know result length until
conversion is done.
For example, when converting from utf8
(mbmaxlen=3) to latin1,
conv_length=300 means that the result
length can vary between 100 to 300.
length=100 needs one byte, length=300
needs to bytes.
Thus conversion directly to
"packet" is not worthy.
Let's use "convert" as a temporary
buffer.
*/
return (convert->copy((const char*) from, length, from_cs,
to_cs, &dummy_errors)
||
net_store_data((const uchar*) convert->ptr(),
convert->length()));
}
Copy函数如下:
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;//复制数据到目标缓冲区
return copy(str, arg_length, to_cs);
}
if ((from_cs == &my_charset_bin)
&& offset)//如果不能直接复制,下面就是要对字符进行转换后重新复制,这中间当然会浪费时间,为什么不能够复制呢,因为不同的字符集之间同一字符占用的字节数都是不一样的,如果强制复制当然会造成乱码的了。
{
*errors=
0;
return copy_aligned(str,
arg_length, offset,
to_cs);
}
uint32 new_length= to_cs->mbmaxlen*arg_length;
if (alloc(new_length))
return TRUE;
str_length=copy_and_convert((char*)
Ptr, new_length,
to_cs,
str, arg_length,
from_cs, errors);
str_charset=to_cs;
return FALSE;
}
下面的用于判断是否需要转换的函数
bool String::needs_conversion(uint32
arg_length,
CHARSET_INFO
*from_cs,
CHARSET_INFO
*to_cs,
uint32
*offset)
{
*offset=
0;
if (!to_cs ||
(to_cs
== &my_charset_bin) ||
(to_cs
== from_cs) ||
my_charset_same(from_cs, to_cs)
||
((from_cs
== &my_charset_bin) &&
(!(*offset=(arg_length % to_cs->mbminlen)))))
return FALSE;
return TRUE;
}
恩
下班了 MySQL自己封装的字符串应该要好好看看,在文件sql_string.h和sql_string.cc中