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: 56 SVInputStream( SvStream* pSt ):pStream( pSt ){}; 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 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 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 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 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 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: 116 Node( NodeType aType ): aNodeType( aType ), pParent( NULL ){}; 117 virtual ~Node(); 118 119 public: 120 NodeType GetNodeType() { return aNodeType; } 121 void SetParent( NodeRef xNewParent ); 122 NodeRef GetParent(); 123 }; 124 125 SV_IMPL_REF(Node) 126 // generate NodeRefMemberList 127 SV_DECL_IMPL_REF_LIST( NodeRef, Node* ) 128 129 Node::~Node() 130 { 131 } 132 133 void Node::SetParent( NodeRef xNewParent ) 134 { 135 pParent = &xNewParent; 136 } 137 138 NodeRef Node::GetParent() 139 { 140 return NodeRef( pParent ); 141 } 142 143 class CharacterNode : public Node 144 { 145 String aCharacters; 146 public: 147 CharacterNode( const String& aChars ): Node( NODE_CHARACTER ), aCharacters( aChars ){}; 148 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 ); 160 sal_uLong GetChildCount(){ return aDocumentNodeList.Count(); } 161 NodeRef GetChild( sal_uInt16 nIndex ){ return aDocumentNodeList.GetObject( nIndex ); } 162 Reference < XAttributeList > GetAttributes(){ return xAttributeList; } 163 164 String GetNodeName() { return aNodeName; } 165 }; 166 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 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 216 NodeRef GetCurrentNode(){ return xCurrentNode; } 217 void SetCurrentNode( NodeRef xCurrent ){ xCurrentNode = xCurrent; } 218 NodeRef GetRootNode(){ return xTreeRoot; } 219 sal_uLong GetTimestamp(){ return nTimestamp; } 220 void Touch(){ nTimestamp = Time::GetSystemTicks(); } 221 222 // Methods SAXParser 223 sal_Bool Parse( ParseAction aAct ); 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 243 SAXParser::SAXParser( const String &rFilename ) 244 : aFilename( rFilename ) 245 { 246 Touch(); 247 } 248 249 SAXParser::~SAXParser() 250 { 251 xParser.clear(); 252 } 253 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 deletet 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 ); // otherwile Object holds itself 292 if ( aAction == COLLECT_DATA || aAction == COLLECT_DATA_IGNORE_WHITESPACE ) 293 xParser->setDocumentHandler( NULL ); // otherwile Object holds itself 294 } 295 else 296 return sal_False; 297 return sal_True; 298 } 299 300 301 // Helper Methods XErrorHandler 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 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 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 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 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 344 void SAXParser::endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException) 345 { 346 } 347 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 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 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 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 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 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 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 spechial 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