[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