20 #ifndef RIPPLE_NODESTORE_CODEC_H_INCLUDED
21 #define RIPPLE_NODESTORE_CODEC_H_INCLUDED
24 #define LZ4_DISABLE_DEPRECATE_WARNINGS
26 #include <ripple/basics/contract.h>
27 #include <ripple/basics/safe_cast.h>
28 #include <ripple/nodestore/NodeObject.h>
29 #include <ripple/nodestore/impl/varint.h>
30 #include <ripple/protocol/HashPrefix.h>
34 #include <nudb/detail/field.hpp>
41 template <
class BufferFactory>
45 if (
static_cast<int>(in_size) < 0)
46 Throw<std::runtime_error>(
"lz4_decompress: integer overflow (input)");
53 if (n == 0 || n >= in_size)
54 Throw<std::runtime_error>(
"lz4_decompress: invalid blob");
56 if (
static_cast<int>(outSize) <= 0)
57 Throw<std::runtime_error>(
"lz4_decompress: integer overflow (output)");
59 void*
const out = bf(outSize);
61 if (LZ4_decompress_safe(
62 reinterpret_cast<char const*
>(
in) + n,
63 reinterpret_cast<char*
>(
out),
64 static_cast<int>(in_size - n),
65 static_cast<int>(outSize)) !=
static_cast<int>(outSize))
66 Throw<std::runtime_error>(
"lz4_decompress: LZ4_decompress_safe");
68 return {
out, outSize};
71 template <
class BufferFactory>
76 using namespace nudb::detail;
80 auto const out_max = LZ4_compressBound(in_size);
84 auto const out_size = LZ4_compress_default(
85 reinterpret_cast<char const*
>(
in),
86 reinterpret_cast<char*
>(
out + n),
90 Throw<std::runtime_error>(
"lz4 compress");
91 result.
second = n + out_size;
106 template <
class BufferFactory>
110 using namespace nudb::detail;
116 Throw<std::runtime_error>(
"nodeobject decompress");
136 auto const hs = field<std::uint16_t>::size;
137 if (in_size < hs + 32)
138 Throw<std::runtime_error>(
139 "nodeobject codec v1: short inner node size: " +
142 istream is(p, in_size);
144 read<std::uint16_t>(is, mask);
150 write<std::uint32_t>(os, 0);
151 write<std::uint32_t>(os, 0);
153 write<std::uint32_t>(
156 Throw<std::runtime_error>(
157 "nodeobject codec v1: empty inner node");
159 for (
int i = 16; i--; bit >>= 1)
164 Throw<std::runtime_error>(
165 "nodeobject codec v1: short inner node subsize: " +
178 Throw<std::runtime_error>(
179 "nodeobject codec v1: long inner node, in_size = " +
185 if (in_size != 16 * 32)
186 Throw<std::runtime_error>(
187 "nodeobject codec v1: short full inner node, in_size = " +
189 istream is(p, in_size);
194 write<std::uint32_t>(os, 0);
195 write<std::uint32_t>(os, 0);
197 write<std::uint32_t>(
199 write(os, is(512), 512);
203 Throw<std::runtime_error>(
209 template <
class =
void>
217 template <
class BufferFactory>
222 using namespace nudb::detail;
227 istream is(
in, in_size);
232 read<std::uint32_t>(is, index);
233 read<std::uint32_t>(is, unused);
234 read<std::uint8_t>(is, kind);
235 read<std::uint32_t>(is, prefix);
241 for (
unsigned bit = 0x8000; bit; bit >>= 1)
243 void const*
const h = is(32);
254 auto const type = 2U;
256 result.
second = vs + field<std::uint16_t>::size +
262 write<varint>(os, type);
263 write<std::uint16_t>(os, mask);
268 auto const type = 3U;
270 result.
second = vs + n * 32;
275 write<varint>(os, type);
299 result.
second = vn + lzr.second;
303 Throw<std::logic_error>(
313 template <
class =
void>
317 using namespace nudb::detail;
322 istream is(
in, in_size);
327 read<std::uint32_t>(is, index);
328 read<std::uint32_t>(is, unused);
329 read<std::uint8_t>(is, kind);
330 read<std::uint32_t>(is, prefix);
334 write<std::uint32_t>(os, 0);
335 write<std::uint32_t>(os, 0);