Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Unified Diff: components/metrics/compression_utils.cc

Issue 318203004: Make MetricsService save compressed logs to local state. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/metrics/compression_utils.cc
===================================================================
--- components/metrics/compression_utils.cc (working copy)
+++ components/metrics/compression_utils.cc (working copy)
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/metrics/net/compression_utils.h"
+#include "components/metrics/compression_utils.h"
#include <vector>
#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/sys_byteorder.h"
#include "third_party/zlib/zlib.h"
namespace {
@@ -15,7 +17,7 @@
const size_t kGzipZlibHeaderDifferenceBytes = 16;
// Pass an integer greater than the following get a gzip header instead of a
-// zlib header when calling deflateInit2_.
+// zlib header when calling deflateInit2() and inflateInit2().
const int kWindowBitsToGetGzipHeader = 16;
// This describes the amount of memory zlib uses to compress data. It can go
@@ -24,53 +26,101 @@
const int kZlibMemoryLevel = 8;
// This code is taken almost verbatim from third_party/zlib/compress.c. The only
-// difference is deflateInit2_ is called which sets the window bits to be > 16.
+// difference is deflateInit2() is called which sets the window bits to be > 16.
// That causes a gzip header to be emitted rather than a zlib header.
int GzipCompressHelper(Bytef* dest,
uLongf* dest_length,
const Bytef* source,
uLong source_length) {
- z_stream stream;
+ z_stream stream;
- stream.next_in = bit_cast<Bytef*>(source);
- stream.avail_in = static_cast<uInt>(source_length);
- stream.next_out = dest;
- stream.avail_out = static_cast<uInt>(*dest_length);
- if (static_cast<uLong>(stream.avail_out) != *dest_length)
- return Z_BUF_ERROR;
+ stream.next_in = bit_cast<Bytef*>(source);
+ stream.avail_in = static_cast<uInt>(source_length);
+ stream.next_out = dest;
+ stream.avail_out = static_cast<uInt>(*dest_length);
+ if (static_cast<uLong>(stream.avail_out) != *dest_length)
+ return Z_BUF_ERROR;
- stream.zalloc = static_cast<alloc_func>(0);
- stream.zfree = static_cast<free_func>(0);
- stream.opaque = static_cast<voidpf>(0);
+ stream.zalloc = static_cast<alloc_func>(0);
+ stream.zfree = static_cast<free_func>(0);
+ stream.opaque = static_cast<voidpf>(0);
- gz_header gzip_header;
- memset(&gzip_header, 0, sizeof(gzip_header));
- int err = deflateInit2_(&stream,
- Z_DEFAULT_COMPRESSION,
- Z_DEFLATED,
- MAX_WBITS + kWindowBitsToGetGzipHeader,
- kZlibMemoryLevel,
- Z_DEFAULT_STRATEGY,
- ZLIB_VERSION,
- sizeof(z_stream));
- if (err != Z_OK)
- return err;
+ gz_header gzip_header;
+ memset(&gzip_header, 0, sizeof(gzip_header));
+ int err = deflateInit2(&stream,
+ Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED,
+ MAX_WBITS + kWindowBitsToGetGzipHeader,
+ kZlibMemoryLevel,
+ Z_DEFAULT_STRATEGY);
+ if (err != Z_OK)
+ return err;
- err = deflateSetHeader(&stream, &gzip_header);
- if (err != Z_OK)
- return err;
+ err = deflateSetHeader(&stream, &gzip_header);
+ if (err != Z_OK)
+ return err;
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *dest_length = stream.total_out;
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *dest_length = stream.total_out;
- err = deflateEnd(&stream);
+ err = deflateEnd(&stream);
+ return err;
+}
+
+// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
+// difference is inflateInit2() is called which sets the window bits to be > 16.
+// That causes a gzip header to be parsed rather than a zlib header.
+int GzipUncompressHelper(Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length) {
+ z_stream stream;
+
+ stream.next_in = bit_cast<Bytef*>(source);
+ stream.avail_in = static_cast<uInt>(source_length);
+ if (static_cast<uLong>(stream.avail_in) != source_length)
+ return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = static_cast<uInt>(*dest_length);
+ if (static_cast<uLong>(stream.avail_out) != *dest_length)
+ return Z_BUF_ERROR;
+
+ stream.zalloc = static_cast<alloc_func>(0);
+ stream.zfree = static_cast<free_func>(0);
+
+ int err = inflateInit2(&stream, MAX_WBITS + kWindowBitsToGetGzipHeader);
+ if (err != Z_OK)
return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *dest_length = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
}
+// Returns the uncompressed size from GZIP-compressed |compressed_data|.
+uint32 GetUncompressedSize(const std::string& compressed_data) {
+ // The uncompressed size is stored in the last 4 bytes of |input| in LE.
+ uint32 size;
+ if (compressed_data.length() < sizeof(size))
+ return 0;
+ memcpy(&size, &compressed_data[compressed_data.length() - sizeof(size)],
+ sizeof(size));
+ return base::ByteSwapToLE32(size);
+}
+
} // namespace
namespace metrics {
@@ -90,7 +140,17 @@
compressed_data.resize(compressed_size);
output->assign(compressed_data.begin(), compressed_data.end());
+ DCHECK_EQ(input.size(), GetUncompressedSize(*output));
return true;
}
+bool GzipUncompress(const std::string& input, std::string* output) {
+ output->resize(GetUncompressedSize(input));
+ uLongf uncompressed_size = static_cast<uLongf>(output->length());
+ return GzipUncompressHelper(bit_cast<Bytef*>(output->data()),
+ &uncompressed_size,
+ bit_cast<const Bytef*>(input.data()),
+ static_cast<uLongf>(input.length())) == Z_OK;
+}
+
} // namespace metrics

Powered by Google App Engine
This is Rietveld 408576698