ObjFW
macros.h
1 /*
2  * Copyright (c) 2008-2021 Jonathan Schleifer <js@nil.im>
3  *
4  * All rights reserved.
5  *
6  * This file is part of ObjFW. It may be distributed under the terms of the
7  * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
8  * the packaging of this file.
9  *
10  * Alternatively, it may be distributed under the terms of the GNU General
11  * Public License, either version 2 or 3, which can be found in the file
12  * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
13  * file.
14  */
15 
16 #ifndef OBJFW_MACROS_H
17 #define OBJFW_MACROS_H
18 
19 #include "objfw-defs.h"
20 
21 #ifndef __STDC_LIMIT_MACROS
22 # define __STDC_LIMIT_MACROS
23 #endif
24 #ifndef __STDC_CONSTANT_MACROS
25 # define __STDC_CONSTANT_MACROS
26 #endif
27 
28 #include <limits.h>
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include <sys/time.h>
37 
38 #include "platform.h"
39 
40 #ifdef OF_OBJFW_RUNTIME
41 # ifdef OF_COMPILING_OBJFW
42 # include "ObjFWRT.h"
43 # else
44 # include <ObjFWRT/ObjFWRT.h>
45 # endif
46 #endif
47 #ifdef OF_APPLE_RUNTIME
48 # include <objc/objc.h>
49 # include <objc/runtime.h>
50 # include <objc/message.h>
51 #endif
52 
53 #if defined(__GNUC__)
54 # define restrict __restrict__
55 #elif __STDC_VERSION__ < 199901L
56 # define restrict
57 #endif
58 
59 #if __STDC_VERSION__ >= 201112L && !defined(static_assert)
60 /* C11 compiler, but old libc */
61 # define static_assert _Static_assert
62 #endif
63 
64 #if defined(OF_HAVE__THREAD_LOCAL)
65 # define OF_HAVE_COMPILER_TLS
66 # ifdef OF_HAVE_THREADS_H
67 # include <threads.h>
68 # ifdef OF_AIX
69 /* AIX has a bug where thread_local is defined to "Thread_local;". */
70 # undef thread_local
71 # define thread_local _Thread_local
72 # endif
73 # else
74 # define thread_local _Thread_local
75 # endif
76 #elif defined(OF_HAVE___THREAD)
77 # define OF_HAVE_COMPILER_TLS
78 # define thread_local __thread
79 #endif
80 
81 /*
82  * Do not use compiler TLS when targeting the iOS simulator, as the iOS 9
83  * simulator does not support it (fails at runtime).
84  */
85 #if defined(OF_HAVE_COMPILER_TLS) && defined(OF_IOS) && defined(OF_X86)
86 # undef OF_HAVE_COMPILER_TLS
87 #endif
88 
89 #ifdef __GNUC__
90 # define OF_INLINE inline __attribute__((__always_inline__))
91 # define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1))
92 # define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0))
93 # define OF_CONST_FUNC __attribute__((__const__))
94 # define OF_NO_RETURN_FUNC __attribute__((__noreturn__))
95 # define OF_WEAK_REF(sym) __attribute__((__weakref__(sym)))
96 #else
97 # define OF_INLINE inline
98 # define OF_LIKELY(cond) (cond)
99 # define OF_UNLIKELY(cond) (cond)
100 # define OF_CONST_FUNC
101 # define OF_NO_RETURN_FUNC
102 # define OF_WEAK_REF(sym)
103 #endif
104 
105 #ifdef OF_BIG_ENDIAN
106 # define OF_BYTE_ORDER_NATIVE OF_BYTE_ORDER_BIG_ENDIAN
107 #else
108 # define OF_BYTE_ORDER_NATIVE OF_BYTE_ORDER_LITTLE_ENDIAN
109 #endif
110 
111 #if __STDC_VERSION__ >= 201112L
112 # define OF_ALIGNOF(type) _Alignof(type)
113 # define OF_ALIGNAS(type) _Alignas(type)
114 #else
115 # define OF_ALIGNOF(type) __alignof__(type)
116 # define OF_ALIGNAS(type) __attribute__((__aligned__(__alignof__(type))))
117 #endif
118 
119 #if __STDC_VERSION__ >= 201112L && defined(OF_HAVE_MAX_ALIGN_T)
120 # define OF_BIGGEST_ALIGNMENT _Alignof(max_align_t)
121 #else
122 # ifdef __BIGGEST_ALIGNMENT__
123 # define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__
124 # else
125 # /* Hopefully no arch needs more than 16 byte alignment */
126 # define OF_BIGGEST_ALIGNMENT 16
127 # endif
128 #endif
129 
130 #define OF_PREPROCESSOR_CONCAT2(a, b) a##b
131 #define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b)
132 
133 #if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__))
134 # define OF_HAVE_NONFRAGILE_IVARS
135 #endif
136 
137 #ifdef OF_HAVE_NONFRAGILE_IVARS
138 # define OF_RESERVE_IVARS(cls, num)
139 #else
140 # define OF_RESERVE_IVARS(cls, num) \
141  @private \
142  void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num];
143 #endif
144 
145 #ifdef __GNUC__
146 # define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
147 #else
148 # define OF_GCC_VERSION 0
149 #endif
150 
151 #define OF_STRINGIFY(s) OF_STRINGIFY2(s)
152 #define OF_STRINGIFY2(s) #s
153 
154 #ifndef __has_feature
155 # define __has_feature(x) 0
156 #endif
157 
158 #ifndef __has_attribute
159 # define __has_attribute(x) 0
160 #endif
161 
162 #if __has_feature(objc_bool)
163 # undef YES
164 # define YES __objc_yes
165 # undef NO
166 # define NO __objc_no
167 # ifndef __cplusplus
168 # undef true
169 # define true ((bool)1)
170 # undef false
171 # define false ((bool)0)
172 # endif
173 #endif
174 
175 #if !__has_feature(objc_instancetype)
176 # define instancetype id
177 #endif
178 
179 #if __has_feature(blocks)
180 # define OF_HAVE_BLOCKS
181 #endif
182 
183 #if __has_feature(objc_arc)
184 # define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
185 # define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__))
186 # define OF_RETURNS_INNER_POINTER \
187  __attribute__((__objc_returns_inner_pointer__))
188 # define OF_CONSUMED __attribute__((__ns_consumed__))
189 # define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__))
190 #else
191 # define OF_RETURNS_RETAINED
192 # define OF_RETURNS_NOT_RETAINED
193 # define OF_RETURNS_INNER_POINTER
194 # define OF_CONSUMED
195 # define OF_WEAK_UNAVAILABLE
196 /*
197  * undef them first, as new Clang versions have these as built-in defines even
198  * when ARC is disabled.
199  */
200 # undef __unsafe_unretained
201 # undef __bridge
202 # undef __autoreleasing
203 # define __unsafe_unretained
204 # define __bridge
205 # define __autoreleasing
206 #endif
207 
208 #if __has_feature(objc_generics)
209 # define OF_HAVE_GENERICS
210 # define OF_GENERIC(...) <__VA_ARGS__>
211 #else
212 # define OF_GENERIC(...)
213 #endif
214 
215 #if __has_feature(nullability)
216 # define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
217 # define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
218 # define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable)
219 # define OF_NULL_RESETTABLE_PROPERTY(...) (__VA_ARGS__, null_resettable)
220 #else
221 # define OF_ASSUME_NONNULL_BEGIN
222 # define OF_ASSUME_NONNULL_END
223 # define _Nonnull
224 # define _Nullable
225 # define _Null_unspecified
226 # define OF_NULLABLE_PROPERTY
227 # define OF_NULL_RESETTABLE_PROPERTY
228 # define nonnull
229 # define nullable
230 # define null_unspecified
231 #endif
232 
233 #if __has_feature(objc_kindof)
234 # define OF_KINDOF(class_) __kindof class_
235 #else
236 # define OF_KINDOF(class_) id
237 #endif
238 
239 #if __has_feature(objc_class_property)
240 # define OF_HAVE_CLASS_PROPERTIES
241 #endif
242 
243 #if defined(__clang__) || OF_GCC_VERSION >= 405
244 # define OF_UNREACHABLE __builtin_unreachable();
245 #else
246 # define OF_UNREACHABLE abort();
247 #endif
248 
249 #if defined(__clang__) || OF_GCC_VERSION >= 406
250 # define OF_SENTINEL __attribute__((__sentinel__))
251 # define OF_NO_RETURN __attribute__((__noreturn__))
252 #else
253 # define OF_SENTINEL
254 # define OF_NO_RETURN
255 #endif
256 
257 #ifdef __clang__
258 # define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
259 #else
260 # define OF_WARN_UNUSED_RESULT
261 #endif
262 
263 #if __has_attribute(__unavailable__)
264 # define OF_UNAVAILABLE __attribute__((__unavailable__))
265 # define OF_HAVE_UNAVAILABLE
266 #else
267 # define OF_UNAVAILABLE
268 #endif
269 
270 #if __has_attribute(__objc_requires_super__)
271 # define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__))
272 #else
273 # define OF_REQUIRES_SUPER
274 #endif
275 
276 #if __has_attribute(__objc_root_class__)
277 # define OF_ROOT_CLASS __attribute__((__objc_root_class__))
278 #else
279 # define OF_ROOT_CLASS
280 #endif
281 
282 #if __has_attribute(__objc_subclassing_restricted__)
283 # define OF_SUBCLASSING_RESTRICTED \
284  __attribute__((__objc_subclassing_restricted__))
285 #else
286 # define OF_SUBCLASSING_RESTRICTED
287 #endif
288 
289 #if __has_attribute(__objc_method_family__)
290 # define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f)))
291 #else
292 # define OF_METHOD_FAMILY(f)
293 #endif
294 
295 #if __has_attribute(__objc_designated_initializer__)
296 # define OF_DESIGNATED_INITIALIZER \
297  __attribute__((__objc_designated_initializer__))
298 #else
299 # define OF_DESIGNATED_INITIALIZER
300 #endif
301 
302 #if __has_attribute(__objc_boxable__)
303 # define OF_BOXABLE __attribute__((__objc_boxable__))
304 #else
305 # define OF_BOXABLE
306 #endif
307 
308 #if __has_attribute(__swift_name__)
309 # define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name)))
310 #else
311 # define OF_SWIFT_NAME(name)
312 #endif
313 
314 #if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME)
315 # define OF_DIRECT __attribute__((__objc_direct__))
316 #else
317 # define OF_DIRECT
318 #endif
319 #if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME)
320 # define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__))
321 #else
322 # define OF_DIRECT_MEMBERS
323 #endif
324 
325 #ifdef OF_APPLE_RUNTIME
326 # if defined(OF_X86_64) || defined(OF_X86) || defined(OF_ARM64) || \
327  defined(OF_ARM) || defined(OF_POWERPC)
328 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
329 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
330 # endif
331 #else
332 # if defined(OF_ELF)
333 # if defined(OF_X86_64) || defined(OF_X86) || \
334  defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \
335  defined(OF_MIPS) || defined(OF_SPARC64) || defined(OF_SPARC)
336 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
337 # if __OBJFW_RUNTIME_ABI__ >= 800
338 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
339 # endif
340 # endif
341 # elif defined(OF_MACH_O)
342 # if defined(OF_X86_64)
343 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
344 # if __OBJFW_RUNTIME_ABI__ >= 800
345 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
346 # endif
347 # endif
348 # elif defined(OF_WINDOWS)
349 # if defined(OF_X86_64) || defined(OF_X86)
350 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
351 # if __OBJFW_RUNTIME_ABI__ >= 800
352 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
353 # endif
354 # endif
355 # endif
356 #endif
357 
358 #define OF_RETAIN_COUNT_MAX UINT_MAX
359 #define OF_NOT_FOUND SIZE_MAX
360 
361 #ifdef OBJC_COMPILING_RUNTIME
362 # define OF_ENSURE(cond) \
363  do { \
364  if OF_UNLIKELY (!(cond)) \
365  objc_error("ObjFWRT @ " __FILE__ ":" \
366  OF_STRINGIFY(__LINE__), \
367  "Failed to ensure condition:\n" #cond); \
368  } while(0)
369 #else
370 # define OF_ENSURE(cond) \
371  do { \
372  if OF_UNLIKELY (!(cond)) { \
373  fprintf(stderr, "Failed to ensure condition " \
374  "in " __FILE__ ":%d:\n" #cond "\n", \
375  __LINE__); \
376  abort(); \
377  } \
378  } while (0)
379 #endif
380 
381 #define OF_UNRECOGNIZED_SELECTOR of_method_not_found(self, _cmd);
382 #if __has_feature(objc_arc)
383 # define OF_INVALID_INIT_METHOD of_method_not_found(self, _cmd);
384 #else
385 # define OF_INVALID_INIT_METHOD \
386  @try { \
387  of_method_not_found(self, _cmd); \
388  } @catch (id e) { \
389  [self release]; \
390  @throw e; \
391  } \
392  \
393  abort();
394 #endif
395 #ifdef __clang__
396 # define OF_DEALLOC_UNSUPPORTED \
397  [self doesNotRecognizeSelector: _cmd]; \
398  \
399  abort(); \
400  \
401  _Pragma("clang diagnostic push ignored \"-Wunreachable-code\""); \
402  [super dealloc]; /* Get rid of a stupid warning */ \
403  _Pragma("clang diagnostic pop");
404 #else
405 # define OF_DEALLOC_UNSUPPORTED \
406  [self doesNotRecognizeSelector: _cmd]; \
407  \
408  abort(); \
409  \
410  [super dealloc]; /* Get rid of a stupid warning */
411 #endif
412 
413 #define OF_CONSTRUCTOR(prio) \
414  static void __attribute__((__constructor__(prio))) \
415  OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void)
416 #define OF_DESTRUCTOR(prio) \
417  static void __attribute__((__destructor__(prio))) \
418  OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void)
419 
420 static OF_INLINE uint16_t OF_CONST_FUNC
421 OF_BSWAP16_CONST(uint16_t i)
422 {
423  return (i & 0xFF00) >> 8 | (i & 0x00FF) << 8;
424 }
425 
426 static OF_INLINE uint32_t OF_CONST_FUNC
427 OF_BSWAP32_CONST(uint32_t i)
428 {
429  return (i & 0xFF000000) >> 24 | (i & 0x00FF0000) >> 8 |
430  (i & 0x0000FF00) << 8 | (i & 0x000000FF) << 24;
431 }
432 
433 static OF_INLINE uint64_t OF_CONST_FUNC
434 OF_BSWAP64_CONST(uint64_t i)
435 {
436  return (i & 0xFF00000000000000) >> 56 | (i & 0x00FF000000000000) >> 40 |
437  (i & 0x0000FF0000000000) >> 24 | (i & 0x000000FF00000000) >> 8 |
438  (i & 0x00000000FF000000) << 8 | (i & 0x0000000000FF0000) << 24 |
439  (i & 0x000000000000FF00) << 40 | (i & 0x00000000000000FF) << 56;
440 }
441 
442 static OF_INLINE uint16_t OF_CONST_FUNC
443 OF_BSWAP16_NONCONST(uint16_t i)
444 {
445 #if defined(OF_HAVE_BUILTIN_BSWAP16)
446  return __builtin_bswap16(i);
447 #elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__)
448  __asm__ (
449  "xchgb %h0, %b0"
450  : "=Q"(i)
451  : "0"(i)
452  );
453 #elif defined(OF_POWERPC) && defined(__GNUC__)
454  __asm__ (
455  "lhbrx %0, 0, %1"
456  : "=r"(i)
457  : "r"(&i), "m"(i)
458  );
459 #elif defined(OF_ARMV6) && defined(__GNUC__)
460  __asm__ (
461  "rev16 %0, %0"
462  : "=r"(i)
463  : "0"(i)
464  );
465 #else
466  i = (i & UINT16_C(0xFF00)) >> 8 |
467  (i & UINT16_C(0x00FF)) << 8;
468 #endif
469  return i;
470 }
471 
472 static OF_INLINE uint32_t OF_CONST_FUNC
473 OF_BSWAP32_NONCONST(uint32_t i)
474 {
475 #if defined(OF_HAVE_BUILTIN_BSWAP32)
476  return __builtin_bswap32(i);
477 #elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__)
478  __asm__ (
479  "bswap %0"
480  : "=q"(i)
481  : "0"(i)
482  );
483 #elif defined(OF_POWERPC) && defined(__GNUC__)
484  __asm__ (
485  "lwbrx %0, 0, %1"
486  : "=r"(i)
487  : "r"(&i), "m"(i)
488  );
489 #elif defined(OF_ARMV6) && defined(__GNUC__)
490  __asm__ (
491  "rev %0, %0"
492  : "=r"(i)
493  : "0"(i)
494  );
495 #else
496  i = (i & UINT32_C(0xFF000000)) >> 24 |
497  (i & UINT32_C(0x00FF0000)) >> 8 |
498  (i & UINT32_C(0x0000FF00)) << 8 |
499  (i & UINT32_C(0x000000FF)) << 24;
500 #endif
501  return i;
502 }
503 
504 static OF_INLINE uint64_t OF_CONST_FUNC
505 OF_BSWAP64_NONCONST(uint64_t i)
506 {
507 #if defined(OF_HAVE_BUILTIN_BSWAP64)
508  return __builtin_bswap64(i);
509 #elif defined(OF_X86_64) && defined(__GNUC__)
510  __asm__ (
511  "bswap %0"
512  : "=r"(i)
513  : "0"(i)
514  );
515 #elif defined(OF_X86) && defined(__GNUC__)
516  __asm__ (
517  "bswap %%eax\n\t"
518  "bswap %%edx\n\t"
519  "xchgl %%eax, %%edx"
520  : "=A"(i)
521  : "0"(i)
522  );
523 #else
524  i = (uint64_t)OF_BSWAP32_NONCONST((uint32_t)(i & 0xFFFFFFFF)) << 32 |
525  OF_BSWAP32_NONCONST((uint32_t)(i >> 32));
526 #endif
527  return i;
528 }
529 
530 #ifdef __GNUC__
531 # define OF_BSWAP16(i) \
532  (__builtin_constant_p(i) ? OF_BSWAP16_CONST(i) : OF_BSWAP16_NONCONST(i))
533 # define OF_BSWAP32(i) \
534  (__builtin_constant_p(i) ? OF_BSWAP32_CONST(i) : OF_BSWAP32_NONCONST(i))
535 # define OF_BSWAP64(i) \
536  (__builtin_constant_p(i) ? OF_BSWAP64_CONST(i) : OF_BSWAP64_NONCONST(i))
537 #else
538 # define OF_BSWAP16(i) OF_BSWAP16_CONST(i)
539 # define OF_BSWAP32(i) OF_BSWAP32_CONST(i)
540 # define OF_BSWAP64(i) OF_BSWAP64_CONST(i)
541 #endif
542 
543 static OF_INLINE uint32_t
544 OF_FLOAT_TO_INT_RAW(float f)
545 {
546  uint32_t ret;
547  memcpy(&ret, &f, 4);
548  return ret;
549 }
550 
551 static OF_INLINE float
552 OF_INT_TO_FLOAT_RAW(uint32_t uInt32)
553 {
554  float ret;
555  memcpy(&ret, &uInt32, 4);
556  return ret;
557 }
558 
559 static OF_INLINE uint64_t
560 OF_DOUBLE_TO_INT_RAW(double d)
561 {
562  uint64_t ret;
563  memcpy(&ret, &d, 8);
564  return ret;
565 }
566 
567 static OF_INLINE double
568 OF_INT_TO_DOUBLE_RAW(uint64_t uInt64)
569 {
570  double ret;
571  memcpy(&ret, &uInt64, 8);
572  return ret;
573 }
574 
575 static OF_INLINE float OF_CONST_FUNC
576 OF_BSWAP_FLOAT(float f)
577 {
578  return OF_INT_TO_FLOAT_RAW(OF_BSWAP32(OF_FLOAT_TO_INT_RAW(f)));
579 }
580 
581 static OF_INLINE double OF_CONST_FUNC
582 OF_BSWAP_DOUBLE(double d)
583 {
584  return OF_INT_TO_DOUBLE_RAW(OF_BSWAP64(OF_DOUBLE_TO_INT_RAW(d)));
585 }
586 
587 #ifdef OF_BIG_ENDIAN
588 # define OF_BSWAP16_IF_BE(i) OF_BSWAP16(i)
589 # define OF_BSWAP32_IF_BE(i) OF_BSWAP32(i)
590 # define OF_BSWAP64_IF_BE(i) OF_BSWAP64(i)
591 # define OF_BSWAP16_IF_LE(i) (i)
592 # define OF_BSWAP32_IF_LE(i) (i)
593 # define OF_BSWAP64_IF_LE(i) (i)
594 #else
595 # define OF_BSWAP16_IF_BE(i) (i)
596 # define OF_BSWAP32_IF_BE(i) (i)
597 # define OF_BSWAP64_IF_BE(i) (i)
598 # define OF_BSWAP16_IF_LE(i) OF_BSWAP16(i)
599 # define OF_BSWAP32_IF_LE(i) OF_BSWAP32(i)
600 # define OF_BSWAP64_IF_LE(i) OF_BSWAP64(i)
601 #endif
602 
603 #ifdef OF_FLOAT_BIG_ENDIAN
604 # define OF_BSWAP_FLOAT_IF_BE(i) OF_BSWAP_FLOAT(i)
605 # define OF_BSWAP_DOUBLE_IF_BE(i) OF_BSWAP_DOUBLE(i)
606 # define OF_BSWAP_FLOAT_IF_LE(i) (i)
607 # define OF_BSWAP_DOUBLE_IF_LE(i) (i)
608 #else
609 # define OF_BSWAP_FLOAT_IF_BE(i) (i)
610 # define OF_BSWAP_DOUBLE_IF_BE(i) (i)
611 # define OF_BSWAP_FLOAT_IF_LE(i) OF_BSWAP_FLOAT(i)
612 # define OF_BSWAP_DOUBLE_IF_LE(i) OF_BSWAP_DOUBLE(i)
613 #endif
614 
615 static OF_INLINE uint16_t
616 of_be16_ptr_read(void *_Nonnull ptr)
617 {
618  uint16_t value;
619  memcpy(&value, ptr, sizeof(value));
620  return OF_BSWAP16_IF_LE(value);
621 }
622 
623 static OF_INLINE uint32_t
624 of_be32_ptr_read(void *_Nonnull ptr)
625 {
626  uint32_t value;
627  memcpy(&value, ptr, sizeof(value));
628  return OF_BSWAP32_IF_LE(value);
629 }
630 
631 static OF_INLINE uint64_t
632 of_be64_ptr_read(void *_Nonnull ptr)
633 {
634  uint64_t value;
635  memcpy(&value, ptr, sizeof(value));
636  return OF_BSWAP64_IF_LE(value);
637 }
638 
639 static OF_INLINE float
640 of_be_float_ptr_read(void *_Nonnull ptr)
641 {
642  float value;
643  memcpy(&value, ptr, sizeof(value));
644  return OF_BSWAP_FLOAT_IF_LE(value);
645 }
646 
647 static OF_INLINE double
648 of_be_double_ptr_read(void *_Nonnull ptr)
649 {
650  double value;
651  memcpy(&value, ptr, sizeof(value));
652  return OF_BSWAP_DOUBLE_IF_LE(value);
653 }
654 
655 static OF_INLINE uint16_t
656 of_le16_ptr_read(void *_Nonnull ptr)
657 {
658  uint16_t value;
659  memcpy(&value, ptr, sizeof(value));
660  return OF_BSWAP16_IF_BE(value);
661 }
662 
663 static OF_INLINE uint32_t
664 of_le32_ptr_read(void *_Nonnull ptr)
665 {
666  uint32_t value;
667  memcpy(&value, ptr, sizeof(value));
668  return OF_BSWAP32_IF_BE(value);
669 }
670 
671 static OF_INLINE uint64_t
672 of_le64_ptr_read(void *_Nonnull ptr)
673 {
674  uint64_t value;
675  memcpy(&value, ptr, sizeof(value));
676  return OF_BSWAP64_IF_BE(value);
677 }
678 
679 static OF_INLINE float
680 of_le_float_ptr_read(void *_Nonnull ptr)
681 {
682  float value;
683  memcpy(&value, ptr, sizeof(value));
684  return OF_BSWAP_FLOAT_IF_BE(value);
685 }
686 
687 static OF_INLINE double
688 of_le_double_ptr_read(void *_Nonnull ptr)
689 {
690  double value;
691  memcpy(&value, ptr, sizeof(value));
692  return OF_BSWAP_DOUBLE_IF_BE(value);
693 }
694 
695 static OF_INLINE void
696 of_be16_ptr_write(void *_Nonnull ptr, uint16_t value)
697 {
698  value = OF_BSWAP16_IF_LE(value);
699  memcpy(ptr, &value, sizeof(value));
700 }
701 
702 static OF_INLINE void
703 of_be32_ptr_write(void *_Nonnull ptr, uint32_t value)
704 {
705  value = OF_BSWAP32_IF_LE(value);
706  memcpy(ptr, &value, sizeof(value));
707 }
708 
709 static OF_INLINE void
710 of_be64_ptr_write(void *_Nonnull ptr, uint64_t value)
711 {
712  value = OF_BSWAP64_IF_LE(value);
713  memcpy(ptr, &value, sizeof(value));
714 }
715 
716 static OF_INLINE void
717 of_be_float_ptr_write(void *_Nonnull ptr, float value)
718 {
719  value = OF_BSWAP_FLOAT_IF_LE(value);
720  memcpy(ptr, &value, sizeof(value));
721 }
722 
723 static OF_INLINE void
724 of_be_double_ptr_write(void *_Nonnull ptr, double value)
725 {
726  value = OF_BSWAP_DOUBLE_IF_LE(value);
727  memcpy(ptr, &value, sizeof(value));
728 }
729 
730 static OF_INLINE void
731 of_le16_ptr_write(void *_Nonnull ptr, uint16_t value)
732 {
733  value = OF_BSWAP16_IF_BE(value);
734  memcpy(ptr, &value, sizeof(value));
735 }
736 
737 static OF_INLINE void
738 of_le32_ptr_write(void *_Nonnull ptr, uint32_t value)
739 {
740  value = OF_BSWAP32_IF_BE(value);
741  memcpy(ptr, &value, sizeof(value));
742 }
743 
744 static OF_INLINE void
745 of_le64_ptr_write(void *_Nonnull ptr, uint64_t value)
746 {
747  value = OF_BSWAP64_IF_BE(value);
748  memcpy(ptr, &value, sizeof(value));
749 }
750 
751 static OF_INLINE void
752 of_le_float_ptr_write(void *_Nonnull ptr, float value)
753 {
754  value = OF_BSWAP_FLOAT_IF_BE(value);
755  memcpy(ptr, &value, sizeof(value));
756 }
757 
758 static OF_INLINE void
759 of_le_double_ptr_write(void *_Nonnull ptr, double value)
760 {
761  value = OF_BSWAP_DOUBLE_IF_BE(value);
762  memcpy(ptr, &value, sizeof(value));
763 }
764 
765 #define OF_ROL(value, bits) \
766  (((bits) % (sizeof(value) * 8)) > 0 \
767  ? ((value) << ((bits) % (sizeof(value) * 8))) | \
768  ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
769  : (value))
770 #define OF_ROR(value, bits) \
771  (((bits) % (sizeof(value) * 8)) > 0 \
772  ? ((value) >> ((bits) % (sizeof(value) * 8))) | \
773  ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
774  : (value))
775 
776 #define OF_ROUND_UP_POW2(pow2, value) (((value) + (pow2) - 1) & ~((pow2) - 1))
777 
778 #define OF_HASH_INIT(hash) hash = of_hash_seed;
779 #define OF_HASH_ADD(hash, byte) \
780  { \
781  hash += (uint8_t)(byte); \
782  hash += (hash << 10); \
783  hash ^= (hash >> 6); \
784  }
785 #define OF_HASH_FINALIZE(hash) \
786  { \
787  hash += (hash << 3); \
788  hash ^= (hash >> 11); \
789  hash += (hash << 15); \
790  }
791 #define OF_HASH_ADD_HASH(hash, other) \
792  { \
793  uint32_t otherCopy = (uint32_t)other; \
794  OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF); \
795  OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF); \
796  OF_HASH_ADD(hash, (otherCopy >> 8) & 0xFF); \
797  OF_HASH_ADD(hash, otherCopy & 0xFF); \
798  }
799 
800 static OF_INLINE bool
801 of_bitset_isset(unsigned char *_Nonnull storage, size_t idx)
802 {
803  return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT));
804 }
805 
806 static OF_INLINE void
807 of_bitset_set(unsigned char *_Nonnull storage, size_t idx)
808 {
809  storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT));
810 }
811 
812 static OF_INLINE void
813 of_bitset_clear(unsigned char *_Nonnull storage, size_t idx)
814 {
815  storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT));
816 }
817 
818 static OF_INLINE char *_Nullable
819 of_strdup(const char *_Nonnull string)
820 {
821  char *copy;
822  size_t length = strlen(string);
823 
824  if ((copy = (char *)malloc(length + 1)) == NULL)
825  return NULL;
826 
827  memcpy(copy, string, length + 1);
828 
829  return copy;
830 }
831 
832 static OF_INLINE void
833 of_explicit_memset(void *_Nonnull buffer_, int character, size_t length)
834 {
835  volatile unsigned char *buffer = (volatile unsigned char *)buffer_;
836 
837  while (buffer < (unsigned char *)buffer_ + length)
838  *buffer++ = character;
839 }
840 
841 static OF_INLINE bool
842 of_ascii_isalpha(char c)
843 {
844  return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
845 }
846 
847 static OF_INLINE bool
848 of_ascii_isdigit(char c)
849 {
850  return (c >= '0' && c <= '9');
851 }
852 
853 static OF_INLINE bool
854 of_ascii_isalnum(char c)
855 {
856  return (of_ascii_isalpha(c) || of_ascii_isdigit(c));
857 }
858 
859 static OF_INLINE bool
860 of_ascii_isspace(char c)
861 {
862  return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
863  c == '\v');
864 }
865 
866 static OF_INLINE char
867 of_ascii_toupper(char c)
868 {
869  return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
870 }
871 
872 static OF_INLINE char
873 of_ascii_tolower(char c)
874 {
875  return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
876 }
877 #endif