subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1498000 - /subversion/trunk/subversion/libsvn_ra_serf/inherited_props.c
Date Sat, 29 Jun 2013 19:51:51 GMT
Author: rhuijben
Date: Sat Jun 29 18:46:37 2013
New Revision: 1498000

URL: http://svn.apache.org/r1498000
Log:
Convert the inherited property code in serf to the 'new' transition based XML
processing.

* subversion/libsvn_ra_serf/inherited_props.c
  (iprops_state_e): Rename initial state to INITIAL
  (iprops_context_t): Remove no longer needed variables.
  (iprops_table): New transition table.

  (start_element): Rename to ...
  (iprops_opened): ... this and implement svn_ra_serf__xml_opened_t.

  (end_element): Rename to ...
  (iprops_closed): ... this and implement svn_ra_serf__xml_closed_t.

  (cdata_handler): Remove function.

  (svn_ra_serf__get_inherited_props): Update handler initialization.

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

Modified: subversion/trunk/subversion/libsvn_ra_serf/inherited_props.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/inherited_props.c?rev=1498000&r1=1497999&r2=1498000&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/inherited_props.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/inherited_props.c Sat Jun 29 18:46:37 2013
@@ -41,7 +41,7 @@
 
 /* The current state of our XML parsing. */
 typedef enum iprops_state_e {
-  NONE = 0,
+  INITIAL = 0,
   IPROPS_REPORT,
   IPROPS_ITEM,
   IPROPS_PATH,
@@ -61,18 +61,12 @@ typedef struct iprops_context_t {
   /* The repository's root URL. */
   const char *repos_root_url;
 
-  /* Current CDATA values*/
-  svn_stringbuf_t *curr_path;
+  /* Current property name */
   svn_stringbuf_t *curr_propname;
-  svn_stringbuf_t *curr_propval;
-  const char *curr_prop_val_encoding;
 
   /* Current element in IPROPS. */
   svn_prop_inherited_item_t *curr_iprop;
 
-  /* Serf context completion flag for svn_ra_serf__context_run_wait() */
-  svn_boolean_t done;
-
   /* Path we are finding inherited properties for.  This is relative to
      the RA session passed to svn_ra_serf__get_inherited_props. */
   const char *path;
@@ -80,162 +74,121 @@ typedef struct iprops_context_t {
   svn_revnum_t revision;
 } iprops_context_t;
 
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t iprops_table[] = {
+  { INITIAL, S_, SVN_DAV__INHERITED_PROPS_REPORT, IPROPS_REPORT,
+    FALSE, { NULL }, FALSE },
+
+  { IPROPS_REPORT, S_, SVN_DAV__IPROP_ITEM, IPROPS_ITEM,
+    FALSE, { NULL }, TRUE },
+
+  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PATH, IPROPS_PATH,
+    TRUE, { NULL }, TRUE },
+
+  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPNAME, IPROPS_PROPNAME,
+    TRUE, { NULL }, TRUE },
+
+  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPVAL, IPROPS_PROPVAL,
+    TRUE, { "?V:encoding", NULL }, TRUE },
+
+  { 0 }
+};
+
+/* Conforms to svn_ra_serf__xml_opened_t */
 static svn_error_t *
-start_element(svn_ra_serf__xml_parser_t *parser,
-              svn_ra_serf__dav_props_t name,
-              const char **attrs,
+iprops_opened(svn_ra_serf__xml_estate_t *xes,
+              void *baton,
+              int entered_state,
+              const svn_ra_serf__dav_props_t *tag,
               apr_pool_t *scratch_pool)
 {
-  iprops_context_t *iprops_ctx = parser->user_data;
-  iprops_state_e state;
+  iprops_context_t *iprops_ctx = baton;
 
-  state = parser->state->current_state;
-  if (state == NONE
-      && strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
+  if (entered_state == IPROPS_ITEM)
     {
-      svn_ra_serf__xml_push_state(parser, IPROPS_REPORT);
-    }
-  else if (state == IPROPS_REPORT &&
-           strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
-    {
-      svn_stringbuf_setempty(iprops_ctx->curr_path);
       svn_stringbuf_setempty(iprops_ctx->curr_propname);
-      svn_stringbuf_setempty(iprops_ctx->curr_propval);
-      iprops_ctx->curr_prop_val_encoding = NULL;
-      iprops_ctx->curr_iprop = NULL;
-      svn_ra_serf__xml_push_state(parser, IPROPS_ITEM);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
-    {
-      const char *prop_val_encoding = svn_xml_get_attr_value("encoding",
-                                                             attrs);
-      iprops_ctx->curr_prop_val_encoding = apr_pstrdup(iprops_ctx->pool,
-                                                       prop_val_encoding);
-      svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, IPROPS_PATH);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, IPROPS_PROPNAME);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
-    }
 
+      iprops_ctx->curr_iprop = apr_pcalloc(iprops_ctx->pool,
+                                           sizeof(*iprops_ctx->curr_iprop));
+
+      iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
+    }
   return SVN_NO_ERROR;
 }
 
+/* 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)
+iprops_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)
 {
-  iprops_context_t *iprops_ctx = parser->user_data;
-  iprops_state_e state;
-
-  state = parser->state->current_state;
+  iprops_context_t *iprops_ctx = baton;
 
-    if (state == IPROPS_REPORT &&
-      strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
+  if (leaving_state == IPROPS_ITEM)
     {
-      svn_ra_serf__xml_pop_state(parser);
+      APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
+        iprops_ctx->curr_iprop;
+
+      iprops_ctx->curr_iprop = NULL;
     }
-  else if (state == IPROPS_PATH
-           && strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
+  else if (leaving_state == IPROPS_PATH)
     {
-      iprops_ctx->curr_iprop = apr_palloc(
-        iprops_ctx->pool, sizeof(svn_prop_inherited_item_t));
+      /* Every <iprop-item> has a single <iprop-path> */
+      if (iprops_ctx->curr_iprop->path_or_url)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
 
       iprops_ctx->curr_iprop->path_or_url =
         svn_path_url_add_component2(iprops_ctx->repos_root_url,
-                                    iprops_ctx->curr_path->data,
+                                    cdata->data,
                                     iprops_ctx->pool);
-      iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == IPROPS_PROPVAL
-           && strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
+  else if (leaving_state == IPROPS_PROPNAME)
     {
-      const svn_string_t *prop_val;
+      if (iprops_ctx->curr_propname->len)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
 
-      if (iprops_ctx->curr_prop_val_encoding)
-        {
-          svn_string_t encoded_prop_val;
+      /* Store propname for value */
+      svn_stringbuf_set(iprops_ctx->curr_propname, cdata->data);
+    }
+  else if (leaving_state == IPROPS_PROPVAL)
+    {
+      const char *encoding;
+      const svn_string_t *val_str;
+
+      if (! iprops_ctx->curr_propname->len)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+
+      encoding = svn_hash_gets(attrs, "V:encoding");
 
-          if (strcmp(iprops_ctx->curr_prop_val_encoding, "base64") != 0)
-            return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+      if (encoding)
+        {
+          if (strcmp(encoding, "base64") != 0)
+            return svn_error_createf(SVN_ERR_XML_MALFORMED,
+                                     NULL,
+                                     _("Got unrecognized encoding '%s'"),
+                                     encoding);
 
-          encoded_prop_val.data = iprops_ctx->curr_propval->data;
-          encoded_prop_val.len = iprops_ctx->curr_propval->len;
-          prop_val = svn_base64_decode_string(&encoded_prop_val,
-                                              iprops_ctx->pool);
+          /* Decode into the right pool.  */
+          val_str = svn_base64_decode_string(cdata, iprops_ctx->pool);
         }
       else
         {
-          prop_val = svn_string_create_from_buf(iprops_ctx->curr_propval,
-                                                iprops_ctx->pool);
+          /* Copy into the right pool.  */
+          val_str = svn_string_dup(cdata, iprops_ctx->pool);
         }
 
       svn_hash_sets(iprops_ctx->curr_iprop->prop_hash,
                     apr_pstrdup(iprops_ctx->pool,
                                 iprops_ctx->curr_propname->data),
-                    prop_val);
-      /* Clear current propname and propval in the event there are
-         multiple properties on the current path. */
+                    val_str);
+      /* Clear current propname. */
       svn_stringbuf_setempty(iprops_ctx->curr_propname);
-      svn_stringbuf_setempty(iprops_ctx->curr_propval);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == IPROPS_PROPNAME
-           && strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == IPROPS_ITEM
-           && strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
-    {
-      APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
-        iprops_ctx->curr_iprop;
-      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)
-{
-  iprops_context_t *iprops_ctx = parser->user_data;
-  iprops_state_e state = parser->state->current_state;
-
-  switch (state)
-    {
-    case IPROPS_PATH:
-      svn_stringbuf_appendbytes(iprops_ctx->curr_path, data, len);
-      break;
-
-    case IPROPS_PROPNAME:
-      svn_stringbuf_appendbytes(iprops_ctx->curr_propname, data, len);
-      break;
-
-    case IPROPS_PROPVAL:
-      svn_stringbuf_appendbytes(iprops_ctx->curr_propval, data, len);
-      break;
-
-    default:
-      break;
     }
+  else
+    SVN_ERR_MALFUNCTION(); /* Invalid transition table */
 
   return SVN_NO_ERROR;
 }
@@ -281,7 +234,7 @@ svn_ra_serf__get_inherited_props(svn_ra_
   iprops_context_t *iprops_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;
 
   SVN_ERR(svn_ra_serf__get_stable_url(&req_url,
@@ -295,19 +248,20 @@ svn_ra_serf__get_inherited_props(svn_ra_
   SVN_ERR_ASSERT(session->repos_root_str);
 
   iprops_ctx = apr_pcalloc(scratch_pool, sizeof(*iprops_ctx));
-  iprops_ctx->done = FALSE;
   iprops_ctx->repos_root_url = session->repos_root_str;
   iprops_ctx->pool = result_pool;
-  iprops_ctx->curr_path = svn_stringbuf_create_empty(scratch_pool);
   iprops_ctx->curr_propname = svn_stringbuf_create_empty(scratch_pool);
-  iprops_ctx->curr_propval = svn_stringbuf_create_empty(scratch_pool);
   iprops_ctx->curr_iprop = NULL;
   iprops_ctx->iprops = apr_array_make(result_pool, 1,
                                        sizeof(svn_prop_inherited_item_t *));
   iprops_ctx->path = path;
   iprops_ctx->revision = revision;
 
-  handler = apr_pcalloc(scratch_pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(iprops_table,
+                                           iprops_opened, iprops_closed, NULL,
+                                           iprops_ctx,
+                                           scratch_pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
@@ -318,18 +272,6 @@ svn_ra_serf__get_inherited_props(svn_ra_
   handler->body_type = "text/xml";
   handler->handler_pool = scratch_pool;
 
-  parser_ctx = apr_pcalloc(scratch_pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = scratch_pool;
-  parser_ctx->user_data = iprops_ctx;
-  parser_ctx->start = start_element;
-  parser_ctx->end = end_element;
-  parser_ctx->cdata = cdata_handler;
-  parser_ctx->done = &iprops_ctx->done;
-
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
   err = svn_ra_serf__context_run_one(handler, scratch_pool);
   SVN_ERR(svn_error_compose_create(
                     svn_ra_serf__error_on_status(handler->sline,
@@ -337,8 +279,7 @@ svn_ra_serf__get_inherited_props(svn_ra_
                                                  handler->location),
                     err));
 
-  if (iprops_ctx->done)
-    *iprops = iprops_ctx->iprops;
+  *iprops = iprops_ctx->iprops;
 
   return SVN_NO_ERROR;
 }



Mime
View raw message