From 5deac1e6e14c641bc5f6a30ce8027179f5164934 Mon Sep 17 00:00:00 2001 From: Evan Huus Date: Fri, 26 Apr 2013 21:30:24 +0000 Subject: [PATCH] Wmem string-buffer improvements: - better tests - fix a bug caught by the better tests - implement append_c and append_unichar, with tests Wmem string-buffers now have feature parity with their emem equivalents, so remove them from the TODO list. svn path=/trunk/; revision=49060 --- doc/README.wmem | 1 - epan/wmem/wmem_strbuf.c | 39 +++++++++++++++++++++++++++++++++++++-- epan/wmem/wmem_strbuf.h | 8 ++++++++ epan/wmem/wmem_test.c | 29 ++++++++++++++++++++++++++--- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/doc/README.wmem b/doc/README.wmem index d8d5b1d846..e8b0415055 100644 --- a/doc/README.wmem +++ b/doc/README.wmem @@ -322,7 +322,6 @@ intimately familiar with Glib's testing framework, but it does the job. The following is a list of things that wmem provides but are incomplete (i.e. missing common operations): - - string buffers - singly-linked list The following is an incomplete list of things that emem provides but wmem has diff --git a/epan/wmem/wmem_strbuf.c b/epan/wmem/wmem_strbuf.c index 25e8a254df..61712df230 100644 --- a/epan/wmem/wmem_strbuf.c +++ b/epan/wmem/wmem_strbuf.c @@ -53,6 +53,11 @@ struct _wmem_strbuf_t { gsize max_len; }; +/* _ROOM accounts for the null-terminator, _RAW_ROOM does not. + * Some functions need one, some functions need the other. */ +#define WMEM_STRBUF_ROOM(S) ((S)->alloc_len - (S)->len - 1) +#define WMEM_STRBUF_RAW_ROOM(S) ((S)->alloc_len - (S)->len) + wmem_strbuf_t * wmem_strbuf_sized_new(wmem_allocator_t *allocator, gsize alloc_len, gsize max_len) @@ -138,7 +143,7 @@ wmem_strbuf_append(wmem_strbuf_t *strbuf, const gchar *str) wmem_strbuf_grow(strbuf, append_len); - g_strlcpy(&strbuf->str[strbuf->len], str, strbuf->alloc_len); + g_strlcpy(&strbuf->str[strbuf->len], str, WMEM_STRBUF_RAW_ROOM(strbuf)); strbuf->len = MIN(strbuf->len + append_len, strbuf->alloc_len - 1); } @@ -158,7 +163,7 @@ wmem_strbuf_append_vprintf(wmem_strbuf_t *strbuf, const gchar *fmt, va_list ap) wmem_strbuf_grow(strbuf, append_len - 1); append_len = g_vsnprintf(&strbuf->str[strbuf->len], - (gulong) (strbuf->alloc_len - strbuf->len), + (gulong) WMEM_STRBUF_RAW_ROOM(strbuf), fmt, ap2); va_end(ap2); @@ -176,6 +181,36 @@ wmem_strbuf_append_printf(wmem_strbuf_t *strbuf, const gchar *format, ...) va_end(ap); } +void +wmem_strbuf_append_c(wmem_strbuf_t *strbuf, const gchar c) +{ + wmem_strbuf_grow(strbuf, 1); + + /* one for the char, one for the null-terminator */ + if (WMEM_STRBUF_ROOM(strbuf) >= 1) { + strbuf->str[strbuf->len] = c; + strbuf->len++; + strbuf->str[strbuf->len] = '\0'; + } +} + +void +wmem_strbuf_append_unichar(wmem_strbuf_t *strbuf, const gunichar c) +{ + gchar buf[6]; + gsize charlen; + + charlen = g_unichar_to_utf8(c, buf); + + wmem_strbuf_grow(strbuf, charlen); + + if (WMEM_STRBUF_ROOM(strbuf) >= charlen) { + memcpy(&strbuf->str[strbuf->len], buf, charlen); + strbuf->len += charlen; + strbuf->str[strbuf->len] = '\0'; + } +} + void wmem_strbuf_truncate(wmem_strbuf_t *strbuf, const gsize len) { diff --git a/epan/wmem/wmem_strbuf.h b/epan/wmem/wmem_strbuf.h index 34bb73d1e7..3e24a36e75 100644 --- a/epan/wmem/wmem_strbuf.h +++ b/epan/wmem/wmem_strbuf.h @@ -59,6 +59,14 @@ void wmem_strbuf_append_printf(wmem_strbuf_t *strbuf, const gchar *format, ...) G_GNUC_PRINTF(2, 3); +WS_DLL_PUBLIC +void +wmem_strbuf_append_c(wmem_strbuf_t *strbuf, const gchar c); + +WS_DLL_PUBLIC +void +wmem_strbuf_append_unichar(wmem_strbuf_t *strbuf, const gunichar c); + WS_DLL_PUBLIC void wmem_strbuf_truncate(wmem_strbuf_t *strbuf, const gsize len); diff --git a/epan/wmem/wmem_test.c b/epan/wmem/wmem_test.c index 5461e8d147..d6a574c233 100644 --- a/epan/wmem/wmem_test.c +++ b/epan/wmem/wmem_test.c @@ -368,9 +368,20 @@ wmem_test_strbuf(void) g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3a"); g_assert(wmem_strbuf_get_len(strbuf) == 10); - wmem_strbuf_truncate(strbuf, 10); - g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3a"); - g_assert(wmem_strbuf_get_len(strbuf) == 10); + wmem_strbuf_append_c(strbuf, 'q'); + g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq"); + g_assert(wmem_strbuf_get_len(strbuf) == 11); + + wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9")); + g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9"); + g_assert(wmem_strbuf_get_len(strbuf) == 13); + + wmem_strbuf_truncate(strbuf, 32); + wmem_strbuf_truncate(strbuf, 24); + wmem_strbuf_truncate(strbuf, 16); + wmem_strbuf_truncate(strbuf, 13); + g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9"); + g_assert(wmem_strbuf_get_len(strbuf) == 13); wmem_strbuf_truncate(strbuf, 3); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TES"); @@ -389,6 +400,18 @@ wmem_test_strbuf(void) g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); g_assert(wmem_strbuf_get_len(strbuf) == 9); + wmem_strbuf_append(strbuf, "abcdefghijklmnopqrstuvwxyz"); + g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); + g_assert(wmem_strbuf_get_len(strbuf) == 9); + + wmem_strbuf_append_c(strbuf, 'q'); + g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); + g_assert(wmem_strbuf_get_len(strbuf) == 9); + + wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9")); + g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); + g_assert(wmem_strbuf_get_len(strbuf) == 9); + wmem_free_all(allocator); strbuf = wmem_strbuf_new(allocator, "TEST");