You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/08/17 23:12:12 UTC

svn commit: r986485 - in /subversion/branches/performance/subversion: include/svn_io.h libsvn_subr/stream.c libsvn_subr/subst.c

Author: stefan2
Date: Tue Aug 17 21:12:12 2010
New Revision: 986485

URL: http://svn.apache.org/viewvc?rev=986485&view=rev
Log:
Replace the "move mark" concept by one that is strictly compatible with 
the stream semantics: skipping a number of chars from the stream. This
can always be emulated by reading that amount of data and discarding it.

* subversion/include/svn_io.h
  (svn_skip_fn_t): introduce as replacement for svn_io_move_mark_fn_t
  (svn_stream_set_skip): introduce as replacement for svn_io_skip_fn_t
  (svn_stream_skip): introduce as replacement for svn_stream_move_mark

* subversion/libsvn_subr/stream.c
  (svn_stream_t, svn_stream_create): adapt
  (svn_stream_set_skip, svn_stream_skip): implement
  (svn_stream_set_move_mark, svn_stream_move_mark): drop
  (stream_readline_chunky): adapt
  (skip_default_handler): new utility function implementing "skip" in terms of "read"
  (skip_handler_empty, skip_handler_disown, skip_handler_apr,
   skip_range_handler_apr, skip_handler_gz, skip_handler_checksum, 
   skip_handler_md5, skip_handler_stringbuf):
   implement "skip" for various types of stream
  (move_mark_handler_empty, move_mark_handler_disown,
   move_mark_handler_apr, move_mark_handler_stringbuf, skip_handler_string): drop 
  (svn_stream_empty, svn_stream_disown, stream_from_aprfile,
   svn_stream_from_aprfile_range_readonly, svn_stream_compressed, 
   svn_stream_checksummed2, svn_stream_checksummed,
   svn_stream_from_stringbuf, svn_stream_from_string):
   adapt vtable initialization
  (read_handler_apr, write_handler_apr): fix formatting

* subversion/libsvn_subr/subst.c
  (translated_stream_skip): implement "skip" for translated streams
  (translated_stream_move_mark): drop
  (svn_subst_stream_translated): adapt vtable initialization

Modified:
    subversion/branches/performance/subversion/include/svn_io.h
    subversion/branches/performance/subversion/libsvn_subr/stream.c
    subversion/branches/performance/subversion/libsvn_subr/subst.c

Modified: subversion/branches/performance/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_io.h?rev=986485&r1=986484&r2=986485&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_io.h (original)
+++ subversion/branches/performance/subversion/include/svn_io.h Tue Aug 17 21:12:12 2010
@@ -741,6 +741,12 @@ typedef svn_error_t *(*svn_read_fn_t)(vo
                                       char *buffer,
                                       apr_size_t *len);
 
+/** Skip data handler function for a generic stream.  @see svn_stream_t.
+ * @since New in 1.7.
+ */
+typedef svn_error_t *(*svn_skip_fn_t)(void *baton,
+                                      apr_size_t *count);
+
 /** Write handler function for a generic stream.  @see svn_stream_t. */
 typedef svn_error_t *(*svn_write_fn_t)(void *baton,
                                        const char *data,
@@ -780,15 +786,6 @@ typedef svn_error_t *(*svn_io_mark_fn_t)
 typedef svn_error_t *(*svn_io_seek_fn_t)(void *baton,
                                          svn_stream_mark_t *mark);
 
-/** Mark movement handler function for a generic stream. @see svn_stream_t 
- * and svn_stream_move_mark().
- *
- * @since New in 1.7.
- */
-typedef svn_error_t *(*svn_io_move_mark_fn_t)(void *baton,
-                                              svn_stream_mark_t *mark,
-                                              apr_off_t delta);
-
 /** Buffer test handler function for a generic stream. @see svn_stream_t 
  * and svn_stream_buffered().
  *
@@ -811,6 +808,14 @@ void
 svn_stream_set_read(svn_stream_t *stream,
                     svn_read_fn_t read_fn);
 
+/** Set @a stream's skip function to @a skip_fn
+ *
+ * @since New in 1.7
+ */
+void
+svn_stream_set_skip(svn_stream_t *stream,
+                    svn_skip_fn_t skip_fn);
+
 /** Set @a stream's write function to @a write_fn */
 void
 svn_stream_set_write(svn_stream_t *stream,
@@ -845,14 +850,6 @@ void
 svn_stream_set_seek(svn_stream_t *stream,
                     svn_io_seek_fn_t seek_fn);
 
-/** Set @a stream's move mark function to @a move_mark_fn
- *
- * @since New in 1.7.
- */
-void
-svn_stream_set_move_mark(svn_stream_t *stream,
-                         svn_io_move_mark_fn_t move_mark_fn);
-
 /** Set @a stream's buffer test function to @a buffered_fn
  *
  * @since New in 1.7.
@@ -1089,6 +1086,11 @@ svn_stream_read(svn_stream_t *stream,
                 char *buffer,
                 apr_size_t *len);
 
+/** Skip data from a generic stream. @see svn_stream_t. */
+svn_error_t *
+svn_stream_skip(svn_stream_t *stream,
+                apr_size_t *count);
+
 /** Write to a generic stream. @see svn_stream_t. */
 svn_error_t *
 svn_stream_write(svn_stream_t *stream,
@@ -1142,18 +1144,6 @@ svn_stream_mark(svn_stream_t *stream,
 svn_error_t *
 svn_stream_seek(svn_stream_t *stream, svn_stream_mark_t *mark);
 
-/** Move a @a mark for a generic @a stream by delta.
- * This function returns the #SVN_ERR_STREAM_SEEK_NOT_SUPPORTED error
- * if the stream doesn't implement seeking.
- *
- * @see svn_stream_mark()
- * @since New in 1.7.
- */
-svn_error_t *
-svn_stream_move_mark(svn_stream_t *stream, 
-                     svn_stream_mark_t *mark, 
-                     apr_off_t delta);
-
 /** Return whether this generic @a stream uses internal buffering.
  * This may be used to work around subtle differences between buffered
  * an non-buffered APR files.

Modified: subversion/branches/performance/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/stream.c?rev=986485&r1=986484&r2=986485&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/stream.c Tue Aug 17 21:12:12 2010
@@ -49,11 +49,11 @@ struct svn_stream_t {
   void *baton;
   svn_read_fn_t read_fn;
   svn_write_fn_t write_fn;
+  svn_skip_fn_t skip_fn;
   svn_close_fn_t close_fn;
   svn_io_reset_fn_t reset_fn;
   svn_io_mark_fn_t mark_fn;
   svn_io_seek_fn_t seek_fn;
-  svn_io_move_mark_fn_t move_mark_fn;
   svn_io_buffered_fn_t buffered_fn;
 };
 
@@ -68,12 +68,12 @@ svn_stream_create(void *baton, apr_pool_
   stream = apr_palloc(pool, sizeof(*stream));
   stream->baton = baton;
   stream->read_fn = NULL;
+  stream->skip_fn = NULL;
   stream->write_fn = NULL;
   stream->close_fn = NULL;
   stream->reset_fn = NULL;
   stream->mark_fn = NULL;
   stream->seek_fn = NULL;
-  stream->move_mark_fn = NULL;
   stream->buffered_fn = NULL;
   return stream;
 }
@@ -92,6 +92,11 @@ svn_stream_set_read(svn_stream_t *stream
   stream->read_fn = read_fn;
 }
 
+void
+svn_stream_set_skip(svn_stream_t *stream, svn_skip_fn_t skip_fn)
+{
+  stream->skip_fn = skip_fn;
+}
 
 void
 svn_stream_set_write(svn_stream_t *stream, svn_write_fn_t write_fn)
@@ -124,14 +129,7 @@ svn_stream_set_seek(svn_stream_t *stream
 }
 
 void
-svn_stream_set_move_mark(svn_stream_t *stream, 
-                         svn_io_move_mark_fn_t move_mark_fn)
-{
-  stream->move_mark_fn = move_mark_fn;
-}
-
-void
-svn_stream_set_buffered(svn_stream_t *stream, 
+svn_stream_set_buffered(svn_stream_t *stream,
                         svn_io_buffered_fn_t buffered_fn)
 {
   stream->buffered_fn = buffered_fn;
@@ -146,6 +144,14 @@ svn_stream_read(svn_stream_t *stream, ch
 
 
 svn_error_t *
+svn_stream_skip(svn_stream_t *stream, apr_size_t *count)
+{
+  SVN_ERR_ASSERT(stream->skip_fn != NULL);
+  return stream->skip_fn(stream->baton, count);
+}
+
+
+svn_error_t *
 svn_stream_write(svn_stream_t *stream, const char *data, apr_size_t *len)
 {
   SVN_ERR_ASSERT(stream->write_fn != NULL);
@@ -187,17 +193,6 @@ svn_stream_seek(svn_stream_t *stream, sv
   return stream->seek_fn(stream->baton, mark);
 }
 
-svn_error_t *
-svn_stream_move_mark(svn_stream_t *stream, 
-                     svn_stream_mark_t *mark, 
-                     apr_off_t delta)
-{
-  if (stream->move_mark_fn == NULL)
-    return svn_error_create(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED, NULL, NULL);
-
-  return stream->move_mark_fn(stream->baton, mark, delta);
-}
-
 svn_boolean_t 
 svn_stream_buffered(svn_stream_t *stream)
 {
@@ -475,8 +470,8 @@ stream_readline_chunky(svn_stringbuf_t *
 
   /* Move the stream read pointer to the first position behind the EOL.
    */
-  SVN_ERR(svn_stream_move_mark(stream, mark, total_parsed));
-  return svn_stream_seek(stream, mark);
+  SVN_ERR(svn_stream_seek(stream, mark));
+  return svn_stream_skip(stream, &total_parsed);
 }
 
 /* Guts of svn_stream_readline() and svn_stream_readline_detect_eol().
@@ -626,6 +621,29 @@ svn_stream_contents_same2(svn_boolean_t 
                                     svn_stream_close(stream2)));
 }
 
+
+/*** Stream implementation utilities ***/
+
+/* Skip data from a compressed stream by reading and discarding it. */
+static svn_error_t *
+skip_default_handler(void *baton, apr_size_t *count, svn_read_fn_t read_fn)
+{
+  apr_size_t total_bytes_read = 0;
+  apr_size_t bytes_read;
+  char buffer[4096];
+  svn_error_t *err = SVN_NO_ERROR;
+
+  while ((total_bytes_read < *count) && !err)
+    {
+      bytes_read = sizeof(buffer) < *count ? sizeof(buffer) : *count;
+      err = read_fn(baton, buffer, &bytes_read);
+      total_bytes_read += bytes_read;
+    }
+
+  *count = total_bytes_read;
+  return err;
+}
+
 
 
 /*** Generic readable empty stream ***/
@@ -637,33 +655,33 @@ read_handler_empty(void *baton, char *bu
   return SVN_NO_ERROR;
 }
 
-
 static svn_error_t *
-write_handler_empty(void *baton, const char *data, apr_size_t *len)
+skip_handler_empty(void *baton, apr_size_t *count)
 {
+  *count = 0;
   return SVN_NO_ERROR;
 }
 
 static svn_error_t *
-reset_handler_empty(void *baton)
+write_handler_empty(void *baton, const char *data, apr_size_t *len)
 {
   return SVN_NO_ERROR;
 }
 
 static svn_error_t *
-mark_handler_empty(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
+reset_handler_empty(void *baton)
 {
   return SVN_NO_ERROR;
 }
 
 static svn_error_t *
-seek_handler_empty(void *baton, svn_stream_mark_t *mark)
+mark_handler_empty(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
   return SVN_NO_ERROR;
 }
 
 static svn_error_t *
-move_mark_handler_empty(void *baton, svn_stream_mark_t *mark, apr_off_t delta)
+seek_handler_empty(void *baton, svn_stream_mark_t *mark)
 {
   return SVN_NO_ERROR;
 }
@@ -682,11 +700,11 @@ svn_stream_empty(apr_pool_t *pool)
 
   stream = svn_stream_create(NULL, pool);
   svn_stream_set_read(stream, read_handler_empty);
+  svn_stream_set_skip(stream, skip_handler_empty);
   svn_stream_set_write(stream, write_handler_empty);
   svn_stream_set_reset(stream, reset_handler_empty);
   svn_stream_set_mark(stream, mark_handler_empty);
   svn_stream_set_seek(stream, seek_handler_empty);
-  svn_stream_set_move_mark(stream, move_mark_handler_empty);
   svn_stream_set_buffered(stream, buffered_handler_empty);
   return stream;
 }
@@ -759,6 +777,12 @@ read_handler_disown(void *baton, char *b
 }
 
 static svn_error_t *
+skip_handler_disown(void *baton, apr_size_t *count)
+{
+  return svn_stream_skip(baton, count);
+}
+
+static svn_error_t *
 write_handler_disown(void *baton, const char *buffer, apr_size_t *len)
 {
   return svn_stream_write(baton, buffer, len);
@@ -782,12 +806,6 @@ seek_handler_disown(void *baton, svn_str
   return svn_stream_seek(baton, mark);
 }
 
-static svn_error_t *
-move_mark_handler_disown(void *baton, svn_stream_mark_t *mark, apr_off_t delta)
-{
-  return svn_stream_move_mark(baton, mark, delta);
-}
-
 static svn_boolean_t
 buffered_handler_disown(void *baton)
 {
@@ -800,11 +818,11 @@ svn_stream_disown(svn_stream_t *stream, 
   svn_stream_t *s = svn_stream_create(stream, pool);
 
   svn_stream_set_read(s, read_handler_disown);
+  svn_stream_set_skip(s, skip_handler_disown);
   svn_stream_set_write(s, write_handler_disown);
   svn_stream_set_reset(s, reset_handler_disown);
   svn_stream_set_mark(s, mark_handler_disown);
   svn_stream_set_seek(s, seek_handler_disown);
-  svn_stream_set_move_mark(s, move_mark_handler_disown);
   svn_stream_set_buffered(s, buffered_handler_disown);
 
   return s;
@@ -851,14 +869,21 @@ read_handler_apr(void *baton, char *buff
             }
         }
     }
-    else
-      err = svn_io_file_read_full2(btn->file, buffer, *len, len, 
-                                   TRUE, btn->pool);
+  else
+    err = svn_io_file_read_full2(btn->file, buffer, *len, len, 
+                                 TRUE, btn->pool);
 
   return err;
 }
 
 static svn_error_t *
+skip_handler_apr(void *baton, apr_size_t *count)
+{
+  struct baton_apr *btn = baton;
+  return svn_io_file_seek(btn->file, SEEK_CUR, count, btn->pool);
+}
+
+static svn_error_t *
 write_handler_apr(void *baton, const char *data, apr_size_t *len)
 {
   struct baton_apr *btn = baton;
@@ -870,8 +895,8 @@ write_handler_apr(void *baton, const cha
       if (err)
         *len = 0;
     }
-    else
-      err = svn_io_file_write_full(btn->file, data, *len, len, btn->pool);
+  else
+    err = svn_io_file_write_full(btn->file, data, *len, len, btn->pool);
 
   return err;
 }
@@ -932,16 +957,6 @@ seek_handler_apr(void *baton, svn_stream
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-move_mark_handler_apr(void *baton, svn_stream_mark_t *mark, apr_off_t delta)
-{
-  struct mark_apr *mark_apr;
-
-  mark_apr = (struct mark_apr *)mark;
-  mark_apr->off += delta;
-  return SVN_NO_ERROR;
-}
-
 static svn_boolean_t
 buffered_handler_apr(void *baton)
 {
@@ -1025,11 +1040,11 @@ stream_from_aprfile(struct baton_apr **b
   /* construct the stream vtable, except for the close() function */
   stream = svn_stream_create(new_baton, pool);
   svn_stream_set_read(stream, read_handler_apr);
+  svn_stream_set_skip(stream, skip_handler_apr);
   svn_stream_set_write(stream, write_handler_apr);
   svn_stream_set_reset(stream, reset_handler_apr);
   svn_stream_set_mark(stream, mark_handler_apr);
   svn_stream_set_seek(stream, seek_handler_apr);
-  svn_stream_set_move_mark(stream, move_mark_handler_apr);
   svn_stream_set_buffered(stream, buffered_handler_apr);
 
   /* return structures */
@@ -1126,6 +1141,47 @@ read_range_handler_apr(void *baton, char
 }
 
 
+/* A skip data handler (#svn_skip_fn_t) that forwards to skip_handler_apr()
+   but only allows reading between BATON->start and BATON->end. */
+static svn_error_t *
+skip_range_handler_apr(void *baton, apr_size_t *count)
+{
+  struct baton_apr *btn = baton;
+
+  /* ### BH: I think this can be simplified/optimized by just keeping
+             track of the current position. */
+
+  /* Check for range restriction. */
+  if (btn->start >= 0 && btn->end > 0)
+    {
+      /* Get the current file position and make sure it is in range. */
+      apr_off_t pos;
+
+      pos = 0;
+      SVN_ERR(svn_io_file_seek(btn->file, APR_CUR, &pos, btn->pool));
+      if (pos < btn->start)
+        {
+          /* We're before the range, so forward the file cursor to
+           * the start of the range. */
+          pos = btn->start;
+          SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &pos, btn->pool));
+        }
+      else if (pos >= btn->end)
+        {
+          /* We're past the range, indicate that no bytes can be read. */
+          *count = 0;
+          return SVN_NO_ERROR;
+        }
+
+      /* We're in range, but don't read over the end of the range. */
+      if (pos + *count > btn->end)
+        *count = (apr_size_t)(btn->end - pos);
+    }
+
+  return skip_handler_apr(baton, count);
+}
+
+
 svn_stream_t *
 svn_stream_from_aprfile_range_readonly(apr_file_t *file,
                                        svn_boolean_t disown,
@@ -1153,10 +1209,10 @@ svn_stream_from_aprfile_range_readonly(a
   baton->end = end;
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_range_handler_apr);
+  svn_stream_set_skip(stream, skip_range_handler_apr);
   svn_stream_set_reset(stream, reset_handler_apr);
   svn_stream_set_mark(stream, mark_handler_apr);
   svn_stream_set_seek(stream, seek_handler_apr);
-  svn_stream_set_move_mark(stream, move_mark_handler_apr);
   svn_stream_set_buffered(stream, buffered_handler_apr);
 
   if (! disown)
@@ -1332,6 +1388,13 @@ read_handler_gz(void *baton, char *buffe
   return SVN_NO_ERROR;
 }
 
+/* Skip data from a compressed stream by reading and discarding it. */
+static svn_error_t *
+skip_handler_gz(void *baton, apr_size_t *count)
+{
+  return skip_default_handler(baton, count, read_handler_gz);
+}
+
 /* Compress data and write it to the substream */
 static svn_error_t *
 write_handler_gz(void *baton, const char *buffer, apr_size_t *len)
@@ -1445,6 +1508,7 @@ svn_stream_compressed(svn_stream_t *stre
 
   zstream = svn_stream_create(baton, pool);
   svn_stream_set_read(zstream, read_handler_gz);
+  svn_stream_set_skip(zstream, skip_handler_gz);
   svn_stream_set_write(zstream, write_handler_gz);
   svn_stream_set_close(zstream, close_handler_gz);
 
@@ -1487,6 +1551,13 @@ read_handler_checksum(void *baton, char 
 
 
 static svn_error_t *
+skip_handler_checksum(void *baton, apr_size_t *count)
+{
+  return skip_default_handler(baton, count, read_handler_checksum);
+}
+
+
+static svn_error_t *
 write_handler_checksum(void *baton, const char *buffer, apr_size_t *len)
 {
   struct checksum_stream_baton *btn = baton;
@@ -1560,6 +1631,7 @@ svn_stream_checksummed2(svn_stream_t *st
 
   s = svn_stream_create(baton, pool);
   svn_stream_set_read(s, read_handler_checksum);
+  svn_stream_set_skip(s, skip_handler_checksum);
   svn_stream_set_write(s, write_handler_checksum);
   svn_stream_set_close(s, close_handler_checksum);
   return s;
@@ -1583,6 +1655,13 @@ read_handler_md5(void *baton, char *buff
 }
 
 static svn_error_t *
+skip_handler_md5(void *baton, apr_size_t *count)
+{
+  struct md5_stream_baton *btn = baton;
+  return svn_stream_skip(btn->proxy, count);
+}
+
+static svn_error_t *
 write_handler_md5(void *baton, const char *buffer, apr_size_t *len)
 {
   struct md5_stream_baton *btn = baton;
@@ -1642,6 +1721,7 @@ svn_stream_checksummed(svn_stream_t *str
    * want them) after it closes BATON->proxy. */
   s = svn_stream_create(baton, pool);
   svn_stream_set_read(s, read_handler_md5);
+  svn_stream_set_skip(s, skip_handler_md5);
   svn_stream_set_write(s, write_handler_md5);
   svn_stream_set_close(s, close_handler_md5);
   return s;
@@ -1675,6 +1755,17 @@ read_handler_stringbuf(void *baton, char
 }
 
 static svn_error_t *
+skip_handler_stringbuf(void *baton, apr_size_t *count)
+{
+  struct stringbuf_stream_baton *btn = baton;
+  apr_size_t left_to_read = btn->str->len - btn->amt_read;
+
+  *count = (*count > left_to_read) ? left_to_read : *count;
+  btn->amt_read += *count;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 write_handler_stringbuf(void *baton, const char *data, apr_size_t *len)
 {
   struct stringbuf_stream_baton *btn = baton;
@@ -1716,18 +1807,6 @@ seek_handler_stringbuf(void *baton, svn_
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-move_mark_handler_stringbuf(void *baton, 
-                            svn_stream_mark_t *mark, 
-                            apr_off_t delta)
-{
-  struct stringbuf_stream_mark *stringbuf_stream_mark;
-
-  stringbuf_stream_mark = (struct stringbuf_stream_mark *)mark;
-  stringbuf_stream_mark->pos += delta;
-  return SVN_NO_ERROR;
-}
-
 static svn_boolean_t
 buffered_handler_stringbuf(void *baton)
 {
@@ -1749,11 +1828,11 @@ svn_stream_from_stringbuf(svn_stringbuf_
   baton->amt_read = 0;
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_stringbuf);
+  svn_stream_set_skip(stream, skip_handler_stringbuf);
   svn_stream_set_write(stream, write_handler_stringbuf);
   svn_stream_set_reset(stream, reset_handler_stringbuf);
   svn_stream_set_mark(stream, mark_handler_stringbuf);
   svn_stream_set_seek(stream, seek_handler_stringbuf);
-  svn_stream_set_move_mark(stream, move_mark_handler_stringbuf);
   svn_stream_set_buffered(stream, buffered_handler_stringbuf);
   return stream;
 }
@@ -1776,6 +1855,17 @@ read_handler_string(void *baton, char *b
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+skip_handler_string(void *baton, apr_size_t *count)
+{
+  struct string_stream_baton *btn = baton;
+  apr_size_t left_to_read = btn->str->len - btn->amt_read;
+
+  *count = (*count > left_to_read) ? left_to_read : *count;
+  btn->amt_read += *count;
+  return SVN_NO_ERROR;
+}
+
 svn_stream_t *
 svn_stream_from_string(const svn_string_t *str,
                        apr_pool_t *pool)
@@ -1791,6 +1881,7 @@ svn_stream_from_string(const svn_string_
   baton->amt_read = 0;
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read(stream, read_handler_string);
+  svn_stream_set_skip(stream, skip_handler_string);
   return stream;
 }
 

Modified: subversion/branches/performance/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/subst.c?rev=986485&r1=986484&r2=986485&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/subst.c Tue Aug 17 21:12:12 2010
@@ -1191,6 +1191,28 @@ translated_stream_read(void *baton,
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_skip_fn_t. */
+static svn_error_t *
+translated_stream_skip(void *baton,
+                       apr_size_t *count)
+{
+  struct translated_stream_baton *b = baton;
+  apr_size_t total_bytes_read = 0;
+  apr_size_t bytes_read;
+  char buffer[SVN__STREAM_CHUNK_SIZE];
+  svn_error_t *err = SVN_NO_ERROR;
+
+  while ((total_bytes_read < *count) && !err)
+    {
+      bytes_read = sizeof(buffer) < *count ? sizeof(buffer) : *count;
+      err = translated_stream_read(baton, buffer, &bytes_read);
+      total_bytes_read += bytes_read;
+    }
+
+  *count = total_bytes_read;
+  return err;
+}
+
 /* Implements svn_write_fn_t. */
 static svn_error_t *
 translated_stream_write(void *baton,
@@ -1306,34 +1328,6 @@ translated_stream_seek(void *baton, svn_
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_io_move_mark_fn_t. */
-static svn_error_t *
-translated_stream_move_mark(void *baton, 
-                            svn_stream_mark_t *mark, 
-                            apr_off_t delta)
-{
-  struct translated_stream_baton *b = baton;
-  mark_translated_t *mt = (mark_translated_t *)mark;
-
-  /* Flush output buffer if necessary. */
-  if (b->written)
-    SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool));
-
-  SVN_ERR(svn_stream_move_mark(b->stream, mt->mark, delta));
-
-  /* Restore translation state, avoiding new allocations. */
-  *b->in_baton = *mt->saved_baton.in_baton;
-  *b->out_baton = *mt->saved_baton.out_baton;
-  b->written = mt->saved_baton.written;
-  svn_stringbuf_setempty(b->readbuf);
-  svn_stringbuf_appendbytes(b->readbuf, mt->saved_baton.readbuf->data, 
-                            mt->saved_baton.readbuf->len);
-  b->readbuf_off = mt->saved_baton.readbuf_off;
-  memcpy(b->buf, mt->saved_baton.buf, SVN__TRANSLATION_BUF_SIZE);
-
-  return SVN_NO_ERROR;
-}
-
 /* Implements svn_io_buffered_fn_t. */
 static svn_boolean_t
 translated_stream_buffered(void *baton)
@@ -1439,12 +1433,12 @@ svn_subst_stream_translated(svn_stream_t
 
   /* Setup the stream methods */
   svn_stream_set_read(s, translated_stream_read);
+  svn_stream_set_skip(s, translated_stream_skip);
   svn_stream_set_write(s, translated_stream_write);
   svn_stream_set_close(s, translated_stream_close);
   svn_stream_set_reset(s, translated_stream_reset);
   svn_stream_set_mark(s, translated_stream_mark);
   svn_stream_set_seek(s, translated_stream_seek);
-  svn_stream_set_move_mark(s, translated_stream_move_mark);
   svn_stream_set_buffered(s, translated_stream_buffered);
 
   return s;