You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/06/07 16:53:06 UTC

svn commit: r1490669 - in /subversion/trunk/subversion: include/private/svn_ra_svn_private.h libsvn_ra_svn/client.c libsvn_ra_svn/marshal.c

Author: stefan2
Date: Fri Jun  7 14:53:06 2013
New Revision: 1490669

URL: http://svn.apache.org/r1490669
Log:
For RA_SVN, we taught the transmitting side to send commands and some data
using a fully typed API.  Now, let the receiving side begin to use fully
typed APIs.  Start with the "changed path" structure send as part of an
svn log -v.  Other functions may follow later as they turn out to be part
of the hot path.

* subversion/include/private/svn_ra_svn_private.h
  (svn_send_data): tweak doxygen group name
  (svn_ra_svn__read_data_log_changed_entry): declare new private API

* subversion/libsvn_ra_svn/marshal.c
  (CHECK_PROTOCOL_COND,
   svn_ra_svn__read_string,
   svn_ra_svn__read_cstring,
   svn_ra_svn__read_word,
   svn_ra_svn__read_revision,
   svn_ra_svn__read_boolean,
   svn_ra_svn__read_list,
   svn_ra_svn__read_check_array_size): new data extraction & verification
                                       utility functions
  (svn_ra_svn__read_data_log_changed_entry): implement

* subversion/libsvn_ra_svn/client.c
  (ra_svn_log): use the new API for faster processing

Modified:
    subversion/trunk/subversion/include/private/svn_ra_svn_private.h
    subversion/trunk/subversion/libsvn_ra_svn/client.c
    subversion/trunk/subversion/libsvn_ra_svn/marshal.c

Modified: subversion/trunk/subversion/include/private/svn_ra_svn_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_ra_svn_private.h?rev=1490669&r1=1490668&r2=1490669&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_ra_svn_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_ra_svn_private.h Fri Jun  7 14:53:06 2013
@@ -835,7 +835,7 @@ svn_ra_svn__write_cmd_finish_replay(svn_
  */
 
 /**
- * @defgroup svn_data sending data structures over ra_svn
+ * @defgroup svn_send_data sending data structures over ra_svn
  * @{
  */
 
@@ -880,6 +880,30 @@ svn_ra_svn__write_data_log_entry(svn_ra_
 /**
  * @}
  */
+
+/**
+ * @defgroup svn_read_data reading data structures from ra_svn
+ * @{
+ */
+
+/** Take the data tuple ITEMS received over ra_svn and convert it to the
+ * a changed path (as part of receiving a log entry).
+ *
+ * @see svn_log_changed_path2_t for a description of the output parameters.
+ */
+svn_error_t *
+svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items,
+                                        svn_string_t **cpath,
+                                        const char **action,
+                                        const char **copy_path,
+                                        svn_revnum_t *copy_rev,
+                                        const char **kind_str,
+                                        apr_uint64_t *text_mods,
+                                        apr_uint64_t *prop_mods);
+/**
+ * @}
+ */
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/trunk/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/client.c?rev=1490669&r1=1490668&r2=1490669&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/trunk/subversion/libsvn_ra_svn/client.c Fri Jun  7 14:53:06 2013
@@ -1597,8 +1597,7 @@ static svn_error_t *ra_svn_log(svn_ra_se
               if (elt->kind != SVN_RA_SVN_LIST)
                 return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                         _("Changed-path entry not a list"));
-              SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool,
-                                              "sw(?cr)?(?c?BB)",
+              SVN_ERR(svn_ra_svn__read_data_log_changed_entry(elt->u.list,
                                               &cpath, &action, &copy_path,
                                               &copy_rev, &kind_str,
                                               &text_mods, &prop_mods));

Modified: subversion/trunk/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/marshal.c?rev=1490669&r1=1490668&r2=1490669&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/trunk/subversion/libsvn_ra_svn/marshal.c Fri Jun  7 14:53:06 2013
@@ -2422,3 +2422,161 @@ svn_ra_svn__write_data_log_entry(svn_ra_
   
   return SVN_NO_ERROR;
 }
+
+/* If condition COND is not met, return a "malformed network data" error.
+ */
+#define CHECK_PROTOCOL_COND(cond)\
+  if (!(cond)) \
+    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, \
+                            _("Malformed network data"));
+
+/* In *RESULT, return the SVN-style string at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_string(const apr_array_header_t *items,
+                        int idx,
+                        svn_string_t **result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_STRING);
+  *result = elt->u.string;
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the C-style string at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_cstring(const apr_array_header_t *items,
+                         int idx,
+                         const char **result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_STRING);
+  *result = elt->u.string->data;
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the word at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_word(const apr_array_header_t *items,
+                      int idx,
+                      const char **result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
+  *result = elt->u.word;
+   
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the revision at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_revision(const apr_array_header_t *items,
+                          int idx,
+                          svn_revnum_t *result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_NUMBER);
+  *result = (svn_revnum_t)elt->u.number;
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the boolean at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_boolean(const apr_array_header_t *items,
+                         int idx,
+                         apr_uint64_t *result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
+  if (elt->u.word[0] == 't' && strcmp(elt->u.word, "true") == 0)
+    *result = TRUE;
+  else if (strcmp(elt->u.word, "false") == 0)
+    *result = FALSE;
+  else
+    CHECK_PROTOCOL_COND(FALSE);
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the tuple at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_list(const apr_array_header_t *items,
+                      int idx,
+                      const apr_array_header_t **result)
+{
+  svn_ra_svn_item_t *elt  = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_LIST);
+
+  *result = elt->u.list;
+  return SVN_NO_ERROR;
+}
+
+/* Verify the tuple ITEMS contains at least MIN and at most MAX elements.
+ */
+static svn_error_t *
+svn_ra_svn__read_check_array_size(const apr_array_header_t *items,
+                                  int min,
+                                  int max)
+{
+  CHECK_PROTOCOL_COND(items->nelts >= min && items->nelts <= max);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items,
+                                        svn_string_t **cpath,
+                                        const char **action,
+                                        const char **copy_path,
+                                        svn_revnum_t *copy_rev,
+                                        const char **kind_str,
+                                        apr_uint64_t *text_mods,
+                                        apr_uint64_t *prop_mods)
+{
+  const apr_array_header_t *sub_items;
+
+  /* initialize optional values */
+  *copy_path = NULL;
+  *copy_rev = SVN_INVALID_REVNUM;
+  *kind_str = NULL;
+  *text_mods = SVN_RA_SVN_UNSPECIFIED_NUMBER;
+  *prop_mods = SVN_RA_SVN_UNSPECIFIED_NUMBER;
+
+  /* top-level elements (mandatory) */
+  SVN_ERR(svn_ra_svn__read_check_array_size(items, 3, 4));
+  SVN_ERR(svn_ra_svn__read_string(items, 0, cpath));
+  SVN_ERR(svn_ra_svn__read_word(items, 1, action));
+
+  /* first sub-structure (mandatory) */
+  SVN_ERR(svn_ra_svn__read_list(items, 2, &sub_items));
+  if (sub_items->nelts)
+    {
+      SVN_ERR(svn_ra_svn__read_check_array_size(sub_items, 2, 2));
+      SVN_ERR(svn_ra_svn__read_cstring(sub_items, 0, copy_path));
+      SVN_ERR(svn_ra_svn__read_revision(sub_items, 1, copy_rev));
+    }
+
+  /* second sub-structure (optional) */
+  if (items->nelts == 4)
+    {
+      SVN_ERR(svn_ra_svn__read_list(items, 3, &sub_items));
+      SVN_ERR(svn_ra_svn__read_check_array_size(sub_items, 0, 3));
+
+      switch (sub_items->nelts)
+        {
+          case 3 : SVN_ERR(svn_ra_svn__read_boolean(sub_items, 2, prop_mods));
+          case 2 : SVN_ERR(svn_ra_svn__read_boolean(sub_items, 1, text_mods));
+          case 1 : SVN_ERR(svn_ra_svn__read_cstring(sub_items, 0, kind_str));
+          default: break;
+        }
+    }
+
+  return SVN_NO_ERROR;
+}