source: trunk/libtransmission/utils.h @ 7581

Last change on this file since 7581 was 7581, checked in by charles, 12 years ago

(trunk libT) make the tr_bandwidth macros into safer inline funcs. inline utils' one-liners.

  • Property svn:keywords set to Date Rev Author Id
File size: 12.4 KB
Line 
1/******************************************************************************
2 * $Id: utils.h 7581 2009-01-02 20:12:23Z charles $
3 *
4 * Copyright (c) 2005-2008 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#ifndef TR_UTILS_H
26#define TR_UTILS_H 1
27
28#include <inttypes.h>
29#include <stdarg.h>
30#include <stddef.h> /* size_t */
31#include <stdio.h> /* FILE* */
32#include <string.h> /* memcpy()* */
33#include <stdlib.h> /* malloc() */
34#include <time.h> /* time_t* */
35
36#include "transmission.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/***
43****
44***/
45
46#ifndef FALSE
47 #define FALSE 0
48#endif
49
50#ifndef TRUE
51 #define TRUE 1
52#endif
53
54#ifndef UNUSED
55 #ifdef __GNUC__
56  #define UNUSED __attribute__ ( ( unused ) )
57 #else
58  #define UNUSED
59 #endif
60#endif
61
62#ifndef TR_GNUC_PRINTF
63 #ifdef __GNUC__
64  #define TR_GNUC_PRINTF( fmt,\
65                          args ) __attribute__ ( ( format ( printf, fmt,\
66                                                            args ) ) )
67 #else
68  #define TR_GNUC_PRINTF( fmt, args )
69 #endif
70#endif
71
72#ifndef TR_GNUC_NULL_TERMINATED
73 #if __GNUC__ >= 4
74  #define TR_GNUC_NULL_TERMINATED __attribute__ ( ( __sentinel__ ) )
75 #else
76  #define TR_GNUC_NULL_TERMINATED
77 #endif
78#endif
79
80#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 96 )
81 #define TR_GNUC_PURE __attribute__ ( ( __pure__ ) )
82 #define TR_GNUC_MALLOC __attribute__ ( ( __malloc__ ) )
83#else
84 #define TR_GNUC_PURE
85 #define TR_GNUC_MALLOC
86#endif
87
88
89/***
90****
91***/
92
93#if !defined( _ )
94 #if defined( SYS_DARWIN )
95  #define _( a ) ( a )
96 #elif defined( HAVE_LIBINTL_H )
97  #include <libintl.h>
98  #define _( a ) gettext ( a )
99 #else
100  #define _( a ) ( a )
101 #endif
102#endif
103
104/* #define DISABLE_GETTEXT */
105#if defined(TR_EMBEDDED) && !defined(DISABLE_GETTEXT)
106 #define DISABLE_GETTEXT
107#endif
108#ifdef DISABLE_GETTEXT
109 const char * tr_strip_positional_args( const char * fmt );
110 #undef _
111 #define _( a ) tr_strip_positional_args( a )
112#endif
113
114/****
115*****
116****/
117
118int            tr_msgLoggingIsActive( int level );
119
120void           tr_msg( const char * file,
121                       int          line,
122                       int          level,
123                       const char * torrent,
124                       const char * fmt,
125                       ... ) TR_GNUC_PRINTF( 5, 6 );
126
127#define tr_nerr( n, ... ) \
128    do { \
129        if( tr_msgLoggingIsActive( TR_MSG_ERR ) ) \
130            tr_msg( __FILE__, __LINE__, TR_MSG_ERR, n, __VA_ARGS__ ); \
131    } while( 0 )
132
133#define tr_ninf( n, ... ) \
134    do { \
135        if( tr_msgLoggingIsActive( TR_MSG_INF) ) \
136            tr_msg( __FILE__, __LINE__, TR_MSG_INF, n, __VA_ARGS__ ); \
137    } while( 0 )
138
139#define tr_ndbg( n, ... ) \
140    do { \
141        if( tr_msgLoggingIsActive( TR_MSG_DBG) ) \
142            tr_msg( __FILE__, __LINE__, TR_MSG_DBG, n, __VA_ARGS__ ); \
143    } while( 0 )
144
145#define tr_torerr( tor, ... ) \
146    do { \
147        if( tr_msgLoggingIsActive( TR_MSG_ERR ) ) \
148            tr_msg( __FILE__, __LINE__, TR_MSG_ERR, tor->info.name, __VA_ARGS__ ); \
149    } while( 0 )
150
151#define tr_torinf( tor, ... ) \
152    do { \
153        if( tr_msgLoggingIsActive( TR_MSG_INF ) ) \
154            tr_msg( __FILE__, __LINE__, TR_MSG_INF, tor->info.name, __VA_ARGS__ ); \
155    } while( 0 )
156
157#define tr_tordbg( tor, ... ) \
158    do { \
159        if( tr_msgLoggingIsActive( TR_MSG_DBG ) ) \
160            tr_msg( __FILE__, __LINE__, TR_MSG_DBG, tor->info.name, __VA_ARGS__ ); \
161    } while( 0 )
162
163#define tr_err( ... ) \
164    do { \
165        if( tr_msgLoggingIsActive( TR_MSG_ERR ) ) \
166            tr_msg( __FILE__, __LINE__, TR_MSG_ERR, NULL, __VA_ARGS__ ); \
167    } while( 0 )
168
169#define tr_inf( ... ) \
170    do { \
171        if( tr_msgLoggingIsActive( TR_MSG_INF ) ) \
172            tr_msg( __FILE__, __LINE__, TR_MSG_INF, NULL, __VA_ARGS__ ); \
173    } while( 0 )
174
175#define tr_dbg( ... ) \
176    do { \
177        if( tr_msgLoggingIsActive( TR_MSG_DBG ) ) \
178            tr_msg( __FILE__, __LINE__, TR_MSG_DBG, NULL, __VA_ARGS__ ); \
179    } while( 0 )
180
181
182
183FILE*          tr_getLog( void );
184
185int            tr_deepLoggingIsActive( void );
186
187void           tr_deepLog( const char * file,
188                           int          line,
189                           const char * name,
190                           const char * fmt,
191                           ... ) TR_GNUC_PRINTF( 4, 5 );
192
193char*          tr_getLogTimeStr( char * buf,
194                                 int    buflen );
195
196
197int            tr_wildmat( const char * text,
198                           const char * pattern );
199
200/** a portability wrapper for basename(). */
201char*          tr_basename( const char * path ) TR_GNUC_MALLOC;
202
203/** a portability wrapper for dirname(). */
204char*          tr_dirname( const char * path ) TR_GNUC_MALLOC;
205
206/**
207 * a portability wrapper around mkdir().
208 * On WIN32, the `permissions' argument is unused.
209 *
210 * @return zero on success, or -1 if an error occurred
211 * (in which case errno is set appropriately).
212 */
213int            tr_mkdir( const char * path,
214                         int          permissions );
215
216/**
217 * Like mkdir, but makes parent directories as needed.
218 *
219 * @return zero on success, or -1 if an error occurred
220 * (in which case errno is set appropriately).
221 */
222int            tr_mkdirp( const char * path,
223                          int          permissions );
224
225
226/**
227 * Loads a file and returns its contents.
228 * On failure, NULL is returned and errno is set.
229 */
230uint8_t*       tr_loadFile( const char * filename,
231                            size_t *     size ) TR_GNUC_MALLOC;
232
233
234/* creates a filename from a series of elements using the
235   correct separator for filenames. */
236char*          tr_buildPath( const char * first_element, ... )
237                                              TR_GNUC_NULL_TERMINATED
238                                              TR_GNUC_MALLOC;
239
240struct timeval;
241
242void tr_timevalMsec( uint64_t           milliseconds,
243                     struct timeval   * setme );
244
245
246/* return the current date in milliseconds */
247uint64_t       tr_date( void );
248
249/* wait the specified number of milliseconds */
250void           tr_wait( uint64_t delay_milliseconds );
251
252/***
253****
254***/
255
256struct evbuffer;
257
258/** @brief pool of reusable buffers
259    @see tr_releaseBuffer() */
260struct evbuffer * tr_getBuffer( void );
261
262/** @brief return a buffer to the pool
263    @see tr_getBuffer() */
264void tr_releaseBuffer( struct evbuffer * buf );
265
266
267/***
268****
269***/
270
271/* Sometimes the system defines MAX/MIN, sometimes not. In the latter
272   case, define those here since we will use them */
273#ifndef MAX
274 #define MAX( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) )
275#endif
276#ifndef MIN
277 #define MIN( a, b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
278#endif
279
280/***
281****
282***/
283
284static inline void* tr_malloc( size_t size )
285{
286    return size ? malloc( size ) : NULL;
287}
288static inline void* tr_malloc0( size_t size )
289{
290    return size ? calloc( 1, size ) : NULL;
291}
292static inline void tr_free( void * p )
293{
294    if( p != NULL )
295        free( p );
296}
297static inline void* tr_memdup( const void * src, int byteCount )
298{
299    return memcpy( tr_malloc( byteCount ), src, byteCount );
300}
301
302#define tr_new( struct_type, n_structs )           \
303    ( (struct_type *) tr_malloc ( ( (size_t) sizeof ( struct_type ) ) * ( ( size_t) ( n_structs ) ) ) )
304
305#define tr_new0( struct_type, n_structs )          \
306    ( (struct_type *) tr_malloc0 ( ( (size_t) sizeof ( struct_type ) ) * ( ( size_t) ( n_structs ) ) ) )
307
308#define tr_renew( struct_type, mem, n_structs )    \
309    ( (struct_type *) realloc ( ( mem ), ( (size_t) sizeof ( struct_type ) ) * ( ( size_t) ( n_structs ) ) ) )
310
311char*       tr_strndup( const void * str, int len ) TR_GNUC_MALLOC;
312
313static inline char* tr_strdup( const void * in )
314{
315    return tr_strndup( in, in ? strlen( (const char*)in ) : 0 );
316}
317
318char*       tr_strdup_printf( const char * fmt,
319                              ... )  TR_GNUC_PRINTF( 1, 2 ) TR_GNUC_MALLOC;
320
321char*       tr_base64_encode( const void * input,
322                              int          inlen,
323                              int *        outlen ) TR_GNUC_MALLOC;
324
325char*       tr_base64_decode( const void * input,
326                              int          inlen,
327                              int *        outlen ) TR_GNUC_MALLOC;
328
329size_t      tr_strlcpy( char *       dst,
330                        const void * src,
331                        size_t       siz );
332
333int         tr_snprintf( char *       buf,
334                         size_t       buflen,
335                         const char * fmt,
336                         ... ) TR_GNUC_PRINTF( 3, 4 );
337
338const char* tr_strerror( int );
339
340char*       tr_strstrip( char * str );
341
342/***
343****
344***/
345
346typedef void ( tr_set_func )( void * element, void * userData );
347
348void        tr_set_compare( const void * a,
349                            size_t aCount,
350                            const void * b,
351                            size_t bCount,
352                            int compare( const void * a, const void * b ),
353                            size_t elementSize,
354                            tr_set_func in_a_cb,
355                            tr_set_func in_b_cb,
356                            tr_set_func in_both_cb,
357                            void * userData );
358
359void tr_sha1_to_hex( char *          out,
360                     const uint8_t * sha1 );
361
362
363int  tr_httpIsValidURL( const char * url );
364
365int  tr_httpParseURL( const char * url,
366                      int          url_len,
367                      char **      setme_host,
368                      int *        setme_port,
369                      char **      setme_path );
370
371
372/***
373****
374***/
375
376typedef struct tr_bitfield
377{
378    uint8_t *  bits;
379    size_t     bitCount;
380    size_t     byteCount;
381}
382tr_bitfield;
383
384tr_bitfield* tr_bitfieldConstruct( tr_bitfield*, size_t bitcount );
385
386tr_bitfield* tr_bitfieldDestruct( tr_bitfield* );
387
388static inline tr_bitfield* tr_bitfieldNew( size_t bitcount )
389{
390    return tr_bitfieldConstruct( tr_new0( tr_bitfield, 1 ), bitcount );
391}
392
393static inline void tr_bitfieldFree( tr_bitfield * b )
394{
395    tr_free( tr_bitfieldDestruct( b ) );
396}
397
398tr_bitfield* tr_bitfieldDup( const tr_bitfield* ) TR_GNUC_MALLOC;
399
400void         tr_bitfieldClear( tr_bitfield* );
401
402int          tr_bitfieldAdd( tr_bitfield*, size_t bit );
403
404int          tr_bitfieldRem( tr_bitfield*, size_t bit );
405
406int          tr_bitfieldAddRange( tr_bitfield *, size_t begin, size_t end );
407
408int          tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );
409
410void         tr_bitfieldDifference( tr_bitfield *, const tr_bitfield * );
411
412int          tr_bitfieldIsEmpty( const tr_bitfield* );
413
414size_t       tr_bitfieldCountTrueBits( const tr_bitfield* );
415
416tr_bitfield* tr_bitfieldOr( tr_bitfield*, const tr_bitfield* );
417
418/** A stripped-down version of bitfieldHas to be used
419    for speed when you're looping quickly.  This version
420    has none of tr_bitfieldHas()'s safety checks, so you
421    need to call tr_bitfieldTestFast() first before you
422    start looping. */
423static inline tr_bool tr_bitfieldHasFast( const tr_bitfield * b, const size_t nth )
424{
425    return ( b->bits[nth>>3u] << ( nth & 7u ) & 0x80 ) != 0;
426}
427
428/** @param high the highest nth bit you're going to access */
429static inline tr_bool tr_bitfieldTestFast( const tr_bitfield * b, const size_t high )
430{
431    return ( b != NULL )
432        && ( b->bits != NULL )
433        && ( high < b->bitCount );
434}
435
436static inline tr_bool tr_bitfieldHas( const tr_bitfield * b, size_t nth )
437{
438    return tr_bitfieldTestFast( b, nth ) && tr_bitfieldHasFast( b, nth );
439}
440
441double tr_getRatio( double numerator, double denominator );
442
443
444int tr_ptr2int( void* );
445
446void* tr_int2ptr( int );
447
448#ifdef __cplusplus
449}
450#endif
451
452#endif
Note: See TracBrowser for help on using the repository browser.