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. poj 1088 滑雪(贪心算法)

    思想: (贪心算法 ,看到题目是中文才做的) 先对数组中的数据进行排序,从最小的数据计算 当前的顶点的可以滑行的最大值=max(周围可达的顶点的可以滑行的最大值)+1 这样计算最后产生的路径肯定是最大 ...

  2. 开源中文分词工具探析(三):Ansj

    Ansj是由孙健(ansjsun)开源的一个中文分词器,为ICTLAS的Java版本,也采用了Bigram + HMM分词模型(可参考我之前写的文章):在Bigram分词的基础上,识别未登录词,以提高 ...

  3. Springmvc @CookieValue实用

    页面直接请求,  Controller代码 @RequestMapping("/testCookieValue") public String testCookieValue(@C ...

  4. vim 模式基础操作

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 前言 虽然Emacs已经可以完成大部分的编辑操作,但有时候为了方便也会用到vim.所以记录了 ...

  5. oracle数据库连接串格式

    oracle常用链接串格式:jdbc:oracle:thin:@//<host>:<port>/<service_name> jdbc:oracle:thin:@& ...

  6. URL传值问题,不同浏览器对URL的长度要求

    通过URL传值的问题,所以对url字符串进行encodeURIComponent对url字符串内容进行编码,问题解决,但是有时候会出现 The request filtering module is ...

  7. 各种Python小玩意收集

    快速排序 quicksort = lambda lst: [] if not lst else quicksort([i for i in lst[1:] if i <= lst[0]]) + ...

  8. CMD常用指令

    列出所有端口使用情况 netstat -ano 只查看端口5060使用情况 netstat -ano|findstr "5060" 查看进程8612的信息 tasklist|fin ...

  9. Windows下载地址

    文件名 cn_windows_7_professional_with_sp1_x64_dvd_u_677031.iso SHA1 9B57E67888434C24DD683968A3CE2C72755 ...

  10. Java 不使用科学计数法表示数据设置

    java.text.NumberFormat nf = java.text.NumberFormat.getInstance(); nf.setGroupingUsed(false); nf.form ...