Simple data structures / objects in plain C Snapshot
|
00001 /* Copyright (c) Michael Moser (2011) . 3-clause BSD License applies */ 00002 00003 #ifndef _UTIL_UTIL_H_ 00004 #define _UTIL_UTIL_H_ 00005 00006 #ifdef __cplusplus 00007 extern "C" { 00008 #endif 00009 00010 #include <cutils/base.h> 00011 #include <ctype.h> 00012 00013 M_INLINE void UTIL_swapbytes(unsigned char *src, unsigned char *dst, size_t size) 00014 { 00015 unsigned char tmp; 00016 00017 while(size>0) { 00018 tmp = *src; 00019 *src = *dst; 00020 *dst = tmp; 00021 00022 ++src; 00023 ++dst; 00024 --size; 00025 } 00026 } 00027 00028 /* 00029 * @brief returns 1 if num is a power of two. 00030 */ 00031 M_INLINE int UTIL_is_power_of_two( uint32_t num ) 00032 { 00033 return (num & (num - 1)) == 0; 00034 /* num == 2 ^ n -1 | all ones 00035 * num == 2 ^ n | one on next position after the last one. 00036 * & will return 0 (no overlap) if num is 2 ^ n 00037 */ 00038 } 00039 00040 /* 00041 * @brief align integer (alignment must be power of 2) 00042 */ 00043 M_INLINE uint32_t UTIL_align( uint32_t num, uint32_t align) 00044 { 00045 /* assert( UTIL_is_power_of_two( align ) ); */ 00046 return (num + align - 1 ) & (~(align - 1)); 00047 /* 00048 * & (x) (~(align -1 )) set align to the closers alignment (x % align == 0) (round down to closest alignment) 00049 * num + align - 1 make sure that the argument crosses alignment border, 00050 */ 00051 } 00052 00053 /* 00054 * @brief align pointer integer (alignment must be power of 2) 00055 */ 00056 M_INLINE void * UTIL_ptr_align( void *ptr, size_t align) 00057 { 00058 /* assert( UTIL_is_power_of_two( align ) ); */ 00059 return (void *) ( (((ptrdiff_t) ptr) & ~(align - 1)) + align ); 00060 } 00061 /* 00062 * @brief return pointer to start of "page" ("page" size is power of two). 00063 */ 00064 M_INLINE void * UTIL_ptr_page_start( void *ptr, size_t page_size) 00065 { 00066 /* assert( UTIL_is_power_of_two( align ) ); */ 00067 return (void *) ( ((ptrdiff_t) ptr) & ~ ((ptrdiff_t) page_size - 1) ); 00068 /* 00069 * round argument pointer down to the closes pagesize (assuming pagesize is power of two) 00070 */ 00071 } 00072 00073 /* 00074 * @brief checks if pointer is aligned to given power of two 00075 */ 00076 M_INLINE int UTIL_ptr_is_aligned( void *ptr, size_t page_size) 00077 { 00078 /* assert( UTIL_is_power_of_two( align ) ); */ 00079 return ( ((ptrdiff_t) ptr) & ((ptrdiff_t) page_size - 1) ) == 0; 00080 } 00081 00082 /* 00083 * @brief check if argument pointer (ptr) is in memory range specified by [from ... to) 00084 */ 00085 M_INLINE int UTIL_ptr_in_range(void *ptr, void *from , void *to ) 00086 { 00087 return (uint8_t *) ptr >= (uint8_t *) from && (uint8_t *) ptr < (uint8_t *) to; 00088 } 00089 00090 00091 M_INLINE size_t UTIL_round_to_power_of_n( size_t num ) 00092 { 00093 size_t n = 1; 00094 00095 while( n < num ) { 00096 n <<= 1; 00097 } 00098 return n; 00099 } 00100 00101 M_INLINE size_t UTIL_log_base_2_of_n( size_t num ) 00102 { 00103 size_t ret = 0; 00104 00105 while( num ) { 00106 num >>= 1; 00107 ret ++; 00108 } 00109 return ret; 00110 } 00111 00112 00113 00114 M_INLINE char *UTIL_skip_spaces( const char *p) { 00115 while( *p != '\0' && isspace((int) *p)) { 00116 ++p; 00117 } 00118 return (char *) p; 00119 } 00120 00121 M_INLINE char *UTIL_skip_nspace( const char *p) { 00122 while( *p != '\0' && !isspace((int) *p)) { 00123 ++p; 00124 } 00125 return (char *) p; 00126 } 00127 00128 #ifdef __cplusplus 00129 } 00130 #endif 00131 00132 #endif 00133