static apr_off_t print_delta_window(const svn_txdelta_window_t *window, const char *tag, int quiet, FILE *stream) { if (quiet) return delta_window_size_estimate(window); else return delta_window_print(window, tag, stream); }
/* (Note: *LAST_SEED is an output parameter.) */ static svn_error_t * do_random_combine_test(const char **msg, svn_boolean_t msg_only, apr_pool_t *pool, apr_uint32_t *last_seed) { static char msg_buff[256]; apr_uint32_t seed, bytes_range, maxlen; int i, iterations, dump_files, print_windows; const char *random_bytes; /* Initialize parameters and print out the seed in case we dump core or something. */ init_params(&seed, &maxlen, &iterations, &dump_files, &print_windows, &random_bytes, &bytes_range, pool); sprintf(msg_buff, "random combine delta test, seed = %lu", (unsigned long) seed); *msg = msg_buff; if (msg_only) return SVN_NO_ERROR; else printf("SEED: %s\n", msg_buff); for (i = 0; i < iterations; i++) { /* Generate source and target for the delta and its application. */ apr_uint32_t subseed_base = svn_test_rand((*last_seed = seed, &seed)); apr_file_t *source = generate_random_file(maxlen, subseed_base, &seed, random_bytes, bytes_range, dump_files, pool); apr_file_t *middle = generate_random_file(maxlen, subseed_base, &seed, random_bytes, bytes_range, dump_files, pool); apr_file_t *target = generate_random_file(maxlen, subseed_base, &seed, random_bytes, bytes_range, dump_files, pool); apr_file_t *source_copy = copy_tempfile(source, pool); apr_file_t *middle_copy = copy_tempfile(middle, pool); apr_file_t *target_regen = open_tempfile(NULL, pool); svn_txdelta_stream_t *txdelta_stream_A; svn_txdelta_stream_t *txdelta_stream_B; svn_txdelta_window_handler_t handler; svn_stream_t *stream; void *handler_baton; /* Set up a four-stage pipeline: create two deltas, combine them and convert the result to svndiff format, parse that back into delta format, and apply it to a copy of the source file to see if we get the same target back. */ apr_pool_t *delta_pool = svn_pool_create(pool); /* Make stage 4: apply the text delta. */ svn_txdelta_apply(svn_stream_from_aprfile(source_copy, delta_pool), svn_stream_from_aprfile(target_regen, delta_pool), NULL, NULL, delta_pool, &handler, &handler_baton); /* Make stage 3: reparse the text delta. */ stream = svn_txdelta_parse_svndiff(handler, handler_baton, TRUE, delta_pool); /* Make stage 2: encode the text delta in svndiff format. */ svn_txdelta_to_svndiff2(&handler, &handler_baton, stream, 1, delta_pool); /* Make stage 1: create the text deltas. */ svn_txdelta(&txdelta_stream_A, svn_stream_from_aprfile(source, delta_pool), svn_stream_from_aprfile(middle, delta_pool), delta_pool); svn_txdelta(&txdelta_stream_B, svn_stream_from_aprfile(middle_copy, delta_pool), svn_stream_from_aprfile(target, delta_pool), delta_pool); { svn_txdelta_window_t *window_A; svn_txdelta_window_t *window_B; svn_txdelta_window_t *composite; apr_pool_t *wpool = svn_pool_create(delta_pool); do { SVN_ERR(svn_txdelta_next_window(&window_A, txdelta_stream_A, wpool)); if (print_windows) delta_window_print(window_A, "A ", stdout); SVN_ERR(svn_txdelta_next_window(&window_B, txdelta_stream_B, wpool)); if (print_windows) delta_window_print(window_B, "B ", stdout); if (!window_B) break; assert(window_A != NULL || window_B->src_ops == 0); if (window_B->src_ops == 0) { composite = window_B; composite->sview_len = 0; } else composite = svn_txdelta_compose_windows(window_A, window_B, wpool); if (print_windows) delta_window_print(composite, "AB", stdout); /* The source view length should not be 0 if there are source copy ops in the window. */ if (composite && composite->sview_len == 0 && composite->src_ops > 0) return svn_error_create (SVN_ERR_FS_GENERAL, NULL, "combined delta window is inconsistent"); SVN_ERR(handler(composite, handler_baton)); svn_pool_clear(wpool); } while (composite != NULL); svn_pool_destroy(wpool); } svn_pool_destroy(delta_pool); SVN_ERR(compare_files(target, target_regen, dump_files)); apr_file_close(source); apr_file_close(middle); apr_file_close(target); apr_file_close(source_copy); apr_file_close(middle_copy); apr_file_close(target_regen); } return SVN_NO_ERROR; }