#include <alma/ASDMBinaries/SDMDataObjectParser.h> #include <iostream> #include <sstream> #include <string> #include <algorithm> #include <vector> #include <iterator> using namespace AtmPhaseCorrectionMod; using namespace AxisNameMod; using namespace BasebandNameMod; using namespace CorrelationModeMod; using namespace CorrelatorTypeMod; using namespace NetSidebandMod; using namespace PrimitiveDataTypeMod; using namespace ProcessorTypeMod; using namespace SpectralResolutionTypeMod; using namespace StokesParameterMod; using namespace std; namespace asdmbinaries { // Names of XML elements/attributes in an sdmDataHeader. #ifndef WITHOUT_BOOST const boost::regex HeaderParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); #else const std::regex HeaderParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); #endif const string HeaderParser::SDMDATAHEADER = "sdmDataHeader"; const string HeaderParser::SCHEMAVERSION = "schemaVersion"; const string HeaderParser::BYTEORDER = "byteOrder"; const string HeaderParser::PROJECTPATH = "projectPath"; const string HeaderParser::STARTTIME = "startTime"; const string HeaderParser::DATAOID = "dataOID"; const string HeaderParser::XLINKHREF = "href"; const string HeaderParser::XLINKTITLE = "title"; const string HeaderParser::DIMENSIONALITY = "dimensionality"; const string HeaderParser::NUMTIME = "numTime"; const string HeaderParser::EXECBLOCK = "execBlock"; const string HeaderParser::EXECBLOCKNUM = "execBlockNum"; const string HeaderParser::SCANNUM = "scanNum"; const string HeaderParser::SUBSCANNUM = "subscanNum"; const string HeaderParser::NUMANTENNA = "numAntenna"; const string HeaderParser::CORRELATIONMODE = "correlationMode"; const string HeaderParser::SPECTRALRESOLUTION = "spectralResolution"; const string HeaderParser::PROCESSORTYPE = "processorType"; const string HeaderParser::DATASTRUCT = "dataStruct"; const string HeaderParser::APC = "apc"; const string HeaderParser::REF = "ref"; const string HeaderParser::BASEBAND = "baseband"; const string HeaderParser::NAME = "name"; const string HeaderParser::SPECTRALWINDOW = "spectralWindow"; const string HeaderParser::SW = "sw"; const string HeaderParser::SWBB = "swbb"; const string HeaderParser::CROSSPOLPRODUCTS = "crossPolProducts"; const string HeaderParser::SDPOLPRODUCTS = "sdPolProducts"; const string HeaderParser::SCALEFACTOR = "scaleFactor"; const string HeaderParser::NUMSPECTRALPOINT = "numSpectralPoint"; const string HeaderParser::NUMBIN = "numBin"; const string HeaderParser::SIDEBAND = "sideband"; const string HeaderParser::IMAGE = "image"; const string HeaderParser::FLAGS = "flags"; const string HeaderParser::ACTUALTIMES = "actualTimes"; const string HeaderParser::ACTUALDURATIONS = "actualDurations"; const string HeaderParser::ZEROLAGS = "zeroLags"; const string HeaderParser::CORRELATORTYPE = "correlatorType"; const string HeaderParser::CROSSDATA = "crossData"; const string HeaderParser::AUTODATA = "autoData"; const string HeaderParser::NORMALIZED = "normalized"; const string HeaderParser::SIZE = "size"; const string HeaderParser::AXES = "axes"; const string HeaderParser::TYPE = "type"; // Names of XML elements/attributes in an sdmSubsetDataHeader with dimensionality==1 (Correlator) #ifndef WITHOUT_BOOST const boost::regex SDMDataObjectParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); const boost::regex SDMDataObjectParser::PROJECTPATH4("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/"); const boost::regex SDMDataObjectParser::PROJECTPATH5("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/"); #else const std::regex SDMDataObjectParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); const std::regex SDMDataObjectParser::PROJECTPATH4("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/"); const std::regex SDMDataObjectParser::PROJECTPATH5("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/"); #endif const string CorrSubsetHeaderParser::SDMDATASUBSETHEADER = "sdmDataSubsetHeader"; const string CorrSubsetHeaderParser::PROJECTPATH = "projectPath"; const string CorrSubsetHeaderParser::SCHEDULEPERIODTIME = "schedulePeriodTime"; const string CorrSubsetHeaderParser::TIME = "time"; const string CorrSubsetHeaderParser::INTERVAL = "interval"; const string CorrSubsetHeaderParser::DATASTRUCT = "dataStruct"; const string CorrSubsetHeaderParser::REF = "ref"; const string CorrSubsetHeaderParser::ABORTOBSERVATION = "abortObservation"; const string CorrSubsetHeaderParser::ABORTTIME = "stopTime"; const string CorrSubsetHeaderParser::ABORTREASON = "abortReason"; const string CorrSubsetHeaderParser::XLINKHREF = "href"; const string CorrSubsetHeaderParser::DATAREF = "dataRef"; const string CorrSubsetHeaderParser::FLAGSREF = "flags"; const string CorrSubsetHeaderParser::ACTUALTIMESREF = "actualTimes"; const string CorrSubsetHeaderParser::ACTUALDURATIONSREF = "actualDurations"; const string CorrSubsetHeaderParser::ZEROLAGSREF = "zeroLags"; const string CorrSubsetHeaderParser::CROSSDATAREF = "crossData"; const string CorrSubsetHeaderParser::AUTODATAREF = "autoData"; const string CorrSubsetHeaderParser::TYPE = "type"; // Names of XML elements/attributes in an sdmSubsetDataHeader with dimensionality==0 (TP) #ifndef WITHOUT_BOOST const boost::regex TPSubsetHeaderParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); #else const std::regex TPSubsetHeaderParser::PROJECTPATH3("([0-9]+)/([0-9]+)/([0-9]+)/"); #endif const string TPSubsetHeaderParser::SDMDATASUBSETHEADER = "sdmDataSubsetHeader"; const string TPSubsetHeaderParser::PROJECTPATH = "projectPath"; const string TPSubsetHeaderParser::SCHEDULEPERIODTIME = "schedulePeriodTime"; const string TPSubsetHeaderParser::TIME = "time"; const string TPSubsetHeaderParser::INTERVAL = "interval"; const string TPSubsetHeaderParser::DATASTRUCT = "dataStruct"; const string TPSubsetHeaderParser::REF = "ref"; const string TPSubsetHeaderParser::DATAREF = "dataRef"; const string TPSubsetHeaderParser::XLINKHREF = "href"; const string TPSubsetHeaderParser::FLAGSREF = "flags"; const string TPSubsetHeaderParser::ACTUALTIMESREF = "actualTimes"; const string TPSubsetHeaderParser::ACTUALDURATIONSREF = "actualDurations"; const string TPSubsetHeaderParser::AUTODATAREF = "autoData"; // HeaderParser methods. HeaderParser::HeaderParser(){ doc = NULL; } HeaderParser::~HeaderParser() { if (doc != NULL) xmlFreeDoc(doc); } void HeaderParser::parseFile(const string& filename, SDMDataObject& sdmDataObject){ if (doc != NULL) xmlFreeDoc(doc); doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { throw SDMDataObjectParserException("The file '"+filename+"' could not be transformed into a DOM structure"); } xmlNode* root_element = xmlDocGetRootElement(doc); parseSDMDataHeader(root_element, sdmDataObject); } void HeaderParser::parseMemory(const string& buffer, SDMDataObject& sdmDataObject) { if (doc != NULL) xmlFreeDoc(doc); doc = xmlReadMemory(buffer.data(), buffer.size(), "SDMDataHeader.xml", NULL, XML_PARSE_NOBLANKS ); if (doc == NULL) { throw SDMDataObjectParserException("The buffer containing the XML document could not be transformed into a DOM structure"); } xmlNode* root_element = xmlDocGetRootElement(doc); parseSDMDataHeader(root_element, sdmDataObject); } void HeaderParser::reset() { if (doc) xmlFreeDoc(doc); doc = NULL; } void HeaderParser::parseSDMDataHeader(xmlNode* a_node, SDMDataObject& sdmDataObject){ //cout << "Entering parseSDMDataHeader" << endl; // Look up for the <sdmDataHeader ... element. SDMDataObjectParser::isElement(a_node, HeaderParser::SDMDATAHEADER); // And parse some of its attributes. sdmDataObject.schemaVersion_ = SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SCHEMAVERSION); sdmDataObject.byteOrder_ = SDMDataObjectParser::parseByteOrderAttr(a_node, HeaderParser::BYTEORDER); // Look up for its projectPath attribute // and determine execBlockNum, scanNum and subscanNum from its projectPath attribute. vector<unsigned int> v = SDMDataObjectParser::parseProjectPath(a_node, 3); sdmDataObject.execBlockNum_ = v.at(0); sdmDataObject.scanNum_ = v.at(1); sdmDataObject.subscanNum_ = v.at(2); // Traverse the children. xmlNode* child = a_node->children; // Look up for the <startTime... child sdmDataObject.startTime(parseStartTime(child)); // Look up for the <dataOID... child child = child->next; sdmDataObject.dataOID(parseDataOID(child)); // ...and its title attribute sdmDataObject.title(SDMDataObjectParser::parseStringAttr(child, HeaderParser::XLINKTITLE)); // Look up for the <dimensionality... child = child->next; unsigned int dimensionality = parseDimensionality(child); sdmDataObject.dimensionality(dimensionality); if ( dimensionality == 0 ) { // Look up for numTime... only if dimensionality == 0 sdmDataObject.numTime((unsigned int) parseNumTime(child) ); } // Look up for the <execBlock... child child = child->next; parseExecBlock(child, sdmDataObject); // Look up for the <numAntenna... child child = child->next; int numAntenna = parseNumAntenna(child); //cout << child->name << "=" << numAntenna << endl; sdmDataObject.numAntenna((unsigned int) numAntenna); // Look up for the <correlationMode> ... child child = child->next; parseCorrelationMode(child, sdmDataObject); // Look up for the <spectralResolution> ... child child = child->next; parseSpectralResolution(child, sdmDataObject); // Look up for child <processorType> ... child child = child->next; parseProcessorType(child, sdmDataObject); // Look up for the <dataStruct> ... child child = child->next; parseDataStruct(child, sdmDataObject); //cout << "Exiting parseSDMDataHeader" << endl; } // void HeaderParser::parseProjectPath(xmlNode* a_node, SDMDataObject& sdmDataObject) { // string projectPath = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::PROJECTPATH); // boost::cmatch what; // if (boost::regex_match(projectPath.c_str(), what,PROJECTPATH3) && what[0].matched) { // sdmDataObject.execBlockNum(::atoi(what[1].first)); // sdmDataObject.scanNum(::atoi(what[2].first)); // sdmDataObject.subscanNum(::atoi(what[3].first)); // } // else // throw SDMDataObjectParserException("HeaderParser::parseProjectPath: Invalid string for projectPath '" + projectPath + "'"); // } long long HeaderParser::parseStartTime(xmlNode* a_node){ SDMDataObjectParser::isElement(a_node, HeaderParser::STARTTIME); return SDMDataObjectParser::parseLongLong(a_node->children); } string HeaderParser::parseDataOID(xmlNode* a_node) { SDMDataObjectParser::isElement(a_node, HeaderParser::DATAOID); // Look for attribute string dataOID = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::XLINKHREF); return dataOID; } int HeaderParser::parseDimensionality(xmlNode* a_node) { //cout << "Entering parseDimensionality with " << a_node->name << endl; if (SDMDataObjectParser::testElement(a_node, HeaderParser::DIMENSIONALITY)) { return SDMDataObjectParser::parseInt(a_node->children); } else return 0; } int HeaderParser::parseNumTime(xmlNode* a_node) { SDMDataObjectParser::isElement(a_node, HeaderParser::NUMTIME); return SDMDataObjectParser::parseInt(a_node->children); } void HeaderParser::parseExecBlock(xmlNode* a_node, SDMDataObject& sdmDataObject){ //cout << "Entering parseExecBlock with " << a_node << endl; SDMDataObjectParser::isElement(a_node, HeaderParser::EXECBLOCK); // Look up for the execBlockUID attribute. sdmDataObject.execBlockUID(SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::XLINKHREF)); } int HeaderParser::parseExecBlockNum(xmlNode* a_node){ SDMDataObjectParser::isElement(a_node, HeaderParser::EXECBLOCKNUM); return SDMDataObjectParser::parseInt(a_node->children); } int HeaderParser::parseScanNum(xmlNode* a_node){ SDMDataObjectParser::isElement(a_node, HeaderParser::SCANNUM); return SDMDataObjectParser::parseInt(a_node->children); } int HeaderParser::parseSubscanNum(xmlNode* a_node){ SDMDataObjectParser::isElement(a_node, HeaderParser::SUBSCANNUM); return SDMDataObjectParser::parseInt(a_node->children); } int HeaderParser::parseNumAntenna(xmlNode* a_node){ SDMDataObjectParser::isElement(a_node, HeaderParser::NUMANTENNA); return SDMDataObjectParser::parseInt(a_node->children); } void HeaderParser::parseCorrelationMode(xmlNode* a_node, SDMDataObject& sdmDataObject) { SDMDataObjectParser::isElement(a_node, HeaderParser::CORRELATIONMODE); sdmDataObject.correlationMode_ = SDMDataObjectParser::parseLiteral<CorrelationMode, CCorrelationMode>(a_node->children); } void HeaderParser::parseSpectralResolution(xmlNode* a_node, SDMDataObject& sdmDataObject) { SDMDataObjectParser::isElement(a_node, HeaderParser::SPECTRALRESOLUTION); sdmDataObject.spectralResolutionType_ = SDMDataObjectParser::parseLiteral<SpectralResolutionType, CSpectralResolutionType>(a_node->children); } void HeaderParser::parseProcessorType(xmlNode* a_node, SDMDataObject& sdmDataObject) { SDMDataObjectParser::isElement(a_node, HeaderParser::PROCESSORTYPE); sdmDataObject.processorType_ = SDMDataObjectParser::parseLiteral<ProcessorType, CProcessorType>(a_node->children); } void HeaderParser::parseDataStruct(xmlNode* a_node, SDMDataObject& sdmDataObject){ //cout << "Entering parseDataStruct with " << a_node->name << endl; SDMDataObjectParser::isElement(a_node, HeaderParser::DATASTRUCT); SDMDataObject::DataStruct dataStruct; switch (sdmDataObject.correlationMode()) { case AUTO_ONLY: break; case CROSS_ONLY: case CROSS_AND_AUTO: dataStruct.apc_ = SDMDataObjectParser::parseStringsAttr<AtmPhaseCorrection, CAtmPhaseCorrection>(a_node, HeaderParser::APC); break; } // Traverse the children // BaseBands... xmlNode* child = a_node->children; vector <SDMDataObject::Baseband> basebands; while (SDMDataObjectParser::testElement(child, HeaderParser::BASEBAND)) { basebands.push_back(parseBaseband(child, sdmDataObject )); child = child->next; } dataStruct.basebands_ = (basebands); // Now that all the spectral windows are read set the associations between spectral windows. // We have recorded the id and image attributes when they are present in private strings in each spectralWindow. // // I want a map to associate a string of the form "<int>_<int>" to a string of the form "<int>_<int>" // and I define an entry in this map for each spectralWindow with an strSw_ non empty, the value // associated is of the form <int>_<int> where the two integers are the coordinates // (baseband index, spectralWindow index in the baseband) // map<string, string> id2int_int; ostringstream oss; string key, value; for (unsigned int ibb = 0; ibb < dataStruct.basebands_.size(); ibb++) { vector<SDMDataObject::SpectralWindow>& spws = dataStruct.basebands_.at(ibb).spectralWindows_; for (unsigned int ispw = 0; ispw < spws.size(); ispw++) { oss.str(""); oss << ibb << " " << ispw; value = oss.str(); oss.str(""); oss << ibb << " " << spws.at(ispw).strSw(); key = oss.str(); id2int_int[key] = value; } } // Now re scan all the spectralWindows and look for the ones with an strImage_ non empty. // and define the associations. // istringstream iss; map<string, string>::iterator iter; int ibbImage, ispwImage; for (unsigned int ibb = 0; ibb < dataStruct.basebands_.size(); ibb++) { vector<SDMDataObject::SpectralWindow>& spws = dataStruct.basebands_.at(ibb).spectralWindows_; for (unsigned int ispw = 0; ispw < spws.size(); ispw++) { string image = spws.at(ispw).strImage(); if (image.size() > 0) { oss.str(""); oss << ibb << " " << image; key = oss.str(); if ((iter = id2int_int.find(key)) != id2int_int.end()) { iss.str(iter->second); iss >> ibbImage; iss >> ispwImage; dataStruct.imageSPW(ibb, ispw, ispwImage); } else { oss.str(""); oss << "In baseband #" << ibb << " the spectral window #" << ispw << " refers to non defined image ('" << image << "')"; throw SDMDataObjectParserException(oss.str()); } } } } // Metadata attachments. // flags (optional) if (SDMDataObjectParser::testElement(child, HeaderParser::FLAGS)) { dataStruct.flags_ = (parseBinaryPart(child, HeaderParser::FLAGS)); child = child->next; } // actualTimes (optional) if (SDMDataObjectParser::testElement(child, HeaderParser::ACTUALTIMES)) { dataStruct.actualTimes_ = (parseBinaryPart(child, HeaderParser::ACTUALTIMES)); child = child->next; } // actualDurations (optional) if (SDMDataObjectParser::testElement(child, HeaderParser::ACTUALDURATIONS)) { dataStruct.actualDurations_ = (parseBinaryPart(child, HeaderParser::ACTUALDURATIONS)); child = child->next; } // Binary attachments elements... switch (sdmDataObject.correlationMode()) { case CROSS_ONLY : dataStruct.crossData_ = (parseBinaryPart(child, HeaderParser::CROSSDATA)); child = child->next; break; case AUTO_ONLY : dataStruct.autoData_ = (parseAutoDataBinaryPart(child, HeaderParser::AUTODATA)); child = child->next; break; case CROSS_AND_AUTO : dataStruct.crossData_ = (parseBinaryPart(child, HeaderParser::CROSSDATA)); child = child->next; dataStruct.autoData_ = (parseAutoDataBinaryPart(child, HeaderParser::AUTODATA)); child = child->next; break; } /* // zeroLags (mandatory in FULL_RESOLUTION) if (sdmDataObject.spectralResolutionType() == FULL_RESOLUTION) { dataStruct.zeroLags_ = (parseBinaryPart(child, HeaderParser::ZEROLAGS)); child = child->next; } // (and optional in CHANNEL_AVERAGE) else if (sdmDataObject.spectralResolutionType() == CHANNEL_AVERAGE) { if (SDMDataObjectParser::testElement(child, HeaderParser::ZEROLAGS)) { dataStruct.zeroLags_ = (parseBinaryPart(child, HeaderParser::ZEROLAGS)); child = child->next; } } */ // zeroLags are allowed only with a non FX correlator. if (SDMDataObjectParser::testElement(child, HeaderParser::ZEROLAGS)) { // Reject zeroLags if the context does not allow them if (sdmDataObject.processorType_ != CORRELATOR) throw SDMDataObjectParserException("zeroLags are not expected with the declared processor type ('" + CProcessorType::name(sdmDataObject.processorType_) + "')"); dataStruct.zeroLags_ = (parseZeroLagsBinaryPart(child, HeaderParser::ZEROLAGS)); // Reject zeroLags if the context does not allow them ... again if (dataStruct.zeroLags_.correlatorType_ == FX) throw SDMDataObjectParserException ("zeroLags are not expected with the declared correlator type ('" + CCorrelatorType::name(dataStruct.zeroLags_.correlatorType_) + "')"); child = child->next; } sdmDataObject.dataStruct_ = (dataStruct); } SDMDataObject::Baseband HeaderParser::parseBaseband(xmlNode* a_node, SDMDataObject& sdmDataObject){ SDMDataObject::Baseband bb; SDMDataObjectParser::isElement(a_node, HeaderParser::BASEBAND); bb.name_ = (SDMDataObjectParser::parseStringAttr<BasebandName, CBasebandName>(a_node, HeaderParser::NAME)); // Traverse the children (spectralWindow). xmlNode* child = a_node->children; vector<SDMDataObject::SpectralWindow> spw; parseSpectralWindow(child, sdmDataObject, spw); bb.spectralWindows(spw); return bb; } void HeaderParser::parseSpectralWindow(xmlNode* a_node, SDMDataObject& sdmDataObject , vector<SDMDataObject::SpectralWindow>& spectralWindow){ for (xmlNode* cur_node = a_node; cur_node; cur_node = cur_node->next) { SDMDataObjectParser::isElement(a_node, HeaderParser::SPECTRALWINDOW); //Look for attributes vector<StokesParameter> crossPolProducts; vector<StokesParameter> sdPolProducts; float scaleFactor; int numSpectralPoint; int numBin; NetSideband sideband; SDMDataObject::SpectralWindow spw; string dummy = SDMDataObjectParser::parseStringAttr(cur_node, HeaderParser::SWBB); switch (sdmDataObject.correlationMode()) { case CROSS_ONLY: crossPolProducts = SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::CROSSPOLPRODUCTS ); scaleFactor = SDMDataObjectParser::parseFloatAttr(cur_node, HeaderParser::SCALEFACTOR ); numSpectralPoint = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMSPECTRALPOINT ); numBin = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMBIN ); sideband = SDMDataObjectParser::parseStringAttr<NetSideband, CNetSideband>(cur_node, HeaderParser::SIDEBAND); spw = SDMDataObject::SpectralWindow(crossPolProducts, scaleFactor, (unsigned int)numSpectralPoint, (unsigned int)numBin, sideband); break; case AUTO_ONLY: sdPolProducts = SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::SDPOLPRODUCTS ); numSpectralPoint = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMSPECTRALPOINT ); numBin = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMBIN ); sideband = SDMDataObjectParser::parseStringAttr<NetSideband, CNetSideband>(cur_node, HeaderParser::SIDEBAND); spw = SDMDataObject::SpectralWindow(sdPolProducts, (unsigned int)numSpectralPoint, (unsigned int)numBin, sideband); break; case CROSS_AND_AUTO: crossPolProducts = SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::CROSSPOLPRODUCTS ); sdPolProducts = SDMDataObjectParser::parseStringsAttr<StokesParameter, CStokesParameter>(cur_node, HeaderParser::SDPOLPRODUCTS ); scaleFactor = SDMDataObjectParser::parseFloatAttr(cur_node, HeaderParser::SCALEFACTOR ); numSpectralPoint = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMSPECTRALPOINT ); numBin = SDMDataObjectParser::parseIntAttr(cur_node, HeaderParser::NUMBIN ); sideband = SDMDataObjectParser::parseStringAttr<NetSideband, CNetSideband>(cur_node, HeaderParser::SIDEBAND); spw = SDMDataObject::SpectralWindow(crossPolProducts, sdPolProducts, scaleFactor, (unsigned int)numSpectralPoint, (unsigned int)numBin, sideband); break; } spw.strSw(SDMDataObjectParser::parseStringAttr(cur_node, HeaderParser::SW)); if (SDMDataObjectParser::hasAttr(cur_node, HeaderParser::IMAGE)) spw.strImage(SDMDataObjectParser::parseStringAttr(cur_node, HeaderParser::IMAGE)); spectralWindow.push_back(spw); } } SDMDataObject::BinaryPart HeaderParser::parseBinaryPart(xmlNode* a_node, const string& attachmentName) { SDMDataObjectParser::isElement(a_node, attachmentName); return SDMDataObject::BinaryPart(SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SIZE), SDMDataObjectParser::parseStringsAttr<AxisName, CAxisName>(a_node, HeaderParser::AXES)); } SDMDataObject::AutoDataBinaryPart HeaderParser::parseAutoDataBinaryPart(xmlNode* a_node, const string& attachmentName) { SDMDataObjectParser::isElement(a_node, attachmentName); return SDMDataObject::AutoDataBinaryPart(SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SIZE), SDMDataObjectParser::parseStringsAttr<AxisName, CAxisName>(a_node, HeaderParser::AXES), SDMDataObjectParser::parseBoolAttr(a_node, HeaderParser::NORMALIZED)); } SDMDataObject::ZeroLagsBinaryPart HeaderParser::parseZeroLagsBinaryPart(xmlNode* a_node, const string& attachmentName) { SDMDataObjectParser::isElement(a_node, attachmentName); return SDMDataObject::ZeroLagsBinaryPart(SDMDataObjectParser::parseIntAttr(a_node, HeaderParser::SIZE), SDMDataObjectParser::parseStringsAttr<AxisName, CAxisName>(a_node, HeaderParser::AXES), SDMDataObjectParser::parseStringAttr<CorrelatorType, CCorrelatorType>(a_node, HeaderParser::CORRELATORTYPE)); } // CorrSubsetHeaderParser methods. CorrSubsetHeaderParser::CorrSubsetHeaderParser() { doc = NULL; } CorrSubsetHeaderParser::~CorrSubsetHeaderParser() { if (doc != NULL) xmlFreeDoc(doc); } void CorrSubsetHeaderParser::parseFile(const string& filename, SDMDataSubset& sdmCorrDataSubset){ if (doc != NULL) xmlFreeDoc(doc); doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { throw SDMDataObjectParserException("The file '"+filename+"' could not be transformed into a DOM structure"); } xmlNode* root_element = xmlDocGetRootElement(doc); parseSDMDataSubsetHeader(root_element, sdmCorrDataSubset); } void CorrSubsetHeaderParser::parseMemory(const string& buffer, SDMDataSubset& sdmCorrDataSubset) { if (doc != NULL) xmlFreeDoc(doc); doc = xmlReadMemory(buffer.data(), buffer.size(), "SDMDataHeader.xml", NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { throw SDMDataObjectParserException("The buffer containing the XML document could not be transformed into a DOM structure"); } xmlNode* root_element = xmlDocGetRootElement(doc); parseSDMDataSubsetHeader(root_element, sdmCorrDataSubset ); }; void CorrSubsetHeaderParser::parseSDMDataSubsetHeader(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) { // Look up for <sdmSubsetDataHeader... SDMDataObjectParser::isElement(a_node, SDMDATASUBSETHEADER); // Project path. vector<unsigned int> v; v = SDMDataObjectParser::parseProjectPath(a_node); // v should contain 4 (integration) or 5 (subintegration) elements. // Check conformity of execBlockNum, scanNum and subscanNum. if (v.at(0) != sdmCorrDataSubset.owner()->execBlockNum() || v.at(1) != sdmCorrDataSubset.owner()->scanNum() || v.at(2) != sdmCorrDataSubset.owner()->subscanNum()) throw SDMDataObjectParserException("The project path of this data subset '" +SDMDataObjectParser::parseStringAttr(a_node, PROJECTPATH) +"' is not compatible with the project path announced in the global header" +" '"+sdmCorrDataSubset.owner()->projectPath()+"'"); // Determine integrationNum [, subintegrationNum] sdmCorrDataSubset.integrationNum_ = v.at(3); sdmCorrDataSubset.subintegrationNum_ = (v.size() == 5) ? v.at(4) : 0; // Traverse the children . xmlNode* child = a_node->children; // <schedulePeriodTime... parseSchedulePeriodTime(child, sdmCorrDataSubset); // <dataStruct... child = child->next; SDMDataObjectParser::isElement(child, CorrSubsetHeaderParser::DATASTRUCT); sdmCorrDataSubset.dataStruct_ = SDMDataObjectParser::parseStringAttr(child, CorrSubsetHeaderParser::REF); child = child->next; if (SDMDataObjectParser::testElement(child, CorrSubsetHeaderParser::ABORTOBSERVATION)) { // Is it a cancelling [sub]integration ? sdmCorrDataSubset.aborted_ = true; parseAbortObservation(child, sdmCorrDataSubset); } else { // ... or a sequence of attachments description. if (SDMDataObjectParser::testElement(child, FLAGSREF)) { sdmCorrDataSubset.flagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } if (SDMDataObjectParser::testElement(child, ACTUALTIMESREF)) { sdmCorrDataSubset.actualTimesREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } if (SDMDataObjectParser::testElement(child, ACTUALDURATIONSREF)) { sdmCorrDataSubset.actualDurationsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } switch (sdmCorrDataSubset.owner()->correlationMode()) { case CROSS_ONLY: SDMDataObjectParser::isElement(child, CROSSDATAREF); sdmCorrDataSubset.crossDataREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); sdmCorrDataSubset.crossDataType_ = SDMDataObjectParser::parseStringAttr<PrimitiveDataType, CPrimitiveDataType>(child, CorrSubsetHeaderParser::TYPE); child = child->next; break; case AUTO_ONLY: SDMDataObjectParser::isElement(child, AUTODATAREF); sdmCorrDataSubset.autoDataREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; break; case CROSS_AND_AUTO: SDMDataObjectParser::isElement(child, CROSSDATAREF); sdmCorrDataSubset.crossDataREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); sdmCorrDataSubset.crossDataType_ = SDMDataObjectParser::parseStringAttr<PrimitiveDataType, CPrimitiveDataType>(child, CorrSubsetHeaderParser::TYPE); child = child->next; SDMDataObjectParser::isElement(child, AUTODATAREF); sdmCorrDataSubset.autoDataREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; break; } /* if (sdmCorrDataSubset.owner()->spectralResolutionType() != CHANNEL_AVERAGE) { SDMDataObjectParser::isElement(child, ZEROLAGSREF); sdmCorrDataSubset.zeroLagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } */ // zeroLags are optional in any case. Michel Caillat. 24 Jul 2008 if (SDMDataObjectParser::testElement(child, ZEROLAGSREF)) { sdmCorrDataSubset.zeroLagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } } } // void CorrSubsetHeaderParser::parseProjectPath (xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) { // string projectPath = SDMDataObjectParser::parseStringAttr(a_node,CorrSubsetHeaderParser::PROJECTPATH); // boost::cmatch what; // unsigned int execBlockNum = 0; // unsigned int scanNum = 0; // unsigned int subscanNum = 0; // switch (sdmCorrDataSubset.owner()->spectralResolutionType()) { // case FULL_RESOLUTION: // if (boost::regex_match(projectPath.c_str(), what, SDMDataObjectParser::PROJECTPATH4) && what[0].matched) { // execBlockNum = ::atoi(what[1].first); // scanNum = ::atoi(what[2].first); // subscanNum = ::atoi(what[3].first); // sdmCorrDataSubset.integrationNum_ = ::atoi(what[4].first); // } // else // throw SDMDataObjectParserException("Invalid string for projectPath '" + projectPath + "'"); // break; // case CHANNEL_AVERAGE: // if (boost::regex_match(projectPath.c_str(), what, SDMDataObjectParser::PROJECTPATH5) && what[0].matched) { // execBlockNum = ::atoi(what[1].first); // scanNum = ::atoi(what[2].first); // subscanNum = ::atoi(what[3].first); // sdmCorrDataSubset.integrationNum_ = ::atoi(what[4].first); // sdmCorrDataSubset.subintegrationNum_ = ::atoi(what[5].first); // } // else // throw SDMDataObjectParserException("Invalid string for projectPath '" + projectPath + "'"); // break; // case BASEBAND_WIDE: // throw SDMDataObjectParserException("'"+CSpectralResolutionType::name(BASEBAND_WIDE)+"' cannot appear in this context."); // break; // } // if (execBlockNum != sdmCorrDataSubset.owner()->execBlockNum() // || scanNum != sdmCorrDataSubset.owner()->scanNum() // || subscanNum != sdmCorrDataSubset.owner()->subscanNum()) // throw SDMDataObjectParserException("The project path of this data subset '" // +projectPath // +"' is not compatible with the project path announced in the global header" // +" '"+sdmCorrDataSubset.owner()->projectPath()+"'"); // } void CorrSubsetHeaderParser::parseSchedulePeriodTime(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) { SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::SCHEDULEPERIODTIME); xmlNode* child = a_node->children; // <time... sdmCorrDataSubset.time_ = parseTime(child); // <interval... child = child->next; sdmCorrDataSubset.interval_ = parseInterval(child); } long long CorrSubsetHeaderParser::parseTime(xmlNode* a_node) { SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::TIME); return SDMDataObjectParser::parseLongLong(a_node->children); } long long CorrSubsetHeaderParser::parseInterval(xmlNode* a_node) { SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::INTERVAL); return SDMDataObjectParser::parseLongLong(a_node->children); } void CorrSubsetHeaderParser::parseAbortObservation(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) { xmlNode* child = a_node->children; // <abortTime... SDMDataObjectParser::isElement(child, CorrSubsetHeaderParser::ABORTTIME); sdmCorrDataSubset.abortTime_ = SDMDataObjectParser::parseLongLong(child->children); // <abortReason... child = child->next; SDMDataObjectParser::isElement(child, CorrSubsetHeaderParser::ABORTREASON); sdmCorrDataSubset.abortReason_ = SDMDataObjectParser::parseString(child->children); } void CorrSubsetHeaderParser::parseCrossDataType(xmlNode* a_node, SDMDataSubset& sdmCorrDataSubset) { SDMDataObjectParser::isElement(a_node, CorrSubsetHeaderParser::TYPE); sdmCorrDataSubset.crossDataType(SDMDataObjectParser::parseLiteral<PrimitiveDataType, CPrimitiveDataType>(a_node->children)); } void CorrSubsetHeaderParser::reset() { if (doc) xmlFreeDoc(doc); doc = NULL; } // TPSubsetHeaderParser methods. TPSubsetHeaderParser::TPSubsetHeaderParser() { doc = NULL; } TPSubsetHeaderParser::~TPSubsetHeaderParser() { if (doc != NULL) xmlFreeDoc(doc); } void TPSubsetHeaderParser::parseFile(const string& filename, SDMDataSubset& sdmTPDataSubset){ if (doc != NULL) xmlFreeDoc(doc); doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { throw SDMDataObjectParserException("The file '"+filename+"' could not be transformed into a DOM structure"); } xmlNode* root_element = xmlDocGetRootElement(doc); parseSDMDataSubsetHeader(root_element, sdmTPDataSubset); } void TPSubsetHeaderParser::parseMemory(const string& buffer, SDMDataSubset& sdmTPDataSubset) { if (doc != NULL) xmlFreeDoc(doc); doc = xmlReadMemory(buffer.data(), buffer.size(), "SDMDataHeader.xml", NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { throw SDMDataObjectParserException("The buffer containing the XML document could not be transformed into a DOM structure"); } xmlNode* root_element = xmlDocGetRootElement(doc); parseSDMDataSubsetHeader(root_element, sdmTPDataSubset); } void TPSubsetHeaderParser::parseSDMDataSubsetHeader(xmlNode* a_node, SDMDataSubset& sdmTPDataSubset) { // Look up for <sdmSubsetDataHeader... SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::SDMDATASUBSETHEADER); // Project path. int pathLen = (sdmTPDataSubset.owner()->dimensionality() == 0) ? 3 : 4; vector<unsigned int> v = SDMDataObjectParser::parseProjectPath(a_node, pathLen); // Check conformity of execBlockNum, scanNum and subscanNum. if (v.at(0) != sdmTPDataSubset.owner()->execBlockNum() || v.at(1) != sdmTPDataSubset.owner()->scanNum() || v.at(2) != sdmTPDataSubset.owner()->subscanNum()) throw SDMDataObjectParserException("The project path of this data subset '" +SDMDataObjectParser::parseStringAttr(a_node, PROJECTPATH) +"' is not compatible with the project path announced in the global header" +" '"+sdmTPDataSubset.owner()->projectPath()+"'"); if (pathLen == 4) sdmTPDataSubset.integrationNum_ = v.at(3); // Traverse the children... xmlNode* child = a_node->children; // <schedulePeriodTime... parseSchedulePeriodTime(child, sdmTPDataSubset); // <dataStruct... child = child->next; SDMDataObjectParser::isElement(child, TPSubsetHeaderParser::DATASTRUCT); sdmTPDataSubset.dataStruct_ = (SDMDataObjectParser::parseStringAttr(child, TPSubsetHeaderParser::REF)); child = child->next; // Optional flags attachments. if (SDMDataObjectParser::testElement(child, FLAGSREF)) { sdmTPDataSubset.flagsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } if (SDMDataObjectParser::testElement(child, ACTUALTIMESREF)) { sdmTPDataSubset.actualTimesREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } if (SDMDataObjectParser::testElement(child, ACTUALDURATIONSREF)) { sdmTPDataSubset.actualDurationsREF_ = SDMDataObjectParser::parseStringAttr(child, XLINKHREF); child = child->next; } // Look for mandatory autoData element. SDMDataObjectParser::isElement(child, AUTODATAREF); sdmTPDataSubset.autoDataREF_ = (SDMDataObjectParser::parseStringAttr(child, TPSubsetHeaderParser::XLINKHREF )); } void TPSubsetHeaderParser::parseProjectPath(xmlNode* a_node, SDMDataSubset& sdmTPDataSubset) { string projectPath = SDMDataObjectParser::parseStringAttr(a_node,TPSubsetHeaderParser::PROJECTPATH); #ifndef WITHOUT_BOOST boost::cmatch what; #else std::cmatch what; #endif unsigned int execBlockNum = 0; unsigned int scanNum = 0; unsigned int subscanNum = 0; #ifndef WITHOUT_BOOST if (boost::regex_match(projectPath.c_str(), what, PROJECTPATH3) && what[0].matched) { #else if (std::regex_match(projectPath.c_str(), what, PROJECTPATH3) && what[0].matched) { #endif execBlockNum = ::atoi(what[1].first); scanNum = ::atoi(what[2].first); subscanNum = ::atoi(what[3].first); } else throw SDMDataObjectParserException("Invalid string for projectPath '" + projectPath + "'"); if (execBlockNum != sdmTPDataSubset.owner()->execBlockNum() || scanNum != sdmTPDataSubset.owner()->scanNum() || subscanNum != sdmTPDataSubset.owner()->subscanNum()) throw SDMDataObjectParserException("The project path of this data subset '" +projectPath +"' is not compatible with the project path announced in the global header" +" '"+sdmTPDataSubset.owner()->projectPath()+"'"); } void TPSubsetHeaderParser::parseSchedulePeriodTime(xmlNode* a_node, SDMDataSubset& sdmTPDataSubset) { SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::SCHEDULEPERIODTIME); xmlNode* child = a_node->children; // <time... sdmTPDataSubset.time_ = parseTime(child); // <interval... child = child->next; sdmTPDataSubset.interval_ = parseInterval(child); } long long TPSubsetHeaderParser::parseTime(xmlNode* a_node) { SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::TIME); return SDMDataObjectParser::parseLongLong(a_node->children); } long long TPSubsetHeaderParser::parseInterval(xmlNode* a_node) { SDMDataObjectParser::isElement(a_node, TPSubsetHeaderParser::INTERVAL); return SDMDataObjectParser::parseLongLong(a_node->children); } // SDMDataObject::TPSubsetHeaderParser:: methods. // SDMDataObjectHeaderParser:: methods. void SDMDataObjectParser::isElement(xmlNode* a_node, const string& elementName) { //cout << "Entering isElement for " << a_node->name << endl; if ((a_node == NULL) || (a_node->type != XML_ELEMENT_NODE) || (elementName.compare((const char*)a_node->name) != 0)) { ostringstream oss; oss << "Could not find '<" << elementName << "..."; if ((a_node != NULL) && (a_node->type == XML_ELEMENT_NODE)) oss << " ( I was given '<" << a_node->name <<"...')"; else oss << " ( node is not an xml element ) " << endl; throw SDMDataObjectParserException(oss.str()); } //cout << "Exiting isElement" << endl; } bool SDMDataObjectParser::testElement(xmlNode* a_node, const string& elementName) { //cout << "Entering testElement with " << elementName << " against " << a_node->name << endl; bool result = ((a_node != NULL) && (a_node->type == XML_ELEMENT_NODE) && (elementName.compare((const char*)a_node->name) == 0)); return result; } void SDMDataObjectParser::inElements(xmlNode* a_node, const vector<string>& elementNames) { if (find(elementNames.begin(), elementNames.end(), string((char*) a_node->name)) == elementNames.end()) { ostringstream message; copy(elementNames.begin(), elementNames.end(), ostream_iterator<string>(message, " ")); throw SDMDataObjectParserException("Could not find any of elements '" + message.str()+"' in " + string((const char*) a_node->name)); } } xmlAttr* SDMDataObjectParser::hasAttr(xmlNode* a_node, const string& attrName) { xmlAttr* result = 0; for (struct _xmlAttr* attr = a_node->properties; attr; attr = attr->next) { if (attrName.compare((const char*) attr->name) == 0) { result = attr; break; } } return result; } void SDMDataObjectParser::tokenize(const string& str, vector<string>& tokens, const string& delimiters) { // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } } void SDMDataObjectParser::tokenize(const string& str, set<string>& tokens, const string& delimiters) { // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // Found a token, add it to the vector. tokens.insert(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } } string SDMDataObjectParser::substring(const string &s, int a, int b) { return s.substr(a,(b - a)); } string SDMDataObjectParser::trim(const string& s) { unsigned int i = 0; while (s.at(i) == ' ' && i < s.length()) ++i; if (i == s.length()) return ""; unsigned int j = s.length() - 1; while (s.at(j) == ' ' && j > i) --j; return substring(s,i,j + 1); } string SDMDataObjectParser::parseString(xmlNode* a_node) { if ((a_node != NULL) && (a_node->next == NULL)) return string((const char*) a_node->content); throw SDMDataObjectParserException("Invalid node , can't be parsed into a long long"); } long long SDMDataObjectParser::parseLongLong(xmlNode* a_node) { if ((a_node != NULL) && (a_node->next == NULL)) { istringstream in; in.str((const char*) a_node->content); long long x; in >> x; if (in.rdstate() == istream::failbit) throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as a long long in" + string((const char*)a_node->parent->name)); return x; } throw SDMDataObjectParserException("Invalid node , can't be parsed into a long long"); } int SDMDataObjectParser::parseInt(xmlNode* a_node) { //cout << "Entering parseInt with " << a_node->content << endl; if ((a_node != NULL) && (a_node->next == NULL)) { #ifndef WITHOUT_BOOST const boost::regex UINT("[0-9]+"); boost::cmatch what; if (boost::regex_match((char*)a_node->content, what, UINT)) { return (::atoi(what[0].first)); } #else const std::regex UINT("[0-9]+"); std::cmatch what; if (std::regex_match((char*)a_node->content, what, UINT)) { return (::atoi(what[0].first)); } #endif else throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as an int in " + string((const char*)a_node->parent->name)); } throw SDMDataObjectParserException("Invalid node , can't be parsed into an int"); } bool SDMDataObjectParser::parseBool(xmlNode* a_node) { if ((a_node != NULL) && (a_node->next == NULL)) { #ifndef WITHOUT_BOOST const boost::regex TORF("true|false"); boost::cmatch what; if (boost::regex_match((char*)a_node->content, what, TORF)) { return ( *(what[0].first) == 't') ? true:false; } #else const std::regex TORF("true|false"); std::cmatch what; if (std::regex_match((char*)a_node->content, what, TORF)) { return ( *(what[0].first) == 't') ? true:false; } #endif else throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as an int in " + string((const char*)a_node->parent->name)); } throw SDMDataObjectParserException("Invalid node , can't be parsed into an bool"); } float SDMDataObjectParser::parseFloat(xmlNode* a_node) { if ((a_node != NULL) && (a_node->next == NULL)) { istringstream in; in.str((const char*) a_node->content); float x; in >> x; if (in.rdstate() == istream::failbit) throw SDMDataObjectParserException("failed to parse '"+string((const char*)a_node->content)+"' as a float in " + string((const char*)a_node->parent->name)); return x; } throw SDMDataObjectParserException("Invalid node , can't be parsed into an float"); } int SDMDataObjectParser::parseIntAttr(xmlNode* a_node, const string& attrName) { xmlAttr* attr = 0; if ((attr = hasAttr(a_node, attrName))) { int result =parseInt(attr->children); return result; } else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name)); } bool SDMDataObjectParser::parseBoolAttr(xmlNode* a_node, const string& attrName) { xmlAttr* attr = 0; if ((attr = hasAttr(a_node, attrName))) { bool result = parseBool(attr->children); return result; } else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name)); } float SDMDataObjectParser::parseFloatAttr(xmlNode* a_node, const string& attrName) { xmlAttr* attr = 0; if ((attr = hasAttr(a_node, attrName))) { float result = parseFloat(attr->children); //cout << attr->name << " = " << result << endl; return result; } else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name)); } string SDMDataObjectParser::parseStringAttr(xmlNode* a_node, const string& attrName) { //cout << "Entering parseStringAttr with " << attrName << " in " << a_node->name << endl; xmlAttr* attr = 0; if ((attr = hasAttr(a_node, attrName))) { string result = string((const char*)attr->children->content); //cout << attr->name << " = " << result << endl; return result; } else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name)); } vector<string> SDMDataObjectParser::parseStringsAttr(xmlNode* a_node, const string& attrName) { xmlAttr* attr = 0; if ((attr = hasAttr(a_node, attrName))) { vector<string> result; tokenize((const char*)attr->children->content, result); //cout << attr->name << " = '"; copy(result.begin(), result.end(), ostream_iterator<string>(cout, " ")); cout << "'" << endl; return result; } else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name)); } set<string> SDMDataObjectParser::parseStringSetAttr(xmlNode* a_node, const string& attrName) { xmlAttr* attr = 0; if ((attr = hasAttr(a_node, attrName))) { set<string> result; tokenize((const char*)attr->children->content, result); //cout << attr->name << " = '"; copy(result.begin(), result.end(), ostream_iterator<string>(cout, " ")); cout << "'" << endl; return result; } else throw SDMDataObjectParserException("could not find attribute '" + attrName + "' in " + string((const char*)a_node->name)); } vector<unsigned int> SDMDataObjectParser::parseProjectPath(xmlNode* a_node, unsigned int len) { string projectPath = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::PROJECTPATH); vector<unsigned int> result; bool matched = true; #ifndef WITHOUT_BOOST boost::cmatch what; switch (len) { case 3: matched = boost::regex_match(projectPath.c_str(), what, PROJECTPATH3); break; case 4: matched = boost::regex_match(projectPath.c_str(), what, PROJECTPATH4); break; case 5: matched = boost::regex_match(projectPath.c_str(), what, PROJECTPATH5); break; #else std::cmatch what; switch (len) { case 3: matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH3); break; case 4: matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH4); break; case 5: matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH5); break; #endif default: throw SDMDataObjectParserException ("internal error in method 'parseProjectPath'. The parameter 'len' has a value out of the range [3,5]"); } if (!matched) throw SDMDataObjectException("'" + projectPath + "' is an invalid string for a 'projectPath' attribute"); for (unsigned int i = 0; i < len; i++) { result.push_back(::atoi(what[i+1].first)); } return result; } #ifndef WITHOUT_BOOST const boost::regex SDMDataObjectParser::PROJECTPATH4OR5("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+/)?"); #else const std::regex SDMDataObjectParser::PROJECTPATH4OR5("([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+/)?"); #endif vector<unsigned int> SDMDataObjectParser::parseProjectPath(xmlNode* a_node) { string projectPath = SDMDataObjectParser::parseStringAttr(a_node, HeaderParser::PROJECTPATH); vector<unsigned int> result; bool matched = true; #ifndef WITHOUT_BOOST boost::cmatch what; matched = boost::regex_match(projectPath.c_str(), what, PROJECTPATH4OR5); #else std::cmatch what; matched = std::regex_match(projectPath.c_str(), what, PROJECTPATH4OR5); #endif if (!matched) throw SDMDataObjectException("'" + projectPath + "' is an invalid string for a 'projectPath' attribute."); // Let's retrieve the 4 first numbers. for (unsigned int i = 0; i < 4; i++) result.push_back(::atoi(what[i+1].first)); // and the fifth if it exists... if (what[5].matched) { result.push_back(::atoi(what[5].first)); } return result; } const ByteOrder* SDMDataObjectParser::parseByteOrderAttr(xmlNode* a_node, const string& attrName) { string byteOrder = SDMDataObjectParser::parseStringAttr(a_node, attrName); if (byteOrder.compare("Little_Endian")==0) return ByteOrder::Little_Endian; if (byteOrder.compare("Big_Endian")==0) return ByteOrder::Big_Endian; throw SDMDataObjectParserException("'" + byteOrder + "' is an invalid string for a 'byteOrder' attribute."); } SDMDataObjectParser::SDMDataObjectParser() {;} SDMDataObjectParser::~SDMDataObjectParser() {;} void SDMDataObjectParser::parseFileHeader(const string& filename, SDMDataObject& sdmDataObject) { headerParser.parseFile(filename, sdmDataObject); } void SDMDataObjectParser::parseMemoryHeader(const string& buffer, SDMDataObject& sdmDataObject) { headerParser.parseMemory(buffer, sdmDataObject); } void SDMDataObjectParser::parseFileCorrSubsetHeader(const string& filename, SDMDataSubset& sdmCorrDataSubset) { corrSubsetHeaderParser.parseFile(filename, sdmCorrDataSubset); } void SDMDataObjectParser::parseMemoryCorrSubsetHeader(const string& buffer, SDMDataSubset& sdmCorrDataSubset) { corrSubsetHeaderParser.parseMemory(buffer, sdmCorrDataSubset); } void SDMDataObjectParser::parseFileTPSubsetHeader(const string& filename, SDMDataSubset& sdmCorrDataSubset) { tpSubsetHeaderParser.parseFile(filename, sdmCorrDataSubset); } void SDMDataObjectParser::parseMemoryTPSubsetHeader(const string& buffer, SDMDataSubset& sdmCorrDataSubset) { tpSubsetHeaderParser.parseMemory(buffer, sdmCorrDataSubset); } } #if 0 using namespace asdmbinaries; int main (int argC, char* argV[]) { if (argC != 3) return (1); SDMDataObjectParser parser; SDMDataObject sdmDataObject; SDMDataSubset sdmDataSubset; cout << "Trying to parse an SDMDataHeader in " << argV[1] << " and an SDMDataSubsetHeader in " << argV[2] <<endl; try { parser.parseFileHeader(argV[1], sdmDataObject); cout << "----- SDMDataObject ------" << endl; cout << "SDMDataHeader: " << endl; cout << endl; cout << sdmDataObject.toString() << endl; // Now process the sdmDataSubsetHeader passed in argV[2] switch (sdmDataObject.dimensionality()) { case 0: { parser.parseFileTPSubsetHeader(argV[2], sdmDataSubset); cout << endl; cout << "SDMDataSubsetHeader: " << endl; cout << endl; cout << sdmDataSubset.toString(sdmDataObject.dimensionality()) << endl; break; } case 1: { parser.parseFileCorrSubsetHeader(argV[2], sdmDataSubset); cout << endl; cout << "SDMDataSubsetHeader: " << endl; cout << endl; cout << sdmDataSubset.toString(sdmDataObject.dimensionality()); break; } default: break; } } catch (SDMDataObjectParserException e) { cout << e.getMessage() << endl; exit(1); } cout << endl; cout << "----------------------" << endl; cout << "XML representation of the sdmDataHeader: " << endl; cout << endl; cout << sdmDataObject.toXML() << endl; cout << endl; cout << "----------------------" << endl; cout << "XML representation of the sdmDataSubsetHeader: " << endl; cout << endl; cout << sdmDataSubset.toXML(sdmDataObject.dimensionality()) << endl; } #endif