⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strings.h

📁 asterisk 是一个很有知名度开源软件
💻 H
📖 第 1 页 / 共 2 页
字号:
 */AST_INLINE_API(struct ast_str * attribute_malloc ast_str_create(size_t init_len),{	struct ast_str *buf;	buf = (struct ast_str *)ast_calloc(1, sizeof(*buf) + init_len);	if (buf == NULL)		return NULL;		buf->len = init_len;	buf->used = 0;	buf->ts = DS_MALLOC;	return buf;})/*! \brief Reset the content of a dynamic string. * Useful before a series of ast_str_append. */AST_INLINE_API(void ast_str_reset(struct ast_str *buf),{	if (buf) {		buf->used = 0;		if (buf->len)			buf->str[0] = '\0';	}})/* * AST_INLINE_API() is a macro that takes a block of code as an argument. * Using preprocessor #directives in the argument is not supported by all * compilers, and it is a bit of an obfuscation anyways, so avoid it. * As a workaround, define a macro that produces either its argument * or nothing, and use that instead of #ifdef/#endif within the * argument to AST_INLINE_API(). */#if defined(DEBUG_THREADLOCALS)#define	_DB1(x)	x#else#define _DB1(x)#endif/*! * Make space in a new string (e.g. to read in data from a file) */AST_INLINE_API(int ast_str_make_space(struct ast_str **buf, size_t new_len),{	_DB1(struct ast_str *old_buf = *buf;)	if (new_len <= (*buf)->len) 		return 0;	/* success */	if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC)		return -1;	/* cannot extend */	*buf = (struct ast_str *)ast_realloc(*buf, new_len + sizeof(struct ast_str));	if (*buf == NULL) /* XXX watch out, we leak memory here */		return -1;	if ((*buf)->ts != DS_MALLOC) {		pthread_setspecific((*buf)->ts->key, *buf);		_DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));)	}        (*buf)->len = new_len;        return 0;})#define ast_str_alloca(init_len)			\	({						\		struct ast_str *buf;			\		buf = alloca(sizeof(*buf) + init_len);	\		buf->len = init_len;			\		buf->used = 0;				\		buf->ts = DS_ALLOCA;			\		buf->str[0] = '\0';			\		(buf);					\	})/*! * \brief Retrieve a thread locally stored dynamic string * * \arg ts This is a pointer to the thread storage structure declared by using *      the AST_THREADSTORAGE macro.  If declared with  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be  *      (&my_buf). * \arg init_len This is the initial length of the thread's dynamic string. The *      current length may be bigger if previous operations in this thread have *      caused it to increase. * * \return This function will return the thread locally stored dynamic string *         associated with the thread storage management variable passed as the *         first argument. *         The result will be NULL in the case of a memory allocation error. * * Example usage: * \code * AST_THREADSTORAGE(my_str, my_str_init); * #define MY_STR_INIT_SIZE   128 * ... * void my_func(const char *fmt, ...) * { *      struct ast_str *buf; * *      if (!(buf = ast_str_thread_get(&my_str, MY_STR_INIT_SIZE))) *           return; *      ... * } * \endcode */#if !defined(DEBUG_THREADLOCALS)AST_INLINE_API(struct ast_str *ast_str_thread_get(struct ast_threadstorage *ts,	size_t init_len),{	struct ast_str *buf;	buf = (struct ast_str *)ast_threadstorage_get(ts, sizeof(*buf) + init_len);	if (buf == NULL)		return NULL;		if (!buf->len) {		buf->len = init_len;		buf->used = 0;		buf->ts = ts;	}	return buf;})#else /* defined(DEBUG_THREADLOCALS) */AST_INLINE_API(struct ast_str *__ast_str_thread_get(struct ast_threadstorage *ts,	size_t init_len, const char *file, const char *function, unsigned int line),{	struct ast_str *buf;	buf = (struct ast_str *)__ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line);	if (buf == NULL)		return NULL;		if (!buf->len) {		buf->len = init_len;		buf->used = 0;		buf->ts = ts;	}	return buf;})#define ast_str_thread_get(ts, init_len) __ast_str_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__)#endif /* defined(DEBUG_THREADLOCALS) *//*! * \brief Error codes from __ast_str_helper() * The undelying processing to manipulate dynamic string is done * by __ast_str_helper(), which can return a success, a * permanent failure (e.g. no memory), or a temporary one (when * the string needs to be reallocated, and we must run va_start() * again; XXX this convoluted interface is only here because * FreeBSD 4 lacks va_copy, but this will be fixed and the * interface simplified). */enum {	/*! An error has occured and the contents of the dynamic string	 *  are undefined */	AST_DYNSTR_BUILD_FAILED = -1,	/*! The buffer size for the dynamic string had to be increased, and	 *  __ast_str_helper() needs to be called again after	 *  a va_end() and va_start().	 */	AST_DYNSTR_BUILD_RETRY = -2};/*! * \brief Set a dynamic string from a va_list * * \arg buf This is the address of a pointer to a struct ast_str. *	If it is retrieved using ast_str_thread_get, the	struct ast_threadstorage pointer will need to *      be updated in the case that the buffer has to be reallocated to *      accommodate a longer string than what it currently has space for. * \arg max_len This is the maximum length to allow the string buffer to grow *      to.  If this is set to 0, then there is no maximum length. * \arg fmt This is the format string (printf style) * \arg ap This is the va_list * * \return The return value of this function is the same as that of the printf *         family of functions. * * Example usage (the first part is only for thread-local storage) * \code * AST_THREADSTORAGE(my_str, my_str_init); * #define MY_STR_INIT_SIZE   128 * ... * void my_func(const char *fmt, ...) * { *      struct ast_str *buf; *      va_list ap; * *      if (!(buf = ast_str_thread_get(&my_str, MY_STR_INIT_SIZE))) *           return; *      ... *      va_start(fmt, ap); *      ast_str_set_va(&buf, 0, fmt, ap); *      va_end(ap); *  *      printf("This is the string we just built: %s\n", buf->str); *      ... * } * \endcode * * \note: the following two functions must be implemented as macros *	because we must do va_end()/va_start() on the original arguments. */#define ast_str_set_va(buf, max_len, fmt, ap)			\	({								\		int __res;						\		while ((__res = __ast_str_helper(buf, max_len,		\			0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {	\			va_end(ap);					\			va_start(ap, fmt);				\		}							\		(__res);						\	})/*! * \brief Append to a dynamic string using a va_list * * Same as ast_str_set_va(), but append to the current content. */#define ast_str_append_va(buf, max_len, fmt, ap)		\	({								\		int __res;						\		while ((__res = __ast_str_helper(buf, max_len,		\			1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {	\			va_end(ap);					\			va_start(ap, fmt);				\		}							\		(__res);						\	})/*! * \brief Core functionality of ast_str_(set|append)_va * * The arguments to this function are the same as those described for * ast_str_set_va except for an addition argument, append. * If append is non-zero, this will append to the current string instead of * writing over it. * * In the case that this function is called and the buffer was not large enough * to hold the result, the partial write will be truncated, and the result * AST_DYNSTR_BUILD_RETRY will be returned to indicate that the buffer size * was increased, and the function should be called a second time. * * A return of AST_DYNSTR_BUILD_FAILED indicates a memory allocation error. * * A return value greater than or equal to zero indicates the number of * characters that have been written, not including the terminating '\0'. * In the append case, this only includes the number of characters appended. * * \note This function should never need to be called directly.  It should *       through calling one of the other functions or macros defined in this *       file. */int __attribute__((format(printf, 4, 0))) __ast_str_helper(struct ast_str **buf, size_t max_len,							   int append, const char *fmt, va_list ap);/*! * \brief Set a dynamic string using variable arguments * * \arg buf This is the address of a pointer to a struct ast_str which should *      have been retrieved using ast_str_thread_get.  It will need to *      be updated in the case that the buffer has to be reallocated to *      accomodate a longer string than what it currently has space for. * \arg max_len This is the maximum length to allow the string buffer to grow *      to.  If this is set to 0, then there is no maximum length. *	If set to -1, we are bound to the current maximum length. * \arg fmt This is the format string (printf style) * * \return The return value of this function is the same as that of the printf *         family of functions. * * All the rest is the same as ast_str_set_va() */AST_INLINE_API(int __attribute__((format(printf, 3, 4))) ast_str_set(	struct ast_str **buf, size_t max_len, const char *fmt, ...),{	int res;	va_list ap;	va_start(ap, fmt);	res = ast_str_set_va(buf, max_len, fmt, ap);	va_end(ap);	return res;})/*! * \brief Append to a thread local dynamic string * * The arguments, return values, and usage of this function are the same as * ast_str_set(), but the new data is appended to the current value. */AST_INLINE_API(int __attribute__((format(printf, 3, 4))) ast_str_append(	struct ast_str **buf, size_t max_len, const char *fmt, ...),{	int res;	va_list ap;	va_start(ap, fmt);	res = ast_str_append_va(buf, max_len, fmt, ap);	va_end(ap);	return res;})/*! * \brief Compute a hash value on a string * * This famous hash algorithm was written by Dan Bernstein and is * commonly used. * * http://www.cse.yorku.ca/~oz/hash.html */static force_inline int ast_str_hash(const char *str){	int hash = 5381;	while (*str)		hash = hash * 33 ^ *str++;	return abs(hash);}/*! * \brief Compute a hash value on a case-insensitive string * * Uses the same hash algorithm as ast_str_hash, but converts * all characters to lowercase prior to computing a hash. This * allows for easy case-insensitive lookups in a hash table. */static force_inline int ast_str_case_hash(const char *str){	int hash = 5381;	while (*str) {		hash = hash * 33 ^ tolower(*str++);	}	return abs(hash);}#endif /* _ASTERISK_STRINGS_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -