summaryrefslogtreecommitdiff
path: root/epan/emem.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2009-03-27 23:05:37 +0000
committerGerald Combs <gerald@wireshark.org>2009-03-27 23:05:37 +0000
commit446d43351ce4f4b03cc9b85831445d7e48e72dc6 (patch)
tree326ce04ad1aac3020ac517473660028fa8f60e6a /epan/emem.c
parentab972611dacb37eb6bdd52ea1ece369070732279 (diff)
downloadwireshark-446d43351ce4f4b03cc9b85831445d7e48e72dc6.tar.gz
Add initial support for string buffers - ep_allocated, growable strings
similar to GLib's GStrings. Use them to create the list of TCP flags. svn path=/trunk/; revision=27872
Diffstat (limited to 'epan/emem.c')
-rw-r--r--epan/emem.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/epan/emem.c b/epan/emem.c
index be64881b04..38ab1005a6 100644
--- a/epan/emem.c
+++ b/epan/emem.c
@@ -1652,3 +1652,156 @@ emem_print_tree(emem_tree_t* emem_tree)
if(emem_tree->tree)
emem_tree_print_nodes(emem_tree->tree, 0);
}
+
+/*
+ * String buffers
+ */
+
+/*
+ * Presumably we're using these routines for building strings for the tree.
+ * Use ITEM_LABEL_LENGTH as the basis for our default lengths.
+ */
+
+#define DEFAULT_STRBUF_LEN (ITEM_LABEL_LENGTH / 10)
+#define MAX_STRBUF_LEN 65536
+
+static gsize
+next_size(gsize cur_len, gsize wanted_len, gsize max_len) {
+ if (max_len < 1 || max_len > MAX_STRBUF_LEN) {
+ max_len = MAX_STRBUF_LEN;
+ }
+
+ if (cur_len < 1) {
+ cur_len = DEFAULT_STRBUF_LEN;
+ }
+
+ while (cur_len < wanted_len) {
+ cur_len *= 2;
+ }
+
+ return cur_len < max_len ? cur_len : max_len;
+}
+
+static void
+ep_strbuf_grow(emem_strbuf_t *strbuf, gsize wanted_len) {
+ gsize new_alloc_len;
+ gchar *new_str;
+
+ if (!strbuf || strbuf->alloc_len >= strbuf->max_len) {
+ return;
+ }
+
+ new_alloc_len = next_size(strbuf->len, wanted_len, strbuf->max_len);
+ new_str = ep_alloc(new_alloc_len);
+ g_strlcpy(new_str, strbuf->str, new_alloc_len);
+
+ strbuf->alloc_len = new_alloc_len;
+ strbuf->str = new_str;
+}
+
+emem_strbuf_t *
+ep_strbuf_sized_new(gsize len, gsize max_len) {
+ emem_strbuf_t *strbuf;
+
+ strbuf = ep_alloc(sizeof(emem_strbuf_t));
+
+ if (len > 0) {
+ strbuf->str = ep_alloc(len);
+ strbuf->str[0] = '\0';
+ } else {
+ strbuf->str = ep_strdup("");
+ }
+
+ strbuf->len = len;
+ strbuf->alloc_len = len;
+ strbuf->max_len = max_len;
+ return strbuf;
+}
+
+emem_strbuf_t *
+ep_strbuf_new(const gchar *init) {
+ emem_strbuf_t *strbuf;
+
+ strbuf = ep_strbuf_sized_new(next_size(0, strlen(init), 0), 0);
+
+ g_strlcpy(strbuf->str, init, strbuf->alloc_len);
+ return strbuf;
+}
+
+emem_strbuf_t *
+ep_strbuf_new_label(const gchar *init) {
+ emem_strbuf_t *strbuf;
+ gsize init_size;
+
+ if (!init) {
+ init = "";
+ }
+
+ init_size = strlen(init);
+ strbuf = ep_strbuf_sized_new(init_size > DEFAULT_STRBUF_LEN ? init_size : DEFAULT_STRBUF_LEN,
+ ITEM_LABEL_LENGTH);
+
+ g_strlcpy(strbuf->str, init, strbuf->alloc_len);
+ strbuf->len = MIN(init_size, strbuf->alloc_len);
+ return strbuf;
+}
+
+void
+ep_strbuf_append(emem_strbuf_t *strbuf, const gchar *str) {
+ gsize add_len;
+
+ if (!strbuf || !str) {
+ return;
+ }
+
+ add_len = strlen(str);
+
+ if (strbuf->len + add_len > strbuf->alloc_len) {
+ ep_strbuf_grow(strbuf, strbuf->len + add_len);
+ }
+
+ g_strlcpy(&strbuf->str[strbuf->len], str, strbuf->alloc_len - add_len);
+ strbuf->len += add_len;
+}
+
+void
+ep_strbuf_append_vprintf(emem_strbuf_t *strbuf, const gchar *format, va_list ap) {
+ va_list ap2;
+ gsize add_len, full_len;
+
+ G_VA_COPY(ap2, ap);
+
+ add_len = g_printf_string_upper_bound(format, ap);
+
+ if (strbuf->len + add_len > strbuf->alloc_len) {
+ ep_strbuf_grow(strbuf, strbuf->len + add_len);
+ }
+
+ if (strbuf->len + add_len > strbuf->alloc_len) {
+ add_len = strbuf->alloc_len - strbuf->len;
+ }
+
+ full_len = g_vsnprintf(&strbuf->str[strbuf->len], add_len, format, ap2);
+ strbuf->len += MIN(add_len, full_len);
+ va_end(ap2);
+
+}
+
+void
+ep_strbuf_append_printf(emem_strbuf_t *strbuf, const gchar *format, ...) {
+ va_list ap;
+
+ va_start(ap, format);
+ ep_strbuf_append_vprintf(strbuf, format, ap);
+ va_end(ap);
+}
+
+void
+ep_strbuf_truncate(emem_strbuf_t *strbuf, gsize len) {
+ if (!strbuf || len >= strbuf->len) {
+ return;
+ }
+
+ strbuf->str[len] = '\0';
+ strbuf->len = len;
+}