| Index: base/strings/string_compress.cc
|
| diff --git a/base/strings/string_compress.cc b/base/strings/string_compress.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b7fb5cad21d27821a5d058d311e9ba3f8bb67d1a
|
| --- /dev/null
|
| +++ b/base/strings/string_compress.cc
|
| @@ -0,0 +1,58 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/strings/string_compress.h"
|
| +
|
| +#if defined(USE_SYSTEM_LIBBZ2)
|
| +#include <bzlib.h>
|
| +#else
|
| +#include "third_party/bzip2/bzlib.h"
|
| +#endif
|
| +
|
| +#include "base/logging.h"
|
| +
|
| +namespace base {
|
| +
|
| +// This implementation is based on the Firefox MetricsService implementation.
|
| +bool Bzip2Compress(const std::string& input, std::string* output) {
|
| + bz_stream stream = {0};
|
| + // As long as our input is smaller than the bzip2 block size, we should get
|
| + // the best compression. For example, if your input was 250k, using a block
|
| + // size of 300k or 500k should result in the same compression ratio. Since
|
| + // our data should be under 100k, using the minimum block size of 100k should
|
| + // allocate less temporary memory, but result in the same compression ratio.
|
| + int result = BZ2_bzCompressInit(&stream,
|
| + 1, // 100k (min) block size
|
| + 0, // quiet
|
| + 0); // default "work factor"
|
| + if (result != BZ_OK) { // out of memory?
|
| + return false;
|
| + }
|
| +
|
| + output->clear();
|
| +
|
| + stream.next_in = const_cast<char*>(input.data());
|
| + stream.avail_in = static_cast<int>(input.size());
|
| + // NOTE: we don't need a BZ_RUN phase since our input buffer contains
|
| + // the entire input
|
| + do {
|
| + output->resize(output->size() + 1024);
|
| + stream.next_out = &((*output)[stream.total_out_lo32]);
|
| + stream.avail_out = static_cast<int>(output->size()) - stream.total_out_lo32;
|
| + result = BZ2_bzCompress(&stream, BZ_FINISH);
|
| + } while (result == BZ_FINISH_OK);
|
| + if (result != BZ_STREAM_END) { // unknown failure?
|
| + output->clear();
|
| + // TODO(jar): See if it would be better to do a CHECK() here.
|
| + return false;
|
| + }
|
| + result = BZ2_bzCompressEnd(&stream);
|
| + DCHECK(result == BZ_OK);
|
| +
|
| + output->resize(stream.total_out_lo32);
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace base
|
|
|