Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:42

0001 #include <iostream>
0002 #include <algorithm>
0003 #include <lzma.h>
0004 
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 
0007 #include "SimDataFormats/GeneratorProducts/interface/LHEXMLStringProduct.h"
0008 
0009 using namespace edm;
0010 using namespace std;
0011 
0012 LHEXMLStringProduct::LHEXMLStringProduct() {}
0013 
0014 LHEXMLStringProduct::LHEXMLStringProduct(const string &onelheoutput) : content_() { content_.push_back(onelheoutput); }
0015 
0016 LHEXMLStringProduct::~LHEXMLStringProduct() {}
0017 
0018 void LHEXMLStringProduct::fillCompressedContent(std::istream &input, unsigned int initialSize) {
0019   //create blob with desired size
0020   compressedContent_.emplace_back(initialSize);
0021   std::vector<uint8_t> &output = compressedContent_.back();
0022 
0023   //read buffer
0024   constexpr unsigned int bufsize = 4096;
0025   char inbuf[bufsize];
0026 
0027   const unsigned int threshsize = 32 * 1024 * 1024;
0028 
0029   //initialize lzma
0030   uint32_t preset = 9;
0031   lzma_stream strm = LZMA_STREAM_INIT;
0032   lzma_ret ret = lzma_easy_encoder(&strm, preset, LZMA_CHECK_CRC64);
0033 
0034   lzma_action action = LZMA_RUN;
0035 
0036   strm.next_in = reinterpret_cast<uint8_t *>(&inbuf[0]);
0037   strm.avail_in = 0;
0038   strm.next_out = output.data();
0039   strm.avail_out = output.size();
0040 
0041   unsigned int compressedSize = 0;
0042 
0043   while (ret == LZMA_OK) {
0044     //read input to buffer if necessary
0045     if (strm.avail_in == 0 && !input.eof()) {
0046       input.read(inbuf, bufsize);
0047       strm.next_in = reinterpret_cast<uint8_t *>(&inbuf[0]);
0048       strm.avail_in = input.gcount();
0049       if (input.eof()) {
0050         //signal to lzma that there is no more input
0051         action = LZMA_FINISH;
0052       }
0053     }
0054 
0055     //actual compression
0056     ret = lzma_code(&strm, action);
0057 
0058     //update compressed size
0059     compressedSize = output.size() - strm.avail_out;
0060 
0061     //if output blob is full and compression is still going, allocate more memory
0062     if (strm.avail_out == 0 && ret == LZMA_OK) {
0063       unsigned int oldsize = output.size();
0064       if (oldsize < threshsize) {
0065         output.resize(2 * oldsize);
0066       } else {
0067         output.resize(oldsize + threshsize);
0068       }
0069       strm.next_out = &output[oldsize];
0070       strm.avail_out = output.size() - oldsize;
0071     }
0072   }
0073 
0074   lzma_end(&strm);
0075 
0076   if (ret != LZMA_STREAM_END) {
0077     throw cms::Exception("CompressionError") << "There was a failure in LZMA compression in LHEXMLStringProduct.";
0078   }
0079 
0080   //trim output blob
0081   output.resize(compressedSize);
0082 }
0083 
0084 void LHEXMLStringProduct::writeCompressedContent(std::ostream &output, unsigned int i) const {
0085   //initialize lzma
0086   lzma_stream strm = LZMA_STREAM_INIT;
0087   lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
0088   //all output available from the start, so start "close out" immediately
0089   lzma_action action = LZMA_FINISH;
0090 
0091   //write buffer
0092   constexpr unsigned int bufsize = 4096;
0093   char outbuf[bufsize];
0094 
0095   const std::vector<uint8_t> &input = compressedContent_[i];
0096 
0097   strm.next_in = input.data();
0098   strm.avail_in = input.size();
0099   strm.next_out = reinterpret_cast<uint8_t *>(&outbuf[0]);
0100   strm.avail_out = bufsize;
0101 
0102   while (ret == LZMA_OK) {
0103     ret = lzma_code(&strm, action);
0104 
0105     //write to stream
0106     output.write(outbuf, bufsize - strm.avail_out);
0107 
0108     //output buffer full, recycle
0109     if (strm.avail_out == 0 && ret == LZMA_OK) {
0110       strm.next_out = reinterpret_cast<uint8_t *>(&outbuf[0]);
0111       strm.avail_out = bufsize;
0112     }
0113   }
0114 
0115   lzma_end(&strm);
0116 
0117   if (ret != LZMA_STREAM_END) {
0118     throw cms::Exception("DecompressionError") << "There was a failure in LZMA decompression in LHEXMLStringProduct.";
0119   }
0120 }
0121 
0122 bool LHEXMLStringProduct::mergeProduct(LHEXMLStringProduct const &other) {
0123   content_.insert(content_.end(), other.getStrings().begin(), other.getStrings().end());
0124   compressedContent_.insert(compressedContent_.end(), other.getCompressed().begin(), other.getCompressed().end());
0125   return true;
0126 }
0127 
0128 void LHEXMLStringProduct::swap(LHEXMLStringProduct &other) {
0129   content_.swap(other.content_);
0130   compressedContent_.swap(other.compressedContent_);
0131 }