static svn_error_t * stream_window_test(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool) { /* Note: put these in data segment, not the stack */ static char source[109001]; static char target[109001]; int i; char *p = &source[9]; svn_checksum_t *expected; svn_checksum_t *actual; svn_string_t source_str; svn_string_t target_str; svn_stream_t *source_stream; svn_stream_t *target_stream; svn_txdelta_stream_t *txstream; *msg = "txdelta stream and windows test"; if (msg_only) return SVN_NO_ERROR; memcpy(source, "a\nb\nc\nd\ne", 9); for (i = 100; i--; ) *p++ = '\n'; for (i = 999; i--; p += 109) memcpy(p, source, 109); source[109000] = '\0'; memcpy(target, source, 109001); for (i = 1000; i--; ) target[i*109 + 4] = 'X'; SVN_ERR(svn_checksum(&expected, svn_checksum_md5, target, 109000, pool)); /* f6fd44565e14c6e44b35292719deb77e */ printf("expected: %s\n", svn_checksum_to_cstring(expected, pool)); source_str.data = source; source_str.len = 109000; source_stream = svn_stream_from_string(&source_str, pool); target_str.data = target; target_str.len = 109000; target_stream = svn_stream_from_string(&target_str, pool); svn_txdelta(&txstream, source_stream, target_stream, pool); while (1) { svn_txdelta_window_t *window; SVN_ERR(svn_txdelta_next_window(&window, txstream, pool)); if (window == NULL) break; /* ### examine the window */ } actual = svn_checksum__from_digest(svn_txdelta_md5_digest(txstream), svn_checksum_md5, pool);; printf(" actual: %s\n", svn_checksum_to_cstring(actual, pool)); if (!svn_checksum_match(expected, actual)) { return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Checksums did not match."); } return SVN_NO_ERROR; }
/* Exercise the pristine text API with a simple write and read. */ static svn_error_t * pristine_write_read(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_wc__db_t *db; const char *wc_abspath; svn_wc__db_install_data_t *install_data; svn_stream_t *pristine_stream; apr_size_t sz; const char data[] = "Blah"; svn_string_t *data_string = svn_string_create(data, pool); svn_checksum_t *data_sha1, *data_md5; SVN_ERR(create_repos_and_wc(&wc_abspath, &db, "pristine_write_read", opts, pool)); /* Write DATA into a new temporary pristine file, set PRISTINE_TMP_ABSPATH * to its path and set DATA_SHA1 and DATA_MD5 to its checksums. */ SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream, &install_data, &data_sha1, &data_md5, db, wc_abspath, pool, pool)); sz = strlen(data); SVN_ERR(svn_stream_write(pristine_stream, data, &sz)); SVN_ERR(svn_stream_close(pristine_stream)); /* Ensure it's not already in the store. */ { svn_boolean_t present; SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1, pool)); SVN_TEST_ASSERT(! present); } /* Install the new pristine file, referenced by its checksum. */ SVN_ERR(svn_wc__db_pristine_install(install_data, data_sha1, data_md5, pool)); /* Ensure it is now found in the store. */ { svn_boolean_t present; SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1, pool)); SVN_TEST_ASSERT(present); } /* Look up its MD-5 from its SHA-1, and check it's the same MD-5. */ { const svn_checksum_t *looked_up_md5; SVN_ERR(svn_wc__db_pristine_get_md5(&looked_up_md5, db, wc_abspath, data_sha1, pool, pool)); SVN_TEST_ASSERT(looked_up_md5->kind == svn_checksum_md5); SVN_TEST_ASSERT(svn_checksum_match(data_md5, looked_up_md5)); } /* Read the pristine text back and verify it's the same content. */ { svn_stream_t *data_stream = svn_stream_from_string(data_string, pool); svn_stream_t *data_read_back; svn_boolean_t same; SVN_ERR(svn_wc__db_pristine_read(&data_read_back, NULL, db, wc_abspath, data_sha1, pool, pool)); SVN_ERR(svn_stream_contents_same2(&same, data_read_back, data_stream, pool)); SVN_TEST_ASSERT(same); } /* Trivially test the "remove if unreferenced" API: it's not referenced so we should be able to remove it. */ { svn_error_t *err; svn_stream_t *data_read_back; SVN_ERR(svn_wc__db_pristine_remove(db, wc_abspath, data_sha1, pool)); err = svn_wc__db_pristine_read(&data_read_back, NULL, db, wc_abspath, data_sha1, pool, pool); SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_PATH_NOT_FOUND); } /* Ensure it's no longer found in the store. */ { svn_boolean_t present; SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1, pool)); SVN_TEST_ASSERT(! present); } return SVN_NO_ERROR; }
inline Try<Diff> diff(const std::string& from, const std::string& to) { // Initialize the Apache Portable Runtime subsystem, as necessary // for using the svn library. initialize(); // Note that svn_pool_create wraps apr_pool_create_ex, which is // thread safe, see: http://goo.gl/NX0hps. apr_pool_t* pool = svn_pool_create(NULL); // First we need to produce a text delta stream by diffing 'source' // against 'target'. svn_string_t source; source.data = from.data(); source.len = from.length(); svn_string_t target; target.data = to.data(); target.len = to.length(); svn_txdelta_stream_t* delta; #if SVN_VER_MAJOR >= 1 && SVN_VER_MINOR >= 8 svn_txdelta2( &delta, svn_stream_from_string(&source, pool), svn_stream_from_string(&target, pool), false, pool); #else svn_txdelta( &delta, svn_stream_from_string(&source, pool), svn_stream_from_string(&target, pool), pool); #endif // Now we want to convert this text delta stream into an svndiff // format based diff. Setup the handler that will consume the text // delta and produce the svndiff. svn_txdelta_window_handler_t handler; void* baton = NULL; svn_stringbuf_t* diff = svn_stringbuf_create_ensure(1024, pool); #if SVN_VER_MAJOR >= 1 && SVN_VER_MINOR >= 7 svn_txdelta_to_svndiff3( &handler, &baton, svn_stream_from_stringbuf(diff, pool), 0, SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool); #elif SVN_VER_MAJOR >= 1 && SVN_VER_MINOR >= 4 svn_txdelta_to_svndiff2( &handler, &baton, svn_stream_from_stringbuf(diff, pool), 0, pool); #else svn_txdelta_to_svndiff( svn_stream_from_stringbuf(diff, pool), pool, &handler, &baton); #endif // Now feed the text delta to the handler. svn_error_t* error = svn_txdelta_send_txstream(delta, handler, baton, pool); if (error != NULL) { char buffer[1024]; std::string message(svn_err_best_message(error, buffer, 1024)); svn_pool_destroy(pool); return Error(message); } Diff d(std::string(diff->data, diff->len)); svn_pool_destroy(pool); return d; }