34 iconv-字符编码转换
孟伟
一、概述
1.1 功能说明
iconv 模块提供字符编码转换功能,支持在不同字符编码格式之间进行转换,如 gb2312/ucs2/ucs2be/utf8。
1.2 主要功能
- 支持打开不同编码格式的转换句柄
- 提供编码之间的字符转换能力
- 转换句柄由 GC 自动释放,无需手动关闭(Lua 侧没有导出 close 接口)
1.3 应用场景
- 处理不同编码格式的文本数据
- 与外部系统进行编码兼容的数据交换
- 多语言环境下的文本处理
二、核心示例
1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/iconv
-- Unicode大端编码转换为UTF-8编码
function ucs2beToUtf8(ucs2s)
local ic = iconv.open("utf8", "ucs2be")
if not ic then
log.info("iconv", "打开转换句柄失败")
return nil
end
local result = ic:iconv(ucs2s)
-- 句柄由 GC 自动释放(元表 __gc 会调用 iconv_close),模块里没有 open 之外的关闭接口,不需要手动关闭
return result
end
-- 实际使用示例
local unicodeStr = "\x00\x41\x00\x42" -- "AB"的UCS2BE编码
local utf8Str = ucs2beToUtf8(unicodeStr)
if utf8Str then
log.info("iconv", "转换结果:", utf8Str)
end
三、常量详解
核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
每个常量对应的常量取值仅做日志打印时查询使用,不要将这个常量取值用做具体的业务逻辑判断,因为LuatOS内核固件可能会变更每个常量对应的常量取值;
如果用做具体的业务逻辑判断,一旦常量取值发生改变,业务逻辑就会出错;
3.1 iconv.ERROR_NO_MEMORY
功能
内存不足。
常量含义:底层编码转换过程中申请内存失败;
数据类型:number;
常量取值:1;
常量含义:底层编码转换过程中申请内存失败;
数据类型:number;
常量取值:1;
3.2 iconv.ERROR_INVALID
功能
输入的字节序列不符合源编码格式。
常量含义:待转换数据在源编码下不合法;
数据类型:number;
常量取值:2;
常量含义:待转换数据在源编码下不合法;
数据类型:number;
常量取值:2;
3.3 iconv.ERROR_INCOMPLETE
功能
输入在源编码下是一个不完整的字符(被截断)。
常量含义:数据末尾只剩半个多字节字符,无法完成一次转换;
数据类型:number;
常量取值:3;
常量含义:数据末尾只剩半个多字节字符,无法完成一次转换;
数据类型:number;
常量取值:3;
3.4 iconv.ERROR_UNKNOWN
功能
其它未归类的错误。
常量含义:不属于上面三类的转换错误;
数据类型:number;
常量取值:4;
注意事项
这四个常量对应的是底层 iconv 实现的 errno 取值。当前 Lua 封装里 ic:iconv(inbuf) 转换失败时直接返回 nil,并没有把 errno 回传给脚本,所以它们主要用于对照日志或做记录,不能用来判断某次转换具体失败在哪里;判断转换是否成功,仍应看返回值是否为 nil。
四、函数详解
4.1 iconv.open(tocode, fromcode)
功能
打开相应字符编码转换函数
参数
tocode
参数含义:目标编码格式;
数据类型:string;
取值范围:"gb2312"/"ucs2"/"ucs2be"/"utf8";
是否必选:必选;
注意事项:暂无;
参数示例:"utf8"
fromcode
参数含义:源编码格式;
数据类型:string;
取值范围:"gb2312"/"ucs2"/"ucs2be"/"utf8";
是否必选:必选;
注意事项:暂无;
参数示例:"ucs2be"
返回值
local ic = iconv.open(tocode, fromcode)
有一个返回值 ic
ic
含义说明:成功时返回一个userdata类型的iconv客户端实例对象,该实例对象可用于后续的iconv编码转换操作;
失败时返回nil;
实例对象名称并不是固定的ic,可自定义;
数据类型:userdata;
取值范围:成功返回有效的句柄,失败返回nil;
注意事项:暂无;
已支持的字符转换,如下表格所示:
| 参数 | tocode | fromcode | 示例 |
|---|---|---|---|
| gb2312编码 转化为 unicode小端编码 | "ucs2" | "gb2312" | iconv.open("ucs2", "gb2312") |
| gb2312编码 转化为 unicode大端编码 | "ucs2be" | "gb2312" | iconv.open("ucs2be", "gb2312") |
| unicode小端编码 转化为 gb2312编码 | "gb2312" | "ucs2" | iconv.open("gb2312", "ucs2") |
| unicode大端编码 转化为 gb2312编码 | "gb2312" | "ucs2be" | iconv.open("gb2312", "ucs2be") |
| unicode小端编码 转化为 utf8编码 | "utf8" | "ucs2" | iconv.open("utf8", "ucs2") |
| unicode大端编码 转化为 utf8编码 | "utf8" | "ucs2be" | iconv.open("utf8", "ucs2be") |
| utf8编码 转化为 unicode小端编码 | "ucs2" | "utf8" | iconv.open("ucs2", "utf8") |
| utf8编码 转化为 unicode大端编码 | "ucs2be" | "utf8" | iconv.open("ucs2be", "utf8") |
示例
-- Unicode大端编码 转化为 utf8编码
local ic = iconv.open("utf8", "ucs2be")
4.2 ic:iconv(inbuf)
功能
字符编码转换,
注意事项
ic 是由 iconv.open(tocode, fromcode)所返回的实例对象。
参数
inbuf
参数含义:待转换字符串;
数据类型:string;
取值范围:任意字符串;
是否必选:必选;
注意事项:暂无;
参数示例:"\x00\x41\x00\x42"
返回值
local result = ic:iconv(inbuf)
有一个返回值 result
result
含义说明:返回编码转换后的结果;
数据类型:string;
取值范围:成功返回转换后的字符串,失败返回nil;
注意事项:暂无;
示例
-- Unicode大端编码 转化为 utf8编码_
function ucs2beToUtf8(ucs2s)
local ic = iconv.open("utf8", "ucs2be")
return ic:iconv(ucs2s)
end
4.3 iconv.new(tocode, fromcode)
功能
打开相应字符编码转换函数。与 4.1 的 iconv.open(tocode, fromcode) 是同一个函数,在注册表里以两个名字同时导出,参数、返回值、行为完全一致。
参数
tocode
参数含义:目标编码格式;
数据类型:string;
取值范围:"gb2312"/"ucs2"/"ucs2be"/"utf8";
是否必选:必选;
注意事项:与 iconv.open 相同;
fromcode
参数含义:源编码格式;
数据类型:string;
取值范围:"gb2312"/"ucs2"/"ucs2be"/"utf8";
是否必选:必选;
注意事项:与 iconv.open 相同;
返回值
local ic = iconv.new(tocode, fromcode)
有一个返回值 ic
含义说明:编码转换函数的转换句柄;
数据类型:userdata;
取值范围:成功返回句柄,编码格式不支持时返回nil;
注意事项:句柄由 GC 自动释放,不需要手动关闭;
示例
-- 与 iconv.open 完全等价,两种写法可互换
local ic = iconv.new("utf8", "gb2312")
local utf8Str = ic:iconv("\xC4\xE3\xBA\xC3") -- "你好"的GB2312编码
log.info("iconv", "new", utf8Str)
注意事项
1、源码里另有 gb2312 ↔ utf8 的快捷函数 gb2utf8 / utf82gb,但它们在注册表中被注释掉了,Lua 侧调用不到(值为 nil),请改用 iconv.open + ic:iconv 的方式转换;
2、句柄关闭接口同样只是源码注释里的东西,没有注册导出,句柄交给 GC 回收即可。
五、产品支持说明
不同产品的LuatOS固件,对iconv核心库的支持情况如下:
1、Air780EX2/Air700ECP/Air780EPM/Air780EGP 所有固件都支持;
2、Air700ECH/Air780EHM/EHV/EGH/EGG/EHU/EHN/Air8000系列 所有固件都支持;
3、Air8101系列 101号、106号固件支持;
4、Air1601 / Air1602 都支持;
各产品固件支持核心库列表详细说明参考下面链接:
Air780EX2/Air700ECP/Air780EPM/Air780EGP固件支持列表