diff --git a/src/ADIOS.cpp b/src/ADIOS.cpp index 4ef442c2d4237ae65e59b6abdf6bdf66b8b46278..179c19ced2916506ccff9c40a924f6e802b351b0 100644 --- a/src/ADIOS.cpp +++ b/src/ADIOS.cpp @@ -126,29 +126,115 @@ void ADIOS::DumpXMLConfigFile( std::string& xmlFileContent ) const void ADIOS::SetGroupsFromXML( const std::string xmlFileContent ) { - auto currentPosition = xmlFileContent.find( '<' ); + //Start with lambda functions + auto lfGetValue = []( const char quote, const std::string::size_type& quotePosition, + std::string& currentTag, std::string& value ) + { + currentTag = currentTag.substr( quotePosition + 1 ); + auto nextQuotePosition = currentTag.find( quote ); + if( nextQuotePosition == currentTag.npos ) + { + throw std::invalid_argument( "ERROR: Invalid attribute in..." + currentTag + "...check XML file\n"); + } + value = currentTag.substr( 0, nextQuotePosition ); + currentTag = currentTag.substr( nextQuotePosition+1 ); + }; + + //Get attributes field1="value1" field2="value2" for a single XML tag and + //puts it in pairs containers first=field + auto lfGetPairs = [&]( const std::string tag, std::vector< std::pair<const std::string, const std::string> >& pairs ) + { + std::string currentTag( tag.substr( tag.find_first_of(" \t\n") ) ); //initialize current tag + //currentTag = currentTag.substr( currentTag.find_first_not_of(" \t\n") ); //first field + + while( currentTag.find('=') != currentTag.npos ) //equalPosition + { + currentTag = currentTag.substr( currentTag.find_first_not_of(" \t\n") ); + auto equalPosition = currentTag.find('='); + const std::string field( currentTag.substr( 0, equalPosition) ); //get field + std::string value; + + //if( currentTag.size() < equalPosition+1 ) throw std::invalid_argument( "ERROR: Invalid tag..." + tag + "...check XML file for =\" syntax\n"); + + const char quote = currentTag[equalPosition+1]; + if( quote == '\'' || quote == '"') //single quotes + { + //quote position? + lfGetValue( quote, equalPosition+1, currentTag, value ); + } + + pairs.push_back( std::pair<const std::string, const std::string>( field, value ) ); + } + }; + + auto lfGetPairsFromTag = [&]( const std::string tag, std::vector< std::pair<const std::string, const std::string> >& pairs ) + { + if( tag.back() == '/' ) //last char is / --> "XML empty tag" + { + lfGetPairs( tag, pairs ); + } + else if( tag[0] == '/' ) // closing tag + { } + else // opening tag + { + //check for closing tagName + const std::string tagName = tag.substr( 0, tag.find_first_of(" \t\n\r") ); + const std::string closingTagName( "</" + tagName + ">" ); + + if( xmlFileContent.find( closingTagName ) == xmlFileContent.npos ) + throw std::invalid_argument( "ERROR: closing tag " + closingTagName + " missing, check XML file\n"); + + lfGetPairs( tag, pairs ); + } + }; + + // ****************************************************************************** //// + // Body of function STARTS ****************************************************** //// + // ****************************************************************************** //// + std::string::size_type currentPosition = xmlFileContent.find( '<' ); std::string currentGroup; // stores current Group name to populate m_Groups map key + std::string currentNonEmptyTag; while( currentPosition < xmlFileContent.size() ) { auto begin = xmlFileContent.find( '<', currentPosition ); - auto end = xmlFileContent.find( '>', currentPosition ); - if( begin == std::string::npos || end == std::string::npos ) + if( begin == xmlFileContent.npos ) break; + + //skip comment sections + if( xmlFileContent.find( "<!--", currentPosition ) == begin ) //found comment opening { - break; + auto endComment = xmlFileContent.find( "-->", currentPosition ); + if( endComment == xmlFileContent.npos ) throw std::invalid_argument( "ERROR: Open comment section, check XML file\n"); + currentPosition = endComment + 3; + continue; } - const std::string xmlItem ( xmlFileContent.substr( begin, end-begin+1 ) ); - if( xmlItem.find("<!") != std::string::npos ) //check for comments + //get and check current tag + auto end = xmlFileContent.find( '>', currentPosition ); + if( end == xmlFileContent.npos ) break; + const std::string tag( xmlFileContent.substr( begin+1, end-begin-1 ) ); //without < > + if( tag.empty() || tag[0] == ' ' ) throw std::invalid_argument( "ERROR: Empty tag, check XML file\n"); + //skip header + if( tag.find("?xml") == 0 ) { - std::cout << "Comment: ..." << xmlItem << "...\n"; currentPosition = end + 1; continue; } + //get pairs of tag fields and values + std::vector< std::pair<const std::string, const std::string> > pairs; + lfGetPairsFromTag( tag, pairs ); + + std::cout << tag << "\n"; + + for( auto& pair : pairs ) + { + std::cout << "field..." << pair.first << "...value..." << pair.second << "\n"; + } + std::cout << "\n"; + currentPosition = end + 1; - std::cout << "Item: ..." << xmlItem << "...\n"; } }