xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
basics
CompressionAlgorithms.h
1
#pragma once
2
3
#include <xrpl/basics/contract.h>
4
5
#include <lz4.h>
6
7
#include <
algorithm
>
8
#include <
cstddef
>
9
#include <
cstdint
>
10
#include <
stdexcept
>
11
#include <
vector
>
12
13
namespace
xrpl::compression_algorithms
{
14
24
template
<
typename
BufferFactory>
25
std::size_t
26
lz4Compress
(
void
const
* in,
std::size_t
inSize, BufferFactory&& bf)
27
{
28
if
(inSize > UINT32_MAX)
29
Throw<std::runtime_error>
(
"lz4 compress: invalid size"
);
30
31
auto
const
outCapacity = LZ4_compressBound(inSize);
32
33
// Request the caller to allocate and return the buffer to hold compressed
34
// data
35
auto
compressed = bf(outCapacity);
36
37
auto
compressedSize = LZ4_compress_default(
38
reinterpret_cast<
char
const*
>
(in),
39
reinterpret_cast<
char
*
>
(compressed),
40
inSize,
41
outCapacity);
42
if
(compressedSize == 0)
43
Throw<std::runtime_error>
(
"lz4 compress: failed"
);
44
45
return
compressedSize;
46
}
47
55
inline
std::size_t
56
lz4Decompress
(
57
std::uint8_t
const
* in,
58
std::size_t
inSizeUnchecked,
59
std::uint8_t
* decompressed,
60
std::size_t
decompressedSizeUnchecked)
61
{
62
int
const
inSize =
static_cast<
int
>
(inSizeUnchecked);
63
int
const
decompressedSize =
static_cast<
int
>
(decompressedSizeUnchecked);
64
65
if
(inSize <= 0)
66
Throw<std::runtime_error>
(
"lz4Decompress: integer overflow (input)"
);
67
68
if
(decompressedSize <= 0)
69
Throw<std::runtime_error>
(
"lz4Decompress: integer overflow (output)"
);
70
71
// NOLINTNEXTLINE(readability-suspicious-call-argument)
72
if
(LZ4_decompress_safe(
73
reinterpret_cast<
char
const*
>
(in),
74
reinterpret_cast<
char
*
>
(decompressed),
75
inSize,
76
decompressedSize) != decompressedSize)
77
{
78
Throw<std::runtime_error>
(
"lz4Decompress: failed"
);
79
}
80
81
return
decompressedSize;
82
}
83
93
template
<
typename
InputStream>
94
std::size_t
95
lz4Decompress
(
96
InputStream& in,
97
std::size_t
inSize,
98
std::uint8_t
* decompressed,
99
std::size_t
decompressedSize)
100
{
101
std::vector<std::uint8_t>
compressed;
102
std::uint8_t
const
* chunk =
nullptr
;
103
int
chunkSize = 0;
104
int
copiedInSize = 0;
105
auto
const
currentBytes = in.ByteCount();
106
107
// Use the first chunk if it is >= inSize bytes of the compressed message.
108
// Otherwise copy inSize bytes of chunks into compressed buffer and
109
// use the buffer to decompress.
110
while
(in.Next(
reinterpret_cast<
void
const**
>
(&chunk), &chunkSize))
111
{
112
if
(copiedInSize == 0)
113
{
114
if
(chunkSize >= inSize)
115
{
116
copiedInSize = inSize;
117
break
;
118
}
119
compressed.
resize
(inSize);
120
}
121
122
chunkSize = chunkSize < (inSize - copiedInSize) ? chunkSize : (inSize - copiedInSize);
123
124
std::copy
(chunk, chunk + chunkSize, compressed.
data
() + copiedInSize);
125
126
copiedInSize += chunkSize;
127
128
if
(copiedInSize == inSize)
129
{
130
chunk = compressed.
data
();
131
break
;
132
}
133
}
134
135
// Put back unused bytes
136
if
(in.ByteCount() > (currentBytes + copiedInSize))
137
in.BackUp(in.ByteCount() - currentBytes - copiedInSize);
138
139
if
((copiedInSize == 0 && chunkSize < inSize) || (copiedInSize > 0 && copiedInSize != inSize))
140
Throw<std::runtime_error>
(
"lz4 decompress: insufficient input size"
);
141
142
return
lz4Decompress
(chunk, inSize, decompressed, decompressedSize);
143
}
144
145
}
// namespace xrpl::compression_algorithms
algorithm
std::copy
T copy(T... args)
cstddef
cstdint
std::vector::data
T data(T... args)
std::uint8_t
xrpl::compression_algorithms
Definition
CompressionAlgorithms.h:13
xrpl::compression_algorithms::lz4Decompress
std::size_t lz4Decompress(std::uint8_t const *in, std::size_t inSizeUnchecked, std::uint8_t *decompressed, std::size_t decompressedSizeUnchecked)
Definition
CompressionAlgorithms.h:56
xrpl::compression_algorithms::lz4Compress
std::size_t lz4Compress(void const *in, std::size_t inSize, BufferFactory &&bf)
LZ4 block compression.
Definition
CompressionAlgorithms.h:26
xrpl::Throw
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition
contract.h:52
std::vector::resize
T resize(T... args)
std::size_t
stdexcept
vector
Generated by
1.17.0