1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_automation.hxx"
30 #include <tools/stream.hxx>
31 #include "statemnt.hxx"
32 #include "rcontrol.hxx"
33 #include "retstrm.hxx"
34 #include <basic/svtmsg.hrc>
35 
36 #ifndef _BASIC_TTRESHLP_HXX
37 #include <basic/ttstrhlp.hxx>
38 #endif
39 
40 #include <com/sun/star/xml/sax/XParser.hpp>
41 #include <com/sun/star/xml/sax/SAXException.hpp>
42 #include <com/sun/star/io/XInputStream.hpp>
43 #include <com/sun/star/io/XInputStream.hpp>
44 #include <com/sun/star/util/XCloneable.hpp>
45 #include <comphelper/processfactory.hxx>
46 #include <cppuhelper/implbase2.hxx>
47 #include <cppuhelper/implbase1.hxx>
48 #include <com/sun/star/xml/sax/SAXParseException.hpp>
49 
50 using namespace com::sun::star::xml::sax;
51 using namespace com::sun::star::io;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::util;
54 using namespace rtl;
55 
56 class SVInputStream : public cppu::WeakImplHelper1< XInputStream >
57 {
58     SvStream* pStream;
59 public:
60     SVInputStream( SvStream* pSt ):pStream( pSt ){};
61     ~SVInputStream(){ delete pStream; pStream=NULL; }
62 
63     // Methods XInputStream
64     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);
65     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);
66     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);
67     virtual sal_Int32 SAL_CALL available(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
68     virtual void SAL_CALL closeInput(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
69 };
70 
71 
72 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)
73 {
74     aData.realloc( nBytesToRead  );
75     sal_Int32 nRead = pStream->Read( aData.getArray(), nBytesToRead );
76     aData.realloc( nRead );
77     return nRead;
78 }
79 
80 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)
81 {
82     return readBytes( aData, nMaxBytesToRead );
83 }
84 
85 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)
86 {
87     if ( nBytesToSkip > 0 )
88         pStream->SeekRel( nBytesToSkip );
89 }
90 
91 sal_Int32 SAL_CALL SVInputStream::available(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
92 {
93     sal_uLong nCurrent = pStream->Tell();
94     sal_uLong nSize = pStream->Seek( STREAM_SEEK_TO_END );
95     sal_uLong nAvailable = nSize - nCurrent;
96     pStream->Seek( nCurrent );
97     return nAvailable;
98 }
99 
100 void SAL_CALL SVInputStream::closeInput(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
101 {
102 //  pStream->Close(); // automatically done in destructor
103     delete pStream;
104     pStream = NULL;
105 }
106 
107 class Node;
108 SV_DECL_REF(Node)
109 
110 enum NodeType { NODE_CHARACTER = CONST_NodeTypeCharacter,
111                 NODE_ELEMENT = CONST_NodeTypeElement,
112                 NODE_COMMENT = CONST_NodeTypeComment };
113 
114 class Node : public SvRefBase
115 {
116     NodeType aNodeType;
117     Node* pParent;  // Use pointer to prevent cyclic references resulting in undeleted objects
118 
119 protected:
120     Node( NodeType aType ): aNodeType( aType ), pParent( NULL ){};
121     virtual ~Node();
122 
123 public:
124     NodeType GetNodeType() { return aNodeType; }
125     void SetParent( NodeRef xNewParent );
126     NodeRef GetParent();
127 };
128 
129 SV_IMPL_REF(Node)
130 // generate NodeRefMemberList
131 SV_DECL_IMPL_REF_LIST( NodeRef, Node* )
132 
133 Node::~Node()
134 {
135 }
136 
137 void Node::SetParent( NodeRef xNewParent )
138 {
139     pParent = &xNewParent;
140 }
141 
142 NodeRef Node::GetParent()
143 {
144     return NodeRef( pParent );
145 }
146 
147 class CharacterNode : public Node
148 {
149     String aCharacters;
150 public:
151     CharacterNode( const String& aChars ): Node( NODE_CHARACTER ), aCharacters( aChars ){};
152 
153     String GetCharacters() { return aCharacters; }
154 };
155 
156 class ElementNode : public Node
157 {
158     String aNodeName;
159     Reference < XAttributeList > xAttributeList;
160     NodeRefMemberList aDocumentNodeList;
161 public:
162     ElementNode( const String& aName, Reference < XAttributeList > xAttributes );
163     void AppendNode( NodeRef xNewNode );
164     sal_uLong GetChildCount(){ return aDocumentNodeList.Count(); }
165     NodeRef GetChild( sal_uInt16 nIndex ){ return aDocumentNodeList.GetObject( nIndex ); }
166     Reference < XAttributeList > GetAttributes(){ return xAttributeList; }
167 
168     String GetNodeName() { return aNodeName; }
169 };
170 
171 ElementNode::ElementNode( const String& aName, Reference < XAttributeList > xAttributes )
172 : Node( NODE_ELEMENT )
173 , aNodeName( aName )
174 {
175     if ( xAttributes.is() )
176     {
177         Reference < XCloneable > xAttributeCloner( xAttributes, UNO_QUERY );
178         if ( xAttributeCloner.is() )
179             xAttributeList = Reference < XAttributeList > ( xAttributeCloner->createClone() , UNO_QUERY );
180         else
181         {
182             DBG_ERROR("Unable to clone AttributeList");
183         }
184     }
185 };
186 
187 void ElementNode::AppendNode( NodeRef xNewNode )
188 {
189     aDocumentNodeList.Insert ( xNewNode, LIST_APPEND );
190     xNewNode->SetParent( this );
191 }
192 
193 //    XIndexAccess
194 
195 
196 
197 
198 
199 enum ParseAction { COLLECT_DATA, COLLECT_DATA_IGNORE_WHITESPACE, PARSE_ONLY };
200 
201 class SAXParser : public cppu::WeakImplHelper2< XErrorHandler, XDocumentHandler >
202 {
203     String aFilename;
204     Reference < XParser > xParser;
205 
206     // XErrorHandler
207     void AddToList( const sal_Char* cuType, const ::com::sun::star::uno::Any& aSAXParseException );
208     String aErrors;
209 
210     NodeRef xTreeRoot;
211     NodeRef xCurrentNode;
212     sal_uLong nTimestamp;
213     ParseAction aAction;
214 
215 public:
216     SAXParser( const String &rFilename );
217     ~SAXParser();
218 
219     // Access Methods
220     NodeRef GetCurrentNode(){ return xCurrentNode; }
221     void SetCurrentNode( NodeRef xCurrent ){ xCurrentNode = xCurrent; }
222     NodeRef GetRootNode(){ return xTreeRoot; }
223     sal_uLong GetTimestamp(){ return nTimestamp; }
224     void Touch(){ nTimestamp = Time::GetSystemTicks(); }
225 
226     // Methods SAXParser
227     sal_Bool Parse( ParseAction aAct );
228     String GetErrors(){ return aErrors; }
229 
230     // Methods XErrorHandler
231     virtual void SAL_CALL error( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
232     virtual void SAL_CALL fatalError( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
233     virtual void SAL_CALL warning( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
234 
235     // Methods XDocumentHandler
236     virtual void SAL_CALL startDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
237     virtual void SAL_CALL endDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
238     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);
239     virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
240     virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
241     virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
242     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);
243     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);
244 };
245 
246 
247 SAXParser::SAXParser( const String &rFilename )
248 : aFilename( rFilename )
249 {
250     Touch();
251 }
252 
253 SAXParser::~SAXParser()
254 {
255     xParser.clear();
256 }
257 
258 sal_Bool SAXParser::Parse( ParseAction aAct )
259 {
260     aAction = aAct;
261     Touch();
262     SvStream* pStream = new SvFileStream( aFilename, STREAM_STD_READ );
263     if ( pStream->GetError() )
264         return sal_False;
265 
266     InputSource sSource;
267     sSource.aInputStream = new SVInputStream( pStream );    // is refcounted and hence deletet appropriately
268     sSource.sPublicId = OUString( aFilename );
269 
270     xParser = Reference < XParser > ( ::comphelper::getProcessServiceFactory()->createInstance( CUniString("com.sun.star.xml.sax.Parser") ), UNO_QUERY );
271     if ( xParser.is() )
272     {
273         xParser->setErrorHandler( ( XErrorHandler*) this );
274         if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE )
275             xParser->setDocumentHandler( ( XDocumentHandler*) this );
276 
277         try
278         {
279             xParser->parseStream ( sSource );
280 	    }
281 	    catch( class SAXParseException & rPEx)
282 	    {
283 #ifdef DBG_ERROR
284             String aMemo( rPEx.Message );
285             aMemo = String( aMemo );
286 #endif
287 	    }
288 	    catch( class Exception & rEx)
289 	    {
290 #ifdef DBG_ERROR
291             String aMemo( rEx.Message );
292             aMemo = String( aMemo );
293 #endif
294 	    }
295         xParser->setErrorHandler( NULL );   // otherwile Object holds itself
296         if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE )
297             xParser->setDocumentHandler( NULL );    // otherwile Object holds itself
298     }
299     else
300         return sal_False;
301     return sal_True;
302 }
303 
304 
305 // Helper Methods XErrorHandler
306 void SAXParser::AddToList( const sal_Char* cuType, const ::com::sun::star::uno::Any& aSAXParseException )
307 {
308     SAXParseException aException;
309     aSAXParseException >>= aException;
310 
311     aErrors.Append( String( aException.PublicId ) );
312     aErrors.AppendAscii( "(" );
313     aErrors.Append( String::CreateFromInt64( aException.LineNumber ) );
314     aErrors.AppendAscii( ":" );
315     aErrors.Append( String::CreateFromInt64( aException.ColumnNumber ) );
316     aErrors.AppendAscii( ") : " );
317     aErrors.AppendAscii( cuType );
318     aErrors.AppendAscii( ": " );
319     aErrors.Append( String( aException.Message ) );
320     aErrors.AppendAscii( "\n" );
321 }
322 
323 // Methods XErrorHandler
324 void SAL_CALL SAXParser::error( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
325 {
326     AddToList( "error", aSAXParseException );
327 }
328 
329 void SAL_CALL SAXParser::fatalError( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
330 {
331     AddToList( "fatal error", aSAXParseException );
332 }
333 
334 void SAL_CALL SAXParser::warning( const ::com::sun::star::uno::Any& aSAXParseException ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
335 {
336     AddToList( "warning", aSAXParseException );
337 }
338 
339 
340 // Methods XDocumentHandler
341 void SAXParser::startDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
342 {
343     xTreeRoot = new ElementNode( CUniString("/"), Reference < XAttributeList > (NULL) );
344     xCurrentNode = xTreeRoot;
345     Touch();
346 }
347 
348 void SAXParser::endDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
349 {
350 }
351 
352 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)
353 {
354     NodeRef xNewNode = new ElementNode ( String(aName), xAttribs );
355     ((ElementNode*)(&xCurrentNode))->AppendNode( xNewNode );
356     xCurrentNode = xNewNode;
357 }
358 
359 void SAXParser::endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
360 {
361     (void) aName; /* avoid warning about unused parameter */
362     xCurrentNode = xCurrentNode->GetParent();
363 }
364 
365 void SAXParser::characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
366 {
367     if ( aAction == COLLECT_DATA_IGNORE_WHITESPACE )
368     {   // check for whitespace
369         sal_Bool bAllWhitespace = sal_True;
370         for ( int i = 0 ; bAllWhitespace && i < aChars.getLength() ; i++ )
371             if ( aChars[i] != 10 // LF
372               && aChars[i] != 13 // CR
373               && aChars[i] != ' ' // Blank
374               && aChars[i] != '\t' ) // Tab
375                 bAllWhitespace = sal_False;
376         if ( bAllWhitespace )
377             return;
378     }
379     NodeRef xNewNode = new CharacterNode ( String(aChars) );
380     ((ElementNode*)(&xCurrentNode))->AppendNode( xNewNode );
381 }
382 
383 void SAXParser::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
384 {
385     (void) aWhitespaces; /* avoid warning about unused parameter */
386 }
387 
388 void SAXParser::processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
389 {
390     (void) aTarget; /* avoid warning about unused parameter */
391     (void) aData; /* avoid warning about unused parameter */
392 }
393 
394 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)
395 {
396     (void) xLocator; /* avoid warning about unused parameter */
397 #if OSL_DEBUG_LEVEL > 1
398     ::rtl::OUString aTester;
399     aTester = xLocator->getPublicId();
400     aTester = xLocator->getSystemId();
401 #endif
402 }
403 
404 
405 
406 
407 void StatementCommand::HandleSAXParser()
408 {
409     static Reference < XReference > xParserKeepaliveReference;  // this is to keep the Object alive only
410     static SAXParser* pSAXParser;
411 
412     // We need spechial prerequisites for these!
413 
414     ElementNode* pElementNode = NULL;
415 	switch ( nMethodId )
416 	{
417         case RC_SAXGetNodeType:
418 		case RC_SAXGetAttributeCount:
419 		case RC_SAXGetAttributeName:
420 		case RC_SAXGetAttributeValue:
421 		case RC_SAXGetChildCount:
422 		case RC_SAXGetElementName:
423 		case RC_SAXGetChars:
424 
425         case RC_SAXSeekElement:
426 		case RC_SAXHasElement:
427 		case RC_SAXGetElementPath:
428             {
429                 if ( xParserKeepaliveReference.is() && pSAXParser->GetCurrentNode().Is() )
430                 {
431                     if ( pSAXParser->GetCurrentNode()->GetNodeType() == NODE_ELEMENT )
432                     {
433                         NodeRef xNode=pSAXParser->GetCurrentNode();
434                         pElementNode = (ElementNode*)(&xNode);
435                     }
436                 }
437                 else
438                 {
439                     ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
440                     return;
441                 }
442 
443             }
444     }
445 
446 	switch ( nMethodId )
447 	{
448 		case RC_SAXCheckWellformed:
449             {
450 				if( (nParams & PARAM_STR_1) )
451 				{
452                     xParserKeepaliveReference.clear();
453                     pSAXParser = new SAXParser( aString1 );
454                     xParserKeepaliveReference = ( XReference* )pSAXParser;
455                     if ( !xParserKeepaliveReference.is() )
456                         ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
457                     else
458                     {
459                         if ( !pSAXParser->Parse( PARSE_ONLY ) )
460                             ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
461         		        pRet->GenReturn ( RET_Value, nMethodId, pSAXParser->GetErrors() );
462                     }
463 
464                     xParserKeepaliveReference.clear();
465 				}
466 				else
467 					ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
468 			}
469 			break;
470 
471         case RC_SAXReadFile:
472             {
473 				if( (nParams & PARAM_STR_1) )
474 				{
475                     ParseAction aAction;
476        				if( (nParams & PARAM_BOOL_1) && bBool1 )
477                         aAction = COLLECT_DATA;
478                     else
479                         aAction = COLLECT_DATA_IGNORE_WHITESPACE;
480 
481                     xParserKeepaliveReference.clear();
482                     pSAXParser = new SAXParser( aString1 );
483                     xParserKeepaliveReference = ( XReference* )pSAXParser;
484                     if ( !xParserKeepaliveReference.is() )
485                         ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
486                     else
487                     {
488 
489                         if ( !pSAXParser->Parse( aAction ) )
490                             ReportError( GEN_RES_STR1( S_NO_SAX_PARSER, RcString( nMethodId ) ) );
491         		        pRet->GenReturn ( RET_Value, nMethodId, pSAXParser->GetErrors() );
492                     }
493 				}
494 				else
495 					ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
496 			}
497 			break;
498 		case RC_SAXGetNodeType:
499             {
500    		        pRet->GenReturn ( RET_Value, nMethodId, (comm_ULONG)pSAXParser->GetCurrentNode()->GetNodeType() );
501 			}
502 			break;
503 		case RC_SAXGetAttributeCount:
504 		case RC_SAXGetAttributeName:
505 		case RC_SAXGetAttributeValue:
506 		case RC_SAXGetChildCount:
507 		case RC_SAXGetElementName:
508             {
509                 if ( pElementNode )
510                 {
511                     Reference < XAttributeList > xAttributeList = pElementNode->GetAttributes();
512                 	switch ( nMethodId )
513                     {
514                         case RC_SAXGetElementName:
515 	                        pRet->GenReturn ( RET_Value, nMethodId, pElementNode->GetNodeName() );
516 			                break;
517 		                case RC_SAXGetChildCount:
518 	                        pRet->GenReturn ( RET_Value, nMethodId, (comm_ULONG)pElementNode->GetChildCount() );
519 			                break;
520 		                case RC_SAXGetAttributeCount:
521                             if ( xAttributeList.is() )
522                                 pRet->GenReturn ( RET_Value, nMethodId, (comm_ULONG)xAttributeList->getLength() );
523                             else
524                                 pRet->GenReturn ( RET_Value, nMethodId, (comm_ULONG)0 );
525 			                break;
526 		                case RC_SAXGetAttributeName:
527                             {
528                                 if( (nParams & PARAM_USHORT_1) && ValueOK( rtl::OString(), RcString( nMethodId ), nNr1, xAttributeList.is()?xAttributeList->getLength():0 ) )
529                                 {
530                                     String aRet( xAttributeList->getNameByIndex( nNr1-1 ) );
531                                     pRet->GenReturn ( RET_Value, nMethodId, aRet );
532                                 }
533                                 else
534                 					ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
535 			                }
536 			                break;
537 		                case RC_SAXGetAttributeValue:
538                             // Number or String
539                             {
540                 				if( (nParams & PARAM_USHORT_1) && ValueOK( rtl::OString(), RcString( nMethodId ), nNr1, xAttributeList.is()?xAttributeList->getLength():0 ) )
541                                 {
542                                     String aRet( xAttributeList->getValueByIndex( nNr1-1 ) );
543                                     pRet->GenReturn ( RET_Value, nMethodId, aRet );
544                                 }
545                 				else if( (nParams & PARAM_STR_1) && xAttributeList.is() )
546                                 {
547                                     String aRet( xAttributeList->getValueByName( aString1 ) );
548                                     pRet->GenReturn ( RET_Value, nMethodId, aRet );
549                                 }
550                                 else
551                 					ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
552 			                }
553 			                break;
554 
555 		                default:
556 			                ReportError( GEN_RES_STR1( S_INTERNAL_ERROR, RcString( nMethodId ) ) );
557                     }
558                 }
559                 else
560 					ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
561             }
562             break;
563 		case RC_SAXGetChars:
564             {
565                 if ( pSAXParser->GetCurrentNode()->GetNodeType() == NODE_CHARACTER )
566                 {
567                     NodeRef xNode=pSAXParser->GetCurrentNode();
568                     CharacterNode* aCharacterNode = (CharacterNode*)(&xNode);
569        		        pRet->GenReturn ( RET_Value, nMethodId, aCharacterNode->GetCharacters() );
570                 }
571                 else
572 					ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
573 			}
574 			break;
575 
576         case RC_SAXSeekElement:
577 		case RC_SAXHasElement:
578             // Number or String
579             {
580                 sal_Bool bCheckOnly = nMethodId == RC_SAXHasElement;
581 
582                 if( (nParams & PARAM_USHORT_1) && !(nParams & PARAM_STR_1) )
583                 {
584                     if ( nNr1 == 0 )
585                     {
586                         if ( bCheckOnly )
587                             pRet->GenReturn ( RET_Value, nMethodId, pSAXParser->GetCurrentNode()->GetParent().Is() );
588                         else if ( pSAXParser->GetCurrentNode()->GetParent().Is() )
589                             pSAXParser->SetCurrentNode( pSAXParser->GetCurrentNode()->GetParent() );
590                     }
591                     else if ( !pElementNode )
592                     	ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
593                     else if ( bCheckOnly )
594                         pRet->GenReturn ( RET_Value, nMethodId, ValueOK( rtl::OString(), RcString( nMethodId ), nNr1, pElementNode->GetChildCount() ) );
595                     else if ( ValueOK( rtl::OString(), RcString( nMethodId ), nNr1, pElementNode->GetChildCount() ) )
596                         pSAXParser->SetCurrentNode( pElementNode->GetChild( nNr1-1 ) );
597                 }
598                 else if( (nParams & PARAM_STR_1) )
599                 {
600                     if ( aString1.EqualsAscii( "/" ) )
601                     {
602                         if ( bCheckOnly )
603                             pRet->GenReturn ( RET_Value, nMethodId, (comm_BOOL)sal_True );
604                         else
605                             pSAXParser->SetCurrentNode( pSAXParser->GetRootNode() );
606                     }
607                     else if ( aString1.Copy(0,2).EqualsAscii( "*:" ) )
608                     {
609                         sal_uLong nTimestamp = (sal_uLong)aString1.GetToken( 1, ':' ).ToInt64();
610                         sal_uLong nPointer = (sal_uLong)aString1.GetToken( 2, ':' ).ToInt64();
611                         if ( bCheckOnly )
612                             pRet->GenReturn ( RET_Value, nMethodId, (comm_BOOL)(pSAXParser->GetTimestamp() == nTimestamp) );
613                         else
614                             if ( pSAXParser->GetTimestamp() == nTimestamp )
615                             {
616                                 {
617                                     Node* pNode = (Node*)nPointer;
618                                     pSAXParser->SetCurrentNode( NodeRef( pNode ) );
619                                 }
620                             }
621                             else
622                                 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
623                     }
624                     else if ( pElementNode )
625                     {
626                         sal_uInt16 nNthOccurance;
627                         if( (nParams & PARAM_USHORT_1) )
628                             nNthOccurance = nNr1;
629                         else
630                             nNthOccurance = 1;
631 
632                         sal_uInt16 i;
633                         NodeRef xNew;
634                         for ( i = 0 ; i < pElementNode->GetChildCount() && !xNew.Is() ; i++ )
635                         {
636                             xNew = pElementNode->GetChild( i );
637                             if ( xNew->GetNodeType() == NODE_ELEMENT )
638                             {
639                                 ElementNode* pNewElement = (ElementNode*)(&xNew);
640                                 if ( aString1.Equals( pNewElement->GetNodeName() ) )
641                                 {
642                                     if ( nNthOccurance > 1 )
643                                     {
644                                         xNew.Clear();
645                                         nNthOccurance--;
646                                     }
647                                 }
648                                 else
649                                     xNew.Clear();
650                             }
651                             else
652                                 xNew.Clear();
653                         }
654                         if ( bCheckOnly )
655                             pRet->GenReturn ( RET_Value, nMethodId, xNew.Is() );
656                         else
657                             if ( xNew.Is() )
658                                 pSAXParser->SetCurrentNode( xNew );
659                             else
660                                 ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
661                     }
662                     else
663                         if ( bCheckOnly )
664                             pRet->GenReturn ( RET_Value, nMethodId, (comm_BOOL)sal_False );
665                         else
666                     	    ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
667                 }
668                 else
669                 	ReportError( GEN_RES_STR0( S_INVALID_PARAMETERS ) );
670 			}
671 			break;
672 		case RC_SAXGetElementPath:
673             {
674                 DBG_ASSERT( sizeof( sal_uIntPtr ) == sizeof ( void* ), "Pointertype has different size than sal_uIntPtr");
675                 String aPath;
676                 aPath.AppendAscii( "*:" );
677                 aPath.Append( String::CreateFromInt64( pSAXParser->GetTimestamp() ) );
678                 aPath.AppendAscii( ":" );
679                 NodeRef xNode=pSAXParser->GetCurrentNode();
680                 Node* pNode = (Node*)(&xNode);
681                 aPath.Append( String::CreateFromInt64( (sal_uIntPtr)pNode ) );
682                 pRet->GenReturn ( RET_Value, nMethodId, aPath );
683 			}
684 			break;
685 
686         case RC_SAXRelease:
687             {
688                 xParserKeepaliveReference.clear();
689 			}
690 			break;
691 		default:
692 			ReportError( GEN_RES_STR1( S_INTERNAL_ERROR, RcString( nMethodId ) ) );
693     }
694 }
695 
696