You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ko...@apache.org on 2017/07/27 08:57:19 UTC

svn commit: r1803141 - in /subversion/trunk/subversion: include/svn_error_codes.h libsvn_ra_serf/ra_serf.h libsvn_ra_serf/stream_bucket.c

Author: kotkov
Date: Thu Jul 27 08:57:19 2017
New Revision: 1803141

URL: http://svn.apache.org/viewvc?rev=1803141&view=rev
Log:
ra_serf: Add new bucket that wraps a readable svn_stream_t.

This new bucket would be required to make ra_serf stream svndiff deltas
without creating temporary files.  (We'll take an svn_txdelta_stream_t,
convert it to a generic svn_stream_t with svn_txdelta_to_svndiff_stream(),
create a bucket around that stream, and use it as the PUT request body.
This change introduces adds the necessary bucket implementation.)

* subversion/include/svn_error_codes.h
  (SVN_ERR_RA_SERF_STREAM_BUCKET_READ_ERROR): New.

* subversion/libsvn_ra_serf/ra_serf.h
  (svn_ra_serf__stream_bucket_errfunc_t): Declare new callback type.
  (svn_ra_serf__create_stream_bucket): Declare new function.

* subversion/libsvn_ra_serf/stream_bucket.c: New file.
  (stream_bucket_ctx_t): New.
  (svn_ra_serf__create_stream_bucket): New, creates the bucket and
   initializes a databuf that would be used in its implementation.
   Remember the passed-in errfunc callback to allow reporting extended
   error information to the caller in the form of an svn_error_t.
  (stream_bucket_read, stream_bucket_readline, stream_bucket_peek):
   New bucket vtable members that forward everything to the databuf.
  (stream_reader): New.  This is the core function of the new bucket that
   reads data from the svn_stream_t and possibly forwards the errors
   using the stored errfunc callback.

Added:
    subversion/trunk/subversion/libsvn_ra_serf/stream_bucket.c   (with props)
Modified:
    subversion/trunk/subversion/include/svn_error_codes.h
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h

Modified: subversion/trunk/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_error_codes.h?rev=1803141&r1=1803140&r2=1803141&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_error_codes.h (original)
+++ subversion/trunk/subversion/include/svn_error_codes.h Thu Jul 27 08:57:19 2017
@@ -1667,6 +1667,11 @@ SVN_ERROR_START
              SVN_ERR_RA_SERF_CATEGORY_START + 3,
              "While handling serf response:")
 
+  /** @since New in 1.10. */
+  SVN_ERRDEF(SVN_ERR_RA_SERF_STREAM_BUCKET_READ_ERROR,
+             SVN_ERR_RA_SERF_CATEGORY_START + 4,
+             "Can't read from stream")
+
   /* malfunctions such as assertion failures */
 
   SVN_ERRDEF(SVN_ERR_ASSERTION_FAIL,

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=1803141&r1=1803140&r2=1803141&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Thu Jul 27 08:57:19 2017
@@ -1609,6 +1609,19 @@ svn_error_t *
 svn_ra_serf__request_body_cleanup(svn_ra_serf__request_body_t *body,
                                   apr_pool_t *scratch_pool);
 
+/* Callback used in svn_ra_serf__create_stream_bucket().  ERR will be
+   will be cleared and becomes invalid after the callback returns,
+   use svn_error_dup() to preserve it. */
+typedef void
+(*svn_ra_serf__stream_bucket_errfunc_t)(void *baton, svn_error_t *err);
+
+/* Create a bucket that wraps a generic readable STREAM.  This function
+   takes ownership of the passed-in stream, and will close it. */
+serf_bucket_t *
+svn_ra_serf__create_stream_bucket(svn_stream_t *stream,
+                                  serf_bucket_alloc_t *allocator,
+                                  svn_ra_serf__stream_bucket_errfunc_t errfunc,
+                                  void *errfunc_baton);
 
 #if defined(SVN_DEBUG)
 /* Wrapper macros to collect file and line information */

Added: subversion/trunk/subversion/libsvn_ra_serf/stream_bucket.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/stream_bucket.c?rev=1803141&view=auto
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/stream_bucket.c (added)
+++ subversion/trunk/subversion/libsvn_ra_serf/stream_bucket.c Thu Jul 27 08:57:19 2017
@@ -0,0 +1,120 @@
+/*
+ * stream_bucket.c : a serf bucket that wraps a readable svn_stream_t
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+#include <serf.h>
+#include <serf_bucket_util.h>
+
+#include "ra_serf.h"
+
+typedef struct stream_bucket_ctx_t
+{
+  svn_stream_t *stream;
+  svn_ra_serf__stream_bucket_errfunc_t errfunc;
+  void *errfunc_baton;
+  serf_databuf_t databuf;
+} stream_bucket_ctx_t;
+
+static apr_status_t
+stream_reader(void *baton, apr_size_t bufsize, char *buf, apr_size_t *len)
+{
+  stream_bucket_ctx_t *ctx = baton;
+  svn_error_t *err;
+
+  *len = bufsize;
+
+  err = svn_stream_read_full(ctx->stream, buf, len);
+  if (err)
+    {
+      if (ctx->errfunc)
+        ctx->errfunc(ctx->errfunc_baton, err);
+      svn_error_clear(err);
+
+      return SVN_ERR_RA_SERF_STREAM_BUCKET_READ_ERROR;
+    }
+
+  if (*len == bufsize)
+    {
+      return APR_SUCCESS;
+    }
+  else
+    {
+      svn_error_clear(svn_stream_close(ctx->stream));
+      return APR_EOF;
+    }
+}
+
+static apr_status_t
+stream_bucket_read(serf_bucket_t *bucket, apr_size_t requested,
+                   const char **data, apr_size_t *len)
+{
+  stream_bucket_ctx_t *ctx = bucket->data;
+
+  return serf_databuf_read(&ctx->databuf, requested, data, len);
+}
+
+static apr_status_t
+stream_bucket_readline(serf_bucket_t *bucket, int acceptable,
+                       int *found, const char **data, apr_size_t *len)
+{
+  stream_bucket_ctx_t *ctx = bucket->data;
+
+  return serf_databuf_readline(&ctx->databuf, acceptable, found, data, len);
+}
+
+static apr_status_t
+stream_bucket_peek(serf_bucket_t *bucket, const char **data, apr_size_t *len)
+{
+  stream_bucket_ctx_t *ctx = bucket->data;
+
+  return serf_databuf_peek(&ctx->databuf, data, len);
+}
+
+static const serf_bucket_type_t stream_bucket_vtable = {
+  "SVNSTREAM",
+  stream_bucket_read,
+  stream_bucket_readline,
+  serf_default_read_iovec,
+  serf_default_read_for_sendfile,
+  serf_default_read_bucket,
+  stream_bucket_peek,
+  serf_default_destroy_and_data
+};
+
+serf_bucket_t *
+svn_ra_serf__create_stream_bucket(svn_stream_t *stream,
+                                  serf_bucket_alloc_t *allocator,
+                                  svn_ra_serf__stream_bucket_errfunc_t errfunc,
+                                  void *errfunc_baton)
+{
+  stream_bucket_ctx_t *ctx;
+
+  ctx = serf_bucket_mem_calloc(allocator, sizeof(*ctx));
+  ctx->stream = stream;
+  ctx->errfunc = errfunc;
+  ctx->errfunc_baton = errfunc_baton;
+  serf_databuf_init(&ctx->databuf);
+  ctx->databuf.read = stream_reader;
+  ctx->databuf.read_baton = ctx;
+
+  return serf_bucket_create(&stream_bucket_vtable, allocator, ctx);
+}

Propchange: subversion/trunk/subversion/libsvn_ra_serf/stream_bucket.c
------------------------------------------------------------------------------
    svn:eol-style = native