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