You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sa...@apache.org on 2004/12/06 04:29:21 UTC

cvs commit: ws-axis/c/graveyard/src/xml/expat Makefile.am ParserLoader.cpp XMLParserExpat.cpp XMLParserExpat.h

samisa      2004/12/05 19:29:21

  Added:       c/graveyard/src/xml/expat Makefile.am ParserLoader.cpp
                        XMLParserExpat.cpp XMLParserExpat.h
  Log:
  Adding Expat based parser lib to graveyard.
  
  Revision  Changes    Path
  1.1                  ws-axis/c/graveyard/src/xml/expat/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  lib_LTLIBRARIES = libaxis_expat.la
  AM_CPPFLAGS = $(CPPFLAGS)
  libaxis_expat_la_SOURCES = XMLParserExpat.cpp ParserLoader.cpp ../AxisParseException.cpp
  
  libaxis_expat_la_LIBADD = @EXPATLIB@ -lstdc++
  INCLUDES = @EXPATINC@ -I../../../include
  
  
  
  
  1.1                  ws-axis/c/graveyard/src/xml/expat/ParserLoader.cpp
  
  Index: ParserLoader.cpp
  ===================================================================
  /*
   *   Copyright 2003-2004 The Apache Software Foundation.
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *   limitations under the License.
   */
  
  /*
   * @author Susantha Kumara (skumara@virtusa.com)
   *
   */
  
  #include "XMLParserExpat.h"
  
  extern "C" {
  STORAGE_CLASS_INFO
  int CreateInstance(XMLParser **inst)
  {
  	*inst = new XMLParserExpat();
  	if (*inst)
  	{
  		return AXIS_SUCCESS;
  	}
  	return AXIS_FAIL;
  }
  STORAGE_CLASS_INFO 
  int DestroyInstance(XMLParser *inst)
  {
  	if (inst)
  	{
  		delete inst;
  		return AXIS_SUCCESS;
  	}
  	return AXIS_FAIL;
  }
  }
  
  
  
  1.1                  ws-axis/c/graveyard/src/xml/expat/XMLParserExpat.cpp
  
  Index: XMLParserExpat.cpp
  ===================================================================
  /*
   *   Copyright 2003-2004 The Apache Software Foundation.
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *   limitations under the License.
   */
  
  /*
   * @author Susantha Kumara (skumara@virtusa.com)
   *
   */
  
  #ifdef WIN32
  #pragma warning (disable : 4786)
  #pragma warning (disable : 4101)
  #endif
  
  #include "../Event.h"
  #include "../SimpleAttribute.h"
  #include "../StartElement.h"
  
  #include "XMLParserExpat.h"
  
  #define EXPAT_BUFFER_SIZE 1024
  
  XMLParserExpat::XMLParserExpat()
  {
      m_pLastEvent = NULL;
      m_Parser = XML_ParserCreateNS(NULL, NAMESPACESEPARATOR);
      m_pCurrentBuffer = 0;
  }
  
  XMLParserExpat::~XMLParserExpat()
  {
      if (m_pLastEvent) delete m_pLastEvent;
      while (!m_Events.empty())
      {
          m_pLastEvent = m_Events.front();
          m_Events.pop();
          delete m_pLastEvent;
      }
      XML_ParserFree(m_Parser);
  }
  
  void XMLParserExpat::startElement(const XML_Ch *qname,const XML_Ch **attrs)
  {
      QName qn;
      qn.splitQNameString(qname, NAMESPACESEPARATOR);
      StartElement *pSE = new StartElement();
      pSE->m_NameOrValue = qn.localname;
      pSE->m_Namespace  = qn.uri ? qn.uri : "";
      qn.mergeQNameString(NAMESPACESEPARATOR);
      SimpleAttribute *pAt = NULL;
      for (int i = 0; attrs[i]; i += 2)
      {
          qn.splitQNameString(attrs[i], NAMESPACESEPARATOR);
          pAt = new SimpleAttribute();
          pAt->m_Name = qn.localname;
          pAt->m_Namespace = qn.uri ? qn.uri : "";
          qn.mergeQNameString(NAMESPACESEPARATOR);
          pAt->m_Value = attrs[i+1];
          pSE->m_Attributes.push_back(pAt);
      }
      m_Events.push(pSE);
  }
  
  void XMLParserExpat::endElement(const XML_Ch *qname)
  {
      QName qn;
      qn.splitQNameString(qname, NAMESPACESEPARATOR);
      EndElement *pEE = new EndElement();
      pEE->m_NameOrValue = qn.localname;
      pEE->m_Namespace  = qn.uri ? qn.uri : "";
      m_Events.push(pEE);
      qn.mergeQNameString(NAMESPACESEPARATOR);
  }
  
  void  XMLParserExpat::characters(const XML_Ch *chars, int length)
  {
  
      XML_Ch* pTemp = const_cast<XML_Ch*>(chars);
      XML_Ch replacedchar = pTemp[length];
      /* copy and keep existing char at length position */
      pTemp[length] = '\0';
      /* putting nul charactor so that chars can be used safely */
      Event* pLastEvent;
      if (!m_Events.empty())
      {
          pLastEvent = m_Events.back();
          if (CHARACTER_ELEMENT == pLastEvent->getType())
          /* continuing same character node */
          {
              pLastEvent->m_NameOrValue += pTemp;
              pTemp[length] = replacedchar;
              /* put back the character that was there before putting nul
               * charactor
               */
              return;
          }
      }
      pLastEvent = new CharElement();
      pLastEvent->m_NameOrValue = pTemp;
      m_Events.push(pLastEvent);
      pTemp[length] = replacedchar;
      /* put back the character that was there before putting nul charactor */
  }
  
  void XMLParserExpat::startPrefixMapping(const XML_Ch *prefix,
                                           const XML_Ch *uri)
  {
      if (uri)
      {
          StartPrefix* pEvent = new StartPrefix();
          if (prefix) pEvent->m_NameOrValue = prefix;
          pEvent->m_Namespace = uri;
          m_Events.push(pEvent);
      }
  }
  
  void XMLParserExpat::endPrefixMapping(const XML_Ch *prefix)
  {
      if (!prefix) return;
      EndPrefix* pEvent = new EndPrefix();
      pEvent->m_NameOrValue = prefix;
      m_Events.push(pEvent);
  }
  
  const XML_Ch* XMLParserExpat::getNS4Prefix(const XML_Ch* prefix)
  {
      if (m_NsStack.find(prefix) != m_NsStack.end())
      {
          return m_NsStack[prefix].c_str();
      }
      return NULL;
  }
  
  /**
   * This method returning NULL means that there is something wrong with the
   * stream and hence parsing should be finished or aborted.
   * @param isCharData - say that Deserializer is expecting a character data event.
   */
  const AnyElement* XMLParserExpat::next(bool isCharData)
  {
      int nStatus = TRANSPORT_IN_PROGRESS;
      if (m_pLastEvent)
      {
          delete m_pLastEvent;
          m_pLastEvent = NULL;
      }
      try
      {
      do
      {
          if (m_Events.empty())
          {
              nStatus = parseNext();
              if (TRANSPORT_FAILED == nStatus) return NULL;
              if ((TRANSPORT_FINISHED == nStatus) && m_Events.empty())
                  //throw AxisParseException(SERVER_PARSE_TRANSPORT_FAILED);
                  return NULL;
              if (AXIS_FAIL == m_nStatus) return NULL;
          }
  
          if (!m_Events.empty())
          {
              m_pLastEvent = m_Events.front();
              XML_NODE_TYPE type = m_pLastEvent->getType();
              m_Events.pop();
              if ((CHARACTER_ELEMENT == type) && m_Events.empty())
              /* current character element may not be parsed completly */
              {
                  m_Events.push(m_pLastEvent);
                  nStatus = parseNext();
                  if (TRANSPORT_FAILED == nStatus) return NULL;
                  if ((TRANSPORT_FINISHED == nStatus) && m_Events.empty())
                      //throw AxisParseException(SERVER_PARSE_TRANSPORT_FAILED);
                      return NULL;
              }
              else
              {
                  int i = 0;
                  switch(type)
                  {
                  case START_ELEMENT:
                      {
                          for (list<SimpleAttribute*>::iterator it =
                              ((StartElement*)m_pLastEvent)->m_Attributes.begin()
                              ; it != ((StartElement*)m_pLastEvent)->
                              m_Attributes.end(); it++)
                          {
                              m_Element.m_pchAttributes[i+0] =
                                  (*it)->m_Name.c_str();
                              if ((*it)->m_Namespace.empty())
                                  m_Element.m_pchAttributes[i+1] = 0;
                              else
                                  m_Element.m_pchAttributes[i+1] =
                                  (*it)->m_Namespace.c_str();
                              m_Element.m_pchAttributes[i+2] =
                                  (*it)->m_Value.c_str();
                              i+=3;
                          }
                          m_Element.m_pchAttributes[i+0] = NULL;
                          m_Element.m_pchAttributes[i+1] = NULL;
                          m_Element.m_pchAttributes[i+2] = NULL;
                      }
                      /* no break */
                  case END_ELEMENT:
                      if (((StartElement*)m_pLastEvent)->
                          m_Namespace.empty())
                          m_Element.m_pchNamespace = 0;
                      else
                          m_Element.m_pchNamespace =
                          ((StartElement*)m_pLastEvent)->m_Namespace.c_str();
                      /* no break */
                  case CHARACTER_ELEMENT:
                      m_Element.m_pchNameOrValue = m_pLastEvent->
                          m_NameOrValue.c_str();
                      m_Element.m_type = type;
                      if (!isCharData && (CHARACTER_ELEMENT == type))
                      { /* ignorable white space */
                          delete m_pLastEvent;
                          m_pLastEvent = NULL;
                          break;
                      }
                      return &m_Element;
                  case START_PREFIX:
  					if (!(m_pLastEvent->m_NameOrValue.empty()))
  						m_NsStack[m_pLastEvent->m_NameOrValue] =
  							((StartPrefix*)m_pLastEvent)->m_Namespace;
                      /* I think the same prifix cannot repeat ??? */
                      delete m_pLastEvent;
                      m_pLastEvent = NULL;
                      break;
                  case END_PREFIX:
                      m_NsStack.erase(m_pLastEvent->m_NameOrValue);
                      /* I think the same prifix cannot repeat ??? */
                      delete m_pLastEvent;
                      m_pLastEvent = NULL;
                      break;
                  }
              }
          }
      } while (TRANSPORT_FAILED != nStatus);
      return NULL;
      }
      catch(AxisParseException& e)
      {
          throw;
      }
      catch(AxisException& e)
      {
          throw;
      }
      catch(...)
      {
          throw;
      }
  }
  
  int XMLParserExpat::parseNext()
  {
      int nChars = EXPAT_BUFFER_SIZE;
      AXIS_TRANSPORT_STATUS iTransportStatus;
      try
      {
      m_pCurrentBuffer = (char*) XML_GetBuffer(m_Parser, EXPAT_BUFFER_SIZE);
      if (m_pCurrentBuffer)
      {
          iTransportStatus = m_pInputStream->getBytes(m_pCurrentBuffer, &nChars);
          if (nChars > 0)
          {
              if (XML_STATUS_ERROR == XML_ParseBuffer(m_Parser, nChars, false))
                  m_nStatus = AXIS_FAIL;
          }
          if (TRANSPORT_FAILED == iTransportStatus) XML_ParseBuffer(m_Parser, 0, true);
                  if(AXIS_FAIL == m_nStatus)
                      throw AxisParseException( SERVER_PARSE_PARSER_FAILED);
                  if(TRANSPORT_FAILED == iTransportStatus)
                      throw AxisParseException(SERVER_PARSE_TRANSPORT_FAILED);
      }
          else throw AxisParseException(SERVER_PARSE_BUFFER_EMPTY);
      /* end of parsing */
      }
      catch(AxisParseException& e)
      {
          throw;
      }
      catch(AxisException& e)
      {
          throw;
      }
      catch(...)
      {
          throw;
      }
      return iTransportStatus;
  }
  
  int XMLParserExpat::getStatus()
  {
      return m_nStatus;
  }
  
  /**
   * Sets the new input stream and resets XMLParserExpat object state to
   * initial state
   */
  int XMLParserExpat::setInputStream(AxisIOStream* pInputStream)
  {
      m_pInputStream = pInputStream;
      XML_ParserReset(m_Parser, NULL);
      XML_SetUserData(m_Parser, this);
      XML_SetNamespaceDeclHandler(m_Parser, s_startPrefixMapping,
          s_endPrefixMapping);
      XML_SetElementHandler(m_Parser, s_startElement, s_endElement);
      XML_SetCharacterDataHandler(m_Parser, s_characters);
      m_nStatus = AXIS_SUCCESS; /*TODO:Check if an error occured in expat */
      m_NsStack.clear(); /* this will also delete any strings there */
      if (m_pLastEvent) delete m_pLastEvent;
      while (!m_Events.empty())
      {
          m_pLastEvent = m_Events.front();
          m_Events.pop();
          delete m_pLastEvent;
      }
      m_pLastEvent = NULL;
      return m_nStatus;
  }
  
  const AnyElement* XMLParserExpat::anyNext()
  {
      int nStatus = TRANSPORT_IN_PROGRESS;
      if (m_pLastEvent)
      {
          delete m_pLastEvent;
          m_pLastEvent = NULL;
      }
      try
      {
      do
      {
          if (m_Events.empty())
          {
              nStatus = parseNext();
              if (TRANSPORT_FAILED == nStatus) return NULL;
              if ((TRANSPORT_FINISHED == nStatus) && m_Events.empty())
                  return NULL;
              if (AXIS_FAIL == m_nStatus) return NULL;
          }
  
          if (!m_Events.empty())
          {
              m_pLastEvent = m_Events.front();
              XML_NODE_TYPE type = m_pLastEvent->getType();
              m_Events.pop();
              if ((CHARACTER_ELEMENT == type) && m_Events.empty())
              /* current character element may not be parsed completly */
              {
                  m_Events.push(m_pLastEvent);
                  nStatus = parseNext();
                  if (TRANSPORT_FAILED == nStatus) return NULL;
                  if ((TRANSPORT_FINISHED == nStatus) && m_Events.empty())
                      return NULL;
              }
              else
              {
                  int i = 0;
                  switch(type)
                  {
                  case START_ELEMENT:
                      {
                          for (list<SimpleAttribute*>::iterator it =
                              ((StartElement*)m_pLastEvent)->m_Attributes.begin()
                              ; it != ((StartElement*)m_pLastEvent)->
                              m_Attributes.end(); it++)
                          {
                              m_Element.m_pchAttributes[i+0] =
                                  (*it)->m_Name.c_str();
                              if ((*it)->m_Namespace.empty())
                                  m_Element.m_pchAttributes[i+1] = 0;
                              else
                                  m_Element.m_pchAttributes[i+1] =
                                  (*it)->m_Namespace.c_str();
                              m_Element.m_pchAttributes[i+2] =
                                  (*it)->m_Value.c_str();
                              i+=3;
                          }
                          m_Element.m_pchAttributes[i+0] = NULL;
                          m_Element.m_pchAttributes[i+1] = NULL;
                          m_Element.m_pchAttributes[i+2] = NULL;
                      }
                      /* no break */
                  case END_ELEMENT:
                      if (((StartElement*)m_pLastEvent)->
                          m_Namespace.empty())
                          m_Element.m_pchNamespace = 0;
                      else
                          m_Element.m_pchNamespace =
                          ((StartElement*)m_pLastEvent)->m_Namespace.c_str();
                      /* no break */
                  case CHARACTER_ELEMENT:
                      m_Element.m_pchNameOrValue = m_pLastEvent->
                          m_NameOrValue.c_str();
                      m_Element.m_type = type;
                      return &m_Element;
                  case START_PREFIX:
  					if (!(m_pLastEvent->m_NameOrValue.empty()))
  						m_NsStack[m_pLastEvent->m_NameOrValue] =
  							((StartPrefix*)m_pLastEvent)->m_Namespace;
                      m_Element.m_pchNamespace = ((StartElement*)m_pLastEvent)->
                          m_Namespace.c_str();
  					if (!(m_pLastEvent->m_NameOrValue.empty()))
  					{
  						m_Element.m_pchNameOrValue = ((StartElement*)m_pLastEvent)
  							->m_NameOrValue.c_str();
  					}
  					else
  					{
  						m_Element.m_pchNameOrValue = 0;
  					}
                      m_Element.m_type = type;
                      return &m_Element;
                  case END_PREFIX:
                      m_NsStack.erase(m_pLastEvent->m_NameOrValue);
                      m_Element.m_pchNameOrValue = ((StartElement*)m_pLastEvent)
                          ->m_NameOrValue.c_str();
                      m_Element.m_type = type;
                      return &m_Element;
                  }
              }
          }
      } while (TRANSPORT_FAILED != nStatus);
      return NULL;
      }
      catch(AxisParseException& e)
      {
          throw;
      }
      catch(AxisException& e)
      {
          throw;
      }
      catch(...)
      {
          throw;
      }
  }
  
  const XML_Ch* XMLParserExpat::getPrefix4NS(const XML_Ch* pcNS)
  {
      for (map<AxisXMLString, AxisXMLString>::iterator it=m_NsStack.begin();
           it!=m_NsStack.end(); it++)
      {
          if ((*it).second == pcNS)
          {
              return (*it).first.c_str();
          }
      }
      return 0;
  }
  
  
  
  
  
  1.1                  ws-axis/c/graveyard/src/xml/expat/XMLParserExpat.h
  
  Index: XMLParserExpat.h
  ===================================================================
  /*
   *   Copyright 2003-2004 The Apache Software Foundation.
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *   limitations under the License.
   */
  
  /*
   * @author Susantha Kumara (skumara@virtusa.com)
   *
   */
  #ifdef WIN32
  #pragma warning (disable : 4786)
  #endif
  
  #if !defined(__XMLPARSEREXPAT_H_OF_AXIS_INCLUDED__)
  #define __XMLPARSEREXPAT_H_OF_AXIS_INCLUDED__
  #ifdef WIN32
  #include <expat/expat.h>
  #else
  #include <expat.h>
  #endif
  //#include <axis/server/Packet.hpp>
  
  #include "../QName.h"
  #include "../AnyElement.h"
  #include "../Event.h"
  #include "../XMLParser.h"
  #include "../AxisParseException.h"
  
  #include <queue>
  #include <map>
  #include <string>
  
  using namespace std;
  
  class XMLParserExpat: public XMLParser
  {
  public:
      XMLParserExpat();
      ~XMLParserExpat();
      int setInputStream(AxisIOStream* pInputStream);
      const XML_Ch* getNS4Prefix(const XML_Ch* prefix);
      int getStatus();
      const AnyElement* next(bool isCharData=false);
      const AnyElement* anyNext();
      const XML_Ch* getPrefix4NS(const XML_Ch* pcNS);
  
  private:
      XML_Parser m_Parser;
      char* m_pCurrentBuffer;
      Event* m_pLastEvent;
      AnyElement m_Element;
      queue<Event*> m_Events;
      map<AxisXMLString, AxisXMLString> m_NsStack;
      int m_nStatus;
      void startElement(const XML_Ch *qname,const XML_Ch **attrs);
      void endElement(const XML_Ch *qname);
      void characters(const XML_Ch *chars,int length);
      void startPrefixMapping(const XML_Ch *prefix, const XML_Ch *uri);
      void endPrefixMapping(const XML_Ch *prefix);
      int parseNext();
  
      inline static void XMLCALL s_startElement(void* p, const XML_Ch *qname,
          const XML_Ch **attrs)
      {((XMLParserExpat*)p)->startElement(qname,attrs);};
      inline static void XMLCALL s_endElement(void* p, const XML_Ch *qname)
      {((XMLParserExpat*)p)->endElement(qname);};
      inline static void XMLCALL s_characters(void* p, const XML_Ch *chars,
          int length)
      {((XMLParserExpat*)p)->characters(chars,length);};
      inline static void XMLCALL s_startPrefixMapping(void* p,
          const XML_Ch *prefix, const XML_Ch *uri)
      {((XMLParserExpat*)p)->startPrefixMapping(prefix, uri);};
      inline static void XMLCALL s_endPrefixMapping(void* p,
          const XML_Ch *prefix)
      {((XMLParserExpat*)p)->endPrefixMapping(prefix);};
  };
  
  #endif