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