You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/09/11 02:19:55 UTC

svn commit: r1383181 - in /subversion/trunk/subversion: libsvn_subr/string.c tests/libsvn_subr/string-test.c

Author: stefan2
Date: Tue Sep 11 00:19:54 2012
New Revision: 1383181

URL: http://svn.apache.org/viewvc?rev=1383181&view=rev
Log:
Add stringbuf functions for insertion, removal and replacement of substrings.

* subversion/include/svn_string.h
  (svn_stringbuf_insert,
   svn_stringbuf_remove,
   svn_stringbuf_replace): declare new API
* subversion/libsvn_subr/string.c
  (svn_stringbuf_insert,
   svn_stringbuf_remove,
   svn_stringbuf_replace): implement new API
* subversion/tests/libsvn_subr/string-test.c
  (expect_stringbuf_equal): new utility function
  (test_stringbuf_insert,
   test_stringbuf_remove,
   test_stringbuf_replace): new tests
  (test_funcs): register them

Modified:
    subversion/trunk/subversion/libsvn_subr/string.c
    subversion/trunk/subversion/tests/libsvn_subr/string-test.c

Modified: subversion/trunk/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/string.c?rev=1383181&r1=1383180&r2=1383181&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/string.c (original)
+++ subversion/trunk/subversion/libsvn_subr/string.c Tue Sep 11 00:19:54 2012
@@ -578,6 +578,80 @@ svn_stringbuf_appendcstr(svn_stringbuf_t
   svn_stringbuf_appendbytes(targetstr, cstr, strlen(cstr));
 }
 
+void
+svn_stringbuf_insert(svn_stringbuf_t *str,
+                     apr_size_t pos,
+                     const char *bytes,
+                     apr_size_t count)
+{
+  if (bytes + count > str->data && bytes < str->data + str->blocksize)
+    {
+      /* special case: BYTES overlaps with this string -> copy the source */
+      const char *temp = apr_pstrndup(str->pool, bytes, count);
+      svn_stringbuf_insert(str, pos, temp, count);
+    }
+  else
+    {
+      if (pos > str->len)
+        pos = str->len;
+
+      svn_stringbuf_ensure(str, str->len + count);
+      memmove(str->data + pos + count, str->data + pos, str->len - pos + 1);
+      memcpy(str->data + pos, bytes, count);
+
+      str->len += count;
+    }
+}
+
+void
+svn_stringbuf_remove(svn_stringbuf_t *str,
+                     apr_size_t pos,
+                     apr_size_t count)
+{
+  if (pos > str->len)
+    pos = str->len;
+  if (pos + count > str->len)
+    count = str->len - pos;
+
+  memmove(str->data + pos, str->data + pos + count, str->len - pos - count + 1);
+  str->len -= count;
+}
+
+void
+svn_stringbuf_replace(svn_stringbuf_t *str,
+                      apr_size_t pos,
+                      apr_size_t old_count,
+                      const char *bytes,
+                      apr_size_t new_count)
+{
+  if (bytes + new_count > str->data && bytes < str->data + str->blocksize)
+    {
+      /* special case: BYTES overlaps with this string -> copy the source */
+      const char *temp = apr_pstrndup(str->pool, bytes, new_count);
+      svn_stringbuf_replace(str, pos, old_count, temp, new_count);
+    }
+  else
+    {
+      if (pos > str->len)
+        pos = str->len;
+      if (pos + old_count > str->len)
+        old_count = str->len - pos;
+
+      if (old_count < new_count)
+        {
+          apr_size_t delta = new_count - old_count;
+          svn_stringbuf_ensure(str, str->len + delta);
+        }
+
+      if (old_count != new_count)
+        memmove(str->data + pos + new_count, str->data + pos + old_count,
+                str->len - pos - old_count + 1);
+
+      memcpy(str->data + pos, bytes, new_count);
+      str->len += new_count - old_count;
+    }
+}
+
 
 svn_stringbuf_t *
 svn_stringbuf_dup(const svn_stringbuf_t *original_string, apr_pool_t *pool)

Modified: subversion/trunk/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/string-test.c?rev=1383181&r1=1383180&r2=1383181&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/string-test.c Tue Sep 11 00:19:54 2012
@@ -540,6 +540,78 @@ test24(apr_pool_t *pool)
   return test_stringbuf_unequal("abc", "abb", pool);
 }
 
+static svn_error_t *
+expect_stringbuf_equal(const svn_stringbuf_t* str1,
+                       const char* str2,
+                       apr_pool_t *pool)
+{
+  if (svn_stringbuf_compare(str1, svn_stringbuf_create(str2, pool)))
+    return SVN_NO_ERROR;
+  else
+    return fail(pool, "test failed");
+}
+
+static svn_error_t *
+test_stringbuf_insert(apr_pool_t *pool)
+{
+  a = svn_stringbuf_create("st , ", pool);
+
+  svn_stringbuf_insert(a, 0, "teflon", 2);
+  SVN_TEST_STRING_ASSERT(a->data, "test , ");
+
+  svn_stringbuf_insert(a, 5, "hllo", 4);
+  SVN_TEST_STRING_ASSERT(a->data, "test hllo, ");
+
+  svn_stringbuf_insert(a, 6, a->data + 1, 1);
+  SVN_TEST_STRING_ASSERT(a->data, "test hello, ");
+  
+  svn_stringbuf_insert(a, 12, "world class", 5);
+  SVN_TEST_STRING_ASSERT(a->data, "test hello, world");
+
+  svn_stringbuf_insert(a, 1200, "!", 1);
+  return expect_stringbuf_equal(a, "test hello, world!", pool);
+}
+
+static svn_error_t *
+test_stringbuf_remove(apr_pool_t *pool)
+{
+  a = svn_stringbuf_create("test hello, world!", pool);
+
+  svn_stringbuf_remove(a, 0, 2);
+  SVN_TEST_STRING_ASSERT(a->data, "st hello, world!");
+
+  svn_stringbuf_remove(a, 2, 2);
+  SVN_TEST_STRING_ASSERT(a->data, "stello, world!");
+
+  svn_stringbuf_remove(a, 5, 200);
+  SVN_TEST_STRING_ASSERT(a->data, "stell");
+
+  svn_stringbuf_remove(a, 1200, 393);
+  return expect_stringbuf_equal(a, "stell", pool);
+}
+
+static svn_error_t *
+test_stringbuf_replace(apr_pool_t *pool)
+{
+  a = svn_stringbuf_create("odd with some world?", pool);
+
+  svn_stringbuf_replace(a, 0, 3, "tester", 4);
+  SVN_TEST_STRING_ASSERT(a->data, "test with some world?");
+
+  svn_stringbuf_replace(a, 5, 10, "hllo, coder", 6);
+  SVN_TEST_STRING_ASSERT(a->data, "test hllo, world?");
+
+  svn_stringbuf_replace(a, 6, 0, a->data + 1, 1);
+  SVN_TEST_STRING_ASSERT(a->data, "test hello, world?");
+
+  svn_stringbuf_replace(a, 17, 10, "!", 1);
+  SVN_TEST_STRING_ASSERT(a->data, "test hello, world!");
+
+  svn_stringbuf_replace(a, 1200, 199, "!!", 2);
+
+  return expect_stringbuf_equal(a, "test hello, world!!!", pool);
+}
+
 /*
    ====================================================================
    If you add a new test to this file, update this array.
@@ -599,5 +671,11 @@ struct svn_test_descriptor_t test_funcs[
                    "compare stringbufs; same length, different content"),
     SVN_TEST_PASS2(test24,
                    "verify i64toa"),
+    SVN_TEST_PASS2(test_stringbuf_insert,
+                   "check inserting into svn_stringbuf_t"),
+    SVN_TEST_PASS2(test_stringbuf_remove,
+                   "check deletion from svn_stringbuf_t"),
+    SVN_TEST_PASS2(test_stringbuf_replace,
+                   "check replacement in svn_stringbuf_t"),
     SVN_TEST_NULL
   };