2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
25 solv_oom(size_t num, size_t len)
28 fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len);
30 fprintf(stderr, "Out of memory allocating %zu bytes!\n", len);
36 solv_malloc(size_t len)
38 void *r = malloc(len ? len : 1);
45 solv_malloc2(size_t num, size_t len)
47 if (len && (num * len) / len != num)
49 return solv_malloc(num * len);
53 solv_realloc(void *old, size_t len)
56 old = malloc(len ? len : 1);
58 old = realloc(old, len ? len : 1);
65 solv_realloc2(void *old, size_t num, size_t len)
67 if (len && (num * len) / len != num)
69 return solv_realloc(old, num * len);
73 solv_calloc(size_t num, size_t len)
76 if (num == 0 || len == 0)
85 /* this was solv_realloc2(old, len, size), but we now overshoot
86 * for huge len sizes */
88 solv_extend_realloc(void *old, size_t len, size_t size, size_t block)
90 size_t xblock = (block + 1) << 5;
91 len = (len + block) & ~block;
92 if (len >= xblock && xblock)
95 while (len >= xblock && xblock)
100 xblock = (xblock >> 5) - 1;
101 nlen = (len + xblock) & ~xblock;
106 return solv_realloc2(old, len, size);
118 solv_strdup(const char *s)
125 solv_oom(0, strlen(s));
130 solv_timems(unsigned int subtract)
133 return GetTickCount() - subtract;
138 if (gettimeofday(&tv, 0))
140 r = (((unsigned int)tv.tv_sec >> 16) * 1000) << 16;
141 r += ((unsigned int)tv.tv_sec & 0xffff) * 1000;
142 r += (unsigned int)tv.tv_usec / 1000;
148 solv_setcloexec(int fd, int state)
151 return SetHandleInformation((HANDLE) _get_osfhandle(fd), HANDLE_FLAG_INHERIT, state ? 0 : HANDLE_FLAG_INHERIT);
153 return fcntl(fd, F_SETFD, state ? FD_CLOEXEC : 0) == 0;
157 /* bsd's qsort_r has different arguments, so we define our
158 own version in case we need to do some clever mapping
160 see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
162 #if (defined(__GLIBC__) || defined(__NEWLIB__)) && (defined(HAVE_QSORT_R) || defined(HAVE___QSORT_R))
165 solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
167 # if defined(HAVE_QSORT_R)
168 qsort_r(base, nmemb, size, compar, compard);
170 /* backported for SLE10-SP2 */
171 __qsort_r(base, nmemb, size, compar, compard);
176 #elif defined(HAVE_QSORT_R) /* not glibc, but has qsort_r() */
178 struct solv_sort_data {
179 int (*compar)(const void *, const void *, void *);
184 solv_sort_helper(void *compard, const void *a, const void *b)
186 struct solv_sort_data *d = compard;
187 return (*d->compar)(a, b, d->compard);
191 solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
193 struct solv_sort_data d;
196 qsort_r(base, nmemb, size, &d, solv_sort_helper);
199 #else /* not glibc and no qsort_r() */
200 /* use own version of qsort if none available */
205 solv_dupjoin(const char *str1, const char *str2, const char *str3)
209 l1 = str1 ? strlen(str1) : 0;
210 l2 = str2 ? strlen(str2) : 0;
211 l3 = str3 ? strlen(str3) : 0;
212 s = str = solv_malloc(l1 + l2 + l3 + 1);
233 solv_dupappend(const char *str1, const char *str2, const char *str3)
235 char *str = solv_dupjoin(str1, str2, str3);
236 solv_free((void *)str1);
241 solv_hex2bin(const char **strp, unsigned char *buf, int bufl)
243 const char *str = *strp;
246 for (i = 0; i < bufl; i++)
250 if (c >= '0' && c <= '9')
252 else if (c >= 'a' && c <= 'f')
254 else if (c >= 'A' && c <= 'F')
260 if (c >= '0' && c <= '9')
262 else if (c >= 'a' && c <= 'f')
264 else if (c >= 'A' && c <= 'F')
276 solv_bin2hex(const unsigned char *buf, int l, char *str)
279 for (i = 0; i < l; i++, buf++)
282 *str++ = c < 10 ? c + '0' : c + ('a' - 10);
284 *str++ = c < 10 ? c + '0' : c + ('a' - 10);
291 solv_validutf8(const char *buf)
293 const unsigned char *p;
296 for (p = (const unsigned char *)buf; (x = *p) != 0; p++)
304 /* one byte to follow */
305 if ((p[1] & 0xc0) != 0x80)
308 break; /* not minimal */
314 /* two bytes to follow */
315 if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80)
317 if ((x & 0x0f) == 0 && (p[1] & 0x20) == 0)
318 break; /* not minimal */
319 if (x == 0xed && (p[1] & 0x20) != 0)
320 break; /* d800-dfff surrogate */
321 if (x == 0xef && p[1] == 0xbf && (p[2] == 0xbe || p[2] == 0xbf))
322 break; /* fffe or ffff */
328 /* three bytes to follow */
329 if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80)
331 if ((x & 0x07) == 0 && (p[1] & 0x30) == 0)
332 break; /* not minimal */
333 if ((x & 0x07) > 4 || ((x & 0x07) == 4 && (p[1] & 0x30) != 0))
334 break; /* above 0x10ffff */
338 break; /* maybe valid utf8, but above 0x10ffff */
340 return (const char *)p - buf;
344 solv_latin1toutf8(const char *buf)
350 for (p = buf; *p; p++)
351 if ((*(const unsigned char *)p & 128) != 0)
353 r = rp = solv_malloc(p - buf + l);
354 for (p = buf; *p; p++)
356 if ((*(const unsigned char *)p & 128) != 0)
358 *rp++ = *(const unsigned char *)p & 64 ? 0xc3 : 0xc2;
369 solv_replacebadutf8(const char *buf, int replchar)
373 char *r = 0, *rp = 0;
376 if (replchar < 0 || replchar > 0x10ffff)
379 repllen = replin = 0;
380 else if (replchar < 0x80)
383 replin = (replchar & 0x40) | 0x80;
385 else if (replchar < 0x800)
390 else if (replchar < 0x10000)
402 for (p = buf, nl = 0; *p; )
404 l = solv_validutf8(p);
414 /* found a bad char, replace with replchar */
420 *rp++ = (replchar >> 18 & 0x3f) | 0x80;
422 *rp++ = (replchar >> 12 & 0x3f) | 0x80;
424 *rp++ = (replchar >> 6 & 0x3f) | 0x80;
426 *rp++ = (replchar & 0x3f) | 0x80;
428 rp[-repllen] ^= replin;
432 while ((*(const unsigned char *)p & 0xc0) == 0x80)
437 r = rp = solv_malloc(nl + 1);