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