apply_textdelta picks up information from the file_baton (set by
add_file or open_file) and sets handler/ handler_baton to write a text
delta. It uses a temporary file because the content length of the
delta needs to be determined. Also add a related window_handler helper
function gets the path of the temporary file written and cleans up
after apply_textdelta. The text and prop deltas will finally be dumped
in close_file.

Signed-off-by: Ramkumar Ramachandra <artag...@gmail.com>
---
 dump_editor.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 dumpr_util.h  |   15 ++++++++++++++
 2 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/dump_editor.c b/dump_editor.c
index 7006a2c..51d5ebe 100644
--- a/dump_editor.c
+++ b/dump_editor.c
@@ -452,11 +452,69 @@ svn_error_t *change_file_prop(void *file_baton,
        return SVN_NO_ERROR;
 }
 
+svn_error_t *window_handler(svn_txdelta_window_t *window, void *baton)
+{
+       struct handler_baton *hb = baton;
+       struct edit_baton *eb = hb->eb;
+       svn_error_t *err;
+
+       err = hb->apply_handler(window, hb->apply_baton);
+       if (window != NULL && !err)
+               return SVN_NO_ERROR;
+
+       if (err)
+               SVN_ERR(err);
+
+       /* Write information about the filepath to hb->eb */
+       eb->temp_filepath = apr_pstrdup(eb->pool,
+                                       hb->temp_filepath);
+
+       /* Cleanup */
+       SVN_ERR(svn_io_file_close(hb->temp_file, hb->pool));
+       SVN_ERR(svn_stream_close(hb->temp_filestream));
+       svn_pool_destroy(hb->pool);
+       return SVN_NO_ERROR;
+}
+
 svn_error_t *apply_textdelta(void *file_baton, const char *base_checksum,
                              apr_pool_t *pool,
                              svn_txdelta_window_handler_t *handler,
                              void **handler_baton)
 {
+       svn_stream_t *source_stream;
+       struct edit_baton *eb = file_baton;
+       apr_status_t apr_err;
+
+       /* Custom handler_baton allocated in a separate pool */
+       apr_pool_t *handler_pool = svn_pool_create(pool);
+       struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
+       hb->pool = handler_pool;
+       hb->eb = eb;
+
+       /* Unset both handlers: To be set by two different functions later */
+       hb->apply_handler = NULL;
+
+       /* Use a temporary file to measure the text-content-length */
+       hb->temp_filepath = apr_psprintf(eb->pool, "/tmp/svn-fe/XXXXXX");
+       apr_err = apr_file_mktemp(&(hb->temp_file), hb->temp_filepath,
+                                 APR_CREATE | APR_READ | APR_WRITE | APR_EXCL,
+                                 hb->pool);
+       if (apr_err != APR_SUCCESS)
+               SVN_ERR(svn_error_wrap_apr(apr_err, NULL));
+
+       hb->temp_filestream = svn_stream_from_aprfile2(hb->temp_file, TRUE, 
hb->pool);
+       source_stream = svn_stream_empty(hb->pool);
+
+       /* Prepare to write the delta to the temporary file */
+       svn_txdelta_to_svndiff2(&(hb->apply_handler), &(hb->apply_baton),
+                               hb->temp_filestream, 0, hb->pool);
+       must_dump_text = TRUE;
+
+       /* The actual writing takes place when this function has finished */
+       /* Set the handler and handler_baton */
+       *handler = window_handler;
+       *handler_baton = hb;
+
        return SVN_NO_ERROR;
 }
 
@@ -493,7 +551,7 @@ svn_error_t *get_dump_editor(const svn_delta_editor_t 
**editor,
        de->close_directory = close_directory;
        de->change_dir_prop = change_dir_prop;
        de->change_file_prop = change_file_prop;
-       /* de->apply_textdelta = apply_textdelta; */
+       de->apply_textdelta = apply_textdelta;
        de->add_file = add_file;
        de->open_file = open_file;
        de->close_file = close_file;
diff --git a/dumpr_util.h b/dumpr_util.h
index 79de1ab..3830a1d 100644
--- a/dumpr_util.h
+++ b/dumpr_util.h
@@ -61,6 +61,21 @@ struct dir_baton {
        apr_pool_t *pool;
 };
 
+struct handler_baton
+{
+       svn_txdelta_window_handler_t apply_handler;
+       void *apply_baton;
+       apr_pool_t *pool;
+
+       /* Information about the path of the tempoarary file used */
+       char *temp_filepath;
+       apr_file_t *temp_file;
+       svn_stream_t *temp_filestream;
+
+       /* To fill in the edit baton fields */
+       struct edit_baton *eb;
+};
+
 void write_hash_to_stringbuf(apr_hash_t *properties,
                             svn_boolean_t deleted,
                             svn_stringbuf_t **strbuf,
-- 
1.7.1

Reply via email to