Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D4194D5A8 for ; Tue, 11 Sep 2012 00:20:39 +0000 (UTC) Received: (qmail 77588 invoked by uid 500); 11 Sep 2012 00:20:39 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 77567 invoked by uid 500); 11 Sep 2012 00:20:39 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 77560 invoked by uid 99); 11 Sep 2012 00:20:39 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Sep 2012 00:20:39 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Sep 2012 00:20:38 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 7932023888E4; Tue, 11 Sep 2012 00:19:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1383181 - in /subversion/trunk/subversion: libsvn_subr/string.c tests/libsvn_subr/string-test.c Date: Tue, 11 Sep 2012 00:19:55 -0000 To: commits@subversion.apache.org From: stefan2@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120911001955.7932023888E4@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 };