Fill in replay_revstart to dump the revprops at the start of every
revision. Add an additional write_hash_to_stringbuf helper function.

Signed-off-by: Ramkumar Ramachandra <artag...@gmail.com>
---
 Makefile     |    4 +-
 dumpr_util.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dumpr_util.h |    5 ++++
 svndumpr.c   |   38 ++++++++++++++++++++++++++++++++-
 4 files changed, 107 insertions(+), 4 deletions(-)
 create mode 100644 dumpr_util.c

diff --git a/Makefile b/Makefile
index fea646e..c0b5c8a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 svndumpr: *.c *.h
-       $(CC) -Wall -Werror -DAPR_POOL_DEBUG -ggdb3 -O0 -o $@ svndumpr.c 
debug_editor.c dump_editor.c -lsvn_client-1 -I. 
-I/usr/local/include/subversion-1 -I/usr/include/apr-1.0
+       $(CC) -Wall -Werror -DAPR_POOL_DEBUG -ggdb3 -O0 -o $@ svndumpr.c 
debug_editor.c dump_editor.c dumpr_util.c -lsvn_client-1 -I. 
-I/usr/local/include/subversion-1 -I/usr/include/apr-1.0
 
 svndumpr_bench: *.c *.h
-       $(CC) -O2 -o $@ svndumpr.c debug_editor.c dump_editor.c -lsvn_client-1 
-I. -I/usr/local/include/subversion-1 -I/usr/include/apr-1.0
+       $(CC) -O2 -o $@ svndumpr.c debug_editor.c dump_editor.c dumpr_util.c 
-lsvn_client-1 -I. -I/usr/local/include/subversion-1 -I/usr/include/apr-1.0
 
 clean:
        $(RM) svndumpr svndumpr_bench
diff --git a/dumpr_util.c b/dumpr_util.c
new file mode 100644
index 0000000..41940d4
--- /dev/null
+++ b/dumpr_util.c
@@ -0,0 +1,64 @@
+/* Licensed under a two-clause BSD-style license.
+ * See LICENSE for details.
+ */
+
+#include "svn_pools.h"
+#include "svn_cmdline.h"
+#include "svn_client.h"
+#include "svn_ra.h"
+#include "svn_repos.h"
+
+#include "dumpr_util.h"
+
+void write_hash_to_stringbuf(apr_hash_t *properties,
+                            svn_boolean_t deleted,
+                            svn_stringbuf_t **strbuf,
+                            apr_pool_t *pool)
+{
+       apr_hash_index_t *this;
+       const void *key;
+       void *val;
+       apr_ssize_t keylen;
+       svn_string_t *value;
+       
+       if (!deleted) {
+               for (this = apr_hash_first(pool, properties); this;
+                    this = apr_hash_next(this)) {
+                       /* Get this key and val. */
+                       apr_hash_this(this, &key, &keylen, &val);
+                       value = val;
+
+                       /* Output name length, then name. */
+                       svn_stringbuf_appendcstr(*strbuf,
+                                                apr_psprintf(pool, "K %" 
APR_SSIZE_T_FMT "\n",
+                                                             keylen));
+
+                       svn_stringbuf_appendbytes(*strbuf, (const char *) key, 
keylen);
+                       svn_stringbuf_appendbytes(*strbuf, "\n", 1);
+
+                       /* Output value length, then value. */
+                       svn_stringbuf_appendcstr(*strbuf,
+                                                apr_psprintf(pool, "V %" 
APR_SIZE_T_FMT "\n",
+                                                             value->len));
+
+                       svn_stringbuf_appendbytes(*strbuf, value->data, 
value->len);
+                       svn_stringbuf_appendbytes(*strbuf, "\n", 1);
+               }
+       }
+       else {
+               /* Output a "D " entry for each deleted property */
+               for (this = apr_hash_first(pool, properties); this;
+                    this = apr_hash_next(this)) {
+                       /* Get this key */
+                       apr_hash_this(this, &key, &keylen, NULL);
+
+                       /* Output name length, then name */
+                       svn_stringbuf_appendcstr(*strbuf,
+                                                apr_psprintf(pool, "D %" 
APR_SSIZE_T_FMT "\n",
+                                                             keylen));
+
+                       svn_stringbuf_appendbytes(*strbuf, (const char *) key, 
keylen);
+                       svn_stringbuf_appendbytes(*strbuf, "\n", 1);
+               }
+       }
+}
diff --git a/dumpr_util.h b/dumpr_util.h
index 166e214..1a5752b 100644
--- a/dumpr_util.h
+++ b/dumpr_util.h
@@ -31,4 +31,9 @@ struct edit_baton {
        svn_checksum_t *checksum;
 };
 
+void write_hash_to_stringbuf(apr_hash_t *properties,
+                            svn_boolean_t deleted,
+                            svn_stringbuf_t **strbuf,
+                            apr_pool_t *pool);
+
 #endif
diff --git a/svndumpr.c b/svndumpr.c
index 853facd..011941f 100644
--- a/svndumpr.c
+++ b/svndumpr.c
@@ -23,6 +23,37 @@ static svn_error_t *replay_revstart(svn_revnum_t revision,
                                     apr_hash_t *rev_props,
                                     apr_pool_t *pool)
 {
+       /* Editing this revision has just started; dump the revprops
+          before invoking the editor callbacks */
+       svn_stringbuf_t *propstring = svn_stringbuf_create("", pool);
+       svn_stream_t *stdout_stream;
+
+       /* Create an stdout stream */
+       svn_stream_for_stdout(&stdout_stream, pool);
+
+        /* Print revision number and prepare the propstring */
+       SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                                 SVN_REPOS_DUMPFILE_REVISION_NUMBER
+                                 ": %ld\n", revision));
+       write_hash_to_stringbuf(rev_props, FALSE, &propstring, pool);
+       svn_stringbuf_appendbytes(propstring, "PROPS-END\n", 10);
+
+       /* prop-content-length header */
+       SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                                 SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
+                                 ": %" APR_SIZE_T_FMT "\n", propstring->len));
+
+       /* content-length header */
+       SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                                 SVN_REPOS_DUMPFILE_CONTENT_LENGTH
+                                 ": %" APR_SIZE_T_FMT "\n\n", 
propstring->len));
+
+       /* Print the revprops now */
+       SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
+                                &(propstring->len)));
+
+       svn_stream_close(stdout_stream);
+
        /* Extract editor and editor_baton from the replay_baton and
           set them so that the editor callbacks can use them */
        struct replay_baton *rb = replay_baton;
@@ -39,6 +70,9 @@ static svn_error_t *replay_revend(svn_revnum_t revision,
                                   apr_hash_t *rev_props,
                                   apr_pool_t *pool)
 {
+       /* Editor has finished for this revision and close_edit has
+          been called; do nothing: just continue to the next
+          revision */
        return SVN_NO_ERROR;
 }
 
@@ -89,8 +123,8 @@ svn_error_t *replay_range(svn_revnum_t start_revision, 
svn_revnum_t end_revision
                                            dump_baton, pool));
 
        struct replay_baton *replay_baton = apr_palloc(pool, sizeof(struct 
replay_baton));
-       replay_baton->editor = debug_editor;
-       replay_baton->baton = debug_baton;
+       replay_baton->editor = dump_editor;
+       replay_baton->baton = dump_baton;
        SVN_ERR(svn_cmdline_printf(pool, SVN_REPOS_DUMPFILE_MAGIC_HEADER ": 
%d\n",
                                   SVN_REPOS_DUMPFILE_FORMAT_VERSION));
        SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision,
-- 
1.7.1

Reply via email to