1251607Sdim//===--- Compression.cpp - Compression implementation ---------------------===// 2251607Sdim// 3251607Sdim// The LLVM Compiler Infrastructure 4251607Sdim// 5251607Sdim// This file is distributed under the University of Illinois Open Source 6251607Sdim// License. See LICENSE.TXT for details. 7251607Sdim// 8251607Sdim//===----------------------------------------------------------------------===// 9251607Sdim// 10251607Sdim// This file implements compression functions. 11251607Sdim// 12251607Sdim//===----------------------------------------------------------------------===// 13251607Sdim 14251607Sdim#include "llvm/Support/Compression.h" 15288943Sdim#include "llvm/ADT/SmallVector.h" 16251607Sdim#include "llvm/ADT/StringRef.h" 17251607Sdim#include "llvm/Config/config.h" 18251607Sdim#include "llvm/Support/Compiler.h" 19251607Sdim#include "llvm/Support/ErrorHandling.h" 20251607Sdim#if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H 21251607Sdim#include <zlib.h> 22251607Sdim#endif 23251607Sdim 24251607Sdimusing namespace llvm; 25251607Sdim 26251607Sdim#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ 27251607Sdimstatic int encodeZlibCompressionLevel(zlib::CompressionLevel Level) { 28251607Sdim switch (Level) { 29251607Sdim case zlib::NoCompression: return 0; 30251607Sdim case zlib::BestSpeedCompression: return 1; 31251607Sdim case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION; 32251607Sdim case zlib::BestSizeCompression: return 9; 33251607Sdim } 34251607Sdim llvm_unreachable("Invalid zlib::CompressionLevel!"); 35251607Sdim} 36251607Sdim 37251607Sdimstatic zlib::Status encodeZlibReturnValue(int ReturnValue) { 38251607Sdim switch (ReturnValue) { 39251607Sdim case Z_OK: return zlib::StatusOK; 40251607Sdim case Z_MEM_ERROR: return zlib::StatusOutOfMemory; 41251607Sdim case Z_BUF_ERROR: return zlib::StatusBufferTooShort; 42251607Sdim case Z_STREAM_ERROR: return zlib::StatusInvalidArg; 43251607Sdim case Z_DATA_ERROR: return zlib::StatusInvalidData; 44251607Sdim default: llvm_unreachable("unknown zlib return status!"); 45251607Sdim } 46251607Sdim} 47251607Sdim 48251607Sdimbool zlib::isAvailable() { return true; } 49251607Sdimzlib::Status zlib::compress(StringRef InputBuffer, 50276479Sdim SmallVectorImpl<char> &CompressedBuffer, 51251607Sdim CompressionLevel Level) { 52251607Sdim unsigned long CompressedSize = ::compressBound(InputBuffer.size()); 53276479Sdim CompressedBuffer.resize(CompressedSize); 54251607Sdim int CLevel = encodeZlibCompressionLevel(Level); 55251607Sdim Status Res = encodeZlibReturnValue(::compress2( 56276479Sdim (Bytef *)CompressedBuffer.data(), &CompressedSize, 57251607Sdim (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel)); 58280031Sdim // Tell MemorySanitizer that zlib output buffer is fully initialized. 59280031Sdim // This avoids a false report when running LLVM with uninstrumented ZLib. 60280031Sdim __msan_unpoison(CompressedBuffer.data(), CompressedSize); 61276479Sdim CompressedBuffer.resize(CompressedSize); 62251607Sdim return Res; 63251607Sdim} 64251607Sdim 65251607Sdimzlib::Status zlib::uncompress(StringRef InputBuffer, 66276479Sdim SmallVectorImpl<char> &UncompressedBuffer, 67251607Sdim size_t UncompressedSize) { 68276479Sdim UncompressedBuffer.resize(UncompressedSize); 69276479Sdim Status Res = encodeZlibReturnValue(::uncompress( 70276479Sdim (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize, 71276479Sdim (const Bytef *)InputBuffer.data(), InputBuffer.size())); 72280031Sdim // Tell MemorySanitizer that zlib output buffer is fully initialized. 73280031Sdim // This avoids a false report when running LLVM with uninstrumented ZLib. 74280031Sdim __msan_unpoison(UncompressedBuffer.data(), UncompressedSize); 75276479Sdim UncompressedBuffer.resize(UncompressedSize); 76251607Sdim return Res; 77251607Sdim} 78251607Sdim 79261991Sdimuint32_t zlib::crc32(StringRef Buffer) { 80261991Sdim return ::crc32(0, (const Bytef *)Buffer.data(), Buffer.size()); 81261991Sdim} 82261991Sdim 83251607Sdim#else 84251607Sdimbool zlib::isAvailable() { return false; } 85251607Sdimzlib::Status zlib::compress(StringRef InputBuffer, 86276479Sdim SmallVectorImpl<char> &CompressedBuffer, 87251607Sdim CompressionLevel Level) { 88251607Sdim return zlib::StatusUnsupported; 89251607Sdim} 90251607Sdimzlib::Status zlib::uncompress(StringRef InputBuffer, 91276479Sdim SmallVectorImpl<char> &UncompressedBuffer, 92251607Sdim size_t UncompressedSize) { 93251607Sdim return zlib::StatusUnsupported; 94251607Sdim} 95261991Sdimuint32_t zlib::crc32(StringRef Buffer) { 96261991Sdim llvm_unreachable("zlib::crc32 is unavailable"); 97261991Sdim} 98251607Sdim#endif 99251607Sdim 100