subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From v...@apache.org
Subject svn commit: r1343447 [10/27] - in /subversion/branches/javahl-ra: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/merge-tracking/ sub...
Date Tue, 29 May 2012 01:39:49 GMT
Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getdate.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getdate.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getdate.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getdate.c Tue May 29 01:39:41 2012
@@ -24,9 +24,6 @@
 
 
 #include <apr_uri.h>
-
-#include <expat.h>
-
 #include <serf.h>
 
 #include "svn_pools.h"
@@ -46,10 +43,11 @@
 /*
  * This enum represents the current state of our XML parsing for a REPORT.
  */
-typedef enum date_state_e {
-  NONE = 0,
+enum date_state_e {
+  INITIAL = 0,
+  REPORT,
   VERSION_NAME
-} date_state_e;
+};
 
 
 typedef struct date_context_t {
@@ -59,79 +57,41 @@ typedef struct date_context_t {
   /* What was the youngest revision at that time? */
   svn_revnum_t *revision;
 
-  /* are we done? */
-  svn_boolean_t done;
-
 } date_context_t;
 
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t date_ttable[] = {
+  { INITIAL, S_, "dated-rev-report", REPORT,
+    FALSE, { NULL }, FALSE, FALSE },
 
-static svn_error_t *
-start_getdate(svn_ra_serf__xml_parser_t *parser,
-              svn_ra_serf__dav_props_t name,
-              const char **attrs,
-              apr_pool_t *scratch_pool)
-{
-  date_context_t *date_ctx = parser->user_data;
-  date_state_e state = parser->state->current_state;
-
-  UNUSED_CTX(date_ctx);
+  { REPORT, D_, SVN_DAV__VERSION_NAME, VERSION_NAME,
+    TRUE, { NULL }, FALSE, TRUE },
 
-  if (state == NONE &&
-      strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, VERSION_NAME);
+  { 0 }
+};
 
-      parser->state->private = svn_stringbuf_create_empty(parser->state->pool);
-    }
-
-  return SVN_NO_ERROR;
-}
 
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_getdate(svn_ra_serf__xml_parser_t *parser,
-            svn_ra_serf__dav_props_t name,
+date_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)
 {
-  date_context_t *date_ctx = parser->user_data;
-  date_state_e state = parser->state->current_state;
+  date_context_t *date_ctx = baton;
 
-  if (state == VERSION_NAME &&
-      strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
-    {
-      const svn_stringbuf_t *datebuf = parser->state->private;
-
-      *date_ctx->revision = SVN_STR_TO_REV(datebuf->data);
-      svn_ra_serf__xml_pop_state(parser);
-    }
+  SVN_ERR_ASSERT(leaving_state == VERSION_NAME);
+  SVN_ERR_ASSERT(cdata != NULL);
 
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-cdata_getdate(svn_ra_serf__xml_parser_t *parser,
-              const char *data,
-              apr_size_t len,
-              apr_pool_t *scratch_pool)
-{
-  date_context_t *date_ctx = parser->user_data;
-  date_state_e state = parser->state->current_state;
-  svn_stringbuf_t *datebuf;
-
-  UNUSED_CTX(date_ctx);
-
-  switch (state)
-    {
-    case VERSION_NAME:
-        datebuf = parser->state->private;
-        svn_stringbuf_appendbytes(datebuf, data, len);
-        break;
-    default:
-        break;
-    }
+  *date_ctx->revision = SVN_STR_TO_REV(cdata->data);
 
   return SVN_NO_ERROR;
 }
 
+
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
 create_getdate_body(serf_bucket_t **body_bkt,
@@ -169,18 +129,19 @@ svn_ra_serf__get_dated_revision(svn_ra_s
   date_context_t *date_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;
   const char *report_target;
-  int status_code;
 
   date_ctx = apr_palloc(pool, sizeof(*date_ctx));
   date_ctx->time = tm;
   date_ctx->revision = revision;
-  date_ctx->done = FALSE;
 
   SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool));
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(date_ttable,
+                                           NULL, date_closed, date_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "REPORT";
   handler->path = report_target;
@@ -188,25 +149,12 @@ svn_ra_serf__get_dated_revision(svn_ra_s
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = date_ctx;
-  parser_ctx->start = start_getdate;
-  parser_ctx->end = end_getdate;
-  parser_ctx->cdata = cdata_getdate;
-  parser_ctx->done = &date_ctx->done;
-  parser_ctx->status_code = &status_code;
-
   handler->body_delegate = create_getdate_body;
   handler->body_delegate_baton = date_ctx;
 
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
-  svn_ra_serf__request_create(handler);
-
   *date_ctx->revision = SVN_INVALID_REVNUM;
 
-  return svn_ra_serf__context_run_wait(&date_ctx->done, session, pool);
+  /* ### use svn_ra_serf__error_on_status() ?  */
+
+  return svn_error_trace(svn_ra_serf__context_run_one(handler, pool));
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocations.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocations.c Tue May 29 01:39:41 2012
@@ -41,18 +41,11 @@
 /*
  * This enum represents the current state of our XML parsing for a REPORT.
  */
-typedef enum loc_state_e {
+enum loc_state_e {
+  INITIAL = 0,
   REPORT,
   LOCATION
-} loc_state_e;
-
-typedef struct loc_state_list_t {
-  /* The current state that we are in now. */
-  loc_state_e state;
-
-  /* The previous state we were in. */
-  struct loc_state_list_t *prev;
-} loc_state_list_t;
+};
 
 typedef struct loc_context_t {
   /* pool to allocate memory from */
@@ -66,114 +59,49 @@ typedef struct loc_context_t {
   /* Returned location hash */
   apr_hash_t *paths;
 
-  /* Current state we're in */
-  loc_state_list_t *state;
-  loc_state_list_t *free_state;
-
-  int status_code;
-
-  svn_boolean_t done;
 } loc_context_t;
 
-
-static void
-push_state(loc_context_t *loc_ctx, loc_state_e state)
-{
-  loc_state_list_t *new_state;
-
-  if (!loc_ctx->free_state)
-    {
-      new_state = apr_palloc(loc_ctx->pool, sizeof(*loc_ctx->state));
-    }
-  else
-    {
-      new_state = loc_ctx->free_state;
-      loc_ctx->free_state = loc_ctx->free_state->prev;
-    }
-  new_state->state = state;
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t getloc_ttable[] = {
+  { INITIAL, S_, "get-locations-report", REPORT,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  /* Add it to the state chain. */
-  new_state->prev = loc_ctx->state;
-  loc_ctx->state = new_state;
-}
+  { REPORT, S_, "location", LOCATION,
+    FALSE, { "?rev", "?path", NULL }, FALSE, TRUE },
 
-static void pop_state(loc_context_t *loc_ctx)
-{
-  loc_state_list_t *free_state;
-  free_state = loc_ctx->state;
-  /* advance the current state */
-  loc_ctx->state = loc_ctx->state->prev;
-  free_state->prev = loc_ctx->free_state;
-  loc_ctx->free_state = free_state;
-}
+  { 0 }
+};
 
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-start_getloc(svn_ra_serf__xml_parser_t *parser,
-             svn_ra_serf__dav_props_t name,
-             const char **attrs,
-             apr_pool_t *scratch_pool)
+getloc_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)
 {
-  loc_context_t *loc_ctx = parser->user_data;
+  loc_context_t *loc_ctx = baton;
+  const char *revstr;
+  const char *path;
 
-  if (!loc_ctx->state && strcmp(name.name, "get-locations-report") == 0)
-    {
-      push_state(loc_ctx, REPORT);
-    }
-  else if (loc_ctx->state &&
-           loc_ctx->state->state == REPORT &&
-           strcmp(name.name, "location") == 0)
-    {
-      svn_revnum_t rev = SVN_INVALID_REVNUM;
-      const char *revstr, *path;
+  SVN_ERR_ASSERT(leaving_state == LOCATION);
 
-      revstr = svn_xml_get_attr_value("rev", attrs);
-      if (revstr)
-        {
-          rev = SVN_STR_TO_REV(revstr);
-        }
-
-      path = svn_xml_get_attr_value("path", attrs);
-
-      if (SVN_IS_VALID_REVNUM(rev) && path)
-        {
-          apr_hash_set(loc_ctx->paths,
-                       apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)),
-                       sizeof(rev),
-                       apr_pstrdup(loc_ctx->pool, path));
-        }
+  revstr = apr_hash_get(attrs, "rev", APR_HASH_KEY_STRING);
+  path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+  if (revstr != NULL && path != NULL)
+    {
+      svn_revnum_t rev = SVN_STR_TO_REV(revstr);
+      apr_hash_set(loc_ctx->paths,
+                   apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)), sizeof(rev),
+                   apr_pstrdup(loc_ctx->pool, path));
     }
 
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-end_getloc(svn_ra_serf__xml_parser_t *parser,
-           svn_ra_serf__dav_props_t name,
-           apr_pool_t *scratch_pool)
-{
-  loc_context_t *loc_ctx = parser->user_data;
-  loc_state_list_t *cur_state;
-
-  if (!loc_ctx->state)
-    {
-      return SVN_NO_ERROR;
-    }
-
-  cur_state = loc_ctx->state;
-
-  if (cur_state->state == REPORT &&
-      strcmp(name.name, "get-locations-report") == 0)
-    {
-      pop_state(loc_ctx);
-    }
-  else if (cur_state->state == LOCATION &&
-           strcmp(name.name, "location") == 0)
-    {
-      pop_state(loc_ctx);
-    }
-
-  return SVN_NO_ERROR;
-}
 
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
@@ -228,8 +156,8 @@ svn_ra_serf__get_locations(svn_ra_sessio
   loc_context_t *loc_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
-  const char *relative_url, *basecoll_url, *req_url;
+  svn_ra_serf__xml_context_t *xmlctx;
+  const char *req_url;
   svn_error_t *err;
 
   loc_ctx = apr_pcalloc(pool, sizeof(*loc_ctx));
@@ -237,18 +165,19 @@ svn_ra_serf__get_locations(svn_ra_sessio
   loc_ctx->path = path;
   loc_ctx->peg_revision = peg_revision;
   loc_ctx->location_revisions = location_revisions;
-  loc_ctx->done = FALSE;
   loc_ctx->paths = apr_hash_make(loc_ctx->pool);
 
   *locations = loc_ctx->paths;
 
-  SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                         NULL, NULL, peg_revision, NULL,
-                                         pool));
-
-  req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool);
-
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
+                                      session, NULL /* conn */,
+                                      NULL /* url */, peg_revision,
+                                      pool, pool));
+
+  xmlctx = svn_ra_serf__xml_context_create(getloc_ttable,
+                                           NULL, getloc_closed, loc_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
@@ -258,26 +187,12 @@ svn_ra_serf__get_locations(svn_ra_sessio
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = loc_ctx;
-  parser_ctx->start = start_getloc;
-  parser_ctx->end = end_getloc;
-  parser_ctx->status_code = &loc_ctx->status_code;
-  parser_ctx->done = &loc_ctx->done;
-
-  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(&loc_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(loc_ctx->status_code,
+              svn_ra_serf__error_on_status(handler->sline.code,
                                            req_url,
-                                           parser_ctx->location),
+                                           handler->location),
               err));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocationsegments.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocationsegments.c Tue May 29 01:39:41 2012
@@ -25,7 +25,6 @@
 
 
 #include <apr_uri.h>
-#include <expat.h>
 #include <serf.h>
 
 #include "svn_pools.h"
@@ -50,82 +49,60 @@ typedef struct gls_context_t {
   svn_location_segment_receiver_t receiver;
   void *receiver_baton;
 
-  /* subpool used only as long as a single receiver invocation */
-  apr_pool_t *subpool;
-
-  /* True iff we're looking at a child of the outer report tag */
-  svn_boolean_t inside_report;
-
-  int status_code;
-
-  svn_boolean_t done;
 } gls_context_t;
 
+enum {
+  INITIAL = 0,
+  REPORT,
+  SEGMENT
+};
+
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t gls_ttable[] = {
+  { INITIAL, S_, "get-location-segments-report", REPORT,
+    FALSE, { NULL }, FALSE, FALSE },
 
-static svn_error_t *
-start_gls(svn_ra_serf__xml_parser_t *parser,
-          svn_ra_serf__dav_props_t name,
-          const char **attrs,
-          apr_pool_t *scratch_pool)
-{
-  gls_context_t *gls_ctx = parser->user_data;
+  { REPORT, S_, "location-segment", SEGMENT,
+    FALSE, { "?path", "range-start", "range-end", NULL }, FALSE, TRUE },
 
-  if ((! gls_ctx->inside_report)
-      && strcmp(name.name, "get-location-segments-report") == 0)
-    {
-      gls_ctx->inside_report = TRUE;
-    }
-  else if (gls_ctx->inside_report
-           && strcmp(name.name, "location-segment") == 0)
-    {
-      const char *rev_str;
-      svn_revnum_t range_start = SVN_INVALID_REVNUM;
-      svn_revnum_t range_end = SVN_INVALID_REVNUM;
-      const char *path = NULL;
-
-      path = svn_xml_get_attr_value("path", attrs);
-      rev_str = svn_xml_get_attr_value("range-start", attrs);
-      if (rev_str)
-        range_start = SVN_STR_TO_REV(rev_str);
-      rev_str = svn_xml_get_attr_value("range-end", attrs);
-      if (rev_str)
-        range_end = SVN_STR_TO_REV(rev_str);
-
-      if (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end))
-        {
-          svn_location_segment_t *segment = apr_pcalloc(gls_ctx->subpool,
-                                                        sizeof(*segment));
-          segment->path = path;
-          segment->range_start = range_start;
-          segment->range_end = range_end;
-          SVN_ERR(gls_ctx->receiver(segment,
-                                    gls_ctx->receiver_baton,
-                                    gls_ctx->subpool));
-          svn_pool_clear(gls_ctx->subpool);
-        }
-      else
-        {
-          return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
-                                  _("Expected valid revision range"));
-        }
-    }
+  { 0 }
+};
 
-  return SVN_NO_ERROR;
-}
 
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_gls(svn_ra_serf__xml_parser_t *parser,
-        svn_ra_serf__dav_props_t name,
-        apr_pool_t *scratch_pool)
+gls_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)
 {
-  gls_context_t *gls_ctx = parser->user_data;
-
-  if (strcmp(name.name, "get-location-segments-report") == 0)
-    gls_ctx->inside_report = FALSE;
+  gls_context_t *gls_ctx = baton;
+  const char *path;
+  const char *start_str;
+  const char *end_str;
+  svn_location_segment_t segment;
+
+  SVN_ERR_ASSERT(leaving_state == SEGMENT);
+
+  path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+  start_str = apr_hash_get(attrs, "range-start", APR_HASH_KEY_STRING);
+  end_str = apr_hash_get(attrs, "range-end", APR_HASH_KEY_STRING);
+
+  /* The transition table said these must exist.  */
+  SVN_ERR_ASSERT(start_str && end_str);
+
+  segment.path = path;  /* may be NULL  */
+  segment.range_start = SVN_STR_TO_REV(start_str);
+  segment.range_end = SVN_STR_TO_REV(end_str);
+  SVN_ERR(gls_ctx->receiver(&segment, gls_ctx->receiver_baton, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
+
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
 create_gls_body(serf_bucket_t **body_bkt,
@@ -182,8 +159,8 @@ svn_ra_serf__get_location_segments(svn_r
   gls_context_t *gls_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
-  const char *relative_url, *basecoll_url, *req_url;
+  svn_ra_serf__xml_context_t *xmlctx;
+  const char *req_url;
   svn_error_t *err;
 
   gls_ctx = apr_pcalloc(pool, sizeof(*gls_ctx));
@@ -193,16 +170,16 @@ svn_ra_serf__get_location_segments(svn_r
   gls_ctx->end_rev = end_rev;
   gls_ctx->receiver = receiver;
   gls_ctx->receiver_baton = receiver_baton;
-  gls_ctx->subpool = svn_pool_create(pool);
-  gls_ctx->inside_report = FALSE;
-  gls_ctx->done = FALSE;
-
-  SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                         NULL, NULL, peg_revision, NULL, pool));
 
-  req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool);
-
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
+                                      session, NULL /* conn */,
+                                      NULL /* url */, peg_revision,
+                                      pool, pool));
+
+  xmlctx = svn_ra_serf__xml_context_create(gls_ttable,
+                                           NULL, gls_closed, gls_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
@@ -212,34 +189,13 @@ svn_ra_serf__get_location_segments(svn_r
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = gls_ctx;
-  parser_ctx->start = start_gls;
-  parser_ctx->end = end_gls;
-  parser_ctx->status_code = &gls_ctx->status_code;
-  parser_ctx->done = &gls_ctx->done;
-
-  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(&gls_ctx->done, session, pool);
-
-  if (gls_ctx->inside_report)
-    err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, err,
-                            _("Location segment report failed on '%s'@'%ld'"),
-                              path, peg_revision);
+  err = svn_ra_serf__context_run_one(handler, pool);
 
   err = svn_error_compose_create(
-         svn_ra_serf__error_on_status(gls_ctx->status_code,
+         svn_ra_serf__error_on_status(handler->sline.code,
                                       handler->path,
-                                      parser_ctx->location),
-         err);;
-
-  svn_pool_destroy(gls_ctx->subpool);
+                                      handler->location),
+         err);
 
   if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))
     return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL);

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocks.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/getlocks.c Tue May 29 01:39:41 2012
@@ -46,8 +46,8 @@
 /*
  * This enum represents the current state of our XML parsing for a REPORT.
  */
-typedef enum lock_state_e {
-  NONE = 0,
+enum {
+  INITIAL = 0,
   REPORT,
   LOCK,
   PATH,
@@ -56,18 +56,7 @@ typedef enum lock_state_e {
   COMMENT,
   CREATION_DATE,
   EXPIRATION_DATE
-} lock_state_e;
-
-typedef struct lock_info_t {
-  /* Temporary pool */
-  apr_pool_t *pool;
-
-  svn_lock_t *lock;
-
-  /* The currently collected value as we build it up */
-  svn_stringbuf_t *cdata;
-
-} lock_info_t;
+};
 
 typedef struct lock_context_t {
   apr_pool_t *pool;
@@ -79,107 +68,55 @@ typedef struct lock_context_t {
   /* return hash */
   apr_hash_t *hash;
 
-  /* are we done? */
-  svn_boolean_t done;
-
 } lock_context_t;
 
-
-static lock_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
-           lock_context_t *lock_ctx,
-           lock_state_e state)
-{
-  svn_ra_serf__xml_push_state(parser, state);
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t getlocks_ttable[] = {
+  { INITIAL, S_, "get-locks-report", REPORT,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  if (state == LOCK)
-    {
-      lock_info_t *info;
+  { REPORT, S_, "lock", LOCK,
+    FALSE, { NULL }, FALSE, TRUE },
 
-      info = apr_pcalloc(parser->state->pool, sizeof(*info));
+  { LOCK, S_, "path", PATH,
+    TRUE, { NULL }, FALSE, TRUE },
 
-      info->pool = lock_ctx->pool;
-      info->lock = svn_lock_create(lock_ctx->pool);
-      info->cdata = svn_stringbuf_create_empty(info->pool);
+  { LOCK, S_, "token", TOKEN,
+    TRUE, { NULL }, FALSE, TRUE },
 
-      parser->state->private = info;
-    }
+  { LOCK, S_, "owner", OWNER,
+    TRUE, { NULL }, FALSE, TRUE },
 
-  return parser->state->private;
-}
+  { LOCK, S_, "comment", COMMENT,
+    TRUE, { NULL }, FALSE, TRUE },
 
-static svn_error_t *
-start_getlocks(svn_ra_serf__xml_parser_t *parser,
-               svn_ra_serf__dav_props_t name,
-               const char **attrs,
-               apr_pool_t *scratch_pool)
-{
-  lock_context_t *lock_ctx = parser->user_data;
-  lock_state_e state;
+  { LOCK, S_, SVN_DAV__CREATIONDATE, CREATION_DATE,
+    TRUE, { NULL }, FALSE, TRUE },
 
-  state = parser->state->current_state;
+  { LOCK, S_, "expirationdate", EXPIRATION_DATE,
+    TRUE, { NULL }, FALSE, TRUE },
 
-  if (state == NONE &&
-      strcmp(name.name, "get-locks-report") == 0)
-    {
-      push_state(parser, lock_ctx, REPORT);
-    }
-  else if (state == REPORT &&
-           strcmp(name.name, "lock") == 0)
-    {
-      push_state(parser, lock_ctx, LOCK);
-    }
-  else if (state == LOCK)
-    {
-      if (strcmp(name.name, "path") == 0)
-        {
-          push_state(parser, lock_ctx, PATH);
-        }
-      else if (strcmp(name.name, "token") == 0)
-        {
-          push_state(parser, lock_ctx, TOKEN);
-        }
-      else if (strcmp(name.name, "owner") == 0)
-        {
-          push_state(parser, lock_ctx, OWNER);
-        }
-      else if (strcmp(name.name, "comment") == 0)
-        {
-          push_state(parser, lock_ctx, COMMENT);
-        }
-      else if (strcmp(name.name, SVN_DAV__CREATIONDATE) == 0)
-        {
-          push_state(parser, lock_ctx, CREATION_DATE);
-        }
-      else if (strcmp(name.name, "expirationdate") == 0)
-        {
-          push_state(parser, lock_ctx, EXPIRATION_DATE);
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
+  { 0 }
+};
 
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_getlocks(svn_ra_serf__xml_parser_t *parser,
-             svn_ra_serf__dav_props_t name,
-             apr_pool_t *scratch_pool)
+getlocks_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)
 {
-  lock_context_t *lock_ctx = parser->user_data;
-  lock_state_e state;
-  lock_info_t *info;
-
-  state = parser->state->current_state;
-  info = parser->state->private;
+  lock_context_t *lock_ctx = baton;
 
-  if (state == REPORT &&
-      strcmp(name.name, "get-locks-report") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == LOCK &&
-           strcmp(name.name, "lock") == 0)
+  if (leaving_state == LOCK)
     {
+      const char *path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+      svn_boolean_t save_lock = FALSE;
+
       /* Filter out unwanted paths.  Since Subversion only allows
          locks on files, we can treat depth=immediates the same as
          depth=files for filtering purposes.  Meaning, we'll keep
@@ -190,108 +127,81 @@ end_getlocks(svn_ra_serf__xml_parser_t *
          c) we've asked for depth=files or depth=immediates, and this
             lock is on an immediate child of our query path.
       */
-      if ((strcmp(lock_ctx->path, info->lock->path) == 0)
-          || (lock_ctx->requested_depth == svn_depth_infinity))
+      if (strcmp(lock_ctx->path, path) == 0
+          || lock_ctx->requested_depth == svn_depth_infinity)
         {
-          apr_hash_set(lock_ctx->hash, info->lock->path,
-                       APR_HASH_KEY_STRING, info->lock);
+          save_lock = TRUE;
         }
-      else if ((lock_ctx->requested_depth == svn_depth_files) ||
-               (lock_ctx->requested_depth == svn_depth_immediates))
+      else if (lock_ctx->requested_depth == svn_depth_files
+               || lock_ctx->requested_depth == svn_depth_immediates)
         {
-          const char *rel_path = svn_fspath__skip_ancestor(lock_ctx->path,
-                                                           info->lock->path);
-          if (rel_path && (svn_path_component_count(rel_path) == 1))
-            apr_hash_set(lock_ctx->hash, info->lock->path,
-                         APR_HASH_KEY_STRING, info->lock);
-        }
+          const char *relpath = svn_fspath__skip_ancestor(lock_ctx->path,
+                                                          path);
+          if (relpath && (svn_path_component_count(relpath) == 1))
+            save_lock = TRUE;
+        }
+
+      if (save_lock)
+        {
+          /* We get to put the structure on the stack rather than using
+             svn_lock_create(). Bwahahaha....   */
+          svn_lock_t lock = { 0 };
+          const char *date;
+          svn_lock_t *result_lock;
+
+          /* Note: these "attributes" came from child elements. Some of
+             them may have not been sent, so the value will be NULL.  */
+
+          lock.path = path;
+          lock.token = apr_hash_get(attrs, "token", APR_HASH_KEY_STRING);
+          lock.owner = apr_hash_get(attrs, "owner", APR_HASH_KEY_STRING);
+          lock.comment = apr_hash_get(attrs, "comment", APR_HASH_KEY_STRING);
+
+          date = apr_hash_get(attrs, SVN_DAV__CREATIONDATE,
+                              APR_HASH_KEY_STRING);
+          if (date)
+            SVN_ERR(svn_time_from_cstring(&lock.creation_date, date,
+                                          scratch_pool));
+
+          date = apr_hash_get(attrs, "expirationdate",
+                              APR_HASH_KEY_STRING);
+          if (date)
+            SVN_ERR(svn_time_from_cstring(&lock.expiration_date, date,
+                                          scratch_pool));
+
+          result_lock = svn_lock_dup(&lock, lock_ctx->pool);
+          apr_hash_set(lock_ctx->hash, result_lock->path, APR_HASH_KEY_STRING,
+                       result_lock);
+        }
+    }
+  else
+    {
+      const char *name;
+
+      SVN_ERR_ASSERT(cdata != NULL);
+
+      if (leaving_state == PATH)
+        name = "path";
+      else if (leaving_state == TOKEN)
+        name = "token";
+      else if (leaving_state == OWNER)
+        name = "owner";
+      else if (leaving_state == COMMENT)
+        name = "comment";
+      else if (leaving_state == CREATION_DATE)
+        name = SVN_DAV__CREATIONDATE;
+      else if (leaving_state == EXPIRATION_DATE)
+        name = "expirationdate";
+      else
+        SVN_ERR_MALFUNCTION();
 
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == PATH &&
-           strcmp(name.name, "path") == 0)
-    {
-      info->lock->path = apr_pstrmemdup(info->pool,
-                                        info->cdata->data, info->cdata->len);
-      svn_stringbuf_setempty(info->cdata);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == TOKEN &&
-           strcmp(name.name, "token") == 0)
-    {
-      info->lock->token = apr_pstrmemdup(info->pool,
-                                         info->cdata->data, info->cdata->len);
-      svn_stringbuf_setempty(info->cdata);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == OWNER &&
-           strcmp(name.name, "owner") == 0)
-    {
-      info->lock->owner = apr_pstrmemdup(info->pool,
-                                         info->cdata->data, info->cdata->len);
-      svn_stringbuf_setempty(info->cdata);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == COMMENT &&
-           strcmp(name.name, "comment") == 0)
-    {
-      info->lock->comment = apr_pstrmemdup(info->pool,
-                                           info->cdata->data,
-                                           info->cdata->len);
-      svn_stringbuf_setempty(info->cdata);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == CREATION_DATE &&
-           strcmp(name.name, SVN_DAV__CREATIONDATE) == 0)
-    {
-      SVN_ERR(svn_time_from_cstring(&info->lock->creation_date,
-                                    info->cdata->data, info->pool));
-      svn_stringbuf_setempty(info->cdata);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == EXPIRATION_DATE &&
-           strcmp(name.name, "expirationdate") == 0)
-    {
-      SVN_ERR(svn_time_from_cstring(&info->lock->expiration_date,
-                                    info->cdata->data, info->pool));
-      svn_stringbuf_setempty(info->cdata);
-      svn_ra_serf__xml_pop_state(parser);
+      /* Store the lock information onto the LOCK elemstate.  */
+      svn_ra_serf__xml_note(xes, LOCK, name, cdata->data);
     }
 
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-cdata_getlocks(svn_ra_serf__xml_parser_t *parser,
-               const char *data,
-               apr_size_t len,
-               apr_pool_t *scratch_pool)
-{
-  lock_context_t *lock_ctx = parser->user_data;
-  lock_state_e state;
-  lock_info_t *info;
-
-  UNUSED_CTX(lock_ctx);
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  switch (state)
-    {
-    case PATH:
-    case TOKEN:
-    case OWNER:
-    case COMMENT:
-    case CREATION_DATE:
-    case EXPIRATION_DATE:
-        svn_stringbuf_appendbytes(info->cdata, data, len);
-        break;
-      default:
-        break;
-    }
-
-  return SVN_NO_ERROR;
-}
 
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
@@ -324,9 +234,8 @@ svn_ra_serf__get_locks(svn_ra_session_t 
   lock_context_t *lock_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;
   const char *req_url, *rel_path;
-  int status_code;
 
   req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
   SVN_ERR(svn_ra_serf__get_relative_path(&rel_path, req_url, session,
@@ -337,9 +246,11 @@ svn_ra_serf__get_locks(svn_ra_session_t 
   lock_ctx->path = apr_pstrcat(pool, "/", rel_path, (char *)NULL);
   lock_ctx->requested_depth = depth;
   lock_ctx->hash = apr_hash_make(pool);
-  lock_ctx->done = FALSE;
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(getlocks_ttable,
+                                           NULL, getlocks_closed, lock_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
@@ -347,25 +258,12 @@ svn_ra_serf__get_locks(svn_ra_session_t 
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = lock_ctx;
-  parser_ctx->start = start_getlocks;
-  parser_ctx->end = end_getlocks;
-  parser_ctx->cdata = cdata_getlocks;
-  parser_ctx->done = &lock_ctx->done;
-  parser_ctx->status_code = &status_code;
-
   handler->body_delegate = create_getlocks_body;
   handler->body_delegate_baton = lock_ctx;
 
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
-  svn_ra_serf__request_create(handler);
+  /* ### use svn_ra_serf__error_on_status() ?  */
 
-  SVN_ERR(svn_ra_serf__context_run_wait(&lock_ctx->done, session, pool));
+  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
   *locks = lock_ctx->hash;
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/locks.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/locks.c Tue May 29 01:39:41 2012
@@ -24,9 +24,6 @@
 
 
 #include <apr_uri.h>
-
-#include <expat.h>
-
 #include <serf.h>
 
 #include "svn_dav.h"
@@ -45,8 +42,11 @@
 /*
  * This enum represents the current state of our XML parsing for a REPORT.
  */
-typedef enum lock_state_e {
-  NONE = 0,
+enum {
+  INITIAL = 0,
+  MULTISTATUS,
+  RESPONSE,
+  PROPSTAT,
   PROP,
   LOCK_DISCOVERY,
   ACTIVE_LOCK,
@@ -55,8 +55,9 @@ typedef enum lock_state_e {
   DEPTH,
   TIMEOUT,
   LOCK_TOKEN,
-  COMMENT
-} lock_state_e;
+  OWNER,
+  HREF
+};
 
 typedef struct lock_info_t {
   apr_pool_t *pool;
@@ -70,246 +71,119 @@ typedef struct lock_info_t {
 
   svn_boolean_t read_headers;
 
-  /* Our HTTP status code and reason. */
-  int status_code;
-  const char *reason;
+  svn_ra_serf__handler_t *handler;
+
+  /* The expat handler. We wrap this to do a bit more work.  */
+  svn_ra_serf__response_handler_t inner_handler;
+  void *inner_baton;
 
-  /* are we done? */
-  svn_boolean_t done;
 } lock_info_t;
 
-
-static svn_stringbuf_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
-           lock_info_t *lock_ctx,
-           lock_state_e state)
-{
-  svn_ra_serf__xml_push_state(parser, state);
-  switch (state)
-    {
-    case LOCK_TYPE:
-    case LOCK_SCOPE:
-    case DEPTH:
-    case TIMEOUT:
-    case LOCK_TOKEN:
-    case COMMENT:
-        parser->state->private =
-          svn_stringbuf_create_empty(parser->state->pool);
-        break;
-      default:
-        break;
-    }
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t locks_ttable[] = {
+  /* The INITIAL state can transition into D:prop (LOCK) or
+     to D:multistatus (PROPFIND)  */
+  { INITIAL, D_, "prop", PROP,
+    FALSE, { NULL }, FALSE, FALSE },
+  { INITIAL, D_, "multistatus", MULTISTATUS,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  return parser->state->private;
-}
+  { MULTISTATUS, D_, "response", RESPONSE,
+    FALSE, { NULL }, FALSE, FALSE },
 
-/*
- * Expat callback invoked on a start element tag for a PROPFIND response.
- */
-static svn_error_t *
-start_lock(svn_ra_serf__xml_parser_t *parser,
-           svn_ra_serf__dav_props_t name,
-           const char **attrs,
-           apr_pool_t *scratch_pool)
-{
-  lock_info_t *ctx = parser->user_data;
-  lock_state_e state;
+  { RESPONSE, D_, "propstat", PROPSTAT,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  state = parser->state->current_state;
+  { PROPSTAT, D_, "prop", PROP,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  if (state == NONE && strcmp(name.name, "prop") == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, PROP);
-    }
-  else if (state == PROP &&
-           strcmp(name.name, "lockdiscovery") == 0)
-    {
-      push_state(parser, ctx, LOCK_DISCOVERY);
-    }
-  else if (state == LOCK_DISCOVERY &&
-           strcmp(name.name, "activelock") == 0)
-    {
-      push_state(parser, ctx, ACTIVE_LOCK);
-    }
-  else if (state == ACTIVE_LOCK)
-    {
-      if (strcmp(name.name, "locktype") == 0)
-        {
-          push_state(parser, ctx, LOCK_TYPE);
-        }
-      else if (strcmp(name.name, "lockscope") == 0)
-        {
-          push_state(parser, ctx, LOCK_SCOPE);
-        }
-      else if (strcmp(name.name, "depth") == 0)
-        {
-          push_state(parser, ctx, DEPTH);
-        }
-      else if (strcmp(name.name, "timeout") == 0)
-        {
-          push_state(parser, ctx, TIMEOUT);
-        }
-      else if (strcmp(name.name, "locktoken") == 0)
-        {
-          push_state(parser, ctx, LOCK_TOKEN);
-        }
-      else if (strcmp(name.name, "owner") == 0)
-        {
-          push_state(parser, ctx, COMMENT);
-        }
-    }
-  else if (state == LOCK_TYPE)
-    {
-      if (strcmp(name.name, "write") == 0)
-        {
-          /* Do nothing. */
-        }
-      else
-        {
-          SVN_ERR_MALFUNCTION();
-        }
-    }
-  else if (state == LOCK_SCOPE)
-    {
-      if (strcmp(name.name, "exclusive") == 0)
-        {
-          /* Do nothing. */
-        }
-      else
-        {
-          SVN_ERR_MALFUNCTION();
-        }
-    }
+  { PROP, D_, "lockdiscovery", LOCK_DISCOVERY,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  return SVN_NO_ERROR;
-}
+  { LOCK_DISCOVERY, D_, "activelock", ACTIVE_LOCK,
+    FALSE, { NULL }, FALSE, FALSE },
 
-/*
- * Expat callback invoked on an end element tag for a PROPFIND response.
- */
+#if 0
+  /* ### we don't really need to parse locktype/lockscope. we know what
+     ### the values are going to be. we *could* validate that the only
+     ### possible children are D:write and D:exclusive. we'd need to
+     ### modify the state transition to tell us about all children
+     ### (ie. maybe support "*" for the name) and then validate. but it
+     ### just isn't important to validate, so disable this for now... */
+
+  { ACTIVE_LOCK, D_, "locktype", LOCK_TYPE,
+    FALSE, { NULL }, FALSE, FALSE },
+
+  { LOCK_TYPE, D_, "write", WRITE,
+    FALSE, { NULL }, FALSE, TRUE },
+
+  { ACTIVE_LOCK, D_, "lockscope", LOCK_SCOPE,
+    FALSE, { NULL }, FALSE, FALSE },
+
+  { LOCK_SCOPE, D_, "exclusive", EXCLUSIVE,
+    FALSE, { NULL }, FALSE, TRUE },
+#endif /* 0  */
+
+  { ACTIVE_LOCK, D_, "timeout", TIMEOUT,
+    TRUE, { NULL }, FALSE, TRUE },
+
+  { ACTIVE_LOCK, D_, "locktoken", LOCK_TOKEN,
+    FALSE, { NULL }, FALSE, FALSE },
+
+  { LOCK_TOKEN, D_, "href", HREF,
+    TRUE, { NULL }, FALSE, TRUE },
+
+  { ACTIVE_LOCK, D_, "owner", OWNER,
+    TRUE, { NULL }, FALSE, TRUE },
+
+  /* ACTIVE_LOCK has a D:depth child, but we can ignore that.  */
+
+  { 0 }
+};
+
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_lock(svn_ra_serf__xml_parser_t *parser,
-         svn_ra_serf__dav_props_t name,
-         apr_pool_t *scratch_pool)
+locks_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)
 {
-  lock_info_t *ctx = parser->user_data;
-  lock_state_e state;
-
-  state = parser->state->current_state;
+  lock_info_t *lock_ctx = baton;
 
-  if (state == PROP &&
-      strcmp(name.name, "prop") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == LOCK_DISCOVERY &&
-           strcmp(name.name, "lockdiscovery") == 0)
+  if (leaving_state == TIMEOUT)
     {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == ACTIVE_LOCK &&
-           strcmp(name.name, "activelock") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == LOCK_TYPE &&
-           strcmp(name.name, "locktype") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == LOCK_SCOPE &&
-           strcmp(name.name, "lockscope") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == DEPTH &&
-           strcmp(name.name, "depth") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == TIMEOUT &&
-           strcmp(name.name, "timeout") == 0)
-    {
-      svn_stringbuf_t *info = parser->state->private;
-
-      if (strcmp(info->data, "Infinite") == 0)
-        {
-          ctx->lock->expiration_date = 0;
-        }
+      if (strcmp(cdata->data, "Infinite") == 0)
+        lock_ctx->lock->expiration_date = 0;
       else
-        {
-          SVN_ERR(svn_time_from_cstring(&ctx->lock->creation_date,
-                                        info->data, ctx->pool));
-        }
-      svn_ra_serf__xml_pop_state(parser);
+        SVN_ERR(svn_time_from_cstring(&lock_ctx->lock->creation_date,
+                                      cdata->data, lock_ctx->pool));
     }
-  else if (state == LOCK_TOKEN &&
-           strcmp(name.name, "locktoken") == 0)
+  else if (leaving_state == HREF)
     {
-      svn_stringbuf_t *info = parser->state->private;
-
-      if (!ctx->lock->token && info->len)
+      if (cdata->len)
         {
-          apr_collapse_spaces(info->data, info->data);
-          ctx->lock->token = apr_pstrmemdup(ctx->pool, info->data, info->len);
+          char *buf = apr_pstrmemdup(lock_ctx->pool, cdata->data, cdata->len);
+
+          apr_collapse_spaces(buf, buf);
+          lock_ctx->lock->token = buf;
         }
-      /* We don't actually need the lock token. */
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == COMMENT &&
-           strcmp(name.name, "owner") == 0)
+  else if (leaving_state == OWNER)
     {
-      svn_stringbuf_t *info = parser->state->private;
-
-      if (info->len)
+      if (cdata->len)
         {
-          ctx->lock->comment = apr_pstrmemdup(ctx->pool,
-                                              info->data, info->len);
+          lock_ctx->lock->comment = apr_pstrmemdup(lock_ctx->pool,
+                                                   cdata->data, cdata->len);
         }
-      svn_ra_serf__xml_pop_state(parser);
     }
 
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-cdata_lock(svn_ra_serf__xml_parser_t *parser,
-           const char *data,
-           apr_size_t len,
-           apr_pool_t *scratch_pool)
-{
-  lock_info_t *lock_ctx = parser->user_data;
-  lock_state_e state;
-  svn_stringbuf_t *info;
-
-  UNUSED_CTX(lock_ctx);
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  switch (state)
-    {
-    case LOCK_TYPE:
-    case LOCK_SCOPE:
-    case DEPTH:
-    case TIMEOUT:
-    case LOCK_TOKEN:
-    case COMMENT:
-        svn_stringbuf_appendbytes(info, data, len);
-        break;
-
-      default:
-        break;
-    }
-
-  return SVN_NO_ERROR;
-}
-
-static const svn_ra_serf__dav_props_t lock_props[] =
-{
-  { "DAV:", "lockdiscovery" },
-  { NULL }
-};
 
 static svn_error_t *
 set_lock_headers(serf_bucket_t *headers,
@@ -333,6 +207,39 @@ set_lock_headers(serf_bucket_t *headers,
   return APR_SUCCESS;
 }
 
+
+/* Register an error within the session. If something is already there,
+   then it will take precedence.  */
+static svn_error_t *
+determine_error(svn_ra_serf__handler_t *handler,
+                svn_error_t *err)
+{
+    {
+      apr_status_t errcode;
+
+      if (handler->sline.code == 423)
+        errcode = SVN_ERR_FS_PATH_ALREADY_LOCKED;
+      else if (handler->sline.code == 403)
+        errcode = SVN_ERR_RA_DAV_FORBIDDEN;
+      else
+        return err;
+
+      /* Client-side or server-side error already. Return it.  */
+      if (err != NULL)
+        return err;
+
+      /* The server did not send us a detailed human-readable error.
+         Provide a generic error.  */
+      err = svn_error_createf(errcode, NULL,
+                              _("Lock request failed: %d %s"),
+                              handler->sline.code,
+                              handler->sline.reason);
+    }
+
+  return err;
+}
+
+
 /* Implements svn_ra_serf__response_handler_t */
 static svn_error_t *
 handle_lock(serf_request_t *request,
@@ -340,43 +247,25 @@ handle_lock(serf_request_t *request,
             void *handler_baton,
             apr_pool_t *pool)
 {
-  svn_ra_serf__xml_parser_t *xml_ctx = handler_baton;
-  lock_info_t *ctx = xml_ctx->user_data;
-  svn_error_t *err;
+  lock_info_t *ctx = handler_baton;
+
+  /* 403 (Forbidden) when a lock doesn't exist.
+     423 (Locked) when a lock already exists.  */
+  if (ctx->handler->sline.code == 403
+      || ctx->handler->sline.code == 423)
+    {
+      /* Go look in the body for a server-provided error. This will
+         reset flags for the core handler to Do The Right Thing. We
+         won't be back to this handler again.  */
+      return svn_error_trace(svn_ra_serf__expect_empty_body(
+                               request, response, ctx->handler, pool));
+    }
 
   if (ctx->read_headers == FALSE)
     {
       serf_bucket_t *headers;
       const char *val;
 
-      serf_status_line sl;
-      apr_status_t status;
-
-      status = serf_bucket_response_status(response, &sl);
-      if (SERF_BUCKET_READ_ERROR(status))
-        {
-          return svn_error_wrap_apr(status, NULL);
-        }
-
-      ctx->status_code = sl.code;
-      ctx->reason = sl.reason;
-
-      /* 423 == Locked */
-      if (sl.code == 423)
-        {
-          /* Older servers may not give a descriptive error, so we'll
-             make one of our own if we can't find one in the response. */
-          err = svn_ra_serf__handle_server_error(request, response, pool);
-          if (!err)
-            {
-              err = svn_error_createf(SVN_ERR_FS_PATH_ALREADY_LOCKED,
-                                      NULL,
-                                      _("Lock request failed: %d %s"),
-                                      ctx->status_code, ctx->reason);
-            }
-          return err;
-        }
-
       headers = serf_bucket_response_get_headers(response);
 
       val = serf_bucket_headers_get(headers, SVN_DAV_LOCK_OWNER_HEADER);
@@ -395,25 +284,7 @@ handle_lock(serf_request_t *request,
       ctx->read_headers = TRUE;
     }
 
-  /* Forbidden when a lock doesn't exist. */
-  if (ctx->status_code == 403)
-    {
-      /* If we get an "unexpected EOF" error, we'll wrap it with
-         generic request failure error. */
-      err = svn_ra_serf__handle_discard_body(request, response, NULL, pool);
-      if (err && APR_STATUS_IS_EOF(err->apr_err))
-        {
-          ctx->done = TRUE;
-          err = svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN,
-                                  err,
-                                  _("Lock request failed: %d %s"),
-                                  ctx->status_code, ctx->reason);
-        }
-      return err;
-    }
-
-  return svn_ra_serf__handle_xml_parser(request, response,
-                                        handler_baton, pool);
+  return ctx->inner_handler(request, response, ctx->inner_baton, pool);
 }
 
 /* Implements svn_ra_serf__request_body_delegate_t */
@@ -445,7 +316,7 @@ setup_getlock_headers(serf_bucket_t *hea
                       void *baton,
                       apr_pool_t *pool)
 {
-  serf_bucket_headers_set(headers, "Depth", "0");
+  serf_bucket_headers_setn(headers, "Depth", "0");
 
   return SVN_NO_ERROR;
 }
@@ -495,11 +366,10 @@ svn_ra_serf__get_lock(svn_ra_session_t *
 {
   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;
   lock_info_t *lock_ctx;
   const char *req_url;
   svn_error_t *err;
-  int status_code;
 
   req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
 
@@ -508,9 +378,12 @@ svn_ra_serf__get_lock(svn_ra_session_t *
   lock_ctx->pool = pool;
   lock_ctx->path = req_url;
   lock_ctx->lock = svn_lock_create(pool);
-  lock_ctx->lock->path = path;
+  lock_ctx->lock->path = apr_pstrdup(pool, path); /* be sure  */
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(locks_ttable,
+                                           NULL, locks_closed, lock_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "PROPFIND";
   handler->path = req_url;
@@ -518,29 +391,23 @@ svn_ra_serf__get_lock(svn_ra_session_t *
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = lock_ctx;
-  parser_ctx->start = start_lock;
-  parser_ctx->end = end_lock;
-  parser_ctx->cdata = cdata_lock;
-  parser_ctx->done = &lock_ctx->done;
-  parser_ctx->status_code = &status_code;
-
   handler->body_delegate = create_getlock_body;
   handler->body_delegate_baton = lock_ctx;
 
   handler->header_delegate = setup_getlock_headers;
   handler->header_delegate_baton = lock_ctx;
 
+  lock_ctx->inner_handler = handler->response_handler;
+  lock_ctx->inner_baton = handler->response_baton;
   handler->response_handler = handle_lock;
-  handler->response_baton = parser_ctx;
+  handler->response_baton = lock_ctx;
 
-  svn_ra_serf__request_create(handler);
-  err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, pool);
+  lock_ctx->handler = handler;
 
-  if (status_code == 404)
+  err = svn_ra_serf__context_run_one(handler, pool);
+  err = determine_error(handler, err);
+
+  if (handler->sline.code == 404)
     {
       return svn_error_create(SVN_ERR_RA_ILLEGAL_URL, err,
                               _("Malformed URL for repository"));
@@ -573,13 +440,16 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
   iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
-     loop is just a temporary shim. */
+     ### loop is just a temporary shim.
+     ### an alternative, which is backwards-compat with all servers is to
+     ### pipeline these requests. ie. stop using run_wait/run_one.  */
+
   for (hi = apr_hash_first(scratch_pool, path_revs);
        hi;
        hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
-      svn_ra_serf__xml_parser_t *parser_ctx;
+      svn_ra_serf__xml_context_t *xmlctx;
       const char *req_url;
       lock_info_t *lock_ctx;
       svn_error_t *err;
@@ -600,7 +470,10 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       req_url = svn_path_url_add_component2(session->session_url.path,
                                             lock_ctx->path, iterpool);
 
-      handler = apr_pcalloc(iterpool, sizeof(*handler));
+      xmlctx = svn_ra_serf__xml_context_create(locks_ttable,
+                                               NULL, locks_closed, lock_ctx,
+                                               iterpool);
+      handler = svn_ra_serf__create_expat_handler(xmlctx, iterpool);
 
       handler->method = "LOCK";
       handler->path = req_url;
@@ -608,26 +481,21 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       handler->conn = session->conns[0];
       handler->session = session;
 
-      parser_ctx = apr_pcalloc(iterpool, sizeof(*parser_ctx));
-
-      parser_ctx->pool = iterpool;
-      parser_ctx->user_data = lock_ctx;
-      parser_ctx->start = start_lock;
-      parser_ctx->end = end_lock;
-      parser_ctx->cdata = cdata_lock;
-      parser_ctx->done = &lock_ctx->done;
-
       handler->header_delegate = set_lock_headers;
       handler->header_delegate_baton = lock_ctx;
 
       handler->body_delegate = create_lock_body;
       handler->body_delegate_baton = lock_ctx;
 
+      lock_ctx->inner_handler = handler->response_handler;
+      lock_ctx->inner_baton = handler->response_baton;
       handler->response_handler = handle_lock;
-      handler->response_baton = parser_ctx;
+      handler->response_baton = lock_ctx;
+
+      lock_ctx->handler = handler;
 
-      svn_ra_serf__request_create(handler);
-      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, iterpool);
+      err = svn_ra_serf__context_run_one(handler, iterpool);
+      err = determine_error(handler, err);
 
       if (lock_func)
         new_err = lock_func(lock_baton, lock_ctx->path, TRUE, lock_ctx->lock,
@@ -679,13 +547,15 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
   iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
-     loop is just a temporary shim. */
+     ### loop is just a temporary shim.
+     ### an alternative, which is backwards-compat with all servers is to
+     ### pipeline these requests. ie. stop using run_wait/run_one.  */
+
   for (hi = apr_hash_first(scratch_pool, path_tokens);
        hi;
        hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
-      svn_ra_serf__simple_request_context_t *ctx;
       const char *req_url, *path, *token;
       svn_lock_t *existing_lock = NULL;
       struct unlock_context_t unlock_ctx;
@@ -695,9 +565,6 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
 
       svn_pool_clear(iterpool);
 
-      ctx = apr_pcalloc(iterpool, sizeof(*ctx));
-      ctx->pool = iterpool;
-
       path = svn__apr_hash_index_key(hi);
       token = svn__apr_hash_index_val(hi);
 
@@ -739,6 +606,7 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
 
       handler = apr_pcalloc(iterpool, sizeof(*handler));
 
+      handler->handler_pool = iterpool;
       handler->method = "UNLOCK";
       handler->path = req_url;
       handler->conn = session->conns[0];
@@ -747,13 +615,12 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
       handler->header_delegate = set_unlock_headers;
       handler->header_delegate_baton = &unlock_ctx;
 
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = ctx;
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
 
-      svn_ra_serf__request_create(handler);
-      SVN_ERR(svn_ra_serf__context_run_wait(&ctx->done, session, iterpool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, iterpool));
 
-      switch (ctx->status)
+      switch (handler->sline.code)
         {
           case 204:
             break; /* OK */
@@ -761,12 +628,14 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
             /* Api users expect this specific error code to detect failures */
             err = svn_error_createf(SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL,
                                     _("Unlock request failed: %d %s"),
-                                    ctx->status, ctx->reason);
+                                    handler->sline.code,
+                                    handler->sline.reason);
             break;
           default:
             err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                     _("Unlock request failed: %d %s"),
-                                    ctx->status, ctx->reason);
+                                    handler->sline.code,
+                                    handler->sline.reason);
         }
 
       if (lock_func)

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/log.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/log.c Tue May 29 01:39:41 2012
@@ -24,9 +24,6 @@
 
 
 #include <apr_uri.h>
-
-#include <expat.h>
-
 #include <serf.h>
 
 #include "svn_pools.h"
@@ -40,6 +37,7 @@
 
 #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"
@@ -49,8 +47,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,
@@ -64,26 +62,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).
-   */
-  svn_stringbuf_t *tmp;
-  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 +79,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,411 +95,312 @@ 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, 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, TRUE },
 
-      info = apr_pcalloc(info_pool, sizeof(*info));
-      info->pool = info_pool;
-      info->tmp = svn_stringbuf_create_empty(info_pool);
-      info->log_entry = svn_log_entry_create(info_pool);
+  { ITEM, D_, SVN_DAV__VERSION_NAME, VERSION,
+    TRUE, { NULL }, FALSE, TRUE },
 
-      info->log_entry->revision = SVN_INVALID_REVNUM;
+  { ITEM, D_, "creator-displayname", CREATOR,
+    TRUE, { "?encoding", NULL }, FALSE, TRUE },
 
-      parser->state->private = info;
-    }
+  { ITEM, S_, "date", DATE,
+    TRUE, { "?encoding", NULL }, FALSE, 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 }, FALSE, 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 }, FALSE, 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 }, FALSE, 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 }, FALSE, 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 }, FALSE, 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 }, FALSE, TRUE },
 
-  return parser->state->private;
-}
+  { ITEM, S_, "deleted-path", DELETED_PATH,
+    TRUE, { "?node-kind", "?text-mods", "?prop-mods", NULL }, FALSE, 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 }, FALSE, 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,
-          svn_ra_serf__dav_props_t name,
-          const char **attrs,
-          apr_pool_t *scratch_pool)
+collect_revprop(apr_hash_t *revprops,
+                const char *propname,
+                const svn_string_t *cdata,
+                const char *encoding)
 {
-  log_context_t *log_ctx = parser->user_data;
-  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)
-    {
-      push_state(parser, log_ctx, REPORT, attrs);
-    }
-  else if (state == REPORT &&
-           strcmp(name.name, "log-item") == 0)
-    {
-      push_state(parser, log_ctx, ITEM, attrs);
-    }
-  else if (state == ITEM)
+  if (encoding)
     {
-      log_info_t *info;
-
-      if (strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
-        {
-          push_state(parser, log_ctx, VERSION, attrs);
-        }
-      else if (strcmp(name.name, "creator-displayname") == 0)
-        {
-          push_state(parser, log_ctx, CREATOR, attrs);
-        }
-      else if (strcmp(name.name, "date") == 0)
-        {
-          push_state(parser, log_ctx, DATE, attrs);
-        }
-      else if (strcmp(name.name, "comment") == 0)
-        {
-          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)
+      /* Check for a known encoding type.  This is easy -- there's
+         only one.  */
+      if (strcmp(encoding, "base64") != 0)
         {
-          push_state(parser, log_ctx, SUBTRACTIVE_MERGE, attrs);
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unsupported encoding '%s'"),
+                                   encoding);
         }
-      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)
-        {
-          const char *copy_path, *copy_rev_str;
+      decoded = svn_base64_decode_string(cdata, result_pool);
+    }
+  else
+    {
+      decoded = svn_string_dup(cdata, result_pool);
+    }
 
-          info = push_state(parser, log_ctx, REPLACED_PATH, attrs);
-          info->tmp_path->action = 'R';
+  /* Caller has ensured PROPNAME has sufficient lifetime.  */
+  apr_hash_set(revprops, propname, APR_HASH_KEY_STRING, decoded);
 
-          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;
+  return SVN_NO_ERROR;
+}
 
-              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));
+/* 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 = apr_hash_get(attrs, "copyfrom-path", APR_HASH_KEY_STRING);
+  copyfrom_rev = apr_hash_get(attrs, "copyfrom-rev", APR_HASH_KEY_STRING);
+  if (copyfrom_path && copyfrom_rev)
+    {
+      svn_revnum_t rev = SVN_STR_TO_REV(copyfrom_rev);
+
+      if (SVN_IS_VALID_REVNUM(rev))
+        {
+          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(apr_hash_get(
+                                             attrs, "node-kind",
+                                             APR_HASH_KEY_STRING));
+  lcp->text_modified = svn_tristate__from_word(apr_hash_get(
+                                                 attrs, "text-mods",
+                                                 APR_HASH_KEY_STRING));
+  lcp->props_modified = svn_tristate__from_word(apr_hash_get(
+                                                  attrs, "prop-mods",
+                                                  APR_HASH_KEY_STRING));
 
-          SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
-        }
-    }
+  path = apr_pstrmemdup(result_pool, cdata->data, cdata->len);
+  apr_hash_set(paths, path, APR_HASH_KEY_STRING, 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,
+           apr_pool_t *scratch_pool)
 {
+  log_context_t *log_ctx = baton;
+  apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
 
-  if (info->tmp_encoding)
-    {
-      svn_string_t tmp;
-
-      /* Don't use morph_info_string cuz we need info->tmp to
-         remain usable.  */
-      tmp.data = info->tmp->data;
-      tmp.len = info->tmp->len;
+  SVN_ERR_ASSERT(entered_state == ITEM);
 
-      /* 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_ctx->collect_revprops = apr_hash_make(state_pool);
+  log_ctx->collect_paths = apr_hash_make(state_pool);
 
-      *decoded_cdata = svn_base64_decode_string(&tmp, info->pool);
-    }
-  else
-    {
-      *decoded_cdata = svn_string_create_from_buf(info->tmp, info->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,
-        svn_ra_serf__dav_props_t name,
-        apr_pool_t *scratch_pool)
+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 = parser->user_data;
-  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 = apr_hash_get(attrs, "revision", APR_HASH_KEY_STRING);
+      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->data);
-      svn_stringbuf_setempty(info->tmp);
-      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,
+                                  apr_hash_get(attrs, "encoding",
+                                               APR_HASH_KEY_STRING)));
         }
-      svn_stringbuf_setempty(info->tmp);
-      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,
+                                  apr_hash_get(attrs, "encoding",
+                                               APR_HASH_KEY_STRING)));
         }
-      svn_stringbuf_setempty(info->tmp);
-      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_stringbuf_setempty(info->tmp);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (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);
-      svn_stringbuf_setempty(info->tmp);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == HAS_CHILDREN &&
-           strcmp(name.name, "has-children") == 0)
-    {
-      info->log_entry->has_children = TRUE;
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == SUBTRACTIVE_MERGE &&
-           strcmp(name.name, "subtractive-merge") == 0)
-    {
-      info->log_entry->subtractive_merge = TRUE;
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  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))
-    {
-      char *path;
-
-      path = apr_pstrmemdup(info->pool, info->tmp->data, info->tmp->len);
-      svn_stringbuf_setempty(info->tmp);
-
-      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_revprop(log_ctx->collect_revprops,
+                                  SVN_PROP_REVISION_LOG,
+                                  cdata,
+                                  apr_hash_get(attrs, "encoding",
+                                               APR_HASH_KEY_STRING)));
+        }
     }
+  else if (leaving_state == REVPROP)
+    {
+      apr_pool_t *result_pool = apr_hash_pool_get(log_ctx->collect_revprops);
 
-  return SVN_NO_ERROR;
-}
+      SVN_ERR(collect_revprop(
+                log_ctx->collect_revprops,
+                apr_pstrdup(result_pool,
+                            apr_hash_get(attrs, "name", APR_HASH_KEY_STRING)),
+                cdata,
+                apr_hash_get(attrs, "encoding", APR_HASH_KEY_STRING)
+                ));
+    }
+  else if (leaving_state == HAS_CHILDREN)
+    {
+      svn_ra_serf__xml_note(xes, ITEM, "has-children", "yes");
+    }
+  else if (leaving_state == SUBTRACTIVE_MERGE)
+    {
+      svn_ra_serf__xml_note(xes, ITEM, "subtractive-merge", "yes");
+    }
+  else
+    {
+      char action;
 
-static svn_error_t *
-cdata_log(svn_ra_serf__xml_parser_t *parser,
-          const char *data,
-          apr_size_t len,
-          apr_pool_t *scratch_pool)
-{
-  log_context_t *log_ctx = parser->user_data;
-  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_stringbuf_appendbytes(info->tmp, data, len);
-        break;
+      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';
+        }
 
-      default:
-        break;
+      SVN_ERR(collect_path(log_ctx->collect_paths, action, cdata, attrs));
     }
 
   return SVN_NO_ERROR;
 }
 
+
 static svn_error_t *
 create_log_body(serf_bucket_t **body_bkt,
                 void *baton,
@@ -636,11 +518,11 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   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;
@@ -655,7 +537,6 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   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)
@@ -695,12 +576,15 @@ svn_ra_serf__get_log(svn_ra_session_t *r
    */
   peg_rev = (start > end) ? start : end;
 
-  SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                         NULL, NULL, peg_rev, NULL, pool));
-
-  req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool);
-
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
+                                      session, NULL /* conn */,
+                                      NULL /* url */, peg_rev,
+                                      pool, pool));
+
+  xmlctx = svn_ra_serf__xml_context_create(log_ttable,
+                                           log_opened, log_closed, log_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
@@ -710,27 +594,12 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   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.code,
                                            req_url,
-                                           parser_ctx->location),
+                                           handler->location),
               err));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/merge.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/merge.c Tue May 29 01:39:41 2012
@@ -90,6 +90,7 @@ struct svn_ra_serf__merge_context_t
   apr_pool_t *pool;
 
   svn_ra_serf__session_t *session;
+  svn_ra_serf__handler_t *handler;
 
   apr_hash_t *lock_tokens;
   svn_boolean_t keep_locks;
@@ -97,8 +98,6 @@ struct svn_ra_serf__merge_context_t
   const char *merge_resource_url; /* URL of resource to be merged. */
   const char *merge_url; /* URL at which the MERGE request is aimed. */
 
-  int status;
-
   svn_boolean_t done;
 
   svn_commit_info_t *commit_info;
@@ -535,6 +534,7 @@ svn_ra_serf__merge_create_req(svn_ra_ser
 
   handler = apr_pcalloc(pool, sizeof(*handler));
 
+  handler->handler_pool = pool;
   handler->method = "MERGE";
   handler->path = merge_ctx->merge_url;
   handler->body_delegate = create_merge_body;
@@ -550,7 +550,6 @@ svn_ra_serf__merge_create_req(svn_ra_ser
   parser_ctx->end = end_merge;
   parser_ctx->cdata = cdata_merge;
   parser_ctx->done = &merge_ctx->done;
-  parser_ctx->status_code = &merge_ctx->status;
 
   handler->header_delegate = setup_merge_headers;
   handler->header_delegate_baton = merge_ctx;
@@ -558,6 +557,8 @@ svn_ra_serf__merge_create_req(svn_ra_ser
   handler->response_handler = svn_ra_serf__handle_xml_parser;
   handler->response_baton = parser_ctx;
 
+  merge_ctx->handler = handler;
+
   svn_ra_serf__request_create(handler);
 
   *ret_ctx = merge_ctx;
@@ -580,5 +581,5 @@ svn_ra_serf__merge_get_commit_info(svn_r
 int
 svn_ra_serf__merge_get_status(svn_ra_serf__merge_context_t *ctx)
 {
-  return ctx->status;
+  return ctx->handler->sline.code;
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/mergeinfo.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/mergeinfo.c Tue May 29 01:39:41 2012
@@ -229,8 +229,6 @@ create_mergeinfo_body(serf_bucket_t **bk
   return SVN_NO_ERROR;
 }
 
-/* Request a mergeinfo-report from the URL attached to SESSION,
-   and fill in the MERGEINFO hash with the results.  */
 svn_error_t *
 svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
                            svn_mergeinfo_catalog_t *catalog,
@@ -241,21 +239,18 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
                            apr_pool_t *pool)
 {
   svn_error_t *err, *err2;
-  int status_code;
-
   mergeinfo_context_t *mergeinfo_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
-  const char *relative_url, *basecoll_url;
   const char *path;
 
   *catalog = NULL;
 
-  SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                         NULL, NULL, revision, NULL, pool));
-
-  path = svn_path_url_add_component2(basecoll_url, relative_url, pool);
+  SVN_ERR(svn_ra_serf__get_stable_url(&path, NULL /* latest_revnum */,
+                                      session, NULL /* conn */,
+                                      NULL /* url */, revision,
+                                      pool, pool));
 
   mergeinfo_ctx = apr_pcalloc(pool, sizeof(*mergeinfo_ctx));
   mergeinfo_ctx->pool = pool;
@@ -270,6 +265,7 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   handler = apr_pcalloc(pool, sizeof(*handler));
 
+  handler->handler_pool = pool;
   handler->method = "REPORT";
   handler->path = path;
   handler->conn = session->conns[0];
@@ -286,7 +282,6 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
   parser_ctx->end = end_element;
   parser_ctx->cdata = cdata_handler;
   parser_ctx->done = &mergeinfo_ctx->done;
-  parser_ctx->status_code = &status_code;
 
   handler->response_handler = svn_ra_serf__handle_xml_parser;
   handler->response_baton = parser_ctx;
@@ -295,8 +290,8 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   err = svn_ra_serf__context_run_wait(&mergeinfo_ctx->done, session, pool);
 
-  err2 = svn_ra_serf__error_on_status(status_code, handler->path,
-                                      parser_ctx->location);
+  err2 = svn_ra_serf__error_on_status(handler->sline.code, handler->path,
+                                      handler->location);
   if (err2)
     {
       svn_error_clear(err);



Mime
View raw message