2017-1-15-libubox analysis

libubox

utils.h

提供了一些简单的实用工具函数。比如大小端转换,位图操作,编译器属性的封装,连续内存申请函数calloc_a,静态计算数组大小的宏,断言/调试的实用工具,苹果兼容的时钟获取时间的封装,base64编解码。

  1. /* 

  2. *  

  3. * calloc_a(size_t len, [void **addr, size_t len,...], NULL) 

  4. * 申请一个足够大内存块来保存多个对齐的对象。 

  5. * 返回一个指针,指针指向全部对象(以第一个块开始)注意:释放这个指针将释放所有全部对象的内存 

  6. * 所有其它指针被保存在额外的addr参数指向的位置。 

  7. * 最后一个参数必须是NULL指针 

  8. */ 


  9. #define calloc_a(len, ...) __calloc_a(len, ##__VA_ARGS__, NULL) 

  10. void *__calloc_a(size_t len, ...); 


calloc_a示例:

  1. #include <string.h> 

  2. #include <libubox/utils.h> 


  3. struct sleeper { 

  4. int aa; 

  5. int bb; 

  6. }; 


  7. #define NAME_LEN 32 

  8. int main(int argc, char **argv) 



  9. struct sleeper *s; 

  10. char *name; 

  11. int *a1; 

  12. s = (struct sleeper *)calloc_a(sizeof(*s), &name, NAME_LEN, &a1, sizeof(*a1)); 

  13. s->aa = 0x10101010; 

  14. s->bb = 0x20202020; 

  15. strncpy(name, "SSSSSSSSSSSSSSSSSSSSSSSS", NAME_LEN-1); 

  16. name[NAME_LEN-1] = '\0'; 

  17. *a1 = 0xaaaaaaaa; 

  18. free(s); 

  19. return 0; 




  20. (gdb) x/20x s 

  21. 0x602010: 0x10101010 0x20202020 0x53535353 0x53535353 

  22. 0x602020: 0x53535353 0x53535353 0x53535353 0x53535353 

  23. 0x602030: 0x00000000 0x00000000 0xaaaaaaaa 0x00000000 

  1. /* 

  2. * 计算数组大小 

  3. */ 

  4. #ifndef ARRAY_SIZE 

  5. #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 

  6. #endif 

  1. /* 

  2. * BUILD_BUG_ON基于一个GCC不支持负数数组,在编译时报错 

  3. * 但是4.4后GCC支持变长数组,不会引起编译器报错。 

  4. * 加入GCC优化选项后,编译时不会错,但是链接时会有找不到符号__BUILD_BUG_ON_CONDITION_FAILED的错误 

  5. */ 

  6. #define __BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 


  7. #ifdef __OPTIMIZE__ 

  8. extern int __BUILD_BUG_ON_CONDITION_FAILED; 

  9. #define BUILD_BUG_ON(condition) \ 

  10. do { \ 

  11. __BUILD_BUG_ON(condition); \ 

  12. if (condition) \ 

  13. __BUILD_BUG_ON_CONDITION_FAILED = 1; \ 

  14. } while(0) 

  15. #else 

  16. #define BUILD_BUG_ON __BUILD_BUG_ON 

  17. #endif 

FIXUP for BUILD_BUG_ON:

  1. /* Force a compilation error if condition is true */ 

  2. -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 

  3. +#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition)) 



  4. +/* Force a compilation error if condition is constant and true */ 

  5. +#define MAYBE_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)])) 


  6. /* Force a compilation error if condition is true, but also produce a 

  7. result (of value 0 and type size_t), so the expression can be used 

  8. e.g. in a structure initializer (or where-ever else comma expressions 

  9. aren't permitted). */ 

  10. -#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) 

  11. +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) 

  12. +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) 

  1. /* 

  2. */ 

  3. #ifdef __APPLE__ 


  4. #define CLOCK_REALTIME 0 

  5. #define CLOCK_MONOTONIC 1 


  6. void clock_gettime(int type, struct timespec *tv); 


  7. #endif 

  1. #ifdef __GNUC__ 

  2. #define _GNUC_MIN_VER(maj, min) (((__GNUC__ << 8) + __GNUC_MINOR__) >= (((maj) << 8) + (min))) 

  3. #else 

  4. #define _GNUC_MIN_VER(maj, min) 0 

  5. #endif 


  6. #if defined(__linux__) || defined(__CYGWIN__) 

  7. #include <byteswap.h> 

  8. #include <endian.h> 


  9. #elif defined(__APPLE__) 

  10. #include <machine/endian.h> 

  11. #include <machine/byte_order.h> 

  12. #define bswap_32(x) OSSwapInt32(x) 

  13. #define bswap_64(x) OSSwapInt64(x) 

  14. #elif defined(__FreeBSD__) 

  15. #include <sys/endian.h> 

  16. #define bswap_32(x) bswap32(x) 

  17. #define bswap_64(x) bswap64(x) 

  18. #else 

  19. #include <machine/endian.h> 

  20. #define bswap_32(x) swap32(x) 

  21. #define bswap_64(x) swap64(x) 

  22. #endif 


  23. #ifndef __BYTE_ORDER 

  24. #define __BYTE_ORDER BYTE_ORDER 

  25. #endif 

  26. #ifndef __BIG_ENDIAN 

  27. #define __BIG_ENDIAN BIG_ENDIAN 

  28. #endif 

  29. #ifndef __LITTLE_ENDIAN 

  30. #define __LITTLE_ENDIAN LITTLE_ENDIAN 

  31. #endif 


  32. #define __u_bswap16(x) ({ uint16_t val = (x); ((uint16_t)(((val >> 8) & 0xffu) | ((val & 0xffu) << 8))); }) 


  33. #if _GNUC_MIN_VER(4, 2) 

  34. #define __u_bswap32(x) __builtin_bswap32(x) 

  35. #define __u_bswap64(x) __builtin_bswap64(x) 

  36. #else 

  37. #define __u_bswap32(x) bswap_32(x) 

  38. #define __u_bswap64(x) bswap_64(x) 

  39. #endif 


  40. #if __BYTE_ORDER == __LITTLE_ENDIAN 


  41. #define cpu_to_be64(x) __u_bswap64(x) 

  42. #define cpu_to_be32(x) __u_bswap32(x) 

  43. #define cpu_to_be16(x) __u_bswap16((uint16_t) (x)) 


  44. #define be64_to_cpu(x) __u_bswap64(x) 

  45. #define be32_to_cpu(x) __u_bswap32(x) 

  46. #define be16_to_cpu(x) __u_bswap16((uint16_t) (x)) 


  47. #define cpu_to_le64(x) (x) 

  48. #define cpu_to_le32(x) (x) 

  49. #define cpu_to_le16(x) (x) 


  50. #define le64_to_cpu(x) (x) 

  51. #define le32_to_cpu(x) (x) 

  52. #define le16_to_cpu(x) (x) 


  53. #else /* __BYTE_ORDER == __LITTLE_ENDIAN */ 


  54. #define cpu_to_le64(x) __u_bswap64(x) 

  55. #define cpu_to_le32(x) __u_bswap32(x) 

  56. #define cpu_to_le16(x) __u_bswap16((uint16_t) (x)) 


  57. #define le64_to_cpu(x) __u_bswap64(x) 

  58. #define le32_to_cpu(x) __u_bswap32(x) 

  59. #define le16_to_cpu(x) __u_bswap16((uint16_t) (x)) 


  60. #define cpu_to_be64(x) (x) 

  61. #define cpu_to_be32(x) (x) 

  62. #define cpu_to_be16(x) (x) 


  63. #define be64_to_cpu(x) (x) 

  64. #define be32_to_cpu(x) (x) 

  65. #define be16_to_cpu(x) (x) 


  66. #endif 


  67. #ifndef __packed 

  68. #define __packed __attribute__((packed)) 

  69. #endif 


  70. #ifndef BITS_PER_LONG 

  71. #define BITS_PER_LONG (8 * sizeof(unsigned long)) 

  72. #endif 


  73. static inline void bitfield_set(unsigned long *bits, int bit) 



  74. bits[bit / BITS_PER_LONG] |= (1UL << (bit % BITS_PER_LONG)); 




  75. static inline bool bitfield_test(unsigned long *bits, int bit) 



  76. return !!(bits[bit / BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))); 




  77. #endif 


nicephil@gmail.com

2017-1-15-libubox analysis的更多相关文章

  1. Visual Studio 2017 发布 15.5 版本,百度网盘离线安装包下载。

    Visual Studio 2017 15.5 版本已正式发布,同时发布的还有 Visual Studio for Mac 7.3 .此次更新包含主要性能改进,新特性以及 bug 修复.发行说明中文版 ...

  2. Visual Studio 2017 版本 15.5.5

    Visual Studio 2017 版本 15.5.5 已修复的问题 (1)Xamarin 应用会引发“Cannot access a disposed object. Object name: ' ...

  3. 2017.11.15 String、StringBuffer、StringBuilder的比较(todo)

    参考来自:http://blog.csdn.net/jeffleo/article/details/52194433 1.速度 一般来说,三者的速度是:StringBuilder > Strin ...

  4. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第二十一章-授予身份与切换身份(二) 1.回顾 ...

  5. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某 ...

  6. CUDA 9.1/9.2 与 Visual Studio 2017 (VS2017 15.6.4) 的不兼容问题

    2018年7月9日更新: CUDA已推出9.2版本,最高支持MSVC++ 14.13 _MSC_VER == 1913 (Visual Studio 2017 version 15.6). 然而最新版 ...

  7. Visual Studio 2017版本15.9现在可用

    本文转自 https://blogs.msdn.microsoft.com/visualstudio/2018/11/19/visual-studio-2017-version-15-9-now-av ...

  8. Codeforces Educational Codeforces Round 15 E - Analysis of Pathes in Functional Graph

    E. Analysis of Pathes in Functional Graph time limit per test 2 seconds memory limit per test 512 me ...

  9. April 11 2017 Week 15 Tuesday

    Love is hard to get into, but harder to get out of. 相爱不易,相忘更难. The past are hurt, but I think we can ...

  10. 2017.5.15 markdown简明教程

    0.说明 markdown是一种书写格式,html是一种发布格式.markdown的语法种类只对应html标记的一小部分(只涵盖纯文本). 不在markdown涵盖范围的标签,都可以直接在文档里用ht ...

随机推荐

  1. dd命令详解

    一.dd命令的解释. dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾则乘以相应的数字:b=512:c=1:k=1024:w=2 参数: 1. i ...

  2. canvas中window坐标转换为canvas坐标

    function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return { x: evt.clien ...

  3. windows下安装Django

    因为Django本身是由Python编写,所以先要安装Python.下载地址(可以根据读者当前版本自行下载):http://www.python.org/download/releases/3.3.4 ...

  4. azkaben任务调度器

    azkaban学习笔记总结 01.工作流调度器azkaban 1. 任务调度概述 一个完整的数据分析系统通常都是由大量任务单元组成: shell脚本程序,java程序,mapreduce程序.hive ...

  5. 结构-行为-样式-Javascript 深度克隆函数(转)

    突然想到有一回面试的时候有一个问题一直挂在心头,于是乎在网上找了找,这个比较好: //深度克隆 function deepClone(obj) { var result, oClass = isCla ...

  6. H3 BPM报销流程开发示例

    以报销流程为示例,介绍H3 BPM的流程开发过程. 报销流程的表单效果如下: 审核流程为填写报销申请.主管审核.总监审核(1000以上).出纳付款,显示如下: 步骤一:准备工作 使用管理员账号的登录H ...

  7. 第一百三十一节,JavaScript,封装库--CSS

    JavaScript,封装库--CSS 将封装库里的方法,改成了原型添加方法 增加4个方法 tian_jia_class()方法,给获取到的元素添加class属性,参数是class属性值,可以连缀1 ...

  8. mac nodejs安装

    很久没有配置开发环境了,刚换了新电脑,正好借机会重新配置一下node相关的开发环境 安装 nvm :Node Version Manager 由于nodejs版本更新迭代较快,而不同版本间的差异又很大 ...

  9. cocoaPods第三方库使用详解

    终端上安装了cocoapods后,打开终端输入下面命令: cd /Users/Sivek_lin/Desktop/AFNTest/AFNTest touch podfile pod search af ...

  10. DuiLib 中滚动条不显示的问题

    DuiLib 很好用,同时在没有完全理解源码的前提下,坑也不少,比如今天遇到的添加滚动条不显示... 情况是这样的,将一个页面作为Tab控件的其中一页,为了代码不窝在一起,就没有在CreateCont ...