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. { 

  10. struct sleeper *s; 

  11. char *name; 

  12. int *a1; 

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

  14. s->aa = 0x10101010; 

  15. s->bb = 0x20202020; 

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

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

  18. *a1 = 0xaaaaaaaa; 

  19. free(s); 

  20. return 0; 

  21. } 


  22. (gdb) x/20x s 

  23. 0x602010: 0x10101010 0x20202020 0x53535353 0x53535353 

  24. 0x602020: 0x53535353 0x53535353 0x53535353 0x53535353 

  25. 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. + 

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

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


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

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

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

  10. aren't permitted). */ 

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

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

  13. +#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. { 

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

  76. } 


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

  78. { 

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

  80. } 


  81. #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. Netty轻量级对象池实现分析

    什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的概念.对象池缓存了一些已经创建好的对象,避免需要时才创建对象,同时限制了实例的个数.池 ...

  2. PHP关于foreach使用引用变量的坑

    写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: <?php $arr = ['a', 'b', 'c', 'd', 'e' ...

  3. (二)Python是一门什么样的语言?

    在学习python是一门什么样的语言之前首先需要知道什么是编译和解释? 编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快; 而 ...

  4. USB调试不能弹出授权窗口 unauthorized 的解决办法

    今天把 AndroidStudio 1.5 给卸载了,重新安装 2.1版本,据说速度快了很多,结果手机一直没法授权调试,授权USB调试信任PC设备的窗口始终没看到,网上找了好多方法,什么驱动.重启.各 ...

  5. Perception(1.2)

    4.1.2 Definition of Coordinate Systems The global coordinate system is described by its origin lying ...

  6. RelativeLayout各个属性

    android:layout_above="@id/xxx"  --将控件置于给定ID控件之上 android:layout_below="@id/xxx"  ...

  7. Zabbix概念、安装以及快速入门

    Zabbix is an enterprise-class open source distributed monitoring solution.[1] Zabbix是一个企业级的.开源的.分布式的 ...

  8. jQuery datepicker和jQuery validator 共用时bug

    当我们给一个元素绑定一个datepick后又要对它用validator进行验证时会发现验证并没有成功 因为当点击该元素时候input弹出datepick的UI就已经失去了焦点它验证的仍然是前一个值, ...

  9. JavaScript进阶(一)

     OK接下来,我们再次梳理一遍js并且提高一个等级. 众所周知,web前端开发者需要了解html和css,会只用html和css创建一个漂亮的页 面,但是这肯定是不够的,因为它只是一个静态的页面,我们 ...

  10. 关于java的设计模式(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...