Author: gstein
Date: Wed Jun  6 21:52:53 2012
New Revision: 1347156

URL: http://svn.apache.org/viewvc?rev=1347156&view=rev
Log:
Switch the mergeinfo processing over to the new XML processing.

* subversion/libsvn_ra_serf/mergeinfo.c:
  (NONE): renamed to ...
  (INITIAL): ... this.
  (mergeinfo_context_t): removed CURR_PATH, CURR_INFO, DONE. no longer
    required.
  (mergeinfo_ttable): new transition table
  (start_element, end_element, cdata_handler): removed. obsolete.
  (mergeinfo_closed): new handler to capture a piece of mergeinfo data
  (svn_ra_serf__get_mergeinfo): switch to the new parser.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c?rev=1347156&r1=1347155&r2=1347156&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c Wed Jun  6 21:52:53 
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, FALSE },
+
+  { MERGEINFO_REPORT, S_, SVN_DAV__MERGEINFO_ITEM, MERGEINFO_ITEM,
+    FALSE, { NULL }, FALSE, TRUE },
+
+  { MERGEINFO_ITEM, S_, SVN_DAV__MERGEINFO_PATH, MERGEINFO_PATH,
+    TRUE, { NULL }, FALSE, TRUE },
+
+  { MERGEINFO_ITEM, S_, SVN_DAV__MERGEINFO_INFO, MERGEINFO_INFO,
+    TRUE, { NULL }, FALSE, 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)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == MERGEINFO_ITEM
-           && strcmp(name.name, SVN_DAV__MERGEINFO_ITEM) == 0)
+  if (leaving_state == MERGEINFO_ITEM)
     {
-      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)
+  else
     {
-      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;
-}
-
+      SVN_ERR_ASSERT(leaving_state == MERGEINFO_PATH
+                     || leaving_state == MERGEINFO_INFO);
 
-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)
-    {
-    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;
-
-    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,
@@ -242,7 +195,7 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
   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;
+  svn_ra_serf__xml_context_t *xmlctx;
   const char *path;
 
   *catalog = NULL;
@@ -254,18 +207,18 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   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,
+                                           mergeinfo_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
-  handler->handler_pool = pool;
   handler->method = "REPORT";
   handler->path = path;
   handler->conn = session->conns[0];
@@ -274,21 +227,7 @@ 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;
-
-  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(handler->sline.code, handler->path,
                                       handler->location);
@@ -300,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;


Reply via email to