编解码库使用
- 编解码库libhiasn1.so,位于“/usr/local/ksl/lib”下。用户可以在编译源码时链接此库,提供用于将用户数据编码成码流,或将码流解码成用户数据的接口。
- 编解码接口定义头文件,位于“/usr/local/ksl/include/hiasn1/”下,KSL_ASN1相关数据结构和接口定义位于此目录下。
本章节将演示如何使用编译工具使用中解析asn1文件生成的C代码文件,通过调用KSL_ASN1的编解码库接口,实现将已有数据编码成流,及如何将流解码为数据的方法。
- 在“test_demo”目录下新建一个code_test.c文件。
vim code_test.c
- 按“i”进入编辑模式,填写编解码样例代码。
#include <stdio.h> #include <stdbool.h> #include <string.h> #include "asn_codec.h" #include "exports/test/codec_index.h" #include "exports/test/codec_interfaces.h" // 缓冲区大小 #define BUF_SIZE 128 // 缓冲区 uint8_t g_buffer[BUF_SIZE]; // 用户数据 MyType g_userData = { .boolType = 0, .intType = 10, .enumType = MY_TYPE_ENUM_TYPE_B, .bitStrType = {.bitCnt = 24, .item = "bit"}, .octStrType = {.len = 12, .item = "Octet String"}, .seqOfType = {.cnt = 3, .item = { -1, 0, 255, }}, .choiceType = {.choice = MY_TYPE_CHOICE_TYPE_B, .u = { .b = 1, }}, }; // 编码测试 bool EncodeTest(const AsnDesc *desc, AsnCodecMethod codecMethod) { AsnBuf buf = {0}; // 缓冲区结构体 buf.buf = g_buffer; // 设置缓冲区 buf.bufLen = BUF_SIZE; // 设置缓冲区大小 AsnCtx ctx = {0}; // 上下文结构体,需要清零 ctx.buf = &buf; // 设置缓冲区 ctx.method = codecMethod; // 设置编码规则 // 编码 ssize_t ret = AsnEncode(desc, &g_userData, &ctx); if (ret < 0) { printf("failed to encoding data, ret: %zd\n", -ret); return false; } size_t encodedBytes = (size_t)ret; printf("successfully encoded into %zu bytes data\n", encodedBytes); // 打印编码结果 printf("encoded: "); for (size_t i = 0; i < encodedBytes; ++i) { printf("%02X ", g_buffer[i]); } printf("\n"); return true; } // 解码测试 bool DecodeTest(const AsnDesc *desc, AsnCodecMethod codecMethod) { AsnBuf buf = {0}; // 缓冲区结构体 buf.buf = g_buffer; // 设置缓冲区 buf.bufLen = BUF_SIZE; // 设置缓冲区大小 AsnCtx ctx = {0}; // 上下文结构体,需要清零 ctx.buf = &buf; // 设置缓冲区 ctx.method = codecMethod; // 设置编码规则 // 解码 MyType decoded = {0}; ssize_t ret = AsnDecode(desc, &decoded, &ctx); if (ret < 0) { printf("failed to decoding data, ret: %zd\n", -ret); return false; } printf("successfully decoded\n"); // 比较解码结果 if (memcmp(&decoded, &g_userData, sizeof(MyType)) != 0) { printf("decoded result unexpected\n"); return false; } return true; } int main() { // 获取结构对应的描述符 const AsnDesc *desc = CODEC_GET_TEST(CODEC_IDX_TEST_MY_TYPE); // 编解码规则 AsnCodecMethod codecMethod = ASN_BER; // 编码测试 if (!EncodeTest(desc, codecMethod)) { return 1; } // 解码测试 if (!DecodeTest(desc, codecMethod)) { return 1; } return 0; }
- AsnBuf结构体的缓冲区和缓冲区大小的合法性由用户保证。
- AsnCtx结构体需先清零,再对buf和method字段赋值。
- 使用统一的编解码接口AsnEncode、AsnDecode,接口内部通过ctx.method判断编码模式。
- 编解码接口返回值是ssize_t类型的:
- 当返回值大于等于0时,表示编码成功,返回已编码字节数或比特数。
- 当返回值小于0时,表示编码失败,错误码为返回值的绝对值,可在asn_codec_errors.h中找到对应的错误信息。
- 按“Esc”键,输入:wq,按“Enter”保存并退出编辑。
- 编译运行。
gcc codec_test.c exports/test/*.c -I/usr/local/ksl/include/hiasn1/ -L/usr/local/ksl/lib/ -Wl,-rpath=/usr/local/ksl/lib/ -lhiasn1 -o codec_test ./codec_test
父主题: 使用说明