/*********************************************************************
 * This file is part of the cpplibs suite.
 *
 * Copyright (C) 2001 Topi Mäenpää
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.6 $
 *********************************************************************/

#ifndef _XMLPARSER_H
#define _XMLPARSER_H

#include "XMLDocument.h"
#include "../StreamTokenizer.h"
#include <io/IO.h>
#include <string>
#include "XMLException.h"

namespace util { namespace xml {
	
	/**
	 * XMLParser is a class that can be used to parse XML documents. It
	 * may be used in a streaming mode or as a DOM-like parser. The
	 * objects representing XML markup are close approximations to those
	 * defined in the DOM 1.0 specification.
	 **/
	class XMLParser : virtual public Object
	{
	public:
		/**
		 * Create a new XML parser.
		 **/
		XMLParser();
		
		/**
		 * Get the XML element from an input stream. The next element may
		 * be any XML document element inherited from Node.
		 *
		 * @param in an input stream
		 * @return a newly allocated Node object
		 * @exception IOException& if a reading error occurs
		 * @exception XMLException& if the stream is not properly formatted
		 **/
		Node* getNextNode(std::istream& in) throw (util::io::IOException&, XMLException&);

		/**
		 * Read an XML document and return a pointer to a newly allocated
		 * Document object. The document must be a well-formed XML
		 * document, i.e. it must start with &lt;?xml version="1.0"?&gt;,
		 * have a single root element, nest properly, etc.
		 *
		 * @param in an input stream
		 * @exception IOException& if a reading error occurs
		 * @exception XMLException& if the stream is not properly formatted
		 **/
		Document* readDocument(std::istream& in) throw (util::io::IOException&, XMLException&);
		/**
		 * Read a fragment of an XML document. If the next Node red from a
		 * stream is an Element, its children will be read as well.
		 **/
		Node* readFragment(std::istream& in) throw (util::io::IOException&, XMLException&);

	private:
		EndDelimitedSection _sctText;
		StreamTokenizer _tokenizer;

		Node* constructTag(std::string contents)	throw (util::io::IOException&, XMLException&);
	};
}}

#endif
