1*2fb337e7SAlexey Samsonov //===--- Compression.cpp - Compression implementation ---------------------===// 2*2fb337e7SAlexey Samsonov // 3*2fb337e7SAlexey Samsonov // The LLVM Compiler Infrastructure 4*2fb337e7SAlexey Samsonov // 5*2fb337e7SAlexey Samsonov // This file is distributed under the University of Illinois Open Source 6*2fb337e7SAlexey Samsonov // License. See LICENSE.TXT for details. 7*2fb337e7SAlexey Samsonov // 8*2fb337e7SAlexey Samsonov //===----------------------------------------------------------------------===// 9*2fb337e7SAlexey Samsonov // 10*2fb337e7SAlexey Samsonov // This file implements compression functions. 11*2fb337e7SAlexey Samsonov // 12*2fb337e7SAlexey Samsonov //===----------------------------------------------------------------------===// 13*2fb337e7SAlexey Samsonov 14*2fb337e7SAlexey Samsonov #include "llvm/Support/Compression.h" 15*2fb337e7SAlexey Samsonov #include "llvm/ADT/OwningPtr.h" 16*2fb337e7SAlexey Samsonov #include "llvm/ADT/StringRef.h" 17*2fb337e7SAlexey Samsonov #include "llvm/Config/config.h" 18*2fb337e7SAlexey Samsonov #include "llvm/Support/ErrorHandling.h" 19*2fb337e7SAlexey Samsonov #include "llvm/Support/MemoryBuffer.h" 20*2fb337e7SAlexey Samsonov #if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H 21*2fb337e7SAlexey Samsonov #include <zlib.h> 22*2fb337e7SAlexey Samsonov #endif 23*2fb337e7SAlexey Samsonov 24*2fb337e7SAlexey Samsonov using namespace llvm; 25*2fb337e7SAlexey Samsonov 26*2fb337e7SAlexey Samsonov #if LLVM_ENABLE_ZLIB == 1 27*2fb337e7SAlexey Samsonov static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) { 28*2fb337e7SAlexey Samsonov switch (Level) { 29*2fb337e7SAlexey Samsonov case zlib::NoCompression: return 0; 30*2fb337e7SAlexey Samsonov case zlib::BestSpeedCompression: return 1; 31*2fb337e7SAlexey Samsonov case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION; 32*2fb337e7SAlexey Samsonov case zlib::BestSizeCompression: return 9; 33*2fb337e7SAlexey Samsonov } 34*2fb337e7SAlexey Samsonov } 35*2fb337e7SAlexey Samsonov 36*2fb337e7SAlexey Samsonov static zlib::Status encodeZlibReturnValue(int ReturnValue) { 37*2fb337e7SAlexey Samsonov switch (ReturnValue) { 38*2fb337e7SAlexey Samsonov case Z_OK: return zlib::StatusOK; 39*2fb337e7SAlexey Samsonov case Z_MEM_ERROR: return zlib::StatusOutOfMemory; 40*2fb337e7SAlexey Samsonov case Z_BUF_ERROR: return zlib::StatusBufferTooShort; 41*2fb337e7SAlexey Samsonov case Z_STREAM_ERROR: return zlib::StatusInvalidArg; 42*2fb337e7SAlexey Samsonov case Z_DATA_ERROR: return zlib::StatusInvalidData; 43*2fb337e7SAlexey Samsonov default: llvm_unreachable("unknown zlib return status!"); 44*2fb337e7SAlexey Samsonov } 45*2fb337e7SAlexey Samsonov } 46*2fb337e7SAlexey Samsonov 47*2fb337e7SAlexey Samsonov bool zlib::isAvailable() { return true; } 48*2fb337e7SAlexey Samsonov zlib::Status zlib::compress(StringRef InputBuffer, 49*2fb337e7SAlexey Samsonov OwningPtr<MemoryBuffer> &CompressedBuffer, 50*2fb337e7SAlexey Samsonov CompressionLevel Level) { 51*2fb337e7SAlexey Samsonov unsigned long CompressedSize = ::compressBound(InputBuffer.size()); 52*2fb337e7SAlexey Samsonov OwningArrayPtr<char> TmpBuffer(new char[CompressedSize]); 53*2fb337e7SAlexey Samsonov int CLevel = encodeZlibCompressionLevel(Level); 54*2fb337e7SAlexey Samsonov Status Res = encodeZlibReturnValue(::compress2( 55*2fb337e7SAlexey Samsonov (Bytef *)TmpBuffer.get(), &CompressedSize, 56*2fb337e7SAlexey Samsonov (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel)); 57*2fb337e7SAlexey Samsonov if (Res == StatusOK) 58*2fb337e7SAlexey Samsonov CompressedBuffer.reset(MemoryBuffer::getMemBufferCopy( 59*2fb337e7SAlexey Samsonov StringRef(TmpBuffer.get(), CompressedSize))); 60*2fb337e7SAlexey Samsonov return Res; 61*2fb337e7SAlexey Samsonov } 62*2fb337e7SAlexey Samsonov 63*2fb337e7SAlexey Samsonov zlib::Status zlib::uncompress(StringRef InputBuffer, 64*2fb337e7SAlexey Samsonov OwningPtr<MemoryBuffer> &UncompressedBuffer, 65*2fb337e7SAlexey Samsonov size_t UncompressedSize) { 66*2fb337e7SAlexey Samsonov OwningArrayPtr<char> TmpBuffer(new char[UncompressedSize]); 67*2fb337e7SAlexey Samsonov Status Res = encodeZlibReturnValue( 68*2fb337e7SAlexey Samsonov ::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize, 69*2fb337e7SAlexey Samsonov (const Bytef *)InputBuffer.data(), InputBuffer.size())); 70*2fb337e7SAlexey Samsonov if (Res == StatusOK) 71*2fb337e7SAlexey Samsonov UncompressedBuffer.reset(MemoryBuffer::getMemBufferCopy( 72*2fb337e7SAlexey Samsonov StringRef(TmpBuffer.get(), UncompressedSize))); 73*2fb337e7SAlexey Samsonov return Res; 74*2fb337e7SAlexey Samsonov } 75*2fb337e7SAlexey Samsonov 76*2fb337e7SAlexey Samsonov #else 77*2fb337e7SAlexey Samsonov bool zlib::isAvailable() { return false; } 78*2fb337e7SAlexey Samsonov zlib::Status zlib::compress(StringRef InputBuffer, 79*2fb337e7SAlexey Samsonov OwningPtr<MemoryBuffer> &CompressedBuffer, 80*2fb337e7SAlexey Samsonov CompressionLevel Level) { 81*2fb337e7SAlexey Samsonov return zlib::StatusUnsupported; 82*2fb337e7SAlexey Samsonov } 83*2fb337e7SAlexey Samsonov zlib::Status zlib::uncompress(StringRef InputBuffer, 84*2fb337e7SAlexey Samsonov OwningPtr<MemoryBuffer> &UncompressedBuffer, 85*2fb337e7SAlexey Samsonov size_t UncompressedSize) { 86*2fb337e7SAlexey Samsonov return zlib::StatusUnsupported; 87*2fb337e7SAlexey Samsonov } 88*2fb337e7SAlexey Samsonov #endif 89*2fb337e7SAlexey Samsonov 90