Add a slightly trickier string-join interface for making NUL-terminated string messages

svn:r2659
This commit is contained in:
Nick Mathewson 2004-11-03 18:28:00 +00:00
parent 11979dc1f5
commit 11de62aa60
2 changed files with 29 additions and 9 deletions

View File

@ -301,32 +301,49 @@ int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
/** Allocate and return a new string containing the concatenation of /** Allocate and return a new string containing the concatenation of
* the elements of <b>sl</b>, in order, separated by <b>join</b>. If * the elements of <b>sl</b>, in order, separated by <b>join</b>. If
* <b>terminate</b> is true, also terminate the string with <b>join</b>. * <b>terminate</b> is true, also terminate the string with <b>join</b>.
* Requires that every element of <b>sl</b> is NUL-terminated string. * If <b>len_out</b> is not NULL, set <b>len_out</b> to the length of
* the returned string. Requires that every element of <b>sl</b> is
* NUL-terminated string.
*/ */
char *smartlist_join_strings(smartlist_t *sl, const char *join, int terminate) char *smartlist_join_strings(smartlist_t *sl, const char *join,
int terminate, size_t *len_out)
{
return smartlist_join_strings2(sl,join,strlen(join),terminate,len_out);
}
/** As smartlist_join_strings2, but instead of separating/terminated with a
* NUL-terminated string <b>join</b>, uses the <b>join_len</b>-byte sequence
* at <b>join</b>. (Useful for generating a sequenct of NUL-terminated
* strings.)
*/
char *smartlist_join_strings2(smartlist_t *sl, const char *join,
size_t join_len, int terminate, size_t *len_out)
{ {
int i; int i;
size_t n = 0, jlen; size_t n = 0;
char *r = NULL, *dst, *src; char *r = NULL, *dst, *src;
tor_assert(sl); tor_assert(sl);
tor_assert(join); tor_assert(join);
jlen = strlen(join); join_len = strlen(join);
for (i = 0; i < sl->num_used; ++i) { for (i = 0; i < sl->num_used; ++i) {
n += strlen(sl->list[i]); n += strlen(sl->list[i]);
n += jlen; n += join_len;
} }
if (!terminate) n -= jlen; if (!terminate) n -= join_len;
dst = r = tor_malloc(n+1); dst = r = tor_malloc(n+1);
for (i = 0; i < sl->num_used; ) { for (i = 0; i < sl->num_used; ) {
for (src = sl->list[i]; *src; ) for (src = sl->list[i]; *src; )
*dst++ = *src++; *dst++ = *src++;
if (++i < sl->num_used || terminate) { if (++i < sl->num_used || terminate) {
memcpy(dst, join, jlen); memcpy(dst, join, join_len);
dst += jlen; dst += join_len;
} }
} }
*dst = '\0'; *dst = '\0';
if (len_out)
*len_out = dst-r;
return r; return r;
} }

View File

@ -32,7 +32,10 @@ int smartlist_len(const smartlist_t *sl);
#define SPLIT_IGNORE_BLANK 0x02 #define SPLIT_IGNORE_BLANK 0x02
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
int flags, int max); int flags, int max);
char *smartlist_join_strings(smartlist_t *sl, const char *join, int terminate); char *smartlist_join_strings(smartlist_t *sl, const char *join, int terminate,
size_t *len_out);
char *smartlist_join_strings2(smartlist_t *sl, const char *join,
size_t join_len, int terminate, size_t *len_out);
#define SMARTLIST_FOREACH(sl, type, var, cmd) \ #define SMARTLIST_FOREACH(sl, type, var, cmd) \
do { \ do { \