/*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return data->clone();
}
+#if (FOLLY_HAVE_LIBLZ4 || FOLLY_HAVE_LIBLZMA)
+
namespace {
void encodeVarintToIOBuf(uint64_t val, folly::IOBuf* out) {
out->append(encodeVarint(val, out->writableTail()));
}
-uint64_t decodeVarintFromCursor(folly::io::Cursor& cursor) {
- // Must have enough room in *this* buffer.
- auto p = cursor.peek();
- folly::ByteRange range(p.first, p.second);
- uint64_t val = decodeVarint(range);
- cursor.skip(range.data() - p.first);
+inline uint64_t decodeVarintFromCursor(folly::io::Cursor& cursor) {
+ uint64_t val = 0;
+ int8_t b = 0;
+ for (int shift = 0; shift <= 63; shift += 7) {
+ b = cursor.read<int8_t>();
+ val |= static_cast<uint64_t>(b & 0x7f) << shift;
+ if (b >= 0) {
+ break;
+ }
+ }
+ if (b < 0) {
+ throw std::invalid_argument("Invalid varint value. Too big.");
+ }
return val;
}
} // namespace
+#endif // FOLLY_HAVE_LIBLZ4 || FOLLY_HAVE_LIBLZMA
+
#if FOLLY_HAVE_LIBLZ4
/**
p.second,
actualUncompressedLength);
- if (n != actualUncompressedLength) {
+ if (n < 0 || uint64_t(n) != actualUncompressedLength) {
throw std::runtime_error(to<std::string>(
"LZ4 decompression returned invalid value ", n));
}
defaultBufferLength));
for (auto& range : *data) {
- if (range.empty()) {
- continue;
- }
-
- stream.next_in = const_cast<uint8_t*>(range.data());
- stream.avail_in = range.size();
-
- while (stream.avail_in != 0) {
- if (stream.avail_out == 0) {
- out->prependChain(addOutputBuffer(&stream, defaultBufferLength));
+ uint64_t remaining = range.size();
+ uint64_t written = 0;
+ while (remaining) {
+ uint32_t step = (remaining > maxSingleStepLength ?
+ maxSingleStepLength : remaining);
+ stream.next_in = const_cast<uint8_t*>(range.data() + written);
+ stream.avail_in = step;
+ remaining -= step;
+ written += step;
+
+ while (stream.avail_in != 0) {
+ if (stream.avail_out == 0) {
+ out->prependChain(addOutputBuffer(&stream, defaultBufferLength));
+ }
+
+ rc = deflate(&stream, Z_NO_FLUSH);
+
+ CHECK_EQ(rc, Z_OK) << stream.msg;
}
-
- rc = deflate(&stream, Z_NO_FLUSH);
-
- CHECK_EQ(rc, Z_OK) << stream.msg;
}
}
#endif // FOLLY_HAVE_LIBLZMA
-typedef std::unique_ptr<Codec> (*CodecFactory)(int, CodecType);
+} // namespace
+
+std::unique_ptr<Codec> getCodec(CodecType type, int level) {
+ typedef std::unique_ptr<Codec> (*CodecFactory)(int, CodecType);
-CodecFactory gCodecFactories[
+ static CodecFactory codecFactories[
static_cast<size_t>(CodecType::NUM_CODEC_TYPES)] = {
- nullptr, // USER_DEFINED
- NoCompressionCodec::create,
+ nullptr, // USER_DEFINED
+ NoCompressionCodec::create,
#if FOLLY_HAVE_LIBLZ4
- LZ4Codec::create,
+ LZ4Codec::create,
#else
- nullptr,
+ nullptr,
#endif
#if FOLLY_HAVE_LIBSNAPPY
- SnappyCodec::create,
+ SnappyCodec::create,
#else
- nullptr,
+ nullptr,
#endif
#if FOLLY_HAVE_LIBZ
- ZlibCodec::create,
+ ZlibCodec::create,
#else
- nullptr,
+ nullptr,
#endif
#if FOLLY_HAVE_LIBLZ4
- LZ4Codec::create,
+ LZ4Codec::create,
#else
- nullptr,
+ nullptr,
#endif
#if FOLLY_HAVE_LIBLZMA
- LZMA2Codec::create,
- LZMA2Codec::create,
+ LZMA2Codec::create,
+ LZMA2Codec::create,
#else
- nullptr,
- nullptr,
+ nullptr,
+ nullptr,
#endif
-};
-
-} // namespace
+ };
-std::unique_ptr<Codec> getCodec(CodecType type, int level) {
size_t idx = static_cast<size_t>(type);
if (idx >= static_cast<size_t>(CodecType::NUM_CODEC_TYPES)) {
throw std::invalid_argument(to<std::string>(
"Compression type ", idx, " not supported"));
}
- auto factory = gCodecFactories[idx];
+ auto factory = codecFactories[idx];
if (!factory) {
throw std::invalid_argument(to<std::string>(
"Compression type ", idx, " not supported"));
}
}} // namespaces
-