MINOR: chunks: add chunk_strcat() and chunk_newstr()
These two new functions will make it easier to manipulate small strings
from within functions, because at many places, multiple short strings
are needed which do not deserve a malloc() nor a free(), and alloca()
is often discouraged. Since we already have trash chunks, it's convenient
to be able to allocate substrings from a chunk and use them later since
our functions already perform all the length checks. chunk_newstr() adds
a trailing zero at the end of a chunk and returns the pointer to the next
character, which can be used as an independant string. chunk_strcat()
does what it says.
(cherry picked from commit 601360b41d4caffd098edae17145f7d640fab63a)
[wt: not strictly needed but backported to ensure that any future patch
relying on it works as expected]
(cherry picked from commit 81c0599bb878e8a6fe7ddf3d318aba9e365ad1de)
diff --git a/include/common/chunk.h b/include/common/chunk.h
index 882cc93..b6433b8 100644
--- a/include/common/chunk.h
+++ b/include/common/chunk.h
@@ -101,6 +101,44 @@
return 1;
}
+/* appends str after <chk> followed by a trailing zero. Returns 0 in
+ * case of failure.
+ */
+static inline int chunk_strcat(struct chunk *chk, const char *str)
+{
+ size_t len;
+
+ len = strlen(str);
+
+ if (unlikely(chk->len + len >= chk->size))
+ return 0;
+
+ memcpy(chk->str + chk->len, str, len + 1);
+ chk->len += len;
+ return 1;
+}
+
+/* Adds a trailing zero to the current chunk and returns the pointer to the
+ * following part. The purpose is to be able to use a chunk as a series of
+ * short independant strings with chunk_* functions, which do not need to be
+ * released. Returns NULL if no space is available to ensure that the new
+ * string will have its own trailing zero. For example :
+ * chunk_init(&trash);
+ * pid = chunk_newstr(&trash);
+ * chunk_appendf(&trash, "%d", getpid()));
+ * name = chunk_newstr(&trash);
+ * chunk_appendf(&trash, "%s", gethosname());
+ * printf("hostname=<%s>, pid=<%d>\n", name, pid);
+ */
+static inline char *chunk_newstr(struct chunk *chk)
+{
+ if (chk->len + 1 >= chk->size)
+ return NULL;
+
+ chk->str[chk->len++] = 0;
+ return chk->str + chk->len;
+}
+
static inline void chunk_drop(struct chunk *chk)
{
chk->str = NULL;