Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

misc.h

Go to the documentation of this file.
00001 /*
00002  * $Id: misc.h,v 1.93 2005/12/27 13:10:50 cbiere Exp $
00003  *
00004  * Copyright (c) 2001-2003, Raphael Manfredi
00005  *
00006  *----------------------------------------------------------------------
00007  * This file is part of gtk-gnutella.
00008  *
00009  *  gtk-gnutella is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  gtk-gnutella is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with gtk-gnutella; if not, write to the Free Software
00021  *  Foundation, Inc.:
00022  *      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *----------------------------------------------------------------------
00024  */
00025 
00050 #ifndef _misc_h_
00051 #define _misc_h_
00052 
00053 #include "config.h"
00054 
00055 #include <time.h>
00056 #include <stdio.h>
00057 #include <ctype.h>
00058 
00059 #include <glib.h>
00060 
00061 #define SIZE_FIELD_MAX 64       
00062 #define GUID_RAW_SIZE   16      
00063 #define GUID_HEX_SIZE   32      
00068 #ifndef USE_GLIB2
00069 
00070 #ifndef HAS_STRLCPY
00071 size_t strlcpy(gchar *dst, const gchar *src, size_t dst_size);
00072 #endif /* HAS_STRLCPY */
00073 
00074 #ifndef HAS_STRLCAT
00075 size_t strlcat(gchar *dst, const gchar *src, size_t dst_size);
00076 #endif /* HAS_STRLCAT */
00077 
00078 #define g_string_printf g_string_sprintf
00079 #define g_strlcpy strlcpy
00080 #define g_strlcat strlcat
00081 #endif
00082 
00083 size_t concat_strings(gchar *dst, size_t size,
00084     const gchar *s, ...) WARN_NEED_SENTINEL;
00085 size_t w_concat_strings(gchar **dst,
00086     const gchar *first, ...) WARN_NEED_SENTINEL;
00087 
00093 static inline G_GNUC_CONST WARN_UNUSED_RESULT gchar *
00094 deconstify_gchar(const gchar *p)
00095 {
00096     return (gchar *) p;
00097 }
00098 
00099 static inline G_GNUC_CONST WARN_UNUSED_RESULT guint32 *
00100 deconstify_guint32(const guint32 *p)
00101 {
00102     return (guint32 *) p;
00103 }
00104 
00105 static inline G_GNUC_CONST WARN_UNUSED_RESULT gpointer
00106 deconstify_gpointer(gconstpointer p)
00107 {
00108     return (gpointer) p;
00109 }
00110 
00111 static inline G_GNUC_CONST WARN_UNUSED_RESULT gconstpointer
00112 cast_to_gconstpointer(gconstpointer p)
00113 {
00114     return p; 
00115 }
00116 
00117 static inline G_GNUC_CONST WARN_UNUSED_RESULT gpointer
00118 cast_to_gpointer(gpointer p)
00119 {
00120     return p;
00121 }
00122 
00123 static inline G_GNUC_CONST WARN_UNUSED_RESULT gchar *
00124 cast_to_gchar_ptr(gpointer p)
00125 {
00126     return p;
00127 }
00128 
00129 static inline G_GNUC_CONST WARN_UNUSED_RESULT guchar *
00130 cast_to_guchar_ptr(gpointer p)
00131 {
00132     return p;
00133 }
00134 
00135 typedef void (*func_ptr_t)(void);
00136 
00137 static inline G_GNUC_CONST WARN_UNUSED_RESULT gpointer
00138 cast_func_to_gpointer(func_ptr_t f)
00139 {
00140     union {
00141         func_ptr_t f;
00142         gpointer p;
00143     } u;
00144 
00145     u.f = f;
00146     return u.p;
00147 }
00148 
00149 static inline G_GNUC_CONST WARN_UNUSED_RESULT func_ptr_t
00150 cast_gpointer_to_func(gconstpointer p)
00151 {
00152     union {
00153         func_ptr_t f;
00154         gconstpointer p;
00155     } u;
00156 
00157     u.p = p;
00158     return u.f;
00159 }
00160 
00161 gint ascii_strcasecmp(const gchar *s1, const gchar *s2);
00162 gint ascii_strncasecmp(const gchar *s1, const gchar *s2, size_t len);
00163 
00170 static inline gint
00171 hex2int_inline(guchar c)
00172 {
00173     extern const gint8 *hex2int_tab;
00174     return hex2int_tab[c];
00175 }
00176 
00183 static inline gint
00184 dec2int_inline(guchar c)
00185 {
00186     extern const gint8 *dec2int_tab;
00187     return dec2int_tab[c];
00188 }
00189 
00196 static inline gint
00197 alnum2int_inline(guchar c)
00198 {
00199     extern const gint8 *alnum2int_tab;
00200     return alnum2int_tab[c];
00201 }
00202 
00211 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00212 is_ascii_blank(gint c)
00213 {
00214     return c == 32 || c == 9;   /* space, tab */
00215 }
00216 
00217 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00218 is_ascii_cntrl(gint c)
00219 {
00220     return (c >= 0 && c <= 31) || c == 127;
00221 }
00222 
00223 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00224 is_ascii_digit(gint c)
00225 {
00226     return c >= 48 && c <= 57;  /* 0-9 */
00227 }
00228 
00229 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00230 is_ascii_xdigit(gint c)
00231 {
00232     return -1 != hex2int_inline(c) && !(c & ~0x7f);
00233 }
00234 
00235 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00236 is_ascii_upper(gint c)
00237 {
00238     return c >= 65 && c <= 90;      /* A-Z */
00239 }
00240 
00241 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00242 is_ascii_lower(gint c)
00243 {
00244     return c >= 97 && c <= 122;     /* a-z */
00245 }
00246 
00247 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00248 is_ascii_alpha(gint c)
00249 {
00250     return is_ascii_upper(c) || is_ascii_lower(c);  /* A-Z, a-z */
00251 }
00252 
00253 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00254 is_ascii_alnum(gint c)
00255 {
00256     return -1 != alnum2int_inline(c) && !(c & ~0x7f); /* A-Z, a-z, 0-9 */
00257 }
00258 
00259 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00260 is_ascii_space(gint c)
00261 {
00262     return c == 32 || (c >= 9 && c <= 13);
00263 }
00264 
00265 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00266 is_ascii_graph(gint c)
00267 {
00268     return c >= 33 && c <= 126;
00269 }
00270 
00271 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00272 is_ascii_print(gint c)
00273 {
00274     return is_ascii_graph(c) || c == 32;
00275 }
00276 
00277 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00278 is_ascii_punct(gint c)
00279 {
00280     return c >= 33 && c <= 126 && !is_ascii_alnum(c);
00281 }
00282 
00283 static inline G_GNUC_CONST WARN_UNUSED_RESULT gint
00284 ascii_toupper(gint c)
00285 {
00286     return is_ascii_lower(c) ? c - 32 : c;
00287 }
00288 
00289 static inline G_GNUC_CONST WARN_UNUSED_RESULT gint
00290 ascii_tolower(gint c)
00291 {
00292     return is_ascii_upper(c) ? c + 32 : c;
00293 }
00294 
00295 #if !GLIB_CHECK_VERSION(2,4,0)
00296 static inline WARN_UNUSED_RESULT const gchar *
00297 g_strip_context(const gchar *id, const gchar *val)
00298 {
00299     const gchar *s;
00300 
00301     s = id != val ? NULL : strchr(id, '|');
00302     return s ? ++s : val;
00303 }
00304 #endif /* GLib < 2.4.0 */
00305 
00311 static inline WARN_UNUSED_RESULT gchar *
00312 skip_ascii_spaces(const gchar *s)
00313 {
00314     while (is_ascii_space(*s))
00315         s++;
00316 
00317     return deconstify_gchar(s);
00318 }
00319 
00325 static inline WARN_UNUSED_RESULT gchar *
00326 skip_ascii_blanks(const gchar *s)
00327 {
00328     while (is_ascii_blank(*s))
00329         s++;
00330 
00331     return deconstify_gchar(s);
00332 }
00333 
00334 /*
00335  * Determine the length of string literals
00336  */
00337 #define CONST_STRLEN(x) (sizeof(x) - 1)
00338 
00339 /*
00340  * Array size determination
00341  */
00342 #ifndef G_N_ELEMENTS
00343 #define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
00344 #endif
00345 
00346 /*
00347  * Set/clear binary flags
00348  */
00349 typedef guint16 flag_t;
00350 #define set_flags(r,f) (r |= (f))
00351 #define clear_flags(r,f) (r &= ~(f))
00352 
00353 /*
00354  * Macros to determine the maximum buffer size required to hold a
00355  * NUL-terminated string.
00356  */
00357 #define UINT8_HEX_BUFLEN    (sizeof "FF")
00358 #define UINT8_DEC_BUFLEN    (sizeof "255")
00359 #define UINT16_HEX_BUFLEN   (sizeof "01234")
00360 #define UINT16_DEC_BUFLEN   (sizeof "65535")
00361 #define UINT32_HEX_BUFLEN   (sizeof "012345678")
00362 #define UINT32_DEC_BUFLEN   (sizeof "4294967295")
00363 #define UINT64_HEX_BUFLEN   (sizeof "0123456789ABCDEF")
00364 #define UINT64_DEC_BUFLEN   (sizeof "18446744073709551615")
00365 #define IPV4_ADDR_BUFLEN    (sizeof "255.255.255.255")
00366 #define IPV6_ADDR_BUFLEN \
00367       (sizeof "0001:0203:0405:0607:0809:1011:255.255.255.255")
00368 #define TIMESTAMP_BUF_LEN   (sizeof "9999-12-31 23:59:61")
00369 
00370 gboolean parse_ipv6_addr(const gchar *s, uint8_t *dst, const gchar **endptr);
00371 const gchar *ipv6_to_string(const guint8 *ipv6);
00372 size_t ipv6_to_string_buf(const guint8 *ipv6, gchar *dst, size_t size);
00373 
00374 /*
00375  * Network related string routines
00376  */
00377 guint32  string_to_ip(const gchar *);
00378 gboolean string_to_ip_strict(const gchar *s, guint32 *addr, const gchar **ep);
00379 gboolean string_to_ip_and_mask(const gchar *str, guint32 *ip, guint32 *netmask);
00380 gboolean string_to_ip_port(const gchar *str, guint32 *ip, guint16 *port);
00381 const gchar *ip_to_string(guint32);
00382 const gchar *ip_to_string2(guint32);
00383 size_t ip_to_string_buf(guint32 ip, gchar *buf, size_t size);
00384 const gchar *ip_port_to_string(guint32, guint16);
00385 const gchar *hostname_port_to_string(const gchar *hostname, guint16 port);
00386 const gchar *local_hostname(void);
00387 #define port_is_valid(port) (port != 0)
00388 
00389 /*
00390  * Date string conversions
00391  */
00392 const gchar *timestamp_to_string(time_t date);
00393 const gchar *timestamp_utc_to_string(time_t date);
00394 const gchar *timestamp_rfc822_to_string(time_t date);
00395 const gchar *timestamp_rfc822_to_string2(time_t date);
00396 const gchar *timestamp_rfc1123_to_string(time_t date);
00397 
00398 size_t timestamp_to_string_buf(time_t date, gchar *dst, size_t size);
00399 size_t time_locale_to_string_buf(time_t date, gchar *dst, size_t size);
00400 /*
00401  * Time string conversions
00402  */
00403 gchar *short_time(gint s);
00404 gchar *short_uptime(gint s);
00405 
00406 /* Use the direct difference instead of difftime() for systems that are
00407  * known to use a flat time_t encoding. */
00408 #if !defined(LINUX_SYSTEM) && \
00409     !defined(__FreeBSD__) && \
00410     !defined(__NetBSD__) && \
00411     !defined(__OpenBSD__)
00412 #define USE_DIFFTIME
00413 #endif
00414 
00415 /* Use a macro so that's possible to not use difftime where it's not
00416  * necessary because time_t is flat encoded */
00417 #if defined(USE_DIFFTIME)
00418 #define delta_time(a, b) ((gint64) difftime((a), (b)))
00419 #else
00420 #define delta_time(a, b) ((gint64) ((a) - (b)))
00421 #endif
00422 
00423 /*
00424  * Size string conversions
00425  */
00426 const gchar *short_size(guint64 size);
00427 const gchar *short_html_size(guint64 size);
00428 const gchar *short_kb_size(guint64 size);
00429 const gchar *short_rate(guint64 rate);
00430 const gchar *compact_size(guint64 size);
00431 const gchar *compact_rate(guint64 rate);
00432 const gchar *compact_kb_size(guint32 size);
00433 gchar *short_value(gchar *buf, size_t size, guint64 v);
00434 gchar *compact_value(gchar *buf, size_t size, guint64 v);
00435 
00436 /*
00437  * SHA1<->base32 string conversion
00438  */
00439 gchar *sha1_base32(const gchar *sha1);
00440 gchar *base32_sha1(const gchar *base32);
00441 
00442 /*
00443  * GUID<->hex string conversion
00444  */
00445 gchar *guid_hex_str(const gchar *guid);
00446 gboolean hex_to_guid(const gchar *hexguid, gchar *guid);
00447 
00448 /*
00449  * GUID<->base32 string conversion
00450  */
00451 gchar *guid_base32_str(const gchar *guid);
00452 gchar *base32_to_guid(const gchar *base32);
00453 
00454 /*
00455  * Tests
00456  */
00457 gboolean is_absolute_path(const char *);
00458 gboolean is_directory(const gchar *);
00459 gboolean is_regular(const gchar *);
00460 gboolean is_symlink(const gchar *);
00461 gboolean file_exists(const gchar *);
00462 guint32 next_pow2(guint32 n);
00463 
00470 static inline G_GNUC_CONST gboolean
00471 is_pow2(guint32 value)
00472 #ifdef HAVE_BUILTIN_POPCOUNT
00473 {
00474     return 0 == __builtin_popcount(value);
00475 }
00476 #else /* !HAVE_BUILTIN_POPCOUNT */
00477 {
00478     return value && !(value & (value - 1));
00479 }
00480 #endif /* HAVE_BUILTIN_POPCOUNT */
00481 
00482 /*
00483  * Random numbers
00484  */
00485 void random_init(void);
00486 guint32 random_value(guint32 max) WARN_UNUSED_RESULT;
00487 void guid_random_fill(gchar *xuid);
00488 
00489 /*
00490  * Stuff
00491  */
00492 void misc_init(void);
00493 gint str_chomp(gchar *str, gint len);
00494 gint hex2int(guchar c);
00495 gboolean is_printable(const gchar *buf, gint len);
00496 void dump_hex(FILE *, const gchar *, gconstpointer, gint);
00497 void locale_strlower(gchar *, const gchar *);
00498 void ascii_strlower(gchar *dst, const gchar *src);
00499 gint strcmp_delimit(const gchar *a, const gchar *b, const gchar *delimit);
00500 gint strcasecmp_delimit(const gchar *a, const gchar *b, const gchar *delimit);
00501 char *unique_filename(const gchar *path, const gchar *file, const gchar *ext);
00502 gchar *hex_escape(const gchar *name, gboolean strict);
00503 gchar *control_escape(const gchar *s);
00504 const gchar *lazy_string_to_printf_escape(const gchar *src);
00505 gint highest_bit_set(guint32 n) G_GNUC_CONST;
00506 gfloat force_range(gfloat value, gfloat min, gfloat max);
00507 gchar *make_pathname(const gchar *dir, const gchar *file);
00508 gchar *short_filename(gchar *fullname);
00509 gchar *data_hex_str(const gchar *data, size_t len);
00510 gint create_directory(const gchar *dir);
00511 gboolean filepath_exists(const gchar *dir, const gchar *file);
00512 guint16 parse_uint16(const gchar *, gchar const **, guint, gint *)
00513     NON_NULL_PARAM((1, 4));
00514 guint32 parse_uint32(const gchar *, gchar const **, guint, gint *)
00515     NON_NULL_PARAM((1, 4));
00516 guint64 parse_uint64(const gchar *, gchar const **, guint, gint *)
00517     NON_NULL_PARAM((1, 4));
00518 size_t uint32_to_string_buf(guint64 v, gchar *dst, size_t size);
00519 size_t uint64_to_string_buf(guint64 v, gchar *dst, size_t size);
00520 const gchar *uint32_to_string(guint32 v);
00521 const gchar *uint64_to_string(guint64 v);
00522 const gchar *uint64_to_string2(guint64 v);
00523 gint parse_major_minor(const gchar *src, gchar const **endptr,
00524     guint *major, guint *minor);
00525 gchar *is_strprefix(const gchar *s, const gchar *prefix) WARN_UNUSED_RESULT;
00526 gchar *is_strcaseprefix(const gchar *s, const gchar *prefix) WARN_UNUSED_RESULT;
00527 size_t html_escape(const gchar *src, gchar *dst, size_t dst_size);
00528 gint canonize_path(gchar *dst, const gchar *path);
00529 guint compat_max_fd(void);
00530 gint compat_mkdir(const gchar *path, mode_t mode);
00531 size_t compat_pagesize(void);
00532 gpointer compat_page_align(size_t size);
00533 void compat_page_free(gpointer p, size_t size);
00534 gboolean compat_is_superuser(void);
00535 
00536 typedef void (*signal_handler_t)(gint signo);
00537 signal_handler_t set_signal(gint signo, signal_handler_t handler);
00538 
00539 gchar *ascii_strcasestr(const gchar *haystack, const gchar *needle);
00540 
00541 #define NULL_STRING(s) (NULL != (s) ? (s) : "(null)")
00542 #define EMPTY_STRING(s) (NULL != (s) ? (s) : "")
00543 
00551 static inline G_GNUC_CONST guint32
00552 swap_guint32(guint32 i)
00553 {
00554     gint a = i & 0x000000ff;
00555     gint b = (i & 0x0000ff00) >> 8;
00556     gint c = (i & 0x00ff0000) >> 16;
00557     gint d = (i & 0xff000000) >> 24;
00558 
00559     return d + (c << 8) + (b << 16) + (a << 24);
00560 }
00561 
00570 static inline G_GNUC_CONST WARN_UNUSED_RESULT guint8
00571 netmask_to_cidr(guint32 netmask)
00572 #ifdef HAVE_BUILTIN_POPCOUNT
00573 {
00574     __builtin_popcount(netmask);
00575 }
00576 #else   /* HAVE_BUILTIN_POPCOUNT */
00577 {
00578     guint8 bits = 32;
00579 
00580     while (0 == (netmask & 0x1)) {
00581         netmask >>= 1;
00582         bits--;
00583     }
00584     return bits;
00585 }
00586 #endif /* HAVE_BUILTIN_POPCOUNT */
00587 
00591 static inline size_t
00592 round_size(size_t align, size_t n)
00593 {
00594     size_t m = n % align;
00595     return m ? n + (align - m) : MAX(n, align);
00596 }
00597 
00598 /*
00599  * Syscall wrappers for errno == 0 bug. --RAM, 27/10/2003
00600  */
00601 
00602 struct stat;
00603 
00604 extern gint do_errno;
00605 
00606 gint do_stat(const gchar *path, struct stat *buf);
00607 
00608 /*
00609  * CIDR split of IP range.
00610  */
00611 
00612 typedef void (*cidr_split_t)(guint32 ip, guint bits, gpointer udata);
00613 
00614 void ip_range_split(
00615     guint32 lower_ip, guint32 upper_ip, cidr_split_t cb, gpointer udata);
00616 
00630 #define BINARY_SEARCH(bs_type, bs_key, bs_size, bs_cmp, bs_get_key, bs_found) \
00631 G_STMT_START { \
00632     size_t bs_index, bs_j = 0, bs_k; \
00633     for (bs_k = (bs_size); bs_k != 0; bs_k >>= 1) { \
00634         bs_type bs_item; \
00635         gint bs_cmp_result; \
00636 \
00637         bs_index = bs_j + (bs_k >> 1); \
00638         bs_item = bs_get_key(bs_index); \
00639         bs_cmp_result = bs_cmp(bs_item, bs_key); \
00640         if (0 == bs_cmp_result) {   \
00641             bs_found(bs_index); \
00642             break; \
00643         } else if (bs_cmp_result < 0) { \
00644             bs_j = bs_index + 1; \
00645             bs_k--; \
00646         } \
00647     } \
00648 } G_STMT_END
00649 
00662 #define BINARY_ARRAY_SORTED(bs_array, bs_type, bs_field, bs_cmp, bs_field2str) \
00663 G_STMT_START { \
00664     size_t bs_index; \
00665     size_t bs_size = G_N_ELEMENTS(bs_array); \
00666 \
00667     for (bs_index = 1; bs_index < bs_size; bs_index++) { \
00668         const bs_type *prev = &bs_array[bs_index - 1]; \
00669         const bs_type *e = &bs_array[bs_index]; \
00670 \
00671         if (bs_cmp(prev->bs_field, e->bs_field) >= 0) \
00672             g_error(STRINGIFY(bs_array) "[] unsorted (near item \"%s\")", \
00673                 bs_field2str(e->bs_field)); \
00674     } \
00675 } G_STMT_END
00676 
00677 #endif /* _misc_h_ */
00678 
00679 /* vi: set ts=4 sw=4 cindent: */

Generated on Sun Feb 12 10:49:56 2006 for Gtk-Gnutella by doxygen 1.3.6