CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/GeneratorInterface/ReggeGribovPartonMCInterface/src/LzmaFile.cc

Go to the documentation of this file.
00001 #include "LzmaFile.h"
00002 
00003 #include "LzmaDec.h"
00004 #include "Alloc.h"
00005 #include "Types.h"
00006 #include "7zFile.h"
00007 
00008 //#include <sstream>
00009 //#include <string>
00010 #include <cmath>
00011 #include <iostream>
00012 #include <queue>
00013 #include <cstdlib>
00014 using namespace std;
00015 
00016 const char *kCantReadMessage = "Can not read input file";
00017 const char *kCantWriteMessage = "Can not write output file";
00018 const char *kCantAllocateMessage = "Can not allocate memory";
00019 const char *kDataErrorMessage = "Data error";
00020 
00021 static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
00022 static void SzFree(void *p, void *address) { p = p; MyFree(address); }
00023 static ISzAlloc g_Alloc = { SzAlloc, SzFree };
00024 
00025 LzmaFile::LzmaFile()
00026 {
00027   // fStorage.reserve(10000);
00028   fStartNumber = false;
00029 
00030   fReadSign = true;
00031   fReadMantisseR = true;
00032   fReadMantisseF = false;
00033   fReadExponentSign = false;
00034   fReadExponent = false;
00035       
00036   fNegative = false;
00037   fExponentNegative = false;
00038       
00039   fMantisseR = 0;
00040   fMantisseF = 0;
00041   fMantisseFcount = 0;
00042   fExponent = 0;
00043 }
00044 
00045 
00046 SRes 
00047 LzmaFile::Open(const string& fileName) 
00048 {
00049   //fStrNumber.str("");
00050   //fStrNumber.clear();
00051   
00052   FileSeqInStream_CreateVTable(&inStream);
00053   File_Construct(&inStream.file);
00054 
00055   if (InFile_Open(&inStream.file, fileName.c_str()) != 0) {
00056     cout << "Cannot open input file: " << fileName << endl;
00057     cout << "First use: \n\t \'lzma --best " << fileName.substr(0, fileName.rfind(".lzma")) << "\'"
00058          << " to create it. "
00059          << endl;
00060     exit(1);
00061   }
00062   
00063   ISeqInStream *stream = &inStream.s;
00064   
00065   /* Read and parse header */
00066   /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */
00067   unsigned char header[LZMA_PROPS_SIZE + 8];
00068   RINOK(SeqInStream_Read(stream, header, sizeof(header)));
00069   
00070   unpackSize = 0;
00071   int i = 0;
00072   for (i = 0; i < 8; i++)
00073     unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);
00074   
00075   LzmaDec_Construct(&state);
00076   RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));
00077   LzmaDec_Init(&state);
00078   
00079   inPos = 0;
00080   inSize = 0;
00081   outPos = 0;
00082   return SZ_OK;  
00083 }
00084 
00085 SRes
00086 LzmaFile::ReadNextNumber(double& data)
00087 {
00088   if (fStorage.empty()) {
00089     const int ret = DecodeBuffer();
00090     if (ret != SZ_OK) {
00091       cout << "Error in ReadNextNumber  ret=" << ret << endl;
00092       return SZ_ERROR_DATA;
00093     }
00094   }
00095   
00096   data = fStorage.front();
00097   fStorage.pop();
00098   return SZ_OK;
00099 }
00100 
00101 
00102 
00103 SRes
00104 LzmaFile::FillArray(double* data, const int length)
00105 {
00106   for (int i=0; i<length; ++i) {
00107     
00108     if (fStorage.empty()) {
00109       const int ret = DecodeBuffer();
00110       if (ret != SZ_OK) {
00111         cout << "Error in FillArray i=" << i << " ret=" << ret << endl;
00112         return SZ_ERROR_DATA;
00113       }
00114     }
00115     
00116     data[i] = fStorage.front();
00117     fStorage.pop();
00118     
00119   }
00120   
00121   return SZ_OK;
00122   
00123 }
00124 
00125 
00126 /*
00127 double 
00128 LzmaFile::strToDouble(const char& p) {
00129 
00130   // init
00131   fR = 0;  
00132   fNegative = false;
00133   
00134   if (*p == '-') {
00135     neg = true;
00136     ++p;
00137   }
00138   while (*p >= '0' && *p <= '9') {
00139     r = (r*10.0) + (*p - '0');
00140     ++p;
00141   }
00142   if (*p == '.') {
00143     double f = 0.0;
00144     int n = 0;
00145     ++p;
00146     while (*p >= '0' && *p <= '9') {
00147       f = (f*10.0) + (*p - '0');
00148       ++p;
00149       ++n;
00150     }
00151     r += f / std::pow(10.0, n);
00152   }
00153   if (neg) {
00154     r = -r;
00155   }
00156   return r;
00157 }
00158 */
00159 
00160 
00161 SRes
00162 LzmaFile::DecodeBuffer()
00163 {
00164   ISeqInStream *stream = &inStream.s;
00165   
00166   const int thereIsSize = (unpackSize != (UInt64)(Int64)-1);
00167   
00168     
00169   if (inPos == inSize) {
00170     inSize = IN_BUF_SIZE;
00171     RINOK(stream->Read(stream, inBuf, &inSize));
00172     inPos = 0;
00173   }
00174   
00175   SizeT inProcessed = inSize - inPos;
00176   SizeT outProcessed = OUT_BUF_SIZE - outPos;
00177   ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
00178   ELzmaStatus status;
00179   
00180   if (thereIsSize && outProcessed > unpackSize) {
00181     outProcessed = (SizeT)unpackSize;
00182     finishMode = LZMA_FINISH_END;
00183   }
00184   
00185   SRes res = LzmaDec_DecodeToBuf(&state, outBuf, &outProcessed,
00186                                  inBuf + inPos, &inProcessed, finishMode, &status);
00187   inPos += inProcessed;
00188   unpackSize -= outProcessed;
00189   
00190     
00191   const char* strBuf = (const char*)outBuf;
00192 
00193   int countC = 0;
00194   int countNum = 0;
00195   do {
00196     
00197     if (countC >= int(outProcessed)) {
00198       // cout << " countC=" << countC 
00199       //           << " outProcessed=" << outProcessed
00200       //           << endl;
00201       break;
00202     }
00203     
00204     const char& C = strBuf[countC]; 
00205     countC++;
00206     
00207     //cout << "\'" << C << "\'" << endl;
00208     
00209     if (C==' ' || C=='\n') { // END OF NUMBER
00210 
00211       if (!fStartNumber) 
00212         continue;
00213       
00214       //istringstream strToNum(fStrNumber.str().c_str());
00215       //double number = atof(fStrNumber.str().c_str());
00216       //strToNum >> number;
00217       
00218       const double number = (fNegative?-1:1) * (fMantisseR + fMantisseF/pow(10, fMantisseFcount)) * pow(10, (fExponentNegative?-1:1) * fExponent);
00219       //cout << " number=" << number << endl;
00220       
00221       fStorage.push(number);      
00222       countNum++;
00223       
00224       fStartNumber = false;
00225 
00226       fReadSign = true;
00227       fReadMantisseR = true;
00228       fReadMantisseF = false;
00229       fReadExponentSign = false;
00230       fReadExponent = false;
00231       
00232       fNegative = false;
00233       fExponentNegative = false;
00234       
00235       fMantisseR = 0;
00236       fMantisseF = 0;
00237       fMantisseFcount = 0;
00238       fExponent = 0;
00239       
00240       continue;
00241     }
00242     
00243     fStartNumber = true;
00244     const int num = C - '0';
00245     if (num >= 0 && num <= 9) {
00246         
00247       if (fReadMantisseR) {
00248         fReadSign = false;
00249         fMantisseR = fMantisseR*10 + num;
00250       } else if (fReadMantisseF) {
00251         fReadSign = false;
00252         fMantisseF = fMantisseF*10 + num;
00253         ++fMantisseFcount;
00254       } else if (fReadExponent) {
00255         fReadExponentSign = false;
00256         fExponent = fExponent*10 + num;
00257       }
00258       
00259     } else {
00260       
00261       switch(C) {
00262       case '-':
00263         {
00264           if (fReadSign) {
00265             fNegative = true;
00266             fReadSign = false;
00267             fReadMantisseR = true;
00268           } else if (fReadExponentSign) {       
00269             fExponentNegative = true;
00270             fReadExponentSign = false;
00271             fReadExponent = true;
00272           } else {
00273             cout << "LzmaFile: found \'" << C << "\' at wrong position. " << endl;
00274             exit(10);
00275           }
00276         }
00277         break;
00278       case '.': 
00279         if (!fReadMantisseR) {
00280           cout << "LzmaFile: found \'" << C << "\' at wrong position. " << endl;
00281           exit(10);
00282         }
00283         fReadMantisseR = false;
00284         fReadMantisseF = true;
00285         break;
00286       case 'e':
00287       case 'E':
00288       case 'D': 
00289       case 'd':
00290         if (!fReadMantisseR || !fReadMantisseF) {
00291           fReadMantisseR = false;
00292           fReadMantisseF = false;
00293           fReadExponentSign = true;
00294           fReadExponent = true;
00295         }
00296         break;
00297       default:
00298         cout << "LzmaFile: found \'" << C << "\' at wrong position. " << endl;
00299         exit(10);
00300         break;
00301       }
00302     }
00303         
00304   } while(true);
00305   
00306   //strBuf.str("");
00307   //strBuf.clear();
00308   
00309 
00310   /*    
00311   if (!strNumber.str().empty()) {
00312     cout << "NACHZUEGLER" << endl;
00313     istringstream strToNum(strNumber.str());
00314     double number;
00315     strToNum >> number;
00316     fStorage.push(number);
00317   }
00318   */
00319     
00320   
00321 
00322     
00323   if (res != SZ_OK || (thereIsSize && unpackSize == 0)) 
00324     return res;
00325     
00326   if (inProcessed == 0 && outProcessed == 0) {
00327     if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
00328       return SZ_ERROR_DATA;
00329     return res;
00330   }
00331 
00332   return SZ_OK;
00333 }
00334 
00335 
00336 
00337 
00338 SRes
00339 LzmaFile::DecodeAll()
00340 {
00341   ISeqInStream *stream = &inStream.s;
00342 
00343   int thereIsSize = (unpackSize != (UInt64)(Int64)-1);
00344   
00345   for (;;) {
00346 
00347     if (inPos == inSize) {
00348       inSize = IN_BUF_SIZE;
00349       RINOK(stream->Read(stream, inBuf, &inSize));
00350       inPos = 0;
00351     }
00352     
00353     SizeT inProcessed = inSize - inPos;
00354     SizeT outProcessed = OUT_BUF_SIZE - outPos;
00355     ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
00356     ELzmaStatus status;
00357     
00358     if (thereIsSize && outProcessed > unpackSize) {
00359       outProcessed = (SizeT)unpackSize;
00360       finishMode = LZMA_FINISH_END;
00361     }
00362     
00363     SRes res = LzmaDec_DecodeToBuf(&state, outBuf, &outProcessed,
00364                                    inBuf + inPos, &inProcessed, finishMode, &status);
00365     inPos += inProcessed;
00366     unpackSize -= outProcessed;
00367     
00368     
00369     unsigned int k=0;
00370     for (k=0; k<outProcessed; ++k) {
00371       printf("%c", outBuf[k]);
00372     }
00373   
00374     if (res != SZ_OK || (thereIsSize && unpackSize == 0))
00375       return res;
00376     
00377     if (inProcessed == 0 && outProcessed == 0) {
00378       if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
00379         return SZ_ERROR_DATA;
00380       return res;
00381     }
00382 
00383   } // for loop
00384   
00385   return 0;
00386 }
00387 
00388 
00389 
00390 SRes
00391 LzmaFile::Close()
00392 {
00393   LzmaDec_Free(&state, &g_Alloc);
00394   res = File_Close(&inStream.file);
00395   return res;
00396 }