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 2012/07/07 09:27:24 UTC

svn commit: r1358515 - in /subversion/trunk/subversion: include/private/svn_delta_private.h libsvn_delta/svndiff.c

Author: stefan2
Date: Sat Jul  7 07:27:23 2012
New Revision: 1358515

URL: http://svn.apache.org/viewvc?rev=1358515&view=rev
Log:
Provide a simple API that allows us to compress / decompress
a given block of data without creating delta streams an such.

Update the underlying zlib_* functions to be a better fit
for the new API.

* subversion/include/private/svn_delta_private.h
  (svn__compress, svn__decompress): declare new private API

* subversion/libsvn_delta/svndiff.c
  (zlib_encode): make sure to overwrite the OUT buffer;
   update docstring
  (zlib_decode): add copyless_allowed parameter;
   update docstring
  (decode_window): update caller
  (svn__compress, svn__decompress): implement new API

Modified:
    subversion/trunk/subversion/include/private/svn_delta_private.h
    subversion/trunk/subversion/libsvn_delta/svndiff.c

Modified: subversion/trunk/subversion/include/private/svn_delta_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_delta_private.h?rev=1358515&r1=1358514&r2=1358515&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_delta_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_delta_private.h Sat Jul  7 07:27:23 2012
@@ -101,6 +101,25 @@ svn_delta__delta_from_editor(const svn_d
                              struct svn_delta__extra_baton *exb,
                              apr_pool_t *pool);
 
+/**
+ * Get the data from IN, compress it according to the specified
+ * COMPRESSION_LEVEL and write the result to OUT.
+ * SVN_DELTA_COMPRESSION_LEVEL_NONE is valid for COMPRESSION_LEVEL.
+ */
+svn_error_t *
+svn__compress(svn_string_t *in,
+              svn_stringbuf_t *out,
+              int compression_level);
+
+/**
+ * Get the compressed data from IN, decompress it and write the result to
+ * OUT.  Return an error if the decompressed size is larger than LIMIT.
+ */
+svn_error_t *
+svn__decompress(svn_string_t *in,
+                svn_stringbuf_t *out,
+                apr_size_t limit);
+
 
 #ifdef __cplusplus
 }

Modified: subversion/trunk/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/svndiff.c?rev=1358515&r1=1358514&r2=1358515&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/trunk/subversion/libsvn_delta/svndiff.c Sat Jul  7 07:27:23 2012
@@ -129,11 +129,12 @@ append_encoded_int(svn_stringbuf_t *head
   svn_stringbuf_appendbytes(header, (const char *)buf, p - buf);
 }
 
-/* If IN is a string that is >= MIN_COMPRESS_SIZE, zlib compress it and
-   place the result in OUT, with an integer prepended specifying the
-   original size.  If IN is < MIN_COMPRESS_SIZE, or if the compressed
-   version of IN was no smaller than the original IN, OUT will be a copy
-   of IN with the size prepended as an integer. */
+/* If IN is a string that is >= MIN_COMPRESS_SIZE and the COMPRESSION_LEVEL
+   is not SVN_DELTA_COMPRESSION_LEVEL_NONE, zlib compress it and places the
+   result in OUT, with an integer prepended specifying the original size.
+   If IN is < MIN_COMPRESS_SIZE, or if the compressed version of IN was no
+   smaller than the original IN, OUT will be a copy of IN with the size
+   prepended as an integer. */
 static svn_error_t *
 zlib_encode(const char *data,
             apr_size_t len,
@@ -143,6 +144,7 @@ zlib_encode(const char *data,
   unsigned long endlen;
   apr_size_t intlen;
 
+  svn_stringbuf_setempty(out);
   append_encoded_int(out, len);
   intlen = out->len;
 
@@ -441,12 +443,13 @@ decode_size(apr_size_t *val,
    the original size, and that if encoded size == original size, that the
    remaining data is not compressed.
    In that case, we will simply return pointer into IN as data pointer for
-   OUT.  The caller is expected not to modify the contents of OUT.
+   OUT, COPYLESS_ALLOWED has been set.  The, the caller is expected not to
+   modify the contents of OUT.
    An error is returned if the decoded length exceeds the given LIMIT.
  */
 static svn_error_t *
 zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
-            apr_size_t limit)
+            apr_size_t limit, svn_boolean_t copyless_allowed)
 {
   apr_size_t len;
   const unsigned char *oldplace = in;
@@ -465,12 +468,21 @@ zlib_decode(const unsigned char *in, apr
   inLen -= (in - oldplace);
   if (inLen == len)
     {
-      /* "in" is no longer used but the memory remains allocated for
-       * at least as long as "out" will be used by the caller.
-       */
-      out->data = (char *)in;
-      out->len = len;
-      out->blocksize = len; /* sic! */
+      if (copyless_allowed)
+        {
+          /* "in" is no longer used but the memory remains allocated for
+           * at least as long as "out" will be used by the caller.
+           */
+          out->data = (char *)in;
+          out->len = len;
+          out->blocksize = len; /* sic! */
+        }
+      else
+        {
+          svn_stringbuf_ensure(out, len);
+          memcpy(out->data, in, len);
+          out->data[len] = 0;
+        }
 
       return SVN_NO_ERROR;
     }
@@ -647,9 +659,9 @@ decode_window(svn_txdelta_window_t *wind
       /* these may in fact simply return references to insend */
 
       SVN_ERR(zlib_decode(insend, newlen, ndout,
-                          SVN_DELTA_WINDOW_SIZE));
+                          SVN_DELTA_WINDOW_SIZE, TRUE));
       SVN_ERR(zlib_decode(data, insend - data, instout,
-                          MAX_INSTRUCTION_SECTION_LEN));
+                          MAX_INSTRUCTION_SECTION_LEN, TRUE));
 
       newlen = ndout->len;
       data = (unsigned char *)instout->data;
@@ -987,3 +999,22 @@ svn_txdelta_skip_svndiff_window(apr_file
   offset = inslen + newlen;
   return svn_io_file_seek(file, APR_CUR, &offset, pool);
 }
+
+
+svn_error_t *
+svn__compress(svn_string_t *in,
+              svn_stringbuf_t *out,
+              int compression_level)
+{
+  return zlib_encode((const unsigned char*)in->data, in->len, out,
+                     compression_level);
+}
+
+svn_error_t *
+svn__decompress(svn_string_t *in,
+                svn_stringbuf_t *out,
+                apr_size_t limit)
+{
+  return zlib_decode((const unsigned char*)in->data, in->len, out, limit,
+                     FALSE);
+}