// Copyright 2014 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 "third_party/zlib/google/compression_utils.h"

#include "base/bit_cast.h"
#include "base/logging.h"
#include "base/process/memory.h"
#include "base/strings/string_piece.h"
#include "base/sys_byteorder.h"

#include "third_party/zlib/google/compression_utils_portable.h"

namespace compression {

bool GzipCompress(base::StringPiece input,
                  char* output_buffer,
                  size_t output_buffer_size,
                  size_t* compressed_size,
                  void* (*malloc_fn)(size_t),
                  void (*free_fn)(void*)) {
  static_assert(sizeof(Bytef) == 1, "");

  // uLongf can be larger than size_t.
  uLongf compressed_size_long = static_cast<uLongf>(output_buffer_size);
  if (zlib_internal::GzipCompressHelper(
          bit_cast<Bytef*>(output_buffer), &compressed_size_long,
          bit_cast<const Bytef*>(input.data()),
          static_cast<uLongf>(input.size()), malloc_fn, free_fn) != Z_OK) {
    return false;
  }
  // No overflow, as compressed_size_long <= output.size() which is a size_t.
  *compressed_size = static_cast<size_t>(compressed_size_long);
  return true;
}

bool GzipCompress(base::StringPiece input, std::string* output) {
  // Not using std::vector<> because allocation failures are recoverable,
  // which is hidden by std::vector<>.
  static_assert(sizeof(Bytef) == 1, "");
  const uLongf input_size = static_cast<uLongf>(input.size());

  uLongf compressed_data_size =
      zlib_internal::GZipExpectedCompressedSize(input_size);

  Bytef* compressed_data;
  if (!base::UncheckedMalloc(compressed_data_size,
                             reinterpret_cast<void**>(&compressed_data))) {
    return false;
  }

  if (zlib_internal::GzipCompressHelper(compressed_data, &compressed_data_size,
                                        bit_cast<const Bytef*>(input.data()),
                                        input_size, nullptr, nullptr) != Z_OK) {
    free(compressed_data);
    return false;
  }

  Bytef* resized_data =
      reinterpret_cast<Bytef*>(realloc(compressed_data, compressed_data_size));
  if (!resized_data) {
    free(compressed_data);
    return false;
  }
  output->assign(resized_data, resized_data + compressed_data_size);
  DCHECK_EQ(input_size, GetUncompressedSize(*output));

  free(resized_data);
  return true;
}

bool GzipUncompress(const std::string& input, std::string* output) {
  std::string uncompressed_output;
  uLongf uncompressed_size = static_cast<uLongf>(GetUncompressedSize(input));
  if (uncompressed_size > uncompressed_output.max_size())
    return false;

  uncompressed_output.resize(uncompressed_size);
  if (zlib_internal::GzipUncompressHelper(
          bit_cast<Bytef*>(uncompressed_output.data()), &uncompressed_size,
          bit_cast<const Bytef*>(input.data()),
          static_cast<uLongf>(input.length())) == Z_OK) {
    output->swap(uncompressed_output);
    return true;
  }
  return false;
}

bool GzipUncompress(base::StringPiece input, base::StringPiece output) {
  uLongf uncompressed_size = GetUncompressedSize(input);
  if (uncompressed_size > output.size())
    return false;
  return zlib_internal::GzipUncompressHelper(
             bit_cast<Bytef*>(output.data()), &uncompressed_size,
             bit_cast<const Bytef*>(input.data()),
             static_cast<uLongf>(input.length())) == Z_OK;
}

bool GzipUncompress(base::StringPiece input, std::string* output) {
  // Disallow in-place usage, i.e., |input| using |*output| as underlying data.
  DCHECK_NE(input.data(), output->data());
  uLongf uncompressed_size = GetUncompressedSize(input);
  output->resize(uncompressed_size);
  return zlib_internal::GzipUncompressHelper(
             bit_cast<Bytef*>(output->data()), &uncompressed_size,
             bit_cast<const Bytef*>(input.data()),
             static_cast<uLongf>(input.length())) == Z_OK;
}

uint32_t GetUncompressedSize(base::StringPiece compressed_data) {
  // The uncompressed size is stored in the last 4 bytes of |input| in LE.
  uint32_t size;
  if (compressed_data.length() < sizeof(size))
    return 0;
  memcpy(&size,
         &compressed_data.data()[compressed_data.length() - sizeof(size)],
         sizeof(size));
  return base::ByteSwapToLE32(size);
}

}  // namespace compression
