]> wimlib.net Git - wimlib/blob - src/util.c
Clean up util.h and util.c
[wimlib] / src / util.c
1 /*
2  * util.c - utility functions
3  */
4
5 /*
6  * Copyright (C) 2012, 2013, 2014 Eric Biggers
7  *
8  * This file is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the Free
10  * Software Foundation; either version 3 of the License, or (at your option) any
11  * later version.
12  *
13  * This file is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this file; if not, see http://www.gnu.org/licenses/.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "wimlib.h"
31 #include "wimlib/assert.h"
32 #include "wimlib/timestamp.h"
33 #include "wimlib/util.h"
34 #include "wimlib/xml.h"
35
36 /*******************
37  * Memory allocation
38  *******************/
39
40 static void *(*wimlib_malloc_func) (size_t)         = malloc;
41 static void  (*wimlib_free_func)   (void *)         = free;
42 static void *(*wimlib_realloc_func)(void *, size_t) = realloc;
43
44 void *
45 wimlib_malloc(size_t size)
46 {
47         void *ptr;
48
49 retry:
50         ptr = (*wimlib_malloc_func)(size);
51         if (unlikely(!ptr)) {
52                 if (size == 0) {
53                         size = 1;
54                         goto retry;
55                 }
56         }
57         return ptr;
58 }
59
60 void
61 wimlib_free_memory(void *ptr)
62 {
63         (*wimlib_free_func)(ptr);
64 }
65
66 void *
67 wimlib_realloc(void *ptr, size_t size)
68 {
69         if (size == 0)
70                 size = 1;
71         return (*wimlib_realloc_func)(ptr, size);
72 }
73
74 void *
75 wimlib_calloc(size_t nmemb, size_t size)
76 {
77         size_t total_size = nmemb * size;
78         void *p = MALLOC(total_size);
79         if (p)
80                 p = memset(p, 0, total_size);
81         return p;
82 }
83
84 char *
85 wimlib_strdup(const char *str)
86 {
87         size_t size;
88         char *p;
89
90         size = strlen(str);
91         p = MALLOC(size + 1);
92         if (p)
93                 p = memcpy(p, str, size + 1);
94         return p;
95 }
96
97 #ifdef __WIN32__
98 wchar_t *
99 wimlib_wcsdup(const wchar_t *str)
100 {
101         size_t size;
102         wchar_t *p;
103
104         size = wcslen(str);
105         p = MALLOC((size + 1) * sizeof(wchar_t));
106         if (p)
107                 p = wmemcpy(p, str, size + 1);
108         return p;
109 }
110 #endif
111
112 void *
113 wimlib_aligned_malloc(size_t size, size_t alignment)
114 {
115         u8 *raw_ptr;
116         u8 *ptr;
117         uintptr_t mask;
118
119         wimlib_assert(alignment != 0 && is_power_of_2(alignment) &&
120                       alignment <= 4096);
121         mask = alignment - 1;
122
123         raw_ptr = MALLOC(size + alignment - 1 + sizeof(size_t));
124         if (!raw_ptr)
125                 return NULL;
126
127         ptr = (u8 *)raw_ptr + sizeof(size_t);
128         while ((uintptr_t)ptr & mask)
129                 ptr++;
130         *((size_t *)ptr - 1) = (ptr - raw_ptr);
131
132         return ptr;
133 }
134
135 void
136 wimlib_aligned_free(void *ptr)
137 {
138         if (ptr)
139                 FREE((u8 *)ptr - *((size_t *)ptr - 1));
140 }
141
142 void *
143 memdup(const void *mem, size_t size)
144 {
145         void *ptr = MALLOC(size);
146         if (ptr)
147                 ptr = memcpy(ptr, mem, size);
148         return ptr;
149 }
150
151 /* API function documented in wimlib.h  */
152 WIMLIBAPI int
153 wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
154                             void (*free_func)(void *),
155                             void *(*realloc_func)(void *, size_t))
156 {
157         wimlib_malloc_func  = malloc_func  ? malloc_func  : malloc;
158         wimlib_free_func    = free_func    ? free_func    : free;
159         wimlib_realloc_func = realloc_func ? realloc_func : realloc;
160
161         xml_set_memory_allocator(wimlib_malloc_func, wimlib_free_func,
162                                  wimlib_realloc_func);
163         return 0;
164 }
165
166 /*******************
167  * String utilities
168  *******************/
169
170 #ifndef HAVE_MEMPCPY
171 void *mempcpy(void *dst, const void *src, size_t n)
172 {
173         return memcpy(dst, src, n) + n;
174 }
175 #endif
176
177 size_t
178 utf16le_strlen(const utf16lechar *s)
179 {
180         const utf16lechar *p = s;
181         while (*p)
182                 p++;
183         return (p - s) * sizeof(utf16lechar);
184 }
185
186 static bool seeded = false;
187
188 static void
189 seed_random(void)
190 {
191         srand(now_as_wim_timestamp());
192         seeded = true;
193 }
194
195 /* Fills @n characters pointed to by @p with random alphanumeric characters. */
196 void
197 randomize_char_array_with_alnum(tchar *p, size_t n)
198 {
199         if (!seeded)
200                 seed_random();
201         while (n--) {
202                 int r = rand() % 62;
203                 if (r < 26)
204                         *p++ = r + 'a';
205                 else if (r < 52)
206                         *p++ = r - 26 + 'A';
207                 else
208                         *p++ = r - 52 + '0';
209         }
210 }
211
212 /* Fills @n bytes pointer to by @p with random numbers. */
213 void
214 randomize_byte_array(u8 *p, size_t n)
215 {
216         if (!seeded)
217                 seed_random();
218         while (n--)
219                 *p++ = rand();
220 }