blob: 0f7a137f5ac316708099682640e0332f492d2f3b [file] [log] [blame]
/*
* 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 (susantha@opensource.lk)
*/
#ifdef WIN32
#pragma warning (disable : 4786)
#pragma warning (disable : 4101)
#endif
#include "XMLParserAxis.hpp"
#include "AxisInputStream.hpp"
XMLParserAxis::XMLParserAxis()
{
m_bEndElementFollows = false;
m_pParser = 0;
m_pInputStream = 0;
m_Element.m_pchNamespace = 0;
m_Element.m_pchNameOrValue = 0;
m_Element.m_pchAttributes[0] = 0;
}
XMLParserAxis::~XMLParserAxis()
{
if (m_pParser)
delete m_pParser;
if (m_pInputStream)
delete m_pInputStream;
}
int XMLParserAxis::setInputStream(AxisIOStream* pInputStream)
{
try
{
m_bEndElementFollows = false;
if (m_pInputStream)
delete m_pInputStream;
m_pInputStream = new AxisInputStream(pInputStream);
//TODO : Reusing the same parser object should be possible. Improve the
// parser and then remove the following.
if (m_pParser)
delete m_pParser;
m_pParser = new XmlPullParser(m_pInputStream);
return AXIS_SUCCESS;
}
catch(XmlPullParserException* pException)
{
delete pException;
throw new AxisParseException();
}
}
const XML_Ch* XMLParserAxis::getNS4Prefix(const XML_Ch* prefix)
{
try
{
return m_pParser->getNamespace4Prefix(prefix);
}
catch(XmlPullParserException* pException)
{
delete pException;
throw new AxisParseException();
}
}
int XMLParserAxis::getStatus()
{
//TODO : implement this correctly
return AXIS_SUCCESS;
}
void XMLParserAxis::freeElement()
{
if (m_bEndElementFollows) // free only attributes list if available.
{
m_Element.m_type = END_ELEMENT;
}
else // free all inner strings
{
if (m_Element.m_pchNameOrValue)
{
free (const_cast<void*>((const void*)m_Element.m_pchNameOrValue));
m_Element.m_pchNameOrValue = 0;
}
if (m_Element.m_pchNamespace)
{
free (const_cast<void*>((const void*)m_Element.m_pchNamespace));
m_Element.m_pchNamespace = 0;
}
}
freeAttributes();
}
void XMLParserAxis::freeAttributes()
{
for (int ix=0; m_Element.m_pchAttributes[ix]; ix+=3)
{
if (m_Element.m_pchAttributes[ix])
{
free (const_cast<void*>((const void*)m_Element.m_pchAttributes[ix]));
if (m_Element.m_pchAttributes[ix+1])
free (const_cast<void*>((const void*)m_Element.m_pchAttributes[ix+1]));
if (m_Element.m_pchAttributes[ix+2])
free (const_cast<void*>((const void*)m_Element.m_pchAttributes[ix+2]));
}
}
m_Element.m_pchAttributes[0] = 0;
}
void XMLParserAxis::setAttributes()
{
int iAttribIx=0;
int iAttrib = m_pParser->getAttributeCount();
m_Element.m_pchAttributes[iAttrib*3]=0;
for (int ix = 0; ix < iAttrib; ix++)
{
iAttribIx=ix*3;
m_Element.m_pchAttributes[iAttribIx] = m_pParser->getAttributeName(ix);
m_Element.m_pchAttributes[iAttribIx+1] =
m_pParser->getAttributeNamespaceUri(ix);
m_Element.m_pchAttributes[iAttribIx+2] = m_pParser->getAttributeValue(ix);
}
}
const AnyElement* XMLParserAxis::next(bool isCharData)
{
int nType;
try
{
freeElement();
if (m_bEndElementFollows)
{
m_bEndElementFollows = false;
return &m_Element;
}
while (true)
{
if ((nType= m_pParser->next()) != -1)
{
if (!isCharData && (XmlPullParser::Content == nType))
{ // ignorable white space
continue;
}
switch (nType)
{
case XmlPullParser::STag:
m_Element.m_type = START_ELEMENT;
m_Element.m_pchNameOrValue = m_pParser->getName();
m_Element.m_pchNamespace = m_pParser->getNamespaceUri();
setAttributes();
break;
case XmlPullParser::EmptyElemTag:
m_Element.m_type = START_ELEMENT;
m_Element.m_pchNameOrValue = m_pParser->getName();
m_Element.m_pchNamespace = m_pParser->getNamespaceUri();
setAttributes();
m_bEndElementFollows = true;
break;
case XmlPullParser::ETag:
m_Element.m_type = END_ELEMENT;
m_Element.m_pchNameOrValue = m_pParser->getName();
m_Element.m_pchNamespace = m_pParser->getNamespaceUri();
break;
case XmlPullParser::Content:
m_Element.m_type = CHARACTER_ELEMENT;
m_Element.m_pchNameOrValue = m_pParser->getCharData();
break;
default:;
}
return &m_Element;
}
else
{
return NULL;
}
}
}
catch(XmlPullParserException* pException)
{
delete pException;
throw new AxisParseException();
}
}
const AnyElement* XMLParserAxis::anyNext()
{
//TODO : not implemented. I dont think that this ever need to be implemented
//because we are not using this any more in Axis.
return NULL;
}
const XML_Ch* XMLParserAxis::getPrefix4NS(const XML_Ch* pcNS)
{
try
{
return m_pParser->getPrefix4Namespace(pcNS);
}
catch(XmlPullParserException* pException)
{
delete pException;
throw new AxisParseException();
}
}