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