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. Hexo+NextT第三方服务调用【4】

    该系列博客列表请访问:http://www.cnblogs.com/penglei-it/category/934299.html 摘要        静态站点与动态站点有很大的不一样,它拥有一定的局 ...

  2. Java Volatile transient 关键字

    随笔-204  评论-134  文章-0  trackbacks-0   Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变 ...

  3. [原译]在mongoose中对Array Schema进行增删改

    原文地址: http://tech-blog.maddyzone.com/node/add-update-delete-object-array-schema-mongoosemongodb 本文为上 ...

  4. 无U盘安装Linux openSUSE(通过硬盘安装Linux)

    一.说明 为什么会想着用硬盘安装Linux?只是因为我陆陆续续买了两个U盘,然后它们都丢了,就没再买了.然而现在又想装个openSUSE,没有U盘,只能想办法通过硬盘安装. 记录自己走过的弯路,同时也 ...

  5. [ios2] CABasicAnimation【转】

    caanimation 整理了解  http://geeklu.com/2012/09/animation-in-ios/ 几个可以用来实现热门APP应用PATH中menu效果的几个方法 +(CABa ...

  6. 【转】关于python中re模块split方法的使用

    注:最近在研究文本处理,需要用到正则切割文本,所以收索到了这篇文章,很有用,谢谢原作者. 原址:http://blog.sciencenet.cn/blog-314114-775285.html 关于 ...

  7. Linux系统下给非root用户添加sudo权限

    Linux系统下给非root用户添加sudo权限 有时,在linux系统中非root用户运行sudo命令,会提示类似信息:  xxx is not in the sudoers file. This ...

  8. HDU 3361 ASCII

    Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others)Total Submission ...

  9. 关于onCreate(Bundle savedInstanceState, PersistableBundle persistentState)

    API 21为Activity增加了一个新的属性,只要将其设置成persistAcrossReboots,activity就有了持久化的能力,另外需要配合一个新的bundle才行,那就是Persist ...

  10. 带分页、过滤条件的DSL

    "query": { "bool": { "must_not": { "match_phrase": { "p ...