1#include "ICompressionCodec.h"
2
3#include <Compression/LZ4_decompress_faster.h>
4#include <common/unaligned.h>
5#include <Common/hex.h>
6#include <IO/WriteHelpers.h>
7#include <IO/ReadBufferFromFileBase.h>
8#include <Common/typeid_cast.h>
9#include <Compression/CompressionFactory.h>
10
11
12namespace ProfileEvents
13{
14 extern const Event ReadCompressedBytes;
15 extern const Event CompressedReadBufferBlocks;
16 extern const Event CompressedReadBufferBytes;
17}
18
19namespace DB
20{
21
22namespace ErrorCodes
23{
24 extern const int CHECKSUM_DOESNT_MATCH;
25 extern const int TOO_LARGE_SIZE_COMPRESSED;
26 extern const int UNKNOWN_COMPRESSION_METHOD;
27 extern const int CANNOT_DECOMPRESS;
28 extern const int SEEK_POSITION_OUT_OF_BOUND;
29 extern const int CORRUPTED_DATA;
30}
31
32
33UInt32 ICompressionCodec::compress(const char * source, UInt32 source_size, char * dest) const
34{
35 dest[0] = getMethodByte();
36 UInt8 header_size = getHeaderSize();
37 /// Write data from header_size
38 UInt32 compressed_bytes_written = doCompressData(source, source_size, &dest[header_size]);
39 unalignedStore<UInt32>(&dest[1], compressed_bytes_written + header_size);
40 unalignedStore<UInt32>(&dest[5], source_size);
41 return header_size + compressed_bytes_written;
42}
43
44
45UInt32 ICompressionCodec::decompress(const char * source, UInt32 source_size, char * dest) const
46{
47 UInt8 header_size = getHeaderSize();
48
49 if (source_size < header_size)
50 throw Exception("Can't decompress data: the compressed data size (" + toString(source_size)
51 + ", this should include header size) is less than the header size (" + toString(header_size) + ")", ErrorCodes::CORRUPTED_DATA);
52
53 UInt8 method = source[0];
54 if (method != getMethodByte())
55 throw Exception("Can't decompress data with codec byte " + toString(method) + " from codec with byte " + toString(method), ErrorCodes::CANNOT_DECOMPRESS);
56
57 UInt32 decompressed_size = readDecompressedBlockSize(source);
58 doDecompressData(&source[header_size], source_size - header_size, dest, decompressed_size);
59
60 return decompressed_size;
61}
62
63UInt32 ICompressionCodec::readCompressedBlockSize(const char * source)
64{
65 return unalignedLoad<UInt32>(&source[1]);
66}
67
68
69UInt32 ICompressionCodec::readDecompressedBlockSize(const char * source)
70{
71 return unalignedLoad<UInt32>(&source[5]);
72}
73
74
75UInt8 ICompressionCodec::readMethod(const char * source)
76{
77 return static_cast<UInt8>(source[0]);
78}
79
80}
81