Wmem string-buffer improvements:
authorEvan Huus <eapache@gmail.com>
Fri, 26 Apr 2013 21:30:24 +0000 (21:30 -0000)
committerEvan Huus <eapache@gmail.com>
Fri, 26 Apr 2013 21:30:24 +0000 (21:30 -0000)
- 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
epan/wmem/wmem_strbuf.c
epan/wmem/wmem_strbuf.h
epan/wmem/wmem_test.c

index d8d5b1d8465aee104c655e342f7c882b53429d5d..e8b04150558b7b651fb7a13e0f0718831c22d425 100644 (file)
@@ -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
index 25e8a254dfba750442dd0cb12fc26e2e5c956fc7..61712df230c1220dd829dc7c9f9ca2f21c6284e4 100644 (file)
@@ -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)
 {
index 34bb73d1e7ae508dde2f6a2a888f0b99df100e51..3e24a36e7528b50851cc130267d69f67e101ae77 100644 (file)
@@ -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);
index 5461e8d14711882327ad9037298b0514ccc4c423..d6a574c2337bf4f74f6cce0d5af966d01540059e 100644 (file)
@@ -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");