/* Generate a temporary file containing sort-of random data. Diffs between files of random data tend to be pretty boring, so we try to make sure there are a bunch of common substrings between two runs of this function with the same seedbase. */ static apr_file_t * generate_random_file(apr_uint32_t maxlen, apr_uint32_t subseed_base, apr_uint32_t *seed, const char *random_bytes, apr_size_t bytes_range, int dump_files, apr_pool_t *pool) { static char file_buffer[10240]; char *buf = file_buffer; char *const end = buf + sizeof file_buffer; apr_uint32_t len, seqlen; apr_file_t *fp; unsigned long r; fp = open_tempfile("random_XXXXXX", pool); len = svn_test_rand(seed) % maxlen; /* We might go over this by a bit. */ while (len > 0) { /* Generate a pseudo-random sequence of up to MAXSEQ bytes, where the seed is in the range [seedbase..seedbase+MAXSEQ-1]. (Use our own pseudo-random number generator here to avoid clobbering the seed of the libc random number generator.) */ seqlen = svn_test_rand(seed) % MAXSEQ; if (seqlen > len) seqlen = len; len -= seqlen; r = subseed_base + svn_test_rand(seed) % SEEDS; while (seqlen-- > 0) { const int ch = (random_bytes ? (unsigned)random_bytes[r % bytes_range] : (int)(r % bytes_range)); if (buf == end) { apr_size_t ignore_length; apr_file_write_full(fp, file_buffer, sizeof file_buffer, &ignore_length); buf = file_buffer; } *buf++ = (char)ch; r = r * 1103515245 + 12345; } } if (buf > file_buffer) { apr_size_t ignore_length; apr_file_write_full(fp, file_buffer, buf - file_buffer, &ignore_length); } rewind_file(fp); if (dump_files) dump_file_contents(fp); return fp; }
/* Compare two open files. The file positions may change. */ static svn_error_t * compare_files(apr_file_t *f1, apr_file_t *f2, int dump_files) { static char file_buffer_1[10240]; static char file_buffer_2[10240]; char *c1, *c2; apr_off_t pos = 0; apr_size_t len1, len2; rewind_file(f1); rewind_file(f2); if (dump_files) dump_file_contents(f2); do { apr_file_read_full(f1, file_buffer_1, sizeof file_buffer_1, &len1); apr_file_read_full(f2, file_buffer_2, sizeof file_buffer_2, &len2); for (c1 = file_buffer_1, c2 = file_buffer_2; c1 < file_buffer_1 + len1 && c2 < file_buffer_2 + len2; ++c1, ++c2, ++pos) { if (*c1 != *c2) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "mismatch at position %"APR_OFF_T_FMT, pos); } if (len1 != len2) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "unequal file sizes at position" " %"APR_OFF_T_FMT, pos); } while (len1 == sizeof file_buffer_1); return SVN_NO_ERROR; }