/*************************************************************************
Copyright © 1999-2002 Novell, Inc. All Rights Reserved. 

THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND 
TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE
AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS
THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS
TO DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S
SAMPLE CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION
RIGHTS TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT
OF DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR
DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE.

***************************************************************************/
/*******************************************************************
* Name: sax.h
* Description: define a C/C++ interface for the Simple API for XML
* functionality (SAX)
* Tabs: 4
*******************************************************************/
#ifndef _SAX_H_
#define	_SAX_H_

#include	"define_interface.h"

/*
	This is a C/C++ definition of The Simple API for XML (SAX) event
	interface for receiving information about XML documents

	See http://www.megginson.com/SAX/index.html for	additional documentation.

	Note that there is not a publicly-available binding for SAX to C or
	C++, so this probably won't interoperate with anyone other than
	DirXML's implementation.

	Because this must support C as well as C++ exceptions are not enabled
	by default. Instead, various methods return a pointer to a SAXException
	interface. If the method returns null, there was no error.

	The interfaces Parser, DocumentHandler, and DTDHandler have a method 
	called enableExceptions(). Passing a non-zero value to this should enable
	exceptions if the interface is implemented in C++. If the interface is 
	implemented in C, this will have no effect. The return from enableExceptions()
	will be the exception-enabled state. Therefore, if calling enableExceptions()
	with a non-zero value returns 0, exceptions are not available.

	In addition, because C does not allow the overloading of functions
	methods that are overloaded in the Java version of SAX have been
	given slightly different names in the C interface (they are the same in C++).

	Note that the interface and method names otherwise follow the Java-binding
	names exactly.

	For C++, the interfaces are in the namespace "SAX"
*/

//define a 16-bit unicode character (we can't use wchar_t because wchar_t
//is 32-bits on Solaris)
typedef unsigned short unicode;

#if	defined(__cplusplus)
namespace SAX
{
#endif

INTERFACE_FWD_DECL(AttributeList);
INTERFACE_FWD_DECL(DocumentHandler);
INTERFACE_FWD_DECL(DTDHandler);
INTERFACE_FWD_DECL(EntityResolver);
INTERFACE_FWD_DECL(ErrorHandler);
INTERFACE_FWD_DECL(InputSource);
INTERFACE_FWD_DECL(Locator);
INTERFACE_FWD_DECL(Parser);
INTERFACE_FWD_DECL(SAXException);
INTERFACE_FWD_DECL(SAXParseException);

//++
/*****************************************************************
Interface: AttributeList
Desc:
	From the Java interface (with modifications):

	Interface for an element's attribute specifications.

	<p>The SAX parser implements this interface and passes an instance
	to the SAX application as the second argument of each startElement
	event.</p>

	<p>The instance provided will return valid results only during the
	scope of the startElement invocation (to save it for future
	use, the application must make a copy: the AttributeListImpl
	helper class provides a convenient constructor for doing so).</p>

	<p>An AttributeList includes only attributes that have been
	specified or defaulted: #IMPLIED attributes will not be included.</p>

	<p>There are two ways for the SAX application to obtain information
	from the AttributeList.  First, it can iterate through the entire
	list:</p>

	<pre>
	SAXException * startElement (const unicode * name, AttributeList * atts) {
	for (int i = 0; i < atts->getLength(); i++) {
	  const unicode * name = atts->getName(i);
	  const unicode * type = atts->getType(i);
	  const unicode * value = atts->getValue(i);
	  [...]
	}
	}
	</pre>
	*
	<p>(Note that the result of getLength() will be zero if there
	are no attributes.)
	*
	<p>As an alternative, the application can request the value or
	type of specific attributes:</p>
	*
	<pre>
	SAXException * startElement (const unicode * name, AttributeList * atts) {
	const unicode * identifier = atts->getValue(L"id");
	const unicode * label = atts->getValue(L"label");
	[...]
	}
	</pre>

Notes: 
	DirXML provides an implementation of AttributeList via the
	C++ class AttributeListImpl. There are also C methods to
	allocated and use an AttributeListImpl.
*****************************************************************/
INTERFACE(AttributeList)
//--

	//++
	//=========================================================================
	// Method:	getLength
	// Desc:	Return the number of attributes in the list. This may be zero.
	// 
	// Notes:	
	//=========================================================================
	METHOD(AttributeList, getLength, int)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getName
	// Desc:	Return the name of an attribute in this list by position. This
	//			will return null if the specified index is out of range.
	// 
	// Notes:	
	//=========================================================================
	METHOD(AttributeList, getName, const unicode *)
		METHOD_PARM1(int i)			//0-based index of the attribute
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getType
	// Desc:	Return the type of an attribute in this list by	position. This
	//			will return null if the specified index is out of range.
	// 
	// Notes:	The attribute type is one of the strings "CDATA", "ID", "IDREF",
	//			"IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES" or "NOTATION"
	//			(always in upper case).
	//=========================================================================
	METHOD(AttributeList, getType, const unicode *)
		METHOD_PARM1(int i)			//0-based index of the attribute
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getValue
	// Desc:	Return the value of an attribute in this list by position. This
	//			will return null if the specified index is out of range.
	// 
	// Notes:	If the attribute value is a list of tokens (IDREFS, ENTITIES, or
	//			NMTOKENS), the tokens will be concatenated into a single string
	//			separated by whitespace.
	//=========================================================================
	METHOD(AttributeList, getValue, const unicode *)
		METHOD_PARM1(int i)			//0-based index of the attribute
	END_METHOD
	//--

#if defined(__cplusplus)
	//++
	//=========================================================================
	// Method:	getType
	// Desc:	Return the type of an attribute in list list by name. If the
	//			passed name doesn't match an attribute in the list null is
	//			returned.
	// 
	// Notes:	The attribute type is one of the strings "CDATA", "ID", "IDREF",
	//			"IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES" or "NOTATION"
	//			(always in upper case).
	//=========================================================================
	METHOD(AttributeList, getType, const unicode *)
		METHOD_PARM1(const unicode * name)	//name of attribute
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getValue
	// Desc:	Return the value of an attribute in list list by name. If the
	//			passed name doesn't match an attribute in the list null is
	//			returned.
	// 
	// Notes:	If the attribute value is a list of tokens (IDREFS, ENTITIES, or
	//			NMTOKENS), the tokens will be concatenated into a single string
	//			separated by whitespace.
	//=========================================================================
	METHOD(AttributeList, getValue, const unicode *)
		METHOD_PARM1(const unicode * name)	//name of attribute
	END_METHOD
	//--
#else
	//++
	//=========================================================================
	// Method:	getTypeN
	// Desc:	Return the type of an attribute in list list by name. If the
	//			passed name doesn't match an attribute in the list null is
	//			returned.
	// 
	// Notes:	The attribute type is one of the strings "CDATA", "ID", "IDREF",
	//			"IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES" or "NOTATION"
	//			(always in upper case).
	//
	//			This method by this name exists only in C.
	//=========================================================================
	METHOD(AttributeList, getTypeN, const unicode *)
		METHOD_PARM1(const unicode * name)	//name of attribute
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getValueN
	// Desc:	Return the value of an attribute in list list by name. If the
	//			passed name doesn't match an attribute in the list null is
	//			returned.
	// 
	// Notes:	If the attribute value is a list of tokens (IDREFS, ENTITIES, or
	//			NMTOKENS), the tokens will be concatenated into a single string
	//			separated by whitespace.
	//
	//			This method by this name exists only in C.
	//=========================================================================
	METHOD(AttributeList, getValueN, const unicode *)
		METHOD_PARM1(const unicode * name)	//name of attribute
	END_METHOD
	//--
#endif

END_INTERFACE(AttributeList)

//++
/*****************************************************************
Interface: DocumentHandler
Desc:
	From the Java interface:

	Receive notification of general document events.
	*
	<p>This is the main interface that most SAX applications
	implement: if the application needs to be informed of basic parsing 
	events, it implements this interface and registers an instance with 
	the SAX parser using the setDocumentHandler method.  The parser 
	uses the instance to report basic document-related events like
	the start and end of elements and character data.</p>
	*
	<p>The order of events in this interface is very important, and
	mirrors the order of information in the document itself.  For
	example, all of an element's content (character data, processing
	instructions, and/or subelements) will appear, in order, between
	the startElement event and the corresponding endElement event.</p>
	*
	<p>Application writers who do not want to implement the entire
	interface can derive a class from HandlerBase, which implements
	the default functionality; parser writers can instantiate
	HandlerBase to obtain a default handler.  The application can find
	the location of any document event using the Locator interface
	supplied by the Parser through the setDocumentLocator method.</p>

Notes: 
	The specification extends the Java org.xml.sax.DocumentHandler
	with the following methods:

		SAXException * comment(const unicode * data);
		int enableExceptions(int enable);

*****************************************************************/
INTERFACE(DocumentHandler)
//--

	//++
	//=========================================================================
	// Method:	setDocumentLocator
	// Desc:	Receive an object for locating the origin of SAX document
	//			events.
	// 
	// Notes:	From the Java implementation:	
	//			SAX parsers are strongly encouraged (though not absolutely
	//			required) to supply a locator: if it does so, it must supply
	//			the locator to the application by invoking this method before
	//			invoking any of the other methods in the DocumentHandler
	//			interface.
	//
	//			The locator allows the application to determine the end
	//			position of any document-related event, even if the parser is
	//			not reporting an error.  Typically, the application will
	//			use this information for reporting its own errors (such as
	//			character content that does not match an application's
	//			business rules).  The information returned by the locator
	//			is probably not sufficient for use with a search engine.
	//
	//			Note that the locator will return correct information only
	//			during the invocation of the events in this interface.  The
	//			application should not attempt to use it at any other time.
	//=========================================================================
	METHOD(DocumentHandler, setDocumentLocator, void)
		METHOD_PARM1(Locator * locator)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	startDocument
	// Desc:	Receive notification of the beginning of a document.
	// 
	// Notes:	From the Java implementation:
	//			The SAX parser will invoke this method only once, before any
	//			other methods in this interface or in DTDHandler (except for
	//			setDocumentLocator).
	//=========================================================================
	METHOD(DocumentHandler, startDocument, SAXException *)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	endDocument
	// Desc:	Receive notification of the end of a document.
	// 
	// Notes:	From the Java implementation:
	//			The SAX parser will invoke this method only once, and it will
	//			be the last method invoked during the parse.  The parser shall
	//			not invoke this method until it has either abandoned parsing
	//			(because of an unrecoverable error) or reached the end of
	//			input.
	//=========================================================================
	METHOD(DocumentHandler, endDocument, SAXException *)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	startElement
	// Desc:	Receive notification of the beginning of an element.
	// 
	// Notes:	From the Java implementation:
	//			The Parser will invoke this method at the beginning of every
	//			element in the XML document; there will be a corresponding
	//			endElement() event for every startElement() event (even when the
	//			element is empty). All of the element's content will be
	//			reported, in order, before the corresponding endElement()
	//			event.
	//
	//			If the element name has a namespace prefix, the prefix will
	//			still be attached.  Note that the attribute list provided will
	//			contain only attributes with explicit values (specified or
	//			defaulted): #IMPLIED attributes will be omitted.
	//=========================================================================
	METHOD(DocumentHandler, startElement, SAXException *)
		METHOD_PARM1(const unicode * name)
		METHOD_PARM(AttributeList * atts)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	endElement
	// Desc:	Receive notification of the end of an element.
	// 
	// Notes:	From the Java implementation:
	//			The SAX parser will invoke this method at the end of every
	//			element in the XML document; there will be a corresponding
	//			startElement() event for every endElement() event (even when the
	//			element is empty).
	//
	//			If the element name has a namespace prefix, the prefix will
	//			still be attached to the name.
	//=========================================================================
	METHOD(DocumentHandler, endElement, SAXException *)
		METHOD_PARM1(const unicode * name)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	characters
	// Desc:	Receive notification of character data.
	// 
	// Notes:	From the Java implementation:
	//			The Parser will call this method to report each chunk of
	//			character data.  SAX parsers may return all contiguous character
	//			data in a single chunk, or they may split it into several
	//			chunks; however, all of the characters in any single event
	//			must come from the same external entity, so that the Locator
	//			provides useful information.
	//
	//			The application must not attempt to read from the array
	//			outside of the specified range.
	//
	//			Note that some parsers will report whitespace using the
	//			ignorableWhitespace() method rather than this one (validating
	//			parsers must do so).
	//=========================================================================
	METHOD(DocumentHandler, characters, SAXException *)
		METHOD_PARM1(const unicode ch[])
		METHOD_PARM(int start)
		METHOD_PARM(int length)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	ignorableWhitespace
	// Desc:	Receive notification of ignorable whitespace in element content.
	// 
	// Notes:	From the Java implementation:
	//			Validating Parsers must use this method to report each chunk
	//			of ignorable whitespace (see the W3C XML 1.0 recommendation,
	//			section 2.10): non-validating parsers may also use this method
	//			if they are capable of parsing and using content models.</p>
	//
	//			SAX parsers may return all contiguous whitespace in a single
	//			chunk, or they may split it into several chunks; however, all of
	//			the characters in any single event must come from the same
	//			external entity, so that the Locator provides useful
	//			information.
	//
	//			The application must not attempt to read from the array
	//			outside of the specified range.
	//=========================================================================
	METHOD(DocumentHandler, ignorableWhitespace, SAXException *)
		METHOD_PARM1(const unicode ch[])
		METHOD_PARM(int start)
		METHOD_PARM(int length)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	processingInstruction
	// Desc:	Receive notification of a processing instruction.
	// 
	// Notes:	From the Java implementation:
	//			The Parser will invoke this method once for each processing
	//			instruction found: note that processing instructions may occur
	//			before or after the main document element.
	//
	//			A SAX parser should never report an XML declaration (XML 1.0,
	//			section 2.8) or a text declaration (XML 1.0, section 4.3.1)
	//			using this method.
	//=========================================================================
	METHOD(DocumentHandler, processingInstruction, SAXException *)
		METHOD_PARM1(const unicode * target)
		METHOD_PARM(const unicode * data)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	comment
	// Desc:	Receive notification of a comment.
	// 
	// Notes:	The parser will invoke this methos once for each comment found.
	//			This method doesn not exist in the Java interface.
	//=========================================================================
	METHOD(DocumentHandler, comment, SAXException *)
		METHOD_PARM1(const unicode * data)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	enableExceptions
	// Desc:	Enable the throwing of C++ exceptions for all methods in this
	//			interface.
	// 
	// Notes:	C++ extension
	//			A C implementation will not support this and will
	//			always return 0, indicating exceptions are not supported.
	//=========================================================================
	METHOD(DocumentHandler, enableExceptions, int)
		METHOD_PARM1(int enable)
	END_METHOD
	//--

END_INTERFACE(DocumentHandler)

//++
/*****************************************************************
Interface: DTDHandler
Desc:
	From the Java interface:

	Receive notification of basic DTD-related events.

	<p>If a SAX application needs information about notations and
	unparsed entities, then the application implements this 
	interface and registers an instance with the SAX parser using 
	the parser's setDTDHandler method.  The parser uses the 
	instance to report notation and unparsed entity declarations to 
	the application.</p>

	<p>The SAX parser may report these events in any order, regardless
	of the order in which the notations and unparsed entities were
	declared; however, all DTD events must be reported after the
	document handler's startDocument event, and before the first
	startElement event.</p>

	<p>It is up to the application to store the information for 
	future use (perhaps in a hash table or object tree).
	If the application encounters attributes of type "NOTATION",
	"ENTITY", or "ENTITIES", it can use the information that it
	obtained through this interface to find the entity and/or
	notation corresponding with the attribute value.</p>

Notes: 
	The specification extends the Java org.xml.sax.DTDHandler
	with the following methods:

		int enableExceptions(int enable);
*****************************************************************/
INTERFACE(DTDHandler)
//--

	//++
	//=========================================================================
	// Method:	notationDecl
	// Desc:	Receive notification of a notation declaration event.
	// 
	// Notes:	From the Java implementation:
	//			<p>It is up to the application to record the notation for later
	//			reference, if necessary.</p>
	//
	//			<p>If a system identifier is present, and it is a URL, the SAX
	//			parser must resolve it fully before passing it to the
	//			application.</p>
	//=========================================================================
	METHOD(DTDHandler, notationDecl, SAXException *)
		METHOD_PARM1(const unicode * name)
		METHOD_PARM(const unicode * publicId)
		METHOD_PARM(const unicode * systemId)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	unparsedEntityDecl
	// Desc:	Receive notification of an unparsed entity declaration event.
	// 
	// Notes:	From the Java implementation:
	//			<p>Note that the notation name corresponds to a notation
	//			reported by the notationDecl() event.  It is up to the
	//			application to record the entity for later reference, if
	//			necessary.</p>
	//
	//			<p>If the system identifier is a URL, the parser must resolve it
	//			fully before passing it to the application.</p>
	//=========================================================================
	METHOD(DTDHandler, unparsedEntityDecl, SAXException *)
		METHOD_PARM1(const unicode * name)
		METHOD_PARM(const unicode * publicId)
		METHOD_PARM(const unicode * systemId)
		METHOD_PARM(const unicode * notationName)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	enableExceptions
	// Desc:	Enable the throwing of C++ exceptions for all methods in this
	//			interface.
	// 
	// Notes:	C++ extension
	//			A C implementation will not support this and will
	//			always return 0, indicating exceptions are not supported.
	//=========================================================================
	METHOD(DTDHandler, enableExceptions, int)
		METHOD_PARM1(int enable)
	END_METHOD
	//--

END_INTERFACE(DTDHandler)

//++
/*****************************************************************
Interface: EntityResolver
Desc:
	From the Java interface:

	<p>If a SAX application needs to implement customized handling
	for external entities, it must implement this interface and
	register an instance with the SAX parser using the parser's
	setEntityResolver method.</p>

	<p>The parser will then allow the application to intercept any
	external entities (including the external DTD subset and external
	parameter entities, if any) before including them.</p>

	<p>Many SAX applications will not need to implement this interface,
	but it will be especially useful for applications that build
	XML documents from databases or other specialised input sources,
	or for applications that use URI types other than URLs.</p>

Notes: 
*****************************************************************/
INTERFACE(EntityResolver)
//--

	//++
	//=========================================================================
	// Method:	resolveEntity
	// Desc:	Allow the application to resolve external entities.
	// 
	// Notes:	From the Java implementation:
	//			<p>The Parser will call this method before opening any external
	//			entity except the top-level document entity (including the
	//			external DTD subset, external entities referenced within the
	//			DTD, and external entities referenced within the document
	//			element): the application may request that the parser resolve
	//			the entity itself, that it use an alternative URI, or that it
	//			use an entirely different input source.</p>
	//
	//			<p>Application writers can use this method to redirect external
	//			system identifiers to secure and/or local URIs, to look up
	//			public identifiers in a catalogue, or to read an entity from a
	//			database or other input source (including, for example, a dialog
	//			box).</p>
	//
	//			<p>If the system identifier is a URL, the SAX parser must
	//			resolve it fully before reporting it to the application.</p>
	//=========================================================================
	METHOD(EntityResolver, resolveEntity, InputSource *)
		METHOD_PARM1(const unicode * publicId)
		METHOD_PARM(const unicode * systemId)
	END_METHOD
	//--

END_INTERFACE(EntityResolver)

//++
/*****************************************************************
Interface: ErrorHandler
Desc:
	From the Java interface:

	Basic interface for SAX error handlers.

	<p>If a SAX application needs to implement customized error
	handling, it must implement this interface and then register an
	instance with the SAX parser using the parser's setErrorHandler
	method.  The parser will then report all errors and warnings
	through this interface.</p>

	<p> The parser shall use this interface instead of throwing an
	exception: it is up to the application whether to throw an
	exception for different types of errors and warnings.  Note,
	however, that there is no requirement that the parser continue to
	provide useful information after a call to fatalError (in other
	words, a SAX driver class could catch an exception and report a
	fatalError).</p>

Notes: 
*****************************************************************/
//--
INTERFACE(ErrorHandler)

	//++
	//=========================================================================
	// Method:	warning
	// Desc:	Receive notification of a warning.
	// 
	// Notes:	From the Java implementation:
	//			<p>SAX parsers will use this method to report conditions that
	//			are not errors or fatal errors as defined by the XML 1.0
	//			recommendation.  The default behaviour is to take no action.</p>
	//
	//			<p>The SAX parser must continue to provide normal parsing events
	//			after invoking this method: it should still be possible for the
	//			application to process the document through to the end.</p>
	//=========================================================================
	METHOD(ErrorHandler, warning, void)
		METHOD_PARM1(SAXParseException * exception)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	error
	// Desc:	Receive notification of a recoverable error.
	// 
	// Notes:	From the Java implementation:
	//			<p>This corresponds to the definition of "error" in section 1.2
	//			of the W3C XML 1.0 Recommendation.  For example, a validating
	//			parser would use this callback to report the violation of a
	//			validity constraint.  The default behaviour is to take no
	//			action.</p>
	//
	//			<p>The SAX parser must continue to provide normal parsing events
	//			after invoking this method: it should still be possible for the
	//			application to process the document through to the end.  If the
	//			application cannot do so, then the parser should report a fatal
	//			error even if the XML 1.0 recommendation does not require it to
	//			do so.</p>
	//=========================================================================
	METHOD(ErrorHandler, error, void)
		METHOD_PARM1(SAXParseException * exception)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	fatalError	
	// Desc:	Receive notification of a non-recoverable error.
	// 
	// Notes:	From the Java implementation:
	//			<p>This corresponds to the definition of "fatal error" in
	//			section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
	//			parser would use this callback to report the violation of a
	//			well-formedness constraint.</p>
	//
	//			<p>The application must assume that the document is unusable
	//			after the parser has invoked this method, and should continue
	//			(if at all) only for the sake of collecting addition error
	//			messages: in fact, SAX parsers are free to stop reporting any
	//			other events once this method has been invoked.</p>
	//=========================================================================
	METHOD(ErrorHandler, fatalError, void)
		METHOD_PARM1(SAXParseException * exception)
	END_METHOD
	//--

END_INTERFACE(ErrorHandler)

//++
/*****************************************************************
Interface: Locator
Desc:
	From the Java interface:

	Interface for associating a SAX event with a document location.

	<p>If a SAX parser provides location information to the SAX
	application, it does so by implementing this interface and then
	passing an instance to the application using the document
	handler's setDocumentLocator method.  The application can use the
	object to obtain the location of any other document handler event
	in the XML source document.</p>

	<p>Note that the results returned by the object will be valid only
	during the scope of each document handler method: the application
	will receive unpredictable results if it attempts to use the
	locator at any other time.</p>

	<p>SAX parsers are not required to supply a locator, but they are
	very strong encouraged to do so.  If the parser supplies a
	locator, it must do so before reporting any other document events.
	If no locator has been set by the time the application receives
	the startDocument event, the application should assume that a
	locator is not available.</p>

Notes: 
	The specification extends the Java org.xml.sax.Locator
	with the following methods:

		//destroy is required so that SAXParseException implementations
		//can destroy the Locator object that they may have
		void destroy();

*****************************************************************/
//--
INTERFACE(Locator)

	//++
	//=========================================================================
	// Method:	getPublicId
	// Desc:	Return the public identifier for the current document event.
	//			Return is null if no public identifier is available.
	// 
	// Notes:
	//=========================================================================
	METHOD(Locator, getPublicId, const unicode *)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getSystemId	
	// Desc:	Return the system identifier for the current document event.
	//			Return is null if no public identifier is available.
	// 
	// Notes:	From the Java implementation:
	//			<p>If the system identifier is a URL, the parser must resolve it
	//			fully before passing it to the application.</p>
	//=========================================================================
	METHOD(Locator, getSystemId, const unicode *)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getLineNumber
	// Desc:	Return the line number where the current document event ends.
	//			Return -1 if none is available.
	// 
	// Notes:	From the Java implementation:
    //			Note that this is the line position of the first character
    //			after the text associated with the document event.
	//=========================================================================
	METHOD(Locator, getLineNumber, int)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getColumnNumber
	// Desc:	Return the column number where the current document event ends.
	//			Return -1 if none is available.
	// 
	// Notes:	From the Java implementation:
	//			Note that this is the column number of the first
	//			character after the text associated with the document
	//			event.  The first column in a line is position 1.
	//=========================================================================
	METHOD(Locator, getColumnNumber, int)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	destroy
	// Desc:	Destroy this locator object.
	// 
	// Notes:	This must not be called by an application. This must only be
	//			called by an implementation of SAXParseException.
	//=========================================================================
	METHOD(Locator, destroy, void)
	END_METHOD
	//--

END_INTERFACE(Locator)

//++
/*****************************************************************
Interface: Parser
Desc:
	From the Java interface:

	Basic interface for SAX (Simple API for XML) parsers.

	<p>All SAX parsers must implement this basic interface: it allows
	applications to register handlers for different types of events
	and to initiate a parse from a URI, or a character stream.</p>

	<p>All SAX parsers must also implement a zero-argument constructor
	(though other constructors are also allowed).</p>

	<p>SAX parsers are reusable but not re-entrant: the application
	may reuse a parser object (possibly with a different input source)
	once the first parse has completed successfully, but it may not
	invoke the parse() methods recursively within a parse.</p>

Notes: 
	The SAX Parser interface is useful for any reporting of XML
	structure events. For example, converting a DOM tree to a 
	series of SAX events is one use.

	The specification extends the Java org.xml.sax.DocumentHandler
	with the following methods:

		int enableExceptions(int enable);
*****************************************************************/
//--
INTERFACE(Parser)

	//++
	//=========================================================================
	// Method:	setLocale
	// Desc:	Allow an application to request a locale for errors and warnings.
	// 
	// Notes:	From the Java implementation:
	//			<p>SAX parsers are not required to provide localisation for errors
	//			and warnings; if they cannot support the requested locale,
	//			however, they must throw a SAX exception.  Applications may
	//			not request a locale change in the middle of a parse.</p>
	//=========================================================================
	METHOD(Parser, setLocale, SAXException *)
		METHOD_PARM1(const unicode * locale)	//A standard locale string
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	setEntityResolver
	// Desc:	Allow an application to register a custom entity resolver.
	// 
	// Notes:	From the Java implementation:
	//			<p>If the application does not register an entity resolver, the
	//			SAX parser will resolve system identifiers and open connections
	//			to entities itself (this is the default behaviour implemented in
	//			HandlerBase).</p>
	//
	//			<p>Applications may register a new or different entity resolver
	//			in the middle of a parse, and the SAX parser must begin using
	//			the new resolver immediately.</p>
	//=========================================================================
	METHOD(Parser, setEntityResolver, void)
		METHOD_PARM1(EntityResolver * resolver)	//The application's EntityResolver
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	setDTDHandler
	// Desc:	Allow an application to register a DTD event handler.
	// 
	// Notes:	From the Java implementation:
	//			<p>If the application does not register a DTD handler, all DTD
	//			events reported by the SAX parser will be silently
	//			ignored (this is the default behaviour implemented by
	//			HandlerBase).</p>
	//
	//			<p>Applications may register a new or different
	//			handler in the middle of a parse, and the SAX parser must
	//			begin using the new handler immediately.</p>
	//=========================================================================
	METHOD(Parser, setDTDHandler, void)
		METHOD_PARM1(DTDHandler * handler)		//The application's DTDHandler
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	setDocumentHandler
	// Desc:	Allow an application to register a document event handler.
	// 
	// Notes:	From the Java implementation:
	//			<p>If the application does not register a document handler, all
	//			document events reported by the SAX parser will be silently
	//			ignored (this is the default behaviour implemented by
	//			HandlerBase).</p>
	//
	//			<p>Applications may register a new or different handler in the
	//			middle of a parse, and the SAX parser must begin using the new
	//			handler immediately.</p>
	//=========================================================================
	METHOD(Parser, setDocumentHandler, void)
		METHOD_PARM1(DocumentHandler * handler)	//The application's DocumentHandler
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	setErrorHandler
	// Desc:	Allow an application to register an error event handler.
	// 
	// Notes:	From the Java implementation:
	//			<p>If the application does not register an error event handler,
	//			all error events reported by the SAX parser will be silently
	//			ignored, except for fatalError, which will throw a SAXException
	//			(this is the default behaviour implemented by HandlerBase).</p>
	//
	//			<p>Applications may register a new or different handler in the
	//			middle of a parse, and the SAX parser must begin using the new
	//			handler immediately.</p>
	//=========================================================================
	METHOD(Parser, setErrorHandler, void)
		METHOD_PARM1(ErrorHandler * handler)
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	parse
	// Desc:	Parse an XML document.
	// 
	// Notes:	From the Java implementation:
	//			<p>The application can use this method to instruct the SAX parser
	//			to begin parsing an XML document from any valid input
	//			source (a character stream, a byte stream, or a URI).</p>
	//
	//			<p>Applications may not invoke this method while a parse is in
	//			progress (they should create a new Parser instead for each
	//			additional XML document).  Once a parse is complete, an
	//			application may reuse the same Parser object, possibly with a
	//			different input source.</p>
	//
	//			Note that other objects than "parsers" may implement this 
	//			interface. For example, to convert a DOM tree to SAX events
	//			a converter might implement this interface and ignore the
	//			InputSource argument.
	//=========================================================================
	METHOD(Parser, parse, SAXException *)
		METHOD_PARM1(InputSource * inputSource)	//The input source for the top level of the XML document
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	enableExceptions
	// Desc:	Enable the throwing of C++ exceptions for all methods in this
	//			interface.
	// 
	// Notes:	C++ extension
	//			A C implementation will not support this and will
	//			always return 0, indicating exceptions are not supported.
	//=========================================================================
	METHOD(Parser, enableExceptions, int)
		METHOD_PARM1(int enable)
	END_METHOD
	//--

END_INTERFACE(Parser)

//++
/*****************************************************************
Interface: InputSource
Desc:
	From the Java interface:

	A single input source for an XML entity.

	<p>This class allows a SAX application to encapsulate information
	about an input source in a single object, which may include
	a public identifier, a system identifier, a byte stream (possibly
	with a specified encoding), and/or a character stream.</p>

	<p>There are two places that the application will deliver this
	input source to the parser: as the argument to the Parser.parse
	method, or as the return value of the EntityResolver.resolveEntity
	method.</p>

	<p>An InputSource object belongs to the application: the SAX parser
	shall never modify it in any way (it may modify a copy if 
	necessary).</p>

Notes: 
	This interface diverges from the Java interface because of the
	lack of a common stream functionality in C/C++.

	The primary divergence is the method readByteChunk() which the
	SAX parser can call to read a chunk of the data stream at a 
	time.

	DirXML provides an implementation via the C++ InputSourceImpl class.

*****************************************************************/
//--
INTERFACE(InputSource)

	//++
	//=========================================================================
	// Method:	setPublicIdd
	// Desc:	Set the public identifier for this input source.
	// 
	// Notes:	From the Java implementation:
	//			<p>The public identifier is always optional: if the application
	//			writer includes one, it will be provided as part of the
	//			location information.</p>
	//=========================================================================
	METHOD(InputSource, setPublicId, void)
		METHOD_PARM1(const char * publicId)		//public id string
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getPublicId
	// Desc:	Get the public identifier for this input source. Return null
	//			if no public id was supplied.
	// 
	// Notes:
	//=========================================================================
	METHOD(InputSource, getPublicId, const char *)	//public id string or 0
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getSystemId
	// Desc:	Set the system identifier for this input source.
	// 
	// Notes:	From the Java implementation:
	//			<p>The system identifier is optional if there is a byte stream
	//			or a character stream, but it is still useful to provide one,
	//			since the application can use it to resolve relative URIs
	//			and can include it in error messages and warnings (the parser
	//			will attempt to open a connection to the URI only if
	//			there is no byte stream or character stream specified).</p>
	//
	//			<p>If the application knows the character encoding of the
	//			object pointed to by the system identifier, it can register
	//			the encoding using the setEncoding method.</p>
	//
	//			<p>If the system ID is a URL, it must be fully resolved.</p>
	//=========================================================================
	METHOD(InputSource, setSystemId, void)
		METHOD_PARM1(const char * systemId)	//system id string
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getSystemId
	// Desc:	Get the system identifier for this input source.
	// 
	// Notes:	From the Java implementation:
	//			<p>The getEncoding method will return the character encoding
	//			of the object pointed to, or null if unknown.</p>
	//
	//			<p>If the system ID is a URL, it will be fully resolved.</p>
	//=========================================================================
	METHOD(InputSource, getSystemId, const char *)	//system id string or 0
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	setByteStream
	// Desc:	Set the byte stream for this input source.
	// 
	// Notes:	From the Java implementation:
	//			<p>The SAX parser will ignore this if there is also a character
	//			stream specified, but it will use a byte stream in preference
	//			to opening a URI connection itself.</p>
	//
	//			<p>If the application knows the character encoding of the
	//			byte stream, it should set it with the setEncoding method.</p>
	//=========================================================================
	METHOD(InputSource, setByteStream, void)
		METHOD_PARM1(const unsigned char * byteStream)	//array of bytes
		METHOD_PARM(int length)							//length of array in bytes
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getByteStream
	// Desc:	Get the byte stream for this input source.
	// 
	// Notes:	From the Java implementation:
	//			<p>The getEncoding method will return the character
	//			encoding for this byte stream, or null if unknown.</p>
	//=========================================================================
	METHOD(InputSource, getByteStream, const unsigned char *)	//array of bytes or 0
		METHOD_PARM1(int * length)			//pointer to variable to receive length of array
	END_METHOD
	//--		

	//++
	//=========================================================================
	// Method:	setEncoding
	// Desc:	Set the character encoding, if known.
	// 
	// Notes:	From the Java implementation:
	//			<p>The encoding must be a string acceptable for an
	//			XML encoding declaration (see section 4.3.3 of the XML 1.0
	//			recommendation).</p>
	//
	//			<p>This method has no effect when the application provides a
	//			character stream.</p>
	//=========================================================================
	METHOD(InputSource, setEncoding, void)
		METHOD_PARM1(const unicode * encoding)	//encoding string
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getEncoding
	// Desc:	Get the character encoding for a byte stream or URI.
	// 
	// Notes:
	//=========================================================================
	METHOD(InputSource, getEncoding, const unicode *)//encoding string or 0
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	setCharacterStream
	// Desc:	Set the character stream for this input source.
	//
	// Notes:	From the Java implementation:
	//			<p>If there is a character stream specified, the SAX parser
	//			will ignore any byte stream and will not attempt to open
	//			a URI connection to the system identifier.</p>
	//=========================================================================
	METHOD(InputSource, setCharacterStream, void)
		METHOD_PARM1(const unicode * charStream)	//array of characters
		METHOD_PARM(int length)						//length of array in characters
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getCharacterStream
	// Desc:	Get the character stream for this input source.
	// 
	// Notes:
	//=========================================================================
	METHOD(InputSource, getCharacterStream, const unicode *)	//array or characters or 0
		METHOD_PARM1(int * length)				//pointer to variable to receive length of array
	END_METHOD
	//--

	//Extensions
	//++
	//=========================================================================
	// Method:	readByteChunk
	// Desc:	Return the number of bytes passed from the input
	//			source.
	// 
	// Notes:
	//			The passed buffer must be at least as large as the count 
	//			parameter.
	//
	//			When the return value is less than count, the source is
	//			exhausted.
	//=========================================================================
	METHOD(InputSource,readByteChunk,int)	//number of bytes actually returned
		METHOD_PARM1(int count)				//number of bytes to read
		METHOD_PARM(unsigned char * buffer)	//buffer for returned bytes
	END_METHOD
	//--

END_INTERFACE(InputSource)

//++
/*****************************************************************
Interface: SAXException
Desc:
	From the Java interface:

	Encapsulate a general SAX error or warning.

	<p>This class can contain basic error or warning information from
	either the XML parser or the application: a parser writer or
	application writer can subclass it to provide additional
	functionality.  SAX handlers may throw this exception or
	any exception subclassed from it.</p>

	<p>If the application needs to pass through other types of
	exceptions, it must wrap those exceptions in a SAXException
	or an exception derived from a SAXException.</p>

	<p>If the parser or application needs to include information about a
	specific location in an XML document, it should use the
	SAXParseException subclass.</p>

Notes: 
*****************************************************************/
//--
INTERFACE(SAXException)
	
	//++
	//=========================================================================
	// Method:	getMessage
	// Desc:	Return the text message associated with this exception (if any).
	// 
	// Notes:
	//=========================================================================
	METHOD(SAXException, getMessage, const unicode *)	//string or 0
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	destroy
	// Desc:	Destroy this SAXException
	// 
	// Notes:
	//=========================================================================
	METHOD(SAXException, destroy, void)
	END_METHOD
	//--

END_INTERFACE(SAXException)

//++
/*****************************************************************
Interface: SAXParseException
Desc:
	From the Java interface:

	Encapsulate an XML parse error or warning.

	<p>This exception will include information for locating the error
	in the original XML document.  Note that although the application
	will receive a SAXParseException as the argument to the handlers
	in the ErrorHandler interface, the application is not actually
	required to throw the exception; instead, it can simply read the
	information in it and take a different action.</p>

Notes: 
*****************************************************************/
//--
DERIVED_INTERFACE(SAXParseException,SAXException)
	
	//++
	//=========================================================================
	// Method:	setLocator
	// Desc:	Allow a Parser to set a Locator object with information on
	//			the exception.
	// 
	// Notes:	
	//=========================================================================
	METHOD(SAXParseException, setLocator, void)
		METHOD_PARM1(Locator * locator)			//Locator object
	END_METHOD
	//--

	//++
	//=========================================================================
	// Method:	getLocator
	// Desc:	Get the Locator (if any) set by the Parser.
	// 
	// Notes:	
	//=========================================================================
	METHOD(SAXParseException, getLocator, Locator *)	//Locator or 0
	END_METHOD
	//--

END_INTERFACE(SAXParseException)

#if defined(__cplusplus)
//close namespace SAX 
}
#endif

#if !defined(__cplusplus)
//C macros for calling methods

//AttributeList
#define AttributeList_getLength(_this)\
	(*_this->vTbl->getLength)(_this)

#define AttributeList_getName(_this,i)\
	(*_this->vTbl->getName)(_this,i)

#define AttributeList_getType(_this,i)\
	(*_this->vTbl->getType)(_this,i)

#define AttributeList_getValue(_this,i)\
	(*_this->vTbl->getValue)(_this,i)

#define AttributeList_getTypeN(_this,name)\
	(*_this->vTbl->getTypeN)(_this,name)

#define AttributeList_getValueN(_this,name)\
	(*_this->vTbl->getValueN)(_this,name)

//DocumentHandler
#define DocumentHandler_setDocumentLocator(_this,locator)\
	(*_this->vTbl->setDocumentLocator)(_this,locator)

#define DocumentHandler_startDocument(_this)\
	(*_this->vTbl->startDocument)(_this)

#define DocumentHandler_endDocument(_this)\
	(*_this->vTbl->endDocument)(_this)

#define DocumentHandler_startElement(_this,name,atts)\
	(*_this->vTbl->startElement)(_this,name,atts)

#define DocumentHandler_endElement(_this,name)\
	(*_this->vTbl->endElement)(_this,name)

#define DocumentHandler_characters(_this,ch,start,length)\
	(*_this->vTbl->characters)(_this,ch,start,length)

#define DocumentHandler_ignorableWhitespace(_this,ch,start,length)\
	(*_this->vTbl->ignorableWhitespace)(_this,ch,start,length)

#define DocumentHandler_processingInstruction(_this,target,data)\
	(*_this->vTbl->processingInstruction)(_this,target,data)

#define DocumentHandler_comment(_this,data)\
	(*_this->vTbl->comment)(_this,data)

//DTDHandler
#define DTDHandler_notationDecl(_this,name,publicId,systemId)\
	(*_this->vTbl->notationDecl)(_this,name,publicId,systemId)

#define DTDHandler_unparsedEntityDecl(_this,name,publicId,systemId,notationName)\
	(*_this->vTbl->unparsedEntityDecl)(_this,name,publicId,systemId,notationName)

//EntityResolver
#define EntityResolver_resolveEntity(_this,publicId,systemId)\
	(*_this->vTbl->resolveEntity)(_this,publicId,systemId)

//ErrorHandler
#define ErrorHandler_warning(_this,ex)\
	(*_this->vTbl->warning)(_this,ex)

#define ErrorHandler_error(_this,ex)\
	(*_this->vTbl->error)(_this,ex)

#define ErrorHandler_fatalError(_this,ex)\
	(*_this->vTbl->fatalError)(_this,ex)

//Locator
#define Locator_getPublicId(_this)\
	(*_this->vTbl->getPublicId)(_this)

#define Locator_getSystemId(_this)\
	(*_this->vTbl->getSystemId)(_this)

#define Locator_getLineNumber(_this)\
	(*_this->vTbl->getLineNumber)(_this)

#define Locator_getColumnNumber(_this)\
	(*_this->vTbl->getColumnNumber)(_this)

//Parser
#define Parser_setLocale(_this,locale)\
	(*_this->vTbl->setLocale)(_this,locale)

#define Parser_setEntityResolver(_this,resolver)\
	(*_this->vTbl->setEntityResolver)(_this,resolver)

#define Parser_setDTDHandler(_this,handler)\
	(*_this->vTbl->setDTDHandler)(_this,handler)

#define Parser_setDocumentHandler(_this,handler)\
	(*_this->vTbl->setDocumentHandler)(_this,handler)

#define Parser_setErrorHandler(_this,handler)\
	(*_this->vTbl->setErrorHandler)(_this,handler)

#define Parser_parse(_this,systemId)\
	(*_this->vTbl->parse)(_this,systemId)

//Locator
#define Locator_getPublicId(_this)\
	(*_this->vTbl->getPublicId)(_this)

#define Locator_getSystemId(_this)\
	(*_this->vTbl->getSystemId)(_this)

#define Locator_getLineNumber(_this)\
	(*_this->vTbl->getLineNumber)(_this)

#define Locator_getColumnNumber(_this)\
	(*_this->vTbl->getColumnNumber)(_this)

#define Locator_destroy(_this)\
	(*_this->vTbl->destroy)(_this)

//SAXException
#define SAXException_getMessage(_this)\
	(*_this->vTbl->getMessage)(_this)

#define SAXException_destroy(_this)\
	(*_this->vTbl->destroy)(_this)

//SAXParseException
//	SAXException-defined methods
#define SAXParseException_getMessage(_this)\
	(*((SAXException *)_this)->vTbl->getMessage)(_this)

#define SAXParseException_destroy(_this)\
	(*((SAXException *)_this)->vTbl->destroy)(_this)

//	SAXParseException-defined methods
#define SAXParseException_setLocator(_this,loc)\
	(_this->vTbl->setLocator)(_this,loc)

#define SAXParseException_getLocator(_this)\
	(_this->vTbl->getLocator)(_this)

//InputSource
#define	InputSource_setPublicId(_this,publicId)\
	(*_this->vTbl->setPublicId)(_this,publicId)

#define	InputSource_getPublicId(_this)\
	(*_this->vTbl->getPublicId)(_this)

#define	InputSource_setSystemId(_this,systemId)\
	(*_this->vTbl->setSystemId)(_this,systemId)

#define	InputSource_getSystemId(_this)\
	(*_this->vTbl->getSystemId)(_this)

#define	InputSource_setByteStream(_this,byteStream,length)\
	(*_this->vTbl->setByteStream)(_this,byteStream,length)

#define	InputSource_getByteStream(_this,length)\
	(*_this->vTbl->getByteStream)(_this,length)

#define	InputSource_setEncoding(_this,encoding)\
	(*_this->vTbl->setEncoding)(_this,encoding)

#define	InputSource_getEncoding(_this)\
	(*_this->vTbl->getEncoding)(_this)

#define	InputSource_setCharacterStream(_this,charStream,length)\
	(*_this->vTbl->setCharacterStream)(_this,charStream,length)

#define	InputSource_getCharacterStream(_this,length)\
	(*_this->vTbl->getCharacterStream)(_this,length)

#define	InputSource_readByteChunk(_this,count,buffer)\
	(*_this->vTbl->readByteChunk)(_this,count,buffer)

#define	InputSource_readCharacterChunk(_this,count,buffer)\
	(*_this->vTbl->readCharacterChunk)(_this,count,buffer)


#endif //if !defined(__cplusplus)

#endif	//#ifndef _SAX_H_
