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_extensions.hxx" 30 #include <smart/com/sun/star/test/XSimpleTest.hxx> 31 #include <smart/com/sun/star/io/XMarkableStream.hxx> 32 #include <smart/com/sun/star/io/XActiveDataSink.hxx> 33 #include <smart/com/sun/star/io/XActiveDataSource.hxx> 34 #include <smart/com/sun/star/io/XConnectable.hxx> 35 36 #include <smart/com/sun/star/lang/XServiceInfo.hxx> 37 38 39 #include <usr/factoryhlp.hxx> 40 41 #include <usr/reflserv.hxx> // for EXTERN_SERVICE_CALLTYPE 42 #include <usr/weak.hxx> // OWeakObject 43 44 #include <vos/conditn.hxx> 45 #include <vos/mutex.hxx> 46 #include <vos/thread.hxx> 47 48 #include <string.h> 49 50 #include "testfactreg.hxx" 51 52 53 using namespace vos; 54 using namespace usr; 55 56 class OMarkableOutputStreamTest : 57 public XSimpleTest, 58 public OWeakObject 59 { 60 public: 61 OMarkableOutputStreamTest( const XMultiServiceFactoryRef & rFactory ); 62 ~OMarkableOutputStreamTest(); 63 64 public: // refcounting 65 BOOL queryInterface( Uik aUik, XInterfaceRef & rOut ); 66 void acquire() { OWeakObject::acquire(); } 67 void release() { OWeakObject::release(); } 68 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } 69 70 public: // implementation names 71 static Sequence< UString > getSupportedServiceNames_Static(void) THROWS( () ); 72 static UString getImplementationName_Static() THROWS( () ); 73 74 public: 75 virtual void testInvariant(const UString& TestName, const XInterfaceRef& TestObject) 76 THROWS( ( IllegalArgumentException, 77 UsrSystemException) ); 78 79 virtual INT32 test( const UString& TestName, 80 const XInterfaceRef& TestObject, 81 INT32 hTestHandle) THROWS( ( IllegalArgumentException, 82 UsrSystemException) ); 83 84 virtual BOOL testPassed(void) THROWS( ( UsrSystemException) ); 85 virtual Sequence< UString > getErrors(void) THROWS( (UsrSystemException) ); 86 virtual Sequence< UsrAny > getErrorExceptions(void) THROWS( (UsrSystemException) ); 87 virtual Sequence< UString > getWarnings(void) THROWS( (UsrSystemException) ); 88 89 private: 90 void testSimple( const XOutputStreamRef &r, const XInputStreamRef &rInput ); 91 92 private: 93 Sequence<UsrAny> m_seqExceptions; 94 Sequence<UString> m_seqErrors; 95 Sequence<UString> m_seqWarnings; 96 XMultiServiceFactoryRef m_rFactory; 97 98 }; 99 100 OMarkableOutputStreamTest::OMarkableOutputStreamTest( const XMultiServiceFactoryRef &rFactory ) 101 : m_rFactory( rFactory ) 102 { 103 104 } 105 106 OMarkableOutputStreamTest::~OMarkableOutputStreamTest() 107 { 108 109 } 110 111 112 BOOL OMarkableOutputStreamTest::queryInterface( Uik uik , XInterfaceRef &rOut ) 113 { 114 if( XSimpleTest::getSmartUik() == uik ) { 115 rOut = (XSimpleTest *) this; 116 } 117 else { 118 return OWeakObject::queryInterface( uik , rOut ); 119 } 120 return TRUE; 121 } 122 123 124 void OMarkableOutputStreamTest::testInvariant( const UString& TestName, const XInterfaceRef& TestObject ) 125 THROWS( ( IllegalArgumentException, 126 UsrSystemException) ) 127 { 128 XServiceInfoRef info( TestObject, USR_QUERY ); 129 ERROR_ASSERT( info.is() , "XServiceInfo not supported !" ); 130 if( info.is() ) 131 { 132 ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" ); 133 ERROR_ASSERT( ! info->supportsService( L"bla bluzb" ) , "XServiceInfo test failed" ); 134 } 135 } 136 137 138 INT32 OMarkableOutputStreamTest::test( const UString& TestName, 139 const XInterfaceRef& TestObject, 140 INT32 hTestHandle) THROWS( ( IllegalArgumentException, 141 UsrSystemException) ) 142 { 143 if( L"com.sun.star.io.MarkableOutputStream" == TestName ) { 144 try { 145 if( 0 == hTestHandle ) { 146 testInvariant( TestName , TestObject ); 147 } 148 else { 149 XInterfaceRef x = m_rFactory->createInstance( L"com.sun.star.io.Pipe"); 150 XOutputStreamRef rPipeOutput( x , USR_QUERY ); 151 XInputStreamRef rPipeInput( x , USR_QUERY ); 152 153 XActiveDataSourceRef source( TestObject , USR_QUERY ); 154 source->setOutputStream( rPipeOutput ); 155 156 XOutputStreamRef rOutput( TestObject , USR_QUERY ); 157 158 OSL_ASSERT( rPipeInput.is() ); 159 OSL_ASSERT( rOutput.is() ); 160 if( 1 == hTestHandle ) { 161 // checks usual streaming 162 testSimple( rOutput , rPipeInput ); 163 } 164 } 165 166 } 167 catch( Exception& e ) { 168 BUILD_ERROR( 0 , UStringToString( e.getName() , CHARSET_SYSTEM ).GetCharStr() ); 169 } 170 catch(...) { 171 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); 172 } 173 174 hTestHandle ++; 175 176 if( 2 == hTestHandle ) { 177 // all tests finished. 178 hTestHandle = -1; 179 } 180 } 181 else { 182 THROW( IllegalArgumentException() ); 183 } 184 return hTestHandle; 185 } 186 187 188 189 BOOL OMarkableOutputStreamTest::testPassed(void) THROWS( (UsrSystemException) ) 190 { 191 return m_seqErrors.getLen() == 0; 192 } 193 194 195 Sequence< UString > OMarkableOutputStreamTest::getErrors(void) THROWS( (UsrSystemException) ) 196 { 197 return m_seqErrors; 198 } 199 200 201 Sequence< UsrAny > OMarkableOutputStreamTest::getErrorExceptions(void) THROWS( (UsrSystemException) ) 202 { 203 return m_seqExceptions; 204 } 205 206 207 Sequence< UString > OMarkableOutputStreamTest::getWarnings(void) THROWS( (UsrSystemException) ) 208 { 209 return m_seqWarnings; 210 } 211 212 213 void OMarkableOutputStreamTest::testSimple( const XOutputStreamRef &rOutput , 214 const XInputStreamRef &rInput ) 215 { 216 XMarkableStreamRef rMarkable( rOutput , USR_QUERY ); 217 218 ERROR_ASSERT( rMarkable.is() , "no MarkableStream implemented" ); 219 220 // first check normal input/output facility 221 char pcStr[] = "Live long and prosper !"; 222 223 Sequence<BYTE> seqWrite( strlen( pcStr )+1 ); 224 memcpy( seqWrite.getArray() , pcStr , seqWrite.getLen() ); 225 226 Sequence<BYTE> seqRead( seqWrite.getLen() ); 227 228 int nMax = 10,i; 229 230 for( i = 0 ; i < nMax ; i ++ ) { 231 rOutput->writeBytes( seqWrite ); 232 rInput->readBytes( seqRead , rInput->available() ); 233 ERROR_ASSERT( ! strcmp( (char *) seqWrite.getArray() , (char * )seqRead.getArray() ) , 234 "error during read/write/skip" ); 235 } 236 237 // Check buffer resizing 238 nMax = 3000; 239 for( i = 0 ; i < nMax ; i ++ ) { 240 rOutput->writeBytes( seqWrite ); 241 } 242 243 for( i = 0 ; i < nMax ; i ++ ) { 244 rInput->readBytes( seqRead , seqWrite.getLen() ); 245 ERROR_ASSERT( ! strcmp( (char *) seqWrite.getArray() , (char * )seqRead.getArray() ) , 246 "error during read/write" ); 247 } 248 249 // Check creating marks ! 250 INT32 nMark = rMarkable->createMark(); 251 252 for( i = 0 ; i < nMax ; i ++ ) { 253 rOutput->writeBytes( seqWrite ); 254 } 255 256 ERROR_ASSERT( 0 == rInput->available() , "bytes available though mark is holded" ); 257 258 ERROR_ASSERT( nMax*seqWrite.getLen() == rMarkable->offsetToMark( nMark ) , 259 "offsetToMark failure" ); 260 261 rMarkable->deleteMark( nMark ); 262 ERROR_ASSERT( nMax*seqWrite.getLen() == rInput->available(),"bytes are not available though mark has been deleted" ); 263 264 rInput->skipBytes( nMax*seqWrite.getLen() ); 265 ERROR_ASSERT( 0 == rInput->available(), "skip bytes failure" ); 266 267 try { 268 rMarkable->jumpToMark( nMark ); 269 ERROR_ASSERT( 0 , "jump to non existing mark possible !" ); 270 } 271 catch ( IllegalArgumentException& e ) 272 { 273 e;// 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< BYTE > aByte(256); 280 281 for( i = 0 ; i < 256 ; i ++ ) 282 { 283 aByte.getArray()[i] = i; 284 } 285 INT32 nMark1 = rMarkable->createMark(); 286 287 rOutput->writeBytes( aByte ); 288 rMarkable->jumpToMark( nMark1 ); 289 aByte.realloc( 10 ); 290 rOutput->writeBytes( aByte ); 291 292 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 == aByte.getArray()[i] , "in between mark failure" ); 311 } 312 } 313 314 { 315 // now a more extensive mark test ! 316 Sequence<BYTE> as[4]; 317 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 XInterfaceRef OMarkableOutputStreamTest_CreateInstance( const XMultiServiceFactoryRef & rSMgr ) THROWS((Exception)) 382 { 383 OMarkableOutputStreamTest *p = new OMarkableOutputStreamTest( rSMgr ); 384 XInterfaceRef xService = *p; 385 return xService; 386 } 387 388 389 390 Sequence<UString> OMarkableOutputStreamTest_getSupportedServiceNames(void) THROWS( () ) 391 { 392 Sequence<UString> aRet(1); 393 aRet.getArray()[0] = OMarkableOutputStreamTest_getImplementationName(); 394 395 return aRet; 396 } 397 398 UString OMarkableOutputStreamTest_getServiceName() THROWS( () ) 399 { 400 return L"test.com.sun.star.io.MarkableOutputStream"; 401 } 402 403 UString OMarkableOutputStreamTest_getImplementationName() THROWS( () ) 404 { 405 return L"test.com.sun.starextensions.stm.MarkableOutputStream"; 406 } 407 408 409 410 411 412 413 414 //----------------------------------------------------- 415 // Input stream 416 417 418 class OMarkableInputStreamTest : 419 public XSimpleTest, 420 public OWeakObject 421 { 422 public: 423 OMarkableInputStreamTest( const XMultiServiceFactoryRef & rFactory ); 424 ~OMarkableInputStreamTest(); 425 426 public: // refcounting 427 BOOL queryInterface( Uik aUik, XInterfaceRef & rOut ); 428 void acquire() { OWeakObject::acquire(); } 429 void release() { OWeakObject::release(); } 430 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } 431 432 public: // implementation names 433 static Sequence< UString > getSupportedServiceNames_Static(void) THROWS( () ); 434 static UString getImplementationName_Static() THROWS( () ); 435 436 public: 437 virtual void testInvariant(const UString& TestName, const XInterfaceRef& TestObject) 438 THROWS( ( IllegalArgumentException, 439 UsrSystemException) ); 440 441 virtual INT32 test( const UString& TestName, 442 const XInterfaceRef& TestObject, 443 INT32 hTestHandle) THROWS( ( IllegalArgumentException, 444 UsrSystemException) ); 445 446 virtual BOOL testPassed(void) THROWS( ( UsrSystemException) ); 447 virtual Sequence< UString > getErrors(void) THROWS( (UsrSystemException) ); 448 virtual Sequence< UsrAny > getErrorExceptions(void) THROWS( (UsrSystemException) ); 449 virtual Sequence< UString > getWarnings(void) THROWS( (UsrSystemException) ); 450 451 private: 452 void testSimple( const XOutputStreamRef &r, const XInputStreamRef &rInput ); 453 454 private: 455 Sequence<UsrAny> m_seqExceptions; 456 Sequence<UString> m_seqErrors; 457 Sequence<UString> m_seqWarnings; 458 XMultiServiceFactoryRef m_rFactory; 459 460 }; 461 462 OMarkableInputStreamTest::OMarkableInputStreamTest( const XMultiServiceFactoryRef &rFactory ) 463 : m_rFactory( rFactory ) 464 { 465 466 } 467 468 OMarkableInputStreamTest::~OMarkableInputStreamTest() 469 { 470 471 } 472 473 474 BOOL OMarkableInputStreamTest::queryInterface( Uik uik , XInterfaceRef &rOut ) 475 { 476 if( XSimpleTest::getSmartUik() == uik ) { 477 rOut = (XSimpleTest *) this; 478 } 479 else { 480 return OWeakObject::queryInterface( uik , rOut ); 481 } 482 return TRUE; 483 } 484 485 486 void OMarkableInputStreamTest::testInvariant( const UString& TestName, const XInterfaceRef& TestObject ) 487 THROWS( ( IllegalArgumentException, 488 UsrSystemException) ) 489 { 490 if( L"com.sun.star.io.MarkableInputStream" == TestName ) { 491 XServiceInfoRef info( TestObject, USR_QUERY ); 492 ERROR_ASSERT( info.is() , "XServiceInfo not supported !" ); 493 if( info.is() ) 494 { 495 ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" ); 496 ERROR_ASSERT( ! info->supportsService( L"bla bluzb" ) , "XServiceInfo test failed" ); 497 } 498 } 499 else { 500 THROW( IllegalArgumentException() ); 501 } 502 } 503 504 505 INT32 OMarkableInputStreamTest::test( const UString& TestName, 506 const XInterfaceRef& TestObject, 507 INT32 hTestHandle) THROWS( ( IllegalArgumentException, 508 UsrSystemException) ) 509 { 510 if( L"com.sun.star.io.MarkableInputStream" == TestName ) { 511 try { 512 if( 0 == hTestHandle ) { 513 testInvariant( TestName , TestObject ); 514 } 515 else { 516 XInterfaceRef x = m_rFactory->createInstance( L"com.sun.star.io.Pipe"); 517 XOutputStreamRef rPipeOutput( x , USR_QUERY ); 518 XInputStreamRef rPipeInput( x , USR_QUERY ); 519 520 XActiveDataSinkRef sink( TestObject , USR_QUERY ); 521 sink->setInputStream( rPipeInput ); 522 523 XInputStreamRef rInput( TestObject , USR_QUERY ); 524 525 OSL_ASSERT( rPipeOutput.is() ); 526 OSL_ASSERT( rInput.is() ); 527 if( 1 == hTestHandle ) { 528 // checks usual streaming 529 testSimple( rPipeOutput , rInput ); 530 } 531 } 532 533 } 534 catch( Exception& e ) { 535 BUILD_ERROR( 0 , UStringToString( e.getName() , CHARSET_SYSTEM ).GetCharStr() ); 536 } 537 catch(...) { 538 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); 539 } 540 541 hTestHandle ++; 542 543 if( 2 == hTestHandle ) { 544 // all tests finished. 545 hTestHandle = -1; 546 } 547 } 548 else { 549 THROW( IllegalArgumentException() ); 550 } 551 return hTestHandle; 552 } 553 554 555 556 BOOL OMarkableInputStreamTest::testPassed(void) THROWS( (UsrSystemException) ) 557 { 558 return m_seqErrors.getLen() == 0; 559 } 560 561 562 Sequence< UString > OMarkableInputStreamTest::getErrors(void) THROWS( (UsrSystemException) ) 563 { 564 return m_seqErrors; 565 } 566 567 568 Sequence< UsrAny > OMarkableInputStreamTest::getErrorExceptions(void) THROWS( (UsrSystemException) ) 569 { 570 return m_seqExceptions; 571 } 572 573 574 Sequence< UString > OMarkableInputStreamTest::getWarnings(void) THROWS( (UsrSystemException) ) 575 { 576 return m_seqWarnings; 577 } 578 579 580 void OMarkableInputStreamTest::testSimple( const XOutputStreamRef &rOutput , 581 const XInputStreamRef &rInput ) 582 { 583 XMarkableStreamRef rMarkable( rInput , USR_QUERY ); 584 585 Sequence<BYTE> seqWrite( 256 ); 586 Sequence<BYTE> seqRead(10); 587 588 for( int i = 0 ; i < 256 ; i ++ ) 589 { 590 seqWrite.getArray()[i] = i; 591 } 592 593 rOutput->writeBytes( seqWrite ); 594 ERROR_ASSERT( 256 == rInput->available() , "basic read/write failure" ); 595 596 rInput->readBytes( seqRead , 10 ); 597 ERROR_ASSERT( 9 == seqRead.getArray()[9] , "basic read/write failure" ); 598 599 INT32 nMark = rMarkable->createMark(); 600 601 rInput->skipBytes( 50 ); 602 ERROR_ASSERT( 256-10-50 == rInput->available() , "marking error" ); 603 ERROR_ASSERT( 50 == rMarkable->offsetToMark( nMark ) , "marking error" ); 604 605 rMarkable->jumpToMark( nMark ); 606 ERROR_ASSERT( 256-10 == rInput->available() , "marking error" ); 607 608 rInput->readBytes( seqRead , 10 ); 609 ERROR_ASSERT( 10 == seqRead.getArray()[0] , "marking error" ); 610 611 // pos 20 612 { 613 INT32 nInBetweenMark = rMarkable->createMark( ); 614 rMarkable->jumpToMark( nMark ); 615 rMarkable->jumpToMark( nInBetweenMark ); 616 617 rInput->readBytes( seqRead , 10 ); 618 ERROR_ASSERT( 20 == seqRead.getArray()[0] , "Inbetween mark failed!\n" ); 619 620 rMarkable->deleteMark( nMark ); 621 622 // Check if releasing the first bytes works correct. 623 rMarkable->jumpToMark( nInBetweenMark); 624 rInput->readBytes( seqRead , 10 ); 625 ERROR_ASSERT( 20 == seqRead.getArray()[0] , "Inbetween mark failed!\n" ); 626 627 rMarkable->deleteMark( nInBetweenMark ); 628 } 629 630 rMarkable->jumpToFurthest(); 631 ERROR_ASSERT( 256-10-50 == rInput->available() , "marking error" ); 632 633 634 ERROR_ASSERT( 100 == rInput->readSomeBytes( seqRead , 100 ) , "wrong results using readSomeBytes" ); 635 ERROR_ASSERT( 96 == rInput->readSomeBytes( seqRead , 1000) , "wrong results using readSomeBytes" ); 636 rOutput->closeOutput(); 637 rInput->closeInput(); 638 } 639 640 /*** 641 * the test methods 642 * 643 ****/ 644 645 646 647 648 649 /** 650 * for external binding 651 * 652 * 653 **/ 654 XInterfaceRef OMarkableInputStreamTest_CreateInstance( const XMultiServiceFactoryRef & rSMgr ) THROWS((Exception)) 655 { 656 OMarkableInputStreamTest *p = new OMarkableInputStreamTest( rSMgr ); 657 XInterfaceRef xService = *p; 658 return xService; 659 } 660 661 662 663 Sequence<UString> OMarkableInputStreamTest_getSupportedServiceNames(void) THROWS( () ) 664 { 665 Sequence<UString> aRet(1); 666 aRet.getArray()[0] = OMarkableInputStreamTest_getImplementationName(); 667 668 return aRet; 669 } 670 671 UString OMarkableInputStreamTest_getServiceName() THROWS( () ) 672 { 673 return L"test.com.sun.star.io.MarkableInputStream"; 674 } 675 676 UString OMarkableInputStreamTest_getImplementationName() THROWS( () ) 677 { 678 return L"test.com.sun.star.extensions.stm.MarkableInputStream"; 679 } 680