Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3167762
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: 嵌入式

2015-01-04 09:23:23

原文地址:http://blog.csdn.net/tyheist/article/details/37053327

实用函数 - utils.c/h


  1. /* 
  2.  * calloc_a(size_t len, [void **addr, size_t len,...], NULL) 
  3.  * 
  4.  * allocate a block of memory big enough to hold multiple aligned objects. 
  5.  * the pointer to the full object (starting with the first chunk) is returned, 
  6.  * all other pointers are stored in the locations behind extra addr arguments. 
  7.  * the last argument needs to be a NULL pointer 
  8.  * 
  9.  * 分配一段连续内存给多个指针对象使用,多个指针对象必须保证同时进行free()操作 
  10.  */  
  11. #define calloc_a(len, ...) __calloc_a(len, ##__VA_ARGS__, NULL)  
  1. /** 
  2.  * 计算对象数组个数 
  3.  */  
  4. #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))  

Socket帮助函数 - usock.c/h

类型标志

  1. #define USOCK_TCP 0  
  2. #define USOCK_UDP 1  
  3.   
  4. #define USOCK_SERVER        0x0100  
  5. #define USOCK_NOCLOEXEC 0x0200  
  6. #define USOCK_NONBLOCK      0x0400  
  7. #define USOCK_NUMERIC       0x0800  
  8. #define USOCK_IPV6ONLY      0x2000  
  9. #define USOCK_IPV4ONLY      0x4000  
  10. #define USOCK_UNIX          0x8000  

接口说明

  1. /** 
  2.  * 创建一个新的网络sock 
  3.  *  
  4.  * @param type - 类型标志 
  5.  * @param host - 作为server表示绑定本地地址;作为client表示需连接的地址 
  6.  * @param service - 端口 
  7.  * @return - sock fd > 0; 错误 < 0 
  8.  */  
  9. int usock(int type, const char *host, const char *service)  

双向链表 - list.h

数据结构

  1. struct list_head {  
  2.     struct list_head *next;  
  3.     struct list_head *prev;  
  4. };  

初始化

  1. #define LIST_HEAD_INIT(name) { &(name), &(name) }  
  2. #undef LIST_HEAD  
  3.   #define LIST_HEAD(name)   struct list_head name = LIST_HEAD_INIT(name)  
  4. static inline void INIT_LIST_HEAD(struct list_head *list)  

基本操作

加入

  1. /**  
  2.  * 加入链表头部 
  3.  */  
  4. list_add(struct list_head *_new, struct list_head *head)  
  5.   
  6. /** 
  7.  * 加入链表尾部 
  8.  */  
  9. list_add_tail(struct list_head *_new, struct list_head *head)  

移动

  1. /** 
  2.  * 把指定节点移动到链表头部 
  3.  */  
  4. list_move(struct list_head *list, struct list_head *head)  
  5.   
  6. /** 
  7.  * 把指定节点移动到链表尾部 
  8.  */  
  9. list_move_tail(struct list_head *entry, struct list_head *head)  

拼接

  1. /** 
  2.  * 将list链表拼接到head链表头部 
  3.  */  
  4. list_splice(const struct list_head *list, struct list_head *head)  
  5.   
  6. /** 
  7.  * 将list链表拼接到head链表尾部 
  8.  */  
  9. list_splice_tail(struct list_head *list, struct list_head *head)  
  10.   
  11. /** 
  12.  * 将list链表拼接到head链表头部,并初始化list 
  13.  */  
  14. list_splice_init(struct list_head *list, struct list_head *head)  
  15.   
  16. /** 
  17.  * 将list链表拼接到head链表尾部,并初始化list 
  18.  */  
  19. list_splice_tail_init(struct list_head *list, struct list_head *head)  

删除

  1. /** 
  2.  * 把指定节点从链表中删除 
  3.  */  
  4. list_del(struct list_head *entry)  
  5.   
  6. /** 
  7.  * 把指定节点从链表中删除,并初始此节点 
  8.  */  
  9. list_del_init(struct list_head *entry)  

获取链表节点元素

  1. /** 
  2.  * 获取当前节点元素 
  3.  */  
  4. list_entry(ptr, type, field)  
  5.   
  6. /** 
  7.  * 获取后一个节点元素 
  8.  */  
  9. list_first_entry(ptr, type, field)  
  10.   
  11. /** 
  12.  * 获取前一个节点元素 
  13.  */  
  14. list_last_entry(ptr, type, field)  

状态判断

  1. /** 
  2.  * 是否为空链表 
  3.  */  
  4. bool list_empty(const struct list_head *head)  
  5.   
  6. /** 
  7.  * 指定节点是否为链表第一个节点 
  8.  */  
  9. bool list_is_first(const struct list_head *list, const struct list_head *head)  
  10.   
  11. /** 
  12.  * 指定节点是否为链表最后一个节点 
  13.  */  
  14. bool list_is_last(const struct list_head *list, const struct list_head *head)  

遍历链表

  1. /** 
  2.  * 向后遍历链表,遍历过程不能操作链表,p为链表结构体 
  3.  */  
  4. list_for_each(p, head)  
  5.   
  6. /** 
  7.  * 向后遍历链表,遍历过程可操作链表,p为链表结构体 
  8.  */  
  9. list_for_each_safe(p, n, head)  
  10.   
  11. /** 
  12.  * 向前遍历链表,遍历过程不能操作链表,p为链表结构体 
  13.  */  
  14. list_for_each_prev(p, h)  
  15.   
  16. /** 
  17.  * 向前遍历链表,遍历过程可操作链表,p为链表结构体 
  18.  */  
  19. list_for_each_prev_safe(p, n, h)  
  20.   
  21. /** 
  22.  * 向后遍历链表,遍历过程不能操作链表,p为节点元素结构体 
  23.  */  
  24. list_for_each_entry(p, h, field)  
  25.   
  26. /** 
  27.  * 向后遍历链表,遍历过程可操作链表,p为节点元素结构体 
  28.  */  
  29. list_for_each_entry_safe(p, n, h, field)  
  30.   
  31. /** 
  32.  * 向前遍历链表,遍历过程不能操作链表,p为节点元素结构体 
  33.  */  
  34. list_for_each_entry_reverse(p, h, field)  

平衡二叉树 - avl.c/h


数据结构

  1. /** 
  2.  * This element is a member of a avl-tree. It must be contained in all 
  3.  * larger structs that should be put into a tree. 
  4.  */  
  5. struct avl_node {  
  6.   /** 
  7.    * Linked list node for supporting easy iteration and multiple 
  8.    * elments with the same key. 
  9.    * 
  10.    * this must be the first element of an avl_node to 
  11.    * make casting for lists easier 
  12.    */  
  13.   struct list_head list;  
  14.   
  15.   /** 
  16.    * Pointer to parent node in tree, NULL if root node 
  17.    */  
  18.   struct avl_node *parent;  
  19.   
  20.   /** 
  21.    * Pointer to left child 
  22.    */  
  23.   struct avl_node *left;  
  24.   
  25.   /** 
  26.    * Pointer to right child 
  27.    */  
  28.   struct avl_node *right;  
  29.   
  30.   /** 
  31.    * pointer to key of node 
  32.    */  
  33.   const void *key;  
  34.   
  35.   /** 
  36.    * balance state of AVL tree (0,-1,+1) 
  37.    */  
  38.   signed char balance;  
  39.   
  40.   /** 
  41.    * true if first of a series of nodes with same key 
  42.    */  
  43.   bool leader;  
  44. };  
  1. /** 
  2.  * This struct is the central management part of an avl tree. 
  3.  * One of them is necessary for each avl_tree. 
  4.  */  
  5. struct avl_tree {  
  6.   /** 
  7.    * Head of linked list node for supporting easy iteration 
  8.    * and multiple elments with the same key. 
  9.    */  
  10.   struct list_head list_head;  
  11.   
  12.   /** 
  13.    * pointer to the root node of the avl tree, NULL if tree is empty 
  14.    */  
  15.   struct avl_node *root;  
  16.   
  17.   /** 
  18.    * number of nodes in the avl tree 
  19.    */  
  20.   unsigned int count;  
  21.   
  22.   /** 
  23.    * true if multiple nodes with the same key are 
  24.    * allowed in the tree, false otherwise 
  25.    */  
  26.   bool allow_dups;  
  27.   
  28.   /** 
  29.    * pointer to the tree comparator 
  30.    * 
  31.    * First two parameters are keys to compare, 
  32.    * third parameter is a copy of cmp_ptr 
  33.    */  
  34.   avl_tree_comp comp;  
  35.   
  36.   /** 
  37.    * custom pointer delivered to the tree comparator 
  38.    */  
  39.   void *cmp_ptr;  
  40. };  

初始化

  1. #define AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)  \  
  2.     {                           \  
  3.         .list_head = LIST_HEAD_INIT(_name.list_head),   \  
  4.         .comp = _comp,                  \  
  5.         .allow_dups = _allow_dups,          \  
  6.         .cmp_ptr = _cmp_ptr             \  
  7.     }  
  1. #define AVL_TREE(_name, _comp, _allow_dups, _cmp_ptr)       \  
  2.     struct avl_tree _name =                 \  
  3.         AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)  
  1. /** 
  2.  * Initialize a new avl_tree struct 
  3.  * @param tree pointer to avl-tree 
  4.  * @param comp pointer to comparator for the tree 
  5.  * @param allow_dups true if the tree allows multiple elements with the same 
  6.  * @param ptr custom parameter for comparator 
  7.  */  
  8. void avl_init(struct avl_tree *tree, avl_tree_comp comp,   
  9.               bool allow_dups, void *ptr)  

基本操作

加入

  1. /** 
  2.  * Inserts an avl_node into a tree 
  3.  * @param tree pointer to tree 
  4.  * @param new pointer to node 
  5.  * @return 0 if node was inserted successfully, -1 if it was not inserted 
  6.  *   because of a key collision 
  7.  */  
  8. int avl_insert(struct avl_tree *tree, struct avl_node *new)  

删除

  1. /** 
  2.  * Remove a node from an avl tree 
  3.  * @param tree pointer to tree 
  4.  * @param node pointer to node 
  5.  */  
  6. void avl_delete(struct avl_tree *tree, struct avl_node *node)  

查找

  1. /** 
  2.  * Finds a node in an avl-tree with a certain key 
  3.  * @param tree pointer to avl-tree 
  4.  * @param key pointer to key 
  5.  * @return pointer to avl-node with key, NULL if no node with 
  6.  *    this key exists. 
  7.  */  
  8. struct avl_node * avl_find(const struct avl_tree *tree, const void *key)  
  1. /** 
  2.  * Finds the first node in an avl-tree with a key greater or equal 
  3.  * than the specified key 
  4.  * @param tree pointer to avl-tree 
  5.  * @param key pointer to specified key 
  6.  * @return pointer to avl-node, NULL if no node with 
  7.  *    key greater or equal specified key exists. 
  8.  */  
  9. struct avl_node * avl_find_greaterequal(const struct avl_tree *tree,   
  10.                                          const void *key)  
  1. /** 
  2.  * Finds the last node in an avl-tree with a key less or equal 
  3.  * than the specified key 
  4.  * 
  5.  * @param tree pointer to avl-tree 
  6.  * @param key pointer to specified key 
  7.  * @return pointer to avl-node, NULL if no node with 
  8.  *         key less or equal specified key exists. 
  9.  */  
  10. struct avl_node * avl_find_lessequal(const struct avl_tree *tree, const void *key)  
  1. /** 
  2.  * @param tree pointer to avl-tree 
  3.  * @param key pointer to key 
  4.  * @param element pointer to a node element(don't need to be initialized) 
  5.  * @param node_element name of the avl_node element inside the larger struct 
  6.  * return pointer to tree element with the specified key, 
  7.  *        NULL if no element was found 
  8.  */  
  9. #define avl_find_element(tree, key, element, node_element)  
  1. /** 
  2.  * @param tree pointer to avl-tree 
  3.  * @param key pointer to specified key 
  4.  * @param element pointer to a node element (don't need to be initialized) 
  5.  * @param node_element name of the avl_node element inside the larger struct 
  6.  * return pointer to last tree element with less or equal key than specified key, 
  7.  *        NULL if no element was found 
  8.  */  
  9. #define avl_find_le_element(tree, key, element, node_element)  
  1. /** 
  2.  * @param tree pointer to avl-tree 
  3.  * @param key pointer to specified key 
  4.  * @param element pointer to a node element (don't need to be initialized) 
  5.  * @param node_element name of the avl_node element inside the larger struct 
  6.  * return pointer to first tree element with greater or equal key than  
  7.  *        specified key, NULL if no element was found 
  8.  */  
  9. #define avl_find_ge_element(tree, key, element, node_element)  

获取节点元素

  1. /** 
  2.  * This function must not be called for an empty tree 
  3.  * 
  4.  * @param tree pointer to avl-tree 
  5.  * @param element pointer to a node element (don't need to be initialized) 
  6.  * @param node_member name of the avl_node element inside the larger struct 
  7.  * @return pointer to the first element of the avl_tree 
  8.  *         (automatically converted to type 'element') 
  9.  */  
  10. #define avl_first_element(tree, element, node_member)  
  1. /** 
  2.  * @param tree pointer to tree 
  3.  * @param element pointer to a node struct that contains the avl_node 
  4.  *        (don't need to be initialized) 
  5.  * @param node_member name of the avl_node element inside the 
  6.  *        larger struct 
  7.  * @return pointer to the last element of the avl_tree 
  8.  *         (automatically converted to type 'element') 
  9.  */  
  10. #define avl_last_element(tree, element, node_member)  
  1. /** 
  2.  * This function must not be called for the last element of an avl tree 
  3.  * 
  4.  * @param element pointer to a node of the tree 
  5.  * @param node_member name of the avl_node element inside the larger struct 
  6.  * @return pointer to the node after 'element' 
  7.  *         (automatically converted to type 'element') 
  8.  */  
  9. #define avl_next_element(element, node_member)  
  1. /** 
  2.  * This function must not be called for the first element of 
  3.  * an avl tree 
  4.  * 
  5.  * @param element pointer to a node of the tree 
  6.  * @param node_member name of the avl_node element inside the larger struct 
  7.  * @return pointer to the node before 'element' 
  8.  *         (automatically converted to type 'element') 
  9.  */  
  10. #define avl_prev_element(element, node_member)  

状态判断

  1. /** 
  2.  * @param tree pointer to avl-tree 
  3.  * @param node pointer to node of the tree 
  4.  * @return true if node is the first one of the tree, false otherwise 
  5.  */  
  6. static inline bool avl_is_first(struct avl_tree *tree, struct avl_node *node)  
  1. /** 
  2.  * @param tree pointer to avl-tree 
  3.  * @param node pointer to node of the tree 
  4.  * @return true if node is the last one of the tree, false otherwise 
  5.  */  
  6. static inline bool avl_is_last(struct avl_tree *tree, struct avl_node *node)  
  1. /** 
  2.  * @param tree pointer to avl-tree 
  3.  * @return true if the tree is empty, false otherwise 
  4.  */  
  5. static inline bool avl_is_empty(struct avl_tree *tree)   

遍历

  1. /** 
  2.  * Loop over all elements of an avl_tree, used similar to a for() command. 
  3.  * This loop should not be used if elements are removed from the tree during 
  4.  * the loop. 
  5.  * 
  6.  * @param tree pointer to avl-tree 
  7.  * @param element pointer to a node of the tree, this element will 
  8.  *        contain the current node of the tree during the loop 
  9.  * @param node_member name of the avl_node element inside the 
  10.  *        larger struct 
  11.  */  
  12. #define avl_for_each_element(tree, element, node_member)  
  1. /** 
  2.  * Loop over all elements of an avl_tree backwards, used similar to a for() command. 
  3.  * This loop should not be used if elements are removed from the tree during 
  4.  * the loop. 
  5.  * 
  6.  * @param tree pointer to avl-tree 
  7.  * @param element pointer to a node of the tree, this element will 
  8.  *        contain the current node of the tree during the loop 
  9.  * @param node_member name of the avl_node element inside the 
  10.  *        larger struct 
  11.  */  
  12. #define avl_for_each_element_reverse(tree, element, node_member)  
  1. /** 
  2.  * Loop over all elements of an avl_tree, used similar to a for() command. 
  3.  * This loop can be used if the current element might be removed from 
  4.  * the tree during the loop. Other elements should not be removed during 
  5.  * the loop. 
  6.  * 
  7.  * @param tree pointer to avl-tree 
  8.  * @param element pointer to a node of the tree, this element will 
  9.  *        contain the current node of the tree during the loop 
  10.  * @param node_member name of the avl_node element inside the 
  11.  *        larger struct 
  12.  * @param ptr pointer to a tree element which is used to store 
  13.  *        the next node during the loop 
  14.  */  
  15. #define avl_for_each_element_safe(tree, element, node_member, ptr)  
  1. /** 
  2.  * Loop over all elements of an avl_tree backwards, used similar to a for() command. 
  3.  * This loop can be used if the current element might be removed from 
  4.  * the tree during the loop. Other elements should not be removed during 
  5.  * the loop. 
  6.  * 
  7.  * @param tree pointer to avl-tree 
  8.  * @param element pointer to a node of the tree, this element will 
  9.  *        contain the current node of the tree during the loop 
  10.  * @param node_member name of the avl_node element inside the 
  11.  *        larger struct 
  12.  * @param ptr pointer to a tree element which is used to store 
  13.  *        the next node during the loop 
  14.  */  
  15. #define avl_for_each_element_reverse_safe(tree, element, node_member, ptr)  
  1. /** 
  2.  * A special loop that removes all elements of the tree and cleans up the tree 
  3.  * root. The loop body is responsible to free the node elements of the tree. 
  4.  * 
  5.  * This loop is much faster than a normal one for clearing the tree because it 
  6.  * does not rebalance the tree after each removal. Do NOT use a break command 
  7.  * inside. 
  8.  * You can free the memory of the elements within the loop. 
  9.  * Do NOT call avl_delete() on the elements within the loop, 
  10.  * 
  11.  * @param tree pointer to avl-tree 
  12.  * @param element pointer to a node of the tree, this element will 
  13.  *        contain the current node of the tree during the loop 
  14.  * @param node_member name of the avl_node element inside the 
  15.  *        larger struct 
  16.  * @param ptr pointer to a tree element which is used to store 
  17.  *        the next node during the loop 
  18.  */  
  19. #define avl_remove_all_elements(tree, element, node_member, ptr)  

比较回调函数

查找操作时被调用,此函数在初始化由调用者设置

  1. /** 
  2.  * Prototype for avl comparators 
  3.  * @param k1 first key 
  4.  * @param k2 second key 
  5.  * @param ptr custom data for tree comparator 
  6.  * @return +1 if k1>k2, -1 if k1 
  7.  */  
  8. typedef int (*avl_tree_comp) (const void *k1, const void *k2, void *ptr)  

平衡二叉树Key比较 - avl-cmp.c/h


  1. /** 
  2.  * 用于初始化平衡二叉树,将k1和k2进行字符串比较 
  3.  */  
  4. int avl_strcmp(const void *k1, const void *k2, void *ptr)  

VList(vlist.c/h)

数据结构

  1. struct vlist_tree {  
  2.     struct avl_tree avl;  
  3.   
  4.     vlist_update_cb update;     /** 初始化时调用者设置 */  
  5.     bool keep_old;              /** true-加入相同节点时不删除旧节点,false-删除 
  6.     bool no_delete;             /** true-加入相同节点时不删除旧节点, 
  7.                                  *       删除节点时不做删除操作 
  8.                                  *  false-加入相同节点时删除旧节点 
  9.                                  *        删除节点时做删除操作 
  10.                                  */  
  11.     int version;  
  12. };  
  1. struct vlist_node {  
  2.     struct avl_node avl;  
  3.     int version;  
  4. };  

初始化

  1. void vlist_init(struct vlist_tree *tree, avl_tree_comp cmp, vlist_update_cb update)  

基本操作

加入

  1. void vlist_add(struct vlist_tree *tree, struct vlist_node *node, const void *key)  

删除

  1. void vlist_delete(struct vlist_tree *tree, struct vlist_node *node)  


清除

  1. void vlist_flush(struct vlist_tree *tree)  
  2. void vlist_flush_all(struct vlist_tree *tree)  


查找

  1. #define vlist_find(tree, name, element, node_member)  

遍历

  1. #define vlist_for_each_element(tree, element, node_member)  

更新回调函数


增加和删除节点被回调

  1. typedef void (*vlist_update_cb)(struct vlist_tree *tree,  
  2.                                 struct vlist_node *node_new,  
  3.                 struct vlist_node *node_old);  

Key/Value存储 - kvlist.c/h

数据结构

  1. struct kvlist {  
  2.     struct avl_tree avl;  
  3.     int (*get_len)(struct kvlist *kv, const void *data);  
  4. };  
  1. struct kvlist_node {  
  2.     struct avl_node avl;  
  3.     char data[0] __attribute__((aligned(4)));  
  4. };  

初始化/销毁

  1. void kvlist_init(struct kvlist *kv, int (*get_len)(struct kvlist *kv, const void *data))  
  2. void kvlist_free(struct kvlist *kv)  


基本操作

加入

  1. void kvlist_set(struct kvlist *kv, const char *name, const void *data)  

删除

  1. bool kvlist_delete(struct kvlist *kv, const char *name)  

获取

  1. void *kvlist_get(struct kvlist *kv, const char *name)  

遍历

  1. #define kvlist_for_each(kv, name, value)  

回调用函数

加入操作时被回调,初始化时由调用者设置,用于计算data的内存空间大小

  1. int (*get_len)(struct kvlist *kv, const void *data)  


BLOB二进制大对象 - blob.c/h

数据结构

  1. struct blob_attr {  
  2.     uint32_t id_len;    /** 高1位为extend标志,高7位存储id, 
  3.                          *  低24位存储data的内存大小 */  
  4.     char data[];  
  5. } __packed;  
  1. struct blob_attr_info {  
  2.     unsigned int type;  
  3.     unsigned int minlen;  
  4.     unsigned int maxlen;  
  5.     bool (*validate)(const struct blob_attr_info *, struct blob_attr *);  
  6. };  
  1. struct blob_buf {  
  2.     struct blob_attr *head;  
  3.     bool (*grow)(struct blob_buf *buf, int minlen);  
  4.     int buflen;  
  5.     void *buf;  
  6. };  

存储结构


接口

获取BLOB属性信息

  1. /** 
  2.  * 返回指向BLOB属性数据区指针 
  3.  */  
  4. static inline void * blob_data(const struct blob_attr *attr)  
  1. /** 
  2.  * 返回BLOB属性ID 
  3.  */  
  4. static inline unsigned int blob_id(const struct blob_attr *attr)  
  1. /** 
  2.  * 判断BLOB属性扩展标志是否为真 
  3.  */  
  4. static inline bool blob_is_extended(const struct blob_attr *attr)  
  1. /** 
  2.  * 返回BLOB属性有效存储空间大小 
  3.  */  
  4. static inline unsigned int blob_len(const struct blob_attr *attr)  
  1. /* 
  2.  * 返回BLOB属性完全存储空间大小(包括头部) 
  3.  */  
  4. static inline unsigned int blob_raw_len(const struct blob_attr *attr)  
  1. /* 
  2.  * 返回BLOB属性填补后存储空间大小(包括头部) 
  3.  */  
  4. static inline unsigned int blob_pad_len(const struct blob_attr *attr)  

获取BLOB数据信息

  1. static inline uint8_t blob_get_u8(const struct blob_attr *attr)  
  2.   
  3. static inline uint16_t blob_get_u16(const struct blob_attr *attr)  
  4.   
  5. static inline uint32_t blob_get_u32(const struct blob_attr *attr)  
  6.   
  7. static inline uint64_t blob_get_u64(const struct blob_attr *attr)  
  8.   
  9. static inline int8_t blob_get_int8(const struct blob_attr *attr)  
  10.   
  11. static inline int16_t blob_get_int16(const struct blob_attr *attr)  
  12.   
  13. static inline int32_t blob_get_int32(const struct blob_attr *attr)  
  14.   
  15. static inline int64_t blob_get_int64(const struct blob_attr *attr)  
  16.   
  17. static inline const char * blob_get_string(const struct blob_attr *attr)  


设置BLOB数据信息

  1. static inline struct blob_attr *  
  2.   blob_put_string(struct blob_buf *buf, int id, const char *str)  
  3.     
  4. static inline struct blob_attr *  
  5.   blob_put_u8(struct blob_buf *buf, int id, uint8_t val)  
  6.     
  7. static inline struct blob_attr *  
  8.   blob_put_u16(struct blob_buf *buf, int id, uint16_t val)  
  9.     
  10. static inline struct blob_attr *  
  11.   blob_put_u32(struct blob_buf *buf, int id, uint32_t val)  
  12.     
  13. static inline struct blob_attr *  
  14.   blob_put_u64(struct blob_buf *buf, int id, uint64_t val)  
  1. #define blob_put_int8   blob_put_u8  
  2. #define blob_put_int16  blob_put_u16  
  3. #define blob_put_int32  blob_put_u32  
  4. #define blob_put_int64  blob_put_u64  
  1. struct blob_attr *  
  2.   blob_put(struct blob_buf *buf, int id, const void *ptr, unsigned int len)  
  3.   
  4. /** 
  5.  * ptr - 指向struct blob_attr 
  6.  */  
  7. struct blob_attr *  
  8.   blob_put_raw(struct blob_buf *buf, const void *ptr, unsigned int len)  

遍历

  1. #define __blob_for_each_attr(pos, attr, rem)  
  2. #define blob_for_each_attr(pos, attr, rem)  

复制

  1. struct blob_attr * blob_memdup(struct blob_attr *attr)  

数据类型判断

  1. enum {  
  2.     BLOB_ATTR_UNSPEC,  
  3.     BLOB_ATTR_NESTED,  /** 嵌套 */  
  4.     BLOB_ATTR_BINARY,  
  5.     BLOB_ATTR_STRING,  
  6.     BLOB_ATTR_INT8,  
  7.     BLOB_ATTR_INT16,  
  8.     BLOB_ATTR_INT32,  
  9.     BLOB_ATTR_INT64,  
  10.     BLOB_ATTR_LAST  
  11. };  
  12. bool blob_check_type(const void *ptr, unsigned int len, int type)  

嵌套操作

  1. void * blob_nest_start(struct blob_buf *buf, int id)  
  2. Void blob_nest_end(struct blob_buf *buf, void *cookie)  

判断

  1. bool blob_attr_equal(const struct blob_attr *a1, const struct blob_attr *a2)  

初始化/销毁

  1. /** 
  2.  * 初始化BLOB buffer 
  3.  */  
  4. int blob_buf_init(struct blob_buf *buf, int id)  
  5.   
  6. /** 
  7.  * 销毁BLOB buffer 
  8.  */  
  9. void blob_buf_free(struct blob_buf *buf)  

解析BLOB

  1. /** 
  2.  * 从attr串中根据info策略过滤,得到的结果存储在data属性数组中 
  3.  * 
  4.  * @param  attr 输入BLOB属性串 
  5.  * @param  data 输出BLOB属性数组 
  6.  * @param  info 属性过滤策略 
  7.  * @param  max data数组大小 
  8.  */  
  9. int blob_parse(struct blob_attr *attr, struct blob_attr **data,   
  10.                const struct blob_attr_info *info, int max)  

BLOB消息对象 - blobmsg.c/h

数据结构

  1. struct blobmsg_hdr {  
  2.     uint16_t namelen;  
  3.     uint8_t name[];  
  4. } __packed;  
  5.   
  6. struct blobmsg_policy {  
  7.     const char *name;  
  8.     enum blobmsg_type type;  
  9. };  

存储结构


消息类型

  1. enum blobmsg_type {  
  2.     BLOBMSG_TYPE_UNSPEC,  
  3.     BLOBMSG_TYPE_ARRAY,  
  4.     BLOBMSG_TYPE_TABLE,  
  5.     BLOBMSG_TYPE_STRING,  
  6.     BLOBMSG_TYPE_INT64,  
  7.     BLOBMSG_TYPE_INT32,  
  8.     BLOBMSG_TYPE_INT16,  
  9.     BLOBMSG_TYPE_INT8,  
  10.     __BLOBMSG_TYPE_LAST,  
  11.     BLOBMSG_TYPE_LAST = __BLOBMSG_TYPE_LAST - 1,  
  12.     BLOBMSG_TYPE_BOOL = BLOBMSG_TYPE_INT8,  
  13. };  

接口

基本操作

  1. /** 
  2.  * 根据BLOB消息名字长度计算出blobmsg头部大小 
  3.  */  
  4. static inline int blobmsg_hdrlen(unsigned int namelen)  
  5.   
  6. /** 
  7.  * 获取BLOB消息名字 
  8.  */  
  9. static inline const char *blobmsg_name(const struct blob_attr *attr)  
  10.   
  11. /** 
  12.  * 获取BLOB消息类型 
  13.  */  
  14. static inline int blobmsg_type(const struct blob_attr *attr)  
  15.   
  16. /** 
  17.  * 获取BLOB消息数据内容 
  18.  */  
  19. static inline void *blobmsg_data(const struct blob_attr *attr)  
  20.   
  21. /** 
  22.  * 获取BLOB消息数据内容大小 
  23.  */  
  24. static inline int blobmsg_data_len(const struct blob_attr *attr)  
  25. static inline int blobmsg_len(const struct blob_attr *attr)  

数据类型判断

  1. /** 
  2.  * 判断BLOBMSG属性类型是否合法 
  3.  */  
  4. bool blobmsg_check_attr(const struct blob_attr *attr, bool name)  

设置

  1. int blobmsg_add_field(struct blob_buf *buf, int type, const char *name,  
  2.                       const void *data, unsigned int len)  
  3.   
  4. static inline int  
  5. blobmsg_add_u8(struct blob_buf *buf, const char *name, uint8_t val)  
  6.   
  7. static inline int  
  8. blobmsg_add_u16(struct blob_buf *buf, const char *name, uint16_t val)  
  9.   
  10. static inline int  
  11. blobmsg_add_u32(struct blob_buf *buf, const char *name, uint32_t val)  
  12.   
  13. static inline int  
  14. blobmsg_add_u64(struct blob_buf *buf, const char *name, uint64_t val)  
  15.   
  16. static inline int  
  17. blobmsg_add_string(struct blob_buf *buf, const char *name, const char *string)  
  18.   
  19. static inline int  
  20. blobmsg_add_blob(struct blob_buf *buf, struct blob_attr *attr)  
  21.   
  22. /** 
  23.  * 格式化设备BLOGMSG 
  24.  */  
  25. void blobmsg_printf(struct blob_buf *buf, const char *name, const char *format, ...)  

获取

  1. static inline uint8_t blobmsg_get_u8(struct blob_attr *attr)  
  2. static inline bool blobmsg_get_bool(struct blob_attr *attr)  
  3. static inline uint16_t blobmsg_get_u16(struct blob_attr *attr)  
  4. static inline uint32_t blobmsg_get_u32(struct blob_attr *attr)  
  5. static inline uint64_t blobmsg_get_u64(struct blob_attr *attr)  
  6. static inline char *blobmsg_get_string(struct blob_attr *attr)  

创建

  1. /** 
  2.  * 创建BLOBMSG,返回数据区开始地址 
  3.  */  
  4. void *blobmsg_alloc_string_buffer(struct blob_buf *buf, const char *name,   
  5.   unsigned int maxlen)  
  6.   
  7. /** 
  8.  * 扩大BLOGMSG,返回数据区开始地址 
  9.  */  
  10. void *blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen)  
  11.   
  12. void blobmsg_add_string_buffer(struct blob_buf *buf)  

遍历

  1. #define blobmsg_for_each_attr(pos, attr, rem)  

嵌套操作

  1. static inline void * blobmsg_open_array(struct blob_buf *buf, const char *name)  
  2. static inline void blobmsg_close_array(struct blob_buf *buf, void *cookie)  
  3.   
  4. static inline void *blobmsg_open_table(struct blob_buf *buf, const char *name)  
  5. static inline void blobmsg_close_table(struct blob_buf *buf, void *cookie)  

解析BLOGMSG

  1. /** 
  2.  * 从data BLOGMSG串中根据policy策略过滤,得到的结果存储在tb BLOGATTR数组中 
  3.  * 
  4.  * @param  policy 过滤策略 
  5.  * @param  policy_len 策略个数 
  6.  * @param  tb 返回属性数据 
  7.  * @param  len data属性个数 
  8.  */  
  9. int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len,  
  10.                   struct blob_attr **tb, void *data, unsigned int len)  

事件处理循环 - uloop.c/h

接口说明

主框架

  1. /** 
  2.  * 初始化事件循环 
  3.  */  
  4. int uloop_init(void)  
  5.   
  6. /** 
  7.  * 事件循环主处理入口 
  8.  */  
  9. void uloop_run(void)  
  10.   
  11. /** 
  12.  * 销毁事件循环 
  13.  */  
  14. void uloop_done(void)  

描述符事件

  1. /** 
  2.  * 注册一个新描述符到事件处理循环 
  3.  */  
  4. int uloop_fd_add(struct uloop_fd *sock, unsigned int flags)  
  5.   
  6. /**  
  7.  * 从事件处理循环中销毁指定描述符 
  8.  */  
  9. int uloop_fd_delete(struct uloop_fd *sock)  

定时器事件

  1. /** 
  2.  * 注册一个新定时器 
  3.  */  
  4. int uloop_timeout_add(struct uloop_timeout *timeout)  
  5.   
  6. /** 
  7.  * 设置定时器超时时间(毫秒),并添加 
  8.  */  
  9. int uloop_timeout_set(struct uloop_timeout *timeout, int msecs)  
  10.   
  11. /** 
  12.  * 销毁指定定时器 
  13.  */  
  14. int uloop_timeout_cancel(struct uloop_timeout *timeout)  
  15.   
  16. /** 
  17.  * 获取定时器还剩多长时间超时 
  18.  */  
  19. int uloop_timeout_remaining(struct uloop_timeout *timeout)  

进程事件

  1. /** 
  2.  * 注册新进程到事件处理循环 
  3.  */  
  4. int uloop_process_add(struct uloop_process *p)  
  5.   
  6. /** 
  7.  * 从事件处理循环中销毁指定进程 
  8.  */  
  9. int uloop_process_delete(struct uloop_process *p)  

数据结构

描述符

  1. struct uloop_fd  
  2. {  
  3.     uloop_fd_handler cb;                /** 文件描述符,调用者初始化 */  
  4.     int fd;                         /** 文件描述符,调用者初始化 */  
  5.     bool eof;                         
  6.     bool error;                       
  7.     bool registered;                      
  8.     uint8_t flags;                        
  9. };  

定时器

  1. struct uloop_timeout  
  2. {  
  3.     struct list_head list;                
  4.     bool pending;                 
  5.     uloop_timeout_handler cb;           /** 文件描述符, 调用者初始化 */  
  6.     struct timeval time;                /** 文件描述符, 调用者初始化 */  
  7. };  

进程

  1. struct uloop_process  
  2. {  
  3.     struct list_head list;                
  4.     bool pending;                     
  5.     uloop_process_handler cb;       /** 文件描述符, 调用者初始化 */  
  6.     pid_t pid;                      /** 文件描述符, 调用者初始化 */  
  7. };  

事件回调函数

描述符

  1. typedef void (*uloop_fd_handler)(struct uloop_fd *u, unsigned int events)  

定时器

  1. typedef void (*uloop_timeout_handler)(struct uloop_timeout *t)  

进程

  1. typedef void (*uloop_process_handler)(struct uloop_process *c, int ret)  

事件标志

  1. #define ULOOP_READ      (1 << 0)  
  2. #define ULOOP_WRITE     (1 << 1)  
  3. #define ULOOP_EDGE_TRIGGER  (1 << 2)  
  4. #define ULOOP_BLOCKING      (1 << 3)  
  5. #define ULOOP_EVENT_MASK    (ULOOP_READ | ULOOP_WRITE)  

流缓冲管理 - ustream.c/h/ustream-fd.c

数据结构

  1. struct ustream_buf {  
  2.     struct ustream_buf *next;  
  3.   
  4.     char *data;     /** 指向上次操作buff开始地址 */  
  5.     char *tail;     /** 指向未使用buff开始地址 */  
  6.     char *end;      /** 指向buf结束地址 */  
  7.   
  8.     char head[];    /** 指向buf开始地址 */  
  9. };  
  1. struct ustream_buf_list {  
  2.     struct ustream_buf *head;       /** 指向第1块ustream_buf */  
  3.     struct ustream_buf *data_tail;  /** 指向未使用的ustream_buf */  
  4.     struct ustream_buf *tail;       /** 指向最后的ustream_buf */  
  5.   
  6.     int (*alloc)(struct ustream *s, struct ustream_buf_list *l);  
  7.   
  8.     int data_bytes;    /** 已用存储空间大小 */  
  9.   
  10.     int min_buffers;   /** 可存储最小的ustream_buf块个数 */  
  11.     int max_buffers;   /** 可存储最大的ustream_buf块个数 */  
  12.     int buffer_len;    /** 每块ustream_buf块存储空间大小 */  
  13.   
  14.     int buffers;       /** ustream_buf块个数 */  
  15. };  
  1. struct ustream {  
  2.     struct ustream_buf_list r, w;  
  3.     struct uloop_timeout state_change;  
  4.     struct ustream *next;  
  5.   
  6.     /* 
  7.      * notify_read: (optional) 
  8.      * called by the ustream core to notify that new data is available 
  9.      * for reading. 
  10.      * must not free the ustream from this callback 
  11.      */  
  12.     void (*notify_read)(struct ustream *s, int bytes_new);  
  13.   
  14.     /* 
  15.      * notify_write: (optional) 
  16.      * called by the ustream core to notify that some buffered data has 
  17.      * been written to the stream. 
  18.      * must not free the ustream from this callback 
  19.      */  
  20.     void (*notify_write)(struct ustream *s, int bytes);  
  21.   
  22.     /* 
  23.      * notify_state: (optional) 
  24.      * called by the ustream implementation to notify that the read 
  25.      * side of the stream is closed (eof is set) or there was a write 
  26.      * error (write_error is set). 
  27.      * will be called again after the write buffer has been emptied when 
  28.      * the read side has hit EOF. 
  29.      */  
  30.     void (*notify_state)(struct ustream *s);  
  31.   
  32.     /* 
  33.      * write: 
  34.      * must be defined by ustream implementation, accepts new write data. 
  35.      * 'more' is used to indicate that a subsequent call will provide more 
  36.      * data (useful for aggregating writes) 
  37.      * returns the number of bytes accepted, or -1 if no more writes can 
  38.      * be accepted (link error) 
  39.      */  
  40.     int (*write)(struct ustream *s, const char *buf, int len, bool more);  
  41.   
  42.     /* 
  43.      * free: (optional) 
  44.      * defined by ustream implementation, tears down the ustream and frees data 
  45.      */  
  46.     void (*free)(struct ustream *s);  
  47.   
  48.     /* 
  49.      * set_read_blocked: (optional) 
  50.      * defined by ustream implementation, called when the read_blocked flag 
  51.      * changes 
  52.      */  
  53.     void (*set_read_blocked)(struct ustream *s);  
  54.   
  55.     /* 
  56.      * poll: (optional) 
  57.      * defined by the upstream implementation, called to request polling for 
  58.      * available data. 
  59.      * returns true if data was fetched. 
  60.      */  
  61.     bool (*poll)(struct ustream *s);  
  62.   
  63.     /* 
  64.      * ustream user should set this if the input stream is expected 
  65.      * to contain string data. the core will keep all data 0-terminated. 
  66.      */  
  67.     bool string_data;     /** 此ustream是否为字符串,true-是;false-否 */  
  68.     bool write_error;     /** 写出错,true-是;false-否 */  
  69.     bool eof, eof_write_done;  
  70.   
  71.     enum read_blocked_reason read_blocked;  
  72. };  
  1. struct ustream_fd {  
  2.     struct ustream stream;  
  3.     struct uloop_fd fd;  
  4. };  

存储结构



接口

初始/销毁

  1. /** 
  2.  * ustream_fd_init: create a file descriptor ustream (uses uloop)  
  3.  */  
  4. void ustream_fd_init(struct ustream_fd *s, int fd)  
  5.   
  6. /** 
  7.  * ustream_init_defaults: fill default callbacks and options  
  8.  */  
  9. void ustream_init_defaults(struct ustream *s)  
  10.   
  11. /** 
  12.  * ustream_free: free all buffers and data associated with a ustream  
  13.  */  
  14. void ustream_free(struct ustream *s)  

写入read buffer

  1. /* 
  2.  * ustream_reserve: allocate rx buffer space 
  3.  *      分配len大小的read buffer可用内存空间,与ustream_fill_read()配合使用 
  4.  * 
  5.  * len: hint for how much space is needed (not guaranteed to be met) 
  6.  * maxlen: pointer to where the actual buffer size is going to be stored 
  7.  */  
  8. char *ustream_reserve(struct ustream *s, int len, int *maxlen)  
  1. /** 
  2.  * ustream_fill_read: mark rx buffer space as filled  
  3.  *      设置被ustream_reseve()分配read buffer后写入的数据大小, 
  4.  *      回调notify_read()接口,表示有数据可读 
  5.  */  
  6. void ustream_fill_read(struct ustream *s, int len)  

读出read buffer

一般在notify_read()回调接口使用

  1. /*  
  2.  * ustream_get_read_buf: get a pointer to the next read buffer data  
  3.  *      获取新一次写入的内容,与ustream_consume()配置使用 
  4.  */  
  5. char *ustream_get_read_buf(struct ustream *s, int *buflen)  
  1. /** 
  2.  * ustream_consume: remove data from the head of the read buffer  
  3.  */  
  4. void ustream_consume(struct ustream *s, int len)  

操作write buffer

尽最大能力调用write()回调用接口写入,如果超出能力将把未写入的数据存储在write buffer中

  1. /*  
  2.  * ustream_write: add data to the write buffer  
  3.  */  
  4. int ustream_write(struct ustream *s, const char *buf, int len, bool more)  
  5. int ustream_printf(struct ustream *s, const char *format, ...)  
  6. int ustream_vprintf(struct ustream *s, const char *format, va_list arg)  

把在write buffer中的数据写入实际地方,调用write()回调接口和notify_write()回调接口。一般在描述符的poll操作中调用,表示当描述符变为可写时立即把上一次未写入的内容进行写入操作。

  1. /* 
  2.  * ustream_write_pending: attempt to write more data from write buffers 
  3.  * returns true if all write buffers have been emptied. 
  4.  */  
  5. bool ustream_write_pending(struct ustream *s)  

任务队列 - runqueue.c/h

数据结构 

  1. struct runqueue {  
  2.     struct safe_list tasks_active;      /** 活动任务队列 */  
  3.     struct safe_list tasks_inactive;    /** 不活动任务队列 */  
  4.     struct uloop_timeout timeout;  
  5.   
  6.     int running_tasks;      /** 当前活动任务数目 */  
  7.     int max_running_tasks;  /** 允许最大活动任务数目 */  
  8.     bool stopped;           /** 是否停止任务队列 */  
  9.     bool empty;             /** 任务队列(包括活动和不活动)是否为空 */  
  10.   
  11.     /* called when the runqueue is emptied */  
  12.     void (*empty_cb)(struct runqueue *q);  
  13. };  
  1. struct runqueue_task_type {  
  2.     const char *name;  
  3.   
  4.     /* 
  5.      * called when a task is requested to run 
  6.      * 
  7.      * The task is removed from the list before this callback is run. It 
  8.      * can re-arm itself using runqueue_task_add. 
  9.      */  
  10.     void (*run)(struct runqueue *q, struct runqueue_task *t);  
  11.   
  12.     /* 
  13.      * called to request cancelling a task 
  14.      * 
  15.      * int type is used as an optional hint for the method to be used when 
  16.      * cancelling the task, e.g. a signal number for processes. Calls 
  17.      * runqueue_task_complete when done. 
  18.      */  
  19.     void (*cancel)(struct runqueue *q, struct runqueue_task *t, int type);  
  20.   
  21.     /* 
  22.      * called to kill a task. must not make any calls to runqueue_task_complete, 
  23.      * it has already been removed from the list. 
  24.      */  
  25.     void (*kill)(struct runqueue *q, struct runqueue_task *t);  
  26. };  
  1. struct runqueue_task {  
  2.     struct safe_list list;  
  3.     const struct runqueue_task_type *type;  
  4.     struct runqueue *q;  
  5.   
  6.     void (*complete)(struct runqueue *q, struct runqueue_task *t);  
  7.   
  8.     struct uloop_timeout timeout;  
  9.     int run_timeout;    /** >0表示规定此任务执行只有run_timeout毫秒 */  
  10.     int cancel_timeout; /** >0表示规则任务延取消操作执行只有run_timeout毫秒*/  
  11.     int cancel_type;  
  12.   
  13.     bool queued;        /** 此任务是否已加入任务队列中 */  
  14.     bool running;       /** 此任务是否活动,即已在活动队列中 */  
  15.     bool cancelled;     /** 此任务是否已被取消 */  
  16. };  
  1. struct runqueue_process {  
  2.     struct runqueue_task task;  
  3.     struct uloop_process proc;  
  4. };  

接口说明

任务队列

  1. /** 
  2.  * 初始化任务队列 
  3.  */  
  4. void runqueue_init(struct runqueue *q)  
  5.   
  6. /**  
  7.  * 取消所有任务队列 
  8.  */  
  9. void runqueue_cancel(struct runqueue *q);  
  10.   
  11. /**  
  12.  * 取消活动中的任务 
  13.  */  
  14. void runqueue_cancel_active(struct runqueue *q);  
  15.   
  16. /**  
  17.  * 取消不活动的任务  
  18.  */  
  19. void runqueue_cancel_pending(struct runqueue *q);  
  20.   
  21. /** 
  22.  * 杀死所有任务 
  23.  */  
  24. void runqueue_kill(struct runqueue *q);  
  25.   
  26. /**  
  27.  * 停止所有任务 
  28.  */  
  29. void runqueue_stop(struct runqueue *q);  
  30.   
  31. /** 
  32.  * 重新开始任务 
  33.  */  
  34. void runqueue_resume(struct runqueue *q);  

任务操作

  1. /** 
  2.  * 添加新任务到队列尾 
  3.  * 
  4.  * @running true-加入活动队列;false-加入不活动队列 
  5.  */  
  6. void runqueue_task_add(struct runqueue *q, struct runqueue_task *t, bool running);  
  7.   
  8. /** 
  9.  * 添加新任务到队列头 
  10.  * 
  11.  * @running true-加入活动队列;false-加入不活动队列 
  12.  */  
  13. void runqueue_task_add_first(struct runqueue *q, struct runqueue_task *t,   
  14.   bool running);  
  15.   
  16. /** 
  17.  * 完全任务 
  18.  */  
  19. void runqueue_task_complete(struct runqueue_task *t);  
  20.   
  21. /** 
  22.  * 取消任务 
  23.  */  
  24. void runqueue_task_cancel(struct runqueue_task *t, int type);  
  25.   
  26. /** 
  27.  * 杀死任务 
  28.  */  
  29. void runqueue_task_kill(struct runqueue_task *t);  

进程任务

  1. void runqueue_process_add(struct runqueue *q, struct runqueue_process *p,   
  2.   pid_t pid);  
  3.   
  4. /** 
  5.  * to be used only from runqueue_process callbacks  
  6.  */  
  7. void runqueue_process_cancel_cb(struct runqueue *q, struct runqueue_task *t,   
  8.   int type);  
  9. void runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *t);  

阅读(2312) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~