17 #import "objfw-defs.h"
19 #ifndef __STDC_LIMIT_MACROS
20 # define __STDC_LIMIT_MACROS
22 #ifndef __STDC_CONSTANT_MACROS
23 # define __STDC_CONSTANT_MACROS
32 #ifdef OF_OBJFW_RUNTIME
35 #ifdef OF_APPLE_RUNTIME
36 # import <objc/objc.h>
37 # import <objc/runtime.h>
38 # import <objc/message.h>
42 # define restrict __restrict__
43 #elif __STDC_VERSION__ < 199901L
47 #if __STDC_VERSION__ >= 201112L && !defined(static_assert)
49 # define static_assert _Static_assert
52 #if defined(OF_HAVE__THREAD_LOCAL)
53 # define OF_HAVE_COMPILER_TLS
54 # ifdef OF_HAVE_THREADS_H
57 # define thread_local _Thread_local
59 #elif defined(OF_HAVE___THREAD)
60 # define OF_HAVE_COMPILER_TLS
61 # define thread_local __thread
65 # define OF_INLINE inline __attribute__((__always_inline__))
66 # define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1))
67 # define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0))
68 # define OF_CONST_FUNC __attribute__((__const__))
69 # define OF_NO_RETURN_FUNC __attribute__((__noreturn__))
71 # define OF_INLINE inline
72 # define OF_LIKELY(cond) cond
73 # define OF_UNLIKELY(cond) cond
74 # define OF_CONST_FUNC
75 # define OF_NO_RETURN_FUNC
81 # define OF_BIG_ENDIAN
82 # define OF_FLOAT_BIG_ENDIAN
83 # elif !__LITTLE_ENDIAN__
84 # error OF_UNIVERSAL defined, but neither __BIG_ENDIAN__ nor __LITTLE_ENDIAN__!
89 # define OF_BYTE_ORDER_NATIVE OF_BYTE_ORDER_BIG_ENDIAN
91 # define OF_BYTE_ORDER_NATIVE OF_BYTE_ORDER_LITTLE_ENDIAN
94 #if __STDC_VERSION__ >= 201112L && defined(OF_HAVE_MAX_ALIGN_T)
95 # define OF_BIGGEST_ALIGNMENT _Alignof(max_align_t)
97 # ifdef __BIGGEST_ALIGNMENT__
98 # define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__
101 # define OF_BIGGEST_ALIGNMENT 16
106 # define __GCC_VERSION__ (__GNUC__ * 100 + __GNUC_MINOR__)
108 # define __GCC_VERSION__ 0
111 #if defined(__clang__) || __GCC_VERSION__ >= 406 || defined(OBJC_NEW_PROPERTIES)
112 # define OF_HAVE_PROPERTIES
113 # define OF_HAVE_OPTIONAL_PROTOCOLS
114 # if defined(__clang__) || __GCC_VERSION__ >= 406 || defined(OF_APPLE_RUNTIME)
115 # define OF_HAVE_FAST_ENUMERATION
117 # define OF_HAVE_CLASS_EXTENSIONS
118 # define OF_PRIVATE_CATEGORY
120 # define OF_PRIVATE_CATEGORY Private
123 #ifndef __has_feature
124 # define __has_feature(x) 0
127 #ifndef __has_attribute
128 # define __has_attribute(x) 0
131 #if __has_feature(objc_bool)
133 # define YES __objc_yes
135 # define NO __objc_no
138 # define true ((bool)1)
140 # define false ((bool)0)
144 #if !__has_feature(objc_instancetype)
145 # define instancetype id
148 #if __has_feature(blocks)
149 # define OF_HAVE_BLOCKS
152 #if __has_feature(objc_arc)
153 # define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
154 # define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__))
155 # define OF_RETURNS_INNER_POINTER \
156 __attribute__((__objc_returns_inner_pointer__))
157 # define OF_CONSUMED __attribute__((__ns_consumed__))
158 # define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__))
160 # define OF_RETURNS_RETAINED
161 # define OF_RETURNS_NOT_RETAINED
162 # define OF_RETURNS_INNER_POINTER
164 # define OF_WEAK_UNAVAILABLE
165 # define __unsafe_unretained
167 # define __autoreleasing
170 #if __has_feature(objc_generics)
171 # define OF_HAVE_GENERICS
172 # define OF_GENERIC(...) <__VA_ARGS__>
174 # define OF_GENERIC(...)
177 #if __has_feature(nullability)
178 # define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
179 # define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
180 # define OF_NONNULL __nonnull
181 # define OF_NULLABLE __nullable
182 # define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable)
184 # define OF_ASSUME_NONNULL_BEGIN
185 # define OF_ASSUME_NONNULL_END
188 # define OF_NULLABLE_PROPERTY
193 #if __has_feature(objc_kindof)
194 # define OF_KINDOF(cls) __kindof cls
196 # define OF_KINDOF(cls) id
199 #if defined(__clang__) || __GCC_VERSION__ >= 405
200 # define OF_UNREACHABLE __builtin_unreachable();
202 # define OF_UNREACHABLE abort();
205 #if defined(__clang__) || __GCC_VERSION__ >= 406
206 # define OF_SENTINEL __attribute__((__sentinel__))
207 # define OF_NO_RETURN __attribute__((__noreturn__))
210 # define OF_NO_RETURN
213 #if __has_attribute(__objc_requires_super__)
214 # define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__))
216 # define OF_REQUIRES_SUPER
219 #if __has_attribute(__objc_root_class__)
220 # define OF_ROOT_CLASS __attribute__((__objc_root_class__))
222 # define OF_ROOT_CLASS
225 #if __has_attribute(__objc_subclassing_restricted__)
226 # define OF_SUBCLASSING_RESTRICTED \
227 __attribute__((__objc_subclassing_restricted__))
229 # define OF_SUBCLASSING_RESTRICTED
233 # if defined(__x86_64__) || defined(__amd64__)
234 # define OF_X86_64_ASM
235 # elif defined(__i386__)
237 # elif defined(__ppc__) || defined(__PPC__)
239 # elif defined(__arm__) || defined(__ARM__)
241 # ifdef __ARM_ARCH_7__
242 # define OF_ARMV7_ASM
244 # ifdef __ARM_ARCH_7A__
245 # define OF_ARMV7_ASM
247 # ifdef __ARM_ARCH_7R__
248 # define OF_ARMV7_ASM
250 # ifdef __ARM_ARCH_7M__
251 # define OF_ARMV7_ASM
253 # ifdef __ARM_ARCH_7EM__
254 # define OF_ARMV7_ASM
256 # ifdef __ARM_ARCH_6__
257 # define OF_ARMV6_ASM
259 # ifdef __ARM_ARCH_6J__
260 # define OF_ARMV6_ASM
262 # ifdef __ARM_ARCH_6K__
263 # define OF_ARMV6_ASM
265 # ifdef __ARM_ARCH_6Z__
266 # define OF_ARMV6_ASM
268 # ifdef __ARM_ARCH_6ZK__
269 # define OF_ARMV6_ASM
271 # ifdef __ARM_ARCH_6T2__
272 # define OF_ARMV6_ASM
275 # define OF_ARMV6_ASM
277 # elif defined(__arm64__) || defined(__aarch64__)
278 # define OF_ARM64_ASM
282 #ifdef OF_APPLE_RUNTIME
283 # if defined(__x86_64__) || defined(__i386__) || defined(__ARM64_ARCH_8__) || \
284 defined(__arm__) || defined(__ppc__)
285 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
286 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
289 # if defined(__ELF__)
290 # if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) || \
291 defined(__arm__) || defined(__ARM__) || defined(__ppc__) || \
293 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
294 # if __OBJFW_RUNTIME_ABI__ >= 800
295 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
298 # if (defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32) || \
299 (defined(__mips_eabi) && _MIPS_SZPTR == 32)
300 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
301 # if __OBJFW_RUNTIME_ABI__ >= 800
302 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
305 # elif defined(_WIN32)
306 # if defined(__x86_64__) || defined(__i386__)
307 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
308 # if __OBJFW_RUNTIME_ABI__ >= 800
309 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
315 #define OF_RETAIN_COUNT_MAX UINT_MAX
316 #define OF_NOT_FOUND SIZE_MAX
318 #if !defined(_WIN32) && !defined(__DJGPP__)
319 # define OF_PATH_DELIMITER '/'
320 # define OF_PATH_DELIMITER_STRING @"/"
321 # define OF_IS_PATH_DELIMITER(c) (c == '/')
323 # define OF_PATH_DELIMITER '\\'
324 # define OF_PATH_DELIMITER_STRING @"\\"
325 # define OF_IS_PATH_DELIMITER(c) (c == '\\' || c == '/')
327 #define OF_PATH_CURRENT_DIRECTORY @"."
328 #define OF_PATH_PARENT_DIRECTORY @".."
330 #define OF_ENSURE(cond) \
333 fprintf(stderr, "Failed to ensure condition " \
334 "in " __FILE__ ":%d:\n" #cond "\n", \
340 #define OF_UNRECOGNIZED_SELECTOR of_method_not_found(self, _cmd);
341 #define OF_INVALID_INIT_METHOD \
343 [self doesNotRecognizeSelector: _cmd]; \
354 extern id objc_getProperty(
id,
SEL, ptrdiff_t, BOOL);
355 extern void objc_setProperty(
id,
SEL, ptrdiff_t,
id, BOOL,
signed char);
360 #define OF_IVAR_OFFSET(ivar) ((intptr_t)&ivar - (intptr_t)self)
361 #define OF_GETTER(ivar, atomic) \
362 return objc_getProperty(self, _cmd, OF_IVAR_OFFSET(ivar), atomic);
363 #define OF_SETTER(ivar, value, atomic, copy) \
364 objc_setProperty(self, _cmd, OF_IVAR_OFFSET(ivar), value, atomic, copy);
366 static OF_INLINE uint16_t OF_CONST_FUNC
367 OF_BSWAP16_CONST(uint16_t i)
369 return (i & UINT16_C(0xFF00)) >> 8 |
370 (i & UINT16_C(0x00FF)) << 8;
373 static OF_INLINE uint32_t OF_CONST_FUNC
374 OF_BSWAP32_CONST(uint32_t i)
376 return (i & UINT32_C(0xFF000000)) >> 24 |
377 (i & UINT32_C(0x00FF0000)) >> 8 |
378 (i & UINT32_C(0x0000FF00)) << 8 |
379 (i & UINT32_C(0x000000FF)) << 24;
382 static OF_INLINE uint64_t OF_CONST_FUNC
383 OF_BSWAP64_CONST(uint64_t i)
385 return (i & UINT64_C(0xFF00000000000000)) >> 56 |
386 (i & UINT64_C(0x00FF000000000000)) >> 40 |
387 (i & UINT64_C(0x0000FF0000000000)) >> 24 |
388 (i & UINT64_C(0x000000FF00000000)) >> 8 |
389 (i & UINT64_C(0x00000000FF000000)) << 8 |
390 (i & UINT64_C(0x0000000000FF0000)) << 24 |
391 (i & UINT64_C(0x000000000000FF00)) << 40 |
392 (i & UINT64_C(0x00000000000000FF)) << 56;
395 static OF_INLINE uint16_t OF_CONST_FUNC
396 OF_BSWAP16_NONCONST(uint16_t i)
398 #if defined(OF_HAVE_BUILTIN_BSWAP16)
399 return __builtin_bswap16(i);
400 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
406 #elif defined(OF_PPC_ASM)
412 #elif defined(OF_ARMV6_ASM)
419 i = (i & UINT16_C(0xFF00)) >> 8 |
420 (i & UINT16_C(0x00FF)) << 8;
425 static OF_INLINE uint32_t OF_CONST_FUNC
426 OF_BSWAP32_NONCONST(uint32_t i)
428 #if defined(OF_HAVE_BUILTIN_BSWAP32)
429 return __builtin_bswap32(i);
430 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
436 #elif defined(OF_PPC_ASM)
442 #elif defined(OF_ARMV6_ASM)
449 i = (i & UINT32_C(0xFF000000)) >> 24 |
450 (i & UINT32_C(0x00FF0000)) >> 8 |
451 (i & UINT32_C(0x0000FF00)) << 8 |
452 (i & UINT32_C(0x000000FF)) << 24;
457 static OF_INLINE uint64_t OF_CONST_FUNC
458 OF_BSWAP64_NONCONST(uint64_t i)
460 #if defined(OF_HAVE_BUILTIN_BSWAP64)
461 return __builtin_bswap64(i);
462 #elif defined(OF_X86_64_ASM)
468 #elif defined(OF_X86_ASM)
477 i = (uint64_t)OF_BSWAP32_NONCONST((uint32_t)(i & 0xFFFFFFFF)) << 32 |
478 OF_BSWAP32_NONCONST((uint32_t)(i >> 32));
484 # define OF_BSWAP16(i) \
485 (__builtin_constant_p(i) ? OF_BSWAP16_CONST(i) : OF_BSWAP16_NONCONST(i))
486 # define OF_BSWAP32(i) \
487 (__builtin_constant_p(i) ? OF_BSWAP32_CONST(i) : OF_BSWAP32_NONCONST(i))
488 # define OF_BSWAP64(i) \
489 (__builtin_constant_p(i) ? OF_BSWAP64_CONST(i) : OF_BSWAP64_NONCONST(i))
491 # define OF_BSWAP16(i) OF_BSWAP16_CONST(i)
492 # define OF_BSWAP32(i) OF_BSWAP32_CONST(i)
493 # define OF_BSWAP64(i) OF_BSWAP64_CONST(i)
496 static OF_INLINE
float OF_CONST_FUNC
497 OF_BSWAP_FLOAT(
float f)
505 u.i = OF_BSWAP32(u.i);
510 static OF_INLINE
double OF_CONST_FUNC
511 OF_BSWAP_DOUBLE(
double d)
519 u.i = OF_BSWAP64(u.i);
525 # define OF_BSWAP16_IF_BE(i) OF_BSWAP16(i)
526 # define OF_BSWAP32_IF_BE(i) OF_BSWAP32(i)
527 # define OF_BSWAP64_IF_BE(i) OF_BSWAP64(i)
528 # define OF_BSWAP16_IF_LE(i) (i)
529 # define OF_BSWAP32_IF_LE(i) (i)
530 # define OF_BSWAP64_IF_LE(i) (i)
532 # define OF_BSWAP16_IF_BE(i) (i)
533 # define OF_BSWAP32_IF_BE(i) (i)
534 # define OF_BSWAP64_IF_BE(i) (i)
535 # define OF_BSWAP16_IF_LE(i) OF_BSWAP16(i)
536 # define OF_BSWAP32_IF_LE(i) OF_BSWAP32(i)
537 # define OF_BSWAP64_IF_LE(i) OF_BSWAP64(i)
540 #ifdef OF_FLOAT_BIG_ENDIAN
541 # define OF_BSWAP_FLOAT_IF_BE(i) OF_BSWAP_FLOAT(i)
542 # define OF_BSWAP_DOUBLE_IF_BE(i) OF_BSWAP_DOUBLE(i)
543 # define OF_BSWAP_FLOAT_IF_LE(i) (i)
544 # define OF_BSWAP_DOUBLE_IF_LE(i) (i)
546 # define OF_BSWAP_FLOAT_IF_BE(i) (i)
547 # define OF_BSWAP_DOUBLE_IF_BE(i) (i)
548 # define OF_BSWAP_FLOAT_IF_LE(i) OF_BSWAP_FLOAT(i)
549 # define OF_BSWAP_DOUBLE_IF_LE(i) OF_BSWAP_DOUBLE(i)
552 #define OF_ROL(value, bits) \
553 (((bits) % (sizeof(value) * 8)) > 0 \
554 ? ((value) << ((bits) % (sizeof(value) * 8))) | \
555 ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
557 #define OF_ROR(value, bits) \
558 (((bits) % (sizeof(value) * 8)) > 0 \
559 ? ((value) >> ((bits) % (sizeof(value) * 8))) | \
560 ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
563 #define OF_ROUND_UP_POW2(pow2, value) (((value) + (pow2) - 1) & ~((pow2) - 1))
565 #define OF_HASH_INIT(hash) hash = of_hash_seed;
566 #define OF_HASH_ADD(hash, byte) \
568 hash += (uint8_t)(byte); \
569 hash += (hash << 10); \
570 hash ^= (hash >> 6); \
572 #define OF_HASH_FINALIZE(hash) \
574 hash += (hash << 3); \
575 hash ^= (hash >> 11); \
576 hash += (hash << 15); \
578 #define OF_HASH_ADD_HASH(hash, other) \
580 uint32_t otherCopy = other; \
581 OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF); \
582 OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF); \
583 OF_HASH_ADD(hash, (otherCopy >> 8) & 0xFF); \
584 OF_HASH_ADD(hash, otherCopy & 0xFF); \
587 static OF_INLINE
char*
588 of_strdup(
const char *
string)
591 size_t length = strlen(
string);
593 if ((copy = (
char*)malloc(length + 1)) == NULL)
596 memcpy(copy,
string, length + 1);