aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-13 08:36:35 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-13 08:36:35 +0000
commita41b34a63c52608e7e5c8e6aced613815461f4c2 (patch)
tree0559c99680217b78c0bda37a131b5f09794f43c6 /include
parentb298a3aa9b396c4055bf75104b4fb89212c44d4a (diff)
Merge ast_str_opaque branch (discontinue usage of ast_str internals)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@163991 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/app.h5
-rw-r--r--include/asterisk/cdr.h2
-rw-r--r--include/asterisk/pbx.h12
-rw-r--r--include/asterisk/strings.h244
-rw-r--r--include/asterisk/tcptls.h2
-rw-r--r--include/asterisk/threadstorage.h16
6 files changed, 264 insertions, 17 deletions
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index 851ad9fa6..79af2313e 100644
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -23,12 +23,17 @@
#ifndef _ASTERISK_APP_H
#define _ASTERISK_APP_H
+#include "asterisk/strings.h"
+#include "asterisk/threadstorage.h"
+
struct ast_flags64;
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
+AST_THREADSTORAGE_EXTERNAL(global_app_buf);
+
/* IVR stuff */
/*! \brief Callback function for IVR
diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h
index 7ece62379..312c2546e 100644
--- a/include/asterisk/cdr.h
+++ b/include/asterisk/cdr.h
@@ -282,7 +282,7 @@ void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chan);
* Changes the value of the last executed app
* Returns nothing
*/
-void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data);
+void ast_cdr_setapp(struct ast_cdr *cdr, const char *app, const char *data);
/*!
* \brief Convert a string to a detail record AMA flag
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index 3348bb8d7..2bb95930f 100644
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -114,11 +114,11 @@ struct ast_switch {
};
struct ast_timing {
- int hastime; /*!< If time construct exists */
- unsigned int monthmask; /*!< Mask for month */
- unsigned int daymask; /*!< Mask for date */
- unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
- unsigned int minmask[24]; /*!< Mask for minute */
+ int hastime; /*!< If time construct exists */
+ unsigned int monthmask; /*!< Mask for month */
+ unsigned int daymask; /*!< Mask for date */
+ unsigned int dowmask; /*!< Mask for day of week (sun-sat) */
+ unsigned int minmask[48]; /*!< Mask for minute */
};
int ast_build_timing(struct ast_timing *i, const char *info);
@@ -866,6 +866,8 @@ int pbx_builtin_raise_exception(struct ast_channel *chan, void *data);
void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count);
+void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used);
+void ast_str_substitute_variables(struct ast_str **buf, size_t maxlen, struct ast_channel *chan, const char *templ);
int ast_extension_patmatch(const char *pattern, const char *data);
diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h
index 43d5bfc41..84782a3ac 100644
--- a/include/asterisk/strings.h
+++ b/include/asterisk/strings.h
@@ -23,14 +23,17 @@
#ifndef _ASTERISK_STRINGS_H
#define _ASTERISK_STRINGS_H
+#define DEBUG_OPAQUE
+
#include <ctype.h>
-#include "asterisk/inline_api.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
/* You may see casts in this header that may seem useless but they ensure this file is C++ clean */
+#define AS_OR(a,b) ast_str_strlen(a) ? ast_str_buffer(a) : (b)
+
#ifdef AST_DEVMODE
#define ast_strlen_zero(foo) _ast_strlen_zero(foo, __FILE__, __PRETTY_FUNCTION__, __LINE__)
static force_inline int _ast_strlen_zero(const char *s, const char *file, const char *function, int line)
@@ -202,7 +205,6 @@ void ast_copy_string(char *dst, const char *src, size_t size),
}
)
-
/*!
\brief Build a string in a buffer, designed to be called repeatedly
@@ -338,13 +340,23 @@ int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default
* struct ast_threadstorage pointer.
*/
struct ast_str {
+#ifdef DEBUG_OPAQUE
+ size_t len2;
+ size_t used2;
+ struct ast_threadstorage *ts2;
+#else
size_t len; /*!< The current maximum length of the string */
size_t used; /*!< Amount of space used */
struct ast_threadstorage *ts; /*!< What kind of storage is this ? */
+#endif
#define DS_MALLOC ((struct ast_threadstorage *)1)
#define DS_ALLOCA ((struct ast_threadstorage *)2)
#define DS_STATIC ((struct ast_threadstorage *)3) /* not supported yet */
+#ifdef DEBUG_OPAQUE
+ char str2[0];
+#else
char str[0]; /*!< The string buffer */
+#endif
};
/*!
@@ -366,10 +378,16 @@ struct ast_str * attribute_malloc ast_str_create(size_t init_len),
buf = (struct ast_str *)ast_calloc(1, sizeof(*buf) + init_len);
if (buf == NULL)
return NULL;
-
+
+#ifdef DEBUG_OPAQUE
+ buf->len2 = init_len;
+ buf->used2 = 0;
+ buf->ts2 = DS_MALLOC;
+#else
buf->len = init_len;
buf->used = 0;
buf->ts = DS_MALLOC;
+#endif
return buf;
}
@@ -382,9 +400,15 @@ AST_INLINE_API(
void ast_str_reset(struct ast_str *buf),
{
if (buf) {
+#ifdef DEBUG_OPAQUE
+ buf->used2 = 0;
+ if (buf->len2)
+ buf->str2[0] = '\0';
+#else
buf->used = 0;
if (buf->len)
buf->str[0] = '\0';
+#endif
}
}
)
@@ -398,12 +422,83 @@ void ast_str_trim_blanks(struct ast_str *buf),
if (!buf) {
return;
}
+#ifdef DEBUG_OPAQUE
+ while (buf->used2 && buf->str2[buf->used2 - 1] < 33) {
+ buf->str2[--(buf->used2)] = '\0';
+ }
+#else
while (buf->used && buf->str[buf->used - 1] < 33) {
buf->str[--(buf->used)] = '\0';
}
+#endif
+}
+)
+
+/*!\brief Returns the current length of the string stored within buf.
+ * \param A pointer to the ast_str string.
+ */
+AST_INLINE_API(
+size_t ast_str_strlen(struct ast_str *buf),
+{
+#ifdef DEBUG_OPAQUE
+ return buf->used2;
+#else
+ return buf->used;
+#endif
+}
+)
+
+/*!\brief Returns the current maximum length (without reallocation) of the current buffer.
+ * \param A pointer to the ast_str string.
+ */
+AST_INLINE_API(
+size_t ast_str_size(struct ast_str *buf),
+{
+#ifdef DEBUG_OPAQUE
+ return buf->len2;
+#else
+ return buf->len;
+#endif
}
)
+/*!\brief Returns the string buffer within the ast_str buf.
+ * \param A pointer to the ast_str string.
+ */
+AST_INLINE_API(
+attribute_pure char *ast_str_buffer(struct ast_str *buf),
+{
+#ifdef DEBUG_OPAQUE
+ return buf->str2;
+#else
+ return buf->str;
+#endif
+}
+)
+
+AST_INLINE_API(
+char *ast_str_truncate(struct ast_str *buf, size_t len),
+{
+#ifdef DEBUG_OPAQUE
+ if (len < 0) {
+ buf->used2 += len;
+ } else {
+ buf->used2 = len;
+ }
+ buf->str2[buf->used2] = '\0';
+ return buf->str2;
+#else
+ if (len < 0) {
+ buf->used += len;
+ } else {
+ buf->used = len;
+ }
+ buf->str[buf->used] = '\0';
+ return buf->str;
+#endif
+}
+)
+
/*
* 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
@@ -427,6 +522,23 @@ int _ast_str_make_space(struct ast_str **buf, size_t new_len, const char *file,
{
struct ast_str *old_buf = *buf;
+#ifdef DEBUG_OPAQUE
+ if (new_len <= (*buf)->len2)
+ return 0; /* success */
+ if ((*buf)->ts2 == DS_ALLOCA || (*buf)->ts2 == DS_STATIC)
+ return -1; /* cannot extend */
+ *buf = (struct ast_str *)__ast_realloc(*buf, new_len + sizeof(struct ast_str), file, lineno, function);
+ if (*buf == NULL) {
+ *buf = old_buf;
+ return -1;
+ }
+ if ((*buf)->ts2 != DS_MALLOC) {
+ pthread_setspecific((*buf)->ts2->key, *buf);
+ _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));)
+ }
+
+ (*buf)->len2 = new_len;
+#else
if (new_len <= (*buf)->len)
return 0; /* success */
if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC)
@@ -442,6 +554,7 @@ int _ast_str_make_space(struct ast_str **buf, size_t new_len, const char *file,
}
(*buf)->len = new_len;
+#endif
return 0;
}
)
@@ -452,6 +565,23 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len),
{
struct ast_str *old_buf = *buf;
+#ifdef DEBUG_OPAQUE
+ if (new_len <= (*buf)->len2)
+ return 0; /* success */
+ if ((*buf)->ts2 == DS_ALLOCA || (*buf)->ts2 == DS_STATIC)
+ return -1; /* cannot extend */
+ *buf = (struct ast_str *)ast_realloc(*buf, new_len + sizeof(struct ast_str));
+ if (*buf == NULL) {
+ *buf = old_buf;
+ return -1;
+ }
+ if ((*buf)->ts2 != DS_MALLOC) {
+ pthread_setspecific((*buf)->ts2->key, *buf);
+ _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));)
+ }
+
+ (*buf)->len2 = new_len;
+#else
if (new_len <= (*buf)->len)
return 0; /* success */
if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC)
@@ -467,11 +597,24 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len),
}
(*buf)->len = new_len;
+#endif
return 0;
}
)
#endif
+#ifdef DEBUG_OPAQUE
+#define ast_str_alloca(init_len) \
+ ({ \
+ struct ast_str *__ast_str_buf; \
+ __ast_str_buf = alloca(sizeof(*__ast_str_buf) + init_len); \
+ __ast_str_buf->len2 = init_len; \
+ __ast_str_buf->used2 = 0; \
+ __ast_str_buf->ts2 = DS_ALLOCA; \
+ __ast_str_buf->str2[0] = '\0'; \
+ (__ast_str_buf); \
+ })
+#else
#define ast_str_alloca(init_len) \
({ \
struct ast_str *__ast_str_buf; \
@@ -482,6 +625,7 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len),
__ast_str_buf->str[0] = '\0'; \
(__ast_str_buf); \
})
+#endif
/*!
* \brief Retrieve a thread locally stored dynamic string
@@ -524,12 +668,20 @@ struct ast_str *ast_str_thread_get(struct ast_threadstorage *ts,
buf = (struct ast_str *)ast_threadstorage_get(ts, sizeof(*buf) + init_len);
if (buf == NULL)
return NULL;
-
+
+#ifdef DEBUG_OPAQUE
+ if (!buf->len2) {
+ buf->len2 = init_len;
+ buf->used2 = 0;
+ buf->ts2 = ts;
+ }
+#else
if (!buf->len) {
buf->len = init_len;
buf->used = 0;
buf->ts = ts;
}
+#endif
return buf;
}
@@ -544,12 +696,20 @@ struct ast_str *__ast_str_thread_get(struct ast_threadstorage *ts,
buf = (struct ast_str *)__ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line);
if (buf == NULL)
return NULL;
-
+
+#ifdef DEBUG_OPAQUE
+ if (!buf->len2) {
+ buf->len2 = init_len;
+ buf->used2 = 0;
+ buf->ts2 = ts;
+ }
+#else
if (!buf->len) {
buf->len = init_len;
buf->used = 0;
buf->ts = ts;
}
+#endif
return buf;
}
@@ -599,6 +759,8 @@ enum {
*/
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);
+char *__ast_str_helper2(struct ast_str **buf, size_t max_len,
+ const char *src, size_t maxsrc, int append, int escapecommas);
/*!
* \brief Set a dynamic string from a va_list
@@ -655,6 +817,78 @@ AST_INLINE_API(int __attribute__((format(printf, 3, 0))) ast_str_append_va(struc
}
)
+/*!\brief Set a dynamic string to a non-NULL terminated substring. */
+AST_INLINE_API(char *ast_str_set_substr(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc),
+{
+ return __ast_str_helper2(buf, maxlen, src, maxsrc, 0, 0);
+}
+)
+
+/*!\brief Append a non-NULL terminated substring to the end of a dynamic string. */
+AST_INLINE_API(char *ast_str_append_substr(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc),
+{
+ return __ast_str_helper2(buf, maxlen, src, maxsrc, 1, 0);
+}
+)
+
+/*!\brief Set a dynamic string to a non-NULL terminated substring, with escaping of commas. */
+AST_INLINE_API(char *ast_str_set_escapecommas(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc),
+{
+ return __ast_str_helper2(buf, maxlen, src, maxsrc, 0, 1);
+}
+)
+
+/*!\brief Append a non-NULL terminated substring to the end of a dynamic string, with escaping of commas. */
+AST_INLINE_API(char *ast_str_append_escapecommas(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc),
+{
+ return __ast_str_helper2(buf, maxlen, src, maxsrc, 1, 1);
+}
+)
+
+/*!\brief Wrapper for SQLGetData to use with dynamic strings
+ * \param buf Address of the pointer to the ast_str structure.
+ * \param maxlen The maximum size of the resulting string, or 0 for no limit.
+ * \param StatementHandle The statement handle from which to retrieve data.
+ * \param ColumnNumber Column number (1-based offset) for which to retrieve data.
+ * \param TargetType The SQL constant indicating what kind of data is to be retrieved (usually SQL_CHAR)
+ * \param StrLen_or_Ind A pointer to a length indicator, specifying the total length of data.
+ */
+#ifdef USE_ODBC
+#include <sql.h>
+#include <sqlext.h>
+#include <sqltypes.h>
+
+AST_INLINE_API(SQLRETURN ast_str_SQLGetData(struct ast_str **buf, size_t maxlen, SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLLEN *StrLen_or_Ind),
+{
+ SQLRETURN res;
+ if (maxlen == 0) {
+#ifdef DEBUG_OPAQUE
+ if (SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str2, 0, StrLen_or_Ind) == SQL_SUCCESS_WITH_INFO) {
+ ast_str_make_space(buf, *StrLen_or_Ind + 1);
+ }
+ maxlen = (*buf)->len2;
+ } else if (maxlen > 0) {
+ ast_str_make_space(buf, maxlen);
+ }
+ res = SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str2, maxlen, StrLen_or_Ind);
+ (*buf)->used2 = *StrLen_or_Ind;
+#else
+ if (SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str, 0, StrLen_or_Ind) == SQL_SUCCESS_WITH_INFO) {
+ ast_str_make_space(buf, *StrLen_or_Ind + 1);
+ }
+ maxlen = (*buf)->len;
+ } else if (maxlen > 0) {
+ ast_str_make_space(buf, maxlen);
+ }
+ res = SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str, maxlen, StrLen_or_Ind);
+ (*buf)->used = *StrLen_or_Ind;
+#endif
+ return res;
+}
+)
+#endif /* defined(USE_ODBC) */
+
+
/*!
* \brief Set a dynamic string using variable arguments
*
diff --git a/include/asterisk/tcptls.h b/include/asterisk/tcptls.h
index 6fb6d4b63..611709cbe 100644
--- a/include/asterisk/tcptls.h
+++ b/include/asterisk/tcptls.h
@@ -157,6 +157,6 @@ void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc);
int ast_ssl_setup(struct ast_tls_config *cfg);
HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *ser, void *buf, size_t count);
-HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, void *buf, size_t count);
+HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, const void *buf, size_t count);
#endif /* _ASTERISK_TCPTLS_H */
diff --git a/include/asterisk/threadstorage.h b/include/asterisk/threadstorage.h
index cf6d47e32..ab586974f 100644
--- a/include/asterisk/threadstorage.h
+++ b/include/asterisk/threadstorage.h
@@ -85,7 +85,11 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len
* \endcode
*/
#define AST_THREADSTORAGE(name) \
- AST_THREADSTORAGE_CUSTOM(name, NULL, ast_free_ptr)
+ AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr, static)
+#define AST_THREADSTORAGE_PUBLIC(name) \
+ AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr,)
+#define AST_THREADSTORAGE_EXTERNAL(name) \
+ extern struct ast_threadstorage name
/*!
* \brief Define a thread storage variable, with custom initialization and cleanup
@@ -103,10 +107,12 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len
* AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup);
* \endcode
*/
+#define AST_THREADSTORAGE_CUSTOM(a,b,c) AST_THREADSTORAGE_CUSTOM_SCOPE(a,b,c,static)
+
#if !defined(DEBUG_THREADLOCALS)
-#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
+#define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \
static void __init_##name(void); \
-static struct ast_threadstorage name = { \
+scope struct ast_threadstorage name = { \
.once = THREADSTORAGE_ONCE_INIT, \
.key_init = __init_##name, \
.custom_init = c_init, \
@@ -116,9 +122,9 @@ static void __init_##name(void) \
pthread_key_create(&(name).key, c_cleanup); \
}
#else /* defined(DEBUG_THREADLOCALS) */
-#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
+#define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \
static void __init_##name(void); \
-static struct ast_threadstorage name = { \
+scope struct ast_threadstorage name = { \
.once = THREADSTORAGE_ONCE_INIT, \
.key_init = __init_##name, \
.custom_init = c_init, \