12fb337e7SAlexey Samsonov //===--- Compression.cpp - Compression implementation ---------------------===// 22fb337e7SAlexey Samsonov // 32fb337e7SAlexey Samsonov // The LLVM Compiler Infrastructure 42fb337e7SAlexey Samsonov // 52fb337e7SAlexey Samsonov // This file is distributed under the University of Illinois Open Source 62fb337e7SAlexey Samsonov // License. See LICENSE.TXT for details. 72fb337e7SAlexey Samsonov // 82fb337e7SAlexey Samsonov //===----------------------------------------------------------------------===// 92fb337e7SAlexey Samsonov // 102fb337e7SAlexey Samsonov // This file implements compression functions. 112fb337e7SAlexey Samsonov // 122fb337e7SAlexey Samsonov //===----------------------------------------------------------------------===// 132fb337e7SAlexey Samsonov 142fb337e7SAlexey Samsonov #include "llvm/Support/Compression.h" 1516132e6fSBenjamin Kramer #include "llvm/ADT/SmallVector.h" 162fb337e7SAlexey Samsonov #include "llvm/ADT/StringRef.h" 172fb337e7SAlexey Samsonov #include "llvm/Config/config.h" 180c9f1bfaSAlexey Samsonov #include "llvm/Support/Compiler.h" 192fb337e7SAlexey Samsonov #include "llvm/Support/ErrorHandling.h" 202fb337e7SAlexey Samsonov #if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H 212fb337e7SAlexey Samsonov #include <zlib.h> 222fb337e7SAlexey Samsonov #endif 232fb337e7SAlexey Samsonov 242fb337e7SAlexey Samsonov using namespace llvm; 252fb337e7SAlexey Samsonov 2628acf056SAlexey Samsonov #if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ 272fb337e7SAlexey Samsonov static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) { 282fb337e7SAlexey Samsonov switch (Level) { 292fb337e7SAlexey Samsonov case zlib::NoCompression: return 0; 302fb337e7SAlexey Samsonov case zlib::BestSpeedCompression: return 1; 312fb337e7SAlexey Samsonov case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION; 322fb337e7SAlexey Samsonov case zlib::BestSizeCompression: return 9; 332fb337e7SAlexey Samsonov } 3463761d4bSHans Wennborg llvm_unreachable("Invalid zlib::CompressionLevel!"); 352fb337e7SAlexey Samsonov } 362fb337e7SAlexey Samsonov 372fb337e7SAlexey Samsonov static zlib::Status encodeZlibReturnValue(int ReturnValue) { 382fb337e7SAlexey Samsonov switch (ReturnValue) { 392fb337e7SAlexey Samsonov case Z_OK: return zlib::StatusOK; 402fb337e7SAlexey Samsonov case Z_MEM_ERROR: return zlib::StatusOutOfMemory; 412fb337e7SAlexey Samsonov case Z_BUF_ERROR: return zlib::StatusBufferTooShort; 422fb337e7SAlexey Samsonov case Z_STREAM_ERROR: return zlib::StatusInvalidArg; 432fb337e7SAlexey Samsonov case Z_DATA_ERROR: return zlib::StatusInvalidData; 442fb337e7SAlexey Samsonov default: llvm_unreachable("unknown zlib return status!"); 452fb337e7SAlexey Samsonov } 462fb337e7SAlexey Samsonov } 472fb337e7SAlexey Samsonov 482fb337e7SAlexey Samsonov bool zlib::isAvailable() { return true; } 492fb337e7SAlexey Samsonov zlib::Status zlib::compress(StringRef InputBuffer, 50857497b9SDavid Blaikie SmallVectorImpl<char> &CompressedBuffer, 512fb337e7SAlexey Samsonov CompressionLevel Level) { 522fb337e7SAlexey Samsonov unsigned long CompressedSize = ::compressBound(InputBuffer.size()); 53857497b9SDavid Blaikie CompressedBuffer.resize(CompressedSize); 542fb337e7SAlexey Samsonov int CLevel = encodeZlibCompressionLevel(Level); 552fb337e7SAlexey Samsonov Status Res = encodeZlibReturnValue(::compress2( 56857497b9SDavid Blaikie (Bytef *)CompressedBuffer.data(), &CompressedSize, 572fb337e7SAlexey Samsonov (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel)); 5828cacae2SEvgeniy Stepanov // Tell MemorySanitizer that zlib output buffer is fully initialized. 5928cacae2SEvgeniy Stepanov // This avoids a false report when running LLVM with uninstrumented ZLib. 6028cacae2SEvgeniy Stepanov __msan_unpoison(CompressedBuffer.data(), CompressedSize); 61857497b9SDavid Blaikie CompressedBuffer.resize(CompressedSize); 622fb337e7SAlexey Samsonov return Res; 632fb337e7SAlexey Samsonov } 642fb337e7SAlexey Samsonov 65*46cdcb03SRafael Espindola zlib::Status zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer, 66*46cdcb03SRafael Espindola size_t &UncompressedSize) { 67*46cdcb03SRafael Espindola Status Res = encodeZlibReturnValue( 68*46cdcb03SRafael Espindola ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize, 69*46cdcb03SRafael Espindola (const Bytef *)InputBuffer.data(), InputBuffer.size())); 70*46cdcb03SRafael Espindola // Tell MemorySanitizer that zlib output buffer is fully initialized. 71*46cdcb03SRafael Espindola // This avoids a false report when running LLVM with uninstrumented ZLib. 72*46cdcb03SRafael Espindola __msan_unpoison(UncompressedBuffer, UncompressedSize); 73*46cdcb03SRafael Espindola return Res; 74*46cdcb03SRafael Espindola } 75*46cdcb03SRafael Espindola 762fb337e7SAlexey Samsonov zlib::Status zlib::uncompress(StringRef InputBuffer, 77a505f247SDavid Blaikie SmallVectorImpl<char> &UncompressedBuffer, 782fb337e7SAlexey Samsonov size_t UncompressedSize) { 79a505f247SDavid Blaikie UncompressedBuffer.resize(UncompressedSize); 80*46cdcb03SRafael Espindola Status Res = 81*46cdcb03SRafael Espindola uncompress(InputBuffer, UncompressedBuffer.data(), UncompressedSize); 82a505f247SDavid Blaikie UncompressedBuffer.resize(UncompressedSize); 832fb337e7SAlexey Samsonov return Res; 842fb337e7SAlexey Samsonov } 852fb337e7SAlexey Samsonov 866ede706dSAlexey Samsonov uint32_t zlib::crc32(StringRef Buffer) { 876ede706dSAlexey Samsonov return ::crc32(0, (const Bytef *)Buffer.data(), Buffer.size()); 886ede706dSAlexey Samsonov } 896ede706dSAlexey Samsonov 902fb337e7SAlexey Samsonov #else 912fb337e7SAlexey Samsonov bool zlib::isAvailable() { return false; } 922fb337e7SAlexey Samsonov zlib::Status zlib::compress(StringRef InputBuffer, 93857497b9SDavid Blaikie SmallVectorImpl<char> &CompressedBuffer, 942fb337e7SAlexey Samsonov CompressionLevel Level) { 952fb337e7SAlexey Samsonov return zlib::StatusUnsupported; 962fb337e7SAlexey Samsonov } 972fb337e7SAlexey Samsonov zlib::Status zlib::uncompress(StringRef InputBuffer, 98857497b9SDavid Blaikie SmallVectorImpl<char> &UncompressedBuffer, 992fb337e7SAlexey Samsonov size_t UncompressedSize) { 1002fb337e7SAlexey Samsonov return zlib::StatusUnsupported; 1012fb337e7SAlexey Samsonov } 1026ede706dSAlexey Samsonov uint32_t zlib::crc32(StringRef Buffer) { 1036ede706dSAlexey Samsonov llvm_unreachable("zlib::crc32 is unavailable"); 1046ede706dSAlexey Samsonov } 1052fb337e7SAlexey Samsonov #endif 1062fb337e7SAlexey Samsonov 107