Author: ivan
Date: Sat Jun 13 16:06:15 2015
New Revision: 1685280
URL: http://svn.apache.org/r1685280
Log:
Refactor svndiff encoding code.
* subversion/libsvn_delta/svndiff.c
(encode_window): New function, extracted from window_handler().
(window_handler): Call encode_window().
Modified:
subversion/trunk/subversion/libsvn_delta/svndiff.c
Modified: subversion/trunk/subversion/libsvn_delta/svndiff.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/svndiff.c?rev=1685280&r1=1685279&r2=1685280&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/trunk/subversion/libsvn_delta/svndiff.c Sat Jun 13 16:06:15 2015
@@ -146,55 +146,28 @@ send_simple_insertion_window(svn_txdelta
return SVN_NO_ERROR;
}
+/* Encodes delta window WINDOW to svndiff-format.
+ The svndiff version is VERSION. COMPRESSION_LEVEL is the zlib
+ compression level to use.
+ Returned values will be allocated in POOL or refer to *WINDOW
+ fields. */
static svn_error_t *
-window_handler(svn_txdelta_window_t *window, void *baton)
+encode_window(svn_stringbuf_t **instructions_p,
+ svn_stringbuf_t **header_p,
+ const svn_string_t **newdata_p,
+ svn_txdelta_window_t *window,
+ int version,
+ int compression_level,
+ apr_pool_t *pool)
{
- struct encoder_baton *eb = baton;
- apr_pool_t *pool;
svn_stringbuf_t *instructions;
svn_stringbuf_t *i1;
svn_stringbuf_t *header;
const svn_string_t *newdata;
unsigned char ibuf[MAX_INSTRUCTION_LEN], *ip;
const svn_txdelta_op_t *op;
- apr_size_t len;
-
- /* use specialized code if there is no source */
- if (window && !window->src_ops && window->num_ops == 1 && !eb->version)
- return svn_error_trace(send_simple_insertion_window(window, eb));
-
- /* Make sure we write the header. */
- if (!eb->header_done)
- {
- len = SVNDIFF_HEADER_SIZE;
- SVN_ERR(svn_stream_write(eb->output, get_svndiff_header(eb->version),
- &len));
- eb->header_done = TRUE;
- }
-
- if (window == NULL)
- {
- svn_stream_t *output = eb->output;
-
- /* We're done; clean up.
-
- We clean our pool first. Given that the output stream was passed
- TO us, we'll assume it has a longer lifetime, and that it will not
- be affected by our pool destruction.
-
- The contrary point of view (close the stream first): that could
- tell our user that everything related to the output stream is done,
- and a cleanup of the user pool should occur. However, that user
- pool could include the subpool we created for our work (eb->pool),
- which would then make our call to svn_pool_destroy() puke.
- */
- svn_pool_destroy(eb->pool);
-
- return svn_stream_close(output);
- }
/* create the necessary data buffers */
- pool = svn_pool_create(eb->pool);
instructions = svn_stringbuf_create_empty(pool);
i1 = svn_stringbuf_create_empty(pool);
header = svn_stringbuf_create_empty(pool);
@@ -223,19 +196,19 @@ window_handler(svn_txdelta_window_t *win
append_encoded_int(header, window->sview_offset);
append_encoded_int(header, window->sview_len);
append_encoded_int(header, window->tview_len);
- if (eb->version == 1)
+ if (version == 1)
{
SVN_ERR(svn__compress(instructions->data, instructions->len,
- i1, eb->compression_level));
+ i1, compression_level));
instructions = i1;
}
append_encoded_int(header, instructions->len);
- if (eb->version == 1)
+ if (version == 1)
{
svn_stringbuf_t *compressed = svn_stringbuf_create_empty(pool);
SVN_ERR(svn__compress(window->new_data->data, window->new_data->len,
- compressed, eb->compression_level));
+ compressed, compression_level));
newdata = svn_stringbuf__morph_into_string(compressed);
}
else
@@ -243,6 +216,62 @@ window_handler(svn_txdelta_window_t *win
append_encoded_int(header, newdata->len);
+ *instructions_p = instructions;
+ *header_p = header;
+ *newdata_p = newdata;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+window_handler(svn_txdelta_window_t *window, void *baton)
+{
+ struct encoder_baton *eb = baton;
+ apr_pool_t *pool;
+ apr_size_t len;
+ svn_stringbuf_t *instructions;
+ svn_stringbuf_t *header;
+ const svn_string_t *newdata;
+
+ /* use specialized code if there is no source */
+ if (window && !window->src_ops && window->num_ops == 1 && !eb->version)
+ return svn_error_trace(send_simple_insertion_window(window, eb));
+
+ /* Make sure we write the header. */
+ if (!eb->header_done)
+ {
+ len = SVNDIFF_HEADER_SIZE;
+ SVN_ERR(svn_stream_write(eb->output, get_svndiff_header(eb->version),
+ &len));
+ eb->header_done = TRUE;
+ }
+
+ if (window == NULL)
+ {
+ svn_stream_t *output = eb->output;
+
+ /* We're done; clean up.
+
+ We clean our pool first. Given that the output stream was passed
+ TO us, we'll assume it has a longer lifetime, and that it will not
+ be affected by our pool destruction.
+
+ The contrary point of view (close the stream first): that could
+ tell our user that everything related to the output stream is done,
+ and a cleanup of the user pool should occur. However, that user
+ pool could include the subpool we created for our work (eb->pool),
+ which would then make our call to svn_pool_destroy() puke.
+ */
+ svn_pool_destroy(eb->pool);
+
+ return svn_stream_close(output);
+ }
+
+ pool = svn_pool_create(eb->pool);
+
+ SVN_ERR(encode_window(&instructions, &header, &newdata, window,
+ eb->version, eb->compression_level, pool));
+
/* Write out the window. */
len = header->len;
SVN_ERR(svn_stream_write(eb->output, header->data, &len));