// // aegis - project change supervisor // Copyright (C) 2005-2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include // for assert #include #include #include xml_text_reader_by_node::~xml_text_reader_by_node() { trace(("~xml_text_reader_by_node()\n")); } xml_text_reader_by_node::xml_text_reader_by_node(input &arg1, bool arg2) : xml_text_reader(arg1, arg2), current_node(0) { trace(("xml_text_reader_by_node()\n")); } void xml_text_reader_by_node::register_node_handler(const nstring &hname, xml_node &handler) { trace(("xml_text_reader_by_node::register_node_handler(name = \"%s\")\n", hname.c_str())); handlers.assign(hname.downcase(), &handler); calculate_current_node_handler(); trace(("}\n")); } void xml_text_reader_by_node::push_name(const nstring &arg) { trace(("xml_text_reader_by_node::push_name(ar = \"%s\")\n{\n", arg.c_str())); if (names.empty()) names.push_back(arg.downcase()); else names.push_back(names.back() + "/" + arg.downcase()); calculate_current_node_handler(); trace(("}\n")); } void xml_text_reader_by_node::pop_name(const nstring &arg) { trace(("xml_text_reader_by_node::pop_name()\n{\n")); assert(!names.empty()); (void)arg; assert ( names.size() == 1 ? names.back() == arg.downcase() : names[names.size() - 2] + "/" + arg.downcase() == names.back() ); names.pop_back(); calculate_current_node_handler(); trace(("}\n")); } void xml_text_reader_by_node::calculate_current_node_handler() { trace(("xml_text_reader_by_node::calculate_current_node_handler()\n{\n")); if (names.empty()) current_node = 0; else current_node = handlers.query(names.back()); trace(("}\n")); } void xml_text_reader_by_node::process_node() { trace(("xml_text_reader_by_node::process_node()\n{\n")); const xmlChar *tmp = name(); nstring the_name((const char *)tmp); if (tmp) xmlFree((void *)tmp); tmp = value(); nstring the_value((const char *)tmp); if (tmp) xmlFree((void *)tmp); switch (node_type()) { case XML_READER_TYPE_NONE: if (current_node) current_node->none(the_name, the_value); break; case XML_READER_TYPE_ELEMENT: push_name(the_name); if (current_node) current_node->element_begin(the_name); break; case XML_READER_TYPE_ATTRIBUTE: if (current_node) current_node->attribute(the_name, the_value); break; case XML_READER_TYPE_TEXT: if (current_node) current_node->text(the_value); break; case XML_READER_TYPE_CDATA: if (current_node) current_node->cdata(the_value); break; case XML_READER_TYPE_ENTITY_REFERENCE: if (current_node) current_node->entity_reference(the_name, the_value); break; case XML_READER_TYPE_ENTITY: push_name(the_name); if (current_node) { current_node->entity_begin(the_name, the_value); if (is_empty_element()) current_node->entity_end(the_name, the_value); } break; case XML_READER_TYPE_PROCESSING_INSTRUCTION: if (current_node) current_node->processing_instruction(the_name, the_value); break; case XML_READER_TYPE_COMMENT: if (current_node) current_node->comment(the_value); break; case XML_READER_TYPE_DOCUMENT: if (current_node) current_node->document(the_value); break; case XML_READER_TYPE_DOCUMENT_TYPE: if (current_node) current_node->document_type(the_name, the_value); break; case XML_READER_TYPE_DOCUMENT_FRAGMENT: if (current_node) current_node->document_fragment(the_value); break; case XML_READER_TYPE_NOTATION: if (current_node) current_node->notation(the_name, the_value); break; case XML_READER_TYPE_WHITESPACE: if (current_node) current_node->whitespace(the_value); break; case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: if (current_node) current_node->significant_whitespace(the_value); break; case XML_READER_TYPE_END_ELEMENT: if (current_node) current_node->element_end(the_name); pop_name(the_name); break; case XML_READER_TYPE_END_ENTITY: if (current_node) current_node->entity_end(the_name, the_value); pop_name(the_name); break; case XML_READER_TYPE_XML_DECLARATION: if (current_node) current_node->xml_declaration(the_name, the_value); break; } trace(("}\n")); } void xml_text_reader_by_node::process_node_end(bool was_empty) { trace(("xml_text_reader_by_node::process_node_end(%d)\n{\n", was_empty)); if (was_empty) { move_back_to_element(); const xmlChar *tmp = name(); nstring the_name((const char *)tmp); if (tmp) xmlFree((void *)tmp); if (current_node) current_node->element_end(the_name); pop_name(the_name); } trace(("}\n")); }