File indexing completed on 2023-03-17 11:16:00
0001 #ifndef PhysicsTools_MVAComputer_zstream_icc
0002 #define PhysicsTools_MVAComputer_zstream_icc
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <iostream>
0014 #include <algorithm>
0015 #include <cstring>
0016 #include <vector>
0017
0018 #include <zlib.h>
0019
0020 #include "PhysicsTools/MVAComputer/interface/zstream.h"
0021
0022 namespace ext {
0023
0024 template <typename Item_t, typename Traits_t, typename Allocator_t>
0025 basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::basic_ozstreambuf(OStream_t *os, int level)
0026 : os(os), outputBuffer(4096), buffer(4096) {
0027 zipStream.zalloc = (alloc_func) nullptr;
0028 zipStream.zfree = (free_func) nullptr;
0029 zipStream.next_in = nullptr;
0030 zipStream.avail_in = 0;
0031 zipStream.avail_out = 0;
0032 zipStream.next_out = nullptr;
0033
0034 err = deflateInit(&zipStream, level);
0035
0036 this->setp(&buffer.front(), &buffer.back());
0037 }
0038
0039 template <typename Item_t, typename Traits_t, typename Allocator_t>
0040 basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::~basic_ozstreambuf() {
0041 flush();
0042 os->flush();
0043 err = deflateEnd(&zipStream);
0044 }
0045
0046 template <typename Item_t, typename Traits_t, typename Allocator_t>
0047 int basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::sync() {
0048 if (pptr() && pptr() > pbase() && traits_type::eq_int_type(overflow(traits_type::eof()), traits_type::eof()))
0049 return -1;
0050 return 0;
0051 }
0052
0053 template <typename Item_t, typename Traits_t, typename Allocator_t>
0054 typename basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::int_type
0055 basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::overflow(
0056 typename basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::int_type c)
0057
0058 {
0059 int w = (int)(pptr() - pbase());
0060 if (!traits_type::eq_int_type(c, traits_type::eof())) {
0061 *pptr() = c;
0062 w++;
0063 }
0064 if (zipToStream(pbase(), w)) {
0065 this->setp(pbase(), epptr());
0066 return c;
0067 }
0068 return traits_type::eof();
0069 }
0070
0071 template <typename Item_t, typename Traits_t, typename Allocator_t>
0072 bool basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::zipToStream(
0073 typename basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::char_type *buf, std::streamsize size) {
0074 zipStream.next_in = (byte_type *)buf;
0075 zipStream.avail_in = size * sizeof(char_type);
0076 zipStream.avail_out = outputBuffer.size();
0077 zipStream.next_out = &outputBuffer.front();
0078
0079 do {
0080 err = deflate(&zipStream, 0);
0081
0082 if (err == Z_OK || err == Z_STREAM_END) {
0083 std::streamsize written = outputBuffer.size() - zipStream.avail_out;
0084 os->write((const char_type *)&outputBuffer.front(), written / sizeof(char_type));
0085 size_t remaining = written % sizeof(char_type);
0086 if (remaining)
0087 std::memcpy(&outputBuffer.front(), &outputBuffer[written - remaining], remaining);
0088
0089 zipStream.avail_out = outputBuffer.size();
0090 zipStream.next_out = &outputBuffer[remaining];
0091 }
0092 } while (zipStream.avail_in && err == Z_OK);
0093
0094 return err == Z_OK;
0095 }
0096
0097 template <typename Item_t, typename Traits_t, typename Allocator_t>
0098 std::streamsize basic_ozstreambuf<Item_t, Traits_t, Allocator_t>::flush() {
0099 std::streamsize total = 0;
0100
0101 do {
0102 err = deflate(&zipStream, Z_FINISH);
0103
0104 if (err == Z_OK || err == Z_STREAM_END) {
0105 std::streamsize written = outputBuffer.size() - zipStream.avail_out;
0106 total += written;
0107 os->write((const char_type *)&outputBuffer.front(), written / sizeof(char_type));
0108 size_t remaining = written % sizeof(char_type);
0109 if (remaining)
0110 std::memcpy(&outputBuffer.front(), &outputBuffer[written - remaining], remaining);
0111
0112 zipStream.avail_out = outputBuffer.size();
0113 zipStream.next_out = &outputBuffer[remaining];
0114 }
0115 } while (err == Z_OK);
0116
0117 os->flush();
0118
0119 return total;
0120 }
0121
0122 template <typename Item_t, typename Traits_t, typename Allocator_t>
0123 basic_izstreambuf<Item_t, Traits_t, Allocator_t>::basic_izstreambuf(IStream_t *is)
0124 : is(is), inputBuffer(4096), buffer(4096) {
0125 zipStream.zalloc = (alloc_func) nullptr;
0126 zipStream.zfree = (free_func) nullptr;
0127
0128 zipStream.next_in = nullptr;
0129 zipStream.avail_in = 0;
0130 zipStream.avail_out = 0;
0131 zipStream.next_out = nullptr;
0132
0133 err = inflateInit(&zipStream);
0134
0135 this->setg(&buffer.front() + 4, &buffer.front() + 4, &buffer.front() + 4);
0136 }
0137
0138 template <typename Item_t, typename Traits_t, typename Allocator_t>
0139 size_t basic_izstreambuf<Item_t, Traits_t, Allocator_t>::fillInputBuffer() {
0140 zipStream.next_in = &inputBuffer.front();
0141 is->read((char_type *)&inputBuffer.front(), inputBuffer.size() / sizeof(char_type));
0142 zipStream.avail_in = is->gcount() * sizeof(char_type);
0143 return zipStream.avail_in;
0144 }
0145
0146 template <typename Item_t, typename Traits_t, typename Allocator_t>
0147 basic_izstreambuf<Item_t, Traits_t, Allocator_t>::~basic_izstreambuf() {
0148 inflateEnd(&zipStream);
0149 }
0150
0151 template <typename Item_t, typename Traits_t, typename Allocator_t>
0152 typename basic_izstreambuf<Item_t, Traits_t, Allocator_t>::int_type
0153 basic_izstreambuf<Item_t, Traits_t, Allocator_t>::underflow() {
0154 if (gptr() && (gptr() < egptr()))
0155 return *reinterpret_cast<byte_type *>(gptr());
0156
0157 int nPutback = (int)(gptr() - eback());
0158 if (nPutback > 4)
0159 nPutback = 4;
0160 std::memcpy(&buffer.front() + (4 - nPutback), gptr() - nPutback, nPutback * sizeof(char_type));
0161
0162 int size = unzipFromStream(&buffer.front() + 4, (buffer.size() - 4) * sizeof(char_type));
0163 if (size <= 0)
0164 return traits_type::eof();
0165
0166 this->setg(&buffer.front() + (4 - nPutback), &buffer.front() + 4, &buffer.front() + (4 + size));
0167
0168 return *reinterpret_cast<byte_type *>(gptr());
0169 }
0170
0171 template <typename Item_t, typename Traits_t, typename Allocator_t>
0172 std::streamsize basic_izstreambuf<Item_t, Traits_t, Allocator_t>::unzipFromStream(char_type *buf,
0173 std::streamsize size) {
0174 zipStream.next_out = (byte_type *)buf;
0175 zipStream.avail_out = size * sizeof(char_type);
0176 size_t count = zipStream.avail_in;
0177
0178 do {
0179 if (!zipStream.avail_in)
0180 count = fillInputBuffer();
0181
0182 if (zipStream.avail_in)
0183 err = inflate(&zipStream, Z_SYNC_FLUSH);
0184 } while (err == Z_OK && zipStream.avail_out && count);
0185
0186 std::streamsize nRead = size - zipStream.avail_out / sizeof(char_type);
0187
0188 if (err == Z_STREAM_END)
0189 putbackFromZStream();
0190
0191 return nRead;
0192 }
0193
0194 template <typename Item_t, typename Traits_t, typename Allocator_t>
0195 void basic_izstreambuf<Item_t, Traits_t, Allocator_t>::putbackFromZStream() {
0196 if (!zipStream.avail_in)
0197 return;
0198
0199 is->clear(std::ios::goodbit);
0200 is->seekg(-zipStream.avail_in, std::ios_base::cur);
0201 zipStream.avail_in = 0;
0202 }
0203
0204 }
0205
0206 #endif