[asterisk-commits] rizzo: branch rizzo/video_v2 r87623 - in /team/rizzo/video_v2: include/asteri...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Oct 30 13:04:51 CDT 2007
Author: rizzo
Date: Tue Oct 30 13:04:51 2007
New Revision: 87623
URL: http://svn.digium.com/view/asterisk?view=rev&rev=87623
Log:
stringfield cleanup - step2:
remove the zero-size markers around fields, and adapt the
code to the change. Still need to add a 'const' back, and
make sure that it compiles with picky compilers doing pedantic
type checks.
Modified:
team/rizzo/video_v2/include/asterisk/stringfields.h
team/rizzo/video_v2/main/utils.c
Modified: team/rizzo/video_v2/include/asterisk/stringfields.h
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/include/asterisk/stringfields.h?view=diff&rev=87623&r1=87622&r2=87623
==============================================================================
--- team/rizzo/video_v2/include/asterisk/stringfields.h (original)
+++ team/rizzo/video_v2/include/asterisk/stringfields.h Tue Oct 30 13:04:51 2007
@@ -116,10 +116,11 @@
/*!
\internal
- \brief Structure used to manage the storage for a set of string fields
+ \brief Structure used to manage the storage for a set of string fields.
+ Because of the way pools are managed, we can only allocate from the topmost
+ pool, so the numbers here reflect just that.
*/
struct ast_string_field_mgr {
- struct ast_string_field_pool *pool; /*!< the address of the pool's structure */
size_t size; /*!< the total size of the current pool */
size_t space; /*!< the space available in the current pool */
size_t used; /*!< the space used in the current pool */
@@ -129,13 +130,12 @@
\internal
\brief Initialize a field pool manager and fields
\param mgr Pointer to the pool manager structure
- \param size Amount of storage to allocate
- \param fields Pointer to the first entry of the field array
- \param num_fields Number of fields in the array
+ \param pool_head Pointer to the pool head (right before the fields)
+ \param needed Amount of storage to allocate
\return 0 on success, non-zero on failure
*/
-int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
- ast_string_field *fields, int num_fields);
+int __ast_string_field_init(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, size_t needed);
/*!
\internal
@@ -149,8 +149,8 @@
the field pool. If the requested amount of space is not available,
an additional pool will be allocated.
*/
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
- ast_string_field *fields);
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, size_t needed);
/*!
\internal
@@ -162,8 +162,8 @@
\return nothing
*/
void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
- ast_string_field *fields,
- int index, const char *format, ...);
+ struct ast_string_field_pool **pool_head,
+ int index, const char *format, ...);
/*!
\internal
@@ -177,32 +177,32 @@
\return nothing
*/
void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
- ast_string_field *fields,
- int index, const char *format, va_list a1, va_list a2);
+ struct ast_string_field_pool **pool_head,
+ int index, const char *format, va_list a1, va_list a2);
/*!
\brief Declare a string field
\param name The field name
*/
-#define AST_STRING_FIELD(name) const ast_string_field name
+#define AST_STRING_FIELD(name) ast_string_field name // was const ast_string ...
/*!
\brief Declare the fields needed in a structure
- \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one
+ \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one.
+ Internally, string fields are stored as a pointer to the head of the pool,
+ followed by individual string fields, and then a struct ast_string_field_mgr
+ which describes the space allocated.
+ We split the two variables so they can be used as markers around the
+ field_list, and this allows us to play various tricks with them.
+
+ \note: we rely on __field_mgr_pool to be a non-const pointer,
+ so we know its size is the same as sizeof(ast_string_field) and we
+ can cast it to char * when writing to the fields.
*/
#define AST_DECLARE_STRING_FIELDS(field_list) \
- ast_string_field __begin_field[0]; \
- field_list \
- ast_string_field __end_field[0]; \
+ struct ast_string_field_pool *__field_mgr_pool; \
+ field_list \
struct ast_string_field_mgr __field_mgr
-
-/*!
- \brief Get the number of string fields in a structure
- \param x Pointer to a structure containing fields
- \return the number of fields in the structure's definition
-*/
-#define ast_string_field_count(x) \
- (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field)
/*!
\brief Get the index of a field in a structure
@@ -212,7 +212,7 @@
array of fields
*/
#define ast_string_field_index(x, field) \
- (offsetof(typeof(*x), field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field)
+ (offsetof(typeof(*x), field) - offsetof(typeof(*x), __field_mgr_pool) - sizeof(ast_string_field)) / sizeof(ast_string_field)
/*!
\brief Initialize a field pool and fields
@@ -221,7 +221,7 @@
\return 0 on success, non-zero on failure
*/
#define ast_string_field_init(x, size) \
- __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x))
+ __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size)
/*!
\brief Set a field to a simple string value
@@ -230,37 +230,17 @@
\param data String value to be copied into the field
\return nothing
*/
-#define ast_string_field_index_set(x, index, data) do { \
- char *__zz__ = (char*)(x)->__begin_field[index]; \
- size_t __dlen__ = strlen(data); \
- if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
- } else { \
- if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
- strcpy(__zz__, data); \
- } else { \
- if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0]))) \
- strcpy((char*)(x)->__begin_field[index], data); \
- } \
- } \
- } while (0)
-
-#ifdef FOR_TEST
-#define ast_string_field_index_logset(x, index, data, logstr) do { \
- char *__zz__ = (char*)(x)->__begin_field[index]; \
- size_t __dlen__ = strlen(data); \
- if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
- } else { \
- if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
- ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, data); \
- strcpy(__zz__, data); \
- } else { \
- ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, data, __zz__); \
- if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0]))) \
- strcpy((char*)(x)->__begin_field[index], data); \
- } \
- } \
- } while (0)
-#endif
+
+#define ast_string_field_index_set(x, index, data) do { \
+ size_t __dlen__ = strlen(data); \
+ const char **__p__ = (const char **)&((x)->__field_mgr_pool) + 1 + index; \
+ if (__dlen__ == 0) \
+ *__p__ = __ast_string_field_empty; \
+ else if (__dlen__ <= strlen(*__p__)) \
+ strcpy((char *)*__p__, data); \
+ else if ( (*__p__ = __ast_string_field_alloc_space(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__ + 1) ) ) \
+ strcpy((char *)*__p__, data); \
+ } while (0)
/*!
\brief Set a field to a simple string value
@@ -269,13 +249,11 @@
\param data String value to be copied into the field
\return nothing
*/
-#define ast_string_field_set(x, field, data) \
- ast_string_field_index_set(x, ast_string_field_index(x, field), data)
-
-#ifdef FOR_TEST
-#define ast_string_field_logset(x, field, data, logstr) \
- ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr)
-#endif
+#define ast_string_field_set(x, field, data) do { \
+ int index = ast_string_field_index(x, field); \
+ ast_string_field_index_set(x, index, data); \
+ } while (0)
+
/*!
\brief Set a field to a complex (built) value
@@ -286,7 +264,7 @@
\return nothing
*/
#define ast_string_field_index_build(x, index, fmt, args...) \
- __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], index, fmt, args)
+ __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, index, fmt, args)
/*!
\brief Set a field to a complex (built) value with prebuilt va_lists.
@@ -298,7 +276,7 @@
\return nothing
*/
#define ast_string_field_index_build_va(x, index, fmt, args1, args2) \
- __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__begin_field[0], index, fmt, args1, args2)
+ __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, index, fmt, args1, args2)
/*!
\brief Set a field to a complex (built) value
@@ -309,7 +287,7 @@
\return nothing
*/
#define ast_string_field_build(x, field, fmt, args...) \
- ast_string_field_index_build(x, ast_string_field_index(x, field), fmt, args)
+ __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, ast_string_field_index(x, field), fmt, args)
/*!
\brief Set a field to a complex (built) value
@@ -321,7 +299,7 @@
\return nothing
*/
#define ast_string_field_build_va(x, field, fmt, args1, args2) \
- ast_string_field_index_build_va(x, ast_string_field_index(x, field), fmt, args1, args2)
+ __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, ast_string_field_index(x, field), fmt, args1, args2)
/*!
\brief Free a field's value.
@@ -347,8 +325,9 @@
occupied by the field's value is \b not recovered; the field
pointer is just changed to point to an empty string.
*/
-#define ast_string_field_free(x, field) \
- ast_string_field_index_free(x, ast_string_field_index(x, field))
+#define ast_string_field_free(x, field) do { \
+ (x)->field = __ast_string_field_empty ; \
+ } while (0)
/*!
\brief Free the stringfield storage pools attached to a structure
@@ -359,12 +338,12 @@
structure; it should only be called immediately before freeing
the structure itself.
*/
-#define ast_string_field_free_pools(x) do { \
- struct ast_string_field_pool *this, *prev; \
- for (this = (x)->__field_mgr.pool; this; this = prev) { \
- prev = this->prev; \
- free(this); \
- } \
+#define ast_string_field_free_pools(x) do { \
+ struct ast_string_field_pool *this; \
+ while ( (this = (x)->__field_mgr_pool)) { \
+ (x)->__field_mgr_pool = this->prev; \
+ free(this); \
+ } \
} while(0)
/*!
@@ -376,12 +355,12 @@
attached to the structure will be available for use by
stringfields again.
*/
-#define ast_string_field_free_all(x) do { \
- int index; \
- for (index = 0; index < ast_string_field_count(x); index++) \
- ast_string_field_index_free(x, index); \
- (x)->__field_mgr.used = 0; \
- (x)->__field_mgr.space = (x)->__field_mgr.size; \
+#define ast_string_field_free_all(x) do { \
+ const char **__p__ = (const char **)&(x)->__field_mgr_pool + 1; \
+ while ((struct ast_string_field_mgr *)__p__ != &(x)->__field_mgr) \
+ *__p__++ = __ast_string_field_empty; \
+ (x)->__field_mgr.used = 0; \
+ (x)->__field_mgr.space = (x)->__field_mgr.size; \
} while(0)
#endif /* _ASTERISK_STRINGFIELDS_H */
Modified: team/rizzo/video_v2/main/utils.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/main/utils.c?view=diff&rev=87623&r1=87622&r2=87623
==============================================================================
--- team/rizzo/video_v2/main/utils.c (original)
+++ team/rizzo/video_v2/main/utils.c Tue Oct 30 13:04:51 2007
@@ -1136,17 +1136,27 @@
s[ofs] = '\0';
}
+/*
+ * stringfields support routines.
+ */
+
+/*! \brief the empty string for stringfield */
const char __ast_string_field_empty[] = "";
-static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
+/*! \brief add a new block to the pool.
+ * We can only allocate from the topmost pool, so the
+ * fields in *mgr reflect the size of that only.
+ */
+static int add_string_pool(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, size_t size)
{
struct ast_string_field_pool *pool;
if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
return -1;
- pool->prev = mgr->pool;
- mgr->pool = pool;
+ pool->prev = *pool_head;
+ *pool_head = pool;
mgr->size = size;
mgr->space = size;
mgr->used = 0;
@@ -1154,22 +1164,26 @@
return 0;
}
-int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
- ast_string_field *fields, int num_fields)
-{
- int index;
-
- if (add_string_pool(mgr, size))
+/*
+ * This is an internal API, code should not use it directly.
+ * Add a pool to the array, then initialize fields as empty.
+ */
+int __ast_string_field_init(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, size_t size)
+{
+ const char **p = (const char **)pool_head + 1;
+
+ if (add_string_pool(mgr, pool_head, size))
return -1;
- for (index = 0; index < num_fields; index++)
- fields[index] = __ast_string_field_empty;
+ while ((struct ast_string_field_mgr *)p != mgr)
+ *p++ = __ast_string_field_empty;
return 0;
}
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
- ast_string_field *fields)
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, size_t needed)
{
char *result = NULL;
@@ -1179,23 +1193,25 @@
while (new_size < needed)
new_size *= 2;
- if (add_string_pool(mgr, new_size))
+ if (add_string_pool(mgr, pool_head, new_size))
return NULL;
}
- result = mgr->pool->base + mgr->used;
+ result = (*pool_head)->base + mgr->used;
mgr->used += needed;
mgr->space -= needed;
return result;
}
void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
- ast_string_field *fields,
- int index, const char *format, va_list ap1, va_list ap2)
+ struct ast_string_field_pool **pool_head,
+ int index, const char *format, va_list ap1, va_list ap2)
{
size_t needed;
-
- needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
+ char *dst = (*pool_head)->base + mgr->used;
+ const char **p = (const char **)pool_head + 1;
+
+ needed = vsnprintf(dst, mgr->space, format, ap1) + 1;
va_end(ap1);
@@ -1205,31 +1221,33 @@
while (new_size < needed)
new_size *= 2;
- if (add_string_pool(mgr, new_size))
+ if (add_string_pool(mgr, pool_head, new_size))
return;
- vsprintf(mgr->pool->base + mgr->used, format, ap2);
- }
-
- fields[index] = mgr->pool->base + mgr->used;
+ dst = (*pool_head)->base + mgr->used;
+ vsprintf(dst, format, ap2);
+ }
+
+ p[index] = dst;
mgr->used += needed;
mgr->space -= needed;
}
void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
- ast_string_field *fields,
- int index, const char *format, ...)
+ struct ast_string_field_pool **pool_head,
+ int index, const char *format, ...)
{
va_list ap1, ap2;
va_start(ap1, format);
va_start(ap2, format); /* va_copy does not exist on FreeBSD */
- __ast_string_field_index_build_va(mgr, fields, index, format, ap1, ap2);
+ __ast_string_field_index_build_va(mgr, pool_head, index, format, ap1, ap2);
va_end(ap1);
va_end(ap2);
}
+/* end of stringfields support */
AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
More information about the asterisk-commits
mailing list