/*
  Copyright (C) 2000-2004

  Code contributed by Greg Collecutt, Joseph Hope and Paul Cochrane

  This file is part of xmds.
 
  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 2
  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, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

/*
  $Id: xmlparser.h,v 1.9 2004/04/29 03:23:00 paultcochrane Exp $
*/

/*! @file xmlparser.h
  @brief Header defining xml parser objects
*/

#ifndef LIST
#include<list>
#define LIST
#endif

// ******************************************************************************
// ******************************************************************************
//	XMLParserException
// ******************************************************************************
// ******************************************************************************

class XMLEntityStream;

//! XMLParserException class
class XMLParserException {

public :

  //! Enumerator of various xml errors
  enum {
    BAD_XML_ERR,
    ENCODING_NOT_SUPPORTED_ERR,
    INVALID_FILE_ERR,
    INTERNAL_ERR,
    UNKNOWN_ERR};

  const unsigned short theError;  //!< Number defining the error

  //! Constructor of XMLParserException object
  XMLParserException();

  //! Constructor of XMLParserException object
  XMLParserException(
		     const list<XMLEntityStream*> *const yourXMLEntityStreamStack,
		     const char *const yourErrorMessage,
		     const unsigned short& yourError);
		
  //! Destructor
  ~XMLParserException();

  //! Gets an xml parser error
  const char* getError();

private :

  char s[2048];                                                //!< Container variable for a string of characters
  const list<XMLEntityStream*> *const theXMLEntityStreamStack; //!< The XML entity stream stack
  const char *const theErrorMessage;                           //!< The error message to print
};

// ******************************************************************************
// ******************************************************************************
//	XMLEntityStream
// ******************************************************************************
// ******************************************************************************

//! Structure containing the stream position
struct StreamPositionStruct {

  unsigned long count;       //!< Counter variable
  unsigned long lineNumber;  //!< Current line number
  unsigned long columnNumber;//!< Current column number
};

class XMLParser;

//! XMLEntityStream class
class XMLEntityStream {

public :

  //! Keeps tabs on the stream position
  StreamPositionStruct streamPos;

  //! Constructor for XMLEntityStream object
  XMLEntityStream(
		  XMLParser *const yourXMLParser,
		  XMLEntityStream *const yourParentXMLEntityStream,
		  const XMLString& yourName,
		  const XMLString& yourSystemID);

  //! Destructor
  virtual ~XMLEntityStream();

  //! Returns the name as an XMLString
  const XMLString* name() const;

  //! Returns the parent xml entity stream
  XMLEntityStream* parentXMLEntityStream();

  //! Enumerator containing the xml entity stream types
  enum XMLEntityStreamType {
    ROOT_ENTITY,
    PARAMETER_ENTITY,
    GENERAL_ENTITY,
    UNPARSED_ENTITY};

  //! Returns the entity type
  virtual XMLEntityStreamType entityType() const = 0;

  //! Enumerator containing the xml entity location type
  enum XMLEntityLocationType {
    INTERNAL_ENTITY,
    EXTERNAL_ENTITY};

  //! Returns the entity location
  virtual XMLEntityLocationType entityLocation() const = 0;

  //! Determines if are at the end of the xml stream
  bool atEnd() const;

  //virtual char nextChar();
  //! Returns the next character in the stream
  virtual signed char nextChar();

  //! Returns the replacement text as an XMLString
  virtual const XMLString* replacementText() = 0;

  //! Adds a parameter xml entity stream
  XMLEntityStream* addParameterXMLEntityStream(
					       const XMLString& name,
					       const XMLString& PublicID,
					       const XMLString& SystemID);

  //! Adds a parameter xml entity stream
  XMLEntityStream* addParameterXMLEntityStream(
					       const XMLString& name,
					       const XMLString& EntityLiteral);

  //! Adds a general xml entity stream
  XMLEntityStream* addGeneralXMLEntityStream(
					     const XMLString& name,
					     const XMLString& EntityLiteral);

  //! Adds a general xml entity stream
  XMLEntityStream* addGeneralXMLEntityStream(
					     const XMLString& name,
					     const XMLString& PublicID,
					     const XMLString& SystemID);

  //! Adds an unparsed xml entity stream
  XMLEntityStream* addUnparsedXMLEntityStream(
					      const XMLString& name,
					      const XMLString& PublicID,
					      const XMLString& SystemID,
					      const XMLString& NotationName);

  //! Gets an xml entity stream
  XMLEntityStream* getXMLEntityStream(
				      const XMLString& getName,
				      const XMLEntityStreamType& ofEntityType);

  //! Prints the stream tree
  void printStreamTree(
		       unsigned long level) const;

protected:

  char errormessage[1024];       //!< Stores the error message
  XMLParser *const myXMLParser;  //!< Declares the xml parser object
  const XMLString myName;        //!< Declares the xml string name
  XMLString myTextString;        //!< Declares the text string
  bool myTextStringValid;        //!< Indicates if the text is valid

  //! Gets the xml entity stream tree walk down
  XMLEntityStream* getXMLEntityStreamTreeWalkDown(
						  const XMLString& name,
						  const XMLEntityStreamType& ofEntityType);

  //! Loads an external text string
  void loadExternalTextString();

  //! Makes a text string
  void virtual makeTextString() = 0;

private :

  XMLEntityStream *const myParentXMLEntityStream;  //!< Undocumented
  const XMLString mySystemID;                      //!< Undocumented

  list<XMLEntityStream*> myXMLEntityStreamList;    //!< Undocumented
};

// ******************************************************************************
// ******************************************************************************
//	RootXMLEntityStream
// ******************************************************************************
// ******************************************************************************

//! RootXMLEntityStream class
class RootXMLEntityStream: public XMLEntityStream {

public:

  //! Constructor of RootXMLEntityStream object
  RootXMLEntityStream(
		      XMLParser *const yourXMLParser,
		      const XMLString& yourSystemID);

  //! Returns the entity type of the xml entity stream
  XMLEntityStreamType entityType() const;

  //! Returns the entity location of the xml entity stream
  XMLEntityLocationType entityLocation() const;

  //! Returns the replacement text as an XMLString
  const XMLString* replacementText();

protected:

  //! Makes a text string
  void makeTextString();
};

// ******************************************************************************
// ******************************************************************************
//	GPXMLEntityStream
// ******************************************************************************
// ******************************************************************************

//! GPXMLEntityStream class
class GPXMLEntityStream: public XMLEntityStream {

public:

  //! Constructor for an internal entity
  //! Finally Greg has commented something!!
  GPXMLEntityStream(
		    XMLParser *const yourXMLParser,
		    XMLEntityStream *const yourParentXMLEntityStream,
		    const XMLString& yourName,
		    const XMLString& yourEntityLiteral);

  //! Constructor for an external entity
  //! Finally Greg has commented something!!
  GPXMLEntityStream(
		    XMLParser *const yourXMLParser,
		    XMLEntityStream *const yourParentXMLEntityStream,
		    const XMLString& yourName,
		    const XMLString& yourPublicID,
		    const XMLString& yourSystemID);

  //! Returns the entity location
  XMLEntityLocationType entityLocation() const;

  //! Returns the replacement text as an XMLString
  const XMLString* replacementText();

protected:

  //! Makes a text string
  void makeTextString();

private:

  const XMLString myPublicID;                     //!< The current public id of the entity
  const XMLString myEntityLiteral;                //!< The literal string of the entity
  const XMLEntityLocationType myEntityLocation;   //!< The entity location
};

// ******************************************************************************
// ******************************************************************************
//	ParameterXMLEntityStream
// ******************************************************************************
// ******************************************************************************

//! ParameterXMLEntityStream class
class ParameterXMLEntityStream: public GPXMLEntityStream {

public:

  //! Constructor for an internal entity
  //! Finally Greg has commented something!!
  ParameterXMLEntityStream(
			   XMLParser *const yourXMLParser,
			   XMLEntityStream *const yourParentXMLEntityStream,
			   const XMLString& yourName,
			   const XMLString& yourEntityLiteral);

  //! Constructor for an external entity
  //! Finally Greg has commented something!!
  ParameterXMLEntityStream(
			   XMLParser *const yourXMLParser,
			   XMLEntityStream *const yourParentXMLEntityStream,
			   const XMLString& yourName,
			   const XMLString& yourPublicID,
			   const XMLString& yourSystemID);

  //! Returns the entity type
  XMLEntityStreamType entityType() const;

};

// ******************************************************************************
// ******************************************************************************
//	GeneralXMLEntityStream
// ******************************************************************************
// ******************************************************************************

//! GeneralXMLEntityStream class
class GeneralXMLEntityStream: public GPXMLEntityStream {

public:

  //! Constructor for an internal entity
  //! Finally Greg has commented something!!
  GeneralXMLEntityStream(
			 XMLParser *const yourXMLParser,
			 XMLEntityStream *const yourParentXMLEntityStream,
			 const XMLString& yourName,
			 const XMLString& yourEntityLiteral);

  //! Constructor for an external entity
  //! Finally Greg has commented something!!
  GeneralXMLEntityStream(
			 XMLParser *const yourXMLParser,
			 XMLEntityStream *const yourParentXMLEntityStream,
			 const XMLString& yourName,
			 const XMLString& yourPublicID,
			 const XMLString& yourSystemID);

  //! Returns the entity type
  XMLEntityStreamType entityType() const;

};

// ******************************************************************************
// ******************************************************************************
//	UnparsedXMLEntityStream
// ******************************************************************************
// ******************************************************************************

//! UnparsedXMLEntityStream class
class UnparsedXMLEntityStream: public XMLEntityStream {

public:

  //! Constructor for an external entity
  //! Finally Greg has commented something!!
  UnparsedXMLEntityStream(
			  XMLParser *const yourXMLParser,
			  XMLEntityStream *const yourParentXMLEntityStream,
			  const XMLString& yourName,
			  const XMLString& yourPublicID,
			  const XMLString& yourSystemID,
			  const XMLString& yourNotationName);

  //! Returns the entity type
  XMLEntityStreamType entityType() const;

  //! Returns the entity location
  XMLEntityLocationType entityLocation() const;

  //! Returns the replacement text
  const XMLString* replacementText();

  // overrides of XMLEntityStream functions that
  // should never be called for this entity

  //! Determines if are at end of entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  bool atEnd() const;

  //! Adds a parameter xml entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  XMLEntityStream* addParameterXMLEntityStream(
					       const XMLString& name,
					       const XMLString& PublicID,
					       const XMLString& SystemID);

  //! Adds a parameter xml entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  XMLEntityStream* addParameterXMLEntityStream(
					       const XMLString& name,
					       const XMLString& EntityLiteral);

  //! Adds a general xml entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  XMLEntityStream* addGeneralXMLEntityStream(
					     const XMLString& name,
					     const XMLString& EntityLiteral);

  //! Adds a general xml entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  XMLEntityStream* addGeneralXMLEntityStream(
					     const XMLString& name,
					     const XMLString& PublicID,
					     const XMLString& SystemID,
					     const XMLString& NotationName);

  //! Adds an unparsed xml entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  XMLEntityStream* addUnparsedXMLEntityStream(
					      const XMLString& name,
					      const XMLString& PublicID,
					      const XMLString& SystemID,
					      const XMLString& NotationName);

  //! Gets an xml entity stream
  /*! Overrides of XMLEntityStream functions that
    should never be called for this entity
  */
  XMLEntityStream* getXMLEntityStream(
				      const XMLString& getName,
				      const XMLEntityStreamType& ofEntityType);

protected:

  //! Makes a text string
  void makeTextString();

private:

  const XMLString myPublicID;      //!< The public id of the entity
  const XMLString myNotationName;  //!< The notation name (of the entity?)
};

// ******************************************************************************
// ******************************************************************************
//	XMLParser
// ******************************************************************************
// ******************************************************************************

//! XMLParser class
class XMLParser {

public :

  //! An xml entity stream stack
  list<XMLEntityStream*> XMLEntityStreamStack;

  //! Constructor for XMLParser object
  XMLParser();

  //! Destructor
  ~XMLParser();

  //! Parses xml given fileName
  Document* parseFromFile(
			  const char* fileName);

  //! Returns xmds byte point (whatever that may mean)
  unsigned long xmdsBytePoint() const;

  //! Matches production 66 character reference (whatever that may mean)
  unsigned long matchProduction66CharRef(
					 XMLEntityStream *const thisStream,
					 //char& cRef) const;
					 signed char& cRef) const;
			
  //! Matches production 69 PE reference (whatever that may mean)
  unsigned long matchProduction69PEReference(
					     XMLEntityStream *const thisStream,
					     XMLString& PEName) const;

  //! Matches production 77 text declaration (whatever that may mean)
  void matchProduction77TextDecl(
				 XMLEntityStream *const thisStream,
				 XMLString& VersionNum,
				 XMLString& encoding);

private :

  KissDOMImplementation myDOMImplementation;  //!< Undocumented
  DocumentType* theDocumentType;              //!< Undocumented
  Document* theDocument;                      //!< Undocumented

  XMLEntityStream* rootXMLEntityStream;       //!< Undocumented
  XMLEntityStream* currentXMLEntityStream;    //!< Undocumented

  char errormessage[1024];                    //!< Undocumented
  unsigned long myxmdsBytePoint;              //!< Undocumented

  // stuff recovered from the XMLDecl routine 
  XMLString rootVersionNum;                   //!< Undocumented
  XMLString rootEncName;                      //!< Undocumented
  bool StandAlone;                            //!< Undocumented

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction01Document();

  //! Undocumented
  /*!
    @todo document this method
  */
  long matchProduction03S(
			  XMLEntityStream *const thisStream,
			  const bool required) const;

  //! Undocumented
  /*!
    @todo document this method
  */
  long matchProduction03SDeep(
			      const bool required);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction05Name(
			     XMLEntityStream *const thisStream,
			     XMLString& Name) const;

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction07Nmtoken(
				XMLEntityStream *const thisStream,
				XMLString& Nmtoken) const;

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction09EntityLiteral(
				      XMLString& EntityLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction10AttValue(
				 XMLString& AttValue);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction11SystemLiteral(
				      XMLString& SystemLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction12PubidLiteral(
				     XMLString& PubidLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction14CharData(
				 Element* containingElement);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction15Comment(
				Element* containingElement);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction16PI(
			   Element* containingElement);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction17PITarget(
				 XMLString& PITarget);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction18CDSect(
			       Element* containingElement);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction19CDStart();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction20CData(
			      XMLString& CData);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction21CDEnd();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction22Prolog();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction23XMLDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction24VersionInfo(
				    XMLEntityStream *const thisStream,
				    XMLString& VersionNum);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction25Eq(
			   XMLEntityStream *const thisStream);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction27Misc(
			     Element* containingElement);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction28doctypedecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction28aDeclSep();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction29markupdecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction31extSubsetDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction32SDDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction39Element(
				Element* containingElement);
  
  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction40STag(
			     XMLString* tagName,
			     list<XMLString>* myAttributeNamesList,
			     list<XMLString>* myAttributeValuesList);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction41Attribute(
				  XMLString& AttName,
				  XMLString& AttValue);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction42ETag(
			     XMLString& RequiredName);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction43content(
				Element* containingElement);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction44EmptyElementTag(
					XMLString* tagName,
					list<XMLString>* myAttributeNamesList,
					list<XMLString>* myAttributeValuesList);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction45elementdecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction46contentspec();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction47children();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction48cp();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction49choice();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction50seq();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction51Mixed();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction52AttlistDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction53AttDef();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction54AttType();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction55StringType();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction56TokenizedType();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction57EnumeratedType();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction58NotationType();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction59Enumeration();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction60DefaultDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction61conditionalSect();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction62includeSect();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction63ignoreSect();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction64ignoreSectContents();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction65ignore();

  //! Undocumented
  /*!
    @todo document this method
  */
  unsigned long matchProduction68EntityRef(
					   XMLEntityStream *const thisStream,
					   XMLString& refName) const;

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction70EntityDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction71GEDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction72PEDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction73EntityDef(
				  XMLString& PubidLiteral,
				  XMLString& SystemLiteral,
				  XMLString& NotationName,
				  XMLString& EntityLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction74PEDef(
			      XMLString& PubidLiteral,
			      XMLString& SystemLiteral,
			      XMLString& EntityLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction75ExternalID(
				   XMLString& PubidLiteral,
				   XMLString& SystemLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction76NDataDecl(
				  XMLString& NotationName);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction80EncodingDecl(
				     XMLEntityStream *const thisStream,
				     XMLString& EncName);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProduction81EncName(
				XMLEntityStream *const thisStream,
				XMLString& EncName);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction82NotationDecl();

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProduction83PublicID(
				 XMLString& PubidLiteral);

  //! Undocumented
  /*!
    @todo document this method
  */
  long howFarTo(
		const char* pattern);

  //! Undocumented
  /*!
    @todo document this method
  */
  bool matchProductionFixedString(
				  XMLEntityStream *const thisStream,
				  const char* pattern);

  //! Undocumented
  /*!
    @todo document this method
  */
  void matchProductionQuotedString(
				   XMLEntityStream *const thisStream,
				   XMLString& quotedString) const;

  //! Undocumented
  /*!
    @todo document this method
  */
  unsigned long sweepContent(
			     char* s);

  //! Undocumented
  /*!
    @todo document this method
  */
  unsigned long sweepAttValue(
			      char* s);

  //! Undocumented
  /*!
    @todo document this method
  */
  void loadNChar(
		 XMLEntityStream *const thisStream,
		 XMLString& outString,
		 const unsigned long& length) const;

  //! Undocumented
  /*!
    @todo document this method
  */
  void storeStreamPos(
		      list<XMLEntityStream*>& lastXMLEntityStreamStack,
		      list<StreamPositionStruct>& StreamPositionStructList);

  //! Undocumented
  /*!
    @todo document this method
  */
  void restoreStreamPos(
			const list<XMLEntityStream*>& lastXMLEntityStreamStack,
			const list<StreamPositionStruct>& andTheirPositions);

  //! Undocumented
  /*!
    @todo document this method
  */
  void printEntityStreamStack() const;
};

#define XMLPARSER  //!< Undocumented


syntax highlighted by Code2HTML, v. 0.9.1