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 };