source: trunk/libtransmission/utils.h

Last change on this file was 14724, checked in by jordan, 5 years ago

use '#pragma once' instead of #ifndef..#define..#endif guards

  • Property svn:keywords set to Date Rev Author Id
File size: 17.0 KB
Line 
1/*
2 * This file Copyright (C) 2009-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: utils.h 14724 2016-03-29 16:37:21Z mikedld $
8 */
9
10#pragma once
11
12#include <inttypes.h>
13#include <stdarg.h>
14#include <stddef.h> /* size_t */
15#include <time.h> /* time_t */
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21/***
22****
23***/
24
25struct evbuffer;
26struct event;
27struct timeval;
28
29struct tr_error;
30
31/**
32 * @addtogroup utils Utilities
33 * @{
34 */
35
36#ifndef UNUSED
37 #ifdef __GNUC__
38  #define UNUSED __attribute__ ((unused))
39 #else
40  #define UNUSED
41 #endif
42#endif
43
44#ifndef TR_GNUC_PRINTF
45 #ifdef __GNUC__
46  #define TR_GNUC_PRINTF(fmt, args) __attribute__ ((format (printf, fmt, args)))
47 #else
48  #define TR_GNUC_PRINTF(fmt, args)
49 #endif
50#endif
51
52#ifndef TR_GNUC_NONNULL
53 #ifdef __GNUC__
54  #define TR_GNUC_NONNULL(...) __attribute__ ((nonnull (__VA_ARGS__)))
55 #else
56  #define TR_GNUC_NONNULL(...)
57 #endif
58#endif
59
60#ifndef TR_GNUC_NULL_TERMINATED
61 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
62  #define TR_GNUC_NULL_TERMINATED __attribute__ ((__sentinel__))
63  #define TR_GNUC_HOT __attribute ((hot))
64 #else
65  #define TR_GNUC_NULL_TERMINATED
66  #define TR_GNUC_HOT
67 #endif
68#endif
69
70#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
71 #define TR_GNUC_MALLOC __attribute__ ((__malloc__))
72#else
73 #define TR_GNUC_MALLOC
74#endif
75
76
77#ifndef __has_feature
78 #define __has_feature(x) 0
79#endif
80#ifndef __has_extension
81 #define __has_extension __has_feature
82#endif
83
84#ifdef __UCLIBC__
85 #define TR_UCLIBC_CHECK_VERSION(major, minor, micro) \
86   (__UCLIBC_MAJOR__ > (major) || \
87    (__UCLIBC_MAJOR__ == (major) && __UCLIBC_MINOR__ > (minor)) || \
88    (__UCLIBC_MAJOR__ == (major) && __UCLIBC_MINOR__ == (minor) && \
89       __UCLIBC_SUBLEVEL__ >= (micro)))
90#else
91 #define TR_UCLIBC_CHECK_VERSION(major, minor, micro) 0
92#endif
93
94/**
95 * @def TR_STATIC_ASSERT
96 * @brief This helper allows to perform static checks at compile time
97 */
98#if defined (static_assert)
99 #define TR_STATIC_ASSERT static_assert
100#elif __has_feature (c_static_assert) || __has_extension (c_static_assert)
101 #define TR_STATIC_ASSERT _Static_assert
102#else
103 #define TR_STATIC_ASSERT(x, msg) { typedef char __tr_static_check__[(x) ? 1 : -1] UNUSED; }
104#endif
105
106
107/***
108****
109***/
110
111const char * tr_strip_positional_args (const char * fmt);
112
113#if !defined (_)
114 #if defined (HAVE_LIBINTL_H) && !defined (__APPLE__)
115  #include <libintl.h>
116  #define _(a) gettext (a)
117 #else
118  #define _(a)(a)
119 #endif
120#endif
121
122/* #define DISABLE_GETTEXT */
123#ifndef DISABLE_GETTEXT
124 #if defined (_WIN32) || defined (TR_LIGHTWEIGHT)
125   #define DISABLE_GETTEXT
126 #endif
127#endif
128#ifdef DISABLE_GETTEXT
129 #undef _
130 #define _(a) tr_strip_positional_args (a)
131#endif
132
133/****
134*****
135****/
136
137/**
138 * @brief Rich Salz's classic implementation of shell-style pattern matching for ?, \, [], and * characters.
139 * @return 1 if the pattern matches, 0 if it doesn't, or -1 if an error occured
140 */
141bool tr_wildmat (const char * text, const char * pattern) TR_GNUC_NONNULL (1,2);
142
143
144/**
145 * @brief Loads a file and returns its contents.
146 * On failure, NULL is returned and errno is set.
147 */
148uint8_t * tr_loadFile (const char       * filename,
149                       size_t           * size,
150                       struct tr_error ** error) TR_GNUC_MALLOC TR_GNUC_NONNULL (1);
151
152
153/** @brief build a filename from a series of elements using the
154           platform's correct directory separator. */
155char* tr_buildPath (const char * first_element, ...) TR_GNUC_NULL_TERMINATED
156                                                      TR_GNUC_MALLOC;
157
158/**
159 * @brief Get available disk space (in bytes) for the specified folder.
160 * @return zero or positive integer on success, -1 in case of error.
161 */
162int64_t tr_getDirFreeSpace (const char * path);
163
164/**
165 * @brief Convenience wrapper around timer_add () to have a timer wake up in a number of seconds and microseconds
166 * @param timer         the timer to set
167 * @param seconds       seconds to wait
168 * @param microseconds  microseconds to wait
169 */
170void tr_timerAdd (struct event * timer, int seconds, int microseconds) TR_GNUC_NONNULL (1);
171
172/**
173 * @brief Convenience wrapper around timer_add () to have a timer wake up in a number of milliseconds
174 * @param timer         the timer to set
175 * @param milliseconds  milliseconds to wait
176 */
177void tr_timerAddMsec (struct event * timer, int milliseconds) TR_GNUC_NONNULL (1);
178
179
180/** @brief return the current date in milliseconds */
181uint64_t tr_time_msec (void);
182
183/** @brief sleep the specified number of milliseconds */
184void tr_wait_msec (long int delay_milliseconds);
185
186/**
187 * @brief make a copy of 'str' whose non-utf8 content has been corrected or stripped
188 * @return a newly-allocated string that must be freed with tr_free ()
189 * @param str the string to make a clean copy of
190 * @param len the length of the string to copy. If -1, the entire string is used.
191 */
192char* tr_utf8clean (const char * str, size_t len) TR_GNUC_MALLOC;
193
194#ifdef _WIN32
195
196char    * tr_win32_native_to_utf8    (const wchar_t * text,
197                                      int             text_size);
198wchar_t * tr_win32_utf8_to_native    (const char    * text,
199                                      int             text_size);
200wchar_t * tr_win32_utf8_to_native_ex (const char    * text,
201                                      int             text_size,
202                                      int             extra_chars_before,
203                                      int             extra_chars_after,
204                                      int           * real_result_size);
205char    * tr_win32_format_message    (uint32_t        code);
206
207void      tr_win32_make_args_utf8    (int    * argc,
208                                      char *** argv);
209
210int       tr_main_win32              (int     argc,
211                                      char ** argv,
212                                      int   (*real_main) (int, char **));
213
214#define tr_main(...) \
215  main_impl (__VA_ARGS__); \
216  int \
217  main (int    argc, \
218        char * argv[]) \
219  { \
220    return tr_main_win32 (argc, argv, &main_impl); \
221  } \
222  int \
223  main_impl (__VA_ARGS__)
224
225#else
226
227#define tr_main main
228
229#endif
230
231/***
232****
233***/
234
235/* Sometimes the system defines MAX/MIN, sometimes not.
236   In the latter case, define those here since we will use them */
237#ifndef MAX
238 #define MAX(a, b)((a) > (b) ? (a) : (b))
239#endif
240#ifndef MIN
241 #define MIN(a, b)((a) > (b) ? (b) : (a))
242#endif
243
244/***
245****
246***/
247
248/** @brief Portability wrapper around malloc () in which `0' is a safe argument */
249void* tr_malloc (size_t size);
250
251/** @brief Portability wrapper around calloc () in which `0' is a safe argument */
252void* tr_malloc0 (size_t size);
253
254/** @brief Portability wrapper around reallocf () in which `0' is a safe argument */
255void * tr_realloc (void * p, size_t size);
256
257/** @brief Portability wrapper around free () in which `NULL' is a safe argument */
258void tr_free (void * p);
259
260/**
261 * @brief make a newly-allocated copy of a chunk of memory
262 * @param src the memory to copy
263 * @param byteCount the number of bytes to copy
264 * @return a newly-allocated copy of `src' that can be freed with tr_free ()
265 */
266void* tr_memdup (const void * src, size_t byteCount);
267
268#define tr_new(struct_type, n_structs)           \
269  ((struct_type *) tr_malloc (sizeof (struct_type) * ((size_t)(n_structs))))
270
271#define tr_new0(struct_type, n_structs)          \
272  ((struct_type *) tr_malloc0 (sizeof (struct_type) * ((size_t)(n_structs))))
273
274#define tr_renew(struct_type, mem, n_structs)    \
275  ((struct_type *) tr_realloc ((mem), sizeof (struct_type) * ((size_t)(n_structs))))
276
277void* tr_valloc (size_t bufLen);
278
279/**
280 * @brief make a newly-allocated copy of a substring
281 * @param in is a void* so that callers can pass in both signed & unsigned without a cast
282 * @param len length of the substring to copy. if a length less than zero is passed in, strlen (len) is used
283 * @return a newly-allocated copy of `in' that can be freed with tr_free ()
284 */
285char* tr_strndup (const void * in, size_t len) TR_GNUC_MALLOC;
286
287/**
288 * @brief make a newly-allocated copy of a string
289 * @param in is a void* so that callers can pass in both signed & unsigned without a cast
290 * @return a newly-allocated copy of `in' that can be freed with tr_free ()
291 */
292char* tr_strdup (const void * in);
293
294/**
295 * @brief like strcmp () but gracefully handles NULL strings
296 */
297int tr_strcmp0 (const char * str1, const char * str2);
298
299char* evbuffer_free_to_str (struct evbuffer * buf,
300                            size_t          * result_len);
301
302/** @brief similar to bsearch () but returns the index of the lower bound */
303int tr_lowerBound (const void * key,
304                   const void * base,
305                   size_t       nmemb,
306                   size_t       size,
307                   int     (* compar)(const void* key, const void* arrayMember),
308                   bool       * exact_match) TR_GNUC_HOT TR_GNUC_NONNULL (1,5,6);
309
310/** @brief moves the best k items to the first slots in the array. O(n) */
311void tr_quickfindFirstK (void * base, size_t nmemb, size_t size,
312                         int (*compar)(const void *, const void *), size_t k);
313
314/**
315 * @brief sprintf () a string into a newly-allocated buffer large enough to hold it
316 * @return a newly-allocated string that can be freed with tr_free ()
317 */
318char* tr_strdup_printf (const char * fmt, ...) TR_GNUC_PRINTF (1, 2)
319                                                TR_GNUC_MALLOC;
320char * tr_strdup_vprintf (const char * fmt,
321                          va_list      args) TR_GNUC_MALLOC;
322
323/** @brief Portability wrapper for strlcpy () that uses the system implementation if available */
324size_t tr_strlcpy (char * dst, const void * src, size_t siz);
325
326/** @brief Portability wrapper for snprintf () that uses the system implementation if available */
327int tr_snprintf (char * buf, size_t buflen,
328                 const char * fmt, ...) TR_GNUC_PRINTF (3, 4) TR_GNUC_NONNULL (1,3);
329
330/** @brief Convenience wrapper around strerorr () guaranteed to not return NULL
331    @param errnum the error number to describe */
332const char* tr_strerror (int errnum);
333
334/** @brief strips leading and trailing whitspace from a string
335    @return the stripped string */
336char* tr_strstrip (char * str);
337
338/** @brief Returns true if the string ends with the specified case-insensitive suffix */
339bool tr_str_has_suffix (const char *str, const char *suffix);
340
341
342/** @brief Portability wrapper for memmem () that uses the system implementation if available */
343const char* tr_memmem (const char * haystack, size_t haystack_len,
344                       const char * needle, size_t needle_len);
345
346/** @brief Portability wrapper for strsep () that uses the system implementation if available */
347char* tr_strsep (char ** str, const char * delim);
348
349/***
350****
351***/
352
353int compareInt (const void * va, const void * vb);
354
355void tr_binary_to_hex (const void * input, char * output, size_t byte_length) TR_GNUC_NONNULL (1,2);
356void tr_hex_to_binary (const char * input, void * output, size_t byte_length) TR_GNUC_NONNULL (1,2);
357
358/** @brief convenience function to determine if an address is an IP address (IPv4 or IPv6) */
359bool tr_addressIsIP (const char * address);
360
361/** @brief return true if the url is a http or https or UDP url that Transmission understands */
362bool tr_urlIsValidTracker (const char * url);
363
364/** @brief return true if the url is a [ http, https, ftp, sftp ] url that Transmission understands */
365bool tr_urlIsValid (const char * url, size_t url_len);
366
367/** @brief parse a URL into its component parts
368    @return True on success or false if an error occurred */
369bool tr_urlParse (const char * url,
370                  size_t       url_len,
371                  char      ** setme_scheme,
372                  char      ** setme_host,
373                  int        * setme_port,
374                  char      ** setme_path) TR_GNUC_NONNULL (1);
375
376
377/** @brief return TR_RATIO_NA, TR_RATIO_INF, or a number in [0..1]
378    @return TR_RATIO_NA, TR_RATIO_INF, or a number in [0..1] */
379double tr_getRatio (uint64_t numerator, uint64_t denominator);
380
381/**
382 * @brief Given a string like "1-4" or "1-4,6,9,14-51", this returns a
383 *        newly-allocated array of all the integers in the set.
384 * @return a newly-allocated array of integers that must be freed with tr_free (),
385 *         or NULL if a fragment of the string can't be parsed.
386 *
387 * For example, "5-8" will return [ 5, 6, 7, 8 ] and setmeCount will be 4.
388 */
389int* tr_parseNumberRange (const char * str,
390                          size_t       str_len,
391                          int        * setmeCount) TR_GNUC_MALLOC TR_GNUC_NONNULL (1);
392
393
394/**
395 * @brief truncate a double value at a given number of decimal places.
396 *
397 * this can be used to prevent a printf () call from rounding up:
398 * call with the decimal_places argument equal to the number of
399 * decimal places in the printf ()'s precision:
400 *
401 * - printf ("%.2f%%",           99.999  ) ==> "100.00%"
402 *
403 * - printf ("%.2f%%", tr_truncd (99.999, 2)) ==>  "99.99%"
404 *             ^                        ^
405 *             |   These should match   |
406 *             +------------------------+
407 */
408double tr_truncd (double x, int decimal_places);
409
410/* return a percent formatted string of either x.xx, xx.x or xxx */
411char* tr_strpercent (char * buf, double x, size_t buflen);
412
413/**
414 * @param buf      the buffer to write the string to
415 * @param buflen   buf's size
416 * @param ratio    the ratio to convert to a string
417 * @param infinity the string represntation of "infinity"
418 */
419char* tr_strratio (char * buf, size_t buflen, double ratio, const char * infinity) TR_GNUC_NONNULL (1,4);
420
421/** @brief Portability wrapper for localtime_r () that uses the system implementation if available */
422struct tm * tr_localtime_r (const time_t *_clock, struct tm *_result);
423
424/** @brief Portability wrapper for gettimeofday (), with tz argument dropped */
425int tr_gettimeofday (struct timeval * tv);
426
427
428/**
429 * @brief move a file
430 * @return `True` on success, `false` otherwise (with `error` set accordingly).
431 */
432bool tr_moveFile (const char       * oldpath,
433                  const char       * newpath,
434                  struct tr_error ** error) TR_GNUC_NONNULL (1,2);
435
436/** @brief convenience function to remove an item from an array */
437void tr_removeElementFromArray (void         * array,
438                                unsigned int   index_to_remove,
439                                size_t         sizeof_element,
440                                size_t         nmemb);
441
442/***
443****
444***/
445
446/** @brief Private libtransmission variable that's visible only for inlining in tr_time () */
447extern time_t __tr_current_time;
448
449/**
450 * @brief very inexpensive form of time (NULL)
451 * @return the current epoch time in seconds
452 *
453 * This function returns a second counter that is updated once per second.
454 * If something blocks the libtransmission thread for more than a second,
455 * that counter may be thrown off, so this function is not guaranteed
456 * to always be accurate. However, it is *much* faster when 100% accuracy
457 * isn't needed
458 */
459static inline time_t tr_time (void) { return __tr_current_time; }
460
461/** @brief Private libtransmission function to update tr_time ()'s counter */
462static inline void tr_timeUpdate (time_t now) { __tr_current_time = now; }
463
464/** @brief Portability wrapper for htonll () that uses the system implementation if available */
465uint64_t tr_htonll (uint64_t);
466
467/** @brief Portability wrapper for htonll () that uses the system implementation if available */
468uint64_t tr_ntohll (uint64_t);
469
470/***
471****
472***/
473
474/* example: tr_formatter_size_init (1024, _ ("KiB"), _ ("MiB"), _ ("GiB"), _ ("TiB")); */
475
476void tr_formatter_size_init (unsigned int kilo, const char * kb, const char * mb,
477                                                const char * gb, const char * tb);
478
479void tr_formatter_speed_init (unsigned int kilo, const char * kb, const char * mb,
480                                                 const char * gb, const char * tb);
481
482void tr_formatter_mem_init (unsigned int kilo, const char * kb, const char * mb,
483                                               const char * gb, const char * tb);
484
485extern unsigned int tr_speed_K;
486extern unsigned int tr_mem_K;
487extern unsigned int tr_size_K;
488
489/* format a speed from KBps into a user-readable string. */
490char* tr_formatter_speed_KBps (char * buf, double KBps, size_t buflen);
491
492/* format a memory size from bytes into a user-readable string. */
493char* tr_formatter_mem_B (char * buf, int64_t bytes, size_t buflen);
494
495/* format a memory size from MB into a user-readable string. */
496static inline char* tr_formatter_mem_MB (char * buf, double MBps, size_t buflen) { return tr_formatter_mem_B (buf, (int64_t)(MBps * tr_mem_K * tr_mem_K), buflen); }
497
498/* format a file size from bytes into a user-readable string. */
499char* tr_formatter_size_B (char * buf, int64_t bytes, size_t buflen);
500
501void tr_formatter_get_units (void * dict);
502
503/***
504****
505***/
506
507/** @brief Check if environment variable exists. */
508bool   tr_env_key_exists (const char * key);
509
510/** @brief Get environment variable value as int. */
511int    tr_env_get_int    (const char * key,
512                          int          default_value);
513
514/** @brief Get environment variable value as string (should be freed afterwards). */
515char * tr_env_get_string (const char * key,
516                          const char * default_value);
517
518/***
519****
520***/
521
522void tr_net_init (void);
523
524/***
525****
526***/
527
528#ifdef __cplusplus
529}
530#endif
531
532/** @} */
533
Note: See TracBrowser for help on using the repository browser.