diff options
author | Jose Fonseca <jfonseca@vmware.com> | 2016-03-23 11:56:35 +0000 |
---|---|---|
committer | Jose Fonseca <jfonseca@vmware.com> | 2016-03-23 12:12:04 +0000 |
commit | b79369892c03bc02af6cbd97f865fb59a9736df4 (patch) | |
tree | 5328721b8cfb6efbbce087af95eb706d592745b7 | |
parent | e1dd915035f845365c88d63b78aedfffc78006b2 (diff) |
common: Read incomplete Snappy compressed blocks.
Using snappy 1.3.1's UncompressAsMuchAsPossible interface.
-rw-r--r-- | common/trace_file_snappy.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/common/trace_file_snappy.cpp b/common/trace_file_snappy.cpp index 039c87d1..4d92cd7f 100644 --- a/common/trace_file_snappy.cpp +++ b/common/trace_file_snappy.cpp @@ -52,6 +52,7 @@ #include <snappy.h> +#include <snappy-sinksource.h> #include <iostream> #include <algorithm> @@ -225,18 +226,34 @@ void SnappyFile::flushReadCache(size_t skipLength) m_stream.read((char*)m_compressedCache, compressedLength); if (m_stream.fail()) { - // XXX: Unforunately Snappy's interface is not expressive enough - // to allow recovering part of the uncompressed bytes. std::cerr << "warning: unexpected end of file while reading trace\n"; + + compressedLength = m_stream.gcount(); + if (!snappy::GetUncompressedLength(m_compressedCache, compressedLength, + &m_cacheSize)) { + createCache(0); + return; + } + + createCache(m_cacheSize); + snappy::ByteArraySource source(m_compressedCache, compressedLength); + + snappy::UncheckedByteArraySink sink(m_cache); + m_cacheSize = snappy::UncompressAsMuchAsPossible(&source, &sink); + + return; + } + + if (!snappy::GetUncompressedLength(m_compressedCache, compressedLength, + &m_cacheSize)) { createCache(0); return; } - ::snappy::GetUncompressedLength(m_compressedCache, compressedLength, - &m_cacheSize); + createCache(m_cacheSize); if (skipLength < m_cacheSize) { - ::snappy::RawUncompress(m_compressedCache, compressedLength, - m_cache); + snappy::RawUncompress(m_compressedCache, compressedLength, + m_cache); } } |