| /* vdelta-test.c -- test driver for text deltas |
| * |
| * ==================================================================== |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * ==================================================================== |
| */ |
| |
| #define APR_WANT_STDIO |
| #include <apr_want.h> |
| |
| #include <apr_general.h> |
| #include <assert.h> |
| |
| #include "../svn_test.h" |
| |
| #include "svn_ctype.h" |
| #include "svn_delta.h" |
| #include "svn_error.h" |
| #include "svn_pools.h" |
| |
| #include "../../libsvn_delta/delta.h" |
| #include "delta-window-test.h" |
| |
| 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); |
| } |
| |
| |
| static void |
| do_one_diff(apr_file_t *source_file, apr_file_t *target_file, |
| int *count, apr_off_t *len, |
| int quiet, apr_pool_t *pool, |
| const char *tag, FILE* stream) |
| { |
| svn_txdelta_stream_t *delta_stream = NULL; |
| svn_txdelta_window_t *delta_window = NULL; |
| apr_pool_t *fpool = svn_pool_create(pool); |
| apr_pool_t *wpool = svn_pool_create(pool); |
| |
| *count = 0; |
| *len = 0; |
| svn_txdelta2(&delta_stream, |
| svn_stream_from_aprfile(source_file, fpool), |
| svn_stream_from_aprfile(target_file, fpool), |
| FALSE, |
| fpool); |
| do { |
| svn_error_t *err; |
| err = svn_txdelta_next_window(&delta_window, delta_stream, wpool); |
| if (err) |
| svn_handle_error2(err, stderr, TRUE, "vdelta-test: "); |
| if (delta_window != NULL) |
| { |
| *len += print_delta_window(delta_window, tag, quiet, stream); |
| svn_pool_clear(wpool); |
| ++*count; |
| } |
| } while (delta_window != NULL); |
| fprintf(stream, "%s: (LENGTH %" APR_OFF_T_FMT " +%d)\n", tag, *len, *count); |
| |
| svn_pool_destroy(fpool); |
| svn_pool_destroy(wpool); |
| } |
| |
| |
| static void |
| do_one_test_cycle(apr_file_t *source_file_A, apr_file_t *target_file_A, |
| apr_file_t *source_file_B, apr_file_t *target_file_B, |
| int quiet, apr_pool_t *pool) |
| { |
| int count_A = 0; |
| apr_off_t len_A = 0; |
| |
| int count_B = 0; |
| apr_off_t len_B = 0; |
| |
| do_one_diff(source_file_A, target_file_A, |
| &count_A, &len_A, quiet, pool, "A ", stdout); |
| |
| if (source_file_B) |
| { |
| apr_pool_t *fpool = svn_pool_create(pool); |
| apr_pool_t *wpool = svn_pool_create(pool); |
| svn_txdelta_stream_t *stream_A = NULL; |
| svn_txdelta_stream_t *stream_B = NULL; |
| svn_txdelta_window_t *window_A = NULL; |
| svn_txdelta_window_t *window_B = NULL; |
| svn_txdelta_window_t *window_AB = NULL; |
| int count_AB = 0; |
| apr_off_t len_AB = 0; |
| |
| putc('\n', stdout); |
| do_one_diff(source_file_B, target_file_B, |
| &count_B, &len_B, quiet, pool, "B ", stdout); |
| |
| putc('\n', stdout); |
| |
| { |
| apr_off_t offset = 0; |
| |
| apr_file_seek(source_file_A, APR_SET, &offset); |
| apr_file_seek(target_file_A, APR_SET, &offset); |
| apr_file_seek(source_file_B, APR_SET, &offset); |
| apr_file_seek(target_file_B, APR_SET, &offset); |
| } |
| |
| svn_txdelta2(&stream_A, |
| svn_stream_from_aprfile(source_file_A, fpool), |
| svn_stream_from_aprfile(target_file_A, fpool), |
| FALSE, |
| fpool); |
| svn_txdelta2(&stream_B, |
| svn_stream_from_aprfile(source_file_B, fpool), |
| svn_stream_from_aprfile(target_file_B, fpool), |
| FALSE, |
| fpool); |
| |
| for (count_AB = 0; count_AB < count_B; ++count_AB) |
| { |
| svn_error_t *err; |
| |
| err = svn_txdelta_next_window(&window_A, stream_A, wpool); |
| if (err) |
| svn_handle_error2(err, stderr, TRUE, "vdelta-test: "); |
| err = svn_txdelta_next_window(&window_B, stream_B, wpool); |
| if (err) |
| svn_handle_error2(err, stderr, TRUE, "vdelta-test: "); |
| |
| /* Note: It's not possible that window_B is null, we already |
| counted the number of windows in the second delta. */ |
| assert(window_A != NULL || window_B->src_ops == 0); |
| if (window_B->src_ops == 0) |
| { |
| window_AB = window_B; |
| window_AB->sview_len = 0; |
| } |
| else |
| window_AB = svn_txdelta_compose_windows(window_A, window_B, |
| wpool); |
| len_AB += print_delta_window(window_AB, "AB", quiet, stdout); |
| svn_pool_clear(wpool); |
| } |
| |
| fprintf(stdout, "AB: (LENGTH %" APR_OFF_T_FMT " +%d)\n", |
| len_AB, count_AB); |
| } |
| } |
| |
| |
| static apr_file_t * |
| open_binary_read(const char *path, apr_pool_t *pool) |
| { |
| apr_status_t apr_err; |
| apr_file_t *fp; |
| |
| apr_err = apr_file_open(&fp, path, (APR_READ | APR_BINARY), |
| APR_OS_DEFAULT, pool); |
| |
| if (apr_err) |
| { |
| fprintf(stderr, "unable to open \"%s\" for reading\n", path); |
| exit(1); |
| } |
| |
| return fp; |
| } |
| |
| |
| int |
| main(int argc, char **argv) |
| { |
| apr_file_t *source_file_A = NULL; |
| apr_file_t *target_file_A = NULL; |
| |
| apr_file_t *source_file_B = NULL; |
| apr_file_t *target_file_B = NULL; |
| |
| apr_pool_t *pool; |
| int quiet = 0; |
| int repeat = 1; |
| |
| while (argc > 1) |
| { |
| const char *const arg = argv[1]; |
| if (arg[0] != '-') |
| break; |
| |
| if (arg[1] == 'q') |
| quiet = 1; |
| else if (svn_ctype_isdigit(arg[1])) |
| repeat = atoi(arg + 1); |
| else |
| break; |
| --argc; ++argv; |
| } |
| |
| apr_initialize(); |
| pool = svn_pool_create(NULL); |
| |
| if (argc == 2) |
| { |
| target_file_A = open_binary_read(argv[1], pool); |
| } |
| else if (argc == 3) |
| { |
| source_file_A = open_binary_read(argv[1], pool); |
| target_file_A = open_binary_read(argv[2], pool); |
| } |
| else if (argc == 4) |
| { |
| source_file_A = open_binary_read(argv[1], pool); |
| target_file_A = open_binary_read(argv[2], pool); |
| source_file_B = open_binary_read(argv[2], pool); |
| target_file_B = open_binary_read(argv[3], pool); |
| } |
| else |
| { |
| fprintf(stderr, |
| "Usage: vdelta-test [-q] [-<repeat>] <target>\n" |
| " or: vdelta-test [-q] [-<repeat>] <source> <target>\n" |
| " or: vdelta-test [-q] [-<repeat>] " |
| "<source> <intermediate> <target>\n"); |
| exit(1); |
| } |
| |
| while (0 < repeat--) |
| { |
| apr_off_t offset = 0; |
| |
| do_one_test_cycle(source_file_A, target_file_A, |
| source_file_B, target_file_B, |
| quiet, pool); |
| |
| if (source_file_A) apr_file_seek(source_file_A, APR_SET, &offset); |
| if (target_file_A) apr_file_seek(target_file_A, APR_SET, &offset); |
| if (source_file_B) apr_file_seek(source_file_B, APR_SET, &offset); |
| if (target_file_B) apr_file_seek(target_file_B, APR_SET, &offset); |
| } |
| |
| if (source_file_A) apr_file_close(source_file_A); |
| if (target_file_A) apr_file_close(target_file_A); |
| if (source_file_B) apr_file_close(source_file_B); |
| if (target_file_B) apr_file_close(source_file_B); |
| |
| svn_pool_destroy(pool); |
| apr_terminate(); |
| exit(0); |
| } |