subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@apache.org
Subject svn commit: r1337788 - in /subversion/trunk/subversion/libsvn_ra_serf: getlocks.c ra_serf.h xml.c
Date Sun, 13 May 2012 07:01:19 GMT
Author: gstein
Date: Sun May 13 07:01:18 2012
New Revision: 1337788

URL: http://svn.apache.org/viewvc?rev=1337788&view=rev
Log:
Convert the get-locks report over to v2 xml processing.

This also tweaks the "note" feature to store a note on a parent state,
rather than "this" state.

* subversion/libsvn_ra_serf/ra_serf.h:
  (svn_ra_serf__xml_note): add a state parameter and document

* subversion/libsvn_ra_serf/xml.c:
  (svn_ra_serf__xml_note): new implementation, with new param

* subversion/libsvn_ra_serf/getlocks.c:
  (lock_state_e): remove typedef/enum name. rename NONE to INITIAL.
  (lock_info_t): removed; obsolete.
  (lock_context_t): remove DONE element
  (push_state, start_getlocks, end_getlocks, cdata_getlocks): removed.
    obsolete.
  (getlocks_ttable): new transition table
  (getlocks_closed): new callback to process the response
  (svn_ra_serf__get_locks): switch to new xml parsing. use run_one().

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/getlocks.c
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
    subversion/trunk/subversion/libsvn_ra_serf/xml.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/getlocks.c?rev=1337788&r1=1337787&r2=1337788&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/getlocks.c Sun May 13 07:01:18 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;
-    }
-
-  return parser->state->private;
-}
+  { LOCK, S_, "owner", OWNER,
+    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_, "comment", COMMENT,
+    TRUE, { NULL }, FALSE, TRUE },
 
-  state = parser->state->current_state;
+  { LOCK, S_, SVN_DAV__CREATIONDATE, CREATION_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);
-        }
-    }
+  { LOCK, S_, "expirationdate", EXPIRATION_DATE,
+    TRUE, { NULL }, FALSE, TRUE },
 
-  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,7 +234,7 @@ 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;
 
   req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
@@ -336,37 +246,24 @@ 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->handler_pool = pool;
   handler->method = "REPORT";
   handler->path = req_url;
   handler->body_type = "text/xml";
   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;
-
   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/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=1337788&r1=1337787&r2=1337788&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Sun May 13 07:01:18 2012
@@ -715,8 +715,20 @@ svn_ra_serf__xml_gather_since(svn_ra_ser
                               int stop_state);
 
 
+/* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
+   The name and value will be copied into the target state's pool.
+
+   These values will be available to the CLOSED_CB for the target state,
+   or part of the gathered state via xml_gather_since().
+
+   Typically, this function is used by a child state's close callback,
+   or within an opening callback to store additional data.
+
+   Note: if the state is not found, then a programmer error has occurred,
+   so the function will invoke SVN_ERR_MALFUNCTION().  */
 void
 svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
+                      int state,
                       const char *name,
                       const char *value);
 

Modified: subversion/trunk/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/xml.c?rev=1337788&r1=1337787&r2=1337788&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/xml.c Sun May 13 07:01:18 2012
@@ -493,12 +493,30 @@ svn_ra_serf__xml_gather_since(svn_ra_ser
 
 void
 svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
+                      int state,
                       const char *name,
                       const char *value)
 {
-  ensure_pool(xes);
+  svn_ra_serf__xml_estate_t *scan;
+
+  for (scan = xes; scan != NULL && scan->state != state; scan = scan->prev)
+    /* pass */ ;
+
+  SVN_ERR_ASSERT_NO_RETURN(scan != NULL);
 
-  /* ### copy into attrs  */
+  /* Make sure the target state has a pool.  */
+  ensure_pool(scan);
+
+  /* ... and attribute storage.  */
+  if (scan->attrs == NULL)
+    scan->attrs = apr_hash_make(scan->state_pool);
+
+  /* In all likelihood, NAME is a string constant. But we can't really
+     be sure. And it isn't like we're storing a billion of these into
+     the state pool.  */
+  apr_hash_set(scan->attrs,
+               apr_pstrdup(scan->state_pool, name), APR_HASH_KEY_STRING,
+               apr_pstrdup(scan->state_pool, value));
 }
 
 



Mime
View raw message