]> wimlib.net Git - wimlib/blob - include/wimlib/util.h
Rewrite of write_stream_list(), and writing packed resources
[wimlib] / include / wimlib / util.h
1 #ifndef _WIMLIB_UTIL_H
2 #define _WIMLIB_UTIL_H
3
4 #include "wimlib/types.h"
5 #include "wimlib/compiler.h"
6
7 #include <stdio.h>
8 #include <stddef.h>
9
10 #ifndef min
11 #define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
12                                         (__a < __b) ? __a : __b; })
13 #endif
14
15 #ifndef max
16 #define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
17                                         (__a > __b) ? __a : __b; })
18 #endif
19
20 #ifndef swap
21 #define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
22 #endif
23
24 /**
25  * container_of - cast a member of a structure out to the containing structure
26  * @ptr:        the pointer to the member.
27  * @type:       the type of the container struct this is embedded in.
28  * @member:     the name of the member within the struct.
29  *
30  */
31 #ifndef container_of
32 #define container_of(ptr, type, member) ({                      \
33         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
34         (type *)( (char *)__mptr - offsetof(type,member) );})
35 #endif
36
37 #define DIV_ROUND_UP(numerator, denominator) \
38         (((numerator) + (denominator) - 1) / (denominator))
39
40 #define MODULO_NONZERO(numerator, denominator) \
41         (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
42
43 #define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
44
45 #define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
46
47 /* Used for buffering FILE IO in a few places */
48 #define BUFFER_SIZE 32768
49
50 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
51
52 /* Maximum number of array elements to allocate on the stack (used in various
53  * places when large temporary buffers are needed).  */
54 #define STACK_MAX 32768
55
56 #ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
57 extern void *
58 wimlib_malloc(size_t) _malloc_attribute;
59
60 extern void
61 wimlib_free_memory(void *p);
62
63 extern void *
64 wimlib_realloc(void *, size_t) _warn_unused_result_attribute;
65
66 extern void *
67 wimlib_calloc(size_t nmemb, size_t size) _malloc_attribute;
68
69 #ifdef __WIN32__
70 extern wchar_t *
71 wimlib_wcsdup(const wchar_t *str) _malloc_attribute;
72
73 #endif
74 extern char *
75 wimlib_strdup(const char *str) _malloc_attribute;
76
77 #  define       MALLOC  wimlib_malloc
78 #  define       FREE    wimlib_free_memory
79 #  define       REALLOC wimlib_realloc
80 #  define       CALLOC  wimlib_calloc
81 #  define       STRDUP  wimlib_strdup
82 #  define       WCSDUP  wimlib_wcsdup
83 #else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
84 #  include <stdlib.h>
85 #  include <string.h>
86 #  define       MALLOC  malloc
87 #  define       FREE    free
88 #  define       REALLOC realloc
89 #  define       CALLOC  calloc
90 #  define       STRDUP  strdup
91 #  define       WCSDUP  wcsdup
92 #endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
93
94 extern void *
95 memdup(const void *mem, size_t size) _malloc_attribute;
96
97 #ifndef HAVE_MEMPCPY
98 extern void *
99 mempcpy(void *dst, const void *src, size_t n);
100 #endif
101
102 /* util.c */
103 extern void
104 randomize_byte_array(u8 *p, size_t n);
105
106 extern void
107 randomize_char_array_with_alnum(tchar p[], size_t n);
108
109 extern void
110 print_byte_field(const u8 field[], size_t len, FILE *out);
111
112 static inline u32
113 bsr32(u32 n)
114 {
115 #if defined(__x86__) || defined(__x86_64__)
116         asm("bsrl %0, %0;"
117                         : "=r"(n)
118                         : "0" (n));
119         return n;
120 #else
121         u32 pow = 0;
122         while ((n >>= 1) != 0)
123                 pow++;
124         return pow;
125 #endif
126 }
127
128 static inline bool
129 is_power_of_2(unsigned long n)
130 {
131         return (n != 0 && (n & (n - 1)) == 0);
132
133 }
134
135 static inline u64
136 hash_u64(u64 n)
137 {
138         return n * 0x9e37fffffffc0001ULL;
139 }
140
141 static inline int
142 cmp_u64(u64 n1, u64 n2)
143 {
144         if (n1 < n2)
145                 return -1;
146         else if (n1 > n2)
147                 return 1;
148         else
149                 return 0;
150 }
151
152 /* is_any_path_separator() - characters treated as path separators in WIM path
153  * specifications and capture configuration files (the former will be translated
154  * to WIM_PATH_SEPARATOR; the latter will be translated to
155  * OS_PREFERRED_PATH_SEPARATOR)
156  *
157  * OS_PREFERRED_PATH_SEPARATOR - preferred (or only) path separator on the
158  * operating system.  Used when constructing filesystem paths to extract or
159  * archive.
160  *
161  * WIM_PATH_SEPARATOR - character treated as path separator for WIM paths.
162  * Currently needs to be '/' on UNIX for the WIM mounting code to work properly.
163  */
164
165 #ifdef __WIN32__
166 #  define OS_PREFERRED_PATH_SEPARATOR L'\\'
167 #  define is_any_path_separator(c) ((c) == L'/' || (c) == L'\\')
168 #else
169 #  define OS_PREFERRED_PATH_SEPARATOR '/'
170 #  define is_any_path_separator(c) ((c) == '/' || (c) == '\\')
171 #endif
172
173 #define WIM_PATH_SEPARATOR WIMLIB_WIM_PATH_SEPARATOR
174
175 #endif /* _WIMLIB_UTIL_H */