Author: ivan
Date: Mon Aug  8 10:32:29 2016
New Revision: 1755486

URL: http://svn.apache.org/viewvc?rev=1755486&view=rev
Log:
Introduce svn_stream_checksum() function to calculate checksum of specified
stream contents. Use new API where it makes sense.

* subversion/include/svn_io.h
  (svn_stream_checksum): New.

* subversion/libsvn_subr/stream.c
  (compute_stream_checksum): New. Helper for svn_stream_checksum().
  (svn_stream_checksum): New.

* subversion/tests/libsvn_subr/stream-test.c
  (test_stream_checksum): New. Simple test for svn_stream_checksum().
  (test_funcs): Add test_stream_checksum to test list.

* subversion/libsvn_fs/fs-loader.c
* subversion/libsvn_repos/config_pool.c
* subversion/libsvn_subr/io.c
* subversion/tests/libsvn_fs/fs-test.c
  (svn_fs_file_checksum, auto_parse, svn_io_file_checksum2,
   get_file_checksum): Use svn_stream_checksum() instead of
   svn_stream_checksummed2(READ_ALL=TRUE) + svn_stream_close(). 

Modified:
    subversion/trunk/subversion/include/svn_io.h
    subversion/trunk/subversion/libsvn_fs/fs-loader.c
    subversion/trunk/subversion/libsvn_repos/config_pool.c
    subversion/trunk/subversion/libsvn_subr/io.c
    subversion/trunk/subversion/libsvn_subr/stream.c
    subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
    subversion/trunk/subversion/tests/libsvn_subr/stream-test.c

Modified: subversion/trunk/subversion/include/svn_io.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_io.h?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_io.h (original)
+++ subversion/trunk/subversion/include/svn_io.h Mon Aug  8 10:32:29 2016
@@ -1254,6 +1254,23 @@ svn_stream_checksummed(svn_stream_t *str
                        svn_boolean_t read_all,
                        apr_pool_t *pool);
 
+/** Return in @a *checksum the checksum of type @a kind of @a stream.
+ *
+ * Stream will be closed before this function returns (regardless of
+ * the result, or any possible error).
+ *
+ * Use @a scratch_pool for temporary allocations and @a result_pool
+ * to allocate @a *checksum. 
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_stream_checksum(svn_checksum_t **checksum,
+                    svn_stream_t *stream,
+                    svn_checksum_kind_t kind,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool);
+
 /** Read from a generic stream until @a buffer is filled upto @a *len or
  * until EOF is reached. @see svn_stream_t
  *

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.c?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.c Mon Aug  8 10:32:29 2016
@@ -1501,15 +1501,10 @@ svn_fs_file_checksum(svn_checksum_t **ch
 
   if (force && (*checksum == NULL || (*checksum)->kind != kind))
     {
-      svn_stream_t *contents, *checksum_contents;
+      svn_stream_t *contents;
 
       SVN_ERR(svn_fs_file_contents(&contents, root, path, pool));
-      checksum_contents = svn_stream_checksummed2(contents, checksum, NULL,
-                                                  kind, TRUE, pool);
-
-      /* This will force a read of any remaining data (which is all of it in
-         this case) and dump the checksum into checksum->digest. */
-      SVN_ERR(svn_stream_close(checksum_contents));
+      SVN_ERR(svn_stream_checksum(checksum, contents, kind, pool, pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/libsvn_repos/config_pool.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/config_pool.c?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/config_pool.c (original)
+++ subversion/trunk/subversion/libsvn_repos/config_pool.c Mon Aug  8 10:32:29 
2016
@@ -199,10 +199,9 @@ auto_parse(svn_config_t **cfg,
   apr_pool_t *cfg_pool;
 
   /* calculate SHA1 over the whole file contents */
-  SVN_ERR(svn_stream_close
-              (svn_stream_checksummed2
-                  (svn_stream_from_stringbuf(contents, scratch_pool),
-                   &checksum, NULL, svn_checksum_sha1, TRUE, scratch_pool)));
+  SVN_ERR(svn_stream_checksum(
+            &checksum, svn_stream_from_stringbuf(contents, scratch_pool),
+            svn_checksum_sha1, scratch_pool, scratch_pool));
 
   /* return reference to suitable config object if that already exists */
   *key = checksum_as_key(checksum, result_pool);

Modified: subversion/trunk/subversion/libsvn_subr/io.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/io.c (original)
+++ subversion/trunk/subversion/libsvn_subr/io.c Mon Aug  8 10:32:29 2016
@@ -1478,18 +1478,13 @@ svn_io_file_checksum2(svn_checksum_t **c
                       apr_pool_t *pool)
 {
   svn_stream_t *file_stream;
-  svn_stream_t *checksum_stream;
   apr_file_t* f;
 
   SVN_ERR(svn_io_file_open(&f, file, APR_READ, APR_OS_DEFAULT, pool));
   file_stream = svn_stream_from_aprfile2(f, FALSE, pool);
-  checksum_stream = svn_stream_checksummed2(file_stream, checksum, NULL, kind,
-                                            TRUE, pool);
+  SVN_ERR(svn_stream_checksum(checksum, file_stream, kind, pool, pool));
 
-  /* Because the checksummed stream will force the reading (and
-     checksumming) of all the file's bytes, we can just close the stream
-     and let its magic work. */
-  return svn_stream_close(checksum_stream);
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Mon Aug  8 10:32:29 2016
@@ -1478,6 +1478,51 @@ svn_stream_checksummed2(svn_stream_t *st
   return s;
 }
 
+/* Helper for svn_stream_checksum() to compute checksum of KIND of STREAM.
+ * This function doesn't close source stream. */
+static svn_error_t *
+compute_stream_checksum(svn_checksum_t **checksum,
+                        svn_stream_t *stream,
+                        svn_checksum_kind_t kind,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
+{
+  svn_checksum_ctx_t *ctx = svn_checksum_ctx_create(kind, scratch_pool);
+  char *buf = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
+
+  while (1)
+    {
+      apr_size_t len = SVN__STREAM_CHUNK_SIZE;
+
+      SVN_ERR(svn_stream_read_full(stream, buf, &len));
+
+      if (len > 0)
+        SVN_ERR(svn_checksum_update(ctx, buf, len));
+
+      if (len != SVN__STREAM_CHUNK_SIZE)
+          break;
+    }
+  SVN_ERR(svn_checksum_final(checksum, ctx, result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_stream_checksum(svn_checksum_t **checksum,
+                    svn_stream_t *stream,
+                    svn_checksum_kind_t kind,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+
+  err = compute_stream_checksum(checksum, stream, kind,
+                                result_pool, scratch_pool);
+
+  /* Close source stream in all cases. */
+  return svn_error_compose_create(err, svn_stream_close(stream));
+}
+
 /* Miscellaneous stream functions. */
 
 /*

Modified: subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs/fs-test.c?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs/fs-test.c Mon Aug  8 10:32:29 
2016
@@ -3593,17 +3593,10 @@ get_file_checksum(svn_checksum_t **check
                   apr_pool_t *pool)
 {
   svn_stream_t *stream;
-  svn_stream_t *checksum_stream;
 
   /* Get a stream for the file contents. */
   SVN_ERR(svn_fs_file_contents(&stream, root, path, pool));
-
-  /* Get a checksummed stream for the contents. */
-  checksum_stream = svn_stream_checksummed2(stream, checksum, NULL,
-                                            checksum_kind, TRUE, pool);
-
-  /* Close the stream, forcing a complete read and copy the digest. */
-  SVN_ERR(svn_stream_close(checksum_stream));
+  SVN_ERR(svn_stream_checksum(checksum, stream, checksum_kind, pool, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/tests/libsvn_subr/stream-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/stream-test.c?rev=1755486&r1=1755485&r2=1755486&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/stream-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/stream-test.c Mon Aug  8 
10:32:29 2016
@@ -848,6 +848,26 @@ test_stream_compressed_read_full(apr_poo
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_stream_checksum(apr_pool_t *pool)
+{
+  svn_string_t *str =
+    svn_string_create("The quick brown fox jumps over the lazy dog", pool);
+  svn_checksum_t *actual;
+
+  SVN_ERR(svn_stream_checksum(&actual, svn_stream_from_string(str, pool),
+                              svn_checksum_md5, pool, pool));
+  SVN_TEST_STRING_ASSERT("9e107d9d372bb6826bd81d3542a419d6",
+                         svn_checksum_to_cstring(actual, pool));
+
+  SVN_ERR(svn_stream_checksum(&actual, svn_stream_from_string(str, pool),
+                              svn_checksum_sha1, pool, pool));
+  SVN_TEST_STRING_ASSERT("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
+                         svn_checksum_to_cstring(actual, pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* The test table.  */
 
 static int max_threads = 1;
@@ -879,6 +899,8 @@ static struct svn_test_descriptor_t test
                    "test svn_stringbuf_from_stream"),
     SVN_TEST_PASS2(test_stream_compressed_read_full,
                    "test compression for streams without partial read"),
+    SVN_TEST_PASS2(test_stream_checksum,
+                   "test svn_stream_checksum()"),
     SVN_TEST_NULL
   };
 


Reply via email to