You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by su...@apache.org on 2004/05/27 07:02:23 UTC

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

susantha    2004/05/26 22:02:23

  Modified:    c/src/xml/expat Makefile.am
  Added:       c/src/xml/expat ParserLoader.cpp XMLParserExpat.cpp
                        XMLParserExpat.h
  Log:
  Renaminng of Some classes in Parser Libraries
  
  Revision  Changes    Path
  1.3       +1 -1      ws-axis/c/src/xml/expat/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  RCS file: /home/cvs/ws-axis/c/src/xml/expat/Makefile.am,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Makefile.am	19 May 2004 09:34:57 -0000	1.2
  +++ Makefile.am	27 May 2004 05:02:23 -0000	1.3
  @@ -1,6 +1,6 @@
   lib_LTLIBRARIES = libaxis_expat.la
   AM_CPPFLAGS = $(CPPFLAGS)
  -libaxis_expat_la_SOURCES = SoapParserExpat.cpp
  +libaxis_expat_la_SOURCES = XMLParserExpat.cpp ParserLoader.cpp
   
   libaxis_expat_la_LIBADD = -L$(EXPAT_HOME) -lexpat -lstdc++
   INCLUDES = -I$(AXISCPP_HOME)/include
  
  
  
  1.1                  ws-axis/c/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"
  
  #ifdef WIN32
  #define STORAGE_CLASS_INFO __declspec(dllexport)
  #else
  #define STORAGE_CLASS_INFO 
  #endif
  
  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/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)
  #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 (prefix && uri)
      {
          StartPrefix* pEvent = new StartPrefix();
          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;
      }
      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();
                              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:
                      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:
                      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;
  }
  
  int XMLParserExpat::parseNext()
  {
      int nChars = EXPAT_BUFFER_SIZE;
      AXIS_TRANSPORT_STATUS iTransportStatus;
  	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);
  	}
      /* end of parsing */
      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;
  }
  
  
  
  
  1.1                  ws-axis/c/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__
  
  #include <expat/expat.h>
  #include <axis/server/Packet.h>
  
  #include "../QName.h"
  #include <axis/server/AnyElement.h>
  #include "../Event.h"
  #include <axis/server/XMLParser.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);
  
  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