ENGLISH 意见建议 网站地图 网站帮助
广泛智力汇聚   高效成果传播   先进机制培育
联盟首页  |  协同开发  |  开放源码库  |  安全告警  |  开源导航  |  文档中心  |  服务支持  |  共创论坛  |  关于联盟


注册会员 网站帮助
    您的位置 »
    今天是: 2010年11月22日    
项目搜索

完全匹配   
开源软件
软件分类表
新发布软件
其它网站镜像
代码片断
协同开发
文档
论坛
寻求协助
热点项目
站点状态
编译工厂

联系我们
关于联盟

代码片段库:
查看代码片段

浏览 | 提交新的代码片段 | 创建代码包

多字节函数库系列:UTF-8相关:cy_wcstoutf8()

类型:
Function
类别:
Other
许可证:
GNU Library Public License
语言:
C++
 
描述:
将wchar_t宽字节字符串转换为UTF-8编码多字节字符串。

〖补充说明〗:
1、本函数库所有函数名皆有“cy_”前缀,以上标题说明中时有遗漏或错位,描述也有类似情况!请以源代码中之说明为准。2、十分地想建议网站设计中,上传文档应有适当的修改许可,至少是临时才写出的标题和描述部分!(可能一次性写出合适而又准确的说明并非易事,当然也可能本人心思欠佳,应该怪自己。Sorry!)

该代码片段的版本系列:

片段ID 下载版本 提交时间 提交人 删除
45790.12002-06-26 21:41renxiao

点击"下载版本"来下载该代码片段.


最新版本的代码片段: 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;
}

		

提交新版本

如果您修改了一个代码片段并且觉得很应该让别人共享,您可以把这作为这个代码片段的最新版本提交上来.


联盟团体会员
合作伙伴
© 共创软件联盟 版权所有
联盟服务条款 | 联盟隐私权规则 | 联系我们
电话: (8610)68313388-5949 | 传真: (8610)88377936
京ICP备05056057号