iconv库函数的学习程序

以前用php的iconv函数,使用起来很简单。
用C来写的时候,发现要完全理解了iconv接口才能好程序。
一点不直观。也许是因为性能问题吧,它没有封装一个简单的接口。
对于懒惰的程序员,还是提供一些简单的接口比较好。
因为我们大部分的程序不考虑性能。

我现在不是在写D程序,完全是在写DC程序。
即要考虑C怎么写,又要考虑D怎么用。

附件包括:
学习例程,和libiconv库

编译方法:
文件中有一个make.brf文件, 用 bud @make 编译

需要用到iconv库,请从 http://www.gnu.org/software/libiconv/ 下载
我编译的时候用的是iconv-1.11版本,dmd-1.020 linux系统

[code]
/**
* iconv 转换库的学习程序
* Edit by Liu Dehong @ 2007/08/11
*
* 参考了libiconv接口
* 本程序的错误处理设计不好,只是个例子。
* 完全没有处理常见的错误: 非法字符,内存空间
* 因为有字符串的复制,性能消耗比较大,考虑完全用D语言改写iconv库,
* 而不是做封装
*
*/


/**
*
*
* 提供跟 GNU libiconv 库的接口
*
* Name: libiconvD
* 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);

import std.stdio;
import std.c.string;
import std.string;
import std.c.stdlib;

char[] utf8_to_gb2312(char[] str)
{
return code_conver("utf-8", "gb2312", str);
}

char[] gb2312_to_utf8(char[] str)
{
return code_conver("gb2312", "utf-8", str);
}

char[] code_conver(string from, string to, in char[] in_str)
{
auto cd = iconv_open(toStringz(to), toStringz(from));
if (cd == cast(iconv_t)-1)
{
throw new Error("Can't Open from " ~ from ~ " to " ~ to);
writefln("aaaa");
}

uint in_len = in_str.length;
auto inp = toStringz(in_str);

uint out_len = 2 * in_len; // may be enough
char* outp = cast(char*) malloc(out_len * char.sizeof);
auto old_outp = outp;

debug (1) {
writefln("in_str.ptr: %s", in_str.ptr);
writefln("inp: %s", inp);
writefln("oup: %s", outp);
}

auto old_in_len = in_len;
auto old_out_len = out_len;
auto i = iconv(cd, &inp, &in_len, &outp, &out_len);
auto conv_len = old_out_len - out_len;

iconv_close(cd);

debug (1) {
writefln("i: %s", i);
writefln("inp: %s", inp);
writefln("oup: %s", outp);
writefln("in_len: %s", in_len);
writefln("out_len %s", out_len);
}

debug (1) {
//printf("%s", inp);
printf("inp: %s"\n, inp - old_in_len);
printf("outp: %s"\n, outp - conv_len);
}

auto ret = toString(old_outp).dup;
free(old_outp);

return ret;
}

void main()
{

try
{
auto str1 = utf8_to_gb2312("aabb我bb");
printf("return: %.*s"\n, str1);

auto str2 = gb2312_to_utf8(str1);
printf("return: %.*s"\n, str2);
}
catch (Error err)
{
writefln("catch error: %s", err);
}

return ;
}

[/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值