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

lib/misc.h

Go to the documentation of this file.
00001 /*
00002  * $Id: misc.h 13970 2007-06-24 20:17:48Z cbiere $
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 "common.h"
00054 
00055 #include "vmm.h"
00056 
00057 #define SIZE_FIELD_MAX 64       
00058 #define GUID_RAW_SIZE       16  
00059 #define GUID_HEX_SIZE       32  
00060 #define GUID_BASE32_SIZE    26  
00062 typedef struct short_string {
00063     gchar str[SIZE_FIELD_MAX];
00064 } short_string_t;
00065 
00069 #ifndef USE_GLIB2
00070 
00071 #ifndef HAS_STRLCPY
00072 size_t strlcpy(gchar *dst, const gchar *src, size_t dst_size);
00073 #endif /* HAS_STRLCPY */
00074 
00075 #ifndef HAS_STRLCAT
00076 size_t strlcat(gchar *dst, const gchar *src, size_t dst_size);
00077 #endif /* HAS_STRLCAT */
00078 
00079 #define g_string_printf g_string_sprintf
00080 #define g_strlcpy strlcpy
00081 #define g_strlcat strlcat
00082 #endif
00083 
00084 size_t concat_strings(gchar *dst, size_t size,
00085     const gchar *s, ...) G_GNUC_NULL_TERMINATED;
00086 size_t w_concat_strings(gchar **dst,
00087     const gchar *first, ...) G_GNUC_NULL_TERMINATED;
00088 
00089 gint ascii_strcasecmp(const gchar *s1, const gchar *s2);
00090 gint ascii_strncasecmp(const gchar *s1, const gchar *s2, size_t len);
00091 
00099 static inline guchar
00100 hex_digit(guchar x)
00101 {
00102     extern const char hex_alphabet_lower[];
00103     return hex_alphabet_lower[x & 0xf]; 
00104 }
00105 
00112 static inline gint
00113 hex2int_inline(guchar c)
00114 {
00115     extern const gint8 *hex2int_tab;
00116     return hex2int_tab[c];
00117 }
00118 
00125 static inline gint
00126 dec2int_inline(guchar c)
00127 {
00128     extern const gint8 *dec2int_tab;
00129     return dec2int_tab[c];
00130 }
00131 
00138 static inline gint
00139 alnum2int_inline(guchar c)
00140 {
00141     extern const gint8 *alnum2int_tab;
00142     return alnum2int_tab[c];
00143 }
00144 
00153 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00154 is_ascii_blank(gint c)
00155 {
00156     return c == 32 || c == 9;   /* space, tab */
00157 }
00158 
00159 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00160 is_ascii_cntrl(gint c)
00161 {
00162     return (c >= 0 && c <= 31) || c == 127;
00163 }
00164 
00165 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00166 is_ascii_digit(gint c)
00167 {
00168     return c >= 48 && c <= 57;  /* 0-9 */
00169 }
00170 
00171 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00172 is_ascii_xdigit(gint c)
00173 {
00174     return -1 != hex2int_inline(c) && !(c & ~0x7f);
00175 }
00176 
00177 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00178 is_ascii_upper(gint c)
00179 {
00180     return c >= 65 && c <= 90;      /* A-Z */
00181 }
00182 
00183 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00184 is_ascii_lower(gint c)
00185 {
00186     return c >= 97 && c <= 122;     /* a-z */
00187 }
00188 
00189 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00190 is_ascii_alpha(gint c)
00191 {
00192     return is_ascii_upper(c) || is_ascii_lower(c);  /* A-Z, a-z */
00193 }
00194 
00195 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00196 is_ascii_alnum(gint c)
00197 {
00198     return -1 != alnum2int_inline(c) && !(c & ~0x7f); /* A-Z, a-z, 0-9 */
00199 }
00200 
00201 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00202 is_ascii_space(gint c)
00203 {
00204     return c == 32 || (c >= 9 && c <= 13);
00205 }
00206 
00207 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00208 is_ascii_graph(gint c)
00209 {
00210     return c >= 33 && c <= 126;
00211 }
00212 
00213 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00214 is_ascii_print(gint c)
00215 {
00216     return is_ascii_graph(c) || c == 32;
00217 }
00218 
00219 static inline G_GNUC_CONST WARN_UNUSED_RESULT gboolean
00220 is_ascii_punct(gint c)
00221 {
00222     return c >= 33 && c <= 126 && !is_ascii_alnum(c);
00223 }
00224 
00225 static inline G_GNUC_CONST WARN_UNUSED_RESULT gint
00226 ascii_toupper(gint c)
00227 {
00228     return is_ascii_lower(c) ? c - 32 : c;
00229 }
00230 
00231 static inline G_GNUC_CONST WARN_UNUSED_RESULT gint
00232 ascii_tolower(gint c)
00233 {
00234     return is_ascii_upper(c) ? c + 32 : c;
00235 }
00236 
00237 #if !GLIB_CHECK_VERSION(2,4,0)
00238 static inline WARN_UNUSED_RESULT const gchar *
00239 g_strip_context(const gchar *id, const gchar *val)
00240 {
00241     const gchar *s;
00242 
00243     s = id != val ? NULL : strchr(id, '|');
00244     return s ? ++s : val;
00245 }
00246 #endif /* GLib < 2.4.0 */
00247 
00253 static inline WARN_UNUSED_RESULT gchar *
00254 skip_ascii_spaces(const gchar *s)
00255 {
00256     while (is_ascii_space(*s))
00257         s++;
00258 
00259     return deconstify_gchar(s);
00260 }
00261 
00267 static inline WARN_UNUSED_RESULT gchar *
00268 skip_ascii_non_spaces(const gchar *s)
00269 {
00270     while ('\0' != *s && !is_ascii_space(*s))
00271         s++;
00272 
00273     return deconstify_gchar(s);
00274 }
00275 
00282 static inline WARN_UNUSED_RESULT gchar *
00283 skip_ascii_alnum(const gchar *s)
00284 {
00285     while (is_ascii_alnum(*s))
00286         s++;
00287 
00288     return deconstify_gchar(s);
00289 }
00290 
00296 static inline WARN_UNUSED_RESULT gchar *
00297 skip_ascii_blanks(const gchar *s)
00298 {
00299     while (is_ascii_blank(*s))
00300         s++;
00301 
00302     return deconstify_gchar(s);
00303 }
00304 
00305 static inline WARN_UNUSED_RESULT gchar *
00306 skip_dir_separators(const gchar *s)
00307 {
00308     while ('/' == s[0] || G_DIR_SEPARATOR == s[0])
00309         s++;
00310 
00311     return deconstify_gchar(s);
00312 }
00313 
00314 /*
00315  * Determine the length of string literals
00316  */
00317 #define CONST_STRLEN(x) (sizeof(x) - 1)
00318 
00319 /*
00320  * Set/clear binary flags
00321  */
00322 typedef guint16 flag_t;
00323 #define set_flags(r,f) (r |= (f))
00324 #define clear_flags(r,f) (r &= ~(f))
00325 
00326 /*
00327  * Macros to determine the maximum buffer size required to hold a
00328  * NUL-terminated string.
00329  */
00330 #define UINT8_HEX_BUFLEN    (sizeof "FF")
00331 #define UINT8_DEC_BUFLEN    (sizeof "255")
00332 #define UINT16_HEX_BUFLEN   (sizeof "01234")
00333 #define UINT16_DEC_BUFLEN   (sizeof "65535")
00334 #define UINT32_HEX_BUFLEN   (sizeof "012345678")
00335 #define UINT32_DEC_BUFLEN   (sizeof "4294967295")
00336 #define UINT64_HEX_BUFLEN   (sizeof "0123456789ABCDEF")
00337 #define UINT64_DEC_BUFLEN   (sizeof "18446744073709551615")
00338 #define IPV4_ADDR_BUFLEN    (sizeof "255.255.255.255")
00339 #define IPV6_ADDR_BUFLEN \
00340       (sizeof "0001:0203:0405:0607:0809:1011:255.255.255.255")
00341 #define TIMESTAMP_BUF_LEN   (sizeof "9999-12-31 23:59:61")
00342 #define OFF_T_DEC_BUFLEN    (sizeof(off_t) * CHAR_BIT) /* very roughly */
00343 #define TIME_T_DEC_BUFLEN   (sizeof(time_t) * CHAR_BIT) /* very roughly */
00344 
00345 #define HOST_ADDR_BUFLEN    (MAX(IPV4_ADDR_BUFLEN, IPV6_ADDR_BUFLEN))
00346 #define HOST_ADDR_PORT_BUFLEN   (HOST_ADDR_BUFLEN + sizeof ":[65535]")
00347 
00348 gboolean parse_ipv6_addr(const gchar *s, uint8_t *dst, const gchar **endptr);
00349 const gchar *ipv6_to_string(const guint8 *ipv6);
00350 size_t ipv6_to_string_buf(const guint8 *ipv6, gchar *dst, size_t size);
00351 
00352 /*
00353  * Network related string routines
00354  */
00355 guint32  string_to_ip(const gchar *);
00356 gboolean string_to_ip_strict(const gchar *s, guint32 *addr, const gchar **ep);
00357 gboolean string_to_ip_and_mask(const gchar *str, guint32 *ip, guint32 *netmask);
00358 gboolean string_to_ip_port(const gchar *str, guint32 *ip, guint16 *port);
00359 const gchar *ip_to_string(guint32);
00360 size_t ipv4_to_string_buf(guint32 ip, gchar *buf, size_t size);
00361 const gchar *hostname_port_to_string(const gchar *hostname, guint16 port);
00362 const gchar *local_hostname(void);
00363 #define port_is_valid(port) (port != 0)
00364 
00365 /*
00366  * Date string conversions
00367  */
00368 const gchar *timestamp_to_string(time_t date);
00369 const gchar *timestamp_utc_to_string(time_t date);
00370 const gchar *timestamp_rfc822_to_string(time_t date);
00371 const gchar *timestamp_rfc822_to_string2(time_t date);
00372 const gchar *timestamp_rfc1123_to_string(time_t date);
00373 
00374 size_t timestamp_to_string_buf(time_t date, gchar *dst, size_t size);
00375 size_t time_locale_to_string_buf(time_t date, gchar *dst, size_t size);
00376 
00377 short_string_t timestamp_get_string(time_t date);
00378 
00379 /*
00380  * We use the direct difference of time_t values instead of difftime()
00381  * for performance. Just in case there is any system which requires difftime()
00382  * e.g. if time_t is BCD-encoded, define USE_DIFFTIME.
00383  */
00384 #if defined(USE_DIFFTIME)
00385 typedef gint64 time_delta_t;
00386 
00387 static inline time_delta_t
00388 delta_time(time_t t1, time_t t0)
00389 {
00390     return difftime(t1, t0);
00391 }
00392 #else   /* !USE_DIFFTIME */
00393 typedef time_t time_delta_t;
00394 
00395 static inline time_delta_t
00396 delta_time(time_t t1, time_t t0)
00397 {
00398     return t1 - t0;
00399 }
00400 
00401 static inline void
00402 time_t_check(void)
00403 {
00404     /* If time_t is not a signed integer type, we cannot calculate properly
00405      * with the raw values. Define USE_DIFFTIME, if this check fails.*/
00406     STATIC_ASSERT((time_t) -1 < 0);
00407 }
00408 #endif /* USE_DIFFTIME*/
00409 
00416 static inline time_t
00417 time_advance(time_t t, gulong delta)
00418 {
00419     /* Using time_t for delta and TIME_T_MAX instead of INT_MAX
00420      * would be cleaner but give a confusing interface. Jumping 136
00421      * years in time should be enough for everyone. Most systems
00422      * don't allow us to advance a time_t beyond 2038 anyway.
00423      */
00424 
00425     do {
00426         glong d;
00427 
00428         d = MIN(delta, (gulong) LONG_MAX);
00429         if (d >= TIME_T_MAX - t) {
00430             t = TIME_T_MAX;
00431             break;
00432         }
00433         t += d;
00434         delta -= d;
00435     } while (delta > 0);
00436 
00437     return t;
00438 }
00439 
00440 /*
00441  * Time string conversions
00442  */
00443 const gchar *short_time(time_delta_t s);
00444 const gchar *short_time_ascii(time_delta_t t);
00445 const gchar *short_uptime(time_delta_t s);
00446 const gchar *compact_time(time_delta_t t);
00447 
00448 /*
00449  * Size string conversions
00450  */
00451 const gchar *short_size(guint64 size, gboolean metric);
00452 const gchar *short_html_size(guint64 size, gboolean metric);
00453 const gchar *short_kb_size(guint64 size, gboolean metric);
00454 const gchar *short_rate(guint64 rate, gboolean metric);
00455 const gchar *compact_size(guint64 size, gboolean metric);
00456 const gchar *compact_rate(guint64 rate, gboolean metric);
00457 const gchar *compact_kb_size(guint32 size, gboolean metric);
00458 gchar *short_value(gchar *buf, size_t size, guint64 v, gboolean metric);
00459 gchar *compact_value(gchar *buf, size_t size, guint64 v, gboolean metric);
00460 
00461 short_string_t short_rate_get_string(guint64 rate, gboolean metric);
00462 
00463 /*
00464  * SHA1<->base32 string conversion
00465  */
00466 typedef struct sha1 {
00467     gchar data[SHA1_RAW_SIZE];
00468 } sha1_t;
00469 
00470 const gchar *sha1_to_string(const struct sha1 sha1);
00471 const gchar *sha1_to_urn_string(const struct sha1 *sha1);
00472 gchar *sha1_to_base32_buf(const struct sha1 *sha1, gchar *dst, size_t size);
00473 const gchar *sha1_base32(const struct sha1 *sha1);
00474 const struct sha1 *base32_sha1(const gchar *base32);
00475 
00476 static inline int
00477 sha1_cmp(const struct sha1 *a, const struct sha1 *b)
00478 {
00479     return memcmp(a, b, SHA1_RAW_SIZE);
00480 }
00481 
00482 /*
00483  * TTH <-> base32 string conversion
00484  */
00485 typedef struct tth {
00486     gchar data[TTH_RAW_SIZE];
00487 } tth_t;
00488 
00489 const gchar *tth_base32(const struct tth *tth);
00490 const struct tth *base32_tth(const gchar *base32);
00491 
00492 
00493 const gchar *bitprint_to_urn_string(const struct sha1 *, const struct tth *);
00494 
00495 /*
00496  * GUID<->hex string conversion
00497  */
00498 const gchar *guid_hex_str(const gchar *guid);
00499 gboolean hex_to_guid(const gchar *hexguid, gchar *guid);
00500 size_t guid_to_string_buf(const gchar *guid, gchar *dst, size_t size);
00501 const gchar *guid_to_string(const gchar *guid);
00502 
00503 /*
00504  * GUID<->base32 string conversion
00505  */
00506 gchar *guid_base32_str(const gchar *guid);
00507 gchar *base32_to_guid(const gchar *base32);
00508 
00509 /*
00510  * Tests
00511  */
00512 gboolean is_absolute_path(const char *pathname);
00513 gboolean is_directory(const gchar *pathname);
00514 gboolean is_regular(const gchar *pathname);
00515 gboolean is_symlink(const gchar *pathname);
00516 gboolean file_exists(const gchar *pathname);
00517 gboolean file_does_not_exist(const gchar *pathname);
00518 guint32 next_pow2(guint32 n);
00519 
00520 #define IS_POWER_OF_2(x) ((x) && 0 == ((x) & ((x) - 1)))
00521 
00527 static inline G_GNUC_CONST gboolean
00528 is_pow2(guint32 value)
00529 #ifdef HAS_BUILTIN_POPCOUNT
00530 {
00531     return 1 == __builtin_popcount(value);
00532 }
00533 #else /* !HAS_BUILTIN_POPCOUNT */
00534 {
00535     return IS_POWER_OF_2(value);
00536 }
00537 #endif /* HAS_BUILTIN_POPCOUNT */
00538 
00539 /*
00540  * Random numbers
00541  */
00542 void random_init(void);
00543 guint32 random_value(guint32 max) WARN_UNUSED_RESULT;
00544 guint32 random_raw(void) WARN_UNUSED_RESULT;
00545 void guid_random_fill(gchar *xuid);
00546 
00547 /*
00548  * Stuff
00549  */
00550 void misc_init(void);
00551 size_t str_chomp(gchar *str, size_t len);
00552 gint hex2int(guchar c);
00553 gboolean is_printable(const gchar *buf, gint len);
00554 void dump_hex(FILE *, const gchar *, gconstpointer, gint);
00555 void locale_strlower(gchar *, const gchar *);
00556 void ascii_strlower(gchar *dst, const gchar *src);
00557 gint strcmp_delimit(const gchar *a, const gchar *b, const gchar *delimit);
00558 gint ascii_strcasecmp_delimit(const gchar *a, const gchar *b,
00559         const gchar *delimit);
00560 size_t filename_shrink(const gchar *filename, gchar *buf, size_t size);
00561 char *unique_filename(const gchar *path, const gchar *file, const gchar *ext,
00562         gboolean (*name_is_uniq)(const gchar *pathname));
00563 gchar *hex_escape(const gchar *name, gboolean strict);
00564 gchar *control_escape(const gchar *s);
00565 const gchar *lazy_string_to_printf_escape(const gchar *src);
00566 gint highest_bit_set(guint32 n) G_GNUC_CONST;
00567 gfloat force_range(gfloat value, gfloat min, gfloat max);
00568 gchar *absolute_pathname(const gchar *file);
00569 gchar *make_pathname(const gchar *dir, const gchar *file);
00570 gchar *short_filename(gchar *fullname);
00571 gchar *data_hex_str(const gchar *data, size_t len);
00572 
00573 #if defined(S_IROTH) && defined(S_IXOTH)
00574 /* 0755 */
00575 #define DEFAULT_DIRECTORY_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
00576 #else
00577 /* 0750 */
00578 #define DEFAULT_DIRECTORY_MODE (S_IRWXU | S_IRGRP | S_IXGRP)
00579 #endif /* S_IROTH && S_IXOTH */
00580 
00581 gint create_directory(const gchar *dir, mode_t mode);
00582 gint compat_mkdir(const gchar *path, mode_t mode);
00583 gboolean filepath_exists(const gchar *dir, const gchar *file);
00584 const gchar * filepath_basename(const gchar *pathname);
00585 gchar * filepath_directory(const gchar *pathname);
00586 guint16 parse_uint16(const gchar *, gchar const **, guint, gint *)
00587     NON_NULL_PARAM((1, 4));
00588 guint32 parse_uint32(const gchar *, gchar const **, guint, gint *)
00589     NON_NULL_PARAM((1, 4));
00590 guint64 parse_uint64(const gchar *, gchar const **, guint, gint *)
00591     NON_NULL_PARAM((1, 4));
00592 size_t uint32_to_string_buf(guint32 v, gchar *dst, size_t size);
00593 size_t uint64_to_string_buf(guint64 v, gchar *dst, size_t size);
00594 size_t off_t_to_string_buf(off_t v, gchar *dst, size_t size);
00595 size_t time_t_to_string_buf(time_t v, gchar *dst, size_t size);
00596 const gchar *uint32_to_string(guint32 v);
00597 const gchar *uint64_to_string(guint64 v);
00598 const gchar *uint64_to_string2(guint64 v);
00599 const gchar *off_t_to_string(off_t v);
00600 const gchar *time_t_to_string(time_t v);
00601 const gchar *filesize_to_string(filesize_t v);
00602 gint parse_major_minor(const gchar *src, gchar const **endptr,
00603     guint *major, guint *minor);
00604 gchar *is_strprefix(const gchar *s, const gchar *prefix) WARN_UNUSED_RESULT;
00605 gchar *is_strcaseprefix(const gchar *s, const gchar *prefix) WARN_UNUSED_RESULT;
00606 size_t html_escape(const gchar *src, gchar *dst, size_t dst_size);
00607 guint32 html_decode_entity(const gchar *src, const gchar **endptr);
00608 gint canonize_path(gchar *dst, const gchar *path);
00609 guint compat_max_fd(void);
00610 void close_file_descriptors(const int first_fd);
00611 gboolean compat_is_superuser(void);
00612 int compat_daemonize(const char *directory);
00613 void set_close_on_exec(gint fd);
00614 void compat_fadvise_sequential(int fd, off_t offset, off_t size);
00615 void *compat_memmem(const void *data, size_t data_size,
00616         const void *pattern, size_t pattern_size);
00617 
00618 int get_non_stdio_fd(int fd);
00619 
00620 typedef void (*signal_handler_t)(gint signo);
00621 signal_handler_t set_signal(gint signo, signal_handler_t handler);
00622 
00623 gchar *ascii_strcasestr(const gchar *haystack, const gchar *needle);
00624 gchar *normalize_dir_separators(const gchar *s);
00625 size_t memcmp_diff(const void *a, const void *b, size_t n);
00626 guint32 cpu_noise(void);
00627 
00628 static inline guint
00629 pointer_hash_func(const void *p)
00630 {
00631     size_t v = (size_t) p;
00632     return (((guint64) 0x4F1BBCDCUL * v) >> 32) ^ v;
00633 }
00634 
00635 static inline guint
00636 str_case_hash_func(gconstpointer key)
00637 {
00638     const guchar *s = key;
00639     gulong c, hash = 0;
00640     
00641     while ((c = ascii_tolower(*s++))) {
00642         hash ^= (hash << 8) | c;
00643     }
00644     return hash ^ (((guint64) 1048573 * hash) >> 32);
00645 }
00646 
00647 static inline gint
00648 str_case_eq_func(gconstpointer a, gconstpointer b)
00649 {
00650     return 0 == ascii_strcasecmp(a, b);
00651 }
00652 
00662 static inline size_t
00663 clamp_strlen(const gchar *src, size_t src_size)
00664 {
00665     const gchar *p;
00666     
00667     p = memchr(src, '\0', src_size);
00668     return (p ? p : &src[src_size]) - src;
00669 }
00670 
00671 static inline const gchar *
00672 NULL_STRING(const gchar *s)
00673 {
00674     return NULL != s ? s : "(null)";
00675 }
00676 
00677 static inline const gchar *
00678 EMPTY_STRING(const gchar *s)
00679 {
00680     return NULL != s ? s : "";
00681 }
00682 
00690 static inline G_GNUC_CONST guint32
00691 swap_guint32(guint32 i)
00692 {
00693     guint32 a;
00694     guint32 b;
00695                                   /* i -> ABCD */
00696     a = (i & 0x00ff00ff) << 8;    /* a -> B0D0 */
00697     b = (i & 0xff00ff00) >> 8;    /* b -> 0A0C */
00698     i = a | b;                    /* i -> BADC */
00699     i = (i << 16) | (i >> 16);    /* i -> DCBA */
00700     
00701     return i;
00702 }
00703 
00712 static inline G_GNUC_CONST WARN_UNUSED_RESULT guint8
00713 netmask_to_cidr(guint32 netmask)
00714 #ifdef HAVE_BUILTIN_POPCOUNT
00715 {
00716     __builtin_popcount(netmask);
00717 }
00718 #else   /* HAVE_BUILTIN_POPCOUNT */
00719 {
00720     guint8 bits = 32;
00721 
00722     while (0 == (netmask & 0x1)) {
00723         netmask >>= 1;
00724         bits--;
00725     }
00726     return bits;
00727 }
00728 #endif /* HAVE_BUILTIN_POPCOUNT */
00729 
00737 static inline G_GNUC_CONST WARN_UNUSED_RESULT guint32
00738 cidr_to_netmask(guint bits)
00739 {
00740     return (guint32)-1 << (32 - bits);
00741 }
00742 
00746 static inline size_t
00747 round_size(size_t align, size_t n)
00748 {
00749     size_t m = n % align;
00750     return m ? n + (align - m) : MAX(n, align);
00751 }
00752 
00753 /*
00754  * Syscall wrappers for errno == 0 bug. --RAM, 27/10/2003
00755  */
00756 
00757 struct stat;
00758 
00759 extern gint do_errno;
00760 
00761 gint do_stat(const gchar *path, struct stat *buf);
00762 
00763 static inline gboolean
00764 is_temporary_error(gint error)
00765 {
00766   switch (error) {
00767   case EAGAIN:
00768 #if defined(EWOULDBLOCK) && EAGAIN != EWOULDBLOCK
00769   case EWOULDBLOCK:
00770 #endif /* EWOULDBLOCK != EAGAIN */
00771   case EINTR:
00772     return TRUE;
00773   }
00774   return FALSE;
00775 }
00776 
00777 /* Wrapper around lseek() to handle filesize -> off_t conversion. */
00778 gint seek_to_filepos(gint fd, filesize_t pos);
00779 
00780 guint filesize_per_100(filesize_t size, filesize_t part);
00781 guint filesize_per_1000(filesize_t size, filesize_t part);
00782 guint filesize_per_10000(filesize_t size, filesize_t part);
00783 
00784 /*
00785  * CIDR split of IP range.
00786  */
00787 
00788 typedef void (*cidr_split_t)(guint32 ip, guint bits, gpointer udata);
00789 
00790 void ip_range_split(
00791     guint32 lower_ip, guint32 upper_ip, cidr_split_t cb, gpointer udata);
00792 
00806 #define BINARY_SEARCH(bs_type, bs_key, bs_size, bs_cmp, bs_get_key, bs_found) \
00807 G_STMT_START { \
00808     size_t bs_index, bs_j = 0, bs_k; \
00809     for (bs_k = (bs_size); bs_k != 0; bs_k >>= 1) { \
00810         bs_type bs_item; \
00811         gint bs_cmp_result; \
00812 \
00813         bs_index = bs_j + (bs_k >> 1); \
00814         bs_item = bs_get_key(bs_index); \
00815         bs_cmp_result = bs_cmp(bs_item, bs_key); \
00816         if (0 == bs_cmp_result) {   \
00817             bs_found(bs_index); \
00818             break; \
00819         } else if (bs_cmp_result < 0) { \
00820             bs_j = bs_index + 1; \
00821             bs_k--; \
00822         } \
00823     } \
00824 } G_STMT_END
00825 
00838 #define BINARY_ARRAY_SORTED(bs_array, bs_type, bs_field, bs_cmp, bs_field2str) \
00839 G_STMT_START { \
00840     size_t bs_index; \
00841     size_t bs_size = G_N_ELEMENTS(bs_array); \
00842 \
00843     for (bs_index = 1; bs_index < bs_size; bs_index++) { \
00844         const bs_type *prev = &bs_array[bs_index - 1]; \
00845         const bs_type *e = &bs_array[bs_index]; \
00846 \
00847         if (bs_cmp(prev->bs_field, e->bs_field) >= 0) \
00848             g_error(STRINGIFY(bs_array) "[] unsorted (near item \"%s\")", \
00849                 bs_field2str(e->bs_field)); \
00850     } \
00851 } G_STMT_END
00852 
00853 static inline const char *
00854 print_number(char *dst, size_t size, unsigned long value)
00855 {
00856     char *p = &dst[size];
00857 
00858     if (size > 0) {
00859         *--p = '\0';
00860     }
00861     while (p != dst) {
00862         *--p = (value % 10) + '0';
00863         value /= 10;
00864         if (0 == value)
00865             break;
00866     }
00867     return p;
00868 }
00869 
00870 #endif /* _misc_h_ */
00871 
00872 /* vi: set ts=4 sw=4 cindent: */

Generated on Sat Jun 30 17:53:23 2007 for gtk-gnutella by  doxygen 1.3.9.1