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