[GS] Implemented lzma compression.

This commit is contained in:
grzegorzs 2014-01-22 14:28:21 +01:00
parent c72ed39acd
commit 8ad02176c6
5 changed files with 213 additions and 3 deletions

View file

@ -58,6 +58,8 @@ option( UNITY_BUILD OFF )
include_directories( ${Boost_INCLUDE_DIR} )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/vendor/salsa20 )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/vendor/easylzma/src )
FIND_PACKAGE( OpenSSL )
include_directories( ${OPENSSL_INCLUDE_DIR} )
SET( ALL_OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES} ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE})
@ -130,6 +132,7 @@ set( fc_sources
src/network/resolve.cpp
src/network/url.cpp
src/compress/smaz.cpp
src/compress/lzma.cpp
vendor/cyoencode-1.0.2/src/CyoDecode.c
vendor/cyoencode-1.0.2/src/CyoEncode.c
# vendor/salsa20/ecrypt.c
@ -151,6 +154,8 @@ add_subdirectory( vendor/easylzma )
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC )
target_link_libraries( fc easylzma_static )
set( BOOST_LIBRARIES ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_CHRONO_LIBRARY} ${ALL_OPENSSL_LIBRARIES} ${Boost_COROUTINE_LIBRARY} ${Boost_CONTEXT_LIBRARY} )
set( BOOST_LIBRARIES ${BOOST_LIBRARIES} PARENT_SCOPE )

View file

@ -1,12 +1,53 @@
#include <fc/compress/lzma.hpp>
#include <fc/exception/exception.hpp>
#include <lzma_c.h>
namespace fc {
std::vector<char> lzma_compress( const std::vector<char>& in )
std::vector<char> lzma_compress(const std::vector<char>& in)
{
FC_ASSERT(!in.empty());
const unsigned char* in_data = reinterpret_cast<const unsigned char*> (&in[0]);;
unsigned char* out_data;
size_t out_len = 0;
int ret = simpleCompress(elzma_file_format::ELZMA_lzma, in_data, in.size(),
&out_data, &out_len);
if(ret != 0)
{
FC_ASSERT(0);
return std::vector<char>();
}
std::vector<char> lzma_decompress( const std::vector<char>& compressed )
std::vector<char> out(out_data, out_data+out_len);
return out;
}
std::vector<char> lzma_decompress( const std::vector<char>& compressed )
{
FC_ASSERT(!compressed.empty());
const unsigned char* in_data = reinterpret_cast<const unsigned char*> (&compressed[0]);;
unsigned char* out_data;
size_t out_len = 0;
int ret = simpleDecompress(elzma_file_format::ELZMA_lzma, in_data, compressed.size(),
&out_data, &out_len);
if(ret != 0)
{
FC_ASSERT(0);
return std::vector<char>();
}
std::vector<char> out(out_data, out_data+out_len);
return out;
}
} // namespace fc

View file

@ -39,7 +39,7 @@ elzma_compress_alloc()
hand->props.lc = 3;
hand->props.lp = 0;
hand->props.pb = 2;
hand->props.level = 5;
hand->props.level = 9;
hand->props.algo = 1;
hand->props.fb = 32;
hand->props.dictSize = 1 << 24;

130
vendor/easylzma/src/lzma_c.c vendored Normal file
View file

@ -0,0 +1,130 @@
#include "lzma_c.h"
#include <string.h>
#include <assert.h>
struct dataStream
{
const unsigned char * inData;
size_t inLen;
unsigned char * outData;
size_t outLen;
};
static int
inputCallback(void *ctx, void *buf, size_t * size)
{
size_t rd = 0;
struct dataStream * ds = (struct dataStream *) ctx;
assert(ds != NULL);
rd = (ds->inLen < *size) ? ds->inLen : *size;
if (rd > 0) {
memcpy(buf, (void *) ds->inData, rd);
ds->inData += rd;
ds->inLen -= rd;
}
*size = rd;
return 0;
}
static size_t
outputCallback(void *ctx, const void *buf, size_t size)
{
struct dataStream * ds = (struct dataStream *) ctx;
assert(ds != NULL);
if (size > 0) {
ds->outData = realloc(ds->outData, ds->outLen + size);
memcpy((void *) (ds->outData + ds->outLen), buf, size);
ds->outLen += size;
}
return size;
}
int
simpleCompress(elzma_file_format format, const unsigned char * inData,
size_t inLen, unsigned char ** outData,
size_t * outLen)
{
int rc = 0;
elzma_compress_handle hand;
/* allocate compression handle */
hand = elzma_compress_alloc();
assert(hand != NULL);
rc = elzma_compress_config(hand, ELZMA_LC_DEFAULT,
ELZMA_LP_DEFAULT, ELZMA_PB_DEFAULT,
5, (1 << 20) /* 1mb */,
format, inLen);
if (rc != ELZMA_E_OK) {
elzma_compress_free(&hand);
return rc;
}
/* now run the compression */
{
struct dataStream ds;
ds.inData = inData;
ds.inLen = inLen;
ds.outData = NULL;
ds.outLen = 0;
rc = elzma_compress_run(hand, inputCallback, (void *) &ds,
outputCallback, (void *) &ds,
NULL, NULL);
if (rc != ELZMA_E_OK) {
if (ds.outData != NULL) free(ds.outData);
elzma_compress_free(&hand);
return rc;
}
*outData = ds.outData;
*outLen = ds.outLen;
}
return rc;
}
int
simpleDecompress(elzma_file_format format, const unsigned char * inData,
size_t inLen, unsigned char ** outData,
size_t * outLen)
{
int rc = 0;
elzma_decompress_handle hand;
hand = elzma_decompress_alloc();
/* now run the compression */
{
struct dataStream ds;
ds.inData = inData;
ds.inLen = inLen;
ds.outData = NULL;
ds.outLen = 0;
rc = elzma_decompress_run(hand, inputCallback, (void *) &ds,
outputCallback, (void *) &ds, format);
if (rc != ELZMA_E_OK) {
if (ds.outData != NULL) free(ds.outData);
elzma_decompress_free(&hand);
return rc;
}
*outData = ds.outData;
*outLen = ds.outLen;
}
return rc;
}

34
vendor/easylzma/src/lzma_c.h vendored Normal file
View file

@ -0,0 +1,34 @@
#ifndef __LZMA_C_H__
#define __LZMA_C_H__
#include <stdlib.h>
#include "easylzma/compress.h"
#include "easylzma/decompress.h"
#ifdef __cplusplus
extern "C" {
#endif
/* compress a chunk of memory and return a dynamically allocated buffer
* if successful. return value is an easylzma error code */
int simpleCompress(elzma_file_format format,
const unsigned char * inData,
size_t inLen,
unsigned char ** outData,
size_t * outLen);
/* decompress a chunk of memory and return a dynamically allocated buffer
* if successful. return value is an easylzma error code */
int simpleDecompress(elzma_file_format format,
const unsigned char * inData,
size_t inLen,
unsigned char ** outData,
size_t * outLen);
#ifdef __cplusplus
};
#endif
#endif