Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | Static Private Attributes

ACEXML_Parser Class Reference

A SAX based parser. More...

#include <ACEXML/parser/parser/Parser.h>

Inheritance diagram for ACEXML_Parser:
Inheritance graph
[legend]
Collaboration diagram for ACEXML_Parser:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ACEXML_Parser (void)
 Default constructor.
virtual ~ACEXML_Parser (void)
 Destructor.
int initialize (ACEXML_InputSource *input)
virtual ACEXML_ContentHandlergetContentHandler (void) const
virtual ACEXML_DTDHandlergetDTDHandler (void) const
virtual ACEXML_EntityResolvergetEntityResolver (void) const
virtual ACEXML_ErrorHandlergetErrorHandler (void) const
virtual int getFeature (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
virtual void setFeature (const ACEXML_Char *name, int boolean_value ACEXML_ENV_ARG_DECL)
virtual void * getProperty (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
virtual void setProperty (const ACEXML_Char *name, void *value ACEXML_ENV_ARG_DECL)
virtual void parse (ACEXML_InputSource *input ACEXML_ENV_ARG_DECL)
virtual void parse (const ACEXML_Char *systemId ACEXML_ENV_ARG_DECL)
virtual void setContentHandler (ACEXML_ContentHandler *handler)
virtual void setDTDHandler (ACEXML_DTDHandler *handler)
virtual void setEntityResolver (ACEXML_EntityResolver *resolver)
virtual void setErrorHandler (ACEXML_ErrorHandler *handler)

Protected Member Functions

void parse_xml_prolog (ACEXML_ENV_SINGLE_ARG_DECL)
void parse_version_info (ACEXML_ENV_SINGLE_ARG_DECL)
void parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_DECL)
void parse_xml_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_text_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_doctypedecl (ACEXML_ENV_SINGLE_ARG_DECL)
void parse_element (int is_root ACEXML_ENV_ARG_DECL)
int parse_content (const ACEXML_Char *startname, const ACEXML_Char *&ns_uri, const ACEXML_Char *&ns_lname, int ns_flag ACEXML_ENV_ARG_DECL)
int parse_char_reference (ACEXML_Char *buf, size_t &len)
ACEXML_Charparse_reference_name (void)
int parse_cdata (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_internal_dtd (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_comment (void)
int parse_element_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_entity_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_attlist_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_atttype (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_notation_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_external_id (ACEXML_Char *&publicId, ACEXML_Char *&systemId ACEXML_ENV_ARG_DECL)
int parse_external_dtd (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_external_subset (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_markup_decl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_conditional_section (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_includesect (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_ignoresect (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_PE_reference (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_entity_reference (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_entity_value (ACEXML_Char *&str ACEXML_ENV_ARG_DECL)
int parse_defaultdecl (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_children_definition (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_child (int skip_open_paren ACEXML_ENV_ARG_DECL)
ACEXML_Charparse_name (ACEXML_Char ch=0)
ACEXML_Charparse_nmtoken (ACEXML_Char ch=0)
int parse_version (ACEXML_Char *&str)
int parse_version_num (ACEXML_Char *&str)
int parse_encname (ACEXML_Char *&str)
int parse_sddecl (ACEXML_Char *&str)
ACEXML_Charparse_attname (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_attvalue (ACEXML_Char *&str ACEXML_ENV_ARG_DECL)
int parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_DECL)
int parse_system_literal (ACEXML_Char *&str)
int parse_pubid_literal (ACEXML_Char *&str)
int is_whitespace (const ACEXML_Char c) const
int isChar (ACEXML_UCS4 c) const
int isCharRef (const ACEXML_Char c) const
int isBasechar (const ACEXML_Char c) const
int isIdeographic (const ACEXML_Char c) const
int isCombiningchar (const ACEXML_Char c) const
int isDigit (const ACEXML_Char c) const
int isExtender (const ACEXML_Char c) const
int isLetter (const ACEXML_Char c) const
int isNameChar (const ACEXML_Char c) const
int isPubidChar (const ACEXML_Char c) const
virtual ACEXML_Char get (void)
 Get a character.
virtual ACEXML_Char peek (void)
 Peek a character.

Private Member Functions

ACEXML_Char skip_whitespace (void)
int skip_whitespace_count (ACEXML_Char *peek=0)
int skip_equal (void)
int get_quoted_string (ACEXML_Char *&str)
int isNormalDigit (const ACEXML_Char c) const
void error (const ACEXML_Char *msg ACEXML_ENV_ARG_DECL)
void warning (const ACEXML_Char *msg ACEXML_ENV_ARG_DECL)
void fatal_error (const ACEXML_Char *msg ACEXML_ENV_ARG_DECL)
void prefix_mapping (const ACEXML_Char *prefix, const ACEXML_Char *uri, int start ACEXML_ENV_ARG_DECL)
int parse_token (const ACEXML_Char *keyword)
int push_context (ACEXML_Parser_Context *context)
size_t pop_context (int GE_ref ACEXML_ENV_ARG_DECL)
virtual int switch_input (ACEXML_CharStream *cstream, const ACEXML_Char *systemId, const ACEXML_Char *publicId=0)
virtual int switch_input (ACEXML_InputSource *input, const ACEXML_Char *systemId, const ACEXML_Char *publicId=0)
int check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_DECL)
void reset (void)
ACEXML_Charnormalize_systemid (const ACEXML_Char *systemId)

Private Attributes

ACEXML_DTDHandlerdtd_handler_
ACEXML_EntityResolverentity_resolver_
ACEXML_ContentHandlercontent_handler_
ACEXML_ErrorHandlererror_handler_
ACEXML_Chardoctype_
 Document Type.
ACEXML_Parser_Contextcurrent_
 Current parser context.
ACE_Unbounded_Stack
< ACEXML_Parser_Context * > 
ctx_stack_
 Stack used to hold the Parser_Context.
ACE_Unbounded_Stack
< ACEXML_Char * > 
GE_reference_
 Set used to hold the general entity references that are active.
ACE_Unbounded_Stack
< ACEXML_Char * > 
PE_reference_
 Set used to hold the parameter entity references that are active.
ACE_Obstack_T< ACEXML_Charobstack_
 Obstack used by the parser to hold all the strings parsed.
ACE_Obstack_T< ACEXML_Charalt_stack_
 Alternative obstack used to hold any strings when the original is in use.
ACEXML_NamespaceSupport xml_namespace_
 Namespace stack used by the parser to implement support for Namespaces.
int nested_namespace_
 T => We are processing a nested namespace.
ACEXML_Entity_Manager internal_GE_
 Set of internal parsed general entities in the document.
ACEXML_Entity_Manager external_GE_
 Set of external parsed general entities in the document.
ACEXML_Entity_Manager unparsed_entities_
 Set of unparsed entities in the document.
ACEXML_Entity_Manager predef_entities_
 Set of predefined entities used by the parser.
ACEXML_Entity_Manager internal_PE_
 Set of internal parsed parameter entities in the document.
ACEXML_Entity_Manager external_PE_
 Set of external parsed parameter entities in the document.
ACEXML_Entity_Manager notations_
 Set of notations declared in the document.
ACEXML_ParserInt::ReferenceState ref_state_
 State of the parser when it encounters a reference.
int external_subset_
 T => We are parsing an external subset.
int external_entity_
 T => We are parsing an external entity value.
int has_pe_refs_
 T => Internal DTD has parameter entity references.
int standalone_
 If set, the document is a standalone XML document.
int external_dtd_
 If set, the document has an external DTD subset.
int internal_dtd_
 If set, the document has an internal DTD.
int simple_parsing_
int validate_
 If set, the parser should also validate.
int namespaces_
 If set, the parser should allow access by namespace qualified names.
int namespace_prefixes_

Static Private Attributes

static const ACEXML_Char simple_parsing_feature_ [] = ACE_TEXT ("Simple")
static const ACEXML_Char namespaces_feature_ [] = ACE_TEXT ("http://xml.org/sax/features/namespaces")
static const ACEXML_Char namespace_prefixes_feature_ [] = ACE_TEXT ("http://xml.org/sax/features/namespace-prefixes")
static const ACEXML_Char validation_feature_ [] = ACE_TEXT ("http://xml.org/sax/features/validation")

Detailed Description

A SAX based parser.

Definition at line 45 of file Parser.h.


Constructor & Destructor Documentation

ACEXML_Parser::ACEXML_Parser ( void   ) 
ACEXML_Parser::~ACEXML_Parser ( void   )  [virtual]

Destructor.

Definition at line 56 of file Parser.cpp.

{

}


Member Function Documentation

int ACEXML_Parser::check_for_PE_reference ( ACEXML_ENV_SINGLE_ARG_DECL   )  [private]

Check for a parameter entity reference. This is used to check for the occurence of a PE Reference withing markupDecl. Additionally this function consumes any leading or trailing whitespace around the PE Reference.

Return values:
Number of whitespace characters skipped.

Definition at line 1454 of file Parser.cpp.

{
  ACEXML_Char fwd = '\xFF';
  // Skip any leading whitespaces and store the number of such chars skipped
  int count = this->skip_whitespace_count (&fwd);
  if (fwd == 0)
    {
      this->get(); // Consume the 0
      this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      fwd = this->peek();
    }
  if (fwd == '%')
    {
      this->get();  // Consume the %
      if (this->external_subset_)
        {
          this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      else
        {
          this->fatal_error(ACE_TEXT ("Illegal PERef within markupDecl")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }
  if (count)
    {
      // We have atleast one whitespace. So just skip any more whitespaces
      // and return the count
      this->skip_whitespace_count();
      return count;
    }
  return this->skip_whitespace_count();
}

void ACEXML_Parser::error ( const ACEXML_Char *msg  ACEXML_ENV_ARG_DECL  )  [private]

Dispatch errors to ErrorHandler.

Definition at line 3074 of file Parser.cpp.

{
  ACEXML_SAXParseException* exception = 0;
  ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
  if (this->error_handler_)
      this->error_handler_->error (*exception ACEXML_ENV_ARG_PARAMETER);
  else
    ACEXML_ENV_RAISE (exception);
  return;
}

void ACEXML_Parser::fatal_error ( const ACEXML_Char *msg  ACEXML_ENV_ARG_DECL  )  [private]

Dispatch fatal errors to ErrorHandler.

Definition at line 3097 of file Parser.cpp.

{
  ACEXML_SAXParseException* exception = 0;
  ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
  if (this->error_handler_)
    this->error_handler_->fatalError (*exception ACEXML_ENV_ARG_PARAMETER);
  this->reset();
  ACEXML_ENV_RAISE (exception);
  return;
}

ACEXML_INLINE ACEXML_Char ACEXML_Parser::get ( void   )  [protected, virtual]

Get a character.

Definition at line 208 of file Parser.inl.

{
  ACEXML_Char ch = 0;
  const ACEXML_InputSource* ip = this->current_->getInputSource();
  ACEXML_CharStream* instream = ip->getCharStream();

  if (instream->get (ch) != -1)
    {
      this->current_->getLocator()->incrColumnNumber();
      // Normalize white-space
      if (ch == '\x0D')
        {
          if (instream->peek() == 0x0A)
            instream->get (ch);
          ch = '\x0A';
        }
      if (ch == '\x0A')
        {
          // Reset column number and increment Line Number.
          this->current_->getLocator()->incrLineNumber();
          this->current_->getLocator()->setColumnNumber (0);
      }
      return ch;
    }
  return 0;
}

int ACEXML_Parser::get_quoted_string ( ACEXML_Char *&  str  )  [private]

Get a quoted string. Quoted strings are used to specify attribute values and this routine will replace character and entity references on-the-fly. Parameter entities are not allowed (or replaced) in this function. (But regular entities are.)

Parameters:
str returns the un-quoted string.
Return values:
0 on success, -1 otherwise.
ACEXML_INLINE ACEXML_ContentHandler * ACEXML_Parser::getContentHandler ( void   )  const [virtual]

Return the current content handler.

Implements ACEXML_XMLReader.

Definition at line 12 of file Parser.inl.

{
  return this->content_handler_;
}

ACEXML_INLINE ACEXML_DTDHandler * ACEXML_Parser::getDTDHandler ( void   )  const [virtual]

Return the current DTD handler.

Implements ACEXML_XMLReader.

Definition at line 18 of file Parser.inl.

{
  return this->dtd_handler_;
}

ACEXML_INLINE ACEXML_EntityResolver * ACEXML_Parser::getEntityResolver ( void   )  const [virtual]

Return the current entity resolver.

Implements ACEXML_XMLReader.

Definition at line 24 of file Parser.inl.

{
  return this->entity_resolver_;
}

ACEXML_INLINE ACEXML_ErrorHandler * ACEXML_Parser::getErrorHandler ( void   )  const [virtual]

Return the current error handler.

Implements ACEXML_XMLReader.

Definition at line 30 of file Parser.inl.

{
  return this->error_handler_;
}

int ACEXML_Parser::getFeature ( const ACEXML_Char *name  ACEXML_ENV_ARG_DECL  )  [virtual]

Look up the value of a feature. This method allows programmers to check whether a specific feature has been activated in the parser.

Implements ACEXML_XMLReader.

Definition at line 3005 of file Parser.cpp.

void * ACEXML_Parser::getProperty ( const ACEXML_Char *name  ACEXML_ENV_ARG_DECL  )  [virtual]

Look up the value of a property.

Implements ACEXML_XMLReader.

Definition at line 3059 of file Parser.cpp.

int ACEXML_Parser::initialize ( ACEXML_InputSource input  ) 

Initialize the parser state.

Return values:
0 if parser was initialized correctly else -1.

Definition at line 62 of file Parser.cpp.

{
  // Initialize namespace support
  if (this->xml_namespace_.init() == -1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("Error initializing namespace support\n")));
      return -1;
    }
  for (int i = 0; i < 5; ++i)
    {
      if (this->predef_entities_.add_entity (ACEXML_ParserInt::predef_ent_[i],
                                             ACEXML_ParserInt::predef_val_[i])
          != 0)
        {
          ACE_ERROR ((LM_DEBUG,
                      ACE_TEXT ("Error adding entity %s to Manager\n"),
                      ACEXML_ParserInt::predef_ent_[i]));
          return -1;
        }
    }
  return this->switch_input (input, input->getSystemId());
}

ACEXML_INLINE int ACEXML_Parser::is_whitespace ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a whitespace.

Return values:
1 if c is a valid white space character. 0 otherwise.

Definition at line 163 of file Parser.inl.

{
  switch (c)
    {
      case '\x0A': case '\x20':
      case '\x09': case '\x0D':
      return 1;
    default:
      return 0;
    }
}

ACEXML_INLINE int ACEXML_Parser::isBasechar ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a BaseChar.

Return values:
1 if c is a valid BaseChar character, 0 otherwise.

Definition at line 84 of file Parser.inl.

{
#if defined (ACE_USES_WCHAR)
  return ACEXML_ParserInt::isBasechar_i (c);
#else
  return ACEXML_ParserInt::base_char_table_[(int) c];
#endif /* ACE_USES_WCHAR */
}

ACEXML_INLINE int ACEXML_Parser::isChar ( ACEXML_UCS4  c  )  const [protected]

Check if a character c is a valid Char.

Return values:
1 if c is a valid character. 0 otherwise.

Definition at line 60 of file Parser.inl.

{
  return (c == 0x9
          || c == 0xA
          || c == 0xD
          || (c >= 0x20 && c <= 0xD7FF)
          || (c >= 0xE000 && c <= 0xFFFD)
          || (c >= 0x10000 && c <= 0x10FFFF));
}

ACEXML_INLINE int ACEXML_Parser::isCharRef ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a valid CharRef character.

Return values:
1 if c is a valid character reference character, 0 otherwise.

Definition at line 71 of file Parser.inl.

{
  return ((c >= 'a' && c <= 'f')
          || (c >= 'A' && c <= 'F'));
}

ACEXML_INLINE int ACEXML_Parser::isCombiningchar ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a CombiningChar.

Return values:
1 if c is a valid CombiningChar character, 0 otherwise.

Definition at line 105 of file Parser.inl.

{
#if defined (ACE_USES_WCHAR)
  return ACEXML_ParserInt::isCombiningchar_i (c);
#else
  ACE_UNUSED_ARG (c);
      return 0;
#endif /* ACE_USES_WCHAR */
    }

ACEXML_INLINE int ACEXML_Parser::isDigit ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a Digit.

Return values:
1 if c is a valid Digit character, 0 otherwise.

Definition at line 116 of file Parser.inl.

{
#if defined (ACE_USES_WCHAR)
  return ACEXML_ParserInt::isDigit_i (c);
#else
  return (this->isNormalDigit (c));
#endif /* ACE_USES_WCHAR */
}

ACEXML_INLINE int ACEXML_Parser::isExtender ( const ACEXML_Char  c  )  const [protected]

Check if a character c is an Extender.

Return values:
1 if c is a valid Extender character, 0 otherwise.

Definition at line 126 of file Parser.inl.

{
#if defined (ACE_USES_WCHAR)
  return ACEXML_ParserInt::isExtender_i (c);
#else
  return (c == '\xB7');
#endif /* ACE_USES_WCHAR */
}

ACEXML_INLINE int ACEXML_Parser::isIdeographic ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a Ideographic.

Return values:
1 if c is a valid Ideographic character, 0 otherwise.

Definition at line 94 of file Parser.inl.

{
#if defined (ACE_USES_WCHAR)
  return ACEXML_ParserInt::isIdeographic_i (c);
#else
  ACE_UNUSED_ARG (c);
  return 0;
#endif /* ACE_USES_WCHAR */
}

ACEXML_INLINE int ACEXML_Parser::isLetter ( const ACEXML_Char  c  )  const [protected]

Check if a character c is a Letter.

Return values:
1 if c is a valid Letter character, 0 otherwise.

Definition at line 136 of file Parser.inl.

{
  return (this->isBasechar (c) || this->isIdeographic (c));
}

ACEXML_INLINE int ACEXML_Parser::isNameChar ( const ACEXML_Char  c  )  const [protected]

Check if a character is an acceptable NameChar.

Return values:
1 if c is a valid NameChar character, 0 otherwise.

Definition at line 142 of file Parser.inl.

{
  return (this->isLetter (c) || this->isDigit (c) || c == '.' || c == '-' ||
          c == '_' || c == ':' || this->isCombiningchar (c) ||
          this->isExtender (c));
}

ACEXML_INLINE int ACEXML_Parser::isNormalDigit ( const ACEXML_Char  c  )  const [private]

Check if a character c is a Digit.

Return values:
1 if c is a valid Digit character, 0 otherwise.

Definition at line 78 of file Parser.inl.

{
  return (c >= '\x30' && c <= '\x39');
}

ACEXML_INLINE int ACEXML_Parser::isPubidChar ( const ACEXML_Char  c  )  const [protected]

Check if a character is a PubidChar.

Return values:
1 if c is a valid PubidChar character, 0 otherwise.

Definition at line 150 of file Parser.inl.

{
  return (c == '\x20' || c == '\x0D' || c == '\x0A' ||
          (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
          (c >= '0' && c <= '9') || c == '-' || c == '\'' || c == '(' ||
          c == ')' || c == '+' || c == ',' || c == '.' || c == '/' ||
          c == ':' || c == '=' || c == '?' || c == ';' || c == '!' ||
          c == '*' || c == '#' || c == '@' || c == '$' || c == '_' ||
          c == '%');
}

ACEXML_Char * ACEXML_Parser::normalize_systemid ( const ACEXML_Char systemId  )  [private]

Very trivial, non-conformant normalization of a systemid.

Definition at line 780 of file Parser.cpp.

{
  if (ACE_OS::strstr (systemId, ACE_TEXT("ftp://")) != 0 ||
      ACE_OS::strstr (systemId, ACE_TEXT ("http://")) != 0 ||
      ACE_OS::strstr (systemId, ACE_TEXT ("file://")) != 0)
    return 0;
  else
    {
      ACEXML_Char* normalized_uri = 0;
      const ACEXML_Char* baseURI = this->current_->getLocator()->getSystemId();
      ACE_ASSERT (baseURI);
      const ACEXML_Char* temp = 0;
      if (ACE_OS::strstr (baseURI, ACE_TEXT ("http://")) != 0)
        {
          // baseURI is a HTTP URL and systemId is relative. Note that this
          // is not compliant with RFC2396. Caveat Emptor !
          temp = ACE_OS::strrchr (baseURI, '/');
        }
      else
        {
          // baseURI is a local file and systemId is relative
          // Unlike the HTTP one, this will work always.
          temp = ACE_OS::strrchr (baseURI, ACE_TEXT ('\\'));
          if (!temp)
            {
              temp = ACE_OS::strrchr (baseURI, ACE_TEXT ('/'));
            }
        }

      if (temp)
        {
          size_t pos = temp - baseURI + 1;
          size_t len = pos + ACE_OS::strlen (systemId) + 1;
          ACE_NEW_RETURN (normalized_uri, ACEXML_Char[len], 0);
          ACE_OS::strncpy (normalized_uri, baseURI, pos);
          ACE_OS::strcpy (normalized_uri + pos, systemId);
          return normalized_uri;
        }
      return 0;
    }
}

void ACEXML_Parser::parse ( ACEXML_InputSource *input  ACEXML_ENV_ARG_DECL  )  [virtual]

Parse an XML document.

Implements ACEXML_XMLReader.

Definition at line 95 of file Parser.cpp.

{
  if (input == 0)
    {
      this->fatal_error(ACE_TEXT ("Invalid input source")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }
  if (this->content_handler_ == 0)
    {
      this->fatal_error (ACE_TEXT ("No content handlers defined. Exiting..")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }

  if (this->validate_ && this->dtd_handler_ == 0)
    {
      this->fatal_error (ACE_TEXT ("No DTD handlers defined. Exiting..")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }


  if (this->initialize(input) == -1)
    {
      this->fatal_error (ACE_TEXT ("Failed to initialize parser state")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }
  // Set up Locator.
  this->content_handler_->setDocumentLocator (this->current_->getLocator());

  int xmldecl_defined = 0;
  ACEXML_Char fwd = this->get();  // Consume '<'
  if (fwd == '<' && this->peek() == '?')
    {
      this->get();      // Consume '?'
      fwd = this->peek();
      if (fwd == 'x' && !xmldecl_defined)
        {
          this->parse_xml_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK;
          xmldecl_defined = 1;
        }
    }
  // We need a XMLDecl in a Valid XML document
  if (this->validate_ && !xmldecl_defined)
    {
      this->fatal_error (ACE_TEXT ("Expecting an XMLDecl at the beginning of")
                         ACE_TEXT (" a valid document")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }
  this->content_handler_->startDocument (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK;

  int doctype_defined = 0;
  for (int prolog_done = 0; prolog_done == 0; )
    {
      // Expect a '<' only if we have encountered a XMLDecl, or we are
      // looping through Misc blocks.
      if (xmldecl_defined)
        {
          if (this->skip_whitespace () != '<')
            {
              this->fatal_error (ACE_TEXT ("Expecting '<' at the beginning of ")
                                 ACE_TEXT ("Misc section")
                                 ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK;
            }
          fwd = this->peek();
        }
      switch (fwd)
        {
          case '?':
            this->get();
            this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
            ACEXML_CHECK;
            xmldecl_defined = 1;
            break;
          case '!':
            this->get();
            fwd = this->peek ();
            if (fwd == 'D' && !doctype_defined)       // DOCTYPE
              {
                // This will also take care of the trailing MISC block if any.
                this->parse_doctypedecl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK;
                doctype_defined = 1;
                // Now that we have a DOCTYPE Decl defined, we shouldn't
                // accept XML Decl any longer
                xmldecl_defined = 1;
              }
            else if (fwd == 'D')
              {
                this->fatal_error (ACE_TEXT ("Duplicate DOCTYPE declaration")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK;
              }
            else if (fwd == '-')  // COMMENT
              {
                if (this->parse_comment () < 0)
                  {
                    this->fatal_error(ACE_TEXT ("Invalid comment in document")
                                      ACEXML_ENV_ARG_PARAMETER);
                    ACEXML_CHECK;
                  }
                xmldecl_defined = 1;
              }
            break;
          case 0:
            this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
          default:                // Root element begins
            prolog_done = 1;
            break;
        }
    }

  if (this->validate_ && !doctype_defined)
    {
      this->warning (ACE_TEXT ("No doctypeDecl in valid document")
                     ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }

  // Now parse root element.
  this->parse_element (1 ACEXML_ENV_ARG_PARAMETER);
  ACEXML_CHECK;

  this->content_handler_->endDocument (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK;

  // Reset the parser state
  this->reset();

}

void ACEXML_Parser::parse ( const ACEXML_Char *systemId  ACEXML_ENV_ARG_DECL  )  [virtual]

Parse an XML document from a system identifier (URI).

Implements ACEXML_XMLReader.

Definition at line 87 of file Parser.cpp.

{
  ACEXML_InputSource* input = 0;
  ACE_NEW (input, ACEXML_InputSource (systemId));
  this->parse (input ACEXML_ENV_ARG_PARAMETER);
}

int ACEXML_Parser::parse_attlist_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse an "ATTLIST" decl. Thse first character this method expects is always the 'A' (the first char) in the word "ATTLIST".

Return values:
0 on success, -1 otherwise.

Definition at line 1376 of file Parser.cpp.

{
  if (this->parse_token (ACE_TEXT ("ATTLIST")) < 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting keyword 'ATTLIST'")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  int count = check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  if (!count)
    {
      this->fatal_error(ACE_TEXT ("Expecting space between ATTLIST and ")
                        ACE_TEXT ("element name") ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char *element_name = this->parse_name ();
  if (element_name == 0)
    {
      this->fatal_error(ACE_TEXT ("Invalid element Name in attlistDecl")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  ACEXML_Char fwd = 0;
  count = this->skip_whitespace_count (&fwd);
  // Parse AttDef*
  while (fwd != '>')
    {
      if (!this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER)
          && !count)
        this->fatal_error(ACE_TEXT ("Expecting space between element ")
                          ACE_TEXT ("name and AttDef")
                          ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      this->skip_whitespace_count (&fwd);
      if (fwd == '>')
        break;

      count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);

      this->parse_attname (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);

      count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      if (!count)
        {
          this->fatal_error(ACE_TEXT ("Expecting space between AttName and ")
                            ACE_TEXT ("AttType") ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      this->parse_atttype (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);

      count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      if (!count)
        {
          this->fatal_error(ACE_TEXT ("Expecting space between AttType and")
                            ACE_TEXT (" DefaultDecl")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      this->parse_defaultdecl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);

      count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      this->skip_whitespace_count(&fwd);
    }
  this->get ();                 // consume closing '>'
  return 0;
}

ACEXML_Char * ACEXML_Parser::parse_attname ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse an attribute name.

Return values:
str String containing the value of the attribute name if successful.
0 otherwise.

Definition at line 1492 of file Parser.cpp.

{
  // Parse attribute name
  ACEXML_Char *att_name = this->parse_name ();
  if (att_name == 0)
    {
      this->fatal_error(ACE_TEXT ("Invalid AttName")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (0);
    }
  return att_name;
}

int ACEXML_Parser::parse_atttype ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a AttType declaration.

AttType ::= StringType | TokenizedType | EnumeratedType StringType ::= 'CDATA' TokenizedType ::= 'ID' [VC: ID] [VC: One ID per Element Type] [VC: ID Attribute Default] | 'IDREF' [VC: IDREF] | 'IDREFS' [VC: IDREF] | 'ENTITY' [VC: Entity Name] | 'ENTITIES' [VC: Entity Name] | 'NMTOKEN' [VC: Name Token] | 'NMTOKENS'

EnumeratedType ::= NotationType | Enumeration NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')' [VC: Notation Attributes] [VC: One Notation Per Element Type] [VC: No Notation on Empty Element] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' [VC: Enumeration]

Definition at line 1702 of file Parser.cpp.

{
  ACEXML_Char nextch = this->peek();
  switch (nextch)
    {
      case 'C':               // CDATA
        if (this->parse_token (ACE_TEXT ("CDATA")) < 0)
          {
            this->fatal_error(ACE_TEXT ("Expecting keyword 'CDATA'")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        // Else, we have successfully identified the type of the
        // attribute as CDATA
        // @@ Set up validator appropriately here.
        break;
      case 'I': case 'E':      // ID, IDREF, IDREFS, ENTITY or ENTITIES
        this->parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;
      case 'N':             // NMTOKEN, NMTOKENS, or NOTATION
        this->get();
        nextch = this->peek();
        if (nextch != 'M' && nextch != 'O')
          {
            this->fatal_error (ACE_TEXT ("Expecting keyword 'NMTOKEN', ")
                               ACE_TEXT ("'NMTOKENS' or 'NOTATION'")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        if (nextch == 'M')
          {
            this->parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            break;
          }
        else                   // NOTATION
          {
            if (this->parse_token (ACE_TEXT ("OTATION")) < 0)
              {
                this->fatal_error(ACE_TEXT ("Expecting keyword `NOTATION'")
                                  ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
            int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            if (!count)
              {
                this->fatal_error (ACE_TEXT ("Expecting space between keyword ")
                                   ACE_TEXT ("NOTATION and '('")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
            if (this->get () != '(')
              {
                this->fatal_error(ACE_TEXT ("Expecting '(' in NotationType")
                                  ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
            this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            do {
              this->skip_whitespace_count();
              ACEXML_Char *notation_name = this->parse_name ();
              if (notation_name == 0)
                {
                  this->fatal_error(ACE_TEXT ("Invalid notation name")
                                    ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              // @@ get another notation name, set up validator as such
              this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
              nextch = this->get();
            } while (nextch == '|');
            if (nextch != ')')
              {
                this->fatal_error (ACE_TEXT ("Expecting a ')' after a ")
                                   ACE_TEXT ("NotationType declaration")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
          }
        break;
      case '(':               // EnumeratedType - Enumeration
        this->get();
        this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        do {
          this->skip_whitespace_count();
          ACEXML_Char *token_name = this->parse_nmtoken ();
          if (token_name == 0)
            {
              this->fatal_error(ACE_TEXT ("Invalid enumeration name")
                                ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
          // @@ get another nmtoken, set up validator as such
          this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          nextch = this->get();
        } while (nextch == '|');
        if (nextch != ')')
          {
            this->fatal_error (ACE_TEXT ("Expecting a ')' after a ")
                               ACE_TEXT ("Enumeration declaration")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        break;
      default:
        {
          this->fatal_error(ACE_TEXT ("Invalid AttType")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
        ACE_NOTREACHED (break);
    }
  return 0;
}

int ACEXML_Parser::parse_attvalue ( ACEXML_Char *&str  ACEXML_ENV_ARG_DECL  )  [protected]

Parse an attribute value.

Parameters:
str String containing the value of the attribute if successful.
Returns:
0 if attribute value was read successfully, -1 otherwise.

Definition at line 2263 of file Parser.cpp.

{
  ACEXML_Char quote = this->get ();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  ACEXML_Char ch = this->get ();
  while (1)
    {
      if (ch == quote)
        {
          ACEXML_Char* temp = this->obstack_.freeze ();
          // If the attribute type is not CDATA, then the XML processor
          // must further process the normalized attribute value by
          // discarding any leading and trailing space (#x20) characters,
          // and by replacing sequences of space (#x20) characters by a
          // single space (#x20) character.

          //           if (atttype != CDATA) {
          //             ACEXML_Char* start = temp;
          //             ACEXML_Char* end = temp + ACE_OS::strlen (temp);
          //             while (*start == '\x20')
          //               start++;
          //             if (start == end) // String which is all spaces
          //               str = start;
          //             while (*start != 0)
          //               {
          //                 this->obstack_.grow (*start);
          //                 start++;
          //                 while (*start == '\x20')
          //                   start++;
          //               }
          //             str = this->obstack_.freeze();
          //           }
          str = temp;
          return 0;
        }
      switch (ch)
        {
          case '&':
            if (this->peek () == '#')
              {
                ACEXML_Char buf[7];
                size_t len = sizeof (buf);
                if (this->parse_char_reference (buf, len) != 0)
                  {
                    // [WFC: Legal Character]
                    this->fatal_error (ACE_TEXT ("Invalid CharacterRef")
                                       ACEXML_ENV_ARG_PARAMETER);
                    ACEXML_CHECK_RETURN (-1);
                  }
                for (size_t j = 0; j < len; ++j)
                  this->obstack_.grow (buf[j]);
              }
            else
              {
                this->ref_state_ = ACEXML_ParserInt::IN_ATT_VALUE;
                this->parse_entity_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
            break;
          case '\x20': case '\x0D': case '\x0A': case '\x09':
            this->obstack_.grow ('\x20');
            break;
          case '<': // [WFC: No < in Attribute Values]
            this->fatal_error (ACE_TEXT ("Illegal '<' in AttValue")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            break;
          case 0:
            this->pop_context (1 ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            break;
          default:
            this->obstack_.grow (ch);
            break;
        }
      ch = this->get();
    }
}

int ACEXML_Parser::parse_cdata ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a CDATA section. The first character should always be the first '[' in CDATA definition.

Return values:
0 on success.
-1 if fail.

Definition at line 1170 of file Parser.cpp.

{
  if (this->parse_token (ACE_TEXT ("[CDATA[")) < 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting '[CDATA[' at beginning of CDATA ")
                        ACE_TEXT ("section")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char ch;
  int datalen = 0;
  ACEXML_Char *cdata = 0;
  while (1)
    {
      ch = this->get ();
      // Anything goes except the sequence "]]>".
      if (ch == ']' && this->peek() == ']')
        {
          ACEXML_Char temp = ch;
          ch = this->get();
          if (ch == ']' && this->peek() == '>')
            {
              ch = this->get();
              cdata = this->obstack_.freeze ();
              this->content_handler_->characters (cdata, 0, datalen
                                                  ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
              this->obstack_.unwind(cdata);
              return 0;
            }
          this->obstack_.grow (temp);
          ++datalen;
        }
      this->obstack_.grow (ch);
      ++datalen;
    };
  ACE_NOTREACHED (return -1);
}

int ACEXML_Parser::parse_char_reference ( ACEXML_Char buf,
size_t &  len 
) [protected]

Parse a character reference, i.e., "&#x20;" or "&#30;". The first character encountered should be the '#' char.

Parameters:
buf points to a character buffer for the result.
len In/out argument which initially specifies the size of the buffer and is later set to the no. of characters in the reference.
Return values:
0 on success and -1 otherwise.

Definition at line 2192 of file Parser.cpp.

{
  if (len < 7)   // Max size of a CharRef plus terminating '\0'
    return -1;
  ACEXML_Char ch = this->get();
  if (ch != '#')      // Internal error.
    return -1;
  int hex = 0;
  ch = this->peek();
  if (ch == 'x')
    {
      hex = 1;
      this->get ();
    }
  size_t i = 0;
  int more_digit = 0;
  ch = this->get ();
  for ( ; i < len &&
          (this->isNormalDigit (ch) || (hex ? this->isCharRef(ch): 0)); ++i)
    {
      buf[i] = ch;
      ch = this->get();
      ++more_digit;
    }
  if (ch != ';' || !more_digit)
    return -1;
  buf[i] = 0;
  ACEXML_UCS4 sum = (ACEXML_UCS4) ACE_OS::strtol (buf, 0, (hex ? 16 : 10));
  // [WFC: Legal Character]
  if (!this->isChar (sum))
    return -1;
  int clen;
#if defined (ACE_USES_WCHAR)
#  if (ACE_SIZEOF_WCHAR == 2)    // UTF-16
  if ((clen = ACEXML_Transcoder::ucs42utf16 (sum, buf, len)) < 0)
    return -1;
#  elif (ACE_SIZEOF_WCHAR == 4)  // UCS 4
  buf [0] = sum;
  buf [1] = 0;
  clen = 2;
#  endif /* ACE_SIZEOF_WCHAR */

#else                          // or UTF-8
  if ((clen = ACEXML_Transcoder::ucs42utf8 (sum, buf, len)) < 0)
    return -1;
#endif
  buf [clen] = 0;
  len = clen;
  return 0;
}

int ACEXML_Parser::parse_child ( int skip_open_paren  ACEXML_ENV_ARG_DECL  )  [protected]

Parse a cp non-terminal. cp can either be a seq or a choice. This function calls itself recursively.

Parameters:
skip_open_paren when non-zero, it indicates that the open paren of the seq or choice has already been removed from the input stream.
Return values:
0 on success, -1 otherwise.

Definition at line 2055 of file Parser.cpp.

{
  // Conditionally consume the open paren.
  if (skip_open_paren == 0 && this->get () != '(')
    {
      this->fatal_error(ACE_TEXT ("Expecting '(' at beginning of children")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char node_type = 0;
  ACEXML_Char nextch;

  do {
    this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
    ACEXML_CHECK_RETURN (-1);
    this->skip_whitespace_count (&nextch);
    switch (nextch)
      {
        case '(':
          this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          this->parse_child (0 ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          break;
        default:
          this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          // must be an element name here.
          ACEXML_Char *subelement = this->parse_name ();
          if (subelement == 0)
            {
              this->fatal_error(ACE_TEXT ("Invalid subelement name")
                                ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
          // Check for trailing '?', '*', '+'
          nextch = this->peek ();
          switch (nextch)
            {
              case '?':
                // @@ Consume the character and inform validator as such,
                this->get ();
                break;
              case '*':
                // @@ Consume the character and inform validator as such,
                this->get ();
                break;
              case '+':
                // @@ Consume the character and inform validator as such,
                this->get ();
                break;
              default:
                break;                    // not much to do.
            }

          // @@ Inform validator of the new element here.
          break;
      }
    this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
    ACEXML_CHECK_RETURN (-1);
    this->skip_whitespace_count (&nextch);
    switch (nextch)
      {
        case '|':
          switch (node_type)
            {
              case 0:
                node_type = '|';
                // @@ inform validator of this new type??
                break;
              case '|':
                break;
              default:
                this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
                                   ACE_TEXT ("while defining an element")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
            }
          break;
        case ',':
          switch (node_type)
            {
              case 0:
                node_type = ',';
                // @@ inform validator of this new type??
                break;
              case ',':
                break;
              default:
                this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
                                   ACE_TEXT ("while defining an element")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
            }
          break;
        case ')':
          break;
        default:
          this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
                             ACE_TEXT ("while defining an element")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
      }
    nextch = this->get();  // Consume the `,' or `|' or `)'
    if (nextch == ')')
      break;
    this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
    ACEXML_CHECK_RETURN (-1);
    this->skip_whitespace_count (&nextch);
  } while (nextch != ')');

  // Check for trailing '?', '*', '+'
  nextch = this->peek ();
  switch (nextch)
    {
      case '?':
        // @@ Consume the character and inform validator as such,
        this->get ();
        break;
      case '*':
        // @@ Consume the character and inform validator as such,
        this->get ();
        break;
      case '+':
        // @@ Consume the character and inform validator as such,
        this->get ();
        break;
      default:
        break;                    // not much to do.
    }


  return 0;
}

int ACEXML_Parser::parse_children_definition ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse the "children" and "Mixed" non-terminals in contentspec.

The first character this function sees must be the first open paren '(' in children.

Return values:
0 on success, -1 otherwise.

Definition at line 1983 of file Parser.cpp.

{
  this->get ();                 // consume the '('
  this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  int subelement_number = 0;
  ACEXML_Char nextch = this->peek();
  switch (nextch)
    {
      case '#':                   // Mixed element,
        if (this->parse_token (ACE_TEXT ("#PCDATA")) < 0)
          {
            this->fatal_error(ACE_TEXT ("Expecting keyword '#PCDATA'")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        nextch = this->get();
        while (nextch == '|')
          {
            this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            ACEXML_Char *name = this->parse_name ();
            // @@ name will be used in the Validator later.
            ACE_UNUSED_ARG (name);
            ++subelement_number;
            // @@ Install Mixed element name into the validator.
            this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            nextch = this->skip_whitespace();
          }
        if (nextch != ')' ||
            (subelement_number && this->get () != '*'))
          {
            this->fatal_error(ACE_TEXT ("Expecing ')' or ')*' at end of Mixed")
                              ACE_TEXT (" element") ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        // @@ close the element definition in the validator.
        break;
      default:
        int status = this->parse_child (1 ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        if (status != 0)
          return -1;
    }

  // Check for trailing '?', '*', '+'
  nextch = this->peek ();
  switch (nextch)
    {
      case '?':
        // @@ Consume the character and inform validator as such,
        this->get ();
        break;
      case '*':
        // @@ Consume the character and inform validator as such,
        this->get ();
        break;
      case '+':
        // @@ Consume the character and inform validator as such,
        this->get ();
        break;
      default:
        break;                    // not much to do.
    }

  return 0;
}

int ACEXML_Parser::parse_comment ( void   )  [protected]

Skip over a comment. The first character encountered should always be the first '-' in the comment prefix "@<@!--".

Definition at line 3247 of file Parser.cpp.

{
  int state = 0;

  if (this->get () != '-' ||    // Skip the opening "<!--"
      this->get () != '-' ||    // completely.
      this->get () == '-')      // and at least something not '-'.
    return -1;

  while (state < 3)
    // Waiting for the trailing three character '-->'. Notice that
    // according to the spec, '--->' is not a valid closing comment
    // sequence. But we'll let it pass anyway.
    {
      ACEXML_Char fwd = this->get ();
      if ((fwd == '-' && state < 2) ||
          (fwd == '>' && state == 2))
        state += 1;
      else
        state = 0;              // Reset parse state.
    }
  return 0;
}

int ACEXML_Parser::parse_conditional_section ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a conditionalSect declaration.

Definition at line 469 of file Parser.cpp.

{
  ACEXML_Char ch = this->get ();
  int include = 0;
  if (ch != '[')
    {
      this->fatal_error(ACE_TEXT ("Internal Parser Error")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  ch = this->skip_whitespace();
  if (ch == '%')
    {
      this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      ch = this->skip_whitespace();
    }
  if (ch == 'I')
    {
      ch = this->get();
      switch (ch)
        {
          case 'N':
            if (this->parse_token (ACE_TEXT ("CLUDE")) < 0)
              {
                this->fatal_error (ACE_TEXT ("Expecting keyword INCLUDE in ")
                                   ACE_TEXT ("conditionalSect")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
            include = 1;
            break;
          case 'G':
            if (this->parse_token (ACE_TEXT ("GNORE")) < 0)
              {
                this->fatal_error (ACE_TEXT ("Expecting keyword IGNORE in ")
                                   ACE_TEXT ("conditionalSect")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
            include = 0;
            break;
          default:
            this->fatal_error (ACE_TEXT ("Invalid conditionalSect")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
        }
      ACEXML_Char fwd = '\xFF';
      this->skip_whitespace_count (&fwd);
      if (fwd == 0)
        {
          this->get(); // Consume the 0
          this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }
  else
    {
      this->fatal_error (ACE_TEXT ("Invalid conditionalSect")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  if (this->skip_whitespace() != '[')
    {
      this->fatal_error (ACE_TEXT ("Expecting '[' in conditionalSect")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  if (include)
    this->parse_includesect (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  else
    this->parse_ignoresect (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  return 0;
}

int ACEXML_Parser::parse_content ( const ACEXML_Char startname,
const ACEXML_Char *&  ns_uri,
const ACEXML_Char *&  ns_lname,
int ns_flag  ACEXML_ENV_ARG_DECL 
) [protected]

Parse a content declaration.

Definition at line 988 of file Parser.cpp.

{
  ACEXML_Char *cdata;
  size_t cdata_length = 0;

  // Parse element contents.
  while (1)
    {
      ACEXML_Char ch = this->get ();
      switch (ch)
        {
          case 0:
            this->pop_context (1 ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            break;
          case '<':
            // Push out old 'characters' event.
            if (cdata_length != 0)
              {
                cdata = this->obstack_.freeze ();
                this->content_handler_->characters (cdata, 0, cdata_length
                                                    ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                this->obstack_.unwind (cdata);
                cdata_length = 0;
              }
            ch = this->peek();
            switch (ch)
              {
                case '!':             // a comment or a CDATA section.
                  this->get ();       // consume '!'
                  ch = this->peek ();
                  if (ch == '-')      // a comment
                    {
                      if (this->parse_comment () < 0)
                        {
                          this->fatal_error(ACE_TEXT ("Invalid comment in ")
                                            ACE_TEXT ("document")
                                            ACEXML_ENV_ARG_PARAMETER);
                          ACEXML_CHECK_RETURN (-1);
                        }
                    }
                  else if (ch == '[') // a CDATA section.
                    {
                      this->parse_cdata (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                      ACEXML_CHECK_RETURN (-1);
                    }
                  else
                    {
                      this->fatal_error(ACE_TEXT ("Expecting a CDATA section ")
                                        ACE_TEXT ("or a comment section")
                                        ACEXML_ENV_ARG_PARAMETER);
                      ACEXML_CHECK_RETURN (-1);
                    }
                  break;
                case '?':             // a PI.
                  this->get();        // consume the '?'
                  this->parse_processing_instruction
                    (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                  break;
                case '/':             // an ETag.
                  {
                    this->get ();       // consume '/'
                    ACEXML_Char* endname = this->parse_name ();
                    if (endname == 0 ||
                        ACE_OS::strcmp (startname, endname) != 0)
                      {
                        this->fatal_error(ACE_TEXT ("Name in ETag doesn't ")
                                          ACE_TEXT ("match name in STag")
                                          ACEXML_ENV_ARG_PARAMETER);
                        ACEXML_CHECK_RETURN (-1);
                      }
                    if (this->skip_whitespace () != '>')
                      {
                        this->fatal_error(ACE_TEXT ("Expecting '>' at end ")
                                          ACE_TEXT ("of element")
                                          ACEXML_ENV_ARG_PARAMETER);
                        return -1;
                      }
                    this->content_handler_->endElement (ns_uri, ns_lname,
                                                        endname
                                                        ACEXML_ENV_ARG_PARAMETER);
                    ACEXML_CHECK_RETURN (-1);
                    this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
                                          ns_uri, 0
                                          ACEXML_ENV_ARG_PARAMETER);
                    ACEXML_CHECK_RETURN (-1);
                    if (this->namespaces_ && ns_flag)
                      {
                    if (this->nested_namespace_ >= 1)
                      {
                        this->xml_namespace_.popContext ();
                        this->nested_namespace_--;
                      }
                      }
                    return 0;
                  }
                default:              // a new nested element?
                  this->parse_element (0 ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                  break;
              }
            break;
          case '&':
            if (this->peek () == '#')
              {
                ACEXML_Char buf[7];
                size_t len = 0;
                do
                  {
                    len = sizeof (buf);
                    if (this->parse_char_reference (buf, len) != 0)
                      {
                        // [WFC: Legal Character]
                        this->fatal_error (ACE_TEXT ("Invalid CharRef")
                                           ACEXML_ENV_ARG_PARAMETER);
                        ACEXML_CHECK_RETURN (-1);
                      }
                  } while (buf[0] == '&' && this->peek() == '#');
                  for (size_t j = 0; j < len; ++j)
                    this->obstack_.grow (buf[j]);
                cdata_length += len;
              }
            else
              {
                this->ref_state_ = ACEXML_ParserInt::IN_CONTENT;
                int length = this->parse_entity_reference(ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                if (length == 1)
                  cdata_length++;
              }
            break;
          case '\x20': case '\x0D': case '\x0A': case '\x09':
//             if (this->validate_)
//               {
//                 // Flush out any non-whitespace characters
//                 if (cdata_length != 0)
//                   {
//                     cdata = this->obstack_.freeze ();
//                     this->content_handler_->characters(cdata, 0, cdata_length
//                                                        ACEXML_ENV_ARG_PARAMETER);
//                     ACEXML_CHECK_RETURN (-1);
//                     this->obstack_.unwind (cdata);
//                     cdata_length = 0;
//                   }
//                 ++cdata_length;
//                 this->obstack_.grow (ch);
//                 while (1)
//                   {
//                     ch = this->peek();
//                     if (ch == '\x20' || ch == '\x0D' || ch == '\x0A' ||
//                         ch == '\x09')
//                       {
//                         ch = this->get();
//                         this->obstack_.grow (ch);
//                         continue;
//                       }
//                     break;
//                   }
//                 cdata = this->obstack_.freeze ();
//                 this->content_handler_->ignorableWhitespace (cdata, 0,
//                                                              cdata_length
//                                                              ACEXML_ENV_ARG_PARAMETER);
//                 ACEXML_CHECK_RETURN (-1);
//                 this->obstack_.unwind (cdata);
//                 cdata_length = 0;
//                 break;
//               }
            // Fall thru...
          default:
            ++cdata_length;
            this->obstack_.grow (ch);
        }
    }
  ACE_NOTREACHED (return 0;)
}

int ACEXML_Parser::parse_defaultdecl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a DefaultDecl specification.

Definition at line 1506 of file Parser.cpp.

{
  // DefaultDecl ::=  '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
  ACEXML_Char nextch = this->peek ();
  ACEXML_Char *fixed_attr = 0;
  switch (nextch)
    {
      case '#':
        this->get ();         // consume the '#'
        switch (this->get ())
          {
            case 'R':
              if (this->parse_token (ACE_TEXT ("EQUIRED")) < 0)
                {
                  this->fatal_error(ACE_TEXT ("Expecting keyword REQUIRED")
                                    ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              // We now know this attribute is required
              // @@ Set up the validator as such.
              break;
            case 'I':
              if (this->parse_token (ACE_TEXT ("MPLIED")) < 0)
                {
                  this->fatal_error(ACE_TEXT ("Expecting keyword IMPLIED")
                                    ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              // We now know this attribute is implied.
              // @@ Set up the validator as such.
              break;
            case 'F':
              if (this->parse_token (ACE_TEXT ("IXED")) < 0 ||
                  this->skip_whitespace_count () == 0)
                {
                  this->fatal_error(ACE_TEXT ("Expecting keyword FIXED")
                                    ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              // We now know this attribute is fixed.
              if (this->parse_attvalue (fixed_attr
                                        ACEXML_ENV_ARG_PARAMETER) != 0)
                {
                  this->fatal_error(ACE_TEXT ("Invalid Default AttValue")
                                    ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              // @@ set up validator
              break;
            default:
              this->fatal_error (ACE_TEXT ("Invalid DefaultDecl")
                                 ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
          }
        break;
      case '\'':
      case '"':
        if (this->parse_attvalue (fixed_attr ACEXML_ENV_ARG_PARAMETER) != 0)
          {
            this->fatal_error(ACE_TEXT ("Invalid AttValue")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        // @@ set up validator
        break;
      default:
        this->fatal_error (ACE_TEXT ("Invalid DefaultDecl")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;
    }
  return 0;
}

int ACEXML_Parser::parse_doctypedecl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse the DOCTYPE declaration. The first character encountered should always be 'D' in doctype prefix: "@<@!DOCTYPE".

Definition at line 235 of file Parser.cpp.

{
  if (this->parse_token (ACE_TEXT ("DOCTYPE")) < 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting keyword DOCTYPE in a doctypedecl")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char nextch = 0;
  if (this->skip_whitespace_count (&nextch) == 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting a space between DOCTYPE keyword ")
                        ACE_TEXT ("and name") ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  this->doctype_ = this->parse_name ();
  if (this->doctype_ == 0)
    {
      this->fatal_error(ACE_TEXT ("Invalid DOCTYPE name")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  int count = this->skip_whitespace_count (&nextch);

  if (nextch == 'S' || nextch == 'P') // ExternalID defined
    {
      if (count == 0)
        {
          this->fatal_error(ACE_TEXT ("Expecting a space between DOCTYPE")
                            ACE_TEXT ("keyword and name")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      this->external_dtd_ = 1;
      this->parse_external_dtd (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  nextch = this->skip_whitespace ();
  switch (nextch)
    {
      case '[':
        this->internal_dtd_ = 1;  // Internal DTD definition
        this->parse_internal_dtd (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;
      case '>':                   // End of DTD definition
        // This is an XML document without a doctypedecl.
        if (this->validate_ && !this->external_dtd_)
          {
            this->fatal_error (ACE_TEXT ("No DTD defined")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        return 0;
      case '0':
        this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
      default:
        break;
    }

  if (this->skip_whitespace() != '>')
    {
      this->fatal_error(ACE_TEXT ("Expecting '>' at end of doctypedecl")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

void ACEXML_Parser::parse_element ( int is_root  ACEXML_ENV_ARG_DECL  )  [protected]

Parse an XML element. The first character encountered should be the first character of the element "Name".

Parameters:
is_root If not 0, then we are expecting to see the "root" element now, and the next element's name need to match the name defined in DOCTYPE definition, i.e., this->doctype_.
Todo:
Instead of simply checking for the root element based on the argument is_root, we should instead either pass in some sort of validator or allow the function to return the element name so it can be used in a validator.

Definition at line 823 of file Parser.cpp.

{
  // Parse STag.
  const ACEXML_Char *startname = this->parse_name ();
  if (startname == 0)
    {
      this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
                         ACEXML_ENV_ARG_PARAMETER);
      return;
    }
  if (is_root && this->doctype_ != 0
      && ACE_OS::strcmp (startname, this->doctype_) != 0)
    {
      this->fatal_error (ACE_TEXT ("Root element different from DOCTYPE")
                         ACEXML_ENV_ARG_PARAMETER);
      return ;
    }
  ACEXML_AttributesImpl attributes;
  ACEXML_Char ch;
  int ns_flag = 0;   // Push only one namespace context onto the stack
                     // if there are multiple namespaces declared.

  const ACEXML_Char* ns_uri = 0;
  const ACEXML_Char* ns_lname = 0; // namespace URI and localName
  for (int start_element_done = 0; start_element_done == 0;)
    {
      ch = this->skip_whitespace ();

      switch (ch)
        {
          case 0:
            this->fatal_error(ACE_TEXT ("Internal Parser error")
                              ACEXML_ENV_ARG_PARAMETER);
            return;
          case '/':
            if (this->get () != '>')
              {
                this->fatal_error(ACE_TEXT ("Expecting '>' at end of element ")
                                  ACE_TEXT ("definition")
                                  ACEXML_ENV_ARG_PARAMETER);
                return;
              }
            this->xml_namespace_.processName(startname, ns_uri,
                                             ns_lname, 0);
            this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
                                  ns_uri, 1
                                  ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
            this->content_handler_->startElement(ns_uri, ns_lname,
                                                 startname, &attributes
                                                 ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
            this->content_handler_->endElement (ns_uri, ns_lname, startname
                                                ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
            this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
                                  ns_uri, 0
                                  ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
            if (ns_flag)
              {
                this->xml_namespace_.popContext ();
                this->nested_namespace_--;
              }
            return;
          case '>':
            this->xml_namespace_.processName (startname, ns_uri,
                                              ns_lname, 0);
            this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
                                  ns_uri, 1
                                  ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
            this->content_handler_->startElement(ns_uri, ns_lname, startname,
                                                 &attributes
                                                 ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK;
            start_element_done = 1;
            break;
          default:
            ACEXML_Char *attvalue = 0;
            ACEXML_Char *attname = this->parse_name (ch);

            if (attname == 0 ||
                this->skip_equal () != 0 ||
                this->parse_attvalue (attvalue ACEXML_ENV_ARG_PARAMETER) != 0)
              {
                this->fatal_error(ACE_TEXT ("Error reading attribute value")
                                  ACEXML_ENV_ARG_PARAMETER);
                return;
              }

            // Handling new namespace if any. Notice that the order of
            // namespace declaration does matter.
            if (ACE_OS::strncmp (attname, ACE_TEXT("xmlns"), 5) == 0)
              {
                if (this->namespaces_)
                  {
                    if (!ns_flag)
                      {
                        this->xml_namespace_.pushContext ();
                        this->nested_namespace_++;
                        ns_flag = 1;
                      }

                    ACEXML_Char* name = ACE_OS::strchr (attname, ':');
                    const ACEXML_Char* ns_name = (name == 0)?
                                                 empty_string:name+1;
                    if (this->xml_namespace_.declarePrefix (ns_name,
                                                            attvalue) == -1)
                      {
                        this->fatal_error(ACE_TEXT ("Duplicate definition of ")
                                          ACE_TEXT ("prefix")
                                          ACEXML_ENV_ARG_PARAMETER);
                        return;
                      }
                  }
                if (this->namespace_prefixes_)
                  {
                    // Namespace_prefixes_feature_ is required. So add the
                    // xmlns:foo to the list of attributes.
                    if (attributes.addAttribute (ACE_TEXT (""), ACE_TEXT (""),
                                                 attname,
                                                 default_attribute_type,
                                                 attvalue) == -1)
                      {
                        this->fatal_error(ACE_TEXT ("Duplicate attribute ")
                                          ACE_TEXT ("definition. Hint: Try ")
                                          ACE_TEXT ("setting namespace_prefix")
                                          ACE_TEXT ("es feature to 0")
                                          ACEXML_ENV_ARG_PARAMETER);
                        return;
                      }
                  }
                if (!this->namespaces_ && !this->namespace_prefixes_)
                  {
                    this->fatal_error(ACE_TEXT ("One of namespaces or ")
                                      ACE_TEXT ("namespace_prefixes should be")
                                      ACE_TEXT (" declared")
                                      ACEXML_ENV_ARG_PARAMETER);
                    return;
                  }
              }
            else
              {
                const ACEXML_Char *uri, *lName;
                this->xml_namespace_.processName (attname, uri, lName, 1);
                if (attributes.addAttribute (uri, lName, attname,
                                             default_attribute_type,
                                             attvalue) == -1)
                  {
                    this->fatal_error(ACE_TEXT ("Duplicate attribute ")
                                      ACE_TEXT ("definition")
                                      ACEXML_ENV_ARG_PARAMETER);
                    return;
                  }
              }
            break;
        }
    }
  if (this->parse_content (startname, ns_uri, ns_lname, ns_flag
                           ACEXML_ENV_ARG_PARAMETER) != 0)
    return;
}

int ACEXML_Parser::parse_element_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse an "ELEMENT" decl. The first character this method expects is always the 'L' (the second char) in the word "ELEMENT".

Return values:
0 on success, -1 otherwise.

Definition at line 1909 of file Parser.cpp.

{
  if (this->parse_token (ACE_TEXT ("LEMENT")) < 0)
    {
      this->fatal_error (ACE_TEXT ("Expecting keyword ELEMENT")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  if (!count)
    {
      this->fatal_error (ACE_TEXT ("Expecting a space between keyword ELEMENT")
                         ACE_TEXT (" and element name")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  ACEXML_Char *element_name = this->parse_name ();
  if (element_name == 0)
    {
      this->fatal_error (ACE_TEXT ("Invalid element name")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  if (!count)
    {
      this->fatal_error (ACE_TEXT ("Expecting a space between element name ")
                         ACE_TEXT ("and element definition")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  ACEXML_Char nextch = this->peek();
  switch (nextch)
    {
      case 'E':                   // EMPTY
        if (this->parse_token (ACE_TEXT ("EMPTY")) < 0)
          {
            this->fatal_error (ACE_TEXT ("Expecting keyword EMPTY")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        break;
      case 'A':                   // ANY
        if (this->parse_token (ACE_TEXT ("ANY")) < 0)
          {
            this->fatal_error (ACE_TEXT ("Expecting keyword ANY")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        break;
      case '(':                   // children
        this->parse_children_definition (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;
      default:                    // error
        this->fatal_error (ACE_TEXT ("Invalid element definition")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
    }
  count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  if (this->skip_whitespace () != '>')
    {
      this->fatal_error (ACE_TEXT ("Expecting '>' after element defintion")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

int ACEXML_Parser::parse_encname ( ACEXML_Char *&  str  )  [protected]

Parse the encoding name in an XML Prolog section.

Parameters:
str String containing the encoding name if successful.
Returns:
0 if the string was read successfully, 0 otherwise.

Definition at line 2820 of file Parser.cpp.

{
  const ACEXML_Char quote = this->get ();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  int numchars = 0;
  while (1)
    {
      ACEXML_Char ch = this->get ();
      if (ch == quote && !numchars)
        return -1;
      else if (ch == quote)
        {
          str = this->obstack_.freeze ();
          return 0;
        }
      // [81]    EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
      if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
          && !numchars)
        return -1;
      if (ch == '-' || ((ch >= 'a' && ch <= 'z') ||
                        (ch >= 'A' && ch <= 'Z') ||
                        (ch >= '0' && ch <= '9') ||
                        (ch == '_' || ch == '.')))
        {
          this->obstack_.grow (ch);
          numchars++;
        }
      else
        return -1;
    }
}

void ACEXML_Parser::parse_encoding_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a EncodingDecl declaration.

Definition at line 3129 of file Parser.cpp.

{
  ACEXML_Char* astring = 0;
  if ((this->parse_token (ACE_TEXT("ncoding")) < 0)
      || this->skip_equal () != 0
      || this->parse_encname (astring) != 0)
    {
      this->fatal_error (ACE_TEXT ("Invalid EncodingDecl specification")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }
  const ACEXML_Char* encoding = this->current_->getInputSource()->getEncoding();
  if (encoding != 0 && ACE_OS::strcasecmp (astring, encoding) != 0)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("Detected Encoding is %s ")
                  ACE_TEXT (": Declared Encoding is %s\n"),
                  encoding, astring));
      this->warning (ACE_TEXT ("Declared encoding differs from detected ")
                     ACE_TEXT ("encoding") ACEXML_ENV_ARG_PARAMETER);
    }
}

int ACEXML_Parser::parse_entity_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse an "ENTITY" decl. The first character this method expects is always the 'N' (the second char) in the word "ENTITY".

Return values:
0 on success, -1 otherwise.

Definition at line 1212 of file Parser.cpp.

{
  ACEXML_Char nextch = 0;

  if ((this->parse_token (ACE_TEXT ("NTITY")) < 0) ||
      this->skip_whitespace_count (&nextch) == 0)
    {
      this->fatal_error (ACE_TEXT ("Expecting keyword ENTITY followed by a ")
                         ACE_TEXT ("space") ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  int is_GEDecl = 1;
  if (nextch == '%')            // This is a PEDecl.
    {
      is_GEDecl = 0;
      this->get ();             // consume the '%'
      if (this->skip_whitespace_count (&nextch) == 0)
        {
          this->fatal_error (ACE_TEXT ("Expecting space between % and ")
                             ACE_TEXT ("entity name")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }

  ACEXML_Char *entity_name = this->parse_name ();
  if (entity_name == 0)
    {
      this->fatal_error (ACE_TEXT ("Invalid entity name")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  if (this->skip_whitespace_count (&nextch) == 0)
    {
      this->fatal_error (ACE_TEXT ("Expecting space between entity name and ")
                         ACE_TEXT ("entityDef")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  int retval = 0;
  if (nextch == '\'' || nextch == '"')
    {
      ACEXML_Char *entity_value = 0;
      if (this->parse_entity_value (entity_value
                                    ACEXML_ENV_ARG_PARAMETER) != 0)
        {
          this->fatal_error(ACE_TEXT ("Invalid EntityValue")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      if (is_GEDecl)
        retval = this->internal_GE_.add_entity (entity_name,
                                                entity_value);
      else
        retval = this->internal_PE_.add_entity (entity_name,
                                                entity_value);
      if (retval < 0)
        {
          this->fatal_error (ACE_TEXT ("Internal Parser Error in adding")
                             ACE_TEXT ("Entity to map")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      else if (retval == 1)
        {
          this->warning (ACE_TEXT ("Duplicate entity found")
                         ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }
  else
    {
      ACEXML_Char *systemid, *publicid;

      this->parse_external_id (publicid, systemid
                               ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      if (systemid == 0)
        {
          this->fatal_error(ACE_TEXT ("Invalid SystemLiteral")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      this->skip_whitespace_count (&nextch);
      if (nextch == 'N')        // NDATA section followed
        {
          if (is_GEDecl == 0)
            {
              this->fatal_error(ACE_TEXT ("Invalid NDataDecl in PEDef")
                                ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }

          if ((this->parse_token (ACE_TEXT ("NDATA")) < 0) ||
              this->skip_whitespace_count (&nextch) == 0)
            {
              this->fatal_error(ACE_TEXT ("Expecting keyword NDATA followed ")
                                ACE_TEXT ("by a space") ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }

          ACEXML_Char *ndata = this->parse_name ();
          if (this->validate_) // [VC: Notation Declared]
            {
              if (!this->notations_.resolve_entity (ndata))
                {
                  this->fatal_error (ACE_TEXT ("Undeclared Notation name")
                                     ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              this->dtd_handler_->unparsedEntityDecl(entity_name, publicid,
                                                     systemid, ndata
                                                     ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
        }
      else
        {
          if (is_GEDecl)
            retval = this->external_GE_.add_entity (entity_name,
                                                    systemid);
          else
            retval = this->external_PE_.add_entity (entity_name,
                                                    systemid);
          if (retval < 0)
            {
              this->fatal_error(ACE_TEXT ("Internal Parser Error")
                                ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
          else if (retval == 1)
            this->warning(ACE_TEXT ("Duplicate external entity")
                          ACEXML_ENV_ARG_PARAMETER);
          if (is_GEDecl)
            retval = this->external_GE_.add_entity (entity_name,
                                                    publicid);
          else
            retval = this->external_PE_.add_entity (entity_name,
                                                    publicid);
          if (retval < 0)
            {
              this->fatal_error(ACE_TEXT ("Internal Parser Error")
                                ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
          else if (retval == 1)
            this->warning (ACE_TEXT ("Duplicate entity definition")
                           ACEXML_ENV_ARG_PARAMETER);
        }
    }

  // End of ENTITY definition
  if (this->skip_whitespace() != '>')
    {
      this->fatal_error(ACE_TEXT ("Expecting '>' at end of entityDef")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

int ACEXML_Parser::parse_entity_reference ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a Reference.

Definition at line 2346 of file Parser.cpp.

{
  ACEXML_Char* replace = this->parse_reference_name ();
  if (replace == 0)
    {
      this->fatal_error (ACE_TEXT ("Invalid Reference name")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  //  [WFC: Parsed Entity]
  if (this->unparsed_entities_.resolve_entity (replace)) {
    this->fatal_error (ACE_TEXT ("EntityRef refers to unparsed entity")
                       ACEXML_ENV_ARG_PARAMETER);
    ACEXML_CHECK_RETURN (-1);
  }
  // Look in the internal general entities set first.
  const ACEXML_Char* entity = this->internal_GE_.resolve_entity(replace);

  // Look in the predefined entities.
  if (!entity)
    {
      entity = this->predef_entities_.resolve_entity (replace);
      if (entity)
        {
          // Special case to return the length in case of predefined entities
          this->obstack_.grow (*entity);
          return 1;
        }
    }

  if (!this->validate_)
    {
      if (this->standalone_)
        {
          // [WFC: Entity Declared]
          this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      else
        {
          this->content_handler_->skippedEntity (replace
                                                 ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          return 0;
        }
    }

  // No match in internal subset
  if (!entity
          // or No DTDs
      && (!(this->internal_dtd_ || this->external_dtd_)
          // or Only Internal DTD and no parameter entity references
          || (this->internal_dtd_ && !this->external_dtd_
              && !this->has_pe_refs_)
          // or Standalone = 'yes'
          || this->standalone_))
    {
      // [WFC: Entity Declared]
      this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char* systemId = 0;
  ACEXML_Char* publicId = 0;
  if (!entity)
    {
      if (this->external_GE_.resolve_entity (replace, systemId, publicId) < 0)
        {
          this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      if (this->ref_state_ == ACEXML_ParserInt::IN_ATT_VALUE)
        {
          this->fatal_error (ACE_TEXT ("External EntityRef in Attribute Value")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      this->external_entity_++;
    }


  // [WFC: No Recursion]
  ACEXML_Char* ref_name = replace;
  int present = this->GE_reference_.insert (ref_name);
  if (present == 1 || present == -1)
    {
      while (this->GE_reference_.pop(ref_name) != -1)
        ;
      this->fatal_error (ACE_TEXT ("Recursion in resolving entity")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  if (!this->external_entity_)
    {
      ACEXML_StrCharStream* str = 0;
      ACE_NEW_RETURN (str, ACEXML_StrCharStream, -1);
      if (str->open (entity, replace) < 0
          || this->switch_input (str, replace) != 0)
        {
          this->fatal_error (ACE_TEXT ("Unable to create internal input ")
                             ACE_TEXT ("stream")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      return 0;
    }
  else
    {
      ACEXML_Char* uri = this->normalize_systemid (systemId);
      ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
      ACEXML_InputSource* ip = 0;
      if (this->entity_resolver_)
        {
          ip = this->entity_resolver_->resolveEntity (publicId,
                                                      (uri ? uri : systemId)
                                                      ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          if (ip)
            {
              if (this->switch_input (ip, (uri ? uri : systemId),
                                      publicId) != 0)
                {
                  this->fatal_error (ACE_TEXT ("Internal Parser Error")
                                     ACEXML_ENV_ARG_PARAMETER);
                  ACEXML_CHECK_RETURN (-1);
                }
              return 0;
            }
        }
      ACEXML_StreamFactory factory;
      ACEXML_CharStream* cstream = factory.create_stream (uri ? uri: systemId);
      if (!cstream) {
        this->fatal_error (ACE_TEXT ("Invalid input source")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
      }
      if (this->switch_input (cstream, systemId, publicId) != 0)
        {
          this->fatal_error (ACE_TEXT ("Internal Parser Error")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }
  return 0;
}

int ACEXML_Parser::parse_entity_value ( ACEXML_Char *&str  ACEXML_ENV_ARG_DECL  )  [protected]

Parse an entityValue.

Definition at line 2638 of file Parser.cpp.

{
  ACEXML_ParserInt::ReferenceState temp = this->ref_state_;
  ACEXML_Char quote = this->get ();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  ACEXML_Char ch = this->get ();
  while (1)
    {
      if (ch == quote)
        {
          str = this->obstack_.freeze ();
          this->ref_state_ = temp;
          return 0;
        }
      switch (ch)
        {
          case '&':
            if (this->peek () == '#')
              {
                if (!this->external_entity_)
                  {
                    ACEXML_Char buf[7];
                    size_t len = sizeof (buf);
                    if (this->parse_char_reference (buf, len) != 0)
                      {
                        // [WFC: Legal Character]
                        this->fatal_error (ACE_TEXT ("Invalid character ")
                                           ACE_TEXT ("reference")
                                           ACEXML_ENV_ARG_PARAMETER);
                        return -1;
                      }
                    for (size_t j = 0; j < len; ++j)
                      this->obstack_.grow (buf[j]);
                    break;
                  }
              }
            this->obstack_.grow (ch);
            break;
          case '%':
            if (!this->external_entity_)
              {
                this->ref_state_ = ACEXML_ParserInt::IN_ENTITY_VALUE;
                this->parse_PE_reference(ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              }
            this->obstack_.grow (ch);
            break;
          case 0:
            this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
            break;
          default:
            this->obstack_.grow (ch);
            break;
        }
      ch = this->get();
    }
}

int ACEXML_Parser::parse_external_dtd ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse an external DTD.

Definition at line 364 of file Parser.cpp.

{
  this->ref_state_ = ACEXML_ParserInt::IN_EXT_DTD;
  ACEXML_Char* publicId = 0;
  ACEXML_Char* systemId = 0;
  if (this->parse_external_id (publicId, systemId
                               ACEXML_ENV_ARG_PARAMETER) != 0)
    {
      this->fatal_error (ACE_TEXT ("Error in parsing ExternalID")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  if (this->validate_)
    {
      ACEXML_Char* uri = this->normalize_systemid (systemId);
      ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
      ACEXML_InputSource* ip = 0;
      if (this->entity_resolver_)
        {
          ip = this->entity_resolver_->resolveEntity (publicId,
                                                      (uri ? uri : systemId)
                                                      ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      if (ip)
        {
          if (this->switch_input (ip, (uri ? uri : systemId), publicId) != 0)
            return -1;
        }
      else
        {
          ACEXML_StreamFactory factory;
          ACEXML_CharStream* cstream = factory.create_stream (uri ?
                                                              uri: systemId);
          if (!cstream) {
            this->fatal_error (ACE_TEXT ("Invalid input source")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
          if (this->switch_input (cstream, systemId, publicId) != 0)
            return -1;
        }
      this->parse_external_subset (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

int ACEXML_Parser::parse_external_id ( ACEXML_Char *&  publicId,
ACEXML_Char *&systemId  ACEXML_ENV_ARG_DECL 
) [protected]

Parse an ExternalID or a reference to PUBLIC ExternalID. Possible cases are in the forms of:

SYSTEM 'quoted string representing system resource' PUBLIC 'quoted name of public ID' 'quoted resource' PUBLIC 'quoted name we are referring to'

The first character this function sees must be either 'S' or 'P'. When the function finishes parsing, the input stream points at the first non-whitespace character.

Parameters:
publicId returns the unquoted publicId read. If none is available, it will be reset to 0.
systemId returns the unquoted systemId read. If none is available, it will be reset to 0.
Return values:
0 on success, -1 otherwise.

Definition at line 715 of file Parser.cpp.

{
  publicId = systemId = 0;
  ACEXML_Char nextch = this->get ();
  ACEXML_Char fwd = 0;
  switch (nextch)
    {
      case 'S':                   // External SYSTEM id.
        if (this->parse_token (ACE_TEXT ("YSTEM")) < 0 ||
            this->skip_whitespace_count () < 1)
          {
            this->fatal_error(ACE_TEXT ("Expecting keyword SYSTEM")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        if (this->parse_system_literal (systemId) != 0)
          {
            this->fatal_error(ACE_TEXT ("Invalid systemLiteral")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        break;
      case 'P': // External PUBLIC id or previously defined PUBLIC id.
        if (this->parse_token (ACE_TEXT ("UBLIC")) < 0 ||
            this->skip_whitespace_count () < 1)
          {
            this->fatal_error(ACE_TEXT ("Expecing keyword PUBLIC")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        if (this->parse_pubid_literal (publicId) != 0)
          {
            this->fatal_error(ACE_TEXT ("Invalid PubidLiteral")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        this->skip_whitespace_count(&fwd);
        if (fwd == '\'' || fwd == '"')
          {
            if (this->parse_system_literal (systemId) != 0)
              {
                this->fatal_error(ACE_TEXT ("Invalid systemLiteral")
                                  ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
              }
          }
        else if (this->ref_state_ != ACEXML_ParserInt::IN_NOTATION)
          {
            this->fatal_error(ACE_TEXT ("Expecting systemLiteral after a ")
                              ACE_TEXT ("PUBLIC keyword")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        break;
      default:
        this->fatal_error(ACE_TEXT ("Invalid system/public Literal")
                          ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

int ACEXML_Parser::parse_external_subset ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse an external subset. This does the actual parsing of an external subset and is called by

See also:
parse_external_dtd.

Definition at line 414 of file Parser.cpp.

{
  this->ref_state_ = ACEXML_ParserInt::IN_EXT_DTD;
  this->external_subset_ = 1;
  size_t nrelems = 0;
  ACEXML_Char nextch = this->skip_whitespace();
  do {
    switch (nextch)
      {
        case '<':
          nextch = this->get();
          switch (nextch)
            {
              case '!':
                nextch = this->peek();
                if (nextch == '[')
                  this->parse_conditional_section (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                else
                  this->parse_markup_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              case '?':
                nextch = this->peek();
                if (nextch == 'x')
                  this->parse_text_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                else
                  this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              default:
                this->fatal_error (ACE_TEXT ("Invalid content in external DTD")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
            }
          break;
        case '%':
          this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          break;
        case 0:
          nrelems = this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          if (nrelems == 1)
            return 0;
          break;
        default:
          this->fatal_error (ACE_TEXT ("Invalid content in external DTD")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
      }
    nextch = this->skip_whitespace();
  } while (1);
}

int ACEXML_Parser::parse_ignoresect ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a ignoreSect declaration.

Definition at line 546 of file Parser.cpp.

{
  ACEXML_Char nextch = this->skip_whitespace();
  int count = 0;
  int done = 0;
  do {
    switch (nextch)
      {
        case '<':
          if (this->peek() == '!')
            {
              this->get();
              if (this->peek() == '[')
                {
                  this->get();
                  count++;
                }
            }
          break;
        case ']':
          if (this->peek() == ']')
            {
              this->get();
              if (this->peek() == '>')
                {
                  this->get();
                  if (count)
                    {
                      --count;
                      break;
                    }
                  done = 1;
                }
            }
          break;
        case 0: // [VC: Proper Conditional Section/PE Nesting]
          if (count != 0)
            {
              this->fatal_error (ACE_TEXT ("Invalid Conditional Section/PE ")
                                 ACE_TEXT ("Nesting ")
                                 ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
        default:
          break;
      }
    if (done)
      break;
    nextch = this->get();
  } while (1);

  return 0;
}

int ACEXML_Parser::parse_includesect ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a includeSect declaration.

Definition at line 601 of file Parser.cpp.

{
  ACEXML_Char nextch = this->skip_whitespace();
  do {
    switch (nextch)
      {
        case '<':
          nextch = this->get();
          switch (nextch)
            {
              case '!':
                nextch = this->peek();
                if (nextch == '[')
                  this->parse_conditional_section (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                else
                  this->parse_markup_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              case '?':
                nextch = this->peek();
                this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              default:
                this->fatal_error (ACE_TEXT ("Invalid includeSect")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
            }
          break;
        case '%':
          this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          break;
        case 0: // [VC: Proper Conditional Section/PE Nesting]
          this->fatal_error (ACE_TEXT ("Invalid Conditional Section/PE ")
                             ACE_TEXT ("Nesting ")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        case ']':
          if (this->peek() == ']')
            {
              nextch = this->get();
              if (this->peek() == '>')
                {
                  nextch = this->get();
                  return 0;
                }
            }
        default:
          this->fatal_error (ACE_TEXT ("Invalid includeSect")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
      }
    nextch = this->skip_whitespace();
  } while (1);
}

int ACEXML_Parser::parse_internal_dtd ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a "markupdecl" section, this includes both "markupdecl" and "DeclSep" sections in XML specification

Definition at line 310 of file Parser.cpp.

{
  this->ref_state_ = ACEXML_ParserInt::IN_INT_DTD;
  ACEXML_Char nextch = this->skip_whitespace ();
  do {
    switch (nextch)
      {
        case '<':
          nextch = this->get();
          switch (nextch)
            {
              case '!':
                this->parse_markup_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              case '?':
                this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
              default:
                this->fatal_error (ACE_TEXT ("Invalid internal subset")
                                   ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                break;
            }
          break;
        case '%':
          this->has_pe_refs_ = 1;
          this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          break;
        case ']':                 // End of internal definitions.
          return 0;
        case '&':
          this->fatal_error (ACE_TEXT ("Invalid Reference in internal DTD")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          break;
        case 0:
          this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
          break;
        default:
          this->fatal_error (ACE_TEXT ("Invalid content in internal subset")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
      };
    nextch = this->skip_whitespace ();
  } while (1);

  ACE_NOTREACHED (return -1);
}

int ACEXML_Parser::parse_markup_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a markupDecl section.

Definition at line 659 of file Parser.cpp.

{
  ACEXML_Char nextch = this->peek ();
  switch (nextch)
    {
      case 'E':         // An ELEMENT or ENTITY decl
        this->get ();
        nextch = this->peek ();
        switch (nextch)
          {
            case 'L':
              this->parse_element_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
              break;
            case 'N':
              this->parse_entity_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
              break;
            default:
              this->fatal_error(ACE_TEXT ("Expecting keyword ELEMENT/ENTITY")
                                ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
          }
        break;

      case 'A':         // An ATTLIST decl
        this->parse_attlist_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;

      case 'N':         // A NOTATION decl
        this->parse_notation_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;

      case '-':         // a comment.
        if (this->parse_comment () < 0)
          {
            this->fatal_error(ACE_TEXT ("Invalid comment")
                              ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
        break;
      case 0: //  [VC: Proper Declaration/PE Nesting]
        this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
      default:
        this->fatal_error (ACE_TEXT ("Invalid markupDecl")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

ACEXML_Char * ACEXML_Parser::parse_name ( ACEXML_Char  ch = 0  )  [protected]

Parse a name from the input CharStream. If ch @!= 0, then we have already consumed the first name character from the input CharStream, otherwise, parse_name will use this->get() to acquire the initial character.

Returns:
A pointer to the string in the obstack, 0 if it's not a valid name.

Definition at line 2701 of file Parser.cpp.

{
  if (ch == 0)
    ch = this->get ();
  if (!this->isLetter (ch) && ch != '_' && ch != ':')
    return 0;
  while (ch) {
    this->obstack_.grow (ch);
    ch = this->peek ();
    if (!this->isNameChar (ch))
      break;
    ch = this->get ();
  };
  return this->obstack_.freeze ();
}

ACEXML_Char * ACEXML_Parser::parse_nmtoken ( ACEXML_Char  ch = 0  )  [protected]

Parse a NMTOKEN from the input stream.

Returns:
A pointer to the string in the obstack, 0 if it's not a valid NMTOKEN.

Definition at line 2718 of file Parser.cpp.

{
  if (ch == 0)
    ch = this->get ();
  if (!this->isNameChar (ch))
    return 0;
  while (ch) {
    this->obstack_.grow (ch);
    ch = this->peek ();
    if (!this->isNameChar (ch))
      break;
    ch = this->get ();
  };
  return this->obstack_.freeze ();
}

int ACEXML_Parser::parse_notation_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a "NOTATION" decl. The first character this method expects is always the 'N' (the first char) in the word "NOTATION".

Return values:
0 on success, -1 otherwise.

Definition at line 1824 of file Parser.cpp.

{
  if (this->parse_token (ACE_TEXT ("NOTATION")) < 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting Keyword 'NOTATION'")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  if (!count)
    {
      this->fatal_error (ACE_TEXT ("Expecting a space between keyword NOTATION")
                         ACE_TEXT (" and notation name")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  ACEXML_Char *notation = this->parse_name ();
  if (notation == 0)
    {
      this->fatal_error(ACE_TEXT ("Invalid Notation name")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  if (!count)
    {
      this->fatal_error (ACE_TEXT ("Expecting a space between notation name ")
                         ACE_TEXT ("and ExternalID/PublicID")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char *systemid, *publicid;

  // Gross hack but otherwise we need to go around a lot of loops to parse,
  // When the ExternalID starts with 'PUBLIC' we cannot distinguish a
  // PublicId from a ExternalID by looking using a one character read-ahead
  ACEXML_ParserInt::ReferenceState temp = this->ref_state_;
  this->ref_state_ = ACEXML_ParserInt::IN_NOTATION;

  this->parse_external_id (publicid, systemid
                           ACEXML_ENV_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  // Restore the original value.
  this->ref_state_ = temp;

  // [VC: Unique Notation Name]
  if (systemid && this->notations_.add_entity (notation, systemid) != 0
      && this->validate_)
    {
      this->fatal_error(ACE_TEXT ("Internal Parser Error")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  if (publicid)
    {
      int retval = this->notations_.add_entity (notation, publicid);
      if (retval != 0 && !systemid && this->validate_)
        {
          this->fatal_error(ACE_TEXT ("Internal Parser Error")
                            ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }

  if (this->skip_whitespace() != '>')
    {
      this->fatal_error(ACE_TEXT ("Expecting '>' at end of NotationDecl")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  if (this->validate_ && this->dtd_handler_)
    {
      this->dtd_handler_->notationDecl (notation,
                                        publicid,
                                        systemid ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  return 0;
}

int ACEXML_Parser::parse_PE_reference ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a PEReference.

Definition at line 2498 of file Parser.cpp.

{
  ACEXML_Char* replace = this->parse_reference_name ();
  if (replace == 0)
    {
      this->fatal_error (ACE_TEXT ("Invalid PEReference name")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  // Look in the internal general entities set first.
  const ACEXML_Char* entity = this->internal_PE_.resolve_entity(replace);

  if (!entity &&                     // No match in internal
      (!this->external_dtd_ ||       // or No External DTDs
       this->standalone_))           // or Standalone
    {
      // [VC: Entity Declared]
      this->fatal_error (ACE_TEXT ("Undefined Internal PEReference")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char* systemId = 0;
  ACEXML_Char* publicId = 0;
  if (!entity && this->validate_)
    {
      if (this->external_PE_.resolve_entity (replace, systemId, publicId) < 0)
        {
          this->fatal_error (ACE_TEXT ("Undefined PEReference")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      this->external_entity_++;
    }

  // [WFC: No Recursion]
  ACEXML_Char* ref_name = replace;
  int present = this->PE_reference_.insert (ref_name);
  if (present == 1 || present == -1)
    {
      while (this->PE_reference_.pop(ref_name) != -1)
        ;
      this->fatal_error (ACE_TEXT ("Recursion in resolving entity")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  if (entity && !this->external_entity_)
    {
      ACEXML_StrCharStream* sstream = 0;
      ACEXML_String str (entity);
      if (this->ref_state_ != ACEXML_ParserInt::IN_ENTITY_VALUE)
        {
          const ACEXML_Char* ch = ACE_TEXT (" ");
          str = ch + str + ch;
        }
      //  ACE_DEBUG ((LM_DEBUG,
      //             ACE_TEXT ("Entity is %s\n Replacement Text is : %s\n"),
      //             replace, str.c_str()));
      ACE_NEW_RETURN (sstream, ACEXML_StrCharStream, -1);
      if (sstream->open (str.c_str(), replace) < 0
          || this->switch_input (sstream, replace) != 0)
        {
          this->fatal_error (ACE_TEXT ("Error in switching InputSource")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      return 0;
    }
  else if (this->external_entity_ && this->validate_)
    {
      ACEXML_Char* uri = this->normalize_systemid (systemId);
      ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
      ACEXML_InputSource* ip = 0;
      if (this->entity_resolver_)
        {
          ip = this->entity_resolver_->resolveEntity (publicId,
                                                      (uri ? uri : systemId)
                                                      ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
      if (ip)
        {
          if (this->switch_input (ip, (uri ? uri : systemId), publicId) != 0)
            {
              this->fatal_error (ACE_TEXT ("Error in switching InputSource")
                                 ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
          return 0;
        }
      else
        {
          ACEXML_StreamFactory factory;
          ACEXML_CharStream* cstream = factory.create_stream (uri ? uri: systemId);
          if (!cstream) {
            this->fatal_error (ACE_TEXT ("Invalid input source")
                               ACEXML_ENV_ARG_PARAMETER);
            ACEXML_CHECK_RETURN (-1);
          }
          if (this->switch_input (cstream, systemId, publicId) != 0)
            {
              this->fatal_error (ACE_TEXT ("Error in switching InputSource")
                                 ACEXML_ENV_ARG_PARAMETER);
              ACEXML_CHECK_RETURN (-1);
            }
          if (this->ref_state_ == ACEXML_ParserInt::IN_ENTITY_VALUE)
            {
              ACEXML_Char less, mark;
              if (this->peek() == '<')
                {
                  less = this->get();
                  if (this->peek() == '?')
                    {
                      mark = this->get();
                      if (this->peek() == 'x')
                        {
                          this->parse_text_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
                          ACEXML_CHECK_RETURN (-1);
                        }
                      else
                        {
                          this->obstack_.grow (less);
                          this->obstack_.grow (mark);
                        }
                    }
                  this->obstack_.grow (less);
                }
            }
          return 0;
        }
    }
  this->fatal_error (ACE_TEXT ("Undefined PEReference")
                     ACEXML_ENV_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  return -1;
}

int ACEXML_Parser::parse_processing_instruction ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a PI statement. The first character encountered should always be '?' in the PI prefix "@<?".

Return values:
0 on success, -1 otherwise.

Definition at line 3272 of file Parser.cpp.

{
  const ACEXML_Char *pitarget = this->parse_name ();
  ACEXML_Char *instruction = 0;

  if (!ACE_OS::strcasecmp (ACE_TEXT ("xml"), pitarget))
    {
      // Invalid PITarget name.
      this->fatal_error(ACE_TEXT ("PI can't have 'xml' in PITarget")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  int state = 0;

  ACEXML_Char ch = this->skip_whitespace();
  while (state < 2)
    {
      switch (ch)
        {
          case '?':
            if (state == 0)
              state = 1;
            break;
          case '>':
            if (state == 1)
              {
                instruction = this->obstack_.freeze ();
                this->content_handler_->processingInstruction (pitarget,
                                                               instruction
                                                               ACEXML_ENV_ARG_PARAMETER);
                ACEXML_CHECK_RETURN (-1);
                this->obstack_.unwind (const_cast<ACEXML_Char*> (pitarget));
                return 0;
              }
            break;
          case 0x0A:
            // Fall thru...
          default:
            if (state == 1)
              this->obstack_.grow ('?');
            this->obstack_.grow (ch);
            state = 0;
        }
      ch = this->get ();
    }
  return -1;
}

int ACEXML_Parser::parse_pubid_literal ( ACEXML_Char *&  str  )  [protected]

Parse a PubidLiteral.

Parameters:
str String containing the PubidLiteral if successful.
Returns:
0 if the string was read successfully, 0 otherwise.

Definition at line 2799 of file Parser.cpp.

{
  const ACEXML_Char quote = this->get();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  while (1)
    {
      ACEXML_Char ch = this->get ();
      if (ch == quote)
        {
          str = this->obstack_.freeze ();
          return 0;
        }
      else if (this->isPubidChar (ch))
        this->obstack_.grow (ch);
      else
        return -1;
    }
}

ACEXML_Char * ACEXML_Parser::parse_reference_name ( void   )  [protected]

Parse a reference name, i.e., foo in "&foo;" or "%foo;". The first character encountered should be the character following '&' or ''. Effectively the same as

See also:
parse_name but we don't use the parser's obstack. Caller is responsible for deleting the memory.
Return values:
A pointer to name of reference, 0 otherwise.

Definition at line 2244 of file Parser.cpp.

{
  ACEXML_Char ch = this->get ();
  if (!this->isLetter (ch) && (ch != '_' || ch != ':'))
    return 0;
  while (ch) {
    this->alt_stack_.grow (ch);
    ch = this->peek ();
    if (!this->isNameChar (ch))
      break;
    ch = this->get ();
  };
  if (ch != ';')
    return 0;
  ch = this->get();
  return this->alt_stack_.freeze ();
}

int ACEXML_Parser::parse_sddecl ( ACEXML_Char *&  str  )  [protected]

Parse a SDDecl string.

Parameters:
str String containing the encoding name if successful.
Returns:
0 if the string was read successfully, -1 otherwise.

Definition at line 2854 of file Parser.cpp.

{
  ACEXML_Char quote = this->get ();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  int numchars = 0;
  while (1)
    {
      ACEXML_Char ch = this->get ();
      if (ch == quote && numchars < 2)
        return -1;
      else if (ch == quote)
        {
          str = this->obstack_.freeze ();
          return 0;
        }
      // [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
      //                                   | ('"' ('yes' | 'no') '"'))
      switch (ch)
        {
          case 'y': case 'e': case 's': case 'n': case 'o':
            this->obstack_.grow (ch);
            numchars++;
            break;
          default:
            return -1;
        }
    }
}

int ACEXML_Parser::parse_system_literal ( ACEXML_Char *&  str  )  [protected]

Parse a SystemLiteral.

Parameters:
str String containing the SystemLiteral if successful.
Returns:
0 if the string was read successfully, 0 otherwise.

Definition at line 2766 of file Parser.cpp.

{
  const ACEXML_Char quote = this->get();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  while (1)
    {
      ACEXML_Char ch = this->get ();
      if (ch == quote)
        {
          str = this->obstack_.freeze ();
          return 0;
        }
      switch (ch)
        {
          case '\x00': case '\x01': case '\x02': case '\x03': case '\x04':
          case '\x05': case '\x06': case '\x07': case '\x08': case '\x09':
          case '\x0A': case '\x0B': case '\x0C': case '\x0D': case '\x0E':
          case '\x0F': case '\x10': case '\x11': case '\x12': case '\x13':
          case '\x14': case '\x15': case '\x16': case '\x17': case '\x18':
          case '\x19': case '\x1A': case '\x1B': case '\x1C': case '\x1D':
          case '\x1E': case '\x1F': case '\x7F': case '\x20': case '<':
          case '>': case '#': case '%':
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("Invalid char %c in SystemLiteral\n"), ch));
            return -1;
          default:
            this->obstack_.grow (ch);
        }
    }
}

int ACEXML_Parser::parse_text_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a TextDecl declaration.

Definition at line 3152 of file Parser.cpp.

{
  // Read xml
  if (this->parse_token (ACE_TEXT("xml")) < 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting keyword 'xml' in TextDecl")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Char fwd = this->skip_whitespace();
  // Read version
  if (fwd == 'v')
    {
      this->parse_version_info (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      fwd = this->skip_whitespace();
    }

  if (fwd == 'e')
    {
      this->parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
      fwd = this->skip_whitespace();
    }
  else
    {
      this->fatal_error (ACE_TEXT ("Missing encodingDecl in TextDecl")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  if (fwd == '?' && this->get() == '>')
    return 0;
  // All the rules fail. So return an error.
  this->fatal_error (ACE_TEXT ("Invalid TextDecl") ACEXML_ENV_ARG_PARAMETER);
  ACEXML_CHECK_RETURN (-1);
  return -1;
}

ACEXML_INLINE int ACEXML_Parser::parse_token ( const ACEXML_Char keyword  )  [private]

Parse a keyword.

Definition at line 248 of file Parser.inl.

{
  if (keyword == 0)
    return -1;
  const ACEXML_Char* ptr = keyword;
  for (; *ptr != 0 && (this->get() == *ptr); ++ptr)
    ;
  if (*ptr == 0)
  return 0;
  else
    return -1;
}

int ACEXML_Parser::parse_tokenized_type ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a tokenized type attribute.

Returns:
0 if attribute type was read successfully, -1 otherwise.

Definition at line 1581 of file Parser.cpp.

{
  ACEXML_Char ch = this->get();
  switch (ch)
    {
      case 'I':
        if (this->get () == 'D')
          {
            if (this->peek() != 'R' && this->is_whitespace (this->peek()))
              {
                // We have successfully identified the type of the
                // attribute as ID
                // @@ Set up validator as such.
                break;
              }
            if (this->parse_token (ACE_TEXT ("REF")) == 0)
              {
                if (this->peek() != 'S' && this->is_whitespace (this->peek()))
                  {
                    // We have successfully identified the type of
                    // the attribute as IDREF
                    // @@ Set up validator as such.
                    break;
                  }
                else if (this->peek() == 'S'
                         && this->get() // consume the 'S'
                         && this->is_whitespace (this->peek()))
                  {
                    // We have successfully identified the type of
                    // the attribute as IDREFS
                    // @@ Set up validator as such.
                    break;
                  }
              }
          }
        // Admittedly, this error message is not precise enough
        this->fatal_error(ACE_TEXT ("Expecting keyword `ID', `IDREF', or")
                          ACE_TEXT ("`IDREFS'") ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
      case 'E':               // ENTITY or ENTITIES
        if (this->parse_token (ACE_TEXT ("NTIT")) == 0)
          {
            ACEXML_Char nextch = this->get ();
            if (nextch == 'Y')
              {
                // We have successfully identified the type of
                // the attribute as ENTITY
                // @@ Set up validator as such.
              }
            else if (this->parse_token (ACE_TEXT ("IES")) == 0)
              {
                // We have successfully identified the type of
                // the attribute as ENTITIES
                // @@ Set up validator as such.
              }
            if (this->is_whitespace (this->peek()))
              {
                // success
                break;
              }
          }
        // Admittedly, this error message is not precise enough
        this->fatal_error(ACE_TEXT ("Expecting keyword `ENTITY', or")
                          ACE_TEXT ("`ENTITIES'") ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
      case 'M':
        if (this->parse_token (ACE_TEXT ("TOKEN")) == 0)
          {
            if (this->is_whitespace (this->peek()))
              {
                // We have successfully identified the type of
                // the attribute as NMTOKEN
                // @@ Set up validator as such.
                break;
              }
            else if (this->peek() == 'S'
                     && this->get()
                     && this->is_whitespace (this->peek()))
              {
                // We have successfully identified the type of
                // the attribute as NMTOKENS
                // @@ Set up validator as such.
                break;
              }
          }
        this->fatal_error(ACE_TEXT ("Expecting keyword `NMTOKEN' or `NMTO")
                          ACE_TEXT ("KENS'") ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;
      default:
        this->fatal_error (ACE_TEXT ("Internal Parser Error")
                           ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK_RETURN (-1);
        break;
    }
  return 0;
}

int ACEXML_Parser::parse_version ( ACEXML_Char *&  str  )  [protected]

Parse the version string in an XML Prolog section.

Parameters:
str String containing the version number if successful.
Returns:
0 if the string was read successfully, 0 otherwise.
void ACEXML_Parser::parse_version_info ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse VersionInfo declaration.

Definition at line 3109 of file Parser.cpp.

{
  ACEXML_Char* astring;
  if (this->parse_token (ACE_TEXT("ersion")) < 0
      || this->skip_equal () != 0
      || this->parse_version_num (astring) != 0)
    {
      this->fatal_error (ACE_TEXT ("Invalid VersionInfo specification")
                         ACEXML_ENV_ARG_PARAMETER);
      return;
    }
  if (ACE_OS::strcmp (astring, ACE_TEXT ("1.0")) != 0)
    {
      this->fatal_error (ACE_TEXT ("ACEXML Parser supports XML version 1.0 ")
                         ACE_TEXT ("documents only") ACEXML_ENV_ARG_PARAMETER);
      return;
    }
}

int ACEXML_Parser::parse_version_num ( ACEXML_Char *&  str  )  [protected]

Parse the version number in a VersionInfo declaration.

Definition at line 2735 of file Parser.cpp.

{
  ACEXML_Char quote = this->get ();
  if (quote != '\'' && quote != '"')  // Not a quoted string.
    return -1;
  int numchars = 0;
  while (1)
    {
      ACEXML_Char ch = this->get ();
      if (ch == quote && !numchars)
        return -1;
      else if (ch == quote)
        {
          str = this->obstack_.freeze ();
          return 0;
        }
      // [26]    VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
      if (ch == '-' || ((ch >= 'a' && ch <= 'z') ||
                        (ch >= 'A' && ch <= 'Z') ||
                        (ch >= '0' && ch <= '9') ||
                        (ch == '_' || ch == '.' || ch == ':')))
        {
          this->obstack_.grow (ch);
          numchars++;
        }
      else
        return -1;
    }
}

void ACEXML_Parser::parse_xml_decl ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse a XMLDecl declaration.

Definition at line 3193 of file Parser.cpp.

{
  // Read <?xml
  if (this->parse_token (ACE_TEXT("xml")) < 0)
    {
      this->fatal_error(ACE_TEXT ("Expecting keyword xml in XMLDecl")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }

  ACEXML_Char fwd = this->skip_whitespace();

  // Read version
  if (fwd != 'v')
    {
      this->fatal_error (ACE_TEXT ("Expecting VersionInfo declaration")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK;
    }

  this->parse_version_info (ACEXML_ENV_SINGLE_ARG_PARAMETER);
  ACEXML_CHECK;

  fwd = this->skip_whitespace();
  if (fwd != '?')
    {
      if (fwd == 'e')
        {
          this->parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
          ACEXML_CHECK;
          fwd = this->skip_whitespace();
        }
      if (fwd == 's')
        {
          ACEXML_Char* astring;
          if ((this->parse_token (ACE_TEXT("tandalone")) == 0) &&
              this->skip_equal () == 0 &&
              this->parse_sddecl (astring) == 0)
            {
              if (ACE_OS::strcmp (astring, ACE_TEXT ("yes")) == 0)
                this->standalone_ = 1;
              fwd = this->skip_whitespace();
            }
        }
    }
  if (fwd == '?' && this->get() == '>')
    return;
  // All the rules fail. So return an error.
  this->fatal_error (ACE_TEXT ("Invalid XMLDecl declaration")
                     ACEXML_ENV_ARG_PARAMETER);
  ACEXML_CHECK;
}

void ACEXML_Parser::parse_xml_prolog ( ACEXML_ENV_SINGLE_ARG_DECL   )  [protected]

Parse XML Prolog.

ACEXML_INLINE ACEXML_Char ACEXML_Parser::peek ( void   )  [protected, virtual]

Peek a character.

Definition at line 236 of file Parser.inl.

{
  // Using an extra level of indirection so we can
  // manage document location in the future.
  ACEXML_Char ch = 0;
  const ACEXML_InputSource* ip = this->current_->getInputSource();
  ACEXML_CharStream* instream = ip->getCharStream();
  ch = static_cast<ACEXML_Char> (instream->peek ());
  return (ch > 0 ? ch : 0);
}

size_t ACEXML_Parser::pop_context ( int GE_ref  ACEXML_ENV_ARG_DECL  )  [private]

Pop the top element in the stack and replace current context with that.

Definition at line 2950 of file Parser.cpp.

{
  size_t nrelems = this->ctx_stack_.size();
  if (nrelems <= 1)
    {
      this->fatal_error(ACE_TEXT ("Unexpected end-of-file")
                        ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }

  ACEXML_Parser_Context* temp = 0;
  int retval = this->ctx_stack_.pop (temp);
  if (retval != 0)
    {
      this->fatal_error (ACE_TEXT ("Unable to pop element of the input stack")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  delete temp;
  if (this->ctx_stack_.top (this->current_) != 0)
    {
      this->fatal_error (ACE_TEXT ("Unable to read top element of input stack")
                         ACEXML_ENV_ARG_PARAMETER);
      ACEXML_CHECK_RETURN (-1);
    }
  ACEXML_Char* reference = 0;
  if (GE_ref == 1 && this->GE_reference_.size() > 0)
    {
      if (this->GE_reference_.pop (reference) < 0)
        {
          this->fatal_error (ACE_TEXT ("Internal Parser Error")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }
  else if (GE_ref == 0 && this->PE_reference_.size() > 0)
    {
      if (this->PE_reference_.pop (reference) < 0)
        {
          this->fatal_error (ACE_TEXT ("Internal Parser Error")
                             ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK_RETURN (-1);
        }
    }
  nrelems = this->ctx_stack_.size();

  if (this->external_entity_ && (GE_ref == 0 || GE_ref == 1))
    this->external_entity_--;

  this->content_handler_->setDocumentLocator (this->current_->getLocator());

  return nrelems;
}

void ACEXML_Parser::prefix_mapping ( const ACEXML_Char prefix,
const ACEXML_Char uri,
int start  ACEXML_ENV_ARG_DECL 
) [private]

Dispatch prefix mapping calls to the ContentHandler.

Parameters:
prefix Namespace prefix
uri Namespace URI
name Local name
start 1 => startPrefixMapping 0 => endPrefixMapping

Definition at line 2885 of file Parser.cpp.

{
  if (this->namespaces_)
    {
      const ACEXML_Char* temp = (prefix == 0) ? empty_string : prefix;
      if (start) {
        this->content_handler_->startPrefixMapping (temp, uri
                                                    ACEXML_ENV_ARG_PARAMETER);
        ACEXML_CHECK;
      }
      else
        {
          this->content_handler_->endPrefixMapping(temp
                                                   ACEXML_ENV_ARG_PARAMETER);
          ACEXML_CHECK;
        }
    }
}

int ACEXML_Parser::push_context ( ACEXML_Parser_Context context  )  [private]

Push the current context on to the stack.

Definition at line 2939 of file Parser.cpp.

{
  if (this->ctx_stack_.push (context) < 0)
    {
      ACE_ERROR ((LM_ERROR, "Unable to push input source onto the stack"));
      return -1;
    }
  return 0;
}

void ACEXML_Parser::reset ( void   )  [private]

Reset the parser state.

Definition at line 3322 of file Parser.cpp.

{
  this->doctype_ = 0;
  if (this->ctx_stack_.pop (this->current_) == -1)
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("Mismatched push/pop of Context stack")));
  if (this->current_)
    {
      this->current_->getInputSource()->getCharStream()->rewind();

      this->current_->setInputSource (0);
      delete this->current_;
      this->current_ = 0;
    }

  ACEXML_Char* temp = 0;
  while (this->GE_reference_.pop (temp) != -1)
    ;
  while (this->PE_reference_.pop (temp) != -1)
    ;
  this->obstack_.release();
  this->alt_stack_.release();
  this->xml_namespace_.reset();
  this->nested_namespace_ = 0;
  this->internal_GE_.reset();
  this->external_GE_.reset();
  this->unparsed_entities_.reset();
  this->predef_entities_.reset();
  this->internal_PE_.reset();
  this->external_PE_.reset();
  this->notations_.reset();
  this->ref_state_ = ACEXML_ParserInt::INVALID;
  this->external_subset_ = 0;
  this->external_entity_ = 0;
  this->has_pe_refs_ = 0;
  this->standalone_ = 0;
  this->external_dtd_ = 0;
  this->internal_dtd_ = 0;
}

ACEXML_INLINE void ACEXML_Parser::setContentHandler ( ACEXML_ContentHandler handler  )  [virtual]

Allow an application to register a content event handler.

Implements ACEXML_XMLReader.

Definition at line 36 of file Parser.inl.

{
  this->content_handler_ = handler;
}

ACEXML_INLINE void ACEXML_Parser::setDTDHandler ( ACEXML_DTDHandler handler  )  [virtual]

Allow an application to register a DTD event handler.

Implements ACEXML_XMLReader.

Definition at line 42 of file Parser.inl.

{
  this->dtd_handler_ = handler;
}

ACEXML_INLINE void ACEXML_Parser::setEntityResolver ( ACEXML_EntityResolver resolver  )  [virtual]

Allow an application to register an entity resolver.

Implements ACEXML_XMLReader.

Definition at line 48 of file Parser.inl.

{
  this->entity_resolver_ = resolver;
}

ACEXML_INLINE void ACEXML_Parser::setErrorHandler ( ACEXML_ErrorHandler handler  )  [virtual]

Allow an application to register an error event handler.

Implements ACEXML_XMLReader.

Definition at line 54 of file Parser.inl.

{
  this->error_handler_ = handler;
}

void ACEXML_Parser::setFeature ( const ACEXML_Char name,
int boolean_value  ACEXML_ENV_ARG_DECL 
) [virtual]

Activating or deactivating a feature.

Implements ACEXML_XMLReader.

Definition at line 3030 of file Parser.cpp.

{
  if (ACE_OS::strcmp (name, ACEXML_Parser::simple_parsing_feature_) == 0)
    {
      this->simple_parsing_ = (boolean_value == 0 ? 0 : 1);
      return;
    }
  else if (ACE_OS::strcmp (name, ACEXML_Parser::namespaces_feature_) == 0)
    {
      this->namespaces_ = (boolean_value == 0 ? 0 : 1);
      return;
    }
  else if (ACE_OS::strcmp (name,
                           ACEXML_Parser::namespace_prefixes_feature_) == 0)
    {
      this->namespace_prefixes_ = (boolean_value == 0 ? 0 : 1);
      return;
    }
  else if (ACE_OS::strcmp (name, ACEXML_Parser::validation_feature_) == 0)
    {
      this->validate_ = (boolean_value == 0 ? 0 : 1);
      return;
    }

  ACEXML_THROW (ACEXML_SAXNotRecognizedException (name));
}

void ACEXML_Parser::setProperty ( const ACEXML_Char name,
void *value  ACEXML_ENV_ARG_DECL 
) [virtual]

Set the value of a property.

Implements ACEXML_XMLReader.

Definition at line 3065 of file Parser.cpp.

{
  ACE_UNUSED_ARG (value);

  ACEXML_THROW (ACEXML_SAXNotSupportedException (name));
}

ACEXML_INLINE int ACEXML_Parser::skip_equal ( void   )  [private]

Skip an equal sign.

Return values:
0 when succeeds, -1 if no equal sign is found.

Definition at line 198 of file Parser.inl.

{
  if (this->skip_whitespace() != '=')
    return -1;
  while (this->is_whitespace (this->peek()))
    this->get();
  return 0;
}

ACEXML_INLINE ACEXML_Char ACEXML_Parser::skip_whitespace ( void   )  [private]

Skip any whitespaces encountered until the first non-whitespace character is encountered.

Returns:
The next non-whitespace character from the CharStream.
See also:
skip_whitespace_count

Definition at line 176 of file Parser.inl.

{
  ACEXML_Char ch = this->get();
  while (this->is_whitespace (ch))
    ch = this->get ();
  return ch;
}

ACEXML_INLINE int ACEXML_Parser::skip_whitespace_count ( ACEXML_Char peek = 0  )  [private]

Skip any whitespaces encountered until the first non-whitespace character. The first non-whitespace character is not consumed. This method does peek into the input CharStream and therefore is more expensive than skip_whitespace.

Parameters:
peek If non-null, peek points to a ACEXML_Char where skip_whitespace_count stores the first non-whitespace character it sees (character is not removed from the stream.)
Returns:
The number of whitespace characters consumed.
See also:
skip_whitespace

Definition at line 186 of file Parser.inl.

{
  int wscount = 0;
  ACEXML_Char dummy;
  ACEXML_Char &forward = (peeky == 0 ? dummy : *peeky);

  for (;this->is_whitespace ((forward = this->peek ())); ++wscount)
    this->get ();
  return wscount;
}

int ACEXML_Parser::switch_input ( ACEXML_CharStream cstream,
const ACEXML_Char systemId,
const ACEXML_Char publicId = 0 
) [private, virtual]

Create a new ACEXML_CharStream from systemId and publicId and replace the current input stream with the newly created stream.

Definition at line 2907 of file Parser.cpp.

{
  ACEXML_InputSource* input = 0;
  ACE_NEW_RETURN (input, ACEXML_InputSource (cstream), -1);
  return this->switch_input (input, systemId, publicId);
}

int ACEXML_Parser::switch_input ( ACEXML_InputSource input,
const ACEXML_Char systemId,
const ACEXML_Char publicId = 0 
) [private, virtual]

Create a new ACEXML_InputSource from systemId and publicId and replace the current input source with the newly created InputSource.

Definition at line 2917 of file Parser.cpp.

{
  ACEXML_LocatorImpl* locator = 0;
  if (!systemId)
    systemId = input->getSystemId();
  ACE_NEW_RETURN (locator, ACEXML_LocatorImpl (systemId, publicId), -1);
  ACEXML_Parser_Context* new_context = 0;
  ACE_NEW_RETURN (new_context, ACEXML_Parser_Context(input, locator), -1);
  if (this->push_context (new_context) != 0)
    {
      ACE_ERROR ((LM_ERROR, "Unable to switch input streams"));
      delete new_context;
      return -1;
    }
  this->current_ = new_context;
  this->content_handler_->setDocumentLocator (this->current_->getLocator());
  return 0;
}

void ACEXML_Parser::warning ( const ACEXML_Char *msg  ACEXML_ENV_ARG_DECL  )  [private]

Dispatch warnings to ErrorHandler.

Definition at line 3086 of file Parser.cpp.

{
  ACEXML_SAXParseException* exception = 0;
  ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
  if (this->error_handler_)
    this->error_handler_->warning (*exception ACEXML_ENV_ARG_PARAMETER);
  delete exception;
  return;
}


Member Data Documentation

Alternative obstack used to hold any strings when the original is in use.

Definition at line 786 of file Parser.h.

Definition at line 757 of file Parser.h.

Stack used to hold the Parser_Context.

Definition at line 767 of file Parser.h.

Current parser context.

Definition at line 764 of file Parser.h.

Document Type.

Definition at line 761 of file Parser.h.

Keeping track of the handlers. We do not manage the memory for handlers.

Definition at line 755 of file Parser.h.

Definition at line 756 of file Parser.h.

Definition at line 758 of file Parser.h.

If set, the document has an external DTD subset.

Definition at line 831 of file Parser.h.

T => We are parsing an external entity value.

Definition at line 822 of file Parser.h.

Set of external parsed general entities in the document.

Definition at line 798 of file Parser.h.

Set of external parsed parameter entities in the document.

Definition at line 810 of file Parser.h.

T => We are parsing an external subset.

Definition at line 819 of file Parser.h.

Set used to hold the general entity references that are active.

Definition at line 777 of file Parser.h.

T => Internal DTD has parameter entity references.

Definition at line 825 of file Parser.h.

If set, the document has an internal DTD.

Definition at line 834 of file Parser.h.

Set of internal parsed general entities in the document.

Definition at line 795 of file Parser.h.

Set of internal parsed parameter entities in the document.

Definition at line 807 of file Parser.h.

If set, the parser should include namespace declarations in the list of attributes of an element.

Definition at line 848 of file Parser.h.

If set, the parser should allow access by namespace qualified names.

Definition at line 844 of file Parser.h.

T => We are processing a nested namespace.

Definition at line 792 of file Parser.h.

Set of notations declared in the document.

Definition at line 813 of file Parser.h.

Obstack used by the parser to hold all the strings parsed.

Definition at line 783 of file Parser.h.

Set used to hold the parameter entity references that are active.

Definition at line 780 of file Parser.h.

Set of predefined entities used by the parser.

Definition at line 804 of file Parser.h.

State of the parser when it encounters a reference.

Definition at line 816 of file Parser.h.

Feature flags If set, the parser should parse a document without a prolog

Definition at line 838 of file Parser.h.

If set, the document is a standalone XML document.

Definition at line 828 of file Parser.h.

Set of unparsed entities in the document.

Definition at line 801 of file Parser.h.

int ACEXML_Parser::validate_ [private]

If set, the parser should also validate.

Definition at line 841 of file Parser.h.

Namespace stack used by the parser to implement support for Namespaces.

Definition at line 789 of file Parser.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines