LCOV - code coverage report
Current view: top level - alma/ASDMBinaries - SDMDataObjectStreamReader.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 495 0.0 %
Date: 2024-10-04 18:58:15 Functions: 0 56 0.0 %

          Line data    Source code
       1             : #include <alma/ASDMBinaries/SDMDataObjectStreamReader.h>
       2             : 
       3             : #ifdef WITHOUT_BOOST
       4             : #include <regex>
       5             : #include <alma/ASDM/Misc.h>
       6             : #endif
       7             : 
       8             : using namespace CorrelationModeMod;
       9             : using namespace CorrelatorTypeMod;
      10             : using namespace PrimitiveDataTypeMod;
      11             : using namespace ProcessorTypeMod;
      12             : 
      13             : using namespace std;
      14             : 
      15             : namespace asdmbinaries {
      16             : 
      17           0 :   SDMDataObjectStreamReaderException::SDMDataObjectStreamReaderException():message("SDMDataObjectStreamReaderException:") {;}
      18             : 
      19           0 :   SDMDataObjectStreamReaderException::SDMDataObjectStreamReaderException(const string & message): message("SDMDataObjectStreamReaderException:" + message) {;}   
      20             : 
      21           0 :   const string& SDMDataObjectStreamReaderException::getMessage() { return message; }
      22             : 
      23           0 :   SDMDataObjectStreamReader::SDMDataObjectStreamReader()  {
      24             :   // cout << "SDMDataObjectStreamReader::SDMDataObjectStreamReader() : entering" << endl;
      25           0 :     const char *partNames[] = {"actualDurations", "actualTimes", "autoData", "crossData", "zeroLags", "flags"};
      26           0 :     set<string> dummy(partNames, partNames+6);
      27           0 :     s_partNames = dummy;
      28           0 :     sdmDataSubset = SDMDataSubset(&sdmDataObject);
      29             : 
      30           0 :     boundary_1 = "" ;
      31           0 :     currentState = S_NO_BDF;
      32             :   // cout << "SDMDataObjectStreamReader::SDMDataObjectStreamReader() : exiting" << endl;
      33           0 :   }
      34             : 
      35           0 :   SDMDataObjectStreamReader::~SDMDataObjectStreamReader() {
      36             :     //cout << "SDMDataObjectStreamReader::~SDMDataObjectStreamReader : entering" << endl;
      37           0 :     this->close();
      38             :     //cout << "SDMDataObjectStreamReader::~SDMDataObjectStreamReader : exiting" << endl;
      39           0 :   }
      40             : 
      41           0 :   void SDMDataObjectStreamReader::open(const string& path) {
      42           0 :     checkState(T_OPEN, "open");
      43           0 :     this->path = path;
      44           0 :     f.open(path.c_str(), ifstream::in);
      45           0 :     if (f.fail())
      46           0 :       throw SDMDataObjectStreamReaderException("could not open '" + path + "'.");
      47             : 
      48           0 :     boundary_1 = requireMIMEHeader();
      49             :     // cout << "Boundary = " << boundary_1 << endl;
      50           0 :     sdmDataObject.valid_ = true;
      51           0 :     requireSDMDataHeaderMIMEPart();
      52           0 :     sdmDataObject.owns();
      53           0 :     integrationIndex = -1; // We have not yet read any integration.
      54             : 
      55           0 :     currentState = S_AT_BEGINNING;
      56           0 :   }
      57             : 
      58           0 :   int64_t SDMDataObjectStreamReader::position() {
      59           0 :     return (int64_t) f.tellg();
      60             :   }
      61             : 
      62           0 :   void SDMDataObjectStreamReader::position(int64_t p) {
      63           0 :     f.seekg(p);
      64           0 :   }
      65             : 
      66           0 :   void SDMDataObjectStreamReader::close() {
      67             :     // cout << "SDMDataObjectStreamReader::close -- Entering" << endl;
      68           0 :     if (f.is_open()) {
      69           0 :       releaseMemory(sdmDataSubset);
      70           0 :       for (unsigned int i = 0; i < remainingSubsets.size(); i++)
      71           0 :         releaseMemory(remainingSubsets[i]);
      72           0 :       for (unsigned int i = 0; i < someSubsets.size(); i++)
      73           0 :         releaseMemory(someSubsets[i]);
      74           0 :       f.close();
      75           0 :       currentState = S_NO_BDF;
      76             :     }
      77             :     // cout << "SDMDataObjectStreamReader::close -- Exiting" << endl;
      78           0 :   }
      79             : 
      80           0 :   unsigned int SDMDataObjectStreamReader::currentIntegrationIndex() const { checkState(T_QUERY, "currentIntegrationIndex"); return integrationIndex; }
      81           0 :   unsigned long long SDMDataObjectStreamReader::currentIntegrationStartsAt() const { checkState(T_QUERY, "currentIntegrationStartAt"); return integrationStartsAt; }
      82           0 :   string                                SDMDataObjectStreamReader::title() const { checkState(T_QUERY, "title"); return sdmDataObject.title(); }
      83           0 :   const ByteOrder*                      SDMDataObjectStreamReader::byteOrder() const { checkState(T_QUERY, "byteOrder"); return sdmDataObject.byteOrder(); }
      84           0 :   unsigned long long                    SDMDataObjectStreamReader::startTime() const { checkState(T_QUERY, "startTime"); return sdmDataObject.startTime(); }
      85           0 :   unsigned int                          SDMDataObjectStreamReader::numTime() const { checkState(T_QUERY, "numTime"); return sdmDataObject.numTime(); }
      86           0 :   string                                SDMDataObjectStreamReader::dataOID() const { checkState(T_QUERY, "dataOID"); return sdmDataObject.dataOID(); }
      87           0 :   string                                SDMDataObjectStreamReader::execBlockUID() const { checkState(T_QUERY, "execBlockUID"); return sdmDataObject.execBlockUID(); }
      88           0 :   unsigned int                          SDMDataObjectStreamReader::execBlockNum() const { checkState(T_QUERY, "execBlockNum"); return sdmDataObject.execBlockNum(); }
      89           0 :   unsigned int                          SDMDataObjectStreamReader::scanNum() const { checkState(T_QUERY, "scanNum"); return sdmDataObject.scanNum(); }
      90           0 :   unsigned int                          SDMDataObjectStreamReader::subscanNum() const { checkState(T_QUERY, "subscanNum"); return sdmDataObject.subscanNum(); }
      91           0 :   unsigned int                          SDMDataObjectStreamReader::numAntenna() const { checkState(T_QUERY, "numAntenna"); return sdmDataObject.numAntenna(); }
      92           0 :   CorrelationMode                       SDMDataObjectStreamReader::correlationMode() const { checkState(T_QUERY, "correlationMode"); return sdmDataObject.correlationMode(); }
      93           0 :   OptionalSpectralResolutionType        SDMDataObjectStreamReader::spectralResolutionType() const { checkState(T_QUERY, "spectralResolutionType"); return sdmDataObject.spectralResolutionType(); }
      94           0 :   ProcessorType                         SDMDataObjectStreamReader::processorType() const { checkState(T_QUERY, "processorType"); return sdmDataObject.processorType(); }
      95           0 :   CorrelatorType                        SDMDataObjectStreamReader::correlatorType() const { checkState(T_QUERY, "correlatorType"); return sdmDataObject.correlatorType(); }
      96           0 :   bool                                  SDMDataObjectStreamReader::hasPackedData() const { checkState(T_QUERY, "isTP"); return sdmDataObject.hasPackedData();} 
      97           0 :   bool                                  SDMDataObjectStreamReader::isTP() const { checkState(T_QUERY, "isTP"); return sdmDataObject.isTP();} 
      98           0 :   bool                                  SDMDataObjectStreamReader::isWVR() const {checkState(T_QUERY, "isCorrelation"); return sdmDataObject.isWVR();} 
      99           0 :   bool                                  SDMDataObjectStreamReader::isCorrelation() const {checkState(T_QUERY, "isCorrelation"); return sdmDataObject.isCorrelation();} 
     100           0 :   const SDMDataObject::DataStruct&  SDMDataObjectStreamReader::dataStruct() const { checkState(T_QUERY, "dataStruct"); return sdmDataObject.dataStruct();}
     101           0 :   bool                                  SDMDataObjectStreamReader::aborted() const {checkState(T_QUERY, "aborted"); return sdmDataObject.aborted();} 
     102           0 :   unsigned long long                    SDMDataObjectStreamReader::abortTime() const { checkState(T_QUERY, "abortTime"); return sdmDataObject.abortTime(); }
     103           0 :   string                                SDMDataObjectStreamReader::abortReason() const { checkState(T_QUERY, "abortReason"); return sdmDataObject.abortReason(); }
     104           0 :   string                                SDMDataObjectStreamReader::toString() const { checkState(T_QUERY, "toString"); return sdmDataObject.toString(); }
     105             : 
     106           0 :   void SDMDataObjectStreamReader::checkState(Transitions t, const string& methodName) const {
     107             :     // cout << "Entering checkState with currentState = " << currentState << " and transition = " << t << " for method " << methodName << endl;
     108           0 :     switch (currentState) {
     109           0 :     case S_NO_BDF:
     110           0 :       if ( t == T_OPEN ) {
     111           0 :         return;
     112             :       }
     113           0 :       break;
     114             :       
     115           0 :     case S_AT_BEGINNING :
     116           0 :       switch (t) {
     117           0 :       case T_QUERY:
     118             :       case T_TEST_END:
     119             :       case T_READ:
     120             :       case T_READ_NEXT:
     121             :       case T_READ_ALL:
     122             :       case T_CLOSE:
     123           0 :         return;
     124           0 :       default :
     125           0 :         break;
     126             :       }
     127           0 :       break;
     128             :       
     129           0 :     case S_READING:
     130           0 :       switch (t) {
     131           0 :       case T_TEST_END:
     132             :       case T_READ:
     133             :       case T_READ_NEXT:
     134             :       case T_READ_ALL:
     135             :       case T_QUERY:
     136             :       case T_CLOSE:
     137           0 :         return;
     138           0 :       default :
     139           0 :         break;
     140             :       }
     141           0 :       break;
     142             : 
     143           0 :     case S_AT_END:
     144           0 :       switch(t) {
     145           0 :       case  T_TEST_END:
     146             :       case T_QUERY: 
     147             :       case T_READ_NEXT:
     148             :       case T_READ_ALL:
     149             :       case T_CLOSE:
     150           0 :         return;
     151           0 :       default:
     152           0 :         break;
     153             :       }
     154           0 :       break;
     155             :     } // end switch on currentState
     156             : 
     157             :     // Any other pair (transition, currentState) will throw an exception.
     158           0 :     throw SDMDataObjectStreamReaderException("Invalid call of method '" + methodName + "' in the current context.");
     159             :   }
     160             : 
     161           0 :   bool SDMDataObjectStreamReader::hasSubset() {
     162           0 :     checkState(T_TEST_END, "hasSubset");
     163           0 :     bool atEnd = currentLine.compare("--"+boundary_1+"--") == 0;
     164           0 :     if (atEnd) currentState = S_AT_END;
     165           0 :     return !atEnd;
     166             :   }
     167             :  
     168           0 :   const vector<SDMDataSubset>& SDMDataObjectStreamReader::nextSubsets(unsigned int nSubsets) {
     169           0 :     checkState(T_READ_NEXT, "nextSubsets");
     170             :     
     171             :     // Deep empty of the vector nextSubsets
     172             :     // Firstly free all memory dynamically allocated in every element of the vector.
     173           0 :     for (unsigned int i = 0; i < someSubsets.size(); i++)
     174           0 :       releaseMemory(someSubsets.at(i));
     175             :     
     176             :     // Then clear the vector.
     177           0 :     someSubsets.clear();
     178             : 
     179             :     // Then populate the vector nextSubsets with as many SDMDataSubsets as possible up to a limit
     180             :     // of nSubsets read from the current position.
     181           0 :     unsigned int nRead = 0;
     182           0 :     while ((nRead < nSubsets) && hasSubset()) {
     183           0 :       someSubsets.push_back(SDMDataSubset(&sdmDataObject));
     184           0 :       integrationIndex++; nRead++;
     185           0 :       requireSDMDataSubsetMIMEPart(someSubsets.back());
     186           0 :       string line = nextLine();      
     187           0 :     }
     188             : 
     189           0 :     return someSubsets;
     190             :   }
     191             : 
     192           0 :   const vector<SDMDataSubset>& SDMDataObjectStreamReader::allRemainingSubsets() {
     193             :     // cout << "SDMDataObjectStreamReader::allRemainingSubsets: entering." << endl;
     194           0 :     checkState(T_READ_ALL, "allRemainingSubsets");
     195             : 
     196             :     // Deep empty of the vector remainingSubsets.
     197             :     // Firstly free all memory dynamically allocated in every element of the vector.
     198           0 :     for (unsigned int i = 0; i < remainingSubsets.size(); i++)
     199           0 :       releaseMemory(remainingSubsets.at(i));
     200             :     
     201             :     // Then clear the vector.
     202           0 :     remainingSubsets.clear();
     203             : 
     204             :     // Then populate the vector with a new collection.
     205           0 :     while (hasSubset()) {
     206           0 :       remainingSubsets.push_back(SDMDataSubset(&sdmDataObject));
     207           0 :       integrationIndex++;
     208           0 :       requireSDMDataSubsetMIMEPart(remainingSubsets.back());
     209           0 :       string line = nextLine();
     210           0 :     }
     211             : 
     212             :     // cout << "SDMDataObjectStreamReader::allRemainingSubsets: exiting." << endl;
     213           0 :     return remainingSubsets;
     214             :   }
     215             : 
     216           0 :   const SDMDataSubset & SDMDataObjectStreamReader::getSubset() {
     217           0 :     checkState(T_READ, "getSubset");
     218           0 :     integrationIndex++;
     219           0 :     requireSDMDataSubsetMIMEPart(sdmDataSubset);
     220           0 :     string line = nextLine();
     221             : 
     222           0 :     currentState = S_READING;
     223           0 :     return sdmDataSubset;
     224           0 :   }
     225             : 
     226           0 :   string SDMDataObjectStreamReader::nextLine() {
     227           0 :     unsigned long long whereAmI = f.tellg();
     228           0 :     getline(f, currentLine);
     229           0 :     if (f.fail()) {
     230           0 :       ostringstream oss ;
     231           0 :       oss << "SDMDataObjectStreamReader::nextLine() : I could not read a line in '" << path <<  "' at position " << whereAmI << ".";
     232           0 :       throw SDMDataObjectStreamReaderException(oss.str());
     233           0 :     }
     234             :     // cout << "nextLine has read '" << currentLine << "'" << endl;
     235           0 :     return currentLine;
     236             :   }
     237             : 
     238           0 :   pair<string, string> SDMDataObjectStreamReader::headerField2Pair(const string& hf){
     239           0 :     string name, value;
     240           0 :     size_t colonIndex = hf.find(":");
     241           0 :     if (colonIndex == string::npos)
     242           0 :       throw SDMDataObjectStreamReaderException(" could not detect a well formed MIME header field in '"+hf+"'");
     243             : 
     244           0 :     if (colonIndex > 0) {
     245           0 :       name = hf.substr(0, colonIndex);
     246             : #ifndef WITHOUT_BOOST
     247             :       boost::algorithm::trim(name);
     248             : #else
     249           0 :       asdm::trim(name);
     250             : #endif
     251             :     }
     252             : 
     253           0 :     if (colonIndex < hf.size()) {
     254           0 :       value = hf.substr(colonIndex+1);
     255             : #ifndef WITHOUT_BOOST
     256             :       boost::algorithm::trim(value);
     257             : #else
     258           0 :       asdm::trim(value);
     259             : #endif
     260             :     }
     261             : 
     262           0 :     return make_pair(name, value);
     263           0 :   }
     264             : 
     265           0 :   pair<string, string> SDMDataObjectStreamReader::requireHeaderField(const string & hf) {
     266           0 :     pair<string, string> hf2pair(headerField2Pair(nextLine()));
     267             :     // cout << hf2pair.first << ", " << hf2pair.second << endl;
     268             : #ifndef WITHOUT_BOOST
     269             :     if (boost::algorithm::to_upper_copy(hf2pair.first) != hf)
     270             :       throw SDMDataObjectStreamReaderException("read '" + currentLine + "'. Was expecting '" + hf + "'...");
     271             : #else
     272           0 :     if (asdm::str_toupper(hf2pair.first) != hf)
     273           0 :       throw SDMDataObjectStreamReaderException("read '" + currentLine + "'. Was expecting '" + hf + "'...");
     274             : #endif
     275           0 :     return hf2pair;
     276           0 :   }
     277             : 
     278           0 :   string unquote(const string& s, string& unquoted) {
     279           0 :     if (s.size() >= 2) 
     280           0 :       if (((s.at(0) == '"') && (s.at(s.size()-1) == '"')) || ((s.at(0) == '\'') && (s.at(s.size()-1) == '\''))) {
     281           0 :         if (s.size() == 2)
     282           0 :           unquoted = "";
     283             :         else
     284           0 :           unquoted = s.substr(1, s.size() - 2);
     285             :       }
     286             :       else
     287           0 :         unquoted = s;
     288             :     else
     289           0 :       unquoted = s;
     290           0 :     return unquoted;
     291             :   }
     292             :   
     293             : 
     294             : 
     295           0 :   string SDMDataObjectStreamReader::requireBoundaryInCT(const string& ctValue) {
     296           0 :     vector<string> cvValueItems;
     297             :  
     298             : #ifndef WITHOUT_BOOST
     299             :     boost::algorithm::split (cvValueItems, ctValue, boost::algorithm::is_any_of(";"));
     300             :     vector<string> cvValueItemsNameValue;
     301             :     for ( vector<string>::const_iterator iter = cvValueItems.begin(); iter != cvValueItems.end() ; iter++ ) {
     302             :       cvValueItemsNameValue.clear();
     303             :       boost::algorithm::split(cvValueItemsNameValue, *iter, boost::algorithm::is_any_of("="));
     304             :       string boundary;
     305             :       if ((cvValueItemsNameValue.size() > 1) && (boost::algorithm::to_upper_copy(boost::algorithm::trim_copy(cvValueItemsNameValue[0])) == "BOUNDARY") && (unquote(cvValueItemsNameValue[1], boundary).size() > 0))
     306             :         return boundary;
     307             :     }
     308             : #else
     309           0 :     asdm::strsplit (ctValue, ';', cvValueItems);
     310           0 :     vector<string> cvValueItemsNameValue;
     311           0 :     for ( vector<string>::const_iterator iter = cvValueItems.begin(); iter != cvValueItems.end() ; iter++ ) {
     312           0 :       cvValueItemsNameValue.clear();
     313           0 :       asdm::strsplit(*iter,'=',cvValueItemsNameValue);
     314           0 :       string boundary;
     315           0 :       if ((cvValueItemsNameValue.size() > 1) && (asdm::str_toupper(asdm::trim_copy(cvValueItemsNameValue[0])) == "BOUNDARY") && (unquote(cvValueItemsNameValue[1], boundary).size() > 0))
     316           0 :         return boundary;
     317           0 :     }
     318             : #endif
     319           0 :     throw SDMDataObjectStreamReaderException("could not find a boundary definition in '" + ctValue + "'.");
     320           0 :   }
     321             : 
     322           0 :   void SDMDataObjectStreamReader::skipAsLongAsLineStartsWith(const string& start) {
     323           0 :     int64_t curpos = 0;
     324             :     do {
     325           0 :       curpos = position();
     326           0 :       nextLine();
     327             :     }
     328           0 :     while (currentLine.find(start) == 0);
     329           0 :     position(curpos);
     330           0 :     return;
     331             :   }
     332             : 
     333           0 :   void SDMDataObjectStreamReader::skipUntilEmptyLine(int maxSkips) {
     334             :     // cout << "Entering skipUntilEmptyLine" << endl;
     335           0 :     int numSkips = 0;
     336           0 :     string line = nextLine();
     337           0 :     while ((line.size() != 0) && (numSkips <= maxSkips)) {
     338           0 :       line = nextLine();
     339           0 :       numSkips += 1;
     340             :     }
     341             : 
     342           0 :     if (numSkips > maxSkips) {
     343           0 :       ostringstream oss;
     344           0 :       oss << "could not find an empty line is less than " << maxSkips + 1 << " lines." << endl;
     345           0 :       throw SDMDataObjectStreamReaderException(oss.str());
     346           0 :     } 
     347             :     // cout << "Exiting skipUntilEmptyLine" << endl;
     348           0 :   }
     349             : 
     350             : 
     351           0 :   string SDMDataObjectStreamReader::requireMIMEHeader() {
     352             :     // MIME-Version
     353           0 :     pair<string, string>name_value(headerField2Pair(nextLine()));
     354             :     // cout << name_value.first << "=" << name_value.second << endl;
     355             :     // if (currentLine != "MIME-Version: 1.0") // a work around for the case when the very first character is not the expected "M" (happened with some corrupted data).
     356             : #ifndef WITHOUT_BOOST
     357             :     if (! boost::algorithm::iends_with(currentLine, "IME-Version: 1.0"))
     358             : #else
     359           0 :     std::string versionEnd = "IME-Version: 1.0";
     360           0 :     if ((currentLine.size()<=versionEnd.size()) || (currentLine.compare((currentLine.size()-versionEnd.size()),versionEnd.size(),versionEnd)!=0))
     361             : #endif
     362           0 :       throw SDMDataObjectStreamReaderException("'MIME-Version: 1.0' missing at the very beginning of the file '"+path+"'.");
     363             : 
     364             :     // Content-Type
     365           0 :     boundary_1 = requireBoundaryInCT(requireHeaderField("CONTENT-TYPE").second);
     366             : 
     367             :     // cout << "boundary_1 =" << boundary_1 << endl;
     368             : 
     369             :     // Content-Description
     370           0 :     name_value = requireHeaderField("CONTENT-DESCRIPTION");
     371             : 
     372             :     // Content-Location
     373           0 :     name_value = requireHeaderField("CONTENT-LOCATION");
     374             : 
     375             :     // Look for an empty line in the at most 10 subsequent lines.
     376           0 :     skipUntilEmptyLine(10);
     377             : 
     378           0 :     return boundary_1;
     379           0 :   }
     380             : 
     381           0 :   string SDMDataObjectStreamReader::accumulateUntilBoundary(const string& boundary, int maxLines) {
     382             :     // cout << "Entering accumulateUntilBoundary with maxLines = " << maxLines << endl;
     383           0 :     int numLines = 0;
     384           0 :     string line = nextLine();
     385           0 :     string result;
     386           0 :     while ((numLines <= maxLines) && (line.find("--"+boundary) == string::npos)) {
     387           0 :       result += line;
     388           0 :       numLines++;
     389           0 :       line = nextLine();
     390             :     }
     391             : 
     392           0 :     if (numLines > maxLines) {
     393           0 :       ostringstream oss;
     394           0 :       oss << "could not find the boundary string '"<< boundary << "' in less than " << maxLines + 1 << " lines." << endl;
     395           0 :       throw SDMDataObjectStreamReaderException(oss.str());    
     396           0 :     }
     397             : 
     398           0 :     return result;
     399           0 :   }
     400             : 
     401           0 :   void SDMDataObjectStreamReader::requireBoundary(const string& boundary, int maxLines) {
     402             :     // cout << "Entering require boundary with boundary == '" << boundary << "' and maxLines = " << maxLines << endl; 
     403           0 :     int numLines = 0;
     404           0 :     string dashdashBoundary = "--"+boundary;
     405           0 :     string line = nextLine();
     406           0 :     while ((numLines <= maxLines) && (line.compare(dashdashBoundary) != 0)) {
     407           0 :       numLines++;
     408           0 :       line = nextLine();
     409             :     }
     410             : 
     411           0 :     if (numLines > maxLines) {
     412           0 :       ostringstream oss;
     413           0 :       oss << "could not find the boundary string '"<< boundary << "' in less than " << maxLines + 1 << " lines." << endl;
     414           0 :       throw SDMDataObjectStreamReaderException(oss.str());
     415           0 :     }
     416           0 :   }
     417             : 
     418           0 :   void SDMDataObjectStreamReader::lookForBinaryPartSize(xmlNode* aNode) {
     419             : #ifndef WITHOUT_BOOST
     420             :     const boost::regex UINT("[0-9]+");
     421             : #else
     422           0 :     const std::regex UINT("[0-9]+");
     423             : #endif
     424           0 :     xmlNode *curNode = NULL;
     425             : 
     426           0 :     for (curNode = aNode; curNode ; curNode = curNode->next) {
     427           0 :       if (curNode->type == XML_ELEMENT_NODE) {
     428           0 :         if (s_partNames.find(string((char *)curNode->name)) != s_partNames.end()){
     429           0 :           if (xmlHasProp(curNode, (const xmlChar*) "size")) {
     430           0 :             xmlChar * value = xmlGetProp(curNode, (const xmlChar *) "size");
     431             : #ifndef WITHOUT_BOOST
     432             :             boost::cmatch what;
     433             :             if (boost::regex_match((char*) value, what, UINT)) {
     434             : #else
     435           0 :             std::cmatch what;
     436           0 :             if (std::regex_match((char*) value, what, UINT)) {
     437             : #endif
     438           0 :               int64_t result = ::atoi(what[0].first);
     439           0 :               xmlFree(value);
     440           0 :               binaryPartSize[string((char *) curNode->name)] = result;
     441             :             }
     442             :             else {
     443           0 :               xmlFree(value);
     444           0 :               throw SDMDataObjectStreamReaderException("In '" + string((const char*) curNode->name) + "' failed to parse the value of '"+string((const char*) value)+"' as an int.");
     445             :             }    
     446           0 :           }
     447             :           else {
     448           0 :             throw SDMDataObjectStreamReaderException("In '" + string((const char*) curNode->name) + "' could not find the attribute 'size'.");
     449             :           }
     450             :         }
     451             :       }
     452           0 :       lookForBinaryPartSize(curNode->children);
     453             :     }
     454           0 :   }
     455             : 
     456           0 :   string SDMDataObjectStreamReader::requireCrossDataType(xmlNode* parent) {
     457           0 :     string result;
     458             : 
     459           0 :     string comparee("crossData");
     460           0 :     xmlNode * child = parent->children;
     461             : 
     462           0 :     while ((child != 0) && (comparee.compare((const char*) child->name) != 0))
     463           0 :       child = child->next;
     464             : 
     465           0 :     if ((child == 0) || (child->type != XML_ELEMENT_NODE)) {
     466           0 :       ostringstream oss;
     467           0 :       oss << "could not find the element 'crossData'." << endl;
     468           0 :       throw SDMDataObjectStreamReaderException(oss.str());
     469           0 :     }
     470             : 
     471           0 :     if (xmlHasProp(child, (const xmlChar*) "type")) {
     472           0 :       xmlChar * value = xmlGetProp(child, (const xmlChar *) "type");
     473           0 :       result = string((const char *) value);
     474           0 :       xmlFree(value);
     475           0 :       return result;
     476             :     }
     477             :     else
     478           0 :       throw SDMDataObjectStreamReaderException("In '" + string((const char*) child->name) + "' could not find the attribute 'type'.");
     479           0 :   }
     480             : 
     481           0 :   void SDMDataObjectStreamReader::printElementNames(xmlNode * a_node) {
     482           0 :     xmlNode *cur_node = NULL;
     483             : 
     484           0 :     for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
     485           0 :       if (cur_node->type == XML_ELEMENT_NODE) {
     486           0 :         cout << "node type: Element, name: " << cur_node->name << endl;
     487             :       }
     488           0 :       printElementNames(cur_node->children);
     489             :     }
     490           0 :   }
     491             : 
     492           0 :   void SDMDataObjectStreamReader::requireSDMDataHeaderMIMEPart() {
     493             :     //
     494             :     // Requires the presense of boundary_1
     495           0 :     requireBoundary(boundary_1, 0);
     496             : 
     497             :     // Ignore header fields
     498             :     // requireHeaderField("CONTENT-TYPE")
     499             :     // requireHeaderField("CONTENT-TRANSFER-ENCODING")
     500             :     // requireHeaderField("CONTENT-LOCATION")
     501             : 
     502             :     //
     503             :     // Look for an empty line at most distant from 100 lines from here.
     504           0 :     skipUntilEmptyLine(10);
     505           0 :     string sdmDataHeader = accumulateUntilBoundary(boundary_1, 100);
     506             :  
     507             :     /*
     508             :     xmlDoc * doc = xmlReadMemory(sdmDataHeader.data(), sdmDataHeader.size(),  "SDMDataHeader.xml", NULL, XML_PARSE_NOBLANKS);
     509             :     xmlChar* xmlBuff;
     510             :     int bufferSize;
     511             :     xmlDocDumpFormatMemory(doc, &xmlBuff, &bufferSize, 1);
     512             :     cout << string((const char*) xmlBuff, bufferSize) << endl;
     513             :     xmlFree(xmlBuff);
     514             :     xmlNode* root_element = xmlDocGetRootElement(doc);
     515             :     if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
     516             :       throw SDMDataObjectStreamReaderException("Failed to parse the SDMDataHeader into a DOM structure."); 
     517             :     */
     518             :  
     519           0 :     parser.parseMemoryHeader(sdmDataHeader, sdmDataObject);
     520             :     unsigned int bps;
     521           0 :     if ((bps = sdmDataObject.dataStruct().flags().size()))
     522           0 :       binaryPartSize["flags"] = bps;
     523             : 
     524           0 :     if ((bps = sdmDataObject.dataStruct().actualTimes().size()))
     525           0 :       binaryPartSize["actualTimes"] = bps;
     526             : 
     527           0 :     if ((bps = sdmDataObject.dataStruct().actualDurations().size()))
     528           0 :       binaryPartSize["actualDurations"] = bps;
     529             : 
     530           0 :     if ((bps = sdmDataObject.dataStruct().zeroLags().size()))
     531           0 :       binaryPartSize["zeroLags"] = bps;
     532             : 
     533           0 :     if ((bps = sdmDataObject.dataStruct().autoData().size()))
     534           0 :       binaryPartSize["autoData"] = bps;
     535             :     
     536           0 :     if ((bps = sdmDataObject.dataStruct().crossData().size()))
     537           0 :       binaryPartSize["crossData"] = bps;
     538           0 :   }
     539             : 
     540           0 :   void SDMDataObjectStreamReader::requireSDMDataSubsetMIMEPart(SDMDataSubset & sdmDataSubset) {
     541           0 :     integrationStartsAt = f.tellg();
     542             :     
     543           0 :     skipAsLongAsLineStartsWith("--"+boundary_1);  // <--- this was added to preserve compatiblity with SDMDataObjectReader, which
     544             :                                                   // was less strict on the respect of the BDF specifications. (cf CAS-8151)
     545             :                                                   // Here the problem was caused by two successive occurrences of --MIME_boundary_1 
     546             :                                                   // instead of only one as indicated in the specs at the very beginning of
     547             :                                                   // an SDMDataSubsetHeader. M.Caillat - 4 decembre 2015
     548           0 :     pair<string, string> name_value = requireHeaderField("CONTENT-TYPE");
     549           0 :     boundary_2 = requireBoundaryInCT(name_value.second);
     550             :     // cout << "boundary_2 = " << boundary_2 << endl;
     551           0 :     name_value = requireHeaderField("CONTENT-DESCRIPTION");
     552           0 :     requireBoundary(boundary_2, 10);
     553           0 :     skipUntilEmptyLine(10);
     554             : 
     555             :     //
     556             :     // We assume that the subset header can't be longer than 100 lines.
     557             :     //
     558           0 :     string sdmDataSubsetHeader = accumulateUntilBoundary(boundary_2, 100);
     559             : 
     560             :     //
     561             :     // Empty sdmDataSubset if necessary.
     562             :     //
     563           0 :     releaseMemory(sdmDataSubset);
     564             : 
     565             :     // We can start to acquire a new SDMDataSubset.
     566           0 :     if (sdmDataObject.isCorrelation())
     567           0 :       parser.parseMemoryCorrSubsetHeader(sdmDataSubsetHeader, sdmDataSubset);
     568             :     else
     569           0 :       parser.parseMemoryTPSubsetHeader(sdmDataSubsetHeader, sdmDataSubset);
     570             : 
     571           0 :     attachmentFlags.reset();
     572             : #ifndef WITHOUT_BOOST
     573             :     boost::regex BINARYPARTLOC("([0-9]+/)+(actualDurations|actualTimes|autoData|crossData|zeroLags|flags)\\.bin");
     574             : #else
     575           0 :     std::regex BINARYPARTLOC("([0-9]+/)+(actualDurations|actualTimes|autoData|crossData|zeroLags|flags)\\.bin");
     576             : #endif
     577           0 :     bool done = false;
     578           0 :     while (!done) {
     579           0 :       name_value = requireHeaderField("CONTENT-TYPE");
     580           0 :       name_value = requireHeaderField("CONTENT-LOCATION");
     581             :     
     582             : #ifndef WITHOUT_BOOST
     583             :       boost::smatch what;
     584             :       const string contentLocation = boost::algorithm::trim_copy(name_value.second);
     585             :       if (!boost::regex_search(contentLocation, what, BINARYPARTLOC)) {
     586             :         throw SDMDataObjectStreamReaderException("Invalid field : '" + name_value.first + ":" + name_value.second + "'.");
     587             :       }
     588             : #else
     589           0 :       std::smatch what;
     590           0 :       const string contentLocation = asdm::trim_copy(name_value.second);
     591           0 :       if (!std::regex_search(contentLocation, what, BINARYPARTLOC)) {
     592           0 :         throw SDMDataObjectStreamReaderException("Invalid field : '" + name_value.first + ":" + name_value.second + "'.");
     593             :       }
     594             : #endif
     595             :       // cout << "Binary part name = " << what[2] << "...";
     596           0 :       string binaryPartName = string(what[2]);
     597           0 :       if (binaryPartSize.find(binaryPartName) == binaryPartSize.end())
     598           0 :         throw SDMDataObjectStreamReaderException("The size of '"+binaryPartName+"' was not announced in the data header.!");
     599             : 
     600           0 :       if (binaryPartSize[binaryPartName] == 0)
     601           0 :         throw SDMDataObjectStreamReaderException("The size of '"+binaryPartName+"' was announced as null. I was not expecting a '"+binaryPartName+"' attachment here.");
     602             : 
     603           0 :       skipUntilEmptyLine(10);
     604           0 :       int numberOfCharsPerValue = 0;
     605           0 :       char** binaryPartPtrPtr = 0;
     606           0 :       if (binaryPartName == "actualDurations") {
     607           0 :         attachmentFlags.set(ACTUALDURATIONS);
     608           0 :         binaryPartPtrPtr = (char**) &sdmDataSubset.actualDurations_;
     609           0 :         sdmDataSubset.nActualDurations_ = binaryPartSize[binaryPartName];
     610           0 :         sdmDataSubset.actualDurationsPosition_ = f.tellg();
     611           0 :         numberOfCharsPerValue = 8;
     612             :       }
     613           0 :       else if (binaryPartName == "actualTimes") {
     614           0 :         attachmentFlags.set(ACTUALTIMES);
     615           0 :         binaryPartPtrPtr = (char **) &sdmDataSubset.actualTimes_;
     616           0 :         sdmDataSubset.nActualTimes_ = binaryPartSize[binaryPartName];
     617           0 :         sdmDataSubset.actualTimesPosition_ = f.tellg();
     618           0 :         numberOfCharsPerValue = 8;
     619             :       }
     620           0 :       else if (binaryPartName == "autoData") {
     621           0 :         attachmentFlags.set(AUTODATA);
     622           0 :         binaryPartPtrPtr = (char **) &sdmDataSubset.autoData_;
     623           0 :         sdmDataSubset.nAutoData_ = binaryPartSize[binaryPartName];
     624           0 :         sdmDataSubset.autoDataPosition_ = f.tellg();
     625           0 :         numberOfCharsPerValue = 4;
     626             :       }
     627           0 :       else if (binaryPartName == "crossData") {
     628           0 :         attachmentFlags.set(CROSSDATA);
     629           0 :         sdmDataSubset.shortCrossData_ = 0;
     630           0 :         sdmDataSubset.longCrossData_  = 0;
     631           0 :         sdmDataSubset.floatCrossData_ = 0;
     632           0 :         sdmDataSubset.nCrossData_ = binaryPartSize[binaryPartName];
     633           0 :         sdmDataSubset.crossDataPosition_ = f.tellg();
     634           0 :         PrimitiveDataType pdt = sdmDataSubset.crossDataType();
     635           0 :         switch (pdt) {
     636           0 :         case  INT16_TYPE:
     637           0 :           binaryPartPtrPtr = (char **) &sdmDataSubset.shortCrossData_;
     638           0 :           numberOfCharsPerValue = 2;
     639           0 :           break;
     640           0 :         case INT32_TYPE:
     641           0 :           binaryPartPtrPtr = (char **) &sdmDataSubset.longCrossData_;
     642           0 :           numberOfCharsPerValue = 4;
     643           0 :           break;
     644           0 :         case FLOAT32_TYPE:
     645           0 :           binaryPartPtrPtr = (char **) &sdmDataSubset.floatCrossData_;
     646           0 :           numberOfCharsPerValue = 4;
     647           0 :             break;
     648           0 :         default:
     649           0 :           throw SDMDataObjectStreamReaderException("Invalid data type for cross data '" + CPrimitiveDataType::name(pdt) + "'.");
     650             :         }
     651             :       }
     652           0 :       else if (binaryPartName == "flags") {
     653           0 :         attachmentFlags.set(FLAGS);
     654           0 :         binaryPartPtrPtr = (char **) &sdmDataSubset.flags_;
     655           0 :         sdmDataSubset.nFlags_ = binaryPartSize[binaryPartName];
     656           0 :         sdmDataSubset.flagsPosition_ = f.tellg();
     657           0 :         numberOfCharsPerValue = 4;
     658             :       }
     659           0 :       else if (binaryPartName == "zeroLags") {
     660           0 :         attachmentFlags.set(ZEROLAGS);
     661           0 :         binaryPartPtrPtr = (char **) &sdmDataSubset.zeroLags_;
     662           0 :         sdmDataSubset.nZeroLags_ = binaryPartSize[binaryPartName];
     663           0 :         sdmDataSubset.zeroLagsPosition_ = f.tellg();
     664           0 :         numberOfCharsPerValue = 4;
     665             :       }
     666             : 
     667           0 :       int64_t numberOfCharsToRead = numberOfCharsPerValue * binaryPartSize[binaryPartName];
     668           0 :       *binaryPartPtrPtr = new char[numberOfCharsToRead * sizeof(char)];
     669           0 :       if (*binaryPartPtrPtr == 0) {
     670           0 :         ostringstream oss;
     671           0 :         oss << "Processing integration # " << integrationIndex << ": I could not get memory to store '" << binaryPartName << "'." << endl;
     672           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     673           0 :       }
     674             : 
     675           0 :       f.read(*binaryPartPtrPtr, numberOfCharsToRead * sizeof(char));
     676           0 :       if (f.fail()) {
     677           0 :         ostringstream oss;
     678           0 :         oss << "Processing integration # " << integrationIndex << ": a problem occurred while reading '" << binaryPartName << "'." << endl;
     679           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     680           0 :       }
     681           0 :       if (f.eof()) {
     682           0 :         ostringstream oss;
     683           0 :         oss << "Processing integration # " << integrationIndex << ": a unexpected end of file occurred while reading '" << binaryPartName  << "'." << endl;
     684           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     685           0 :       }
     686             : 
     687           0 :       string line = nextLine(); // Absorb the nl right after the last byte of the binary attachment
     688           0 :       line = nextLine();   // This should boundary_2                            
     689             :    
     690           0 :       if (line.find("--" + boundary_2) != 0) {
     691           0 :         ostringstream oss;
     692           0 :         oss << "Processing integration # " << integrationIndex << ": unexpected '" <<  line << "' after the binary part '" << binaryPartName << "'." << endl;
     693           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     694           0 :       }
     695             : 
     696           0 :       done = line.compare("--" + boundary_2+"--") == 0;
     697           0 :     }
     698             : 
     699             :     // Now check if the binary attachments found are compatible with the correlation mode
     700             :     // and if their sizes are equal to what is announced in the global header.
     701             :     //
     702             :     // The presence of crossData and autoData depends on the correlation mode.
     703             :     
     704           0 :     switch (sdmDataObject.correlationMode()) {  
     705           0 :     case CROSS_ONLY:
     706           0 :       if (!attachmentFlags.test(CROSSDATA)) {
     707           0 :         ostringstream oss;
     708           0 :         oss << "Data subset '"<<sdmDataSubset.projectPath()<<"': ";
     709           0 :         oss << "a binary attachment 'crossData' was expected in integration #" << integrationIndex;
     710           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     711           0 :       }
     712             :       
     713           0 :       if (attachmentFlags.test(AUTODATA)) {
     714           0 :         ostringstream oss;
     715           0 :         oss << "Data subset '"<<sdmDataSubset.projectPath()<<"': ";
     716           0 :         oss << "found an unexpected attachment 'autoData' in integration #" << integrationIndex << ".";
     717           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     718           0 :       }
     719           0 :       break;
     720             :       
     721           0 :     case AUTO_ONLY:
     722           0 :       if (!attachmentFlags.test(AUTODATA)) {
     723           0 :         ostringstream oss;
     724           0 :         oss << "Data subset '"<<sdmDataSubset.projectPath()<<"': ";
     725           0 :         oss << "a binary attachment 'autoData' was expected.in integration #" << integrationIndex << ".";
     726           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     727           0 :       }
     728             : 
     729           0 :       if (attachmentFlags.test(CROSSDATA)) {
     730           0 :         ostringstream oss;
     731           0 :         oss << "Data subset '"<<sdmDataSubset.projectPath()<<"': ";
     732           0 :         oss << "found an unexpected attachment 'crossData' in integration #" << integrationIndex << ".";
     733           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     734           0 :       }
     735           0 :       break;
     736             :       
     737           0 :     case CROSS_AND_AUTO:
     738           0 :       if (!attachmentFlags.test(AUTODATA)) {
     739           0 :         ostringstream oss;
     740           0 :         oss << "Data subset '"<<sdmDataSubset.projectPath()<<"': ";
     741           0 :         oss << "a binary attachment 'autoData' was expected in integration #" << integrationIndex << ".";
     742           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     743           0 :       }
     744             :       
     745           0 :       if (!attachmentFlags.test(CROSSDATA)) {
     746           0 :         ostringstream oss;
     747           0 :         oss << "Data subset '"<<sdmDataSubset.projectPath()<<"': ";
     748           0 :         oss << "a binary attachment 'crossData' was expected in integration #" << integrationIndex << ".";
     749           0 :         throw SDMDataObjectStreamReaderException(oss.str());
     750           0 :       }      
     751           0 :       break;
     752             : 
     753           0 :     default:
     754           0 :       throw SDMDataObjectStreamReaderException("Data subset '"+sdmDataSubset.projectPath()+"': unrecognized correlation mode");
     755             :       break;
     756             :     }
     757             :     
     758             :     
     759           0 :     if (attachmentFlags.test(ZEROLAGS)) {
     760             :       // Refuse the zeroLags attachment if it's not a Correlator or if the correlator is a CORRELATOR_FX (ACA).
     761           0 :       if ((sdmDataObject.processorType_ != CORRELATOR) || (sdmDataObject.correlatorType() == FX))
     762           0 :         throw SDMDataObjectStreamReaderException("zeroLags are not expected from a correlator CORRELATOR_FX");
     763             :     }
     764           0 :   }
     765             : 
     766           0 :   void SDMDataObjectStreamReader::releaseMemory(SDMDataSubset & sdmDataSubset) {
     767             :     // cout << "SDMDataObjectStreamReader::releaseMemory : entering." << endl;
     768           0 :     if (sdmDataSubset.actualTimes_ != 0) {
     769             :     // cout << "actualTimes" << endl;
     770           0 :       delete[] sdmDataSubset.actualTimes_;
     771           0 :       sdmDataSubset.actualTimes_  = 0;    
     772             :     }
     773           0 :     sdmDataSubset.nActualTimes_ = 0;
     774             : 
     775             : 
     776           0 :     if (sdmDataSubset.actualDurations_ != 0) {
     777             :     // cout << "actualDurations" << endl;
     778           0 :       delete[] sdmDataSubset.actualDurations_;
     779           0 :       sdmDataSubset.actualDurations_  = 0;    
     780             :     }
     781           0 :     sdmDataSubset.nActualDurations_ = 0;
     782             : 
     783           0 :     if (sdmDataSubset.flags_ != 0) {
     784             :     // cout << "Flags" << endl;
     785           0 :       delete[] sdmDataSubset.flags_;
     786           0 :       sdmDataSubset.flags_  = 0;    
     787             :     }
     788           0 :     sdmDataSubset.nFlags_ = 0;
     789             : 
     790           0 :     if (sdmDataSubset.zeroLags_ != 0) {
     791             :     // cout << "zeroLags" << endl;
     792           0 :       delete[] sdmDataSubset.zeroLags_;
     793           0 :       sdmDataSubset.zeroLags_  = 0;    
     794             :     }
     795           0 :     sdmDataSubset.nZeroLags_ = 0;
     796             : 
     797           0 :     if (sdmDataSubset.autoData_ != 0) {
     798             :       //cout << "autoData_ = " << sdmDataSubset.autoData_ << " before deletion" <<  endl;
     799           0 :       delete[] sdmDataSubset.autoData_;
     800           0 :       sdmDataSubset.autoData_  = 0;    
     801             :     }
     802           0 :     sdmDataSubset.nAutoData_ = 0;
     803             : 
     804           0 :     if (sdmDataSubset.shortCrossData_ != 0) {
     805             :       //cout << "shortCrossData_ = " << sdmDataSubset.shortCrossData_ << " before deletion" <<  endl;
     806           0 :       delete[] sdmDataSubset.shortCrossData_;
     807           0 :       sdmDataSubset.shortCrossData_ = 0;
     808             :     }
     809             : 
     810           0 :     if (sdmDataSubset.longCrossData_ != 0) {
     811             :     // cout << "longCrossData" << endl;
     812           0 :       delete[] sdmDataSubset.longCrossData_;
     813           0 :       sdmDataSubset.longCrossData_ = 0;
     814             :     }
     815             : 
     816           0 :     if (sdmDataSubset.floatCrossData_ != 0) {
     817             :     // cout << "floatCrossData" << endl;
     818           0 :       delete[] sdmDataSubset.floatCrossData_;
     819           0 :       sdmDataSubset.floatCrossData_ = 0;
     820             :     }
     821           0 :     sdmDataSubset.nCrossData_ = 0;
     822             : 
     823             :   // cout << "SDMDataObjectStreamReader::releaseMemory : exiting." << endl;
     824           0 :     return;
     825             :   }
     826             : }  // end namespace asdmbinaries
     827             : 
     828             : using namespace asdmbinaries;
     829             : 
     830             : #ifdef TEST_CLASS
     831             : int main (int argC, char* argV[]) {
     832             :   if (argC < 2) {
     833             :     cout << "a.out filename" << endl;
     834             :     exit(1);
     835             :   }
     836             : 
     837             :   SDMDataObjectStreamReader ssr;
     838             :   try {
     839             :     ssr.open(argV[1]);
     840             :     cout << ssr.toString() << endl;
     841             :     while (ssr.hasSubset()) {
     842             :       const SDMDataSubset & sdmdss = ssr.getSubset();
     843             :       cout << "block of data #" << ssr.currentIntegrationIndex() << " starting at byte #" << ssr.currentIntegrationStartsAt() << endl; 
     844             :       cout << sdmdss.toString(128) << endl;
     845             :     }
     846             :   }
     847             :   catch (SDMDataObjectStreamReaderException& e) {
     848             :     cout << e.getMessage() << endl;
     849             :   }
     850             :   catch (SDMDataObjectParserException& e) {
     851             :     cout << e.getMessage() << endl;
     852             :   }
     853             :   catch (SDMDataObjectException& e) {
     854             :     cout << e.getMessage() << endl;
     855             :   }
     856             : }
     857             : #endif

Generated by: LCOV version 1.16