1 /*
2  * Copyright (c) 2010, Sangoma Technologies
3  * Moises Silva <moy@sangoma.com>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * * Neither the name of the original author; nor the names of any contributors
18  * may be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #ifndef __FTDM_OS_H__
36 #define __FTDM_OS_H__
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #if defined(__linux__) && !defined(__USE_BSD)
43 #define __USE_BSD
44 #endif
45 
46 #include "ftdm_declare.h"
47 #include "ftdm_threadmutex.h"
48 #include <string.h>
49 
50 #ifndef __WINDOWS__
51 #include <unistd.h>
52 #endif
53 
54 /*! \brief time data type */
55 typedef uint64_t ftdm_time_t;
56 /*! format string for ftdm_time_t */
57 #define FTDM_TIME_FMT FTDM_UINT64_FMT
58 
59 /*! \brief sleep x amount of milliseconds */
60 #ifdef __WINDOWS__
61 #define ftdm_sleep(x) Sleep(x)
62 #else
63 #define ftdm_sleep(x) usleep(x * 1000)
64 #endif
65 
66 /*! \brief strncpy replacement */
67 #define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1)
68 
69 /*! \brief strncpy into a fixed-length buffer */
70 #define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1)
71 
72 /*! \brief check for null or zero length string buffer */
73 #define ftdm_strlen_zero(s) (!s || *s == '\0')
74 
75 /*! \brief check for zero length string buffer */
76 #define ftdm_strlen_zero_buf(s) (*s == '\0')
77 
78 /*! \brief array len helper */
79 #define ftdm_array_len(array) sizeof(array)/sizeof(array[0])
80 
81 /*! \brief Get smaller value */
82 #define ftdm_min(x,y) ((x) < (y) ? (x) : (y))
83 
84 /*! \brief Get larger value */
85 #define ftdm_max(x,y) ((x) > (y) ? (x) : (y))
86 
87 /*! \brief Get value that is in range [vmin,vmax] */
88 #define ftdm_clamp(val,vmin,vmax) ftdm_max(vmin,ftdm_min(val,vmax))
89 
90 /*!< \brief Safer version of ftdm_clamp(), that swaps vmin/vmax parameters if vmin > vmax */
91 #define ftdm_clamp_safe(val,vmin,vmax)	\
92 	ftdm_clamp(val, ftdm_min(vmin,vmax), ftdm_max(vmin,vmax))
93 
94 /*!
95  * \brief Get offset of member in structure
96  * \param[in]	type	Type of struct
97  * \param[in]	member	Name of struct member
98  * \code
99  * 	struct a {
100  *		int foo;
101  * 		int bar;
102  * 	};
103  *
104  *	int offset_a_bar = ftdm_offset_of(struct a, bar); // 4 byte offset
105  * \endcode
106  */
107 #define ftdm_offset_of(type,member) (uintptr_t)&(((type *)0)->member)
108 
109 /*!
110  * \brief Get pointer to enclosing structrure from pointer to embedded member
111  * \param[in]	ptr	Pointer to embedded member
112  * \param[in]	type	Type of parent/container structure
113  * \param[in]	member	Name of embedded member in parent/container struct
114  * \code
115  *	struct engine {
116  *		int nr_cyl;
117  *	};
118  *
119  *	struct car {
120  *		char model[10];
121  *		struct engine eng;	// struct engine embedded in car(!)
122  *	};
123  *
124  *	int somefunc(struct engine *e) {
125  *		struct car *c = ftdm_container_of(e, struct car, eng);
126  *
127  *		... do something with car ...
128  *	}
129  * \endcode
130  */
131 #define ftdm_container_of(ptr,type,member) (type *)((uintptr_t)(ptr) - ftdm_offset_of(type, member))
132 
133 /*!
134  * \brief Silence "unused parameter" compiler warnings
135  * \note Tested with VS 2010, GCC 4.8, clang 3.1 and suncc
136  * \code
137  *	int example(char *a) {
138  *		ftdm_unused_arg(a);
139  *		return 0;
140  *	}
141  * \endcode
142  */
143 #define ftdm_unused_arg(x) (void)(x)
144 
145 
146 /*! \brief The memory handler.
147     Do not use directly this variable, use the memory macros and ftdm_global_set_memory_handler to override */
148 FT_DECLARE_DATA extern ftdm_memory_handler_t g_ftdm_mem_handler;
149 
150 /*!
151   \brief Allocate uninitialized memory
152   \param chunksize the chunk size
153 */
154 #define ftdm_malloc(chunksize) g_ftdm_mem_handler.malloc(g_ftdm_mem_handler.pool, chunksize)
155 
156 /*!
157   \brief Reallocates memory
158   \param buff the buffer
159   \param chunksize the chunk size
160 */
161 #define ftdm_realloc(buff, chunksize) g_ftdm_mem_handler.realloc(g_ftdm_mem_handler.pool, buff, chunksize)
162 
163 /*!
164   \brief Allocate initialized memory
165   \param chunksize the chunk size
166 */
167 #define ftdm_calloc(elements, chunksize) g_ftdm_mem_handler.calloc(g_ftdm_mem_handler.pool, elements, chunksize)
168 
169 /*!
170   \brief Free chunk of memory
171   \param chunksize the chunk size
172 */
173 #define ftdm_free(chunk) g_ftdm_mem_handler.free(g_ftdm_mem_handler.pool, chunk)
174 
175 /*!
176   \brief Free a pointer and set it to NULL unless it already is NULL
177   \param it the pointer
178 */
179 #define ftdm_safe_free(it) if (it) { ftdm_free(it); it = NULL; }
180 
181 /*! \brief Duplicate string */
182 FT_DECLARE(char *) ftdm_strdup(const char *str);
183 
184 /*! \brief Duplicate string with limit */
185 FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen);
186 
187 /*! \brief Get the current time in milliseconds */
188 FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void);
189 
190 #ifdef __cplusplus
191 } /* extern C */
192 #endif
193 
194 #endif
195 
196 /* For Emacs:
197  * Local Variables:
198  * mode:c
199  * indent-tabs-mode:t
200  * tab-width:4
201  * c-basic-offset:4
202  * End:
203  * For VIM:
204  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
205  */
206