Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:41

0001 #ifndef PhysicsTools_MVAComputer_zstream_icc
0002 #define PhysicsTools_MVAComputer_zstream_icc
0003 // -*- C++ -*-
0004 //
0005 // Package:     Discriminator
0006 //
0007 
0008 //
0009 // Author:  Christophe Saout <christophe.saout@cern.ch>
0010 // Created:     Sat Apr 24 15:18 CEST 2007
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 }  // namespace ext
0205 
0206 #endif  // PhysicsTools_MVAComputer_zstream_icc