summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra_serf/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_ra_serf/log.c')
-rw-r--r--subversion/libsvn_ra_serf/log.c599
1 files changed, 235 insertions, 364 deletions
diff --git a/subversion/libsvn_ra_serf/log.c b/subversion/libsvn_ra_serf/log.c
index cd6a6b2..02f2f29 100644
--- a/subversion/libsvn_ra_serf/log.c
+++ b/subversion/libsvn_ra_serf/log.c
@@ -24,11 +24,9 @@
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
+#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_dav.h"
@@ -39,6 +37,8 @@
#include "svn_props.h"
#include "private/svn_dav_protocol.h"
+#include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
#include "svn_private_config.h"
#include "ra_serf.h"
@@ -48,8 +48,8 @@
/*
* This enum represents the current state of our XML parsing for a REPORT.
*/
-typedef enum log_state_e {
- NONE = 0,
+enum {
+ INITIAL = 0,
REPORT,
ITEM,
VERSION,
@@ -63,27 +63,7 @@ typedef enum log_state_e {
DELETED_PATH,
MODIFIED_PATH,
SUBTRACTIVE_MERGE
-} log_state_e;
-
-typedef struct log_info_t {
- apr_pool_t *pool;
-
- /* The currently collected value as we build it up, and its wire
- * encoding (if any).
- */
- const char *tmp;
- apr_size_t tmp_len;
- const char *tmp_encoding;
-
- /* Temporary change path - ultimately inserted into changed_paths hash. */
- svn_log_changed_path2_t *tmp_path;
-
- /* Log information */
- svn_log_entry_t *log_entry;
-
- /* Place to hold revprop name. */
- const char *revprop_name;
-} log_info_t;
+};
typedef struct log_context_t {
apr_pool_t *pool;
@@ -100,9 +80,11 @@ typedef struct log_context_t {
int nest_level; /* used to track mergeinfo nesting levels */
int count; /* only incremented when nest_level == 0 */
- /* are we done? */
- svn_boolean_t done;
- int status_code;
+ /* Collect information for storage into a log entry. Most of the entry
+ members are collected by individual states. revprops and paths are
+ N datapoints per entry. */
+ apr_hash_t *collect_revprops;
+ apr_hash_t *collect_paths;
/* log receiver function and baton */
svn_log_entry_receiver_t receiver;
@@ -114,406 +96,307 @@ typedef struct log_context_t {
svn_boolean_t want_message;
} log_context_t;
-
-static log_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
- log_context_t *log_ctx,
- log_state_e state,
- const char **attrs)
-{
- svn_ra_serf__xml_push_state(parser, state);
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t log_ttable[] = {
+ { INITIAL, S_, "log-report", REPORT,
+ FALSE, { NULL }, FALSE },
- if (state == ITEM)
- {
- log_info_t *info;
- apr_pool_t *info_pool = svn_pool_create(parser->state->pool);
+ /* Note that we have an opener here. We need to construct a new LOG_ENTRY
+ to record multiple paths. */
+ { REPORT, S_, "log-item", ITEM,
+ FALSE, { NULL }, TRUE },
- info = apr_pcalloc(info_pool, sizeof(*info));
- info->pool = info_pool;
- info->log_entry = svn_log_entry_create(info_pool);
+ { ITEM, D_, SVN_DAV__VERSION_NAME, VERSION,
+ TRUE, { NULL }, TRUE },
- info->log_entry->revision = SVN_INVALID_REVNUM;
+ { ITEM, D_, "creator-displayname", CREATOR,
+ TRUE, { "?encoding", NULL }, TRUE },
- parser->state->private = info;
- }
+ { ITEM, S_, "date", DATE,
+ TRUE, { "?encoding", NULL }, TRUE },
- if (state == ADDED_PATH || state == REPLACED_PATH ||
- state == DELETED_PATH || state == MODIFIED_PATH)
- {
- log_info_t *info = parser->state->private;
+ { ITEM, D_, "comment", COMMENT,
+ TRUE, { "?encoding", NULL }, TRUE },
- if (!info->log_entry->changed_paths2)
- {
- info->log_entry->changed_paths2 = apr_hash_make(info->pool);
- info->log_entry->changed_paths = info->log_entry->changed_paths2;
- }
+ { ITEM, S_, "revprop", REVPROP,
+ TRUE, { "name", "?encoding", NULL }, TRUE },
- info->tmp_path = svn_log_changed_path2_create(info->pool);
- info->tmp_path->copyfrom_rev = SVN_INVALID_REVNUM;
- }
+ { ITEM, S_, "has-children", HAS_CHILDREN,
+ FALSE, { NULL }, TRUE },
- if (state == CREATOR || state == DATE || state == COMMENT
- || state == REVPROP)
- {
- log_info_t *info = parser->state->private;
+ { ITEM, S_, "subtractive-merge", SUBTRACTIVE_MERGE,
+ FALSE, { NULL }, TRUE },
- info->tmp_encoding = svn_xml_get_attr_value("encoding", attrs);
- if (info->tmp_encoding)
- info->tmp_encoding = apr_pstrdup(info->pool, info->tmp_encoding);
+ { ITEM, S_, "added-path", ADDED_PATH,
+ TRUE, { "?node-kind", "?text-mods", "?prop-mods",
+ "?copyfrom-path", "?copyfrom-rev", NULL }, TRUE },
- if (!info->log_entry->revprops)
- {
- info->log_entry->revprops = apr_hash_make(info->pool);
- }
- }
+ { ITEM, S_, "replaced-path", REPLACED_PATH,
+ TRUE, { "?node-kind", "?text-mods", "?prop-mods",
+ "?copyfrom-path", "?copyfrom-rev", NULL }, TRUE },
- return parser->state->private;
-}
+ { ITEM, S_, "deleted-path", DELETED_PATH,
+ TRUE, { "?node-kind", "?text-mods", "?prop-mods", NULL }, TRUE },
-/* Helper function to parse the common arguments availabe in ATTRS into CHANGE. */
-static svn_error_t *
-read_changed_path_attributes(svn_log_changed_path2_t *change, const char **attrs)
-{
- /* All these arguments are optional. The *_from_word() functions can handle
- them for us */
+ { ITEM, S_, "modified-path", MODIFIED_PATH,
+ TRUE, { "?node-kind", "?text-mods", "?prop-mods", NULL }, TRUE },
- change->node_kind = svn_node_kind_from_word(
- svn_xml_get_attr_value("node-kind", attrs));
- change->text_modified = svn_tristate__from_word(
- svn_xml_get_attr_value("text-mods", attrs));
- change->props_modified = svn_tristate__from_word(
- svn_xml_get_attr_value("prop-mods", attrs));
+ { 0 }
+};
- return SVN_NO_ERROR;
-}
+
+/* Store CDATA into REVPROPS, associated with PROPNAME. If ENCODING is not
+ NULL, then it must base "base64" and CDATA will be decoded first.
+ NOTE: PROPNAME must live longer than REVPROPS. */
static svn_error_t *
-start_log(svn_ra_serf__xml_parser_t *parser,
- void *userData,
- svn_ra_serf__dav_props_t name,
- const char **attrs)
+collect_revprop(apr_hash_t *revprops,
+ const char *propname,
+ const svn_string_t *cdata,
+ const char *encoding)
{
- log_context_t *log_ctx = userData;
- log_state_e state;
-
- state = parser->state->current_state;
+ apr_pool_t *result_pool = apr_hash_pool_get(revprops);
+ const svn_string_t *decoded;
- if (state == NONE &&
- strcmp(name.name, "log-report") == 0)
+ if (encoding)
{
- push_state(parser, log_ctx, REPORT, attrs);
+ /* Check for a known encoding type. This is easy -- there's
+ only one. */
+ if (strcmp(encoding, "base64") != 0)
+ {
+ return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("Unsupported encoding '%s'"),
+ encoding);
+ }
+
+ decoded = svn_base64_decode_string(cdata, result_pool);
}
- else if (state == REPORT &&
- strcmp(name.name, "log-item") == 0)
+ else
{
- push_state(parser, log_ctx, ITEM, attrs);
+ decoded = svn_string_dup(cdata, result_pool);
}
- else if (state == ITEM)
+
+ /* Caller has ensured PROPNAME has sufficient lifetime. */
+ svn_hash_sets(revprops, propname, decoded);
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Record ACTION on the path in CDATA into PATHS. Other properties about
+ the action are pulled from ATTRS. */
+static svn_error_t *
+collect_path(apr_hash_t *paths,
+ char action,
+ const svn_string_t *cdata,
+ apr_hash_t *attrs)
+{
+ apr_pool_t *result_pool = apr_hash_pool_get(paths);
+ svn_log_changed_path2_t *lcp;
+ const char *copyfrom_path;
+ const char *copyfrom_rev;
+ const char *path;
+
+ lcp = svn_log_changed_path2_create(result_pool);
+ lcp->action = action;
+ lcp->copyfrom_rev = SVN_INVALID_REVNUM;
+
+ /* COPYFROM_* are only recorded for ADDED_PATH and REPLACED_PATH. */
+ copyfrom_path = svn_hash_gets(attrs, "copyfrom-path");
+ copyfrom_rev = svn_hash_gets(attrs, "copyfrom-rev");
+ if (copyfrom_path && copyfrom_rev)
{
- log_info_t *info;
+ svn_revnum_t rev = SVN_STR_TO_REV(copyfrom_rev);
- if (strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
- {
- push_state(parser, log_ctx, VERSION, attrs);
- }
- else if (strcmp(name.name, "creator-displayname") == 0)
- {
- info = push_state(parser, log_ctx, CREATOR, attrs);
- }
- else if (strcmp(name.name, "date") == 0)
- {
- info = push_state(parser, log_ctx, DATE, attrs);
- }
- else if (strcmp(name.name, "comment") == 0)
- {
- info = push_state(parser, log_ctx, COMMENT, attrs);
- }
- else if (strcmp(name.name, "revprop") == 0)
- {
- const char *revprop_name =
- svn_xml_get_attr_value("name", attrs);
- if (revprop_name == NULL)
- return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
- _("Missing name attr in revprop element"));
- info = push_state(parser, log_ctx, REVPROP, attrs);
- info->revprop_name = apr_pstrdup(info->pool, revprop_name);
- }
- else if (strcmp(name.name, "has-children") == 0)
- {
- push_state(parser, log_ctx, HAS_CHILDREN, attrs);
- }
- else if (strcmp(name.name, "subtractive-merge") == 0)
- {
- push_state(parser, log_ctx, SUBTRACTIVE_MERGE, attrs);
- }
- else if (strcmp(name.name, "added-path") == 0)
- {
- const char *copy_path, *copy_rev_str;
-
- info = push_state(parser, log_ctx, ADDED_PATH, attrs);
- info->tmp_path->action = 'A';
-
- copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
- copy_rev_str = svn_xml_get_attr_value("copyfrom-rev", attrs);
- if (copy_path && copy_rev_str)
- {
- svn_revnum_t copy_rev;
-
- copy_rev = SVN_STR_TO_REV(copy_rev_str);
- if (SVN_IS_VALID_REVNUM(copy_rev))
- {
- info->tmp_path->copyfrom_path = apr_pstrdup(info->pool,
- copy_path);
- info->tmp_path->copyfrom_rev = copy_rev;
- }
- }
-
- SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
- }
- else if (strcmp(name.name, "replaced-path") == 0)
+ if (SVN_IS_VALID_REVNUM(rev))
{
- const char *copy_path, *copy_rev_str;
-
- info = push_state(parser, log_ctx, REPLACED_PATH, attrs);
- info->tmp_path->action = 'R';
-
- copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
- copy_rev_str = svn_xml_get_attr_value("copyfrom-rev", attrs);
- if (copy_path && copy_rev_str)
- {
- svn_revnum_t copy_rev;
-
- copy_rev = SVN_STR_TO_REV(copy_rev_str);
- if (SVN_IS_VALID_REVNUM(copy_rev))
- {
- info->tmp_path->copyfrom_path = apr_pstrdup(info->pool,
- copy_path);
- info->tmp_path->copyfrom_rev = copy_rev;
- }
- }
-
- SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
+ lcp->copyfrom_path = apr_pstrdup(result_pool, copyfrom_path);
+ lcp->copyfrom_rev = rev;
}
- else if (strcmp(name.name, "deleted-path") == 0)
- {
- info = push_state(parser, log_ctx, DELETED_PATH, attrs);
- info->tmp_path->action = 'D';
+ }
- SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
- }
- else if (strcmp(name.name, "modified-path") == 0)
- {
- info = push_state(parser, log_ctx, MODIFIED_PATH, attrs);
- info->tmp_path->action = 'M';
+ lcp->node_kind = svn_node_kind_from_word(svn_hash_gets(attrs, "node-kind"));
+ lcp->text_modified = svn_tristate__from_word(svn_hash_gets(attrs,
+ "text-mods"));
+ lcp->props_modified = svn_tristate__from_word(svn_hash_gets(attrs,
+ "prop-mods"));
- SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
- }
- }
+ path = apr_pstrmemdup(result_pool, cdata->data, cdata->len);
+ svn_hash_sets(paths, path, lcp);
return SVN_NO_ERROR;
}
-/*
- * Set *DECODED_CDATA to a copy of current CDATA being tracked in INFO,
- * decoded as necessary, and allocated from INFO->pool..
- */
+
+/* Conforms to svn_ra_serf__xml_opened_t */
static svn_error_t *
-maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
- log_info_t *info)
+log_opened(svn_ra_serf__xml_estate_t *xes,
+ void *baton,
+ int entered_state,
+ const svn_ra_serf__dav_props_t *tag,
+ apr_pool_t *scratch_pool)
{
- if (info->tmp_encoding)
- {
- svn_string_t in;
- in.data = info->tmp;
- in.len = info->tmp_len;
-
- /* Check for a known encoding type. This is easy -- there's
- only one. */
- if (strcmp(info->tmp_encoding, "base64") != 0)
- {
- return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
- _("Unsupported encoding '%s'"),
- info->tmp_encoding);
- }
+ log_context_t *log_ctx = baton;
- *decoded_cdata = svn_base64_decode_string(&in, info->pool);
- }
- else
+ if (entered_state == ITEM)
{
- *decoded_cdata = svn_string_ncreate(info->tmp, info->tmp_len,
- info->pool);
+ apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
+
+ log_ctx->collect_revprops = apr_hash_make(state_pool);
+ log_ctx->collect_paths = apr_hash_make(state_pool);
}
+
return SVN_NO_ERROR;
}
+
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-end_log(svn_ra_serf__xml_parser_t *parser,
- void *userData,
- svn_ra_serf__dav_props_t name)
+log_closed(svn_ra_serf__xml_estate_t *xes,
+ void *baton,
+ int leaving_state,
+ const svn_string_t *cdata,
+ apr_hash_t *attrs,
+ apr_pool_t *scratch_pool)
{
- log_context_t *log_ctx = userData;
- log_state_e state;
- log_info_t *info;
-
- state = parser->state->current_state;
- info = parser->state->private;
+ log_context_t *log_ctx = baton;
- if (state == REPORT &&
- strcmp(name.name, "log-report") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == ITEM &&
- strcmp(name.name, "log-item") == 0)
+ if (leaving_state == ITEM)
{
+ svn_log_entry_t *log_entry;
+ const char *rev_str;
+
if (log_ctx->limit && (log_ctx->nest_level == 0)
&& (++log_ctx->count > log_ctx->limit))
{
return SVN_NO_ERROR;
}
+ log_entry = svn_log_entry_create(scratch_pool);
+
+ /* Pick up the paths from the context. These have the same lifetime
+ as this state. That is long enough for us to pass the paths to
+ the receiver callback. */
+ if (apr_hash_count(log_ctx->collect_paths) > 0)
+ {
+ log_entry->changed_paths = log_ctx->collect_paths;
+ log_entry->changed_paths2 = log_ctx->collect_paths;
+ }
+
+ /* ... and same story for the collected revprops. */
+ log_entry->revprops = log_ctx->collect_revprops;
+
+ log_entry->has_children = svn_hash__get_bool(attrs,
+ "has-children",
+ FALSE);
+ log_entry->subtractive_merge = svn_hash__get_bool(attrs,
+ "subtractive-merge",
+ FALSE);
+
+ rev_str = svn_hash_gets(attrs, "revision");
+ if (rev_str)
+ log_entry->revision = SVN_STR_TO_REV(rev_str);
+ else
+ log_entry->revision = SVN_INVALID_REVNUM;
+
/* Give the info to the reporter */
SVN_ERR(log_ctx->receiver(log_ctx->receiver_baton,
- info->log_entry,
- info->pool));
+ log_entry,
+ scratch_pool));
- if (info->log_entry->has_children)
+ if (log_entry->has_children)
{
log_ctx->nest_level++;
}
- if (! SVN_IS_VALID_REVNUM(info->log_entry->revision))
+ if (! SVN_IS_VALID_REVNUM(log_entry->revision))
{
SVN_ERR_ASSERT(log_ctx->nest_level);
log_ctx->nest_level--;
}
- svn_pool_destroy(info->pool);
- svn_ra_serf__xml_pop_state(parser);
+ /* These hash tables are going to be unusable once this state's
+ pool is destroyed. But let's not leave stale pointers in
+ structures that have a longer life. */
+ log_ctx->collect_revprops = NULL;
+ log_ctx->collect_paths = NULL;
}
- else if (state == VERSION &&
- strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
+ else if (leaving_state == VERSION)
{
- info->log_entry->revision = SVN_STR_TO_REV(info->tmp);
- info->tmp_len = 0;
- svn_ra_serf__xml_pop_state(parser);
+ svn_ra_serf__xml_note(xes, ITEM, "revision", cdata->data);
}
- else if (state == CREATOR &&
- strcmp(name.name, "creator-displayname") == 0)
+ else if (leaving_state == CREATOR)
{
if (log_ctx->want_author)
{
- const svn_string_t *decoded_cdata;
- SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
- apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
- APR_HASH_KEY_STRING, decoded_cdata);
+ SVN_ERR(collect_revprop(log_ctx->collect_revprops,
+ SVN_PROP_REVISION_AUTHOR,
+ cdata,
+ svn_hash_gets(attrs, "encoding")));
}
- info->tmp_len = 0;
- svn_ra_serf__xml_pop_state(parser);
}
- else if (state == DATE &&
- strcmp(name.name, "date") == 0)
+ else if (leaving_state == DATE)
{
if (log_ctx->want_date)
{
- const svn_string_t *decoded_cdata;
- SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
- apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_DATE,
- APR_HASH_KEY_STRING, decoded_cdata);
+ SVN_ERR(collect_revprop(log_ctx->collect_revprops,
+ SVN_PROP_REVISION_DATE,
+ cdata,
+ svn_hash_gets(attrs, "encoding")));
}
- info->tmp_len = 0;
- svn_ra_serf__xml_pop_state(parser);
}
- else if (state == COMMENT &&
- strcmp(name.name, "comment") == 0)
+ else if (leaving_state == COMMENT)
{
if (log_ctx->want_message)
{
- const svn_string_t *decoded_cdata;
- SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
- apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_LOG,
- APR_HASH_KEY_STRING, decoded_cdata);
+ SVN_ERR(collect_revprop(log_ctx->collect_revprops,
+ SVN_PROP_REVISION_LOG,
+ cdata,
+ svn_hash_gets(attrs, "encoding")));
}
- info->tmp_len = 0;
- svn_ra_serf__xml_pop_state(parser);
}
- else if (state == REVPROP)
+ else if (leaving_state == REVPROP)
{
- const svn_string_t *decoded_cdata;
- SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
- apr_hash_set(info->log_entry->revprops, info->revprop_name,
- APR_HASH_KEY_STRING, decoded_cdata);
- info->tmp_len = 0;
- svn_ra_serf__xml_pop_state(parser);
+ apr_pool_t *result_pool = apr_hash_pool_get(log_ctx->collect_revprops);
+
+ SVN_ERR(collect_revprop(
+ log_ctx->collect_revprops,
+ apr_pstrdup(result_pool,
+ svn_hash_gets(attrs, "name")),
+ cdata,
+ svn_hash_gets(attrs, "encoding")
+ ));
}
- else if (state == HAS_CHILDREN &&
- strcmp(name.name, "has-children") == 0)
+ else if (leaving_state == HAS_CHILDREN)
{
- info->log_entry->has_children = TRUE;
- svn_ra_serf__xml_pop_state(parser);
+ svn_ra_serf__xml_note(xes, ITEM, "has-children", "yes");
}
- else if (state == SUBTRACTIVE_MERGE &&
- strcmp(name.name, "subtractive-merge") == 0)
+ else if (leaving_state == SUBTRACTIVE_MERGE)
{
- info->log_entry->subtractive_merge = TRUE;
- svn_ra_serf__xml_pop_state(parser);
+ svn_ra_serf__xml_note(xes, ITEM, "subtractive-merge", "yes");
}
- else if ((state == ADDED_PATH &&
- strcmp(name.name, "added-path") == 0) ||
- (state == DELETED_PATH &&
- strcmp(name.name, "deleted-path") == 0) ||
- (state == MODIFIED_PATH &&
- strcmp(name.name, "modified-path") == 0) ||
- (state == REPLACED_PATH &&
- strcmp(name.name, "replaced-path") == 0))
+ else
{
- char *path;
-
- path = apr_pstrmemdup(info->pool, info->tmp, info->tmp_len);
- info->tmp_len = 0;
+ char action;
+
+ if (leaving_state == ADDED_PATH)
+ action = 'A';
+ else if (leaving_state == REPLACED_PATH)
+ action = 'R';
+ else if (leaving_state == DELETED_PATH)
+ action = 'D';
+ else
+ {
+ SVN_ERR_ASSERT(leaving_state == MODIFIED_PATH);
+ action = 'M';
+ }
- apr_hash_set(info->log_entry->changed_paths2, path, APR_HASH_KEY_STRING,
- info->tmp_path);
- svn_ra_serf__xml_pop_state(parser);
+ SVN_ERR(collect_path(log_ctx->collect_paths, action, cdata, attrs));
}
return SVN_NO_ERROR;
}
-static svn_error_t *
-cdata_log(svn_ra_serf__xml_parser_t *parser,
- void *userData,
- const char *data,
- apr_size_t len)
-{
- log_context_t *log_ctx = userData;
- log_state_e state;
- log_info_t *info;
-
- UNUSED_CTX(log_ctx);
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- switch (state)
- {
- case VERSION:
- case CREATOR:
- case DATE:
- case COMMENT:
- case REVPROP:
- case ADDED_PATH:
- case REPLACED_PATH:
- case DELETED_PATH:
- case MODIFIED_PATH:
- svn_ra_serf__expand_string(&info->tmp, &info->tmp_len,
- data, len, info->pool);
- break;
- default:
- break;
- }
-
- return SVN_NO_ERROR;
-}
static svn_error_t *
create_log_body(serf_bucket_t **body_bkt,
@@ -632,11 +515,11 @@ svn_ra_serf__get_log(svn_ra_session_t *ra_session,
log_context_t *log_ctx;
svn_ra_serf__session_t *session = ra_session->priv;
svn_ra_serf__handler_t *handler;
- svn_ra_serf__xml_parser_t *parser_ctx;
+ svn_ra_serf__xml_context_t *xmlctx;
svn_boolean_t want_custom_revprops;
svn_revnum_t peg_rev;
svn_error_t *err;
- const char *relative_url, *basecoll_url, *req_url;
+ const char *req_url;
log_ctx = apr_pcalloc(pool, sizeof(*log_ctx));
log_ctx->pool = pool;
@@ -651,7 +534,6 @@ svn_ra_serf__get_log(svn_ra_session_t *ra_session,
log_ctx->include_merged_revisions = include_merged_revisions;
log_ctx->revprops = revprops;
log_ctx->nest_level = 0;
- log_ctx->done = FALSE;
want_custom_revprops = FALSE;
if (revprops)
@@ -689,14 +571,18 @@ svn_ra_serf__get_log(svn_ra_session_t *ra_session,
/* At this point, we may have a deleted file. So, we'll match ra_neon's
* behavior and use the larger of start or end as our 'peg' rev.
*/
- peg_rev = (start > end) ? start : end;
+ peg_rev = (start == SVN_INVALID_REVNUM || start > end) ? start : end;
- SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
- NULL, NULL, peg_rev, NULL, pool));
+ SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
+ session, NULL /* conn */,
+ NULL /* url */, peg_rev,
+ pool, pool));
- req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool);
-
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(log_ttable,
+ log_opened, log_closed, NULL,
+ log_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
handler->method = "REPORT";
handler->path = req_url;
@@ -706,27 +592,12 @@ svn_ra_serf__get_log(svn_ra_session_t *ra_session,
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = log_ctx;
- parser_ctx->start = start_log;
- parser_ctx->end = end_log;
- parser_ctx->cdata = cdata_log;
- parser_ctx->done = &log_ctx->done;
- parser_ctx->status_code = &log_ctx->status_code;
-
- handler->response_handler = svn_ra_serf__handle_xml_parser;
- handler->response_baton = parser_ctx;
-
- svn_ra_serf__request_create(handler);
-
- err = svn_ra_serf__context_run_wait(&log_ctx->done, session, pool);
+ err = svn_ra_serf__context_run_one(handler, pool);
SVN_ERR(svn_error_compose_create(
- svn_ra_serf__error_on_status(log_ctx->status_code,
+ svn_ra_serf__error_on_status(handler->sline,
req_url,
- parser_ctx->location),
+ handler->location),
err));
return SVN_NO_ERROR;