移植了GNU Libiconv,希望大家喜欢
|
heromyth
2007-06-14
接口代码如下,导入库可以去 http://bitworld.ys168.com 下载。
Build命令: dmd -I. testICONV.d libiconv.lib
/**
*
* libiconvD
* 提供跟 GNU libiconv 库的接口
*
* Name: libiconvD.d
* Purpose: 方便在D语言里实现国际编码之间的转换
*
* Author: 张雪平(heromyth)
* Email: zxpmyth@yahoo.com.cn
* Date: 2007-6-14
* Version: 1.0.1
* Copyrights: (c) Public Domain and BitWorld Inc.
* Licence: BSD licence
*
* Plan: 实现方便在D语言里直接使用的函数或者类
*
**/
module libiconvD;
alias libiconv iconv ; ///
alias libiconv_open iconv_open ; ///
alias libiconv_close iconv_close ; ///
typedef void* iconv_t;
/**
* 设置要转换的编码,并为转换操作准备空间
*
* Params:
* fromcode = 需要被转换的源数据的编码格式
* tocode = 需要转换成的目标数据的编码格式
*
* Returns:
* (iconv_t)(-1),如果设置有错误;<br>
* 新分配的转换描述信息器,如果设置成功。
*
* See_Also:
* iconv_open.3.html
*
* 注意:
* 参数的顺序一下不能错,否则会造成后面的转换失败
* 所有支持编码可以在参考里找到
*
*/
extern (C) iconv_t libiconv_open (char *tocode, char *fromcode);
/**
* 转换核心函数
*
* Params:
* cd = 转换描述信息器,由libiconv_open提供,可存放转换过程状态
* inbuf = 指向源字符序列的第一个位置;在执行后,指向新的空间地址:*inbuf + *inbytesleft
* inbytesleft = 源字符序列的字节数;在执行后,通常为0,否则为剩余未被转换的字符数
* outbuf = 指向存放目标字符序列的首地址;在执行后,指向新的空间地址:*outbuf + 实际转换的字节数
* outbytesleft = 存放目标字符序列的总的空间字节数;剩余的目标空间字节数
*
* Returns:
* (iconv_t)(-1) 如果转换有问题;<br>
* 0,调用过程中没有使用可逆转换;<br>
* 其它正数,在一次调用过程中以非可逆方式进行转换的字符数
*
* 注意:
* 对各个参数含义的理解一定要正确,否则很难正确使用这个函数
*
*/
extern (C) size_t libiconv (iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
/**
* 释放先前申请的准备空间
*
* Params:
* cd = 指向先前由libiconv_open申请的转换描述信息器空间
*
*/
extern (C) int libiconv_close (iconv_t cd);
unittest
{
char[] str = "test";
size_t in_len = str.length;
char* inp1 = cast(char*)malloc(256*char.sizeof);
strcpy(cast(char*)inp1, toStringz(str));
char* inp = inp1;
char* outp1 = cast(char*)malloc(256*char.sizeof);
size_t out_len = 256;
char* outp = outp1;
iconv_t cd = iconv_open("UTF-16LE", "UTF-8");
size_t old_in_len = in_len;
size_t old_out_len = out_len;
size_t result = iconv(cd, &inp, &in_len, &outp, &out_len);
debug printf("outp-outp1 = %d\n", outp-outp1);
debug writefln("in_len = %d, out_len = %d\n", in_len, out_len);
assert(inp-inp1 == old_in_len);
assert(outp-outp1 == old_out_len - out_len);
for(int i=0; i < old_in_len; i++)
if( inp1[i] != str[i])
{ assert(0); break;}
char[] s1 ="\x74\x00\x65\x00\x73\x00\x74\x00\x00\x00\x00\x00\x00\x00\x00";
for(int i=0; i < old_out_len - out_len; i++)
{
if( outp1[i] != s1[i])
{ assert(0); break;}
debug writefln("%02X\t%02X\n", s1[i], outp1[i]);
}
if (result == cast(size_t)(-1))
assert(0);
iconv_close(cd);
free(inp1);
free(outp1);
}
|
|
|
tomqyp
2007-06-14
好东西
|
|
|
oldrev
2007-06-14
没封装?
|
|
|
heromyth
2007-06-19
oldrev 写道 没封装?
下一步的工作啦。 |
|
|
DavidL
2007-07-11
个人觉得应该把所有C库移植过来的。。。
|
|
|
xgene
2007-07-11
是啊!! 搞个纯D的好!!
|
|
|
heromyth
2007-07-15
DavidL 写道 个人觉得应该把所有C库移植过来的。。。
我也想个,不过工作量比较大。 先有一个可用的,满足第一要求;至于其它的只有慢慢来啦。 是否要全面移植,我想是一个老问题了。由于D全面支持C库,因此D可以很方便、快速的拥有很多优秀可用的库,而不必费心费力去实现或全面移植。因为那样做,在性能上也不一定有多大的提高。 |
|
|
oldrev
2007-07-15
heromyth 写道 DavidL 写道 个人觉得应该把所有C库移植过来的。。。
我也想个,不过工作量比较大。 先有一个可用的,满足第一要求;至于其它的只有慢慢来啦。 是否要全面移植,我想是一个老问题了。由于D全面支持C库,因此D可以很方便、快速的拥有很多优秀可用的库,而不必费心费力去实现或全面移植。因为那样做,在性能上也不一定有多大的提高。 可以直接用D写个OS了 |

