移植了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了

相关讨论