Exemplo n.º 1
0
svn_error_t *
svn_fs_x__write_properties(svn_stream_t *stream,
                           apr_hash_t *proplist,
                           apr_pool_t *scratch_pool)
{
  apr_byte_t buffer[SVN__MAX_ENCODED_UINT_LEN];
  apr_size_t len;
  apr_hash_index_t *hi;

  /* Write the number of properties in this list. */
  len = svn__encode_uint(buffer, apr_hash_count(proplist)) - buffer;
  SVN_ERR(svn_stream_write(stream, (const char *)buffer, &len));

  /* Serialize each property as follows:
     <Prop-name> <NUL>
     <Value-len> <Prop-value> <NUL>
   */
  for (hi = apr_hash_first(scratch_pool, proplist);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *key;
      apr_size_t key_len;
      svn_string_t *value;
      apr_hash_this(hi, (const void **)&key, (apr_ssize_t *)&key_len,
                    (void **)&value);

      /* Include the terminating NUL. */
      ++key_len;
      SVN_ERR(svn_stream_write(stream, key, &key_len));

      len = svn__encode_uint(buffer, value->len) - buffer;
      SVN_ERR(svn_stream_write(stream, (const char *)buffer, &len));
      SVN_ERR(svn_stream_write(stream, value->data, &value->len));

      /* Terminate with NUL. */
      len = 1;
      SVN_ERR(svn_stream_write(stream, "", &len));
    }

  return SVN_NO_ERROR;
}
Exemplo n.º 2
0
/* 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,
            svn_stringbuf_t *out,
            int compression_level)
{
  unsigned long endlen;
  apr_size_t intlen;
  unsigned char buf[SVN__MAX_ENCODED_UINT_LEN], *p;

  svn_stringbuf_setempty(out);
  p = svn__encode_uint(buf, (apr_uint64_t)len);
  svn_stringbuf_appendbytes(out, (const char *)buf, p - buf);

  intlen = out->len;

  /* Compression initialization overhead is considered to large for
     short buffers.  Also, if we don't actually want to compress data,
     ZLIB will produce an output no shorter than the input.  Hence,
     the DATA would directly appended to OUT, so we can do that directly
     without calling ZLIB before. */
  if (len < MIN_COMPRESS_SIZE || compression_level == SVN__COMPRESSION_NONE)
    {
      svn_stringbuf_appendbytes(out, data, len);
    }
  else
    {
      int zerr;

      svn_stringbuf_ensure(out, svnCompressBound(len) + intlen);
      endlen = out->blocksize;

      zerr = compress2((unsigned char *)out->data + intlen, &endlen,
                       (const unsigned char *)data, len,
                       compression_level);
      if (zerr != Z_OK)
        return svn_error_trace(svn_error__wrap_zlib(
                                 zerr, "compress2",
                                 _("Compression of svndiff data failed")));

      /* Compression didn't help :(, just append the original text */
      if (endlen >= len)
        {
          svn_stringbuf_appendbytes(out, data, len);
          return SVN_NO_ERROR;
        }
      out->len = endlen + intlen;
      out->data[out->len] = 0;
    }
  return SVN_NO_ERROR;
}