Author: hwright
Date: Fri Jul  8 20:12:48 2011
New Revision: 1144478

URL: http://svn.apache.org/viewvc?rev=1144478&view=rev
Log:
On the revprop-packing branch:
Rev the svn_stream_copy3() API and give it an argument which allows the caller
to specify the number of bytes to copy.

* subversion/include/svn_io.h
  (svn_stream_copy4): New.
  (svn_stream_copy3): Deprecate.

* subversion/libsvn_subr/stream.c
  (svn_stream_copy4): New.
  (svn_stream_copy3): Implement as deprecated wrapper.

* subversion/tests/libsvn_subr/stream-test.c
  (test_stream_copy): New.
  (test_funcs): Run the new test.

Modified:
    subversion/branches/revprop-packing/subversion/include/svn_io.h
    subversion/branches/revprop-packing/subversion/libsvn_subr/stream.c
    
subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c

Modified: subversion/branches/revprop-packing/subversion/include/svn_io.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/svn_io.h?rev=1144478&r1=1144477&r2=1144478&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/svn_io.h (original)
+++ subversion/branches/revprop-packing/subversion/include/svn_io.h Fri Jul  8 
20:12:48 2011
@@ -1183,6 +1183,12 @@ svn_stream_readline(svn_stream_t *stream
  * Read the contents of the readable stream @a from and write them to the
  * writable stream @a to calling @a cancel_func before copying each chunk.
  *
+ * If @a len is -1, then the entire source stream will be copied, otherwise,
+ * up to @a len bytes will be copied from @a from to @a to.
+ *
+ * @todo ### Should this API return the number of bytes actually copied,
+ * a la svn_stream_read()?
+ *
  * @a cancel_func may be @c NULL.
  *
  * @note both @a from and @a to will be closed upon successful completion of
@@ -1191,8 +1197,23 @@ svn_stream_readline(svn_stream_t *stream
  * svn_stream_disown() to protect either or both of the streams from
  * being closed.
  *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_stream_copy4(svn_stream_t *from,
+                 svn_stream_t *to,
+                 apr_ssize_t len,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *pool);
+
+/** Same as svn_stream_copy4(), but copies the source to the destination in
+ * its entirety.
+ *
  * @since New in 1.6.
+ * @deprecated Provided for backward compatibility with the 1.6 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_stream_copy3(svn_stream_t *from,
                  svn_stream_t *to,

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/stream.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/stream.c?rev=1144478&r1=1144477&r2=1144478&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/stream.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/stream.c Fri Jul 
 8 20:12:48 2011
@@ -41,6 +41,7 @@
 #include "svn_string.h"
 #include "svn_utf.h"
 #include "svn_checksum.h"
+#include "svn_sorts.h"
 #include "svn_path.h"
 #include "private/svn_eol_private.h"
 #include "private/svn_io_private.h"
@@ -465,21 +466,28 @@ svn_stream_readline(svn_stream_t *stream
                                          pool));
 }
 
-svn_error_t *svn_stream_copy3(svn_stream_t *from, svn_stream_t *to,
-                              svn_cancel_func_t cancel_func,
-                              void *cancel_baton,
-                              apr_pool_t *scratch_pool)
+svn_error_t *
+svn_stream_copy4(svn_stream_t *from,
+                 svn_stream_t *to,
+                 apr_ssize_t len_in,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *scratch_pool)
 {
   char *buf = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
   svn_error_t *err;
   svn_error_t *err2;
+  svn_boolean_t read_everything = (len_in == -1);
+
+  if (read_everything)
+    len_in = SVN__STREAM_CHUNK_SIZE;
 
   /* Read and write chunks until we get a short read, indicating the
      end of the stream.  (We can't get a short write without an
      associated error.) */
   while (1)
     {
-      apr_size_t len = SVN__STREAM_CHUNK_SIZE;
+      apr_size_t len = MIN(SVN__STREAM_CHUNK_SIZE, len_in);
 
       if (cancel_func)
         {
@@ -497,6 +505,9 @@ svn_error_t *svn_stream_copy3(svn_stream
 
       if (err || (len != SVN__STREAM_CHUNK_SIZE))
           break;
+
+      if (!read_everything)
+        len_in -= SVN__STREAM_CHUNK_SIZE;
     }
 
   err2 = svn_error_compose_create(svn_stream_close(from),
@@ -506,6 +517,18 @@ svn_error_t *svn_stream_copy3(svn_stream
 }
 
 svn_error_t *
+svn_stream_copy3(svn_stream_t *from,
+                 svn_stream_t *to,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_stream_copy4(from, to, -1,
+                                          cancel_func, cancel_baton,
+                                          scratch_pool));
+}
+
+svn_error_t *
 svn_stream_contents_same2(svn_boolean_t *same,
                           svn_stream_t *stream1,
                           svn_stream_t *stream2,

Modified: 
subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c?rev=1144478&r1=1144477&r2=1144478&view=diff
==============================================================================
--- 
subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c 
(original)
+++ 
subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c 
Fri Jul  8 20:12:48 2011
@@ -568,6 +568,49 @@ test_stream_base64(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_stream_copy(apr_pool_t *pool)
+{
+#define TEST_BUF_SIZE 100
+
+  static const char * const string =
+        "My Bonnie lies over the ocean,\n"
+        "My Bonnie lies over the sea,\n"
+        "My Bonnie lies over the ocean,\n"
+        "Oh bring back my Bonnie to me!\n"
+        "\n"
+        "Bring back, bring back,\n"
+        "Bring back my Bonnie to me, to me.\n"
+        "Bring back, bring back,\n"
+        "Bring back my Bonnie to me!\n";
+
+  svn_stringbuf_t *orig = svn_stringbuf_create(string, pool);
+  svn_stringbuf_t *actual = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *expected = svn_stringbuf_create(string, pool);
+  svn_stream_t *src;
+  svn_stream_t *dst;
+
+  src = svn_stream_from_stringbuf(orig, pool);
+  dst = svn_stream_from_stringbuf(actual, pool);
+
+  /* Copy all of the original stream. */
+  SVN_ERR(svn_stream_copy4(src, dst, -1, NULL, NULL, pool));
+
+  SVN_TEST_STRING_ASSERT(actual->data, expected->data);
+
+  /* Now, try copying only a subset of the stream. */
+  actual = svn_stringbuf_create("", pool);
+  expected = svn_stringbuf_ncreate(string, TEST_BUF_SIZE, pool);
+  src = svn_stream_from_stringbuf(orig, pool);
+  dst = svn_stream_from_stringbuf(actual, pool);
+
+  SVN_ERR(svn_stream_copy4(src, dst, TEST_BUF_SIZE, NULL, NULL, pool));
+
+  SVN_TEST_STRING_ASSERT(actual->data, expected->data);
+
+  return SVN_NO_ERROR;
+}
+
 /* The test table.  */
 
 struct svn_test_descriptor_t test_funcs[] =
@@ -591,5 +634,7 @@ struct svn_test_descriptor_t test_funcs[
                    "test compressed streams with empty files"),
     SVN_TEST_PASS2(test_stream_base64,
                    "test base64 encoding/decoding streams"),
+    SVN_TEST_PASS2(test_stream_copy,
+                   "test copying streams"),
     SVN_TEST_NULL
   };


Reply via email to