2 * compress_lz4.c: LZ4 data compression routines
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
26 #include "private/svn_subr_private.h"
28 #include "svn_private_config.h"
30 #ifdef SVN_INTERNAL_LZ4
31 #include "lz4/lz4internal.h"
37 svn__compress_lz4(const void *data
, apr_size_t len
,
41 unsigned char buf
[SVN__MAX_ENCODED_UINT_LEN
];
43 int compressed_data_len
;
44 int max_compressed_data_len
;
46 assert(len
<= LZ4_MAX_INPUT_SIZE
);
48 p
= svn__encode_uint(buf
, (apr_uint64_t
)len
);
50 max_compressed_data_len
= LZ4_compressBound((int)len
);
51 svn_stringbuf_setempty(out
);
52 svn_stringbuf_ensure(out
, max_compressed_data_len
+ hdrlen
);
53 svn_stringbuf_appendbytes(out
, (const char *)buf
, hdrlen
);
54 compressed_data_len
= LZ4_compress_default(data
, out
->data
+ out
->len
,
55 (int)len
, max_compressed_data_len
);
56 if (!compressed_data_len
)
57 return svn_error_create(SVN_ERR_LZ4_COMPRESSION_FAILED
, NULL
, NULL
);
59 if (compressed_data_len
>= (int)len
)
61 /* Compression didn't help :(, just append the original text */
62 svn_stringbuf_appendbytes(out
, data
, len
);
66 out
->len
+= compressed_data_len
;
67 out
->data
[out
->len
] = 0;
74 svn__decompress_lz4(const void *data
, apr_size_t len
,
79 int compressed_data_len
;
80 int decompressed_data_len
;
82 const unsigned char *p
= data
;
85 assert(len
<= INT_MAX
);
86 assert(limit
<= INT_MAX
);
88 /* First thing in the string is the original length. */
89 p
= svn__decode_uint(&u64
, p
, p
+ len
);
91 return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA
, NULL
,
92 _("Decompression of compressed data failed: "
95 return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA
, NULL
,
96 _("Decompression of compressed data failed: "
98 decompressed_data_len
= (int)u64
;
99 hdrlen
= p
- (const unsigned char *)data
;
100 compressed_data_len
= (int)(len
- hdrlen
);
102 svn_stringbuf_setempty(out
);
103 svn_stringbuf_ensure(out
, decompressed_data_len
);
105 if (compressed_data_len
== decompressed_data_len
)
107 /* Data is in the original, uncompressed form. */
108 memcpy(out
->data
, p
, decompressed_data_len
);
112 rv
= LZ4_decompress_safe((const char *)p
, out
->data
, compressed_data_len
,
113 decompressed_data_len
);
115 return svn_error_create(SVN_ERR_LZ4_DECOMPRESSION_FAILED
, NULL
, NULL
);
117 if (rv
!= decompressed_data_len
)
118 return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA
,
120 _("Size of uncompressed data "
121 "does not match stored original length"));
124 out
->data
[decompressed_data_len
] = 0;
125 out
->len
= decompressed_data_len
;
131 svn_lz4__compiled_version(void)
133 static const char lz4_version_str
[] = APR_STRINGIFY(LZ4_VERSION_MAJOR
) "." \
134 APR_STRINGIFY(LZ4_VERSION_MINOR
) "." \
135 APR_STRINGIFY(LZ4_VERSION_RELEASE
);
137 return lz4_version_str
;
141 svn_lz4__runtime_version(void)
143 return LZ4_versionNumber();