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_io.hxx" 30 #include <com/sun/star/test/XSimpleTest.hpp> 31 #include <com/sun/star/io/XActiveDataSink.hpp> 32 #include <com/sun/star/io/XActiveDataSource.hpp> 33 #include <com/sun/star/io/XMarkableStream.hpp> 34 #include <com/sun/star/io/XConnectable.hpp> 35 36 #include <com/sun/star/lang/XServiceInfo.hpp> 37 38 #include <cppuhelper/factory.hxx> 39 40 #include <cppuhelper/implbase1.hxx> 41 #include <cppuhelper/implbase2.hxx> 42 43 #include <osl/conditn.hxx> 44 #include <osl/mutex.hxx> 45 46 using namespace ::rtl; 47 using namespace ::osl; 48 using namespace ::cppu; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::io; 51 using namespace ::com::sun::star::lang; 52 using namespace ::com::sun::star::test; 53 // streams 54 55 #include "testfactreg.hxx" 56 57 58 class OMarkableOutputStreamTest : public WeakImplHelper1< XSimpleTest > 59 { 60 public: 61 OMarkableOutputStreamTest( const Reference< XMultiServiceFactory > & rFactory ); 62 ~OMarkableOutputStreamTest(); 63 64 public: // implementation names 65 static Sequence< OUString > getSupportedServiceNames_Static(void) throw (); 66 static OUString getImplementationName_Static() throw (); 67 68 public: 69 virtual void SAL_CALL testInvariant( 70 const OUString& TestName, 71 const Reference < XInterface >& TestObject) 72 throw ( IllegalArgumentException, 73 RuntimeException) ; 74 75 virtual sal_Int32 SAL_CALL test( const OUString& TestName, 76 const Reference < XInterface >& TestObject, 77 sal_Int32 hTestHandle) 78 throw ( IllegalArgumentException, RuntimeException); 79 virtual sal_Bool SAL_CALL testPassed(void) 80 throw ( RuntimeException); 81 virtual Sequence< OUString > SAL_CALL getErrors(void) 82 throw (RuntimeException); 83 virtual Sequence< Any > SAL_CALL getErrorExceptions(void) 84 throw (RuntimeException); 85 virtual Sequence< OUString > SAL_CALL getWarnings(void) 86 throw (RuntimeException); 87 88 private: 89 void testSimple( const Reference< XOutputStream > &r, const Reference < XInputStream > &rInput ); 90 91 private: 92 Sequence<Any> m_seqExceptions; 93 Sequence<OUString> m_seqErrors; 94 Sequence<OUString> m_seqWarnings; 95 Reference< XMultiServiceFactory > m_rFactory; 96 97 }; 98 99 OMarkableOutputStreamTest::OMarkableOutputStreamTest( const Reference< XMultiServiceFactory > &rFactory ) 100 : m_rFactory( rFactory ) 101 { 102 103 } 104 105 OMarkableOutputStreamTest::~OMarkableOutputStreamTest() 106 { 107 108 } 109 110 111 112 113 void OMarkableOutputStreamTest::testInvariant( const OUString& TestName, 114 const Reference < XInterface >& TestObject ) 115 throw ( IllegalArgumentException, RuntimeException) 116 { 117 Reference< XServiceInfo > info( TestObject, UNO_QUERY ); 118 ERROR_ASSERT( info.is() , "XServiceInfo not supported !" ); 119 if( info.is() ) 120 { 121 ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" ); 122 ERROR_ASSERT( ! info->supportsService( 123 OUString( RTL_CONSTASCII_USTRINGPARAM("bla bluzb")) ) , "XServiceInfo test failed" ); 124 } 125 } 126 127 128 sal_Int32 OMarkableOutputStreamTest::test( 129 const OUString& TestName, 130 const Reference < XInterface >& TestObject, 131 sal_Int32 hTestHandle) 132 throw ( IllegalArgumentException, RuntimeException) 133 { 134 if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.MarkableOutputStream") ) 135 == TestName ) { 136 try 137 { 138 if( 0 == hTestHandle ) 139 { 140 testInvariant( TestName , TestObject ); 141 } 142 else 143 { 144 Reference < XInterface > x = m_rFactory->createInstance( OUString::createFromAscii("com.sun.star.io.Pipe")); 145 Reference< XOutputStream > rPipeOutput( x , UNO_QUERY ); 146 Reference < XInputStream > rPipeInput( x , UNO_QUERY ); 147 148 Reference< XActiveDataSource > source( TestObject , UNO_QUERY ); 149 source->setOutputStream( rPipeOutput ); 150 151 Reference< XOutputStream > rOutput( TestObject , UNO_QUERY ); 152 153 OSL_ASSERT( rPipeInput.is() ); 154 OSL_ASSERT( rOutput.is() ); 155 if( 1 == hTestHandle ) { 156 // checks usual streaming 157 testSimple( rOutput , rPipeInput ); 158 } 159 } 160 161 } 162 catch( Exception &e ) 163 { 164 OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); 165 BUILD_ERROR( 0 , o.getStr() ); 166 } 167 catch( ... ) 168 { 169 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); 170 } 171 172 hTestHandle ++; 173 174 if( 2 == hTestHandle ) 175 { 176 // all tests finished. 177 hTestHandle = -1; 178 } 179 } 180 else { 181 throw IllegalArgumentException(); 182 } 183 return hTestHandle; 184 } 185 186 187 188 sal_Bool OMarkableOutputStreamTest::testPassed(void) throw (RuntimeException) 189 { 190 return m_seqErrors.getLength() == 0; 191 } 192 193 194 Sequence< OUString > OMarkableOutputStreamTest::getErrors(void) throw (RuntimeException) 195 { 196 return m_seqErrors; 197 } 198 199 200 Sequence< Any > OMarkableOutputStreamTest::getErrorExceptions(void) throw (RuntimeException) 201 { 202 return m_seqExceptions; 203 } 204 205 206 Sequence< OUString > OMarkableOutputStreamTest::getWarnings(void) throw (RuntimeException) 207 { 208 return m_seqWarnings; 209 } 210 211 212 void OMarkableOutputStreamTest::testSimple( const Reference< XOutputStream > &rOutput , 213 const Reference< XInputStream > &rInput ) 214 { 215 Reference < XMarkableStream > rMarkable( rOutput , UNO_QUERY ); 216 217 ERROR_ASSERT( rMarkable.is() , "no MarkableStream implemented" ); 218 219 // first check normal input/output facility 220 char pcStr[] = "Live long and prosper !"; 221 222 Sequence<sal_Int8> seqWrite( strlen( pcStr )+1 ); 223 memcpy( seqWrite.getArray() , pcStr , seqWrite.getLength() ); 224 225 Sequence<sal_Int8> seqRead( seqWrite.getLength() ); 226 227 int nMax = 10,i; 228 229 for( i = 0 ; i < nMax ; i ++ ) { 230 rOutput->writeBytes( seqWrite ); 231 rInput->readBytes( seqRead , rInput->available() ); 232 ERROR_ASSERT( ! strcmp( (char *) seqWrite.getArray() , (char * )seqRead.getArray() ) , 233 "error during read/write/skip" ); 234 } 235 236 // Check buffer resizing 237 nMax = 3000; 238 for( i = 0 ; i < nMax ; i ++ ) { 239 rOutput->writeBytes( seqWrite ); 240 } 241 242 for( i = 0 ; i < nMax ; i ++ ) { 243 rInput->readBytes( seqRead , seqWrite.getLength() ); 244 ERROR_ASSERT( ! strcmp( (char *) seqWrite.getArray() , (char * )seqRead.getArray() ) , 245 "error during read/write" ); 246 } 247 248 // Check creating marks ! 249 sal_Int32 nMark = rMarkable->createMark(); 250 251 for( i = 0 ; i < nMax ; i ++ ) { 252 rOutput->writeBytes( seqWrite ); 253 } 254 255 ERROR_ASSERT( 0 == rInput->available() , "bytes available though mark is holded" ); 256 257 ERROR_ASSERT( nMax*seqWrite.getLength() == rMarkable->offsetToMark( nMark ) , 258 "offsetToMark failure" ); 259 260 rMarkable->deleteMark( nMark ); 261 ERROR_ASSERT( nMax*seqWrite.getLength() == rInput->available(),"bytes are not available though mark has been deleted" ); 262 263 rInput->skipBytes( nMax*seqWrite.getLength() ); 264 ERROR_ASSERT( 0 == rInput->available(), "skip bytes failure" ); 265 266 try 267 { 268 rMarkable->jumpToMark( nMark ); 269 ERROR_ASSERT( 0 , "jump to non existing mark possible !" ); 270 } 271 catch ( IllegalArgumentException & ) 272 { 273 // ok, exception was thrown 274 } 275 276 // test putting marks not at the end of the stream! 277 ERROR_ASSERT( 0 == rInput->available(), "stream isn't clean" ); 278 { 279 Sequence< sal_Int8 > aByte(256); 280 281 for( i = 0 ; i < 256 ; i ++ ) 282 { 283 aByte.getArray()[i] = i; 284 } 285 sal_Int32 nMark1 = rMarkable->createMark(); 286 287 rOutput->writeBytes( aByte ); 288 rMarkable->jumpToMark( nMark1 ); 289 aByte.realloc( 10 ); 290 rOutput->writeBytes( aByte ); 291 292 sal_Int32 nMark2 = rMarkable->createMark( ); 293 294 for( i = 0 ; i < 10 ; i ++ ) 295 { 296 aByte.getArray()[i] = i+10; 297 } 298 299 rOutput->writeBytes( aByte ); 300 301 // allow the bytes to be written ! 302 rMarkable->jumpToFurthest(); 303 rMarkable->deleteMark( nMark1 ); 304 rMarkable->deleteMark( nMark2 ); 305 306 ERROR_ASSERT( 256 == rInput->available(), "in between mark failure" ); 307 rInput->readBytes( aByte ,256); 308 for( i = 0 ; i < 256 ; i ++ ) 309 { 310 ERROR_ASSERT( i == ((sal_uInt8*)(aByte.getArray()))[i] , "in between mark failure" ); 311 } 312 } 313 314 { 315 // now a more extensive mark test ! 316 Sequence<sal_Int8> as[4]; 317 sal_Int32 an[4]; 318 319 for( i = 0 ; i < 4 ; i ++ ) { 320 as[i].realloc(1); 321 as[i].getArray()[0] = i; 322 an[i] = rMarkable->createMark(); 323 rOutput->writeBytes( as[i] ); 324 } 325 326 // check offset to mark 327 for( i = 0 ; i < 4 ; i ++ ) { 328 ERROR_ASSERT( rMarkable->offsetToMark( an[i] ) == 4-i , "offsetToMark failure" ); 329 } 330 331 rMarkable->jumpToMark( an[1] ); 332 ERROR_ASSERT( rMarkable->offsetToMark( an[3] ) == -2 , "offsetToMark failure" ); 333 334 rMarkable->jumpToFurthest( ); 335 ERROR_ASSERT( rMarkable->offsetToMark( an[0] ) == 4 , "offsetToMark failure" ); 336 337 // now do a rewrite ! 338 for( i = 0 ; i < 4 ; i ++ ) { 339 rMarkable->jumpToMark( an[3-i] ); 340 rOutput->writeBytes( as[i] ); 341 } 342 // NOTE : CursorPos 1 343 344 // now delete the marks ! 345 for( i = 0 ; i < 4 ; i ++ ) { 346 rMarkable->deleteMark( an[i] ); 347 } 348 ERROR_ASSERT( rInput->available() == 1 , "wrong number of bytes flushed" ); 349 350 rMarkable->jumpToFurthest(); 351 352 ERROR_ASSERT( rInput->available() == 4 , "wrong number of bytes flushed" ); 353 354 rInput->readBytes( seqRead , 4 ); 355 356 ERROR_ASSERT( 3 == seqRead.getArray()[0] , "rewrite didn't work" ); 357 ERROR_ASSERT( 2 == seqRead.getArray()[1] , "rewrite didn't work" ); 358 ERROR_ASSERT( 1 == seqRead.getArray()[2] , "rewrite didn't work" ); 359 ERROR_ASSERT( 0 == seqRead.getArray()[3] , "rewrite didn't work" ); 360 361 rOutput->closeOutput(); 362 rInput->closeInput(); 363 } 364 365 } 366 367 /*** 368 * the test methods 369 * 370 ****/ 371 372 373 374 375 376 /** 377 * for external binding 378 * 379 * 380 **/ 381 Reference < XInterface > SAL_CALL OMarkableOutputStreamTest_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) throw(Exception) 382 { 383 OMarkableOutputStreamTest *p = new OMarkableOutputStreamTest( rSMgr ); 384 return Reference < XInterface > ( SAL_STATIC_CAST( OWeakObject * , p ) ); 385 } 386 387 388 389 Sequence<OUString> OMarkableOutputStreamTest_getSupportedServiceNames(void) throw () 390 { 391 Sequence<OUString> aRet(1); 392 aRet.getArray()[0] = OMarkableOutputStreamTest_getImplementationName(); 393 394 return aRet; 395 } 396 397 OUString OMarkableOutputStreamTest_getServiceName() throw () 398 { 399 return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.star.io.MarkableOutputStream")); 400 } 401 402 OUString OMarkableOutputStreamTest_getImplementationName() throw () 403 { 404 return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.starextensions.stm.MarkableOutputStream")); 405 } 406 407 408 409 410 411 412 413 //----------------------------------------------------- 414 // Input stream 415 416 417 class OMarkableInputStreamTest : public WeakImplHelper1< XSimpleTest > 418 { 419 public: 420 OMarkableInputStreamTest( const Reference< XMultiServiceFactory > & rFactory ); 421 ~OMarkableInputStreamTest(); 422 423 public: // implementation names 424 static Sequence< OUString > getSupportedServiceNames_Static(void) throw () ; 425 static OUString getImplementationName_Static() throw () ; 426 427 public: 428 virtual void SAL_CALL testInvariant( 429 const OUString& TestName, 430 const Reference < XInterface >& TestObject) 431 throw ( IllegalArgumentException, RuntimeException) ; 432 433 virtual sal_Int32 SAL_CALL test( 434 const OUString& TestName, 435 const Reference < XInterface >& TestObject, 436 sal_Int32 hTestHandle) 437 throw ( IllegalArgumentException, 438 RuntimeException) ; 439 440 virtual sal_Bool SAL_CALL testPassed(void) 441 throw ( RuntimeException); 442 virtual Sequence< OUString > SAL_CALL getErrors(void) 443 throw (RuntimeException); 444 virtual Sequence< Any > SAL_CALL getErrorExceptions(void) 445 throw (RuntimeException); 446 virtual Sequence< OUString > SAL_CALL getWarnings(void) 447 throw (RuntimeException); 448 449 private: 450 void testSimple( const Reference< XOutputStream > &r, 451 const Reference < XInputStream > &rInput ); 452 453 private: 454 Sequence<Any> m_seqExceptions; 455 Sequence<OUString> m_seqErrors; 456 Sequence<OUString> m_seqWarnings; 457 Reference< XMultiServiceFactory > m_rFactory; 458 459 }; 460 461 OMarkableInputStreamTest::OMarkableInputStreamTest( const Reference< XMultiServiceFactory > &rFactory ) 462 : m_rFactory( rFactory ) 463 { 464 465 } 466 467 OMarkableInputStreamTest::~OMarkableInputStreamTest() 468 { 469 470 } 471 472 473 474 void OMarkableInputStreamTest::testInvariant( 475 const OUString& TestName, const Reference < XInterface >& TestObject ) 476 throw ( IllegalArgumentException, RuntimeException) 477 { 478 if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.MarkableInputStream")) 479 == TestName ) { 480 Reference <XServiceInfo > info( TestObject, UNO_QUERY ); 481 ERROR_ASSERT( info.is() , "XServiceInfo not supported !" ); 482 if( info.is() ) 483 { 484 ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" ); 485 ERROR_ASSERT( 486 ! info->supportsService( 487 OUString(RTL_CONSTASCII_USTRINGPARAM("bla bluzb")) ) , 488 "XServiceInfo test failed" ); 489 } 490 } 491 else 492 { 493 throw IllegalArgumentException(); 494 } 495 } 496 497 498 sal_Int32 OMarkableInputStreamTest::test( 499 const OUString& TestName, 500 const Reference < XInterface >& TestObject, 501 sal_Int32 hTestHandle) throw ( IllegalArgumentException, RuntimeException) 502 { 503 if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.MarkableInputStream")) == TestName ) 504 { 505 try 506 { 507 if( 0 == hTestHandle ) { 508 testInvariant( TestName , TestObject ); 509 } 510 else { 511 Reference < XInterface > x = m_rFactory->createInstance( OUString::createFromAscii("com.sun.star.io.Pipe")); 512 Reference< XOutputStream > rPipeOutput( x , UNO_QUERY ); 513 Reference < XInputStream > rPipeInput( x , UNO_QUERY ); 514 515 Reference < XActiveDataSink > sink( TestObject , UNO_QUERY ); 516 sink->setInputStream( rPipeInput ); 517 518 Reference < XInputStream > rInput( TestObject , UNO_QUERY ); 519 520 OSL_ASSERT( rPipeOutput.is() ); 521 OSL_ASSERT( rInput.is() ); 522 if( 1 == hTestHandle ) { 523 // checks usual streaming 524 testSimple( rPipeOutput , rInput ); 525 } 526 } 527 528 } 529 catch( Exception & e ) 530 { 531 OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); 532 BUILD_ERROR( 0 , o.getStr() ); 533 } 534 catch( ... ) 535 { 536 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); 537 } 538 539 hTestHandle ++; 540 541 if( 2 == hTestHandle ) { 542 // all tests finished. 543 hTestHandle = -1; 544 } 545 } 546 else 547 { 548 throw IllegalArgumentException(); 549 } 550 return hTestHandle; 551 } 552 553 554 555 sal_Bool OMarkableInputStreamTest::testPassed(void) throw (RuntimeException) 556 { 557 return m_seqErrors.getLength() == 0; 558 } 559 560 561 Sequence< OUString > OMarkableInputStreamTest::getErrors(void) throw (RuntimeException) 562 { 563 return m_seqErrors; 564 } 565 566 567 Sequence< Any > OMarkableInputStreamTest::getErrorExceptions(void) throw (RuntimeException) 568 { 569 return m_seqExceptions; 570 } 571 572 573 Sequence< OUString > OMarkableInputStreamTest::getWarnings(void) throw (RuntimeException) 574 { 575 return m_seqWarnings; 576 } 577 578 579 void OMarkableInputStreamTest::testSimple( const Reference< XOutputStream > &rOutput , 580 const Reference < XInputStream > &rInput ) 581 { 582 Reference < XMarkableStream > rMarkable( rInput , UNO_QUERY ); 583 584 Sequence<sal_Int8> seqWrite( 256 ); 585 Sequence<sal_Int8> seqRead(10); 586 587 for( int i = 0 ; i < 256 ; i ++ ) 588 { 589 seqWrite.getArray()[i] = i; 590 } 591 592 rOutput->writeBytes( seqWrite ); 593 ERROR_ASSERT( 256 == rInput->available() , "basic read/write failure" ); 594 595 rInput->readBytes( seqRead , 10 ); 596 ERROR_ASSERT( 9 == seqRead.getArray()[9] , "basic read/write failure" ); 597 598 sal_Int32 nMark = rMarkable->createMark(); 599 600 rInput->skipBytes( 50 ); 601 ERROR_ASSERT( 256-10-50 == rInput->available() , "marking error" ); 602 ERROR_ASSERT( 50 == rMarkable->offsetToMark( nMark ) , "marking error" ); 603 604 rMarkable->jumpToMark( nMark ); 605 ERROR_ASSERT( 256-10 == rInput->available() , "marking error" ); 606 607 rInput->readBytes( seqRead , 10 ); 608 ERROR_ASSERT( 10 == seqRead.getArray()[0] , "marking error" ); 609 610 // pos 20 611 { 612 sal_Int32 nInBetweenMark = rMarkable->createMark( ); 613 rMarkable->jumpToMark( nMark ); 614 rMarkable->jumpToMark( nInBetweenMark ); 615 616 rInput->readBytes( seqRead , 10 ); 617 ERROR_ASSERT( 20 == seqRead.getArray()[0] , "Inbetween mark failed!\n" ); 618 619 rMarkable->deleteMark( nMark ); 620 621 // Check if releasing the first bytes works correct. 622 rMarkable->jumpToMark( nInBetweenMark); 623 rInput->readBytes( seqRead , 10 ); 624 ERROR_ASSERT( 20 == seqRead.getArray()[0] , "Inbetween mark failed!\n" ); 625 626 rMarkable->deleteMark( nInBetweenMark ); 627 } 628 629 rMarkable->jumpToFurthest(); 630 ERROR_ASSERT( 256-10-50 == rInput->available() , "marking error" ); 631 632 633 ERROR_ASSERT( 100 == rInput->readSomeBytes( seqRead , 100 ) , "wrong results using readSomeBytes" ); 634 ERROR_ASSERT( 96 == rInput->readSomeBytes( seqRead , 1000) , "wrong results using readSomeBytes" ); 635 rOutput->closeOutput(); 636 rInput->closeInput(); 637 } 638 639 /*** 640 * the test methods 641 * 642 ****/ 643 644 645 646 647 648 /** 649 * for external binding 650 * 651 * 652 **/ 653 Reference < XInterface > SAL_CALL OMarkableInputStreamTest_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) throw(Exception) 654 { 655 OMarkableInputStreamTest *p = new OMarkableInputStreamTest( rSMgr ); 656 return Reference < XInterface > ( SAL_STATIC_CAST( OWeakObject * , p ) ); 657 } 658 659 660 661 Sequence<OUString> OMarkableInputStreamTest_getSupportedServiceNames(void) throw () 662 { 663 Sequence<OUString> aRet(1); 664 aRet.getArray()[0] = OMarkableInputStreamTest_getImplementationName(); 665 666 return aRet; 667 } 668 669 OUString OMarkableInputStreamTest_getServiceName() throw () 670 { 671 return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.star.io.MarkableInputStream")); 672 } 673 674 OUString OMarkableInputStreamTest_getImplementationName() throw () 675 { 676 return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.star.extensions.stm.MarkableInputStream" )); 677 } 678