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