[asterisk-commits] rizzo: branch rizzo/video_v2 r87742 - in /team/rizzo/video_v2: channels/ incl...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Oct 30 18:30:20 CDT 2007
Author: rizzo
Date: Tue Oct 30 18:30:20 2007
New Revision: 87742
URL: http://svn.digium.com/view/asterisk?view=rev&rev=87742
Log:
almost final (except for remaining bugfixes) cleanup of stringfields.
In this episode:
+ as proposed in the mailing list, change the API to use _ptr_ instead of
_index_ to fields. I think this is far more natural for the programmer,
and simpler to implement. For the records, this feature is used only
in one place in the code.
+ try to improve documentation of the stringfields API;
+ simplify the structure of memory pools, now saving one size_t per pool
entry.
What remains to do now is rename internal APIs to make a better
job at hiding them, and fix ast_string_field_free_all to release
unusable pools.
Modified:
team/rizzo/video_v2/channels/chan_sip.c
team/rizzo/video_v2/include/asterisk/stringfields.h
team/rizzo/video_v2/main/utils.c
Modified: team/rizzo/video_v2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/channels/chan_sip.c?view=diff&rev=87742&r1=87741&r2=87742
==============================================================================
--- team/rizzo/video_v2/channels/chan_sip.c (original)
+++ team/rizzo/video_v2/channels/chan_sip.c Tue Oct 30 18:30:20 2007
@@ -12430,13 +12430,13 @@
/* table of recognised keywords, and places where they should be copied */
const struct x {
const char *key;
- int field_index;
+ const ast_string_field *field;
} *i, keys[] = {
- { "realm=", ast_string_field_index(p, realm) },
- { "nonce=", ast_string_field_index(p, nonce) },
- { "opaque=", ast_string_field_index(p, opaque) },
- { "qop=", ast_string_field_index(p, qop) },
- { "domain=", ast_string_field_index(p, domain) },
+ { "realm=", &p->realm },
+ { "nonce=", &p->nonce },
+ { "opaque=", &p->opaque },
+ { "qop=", &p->qop },
+ { "domain=", &p->domain },
{ NULL, 0 },
};
@@ -12464,7 +12464,7 @@
separator = ",";
}
strsep(&c, separator); /* clear separator and move ptr */
- ast_string_field_index_set(p, i->field_index, src);
+ ast_string_field_ptr_set(p, i->field, src);
break;
}
if (i->key == NULL) /* not found, try ',' */
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=87742&r1=87741&r2=87742
==============================================================================
--- team/rizzo/video_v2/include/asterisk/stringfields.h (original)
+++ team/rizzo/video_v2/include/asterisk/stringfields.h Tue Oct 30 18:30:20 2007
@@ -24,16 +24,16 @@
as fixed-size buffers or requiring individual allocations for
for each field.
- Using this functionality is quite simple... an example structure
+ Using this functionality is quite simple. An example structure
with three fields is defined like this:
\code
struct sample_fields {
int x1;
AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(address);
- AST_STRING_FIELD(password);
+ AST_STRING_FIELD(foo);
+ AST_STRING_FIELD(bar);
+ AST_STRING_FIELD(blah);
);
long x2;
};
@@ -54,22 +54,35 @@
}
if (!sample) {
- ...
+ ... handle error
}
\endcode
Fields will default to pointing to an empty string, and will
revert to that when ast_string_field_set() is called with a NULL
- argument: a string field will \b never contain NULL.
-
- Using the fields is much like using regular 'char *' fields
+ argument: a string field will \b never contain NULL (this is not
+ needed in this code, but comes from external requirements).
+
+ Using the fields is much like using regular 'const char *' fields
in the structure, except that writing into them must be done
- using wrapper macros defined in this file.
-
+ using wrapper macros defined in this file, and assignments are
+ always by value (i.e. strings are copied).
Storing simple values into fields can be done using ast_string_field_set();
more complex values (using printf-style format strings) can be stored
- using ast_string_field_build().
-
+ using ast_string_field_build(). Variant of these function allow passing
+ a pointer to the field as an argument:
+ \code
+ ast_string_field_set(sample, foo, "infinite loop");
+ ast_string_field_set(sample, foo, NULL); // set to an empty string
+ ast_string_field_ptr_set(sample, &sample->bar, "right way");
+ ast_string_field_build(sample, blah, "%d %s", zipcode, city);
+ ast_string_field_ptr_build(sample, &sample->blah, "%d %s", zipcode, city);
+ \endcode
+ There are two more varargs versions of the 'build' functions,
+ and ast_string_field_free_all() which is used to clear all stringfields
+ to the default values (meant to be used when resetting a
+ structure to its initial value).
+
When the structure instance is no longer needed, the fields
and their storage pool must be freed:
@@ -121,9 +134,8 @@
pool, so the numbers here reflect just that.
*/
struct ast_string_field_mgr {
- 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 */
+ size_t size; /*!< the total size of the current pool */
+ size_t used; /*!< the space used in the current pool */
};
/*!
@@ -157,28 +169,28 @@
\brief Set a field to a complex (built) value
\param mgr Pointer to the pool manager structure
\param fields Pointer to the first entry of the field array
- \param index Index position of the field within the structure
+ \param ptr Pointer to a field within the structure
\param format printf-style format string
\return nothing
*/
-void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
+void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
struct ast_string_field_pool **pool_head,
- int index, const char *format, ...);
+ const ast_string_field *ptr, const char *format, ...);
/*!
\internal
\brief Set a field to a complex (built) value
\param mgr Pointer to the pool manager structure
\param fields Pointer to the first entry of the field array
- \param index Index position of the field within the structure
+ \param ptr Pointer to a field within the structure
\param format printf-style format string
\param args va_list of the args for the format_string
\param args_again a copy of the first va_list for the sake of bsd not having a copy routine
\return nothing
*/
-void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
+void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
struct ast_string_field_pool **pool_head,
- int index, const char *format, va_list a1, va_list a2);
+ const ast_string_field *ptr, const char *format, va_list a1, va_list a2);
/*!
\brief Declare a string field
@@ -195,12 +207,9 @@
We split the two variables so they can be used as markers around the
field_list, and this allows us to determine how many entries are in
the field, and play with them.
- In particular, for writing to the field, we rely on __field_mgr_pool to be
- a non-const pointer, so 1) we know it has the same size as ast_string_field,
- and 2) we can cast it to const char * and use it as the base of an array to
- write to the fields.
- Because of this, the low-level functions to manipulate stringfields
- use the index instead of the name of the field.
+ In particular, for writing to the fields, we rely on __field_mgr_pool to be
+ a non-const pointer, so we know it has the same size as ast_string_field,
+ and we can use it to locate the fields.
*/
#define AST_DECLARE_STRING_FIELDS(field_list) \
struct ast_string_field_pool *__field_mgr_pool; \
@@ -208,16 +217,6 @@
struct ast_string_field_mgr __field_mgr
/*!
- \brief Get the index of a field in a structure
- \param x Pointer to a structure containing fields
- \param field Name of the field to locate
- \return the position (index) of the field within the structure's
- array of fields
-*/
-#define ast_string_field_index(x, 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
\param x Pointer to a structure containing fields
\param size Amount of storage to allocate
@@ -229,21 +228,21 @@
/*!
\brief Set a field to a simple string value
\param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
+ \param ptr Pointer to a field within the structure
\param data String value to be copied into the field
\return nothing
*/
-#define ast_string_field_index_set(x, index, data) do { \
- const char *__d__ = (data); \
- size_t __dlen__ = (__d__) ? strlen(__d__) : 0; \
- 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__, __d__); \
+#define ast_string_field_ptr_set(x, ptr, data) do { \
+ const char *__d__ = (data); \
+ size_t __dlen__ = (__d__) ? strlen(__d__) : 0; \
+ const char **__p__ = (const char **)(ptr); \
+ if (__dlen__ == 0) \
+ *__p__ = __ast_string_field_empty; \
+ else if (__dlen__ <= strlen(*__p__)) \
+ strcpy((char *)*__p__, __d__); \
else if ( (*__p__ = __ast_string_field_alloc_space(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__ + 1) ) ) \
- strcpy((char *)*__p__, __d__); \
+ strcpy((char *)*__p__, __d__); \
} while (0)
/*!
@@ -253,34 +252,33 @@
\param data String value to be copied into the field
\return nothing
*/
-#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); \
+#define ast_string_field_set(x, field, data) do { \
+ ast_string_field_ptr_set(x, &(x)->field, data); \
} while (0)
/*!
\brief Set a field to a complex (built) value
\param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
+ \param ptr Pointer to a field within the structure
\param fmt printf-style format string
\param args Arguments for format string
\return nothing
*/
-#define ast_string_field_index_build(x, index, fmt, args...) \
- __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, index, fmt, args)
+#define ast_string_field_ptr_build(x, ptr, fmt, args...) \
+ __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, ptr, fmt, args)
/*!
\brief Set a field to a complex (built) value with prebuilt va_lists.
\param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
+ \param ptr Pointer to a field within the structure
\param fmt printf-style format string
\param args1 Arguments for format string in va_list format
\param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation
\return nothing
*/
-#define ast_string_field_index_build_va(x, index, fmt, args1, args2) \
- __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, index, fmt, args1, args2)
+#define ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) \
+ __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, ptr, fmt, args1, args2)
/*!
\brief Set a field to a complex (built) value
@@ -291,7 +289,7 @@
\return nothing
*/
#define ast_string_field_build(x, field, fmt, args...) \
- __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, ast_string_field_index(x, field), fmt, args)
+ __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, &(x)->field, fmt, args)
/*!
\brief Set a field to a complex (built) value
@@ -303,7 +301,7 @@
\return nothing
*/
#define ast_string_field_build_va(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)
+ __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, &(x)->field, fmt, args1, args2)
/*!
\brief Free the stringfield storage pools attached to a structure
@@ -337,7 +335,6 @@
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
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=87742&r1=87741&r2=87742
==============================================================================
--- team/rizzo/video_v2/main/utils.c (original)
+++ team/rizzo/video_v2/main/utils.c Tue Oct 30 18:30:20 2007
@@ -1140,8 +1140,7 @@
* stringfields support routines.
*/
-/*! \brief the empty string for stringfield */
-const char __ast_string_field_empty[] = "";
+const char __ast_string_field_empty[] = ""; /*!< the empty string */
/*! \brief add a new block to the pool.
* We can only allocate from the topmost pool, so the
@@ -1158,7 +1157,6 @@
pool->prev = *pool_head;
*pool_head = pool;
mgr->size = size;
- mgr->space = size;
mgr->used = 0;
return 0;
@@ -1186,8 +1184,9 @@
struct ast_string_field_pool **pool_head, size_t needed)
{
char *result = NULL;
-
- if (__builtin_expect(needed > mgr->space, 0)) {
+ size_t space = mgr->size - mgr->used;
+
+ if (__builtin_expect(needed > space, 0)) {
size_t new_size = mgr->size * 2;
while (new_size < needed)
@@ -1199,23 +1198,24 @@
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,
+void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
struct ast_string_field_pool **pool_head,
- int index, const char *format, va_list ap1, va_list ap2)
+ const ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
{
size_t needed;
char *dst = (*pool_head)->base + mgr->used;
- const char **p = (const char **)pool_head + 1;
-
- needed = vsnprintf(dst, mgr->space, format, ap1) + 1;
+ const char **p = (const char **)ptr;
+ size_t space = mgr->size - mgr->used;
+
+ /* try to write using available space */
+ needed = vsnprintf(dst, space, format, ap1) + 1;
va_end(ap1);
- if (needed > mgr->space) {
+ if (needed > space) { /* if it fails, reallocate */
size_t new_size = mgr->size * 2;
while (new_size < needed)
@@ -1228,21 +1228,20 @@
vsprintf(dst, format, ap2);
}
- p[index] = dst;
+ *p = dst;
mgr->used += needed;
- mgr->space -= needed;
-}
-
-void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
+}
+
+void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
struct ast_string_field_pool **pool_head,
- int index, const char *format, ...)
+ const ast_string_field *ptr, 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, pool_head, index, format, ap1, ap2);
+ __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
va_end(ap1);
va_end(ap2);
More information about the asterisk-commits
mailing list