Modified: 
subversion/branches/master-passphrase/subversion/libsvn_ra_serf/merge.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_ra_serf/merge.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_ra_serf/merge.c 
(original)
+++ subversion/branches/master-passphrase/subversion/libsvn_ra_serf/merge.c Wed 
Jun 27 15:12:37 2012
@@ -47,7 +47,7 @@
  * This enum represents the current state of our XML parsing for a MERGE.
  */
 typedef enum merge_state_e {
-  NONE = 0,
+  INITIAL = 0,
   MERGE_RESPONSE,
   UPDATED_SET,
   RESPONSE,
@@ -55,41 +55,26 @@ typedef enum merge_state_e {
   PROPSTAT,
   PROP,
   RESOURCE_TYPE,
-  AUTHOR,
-  NAME,
-  DATE,
-  IGNORE_PROP_NAME,
-  NEED_PROP_NAME,
-  PROP_VAL
-} merge_state_e;
-
-typedef enum resource_type_e {
-  UNSET,
   BASELINE,
   COLLECTION,
-  CHECKED_IN
-} resource_type_e;
-
-typedef struct merge_info_t {
-  /* Temporary allocations here please */
-  apr_pool_t *pool;
-
-  resource_type_e type;
-
-  apr_hash_t *props;
+  SKIP_HREF,
+  CHECKED_IN,
+  VERSION_NAME,
+  DATE,
+  AUTHOR,
+  POST_COMMIT_ERR,
 
-  const char *prop_ns;
-  const char *prop_name;
-  svn_stringbuf_t *prop_value;
+  PROP_VAL
+} merge_state_e;
 
-} merge_info_t;
 
 /* Structure associated with a MERGE request. */
-struct svn_ra_serf__merge_context_t
+typedef struct 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,310 +82,194 @@ 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_commit_info_t *commit_info;
 
-  svn_boolean_t done;
+} merge_context_t;
 
-  svn_commit_info_t *commit_info;
-};
 
-
-static merge_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
-           svn_ra_serf__merge_context_t *ctx,
-           merge_state_e state)
-{
-  merge_info_t *info;
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t merge_ttable[] = {
+  { INITIAL, D_, "merge-response", MERGE_RESPONSE,
+    FALSE, { NULL }, FALSE },
 
-  svn_ra_serf__xml_push_state(parser, state);
+  { MERGE_RESPONSE, D_, "updated-set", UPDATED_SET,
+    FALSE, { NULL }, FALSE },
 
-  if (state == RESPONSE)
-    {
-      info = apr_palloc(parser->state->pool, sizeof(*info));
-      info->pool = parser->state->pool;
-      info->props = apr_hash_make(info->pool);
-      info->prop_value = svn_stringbuf_create_empty(info->pool);
+  { UPDATED_SET, D_, "response", RESPONSE,
+    FALSE, { NULL }, TRUE },
 
-      parser->state->private = info;
-    }
+  { RESPONSE, D_, "href", HREF,
+    TRUE, { NULL }, TRUE },
 
-  return parser->state->private;
-}
+  { RESPONSE, D_, "propstat", PROPSTAT,
+    FALSE, { NULL }, FALSE },
 
-static svn_error_t *
-start_merge(svn_ra_serf__xml_parser_t *parser,
-            svn_ra_serf__dav_props_t name,
-            const char **attrs,
-            apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__merge_context_t *ctx = parser->user_data;
-  merge_state_e state;
-  merge_info_t *info;
+#if 0
+  /* Not needed.  */
+  { PROPSTAT, D_, "status", STATUS,
+    FALSE, { NULL }, FALSE },
+#endif
 
-  state = parser->state->current_state;
+  { PROPSTAT, D_, "prop", PROP,
+    FALSE, { NULL }, FALSE },
 
-  if (state == NONE &&
-      strcmp(name.name, "merge-response") == 0)
-    {
-      push_state(parser, ctx, MERGE_RESPONSE);
-    }
-  else if (state == NONE)
-    {
-      /* do nothing as we haven't seen our valid start tag yet. */
-    }
-  else if (state == MERGE_RESPONSE &&
-           strcmp(name.name, "updated-set") == 0)
-    {
-      push_state(parser, ctx, UPDATED_SET);
-    }
-  else if (state == UPDATED_SET &&
-           strcmp(name.name, "response") == 0)
-    {
-      push_state(parser, ctx, RESPONSE);
-    }
-  else if (state == RESPONSE &&
-           strcmp(name.name, "href") == 0)
-    {
-      info = push_state(parser, ctx, PROP_VAL);
+  { PROP, D_, "resourcetype", RESOURCE_TYPE,
+    FALSE, { NULL }, FALSE },
 
-      info->prop_ns = name.namespace;
-      info->prop_name = "href";
-      svn_stringbuf_setempty(info->prop_value);
-    }
-  else if (state == RESPONSE &&
-           strcmp(name.name, "propstat") == 0)
-    {
-      push_state(parser, ctx, PROPSTAT);
-    }
-  else if (state == PROPSTAT &&
-           strcmp(name.name, "prop") == 0)
-    {
-      push_state(parser, ctx, PROP);
-    }
-  else if (state == PROPSTAT &&
-           strcmp(name.name, "status") == 0)
-    {
-      /* Do nothing for now. */
-    }
-  else if (state == PROP &&
-           strcmp(name.name, "resourcetype") == 0)
-    {
-      info = push_state(parser, ctx, RESOURCE_TYPE);
-      info->type = UNSET;
-    }
-  else if (state == RESOURCE_TYPE &&
-           strcmp(name.name, "baseline") == 0)
-    {
-      info = parser->state->private;
+  { RESOURCE_TYPE, D_, "baseline", BASELINE,
+    FALSE, { NULL }, TRUE },
 
-      info->type = BASELINE;
-    }
-  else if (state == RESOURCE_TYPE &&
-           strcmp(name.name, "collection") == 0)
-    {
-      info = parser->state->private;
+  { RESOURCE_TYPE, D_, "collection", COLLECTION,
+    FALSE, { NULL }, TRUE },
 
-      info->type = COLLECTION;
-    }
-  else if (state == PROP &&
-           strcmp(name.name, "checked-in") == 0)
-    {
-      info = push_state(parser, ctx, IGNORE_PROP_NAME);
-      info->prop_ns = name.namespace;
-      info->prop_name = "checked-in";
-      svn_stringbuf_setempty(info->prop_value);
-    }
-  else if (state == PROP)
-    {
-      push_state(parser, ctx, PROP_VAL);
-    }
-  else if (state == IGNORE_PROP_NAME)
-    {
-      push_state(parser, ctx, PROP_VAL);
-    }
-  else if (state == NEED_PROP_NAME)
-    {
-      info = push_state(parser, ctx, PROP_VAL);
-      info->prop_ns = name.namespace;
-      info->prop_name = apr_pstrdup(info->pool, name.name);
-      svn_stringbuf_setempty(info->prop_value);
-    }
-  else
-    {
-      SVN_ERR_MALFUNCTION();
-    }
+  { PROP, D_, "checked-in", SKIP_HREF,
+    FALSE, { NULL }, FALSE },
 
-  return SVN_NO_ERROR;
-}
+  { SKIP_HREF, D_, "href", CHECKED_IN,
+    TRUE, { NULL }, TRUE },
+
+  { PROP, D_, SVN_DAV__VERSION_NAME, VERSION_NAME,
+    TRUE, { NULL }, TRUE },
+
+  { PROP, D_, SVN_DAV__CREATIONDATE, DATE,
+    TRUE, { NULL }, TRUE },
+
+  { PROP, D_, "creator-displayname", AUTHOR,
+    TRUE, { NULL }, TRUE },
 
+  { PROP, S_, "post-commit-err", POST_COMMIT_ERR,
+    TRUE, { NULL }, TRUE },
+
+  { 0 }
+};
+
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_merge(svn_ra_serf__xml_parser_t *parser,
-          svn_ra_serf__dav_props_t name,
-          apr_pool_t *scratch_pool)
+merge_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)
 {
-  svn_ra_serf__merge_context_t *ctx = parser->user_data;
-  merge_state_e state;
-  merge_info_t *info;
+  merge_context_t *merge_ctx = baton;
 
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  if (state == NONE)
+  if (leaving_state == RESPONSE)
     {
-      /* nothing to close yet. */
-      return SVN_NO_ERROR;
-    }
+      const char *rtype;
 
-  if (state == RESPONSE &&
-      strcmp(name.name, "response") == 0)
-    {
-      if (info->type == BASELINE)
+      rtype = apr_hash_get(attrs, "resourcetype", APR_HASH_KEY_STRING);
+
+      /* rtype can only be "baseline" or "collection" (or NULL). We can
+         keep this check simple.  */
+      if (rtype && *rtype == 'b')
         {
-          const char *str;
+          const char *rev_str;
 
-          str = apr_hash_get(info->props, SVN_DAV__VERSION_NAME,
-                             APR_HASH_KEY_STRING);
-          if (str)
-            {
-              ctx->commit_info->revision = SVN_STR_TO_REV(str);
-            }
+          rev_str = apr_hash_get(attrs, "revision", APR_HASH_KEY_STRING);
+          if (rev_str)
+            merge_ctx->commit_info->revision = SVN_STR_TO_REV(rev_str);
           else
-            {
-              ctx->commit_info->revision = SVN_INVALID_REVNUM;
-            }
+            merge_ctx->commit_info->revision = SVN_INVALID_REVNUM;
 
-          ctx->commit_info->date =
-              apr_pstrdup(ctx->pool,
-                          apr_hash_get(info->props, SVN_DAV__CREATIONDATE,
-                                       APR_HASH_KEY_STRING));
-
-          ctx->commit_info->author =
-              apr_pstrdup(ctx->pool,
-                          apr_hash_get(info->props, "creator-displayname",
-                                       APR_HASH_KEY_STRING));
-
-          ctx->commit_info->post_commit_err =
-             apr_pstrdup(ctx->pool,
-                         apr_hash_get(info->props,
+          merge_ctx->commit_info->date =
+              apr_pstrdup(merge_ctx->pool,
+                          apr_hash_get(attrs, "date", APR_HASH_KEY_STRING));
+
+          merge_ctx->commit_info->author =
+              apr_pstrdup(merge_ctx->pool,
+                          apr_hash_get(attrs, "author", APR_HASH_KEY_STRING));
+
+          merge_ctx->commit_info->post_commit_err =
+             apr_pstrdup(merge_ctx->pool,
+                         apr_hash_get(attrs,
                                       "post-commit-err", APR_HASH_KEY_STRING));
         }
       else
         {
           const char *href;
 
-          href = apr_hash_get(info->props, "href", APR_HASH_KEY_STRING);
-          if (! svn_urlpath__skip_ancestor(ctx->merge_url, href))
-            {
-              return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
-                                       _("A MERGE response for '%s' is not "
-                                         "a child of the destination ('%s')"),
-                                       href, ctx->merge_url);
-            }
+          href = svn_urlpath__skip_ancestor(
+                   merge_ctx->merge_url,
+                   apr_hash_get(attrs, "href", APR_HASH_KEY_STRING));
+
+          if (href == NULL)
+            return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                                     _("A MERGE response for '%s' is not "
+                                       "a child of the destination ('%s')"),
+                                     href, merge_ctx->merge_url);
 
           /* We now need to dive all the way into the WC to update the
-           * base VCC url.
-           */
-          if ((! SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(ctx->session))
-              && ctx->session->wc_callbacks->push_wc_prop)
+             base VCC url.  */
+          if (!SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(merge_ctx->session)
+              && merge_ctx->session->wc_callbacks->push_wc_prop)
             {
-              svn_string_t checked_in_str;
               const char *checked_in;
+              svn_string_t checked_in_str;
 
-              /* From the above check, we know that CTX->MERGE_URL is
-                 an ancestor of HREF.  All that remains is to
-                 determine if HREF is the same as CTX->MERGE_URL, or --
-                 if not -- its relative value as a child thereof. */
-              href = svn_urlpath__skip_ancestor(ctx->merge_url, href);
-
-              checked_in = apr_hash_get(info->props, "checked-in",
-                                        APR_HASH_KEY_STRING);
+              checked_in = apr_hash_get(attrs,
+                                        "checked-in", APR_HASH_KEY_STRING);
               checked_in_str.data = checked_in;
               checked_in_str.len = strlen(checked_in);
 
-              SVN_ERR(ctx->session->wc_callbacks->push_wc_prop(
-                ctx->session->wc_callback_baton, href,
-                SVN_RA_SERF__WC_CHECKED_IN_URL, &checked_in_str, info->pool));
+              SVN_ERR(merge_ctx->session->wc_callbacks->push_wc_prop(
+                        merge_ctx->session->wc_callback_baton,
+                        href,
+                        SVN_RA_SERF__WC_CHECKED_IN_URL,
+                        &checked_in_str,
+                        scratch_pool));
             }
         }
-
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == PROPSTAT &&
-           strcmp(name.name, "propstat") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == PROP &&
-           strcmp(name.name, "prop") == 0)
+  else if (leaving_state == BASELINE)
     {
-      svn_ra_serf__xml_pop_state(parser);
+      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "baseline");
     }
-  else if (state == RESOURCE_TYPE &&
-           strcmp(name.name, "resourcetype") == 0)
+  else if (leaving_state == COLLECTION)
     {
-      svn_ra_serf__xml_pop_state(parser);
+      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "collection");
     }
-  else if (state == IGNORE_PROP_NAME || state == NEED_PROP_NAME)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == PROP_VAL)
+  else
     {
-      const char *value;
+      const char *name;
+      const char *value = cdata->data;
 
-      if (!info->prop_name)
+      if (leaving_state == HREF)
         {
-          /* ### gstein sez: dunno what this is about.  */
-          info->prop_name = apr_pstrdup(info->pool, name.name);
+          name = "href";
+          value = svn_urlpath__canonicalize(value, scratch_pool);
         }
-
-      if (strcmp(info->prop_name, "href") == 0)
-        value = svn_urlpath__canonicalize(info->prop_value->data, info->pool);
+      else if (leaving_state == CHECKED_IN)
+        {
+          name = "checked-in";
+          value = svn_urlpath__canonicalize(value, scratch_pool);
+        }
+      else if (leaving_state == VERSION_NAME)
+        name = "revision";
+      else if (leaving_state == DATE)
+        name = "date";
+      else if (leaving_state == AUTHOR)
+        name = "author";
+      else if (leaving_state == POST_COMMIT_ERR)
+        name = "post-commit-err";
       else
-        value = apr_pstrmemdup(info->pool,
-                               info->prop_value->data, info->prop_value->len);
-
-      /* Set our property. */
-      apr_hash_set(info->props, info->prop_name, APR_HASH_KEY_STRING,
-                   value);
-
-      info->prop_ns = NULL;
-      info->prop_name = NULL;
-      svn_stringbuf_setempty(info->prop_value);
+        SVN_ERR_MALFUNCTION();
 
-      svn_ra_serf__xml_pop_state(parser);
+      svn_ra_serf__xml_note(xes, RESPONSE, name, value);
     }
 
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-cdata_merge(svn_ra_serf__xml_parser_t *parser,
-            const char *data,
-            apr_size_t len,
-            apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__merge_context_t *ctx = parser->user_data;
-  merge_state_e state;
-  merge_info_t *info;
-
-  UNUSED_CTX(ctx);
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  if (state == PROP_VAL)
-    svn_stringbuf_appendbytes(info->prop_value, data, len);
-
-  return SVN_NO_ERROR;
-}
 
 static svn_error_t *
 setup_merge_headers(serf_bucket_t *headers,
                     void *baton,
                     apr_pool_t *pool)
 {
-  svn_ra_serf__merge_context_t *ctx = baton;
+  merge_context_t *ctx = baton;
 
   if (!ctx->keep_locks)
     {
@@ -465,7 +334,7 @@ create_merge_body(serf_bucket_t **bkt,
                   serf_bucket_alloc_t *alloc,
                   apr_pool_t *pool)
 {
-  svn_ra_serf__merge_context_t *ctx = baton;
+  merge_context_t *ctx = baton;
   serf_bucket_t *body_bkt;
 
   body_bkt = serf_bucket_aggregate_create(alloc);
@@ -507,21 +376,23 @@ create_merge_body(serf_bucket_t **bkt,
 
 
 svn_error_t *
-svn_ra_serf__merge_create_req(svn_ra_serf__merge_context_t **ret_ctx,
-                              svn_ra_serf__session_t *session,
-                              svn_ra_serf__connection_t *conn,
-                              const char *merge_resource_url,
-                              apr_hash_t *lock_tokens,
-                              svn_boolean_t keep_locks,
-                              apr_pool_t *pool)
+svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
+                       int *response_code,
+                       svn_ra_serf__session_t *session,
+                       svn_ra_serf__connection_t *conn,
+                       const char *merge_resource_url,
+                       apr_hash_t *lock_tokens,
+                       svn_boolean_t keep_locks,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__merge_context_t *merge_ctx;
+  merge_context_t *merge_ctx;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
 
-  merge_ctx = apr_pcalloc(pool, sizeof(*merge_ctx));
+  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));
 
-  merge_ctx->pool = pool;
+  merge_ctx->pool = result_pool;
   merge_ctx->session = session;
 
   merge_ctx->merge_resource_url = merge_resource_url;
@@ -529,11 +400,15 @@ svn_ra_serf__merge_create_req(svn_ra_ser
   merge_ctx->lock_tokens = lock_tokens;
   merge_ctx->keep_locks = keep_locks;
 
-  merge_ctx->commit_info = svn_create_commit_info(pool);
+  merge_ctx->commit_info = svn_create_commit_info(result_pool);
 
   merge_ctx->merge_url = session->session_url.path;
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
+                                           NULL, merge_closed, NULL,
+                                           merge_ctx,
+                                           scratch_pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
 
   handler->method = "MERGE";
   handler->path = merge_ctx->merge_url;
@@ -542,43 +417,15 @@ svn_ra_serf__merge_create_req(svn_ra_ser
   handler->conn = conn;
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = merge_ctx;
-  parser_ctx->start = start_merge;
-  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;
 
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
+  merge_ctx->handler = handler;
 
-  svn_ra_serf__request_create(handler);
+  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
-  *ret_ctx = merge_ctx;
+  *commit_info = merge_ctx->commit_info;
+  *response_code = handler->sline.code;
 
   return SVN_NO_ERROR;
 }
-
-svn_boolean_t*
-svn_ra_serf__merge_get_done_ptr(svn_ra_serf__merge_context_t *ctx)
-{
-  return &ctx->done;
-}
-
-svn_commit_info_t*
-svn_ra_serf__merge_get_commit_info(svn_ra_serf__merge_context_t *ctx)
-{
-  return ctx->commit_info;
-}
-
-int
-svn_ra_serf__merge_get_status(svn_ra_serf__merge_context_t *ctx)
-{
-  return ctx->status;
-}

Modified: 
subversion/branches/master-passphrase/subversion/libsvn_ra_serf/mergeinfo.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_ra_serf/mergeinfo.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_ra_serf/mergeinfo.c 
(original)
+++ subversion/branches/master-passphrase/subversion/libsvn_ra_serf/mergeinfo.c 
Wed Jun 27 15:12:37 2012
@@ -40,7 +40,7 @@
 
 /* The current state of our XML parsing. */
 typedef enum mergeinfo_state_e {
-  NONE = 0,
+  INITIAL = 0,
   MERGEINFO_REPORT,
   MERGEINFO_ITEM,
   MERGEINFO_PATH,
@@ -49,135 +49,88 @@ typedef enum mergeinfo_state_e {
 
 /* Baton for accumulating mergeinfo.  RESULT_CATALOG stores the final
    mergeinfo catalog result we are going to hand back to the caller of
-   get_mergeinfo.  curr_path and curr_info contain the value of the
-   CDATA from the mergeinfo items as we get them from the server.  */
-
+   get_mergeinfo.  */
 typedef struct mergeinfo_context_t {
   apr_pool_t *pool;
-  svn_stringbuf_t *curr_path;
-  svn_stringbuf_t *curr_info;
   svn_mergeinfo_t result_catalog;
-  svn_boolean_t done;
   const apr_array_header_t *paths;
   svn_revnum_t revision;
   svn_mergeinfo_inheritance_t inherit;
   svn_boolean_t include_descendants;
 } mergeinfo_context_t;
 
-static svn_error_t *
-start_element(svn_ra_serf__xml_parser_t *parser,
-              svn_ra_serf__dav_props_t name,
-              const char **attrs,
-              apr_pool_t *scratch_pool)
-{
-  mergeinfo_context_t *mergeinfo_ctx = parser->user_data;
-  mergeinfo_state_e state;
 
-  state = parser->state->current_state;
-  if (state == NONE && strcmp(name.name, SVN_DAV__MERGEINFO_REPORT) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, MERGEINFO_REPORT);
-    }
-  else if (state == MERGEINFO_REPORT &&
-           strcmp(name.name, SVN_DAV__MERGEINFO_ITEM) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, MERGEINFO_ITEM);
-      svn_stringbuf_setempty(mergeinfo_ctx->curr_path);
-      svn_stringbuf_setempty(mergeinfo_ctx->curr_info);
-    }
-  else if (state == MERGEINFO_ITEM &&
-           strcmp(name.name, SVN_DAV__MERGEINFO_PATH) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, MERGEINFO_PATH);
-    }
-  else if (state == MERGEINFO_ITEM &&
-           strcmp(name.name, SVN_DAV__MERGEINFO_INFO) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, MERGEINFO_INFO);
-    }
-  return SVN_NO_ERROR;
-}
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t mergeinfo_ttable[] = {
+  { INITIAL, S_, SVN_DAV__MERGEINFO_REPORT, MERGEINFO_REPORT,
+    FALSE, { NULL }, FALSE },
+
+  { MERGEINFO_REPORT, S_, SVN_DAV__MERGEINFO_ITEM, MERGEINFO_ITEM,
+    FALSE, { NULL }, TRUE },
+
+  { MERGEINFO_ITEM, S_, SVN_DAV__MERGEINFO_PATH, MERGEINFO_PATH,
+    TRUE, { NULL }, TRUE },
+
+  { MERGEINFO_ITEM, S_, SVN_DAV__MERGEINFO_INFO, MERGEINFO_INFO,
+    TRUE, { NULL }, TRUE },
+
+  { 0 }
+};
+
 
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_element(svn_ra_serf__xml_parser_t *parser,
-            svn_ra_serf__dav_props_t name,
-            apr_pool_t *scratch_pool)
+mergeinfo_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)
 {
-  mergeinfo_context_t *mergeinfo_ctx = parser->user_data;
-  mergeinfo_state_e state;
-
-  state = parser->state->current_state;
+  mergeinfo_context_t *mergeinfo_ctx = baton;
 
-  if (state == MERGEINFO_REPORT &&
-      strcmp(name.name, SVN_DAV__MERGEINFO_REPORT) == 0)
+  if (leaving_state == MERGEINFO_ITEM)
     {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == MERGEINFO_ITEM
-           && strcmp(name.name, SVN_DAV__MERGEINFO_ITEM) == 0)
-    {
-      if (mergeinfo_ctx->curr_info && mergeinfo_ctx->curr_path)
+      /* Placed here from the child elements.  */
+      const char *path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+      const char *info = apr_hash_get(attrs, "info", APR_HASH_KEY_STRING);
+
+      if (path != NULL && info != NULL)
         {
           svn_mergeinfo_t path_mergeinfo;
-          const char *path;
 
-          SVN_ERR_ASSERT(mergeinfo_ctx->curr_path->data);
-          path = apr_pstrdup(mergeinfo_ctx->pool,
-                             mergeinfo_ctx->curr_path->data);
-          SVN_ERR(svn_mergeinfo_parse(&path_mergeinfo,
-                                      mergeinfo_ctx->curr_info->data,
-                                      mergeinfo_ctx->pool));
           /* Correct for naughty servers that send "relative" paths
              with leading slashes! */
+          if (path[0] == '/')
+            ++path;
+
+          SVN_ERR(svn_mergeinfo_parse(&path_mergeinfo, info,
+                                      mergeinfo_ctx->pool));
+
           apr_hash_set(mergeinfo_ctx->result_catalog,
-                       path[0] == '/' ? path + 1 : path,
-                       APR_HASH_KEY_STRING, path_mergeinfo);
+                       apr_pstrdup(mergeinfo_ctx->pool, path),
+                       APR_HASH_KEY_STRING,
+                       path_mergeinfo);
         }
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == MERGEINFO_PATH
-           && strcmp(name.name, SVN_DAV__MERGEINFO_PATH) == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == MERGEINFO_INFO
-           && strcmp(name.name, SVN_DAV__MERGEINFO_INFO) == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-cdata_handler(svn_ra_serf__xml_parser_t *parser,
-              const char *data,
-              apr_size_t len,
-              apr_pool_t *scratch_pool)
-{
-  mergeinfo_context_t *mergeinfo_ctx = parser->user_data;
-  mergeinfo_state_e state;
-
-  state = parser->state->current_state;
-  switch (state)
+  else
     {
-    case MERGEINFO_PATH:
-      if (mergeinfo_ctx->curr_path)
-        svn_stringbuf_appendbytes(mergeinfo_ctx->curr_path, data, len);
-      break;
-
-    case MERGEINFO_INFO:
-      if (mergeinfo_ctx->curr_info)
-        svn_stringbuf_appendbytes(mergeinfo_ctx->curr_info, data, len);
-      break;
+      SVN_ERR_ASSERT(leaving_state == MERGEINFO_PATH
+                     || leaving_state == MERGEINFO_INFO);
 
-    default:
-      break;
+      /* Stash the value onto the parent MERGEINFO_ITEM.  */
+      svn_ra_serf__xml_note(xes, MERGEINFO_ITEM,
+                            leaving_state == MERGEINFO_PATH
+                              ? "path"
+                              : "info",
+                            cdata->data);
     }
 
   return SVN_NO_ERROR;
 }
 
+
 static svn_error_t *
 create_mergeinfo_body(serf_bucket_t **bkt,
                       void *baton,
@@ -229,8 +182,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,34 +192,32 @@ 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;
+  svn_ra_serf__xml_context_t *xmlctx;
   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;
-  mergeinfo_ctx->curr_path = svn_stringbuf_create_empty(pool);
-  mergeinfo_ctx->curr_info = svn_stringbuf_create_empty(pool);
-  mergeinfo_ctx->done = FALSE;
   mergeinfo_ctx->result_catalog = apr_hash_make(pool);
   mergeinfo_ctx->paths = paths;
   mergeinfo_ctx->revision = revision;
   mergeinfo_ctx->inherit = inherit;
   mergeinfo_ctx->include_descendants = include_descendants;
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(mergeinfo_ttable,
+                                           NULL, mergeinfo_closed, NULL,
+                                           mergeinfo_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "REPORT";
   handler->path = path;
@@ -278,25 +227,10 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
   handler->body_delegate_baton = mergeinfo_ctx;
   handler->body_type = "text/xml";
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = mergeinfo_ctx;
-  parser_ctx->start = start_element;
-  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;
-
-  svn_ra_serf__request_create(handler);
-
-  err = svn_ra_serf__context_run_wait(&mergeinfo_ctx->done, session, pool);
+  err = svn_ra_serf__context_run_one(handler, 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);
@@ -305,7 +239,7 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   SVN_ERR(err);
 
-  if (mergeinfo_ctx->done && apr_hash_count(mergeinfo_ctx->result_catalog))
+  if (handler->done && apr_hash_count(mergeinfo_ctx->result_catalog))
     *catalog = mergeinfo_ctx->result_catalog;
 
   return SVN_NO_ERROR;

Modified: 
subversion/branches/master-passphrase/subversion/libsvn_ra_serf/options.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_ra_serf/options.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_ra_serf/options.c 
(original)
+++ subversion/branches/master-passphrase/subversion/libsvn_ra_serf/options.c 
Wed Jun 27 15:12:37 2012
@@ -48,165 +48,68 @@
 /*
  * This enum represents the current state of our XML parsing for an OPTIONS.
  */
-typedef enum options_state_e {
+enum options_state_e {
+  INITIAL = 0,
   OPTIONS,
   ACTIVITY_COLLECTION,
   HREF
-} options_state_e;
-
-typedef struct options_state_list_t {
-  /* The current state that we are in now. */
-  options_state_e state;
-
-  /* The previous state we were in. */
-  struct options_state_list_t *prev;
-} options_state_list_t;
+};
 
-struct svn_ra_serf__options_context_t {
+typedef struct options_context_t {
   /* pool to allocate memory from */
   apr_pool_t *pool;
 
-  /* Buffer for the activity-collection  */
-  svn_stringbuf_t *acbuf;
-  svn_boolean_t collect_cdata;
-
-  /* Current state we're in */
-  options_state_list_t *state;
-  options_state_list_t *free_state;
-
-  /* HTTP Status code */
-  int status_code;
-
-  /* are we done? */
-  svn_boolean_t done;
+  /* Have we extracted options values from the headers already?  */
+  svn_boolean_t headers_processed;
 
   svn_ra_serf__session_t *session;
   svn_ra_serf__connection_t *conn;
+  svn_ra_serf__handler_t *handler;
 
-  const char *path;
+  svn_ra_serf__response_handler_t inner_handler;
+  void *inner_baton;
 
   const char *activity_collection;
   svn_revnum_t youngest_rev;
 
-  serf_response_acceptor_t acceptor;
-  serf_response_handler_t handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+} options_context_t;
 
-};
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t options_ttable[] = {
+  { INITIAL, D_, "options-response", OPTIONS,
+    FALSE, { NULL }, FALSE },
 
-static void
-push_state(svn_ra_serf__options_context_t *options_ctx, options_state_e state)
-{
-  options_state_list_t *new_state;
+  { OPTIONS, D_, "activity-collection-set", ACTIVITY_COLLECTION,
+    FALSE, { NULL }, FALSE },
 
-  if (!options_ctx->free_state)
-    {
-      new_state = apr_palloc(options_ctx->pool, sizeof(*options_ctx->state));
-    }
-  else
-    {
-      new_state = options_ctx->free_state;
-      options_ctx->free_state = options_ctx->free_state->prev;
-    }
-  new_state->state = state;
+  { ACTIVITY_COLLECTION, D_, "href", HREF,
+    TRUE, { NULL }, TRUE },
 
-  /* Add it to the state chain. */
-  new_state->prev = options_ctx->state;
-  options_ctx->state = new_state;
-}
-
-static void pop_state(svn_ra_serf__options_context_t *options_ctx)
-{
-  options_state_list_t *free_state;
-  free_state = options_ctx->state;
-  /* advance the current state */
-  options_ctx->state = options_ctx->state->prev;
-  free_state->prev = options_ctx->free_state;
-  options_ctx->free_state = free_state;
-}
-
-static svn_error_t *
-start_options(svn_ra_serf__xml_parser_t *parser,
-              svn_ra_serf__dav_props_t name,
-              const char **attrs,
-              apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__options_context_t *options_ctx = parser->user_data;
-
-  if (!options_ctx->state && strcmp(name.name, "options-response") == 0)
-    {
-      push_state(options_ctx, OPTIONS);
-    }
-  else if (!options_ctx->state)
-    {
-      /* Nothing to do. */
-      return SVN_NO_ERROR;
-    }
-  else if (options_ctx->state->state == OPTIONS &&
-           strcmp(name.name, "activity-collection-set") == 0)
-    {
-      push_state(options_ctx, ACTIVITY_COLLECTION);
-    }
-  else if (options_ctx->state->state == ACTIVITY_COLLECTION &&
-           strcmp(name.name, "href") == 0)
-    {
-      options_ctx->collect_cdata = TRUE;
-      push_state(options_ctx, HREF);
-    }
+  { 0 }
+};
 
-  return SVN_NO_ERROR;
-}
 
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_options(svn_ra_serf__xml_parser_t *parser,
-            svn_ra_serf__dav_props_t name,
-            apr_pool_t *scratch_pool)
+options_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)
 {
-  svn_ra_serf__options_context_t *options_ctx = parser->user_data;
-  options_state_list_t *cur_state;
-
-  if (!options_ctx->state)
-    {
-      return SVN_NO_ERROR;
-    }
+  options_context_t *opt_ctx = baton;
 
-  cur_state = options_ctx->state;
+  SVN_ERR_ASSERT(leaving_state == HREF);
+  SVN_ERR_ASSERT(cdata != NULL);
 
-  if (cur_state->state == OPTIONS &&
-      strcmp(name.name, "options-response") == 0)
-    {
-      pop_state(options_ctx);
-    }
-  else if (cur_state->state == ACTIVITY_COLLECTION &&
-           strcmp(name.name, "activity-collection-set") == 0)
-    {
-      pop_state(options_ctx);
-    }
-  else if (cur_state->state == HREF &&
-           strcmp(name.name, "href") == 0)
-    {
-      options_ctx->collect_cdata = FALSE;
-      options_ctx->activity_collection =
-        svn_urlpath__canonicalize(options_ctx->acbuf->data, options_ctx->pool);
-      pop_state(options_ctx);
-    }
+  opt_ctx->activity_collection = svn_urlpath__canonicalize(cdata->data,
+                                                           opt_ctx->pool);
 
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-cdata_options(svn_ra_serf__xml_parser_t *parser,
-              const char *data,
-              apr_size_t len,
-              apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__options_context_t *ctx = parser->user_data;
-
-  if (ctx->collect_cdata)
-    svn_stringbuf_appendbytes(ctx->acbuf, data, len);
-
-  return SVN_NO_ERROR;
-}
 
 static svn_error_t *
 create_options_body(serf_bucket_t **body_bkt,
@@ -227,47 +130,17 @@ create_options_body(serf_bucket_t **body
   return SVN_NO_ERROR;
 }
 
-svn_boolean_t*
-svn_ra_serf__get_options_done_ptr(svn_ra_serf__options_context_t *ctx)
-{
-  return &ctx->done;
-}
-
-const char *
-svn_ra_serf__options_get_activity_collection(svn_ra_serf__options_context_t 
*ctx)
-{
-  return ctx->activity_collection;
-}
-
-svn_revnum_t
-svn_ra_serf__options_get_youngest_rev(svn_ra_serf__options_context_t *ctx)
-{
-  return ctx->youngest_rev;
-}
-
-/* Context for both options_response_handler() and capabilities callback. */
-struct options_response_ctx_t {
-  /* Baton for __handle_xml_parser() */
-  svn_ra_serf__xml_parser_t *parser_ctx;
-
-  /* Session into which we'll store server capabilities */
-  svn_ra_serf__session_t *session;
-
-  /* For temporary work only. */
-  apr_pool_t *pool;
-};
-
 
 /* We use these static pointers so we can employ pointer comparison
  * of our capabilities hash members instead of strcmp()ing all over
  * the place.
  */
 /* Both server and repository support the capability. */
-static const char *capability_yes = "yes";
+static const char *const capability_yes = "yes";
 /* Either server or repository does not support the capability. */
-static const char *capability_no = "no";
+static const char *const capability_no = "no";
 /* Server supports the capability, but don't yet know if repository does. */
-static const char *capability_server_yes = "server-yes";
+static const char *const capability_server_yes = "server-yes";
 
 
 /* This implements serf_bucket_headers_do_callback_fn_t.
@@ -277,7 +150,8 @@ capabilities_headers_iterator_callback(v
                                        const char *key,
                                        const char *val)
 {
-  struct options_response_ctx_t *orc = baton;
+  options_context_t *opt_ctx = baton;
+  svn_ra_serf__session_t *session = opt_ctx->session;
 
   if (svn_cstring_casecmp(key, "dav") == 0)
     {
@@ -285,7 +159,8 @@ capabilities_headers_iterator_callback(v
            DAV: version-control,checkout,working-resource
            DAV: merge,baseline,activity,version-controlled-collection
            DAV: http://subversion.tigris.org/xmlns/dav/svn/depth */
-      apr_array_header_t *vals = svn_cstring_split(val, ",", TRUE, orc->pool);
+      apr_array_header_t *vals = svn_cstring_split(val, ",", TRUE,
+                                                   opt_ctx->pool);
 
       /* Right now we only have a few capabilities to detect, so just
          seek for them directly.  This could be written slightly more
@@ -294,33 +169,35 @@ capabilities_headers_iterator_callback(v
 
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_DEPTH, vals))
         {
-          apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_DEPTH,
-                       APR_HASH_KEY_STRING, capability_yes);
+          apr_hash_set(session->capabilities,
+                       SVN_RA_CAPABILITY_DEPTH, APR_HASH_KEY_STRING,
+                       capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_MERGEINFO, vals))
         {
           /* The server doesn't know what repository we're referring
              to, so it can't just say capability_yes. */
-          apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
-                       APR_HASH_KEY_STRING, capability_server_yes);
+          apr_hash_set(session->capabilities,
+                       SVN_RA_CAPABILITY_MERGEINFO, APR_HASH_KEY_STRING,
+                       capability_server_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_LOG_REVPROPS, vals))
         {
-          apr_hash_set(orc->session->capabilities,
-                       SVN_RA_CAPABILITY_LOG_REVPROPS,
-                       APR_HASH_KEY_STRING, capability_yes);
+          apr_hash_set(session->capabilities,
+                       SVN_RA_CAPABILITY_LOG_REVPROPS, APR_HASH_KEY_STRING,
+                       capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS, vals))
         {
-          apr_hash_set(orc->session->capabilities,
-                       SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
-                       APR_HASH_KEY_STRING, capability_yes);
+          apr_hash_set(session->capabilities,
+                       SVN_RA_CAPABILITY_ATOMIC_REVPROPS, APR_HASH_KEY_STRING,
+                       capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY, vals))
         {
-          apr_hash_set(orc->session->capabilities,
-                       SVN_RA_CAPABILITY_PARTIAL_REPLAY,
-                       APR_HASH_KEY_STRING, capability_yes);
+          apr_hash_set(session->capabilities,
+                       SVN_RA_CAPABILITY_PARTIAL_REPLAY, APR_HASH_KEY_STRING,
+                       capability_yes);
         }
     }
 
@@ -329,14 +206,12 @@ capabilities_headers_iterator_callback(v
     {
       if (svn_cstring_casecmp(key, SVN_DAV_ROOT_URI_HEADER) == 0)
         {
-          orc->session->repos_root = orc->session->session_url;
-          orc->session->repos_root.path = apr_pstrdup(orc->session->pool, val);
-          orc->session->repos_root_str =
+          session->repos_root = session->session_url;
+          session->repos_root.path = apr_pstrdup(session->pool, val);
+          session->repos_root_str =
             svn_urlpath__canonicalize(
-                apr_uri_unparse(orc->session->pool,
-                                &orc->session->repos_root,
-                                0),
-                orc->session->pool);
+                apr_uri_unparse(session->pool, &session->repos_root, 0),
+                session->pool);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_ME_RESOURCE_HEADER) == 0)
         {
@@ -345,44 +220,42 @@ capabilities_headers_iterator_callback(v
 
           if (!(ignore_v2_env_var
                 && apr_strnatcasecmp(ignore_v2_env_var, "yes") == 0))
-            orc->session->me_resource = apr_pstrdup(orc->session->pool, val);
+            session->me_resource = apr_pstrdup(session->pool, val);
 #else
-          orc->session->me_resource = apr_pstrdup(orc->session->pool, val);
+          session->me_resource = apr_pstrdup(session->pool, val);
 #endif
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_REV_STUB_HEADER) == 0)
         {
-          orc->session->rev_stub = apr_pstrdup(orc->session->pool, val);
+          session->rev_stub = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_REV_ROOT_STUB_HEADER) == 0)
         {
-          orc->session->rev_root_stub = apr_pstrdup(orc->session->pool, val);
+          session->rev_root_stub = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_TXN_STUB_HEADER) == 0)
         {
-          orc->session->txn_stub = apr_pstrdup(orc->session->pool, val);
+          session->txn_stub = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_TXN_ROOT_STUB_HEADER) == 0)
         {
-          orc->session->txn_root_stub = apr_pstrdup(orc->session->pool, val);
+          session->txn_root_stub = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_VTXN_STUB_HEADER) == 0)
         {
-          orc->session->vtxn_stub = apr_pstrdup(orc->session->pool, val);
+          session->vtxn_stub = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_VTXN_ROOT_STUB_HEADER) == 0)
         {
-          orc->session->vtxn_root_stub = apr_pstrdup(orc->session->pool, val);
+          session->vtxn_root_stub = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_REPOS_UUID_HEADER) == 0)
         {
-          orc->session->uuid = apr_pstrdup(orc->session->pool, val);
+          session->uuid = apr_pstrdup(session->pool, val);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_YOUNGEST_REV_HEADER) == 0)
         {
-          struct svn_ra_serf__options_context_t *user_data =
-            orc->parser_ctx->user_data;
-          user_data->youngest_rev = SVN_STR_TO_REV(val);
+          opt_ctx->youngest_rev = SVN_STR_TO_REV(val);
         }
     }
 
@@ -391,7 +264,7 @@ capabilities_headers_iterator_callback(v
 
 
 /* A custom serf_response_handler_t which is mostly a wrapper around
-   svn_ra_serf__handle_xml_parser -- it just notices OPTIONS response
+   the expat-based response handler -- it just notices OPTIONS response
    headers first, before handing off to the xml parser.
    Implements svn_ra_serf__response_handler_t */
 static svn_error_t *
@@ -400,88 +273,117 @@ options_response_handler(serf_request_t 
                          void *baton,
                          apr_pool_t *pool)
 {
-  struct options_response_ctx_t *orc = baton;
-  serf_bucket_t *hdrs = serf_bucket_response_get_headers(response);
+  options_context_t *opt_ctx = baton;
+
+  if (!opt_ctx->headers_processed)
+    {
+      svn_ra_serf__session_t *session = opt_ctx->session;
+      serf_bucket_t *hdrs = serf_bucket_response_get_headers(response);
 
-  /* Start out assuming all capabilities are unsupported. */
-  apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
-               APR_HASH_KEY_STRING, capability_no);
-  apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_DEPTH,
-               APR_HASH_KEY_STRING, capability_no);
-  apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
-               APR_HASH_KEY_STRING, capability_no);
-  apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
-               APR_HASH_KEY_STRING, capability_no);
-  apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
-               APR_HASH_KEY_STRING, capability_no);
+      /* Start out assuming all capabilities are unsupported. */
+      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
+                   APR_HASH_KEY_STRING, capability_no);
+      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_DEPTH,
+                   APR_HASH_KEY_STRING, capability_no);
+      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
+                   APR_HASH_KEY_STRING, capability_no);
+      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
+                   APR_HASH_KEY_STRING, capability_no);
+      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                   APR_HASH_KEY_STRING, capability_no);
+
+      /* Then see which ones we can discover. */
+      serf_bucket_headers_do(hdrs, capabilities_headers_iterator_callback,
+                             opt_ctx);
 
-  /* Then see which ones we can discover. */
-  serf_bucket_headers_do(hdrs, capabilities_headers_iterator_callback, orc);
+      opt_ctx->headers_processed = TRUE;
+    }
 
   /* Execute the 'real' response handler to XML-parse the repsonse body. */
-  return svn_ra_serf__handle_xml_parser(request, response,
-                                        orc->parser_ctx, pool);
+  return opt_ctx->inner_handler(request, response, opt_ctx->inner_baton, pool);
 }
 
 
-svn_error_t *
-svn_ra_serf__create_options_req(svn_ra_serf__options_context_t **opt_ctx,
-                                svn_ra_serf__session_t *session,
-                                svn_ra_serf__connection_t *conn,
-                                const char *path,
-                                apr_pool_t *pool)
+static svn_error_t *
+create_options_req(options_context_t **opt_ctx,
+                   svn_ra_serf__session_t *session,
+                   svn_ra_serf__connection_t *conn,
+                   apr_pool_t *pool)
 {
-  svn_ra_serf__options_context_t *new_ctx;
+  options_context_t *new_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
-  struct options_response_ctx_t *options_response_ctx;
 
   new_ctx = apr_pcalloc(pool, sizeof(*new_ctx));
-
   new_ctx->pool = pool;
-
-  new_ctx->acbuf = svn_stringbuf_create_empty(pool);
-
-  new_ctx->path = path;
-  new_ctx->youngest_rev = SVN_INVALID_REVNUM;
-
   new_ctx->session = session;
   new_ctx->conn = conn;
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  new_ctx->youngest_rev = SVN_INVALID_REVNUM;
+
+  xmlctx = svn_ra_serf__xml_context_create(options_ttable,
+                                           NULL, options_closed, NULL,
+                                           new_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
   handler->method = "OPTIONS";
-  handler->path = path;
+  handler->path = session->session_url.path;
   handler->body_delegate = create_options_body;
   handler->body_type = "text/xml";
   handler->conn = conn;
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = new_ctx;
-  parser_ctx->start = start_options;
-  parser_ctx->end = end_options;
-  parser_ctx->cdata = cdata_options;
-  parser_ctx->done = &new_ctx->done;
-  parser_ctx->status_code = &new_ctx->status_code;
-
-  options_response_ctx = apr_pcalloc(pool, sizeof(*options_response_ctx));
-  options_response_ctx->parser_ctx = parser_ctx;
-  options_response_ctx->session = session;
-  options_response_ctx->pool = pool;
+  new_ctx->handler = handler;
 
+  new_ctx->inner_handler = handler->response_handler;
+  new_ctx->inner_baton = handler->response_baton;
   handler->response_handler = options_response_handler;
-  handler->response_baton = options_response_ctx;
+  handler->response_baton = new_ctx;
+
+  *opt_ctx = new_ctx;
+
+  return SVN_NO_ERROR;
+}
+
 
-  svn_ra_serf__request_create(handler);
+svn_error_t *
+svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
+                                    svn_ra_serf__connection_t *conn,
+                                    apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__session_t *session = conn->session;
+  options_context_t *opt_ctx;
 
-  new_ctx->parser_ctx = parser_ctx;
+  SVN_ERR_ASSERT(SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session));
 
-  *opt_ctx = new_ctx;
+  SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
+  SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
+
+  *youngest = opt_ctx->youngest_rev;
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_ra_serf__v1_get_activity_collection(const char **activity_url,
+                                        svn_ra_serf__connection_t *conn,
+                                        apr_pool_t *result_pool,
+                                        apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__session_t *session = conn->session;
+  options_context_t *opt_ctx;
+
+  SVN_ERR_ASSERT(!SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session));
+
+  SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
+  SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
+
+  *activity_url = apr_pstrdup(result_pool, opt_ctx->activity_collection);
 
   return SVN_NO_ERROR;
+
 }
 
 
@@ -493,32 +395,29 @@ svn_ra_serf__exchange_capabilities(svn_r
                                    const char **corrected_url,
                                    apr_pool_t *pool)
 {
-  svn_ra_serf__options_context_t *opt_ctx;
+  options_context_t *opt_ctx;
   svn_error_t *err;
 
   /* This routine automatically fills in serf_sess->capabilities */
-  SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, serf_sess,
-                                          serf_sess->conns[0],
-                                          serf_sess->session_url.path, pool));
+  SVN_ERR(create_options_req(&opt_ctx, serf_sess, serf_sess->conns[0], pool));
 
-  err = svn_ra_serf__context_run_wait(
-            svn_ra_serf__get_options_done_ptr(opt_ctx), serf_sess, pool);
+  err = svn_ra_serf__context_run_one(opt_ctx->handler, pool);
 
   /* If our caller cares about server redirections, and our response
      carries such a thing, report as much.  We'll disregard ERR --
      it's most likely just a complaint about the response body not
      successfully parsing as XML or somesuch. */
-  if (corrected_url && (opt_ctx->status_code == 301))
+  if (corrected_url && (opt_ctx->handler->sline.code == 301))
     {
       svn_error_clear(err);
-      *corrected_url = opt_ctx->parser_ctx->location;
+      *corrected_url = opt_ctx->handler->location;
       return SVN_NO_ERROR;
     }
 
   return svn_error_compose_create(
-             svn_ra_serf__error_on_status(opt_ctx->status_code,
+             svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
                                           serf_sess->session_url.path,
-                                          opt_ctx->parser_ctx->location),
+                                          opt_ctx->handler->location),
              err);
 }
 
@@ -551,9 +450,7 @@ svn_ra_serf__has_capability(svn_ra_sessi
   cap_result = apr_hash_get(serf_sess->capabilities,
                             capability, APR_HASH_KEY_STRING);
 
-  /* Some capabilities depend on the repository as well as the server.
-     NOTE: svn_ra_neon__has_capability() has a very similar code block.  If
-     you change something here, check there as well. */
+  /* Some capabilities depend on the repository as well as the server. */
   if (cap_result == capability_server_yes)
     {
       if (strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO) == 0)


Reply via email to