You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by vm...@apache.org on 2012/05/29 03:39:49 UTC

svn commit: r1343447 [14/27] - in /subversion/branches/javahl-ra: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/merge-tracking/ sub...

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c Tue May 29 01:39:41 2012
@@ -282,11 +282,11 @@ dump_node(struct edit_baton *eb,
                             SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n",
                             path));
   if (kind == svn_node_file)
-    SVN_ERR(svn_stream_printf(eb->stream, pool,
-                              SVN_REPOS_DUMPFILE_NODE_KIND ": file\n"));
+    SVN_ERR(svn_stream_puts(eb->stream,
+                            SVN_REPOS_DUMPFILE_NODE_KIND ": file\n"));
   else if (kind == svn_node_dir)
-    SVN_ERR(svn_stream_printf(eb->stream, pool,
-                              SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
+    SVN_ERR(svn_stream_puts(eb->stream,
+                            SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
 
   /* Remove leading slashes from copyfrom paths. */
   if (cmp_path)
@@ -301,9 +301,8 @@ dump_node(struct edit_baton *eb,
 
   if (action == svn_node_action_change)
     {
-      SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                SVN_REPOS_DUMPFILE_NODE_ACTION
-                                ": change\n"));
+      SVN_ERR(svn_stream_puts(eb->stream,
+                              SVN_REPOS_DUMPFILE_NODE_ACTION ": change\n"));
 
       /* either the text or props changed, or possibly both. */
       SVN_ERR(svn_fs_revision_root(&compare_root,
@@ -323,9 +322,9 @@ dump_node(struct edit_baton *eb,
       if (! is_copy)
         {
           /* a simple delete+add, implied by a single 'replace' action. */
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_NODE_ACTION
-                                    ": replace\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_NODE_ACTION
+                                  ": replace\n"));
 
           /* definitely need to dump all content for a replace. */
           if (kind == svn_node_file)
@@ -338,9 +337,9 @@ dump_node(struct edit_baton *eb,
 
           /* the path & kind headers have already been printed;  just
              add a delete action, and end the current record.*/
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_NODE_ACTION
-                                    ": delete\n\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_NODE_ACTION
+                                  ": delete\n\n"));
 
           /* recurse:  print an additional add-with-history record. */
           SVN_ERR(dump_node(eb, path, kind, svn_node_action_add,
@@ -354,9 +353,8 @@ dump_node(struct edit_baton *eb,
     }
   else if (action == svn_node_action_delete)
     {
-      SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                SVN_REPOS_DUMPFILE_NODE_ACTION
-                                ": delete\n"));
+      SVN_ERR(svn_stream_puts(eb->stream,
+                              SVN_REPOS_DUMPFILE_NODE_ACTION ": delete\n"));
 
       /* we can leave this routine quietly now, don't need to dump
          any content. */
@@ -365,8 +363,8 @@ dump_node(struct edit_baton *eb,
     }
   else if (action == svn_node_action_add)
     {
-      SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));
+      SVN_ERR(svn_stream_puts(eb->stream,
+                              SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));
 
       if (! is_copy)
         {
@@ -511,9 +509,8 @@ dump_node(struct edit_baton *eb,
              saying that our property contents are a delta. */
           SVN_ERR(svn_fs_node_proplist(&oldhash, compare_root, compare_path,
                                        pool));
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_PROP_DELTA
-                                    ": true\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_PROP_DELTA ": true\n"));
         }
       else
         oldhash = apr_hash_make(pool);
@@ -544,9 +541,8 @@ dump_node(struct edit_baton *eb,
              saying our text contents are a delta. */
           SVN_ERR(store_delta(&delta_file, &textlen, compare_root,
                               compare_path, eb->fs_root, path, pool));
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_TEXT_DELTA
-                                    ": true\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_TEXT_DELTA ": true\n"));
 
           if (compare_root)
             {
@@ -745,10 +741,7 @@ close_directory(void *dir_baton,
        hi;
        hi = apr_hash_next(hi))
     {
-      const void *key;
-      const char *path;
-      apr_hash_this(hi, &key, NULL, NULL);
-      path = key;
+      const char *path = svn__apr_hash_index_key(hi);
 
       svn_pool_clear(subpool);
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/hooks.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/hooks.c Tue May 29 01:39:41 2012
@@ -30,6 +30,7 @@
 #include "svn_error.h"
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
+#include "svn_pools.h"
 #include "svn_repos.h"
 #include "svn_utf.h"
 #include "repos.h"
@@ -212,7 +213,8 @@ run_hook_cmd(svn_string_t **result,
   apr_file_t *null_handle;
   apr_status_t apr_err;
   svn_error_t *err;
-  apr_proc_t cmd_proc;
+  apr_proc_t cmd_proc = {0};
+  apr_pool_t *cmd_pool;
 
   if (result)
     {
@@ -228,42 +230,39 @@ run_hook_cmd(svn_string_t **result,
             (apr_err, _("Can't create null stdout for hook '%s'"), cmd);
     }
 
+  /* Tie resources allocated for the command to a special pool which we can
+   * destroy in order to clean up the stderr pipe opened for the process. */
+  cmd_pool = svn_pool_create(pool);
+
   err = svn_io_start_cmd3(&cmd_proc, ".", cmd, args,
                           env_from_env_hash(hooks_env, pool, pool),
                           FALSE, FALSE, stdin_handle, result != NULL,
-                          null_handle, TRUE, NULL, pool);
-
-  if (err)
-    {
-      /* CMD_PROC is not safe to use. Bail. */
-      return svn_error_createf
-        (SVN_ERR_REPOS_HOOK_FAILURE, err, _("Failed to start '%s' hook"), cmd);
-    }
+                          null_handle, TRUE, NULL, cmd_pool);
+  if (!err)
+    err = check_hook_result(name, cmd, &cmd_proc, cmd_proc.err, pool);
   else
     {
-      err = check_hook_result(name, cmd, &cmd_proc, cmd_proc.err, pool);
+      /* The command could not be started for some reason. */
+      err = svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, err,
+                              _("Failed to start '%s' hook"), cmd);
     }
 
   /* Hooks are fallible, and so hook failure is "expected" to occur at
      times.  When such a failure happens we still want to close the pipe
      and null file */
-  apr_err = apr_file_close(cmd_proc.err);
-  if (!err && apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Error closing read end of stderr pipe"));
-
-  if (result)
+  if (!err && result)
     {
       svn_stringbuf_t *native_stdout;
-      SVN_ERR(svn_stringbuf_from_aprfile(&native_stdout, cmd_proc.out, pool));
-      apr_err = apr_file_close(cmd_proc.out);
-      if (!err && apr_err)
-        return svn_error_wrap_apr
-          (apr_err, _("Error closing read end of stderr pipe"));
-
-      *result = svn_stringbuf__morph_into_string(native_stdout);
+      err = svn_stringbuf_from_aprfile(&native_stdout, cmd_proc.out, pool);
+      if (!err)
+        *result = svn_stringbuf__morph_into_string(native_stdout);
     }
-  else
+
+  /* Close resources allocated by svn_io_start_cmd3(), such as the pipe. */
+  svn_pool_destroy(cmd_pool);
+
+  /* Close the null handle. */
+  if (null_handle)
     {
       apr_err = apr_file_close(null_handle);
       if (!err && apr_err)

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c Tue May 29 01:39:41 2012
@@ -35,6 +35,7 @@
 #include "svn_path.h"
 #include "svn_private_config.h"
 #include "private/svn_fspath.h"
+#include "private/svn_repos_private.h"
 
 
 /*** Backstory ***/
@@ -415,7 +416,12 @@ was_readable(svn_boolean_t *readable,
    revision root, fspath, and revnum of the copyfrom of CHANGE, which
    corresponds to PATH under ROOT.  If the copyfrom info is valid
    (i.e., is not (NULL, SVN_INVALID_REVNUM)), then initialize SRC_READABLE
-   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided. */
+   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided.
+
+   NOTE: If the copyfrom information in CHANGE is marked as unknown
+   (meaning, its ->copyfrom_rev and ->copyfrom_path cannot be
+   trusted), this function will also update those members of the
+   CHANGE structure to carry accurate copyfrom information.  */
 static svn_error_t *
 fill_copyfrom(svn_fs_root_t **copyfrom_root,
               const char **copyfrom_path,
@@ -698,10 +704,18 @@ path_driver_cb_func(void **dir_baton,
         }
     }
 
-  /* Handle property modifications. */
   if (! do_delete || do_add)
     {
-      if (change->prop_mod)
+      /* Is this a copy that was downgraded to a raw add?  (If so,
+         we'll need to transmit properties and file contents and such
+         for it regardless of what the CHANGE structure's text_mod
+         and prop_mod flags say.)  */
+      svn_boolean_t downgraded_copy = (change->copyfrom_known
+                                       && change->copyfrom_path
+                                       && (! copyfrom_path));
+
+      /* Handle property modifications. */
+      if (change->prop_mod || downgraded_copy)
         {
           apr_array_header_t *prop_diffs;
           apr_hash_t *old_props;
@@ -731,14 +745,9 @@ path_driver_cb_func(void **dir_baton,
             }
         }
 
-      /* Handle textual modifications.
-
-         Note that this needs to happen in the "copy from a file we
-         aren't allowed to see" case since otherwise the caller will
-         have no way to actually get the new file's contents, which
-         they are apparently allowed to see. */
+      /* Handle textual modifications. */
       if (change->node_kind == svn_node_file
-          && (change->text_mod || (change->copyfrom_path && ! copyfrom_path)))
+          && (change->text_mod || downgraded_copy))
         {
           svn_txdelta_window_handler_t delta_handler;
           void *delta_handler_baton;
@@ -914,3 +923,16 @@ svn_repos_replay2(svn_fs_root_t *root,
                                SVN_INVALID_REVNUM, paths,
                                path_driver_cb_func, &cb_baton, pool);
 }
+
+svn_error_t *
+svn_repos__replay_ev2(svn_fs_root_t *root,
+                      const char *base_dir,
+                      svn_revnum_t low_water_mark,
+                      svn_boolean_t send_deltas,
+                      svn_editor_t *editor,
+                      svn_repos_authz_func_t authz_read_func,
+                      void *authz_read_baton,
+                      apr_pool_t *scratch_pool)
+{
+  SVN__NOT_IMPLEMENTED();
+}

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/repos.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/repos.c Tue May 29 01:39:41 2012
@@ -36,6 +36,7 @@
 #include "svn_version.h"
 
 #include "private/svn_repos_private.h"
+#include "private/svn_subr_private.h"
 #include "svn_private_config.h" /* for SVN_TEMPLATE_ROOT_DIR */
 
 #include "repos.h"
@@ -1184,9 +1185,9 @@ create_repos_structure(svn_repos_t *repo
   /* Write the top-level README file. */
   {
     const char * const readme_header =
-      "This is a Subversion repository; use the 'svnadmin' tool to examine"  NL
-      "it.  Do not add, delete, or modify files here unless you know how"    NL
-      "to avoid corrupting the repository."                                  NL
+      "This is a Subversion repository; use the 'svnadmin' and 'svnlook' "   NL
+      "tools to examine it.  Do not add, delete, or modify files here "      NL
+      "unless you know how to avoid corrupting the repository."              NL
       ""                                                                     NL;
     const char * const readme_bdb_insert =
       "The directory \"" SVN_REPOS__DB_DIR "\" contains a Berkeley DB environment."  NL

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/error.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/error.c Tue May 29 01:39:41 2012
@@ -218,6 +218,28 @@ svn_error_quick_wrap(svn_error_t *child,
 
 
 svn_error_t *
+svn_error__trace(const char *file, long line, svn_error_t *err)
+{
+#ifndef SVN_DEBUG
+
+  /* We shouldn't even be here, but whatever. Just return the error as-is.  */
+  return err;
+
+#else
+
+  /* Only do the work when an error occurs.  */
+  if (err)
+    {
+      svn_error__locate(file, line);
+      return svn_error_quick_wrap(err, SVN_ERR__TRACED);
+    }
+  return SVN_NO_ERROR;
+
+#endif
+}
+
+
+svn_error_t *
 svn_error_compose_create(svn_error_t *err1,
                          svn_error_t *err2)
 {

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/hash.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/hash.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/hash.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/hash.c Tue May 29 01:39:41 2012
@@ -40,6 +40,7 @@
 #include "svn_pools.h"
 
 #include "private/svn_dep_compat.h"
+#include "private/svn_subr_private.h"
 
 #include "svn_private_config.h"
 
@@ -237,7 +238,7 @@ hash_write(apr_hash_t *hash, apr_hash_t 
                                 valstr->len));
       len = valstr->len;
       SVN_ERR(svn_stream_write(stream, valstr->data, &len));
-      SVN_ERR(svn_stream_printf(stream, subpool, "\n"));
+      SVN_ERR(svn_stream_puts(stream, "\n"));
     }
 
   if (oldhash)
@@ -495,7 +496,7 @@ svn_hash_from_cstring_keys(apr_hash_t **
                            apr_pool_t *pool)
 {
   int i;
-  apr_hash_t *hash = apr_hash_make(pool);
+  apr_hash_t *hash = svn_hash__make(pool);
   for (i = 0; i < keys->nelts; i++)
     {
       const char *key =
@@ -560,3 +561,71 @@ svn_hash__get_bool(apr_hash_t *hash, con
   return default_value;
 }
 
+
+
+/*** Optimized hash function ***/
+
+/* Optimized version of apr_hashfunc_default in APR 1.4.5 and earlier.
+ * It assumes that the CPU has 32-bit multiplications with high throughput
+ * of at least 1 operation every 3 cycles. Latency is not an issue. Another
+ * optimization is a mildly unrolled main loop and breaking the dependency
+ * chain within the loop.
+ *
+ * Note that most CPUs including Intel Atom, VIA Nano, ARM feature the
+ * assumed pipelined multiplication circuitry. They can do one MUL every
+ * or every other cycle.
+ *
+ * The performance is ultimately limited by the fact that most CPUs can
+ * do only one LOAD and only one BRANCH operation per cycle. The best we
+ * can do is to process one character per cycle - provided the processor
+ * is wide enough to do 1 LOAD, COMPARE, BRANCH, MUL and ADD per cycle.
+ */
+static unsigned int
+hashfunc_compatible(const char *char_key, apr_ssize_t *klen)
+{
+    unsigned int hash = 0;
+    const unsigned char *key = (const unsigned char *)char_key;
+    const unsigned char *p;
+    apr_ssize_t i;
+
+    if (*klen == APR_HASH_KEY_STRING)
+      {
+        for (p = key; ; p+=4)
+          {
+            unsigned int new_hash = hash * 33 * 33 * 33 * 33;
+            if (!p[0]) break;
+            new_hash += p[0] * 33 * 33 * 33;
+            if (!p[1]) break;
+            new_hash += p[1] * 33 * 33;
+            if (!p[2]) break;
+            new_hash += p[2] * 33;
+            if (!p[3]) break;
+            hash = new_hash + p[3];
+          }
+        for (; *p; p++)
+            hash = hash * 33 + *p;
+
+        *klen = p - key;
+      }
+    else
+      {
+        for (p = key, i = *klen; i >= 4; i-=4, p+=4)
+          {
+            hash = hash * 33 * 33 * 33 * 33
+                 + p[0] * 33 * 33 * 33
+                 + p[1] * 33 * 33
+                 + p[2] * 33
+                 + p[3];
+          }
+        for (; i; i--, p++)
+            hash = hash * 33 + *p;
+      }
+
+    return hash;
+}
+
+apr_hash_t *
+svn_hash__make(apr_pool_t *pool)
+{
+  return apr_hash_make_custom(pool, hashfunc_compatible);
+}

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/internal_statements.sql
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/internal_statements.sql?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/internal_statements.sql (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/internal_statements.sql Tue May 29 01:39:41 2012
@@ -21,5 +21,27 @@
  * ====================================================================
  */
 
--- STMT_DUMMY_SELECT_FOR_BACKUP
-SELECT * FROM SQLITE_MASTER;
+-- STMT_INTERNAL_SAVEPOINT_SVN
+SAVEPOINT svn
+
+-- STMT_INTERNAL_RELEASE_SAVEPOINT_SVN
+RELEASE SAVEPOINT svn
+
+-- STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN
+ROLLBACK TO SAVEPOINT svn
+
+-- STMT_INTERNAL_BEGIN_TRANSACTION
+BEGIN TRANSACTION
+
+-- STMT_INTERNAL_BEGIN_IMMEDIATE_TRANSACTION
+BEGIN IMMEDIATE TRANSACTION
+
+-- STMT_INTERNAL_COMMIT_TRANSACTION
+COMMIT TRANSACTION
+
+-- STMT_INTERNAL_ROLLBACK_TRANSACTION
+ROLLBACK TRANSACTION
+
+/* Dummmy statement to determine the number of internal statements */
+-- STMT_INTERNAL_LAST
+;

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/io.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/io.c Tue May 29 01:39:41 2012
@@ -168,6 +168,41 @@ cstring_from_utf8(const char **path_apr,
 #endif
 }
 
+/* Helper function that allows to convert an APR-level PATH to something
+ * that we can pass the svn_error_wrap_apr. Since we use it in context
+ * of error reporting, having *some* path info may be more useful than
+ * having none.  Therefore, we use a best effort approach here.
+ *
+ * This is different from svn_io_file_name_get in that it uses a different
+ * signature style and will never fail.
+ */
+static const char *
+try_utf8_from_internal_style(const char *path, apr_pool_t *pool)
+{
+  svn_error_t *error;
+  const char *path_utf8;
+
+  /* Special case. */
+  if (path == NULL)
+    return "(NULL)";
+  
+  /* (try to) convert PATH to UTF-8. If that fails, continue with the plain
+   * PATH because it is the best we have. It may actually be UTF-8 already.
+   */
+  error = cstring_to_utf8(&path_utf8, path, pool);
+  if (error)
+    {
+      /* fallback to best representation we have */
+
+      svn_error_clear(error);
+      path_utf8 = path;
+    }
+
+  /* Toggle (back-)slashes etc. as necessary.
+   */
+  return svn_dirent_local_style(path_utf8, pool);
+}
+
 
 /* Set *NAME_P to the UTF-8 representation of directory entry NAME.
  * NAME is in the internal encoding used by APR; PARENT is in
@@ -193,6 +228,10 @@ entry_name_to_utf8(const char **name_p,
                    const char *parent,
                    apr_pool_t *pool)
 {
+#if defined(WIN32) || defined(DARWIN)
+  *name_p = apr_pstrdup(pool, name);
+  return SVN_NO_ERROR;
+#else
   svn_error_t *err = svn_path_cstring_to_utf8(name_p, name, pool);
   if (err && err->apr_err == APR_EINVAL)
     {
@@ -202,6 +241,7 @@ entry_name_to_utf8(const char **name_p,
                                svn_dirent_local_style(parent, pool));
     }
   return err;
+#endif
 }
 
 
@@ -851,10 +891,10 @@ file_perms_set(const char *fname, apr_fi
 
 /* Set permissions PERMS on the FILE. This is a cheaper variant of the
  * file_perms_set wrapper() function because no locale-dependent string
- * conversion is required.
+ * conversion is required. POOL will be used for allocations.
  */
 static svn_error_t *
-file_perms_set2(apr_file_t* file, apr_fileperms_t perms)
+file_perms_set2(apr_file_t* file, apr_fileperms_t perms, apr_pool_t *pool)
 {
   const char *fname_apr;
   apr_status_t status;
@@ -866,7 +906,7 @@ file_perms_set2(apr_file_t* file, apr_fi
   status = apr_file_perms_set(fname_apr, perms);
   if (status)
     return svn_error_wrap_apr(status, _("Can't set permissions on '%s'"),
-                              fname_apr);
+                              try_utf8_from_internal_style(fname_apr, pool));
   else
     return SVN_NO_ERROR;
 }
@@ -1911,11 +1951,11 @@ svn_io_lock_open_file(apr_file_t *lockfi
         case APR_FLOCK_SHARED:
           return svn_error_wrap_apr(apr_err,
                                     _("Can't get shared lock on file '%s'"),
-                                    fname);
+                                    try_utf8_from_internal_style(fname, pool));
         case APR_FLOCK_EXCLUSIVE:
           return svn_error_wrap_apr(apr_err,
                                     _("Can't get exclusive lock on file '%s'"),
-                                    fname);
+                                    try_utf8_from_internal_style(fname, pool));
         default:
           SVN_ERR_MALFUNCTION();
         }
@@ -1948,7 +1988,8 @@ svn_io_unlock_open_file(apr_file_t *lock
   /* The actual unlock attempt. */
   apr_err = apr_file_unlock(lockfile_handle);
   if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Can't unlock file '%s'"), fname);
+    return svn_error_wrap_apr(apr_err, _("Can't unlock file '%s'"),
+                              try_utf8_from_internal_style(fname, pool));
   
 /* On Windows and OS/2 file locks are automatically released when
    the file handle closes */
@@ -3131,7 +3172,7 @@ do_io_file_wrapper_cleanup(apr_file_t *f
 
   if (name)
     return svn_error_wrap_apr(status, _(msg),
-                              svn_dirent_local_style(name, pool));
+                              try_utf8_from_internal_style(name, pool));
   else
     return svn_error_wrap_apr(status, "%s", _(msg_no_name));
 }
@@ -4296,7 +4337,7 @@ svn_io_open_unique_file3(apr_file_t **fi
   if (!using_system_temp_dir)
     {
       SVN_ERR(merge_default_file_perms(tempfile, &perms, scratch_pool));
-      SVN_ERR(file_perms_set2(tempfile, perms));
+      SVN_ERR(file_perms_set2(tempfile, perms, scratch_pool));
     }
 #endif
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/lock.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/lock.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/lock.c Tue May 29 01:39:41 2012
@@ -54,8 +54,7 @@ svn_lock_dup(const svn_lock_t *lock, apr
   new_l->path = apr_pstrdup(pool, new_l->path);
   new_l->token = apr_pstrdup(pool, new_l->token);
   new_l->owner = apr_pstrdup(pool, new_l->owner);
-  if (new_l->comment)
-    new_l->comment = apr_pstrdup(pool, new_l->comment);
+  new_l->comment = apr_pstrdup(pool, new_l->comment);
 
   return new_l;
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/named_atomic.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/named_atomic.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/named_atomic.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/named_atomic.c Tue May 29 01:39:41 2012
@@ -84,16 +84,13 @@
  */
 #define SHM_NAME_SUFFIX "Shm"
 
-/* Prevent macro re-definition warning (on Windows in particular).
- */
-#ifdef SYNCHRONIZE
-#undef SYNCHRONIZE
-#endif
-
 /* Platform-dependent implementations of our basic atomic operations.
- * SYNCHRONIZE(op) will ensure that the OP gets executed atomically.
+ * NA_SYNCHRONIZE(op) will ensure that the OP gets executed atomically.
  * This will be zero-overhead if OP itself is already atomic.
  *
+ * (We don't call it SYNCHRONIZE because Windows has a preprocess macro by
+ * that name.)
+ *
  * The default implementation will use the same mutex for initialization
  * as well as any type of data access.  This is quite expensive and we
  * can do much better on most platforms.
@@ -108,8 +105,8 @@
 #define synched_cmpxchg(mem, value, comperand) \
   InterlockedCompareExchange64(mem, value, comperand)
 
-#define SYNCHRONIZE(_atomic,op) op;
-#define SYNCHRONIZE_IS_FAST TRUE
+#define NA_SYNCHRONIZE(_atomic,op) op;
+#define NA_SYNCHRONIZE_IS_FAST TRUE
 
 #elif SVN_HAS_ATOMIC_BUILTINS
 
@@ -121,8 +118,8 @@
 #define synched_cmpxchg(mem, value, comperand) \
   __sync_val_compare_and_swap(mem, comperand, value)
 
-#define SYNCHRONIZE(_atomic,op) op;
-#define SYNCHRONIZE_IS_FAST TRUE
+#define NA_SYNCHRONIZE(_atomic,op) op;
+#define NA_SYNCHRONIZE_IS_FAST TRUE
 
 #else
 
@@ -161,12 +158,12 @@ synched_cmpxchg(volatile apr_int64_t *me
   return old_value;
 }
 
-#define SYNCHRONIZE(_atomic,op)\
+#define NA_SYNCHRONIZE(_atomic,op)\
   SVN_ERR(lock(_atomic->mutex));\
   op;\
   SVN_ERR(unlock(_atomic->mutex,SVN_NO_ERROR));
 
-#define SYNCHRONIZE_IS_FAST FALSE
+#define NA_SYNCHRONIZE_IS_FAST FALSE
 
 #endif
 
@@ -344,9 +341,39 @@ return_atomic(svn_named_atomic__t **atom
 /* Implement API */
 
 svn_boolean_t
+svn_named_atomic__is_supported(void)
+{
+#ifdef _WIN32
+  static svn_tristate_t result = svn_tristate_unknown;
+
+  if (result == svn_tristate_unknown)
+    {
+      /* APR SHM implementation requires the creation of global objects */
+      HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE,
+                                         NULL,
+                                         PAGE_READONLY,
+                                         0,
+                                         1,
+                                         "Global\\__RandomXZY_svn");
+      if (handle != NULL)
+        {
+          CloseHandle(handle);
+          result = svn_tristate_true;
+        }
+      else
+        result = svn_tristate_false;
+    }
+
+  return result == svn_tristate_true ? TRUE : FALSE;
+#else
+  return TRUE;
+#endif
+}
+
+svn_boolean_t
 svn_named_atomic__is_efficient(void)
 {
-  return SYNCHRONIZE_IS_FAST;
+  return NA_SYNCHRONIZE_IS_FAST;
 }
 
 svn_error_t *
@@ -518,7 +545,7 @@ svn_named_atomic__read(apr_int64_t *valu
                        svn_named_atomic__t *atomic)
 {
   SVN_ERR(validate(atomic));
-  SYNCHRONIZE(atomic, *value = synched_read(&atomic->data->value));
+  NA_SYNCHRONIZE(atomic, *value = synched_read(&atomic->data->value));
 
   return SVN_NO_ERROR;
 }
@@ -531,7 +558,7 @@ svn_named_atomic__write(apr_int64_t *old
   apr_int64_t temp;
 
   SVN_ERR(validate(atomic));
-  SYNCHRONIZE(atomic, temp = synched_write(&atomic->data->value, new_value));
+  NA_SYNCHRONIZE(atomic, temp = synched_write(&atomic->data->value, new_value));
 
   if (old_value)
     *old_value = temp;
@@ -547,7 +574,7 @@ svn_named_atomic__add(apr_int64_t *new_v
   apr_int64_t temp;
 
   SVN_ERR(validate(atomic));
-  SYNCHRONIZE(atomic, temp = synched_add(&atomic->data->value, delta));
+  NA_SYNCHRONIZE(atomic, temp = synched_add(&atomic->data->value, delta));
 
   if (new_value)
     *new_value = temp;
@@ -564,9 +591,9 @@ svn_named_atomic__cmpxchg(apr_int64_t *o
   apr_int64_t temp;
 
   SVN_ERR(validate(atomic));
-  SYNCHRONIZE(atomic, temp = synched_cmpxchg(&atomic->data->value,
-                                             new_value,
-                                             comperand));
+  NA_SYNCHRONIZE(atomic, temp = synched_cmpxchg(&atomic->data->value,
+                                                new_value,
+                                                comperand));
 
   if (old_value)
     *old_value = temp;

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/path.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/path.c Tue May 29 01:39:41 2012
@@ -399,8 +399,8 @@ svn_path_compare_paths(const char *path1
   apr_size_t min_len = ((path1_len < path2_len) ? path1_len : path2_len);
   apr_size_t i = 0;
 
-  assert(is_canonical(path1, strlen(path1)));
-  assert(is_canonical(path2, strlen(path2)));
+  assert(is_canonical(path1, path1_len));
+  assert(is_canonical(path2, path2_len));
 
   /* Skip past common prefix. */
   while (i < min_len && path1[i] == path2[i])
@@ -1102,15 +1102,19 @@ svn_path_cstring_from_utf8(const char **
                            const char *path_utf8,
                            apr_pool_t *pool)
 {
+#if !defined(WIN32) && !defined(DARWIN)
   svn_boolean_t path_is_utf8;
   SVN_ERR(get_path_encoding(&path_is_utf8, pool));
   if (path_is_utf8)
+#endif
     {
       *path_apr = apr_pstrdup(pool, path_utf8);
       return SVN_NO_ERROR;
     }
+#if !defined(WIN32) && !defined(DARWIN)
   else
     return svn_utf_cstring_from_utf8(path_apr, path_utf8, pool);
+#endif
 }
 
 
@@ -1119,15 +1123,19 @@ svn_path_cstring_to_utf8(const char **pa
                          const char *path_apr,
                          apr_pool_t *pool)
 {
+#if !defined(WIN32) && !defined(DARWIN)
   svn_boolean_t path_is_utf8;
   SVN_ERR(get_path_encoding(&path_is_utf8, pool));
   if (path_is_utf8)
+#endif
     {
       *path_utf8 = apr_pstrdup(pool, path_apr);
       return SVN_NO_ERROR;
     }
+#if !defined(WIN32) && !defined(DARWIN)
   else
     return svn_utf_cstring_to_utf8(path_utf8, path_apr, pool);
+#endif
 }
 
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/properties.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/properties.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/properties.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/properties.c Tue May 29 01:39:41 2012
@@ -122,7 +122,7 @@ svn_categorize_props(const apr_array_hea
       enum svn_prop_kind kind;
 
       prop = &APR_ARRAY_IDX(proplist, i, svn_prop_t);
-      kind = svn_property_kind(NULL, prop->name);
+      kind = svn_property_kind2(prop->name);
       newprop = NULL;
 
       if (kind == svn_prop_regular_kind)
@@ -305,7 +305,7 @@ svn_prop_hash_dup(apr_hash_t *hash,
       void *prop;
 
       apr_hash_this(hi, &key, &klen, &prop);
-      apr_hash_set(new_hash, apr_pstrdup(pool, key), klen,
+      apr_hash_set(new_hash, apr_pstrmemdup(pool, key, klen), klen,
                    svn_string_dup(prop, pool));
     }
   return new_hash;

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/sqlite.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/sqlite.c Tue May 29 01:39:41 2012
@@ -84,7 +84,6 @@ struct svn_sqlite__db_t
   int nbr_statements;
   svn_sqlite__stmt_t **prepared_stmts;
   apr_pool_t *state_pool;
-  unsigned savepoint_nr;
 };
 
 struct svn_sqlite__stmt_t
@@ -204,6 +203,29 @@ svn_sqlite__get_statement(svn_sqlite__st
   return SVN_NO_ERROR;
 }
 
+/* Like svn_sqlite__get_statement but gets an internal statement.
+
+   All internal statements that use this api are executed with step_done(),
+   so we don't need the fallback reset handling here or in the pool cleanup */
+static svn_error_t *
+get_internal_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
+                       int stmt_idx)
+{
+  /* The internal statements are stored after the registered statements */
+  int prep_idx = db->nbr_statements + stmt_idx;
+  SVN_ERR_ASSERT(stmt_idx < STMT_INTERNAL_LAST);
+
+  if (db->prepared_stmts[prep_idx] == NULL)
+    SVN_ERR(prepare_statement(&db->prepared_stmts[prep_idx], db,
+                              internal_statements[stmt_idx],
+                              db->state_pool));
+
+  *stmt = db->prepared_stmts[prep_idx];
+
+  return SVN_NO_ERROR;
+}
+
+
 static svn_error_t *
 step_with_expectation(svn_sqlite__stmt_t* stmt,
                       svn_boolean_t expecting_row)
@@ -300,7 +322,13 @@ vbindf(svn_sqlite__stmt_t *stmt, const c
                                           va_arg(ap, const char *)));
             break;
 
+          case 'd':
+            SVN_ERR(svn_sqlite__bind_int(stmt, count,
+                                         va_arg(ap, int)));
+            break;
+
           case 'i':
+          case 'L':
             SVN_ERR(svn_sqlite__bind_int64(stmt, count,
                                            va_arg(ap, apr_int64_t)));
             break;
@@ -718,8 +746,32 @@ close_apr(void *data)
   for (i = 0; i < db->nbr_statements; i++)
     {
       if (db->prepared_stmts[i])
-        err = svn_error_compose_create(
+        {
+          if (db->prepared_stmts[i]->needs_reset)
+            {
+#ifdef SVN_DEBUG
+              const char *stmt_text = db->statement_strings[i];
+              stmt_text = stmt_text; /* Provide value for debugger */
+
+              SVN_ERR_MALFUNCTION_NO_RETURN();
+#else
+              err = svn_error_compose_create(
+                            err,
+                            svn_sqlite__reset(db->prepared_stmts[i]));
+#endif
+            }
+          err = svn_error_compose_create(
                         svn_sqlite__finalize(db->prepared_stmts[i]), err);
+        }
+    }
+  /* And finalize any used internal statements */
+  for (; i < db->nbr_statements + STMT_INTERNAL_LAST; i++)
+    {
+      if (db->prepared_stmts[i])
+        {
+          err = svn_error_compose_create(
+                        svn_sqlite__finalize(db->prepared_stmts[i]), err);
+        }
     }
 
   result = sqlite3_close(db->db3);
@@ -823,11 +875,19 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
           statements++;
           (*db)->nbr_statements++;
         }
-      (*db)->prepared_stmts = apr_pcalloc(result_pool, (*db)->nbr_statements
+
+      (*db)->prepared_stmts = apr_pcalloc(
+                                  result_pool,
+                                  ((*db)->nbr_statements + STMT_INTERNAL_LAST)
                                                 * sizeof(svn_sqlite__stmt_t *));
     }
   else
-    (*db)->nbr_statements = 0;
+    {
+      (*db)->nbr_statements = 0;
+      (*db)->prepared_stmts = apr_pcalloc(result_pool,
+                                          (0 + STMT_INTERNAL_LAST)
+                                                * sizeof(svn_sqlite__stmt_t *));
+    }
 
   (*db)->state_pool = result_pool;
   apr_pool_cleanup_register(result_pool, *db, close_apr, apr_pool_cleanup_null);
@@ -876,6 +936,7 @@ with_transaction(svn_sqlite__db_t *db,
                  void *cb_baton,
                  apr_pool_t *scratch_pool /* NULL allowed */)
 {
+  svn_sqlite__stmt_t *stmt;
   svn_error_t *err;
 
   err = cb_func(cb_baton, db, scratch_pool);
@@ -883,7 +944,12 @@ with_transaction(svn_sqlite__db_t *db,
   /* Commit or rollback the sqlite transaction. */
   if (err)
     {
-      svn_error_t *err2 = exec_sql(db, "ROLLBACK TRANSACTION;");
+      svn_error_t *err2;
+
+      err2 = get_internal_statement(&stmt, db,
+                                    STMT_INTERNAL_ROLLBACK_TRANSACTION);
+      if (!err2)
+        err2 = svn_sqlite__step_done(stmt);
 
       if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
         {
@@ -908,7 +974,7 @@ with_transaction(svn_sqlite__db_t *db,
 
           err2 = reset_all_statements(db, err2);
           err2 = svn_error_compose_create(
-                      exec_sql(db, "ROLLBACK TRANSACTION;"),
+                      svn_sqlite__step_done(stmt),
                       err2);
         }
 
@@ -916,7 +982,8 @@ with_transaction(svn_sqlite__db_t *db,
                                       err2);
     }
 
-  return svn_error_trace(exec_sql(db, "COMMIT TRANSACTION;"));
+  SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_COMMIT_TRANSACTION));
+  return svn_error_trace(svn_sqlite__step_done(stmt));
 }
 
 svn_error_t *
@@ -925,7 +992,10 @@ svn_sqlite__with_transaction(svn_sqlite_
                              void *cb_baton,
                              apr_pool_t *scratch_pool /* NULL allowed */)
 {
-  SVN_ERR(exec_sql(db, "BEGIN TRANSACTION;"));
+  svn_sqlite__stmt_t *stmt;
+  SVN_ERR(get_internal_statement(&stmt, db,
+                                 STMT_INTERNAL_BEGIN_TRANSACTION));
+  SVN_ERR(svn_sqlite__step_done(stmt));
   return svn_error_trace(with_transaction(db, cb_func, cb_baton,
                                           scratch_pool));
 }
@@ -937,7 +1007,10 @@ svn_sqlite__with_immediate_transaction(
   void *cb_baton,
   apr_pool_t *scratch_pool /* NULL allowed */)
 {
-  SVN_ERR(exec_sql(db, "BEGIN IMMEDIATE TRANSACTION;"));
+  svn_sqlite__stmt_t *stmt;
+  SVN_ERR(get_internal_statement(&stmt, db,
+                                 STMT_INTERNAL_BEGIN_IMMEDIATE_TRANSACTION));
+  SVN_ERR(svn_sqlite__step_done(stmt));
   return svn_error_trace(with_transaction(db, cb_func, cb_baton,
                                           scratch_pool));
 }
@@ -949,20 +1022,21 @@ svn_sqlite__with_lock(svn_sqlite__db_t *
                       apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
-  int savepoint = db->savepoint_nr++;
-  /* This buffer is plenty big to hold the SAVEPOINT and RELEASE commands. */
-  char buf[32];
+  svn_sqlite__stmt_t *stmt;
 
-  snprintf(buf, sizeof(buf), "SAVEPOINT s%u", savepoint);
-  SVN_ERR(exec_sql(db, buf));
+  SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_SAVEPOINT_SVN));
+  SVN_ERR(svn_sqlite__step_done(stmt));
   err = cb_func(cb_baton, db, scratch_pool);
 
   if (err)
     {
       svn_error_t *err2;
 
-      snprintf(buf, sizeof(buf), "ROLLBACK TO s%u", savepoint);
-      err2 = exec_sql(db, buf);
+      err2 = get_internal_statement(&stmt, db,
+                                    STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN);
+
+      if (!err2)
+        err2 = svn_sqlite__step_done(stmt);
 
       if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
         {
@@ -973,17 +1047,23 @@ svn_sqlite__with_lock(svn_sqlite__db_t *
                  further details */
 
           err2 = reset_all_statements(db, err2);
-          err2 = svn_error_compose_create(exec_sql(db, buf), err2);
+          err2 = svn_error_compose_create(svn_sqlite__step_done(stmt), err2);
         }
 
-      snprintf(buf, sizeof(buf), "RELEASE   s%u", savepoint);
-      err2 = svn_error_compose_create(exec_sql(db, buf), err2);
+      err = svn_error_compose_create(err, err2);
+      err2 = get_internal_statement(&stmt, db,
+                                    STMT_INTERNAL_RELEASE_SAVEPOINT_SVN);
+
+      if (!err2)
+        err2 = svn_sqlite__step_done(stmt);
 
       return svn_error_trace(svn_error_compose_create(err, err2));
     }
 
-  snprintf(buf, sizeof(buf), "RELEASE   s%u", savepoint);
-  return svn_error_trace(exec_sql(db, buf));
+  SVN_ERR(get_internal_statement(&stmt, db,
+                                 STMT_INTERNAL_RELEASE_SAVEPOINT_SVN));
+
+  return svn_error_trace(svn_sqlite__step_done(stmt));
 }
 
 svn_error_t *
@@ -994,7 +1074,7 @@ svn_sqlite__hotcopy(const char *src_path
   svn_sqlite__db_t *src_db;
 
   SVN_ERR(svn_sqlite__open(&src_db, src_path, svn_sqlite__mode_readonly,
-                           internal_statements, 0, NULL,
+                           NULL, 0, NULL,
                            scratch_pool, scratch_pool));
 
   {

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/stream.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/stream.c Tue May 29 01:39:41 2012
@@ -140,7 +140,7 @@ svn_error_t *
 svn_stream_read(svn_stream_t *stream, char *buffer, apr_size_t *len)
 {
   SVN_ERR_ASSERT(stream->read_fn != NULL);
-  return stream->read_fn(stream->baton, buffer, len);
+  return svn_error_trace(stream->read_fn(stream->baton, buffer, len));
 }
 
 
@@ -148,9 +148,10 @@ svn_error_t *
 svn_stream_skip(svn_stream_t *stream, apr_size_t len)
 {
   if (stream->skip_fn == NULL)
-    return skip_default_handler(stream->baton, len, stream->read_fn);
+    return svn_error_trace(
+            skip_default_handler(stream->baton, len, stream->read_fn));
 
-  return stream->skip_fn(stream->baton, len);
+  return svn_error_trace(stream->skip_fn(stream->baton, len));
 }
 
 
@@ -158,7 +159,7 @@ svn_error_t *
 svn_stream_write(svn_stream_t *stream, const char *data, apr_size_t *len)
 {
   SVN_ERR_ASSERT(stream->write_fn != NULL);
-  return stream->write_fn(stream->baton, data, len);
+  return svn_error_trace(stream->write_fn(stream->baton, data, len));
 }
 
 
@@ -182,7 +183,7 @@ svn_stream_mark(svn_stream_t *stream, sv
   if (stream->mark_fn == NULL)
     return svn_error_create(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED, NULL, NULL);
 
-  return stream->mark_fn(stream->baton, mark, pool);
+  return svn_error_trace(stream->mark_fn(stream->baton, mark, pool));
 }
 
 svn_error_t *
@@ -191,7 +192,7 @@ svn_stream_seek(svn_stream_t *stream, co
   if (stream->seek_fn == NULL)
     return svn_error_create(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED, NULL, NULL);
 
-  return stream->seek_fn(stream->baton, mark);
+  return svn_error_trace(stream->seek_fn(stream->baton, mark));
 }
 
 svn_boolean_t
@@ -208,9 +209,17 @@ svn_stream_close(svn_stream_t *stream)
 {
   if (stream->close_fn == NULL)
     return SVN_NO_ERROR;
-  return stream->close_fn(stream->baton);
+  return svn_error_trace(stream->close_fn(stream->baton));
 }
 
+svn_error_t *
+svn_stream_puts(svn_stream_t *stream,
+                const char *str)
+{
+  apr_size_t len;
+  len = strlen(str);
+  return svn_error_trace(svn_stream_write(stream, str, &len));
+}
 
 svn_error_t *
 svn_stream_printf(svn_stream_t *stream,
@@ -220,20 +229,12 @@ svn_stream_printf(svn_stream_t *stream,
 {
   const char *message;
   va_list ap;
-  apr_size_t len;
 
-  /* any format controls or is this a static string? */
-  if (strchr(fmt, '%'))
-    {
-      va_start(ap, fmt);
-      message = apr_pvsprintf(pool, fmt, ap);
-      va_end(ap);
-    }
-  else
-    message = fmt;
+  va_start(ap, fmt);
+  message = apr_pvsprintf(pool, fmt, ap);
+  va_end(ap);
 
-  len = strlen(message);
-  return svn_stream_write(stream, message, &len);
+  return svn_error_trace(svn_stream_puts(stream, message));
 }
 
 
@@ -246,7 +247,6 @@ svn_stream_printf_from_utf8(svn_stream_t
 {
   const char *message, *translated;
   va_list ap;
-  apr_size_t len;
 
   va_start(ap, fmt);
   message = apr_pvsprintf(pool, fmt, ap);
@@ -255,9 +255,7 @@ svn_stream_printf_from_utf8(svn_stream_t
   SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated, message, encoding,
                                         pool));
 
-  len = strlen(translated);
-
-  return svn_stream_write(stream, translated, &len);
+  return svn_error_trace(svn_stream_puts(stream, translated));
 }
 
 /* Size that 90% of the lines we encounter will be not longer than.
@@ -417,7 +415,7 @@ stream_readline_chunky(svn_stringbuf_t *
   /* Move the stream read pointer to the first position behind the EOL.
    */
   SVN_ERR(svn_stream_seek(stream, mark));
-  return svn_stream_skip(stream, total_parsed);
+  return svn_error_trace(svn_stream_skip(stream, total_parsed));
 }
 
 /* Guts of svn_stream_readline().
@@ -686,31 +684,31 @@ svn_stream_tee(svn_stream_t *out1,
 static svn_error_t *
 read_handler_disown(void *baton, char *buffer, apr_size_t *len)
 {
-  return svn_stream_read(baton, buffer, len);
+  return svn_error_trace(svn_stream_read(baton, buffer, len));
 }
 
 static svn_error_t *
 skip_handler_disown(void *baton, apr_size_t len)
 {
-  return svn_stream_skip(baton, len);
+  return svn_error_trace(svn_stream_skip(baton, len));
 }
 
 static svn_error_t *
 write_handler_disown(void *baton, const char *buffer, apr_size_t *len)
 {
-  return svn_stream_write(baton, buffer, len);
+  return svn_error_trace(svn_stream_write(baton, buffer, len));
 }
 
 static svn_error_t *
 mark_handler_disown(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
-  return svn_stream_mark(baton, mark, pool);
+  return svn_error_trace(svn_stream_mark(baton, mark, pool));
 }
 
 static svn_error_t *
 seek_handler_disown(void *baton, const svn_stream_mark_t *mark)
 {
-  return svn_stream_seek(baton, mark);
+  return svn_error_trace(svn_stream_seek(baton, mark));
 }
 
 static svn_boolean_t
@@ -771,7 +769,7 @@ read_handler_apr(void *baton, char *buff
     err = svn_io_file_read_full2(btn->file, buffer, *len, len,
                                  &eof, btn->pool);
 
-  return err;
+  return svn_error_trace(err);
 }
 
 static svn_error_t *
@@ -780,7 +778,8 @@ skip_handler_apr(void *baton, apr_size_t
   struct baton_apr *btn = baton;
   apr_off_t offset = len;
 
-  return svn_io_file_seek(btn->file, APR_CUR, &offset, btn->pool);
+  return svn_error_trace(
+            svn_io_file_seek(btn->file, APR_CUR, &offset, btn->pool));
 }
 
 static svn_error_t *
@@ -798,7 +797,7 @@ write_handler_apr(void *baton, const cha
   else
     err = svn_io_file_write_full(btn->file, data, *len, len, btn->pool);
 
-  return err;
+  return svn_error_trace(err);
 }
 
 static svn_error_t *
@@ -806,7 +805,7 @@ close_handler_apr(void *baton)
 {
   struct baton_apr *btn = baton;
 
-  return svn_io_file_close(btn->file, btn->pool);
+  return svn_error_trace(svn_io_file_close(btn->file, btn->pool));
 }
 
 static svn_error_t *
@@ -1133,7 +1132,7 @@ close_handler_gz(void *baton)
     }
 
   if (btn->close != NULL)
-    return btn->close(btn->subbaton);
+    return svn_error_trace(btn->close(btn->subbaton));
   else
     return SVN_NO_ERROR;
 }
@@ -1208,7 +1207,7 @@ write_handler_checksum(void *baton, cons
   if (btn->write_checksum && *len > 0)
     SVN_ERR(svn_checksum_update(btn->write_ctx, buffer, *len));
 
-  return svn_stream_write(btn->proxy, buffer, len);
+  return svn_error_trace(svn_stream_write(btn->proxy, buffer, len));
 }
 
 
@@ -1237,7 +1236,7 @@ close_handler_checksum(void *baton)
   if (btn->write_ctx)
     SVN_ERR(svn_checksum_final(btn->write_checksum, btn->write_ctx, btn->pool));
 
-  return svn_stream_close(btn->proxy);
+  return svn_error_trace(svn_stream_close(btn->proxy));
 }
 
 
@@ -1293,21 +1292,21 @@ static svn_error_t *
 read_handler_md5(void *baton, char *buffer, apr_size_t *len)
 {
   struct md5_stream_baton *btn = baton;
-  return svn_stream_read(btn->proxy, buffer, len);
+  return svn_error_trace(svn_stream_read(btn->proxy, buffer, len));
 }
 
 static svn_error_t *
 skip_handler_md5(void *baton, apr_size_t len)
 {
   struct md5_stream_baton *btn = baton;
-  return svn_stream_skip(btn->proxy, len);
+  return svn_error_trace(svn_stream_skip(btn->proxy, len));
 }
 
 static svn_error_t *
 write_handler_md5(void *baton, const char *buffer, apr_size_t *len)
 {
   struct md5_stream_baton *btn = baton;
-  return svn_stream_write(btn->proxy, buffer, len);
+  return svn_error_trace(svn_stream_write(btn->proxy, buffer, len));
 }
 
 static svn_error_t *
@@ -1662,3 +1661,147 @@ svn_stream_buffered(apr_pool_t *result_p
   return svn_stream__from_spillbuf(BUFFER_BLOCK_SIZE, BUFFER_MAX_SIZE,
                                    result_pool);
 }
+
+
+
+/*** Lazyopen Streams ***/
+
+/* Custom baton for lazyopen-style wrapper streams. */
+typedef struct lazyopen_baton_t {
+
+  /* Callback function and baton for opening the wrapped stream. */
+  svn_stream_lazyopen_func_t open_func;
+  void *open_baton;
+
+  /* The wrapped stream, or NULL if the stream hasn't yet been
+     opened. */
+  svn_stream_t *real_stream;
+  apr_pool_t *pool;
+
+} lazyopen_baton_t;
+
+
+/* Use B->open_func/baton to create and set B->real_stream iff it
+   isn't already set. */
+static svn_error_t *
+lazyopen_if_unopened(lazyopen_baton_t *b)
+{
+  if (b->real_stream == NULL)
+    {
+      svn_stream_t *stream;
+      apr_pool_t *scratch_pool = svn_pool_create(b->pool);
+
+      SVN_ERR(b->open_func(&stream, b->open_baton,
+                           b->pool, scratch_pool));
+
+      svn_pool_destroy(scratch_pool);
+
+      b->real_stream = stream;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_read_fn_t */
+static svn_error_t *
+read_handler_lazyopen(void *baton,
+                      char *buffer,
+                      apr_size_t *len)
+{
+  lazyopen_baton_t *b = baton;
+
+  SVN_ERR(lazyopen_if_unopened(b));
+  SVN_ERR(svn_stream_read(b->real_stream, buffer, len));
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_stream_skip_fn_t */
+static svn_error_t *
+skip_handler_lazyopen(void *baton,
+                      apr_size_t len)
+{
+  lazyopen_baton_t *b = baton;
+
+  SVN_ERR(lazyopen_if_unopened(b));
+  SVN_ERR(svn_stream_skip(b->real_stream, len));
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_write_fn_t */
+static svn_error_t *
+write_handler_lazyopen(void *baton,
+                       const char *data,
+                       apr_size_t *len)
+{
+  lazyopen_baton_t *b = baton;
+
+  SVN_ERR(lazyopen_if_unopened(b));
+  SVN_ERR(svn_stream_write(b->real_stream, data, len));
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_close_fn_t */
+static svn_error_t *
+close_handler_lazyopen(void *baton)
+{
+  lazyopen_baton_t *b = baton;
+
+  if (b->real_stream != NULL)
+    SVN_ERR(svn_stream_close(b->real_stream));
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_stream_mark_fn_t */
+static svn_error_t *
+mark_handler_lazyopen(void *baton,
+                      svn_stream_mark_t **mark,
+                      apr_pool_t *pool)
+{
+  lazyopen_baton_t *b = baton;
+
+  SVN_ERR(lazyopen_if_unopened(b));
+  SVN_ERR(svn_stream_mark(b->real_stream, mark, pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_stream_seek_fn_t */
+static svn_error_t *
+seek_handler_lazyopen(void *baton,
+                      const svn_stream_mark_t *mark)
+{
+  lazyopen_baton_t *b = baton;
+
+  SVN_ERR(lazyopen_if_unopened(b));
+  SVN_ERR(svn_stream_seek(b->real_stream, mark));
+
+  return SVN_NO_ERROR;
+}
+
+svn_stream_t *
+svn_stream_lazyopen_create(svn_stream_lazyopen_func_t open_func,
+                           void *open_baton,
+                           apr_pool_t *result_pool)
+{
+  lazyopen_baton_t *lob = apr_pcalloc(result_pool, sizeof(*lob));
+  svn_stream_t *stream;
+
+  lob->open_func = open_func;
+  lob->open_baton = open_baton;
+  lob->real_stream = NULL;
+  lob->pool = result_pool;
+
+  stream = svn_stream_create(lob, result_pool);
+  svn_stream_set_read(stream, read_handler_lazyopen);
+  svn_stream_set_skip(stream, skip_handler_lazyopen);
+  svn_stream_set_write(stream, write_handler_lazyopen);
+  svn_stream_set_close(stream, close_handler_lazyopen);
+  svn_stream_set_mark(stream, mark_handler_lazyopen);
+  svn_stream_set_seek(stream, seek_handler_lazyopen);
+  
+  return stream;
+}

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/string.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/string.c Tue May 29 01:39:41 2012
@@ -942,8 +942,10 @@ static const char decimal_table[100][4]
       *(apr_uint16_t*)(dest) = *(apr_uint16_t*)(source);
 #else
 #  define COPY_TWO_BYTES(dest,source) \
+    do { \
       (dest)[0] = (source)[0]; \
-      (dest)[1] = (source)[1];
+      (dest)[1] = (source)[1]; \
+    } while (0)
 #endif
 
 apr_size_t

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/win32_crashrpt.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/win32_crashrpt.c Tue May 29 01:39:41 2012
@@ -257,10 +257,10 @@ format_basic_type(char *buf, DWORD basic
   switch(length)
     {
       case 1:
-        sprintf(buf, "%x", *(unsigned char *)address);
+        sprintf(buf, "0x%02x", (int)*(unsigned char *)address);
         break;
       case 2:
-        sprintf(buf, "%x", *(unsigned short *)address);
+        sprintf(buf, "0x%04x", (int)*(unsigned short *)address);
         break;
       case 4:
         switch(basic_type)
@@ -270,7 +270,7 @@ format_basic_type(char *buf, DWORD basic
                 if (!IsBadStringPtr(*(PSTR*)address, 32))
                   sprintf(buf, "\"%.31s\"", *(unsigned long *)address);
                 else
-                  sprintf(buf, "%x", *(unsigned long *)address);
+                  sprintf(buf, "0x%08x", (int)*(unsigned long *)address);
               }
             case 6:  /* btInt */
               sprintf(buf, "%d", *(int *)address);
@@ -279,7 +279,7 @@ format_basic_type(char *buf, DWORD basic
               sprintf(buf, "%f", *(float *)address);
               break;
             default:
-              sprintf(buf, "%x", *(unsigned long *)address);
+              sprintf(buf, "0x%08x", *(unsigned long *)address);
               break;
           }
         break;
@@ -287,7 +287,10 @@ format_basic_type(char *buf, DWORD basic
         if (basic_type == 8) /* btFloat */
           sprintf(buf, "%lf", *(double *)address);
         else
-          sprintf(buf, "%I64X", *(unsigned __int64 *)address);
+          sprintf(buf, "0x%016I64X", *(unsigned __int64 *)address);
+        break;
+      default:
+        sprintf(buf, "[unhandled type 0x%08x of length 0x%08x]", basic_type, length);
         break;
     }
 }
@@ -297,7 +300,7 @@ format_basic_type(char *buf, DWORD basic
 static void
 format_value(char *value_str, DWORD64 mod_base, DWORD type, void *value_addr)
 {
-  DWORD tag;
+  DWORD tag = 0;
   int ptr = 0;
   HANDLE proc = GetCurrentProcess();
 
@@ -332,10 +335,12 @@ format_value(char *value_str, DWORD64 mo
                         type_name, *(DWORD *)value_addr);
               else
                 sprintf(value_str, "(%s **) 0x%08x",
-                        type_name, (DWORD *)value_addr);
+                        type_name, *(DWORD *)value_addr);
 
               free(type_name);
             }
+          else
+            sprintf(value_str, "[no symbol tag]");
         }
         break;
       case 16: /* SymTagBaseType */
@@ -349,17 +354,14 @@ format_value(char *value_str, DWORD64 mo
             {
               sprintf(value_str, "0x%08x \"%s\"",
                       *(DWORD *)value_addr, (char *)*(DWORD*)value_addr);
-              break;
             }
-          if (ptr >= 1)
+          else if (ptr >= 1)
             {
               sprintf(value_str, "0x%08x", *(DWORD *)value_addr);
-              break;
             }
-          if (SymGetTypeInfo_(proc, mod_base, type, TI_GET_BASETYPE, &bt))
+          else if (SymGetTypeInfo_(proc, mod_base, type, TI_GET_BASETYPE, &bt))
             {
               format_basic_type(value_str, bt, length, value_addr);
-              break;
             }
         }
         break;
@@ -369,7 +371,9 @@ format_value(char *value_str, DWORD64 mo
       case 13: /* SymTagFunctionType */
           sprintf(value_str, "0x%08x", *(DWORD *)value_addr);
           break;
-      default: break;
+      default:
+          sprintf(value_str, "[unhandled tag: %d]", tag);
+          break;
     }
 }
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/xml.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/xml.c Tue May 29 01:39:41 2012
@@ -455,7 +455,7 @@ void svn_xml_signal_bailout(svn_error_t 
 /*** Attribute walking. ***/
 
 const char *
-svn_xml_get_attr_value(const char *name, const char **atts)
+svn_xml_get_attr_value(const char *name, const char *const *atts)
 {
   while (atts && (*atts))
     {

Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/adm_files.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/adm_files.c Tue May 29 01:39:41 2012
@@ -56,7 +56,7 @@ static const char default_adm_dir_name[]
 
 /* The name that is actually used for the WC admin directory.  The
    commonest case where this won't be the default is in Windows
-   ASP.NET development environments, which choke on ".svn". */
+   ASP.NET development environments, which used to choke on ".svn". */
 static const char *adm_dir_name = default_adm_dir_name;
 
 
@@ -108,43 +108,19 @@ svn_wc_set_adm_dir(const char *name, apr
 }
 
 
-static const char *
-simple_extend(const char *adm_path,  /* ### adm_abspath?  */
-              svn_boolean_t use_tmp,
-              const char *subdir,
-              const char *child,
-              const char *extension,
-              apr_pool_t *result_pool)
-{
-  if (subdir)
-    child = svn_dirent_join(subdir, child, result_pool);
-  if (extension)
-    child = apr_pstrcat(result_pool, child, extension, (char *)NULL);
-
-  if (use_tmp)
-    return svn_dirent_join_many(result_pool,
-                                adm_path,
-                                adm_dir_name,
-                                SVN_WC__ADM_TMP,
-                                child,
-                                NULL);
-
+const char *
+svn_wc__adm_child(const char *path,
+                  const char *child,
+                  apr_pool_t *result_pool)
+{
   return svn_dirent_join_many(result_pool,
-                              adm_path,
+                              path,
                               adm_dir_name,
                               child,
                               NULL);
 }
 
 
-const char *svn_wc__adm_child(const char *path,
-                              const char *child,
-                              apr_pool_t *result_pool)
-{
-  return simple_extend(path, FALSE, NULL, child, NULL, result_pool);
-}
-
-
 svn_boolean_t
 svn_wc__adm_area_exists(const char *adm_abspath,
                         apr_pool_t *pool)
@@ -173,12 +149,11 @@ svn_wc__adm_area_exists(const char *adm_
 static svn_error_t *
 make_adm_subdir(const char *path,
                 const char *subdir,
-                svn_boolean_t tmp,
                 apr_pool_t *pool)
 {
   const char *fullpath;
 
-  fullpath = simple_extend(path, tmp, NULL, subdir, NULL, pool);
+  fullpath = svn_wc__adm_child(path, subdir, pool);
 
   return svn_io_dir_make(fullpath, APR_OS_DEFAULT, pool);
 }
@@ -360,7 +335,7 @@ static svn_error_t *
 init_adm_tmp_area(const char *path, apr_pool_t *pool)
 {
   /* SVN_WC__ADM_TMP */
-  SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_TMP, FALSE, pool));
+  SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_TMP, pool));
 
   return SVN_NO_ERROR;
 }
@@ -387,7 +362,7 @@ init_adm(svn_wc__db_t *db,
   /** Make subdirectories. ***/
 
   /* SVN_WC__ADM_PRISTINE */
-  SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PRISTINE, FALSE, pool));
+  SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PRISTINE, pool));
 
   /* ### want to add another directory? do a format bump to ensure that
      ### all existing working copies get the new directories. or maybe
@@ -634,3 +609,16 @@ svn_wc_create_tmp_file2(apr_file_t **fp,
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__get_tmpdir(const char **tmpdir_abspath,
+                   svn_wc_context_t *wc_ctx,
+                   const char *wri_abspath,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(tmpdir_abspath,
+                                         wc_ctx->db, wri_abspath,
+                                         result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/adm_ops.c?rev=1343447&r1=1343446&r2=1343447&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/adm_ops.c Tue May 29 01:39:41 2012
@@ -59,7 +59,7 @@
 #include "svn_private_config.h"
 #include "private/svn_io_private.h"
 #include "private/svn_wc_private.h"
-
+#include "private/svn_subr_private.h"
 
 
 struct svn_wc_committed_queue_t
@@ -2251,6 +2251,61 @@ svn_wc_get_pristine_contents2(svn_stream
 }
 
 
+typedef struct get_pristine_lazyopen_baton_t
+{
+  svn_wc_context_t *wc_ctx;
+  const char *wri_abspath;
+  const svn_checksum_t *sha1_checksum;
+
+} get_pristine_lazyopen_baton_t;
+
+
+/* Implements svn_stream_lazyopen_func_t */
+static svn_error_t *
+get_pristine_lazyopen_func(svn_stream_t **stream,
+                           void *baton,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  get_pristine_lazyopen_baton_t *b = baton;
+
+  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, b->wc_ctx->db,
+                                   b->wri_abspath, b->sha1_checksum,
+                                   result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__get_pristine_contents_by_checksum(svn_stream_t **contents,
+                                          svn_wc_context_t *wc_ctx,
+                                          const char *wri_abspath,
+                                          const svn_checksum_t *sha1_checksum,
+                                          apr_pool_t *result_pool,
+                                          apr_pool_t *scratch_pool)
+{
+  svn_boolean_t present;
+  
+  *contents = NULL;
+
+  SVN_ERR(svn_wc__db_pristine_check(&present, wc_ctx->db, wri_abspath,
+                                    sha1_checksum, scratch_pool));
+
+  if (present)
+    {
+      get_pristine_lazyopen_baton_t *gpl_baton;
+
+      gpl_baton = apr_pcalloc(result_pool, sizeof(*gpl_baton));
+      gpl_baton->wc_ctx = wc_ctx;
+      gpl_baton->wri_abspath = wri_abspath;
+      gpl_baton->sha1_checksum = sha1_checksum;
+      
+      *contents = svn_stream_lazyopen_create(get_pristine_lazyopen_func,
+                                             gpl_baton, result_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc__internal_remove_from_revision_control(svn_wc__db_t *db,
                                               const char *local_abspath,