return doCompressString(data);
}
-std::unique_ptr<IOBuf> Codec::uncompress(const IOBuf* data,
- uint64_t uncompressedLength) {
- if (uncompressedLength == UNKNOWN_UNCOMPRESSED_LENGTH) {
+std::unique_ptr<IOBuf> Codec::uncompress(
+ const IOBuf* data,
+ Optional<uint64_t> uncompressedLength) {
+ if (!uncompressedLength) {
if (needsUncompressedLength()) {
throw std::invalid_argument("Codec: uncompressed length required");
}
- } else if (uncompressedLength > maxUncompressedLength()) {
+ } else if (*uncompressedLength > maxUncompressedLength()) {
throw std::runtime_error("Codec: uncompressed length too large");
}
if (data->empty()) {
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != 0) {
+ if (uncompressedLength.value_or(0) != 0) {
throw std::runtime_error("Codec: invalid uncompressed length");
}
return IOBuf::create(0);
std::string Codec::uncompress(
const StringPiece data,
- uint64_t uncompressedLength) {
- if (uncompressedLength == UNKNOWN_UNCOMPRESSED_LENGTH) {
+ Optional<uint64_t> uncompressedLength) {
+ if (!uncompressedLength) {
if (needsUncompressedLength()) {
throw std::invalid_argument("Codec: uncompressed length required");
}
- } else if (uncompressedLength > maxUncompressedLength()) {
+ } else if (*uncompressedLength > maxUncompressedLength()) {
throw std::runtime_error("Codec: uncompressed length too large");
}
if (data.empty()) {
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != 0) {
+ if (uncompressedLength.value_or(0) != 0) {
throw std::runtime_error("Codec: invalid uncompressed length");
}
return "";
return {};
}
-bool Codec::canUncompress(const IOBuf*, uint64_t) const {
+bool Codec::canUncompress(const IOBuf*, Optional<uint64_t>) const {
return false;
}
std::string Codec::doUncompressString(
const StringPiece data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
const IOBuf inputBuffer{IOBuf::WRAP_BUFFER, data};
auto outputBuffer = doUncompress(&inputBuffer, uncompressedLength);
std::string output;
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
};
std::unique_ptr<Codec> NoCompressionCodec::create(int level, CodecType type) {
std::unique_ptr<IOBuf> NoCompressionCodec::doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) {
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- data->computeChainDataLength() != uncompressedLength) {
- throw std::runtime_error(to<std::string>(
- "NoCompressionCodec: invalid uncompressed length"));
+ Optional<uint64_t> uncompressedLength) {
+ if (uncompressedLength &&
+ data->computeChainDataLength() != *uncompressedLength) {
+ throw std::runtime_error(
+ to<std::string>("NoCompressionCodec: invalid uncompressed length"));
}
return data->clone();
}
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
bool highCompression_;
};
std::unique_ptr<IOBuf> LZ4Codec::doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
IOBuf clone;
if (data->isChained()) {
// LZ4 doesn't support streaming, so we have to coalesce
uint64_t actualUncompressedLength;
if (encodeSize()) {
actualUncompressedLength = decodeVarintFromCursor(cursor);
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != actualUncompressedLength) {
+ if (uncompressedLength && *uncompressedLength != actualUncompressedLength) {
throw std::runtime_error("LZ4Codec: invalid uncompressed length");
}
} else {
- actualUncompressedLength = uncompressedLength;
- if (actualUncompressedLength == UNKNOWN_UNCOMPRESSED_LENGTH ||
- actualUncompressedLength > maxUncompressedLength()) {
- throw std::runtime_error("LZ4Codec: invalid uncompressed length");
- }
+ // Invariants
+ DCHECK(uncompressedLength.hasValue());
+ DCHECK(*uncompressedLength <= maxUncompressedLength());
+ actualUncompressedLength = *uncompressedLength;
}
auto sp = StringPiece{cursor.peekBytes()};
~LZ4FrameCodec();
std::vector<std::string> validPrefixes() const override;
- bool canUncompress(const IOBuf* data, uint64_t uncompressedLength)
+ bool canUncompress(const IOBuf* data, Optional<uint64_t> uncompressedLength)
const override;
private:
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
// Reset the dctx_ if it is dirty or null.
void resetDCtx();
return {prefixToStringLE(kLZ4FrameMagicLE)};
}
-bool LZ4FrameCodec::canUncompress(const IOBuf* data, uint64_t) const {
+bool LZ4FrameCodec::canUncompress(const IOBuf* data, Optional<uint64_t>) const {
return dataStartsWithLE(data, kLZ4FrameMagicLE);
}
std::unique_ptr<IOBuf> LZ4FrameCodec::doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
// Reset the dctx if any errors have occurred
resetDCtx();
// Coalesce the data
IOBufQueue queue(IOBufQueue::cacheChainLength());
auto blockSize = uint64_t{64} << 10;
auto growthSize = uint64_t{4} << 20;
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH) {
+ if (uncompressedLength) {
// Allocate uncompressedLength in one chunk (up to 64 MB)
- const auto allocateSize = std::min(uncompressedLength, uint64_t{64} << 20);
+ const auto allocateSize = std::min(*uncompressedLength, uint64_t{64} << 20);
queue.preallocate(allocateSize, allocateSize);
- blockSize = std::min(uncompressedLength, blockSize);
- growthSize = std::min(uncompressedLength, growthSize);
+ blockSize = std::min(*uncompressedLength, blockSize);
+ growthSize = std::min(*uncompressedLength, growthSize);
} else {
// Reduce growthSize for small data
const auto guessUncompressedLen =
} while (code != 0);
// At this point the decompression context can be reused
dirty_ = false;
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- queue.chainLength() != uncompressedLength) {
+ if (uncompressedLength && queue.chainLength() != *uncompressedLength) {
throw std::runtime_error("LZ4Frame error: Invalid uncompressedLength");
}
return queue.move();
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
};
std::unique_ptr<Codec> SnappyCodec::create(int level, CodecType type) {
return out;
}
-std::unique_ptr<IOBuf> SnappyCodec::doUncompress(const IOBuf* data,
- uint64_t uncompressedLength) {
+std::unique_ptr<IOBuf> SnappyCodec::doUncompress(
+ const IOBuf* data,
+ Optional<uint64_t> uncompressedLength) {
uint32_t actualUncompressedLength = 0;
{
if (!snappy::GetUncompressedLength(&source, &actualUncompressedLength)) {
throw std::runtime_error("snappy::GetUncompressedLength failed");
}
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != actualUncompressedLength) {
+ if (uncompressedLength && *uncompressedLength != actualUncompressedLength) {
throw std::runtime_error("snappy: invalid uncompressed length");
}
}
explicit ZlibCodec(int level, CodecType type);
std::vector<std::string> validPrefixes() const override;
- bool canUncompress(const IOBuf* data, uint64_t uncompressedLength)
+ bool canUncompress(const IOBuf* data, Optional<uint64_t> uncompressedLength)
const override;
private:
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
std::unique_ptr<IOBuf> addOutputBuffer(z_stream* stream, uint32_t length);
bool doInflate(z_stream* stream, IOBuf* head, uint32_t bufferLength);
}
}
-bool ZlibCodec::canUncompress(const IOBuf* data, uint64_t) const {
+bool ZlibCodec::canUncompress(const IOBuf* data, Optional<uint64_t>) const {
if (type() == CodecType::ZLIB) {
uint16_t value;
Cursor cursor{data};
return out;
}
-std::unique_ptr<IOBuf> ZlibCodec::doUncompress(const IOBuf* data,
- uint64_t uncompressedLength) {
+std::unique_ptr<IOBuf> ZlibCodec::doUncompress(
+ const IOBuf* data,
+ Optional<uint64_t> uncompressedLength) {
z_stream stream;
stream.zalloc = nullptr;
stream.zfree = nullptr;
auto out = addOutputBuffer(
&stream,
- ((uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength <= maxSingleStepLength) ?
- uncompressedLength :
- defaultBufferLength));
+ ((uncompressedLength && *uncompressedLength <= maxSingleStepLength)
+ ? *uncompressedLength
+ : defaultBufferLength));
bool streamEnd = false;
for (auto& range : *data) {
out->prev()->trimEnd(stream.avail_out);
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != stream.total_out) {
- throw std::runtime_error(to<std::string>(
- "ZlibCodec: invalid uncompressed length"));
+ if (uncompressedLength && *uncompressedLength != stream.total_out) {
+ throw std::runtime_error(
+ to<std::string>("ZlibCodec: invalid uncompressed length"));
}
success = true; // we survived
explicit LZMA2Codec(int level, CodecType type);
std::vector<std::string> validPrefixes() const override;
- bool canUncompress(const IOBuf* data, uint64_t uncompressedLength)
+ bool canUncompress(const IOBuf* data, Optional<uint64_t> uncompressedLength)
const override;
private:
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
std::unique_ptr<IOBuf> addOutputBuffer(lzma_stream* stream, size_t length);
bool doInflate(lzma_stream* stream, IOBuf* head, size_t bufferLength);
return {prefixToStringLE(kLZMA2MagicLE, kLZMA2MagicBytes)};
}
-bool LZMA2Codec::canUncompress(const IOBuf* data, uint64_t) const {
+bool LZMA2Codec::canUncompress(const IOBuf* data, Optional<uint64_t>) const {
if (type() == CodecType::LZMA2_VARINT_SIZE) {
return false;
}
return false;
}
-std::unique_ptr<IOBuf> LZMA2Codec::doUncompress(const IOBuf* data,
- uint64_t uncompressedLength) {
+std::unique_ptr<IOBuf> LZMA2Codec::doUncompress(
+ const IOBuf* data,
+ Optional<uint64_t> uncompressedLength) {
lzma_ret rc;
lzma_stream stream = LZMA_STREAM_INIT;
folly::io::Cursor cursor(data);
if (encodeSize()) {
const uint64_t actualUncompressedLength = decodeVarintFromCursor(cursor);
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != actualUncompressedLength) {
+ if (uncompressedLength && *uncompressedLength != actualUncompressedLength) {
throw std::runtime_error("LZMA2Codec: invalid uncompressed length");
}
uncompressedLength = actualUncompressedLength;
auto out = addOutputBuffer(
&stream,
- ((uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength <= maxSingleStepLength)
- ? uncompressedLength
+ ((uncompressedLength && *uncompressedLength <= maxSingleStepLength)
+ ? *uncompressedLength
: defaultBufferLength));
bool streamEnd = false;
out->prev()->trimEnd(stream.avail_out);
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != stream.total_out) {
+ if (uncompressedLength && *uncompressedLength != stream.total_out) {
throw std::runtime_error(
to<std::string>("LZMA2Codec: invalid uncompressed length"));
}
explicit ZSTDCodec(int level, CodecType type);
std::vector<std::string> validPrefixes() const override;
- bool canUncompress(const IOBuf* data, uint64_t uncompressedLength)
+ bool canUncompress(const IOBuf* data, Optional<uint64_t> uncompressedLength)
const override;
private:
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
int level_;
};
return {prefixToStringLE(kZSTDMagicLE)};
}
-bool ZSTDCodec::canUncompress(const IOBuf* data, uint64_t) const {
+bool ZSTDCodec::canUncompress(const IOBuf* data, Optional<uint64_t>) const {
return dataStartsWithLE(data, kZSTDMagicLE);
}
static std::unique_ptr<IOBuf> zstdUncompressBuffer(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
// Check preconditions
DCHECK(!data->isChained());
- DCHECK(uncompressedLength != Codec::UNKNOWN_UNCOMPRESSED_LENGTH);
+ DCHECK(uncompressedLength.hasValue());
- auto uncompressed = IOBuf::create(uncompressedLength);
+ auto uncompressed = IOBuf::create(*uncompressedLength);
const auto decompressedSize = ZSTD_decompress(
uncompressed->writableTail(),
uncompressed->tailroom(),
static std::unique_ptr<IOBuf> zstdUncompressStream(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
auto zds = ZSTD_createDStream();
SCOPE_EXIT {
ZSTD_freeDStream(zds);
ZSTD_outBuffer out{};
ZSTD_inBuffer in{};
- auto outputSize = ZSTD_DStreamOutSize();
- if (uncompressedLength != Codec::UNKNOWN_UNCOMPRESSED_LENGTH) {
- outputSize = uncompressedLength;
- }
+ auto outputSize = uncompressedLength.value_or(ZSTD_DStreamOutSize());
IOBufQueue queue(IOBufQueue::cacheChainLength());
if (in.pos != in.size || !cursor.isAtEnd()) {
throw std::runtime_error("ZSTD: junk after end of data");
}
- if (uncompressedLength != Codec::UNKNOWN_UNCOMPRESSED_LENGTH &&
- queue.chainLength() != uncompressedLength) {
+ if (uncompressedLength && queue.chainLength() != *uncompressedLength) {
throw std::runtime_error("ZSTD: invalid uncompressed length");
}
std::unique_ptr<IOBuf> ZSTDCodec::doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
{
// Read decompressed size from frame if available in first IOBuf.
const auto decompressedSize =
ZSTD_getDecompressedSize(data->data(), data->length());
if (decompressedSize != 0) {
- if (uncompressedLength != Codec::UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != decompressedSize) {
+ if (uncompressedLength && *uncompressedLength != decompressedSize) {
throw std::runtime_error("ZSTD: invalid uncompressed length");
}
uncompressedLength = decompressedSize;
}
}
// Faster to decompress using ZSTD_decompress() if we can.
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH && !data->isChained()) {
+ if (uncompressedLength && !data->isChained()) {
return zstdUncompressBuffer(data, uncompressedLength);
}
// Fall back to slower streaming decompression.
explicit Bzip2Codec(int level, CodecType type);
std::vector<std::string> validPrefixes() const override;
- bool canUncompress(IOBuf const* data, uint64_t uncompressedLength)
+ bool canUncompress(IOBuf const* data, Optional<uint64_t> uncompressedLength)
const override;
private:
std::unique_ptr<IOBuf> doCompress(IOBuf const* data) override;
std::unique_ptr<IOBuf> doUncompress(
IOBuf const* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
int level_;
};
return {prefixToStringLE(kBzip2MagicLE, kBzip2MagicBytes)};
}
-bool Bzip2Codec::canUncompress(IOBuf const* data, uint64_t) const {
+bool Bzip2Codec::canUncompress(IOBuf const* data, Optional<uint64_t>) const {
return dataStartsWithLE(data, kBzip2MagicLE, kBzip2MagicBytes);
}
std::unique_ptr<IOBuf> Bzip2Codec::doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
bz_stream stream = createBzStream();
bzCheck(BZ2_bzDecompressInit(&stream, 0, 0));
SCOPE_EXIT {
auto out = addOutputBuffer(
&stream,
- ((uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength <= kMaxSingleStepLength)
- ? uncompressedLength
+ ((uncompressedLength && *uncompressedLength <= kMaxSingleStepLength)
+ ? *uncompressedLength
: kDefaultBufferLength));
int rc = BZ_OK;
uint64_t const totalOut =
(uint64_t(stream.total_out_hi32) << 32) + stream.total_out_lo32;
- if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
- uncompressedLength != totalOut) {
+ if (uncompressedLength && uncompressedLength != totalOut) {
throw std::runtime_error("Bzip2 error: Invalid uncompressed length");
}
explicit AutomaticCodec(std::vector<std::unique_ptr<Codec>> customCodecs);
std::vector<std::string> validPrefixes() const override;
- bool canUncompress(const IOBuf* data, uint64_t uncompressedLength)
+ bool canUncompress(const IOBuf* data, Optional<uint64_t> uncompressedLength)
const override;
private:
}
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) override;
+ Optional<uint64_t> uncompressedLength) override;
void addCodecIfSupported(CodecType type);
bool AutomaticCodec::canUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) const {
+ Optional<uint64_t> uncompressedLength) const {
return std::any_of(
codecs_.begin(),
codecs_.end(),
std::unique_ptr<IOBuf> AutomaticCodec::doUncompress(
const IOBuf* data,
- uint64_t uncompressedLength) {
+ Optional<uint64_t> uncompressedLength) {
for (auto&& codec : codecs_) {
if (codec->canUncompress(data, uncompressedLength)) {
return codec->uncompress(data, uncompressedLength);