elua解析器开源文档第二章:2.4、功能库代码

目录

点击这里查看所有博文

2.4、功能库代码

  经过上一节的学习,大家应该也都清楚了怎么才能去添加一些驱动库。一般情况下2.3小节提供的驱动库也够用了。有时候我们不仅仅是驱动设备,还需要运行一些软件算法,比如sha1、md5这些信息摘要算法,还有一些图片的解码算法。json数据处理等等。

  这些算法都是比较常见的,也经常会使用到。我们也在elua代码包中内置了一些纯软算法,具体见下图。

在这里插入图片描述

  上面图片中的命名有的人可能不知道这些库有什么作用,这里做一下简要说明。

代码包功能
crypto加密/摘要功能(sha1、sha2、md5、base64、xxtea、aes)
iconv字体编码转化(gb2312、ucs2、utf8、)
jsonJSON内容或JSON文件进行格式化解析
lpng图片解码
lzma压缩文件接口
pbc基于双线性对的密码学库
qr_encode二维码生成
zlib通用的压缩库
zziplib轻量级的用来从ZIP文件抽读取文件的C语言包

  还是和上节一样,库太多了,这些库里面又有一大堆文件。本来准备选个高大上的库讲讲,就是那个啥----基于双线性对的密码学库。这时候没想到json这么积极,举手要求上台,那我就勉为其难的答应她好了。接下来我们讲讲json,举一反三都一样哈。

在这里插入图片描述

2.4.1、json注册

  和硬件驱动一样,即使json是纯软运算库也没有什么特殊的地方,该有的东西都得有。

  如果想json能在lua脚本中被调用,首先那就必须得在auxmods.h中增加声明json模块的模块名和注册函数。

#ifndef AM_JSON_NOT_SUPPORT
#define AUXLIB_JSON     "json"
LUALIB_API int ( luaopen_cjson)( lua_State *L );
#endif

  声明之后需要在platform_conf.h文件中完成将模块名和初始化函数注册到lua内核中。

_ROM( AUXLIB_JSON, luaopen_cjson, json_map )

  紧接着就在模块初始化函数函数内进行模块函数注册。这一段json库的函数注册代码就要比adc库的函数注册代码要复杂得多。

/* Return cjson module table */
static int lua_cjson_new(lua_State *l)
{
    luaL_Reg reg[] = {
        { "encode", json_encode },
        { "decode", json_decode },
        { "encode_sparse_array", json_cfg_encode_sparse_array },
        { "encode_max_depth", json_cfg_encode_max_depth },
        { "decode_max_depth", json_cfg_decode_max_depth },
        { "encode_number_precision", json_cfg_encode_number_precision },
        { "encode_keep_buffer", json_cfg_encode_keep_buffer },
        { "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
        { "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
        { "new", lua_cjson_new },
        { NULL, NULL }
    };

    /* Initialise number conversions */
    fpconv_init();

    /* cjson module table */
    lua_newtable(l);

    /* Register functions with config data as upvalue */
    json_create_config(l);
    luaL_setfuncs(l, reg, 1);

    /* Set cjson.null */
    lua_pushlightuserdata(l, NULL);
    lua_setfield(l, -2, "null");

    /* Set module name / version fields */
    lua_pushliteral(l, CJSON_MODNAME);
    lua_setfield(l, -2, "_NAME");
    lua_pushliteral(l, CJSON_VERSION);
    lua_setfield(l, -2, "_VERSION");

    return 1;
}
int luaopen_cjson(lua_State *l)
{
    lua_cjson_new(l);

#ifdef ENABLE_CJSON_GLOBAL
    /* Register a global "cjson" table. */
    lua_pushvalue(l, -1);
    lua_setglobal(l, CJSON_MODNAME);
#endif

    /* Return cjson table */
    return 1;
}

2.4.2、json调用函数的实现

  纯软模块和硬件驱动不同的地方现在开始体现出来了。像json这一类纯软模块不依赖外部环境,实现用的都是一些标准库。基本上就是拿来就能用,都不需要改的。如果json模块只是给elua用,不考虑提供给外界使用的话。那我们就可以直接在上述lua调用的实现中直接去调用json库中的函数。而无需去单独在抽象一层。

  看这个adc模块中的adc_open函数实现,去掉一些必须得写的,实际上和adc有关的就一行。这一行platform开头的代码就是我们下一章节要讲的平台适配代码。它可以看作是elua开源项目的一个特殊的抽象层,负责和外界的环境进行交互,这里不做细讲,了解即可。

// adc.open(id)
static int adc_open(lua_State *L) {
    int id = luaL_checkinteger(L, 1);
    int ret;

    MOD_CHECK_ID(adc, id);

    ret = platform_adc_open(id,0);

    lua_pushinteger(L, ret);

    return 1; 
}

  再来看看json模块中的json_decode函数的实现,这就不一样了是吧,这么一大坨看着都晕。这还是我挑选的一个比较简单的,其他的那就更长了。

static int json_decode(lua_State *l)
{
    json_parse_t json;
    json_token_t token;
    size_t json_len;

    luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");

    json.cfg = json_fetch_config(l);
    json.data = luaL_checklstring(l, 1, &json_len);
    json.current_depth = 0;
    json.ptr = json.data;

    /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3)
     *
     * CJSON can support any simple data type, hence only the first
     * character is guaranteed to be ASCII (at worst: '"'). This is
     * still enough to detect whether the wrong encoding is in use. */
    if (json_len >= 2 && (!json.data[0] || !json.data[1]))
        luaL_error(l, "JSON parser does not support UTF-16 or UTF-32");

    /* Ensure the temporary buffer can hold the entire string.
     * This means we no longer need to do length checks since the decoded
     * string must be smaller than the entire json string */
    json.tmp = strbuf_new(json_len);

    json_next_token(&json, &token);
    json_process_value(l, &json, &token);

    /* Ensure there is no more input left */
    json_next_token(&json, &token);

    if (token.type != T_END)
        json_throw_parse_error(l, &json, "the end", &token);

    strbuf_free(json.tmp);

    return 1;
}

  给大家20秒扫一眼,看看上面的代码有没有platform开头的函数。

在这里插入图片描述

  哎,好像没有是吧!这就说明这个json模块是给elua开源项目特供的,不需要给外界使用。也不需要把它拎到项目外面,再另外做一个抽象层与elua对接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇雪长安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值