source: trunk/libtransmission/utils.h @ 7609

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

(trunk libT) new peer request fifo queue with log(N) search time. new unit tests for the queue. new utility tr_lowerBound()

  • Property svn:keywords set to Date Rev Author Id
File size: 12.7 KB
Line 
1/******************************************************************************
2 * $Id: utils.h 7609 2009-01-04 16:29:44Z 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
318/* @brief same argument list as bsearch() */
319int tr_lowerBound( const void * key,
320                   const void * base,
321                   size_t       nmemb,
322                   size_t       size,
323                   int       (* compar)(const void* key, const void* arrayMember),
324                   tr_bool    * exact_match );
325
326
327char*       tr_strdup_printf( const char * fmt,
328                              ... )  TR_GNUC_PRINTF( 1, 2 ) TR_GNUC_MALLOC;
329
330char*       tr_base64_encode( const void * input,
331                              int          inlen,
332                              int *        outlen ) TR_GNUC_MALLOC;
333
334char*       tr_base64_decode( const void * input,
335                              int          inlen,
336                              int *        outlen ) TR_GNUC_MALLOC;
337
338size_t      tr_strlcpy( char *       dst,
339                        const void * src,
340                        size_t       siz );
341
342int         tr_snprintf( char *       buf,
343                         size_t       buflen,
344                         const char * fmt,
345                         ... ) TR_GNUC_PRINTF( 3, 4 );
346
347const char* tr_strerror( int );
348
349char*       tr_strstrip( char * str );
350
351/***
352****
353***/
354
355typedef void ( tr_set_func )( void * element, void * userData );
356
357void        tr_set_compare( const void * a,
358                            size_t aCount,
359                            const void * b,
360                            size_t bCount,
361                            int compare( const void * a, const void * b ),
362                            size_t elementSize,
363                            tr_set_func in_a_cb,
364                            tr_set_func in_b_cb,
365                            tr_set_func in_both_cb,
366                            void * userData );
367
368void tr_sha1_to_hex( char *          out,
369                     const uint8_t * sha1 );
370
371
372int  tr_httpIsValidURL( const char * url );
373
374int  tr_httpParseURL( const char * url,
375                      int          url_len,
376                      char **      setme_host,
377                      int *        setme_port,
378                      char **      setme_path );
379
380
381/***
382****
383***/
384
385typedef struct tr_bitfield
386{
387    uint8_t *  bits;
388    size_t     bitCount;
389    size_t     byteCount;
390}
391tr_bitfield;
392
393tr_bitfield* tr_bitfieldConstruct( tr_bitfield*, size_t bitcount );
394
395tr_bitfield* tr_bitfieldDestruct( tr_bitfield* );
396
397static inline tr_bitfield* tr_bitfieldNew( size_t bitcount )
398{
399    return tr_bitfieldConstruct( tr_new0( tr_bitfield, 1 ), bitcount );
400}
401
402static inline void tr_bitfieldFree( tr_bitfield * b )
403{
404    tr_free( tr_bitfieldDestruct( b ) );
405}
406
407tr_bitfield* tr_bitfieldDup( const tr_bitfield* ) TR_GNUC_MALLOC;
408
409void         tr_bitfieldClear( tr_bitfield* );
410
411int          tr_bitfieldAdd( tr_bitfield*, size_t bit );
412
413int          tr_bitfieldRem( tr_bitfield*, size_t bit );
414
415int          tr_bitfieldAddRange( tr_bitfield *, size_t begin, size_t end );
416
417int          tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );
418
419void         tr_bitfieldDifference( tr_bitfield *, const tr_bitfield * );
420
421int          tr_bitfieldIsEmpty( const tr_bitfield* );
422
423size_t       tr_bitfieldCountTrueBits( const tr_bitfield* );
424
425tr_bitfield* tr_bitfieldOr( tr_bitfield*, const tr_bitfield* );
426
427/** A stripped-down version of bitfieldHas to be used
428    for speed when you're looping quickly.  This version
429    has none of tr_bitfieldHas()'s safety checks, so you
430    need to call tr_bitfieldTestFast() first before you
431    start looping. */
432static inline tr_bool tr_bitfieldHasFast( const tr_bitfield * b, const size_t nth )
433{
434    return ( b->bits[nth>>3u] << ( nth & 7u ) & 0x80 ) != 0;
435}
436
437/** @param high the highest nth bit you're going to access */
438static inline tr_bool tr_bitfieldTestFast( const tr_bitfield * b, const size_t high )
439{
440    return ( b != NULL )
441        && ( b->bits != NULL )
442        && ( high < b->bitCount );
443}
444
445static inline tr_bool tr_bitfieldHas( const tr_bitfield * b, size_t nth )
446{
447    return tr_bitfieldTestFast( b, nth ) && tr_bitfieldHasFast( b, nth );
448}
449
450double tr_getRatio( double numerator, double denominator );
451
452
453int tr_ptr2int( void* );
454
455void* tr_int2ptr( int );
456
457#ifdef __cplusplus
458}
459#endif
460
461#endif
Note: See TracBrowser for help on using the repository browser.