File indexing completed on 2023-03-17 10:39:10
0001 #include <cassert>
0002 #include <cstring>
0003
0004 #include "zlib.h"
0005
0006 #include "Alignment/Geners/interface/BZ2Handle.hh"
0007 #include "Alignment/Geners/interface/CStringStream.hh"
0008 #include "Alignment/Geners/interface/IOException.hh"
0009
0010 static void doZlibCompression(const char *data,
0011 const unsigned long long len,
0012 const bool defl,
0013 z_stream_s &strm,
0014 char *buffer,
0015 const unsigned long long bufLen,
0016 std::ostream &sink) {
0017 assert(buffer);
0018 assert(bufLen);
0019
0020 int status = Z_OK;
0021 strm.next_in = reinterpret_cast<Bytef *>(const_cast<char *>(data));
0022 strm.avail_in = len;
0023 do {
0024 strm.next_out = reinterpret_cast<Bytef *>(buffer);
0025 strm.avail_out = bufLen;
0026 status = defl ? deflate(&strm, Z_FINISH) : inflate(&strm, Z_NO_FLUSH);
0027 assert(status == Z_OK || status == Z_STREAM_END);
0028 const unsigned have = bufLen - strm.avail_out;
0029 sink.write(buffer, have);
0030 if (sink.fail())
0031 throw gs::IOWriteFailure("In gs::doZlibCompression: sink stream failure");
0032 } while (strm.avail_out == 0);
0033
0034 if (defl) {
0035 assert(strm.avail_in == 0);
0036 assert(status == Z_STREAM_END);
0037 assert(deflateReset(&strm) == Z_OK);
0038 } else
0039 assert(inflateReset(&strm) == Z_OK);
0040 }
0041
0042 static void doBZ2Compression(const char *data,
0043 const unsigned long long len,
0044 const bool defl,
0045 bz_stream &strm,
0046 char *buffer,
0047 const unsigned long long bufLen,
0048 std::ostream &sink) {
0049 assert(buffer);
0050 assert(bufLen);
0051
0052 int status = BZ_OK;
0053 strm.next_in = const_cast<char *>(data);
0054 strm.avail_in = len;
0055 do {
0056 strm.next_out = buffer;
0057 strm.avail_out = bufLen;
0058 status = defl ? BZ2_bzCompress(&strm, BZ_FINISH) : BZ2_bzDecompress(&strm);
0059 assert(status == BZ_OK || status == BZ_STREAM_END);
0060 const unsigned have = bufLen - strm.avail_out;
0061 sink.write(buffer, have);
0062 if (sink.fail())
0063 throw gs::IOWriteFailure("In gs::doBZ2Compression: sink stream failure");
0064 } while (status != BZ_STREAM_END);
0065 }
0066
0067 namespace gs {
0068 CStringStream::CStringStream(const CompressionMode m,
0069 const int compressionLevel,
0070 const unsigned minSizeToCompress,
0071 const unsigned bufSize)
0072 : mode_(m),
0073 compressionLevel_(compressionLevel),
0074 minSizeToCompress_(minSizeToCompress),
0075
0076
0077
0078 comprBuf_(bufSize > 1024U ? bufSize : 1024U),
0079 sink_(nullptr) {
0080 this->init(&buf_);
0081 }
0082
0083 void CStringStream::setCompressionMode(const CompressionMode newmode) {
0084 reset();
0085 mode_ = newmode;
0086 }
0087
0088 void CStringStream::reset() {
0089 clear();
0090 seekp(0);
0091 seekg(0);
0092 }
0093
0094 void CStringStream::readCompressed(std::istream &in, const unsigned compressionCode, const unsigned long long len) {
0095 reset();
0096 if (!len)
0097 return;
0098
0099
0100 if (len > readBuf_.size())
0101 readBuf_.resize(len);
0102 in.read(&readBuf_[0], len);
0103
0104 switch (static_cast<CompressionMode>(compressionCode)) {
0105 case NOT_COMPRESSED:
0106 this->write(&readBuf_[0], len);
0107 return;
0108
0109 case ZLIB: {
0110 if (!inflator_.get())
0111 inflator_ = CPP11_auto_ptr<ZlibInflateHandle>(new ZlibInflateHandle());
0112 doZlibCompression(&readBuf_[0], len, false, inflator_->strm(), &comprBuf_[0], comprBuf_.size(), *this);
0113 } break;
0114
0115 case BZIP2: {
0116
0117
0118 bz_stream strm;
0119 BZ2InflateHandle h(strm);
0120 doBZ2Compression(&readBuf_[0], len, false, strm, &comprBuf_[0], comprBuf_.size(), *this);
0121 } break;
0122
0123 default:
0124 assert(!"Unhandled switch case in "
0125 "CStringStream::readCompressed. "
0126 "This is a bug. Please report.");
0127 }
0128 }
0129
0130 CStringStream::CompressionMode CStringStream::writeCompressed() {
0131
0132 assert(sink_);
0133
0134 unsigned long long len = 0;
0135 const char *data = buf_.getPutBuffer(&len);
0136 if (len == 0)
0137 return NOT_COMPRESSED;
0138
0139 if (mode_ == NOT_COMPRESSED || len < minSizeToCompress_) {
0140 sink_->write(data, len);
0141 return NOT_COMPRESSED;
0142 }
0143
0144 switch (mode_) {
0145 case ZLIB: {
0146 if (!deflator_.get())
0147 deflator_ = CPP11_auto_ptr<ZlibDeflateHandle>(new ZlibDeflateHandle(compressionLevel_));
0148 doZlibCompression(data, len, true, deflator_->strm(), &comprBuf_[0], comprBuf_.size(), *sink_);
0149 } break;
0150
0151 case BZIP2: {
0152
0153
0154 bz_stream strm;
0155 BZ2DeflateHandle h(strm);
0156 doBZ2Compression(data, len, true, strm, &comprBuf_[0], comprBuf_.size(), *sink_);
0157 } break;
0158
0159 default:
0160 assert(!"Unhandled switch case in "
0161 "CStringStream::writeCompressed. "
0162 "This is a bug. Please report.");
0163 }
0164
0165 seekp(0);
0166 return mode_;
0167 }
0168
0169 bool CStringStream::getCompressionModeByName(const char *name, CompressionMode *m) {
0170 static const char *names[] = {"n", "z", "b"};
0171 if (!name || !m)
0172 return false;
0173 for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); ++i)
0174 if (strcasecmp(name, names[i]) == 0) {
0175 *m = static_cast<CompressionMode>(i);
0176 return true;
0177 }
0178 return false;
0179 }
0180
0181 std::string CStringStream::compressionModeName(const CompressionMode m, const bool useShortName) {
0182 std::string mode;
0183 switch (m) {
0184 case NOT_COMPRESSED:
0185 mode = useShortName ? "n" : "not compressed";
0186 break;
0187 case ZLIB:
0188 mode = useShortName ? "z" : "zlib";
0189 break;
0190 case BZIP2:
0191 mode = useShortName ? "b" : "bzip2";
0192 break;
0193 default:
0194 assert(!"Unhandled switch case in "
0195 "CStringStream::compressionModeName. "
0196 "This is a bug. Please report.");
0197 }
0198 return mode;
0199 }
0200 }