You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/01/15 18:47:24 UTC

svn commit: r1558485 [2/4] - in /subversion/branches/fsfs-ucsnorm: ./ subversion/bindings/javahl/native/ subversion/bindings/javahl/native/jniwrapper/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/tests/org/apa...

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c?rev=1558485&r1=1558484&r2=1558485&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c Wed Jan 15 17:47:23 2014
@@ -857,7 +857,8 @@ serf__rev_proplist(svn_ra_session_t *ra_
                    svn_revnum_t rev,
                    const svn_ra_serf__dav_props_t *fetch_props,
                    apr_hash_t **ret_props,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_t *props;
@@ -865,7 +866,8 @@ serf__rev_proplist(svn_ra_session_t *ra_
 
   if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
     {
-      propfind_path = apr_psprintf(pool, "%s/%ld", session->rev_stub, rev);
+      propfind_path = apr_psprintf(scratch_pool, "%s/%ld", session->rev_stub,
+                                   rev);
 
       /* svn_ra_serf__retrieve_props() wants to added the revision as
          a Label to the PROPFIND, which isn't really necessary when
@@ -876,16 +878,17 @@ serf__rev_proplist(svn_ra_session_t *ra_
   else
     {
       /* Use the VCC as the propfind target path. */
-      SVN_ERR(svn_ra_serf__discover_vcc(&propfind_path, session, NULL, pool));
+      SVN_ERR(svn_ra_serf__discover_vcc(&propfind_path, session, NULL,
+                                        scratch_pool));
     }
 
   /* ### fix: fetch hash of *just* the PATH@REV props. no nested hash.  */
   SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
                                       propfind_path, rev, "0", fetch_props,
-                                      pool, pool));
+                                      result_pool, scratch_pool));
 
   SVN_ERR(svn_ra_serf__select_revprops(ret_props, propfind_path, rev, props,
-                                       pool, pool));
+                                       result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -895,11 +898,16 @@ static svn_error_t *
 svn_ra_serf__rev_proplist(svn_ra_session_t *ra_session,
                           svn_revnum_t rev,
                           apr_hash_t **ret_props,
-                          apr_pool_t *pool)
+                          apr_pool_t *result_pool)
 {
-  return svn_error_trace(
-            serf__rev_proplist(ra_session, rev, all_props,
-                               ret_props, pool));
+  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
+  svn_error_t *err;
+
+  err = serf__rev_proplist(ra_session, rev, all_props, ret_props,
+                           result_pool, scratch_pool);
+
+  svn_pool_destroy(scratch_pool);
+  return svn_error_trace(err);
 }
 
 
@@ -909,8 +917,9 @@ svn_ra_serf__rev_prop(svn_ra_session_t *
                       svn_revnum_t rev,
                       const char *name,
                       svn_string_t **value,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool)
 {
+  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
   apr_hash_t *props;
   svn_ra_serf__dav_props_t specific_props[2];
   const svn_ra_serf__dav_props_t *fetch_props = all_props;
@@ -930,483 +939,12 @@ svn_ra_serf__rev_prop(svn_ra_session_t *
       fetch_props = specific_props;
     }
 
-  SVN_ERR(serf__rev_proplist(session, rev, fetch_props, &props, pool));
+  SVN_ERR(serf__rev_proplist(session, rev, fetch_props, &props,
+                             result_pool, scratch_pool));
 
   *value = svn_hash_gets(props, name);
 
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-fetch_path_props(apr_hash_t **props,
-                 svn_ra_serf__session_t *session,
-                 const char *session_relpath,
-                 svn_revnum_t revision,
-                 const svn_ra_serf__dav_props_t *desired_props,
-                 apr_pool_t *result_pool,
-                 apr_pool_t *scratch_pool)
-{
-  const char *url;
-
-  url = session->session_url.path;
-
-  /* If we have a relative path, append it. */
-  if (session_relpath)
-    url = svn_path_url_add_component2(url, session_relpath, scratch_pool);
-
-  /* If we were given a specific revision, get a URL that refers to that
-     specific revision (rather than floating with HEAD).  */
-  if (SVN_IS_VALID_REVNUM(revision))
-    {
-      SVN_ERR(svn_ra_serf__get_stable_url(&url, NULL /* latest_revnum */,
-                                          session, NULL /* conn */,
-                                          url, revision,
-                                          scratch_pool, scratch_pool));
-    }
-
-  /* URL is stable, so we use SVN_INVALID_REVNUM since it is now irrelevant.
-     Or we started with SVN_INVALID_REVNUM and URL may be floating.  */
-  SVN_ERR(svn_ra_serf__fetch_node_props(props, session->conns[0],
-                                        url, SVN_INVALID_REVNUM,
-                                        desired_props,
-                                        result_pool, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra__vtable_t.check_path(). */
-static svn_error_t *
-svn_ra_serf__check_path(svn_ra_session_t *ra_session,
-                        const char *rel_path,
-                        svn_revnum_t revision,
-                        svn_node_kind_t *kind,
-                        apr_pool_t *pool)
-{
-  svn_ra_serf__session_t *session = ra_session->priv;
-  apr_hash_t *props;
-
-  svn_error_t *err = fetch_path_props(&props, session, rel_path,
-                                      revision, check_path_props,
-                                      pool, pool);
-
-  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
-    {
-      svn_error_clear(err);
-      *kind = svn_node_none;
-    }
-  else
-    {
-      /* Any other error, raise to caller. */
-      if (err)
-        return svn_error_trace(err);
-
-      SVN_ERR(svn_ra_serf__get_resource_type(kind, props));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-struct dirent_walker_baton_t {
-  /* Update the fields in this entry.  */
-  svn_dirent_t *entry;
-
-  svn_tristate_t *supports_deadprop_count;
-
-  /* If allocations are necessary, then use this pool.  */
-  apr_pool_t *result_pool;
-};
-
-static svn_error_t *
-dirent_walker(void *baton,
-              const char *ns,
-              const char *name,
-              const svn_string_t *val,
-              apr_pool_t *scratch_pool)
-{
-  struct dirent_walker_baton_t *dwb = baton;
-
-  if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
-    {
-      dwb->entry->has_props = TRUE;
-    }
-  else if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
-    {
-      dwb->entry->has_props = TRUE;
-    }
-  else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0)
-    {
-      if(strcmp(name, "deadprop-count") == 0)
-        {
-          if (*val->data)
-            {
-              apr_int64_t deadprop_count;
-              SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
-              dwb->entry->has_props = deadprop_count > 0;
-              if (dwb->supports_deadprop_count)
-                *dwb->supports_deadprop_count = svn_tristate_true;
-            }
-          else if (dwb->supports_deadprop_count)
-            *dwb->supports_deadprop_count = svn_tristate_false;
-        }
-    }
-  else if (strcmp(ns, "DAV:") == 0)
-    {
-      if (strcmp(name, SVN_DAV__VERSION_NAME) == 0)
-        {
-          dwb->entry->created_rev = SVN_STR_TO_REV(val->data);
-        }
-      else if (strcmp(name, "creator-displayname") == 0)
-        {
-          dwb->entry->last_author = val->data;
-        }
-      else if (strcmp(name, SVN_DAV__CREATIONDATE) == 0)
-        {
-          SVN_ERR(svn_time_from_cstring(&dwb->entry->time,
-                                        val->data,
-                                        dwb->result_pool));
-        }
-      else if (strcmp(name, "getcontentlength") == 0)
-        {
-          /* 'getcontentlength' property is empty for directories. */
-          if (val->len)
-            {
-              SVN_ERR(svn_cstring_atoi64(&dwb->entry->size, val->data));
-            }
-        }
-      else if (strcmp(name, "resourcetype") == 0)
-        {
-          if (strcmp(val->data, "collection") == 0)
-            {
-              dwb->entry->kind = svn_node_dir;
-            }
-          else
-            {
-              dwb->entry->kind = svn_node_file;
-            }
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-struct path_dirent_visitor_t {
-  apr_hash_t *full_paths;
-  apr_hash_t *base_paths;
-  const char *orig_path;
-  svn_tristate_t supports_deadprop_count;
-  apr_pool_t *result_pool;
-};
-
-static svn_error_t *
-path_dirent_walker(void *baton,
-                   const char *path, apr_ssize_t path_len,
-                   const char *ns, apr_ssize_t ns_len,
-                   const char *name, apr_ssize_t name_len,
-                   const svn_string_t *val,
-                   apr_pool_t *pool)
-{
-  struct path_dirent_visitor_t *dirents = baton;
-  struct dirent_walker_baton_t dwb;
-  svn_dirent_t *entry;
-
-  /* Skip our original path. */
-  if (strcmp(path, dirents->orig_path) == 0)
-    {
-      return SVN_NO_ERROR;
-    }
-
-  entry = apr_hash_get(dirents->full_paths, path, path_len);
-
-  if (!entry)
-    {
-      const char *base_name;
-
-      entry = svn_dirent_create(pool);
-
-      apr_hash_set(dirents->full_paths, path, path_len, entry);
-
-      base_name = svn_path_uri_decode(svn_urlpath__basename(path, pool),
-                                      pool);
-
-      svn_hash_sets(dirents->base_paths, base_name, entry);
-    }
-
-  dwb.entry = entry;
-  dwb.supports_deadprop_count = &dirents->supports_deadprop_count;
-  dwb.result_pool = dirents->result_pool;
-  return svn_error_trace(dirent_walker(&dwb, ns, name, val, pool));
-}
-
-static const svn_ra_serf__dav_props_t *
-get_dirent_props(apr_uint32_t dirent_fields,
-                 svn_ra_serf__session_t *session,
-                 apr_pool_t *pool)
-{
-  svn_ra_serf__dav_props_t *prop;
-  apr_array_header_t *props = apr_array_make
-    (pool, 7, sizeof(svn_ra_serf__dav_props_t));
-
-  if (session->supports_deadprop_count != svn_tristate_false
-      || ! (dirent_fields & SVN_DIRENT_HAS_PROPS))
-    {
-      if (dirent_fields & SVN_DIRENT_KIND)
-        {
-          prop = apr_array_push(props);
-          prop->xmlns = "DAV:";
-          prop->name = "resourcetype";
-        }
-
-      if (dirent_fields & SVN_DIRENT_SIZE)
-        {
-          prop = apr_array_push(props);
-          prop->xmlns = "DAV:";
-          prop->name = "getcontentlength";
-        }
-
-      if (dirent_fields & SVN_DIRENT_HAS_PROPS)
-        {
-          prop = apr_array_push(props);
-          prop->xmlns = SVN_DAV_PROP_NS_DAV;
-          prop->name = "deadprop-count";
-        }
-
-      if (dirent_fields & SVN_DIRENT_CREATED_REV)
-        {
-          svn_ra_serf__dav_props_t *p = apr_array_push(props);
-          p->xmlns = "DAV:";
-          p->name = SVN_DAV__VERSION_NAME;
-        }
-
-      if (dirent_fields & SVN_DIRENT_TIME)
-        {
-          prop = apr_array_push(props);
-          prop->xmlns = "DAV:";
-          prop->name = SVN_DAV__CREATIONDATE;
-        }
-
-      if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
-        {
-          prop = apr_array_push(props);
-          prop->xmlns = "DAV:";
-          prop->name = "creator-displayname";
-        }
-    }
-  else
-    {
-      /* We found an old subversion server that can't handle
-         the deadprop-count property in the way we expect.
-
-         The neon behavior is to retrieve all properties in this case */
-      prop = apr_array_push(props);
-      prop->xmlns = "DAV:";
-      prop->name = "allprop";
-    }
-
-  prop = apr_array_push(props);
-  prop->xmlns = NULL;
-  prop->name = NULL;
-
-  return (svn_ra_serf__dav_props_t *) props->elts;
-}
-
-/* Implements svn_ra__vtable_t.stat(). */
-static svn_error_t *
-svn_ra_serf__stat(svn_ra_session_t *ra_session,
-                  const char *rel_path,
-                  svn_revnum_t revision,
-                  svn_dirent_t **dirent,
-                  apr_pool_t *pool)
-{
-  svn_ra_serf__session_t *session = ra_session->priv;
-  apr_hash_t *props;
-  svn_error_t *err;
-  struct dirent_walker_baton_t dwb;
-  svn_tristate_t deadprop_count = svn_tristate_unknown;
-
-  err = fetch_path_props(&props,
-                         session, rel_path, revision,
-                         get_dirent_props(SVN_DIRENT_ALL, session, pool),
-                         pool, pool);
-  if (err)
-    {
-      if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
-        {
-          svn_error_clear(err);
-          *dirent = NULL;
-          return SVN_NO_ERROR;
-        }
-      else
-        return svn_error_trace(err);
-    }
-
-  dwb.entry = svn_dirent_create(pool);
-  dwb.supports_deadprop_count = &deadprop_count;
-  dwb.result_pool = pool;
-  SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
-
-  if (deadprop_count == svn_tristate_false
-      && session->supports_deadprop_count == svn_tristate_unknown
-      && !dwb.entry->has_props)
-    {
-      /* We have to requery as the server didn't give us the right
-         information */
-      session->supports_deadprop_count = svn_tristate_false;
-
-      SVN_ERR(fetch_path_props(&props,
-                               session, rel_path, SVN_INVALID_REVNUM,
-                               get_dirent_props(SVN_DIRENT_ALL, session, pool),
-                               pool, pool));
-
-      SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
-    }
-
-  if (deadprop_count != svn_tristate_unknown)
-    session->supports_deadprop_count = deadprop_count;
-
-  *dirent = dwb.entry;
-
-  return SVN_NO_ERROR;
-}
-
-/* Reads the 'resourcetype' property from the list PROPS and checks if the
- * resource at PATH@REVISION really is a directory. Returns
- * SVN_ERR_FS_NOT_DIRECTORY if not.
- */
-static svn_error_t *
-resource_is_directory(apr_hash_t *props)
-{
-  svn_node_kind_t kind;
-
-  SVN_ERR(svn_ra_serf__get_resource_type(&kind, props));
-
-  if (kind != svn_node_dir)
-    {
-      return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
-                              _("Can't get entries of non-directory"));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra__vtable_t.get_dir(). */
-static svn_error_t *
-svn_ra_serf__get_dir(svn_ra_session_t *ra_session,
-                     apr_hash_t **dirents,
-                     svn_revnum_t *fetched_rev,
-                     apr_hash_t **ret_props,
-                     const char *rel_path,
-                     svn_revnum_t revision,
-                     apr_uint32_t dirent_fields,
-                     apr_pool_t *pool)
-{
-  svn_ra_serf__session_t *session = ra_session->priv;
-  const char *path;
-
-  path = session->session_url.path;
-
-  /* If we have a relative path, URI encode and append it. */
-  if (rel_path)
-    {
-      path = svn_path_url_add_component2(path, rel_path, pool);
-    }
-
-  /* If the user specified a peg revision other than HEAD, we have to fetch
-     the baseline collection url for that revision. If not, we can use the
-     public url. */
-  if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
-    {
-      SVN_ERR(svn_ra_serf__get_stable_url(&path, fetched_rev,
-                                          session, NULL /* conn */,
-                                          path, revision,
-                                          pool, pool));
-      revision = SVN_INVALID_REVNUM;
-    }
-  /* REVISION is always SVN_INVALID_REVNUM  */
-  SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
-
-  /* If we're asked for children, fetch them now. */
-  if (dirents)
-    {
-      struct path_dirent_visitor_t dirent_walk;
-      apr_hash_t *props;
-      const char *rtype;
-
-      /* Always request node kind to check that path is really a
-       * directory.
-       */
-      dirent_fields |= SVN_DIRENT_KIND;
-      SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
-                                          path, SVN_INVALID_REVNUM, "1",
-                                          get_dirent_props(dirent_fields,
-                                                           session, pool),
-                                          pool, pool));
-
-      /* Check if the path is really a directory. */
-      rtype = svn_ra_serf__get_prop(props, path, "DAV:", "resourcetype");
-      if (rtype == NULL || strcmp(rtype, "collection") != 0)
-        return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
-                                _("Can't get entries of non-directory"));
-
-      /* We're going to create two hashes to help the walker along.
-       * We're going to return the 2nd one back to the caller as it
-       * will have the basenames it expects.
-       */
-      dirent_walk.full_paths = apr_hash_make(pool);
-      dirent_walk.base_paths = apr_hash_make(pool);
-      dirent_walk.orig_path = svn_urlpath__canonicalize(path, pool);
-      dirent_walk.supports_deadprop_count = svn_tristate_unknown;
-      dirent_walk.result_pool = pool;
-
-      SVN_ERR(svn_ra_serf__walk_all_paths(props, SVN_INVALID_REVNUM,
-                                          path_dirent_walker, &dirent_walk,
-                                          pool));
-
-      if (dirent_walk.supports_deadprop_count == svn_tristate_false
-          && session->supports_deadprop_count == svn_tristate_unknown
-          && dirent_fields & SVN_DIRENT_HAS_PROPS)
-        {
-          /* We have to requery as the server didn't give us the right
-             information */
-          session->supports_deadprop_count = svn_tristate_false;
-          SVN_ERR(svn_ra_serf__retrieve_props(&props, session,
-                                              session->conns[0],
-                                              path, SVN_INVALID_REVNUM, "1",
-                                              get_dirent_props(dirent_fields,
-                                                               session, pool),
-                                              pool, pool));
-
-          apr_hash_clear(dirent_walk.full_paths);
-          apr_hash_clear(dirent_walk.base_paths);
-
-          SVN_ERR(svn_ra_serf__walk_all_paths(props, SVN_INVALID_REVNUM,
-                                              path_dirent_walker,
-                                              &dirent_walk, pool));
-        }
-
-      *dirents = dirent_walk.base_paths;
-
-      if (dirent_walk.supports_deadprop_count != svn_tristate_unknown)
-        session->supports_deadprop_count = dirent_walk.supports_deadprop_count;
-    }
-
-  /* If we're asked for the directory properties, fetch them too. */
-  if (ret_props)
-    {
-      apr_hash_t *props;
-
-      SVN_ERR(svn_ra_serf__fetch_node_props(&props, session->conns[0],
-                                            path, SVN_INVALID_REVNUM,
-                                            all_props,
-                                            pool, pool));
-
-      /* Check if the path is really a directory. */
-      SVN_ERR(resource_is_directory(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(ret_props, props, pool, pool));
-    }
+  svn_pool_destroy(scratch_pool);
 
   return SVN_NO_ERROR;
 }