LCOV - code coverage report
Current view: top level - alma/ASDMBinaries - SDMDataObjectParser.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 462 639 72.3 %
Date: 2025-12-19 19:56:21 Functions: 55 78 70.5 %

          Line data    Source code
       1             : #include <alma/ASDMBinaries/SDMDataObjectParser.h>
       2             : #include <iostream>
       3             : #include <sstream>
       4             : #include <string>
       5             : #include <algorithm>
       6             : #include <vector>
       7             : #include <iterator>
       8             : 
       9             : using namespace AtmPhaseCorrectionMod;
      10             : using namespace AxisNameMod;
      11             : using namespace BasebandNameMod;
      12             : using namespace CorrelationModeMod;
      13             : using namespace CorrelatorTypeMod;
      14             : using namespace NetSidebandMod;
      15             : using namespace PrimitiveDataTypeMod;
      16             : using namespace ProcessorTypeMod;
      17             : using namespace SpectralResolutionTypeMod;
      18             : using namespace StokesParameterMod;
      19             : 
      20             : using namespace std;
      21             : 
      22             : namespace asdmbinaries {
      23             : 
      24             :   // Names of XML elements/attributes in an sdmDataHeader.
      25             : 
      26             :   const std::regex  HeaderParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/");
      27             :   const string HeaderParser::SDMDATAHEADER      = "sdmDataHeader";
      28             :   const string HeaderParser::SCHEMAVERSION      = "schemaVersion";
      29             :   const string HeaderParser::BYTEORDER          = "byteOrder";
      30             :   const string HeaderParser::PROJECTPATH        = "projectPath";
      31             :   const string HeaderParser::STARTTIME          = "startTime";
      32             :   const string HeaderParser::DATAOID            = "dataOID";
      33             :   const string HeaderParser::XLINKHREF          = "href";
      34             :   const string HeaderParser::XLINKTITLE         = "title";
      35             :   const string HeaderParser::DIMENSIONALITY     = "dimensionality";
      36             :   const string HeaderParser::NUMTIME            = "numTime";
      37             :   const string HeaderParser::EXECBLOCK          = "execBlock";
      38             :   const string HeaderParser::EXECBLOCKNUM       = "execBlockNum";
      39             :   const string HeaderParser::SCANNUM            = "scanNum";
      40             :   const string HeaderParser::SUBSCANNUM         = "subscanNum"; 
      41             :   const string HeaderParser::NUMANTENNA         = "numAntenna";
      42             :   const string HeaderParser::CORRELATIONMODE    = "correlationMode";
      43             :   const string HeaderParser::SPECTRALRESOLUTION = "spectralResolution";
      44             :   const string HeaderParser::PROCESSORTYPE      = "processorType";
      45             :   const string HeaderParser::DATASTRUCT         = "dataStruct";
      46             :   const string HeaderParser::APC                = "apc";
      47             :   const string HeaderParser::REF                = "ref";  
      48             :   const string HeaderParser::BASEBAND           = "baseband";
      49             :   const string HeaderParser::NAME               = "name";
      50             :   const string HeaderParser::SPECTRALWINDOW     = "spectralWindow";
      51             :   const string HeaderParser::SW                 = "sw";
      52             :   const string HeaderParser::SWBB               = "swbb";
      53             :   const string HeaderParser::CROSSPOLPRODUCTS   = "crossPolProducts";
      54             :   const string HeaderParser::SDPOLPRODUCTS      = "sdPolProducts"; 
      55             :   const string HeaderParser::SCALEFACTOR        = "scaleFactor"; 
      56             :   const string HeaderParser::NUMSPECTRALPOINT   = "numSpectralPoint";
      57             :   const string HeaderParser::NUMBIN             = "numBin";
      58             :   const string HeaderParser::SIDEBAND           = "sideband";
      59             :   const string HeaderParser::IMAGE              = "image";
      60             :   const string HeaderParser::FLAGS              = "flags";
      61             :   const string HeaderParser::ACTUALTIMES        = "actualTimes";
      62             :   const string HeaderParser::ACTUALDURATIONS    = "actualDurations";
      63             :   const string HeaderParser::ZEROLAGS           = "zeroLags";
      64             :   const string HeaderParser::CORRELATORTYPE     = "correlatorType";
      65             :   const string HeaderParser::CROSSDATA          = "crossData";
      66             :   const string HeaderParser::AUTODATA           = "autoData";
      67             :   const string HeaderParser::NORMALIZED         = "normalized";
      68             :   const string HeaderParser::SIZE               = "size";
      69             :   const string HeaderParser::AXES               = "axes";
      70             :   const string HeaderParser::TYPE               = "type";
      71             : 
      72             : 
      73             :   // Names of XML elements/attributes in an sdmSubsetDataHeader with dimensionality==1 (Correlator)
      74             : 
      75             :   const std::regex  SDMDataObjectParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); 
      76             :   const std::regex  SDMDataObjectParser::PROJECTPATH4("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/");
      77             :   const std::regex  SDMDataObjectParser::PROJECTPATH5("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/");
      78             : 
      79             : 
      80             :   const string CorrSubsetHeaderParser::SDMDATASUBSETHEADER = "sdmDataSubsetHeader";
      81             :   const string CorrSubsetHeaderParser::PROJECTPATH         = "projectPath";
      82             :   const string CorrSubsetHeaderParser::SCHEDULEPERIODTIME  = "schedulePeriodTime";
      83             :   const string CorrSubsetHeaderParser::TIME                = "time";
      84             :   const string CorrSubsetHeaderParser::INTERVAL            = "interval";
      85             :   const string CorrSubsetHeaderParser::DATASTRUCT          = "dataStruct";
      86             :   const string CorrSubsetHeaderParser::REF                 = "ref";
      87             :   const string CorrSubsetHeaderParser::ABORTOBSERVATION    = "abortObservation";
      88             :   const string CorrSubsetHeaderParser::ABORTTIME           = "stopTime";
      89             :   const string CorrSubsetHeaderParser::ABORTREASON         = "abortReason";
      90             :   const string CorrSubsetHeaderParser::XLINKHREF           = "href";
      91             :   const string CorrSubsetHeaderParser::DATAREF             = "dataRef";
      92             :   const string CorrSubsetHeaderParser::FLAGSREF            = "flags";
      93             :   const string CorrSubsetHeaderParser::ACTUALTIMESREF      = "actualTimes";
      94             :   const string CorrSubsetHeaderParser::ACTUALDURATIONSREF  = "actualDurations";
      95             :   const string CorrSubsetHeaderParser::ZEROLAGSREF         = "zeroLags";
      96             :   const string CorrSubsetHeaderParser::CROSSDATAREF        = "crossData";
      97             :   const string CorrSubsetHeaderParser::AUTODATAREF         = "autoData";
      98             :   const string CorrSubsetHeaderParser::TYPE                = "type";
      99             : 
     100             :   // Names of XML elements/attributes in an sdmSubsetDataHeader with dimensionality==0 (TP)
     101             :   const std::regex  TPSubsetHeaderParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/");
     102             :   const string TPSubsetHeaderParser::SDMDATASUBSETHEADER = "sdmDataSubsetHeader";
     103             :   const string TPSubsetHeaderParser::PROJECTPATH         = "projectPath";
     104             :   const string TPSubsetHeaderParser::SCHEDULEPERIODTIME  = "schedulePeriodTime";
     105             :   const string TPSubsetHeaderParser::TIME                = "time";
     106             :   const string TPSubsetHeaderParser::INTERVAL            = "interval";
     107             :   const string TPSubsetHeaderParser::DATASTRUCT          = "dataStruct";
     108             :   const string TPSubsetHeaderParser::REF                 = "ref";
     109             :   const string TPSubsetHeaderParser::DATAREF             = "dataRef";  
     110             :   const string TPSubsetHeaderParser::XLINKHREF           = "href";
     111             :   const string TPSubsetHeaderParser::FLAGSREF            = "flags";
     112             :   const string TPSubsetHeaderParser::ACTUALTIMESREF      = "actualTimes";
     113             :   const string TPSubsetHeaderParser::ACTUALDURATIONSREF  = "actualDurations";
     114             :   const string TPSubsetHeaderParser::AUTODATAREF         = "autoData";
     115             : 
     116             :   // HeaderParser methods.
     117         936 :   HeaderParser::HeaderParser(){
     118         936 :     doc = NULL;
     119         936 :   }
     120             : 
     121         936 :   HeaderParser::~HeaderParser() {
     122         936 :     if (doc != NULL) xmlFreeDoc(doc);
     123         936 :   }
     124             : 
     125           0 :   void HeaderParser::parseFile(const string& filename, SDMDataObject& sdmDataObject){
     126           0 :     if (doc != NULL) xmlFreeDoc(doc);
     127           0 :     doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS);
     128           0 :     if (doc == NULL) {
     129           0 :       throw SDMDataObjectParserException("The file '"+filename+"' could not be transformed into a DOM structure");
     130             :     }
     131             : 
     132           0 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     133           0 :     parseSDMDataHeader(root_element, sdmDataObject);
     134           0 :   }
     135             : 
     136        2955 :   void HeaderParser::parseMemory(const string& buffer, SDMDataObject& sdmDataObject) {
     137        2955 :     if (doc != NULL) xmlFreeDoc(doc);
     138        2955 :     doc = xmlReadMemory(buffer.data(), buffer.size(), "SDMDataHeader.xml", NULL, XML_PARSE_NOBLANKS );
     139        2955 :     if (doc == NULL) {
     140           0 :       throw SDMDataObjectParserException("The buffer containing the XML document could not be transformed into a DOM structure");
     141             :     }    
     142             : 
     143        2955 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     144        2955 :     parseSDMDataHeader(root_element, sdmDataObject);
     145        2955 :   }
     146             : 
     147           0 :   void HeaderParser::reset() {
     148           0 :     if (doc) 
     149           0 :       xmlFreeDoc(doc);
     150             : 
     151           0 :     doc = NULL;
     152           0 :   }
     153             : 
     154        2955 :   void HeaderParser::parseSDMDataHeader(xmlNode* a_node,  SDMDataObject& sdmDataObject){
     155             :     //cout << "Entering parseSDMDataHeader" << endl;
     156             :     // Look up for the <sdmDataHeader ... element.
     157        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::SDMDATAHEADER);
     158             : 
     159             :     // And parse some of its attributes.
     160        2955 :     sdmDataObject.schemaVersion_ = SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SCHEMAVERSION);
     161        2955 :     sdmDataObject.byteOrder_ = SDMDataObjectParser::parseByteOrderAttr(a_node, HeaderParser::BYTEORDER);
     162             : 
     163             : 
     164             :     // Look up for its projectPath attribute
     165             :     // and determine execBlockNum, scanNum and subscanNum from its projectPath attribute.
     166        2955 :     vector<unsigned int> v = SDMDataObjectParser::parseProjectPath(a_node, 3);
     167        2955 :     sdmDataObject.execBlockNum_ = v.at(0);
     168        2955 :     sdmDataObject.scanNum_      = v.at(1);
     169        2955 :     sdmDataObject.subscanNum_   = v.at(2);
     170             : 
     171             :     // Traverse the children.
     172        2955 :     xmlNode* child = a_node->children;
     173             :     
     174             :     // Look up for the <startTime... child
     175        2955 :     sdmDataObject.startTime(parseStartTime(child));
     176             : 
     177             :     // Look up for the <dataOID... child
     178        2955 :     child = child->next;
     179        2955 :     sdmDataObject.dataOID(parseDataOID(child));
     180             : 
     181             :     // ...and its title attribute
     182        2955 :     sdmDataObject.title(SDMDataObjectParser::parseStringAttr(child, HeaderParser::XLINKTITLE));
     183             : 
     184             :     // Look up for the <dimensionality...
     185        2955 :     child = child->next;
     186        2955 :     unsigned int dimensionality = parseDimensionality(child);
     187        2955 :     sdmDataObject.dimensionality(dimensionality);
     188             : 
     189        2955 :     if ( dimensionality == 0 ) {
     190             :       // Look up for numTime... only if dimensionality == 0
     191         884 :       sdmDataObject.numTime((unsigned int) parseNumTime(child) );
     192             :     }
     193             :     
     194             :     // Look up for the <execBlock... child
     195        2955 :     child = child->next;
     196        2955 :     parseExecBlock(child, sdmDataObject);
     197             :     
     198             :     // Look up for the <numAntenna... child
     199        2955 :     child = child->next;
     200        2955 :     int numAntenna = parseNumAntenna(child); //cout << child->name << "=" << numAntenna << endl;
     201        2955 :     sdmDataObject.numAntenna((unsigned int) numAntenna);
     202             : 
     203             :     // Look up for the <correlationMode> ... child
     204        2955 :     child = child->next;
     205        2955 :     parseCorrelationMode(child, sdmDataObject);    
     206             : 
     207             :     // Look up for the <spectralResolution> ... child
     208        2955 :     child = child->next;
     209        2955 :     parseSpectralResolution(child, sdmDataObject);    
     210             : 
     211             :     // Look up for child <processorType> ... child
     212        2955 :     child = child->next;
     213        2955 :     parseProcessorType(child, sdmDataObject);
     214             : 
     215             :     // Look up for the <dataStruct> ... child
     216        2955 :     child = child->next;
     217        2955 :     parseDataStruct(child, sdmDataObject);
     218             : 
     219             :     //cout << "Exiting parseSDMDataHeader" << endl;    
     220        2955 :   }
     221             : 
     222             : //   void HeaderParser::parseProjectPath(xmlNode* a_node, SDMDataObject& sdmDataObject) {
     223             : //     string projectPath = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::PROJECTPATH);
     224             :     
     225             : //     std::cmatch what;
     226             :     
     227             : //     if (std::regex_match(projectPath.c_str(), what,PROJECTPATH3) && what[0].matched) {
     228             : //       sdmDataObject.execBlockNum(::atoi(what[1].first));
     229             : //       sdmDataObject.scanNum(::atoi(what[2].first));
     230             : //       sdmDataObject.subscanNum(::atoi(what[3].first));
     231             : //     }
     232             : //     else
     233             : //       throw SDMDataObjectParserException("HeaderParser::parseProjectPath: Invalid string for projectPath '" + projectPath + "'");
     234             : //   }
     235             :   
     236        2955 :   long long HeaderParser::parseStartTime(xmlNode* a_node){
     237        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::STARTTIME);
     238        2955 :     return SDMDataObjectParser::parseLongLong(a_node->children);
     239             :   }
     240             :   
     241        2955 :   string HeaderParser::parseDataOID(xmlNode* a_node) {
     242        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::DATAOID);
     243             : 
     244             :     // Look for attribute
     245        2955 :     string dataOID = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::XLINKHREF);
     246        2955 :     return dataOID;
     247             :   } 
     248             : 
     249        2955 :   int HeaderParser::parseDimensionality(xmlNode* a_node) {
     250             :     //cout << "Entering parseDimensionality with " << a_node->name << endl;
     251        2955 :     if (SDMDataObjectParser::testElement(a_node, HeaderParser::DIMENSIONALITY)) {
     252        2071 :       return SDMDataObjectParser::parseInt(a_node->children);
     253             :     }
     254             :     else
     255         884 :       return 0;
     256             :   } 
     257             : 
     258         884 :   int HeaderParser::parseNumTime(xmlNode* a_node) {
     259         884 :     SDMDataObjectParser::isElement(a_node, HeaderParser::NUMTIME);
     260         884 :     return SDMDataObjectParser::parseInt(a_node->children);
     261             :   } 
     262             :   
     263        2955 :   void HeaderParser::parseExecBlock(xmlNode* a_node, SDMDataObject& sdmDataObject){
     264             :     //cout << "Entering parseExecBlock with " << a_node << endl;
     265             : 
     266        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::EXECBLOCK);
     267             : 
     268             :     // Look up for the execBlockUID attribute.
     269        2955 :     sdmDataObject.execBlockUID(SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::XLINKHREF));
     270        2955 :   }
     271             : 
     272           0 :   int HeaderParser::parseExecBlockNum(xmlNode* a_node){
     273           0 :     SDMDataObjectParser::isElement(a_node, HeaderParser::EXECBLOCKNUM);
     274           0 :     return SDMDataObjectParser::parseInt(a_node->children);
     275             :   }
     276             : 
     277           0 :   int HeaderParser::parseScanNum(xmlNode* a_node){
     278           0 :     SDMDataObjectParser::isElement(a_node, HeaderParser::SCANNUM);
     279           0 :     return SDMDataObjectParser::parseInt(a_node->children);
     280             :   }
     281             : 
     282           0 :   int HeaderParser::parseSubscanNum(xmlNode* a_node){
     283           0 :     SDMDataObjectParser::isElement(a_node, HeaderParser::SUBSCANNUM);
     284           0 :     return SDMDataObjectParser::parseInt(a_node->children);
     285             :   }
     286             : 
     287        2955 :   int HeaderParser::parseNumAntenna(xmlNode* a_node){
     288        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::NUMANTENNA);
     289        2955 :     return SDMDataObjectParser::parseInt(a_node->children);
     290             :   }
     291             : 
     292        2955 :   void HeaderParser::parseCorrelationMode(xmlNode* a_node, SDMDataObject& sdmDataObject) {
     293        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::CORRELATIONMODE);
     294        2955 :     sdmDataObject.correlationMode_ = SDMDataObjectParser::parseLiteral<CorrelationMode, CCorrelationMode>(a_node->children);
     295        2955 :   }
     296             : 
     297        2955 :   void HeaderParser::parseSpectralResolution(xmlNode* a_node, SDMDataObject& sdmDataObject) {
     298        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::SPECTRALRESOLUTION);
     299        2955 :     sdmDataObject.spectralResolutionType_ = SDMDataObjectParser::parseLiteral<SpectralResolutionType, CSpectralResolutionType>(a_node->children);
     300        2955 :   }
     301             : 
     302        2955 :   void HeaderParser::parseProcessorType(xmlNode* a_node, SDMDataObject& sdmDataObject) {
     303        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::PROCESSORTYPE);
     304        2955 :     sdmDataObject.processorType_ = SDMDataObjectParser::parseLiteral<ProcessorType, CProcessorType>(a_node->children);
     305        2955 :   }
     306             : 
     307        2955 :   void HeaderParser::parseDataStruct(xmlNode* a_node, SDMDataObject& sdmDataObject){
     308             :     //cout << "Entering parseDataStruct with " << a_node->name << endl;
     309        2955 :     SDMDataObjectParser::isElement(a_node, HeaderParser::DATASTRUCT);
     310             : 
     311        2955 :     SDMDataObject::DataStruct dataStruct;
     312             :     
     313        2955 :     switch (sdmDataObject.correlationMode()) {
     314        2148 :     case AUTO_ONLY:
     315        2148 :       break;
     316             :       
     317         807 :     case CROSS_ONLY:
     318             :     case CROSS_AND_AUTO:
     319         807 :       dataStruct.apc_ = SDMDataObjectParser::parseStringsAttr<AtmPhaseCorrection, CAtmPhaseCorrection>(a_node, HeaderParser::APC);
     320         807 :       break;      
     321             :     }
     322             :             
     323             :     // Traverse the children 
     324             : 
     325             :     // BaseBands...
     326        2955 :     xmlNode* child = a_node->children;
     327        5910 :     vector <SDMDataObject::Baseband> basebands;
     328       11635 :     while (SDMDataObjectParser::testElement(child, HeaderParser::BASEBAND)) {
     329        8680 :       basebands.push_back(parseBaseband(child, sdmDataObject ));
     330        8680 :       child = child->next;
     331             :     }
     332             : 
     333        2955 :     dataStruct.basebands_ = (basebands);
     334             : 
     335             :     // Now that all the spectral windows are read set the associations between spectral windows.
     336             :     // We have recorded the id and image attributes when they are present in private strings in each spectralWindow.
     337             :     //
     338             :     
     339             :     // I want a map to associate a string of the form "<int>_<int>" to a string of the form "<int>_<int>"
     340             :     // and I define an entry in this map for each spectralWindow with an strSw_ non empty, the value
     341             :     // associated is of the form <int>_<int> where the two integers are the coordinates 
     342             :     // (baseband index, spectralWindow index in the baseband)
     343             :     //
     344        5910 :     map<string, string> id2int_int;
     345        5910 :     ostringstream oss;
     346             : 
     347        5910 :     string key, value;
     348       11635 :     for (unsigned int ibb = 0; ibb < dataStruct.basebands_.size(); ibb++) {
     349        8680 :       vector<SDMDataObject::SpectralWindow>& spws = dataStruct.basebands_.at(ibb).spectralWindows_;
     350       17719 :       for (unsigned int ispw = 0; ispw < spws.size(); ispw++) {
     351             : 
     352        9039 :         oss.str("");
     353        9039 :         oss << ibb << " " << ispw;
     354        9039 :         value = oss.str();
     355             : 
     356        9039 :         oss.str("");
     357        9039 :         oss << ibb << " " << spws.at(ispw).strSw();
     358        9039 :         key = oss.str();
     359             : 
     360        9039 :         id2int_int[key] = value;
     361             :         
     362             :       }
     363             :     }
     364             : 
     365             : 
     366             :     // Now re scan all the spectralWindows and look for the ones with an strImage_ non empty.
     367             :     // and define the associations.
     368             :     //
     369        5910 :     istringstream iss;
     370        2955 :     map<string, string>::iterator iter;
     371             :     int ibbImage, ispwImage;
     372       11635 :     for (unsigned int ibb = 0; ibb < dataStruct.basebands_.size(); ibb++) {
     373        8680 :       vector<SDMDataObject::SpectralWindow>& spws = dataStruct.basebands_.at(ibb).spectralWindows_;
     374       17719 :       for (unsigned int ispw = 0; ispw < spws.size(); ispw++) {
     375        9039 :         string image = spws.at(ispw).strImage();
     376        9039 :         if (image.size() > 0) {
     377           0 :           oss.str("");
     378           0 :           oss << ibb << " " << image;
     379           0 :           key = oss.str();
     380           0 :           if ((iter = id2int_int.find(key)) != id2int_int.end()) {
     381           0 :             iss.str(iter->second);
     382           0 :             iss >> ibbImage;
     383           0 :             iss >> ispwImage;
     384           0 :             dataStruct.imageSPW(ibb, ispw, ispwImage);
     385             :           }
     386             :           else {
     387           0 :             oss.str("");
     388           0 :             oss << "In baseband #" << ibb << " the spectral window #" << ispw << " refers to non defined image ('" << image << "')";
     389           0 :             throw SDMDataObjectParserException(oss.str());
     390             :           }
     391             :         }
     392        9039 :       }
     393             :     }
     394             : 
     395             :     // Metadata attachments.
     396             : 
     397             :     // flags (optional)
     398        2955 :     if (SDMDataObjectParser::testElement(child, HeaderParser::FLAGS)) {
     399        2786 :       dataStruct.flags_ = (parseBinaryPart(child, HeaderParser::FLAGS));
     400        2786 :       child = child->next;
     401             :     }
     402             :     
     403             :     // actualTimes (optional)
     404        2955 :     if (SDMDataObjectParser::testElement(child, HeaderParser::ACTUALTIMES)) {
     405        1997 :       dataStruct.actualTimes_ = (parseBinaryPart(child, HeaderParser::ACTUALTIMES));
     406        1997 :       child = child->next;
     407             :     }
     408             :     
     409             :     // actualDurations (optional)
     410        2955 :     if (SDMDataObjectParser::testElement(child, HeaderParser::ACTUALDURATIONS)) {
     411        1997 :       dataStruct.actualDurations_ = (parseBinaryPart(child, HeaderParser::ACTUALDURATIONS));
     412        1997 :       child = child->next;
     413             :     }
     414             : 
     415             :     // Binary attachments elements...
     416        2955 :     switch (sdmDataObject.correlationMode()) {
     417          74 :     case CROSS_ONLY :
     418          74 :       dataStruct.crossData_ = (parseBinaryPart(child, HeaderParser::CROSSDATA));
     419          74 :       child = child->next;
     420          74 :       break;
     421             : 
     422        2148 :     case AUTO_ONLY : 
     423        2148 :       dataStruct.autoData_ = (parseAutoDataBinaryPart(child, HeaderParser::AUTODATA));
     424        2148 :       child = child->next;
     425        2148 :       break;
     426             : 
     427         733 :     case CROSS_AND_AUTO :
     428         733 :       dataStruct.crossData_ = (parseBinaryPart(child, HeaderParser::CROSSDATA));
     429         733 :       child = child->next;
     430         733 :       dataStruct.autoData_ = (parseAutoDataBinaryPart(child, HeaderParser::AUTODATA));
     431         733 :       child = child->next;
     432         733 :       break;
     433             :     }
     434             : 
     435             :     /*
     436             :     // zeroLags (mandatory in FULL_RESOLUTION)
     437             :     if (sdmDataObject.spectralResolutionType() == FULL_RESOLUTION) {
     438             :       dataStruct.zeroLags_ = (parseBinaryPart(child, HeaderParser::ZEROLAGS));
     439             :       child = child->next;
     440             :     }
     441             :     // (and optional in CHANNEL_AVERAGE)
     442             :     else if (sdmDataObject.spectralResolutionType() == CHANNEL_AVERAGE) {
     443             :       if (SDMDataObjectParser::testElement(child, HeaderParser::ZEROLAGS)) {
     444             :         dataStruct.zeroLags_ = (parseBinaryPart(child, HeaderParser::ZEROLAGS));
     445             :         child = child->next;
     446             :       }
     447             :     }
     448             :     */
     449             :     
     450             :     // zeroLags are allowed only with a non FX correlator.
     451        2955 :     if (SDMDataObjectParser::testElement(child, HeaderParser::ZEROLAGS)) {
     452             :       // Reject zeroLags if the context does not allow them       
     453         463 :       if (sdmDataObject.processorType_ != CORRELATOR) 
     454           0 :         throw SDMDataObjectParserException("zeroLags are not expected with the declared processor type ('" +
     455           0 :                                            CProcessorType::name(sdmDataObject.processorType_) + "')");
     456             :       
     457             :       
     458         463 :       dataStruct.zeroLags_ = (parseZeroLagsBinaryPart(child, HeaderParser::ZEROLAGS));
     459             :       
     460             :       // Reject zeroLags if the context does not allow them ... again
     461             : 
     462         463 :       if (dataStruct.zeroLags_.correlatorType_ == FX)
     463           0 :         throw SDMDataObjectParserException ("zeroLags are not expected with the declared correlator type ('" +
     464           0 :                                             CCorrelatorType::name(dataStruct.zeroLags_.correlatorType_) + "')");
     465             :       
     466         463 :       child = child->next;
     467             :     }
     468             : 
     469        2955 :     sdmDataObject.dataStruct_ = (dataStruct);
     470        2955 :   }
     471             :   
     472        8680 :   SDMDataObject::Baseband HeaderParser::parseBaseband(xmlNode* a_node, SDMDataObject& sdmDataObject){
     473        8680 :     SDMDataObject::Baseband bb;
     474        8680 :     SDMDataObjectParser::isElement(a_node,  HeaderParser::BASEBAND);
     475             :     
     476        8680 :     bb.name_ = (SDMDataObjectParser::parseStringAttr<BasebandName, CBasebandName>(a_node, HeaderParser::NAME));
     477             : 
     478             :     // Traverse the children (spectralWindow).
     479        8680 :     xmlNode* child = a_node->children;
     480        8680 :     vector<SDMDataObject::SpectralWindow> spw;
     481        8680 :     parseSpectralWindow(child, sdmDataObject, spw);
     482        8680 :     bb.spectralWindows(spw);
     483             : 
     484       17360 :     return bb;
     485        8680 :   }
     486             : 
     487        8680 :   void HeaderParser::parseSpectralWindow(xmlNode* a_node, SDMDataObject& sdmDataObject , vector<SDMDataObject::SpectralWindow>& spectralWindow){
     488       17719 :     for (xmlNode* cur_node = a_node; cur_node; cur_node = cur_node->next) { 
     489        9039 :       SDMDataObjectParser::isElement(a_node, HeaderParser::SPECTRALWINDOW);
     490             :  
     491             :      //Look for attributes
     492        9039 :       vector<StokesParameter> crossPolProducts;
     493        9039 :       vector<StokesParameter> sdPolProducts;
     494             :       float scaleFactor;
     495             :       int numSpectralPoint;
     496             :       int numBin;
     497             :       NetSideband sideband;
     498             : 
     499        9039 :       SDMDataObject::SpectralWindow spw;
     500             : 
     501             :       
     502        9039 :       string dummy = SDMDataObjectParser::parseStringAttr(cur_node, HeaderParser::SWBB);
     503             : 
     504        9039 :       switch (sdmDataObject.correlationMode()) {
     505             : 
     506          74 :       case CROSS_ONLY:
     507          74 :         crossPolProducts = SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::CROSSPOLPRODUCTS ); 
     508          74 :         scaleFactor = SDMDataObjectParser::parseFloatAttr(cur_node, HeaderParser::SCALEFACTOR ); 
     509          74 :         numSpectralPoint = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMSPECTRALPOINT ); 
     510          74 :         numBin = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMBIN ); 
     511          74 :         sideband = SDMDataObjectParser::parseStringAttr<NetSideband, CNetSideband>(cur_node, HeaderParser::SIDEBAND);
     512         148 :         spw = SDMDataObject::SpectralWindow(crossPolProducts,
     513             :                                             scaleFactor,
     514             :                                             (unsigned int)numSpectralPoint,
     515             :                                             (unsigned int)numBin,
     516          74 :                                             sideband);
     517          74 :         break;
     518             :         
     519        5940 :       case AUTO_ONLY:
     520        5940 :         sdPolProducts =  SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::SDPOLPRODUCTS ); 
     521        5940 :         numSpectralPoint = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMSPECTRALPOINT );
     522        5940 :         numBin  = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMBIN ); 
     523        5940 :         sideband = SDMDataObjectParser::parseStringAttr<NetSideband, CNetSideband>(cur_node, HeaderParser::SIDEBAND);
     524       11880 :         spw = SDMDataObject::SpectralWindow(sdPolProducts,
     525             :                                             (unsigned int)numSpectralPoint,
     526             :                                             (unsigned int)numBin,
     527        5940 :                                             sideband);
     528        5940 :         break;
     529             :         
     530        3025 :       case CROSS_AND_AUTO:
     531        3025 :         crossPolProducts = SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::CROSSPOLPRODUCTS ); 
     532        3025 :         sdPolProducts =  SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::SDPOLPRODUCTS ); 
     533        3025 :         scaleFactor = SDMDataObjectParser::parseFloatAttr(cur_node, HeaderParser::SCALEFACTOR ); 
     534        3025 :         numSpectralPoint = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMSPECTRALPOINT ); 
     535        3025 :         numBin = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMBIN );
     536        3025 :         sideband = SDMDataObjectParser::parseStringAttr<NetSideband, CNetSideband>(cur_node, HeaderParser::SIDEBAND);
     537        6050 :         spw = SDMDataObject::SpectralWindow(crossPolProducts,
     538             :                                             sdPolProducts,
     539             :                                             scaleFactor,
     540             :                                             (unsigned int)numSpectralPoint,
     541             :                                             (unsigned int)numBin,
     542        3025 :                                             sideband);
     543        3025 :         break;
     544             :       }
     545             :         
     546        9039 :       spw.strSw(SDMDataObjectParser::parseStringAttr(cur_node, HeaderParser::SW));
     547        9039 :       if (SDMDataObjectParser::hasAttr(cur_node, HeaderParser::IMAGE))
     548           0 :         spw.strImage(SDMDataObjectParser::parseStringAttr(cur_node, HeaderParser::IMAGE));
     549             :       
     550        9039 :       spectralWindow.push_back(spw);
     551             :       
     552        9039 :     }
     553        8680 :   }
     554             :   
     555        7587 :   SDMDataObject::BinaryPart HeaderParser::parseBinaryPart(xmlNode* a_node, const string& attachmentName) {
     556        7587 :     SDMDataObjectParser::isElement(a_node, attachmentName);
     557             : 
     558        7587 :     return SDMDataObject::BinaryPart(SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SIZE),
     559       22761 :                                      SDMDataObjectParser::parseStringsAttr<AxisName, CAxisName>(a_node, HeaderParser::AXES));
     560             :   }
     561             : 
     562        2881 :   SDMDataObject::AutoDataBinaryPart HeaderParser::parseAutoDataBinaryPart(xmlNode* a_node, const string& attachmentName) {
     563        2881 :     SDMDataObjectParser::isElement(a_node, attachmentName);
     564             : 
     565        2881 :     return SDMDataObject::AutoDataBinaryPart(SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SIZE),
     566        2881 :                                              SDMDataObjectParser::parseStringsAttr<AxisName, CAxisName>(a_node, HeaderParser::AXES),
     567        8643 :                                              SDMDataObjectParser::parseBoolAttr(a_node, HeaderParser::NORMALIZED));
     568             :   }
     569             :   
     570         463 :   SDMDataObject::ZeroLagsBinaryPart HeaderParser::parseZeroLagsBinaryPart(xmlNode* a_node, const string& attachmentName) {
     571         463 :     SDMDataObjectParser::isElement(a_node, attachmentName);
     572             :     
     573         463 :     return SDMDataObject::ZeroLagsBinaryPart(SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SIZE),
     574         463 :                                              SDMDataObjectParser::parseStringsAttr<AxisName, CAxisName>(a_node, HeaderParser::AXES),
     575        1389 :                                              SDMDataObjectParser::parseStringAttr<CorrelatorType, CCorrelatorType>(a_node, HeaderParser::CORRELATORTYPE));
     576             :   }
     577             :   
     578             :   // CorrSubsetHeaderParser methods.
     579             : 
     580         936 :   CorrSubsetHeaderParser::CorrSubsetHeaderParser() {
     581         936 :     doc = NULL;
     582         936 :   }
     583             :   
     584         936 :   CorrSubsetHeaderParser::~CorrSubsetHeaderParser() {
     585         936 :     if (doc != NULL) xmlFreeDoc(doc);
     586         936 :   }
     587             : 
     588             : 
     589           0 :   void CorrSubsetHeaderParser::parseFile(const string& filename, SDMDataSubset& sdmCorrDataSubset){
     590           0 :     if (doc != NULL) xmlFreeDoc(doc);
     591           0 :     doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS);
     592           0 :     if (doc == NULL) {
     593           0 :       throw SDMDataObjectParserException("The file '"+filename+"' could not be transformed into a DOM structure");
     594             :     }
     595             : 
     596           0 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     597           0 :     parseSDMDataSubsetHeader(root_element, sdmCorrDataSubset);
     598           0 :   }
     599             : 
     600       41282 :   void CorrSubsetHeaderParser::parseMemory(const string& buffer, SDMDataSubset& sdmCorrDataSubset) {
     601       41282 :     if (doc != NULL) xmlFreeDoc(doc);
     602       41282 :     doc = xmlReadMemory(buffer.data(), buffer.size(), "SDMDataHeader.xml", NULL,  XML_PARSE_NOBLANKS);
     603       41282 :     if (doc == NULL) {
     604           0 :       throw SDMDataObjectParserException("The buffer containing the XML document could not be transformed into a DOM structure");
     605             :     }    
     606             :     
     607       41282 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     608       41282 :     parseSDMDataSubsetHeader(root_element, sdmCorrDataSubset );
     609       41282 :   };
     610             : 
     611       41282 :   void CorrSubsetHeaderParser::parseSDMDataSubsetHeader(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) {
     612             :     // Look up for <sdmSubsetDataHeader...
     613       41282 :     SDMDataObjectParser::isElement(a_node, SDMDATASUBSETHEADER);
     614             : 
     615             :     // Project path.
     616       41282 :     vector<unsigned int> v;
     617       41282 :     v = SDMDataObjectParser::parseProjectPath(a_node);     // v should contain 4 (integration) or 5 (subintegration) elements.
     618             :     
     619             :     // Check conformity of execBlockNum, scanNum and subscanNum.
     620             : 
     621       41282 :     if (v.at(0)      != sdmCorrDataSubset.owner()->execBlockNum()
     622       41282 :         || v.at(1)   != sdmCorrDataSubset.owner()->scanNum()
     623       82564 :         || v.at(2)   != sdmCorrDataSubset.owner()->subscanNum())
     624           0 :       throw SDMDataObjectParserException("The project path of this data subset '"
     625           0 :                                          +SDMDataObjectParser::parseStringAttr(a_node, PROJECTPATH)
     626           0 :                                          +"' is not compatible with the project path announced in the global header"
     627           0 :                                          +" '"+sdmCorrDataSubset.owner()->projectPath()+"'"); 
     628             :     
     629             :     // Determine integrationNum [, subintegrationNum]
     630       41282 :     sdmCorrDataSubset.integrationNum_ = v.at(3); 
     631       41282 :     sdmCorrDataSubset.subintegrationNum_ = (v.size() == 5) ? v.at(4) : 0;
     632             :     
     633             :     // Traverse the children .
     634       41282 :     xmlNode* child = a_node->children;
     635             : 
     636             :     // <schedulePeriodTime...
     637       41282 :     parseSchedulePeriodTime(child, sdmCorrDataSubset);
     638             : 
     639             :     // <dataStruct...
     640       41282 :     child = child->next;
     641       41282 :     SDMDataObjectParser::isElement(child, CorrSubsetHeaderParser::DATASTRUCT);
     642       41282 :     sdmCorrDataSubset.dataStruct_ = SDMDataObjectParser::parseStringAttr(child,  CorrSubsetHeaderParser::REF);
     643             : 
     644       41282 :     child = child->next;
     645       41282 :     if (SDMDataObjectParser::testElement(child, CorrSubsetHeaderParser::ABORTOBSERVATION)) {
     646             :       // Is it a cancelling [sub]integration ?
     647           0 :       sdmCorrDataSubset.aborted_ = true;
     648           0 :       parseAbortObservation(child, sdmCorrDataSubset);
     649             :     } 
     650             :     else {
     651             :       // ... or a sequence of attachments description.
     652       41282 :       if (SDMDataObjectParser::testElement(child, FLAGSREF)) {
     653        9424 :         sdmCorrDataSubset.flagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     654        9424 :         child = child->next;
     655             :       }
     656             : 
     657             :       
     658       41282 :       if (SDMDataObjectParser::testElement(child, ACTUALTIMESREF)) {
     659        1468 :         sdmCorrDataSubset.actualTimesREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     660        1468 :         child = child->next;
     661             :       }
     662             : 
     663             :       
     664       41282 :       if (SDMDataObjectParser::testElement(child, ACTUALDURATIONSREF)) {
     665        1468 :         sdmCorrDataSubset.actualDurationsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     666        1468 :         child = child->next;
     667             :       }
     668             :             
     669       41282 :       switch (sdmCorrDataSubset.owner()->correlationMode()) {
     670         112 :       case CROSS_ONLY:
     671         112 :         SDMDataObjectParser::isElement(child, CROSSDATAREF);
     672         112 :         sdmCorrDataSubset.crossDataREF_  = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     673         112 :         sdmCorrDataSubset.crossDataType_ = SDMDataObjectParser::parseStringAttr<PrimitiveDataType, CPrimitiveDataType>(child, CorrSubsetHeaderParser::TYPE);
     674         112 :         child = child->next;
     675         112 :         break;
     676             :         
     677       13370 :       case AUTO_ONLY:
     678       13370 :         SDMDataObjectParser::isElement(child, AUTODATAREF);
     679       13370 :         sdmCorrDataSubset.autoDataREF_  = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     680       13370 :         child = child->next;
     681       13370 :         break;
     682             :         
     683       27800 :       case CROSS_AND_AUTO:
     684       27800 :         SDMDataObjectParser::isElement(child, CROSSDATAREF);
     685       27800 :         sdmCorrDataSubset.crossDataREF_  = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     686       27800 :         sdmCorrDataSubset.crossDataType_ = SDMDataObjectParser::parseStringAttr<PrimitiveDataType, CPrimitiveDataType>(child, CorrSubsetHeaderParser::TYPE);
     687       27800 :         child = child->next;
     688             :         
     689       27800 :         SDMDataObjectParser::isElement(child, AUTODATAREF);
     690       27800 :         sdmCorrDataSubset.autoDataREF_  = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     691       27800 :         child = child->next;
     692       27800 :         break;
     693             :       }
     694             :       /*      
     695             :       if (sdmCorrDataSubset.owner()->spectralResolutionType()  != CHANNEL_AVERAGE) {
     696             :         SDMDataObjectParser::isElement(child, ZEROLAGSREF);
     697             :         sdmCorrDataSubset.zeroLagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     698             :         child = child->next;
     699             :       } 
     700             :       */
     701             :       
     702             :       // zeroLags are optional in any case. Michel Caillat. 24 Jul 2008
     703       41282 :       if (SDMDataObjectParser::testElement(child, ZEROLAGSREF)) {
     704       22312 :         sdmCorrDataSubset.zeroLagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     705       22312 :         child = child->next;
     706             :       }
     707             :     }
     708       41282 :   }
     709             : 
     710             : //   void CorrSubsetHeaderParser::parseProjectPath (xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) {
     711             : //     string projectPath = SDMDataObjectParser::parseStringAttr(a_node,CorrSubsetHeaderParser::PROJECTPATH);
     712             :     
     713             : //     std::cmatch what;
     714             : //     unsigned int execBlockNum = 0;
     715             : //     unsigned int scanNum      = 0;
     716             : //     unsigned int subscanNum   = 0;
     717             : //     switch (sdmCorrDataSubset.owner()->spectralResolutionType()) {
     718             : //     case FULL_RESOLUTION:
     719             : //       if (std::regex_match(projectPath.c_str(), what, SDMDataObjectParser::PROJECTPATH4) && what[0].matched) {
     720             : //      execBlockNum = ::atoi(what[1].first);
     721             : //      scanNum      = ::atoi(what[2].first);
     722             : //      subscanNum   = ::atoi(what[3].first);
     723             : //      sdmCorrDataSubset.integrationNum_  = ::atoi(what[4].first);
     724             : //       }
     725             : //       else
     726             : //      throw SDMDataObjectParserException("Invalid string for projectPath '" + projectPath + "'");
     727             : //       break;
     728             : 
     729             : //     case  CHANNEL_AVERAGE:
     730             : //       if (std::regex_match(projectPath.c_str(), what, SDMDataObjectParser::PROJECTPATH5) && what[0].matched) {
     731             : //      execBlockNum = ::atoi(what[1].first);
     732             : //      scanNum      = ::atoi(what[2].first);
     733             : //      subscanNum   = ::atoi(what[3].first);
     734             : //      sdmCorrDataSubset.integrationNum_    = ::atoi(what[4].first);
     735             : //      sdmCorrDataSubset.subintegrationNum_ = ::atoi(what[5].first);
     736             : //       }
     737             : //       else
     738             : //      throw SDMDataObjectParserException("Invalid string for projectPath '" + projectPath + "'");
     739             : //       break;
     740             : 
     741             : //     case BASEBAND_WIDE:
     742             : //       throw SDMDataObjectParserException("'"+CSpectralResolutionType::name(BASEBAND_WIDE)+"' cannot appear in this context.");
     743             : //       break;
     744             : //     }
     745             :     
     746             : //     if (execBlockNum    != sdmCorrDataSubset.owner()->execBlockNum()
     747             : //      || scanNum      != sdmCorrDataSubset.owner()->scanNum()
     748             : //      || subscanNum   != sdmCorrDataSubset.owner()->subscanNum())
     749             : //       throw SDMDataObjectParserException("The project path of this data subset '"
     750             : //                                       +projectPath
     751             : //                                       +"' is not compatible with the project path announced in the global header"
     752             : //                                       +" '"+sdmCorrDataSubset.owner()->projectPath()+"'"); 
     753             : //   }
     754             : 
     755       41282 :   void CorrSubsetHeaderParser::parseSchedulePeriodTime(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) {
     756       41282 :     SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::SCHEDULEPERIODTIME);
     757             :     
     758       41282 :     xmlNode* child = a_node->children;
     759             :     // <time...
     760       41282 :     sdmCorrDataSubset.time_ = parseTime(child);
     761             : 
     762             :     // <interval...
     763       41282 :     child = child->next;
     764       41282 :     sdmCorrDataSubset.interval_ = parseInterval(child);
     765       41282 :   }
     766             : 
     767       41282 :   long long CorrSubsetHeaderParser::parseTime(xmlNode* a_node) {
     768       41282 :     SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::TIME);
     769       41282 :     return SDMDataObjectParser::parseLongLong(a_node->children);
     770             :   }
     771             : 
     772             : 
     773       41282 :   long long CorrSubsetHeaderParser::parseInterval(xmlNode* a_node) {
     774       41282 :     SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::INTERVAL);
     775       41282 :     return SDMDataObjectParser::parseLongLong(a_node->children);
     776             :   }
     777             : 
     778             : 
     779           0 :   void CorrSubsetHeaderParser::parseAbortObservation(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) {
     780           0 :     xmlNode* child = a_node->children;
     781             : 
     782             :     // <abortTime...
     783           0 :     SDMDataObjectParser::isElement(child, CorrSubsetHeaderParser::ABORTTIME);
     784           0 :     sdmCorrDataSubset.abortTime_ = SDMDataObjectParser::parseLongLong(child->children);
     785             :     
     786             :     // <abortReason...
     787           0 :     child = child->next;
     788           0 :     SDMDataObjectParser::isElement(child, CorrSubsetHeaderParser::ABORTREASON);
     789           0 :     sdmCorrDataSubset.abortReason_ = SDMDataObjectParser::parseString(child->children);    
     790           0 :   }
     791             : 
     792           0 :   void CorrSubsetHeaderParser::parseCrossDataType(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) {
     793           0 :     SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::TYPE);
     794           0 :     sdmCorrDataSubset.crossDataType(SDMDataObjectParser::parseLiteral<PrimitiveDataType, CPrimitiveDataType>(a_node->children));    
     795           0 :   }
     796             : 
     797             : 
     798           0 :   void CorrSubsetHeaderParser::reset() {
     799           0 :     if (doc) 
     800           0 :       xmlFreeDoc(doc);
     801             :     
     802           0 :     doc = NULL;
     803           0 :   }
     804             : 
     805             : 
     806             :   // TPSubsetHeaderParser methods.
     807             : 
     808         936 :   TPSubsetHeaderParser::TPSubsetHeaderParser() {
     809         936 :     doc = NULL;
     810         936 :   }
     811             :   
     812         936 :   TPSubsetHeaderParser::~TPSubsetHeaderParser() {
     813         936 :     if (doc != NULL) xmlFreeDoc(doc);
     814         936 :   }
     815             : 
     816             :   
     817           0 :   void TPSubsetHeaderParser::parseFile(const string& filename, SDMDataSubset& sdmTPDataSubset){
     818           0 :     if (doc != NULL) xmlFreeDoc(doc);
     819           0 :     doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS);
     820           0 :     if (doc == NULL) {
     821           0 :       throw SDMDataObjectParserException("The file '"+filename+"' could not be transformed into a DOM structure");
     822             :     }
     823             : 
     824           0 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     825           0 :     parseSDMDataSubsetHeader(root_element, sdmTPDataSubset);
     826             : 
     827           0 :   }
     828             : 
     829         884 :   void TPSubsetHeaderParser::parseMemory(const string& buffer, SDMDataSubset& sdmTPDataSubset) {
     830         884 :     if (doc != NULL) xmlFreeDoc(doc);
     831         884 :     doc = xmlReadMemory(buffer.data(), buffer.size(), "SDMDataHeader.xml", NULL,  XML_PARSE_NOBLANKS);
     832         884 :     if (doc == NULL) {
     833           0 :       throw SDMDataObjectParserException("The buffer containing the XML document could not be transformed into a DOM structure");
     834             :     }    
     835             :     
     836         884 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     837         884 :     parseSDMDataSubsetHeader(root_element, sdmTPDataSubset);
     838         884 :   }
     839             : 
     840         884 :   void TPSubsetHeaderParser::parseSDMDataSubsetHeader(xmlNode* a_node, SDMDataSubset& sdmTPDataSubset) {
     841             :     // Look up for <sdmSubsetDataHeader...
     842         884 :     SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::SDMDATASUBSETHEADER);
     843             : 
     844             :     // Project path.
     845         884 :     int pathLen = (sdmTPDataSubset.owner()->dimensionality() == 0) ? 3 : 4;
     846         884 :     vector<unsigned int> v = SDMDataObjectParser::parseProjectPath(a_node, pathLen); 
     847             :     
     848             :     // Check conformity of execBlockNum, scanNum and subscanNum.
     849         884 :     if (v.at(0)      != sdmTPDataSubset.owner()->execBlockNum()
     850         884 :         || v.at(1)   != sdmTPDataSubset.owner()->scanNum()
     851        1768 :         || v.at(2)   != sdmTPDataSubset.owner()->subscanNum())
     852           0 :       throw SDMDataObjectParserException("The project path of this data subset '"
     853           0 :                                          +SDMDataObjectParser::parseStringAttr(a_node, PROJECTPATH)
     854           0 :                                          +"' is not compatible with the project path announced in the global header"
     855           0 :                                          +" '"+sdmTPDataSubset.owner()->projectPath()+"'"); 
     856             : 
     857         884 :     if (pathLen == 4)
     858           0 :       sdmTPDataSubset.integrationNum_ = v.at(3);
     859             : 
     860             :     // Traverse the children...
     861         884 :     xmlNode* child = a_node->children;
     862             : 
     863             :     // <schedulePeriodTime...
     864         884 :     parseSchedulePeriodTime(child, sdmTPDataSubset);
     865             : 
     866             :     // <dataStruct...
     867         884 :     child = child->next;
     868         884 :     SDMDataObjectParser::isElement(child, TPSubsetHeaderParser::DATASTRUCT);
     869         884 :     sdmTPDataSubset.dataStruct_ = (SDMDataObjectParser::parseStringAttr(child,  TPSubsetHeaderParser::REF));
     870             : 
     871         884 :     child = child->next;
     872             :     // Optional flags attachments.
     873         884 :     if (SDMDataObjectParser::testElement(child, FLAGSREF)) {
     874         715 :         sdmTPDataSubset.flagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     875         715 :         child = child->next;      
     876             :     }
     877             : 
     878         884 :     if (SDMDataObjectParser::testElement(child, ACTUALTIMESREF)) {
     879         169 :       sdmTPDataSubset.actualTimesREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     880         169 :       child = child->next;
     881             :     }
     882             :    
     883         884 :     if (SDMDataObjectParser::testElement(child, ACTUALDURATIONSREF)) {
     884         861 :       sdmTPDataSubset.actualDurationsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF);
     885         861 :       child = child->next;
     886             :     }
     887             :     
     888             :     // Look for mandatory autoData element.
     889         884 :     SDMDataObjectParser::isElement(child, AUTODATAREF);
     890         884 :     sdmTPDataSubset.autoDataREF_ = (SDMDataObjectParser::parseStringAttr(child, TPSubsetHeaderParser::XLINKHREF )); 
     891         884 :   }
     892             : 
     893           0 :   void TPSubsetHeaderParser::parseProjectPath(xmlNode* a_node, SDMDataSubset& sdmTPDataSubset) {
     894           0 :     string projectPath = SDMDataObjectParser::parseStringAttr(a_node,TPSubsetHeaderParser::PROJECTPATH);
     895             :     
     896           0 :     std::cmatch what;
     897           0 :     unsigned int execBlockNum = 0;
     898           0 :     unsigned int scanNum      = 0;
     899           0 :     unsigned int subscanNum   = 0;
     900             : 
     901           0 :     if (std::regex_match(projectPath.c_str(), what, PROJECTPATH3) && what[0].matched) {
     902           0 :       execBlockNum = ::atoi(what[1].first);
     903           0 :       scanNum      = ::atoi(what[2].first);
     904           0 :       subscanNum   = ::atoi(what[3].first);
     905             :     }
     906             :     else 
     907           0 :       throw SDMDataObjectParserException("Invalid string for projectPath '" + projectPath + "'");
     908             :     
     909           0 :     if (execBlockNum    != sdmTPDataSubset.owner()->execBlockNum()
     910           0 :         || scanNum      != sdmTPDataSubset.owner()->scanNum()
     911           0 :         || subscanNum   != sdmTPDataSubset.owner()->subscanNum())
     912           0 :       throw SDMDataObjectParserException("The project path of this data subset '"
     913           0 :                                          +projectPath
     914           0 :                                          +"' is not compatible with the project path announced in the global header"
     915           0 :                                          +" '"+sdmTPDataSubset.owner()->projectPath()+"'"); 
     916           0 :   }
     917             : 
     918         884 :   void TPSubsetHeaderParser::parseSchedulePeriodTime(xmlNode* a_node, SDMDataSubset& sdmTPDataSubset) {
     919         884 :     SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::SCHEDULEPERIODTIME);
     920             :     
     921         884 :     xmlNode* child = a_node->children;
     922             :     // <time...
     923         884 :     sdmTPDataSubset.time_ = parseTime(child);
     924             : 
     925             :     // <interval...
     926         884 :     child = child->next;
     927         884 :     sdmTPDataSubset.interval_ = parseInterval(child);
     928         884 :   }
     929             : 
     930         884 :   long long TPSubsetHeaderParser::parseTime(xmlNode* a_node) {
     931         884 :     SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::TIME);
     932         884 :     return SDMDataObjectParser::parseLongLong(a_node->children);
     933             :   }
     934             : 
     935             : 
     936         884 :   long long TPSubsetHeaderParser::parseInterval(xmlNode* a_node) {
     937         884 :     SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::INTERVAL);
     938         884 :     return SDMDataObjectParser::parseLongLong(a_node->children);
     939             :   }
     940             :   // SDMDataObject::TPSubsetHeaderParser:: methods.
     941             : 
     942             : 
     943             :   // SDMDataObjectHeaderParser:: methods.
     944      336925 :   void SDMDataObjectParser::isElement(xmlNode* a_node, const string& elementName) {
     945             :     //cout << "Entering isElement for " << a_node->name << endl;
     946      673850 :     if ((a_node == NULL) ||
     947      673850 :         (a_node->type != XML_ELEMENT_NODE) ||
     948      336925 :         (elementName.compare((const char*)a_node->name) != 0)) {
     949           0 :       ostringstream oss;
     950           0 :       oss << "Could not find '<" << elementName << "...";
     951           0 :       if ((a_node != NULL) && (a_node->type == XML_ELEMENT_NODE))
     952           0 :         oss << " ( I was given '<" << a_node->name <<"...')";
     953             :       else 
     954           0 :         oss << " ( node is not an xml element ) " << endl;
     955             :                                                                 
     956           0 :       throw SDMDataObjectParserException(oss.str());
     957           0 :     }
     958             :     //cout << "Exiting isElement" << endl;
     959      336925 :   }
     960             : 
     961      235472 :   bool SDMDataObjectParser::testElement(xmlNode* a_node, const string& elementName) {
     962             :     //cout << "Entering testElement with " << elementName << " against " << a_node->name << endl;
     963      214010 :     bool result = ((a_node != NULL) &&
     964      449482 :                    (a_node->type == XML_ELEMENT_NODE) &&
     965      214010 :                    (elementName.compare((const char*)a_node->name) == 0));
     966      235472 :     return result;
     967             :   }
     968             : 
     969           0 :   void SDMDataObjectParser::inElements(xmlNode* a_node, const vector<string>& elementNames) {
     970           0 :     if (find(elementNames.begin(), elementNames.end(), string((char*) a_node->name)) == elementNames.end()) {
     971           0 :       ostringstream message;
     972           0 :       copy(elementNames.begin(), elementNames.end(), ostream_iterator<string>(message, " "));
     973           0 :       throw SDMDataObjectParserException("Could not find any of elements '" + message.str()+"' in " + string((const char*) a_node->name));
     974           0 :     }
     975           0 :   }
     976             : 
     977      340447 :   xmlAttr*  SDMDataObjectParser::hasAttr(xmlNode* a_node, const string& attrName) {
     978      340447 :     xmlAttr* result = 0;
     979      687772 :     for (struct _xmlAttr* attr = a_node->properties; attr; attr = attr->next) {
     980      678733 :       if (attrName.compare((const char*) attr->name) == 0) {
     981      331408 :         result = attr;
     982      331408 :         break;
     983             :       }
     984             :     }
     985      340447 :     return result;  
     986             :   }
     987             : 
     988       23802 :   void SDMDataObjectParser::tokenize(const string& str,
     989             :                                      vector<string>& tokens,
     990             :                                      const string& delimiters) {
     991             :     // Skip delimiters at beginning.
     992       23802 :     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
     993             :     // Find first "non-delimiter".
     994       23802 :     string::size_type pos     = str.find_first_of(delimiters, lastPos);
     995             :     
     996       85452 :     while (string::npos != pos || string::npos != lastPos) {
     997             :         // Found a token, add it to the vector.
     998       61650 :         tokens.push_back(str.substr(lastPos, pos - lastPos));
     999             :         // Skip delimiters.  Note the "not_of"
    1000       61650 :         lastPos = str.find_first_not_of(delimiters, pos);
    1001             :         // Find next "non-delimiter"
    1002       61650 :         pos = str.find_first_of(delimiters, lastPos);
    1003             :     }    
    1004       23802 :   }
    1005             : 
    1006             : 
    1007           0 :   void SDMDataObjectParser::tokenize(const string& str,
    1008             :                                      set<string>& tokens,
    1009             :                                      const string& delimiters) {
    1010             :     // Skip delimiters at beginning.
    1011           0 :     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    1012             :     // Find first "non-delimiter".
    1013           0 :     string::size_type pos     = str.find_first_of(delimiters, lastPos);
    1014             :     
    1015           0 :     while (string::npos != pos || string::npos != lastPos) {
    1016             :         // Found a token, add it to the vector.
    1017           0 :         tokens.insert(str.substr(lastPos, pos - lastPos));
    1018             :         // Skip delimiters.  Note the "not_of"
    1019           0 :         lastPos = str.find_first_not_of(delimiters, pos);
    1020             :         // Find next "non-delimiter"
    1021           0 :         pos = str.find_first_of(delimiters, lastPos);
    1022             :     }    
    1023           0 :   }
    1024             : 
    1025       55325 :   string SDMDataObjectParser::substring(const string &s, int a, int b) {
    1026       55325 :     return s.substr(a,(b - a));
    1027             :   }
    1028             : 
    1029       55325 :   string SDMDataObjectParser::trim(const string& s) {
    1030       55325 :     unsigned int i = 0;
    1031       55325 :     while (s.at(i) == ' ' && i < s.length())
    1032           0 :       ++i;
    1033       55325 :     if (i == s.length())
    1034           0 :       return "";
    1035       55325 :     unsigned int j = s.length() - 1;
    1036       55325 :     while (s.at(j) == ' ' && j > i)
    1037           0 :       --j;
    1038       55325 :     return substring(s,i,j + 1);
    1039             :   }
    1040             : 
    1041           0 :   string SDMDataObjectParser::parseString(xmlNode* a_node) {
    1042           0 :     if ((a_node != NULL) && (a_node->next == NULL))
    1043           0 :       return string((const char*) a_node->content);
    1044             :     
    1045           0 :     throw SDMDataObjectParserException("Invalid node , can't be parsed into a long long");
    1046             : 
    1047             :   }
    1048             : 
    1049       87287 :   long long  SDMDataObjectParser::parseLongLong(xmlNode* a_node) {
    1050       87287 :     if ((a_node != NULL) && (a_node->next == NULL)) {
    1051       87287 :       istringstream in;
    1052       87287 :       in.str((const char*) a_node->content);
    1053             :       long long x;
    1054       87287 :       in >> x;
    1055       87287 :       if (in.rdstate() == istream::failbit)
    1056           0 :                         throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as a long long in" + string((const char*)a_node->parent->name));
    1057       87287 :       return x;
    1058       87287 :     }
    1059             :     
    1060           0 :     throw SDMDataObjectParserException("Invalid node , can't be parsed into a long long");
    1061             :   }
    1062             : 
    1063       37874 :   int SDMDataObjectParser::parseInt(xmlNode* a_node) {
    1064             :     //cout << "Entering parseInt with " << a_node->content << endl;
    1065       37874 :     if ((a_node != NULL) && (a_node->next == NULL)) {
    1066       37874 :       const std::regex UINT("[0-9]+");
    1067       37874 :       std::cmatch what;
    1068       37874 :       if (std::regex_match((char*)a_node->content, what, UINT)) {
    1069       75748 :         return (::atoi(what[0].first));
    1070             :       }
    1071             :       else
    1072           0 :         throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as an int in " + string((const char*)a_node->parent->name));
    1073       37874 :     }
    1074             : 
    1075           0 :     throw SDMDataObjectParserException("Invalid node , can't be parsed into an int");
    1076             :   }
    1077             : 
    1078        2881 :   bool SDMDataObjectParser::parseBool(xmlNode* a_node) {
    1079        2881 :     if ((a_node != NULL) && (a_node->next == NULL)) {
    1080        2881 :       const std::regex TORF("true|false");
    1081        2881 :       std::cmatch what;
    1082        2881 :       if (std::regex_match((char*)a_node->content, what, TORF)) {
    1083        5762 :         return ( *(what[0].first) == 't') ? true:false;
    1084             :       }
    1085             :       else
    1086           0 :         throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as an int in " + string((const char*)a_node->parent->name));
    1087        2881 :     }
    1088             : 
    1089           0 :     throw SDMDataObjectParserException("Invalid node , can't be parsed into an bool");    
    1090             :   }
    1091             : 
    1092        3099 :   float SDMDataObjectParser::parseFloat(xmlNode* a_node) {
    1093        3099 :     if ((a_node != NULL) && (a_node->next == NULL)) {
    1094        3099 :       istringstream in;
    1095        3099 :       in.str((const char*) a_node->content);
    1096             :       float x;
    1097        3099 :       in >> x;
    1098        3099 :       if (in.rdstate() == istream::failbit)
    1099           0 :                         throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as a float in " + string((const char*)a_node->parent->name));
    1100        3099 :       return x;
    1101        3099 :     }
    1102             : 
    1103           0 :     throw SDMDataObjectParserException("Invalid node , can't be parsed into an float");
    1104             :   }
    1105             : 
    1106       31964 :   int SDMDataObjectParser::parseIntAttr(xmlNode* a_node, const string& attrName) {
    1107       31964 :     xmlAttr* attr = 0;
    1108             : 
    1109       31964 :     if ((attr = hasAttr(a_node, attrName))) {
    1110       31964 :       int result =parseInt(attr->children);
    1111       31964 :        return result;
    1112             :     }
    1113           0 :     else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name));    
    1114             :   }
    1115             : 
    1116        2881 :   bool SDMDataObjectParser::parseBoolAttr(xmlNode* a_node, const string& attrName) {
    1117        2881 :     xmlAttr* attr = 0;
    1118             : 
    1119        2881 :     if ((attr = hasAttr(a_node, attrName))) {
    1120        2881 :       bool result = parseBool(attr->children);
    1121        2881 :       return result;
    1122             :     }
    1123           0 :     else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name));    
    1124             :   }
    1125             : 
    1126        3099 :   float SDMDataObjectParser::parseFloatAttr(xmlNode* a_node, const string& attrName) {
    1127        3099 :     xmlAttr* attr = 0;
    1128             : 
    1129        3099 :     if ((attr = hasAttr(a_node, attrName))) {
    1130        3099 :       float result = parseFloat(attr->children);
    1131             :       //cout << attr->name << " = " << result << endl;
    1132        3099 :       return result;
    1133             :     }
    1134           0 :     else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name));    
    1135             :   }
    1136             : 
    1137             : 
    1138      223568 :   string SDMDataObjectParser::parseStringAttr(xmlNode* a_node, const string& attrName) {
    1139             :     //cout << "Entering parseStringAttr with " << attrName << " in " << a_node->name << endl;
    1140      223568 :     xmlAttr* attr = 0;
    1141             : 
    1142      223568 :     if ((attr = hasAttr(a_node, attrName))) {
    1143      223568 :       string result = string((const char*)attr->children->content);
    1144             :       //cout << attr->name << " = " << result << endl;
    1145      447136 :       return result;
    1146      223568 :     }
    1147           0 :     else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name));    
    1148             :   }
    1149             : 
    1150             : 
    1151           0 :   vector<string> SDMDataObjectParser::parseStringsAttr(xmlNode* a_node, const string& attrName) {
    1152           0 :     xmlAttr* attr = 0;
    1153             : 
    1154           0 :     if ((attr = hasAttr(a_node, attrName))) {
    1155           0 :       vector<string> result;
    1156           0 :       tokenize((const char*)attr->children->content, result);
    1157             :       //cout << attr->name << " = '"; copy(result.begin(), result.end(), ostream_iterator<string>(cout, " ")); cout << "'" << endl; 
    1158           0 :       return result;
    1159           0 :     }
    1160           0 :     else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name));    
    1161             :   }
    1162             : 
    1163           0 :   set<string> SDMDataObjectParser::parseStringSetAttr(xmlNode* a_node, const string& attrName) {
    1164           0 :     xmlAttr* attr = 0;
    1165             : 
    1166           0 :     if ((attr = hasAttr(a_node, attrName))) {
    1167           0 :       set<string> result;
    1168           0 :       tokenize((const char*)attr->children->content, result);
    1169             :       //cout << attr->name << " = '"; copy(result.begin(), result.end(), ostream_iterator<string>(cout, " ")); cout << "'" << endl; 
    1170           0 :       return result;
    1171           0 :     }
    1172           0 :     else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name));    
    1173             :   }
    1174             : 
    1175             : 
    1176        3839 :   vector<unsigned int> SDMDataObjectParser::parseProjectPath(xmlNode* a_node, unsigned int len) {
    1177        3839 :     string projectPath = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::PROJECTPATH);
    1178        3839 :     vector<unsigned int> result;
    1179        3839 :     bool matched = true;
    1180        3839 :     std::cmatch what;
    1181        3839 :     switch (len) {
    1182        3839 :     case 3: matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH3); break;
    1183           0 :     case 4: matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH4); break;
    1184           0 :     case 5: matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH5); break;
    1185           0 :     default: throw SDMDataObjectParserException ("internal error in method 'parseProjectPath'. The parameter 'len' has a value out of the range [3,5]");
    1186             :     }
    1187             :     
    1188        3839 :     if (!matched)
    1189           0 :       throw SDMDataObjectException("'" + projectPath + "' is an invalid string for a 'projectPath' attribute");
    1190             : 
    1191       15356 :     for (unsigned int i = 0; i < len; i++) {
    1192       11517 :       result.push_back(::atoi(what[i+1].first));
    1193             :     }
    1194        7678 :     return result;
    1195        3839 :   }
    1196             : 
    1197             :   const std::regex  SDMDataObjectParser::PROJECTPATH4OR5("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+/)?");
    1198       41282 :   vector<unsigned int> SDMDataObjectParser::parseProjectPath(xmlNode* a_node) {
    1199       41282 :     string projectPath = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::PROJECTPATH);
    1200       41282 :     vector<unsigned int> result;
    1201             :     
    1202       41282 :     bool matched = true;
    1203             : 
    1204       41282 :     std::cmatch what;
    1205       41282 :     matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH4OR5);
    1206             :     
    1207       41282 :     if (!matched)
    1208           0 :       throw SDMDataObjectException("'" + projectPath + "' is an invalid string for a 'projectPath' attribute.");
    1209             : 
    1210             :     // Let's retrieve the 4 first numbers.
    1211      206410 :     for (unsigned int i = 0; i < 4; i++)
    1212      165128 :       result.push_back(::atoi(what[i+1].first));
    1213             :                        
    1214             :     // and the fifth if it exists...
    1215       41282 :     if (what[5].matched) {
    1216       20131 :       result.push_back(::atoi(what[5].first));
    1217             :     }
    1218             :     
    1219       82564 :     return result;
    1220       41282 :   }
    1221             : 
    1222        2955 :   const ByteOrder* SDMDataObjectParser::parseByteOrderAttr(xmlNode* a_node, const string& attrName) {
    1223        2955 :     string byteOrder = SDMDataObjectParser::parseStringAttr(a_node, attrName);
    1224             : 
    1225        2955 :     if (byteOrder.compare("Little_Endian")==0) return ByteOrder::Little_Endian;
    1226           0 :     if (byteOrder.compare("Big_Endian")==0) return ByteOrder::Big_Endian;
    1227             : 
    1228           0 :     throw SDMDataObjectParserException("'" + byteOrder + "' is an invalid string for a 'byteOrder' attribute.");
    1229        2955 :   }
    1230             : 
    1231         936 :   SDMDataObjectParser::SDMDataObjectParser() {;}
    1232         936 :   SDMDataObjectParser::~SDMDataObjectParser() {;}
    1233             : 
    1234           0 :   void SDMDataObjectParser::parseFileHeader(const string& filename, SDMDataObject& sdmDataObject) {
    1235           0 :     headerParser.parseFile(filename, sdmDataObject);
    1236           0 :   }
    1237             : 
    1238        2955 :   void SDMDataObjectParser::parseMemoryHeader(const string& buffer, SDMDataObject& sdmDataObject) {
    1239        2955 :     headerParser.parseMemory(buffer, sdmDataObject);
    1240        2955 :   }
    1241             : 
    1242           0 :   void SDMDataObjectParser::parseFileCorrSubsetHeader(const string& filename, SDMDataSubset& sdmCorrDataSubset) {
    1243           0 :     corrSubsetHeaderParser.parseFile(filename, sdmCorrDataSubset);
    1244           0 :   }
    1245             : 
    1246       41282 :   void SDMDataObjectParser::parseMemoryCorrSubsetHeader(const string& buffer, SDMDataSubset& sdmCorrDataSubset) {
    1247       41282 :     corrSubsetHeaderParser.parseMemory(buffer, sdmCorrDataSubset);
    1248       41282 :   }
    1249             : 
    1250           0 :   void SDMDataObjectParser::parseFileTPSubsetHeader(const string& filename, SDMDataSubset& sdmCorrDataSubset) {
    1251           0 :     tpSubsetHeaderParser.parseFile(filename, sdmCorrDataSubset);
    1252           0 :   }
    1253             : 
    1254         884 :   void SDMDataObjectParser::parseMemoryTPSubsetHeader(const string& buffer, SDMDataSubset& sdmCorrDataSubset) {
    1255         884 :     tpSubsetHeaderParser.parseMemory(buffer, sdmCorrDataSubset);
    1256         884 :   }
    1257             :   
    1258             : }
    1259             : 
    1260             : #if 0
    1261             : using namespace asdmbinaries;
    1262             : int main (int argC, char* argV[]) {
    1263             : 
    1264             :   if (argC != 3) return (1);
    1265             : 
    1266             :   SDMDataObjectParser parser;
    1267             :   SDMDataObject sdmDataObject;
    1268             : 
    1269             :   SDMDataSubset sdmDataSubset;  
    1270             : 
    1271             :   cout << "Trying to parse an SDMDataHeader in " << argV[1] << " and an SDMDataSubsetHeader in " << argV[2] <<endl;
    1272             :   try {
    1273             :     parser.parseFileHeader(argV[1], sdmDataObject);
    1274             :     cout << "----- SDMDataObject ------" << endl;
    1275             :     cout << "SDMDataHeader: " << endl;
    1276             :     cout << endl;
    1277             :     cout << sdmDataObject.toString() << endl;
    1278             :     
    1279             :     // Now process the sdmDataSubsetHeader passed in argV[2]
    1280             :     switch (sdmDataObject.dimensionality()) {
    1281             :     case 0: 
    1282             :       {
    1283             :         parser.parseFileTPSubsetHeader(argV[2], sdmDataSubset);
    1284             :         cout << endl;
    1285             :         cout << "SDMDataSubsetHeader: " << endl;
    1286             :         cout << endl;
    1287             :         cout << sdmDataSubset.toString(sdmDataObject.dimensionality()) << endl;
    1288             :         break;
    1289             :       }
    1290             :       
    1291             :     case 1: 
    1292             :       {
    1293             :         parser.parseFileCorrSubsetHeader(argV[2], sdmDataSubset);
    1294             :         cout << endl;
    1295             :         cout << "SDMDataSubsetHeader: " << endl;
    1296             :         cout << endl;
    1297             :         cout << sdmDataSubset.toString(sdmDataObject.dimensionality());
    1298             :         break;
    1299             :       }
    1300             :       
    1301             :     default:
    1302             :       break;
    1303             :     }
    1304             :   }
    1305             :   catch (SDMDataObjectParserException e) {
    1306             :     cout << e.getMessage() << endl;
    1307             :     exit(1);
    1308             :   }
    1309             : 
    1310             :   cout << endl;
    1311             :   cout << "----------------------" << endl;
    1312             :   cout << "XML representation of the sdmDataHeader: " << endl;
    1313             :   cout << endl;
    1314             :   cout << sdmDataObject.toXML() << endl;
    1315             : 
    1316             :   cout << endl;
    1317             :   cout << "----------------------" << endl;
    1318             :   cout << "XML representation of the sdmDataSubsetHeader: " << endl;
    1319             :   cout << endl;
    1320             :   cout << sdmDataSubset.toXML(sdmDataObject.dimensionality()) << endl;
    1321             : }
    1322             : #endif

Generated by: LCOV version 1.16