Compression.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //===--- Compression.cpp - Compression implementation ---------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements compression functions.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Support/Compression.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/ADT/StringRef.h"
  15. #include "llvm/Config/config.h"
  16. #include "llvm/Support/Compiler.h"
  17. #include "llvm/Support/Error.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #if LLVM_ENABLE_ZLIB
  20. #include <zlib.h>
  21. #endif
  22. using namespace llvm;
  23. #if LLVM_ENABLE_ZLIB
  24. static Error createError(StringRef Err) {
  25. return make_error<StringError>(Err, inconvertibleErrorCode());
  26. }
  27. static StringRef convertZlibCodeToString(int Code) {
  28. switch (Code) {
  29. case Z_MEM_ERROR:
  30. return "zlib error: Z_MEM_ERROR";
  31. case Z_BUF_ERROR:
  32. return "zlib error: Z_BUF_ERROR";
  33. case Z_STREAM_ERROR:
  34. return "zlib error: Z_STREAM_ERROR";
  35. case Z_DATA_ERROR:
  36. return "zlib error: Z_DATA_ERROR";
  37. case Z_OK:
  38. default:
  39. llvm_unreachable("unknown or unexpected zlib status code");
  40. }
  41. }
  42. bool zlib::isAvailable() { return true; }
  43. Error zlib::compress(StringRef InputBuffer,
  44. SmallVectorImpl<char> &CompressedBuffer, int Level) {
  45. unsigned long CompressedSize = ::compressBound(InputBuffer.size());
  46. CompressedBuffer.resize_for_overwrite(CompressedSize);
  47. int Res =
  48. ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize,
  49. (const Bytef *)InputBuffer.data(), InputBuffer.size(), Level);
  50. // Tell MemorySanitizer that zlib output buffer is fully initialized.
  51. // This avoids a false report when running LLVM with uninstrumented ZLib.
  52. __msan_unpoison(CompressedBuffer.data(), CompressedSize);
  53. CompressedBuffer.truncate(CompressedSize);
  54. return Res ? createError(convertZlibCodeToString(Res)) : Error::success();
  55. }
  56. Error zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer,
  57. size_t &UncompressedSize) {
  58. int Res =
  59. ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize,
  60. (const Bytef *)InputBuffer.data(), InputBuffer.size());
  61. // Tell MemorySanitizer that zlib output buffer is fully initialized.
  62. // This avoids a false report when running LLVM with uninstrumented ZLib.
  63. __msan_unpoison(UncompressedBuffer, UncompressedSize);
  64. return Res ? createError(convertZlibCodeToString(Res)) : Error::success();
  65. }
  66. Error zlib::uncompress(StringRef InputBuffer,
  67. SmallVectorImpl<char> &UncompressedBuffer,
  68. size_t UncompressedSize) {
  69. UncompressedBuffer.resize_for_overwrite(UncompressedSize);
  70. Error E =
  71. uncompress(InputBuffer, UncompressedBuffer.data(), UncompressedSize);
  72. UncompressedBuffer.truncate(UncompressedSize);
  73. return E;
  74. }
  75. uint32_t zlib::crc32(StringRef Buffer) {
  76. return ::crc32(0, (const Bytef *)Buffer.data(), Buffer.size());
  77. }
  78. #else
  79. bool zlib::isAvailable() { return false; }
  80. Error zlib::compress(StringRef InputBuffer,
  81. SmallVectorImpl<char> &CompressedBuffer, int Level) {
  82. llvm_unreachable("zlib::compress is unavailable");
  83. }
  84. Error zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer,
  85. size_t &UncompressedSize) {
  86. llvm_unreachable("zlib::uncompress is unavailable");
  87. }
  88. Error zlib::uncompress(StringRef InputBuffer,
  89. SmallVectorImpl<char> &UncompressedBuffer,
  90. size_t UncompressedSize) {
  91. llvm_unreachable("zlib::uncompress is unavailable");
  92. }
  93. uint32_t zlib::crc32(StringRef Buffer) {
  94. llvm_unreachable("zlib::crc32 is unavailable");
  95. }
  96. #endif