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. ONLY三行脚本 SQL数据恢复到指定时间点

    经常看到有人误删数据,或者误操作,特别是Update和Delete的时候没有加WHERE ... 然后就喊爹喊娘了,怕是亲爹妈也无奈摇肩. 话说,如果没有犯过错误,那你还算是程序猿(媛)麽?!没了偶尔 ...

  2. XAF-Domain Components 技术 使用接口来定义ORM业务对象

    一.简介 Domain Component组件技术,以下简称DC,是扩展自XPO的, 官方不建议新手使用DC. 如果你用过EF,XPO及类似的ORM,这是很容易理解的,DC是基于XPO的,只是原业定义 ...

  3. SharePoint Framework (SPFx)安装配置以及开发-基础篇

    前言 SharePoint Framework(SPFx),是页面 和Webpart的模型,完全支持本地开发(即完全可以脱离SharPoint环境在本地进行开发),SPFx包含了一系列的client- ...

  4. Qt-剪切板

    ClipBoard 存在的意义 进程间数据共享. 方式 Drag And Drop: clipBoard的拖曳方式 app's ClipBoard 缺点 没有权限管理 在Model View中实现Dr ...

  5. smbaclient

    在linux中通过smbaclient获取windows的共享文件 列出windows的共享目录 $ smbclient -L .xxx -U administrator%password 进入指定共 ...

  6. (Nginx学习一)安装和启动及对应文件夹介绍

    nginx 安装和启动及对应文件夹介绍 1 安装 官网下载nginx文件  http://nginx.org/en/download.html 解压即可 2 文件夹介绍 在解压后nginx压缩包后发现 ...

  7. 关于Kafka使用IBM Java报错解决方案

    安装环境 Ubuntu 14.04 Java IBM Java 1.7.0_79 Kakfa 2.10-0.8.2.1 使用bin/kafka-server-start.sh config/serve ...

  8. C++的第一天

    第一次写博客,第一天的C++,从第一讲视屏中了解到了,类,对象,oop编程思想 1.类包括对象和对象的行为,对象具有静态连接(对象的名字)和动态链接(对象的行为),视屏中提到了多态性,应该是不同的类具 ...

  9. VMware安装ubuntu,通过/mnt/hgfs 挂载共享Windows系统文件夹

    网上各种相关的配置说明,但是都没一个完整的,在这里楼主结合实战亲测,这一整套包含各种情况 1.安装VMware tools 2.解压到任意一个文件夹 tar -xzvf VMwareTools**** ...

  10. linux显示行数命令

    linux 如何显示一个文件的某几行(中间几行) [一]从第3000行开始,显示1000行.即显示3000~3999行 cat filename | tail -n +3000 | head -n 1 ...