ObjFW
src/macros.h
00001 /*
00002  * Copyright (c) 2008, 2009, 2010, 2011, 2012
00003  *   Jonathan Schleifer <js@webkeks.org>
00004  *
00005  * All rights reserved.
00006  *
00007  * This file is part of ObjFW. It may be distributed under the terms of the
00008  * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
00009  * the packaging of this file.
00010  *
00011  * Alternatively, it may be distributed under the terms of the GNU General
00012  * Public License, either version 2 or 3, which can be found in the file
00013  * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
00014  * file.
00015  */
00016 
00017 #import "OFObject.h"
00018 
00019 #include <stddef.h>
00020 #include <stdint.h>
00021 
00022 #if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME)
00023 # import <objc/runtime.h>
00024 #elif defined(OF_OLD_GNU_RUNTIME)
00025 # import <objc/objc-api.h>
00026 #endif
00027 
00028 #ifdef _PSP
00029 # define INTMAX_MAX LONG_LONG_MAX
00030 #endif
00031 
00032 #ifdef __GNUC__
00033 # define OF_INLINE inline __attribute__((always_inline))
00034 # define OF_LIKELY(cond) __builtin_expect(!!(cond), 1)
00035 # define OF_UNLIKELY(cond) __builtin_expect(!!(cond), 0)
00036 # define OF_CONST_FUNC __attribute__((const))
00037 #else
00038 # define OF_INLINE inline
00039 # define OF_LIKELY(cond) cond
00040 # define OF_UNLIKELY(cond) cond
00041 # define OF_CONST_FUNC
00042 #endif
00043 
00044 #if defined(__GNUC__)
00045 # define restrict __restrict__
00046 #elif __STDC_VERSION__ < 199901L
00047 # define restrict
00048 #endif
00049 
00050 /* Required to build universal binaries on OS X */
00051 #if __BIG_ENDIAN__ || __LITTLE_ENDIAN__
00052 # if __BIG_ENDIAN__ && __LITTLE_ENDIAN__
00053 #  error __BIG_ENDIAN__ and __LITTLE_ENDIAN__ defined!
00054 # endif
00055 # undef OF_BIG_ENDIAN
00056 # if __BIG_ENDIAN__
00057 #  define OF_BIG_ENDIAN
00058 # endif
00059 #endif
00060 
00061 #ifdef OF_BIG_ENDIAN
00062 # define OF_ENDIANESS_NATIVE OF_ENDIANESS_BIG_ENDIAN
00063 #else
00064 # define OF_ENDIANESS_NATIVE OF_ENDIANESS_LITTLE_ENDIAN
00065 #endif
00066 
00067 #ifdef __GNUC__
00068 # if defined(__amd64__) || defined(__x86_64__)
00069 #  define OF_AMD64_ASM
00070 # elif defined(__i386__)
00071 #  define OF_X86_ASM
00072 # elif defined(__ppc__) || defined(__PPC__)
00073 #  define OF_PPC_ASM
00074 # elif defined(__arm__) || defined(__ARM__)
00075 #  define OF_ARM_ASM
00076 # endif
00077 #endif
00078 
00079 #if defined(OF_OLD_GNU_RUNTIME) || defined(OF_OBJFW_RUNTIME)
00080 # define objc_lookUpClass objc_lookup_class
00081 #endif
00082 
00083 #ifdef OF_OLD_GNU_RUNTIME
00084 # define class_getInstanceSize class_get_instance_size
00085 # define class_getName class_get_class_name
00086 # define class_getSuperclass class_get_super_class
00087 # define sel_getName sel_get_name
00088 # define sel_registerName sel_get_uid
00089 #endif
00090 
00091 #ifndef _WIN32
00092 # define OF_PATH_DELIMITER '/'
00093 #else
00094 # define OF_PATH_DELIMITER '\\'
00095 #endif
00096 
00097 #define OF_IVAR_OFFSET(ivar) ((intptr_t)&ivar - (intptr_t)self)
00098 #define OF_GETTER(ivar, atomic) \
00099         return objc_getProperty(self, _cmd, OF_IVAR_OFFSET(ivar), atomic);
00100 #define OF_SETTER(ivar, value, atomic, copy) \
00101         objc_setProperty(self, _cmd, OF_IVAR_OFFSET(ivar), value, atomic, copy);
00102 
00103 static OF_INLINE uint16_t OF_CONST_FUNC
00104 of_bswap16_const(uint16_t i)
00105 {
00106         return (i & UINT16_C(0xFF00)) >> 8 |
00107             (i & UINT16_C(0x00FF)) << 8;
00108 }
00109 
00110 static OF_INLINE uint32_t OF_CONST_FUNC
00111 of_bswap32_const(uint32_t i)
00112 {
00113         return (i & UINT32_C(0xFF000000)) >> 24 |
00114             (i & UINT32_C(0x00FF0000)) >>  8 |
00115             (i & UINT32_C(0x0000FF00)) <<  8 |
00116             (i & UINT32_C(0x000000FF)) << 24;
00117 }
00118 
00119 static OF_INLINE uint64_t OF_CONST_FUNC
00120 of_bswap64_const(uint64_t i)
00121 {
00122         return (i & UINT64_C(0xFF00000000000000)) >> 56 |
00123             (i & UINT64_C(0x00FF000000000000)) >> 40 |
00124             (i & UINT64_C(0x0000FF0000000000)) >> 24 |
00125             (i & UINT64_C(0x000000FF00000000)) >>  8 |
00126             (i & UINT64_C(0x00000000FF000000)) <<  8 |
00127             (i & UINT64_C(0x0000000000FF0000)) << 24 |
00128             (i & UINT64_C(0x000000000000FF00)) << 40 |
00129             (i & UINT64_C(0x00000000000000FF)) << 56;
00130 }
00131 
00132 static OF_INLINE uint16_t OF_CONST_FUNC
00133 of_bswap16_nonconst(uint16_t i)
00134 {
00135 #if defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
00136         __asm__ (
00137             "xchgb      %h0, %b0"
00138             : "=Q"(i)
00139             : "0"(i)
00140         );
00141 #elif defined(OF_PPC_ASM)
00142         __asm__ (
00143             "lhbrx      %0, 0, %1"
00144             : "=r"(i)
00145             : "r"(&i), "m"(i)
00146         );
00147 #elif defined(OF_ARM_ASM)
00148         __asm__ (
00149             "rev16      %0, %0"
00150             : "=r"(i)
00151             : "0"(i)
00152         );
00153 #else
00154         i = (i & UINT16_C(0xFF00)) >> 8 |
00155             (i & UINT16_C(0x00FF)) << 8;
00156 #endif
00157         return i;
00158 }
00159 
00160 static OF_INLINE uint32_t OF_CONST_FUNC
00161 of_bswap32_nonconst(uint32_t i)
00162 {
00163 #if defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
00164         __asm__ (
00165             "bswap      %0"
00166             : "=q"(i)
00167             : "0"(i)
00168         );
00169 #elif defined(OF_PPC_ASM)
00170         __asm__ (
00171             "lwbrx      %0, 0, %1"
00172             : "=r"(i)
00173             : "r"(&i), "m"(i)
00174         );
00175 #elif defined(OF_ARM_ASM)
00176         __asm__ (
00177             "rev        %0, %0"
00178             : "=r"(i)
00179             : "0"(i)
00180         );
00181 #else
00182         i = (i & UINT32_C(0xFF000000)) >> 24 |
00183             (i & UINT32_C(0x00FF0000)) >>  8 |
00184             (i & UINT32_C(0x0000FF00)) <<  8 |
00185             (i & UINT32_C(0x000000FF)) << 24;
00186 #endif
00187         return i;
00188 }
00189 
00190 static OF_INLINE uint64_t OF_CONST_FUNC
00191 of_bswap64_nonconst(uint64_t i)
00192 {
00193 #if defined(OF_AMD64_ASM)
00194         __asm__ (
00195             "bswap      %0"
00196             : "=r"(i)
00197             : "0"(i)
00198         );
00199 #elif defined(OF_X86_ASM)
00200         __asm__ (
00201             "bswap      %%eax\n\t"
00202             "bswap      %%edx\n\t"
00203             "xchgl      %%eax, %%edx"
00204             : "=A"(i)
00205             : "0"(i)
00206         );
00207 #else
00208         i = (uint64_t)of_bswap32_nonconst((uint32_t)(i & 0xFFFFFFFF)) << 32 |
00209             of_bswap32_nonconst((uint32_t)(i >> 32));
00210 #endif
00211         return i;
00212 }
00213 
00214 #ifdef __GNUC__
00215 # define of_bswap16(i) \
00216         (__builtin_constant_p(i) ? of_bswap16_const(i) : of_bswap16_nonconst(i))
00217 # define of_bswap32(i) \
00218         (__builtin_constant_p(i) ? of_bswap32_const(i) : of_bswap32_nonconst(i))
00219 # define of_bswap64(i) \
00220         (__builtin_constant_p(i) ? of_bswap64_const(i) : of_bswap64_nonconst(i))
00221 #else
00222 # define of_bswap16(i) of_bswap16_const(i)
00223 # define of_bswap32(i) of_bswap32_const(i)
00224 # define of_bswap64(i) of_bswap64_const(i)
00225 #endif
00226 
00227 static OF_INLINE float OF_CONST_FUNC
00228 of_bswap_float(float f)
00229 {
00230         union {
00231                 float f;
00232                 uint32_t i;
00233         } u;
00234 
00235         u.f = f;
00236         u.i = of_bswap32(u.i);
00237 
00238         return u.f;
00239 }
00240 
00241 static OF_INLINE double OF_CONST_FUNC
00242 of_bswap_double(double d)
00243 {
00244         union {
00245                 double d;
00246                 uint64_t i;
00247         } u;
00248 
00249         u.d = d;
00250         u.i = of_bswap64(u.i);
00251 
00252         return u.d;
00253 }
00254 
00255 static OF_INLINE void
00256 of_bswap32_vec(uint32_t *buffer, size_t length)
00257 {
00258         while (length--) {
00259                 *buffer = of_bswap32(*buffer);
00260                 buffer++;
00261         }
00262 }
00263 
00264 #ifdef OF_BIG_ENDIAN
00265 # define of_bswap16_if_be(i) of_bswap16(i)
00266 # define of_bswap32_if_be(i) of_bswap32(i)
00267 # define of_bswap64_if_be(i) of_bswap64(i)
00268 # define of_bswap16_if_le(i) (i)
00269 # define of_bswap32_if_le(i) (i)
00270 # define of_bswap64_if_le(i) (i)
00271 # define of_bswap32_vec_if_be(buffer, length) of_bswap32_vec(buffer, length)
00272 #else
00273 # define of_bswap16_if_be(i) (i)
00274 # define of_bswap32_if_be(i) (i)
00275 # define of_bswap64_if_be(i) (i)
00276 # define of_bswap16_if_le(i) of_bswap16(i)
00277 # define of_bswap32_if_le(i) of_bswap32(i)
00278 # define of_bswap64_if_le(i) of_bswap64(i)
00279 # define of_bswap32_vec_if_be(buffer, length)
00280 #endif
00281 
00282 #ifdef OF_FLOAT_BIG_ENDIAN
00283 # define of_bswap_float_if_be(i) of_bswap_float(i)
00284 # define of_bswap_double_if_be(i) of_bswap_double(i)
00285 # define of_bswap_float_if_le(i) (i)
00286 # define of_bswap_double_if_le(i) (i)
00287 #else
00288 # define of_bswap_float_if_be(i) (i)
00289 # define of_bswap_double_if_be(i) (i)
00290 # define of_bswap_float_if_le(i) of_bswap_float(i)
00291 # define of_bswap_double_if_le(i) of_bswap_double(i)
00292 #endif
00293 
00294 /*
00295  * We define it here and not in objfw-defs.h, as it would be theoretically
00296  * possible to build a universal binary for Mac OS X and iOS.
00297  */
00298 #if defined(__MACH__) && defined(__arm__)
00299 # define OF_IOS
00300 #endif
00301 
00302 #define OF_ROL(value, bits)                                             \
00303         (((value) << ((bits) % (sizeof(value) * 8))) |                  \
00304         (value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8))))
00305 
00306 #define OF_HASH_INIT(hash) hash = 0
00307 #define OF_HASH_ADD(hash, byte)         \
00308         {                               \
00309                 hash += (uint8_t)byte;  \
00310                 hash += (hash << 10);   \
00311                 hash ^= (hash >> 6);    \
00312         }
00313 #define OF_HASH_FINALIZE(hash)          \
00314         {                               \
00315                 hash += (hash << 3);    \
00316                 hash ^= (hash >> 11);   \
00317                 hash += (hash << 15);   \
00318         }
00319 #define OF_HASH_ADD_HASH(hash, other)                           \
00320         {                                                       \
00321                 uint32_t otherCopy = other;                     \
00322                 OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF);    \
00323                 OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF);    \
00324                 OF_HASH_ADD(hash, (otherCopy >>  8) & 0xFF);    \
00325                 OF_HASH_ADD(hash, otherCopy & 0xFF);            \
00326         }
00327 
00328 static OF_INLINE of_range_t
00329 of_range(size_t start, size_t length)
00330 {
00331         of_range_t range = { start, length };
00332 
00333         return range;
00334 }
00335 
00336 static OF_INLINE of_point_t
00337 of_point(int x, int y)
00338 {
00339         of_point_t point = { x, y };
00340 
00341         return point;
00342 }
00343 
00344 static OF_INLINE of_dimension_t
00345 of_dimension(int width, int height)
00346 {
00347         of_dimension_t dimension = { width, height };
00348 
00349         return dimension;
00350 }
00351 
00352 static OF_INLINE of_rectangle_t
00353 of_rectangle(int x, int y, int width, int height)
00354 {
00355         of_rectangle_t rectangle = {
00356                 of_point(x, y),
00357                 of_dimension(width, height)
00358         };
00359 
00360         return rectangle;
00361 }
 All Classes Functions Variables Properties