【openwrt】libubox组件——kvlist

本文介绍了Libubox库中的kvlist组件,这是一个基于平衡二叉树实现的数据结构,用于存储键值对。文章详细讲解了kvlist的主要数据结构、初始化、操作函数,如设置、获取和删除键值对,并提供了一个用户数据结构的使用示例,展示了如何动态添加、遍历和删除键值对。此外,还提供了kvlist_strlen作为获取数据长度的参考函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Libubox 是 OpenWrt 的一个必备的基础库,包含大小端转换、链表、MD5 、定时器等实用工具基础库。
Libubox的kvlist组件基于平衡二叉树实现,另外kvlist是纯数据结构组件,不依赖uloop.
下面介绍其kvlist工具的使用方法:

kvlist主要数据结构和函数

struct kvlist {
	struct avl_tree avl;

	int (*get_len)(struct kvlist *kv, const void *data);
};

struct kvlist用于描述一个kvlist,其数据储存在平衡二叉树avl.
get_len()需要我们自行实现,其作用是获取插入KV值的长度,也就是data的实际长度。

//静态初始化一个kvlist
#define KVLIST(_name, _get_len)							\
	struct kvlist _name = KVLIST_INIT(_name, _get_len)

//动态初始化一个kvlist
void kvlist_init(struct kvlist *kv, int (*get_len)(struct kvlist *kv, const void *data));

//删除一个kvlist
void kvlist_free(struct kvlist *kv);

//根据key值在kvlist中查找value
void *kvlist_get(struct kvlist *kv, const char *name);

//向kvlist中添加kv键值对
bool kvlist_set(struct kvlist *kv, const char *name, const void *data);

//根据key值删除kvlist中指定的键值对
bool kvlist_delete(struct kvlist *kv, const char *name);

//kvlist_strlen是一个参考的(*get_len)函数,不一定适用于所有的情况,例如当data是结构体时就无法通过strlen计算其长度
int kvlist_strlen(struct kvlist *kv, const void *data)
{
	return strlen(data) + 1;
}

//遍历kvlist中所有的成员
#define kvlist_for_each(kv, name, value)
如果key的值一样,那么后添加的kv会覆盖前面的。因此,key的值必须不不同,否则会造成数据覆盖。

kvlist_for_each宏定义可以遍历一个kvlist中所有的成员,调试时使用十分方便。使用方法见下文。

kvlist使用实例

#include "stdio.h"
#include "string.h"
#include "kvlist.h"


typedef struct user_data
{
    int id;
    char name[10];
};

struct user_data data1={1,"data1"};
struct user_data data2={2,"data2"};
struct user_data data3={3,"data3"};

static struct kvlist kv_list;

int get_len(struct kvlist *kv, const void *data)
{
    return sizeof(struct user_data);
}


static void dump_kvnode(struct user_data *p)
{
    if(!p)
    {
        printf("data null\n");
        return;
    } 

    printf("id=%d\n",p->id);
    printf("name=%s\n",p->name);
}


int main()
{
    struct user_data *p = NULL;
    kvlist_init(&kv_list,get_len);

    //set KVs
    kvlist_set(&kv_list,data1.name,&data1);
    kvlist_set(&kv_list,data2.name,&data2);
    kvlist_set(&kv_list,data3.name,&data3);

    //get KV by name
    p=(struct user_data *)kvlist_get(&kv_list,data1.name);
    if(!p)
    {
        printf("kvlist_get failed!\n");
        return -1;
    }
    dump_kvnode(p);

    //iterate over all KVs
    char *p_name;
    struct user_data *p_value;
    kvlist_for_each(&kv_list,p_name,p_value)
    {
        printf("===================\n");
        printf("name=%s\n",p_name);
        printf("id=%d\n",p_value->id);
        printf("===================\n");
    }

    //delete kv_list
    kvlist_delete(&kv_list,data1.name);

    return 0;
}

调试结果

# ./kvlist 
===================
name=data1
id=1
===================
===================
name=data2
id=2
===================
===================
name=data3
id=3
===================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

知否,知否

来一杯冰美式把

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

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

打赏作者

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

抵扣说明:

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

余额充值