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