Simple data structures / objects in plain C Snapshot
util.h
Go to the documentation of this file.
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