跳转至

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;

3.2 iconv.ERROR_INVALID

功能

输入的字节序列不符合源编码格式。

常量含义:待转换数据在源编码下不合法;
数据类型:number;
常量取值:2;

3.3 iconv.ERROR_INCOMPLETE

功能

输入在源编码下是一个不完整的字符(被截断)。

常量含义:数据末尾只剩半个多字节字符,无法完成一次转换;
数据类型: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固件支持列表

Air700ECH/Air780EHM/EHV/EGH/EGG/EHU/EHN固件支持列表

Air8000系列所有型号固件支持列表

Air8101系列所有型号固件支持列表

Air1601/Air1602固件支持列表

搜索