blob: 329a402a07045ca5648154f9da43d693f634383b [file] [log] [blame]
Alexey Samsonov2fb337e2013-04-23 08:28:39 +00001//===--- Compression.cpp - Compression implementation ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements compression functions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Support/Compression.h"
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000015#include "llvm/ADT/StringRef.h"
16#include "llvm/Config/config.h"
Alexey Samsonov0c9f1bf2013-04-23 12:17:46 +000017#include "llvm/Support/Compiler.h"
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000018#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/MemoryBuffer.h"
20#if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H
21#include <zlib.h>
22#endif
23
24using namespace llvm;
25
Alexey Samsonov28acf052013-04-23 08:57:30 +000026#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000027static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) {
28 switch (Level) {
29 case zlib::NoCompression: return 0;
30 case zlib::BestSpeedCompression: return 1;
31 case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION;
32 case zlib::BestSizeCompression: return 9;
33 }
Hans Wennborg63761d4b2013-04-23 10:12:16 +000034 llvm_unreachable("Invalid zlib::CompressionLevel!");
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000035}
36
37static zlib::Status encodeZlibReturnValue(int ReturnValue) {
38 switch (ReturnValue) {
39 case Z_OK: return zlib::StatusOK;
40 case Z_MEM_ERROR: return zlib::StatusOutOfMemory;
41 case Z_BUF_ERROR: return zlib::StatusBufferTooShort;
42 case Z_STREAM_ERROR: return zlib::StatusInvalidArg;
43 case Z_DATA_ERROR: return zlib::StatusInvalidData;
44 default: llvm_unreachable("unknown zlib return status!");
45 }
46}
47
48bool zlib::isAvailable() { return true; }
49zlib::Status zlib::compress(StringRef InputBuffer,
Ahmed Charles56440fd2014-03-06 05:51:42 +000050 std::unique_ptr<MemoryBuffer> &CompressedBuffer,
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000051 CompressionLevel Level) {
52 unsigned long CompressedSize = ::compressBound(InputBuffer.size());
Ahmed Charles56440fd2014-03-06 05:51:42 +000053 std::unique_ptr<char[]> TmpBuffer(new char[CompressedSize]);
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000054 int CLevel = encodeZlibCompressionLevel(Level);
55 Status Res = encodeZlibReturnValue(::compress2(
56 (Bytef *)TmpBuffer.get(), &CompressedSize,
57 (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel));
Alexey Samsonov0c9f1bf2013-04-23 12:17:46 +000058 if (Res == StatusOK) {
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000059 CompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
60 StringRef(TmpBuffer.get(), CompressedSize)));
Alexey Samsonov0c9f1bf2013-04-23 12:17:46 +000061 // Tell MSan that memory initialized by zlib is valid.
Alexey Samsonovfdcff042013-04-23 13:35:32 +000062 __msan_unpoison(CompressedBuffer->getBufferStart(), CompressedSize);
Alexey Samsonov0c9f1bf2013-04-23 12:17:46 +000063 }
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000064 return Res;
65}
66
67zlib::Status zlib::uncompress(StringRef InputBuffer,
David Blaikiea505f242014-04-05 21:26:44 +000068 SmallVectorImpl<char> &UncompressedBuffer,
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000069 size_t UncompressedSize) {
David Blaikiea505f242014-04-05 21:26:44 +000070 UncompressedBuffer.resize(UncompressedSize);
71 Status Res = encodeZlibReturnValue(::uncompress(
72 (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize,
73 (const Bytef *)InputBuffer.data(), InputBuffer.size()));
74 UncompressedBuffer.resize(UncompressedSize);
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000075 return Res;
76}
77
Alexey Samsonov6ede7062013-08-14 16:03:29 +000078uint32_t zlib::crc32(StringRef Buffer) {
79 return ::crc32(0, (const Bytef *)Buffer.data(), Buffer.size());
80}
81
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000082#else
83bool zlib::isAvailable() { return false; }
84zlib::Status zlib::compress(StringRef InputBuffer,
Ahmed Charles56440fd2014-03-06 05:51:42 +000085 std::unique_ptr<MemoryBuffer> &CompressedBuffer,
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000086 CompressionLevel Level) {
87 return zlib::StatusUnsupported;
88}
89zlib::Status zlib::uncompress(StringRef InputBuffer,
Ahmed Charles56440fd2014-03-06 05:51:42 +000090 std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000091 size_t UncompressedSize) {
92 return zlib::StatusUnsupported;
93}
Alexey Samsonov6ede7062013-08-14 16:03:29 +000094uint32_t zlib::crc32(StringRef Buffer) {
95 llvm_unreachable("zlib::crc32 is unavailable");
96}
Alexey Samsonov2fb337e2013-04-23 08:28:39 +000097#endif
98