klee
CompressionStream.cpp
Go to the documentation of this file.
1//===-- CompressionStream.cpp --------------------------------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "klee/Config/config.h"
10#include "klee/Config/Version.h"
11#ifdef HAVE_ZLIB_H
13
14#include "llvm/Support/FileSystem.h"
15
16#include <fcntl.h>
17#include <errno.h>
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <unistd.h>
21
22namespace klee {
23
24compressed_fd_ostream::compressed_fd_ostream(const std::string &Filename,
25 std::string &ErrorInfo)
26 : llvm::raw_ostream(), pos(0) {
27 ErrorInfo = "";
28 // Open file in binary mode
29#if LLVM_VERSION_CODE >= LLVM_VERSION(7, 0)
30 std::error_code EC =
31 llvm::sys::fs::openFileForWrite(Filename, FD);
32#else
33 std::error_code EC =
34 llvm::sys::fs::openFileForWrite(Filename, FD, llvm::sys::fs::F_None);
35#endif
36 if (EC) {
37 ErrorInfo = EC.message();
38 FD = -1;
39 return;
40 }
41 // Initialize the compression library
42 strm.zalloc = Z_NULL;
43 strm.zfree = Z_NULL;
44 strm.opaque = Z_NULL;
45 strm.next_in = Z_NULL;
46 strm.next_out = buffer;
47 strm.avail_in = 0;
48 strm.avail_out = BUFSIZE;
49
50 const auto ret = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, 31,
51 8 /* memory usage default, 0 smallest, 9 highest*/,
52 Z_DEFAULT_STRATEGY);
53 if (ret != Z_OK)
54 ErrorInfo = "Deflate initialisation returned with error: " + std::to_string(ret);
55}
56
57void compressed_fd_ostream::writeFullCompressedData() {
58 // Check if no space available and write the buffer
59 if (strm.avail_out == 0) {
60 write_file(reinterpret_cast<const char *>(buffer), BUFSIZE);
61 strm.next_out = buffer;
62 strm.avail_out = BUFSIZE;
63 }
64}
65
66void compressed_fd_ostream::flush_compressed_data() {
67 // flush data from the raw buffer
68 flush();
69
70 // write the remaining data
71 int deflate_res = Z_OK;
72 while (deflate_res == Z_OK) {
73 // Check if no space available and write the buffer
74 writeFullCompressedData();
75 deflate_res = deflate(&strm, Z_FINISH);
76 }
77 assert(deflate_res == Z_STREAM_END);
78 write_file(reinterpret_cast<const char *>(buffer), BUFSIZE - strm.avail_out);
79}
80
81compressed_fd_ostream::~compressed_fd_ostream() {
82 if (FD >= 0) {
83 // write the remaining data
84 flush_compressed_data();
85 close(FD);
86 }
87 deflateEnd(&strm);
88}
89
90void compressed_fd_ostream::write_impl(const char *Ptr, size_t Size) {
91 strm.next_in =
92 const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(Ptr));
93 strm.avail_in = Size;
94
95 // Check if there is still data to compress
96 while (strm.avail_in != 0) {
97 // compress data
98 const auto res __attribute__ ((unused)) = deflate(&strm, Z_NO_FLUSH);
99 assert(res == Z_OK);
100 writeFullCompressedData();
101 }
102}
103
104void compressed_fd_ostream::write_file(const char *Ptr, size_t Size) {
105 pos += Size;
106 assert(FD >= 0 && "File already closed");
107 do {
108 ssize_t ret = ::write(FD, Ptr, Size);
109 if (ret < 0) {
110 if (errno == EINTR || errno == EAGAIN)
111 continue;
112 assert(0 && "Could not write to file");
113 break;
114 }
115
116 Ptr += ret;
117 Size -= ret;
118 } while (Size > 0);
119}
120}
121#endif
void *__dso_handle __attribute__((__weak__))
compressed_fd_ostream(const std::string &Filename, std::string &ErrorInfo)
Definition: main.cpp:291
const size_t BUFSIZE