ClickHouse/src/Compression/ICompressionCodec.cpp

78 lines
2.2 KiB
C++
Raw Normal View History

2018-12-28 18:15:26 +00:00
#include "ICompressionCodec.h"
2020-07-09 01:00:16 +00:00
#include <cassert>
2020-08-26 08:59:02 +00:00
#include <Parsers/ASTFunction.h>
2018-10-11 02:57:48 +00:00
#include <common/unaligned.h>
2020-07-09 01:00:16 +00:00
#include <Common/Exception.h>
2018-10-11 02:57:48 +00:00
2019-12-19 19:23:49 +00:00
2018-10-11 02:57:48 +00:00
namespace DB
{
namespace ErrorCodes
{
extern const int CANNOT_DECOMPRESS;
2019-12-19 19:23:49 +00:00
extern const int CORRUPTED_DATA;
2018-10-11 02:57:48 +00:00
}
2020-08-26 08:59:02 +00:00
ASTPtr ICompressionCodec::getFullCodecDesc() const
{
std::shared_ptr<ASTFunction> result = std::make_shared<ASTFunction>();
result->name = "CODEC";
result->arguments = getCodecDesc();
return result;
}
2018-12-19 17:20:18 +00:00
UInt32 ICompressionCodec::compress(const char * source, UInt32 source_size, char * dest) const
2018-10-11 02:57:48 +00:00
{
assert(source != nullptr && dest != nullptr);
2018-12-19 17:20:18 +00:00
dest[0] = getMethodByte();
UInt8 header_size = getHeaderSize();
/// Write data from header_size
UInt32 compressed_bytes_written = doCompressData(source, source_size, &dest[header_size]);
unalignedStore<UInt32>(&dest[1], compressed_bytes_written + header_size);
unalignedStore<UInt32>(&dest[5], source_size);
return header_size + compressed_bytes_written;
2018-10-11 02:57:48 +00:00
}
2018-12-19 17:20:18 +00:00
UInt32 ICompressionCodec::decompress(const char * source, UInt32 source_size, char * dest) const
2018-10-11 02:57:48 +00:00
{
assert(source != nullptr && dest != nullptr);
2019-12-19 19:23:49 +00:00
UInt8 header_size = getHeaderSize();
2019-12-19 19:23:49 +00:00
if (source_size < header_size)
2020-07-09 01:00:16 +00:00
throw Exception(ErrorCodes::CORRUPTED_DATA, "Can't decompress data: the compressed data size ({}), this should include header size) is less than the header size ({})", source_size, size_t(header_size));
2019-12-19 19:23:49 +00:00
2020-07-09 01:00:16 +00:00
uint8_t our_method = getMethodByte();
2020-01-03 14:39:24 +00:00
uint8_t method = source[0];
2020-07-09 01:00:16 +00:00
if (method != our_method)
throw Exception(ErrorCodes::CANNOT_DECOMPRESS, "Can't decompress data with codec byte {} using codec with byte {}", method, our_method);
2018-12-19 17:20:18 +00:00
2019-08-26 14:39:49 +00:00
UInt32 decompressed_size = readDecompressedBlockSize(source);
2018-12-19 17:20:18 +00:00
doDecompressData(&source[header_size], source_size - header_size, dest, decompressed_size);
return decompressed_size;
2018-10-11 02:57:48 +00:00
}
2018-12-19 17:20:18 +00:00
UInt32 ICompressionCodec::readCompressedBlockSize(const char * source)
2018-10-11 02:57:48 +00:00
{
2018-12-19 17:20:18 +00:00
return unalignedLoad<UInt32>(&source[1]);
2018-10-11 02:57:48 +00:00
}
2018-12-19 17:20:18 +00:00
UInt32 ICompressionCodec::readDecompressedBlockSize(const char * source)
{
return unalignedLoad<UInt32>(&source[5]);
}
2020-01-03 14:39:24 +00:00
uint8_t ICompressionCodec::readMethod(const char * source)
2018-12-19 17:20:18 +00:00
{
2020-01-03 14:39:24 +00:00
return static_cast<uint8_t>(source[0]);
2018-12-19 17:20:18 +00:00
}
2018-10-11 02:57:48 +00:00
}