From 66a1c08e6b975d38d92c9ce79b51f9f6658d2438 Mon Sep 17 00:00:00 2001
From: Craig Tiller <craig.tiller@gmail.com>
Date: Fri, 23 Jan 2015 13:31:59 -0800
Subject: [PATCH] Utilities for concatenating many strings

---
 src/core/support/string.c | 43 +++++++++++++++++++++++++++++++++++++++
 src/core/support/string.h | 15 ++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/src/core/support/string.c b/src/core/support/string.c
index 9b5cac7596..87c2cd351b 100644
--- a/src/core/support/string.c
+++ b/src/core/support/string.c
@@ -152,3 +152,46 @@ int gpr_ltoa(long value, char *string) {
   string[i] = 0;
   return i;
 }
+
+char *gpr_strjoin(const char **strs, size_t nstrs) {
+  size_t out_length = 0;
+  size_t i;
+  char *out;
+  for (i = 0; i < nstrs; i++) {
+    out_length += strlen(strs[i]);
+  }
+  out_length += 1;  /* null terminator */
+  out = gpr_malloc(out_length);
+  out_length = 0;
+  for (i = 0; i < nstrs; i++) {
+    size_t slen = strlen(strs[i]);
+    memcpy(out + out_length, strs[i], slen);
+    out_length += slen;
+  }
+  out[out_length] = 0;
+  return out;
+}
+
+void gpr_strvec_init(gpr_strvec *sv) {
+  memset(sv, 0, sizeof(*sv));
+}
+
+void gpr_strvec_destroy(gpr_strvec *sv) {
+  size_t i;
+  for (i = 0; i < sv->count; i++) {
+    gpr_free(sv->strs[i]);
+  }
+  gpr_free(sv->strs);
+}
+
+void gpr_strvec_add(gpr_strvec *sv, char *str) {
+  if (sv->count == sv->capacity) {
+    sv->capacity = GPR_MAX(sv->capacity + 8, sv->capacity * 3 / 2);
+    sv->strs = gpr_realloc(sv->strs, sizeof(char*) * sv->capacity);
+  }
+  sv->strs[sv->count++] = str;
+}
+
+char *gpr_strvec_flatten(gpr_strvec *sv) {
+  return gpr_strjoin((const char**)sv->strs, sv->count);
+}
diff --git a/src/core/support/string.h b/src/core/support/string.h
index 71bd3f84e3..f2bf8c1c3a 100644
--- a/src/core/support/string.h
+++ b/src/core/support/string.h
@@ -80,6 +80,21 @@ void gpr_reverse_bytes(char *str, int len);
    the result is undefined. */
 int gpr_asprintf(char **strp, const char *format, ...);
 
+/* Join a set of strings, returning the resulting string */
+char *gpr_strjoin(const char **strs, size_t nstrs);
+
+/* A vector of strings... addition takes ownership of strings */
+typedef struct {
+  char **strs;
+  size_t count;
+  size_t capacity;
+} gpr_strvec;
+
+void gpr_strvec_init(gpr_strvec *strs);
+void gpr_strvec_destroy(gpr_strvec *strs);
+void gpr_strvec_add(gpr_strvec *strs, char *add);
+char *gpr_strvec_flatten(gpr_strvec *strs);
+
 #ifdef __cplusplus
 }
 #endif
-- 
GitLab