Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

xml_attribute_list_parser.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Radko Mihal                                     *
00003  *   rmihal@pobox.sk                                                       *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
00019  ***************************************************************************/
00020 #ifndef GRAMMAR_TO_PARSERBASIC_XML_ATTRIBUTE_LIST_PARSER_H
00021 #define GRAMMAR_TO_PARSERBASIC_XML_ATTRIBUTE_LIST_PARSER_H
00022 
00023 namespace xml_parser {
00031 template< typename E >
00032 class basic_xml_attribute_list_parser : 
00033                         public grammar_to_parser::basic_simple_non_terminal<E>
00034 {
00035 public:
00036 typedef grammar_to_parser::basic_simple_non_terminal<E> non_terminal;
00037 typedef std::list< basic_xml_attribute_parser<E>* > attributes_parsers_list;
00038 typedef typename attributes_parsers_list::iterator attributes_parsers_list_iterator;
00039 typedef typename grammar_to_parser::basic_parser<E>::parser_list parser_list;
00040 typedef typename grammar_to_parser::basic_parser<E>::parser_list_iterator
00041                                                                                                                 parser_list_iterator;
00042 
00043         
00044         basic_xml_attribute_list_parser() :
00045                 grammar_to_parser::basic_simple_non_terminal<E>()
00046         {};
00047         
00048                           
00049         void push_parsers( parser_list &l )
00050         {
00051                 attributes_parsers_list_iterator it = m_attributes_parsers.begin();
00052                 while( it != m_attributes_parsers.end() ) 
00053                 {
00054                         l.push_back((*it));
00055                         it++;
00056                 }
00057         }
00058         
00059         
00060         // called from xml_element_parser
00061         void assign_attributes_parsers( attributes_parsers_list &l )
00062         {
00063                 m_attributes_parsers.empty();
00064                 attributes_parsers_list_iterator it = l.begin();
00065                 while( it != l.end() ) 
00066                 {
00067                         m_attributes_parsers.push_back((*it));
00068                         it++;
00069                 }
00070         }
00071 
00077         virtual unsigned long parse( const E *buf, const unsigned long buf_length )
00078         {
00079                 prepare_for_parsing();
00080         
00081                 attributes_parsers_list attributes_parsers;
00082                 attributes_parsers_list_iterator parse_iterator = m_attributes_parsers.begin();
00083                 bool is_parsed = true;
00084         
00085                 // copy to temporary list seems to be best to me
00086                 while( parse_iterator != m_attributes_parsers.end() ) 
00087                 {
00088                         attributes_parsers.push_back( *(parse_iterator++) );
00089                 }
00090                 while( !attributes_parsers.empty() && is_parsed )
00091                 {
00092                         parse_iterator = attributes_parsers.begin();
00093                         is_parsed = false;
00094                         while( parse_iterator != attributes_parsers.end() && 
00095                                         !is_parsed && m_parsed_size <= buf_length )
00096                         {
00097                                 (*parse_iterator)->parse( buf+m_parsed_size, buf_length-m_parsed_size );
00098                                 if( is_parsed = (*parse_iterator)->is_parsed() && 
00099                                         (*parse_iterator)->get_use_type() != basic_xml_attribute_parser<E>::PROHIBITED)
00100                                 {
00101                                         m_parsed_size += (*parse_iterator)->parsed_size();
00102                                         parse_iterator = attributes_parsers.erase(parse_iterator); // exclude from parsing
00103                                 }
00104                                 else if( is_parsed && 
00105                                                 (*parse_iterator)->get_use_type() == basic_xml_attribute_parser<E>::PROHIBITED)
00106                                 {
00107                                         is_parsed = false;
00108                                         break;
00109                                 }
00110                                 else parse_iterator++; // continue with next
00111                         }
00112                 }
00113                 // check the rest, if not only optional attribute
00114                 while( !attributes_parsers.empty() ) 
00115                 {
00116                         parse_iterator = attributes_parsers.begin();
00117                         if( (*parse_iterator)->get_use_type() == basic_xml_attribute_parser<E>::OPTIONAL ||
00118                                 (*parse_iterator)->get_use_type() == basic_xml_attribute_parser<E>::PROHIBITED)
00119                                 attributes_parsers.erase(parse_iterator);
00120                         else
00121                                 break; // in this case, the parse failed - required attribute not found
00122                 }
00123                 if( !attributes_parsers.empty() ) m_parsed_size = 0;
00124                 else m_is_parsed = true;
00125         
00126                 return m_parsed_size;
00127         }
00128 
00134         virtual std::basic_istream<E>& parse( std::basic_istream<E>& is )
00135         {
00136                 // TODO - implement
00137                 prepare_for_parsing();
00138                 return is;
00139         }
00140         
00141 protected:
00142         attributes_parsers_list                 m_attributes_parsers;
00143 
00144 };
00145 
00146 typedef basic_xml_attribute_list_parser<char> xml_attribute_list_parser;
00147 typedef basic_xml_attribute_list_parser<wchar_t> wxml_attribute_list_parser;
00148 
00149 typedef std::list< basic_xml_attribute_parser<char>* > attributes_parsers_list;
00150 typedef std::list< basic_xml_attribute_parser<wchar_t>* > wattributes_parsers_list;
00151 
00152 };
00153 
00154 #endif

Generated on Sun Jul 2 18:39:43 2006 for grammar2parser.kdevelop by  doxygen 1.4.1