You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/01/25 19:20:02 UTC

svn commit: r1654681 - in /subversion/trunk/subversion/libsvn_ra_serf: get_file.c property.c ra_serf.h stat.c

Author: rhuijben
Date: Sun Jan 25 18:20:02 2015
New Revision: 1654681

URL: http://svn.apache.org/r1654681
Log:
In ra_serf, refactor the get_file() implementation to collect its special
properties directly instead of via an intermediate 'generic hash'.

* subversion/libsvn_ra_serf/get_file.c
  (try_get_wc_contents): Use direct argument for checksum.
  (file_prop_baton_t): New struct.
  (get_file_prop_cb): New function.
  (svn_ra_serf__get_file): Avoid the far too generic node prop functions.

* subversion/libsvn_ra_serf/property.c
  (propfind_context_t,
   svn_ra_serf__create_propfind_handler): Update type usage.
  (set_flat_props,
   svn_ra_serf__flatten_props): Remove functions.
  (svn_ra_serf__get_resource_type): Move this function to stat.c

* subversion/libsvn_ra_serf/ra_serf.h
  (svn_ra_serf__prop_func): Rename to...
  (svn_ra_serf__prop_func_t): ... this.
  (svn_ra_serf__deliver_svn_props,
   svn_ra_serf__deliver_node_props): Update comments.
  (svn_ra_serf__create_propfind_handler): Update type usage.

  (svn_ra_serf__flatten_props,
   svn_ra_serf__get_resource_type): Remove functions.

  (svn_ra_serf__report_resource): Update comment.

* subversion/libsvn_ra_serf/stat.c
  (get_resource_type): New function.
  (svn_ra_serf__check_path): Update caller.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/get_file.c
    subversion/trunk/subversion/libsvn_ra_serf/property.c
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
    subversion/trunk/subversion/libsvn_ra_serf/stat.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/get_file.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/get_file.c?rev=1654681&r1=1654680&r2=1654681&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/get_file.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/get_file.c Sun Jan 25 18:20:02 2015
@@ -144,12 +144,10 @@ cancel_fetch(serf_request_t *request,
 static svn_error_t *
 try_get_wc_contents(svn_boolean_t *found_p,
                     svn_ra_serf__session_t *session,
-                    apr_hash_t *props,
+                    const char *sha1_checksum_prop,
                     svn_stream_t *dst_stream,
                     apr_pool_t *pool)
 {
-  apr_hash_t *svn_props;
-  const char *sha1_checksum_prop;
   svn_checksum_t *checksum;
   svn_stream_t *wc_stream;
   svn_error_t *err;
@@ -157,24 +155,10 @@ try_get_wc_contents(svn_boolean_t *found
   /* No contents found by default. */
   *found_p = FALSE;
 
-  if (!session->wc_callbacks->get_wc_contents)
+  if (!session->wc_callbacks->get_wc_contents
+      || sha1_checksum_prop == NULL)
     {
-      /* No callback, nothing to do. */
-      return SVN_NO_ERROR;
-    }
-
-
-  svn_props = svn_hash_gets(props, SVN_DAV_PROP_NS_DAV);
-  if (!svn_props)
-    {
-      /* No properties -- therefore no checksum property -- in response. */
-      return SVN_NO_ERROR;
-    }
-
-  sha1_checksum_prop = svn_prop_get_value(svn_props, "sha1-checksum");
-  if (sha1_checksum_prop == NULL)
-    {
-      /* No checksum property in response. */
+      /* Nothing to do. */
       return SVN_NO_ERROR;
     }
 
@@ -280,6 +264,55 @@ handle_stream(serf_request_t *request,
   /* not reached */
 }
 
+/* Baton for get_file_prop_cb */
+struct file_prop_baton_t
+{
+  apr_pool_t *result_pool;
+  svn_node_kind_t kind;
+  apr_hash_t *props;
+  const char *sha1_checksum;
+};
+
+/* Implements svn_ra_serf__prop_func_t for svn_ra_serf__get_file */
+static svn_error_t *
+get_file_prop_cb(void *baton,
+                 const char *path,
+                 const char *ns,
+                 const char *name,
+                 const svn_string_t *value,
+                 apr_pool_t *scratch_pool)
+{
+  struct file_prop_baton_t *fb = baton;
+  const char *svn_name;
+
+  if (strcmp(ns, "DAV:") == 0 && strcmp(name, "resourcetype") == 0)
+    {
+      const char *val = value->data;
+
+      if (strcmp(val, "collection") == 0)
+        fb->kind = svn_node_dir;
+      else
+        fb->kind = svn_node_file;
+
+      return SVN_NO_ERROR;
+    }
+  else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0
+           && strcmp(name, "sha1-checksum") == 0)
+    {
+      fb->sha1_checksum = apr_pstrdup(fb->result_pool, value->data);
+    }
+
+  if (!fb->props)
+    return SVN_NO_ERROR;
+
+  svn_name = svn_ra_serf__svnname_from_wirename(ns, name, fb->result_pool);
+  if (svn_name)
+    {
+      svn_hash_sets(fb->props, svn_name,
+                    svn_string_dup(value, fb->result_pool));
+    }
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_ra_serf__get_file(svn_ra_session_t *ra_session,
@@ -292,9 +325,9 @@ svn_ra_serf__get_file(svn_ra_session_t *
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   const char *fetch_url;
-  apr_hash_t *fetch_props;
-  svn_node_kind_t res_kind;
   const svn_ra_serf__dav_props_t *which_props;
+  svn_ra_serf__handler_t *handler;
+  struct file_prop_baton_t fb;
 
   /* Fetch properties. */
 
@@ -317,44 +350,42 @@ svn_ra_serf__get_file(svn_ra_session_t *
   SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
 
   if (props)
-    {
       which_props = all_props;
-    }
   else if (stream && session->wc_callbacks->get_wc_contents)
-    {
       which_props = type_and_checksum_props;
-    }
   else
-    {
       which_props = check_path_props;
-    }
 
-  SVN_ERR(svn_ra_serf__fetch_node_props(&fetch_props, session, fetch_url,
-                                        SVN_INVALID_REVNUM,
-                                        which_props,
-                                        pool, pool));
+  fb.result_pool = pool;
+  fb.props = props ? apr_hash_make(pool) : NULL;
+  fb.kind = svn_node_unknown;
+  fb.sha1_checksum = NULL;
+
+  SVN_ERR(svn_ra_serf__create_propfind_handler(&handler, session, fetch_url,
+                                               SVN_INVALID_REVNUM, "0",
+                                               which_props,
+                                               get_file_prop_cb, &fb,
+                                               pool));
+
+  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
+
+  if (handler->sline.code != 207)
+    return svn_error_trace(svn_ra_serf__unexpected_status(handler));
 
   /* Verify that resource type is not collection. */
-  SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, fetch_props));
-  if (res_kind != svn_node_file)
+  if (fb.kind != svn_node_file)
     {
       return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
                               _("Can't get text contents of a directory"));
     }
 
-  /* TODO Filter out all of our props into a usable format. */
   if (props)
-    {
-      /* ### flatten_props() does not copy PROPVALUE, but fetch_node_props()
-         ### put them into POOL, so we're okay.  */
-      SVN_ERR(svn_ra_serf__flatten_props(props, fetch_props,
-                                         pool, pool));
-    }
+    *props = fb.props;
 
   if (stream)
     {
       svn_boolean_t found;
-      SVN_ERR(try_get_wc_contents(&found, session, fetch_props, stream, pool));
+      SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream, pool));
 
       /* No contents found in the WC, let's fetch from server. */
       if (!found)

Modified: subversion/trunk/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/property.c?rev=1654681&r1=1654680&r2=1654681&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/property.c Sun Jan 25 18:20:02 2015
@@ -73,7 +73,7 @@ typedef struct propfind_context_t {
   /* the list of requested properties */
   const svn_ra_serf__dav_props_t *find_props;
 
-  svn_ra_serf__prop_func prop_func;
+  svn_ra_serf__prop_func_t prop_func;
   void *prop_func_baton;
 
   /* hash table containing all the properties associated with the
@@ -452,7 +452,7 @@ svn_ra_serf__create_propfind_handler(svn
                                      svn_revnum_t rev,
                                      const char *depth,
                                      const svn_ra_serf__dav_props_t *find_props,
-                                     svn_ra_serf__prop_func prop_func,
+                                     svn_ra_serf__prop_func_t prop_func,
                                      void *prop_func_baton,
                                      apr_pool_t *pool)
 {
@@ -668,44 +668,6 @@ svn_ra_serf__svnname_from_wirename(const
   return apr_pstrcat(result_pool, ns, name, SVN_VA_NULL);
 }
 
-
-/* Conforms to svn_ra_serf__walker_visitor_t  */
-static svn_error_t *
-set_flat_props(void *baton,
-               const char *ns,
-               const char *name,
-               const svn_string_t *value,
-               apr_pool_t *pool)
-{
-  apr_hash_t *props = baton;
-  apr_pool_t *result_pool = apr_hash_pool_get(props);
-  const char *prop_name;
-
-  /* ### is VAL in the proper pool?  */
-
-  prop_name = svn_ra_serf__svnname_from_wirename(ns, name, result_pool);
-  if (prop_name != NULL)
-    svn_hash_sets(props, prop_name, value);
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_ra_serf__flatten_props(apr_hash_t **flat_props,
-                           apr_hash_t *props,
-                           apr_pool_t *result_pool,
-                           apr_pool_t *scratch_pool)
-{
-  *flat_props = apr_hash_make(result_pool);
-
-  return svn_error_trace(svn_ra_serf__walk_node_props(
-                            props,
-                            set_flat_props,
-                            *flat_props /* baton */,
-                            scratch_pool));
-}
-
 /*
  * Contact the server (using CONN) to calculate baseline
  * information for BASELINE_URL at REVISION (which may be
@@ -945,36 +907,6 @@ svn_ra_serf__get_stable_url(const char *
 
   return SVN_NO_ERROR;
 }
-
-
-svn_error_t *
-svn_ra_serf__get_resource_type(svn_node_kind_t *kind,
-                               apr_hash_t *props)
-{
-  apr_hash_t *dav_props;
-  const char *res_type;
-
-  dav_props = apr_hash_get(props, "DAV:", 4);
-  res_type = svn_prop_get_value(dav_props, "resourcetype");
-  if (!res_type)
-    {
-      /* How did this happen? */
-      return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
-                              _("The PROPFIND response did not include the "
-                                "requested resourcetype value"));
-    }
-
-  if (strcmp(res_type, "collection") == 0)
-    {
-      *kind = svn_node_dir;
-    }
-  else
-    {
-      *kind = svn_node_file;
-    }
-
-  return SVN_NO_ERROR;
-}
 
 
 svn_error_t *

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=1654681&r1=1654680&r2=1654681&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Sun Jan 25 18:20:02 2015
@@ -927,15 +927,15 @@ svn_ra_serf__keep_only_regular_props(apr
 
 /* Callback used via svn_ra_serf__deliver_props2 */
 typedef svn_error_t *
-(*svn_ra_serf__prop_func)(void *baton,
-                          const char *path,
-                          const char *ns,
-                          const char *name,
-                          const svn_string_t *value,
-                          apr_pool_t *scratch_pool);
+(*svn_ra_serf__prop_func_t)(void *baton,
+                            const char *path,
+                            const char *ns,
+                            const char *name,
+                            const svn_string_t *value,
+                            apr_pool_t *scratch_pool);
 
 /*
- * Implementation of svn_ra_serf__prop_func that just delivers svn compatible
+ * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible
  * properties  in the apr_hash_t * that is used as baton.
  */
 svn_error_t *
@@ -947,7 +947,7 @@ svn_ra_serf__deliver_svn_props(void *bat
                                apr_pool_t *scratch_pool);
 
 /*
- * Implementation of svn_ra_serf__prop_func that delivers all DAV properties
+ * Implementation of svn_ra_serf__prop_func_t that delivers all DAV properties
  * in (const char * -> apr_hash_t *) on Namespace pointing to a second hash
  *    (const char * -> svn_string_t *) to the values.
  */
@@ -972,7 +972,7 @@ svn_ra_serf__create_propfind_handler(svn
                                      svn_revnum_t rev,
                                      const char *depth,
                                      const svn_ra_serf__dav_props_t *find_props,
-                                     svn_ra_serf__prop_func prop_func,
+                                     svn_ra_serf__prop_func_t prop_func,
                                      void *prop_func_baton,
                                      apr_pool_t *result_pool);
 
@@ -1048,30 +1048,6 @@ svn_ra_serf__svnname_from_wirename(const
                                    const char *name,
                                    apr_pool_t *result_pool);
 
-
-/* PROPS is nested hash tables mapping NS -> NAME -> VALUE.
-   This function takes the NS:NAME:VALUE hashes and flattens them into a set of
-   names to VALUE. The names are composed of NS:NAME, with specific
-   rewrite from wire names (DAV) to SVN names. This mapping is managed
-   by the svn_ra_serf__set_baton_props() function.
-
-   FLAT_PROPS is allocated in RESULT_POOL.
-   ### right now, we do a shallow copy from PROPS to FLAT_PROPS. therefore,
-   ### the names and values in PROPS must be in the proper pool.
-
-   Temporary allocations are made in SCRATCH_POOL.  */
-svn_error_t *
-svn_ra_serf__flatten_props(apr_hash_t **flat_props,
-                           apr_hash_t *props,
-                           apr_pool_t *result_pool,
-                           apr_pool_t *scratch_pool);
-
-
-svn_error_t *
-svn_ra_serf__get_resource_type(svn_node_kind_t *kind,
-                               apr_hash_t *props);
-
-
 /** MERGE-related functions **/
 
 /* Create an MERGE request aimed at the SESSION url, requesting the
@@ -1140,9 +1116,7 @@ svn_ra_serf__discover_vcc(const char **v
                           apr_pool_t *scratch_pool);
 
 /* Set @a REPORT_TARGET to the URI of the resource at which generic
- * (path-agnostic) REPORTs should be aimed for @a SESSION.  Use @a
- * CONN for any required network communications if it is non-NULL;
- * otherwise use the default connection.
+ * (path-agnostic) REPORTs should be aimed for @a SESSION.
  *
  * All temporary allocations will be made in @a POOL.
  */

Modified: subversion/trunk/subversion/libsvn_ra_serf/stat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/stat.c?rev=1654681&r1=1654680&r2=1654681&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/stat.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/stat.c Sun Jan 25 18:20:02 2015
@@ -85,6 +85,35 @@ fetch_path_props(apr_hash_t **props,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+get_resource_type(svn_node_kind_t *kind,
+                  apr_hash_t *props)
+{
+  apr_hash_t *dav_props;
+  const char *res_type;
+
+  dav_props = apr_hash_get(props, "DAV:", 4);
+  res_type = svn_prop_get_value(dav_props, "resourcetype");
+  if (!res_type)
+    {
+      /* How did this happen? */
+      return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+                              _("The PROPFIND response did not include the "
+                                "requested resourcetype value"));
+    }
+
+  if (strcmp(res_type, "collection") == 0)
+    {
+      *kind = svn_node_dir;
+    }
+  else
+    {
+      *kind = svn_node_file;
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Implements svn_ra__vtable_t.check_path(). */
 svn_error_t *
 svn_ra_serf__check_path(svn_ra_session_t *ra_session,
@@ -111,7 +140,7 @@ svn_ra_serf__check_path(svn_ra_session_t
       if (err)
         return svn_error_trace(err);
 
-      SVN_ERR(svn_ra_serf__get_resource_type(kind, props));
+      SVN_ERR(get_resource_type(kind, props));
     }
 
   return SVN_NO_ERROR;