| 项目搜索 |
| |
|
代码片段库:
查看代码片段
浏览
| 提交新的代码片段
| 创建代码包
多字节函数库系列:UTF-8相关:cy_wcstoutf8()
|
类型:
Function |
类别:
Other
|
许可证:
GNU Library Public License |
语言:
C++
|
描述:
将wchar_t宽字节字符串转换为UTF-8编码多字节字符串。
〖补充说明〗:
1、本函数库所有函数名皆有“cy_”前缀,以上标题说明中时有遗漏或错位,描述也有类似情况!请以源代码中之说明为准。2、十分地想建议网站设计中,上传文档应有适当的修改许可,至少是临时才写出的标题和描述部分!(可能一次性写出合适而又准确的说明并非易事,当然也可能本人心思欠佳,应该怪自己。Sorry!)
|
该代码片段的版本系列:
片段ID |
下载版本 |
提交时间 |
提交人 |
删除 |
4579 | 0.1 | 2002-06-26 21:41 | renxiao | |
点击"下载版本"来下载该代码片段.
最新版本的代码片段: 0.1
/*-----------------------Own_lib函数库系列 wcstoutf8.cc------------------------
cy_wcstoutf8() /wcstoutf8.o /libcyfunc.a
描述: 对于国际通行用于磁盘存储的8bits字节序列---UTF-8编码字符串, 由一般为内存中
使用的wchar_t宽字节序列转换过来时不需查找码表, 它通过简单的码位析取与分配
即可完成. 本函数提供这一实现.
dest_str:
宽字节字符串转换为UTF-8编码字符串的目标地址.
src_wstr:
被转换的源字符串.
max_length:
转换的目的字符串最多字节数限制, 若置之为0, 则认为目的字符串空间已经足够大!
转换将直到字符串结束符'\0'才结束.
返回值:
返回实际转换后的字符串的字节数. 若遇到错误或检测到非法字节序列, 则返回-1.
注意! 1. 传递的字符串应是能被合法转换为UTF-8编码的宽字节序列.
2. 除0外, 如果返回值等于max_length, 则转换后的字符串不是以'\0'结尾的.
作者: 任逍 |2002.06.05.
版权: GNU General (Library) Public License (GPL/LGPL)
* 编辑器: vim-6.0 |操作系统: TurboLinux7.0简体中文版 *
------------------------------------------------------------------------------*/
#include "cyinclude/cyutf.h"
#define MAX_CONV_LENGTH 65535 // unsigned short int 的最大值
size_t cy_wcstoutf8(char * dest_str,
const wchar_t * src_wstr,
size_t max_length)
{
int count_bytes = 0;
wchar_t byte_one = 0, byte_other = 0x3f; // 用于位与运算以提取位值
unsigned char utf_one = 0, utf_other = 0x80; // 用于位或置标UTF-8编码
size_t test_length = 0;
size_t test_chars = 0;
wchar_t tmp_wchar = L'\0'; // 用于宽字符位置析取和位移(右移6位)
unsigned char tmp_char = '\0';
if ( (!src_wstr) || (!dest_str) )
return (size_t)-1;
if (max_length == 0)
max_length = MAX_CONV_LENGTH; // 无最大字节数限制
do // 此循环可检测到字符串结尾的L'\0'并转换之
{
if (test_length >= max_length)
break;
for (;;) // 检测字节序列长度
{
if (src_wstr[test_chars] <= 0x7f){
count_bytes = 1; // ASCII字符: 0xxxxxxx( ~ 01111111)
byte_one = 0x7f; // 用于位与运算, 提取有效位值, 下同
utf_one = 0x0;
break;
}
if ( (src_wstr[test_chars] > 0x7f) && (src_wstr[test_chars] <= 0x7ff) ){
count_bytes = 2; // 110xxxxx 10xxxxxx[1](最多11个1位, 简写为11*1)
byte_one = 0x1f; // 00011111, 下类推(1位的数量递减)
utf_one = 0xc0; // 11000000
break;
}
if ( (src_wstr[test_chars] > 0x7ff) && (src_wstr[test_chars] <= 0xffff) ){
count_bytes = 3; // 1110xxxx 10xxxxxx[2](MaxBits: 16*1)
byte_one = 0xf; // 00001111
utf_one = 0xe0; // 11100000
break;
}
if ( (src_wstr[test_chars] > 0xffff) && (src_wstr[test_chars] <= 0x1fffff) ){
count_bytes = 4; // 11110xxx 10xxxxxx[3](MaxBits: 21*1)
byte_one = 0x7; // 00000111
utf_one = 0xf0; // 11110000
break;
}
if ( (src_wstr[test_chars] > 0x1fffff) && (src_wstr[test_chars] <= 0x3ffffff) ){
count_bytes = 5; // 111110xx 10xxxxxx[4](MaxBits: 26*1)
byte_one = 0x3; // 00000011
utf_one = 0xf8; // 11111000
break;
}
if ( (src_wstr[test_chars] > 0x3ffffff) && (src_wstr[test_chars] <= 0x7fffffff) ){
count_bytes = 6; // 1111110x 10xxxxxx[5](MaxBits: 31*1)
byte_one = 0x1; // 00000001
utf_one = 0xfc; // 11111100
break;
}
return (size_t)-1; // 以上皆不满足则为非法序列
}
// 以下几行析取宽字节中的相应位, 并分组为UTF-8编码的各个字节
tmp_wchar = src_wstr[test_chars];
for (int i = count_bytes; i > 1; i--)
{ // 一个宽字符的多字节降序赋值
tmp_char = (unsigned char)(tmp_wchar & byte_other);
dest_str[test_length + i - 1] = (tmp_char | utf_other);
tmp_wchar >>= 6;
}
tmp_char = (unsigned char)(tmp_wchar & byte_one);
dest_str[test_length] = (tmp_char | utf_one);
// 位值析取分组__End!
test_length += count_bytes;
test_chars ++;
}while (src_wstr[test_chars] != L'\0');
return test_length;
}
如果您修改了一个代码片段并且觉得很应该让别人共享,您可以把这作为这个代码片段的最新版本提交上来. |
|