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