1feecfec58
2008/04/01 15:00:02 thb 1.9.46.2: #i85898# Stripping all external header guards 2008/03/28 16:03:37 rt 1.9.46.1: #i87441# Change license header to LPGL v3.
698 lines
29 KiB
C++
698 lines
29 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: XMLParser.cxx,v $
|
|
* $Revision: 1.10 $
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_automation.hxx"
|
|
#include <tools/stream.hxx>
|
|
#include "statemnt.hxx"
|
|
#include "rcontrol.hxx"
|
|
#include "retstrm.hxx"
|
|
#include <basic/svtmsg.hrc>
|
|
|
|
#ifndef _BASIC_TTRESHLP_HXX
|
|
#include <basic/ttstrhlp.hxx>
|
|
#endif
|
|
|
|
#include <com/sun/star/xml/sax/XParser.hpp>
|
|
#include <com/sun/star/xml/sax/SAXException.hpp>
|
|
#include <com/sun/star/io/XInputStream.hpp>
|
|
#include <com/sun/star/io/XInputStream.hpp>
|
|
#include <com/sun/star/util/XCloneable.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <cppuhelper/implbase2.hxx>
|
|
#include <cppuhelper/implbase1.hxx>
|
|
#include <com/sun/star/xml/sax/SAXParseException.hpp>
|
|
|
|
using namespace com::sun::star::xml::sax;
|
|
using namespace com::sun::star::io;
|
|
using namespace com::sun::star::uno;
|
|
using namespace com::sun::star::util;
|
|
using namespace rtl;
|
|
|
|
class SVInputStream : public cppu::WeakImplHelper1< XInputStream >
|
|
{
|
|
SvStream* pStream;
|
|
public:
|
|
SVInputStream( SvStream* pSt ):pStream( pSt ){};
|
|
~SVInputStream(){ delete pStream; pStream=NULL; }
|
|
|
|
// Methods XInputStream
|
|
virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
|
|
virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
|
|
virtual sal_Int32 SAL_CALL available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
|
|
};
|
|
|
|
|
|
sal_Int32 SAL_CALL SVInputStream::readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
aData.realloc( nBytesToRead );
|
|
sal_Int32 nRead = pStream->Read( aData.getArray(), nBytesToRead );
|
|
aData.realloc( nRead );
|
|
return nRead;
|
|
}
|
|
|
|
sal_Int32 SAL_CALL SVInputStream::readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
return readBytes( aData, nMaxBytesToRead );
|
|
}
|
|
|
|
void SAL_CALL SVInputStream::skipBytes( sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
if ( nBytesToSkip > 0 )
|
|
pStream->SeekRel( nBytesToSkip );
|
|
}
|
|
|
|
sal_Int32 SAL_CALL SVInputStream::available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
ULONG nCurrent = pStream->Tell();
|
|
ULONG nSize = pStream->Seek( STREAM_SEEK_TO_END );
|
|
ULONG nAvailable = nSize - nCurrent;
|
|
pStream->Seek( nCurrent );
|
|
return nAvailable;
|
|
}
|
|
|
|
void SAL_CALL SVInputStream::closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
// pStream->Close(); // automatically done in destructor
|
|
delete pStream;
|
|
pStream = NULL;
|
|
}
|
|
|
|
class Node;
|
|
SV_DECL_REF(Node)
|
|
|
|
enum NodeType { NODE_CHARACTER = CONST_NodeTypeCharacter,
|
|
NODE_ELEMENT = CONST_NodeTypeElement,
|
|
NODE_COMMENT = CONST_NodeTypeComment };
|
|
|
|
class Node : public SvRefBase
|
|
{
|
|
NodeType aNodeType;
|
|
Node* pParent; // Use pointer to prevent cyclic references resulting in undeleted objects
|
|
|
|
protected:
|
|
Node( NodeType aType ): aNodeType( aType ), pParent( NULL ){};
|
|
virtual ~Node();
|
|
|
|
public:
|
|
NodeType GetNodeType() { return aNodeType; }
|
|
void SetParent( NodeRef xNewParent );
|
|
NodeRef GetParent();
|
|
};
|
|
|
|
SV_IMPL_REF(Node)
|
|
// generate NodeRefMemberList
|
|
SV_DECL_IMPL_REF_LIST( NodeRef, Node* )
|
|
|
|
Node::~Node()
|
|
{
|
|
}
|
|
|
|
void Node::SetParent( NodeRef xNewParent )
|
|
{
|
|
pParent = &xNewParent;
|
|
}
|
|
|
|
NodeRef Node::GetParent()
|
|
{
|
|
return NodeRef( pParent );
|
|
}
|
|
|
|
class CharacterNode : public Node
|
|
{
|
|
String aCharacters;
|
|
public:
|
|
CharacterNode( const String& aChars ): Node( NODE_CHARACTER ), aCharacters( aChars ){};
|
|
|
|
String GetCharacters() { return aCharacters; }
|
|
};
|
|
|
|
class ElementNode : public Node
|
|
{
|
|
String aNodeName;
|
|
Reference < XAttributeList > xAttributeList;
|
|
NodeRefMemberList aDocumentNodeList;
|
|
public:
|
|
ElementNode( const String& aName, Reference < XAttributeList > xAttributes );
|
|
void AppendNode( NodeRef xNewNode );
|
|
ULONG GetChildCount(){ return aDocumentNodeList.Count(); }
|
|
NodeRef GetChild( USHORT nIndex ){ return aDocumentNodeList.GetObject( nIndex ); }
|
|
Reference < XAttributeList > GetAttributes(){ return xAttributeList; }
|
|
|
|
String GetNodeName() { return aNodeName; }
|
|
};
|
|
|
|
ElementNode::ElementNode( const String& aName, Reference < XAttributeList > xAttributes )
|
|
: Node( NODE_ELEMENT )
|
|
, aNodeName( aName )
|
|
{
|
|
if ( xAttributes.is() )
|
|
{
|
|
Reference < XCloneable > xAttributeCloner( xAttributes, UNO_QUERY );
|
|
if ( xAttributeCloner.is() )
|
|
xAttributeList = Reference < XAttributeList > ( xAttributeCloner->createClone() , UNO_QUERY );
|
|
else
|
|
{
|
|
DBG_ERROR("Unable to clone AttributeList")
|
|
}
|
|
}
|
|
};
|
|
|
|
void ElementNode::AppendNode( NodeRef xNewNode )
|
|
{
|
|
aDocumentNodeList.Insert ( xNewNode, LIST_APPEND );
|
|
xNewNode->SetParent( this );
|
|
}
|
|
|
|
// XIndexAccess
|
|
|
|
|
|
|
|
|
|
|
|
enum ParseAction { COLLECT_DATA, COLLECT_DATA_IGNORE_WHITESPACE, PARSE_ONLY };
|
|
|
|
class SAXParser : public cppu::WeakImplHelper2< XErrorHandler, XDocumentHandler >
|
|
{
|
|
String aFilename;
|
|
Reference < XParser > xParser;
|
|
|
|
// XErrorHandler
|
|
void AddToList( const sal_Char* cuType, const ::com::sun::star::uno::Any& aSAXParseException );
|
|
String aErrors;
|
|
|
|
NodeRef xTreeRoot;
|
|
NodeRef xCurrentNode;
|
|
ULONG nTimestamp;
|
|
ParseAction aAction;
|
|
|
|
public:
|
|
SAXParser( const String &rFilename );
|
|
~SAXParser();
|
|
|
|
// Access Methods
|
|
NodeRef GetCurrentNode(){ return xCurrentNode; }
|
|
void SetCurrentNode( NodeRef xCurrent ){ xCurrentNode = xCurrent; }
|
|
NodeRef GetRootNode(){ return xTreeRoot; }
|
|
ULONG GetTimestamp(){ return nTimestamp; }
|
|
void Touch(){ nTimestamp = Time::GetSystemTicks(); }
|
|
|
|
// Methods SAXParser
|
|
BOOL Parse( ParseAction aAct );
|
|
String GetErrors(){ return aErrors; }
|
|
|
|
// Methods XErrorHandler
|
|
virtual void SAL_CALL error( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL fatalError( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL warning( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
|
|
// Methods XDocumentHandler
|
|
virtual void SAL_CALL startDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
|
|
};
|
|
|
|
|
|
SAXParser::SAXParser( const String &rFilename )
|
|
: aFilename( rFilename )
|
|
{
|
|
Touch();
|
|
}
|
|
|
|
SAXParser::~SAXParser()
|
|
{
|
|
xParser.clear();
|
|
}
|
|
|
|
BOOL SAXParser::Parse( ParseAction aAct )
|
|
{
|
|
aAction = aAct;
|
|
Touch();
|
|
SvStream* pStream = new SvFileStream( aFilename, STREAM_STD_READ );
|
|
if ( pStream->GetError() )
|
|
return FALSE;
|
|
|
|
InputSource sSource;
|
|
sSource.aInputStream = new SVInputStream( pStream ); // is refcounted and hence deletet appropriately
|
|
sSource.sPublicId = OUString( aFilename );
|
|
|
|
xParser = Reference < XParser > ( ::comphelper::getProcessServiceFactory()->createInstance( CUniString("com.sun.star.xml.sax.Parser") ), UNO_QUERY );
|
|
if ( xParser.is() )
|
|
{
|
|
xParser->setErrorHandler( ( XErrorHandler*) this );
|
|
if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE )
|
|
xParser->setDocumentHandler( ( XDocumentHandler*) this );
|
|
|
|
try
|
|
{
|
|
xParser->parseStream ( sSource );
|
|
}
|
|
catch( class SAXParseException & rPEx)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
String aMemo( rPEx.Message );
|
|
aMemo = String( aMemo );
|
|
#endif
|
|
}
|
|
catch( class Exception & rEx)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
String aMemo( rEx.Message );
|
|
aMemo = String( aMemo );
|
|
#endif
|
|
}
|
|
xParser->setErrorHandler( NULL ); // otherwile Object holds itself
|
|
if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE )
|
|
xParser->setDocumentHandler( NULL ); // otherwile Object holds itself
|
|
}
|
|
else
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Helper Methods XErrorHandler
|
|
void SAXParser::AddToList( const sal_Char* cuType, const ::com::sun::star::uno::Any& aSAXParseException )
|
|
{
|
|
SAXParseException aException;
|
|
aSAXParseException >>= aException;
|
|
|
|
aErrors.Append( String( aException.PublicId ) );
|
|
aErrors.AppendAscii( "(" );
|
|
aErrors.Append( String::CreateFromInt64( aException.LineNumber ) );
|
|
aErrors.AppendAscii( ":" );
|
|
aErrors.Append( String::CreateFromInt64( aException.ColumnNumber ) );
|
|
aErrors.AppendAscii( ") : " );
|
|
aErrors.AppendAscii( cuType );
|
|
aErrors.AppendAscii( ": " );
|
|
aErrors.Append( String( aException.Message ) );
|
|
aErrors.AppendAscii( "\n" );
|
|
}
|
|
|
|
// Methods XErrorHandler
|
|
void SAL_CALL SAXParser::error( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
AddToList( "error", aSAXParseException );
|
|
}
|
|
|
|
void SAL_CALL SAXParser::fatalError( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
AddToList( "fatal error", aSAXParseException );
|
|
}
|
|
|
|
void SAL_CALL SAXParser::warning( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
AddToList( "warning", aSAXParseException );
|
|
}
|
|
|
|
|
|
// Methods XDocumentHandler
|
|
void SAXParser::startDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
xTreeRoot = new ElementNode( CUniString("/"), Reference < XAttributeList > (NULL) );
|
|
xCurrentNode = xTreeRoot;
|
|
Touch();
|
|
}
|
|
|
|
void SAXParser::endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
}
|
|
|
|
void SAXParser::startElement( const ::rtl::OUString& aName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
NodeRef xNewNode = new ElementNode ( String(aName), xAttribs );
|
|
((ElementNode*)(&xCurrentNode))->AppendNode( xNewNode );
|
|
xCurrentNode = xNewNode;
|
|
}
|
|
|
|
void SAXParser::endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
(void) aName; /* avoid warning about unused parameter */
|
|
xCurrentNode = xCurrentNode->GetParent();
|
|
}
|
|
|
|
void SAXParser::characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
if ( aAction == COLLECT_DATA_IGNORE_WHITESPACE )
|
|
{ // check for whitespace
|
|
BOOL bAllWhitespace = TRUE;
|
|
for ( int i = 0 ; bAllWhitespace && i < aChars.getLength() ; i++ )
|
|
if ( aChars[i] != 10 // LF
|
|
&& aChars[i] != 13 // CR
|
|
&& aChars[i] != ' ' // Blank
|
|
&& aChars[i] != '\t' ) // Tab
|
|
bAllWhitespace = FALSE;
|
|
if ( bAllWhitespace )
|
|
return;
|
|
}
|
|
NodeRef xNewNode = new CharacterNode ( String(aChars) );
|
|
((ElementNode*)(&xCurrentNode))->AppendNode( xNewNode );
|
|
}
|
|
|
|
void SAXParser::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
(void) aWhitespaces; /* avoid warning about unused parameter */
|
|
}
|
|
|
|
void SAXParser::processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
(void) aTarget; /* avoid warning about unused parameter */
|
|
(void) aData; /* avoid warning about unused parameter */
|
|
}
|
|
|
|
void SAXParser::setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
(void) xLocator; /* avoid warning about unused parameter */
|
|
#if OSL_DEBUG_LEVEL > 1
|
|
::rtl::OUString aTester;
|
|
aTester = xLocator->getPublicId();
|
|
aTester = xLocator->getSystemId();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
void StatementCommand::HandleSAXParser()
|
|
{
|
|
static Reference < XReference > xParserKeepaliveReference; // this is to keep the Object alive only
|
|
static SAXParser* pSAXParser;
|
|
|
|
// We need spechial prerequisites for these!
|
|
|
|
ElementNode* pElementNode = NULL;
|
|
switch ( nMethodId )
|
|
{
|
|
case RC_SAXGetNodeType:
|
|
case RC_SAXGetAttributeCount:
|
|
case RC_SAXGetAttributeName:
|
|
case RC_SAXGetAttributeValue:
|
|
case RC_SAXGetChildCount:
|
|
case RC_SAXGetElementName:
|
|
case RC_SAXGetChars:
|
|
|
|
case RC_SAXSeekElement:
|
|
case RC_SAXHasElement:
|
|
case RC_SAXGetElementPath:
|
|
{
|
|
if ( xParserKeepaliveReference.is() && pSAXParser->GetCurrentNode().Is() )
|
|
{
|
|
if ( pSAXParser->GetCurrentNode()->GetNodeType() == NODE_ELEMENT )
|
|
{
|
|
NodeRef xNode=pSAXParser->GetCurrentNode();
|
|
pElementNode = (ElementNode*)(&xNode);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
switch ( nMethodId )
|
|
{
|
|
case RC_SAXCheckWellformed:
|
|
{
|
|
if( (nParams & PARAM_STR_1) )
|
|
{
|
|
xParserKeepaliveReference.clear();
|
|
pSAXParser = new SAXParser( aString1 );
|
|
xParserKeepaliveReference = ( XReference* )pSAXParser;
|
|
if ( !xParserKeepaliveReference.is() )
|
|
ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
|
|
else
|
|
{
|
|
if ( !pSAXParser->Parse( PARSE_ONLY ) )
|
|
ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, pSAXParser->GetErrors() );
|
|
}
|
|
|
|
xParserKeepaliveReference.clear();
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
|
|
case RC_SAXReadFile:
|
|
{
|
|
if( (nParams & PARAM_STR_1) )
|
|
{
|
|
ParseAction aAction;
|
|
if( (nParams & PARAM_BOOL_1) && bBool1 )
|
|
aAction = COLLECT_DATA;
|
|
else
|
|
aAction = COLLECT_DATA_IGNORE_WHITESPACE;
|
|
|
|
xParserKeepaliveReference.clear();
|
|
pSAXParser = new SAXParser( aString1 );
|
|
xParserKeepaliveReference = ( XReference* )pSAXParser;
|
|
if ( !xParserKeepaliveReference.is() )
|
|
ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
|
|
else
|
|
{
|
|
|
|
if ( !pSAXParser->Parse( aAction ) )
|
|
ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, pSAXParser->GetErrors() );
|
|
}
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
case RC_SAXGetNodeType:
|
|
{
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)pSAXParser->GetCurrentNode()->GetNodeType() );
|
|
}
|
|
break;
|
|
case RC_SAXGetAttributeCount:
|
|
case RC_SAXGetAttributeName:
|
|
case RC_SAXGetAttributeValue:
|
|
case RC_SAXGetChildCount:
|
|
case RC_SAXGetElementName:
|
|
{
|
|
if ( pElementNode )
|
|
{
|
|
Reference < XAttributeList > xAttributeList = pElementNode->GetAttributes();
|
|
switch ( nMethodId )
|
|
{
|
|
case RC_SAXGetElementName:
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, pElementNode->GetNodeName() );
|
|
break;
|
|
case RC_SAXGetChildCount:
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)pElementNode->GetChildCount() );
|
|
break;
|
|
case RC_SAXGetAttributeCount:
|
|
if ( xAttributeList.is() )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)xAttributeList->getLength() );
|
|
else
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)0 );
|
|
break;
|
|
case RC_SAXGetAttributeName:
|
|
{
|
|
if( (nParams & PARAM_USHORT_1) && ValueOK( aSmartMethodId, RcString( nMethodId ), nNr1, xAttributeList.is()?xAttributeList->getLength():0 ) )
|
|
{
|
|
String aRet( xAttributeList->getNameByIndex( nNr1-1 ) );
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, aRet );
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
case RC_SAXGetAttributeValue:
|
|
// Number or String
|
|
{
|
|
if( (nParams & PARAM_USHORT_1) && ValueOK( aSmartMethodId, RcString( nMethodId ), nNr1, xAttributeList.is()?xAttributeList->getLength():0 ) )
|
|
{
|
|
String aRet( xAttributeList->getValueByIndex( nNr1-1 ) );
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, aRet );
|
|
}
|
|
else if( (nParams & PARAM_STR_1) && xAttributeList.is() )
|
|
{
|
|
String aRet( xAttributeList->getValueByName( aString1 ) );
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, aRet );
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ReportError( GEN_RES_STR1( S_INTERNAL_ERROR, RcString( nMethodId ) ) );
|
|
}
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
case RC_SAXGetChars:
|
|
{
|
|
if ( pSAXParser->GetCurrentNode()->GetNodeType() == NODE_CHARACTER )
|
|
{
|
|
NodeRef xNode=pSAXParser->GetCurrentNode();
|
|
CharacterNode* aCharacterNode = (CharacterNode*)(&xNode);
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, aCharacterNode->GetCharacters() );
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
|
|
case RC_SAXSeekElement:
|
|
case RC_SAXHasElement:
|
|
// Number or String
|
|
{
|
|
BOOL bCheckOnly = nMethodId == RC_SAXHasElement;
|
|
|
|
if( (nParams & PARAM_USHORT_1) && !(nParams & PARAM_STR_1) )
|
|
{
|
|
if ( nNr1 == 0 )
|
|
{
|
|
if ( bCheckOnly )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, pSAXParser->GetCurrentNode()->GetParent().Is() );
|
|
else if ( pSAXParser->GetCurrentNode()->GetParent().Is() )
|
|
pSAXParser->SetCurrentNode( pSAXParser->GetCurrentNode()->GetParent() );
|
|
}
|
|
else if ( !pElementNode )
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
else if ( bCheckOnly )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, ValueOK( aSmartMethodId, String(), nNr1, pElementNode->GetChildCount() ) );
|
|
else if ( ValueOK( aSmartMethodId, RcString( nMethodId ), nNr1, pElementNode->GetChildCount() ) )
|
|
pSAXParser->SetCurrentNode( pElementNode->GetChild( nNr1-1 ) );
|
|
}
|
|
else if( (nParams & PARAM_STR_1) )
|
|
{
|
|
if ( aString1.EqualsAscii( "/" ) )
|
|
{
|
|
if ( bCheckOnly )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_BOOL)TRUE );
|
|
else
|
|
pSAXParser->SetCurrentNode( pSAXParser->GetRootNode() );
|
|
}
|
|
else if ( aString1.Copy(0,2).EqualsAscii( "*:" ) )
|
|
{
|
|
ULONG nTimestamp = (ULONG)aString1.GetToken( 1, ':' ).ToInt64();
|
|
ULONG nPointer = (ULONG)aString1.GetToken( 2, ':' ).ToInt64();
|
|
if ( bCheckOnly )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_BOOL)(pSAXParser->GetTimestamp() == nTimestamp) );
|
|
else
|
|
if ( pSAXParser->GetTimestamp() == nTimestamp )
|
|
{
|
|
{
|
|
Node* pNode = (Node*)nPointer;
|
|
pSAXParser->SetCurrentNode( NodeRef( pNode ) );
|
|
}
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
else if ( pElementNode )
|
|
{
|
|
USHORT nNthOccurance;
|
|
if( (nParams & PARAM_USHORT_1) )
|
|
nNthOccurance = nNr1;
|
|
else
|
|
nNthOccurance = 1;
|
|
|
|
USHORT i;
|
|
NodeRef xNew;
|
|
for ( i = 0 ; i < pElementNode->GetChildCount() && !xNew.Is() ; i++ )
|
|
{
|
|
xNew = pElementNode->GetChild( i );
|
|
if ( xNew->GetNodeType() == NODE_ELEMENT )
|
|
{
|
|
ElementNode* pNewElement = (ElementNode*)(&xNew);
|
|
if ( aString1.Equals( pNewElement->GetNodeName() ) )
|
|
{
|
|
if ( nNthOccurance > 1 )
|
|
{
|
|
xNew.Clear();
|
|
nNthOccurance--;
|
|
}
|
|
}
|
|
else
|
|
xNew.Clear();
|
|
}
|
|
else
|
|
xNew.Clear();
|
|
}
|
|
if ( bCheckOnly )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, xNew.Is() );
|
|
else
|
|
if ( xNew.Is() )
|
|
pSAXParser->SetCurrentNode( xNew );
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
else
|
|
if ( bCheckOnly )
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_BOOL)FALSE );
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
else
|
|
ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
|
|
}
|
|
break;
|
|
case RC_SAXGetElementPath:
|
|
{
|
|
DBG_ASSERT( sizeof( ULONG ) == sizeof ( void* ), "Pointertype has different size than ULONG")
|
|
String aPath;
|
|
aPath.AppendAscii( "*:" );
|
|
aPath.Append( String::CreateFromInt64( pSAXParser->GetTimestamp() ) );
|
|
aPath.AppendAscii( ":" );
|
|
NodeRef xNode=pSAXParser->GetCurrentNode();
|
|
Node* pNode = (Node*)(&xNode);
|
|
aPath.Append( String::CreateFromInt64( (ULONG)pNode ) );
|
|
pRet->GenReturn ( RET_Value, aSmartMethodId, aPath );
|
|
}
|
|
break;
|
|
|
|
case RC_SAXRelease:
|
|
{
|
|
xParserKeepaliveReference.clear();
|
|
}
|
|
break;
|
|
default:
|
|
ReportError( GEN_RES_STR1( S_INTERNAL_ERROR, RcString( nMethodId ) ) );
|
|
}
|
|
}
|
|
|