Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / metrics / compression_utils.cc
blob71f68ab9f21b74208b167d16a3f01bbf2369463e
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/metrics/compression_utils.h"
7 #include <vector>
9 #include "base/basictypes.h"
10 #include "third_party/zlib/zlib.h"
12 namespace {
14 // The difference in bytes between a zlib header and a gzip header.
15 const size_t kGzipZlibHeaderDifferenceBytes = 16;
17 // Pass an integer greater than the following get a gzip header instead of a
18 // zlib header when calling deflateInit2_.
19 const int kWindowBitsToGetGzipHeader = 16;
21 // This describes the amount of memory zlib uses to compress data. It can go
22 // from 1 to 9, with 8 being the default. For details, see:
23 // http://www.zlib.net/manual.html (search for memLevel).
24 const int kZlibMemoryLevel = 8;
26 // This code is taken almost verbatim from third_party/zlib/compress.c. The only
27 // difference is deflateInit2_ is called which sets the window bits to be > 16.
28 // That causes a gzip header to be emitted rather than a zlib header.
29 int GzipCompressHelper(Bytef* dest,
30 uLongf* dest_length,
31 const Bytef* source,
32 uLong source_length) {
33 z_stream stream;
35 stream.next_in = bit_cast<Bytef*>(source);
36 stream.avail_in = static_cast<uInt>(source_length);
37 stream.next_out = dest;
38 stream.avail_out = static_cast<uInt>(*dest_length);
39 if (static_cast<uLong>(stream.avail_out) != *dest_length)
40 return Z_BUF_ERROR;
42 stream.zalloc = static_cast<alloc_func>(0);
43 stream.zfree = static_cast<free_func>(0);
44 stream.opaque = static_cast<voidpf>(0);
46 gz_header gzip_header;
47 memset(&gzip_header, 0, sizeof(gzip_header));
48 int err = deflateInit2_(&stream,
49 Z_DEFAULT_COMPRESSION,
50 Z_DEFLATED,
51 MAX_WBITS + kWindowBitsToGetGzipHeader,
52 kZlibMemoryLevel,
53 Z_DEFAULT_STRATEGY,
54 ZLIB_VERSION,
55 sizeof(z_stream));
56 if (err != Z_OK)
57 return err;
59 err = deflateSetHeader(&stream, &gzip_header);
60 if (err != Z_OK)
61 return err;
63 err = deflate(&stream, Z_FINISH);
64 if (err != Z_STREAM_END) {
65 deflateEnd(&stream);
66 return err == Z_OK ? Z_BUF_ERROR : err;
68 *dest_length = stream.total_out;
70 err = deflateEnd(&stream);
71 return err;
73 } // namespace
75 namespace chrome {
77 bool GzipCompress(const std::string& input, std::string* output) {
78 std::vector<Bytef> compressed_data(kGzipZlibHeaderDifferenceBytes +
79 compressBound(input.size()));
81 uLongf compressed_size = compressed_data.size();
82 if (GzipCompressHelper(&compressed_data.front(),
83 &compressed_size,
84 bit_cast<const Bytef*>(input.data()),
85 input.size()) != Z_OK)
86 return false;
88 compressed_data.resize(compressed_size);
89 output->assign(compressed_data.begin(), compressed_data.end());
90 return true;
92 } // namespace chrome