source: trunk/libtransmission/utils.h @ 7592

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

(trunk libT) add "deep log" message to help track down freeze reported by the|Navigator. also, small + cheap speedup in tr_deepLoggingIsActive()

  • Property svn:keywords set to Date Rev Author Id
File size: 12.4 KB
Line 
1/******************************************************************************
2 * $Id: utils.h 7592 2009-01-03 02:43:17Z 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
185tr_bool        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.