update dev300-m58
[ooovba.git] / automation / source / server / XMLParser.cxx
blobf575db12c878acb91f76b0bdd234ca73907e37a4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLParser.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_automation.hxx"
33 #include <tools/stream.hxx>
34 #include "statemnt.hxx"
35 #include "rcontrol.hxx"
36 #include "retstrm.hxx"
37 #include <basic/svtmsg.hrc>
39 #ifndef _BASIC_TTRESHLP_HXX
40 #include <basic/ttstrhlp.hxx>
41 #endif
43 #include <com/sun/star/xml/sax/XParser.hpp>
44 #include <com/sun/star/xml/sax/SAXException.hpp>
45 #include <com/sun/star/io/XInputStream.hpp>
46 #include <com/sun/star/io/XInputStream.hpp>
47 #include <com/sun/star/util/XCloneable.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <cppuhelper/implbase2.hxx>
50 #include <cppuhelper/implbase1.hxx>
51 #include <com/sun/star/xml/sax/SAXParseException.hpp>
53 using namespace com::sun::star::xml::sax;
54 using namespace com::sun::star::io;
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::util;
57 using namespace rtl;
59 class SVInputStream : public cppu::WeakImplHelper1< XInputStream >
61 SvStream* pStream;
62 public:
63 SVInputStream( SvStream* pSt ):pStream( pSt ){};
64 ~SVInputStream(){ delete pStream; pStream=NULL; }
66 // Methods XInputStream
67 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);
68 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);
69 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);
70 virtual sal_Int32 SAL_CALL available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
71 virtual void SAL_CALL closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
75 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)
77 aData.realloc( nBytesToRead );
78 sal_Int32 nRead = pStream->Read( aData.getArray(), nBytesToRead );
79 aData.realloc( nRead );
80 return nRead;
83 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)
85 return readBytes( aData, nMaxBytesToRead );
88 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)
90 if ( nBytesToSkip > 0 )
91 pStream->SeekRel( nBytesToSkip );
94 sal_Int32 SAL_CALL SVInputStream::available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
96 ULONG nCurrent = pStream->Tell();
97 ULONG nSize = pStream->Seek( STREAM_SEEK_TO_END );
98 ULONG nAvailable = nSize - nCurrent;
99 pStream->Seek( nCurrent );
100 return nAvailable;
103 void SAL_CALL SVInputStream::closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
105 // pStream->Close(); // automatically done in destructor
106 delete pStream;
107 pStream = NULL;
110 class Node;
111 SV_DECL_REF(Node)
113 enum NodeType { NODE_CHARACTER = CONST_NodeTypeCharacter,
114 NODE_ELEMENT = CONST_NodeTypeElement,
115 NODE_COMMENT = CONST_NodeTypeComment };
117 class Node : public SvRefBase
119 NodeType aNodeType;
120 Node* pParent; // Use pointer to prevent cyclic references resulting in undeleted objects
122 protected:
123 Node( NodeType aType ): aNodeType( aType ), pParent( NULL ){};
124 virtual ~Node();
126 public:
127 NodeType GetNodeType() { return aNodeType; }
128 void SetParent( NodeRef xNewParent );
129 NodeRef GetParent();
132 SV_IMPL_REF(Node)
133 // generate NodeRefMemberList
134 SV_DECL_IMPL_REF_LIST( NodeRef, Node* )
136 Node::~Node()
140 void Node::SetParent( NodeRef xNewParent )
142 pParent = &xNewParent;
145 NodeRef Node::GetParent()
147 return NodeRef( pParent );
150 class CharacterNode : public Node
152 String aCharacters;
153 public:
154 CharacterNode( const String& aChars ): Node( NODE_CHARACTER ), aCharacters( aChars ){};
156 String GetCharacters() { return aCharacters; }
159 class ElementNode : public Node
161 String aNodeName;
162 Reference < XAttributeList > xAttributeList;
163 NodeRefMemberList aDocumentNodeList;
164 public:
165 ElementNode( const String& aName, Reference < XAttributeList > xAttributes );
166 void AppendNode( NodeRef xNewNode );
167 ULONG GetChildCount(){ return aDocumentNodeList.Count(); }
168 NodeRef GetChild( USHORT nIndex ){ return aDocumentNodeList.GetObject( nIndex ); }
169 Reference < XAttributeList > GetAttributes(){ return xAttributeList; }
171 String GetNodeName() { return aNodeName; }
174 ElementNode::ElementNode( const String& aName, Reference < XAttributeList > xAttributes )
175 : Node( NODE_ELEMENT )
176 , aNodeName( aName )
178 if ( xAttributes.is() )
180 Reference < XCloneable > xAttributeCloner( xAttributes, UNO_QUERY );
181 if ( xAttributeCloner.is() )
182 xAttributeList = Reference < XAttributeList > ( xAttributeCloner->createClone() , UNO_QUERY );
183 else
185 DBG_ERROR("Unable to clone AttributeList");
190 void ElementNode::AppendNode( NodeRef xNewNode )
192 aDocumentNodeList.Insert ( xNewNode, LIST_APPEND );
193 xNewNode->SetParent( this );
196 // XIndexAccess
202 enum ParseAction { COLLECT_DATA, COLLECT_DATA_IGNORE_WHITESPACE, PARSE_ONLY };
204 class SAXParser : public cppu::WeakImplHelper2< XErrorHandler, XDocumentHandler >
206 String aFilename;
207 Reference < XParser > xParser;
209 // XErrorHandler
210 void AddToList( const sal_Char* cuType, const ::com::sun::star::uno::Any& aSAXParseException );
211 String aErrors;
213 NodeRef xTreeRoot;
214 NodeRef xCurrentNode;
215 ULONG nTimestamp;
216 ParseAction aAction;
218 public:
219 SAXParser( const String &rFilename );
220 ~SAXParser();
222 // Access Methods
223 NodeRef GetCurrentNode(){ return xCurrentNode; }
224 void SetCurrentNode( NodeRef xCurrent ){ xCurrentNode = xCurrent; }
225 NodeRef GetRootNode(){ return xTreeRoot; }
226 ULONG GetTimestamp(){ return nTimestamp; }
227 void Touch(){ nTimestamp = Time::GetSystemTicks(); }
229 // Methods SAXParser
230 BOOL Parse( ParseAction aAct );
231 String GetErrors(){ return aErrors; }
233 // Methods XErrorHandler
234 virtual void SAL_CALL error( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
235 virtual void SAL_CALL fatalError( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
236 virtual void SAL_CALL warning( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
238 // Methods XDocumentHandler
239 virtual void SAL_CALL startDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
240 virtual void SAL_CALL endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
241 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);
242 virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
243 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
244 virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
245 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);
246 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);
250 SAXParser::SAXParser( const String &rFilename )
251 : aFilename( rFilename )
253 Touch();
256 SAXParser::~SAXParser()
258 xParser.clear();
261 BOOL SAXParser::Parse( ParseAction aAct )
263 aAction = aAct;
264 Touch();
265 SvStream* pStream = new SvFileStream( aFilename, STREAM_STD_READ );
266 if ( pStream->GetError() )
267 return FALSE;
269 InputSource sSource;
270 sSource.aInputStream = new SVInputStream( pStream ); // is refcounted and hence deletet appropriately
271 sSource.sPublicId = OUString( aFilename );
273 xParser = Reference < XParser > ( ::comphelper::getProcessServiceFactory()->createInstance( CUniString("com.sun.star.xml.sax.Parser") ), UNO_QUERY );
274 if ( xParser.is() )
276 xParser->setErrorHandler( ( XErrorHandler*) this );
277 if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE )
278 xParser->setDocumentHandler( ( XDocumentHandler*) this );
282 xParser->parseStream ( sSource );
284 catch( class SAXParseException & rPEx)
286 #ifdef DBG_ERROR
287 String aMemo( rPEx.Message );
288 aMemo = String( aMemo );
289 #endif
291 catch( class Exception & rEx)
293 #ifdef DBG_ERROR
294 String aMemo( rEx.Message );
295 aMemo = String( aMemo );
296 #endif
298 xParser->setErrorHandler( NULL ); // otherwile Object holds itself
299 if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE )
300 xParser->setDocumentHandler( NULL ); // otherwile Object holds itself
302 else
303 return FALSE;
304 return TRUE;
308 // Helper Methods XErrorHandler
309 void SAXParser::AddToList( const sal_Char* cuType, const ::com::sun::star::uno::Any& aSAXParseException )
311 SAXParseException aException;
312 aSAXParseException >>= aException;
314 aErrors.Append( String( aException.PublicId ) );
315 aErrors.AppendAscii( "(" );
316 aErrors.Append( String::CreateFromInt64( aException.LineNumber ) );
317 aErrors.AppendAscii( ":" );
318 aErrors.Append( String::CreateFromInt64( aException.ColumnNumber ) );
319 aErrors.AppendAscii( ") : " );
320 aErrors.AppendAscii( cuType );
321 aErrors.AppendAscii( ": " );
322 aErrors.Append( String( aException.Message ) );
323 aErrors.AppendAscii( "\n" );
326 // Methods XErrorHandler
327 void SAL_CALL SAXParser::error( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
329 AddToList( "error", aSAXParseException );
332 void SAL_CALL SAXParser::fatalError( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
334 AddToList( "fatal error", aSAXParseException );
337 void SAL_CALL SAXParser::warning( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
339 AddToList( "warning", aSAXParseException );
343 // Methods XDocumentHandler
344 void SAXParser::startDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
346 xTreeRoot = new ElementNode( CUniString("/"), Reference < XAttributeList > (NULL) );
347 xCurrentNode = xTreeRoot;
348 Touch();
351 void SAXParser::endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
355 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)
357 NodeRef xNewNode = new ElementNode ( String(aName), xAttribs );
358 ((ElementNode*)(&xCurrentNode))->AppendNode( xNewNode );
359 xCurrentNode = xNewNode;
362 void SAXParser::endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
364 (void) aName; /* avoid warning about unused parameter */
365 xCurrentNode = xCurrentNode->GetParent();
368 void SAXParser::characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
370 if ( aAction == COLLECT_DATA_IGNORE_WHITESPACE )
371 { // check for whitespace
372 BOOL bAllWhitespace = TRUE;
373 for ( int i = 0 ; bAllWhitespace && i < aChars.getLength() ; i++ )
374 if ( aChars[i] != 10 // LF
375 && aChars[i] != 13 // CR
376 && aChars[i] != ' ' // Blank
377 && aChars[i] != '\t' ) // Tab
378 bAllWhitespace = FALSE;
379 if ( bAllWhitespace )
380 return;
382 NodeRef xNewNode = new CharacterNode ( String(aChars) );
383 ((ElementNode*)(&xCurrentNode))->AppendNode( xNewNode );
386 void SAXParser::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
388 (void) aWhitespaces; /* avoid warning about unused parameter */
391 void SAXParser::processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
393 (void) aTarget; /* avoid warning about unused parameter */
394 (void) aData; /* avoid warning about unused parameter */
397 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)
399 (void) xLocator; /* avoid warning about unused parameter */
400 #if OSL_DEBUG_LEVEL > 1
401 ::rtl::OUString aTester;
402 aTester = xLocator->getPublicId();
403 aTester = xLocator->getSystemId();
404 #endif
410 void StatementCommand::HandleSAXParser()
412 static Reference < XReference > xParserKeepaliveReference; // this is to keep the Object alive only
413 static SAXParser* pSAXParser;
415 // We need spechial prerequisites for these!
417 ElementNode* pElementNode = NULL;
418 switch ( nMethodId )
420 case RC_SAXGetNodeType:
421 case RC_SAXGetAttributeCount:
422 case RC_SAXGetAttributeName:
423 case RC_SAXGetAttributeValue:
424 case RC_SAXGetChildCount:
425 case RC_SAXGetElementName:
426 case RC_SAXGetChars:
428 case RC_SAXSeekElement:
429 case RC_SAXHasElement:
430 case RC_SAXGetElementPath:
432 if ( xParserKeepaliveReference.is() && pSAXParser->GetCurrentNode().Is() )
434 if ( pSAXParser->GetCurrentNode()->GetNodeType() == NODE_ELEMENT )
436 NodeRef xNode=pSAXParser->GetCurrentNode();
437 pElementNode = (ElementNode*)(&xNode);
440 else
442 ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
443 return;
449 switch ( nMethodId )
451 case RC_SAXCheckWellformed:
453 if( (nParams & PARAM_STR_1) )
455 xParserKeepaliveReference.clear();
456 pSAXParser = new SAXParser( aString1 );
457 xParserKeepaliveReference = ( XReference* )pSAXParser;
458 if ( !xParserKeepaliveReference.is() )
459 ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
460 else
462 if ( !pSAXParser->Parse( PARSE_ONLY ) )
463 ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
464 pRet->GenReturn ( RET_Value, aSmartMethodId, pSAXParser->GetErrors() );
467 xParserKeepaliveReference.clear();
469 else
470 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
472 break;
474 case RC_SAXReadFile:
476 if( (nParams & PARAM_STR_1) )
478 ParseAction aAction;
479 if( (nParams & PARAM_BOOL_1) && bBool1 )
480 aAction = COLLECT_DATA;
481 else
482 aAction = COLLECT_DATA_IGNORE_WHITESPACE;
484 xParserKeepaliveReference.clear();
485 pSAXParser = new SAXParser( aString1 );
486 xParserKeepaliveReference = ( XReference* )pSAXParser;
487 if ( !xParserKeepaliveReference.is() )
488 ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
489 else
492 if ( !pSAXParser->Parse( aAction ) )
493 ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
494 pRet->GenReturn ( RET_Value, aSmartMethodId, pSAXParser->GetErrors() );
497 else
498 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
500 break;
501 case RC_SAXGetNodeType:
503 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)pSAXParser->GetCurrentNode()->GetNodeType() );
505 break;
506 case RC_SAXGetAttributeCount:
507 case RC_SAXGetAttributeName:
508 case RC_SAXGetAttributeValue:
509 case RC_SAXGetChildCount:
510 case RC_SAXGetElementName:
512 if ( pElementNode )
514 Reference < XAttributeList > xAttributeList = pElementNode->GetAttributes();
515 switch ( nMethodId )
517 case RC_SAXGetElementName:
518 pRet->GenReturn ( RET_Value, aSmartMethodId, pElementNode->GetNodeName() );
519 break;
520 case RC_SAXGetChildCount:
521 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)pElementNode->GetChildCount() );
522 break;
523 case RC_SAXGetAttributeCount:
524 if ( xAttributeList.is() )
525 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)xAttributeList->getLength() );
526 else
527 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_ULONG)0 );
528 break;
529 case RC_SAXGetAttributeName:
531 if( (nParams & PARAM_USHORT_1) && ValueOK( aSmartMethodId, RcString( nMethodId ), nNr1, xAttributeList.is()?xAttributeList->getLength():0 ) )
533 String aRet( xAttributeList->getNameByIndex( nNr1-1 ) );
534 pRet->GenReturn ( RET_Value, aSmartMethodId, aRet );
536 else
537 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
539 break;
540 case RC_SAXGetAttributeValue:
541 // Number or String
543 if( (nParams & PARAM_USHORT_1) && ValueOK( aSmartMethodId, RcString( nMethodId ), nNr1, xAttributeList.is()?xAttributeList->getLength():0 ) )
545 String aRet( xAttributeList->getValueByIndex( nNr1-1 ) );
546 pRet->GenReturn ( RET_Value, aSmartMethodId, aRet );
548 else if( (nParams & PARAM_STR_1) && xAttributeList.is() )
550 String aRet( xAttributeList->getValueByName( aString1 ) );
551 pRet->GenReturn ( RET_Value, aSmartMethodId, aRet );
553 else
554 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
556 break;
558 default:
559 ReportError( GEN_RES_STR1( S_INTERNAL_ERROR, RcString( nMethodId ) ) );
562 else
563 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
565 break;
566 case RC_SAXGetChars:
568 if ( pSAXParser->GetCurrentNode()->GetNodeType() == NODE_CHARACTER )
570 NodeRef xNode=pSAXParser->GetCurrentNode();
571 CharacterNode* aCharacterNode = (CharacterNode*)(&xNode);
572 pRet->GenReturn ( RET_Value, aSmartMethodId, aCharacterNode->GetCharacters() );
574 else
575 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
577 break;
579 case RC_SAXSeekElement:
580 case RC_SAXHasElement:
581 // Number or String
583 BOOL bCheckOnly = nMethodId == RC_SAXHasElement;
585 if( (nParams & PARAM_USHORT_1) && !(nParams & PARAM_STR_1) )
587 if ( nNr1 == 0 )
589 if ( bCheckOnly )
590 pRet->GenReturn ( RET_Value, aSmartMethodId, pSAXParser->GetCurrentNode()->GetParent().Is() );
591 else if ( pSAXParser->GetCurrentNode()->GetParent().Is() )
592 pSAXParser->SetCurrentNode( pSAXParser->GetCurrentNode()->GetParent() );
594 else if ( !pElementNode )
595 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
596 else if ( bCheckOnly )
597 pRet->GenReturn ( RET_Value, aSmartMethodId, ValueOK( aSmartMethodId, String(), nNr1, pElementNode->GetChildCount() ) );
598 else if ( ValueOK( aSmartMethodId, RcString( nMethodId ), nNr1, pElementNode->GetChildCount() ) )
599 pSAXParser->SetCurrentNode( pElementNode->GetChild( nNr1-1 ) );
601 else if( (nParams & PARAM_STR_1) )
603 if ( aString1.EqualsAscii( "/" ) )
605 if ( bCheckOnly )
606 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_BOOL)TRUE );
607 else
608 pSAXParser->SetCurrentNode( pSAXParser->GetRootNode() );
610 else if ( aString1.Copy(0,2).EqualsAscii( "*:" ) )
612 ULONG nTimestamp = (ULONG)aString1.GetToken( 1, ':' ).ToInt64();
613 ULONG nPointer = (ULONG)aString1.GetToken( 2, ':' ).ToInt64();
614 if ( bCheckOnly )
615 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_BOOL)(pSAXParser->GetTimestamp() == nTimestamp) );
616 else
617 if ( pSAXParser->GetTimestamp() == nTimestamp )
620 Node* pNode = (Node*)nPointer;
621 pSAXParser->SetCurrentNode( NodeRef( pNode ) );
624 else
625 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
627 else if ( pElementNode )
629 USHORT nNthOccurance;
630 if( (nParams & PARAM_USHORT_1) )
631 nNthOccurance = nNr1;
632 else
633 nNthOccurance = 1;
635 USHORT i;
636 NodeRef xNew;
637 for ( i = 0 ; i < pElementNode->GetChildCount() && !xNew.Is() ; i++ )
639 xNew = pElementNode->GetChild( i );
640 if ( xNew->GetNodeType() == NODE_ELEMENT )
642 ElementNode* pNewElement = (ElementNode*)(&xNew);
643 if ( aString1.Equals( pNewElement->GetNodeName() ) )
645 if ( nNthOccurance > 1 )
647 xNew.Clear();
648 nNthOccurance--;
651 else
652 xNew.Clear();
654 else
655 xNew.Clear();
657 if ( bCheckOnly )
658 pRet->GenReturn ( RET_Value, aSmartMethodId, xNew.Is() );
659 else
660 if ( xNew.Is() )
661 pSAXParser->SetCurrentNode( xNew );
662 else
663 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
665 else
666 if ( bCheckOnly )
667 pRet->GenReturn ( RET_Value, aSmartMethodId, (comm_BOOL)FALSE );
668 else
669 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
671 else
672 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
674 break;
675 case RC_SAXGetElementPath:
677 DBG_ASSERT( sizeof( ULONG ) == sizeof ( void* ), "Pointertype has different size than ULONG");
678 String aPath;
679 aPath.AppendAscii( "*:" );
680 aPath.Append( String::CreateFromInt64( pSAXParser->GetTimestamp() ) );
681 aPath.AppendAscii( ":" );
682 NodeRef xNode=pSAXParser->GetCurrentNode();
683 Node* pNode = (Node*)(&xNode);
684 aPath.Append( String::CreateFromInt64( (ULONG)pNode ) );
685 pRet->GenReturn ( RET_Value, aSmartMethodId, aPath );
687 break;
689 case RC_SAXRelease:
691 xParserKeepaliveReference.clear();
693 break;
694 default:
695 ReportError( GEN_RES_STR1( S_INTERNAL_ERROR, RcString( nMethodId ) ) );