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 31 32 // streams 33 #include <hash_map> 34 #include <vector> 35 36 #include <com/sun/star/io/XObjectInputStream.hpp> 37 #include <com/sun/star/io/XObjectOutputStream.hpp> 38 #include <com/sun/star/io/XActiveDataSource.hpp> 39 #include <com/sun/star/io/XActiveDataSink.hpp> 40 #include <com/sun/star/io/XMarkableStream.hpp> 41 #include <com/sun/star/io/XConnectable.hpp> 42 #include <com/sun/star/io/UnexpectedEOFException.hpp> 43 #include <com/sun/star/io/WrongFormatException.hpp> 44 #include <com/sun/star/lang/XServiceInfo.hpp> 45 46 #include <cppuhelper/weak.hxx> // OWeakObject 47 #include <cppuhelper/factory.hxx> 48 #include <cppuhelper/implbase4.hxx> 49 #include <cppuhelper/typeprovider.hxx> 50 #include <cppuhelper/queryinterface.hxx> 51 52 #include <osl/mutex.hxx> 53 54 #include <string.h> 55 56 57 using namespace ::cppu; 58 using namespace ::osl; 59 using namespace ::std; 60 using namespace ::rtl; 61 using namespace ::com::sun::star::io; 62 using namespace ::com::sun::star::uno; 63 using namespace ::com::sun::star::lang; 64 65 #include "factreg.hxx" 66 67 namespace io_stm { 68 69 class ODataInputStream : 70 public WeakImplHelper4 < 71 XDataInputStream, 72 XActiveDataSink, 73 XConnectable, 74 XServiceInfo 75 > 76 { 77 public: 78 ODataInputStream( ) 79 : m_bValidStream( sal_False ) 80 { 81 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 82 } 83 84 ~ODataInputStream(); 85 public: // XInputStream 86 virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) 87 throw ( NotConnectedException, 88 BufferSizeExceededException, 89 RuntimeException); 90 virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) 91 throw ( NotConnectedException, 92 BufferSizeExceededException, 93 RuntimeException); 94 virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw ( NotConnectedException, 95 BufferSizeExceededException, 96 RuntimeException); 97 virtual sal_Int32 SAL_CALL available(void) throw ( NotConnectedException, 98 RuntimeException); 99 virtual void SAL_CALL closeInput(void) throw ( NotConnectedException, 100 RuntimeException); 101 102 public: // XDataInputStream 103 virtual sal_Int8 SAL_CALL readBoolean(void) throw (IOException, RuntimeException); 104 virtual sal_Int8 SAL_CALL readByte(void) throw (IOException, RuntimeException); 105 virtual sal_Unicode SAL_CALL readChar(void) throw (IOException, RuntimeException); 106 virtual sal_Int16 SAL_CALL readShort(void) throw (IOException, RuntimeException); 107 virtual sal_Int32 SAL_CALL readLong(void) throw (IOException, RuntimeException); 108 virtual sal_Int64 SAL_CALL readHyper(void) throw (IOException, RuntimeException); 109 virtual float SAL_CALL readFloat(void) throw (IOException, RuntimeException); 110 virtual double SAL_CALL readDouble(void) throw (IOException, RuntimeException); 111 virtual OUString SAL_CALL readUTF(void) throw (IOException, RuntimeException); 112 113 114 115 public: // XActiveDataSink 116 virtual void SAL_CALL setInputStream(const Reference< XInputStream > & aStream) 117 throw (RuntimeException); 118 virtual Reference< XInputStream > SAL_CALL getInputStream(void) throw (RuntimeException); 119 120 public: // XConnectable 121 virtual void SAL_CALL setPredecessor(const Reference < XConnectable >& aPredecessor) throw (RuntimeException); 122 virtual Reference < XConnectable > SAL_CALL getPredecessor(void) throw (RuntimeException); 123 virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) throw (RuntimeException); 124 virtual Reference < XConnectable > SAL_CALL getSuccessor(void) throw (RuntimeException) ; 125 126 127 public: // XServiceInfo 128 OUString SAL_CALL getImplementationName() throw (); 129 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); 130 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); 131 132 protected: 133 134 Reference < XConnectable > m_pred; 135 Reference < XConnectable > m_succ; 136 Reference < XInputStream > m_input; 137 sal_Bool m_bValidStream; 138 }; 139 140 ODataInputStream::~ODataInputStream() 141 { 142 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 143 } 144 145 // XInputStream 146 sal_Int32 ODataInputStream::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) 147 throw ( NotConnectedException, 148 BufferSizeExceededException, 149 RuntimeException) 150 { 151 sal_Int32 nRead; 152 153 if( m_bValidStream ) 154 { 155 nRead = m_input->readBytes( aData , nBytesToRead ); 156 } 157 else 158 { 159 throw NotConnectedException( ); 160 } 161 162 return nRead; 163 } 164 165 sal_Int32 ODataInputStream::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) 166 throw ( NotConnectedException, 167 BufferSizeExceededException, 168 RuntimeException) 169 { 170 sal_Int32 nRead; 171 if( m_bValidStream ) { 172 nRead = m_input->readSomeBytes( aData , nMaxBytesToRead ); 173 } 174 else { 175 throw NotConnectedException( ); 176 } 177 178 return nRead; 179 } 180 void ODataInputStream::skipBytes(sal_Int32 nBytesToSkip) 181 throw ( NotConnectedException, 182 BufferSizeExceededException, 183 RuntimeException) 184 { 185 if( m_bValidStream ) { 186 m_input->skipBytes( nBytesToSkip ); 187 } 188 else 189 { 190 throw NotConnectedException( ); 191 } 192 } 193 194 195 sal_Int32 ODataInputStream::available(void) 196 throw ( NotConnectedException, 197 RuntimeException) 198 { 199 sal_Int32 nAvail; 200 201 if( m_bValidStream ) 202 { 203 nAvail = m_input->available( ); 204 } 205 else 206 { 207 throw NotConnectedException( ); 208 } 209 return nAvail; 210 } 211 212 void ODataInputStream::closeInput(void ) 213 throw ( NotConnectedException, 214 RuntimeException) 215 { 216 if( m_bValidStream ) { 217 m_input->closeInput( ); 218 setInputStream( Reference< XInputStream > () ); 219 setPredecessor( Reference < XConnectable >() ); 220 setSuccessor( Reference < XConnectable >() ); 221 m_bValidStream = sal_False; 222 } 223 else 224 { 225 throw NotConnectedException( ); 226 } 227 } 228 229 230 231 232 //== XDataInputStream =========================================== 233 234 // XDataInputStream 235 sal_Int8 ODataInputStream::readBoolean(void) throw (IOException, RuntimeException) 236 { 237 return readByte(); 238 } 239 240 sal_Int8 ODataInputStream::readByte(void) throw (IOException, RuntimeException) 241 { 242 Sequence<sal_Int8> aTmp(1); 243 if( 1 != readBytes( aTmp, 1 ) ) 244 { 245 throw UnexpectedEOFException(); 246 } 247 return aTmp.getArray()[0]; 248 } 249 250 sal_Unicode ODataInputStream::readChar(void) throw (IOException, RuntimeException) 251 { 252 Sequence<sal_Int8> aTmp(2); 253 if( 2 != readBytes( aTmp, 2 ) ) 254 { 255 throw UnexpectedEOFException(); 256 } 257 258 const sal_uInt8 * pBytes = ( const sal_uInt8 * )aTmp.getConstArray(); 259 return ((sal_Unicode)pBytes[0] << 8) + pBytes[1]; 260 } 261 262 sal_Int16 ODataInputStream::readShort(void) throw (IOException, RuntimeException) 263 { 264 Sequence<sal_Int8> aTmp(2); 265 if( 2 != readBytes( aTmp, 2 ) ) 266 { 267 throw UnexpectedEOFException(); 268 } 269 270 const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray(); 271 return ((sal_Int16)pBytes[0] << 8) + pBytes[1]; 272 } 273 274 275 sal_Int32 ODataInputStream::readLong(void) throw (IOException, RuntimeException) 276 { 277 Sequence<sal_Int8> aTmp(4); 278 if( 4 != readBytes( aTmp, 4 ) ) 279 { 280 throw UnexpectedEOFException( ); 281 } 282 283 const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray(); 284 return ((sal_Int32)pBytes[0] << 24) + ((sal_Int32)pBytes[1] << 16) + ((sal_Int32)pBytes[2] << 8) + pBytes[3]; 285 } 286 287 288 sal_Int64 ODataInputStream::readHyper(void) throw (IOException, RuntimeException) 289 { 290 Sequence<sal_Int8> aTmp(8); 291 if( 8 != readBytes( aTmp, 8 ) ) 292 { 293 throw UnexpectedEOFException( ); 294 } 295 296 const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray(); 297 return 298 (((sal_Int64)pBytes[0]) << 56) + 299 (((sal_Int64)pBytes[1]) << 48) + 300 (((sal_Int64)pBytes[2]) << 40) + 301 (((sal_Int64)pBytes[3]) << 32) + 302 (((sal_Int64)pBytes[4]) << 24) + 303 (((sal_Int64)pBytes[5]) << 16) + 304 (((sal_Int64)pBytes[6]) << 8) + 305 pBytes[7]; 306 } 307 308 float ODataInputStream::readFloat(void) throw (IOException, RuntimeException) 309 { 310 union { float f; sal_uInt32 n; } a; 311 a.n = readLong(); 312 return a.f; 313 } 314 315 double ODataInputStream::readDouble(void) throw (IOException, RuntimeException) 316 { 317 sal_uInt32 n = 1; 318 union { double d; struct { sal_uInt32 n1; sal_uInt32 n2; } ad; } a; 319 if( *(sal_uInt8 *)&n == 1 ) 320 { 321 // little endian 322 a.ad.n2 = readLong(); 323 a.ad.n1 = readLong(); 324 } 325 else 326 { 327 // big endian 328 a.ad.n1 = readLong(); 329 a.ad.n2 = readLong(); 330 } 331 return a.d; 332 } 333 334 OUString ODataInputStream::readUTF(void) throw (IOException, RuntimeException) 335 { 336 sal_uInt16 nShortLen = (sal_uInt16)readShort(); 337 sal_Int32 nUTFLen; 338 339 if( ((sal_uInt16)0xffff) == nShortLen ) 340 { 341 // is interpreted as a sign, that string is longer than 64k 342 // incompatible to older XDataInputStream-routines, when strings are exactly 64k 343 nUTFLen = readLong(); 344 } 345 else 346 { 347 nUTFLen = ( sal_Int32 ) nShortLen; 348 } 349 350 Sequence<sal_Unicode> aBuffer( nUTFLen ); 351 sal_Unicode * pStr = aBuffer.getArray(); 352 353 sal_Int32 nCount = 0; 354 sal_Int32 nStrLen = 0; 355 while( nCount < nUTFLen ) 356 { 357 sal_uInt8 c = (sal_uInt8)readByte(); 358 sal_uInt8 char2, char3; 359 switch( c >> 4 ) 360 { 361 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 362 // 0xxxxxxx 363 nCount++; 364 pStr[nStrLen++] = c; 365 break; 366 367 case 12: case 13: 368 // 110x xxxx 10xx xxxx 369 nCount += 2; 370 if( ! ( nCount <= nUTFLen ) ) 371 { 372 throw WrongFormatException( ); 373 } 374 375 char2 = (sal_uInt8)readByte(); 376 if( ! ( (char2 & 0xC0) == 0x80 ) ) 377 { 378 throw WrongFormatException( ); 379 } 380 381 pStr[nStrLen++] = (sal_Unicode(c & 0x1F) << 6) | (char2 & 0x3F); 382 break; 383 384 case 14: 385 // 1110 xxxx 10xx xxxx 10xx xxxx 386 nCount += 3; 387 if( !( nCount <= nUTFLen) ) 388 { 389 throw WrongFormatException( ); 390 } 391 392 char2 = (sal_uInt8)readByte(); 393 char3 = (sal_uInt8)readByte(); 394 395 if( (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) ) { 396 throw WrongFormatException( ); 397 } 398 pStr[nStrLen++] = (sal_Unicode(c & 0x0F) << 12) | 399 (sal_Unicode(char2 & 0x3F) << 6) | 400 (char3 & 0x3F); 401 break; 402 403 default: 404 // 10xx xxxx, 1111 xxxx 405 throw WrongFormatException(); 406 //throw new UTFDataFormatException(); 407 } 408 } 409 return OUString( pStr, nStrLen ); 410 } 411 412 413 414 // XActiveDataSource 415 void ODataInputStream::setInputStream(const Reference< XInputStream > & aStream) 416 throw (RuntimeException) 417 { 418 419 if( m_input != aStream ) { 420 m_input = aStream; 421 422 Reference < XConnectable > pred( m_input , UNO_QUERY ); 423 setPredecessor( pred ); 424 } 425 426 m_bValidStream = m_input.is(); 427 } 428 429 Reference< XInputStream > ODataInputStream::getInputStream(void) throw (RuntimeException) 430 { 431 return m_input; 432 } 433 434 435 436 // XDataSink 437 void ODataInputStream::setSuccessor( const Reference < XConnectable > &r ) throw (RuntimeException) 438 { 439 /// if the references match, nothing needs to be done 440 if( m_succ != r ) { 441 /// store the reference for later use 442 m_succ = r; 443 444 if( m_succ.is() ) { 445 /// set this instance as the sink ! 446 m_succ->setPredecessor( Reference< XConnectable > ( 447 SAL_STATIC_CAST( XConnectable * , this ) ) ); 448 } 449 } 450 } 451 452 Reference < XConnectable > ODataInputStream::getSuccessor() throw (RuntimeException) 453 { 454 return m_succ; 455 } 456 457 458 // XDataSource 459 void ODataInputStream::setPredecessor( const Reference < XConnectable > &r ) 460 throw (RuntimeException) 461 { 462 if( r != m_pred ) { 463 m_pred = r; 464 if( m_pred.is() ) { 465 m_pred->setSuccessor( Reference< XConnectable > ( 466 SAL_STATIC_CAST( XConnectable * , this ) ) ); 467 } 468 } 469 } 470 Reference < XConnectable > ODataInputStream::getPredecessor() throw (RuntimeException) 471 { 472 return m_pred; 473 } 474 475 // XServiceInfo 476 OUString ODataInputStream::getImplementationName() throw () 477 { 478 return ODataInputStream_getImplementationName(); 479 } 480 481 // XServiceInfo 482 sal_Bool ODataInputStream::supportsService(const OUString& ServiceName) throw () 483 { 484 Sequence< OUString > aSNL = getSupportedServiceNames(); 485 const OUString * pArray = aSNL.getConstArray(); 486 487 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 488 if( pArray[i] == ServiceName ) 489 return sal_True; 490 491 return sal_False; 492 } 493 494 // XServiceInfo 495 Sequence< OUString > ODataInputStream::getSupportedServiceNames(void) throw () 496 { 497 return ODataInputStream_getSupportedServiceNames(); 498 } 499 500 /*** 501 * 502 * registration information 503 * 504 * 505 ****/ 506 507 Reference< XInterface > SAL_CALL ODataInputStream_CreateInstance( const Reference < XComponentContext > & ) throw( Exception) 508 { 509 ODataInputStream *p = new ODataInputStream; 510 return Reference< XInterface > ( (OWeakObject * ) p ); 511 } 512 513 OUString ODataInputStream_getImplementationName() 514 { 515 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.DataInputStream" ) ); 516 } 517 518 Sequence<OUString> ODataInputStream_getSupportedServiceNames(void) 519 { 520 Sequence<OUString> aRet(1); 521 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.DataInputStream" ) ); 522 return aRet; 523 } 524 525 526 527 528 class ODataOutputStream : 529 public WeakImplHelper4 < 530 XDataOutputStream, 531 XActiveDataSource, 532 XConnectable, 533 XServiceInfo > 534 { 535 public: 536 ODataOutputStream() 537 : m_bValidStream( sal_False ) 538 { 539 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 540 } 541 ~ODataOutputStream(); 542 543 public: // XOutputStream 544 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) 545 throw ( NotConnectedException, 546 BufferSizeExceededException, 547 RuntimeException); 548 virtual void SAL_CALL flush(void) 549 throw ( NotConnectedException, 550 BufferSizeExceededException, 551 RuntimeException); 552 virtual void SAL_CALL closeOutput(void) 553 throw ( NotConnectedException, 554 BufferSizeExceededException, 555 RuntimeException); 556 557 public: // XDataOutputStream 558 virtual void SAL_CALL writeBoolean(sal_Bool Value) throw (IOException, RuntimeException); 559 virtual void SAL_CALL writeByte(sal_Int8 Value) throw (IOException, RuntimeException); 560 virtual void SAL_CALL writeChar(sal_Unicode Value) throw (IOException, RuntimeException); 561 virtual void SAL_CALL writeShort(sal_Int16 Value) throw (IOException, RuntimeException); 562 virtual void SAL_CALL writeLong(sal_Int32 Value) throw (IOException, RuntimeException); 563 virtual void SAL_CALL writeHyper(sal_Int64 Value) throw (IOException, RuntimeException); 564 virtual void SAL_CALL writeFloat(float Value) throw (IOException, RuntimeException); 565 virtual void SAL_CALL writeDouble(double Value) throw (IOException, RuntimeException); 566 virtual void SAL_CALL writeUTF(const OUString& Value) throw (IOException, RuntimeException); 567 568 public: // XActiveDataSource 569 virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream) 570 throw (RuntimeException); 571 virtual Reference < XOutputStream > SAL_CALL getOutputStream(void) throw (RuntimeException); 572 573 public: // XConnectable 574 virtual void SAL_CALL setPredecessor(const Reference < XConnectable >& aPredecessor) 575 throw (RuntimeException); 576 virtual Reference < XConnectable > SAL_CALL getPredecessor(void) 577 throw (RuntimeException); 578 virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) 579 throw (RuntimeException); 580 virtual Reference < XConnectable > SAL_CALL getSuccessor(void) 581 throw (RuntimeException); 582 583 public: // XServiceInfo 584 OUString SAL_CALL getImplementationName() throw (); 585 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); 586 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); 587 588 protected: 589 Reference < XConnectable > m_succ; 590 Reference < XConnectable > m_pred; 591 Reference< XOutputStream > m_output; 592 sal_Bool m_bValidStream; 593 }; 594 595 ODataOutputStream::~ODataOutputStream() 596 { 597 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 598 } 599 600 601 // XOutputStream 602 void ODataOutputStream::writeBytes(const Sequence< sal_Int8 >& aData) 603 throw ( NotConnectedException, 604 BufferSizeExceededException, 605 RuntimeException) 606 { 607 if( m_bValidStream ) 608 { 609 m_output->writeBytes( aData ); 610 } 611 else { 612 throw NotConnectedException( ); 613 } 614 } 615 616 void ODataOutputStream::flush(void) 617 throw ( NotConnectedException, 618 BufferSizeExceededException, 619 RuntimeException) 620 { 621 if( m_bValidStream ) 622 { 623 m_output->flush(); 624 } 625 else 626 { 627 throw NotConnectedException(); 628 } 629 630 } 631 632 633 void ODataOutputStream::closeOutput(void) 634 throw ( NotConnectedException, 635 BufferSizeExceededException, 636 RuntimeException) 637 { 638 if( m_bValidStream ) 639 { 640 m_output->closeOutput(); 641 setOutputStream( Reference< XOutputStream > () ); 642 setPredecessor( Reference < XConnectable >() ); 643 setSuccessor( Reference < XConnectable >() ); 644 } 645 else 646 { 647 throw NotConnectedException(); 648 } 649 } 650 651 // XDataOutputStream 652 void ODataOutputStream::writeBoolean(sal_Bool Value) 653 throw ( IOException, 654 RuntimeException) 655 { 656 if( Value ) 657 { 658 writeByte( 1 ); 659 } 660 else 661 { 662 writeByte( 0 ); 663 } 664 } 665 666 667 void ODataOutputStream::writeByte(sal_Int8 Value) 668 throw ( IOException, 669 RuntimeException) 670 { 671 Sequence<sal_Int8> aTmp( 1 ); 672 aTmp.getArray()[0] = Value; 673 writeBytes( aTmp ); 674 } 675 676 void ODataOutputStream::writeChar(sal_Unicode Value) 677 throw ( IOException, 678 RuntimeException) 679 { 680 Sequence<sal_Int8> aTmp( 2 ); 681 sal_Int8 * pBytes = ( sal_Int8 * ) aTmp.getArray(); 682 pBytes[0] = sal_Int8(Value >> 8); 683 pBytes[1] = sal_Int8(Value); 684 writeBytes( aTmp ); 685 } 686 687 688 void ODataOutputStream::writeShort(sal_Int16 Value) 689 throw ( IOException, 690 RuntimeException) 691 { 692 Sequence<sal_Int8> aTmp( 2 ); 693 sal_Int8 * pBytes = aTmp.getArray(); 694 pBytes[0] = sal_Int8(Value >> 8); 695 pBytes[1] = sal_Int8(Value); 696 writeBytes( aTmp ); 697 } 698 699 void ODataOutputStream::writeLong(sal_Int32 Value) 700 throw ( IOException, 701 RuntimeException) 702 { 703 Sequence<sal_Int8> aTmp( 4 ); 704 sal_Int8 * pBytes = aTmp.getArray(); 705 pBytes[0] = sal_Int8(Value >> 24); 706 pBytes[1] = sal_Int8(Value >> 16); 707 pBytes[2] = sal_Int8(Value >> 8); 708 pBytes[3] = sal_Int8(Value); 709 writeBytes( aTmp ); 710 } 711 712 void ODataOutputStream::writeHyper(sal_Int64 Value) 713 throw ( IOException, 714 RuntimeException) 715 { 716 Sequence<sal_Int8> aTmp( 8 ); 717 sal_Int8 * pBytes = aTmp.getArray(); 718 pBytes[0] = sal_Int8(Value >> 56); 719 pBytes[1] = sal_Int8(Value >> 48); 720 pBytes[2] = sal_Int8(Value >> 40); 721 pBytes[3] = sal_Int8(Value >> 32); 722 pBytes[4] = sal_Int8(Value >> 24); 723 pBytes[5] = sal_Int8(Value >> 16); 724 pBytes[6] = sal_Int8(Value >> 8); 725 pBytes[7] = sal_Int8(Value); 726 writeBytes( aTmp ); 727 } 728 729 730 void ODataOutputStream::writeFloat(float Value) 731 throw ( IOException, 732 RuntimeException) 733 { 734 union { float f; sal_uInt32 n; } a; 735 a.f = Value; 736 writeLong( a.n ); 737 } 738 739 void ODataOutputStream::writeDouble(double Value) 740 throw ( IOException, 741 RuntimeException) 742 { 743 sal_uInt32 n = 1; 744 union { double d; struct { sal_uInt32 n1; sal_uInt32 n2; } ad; } a; 745 a.d = Value; 746 if( *(sal_Int8 *)&n == 1 ) 747 { 748 // little endian 749 writeLong( a.ad.n2 ); 750 writeLong( a.ad.n1 ); 751 } 752 else 753 { 754 // big endian 755 writeLong( a.ad.n1 ); 756 writeLong( a.ad.n2 ); 757 } 758 } 759 760 void ODataOutputStream::writeUTF(const OUString& Value) 761 throw ( IOException, 762 RuntimeException) 763 { 764 sal_Int32 nStrLen = Value.getLength(); 765 const sal_Unicode * pStr = Value.getStr(); 766 sal_Int32 nUTFLen = 0; 767 sal_Int32 i; 768 769 for( i = 0 ; i < nStrLen ; i++ ) 770 { 771 sal_uInt16 c = pStr[i]; 772 if( (c >= 0x0001) && (c <= 0x007F) ) 773 { 774 nUTFLen++; 775 } 776 else if( c > 0x07FF ) 777 { 778 nUTFLen += 3; 779 } 780 else 781 { 782 nUTFLen += 2; 783 } 784 } 785 786 787 // compatibility mode for older implementations, where it was not possible 788 // to write blocks bigger than 64 k. Note that there is a tradeoff. Blocks, 789 // that are exactly 64k long can not be read by older routines when written 790 // with these routines and the other way round !!!!! 791 if( nUTFLen >= 0xFFFF ) { 792 writeShort( (sal_Int16)-1 ); 793 writeLong( nUTFLen ); 794 } 795 else { 796 writeShort( ((sal_uInt16)nUTFLen) ); 797 } 798 for( i = 0 ; i < nStrLen ; i++ ) 799 { 800 sal_uInt16 c = pStr[i]; 801 if( (c >= 0x0001) && (c <= 0x007F) ) 802 { 803 writeByte(sal_Int8(c)); 804 } 805 else if( c > 0x07FF ) 806 { 807 writeByte(sal_Int8(0xE0 | ((c >> 12) & 0x0F))); 808 writeByte(sal_Int8(0x80 | ((c >> 6) & 0x3F))); 809 writeByte(sal_Int8(0x80 | ((c >> 0) & 0x3F))); 810 //written += 2; 811 } 812 else 813 { 814 writeByte(sal_Int8(0xC0 | ((c >> 6) & 0x1F))); 815 writeByte(sal_Int8(0x80 | ((c >> 0) & 0x3F))); 816 //written += 1; 817 } 818 } 819 //written += strlen + 2; 820 } 821 822 // XActiveDataSource 823 void ODataOutputStream::setOutputStream(const Reference< XOutputStream > & aStream) 824 throw (RuntimeException) 825 { 826 if( m_output != aStream ) { 827 m_output = aStream; 828 m_bValidStream = m_output.is(); 829 830 Reference < XConnectable > succ( m_output , UNO_QUERY ); 831 setSuccessor( succ ); 832 } 833 } 834 835 Reference< XOutputStream > ODataOutputStream::getOutputStream(void) 836 throw (RuntimeException) 837 { 838 return m_output; 839 } 840 841 842 843 844 // XDataSink 845 void ODataOutputStream::setSuccessor( const Reference < XConnectable > &r ) 846 throw (RuntimeException) 847 { 848 /// if the references match, nothing needs to be done 849 if( m_succ != r ) 850 { 851 /// store the reference for later use 852 m_succ = r; 853 854 if( m_succ.is() ) 855 { 856 /// set this instance as the sink ! 857 m_succ->setPredecessor( Reference < XConnectable > ( 858 SAL_STATIC_CAST( XConnectable * , this ) )); 859 } 860 } 861 } 862 Reference < XConnectable > ODataOutputStream::getSuccessor() throw (RuntimeException) 863 { 864 return m_succ; 865 } 866 867 868 // XDataSource 869 void ODataOutputStream::setPredecessor( const Reference < XConnectable > &r ) throw (RuntimeException) 870 { 871 if( r != m_pred ) { 872 m_pred = r; 873 if( m_pred.is() ) { 874 m_pred->setSuccessor( Reference< XConnectable > ( 875 SAL_STATIC_CAST( XConnectable * , this ) )); 876 } 877 } 878 } 879 Reference < XConnectable > ODataOutputStream::getPredecessor() throw (RuntimeException) 880 { 881 return m_pred; 882 } 883 884 885 886 // XServiceInfo 887 OUString ODataOutputStream::getImplementationName() throw () 888 { 889 return ODataOutputStream_getImplementationName(); 890 } 891 892 // XServiceInfo 893 sal_Bool ODataOutputStream::supportsService(const OUString& ServiceName) throw () 894 { 895 Sequence< OUString > aSNL = getSupportedServiceNames(); 896 const OUString * pArray = aSNL.getConstArray(); 897 898 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 899 if( pArray[i] == ServiceName ) 900 return sal_True; 901 902 return sal_False; 903 } 904 905 // XServiceInfo 906 Sequence< OUString > ODataOutputStream::getSupportedServiceNames(void) throw () 907 { 908 return ODataOutputStream_getSupportedServiceNames(); 909 } 910 911 912 913 914 Reference< XInterface > SAL_CALL ODataOutputStream_CreateInstance( const Reference < XComponentContext > & ) throw(Exception) 915 { 916 ODataOutputStream *p = new ODataOutputStream; 917 Reference< XInterface > xService = *p; 918 return xService; 919 } 920 921 922 OUString ODataOutputStream_getImplementationName() 923 { 924 return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.DataOutputStream" ) ); 925 } 926 927 Sequence<OUString> ODataOutputStream_getSupportedServiceNames(void) 928 { 929 Sequence<OUString> aRet(1); 930 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.DataOutputStream" ) ); 931 return aRet; 932 } 933 934 //-------------------------------------- 935 struct equalObjectContainer_Impl 936 { 937 sal_Int32 operator()(const Reference< XInterface > & s1, 938 const Reference< XInterface > & s2) const 939 { 940 return s1 == s2; 941 } 942 }; 943 944 //----------------------------------------------------------------------------- 945 struct hashObjectContainer_Impl 946 { 947 size_t operator()(const Reference< XInterface > & xRef) const 948 { 949 return (size_t)xRef.get(); 950 } 951 }; 952 953 typedef hash_map 954 < 955 Reference< XInterface >, 956 sal_Int32, 957 hashObjectContainer_Impl, 958 equalObjectContainer_Impl 959 > ObjectContainer_Impl; 960 961 /*--------------------------------------------- 962 * 963 * 964 * 965 * 966 *--------------------------------------------*/ 967 class OObjectOutputStream : 968 public ODataOutputStream, 969 public XObjectOutputStream, 970 public XMarkableStream 971 { 972 public: 973 OObjectOutputStream() 974 : m_nMaxId(0) , 975 m_bValidMarkable(sal_False) 976 { 977 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 978 } 979 980 ~OObjectOutputStream(); 981 982 public: 983 Any SAL_CALL queryInterface( const Type &type ) throw (::com::sun::star::uno::RuntimeException); 984 void SAL_CALL acquire() throw() { ODataOutputStream::acquire(); } 985 void SAL_CALL release() throw() { ODataOutputStream::release(); } 986 987 public: 988 // XOutputStream 989 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) 990 throw ( NotConnectedException, 991 BufferSizeExceededException, 992 RuntimeException) 993 { ODataOutputStream::writeBytes( aData ); } 994 995 virtual void SAL_CALL flush(void) 996 throw ( NotConnectedException, 997 BufferSizeExceededException, 998 RuntimeException) 999 { ODataOutputStream::flush(); } 1000 1001 virtual void SAL_CALL closeOutput(void) 1002 throw ( NotConnectedException, 1003 BufferSizeExceededException, 1004 RuntimeException) 1005 { ODataOutputStream::closeOutput(); } 1006 1007 public: 1008 // XDataOutputStream 1009 virtual void SAL_CALL writeBoolean(sal_Bool Value) throw (IOException, RuntimeException) 1010 { ODataOutputStream::writeBoolean( Value ); } 1011 virtual void SAL_CALL writeByte(sal_Int8 Value) throw (IOException, RuntimeException) 1012 { ODataOutputStream::writeByte( Value ); } 1013 virtual void SAL_CALL writeChar(sal_Unicode Value) throw (IOException, RuntimeException) 1014 { ODataOutputStream::writeChar( Value ); } 1015 virtual void SAL_CALL writeShort(sal_Int16 Value) throw (IOException, RuntimeException) 1016 { ODataOutputStream::writeShort( Value ); } 1017 virtual void SAL_CALL writeLong(sal_Int32 Value) throw (IOException, RuntimeException) 1018 { ODataOutputStream::writeLong( Value ); } 1019 virtual void SAL_CALL writeHyper(sal_Int64 Value) throw (IOException, RuntimeException) 1020 { ODataOutputStream::writeHyper( Value ); } 1021 virtual void SAL_CALL writeFloat(float Value) throw (IOException, RuntimeException) 1022 { ODataOutputStream::writeFloat( Value ); } 1023 virtual void SAL_CALL writeDouble(double Value) throw (IOException, RuntimeException) 1024 { ODataOutputStream::writeDouble( Value ); } 1025 virtual void SAL_CALL writeUTF(const OUString& Value) throw (IOException, RuntimeException) 1026 { ODataOutputStream::writeUTF( Value );} 1027 1028 // XObjectOutputStream 1029 virtual void SAL_CALL writeObject( const Reference< XPersistObject > & r ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); 1030 1031 public: // XMarkableStream 1032 virtual sal_Int32 SAL_CALL createMark(void) throw (IOException, RuntimeException); 1033 virtual void SAL_CALL deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException); 1034 virtual void SAL_CALL jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException); 1035 virtual void SAL_CALL jumpToFurthest(void) throw (IOException, RuntimeException); 1036 virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) 1037 throw (IOException, IllegalArgumentException, RuntimeException); 1038 1039 public: //XTypeProvider 1040 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL 1041 getTypes( ) throw(::com::sun::star::uno::RuntimeException); 1042 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL 1043 getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); 1044 1045 public: // XServiceInfo 1046 OUString SAL_CALL getImplementationName() throw (); 1047 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); 1048 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); 1049 1050 private: 1051 void connectToMarkable(); 1052 private: 1053 ObjectContainer_Impl m_mapObject; 1054 sal_Int32 m_nMaxId; 1055 Reference< XMarkableStream > m_rMarkable; 1056 sal_Bool m_bValidMarkable; 1057 }; 1058 1059 OObjectOutputStream::~OObjectOutputStream() 1060 { 1061 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 1062 } 1063 1064 Any OObjectOutputStream::queryInterface( const Type &aType ) throw (::com::sun::star::uno::RuntimeException) 1065 { 1066 Any a = ::cppu::queryInterface( 1067 aType , 1068 SAL_STATIC_CAST( XMarkableStream * , this ), 1069 SAL_STATIC_CAST( XObjectOutputStream * , this ) ); 1070 if( a.hasValue() ) 1071 { 1072 return a; 1073 } 1074 1075 return ODataOutputStream::queryInterface( aType ); 1076 1077 } 1078 void OObjectOutputStream::writeObject( const Reference< XPersistObject > & xPObj ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 1079 { 1080 1081 connectToMarkable(); 1082 sal_Bool bWriteObj = sal_False; 1083 // create Mark to write length of info 1084 sal_uInt32 nInfoLenMark = m_rMarkable->createMark(); 1085 1086 // length of the info data (is later rewritten) 1087 OObjectOutputStream::writeShort( 0 ); 1088 1089 // write the object identifier 1090 if( xPObj.is() ) 1091 { 1092 Reference< XInterface > rX( xPObj , UNO_QUERY ); 1093 1094 ObjectContainer_Impl::const_iterator aIt 1095 = m_mapObject.find( rX ); 1096 if( aIt == m_mapObject.end() ) 1097 { 1098 // insert new object in hash table 1099 m_mapObject[ rX ] = ++m_nMaxId; 1100 ODataOutputStream::writeLong( m_nMaxId ); 1101 ODataOutputStream::writeUTF( xPObj->getServiceName() ); 1102 bWriteObj = sal_True; 1103 } 1104 else 1105 { 1106 ODataOutputStream::writeLong( (*aIt).second ); 1107 OUString aName; 1108 ODataOutputStream::writeUTF( aName ); 1109 } 1110 } 1111 else 1112 { 1113 ODataOutputStream::writeLong( 0 ); 1114 OUString aName; 1115 ODataOutputStream::writeUTF( aName ); 1116 } 1117 1118 sal_uInt32 nObjLenMark = m_rMarkable->createMark(); 1119 ODataOutputStream::writeLong( 0 ); 1120 1121 sal_Int32 nInfoLen = m_rMarkable->offsetToMark( nInfoLenMark ); 1122 m_rMarkable->jumpToMark( nInfoLenMark ); 1123 // write length of the info data 1124 ODataOutputStream::writeShort( (sal_Int16)nInfoLen ); 1125 // jump to the end of the stream 1126 m_rMarkable->jumpToFurthest(); 1127 1128 if( bWriteObj ) 1129 xPObj->write( Reference< XObjectOutputStream > ( 1130 SAL_STATIC_CAST( XObjectOutputStream * , this ) ) ); 1131 1132 sal_Int32 nObjLen = m_rMarkable->offsetToMark( nObjLenMark ) -4; 1133 m_rMarkable->jumpToMark( nObjLenMark ); 1134 // write length of the info data 1135 ODataOutputStream::writeLong( nObjLen ); 1136 // jump to the end of the stream 1137 m_rMarkable->jumpToFurthest(); 1138 1139 m_rMarkable->deleteMark( nObjLenMark ); 1140 m_rMarkable->deleteMark( nInfoLenMark ); 1141 } 1142 1143 1144 1145 void OObjectOutputStream::connectToMarkable(void) 1146 { 1147 if( ! m_bValidMarkable ) { 1148 if( ! m_bValidStream ) 1149 { 1150 throw NotConnectedException(); 1151 } 1152 1153 // find the markable stream ! 1154 Reference< XInterface > rTry(m_output); 1155 while( sal_True ) { 1156 if( ! rTry.is() ) 1157 { 1158 throw NotConnectedException(); 1159 } 1160 Reference < XMarkableStream > markable( rTry , UNO_QUERY ); 1161 if( markable.is() ) 1162 { 1163 m_rMarkable = markable; 1164 break; 1165 } 1166 Reference < XActiveDataSource > source( rTry , UNO_QUERY ); 1167 rTry = source; 1168 } 1169 m_bValidMarkable = sal_True; 1170 } 1171 } 1172 1173 1174 sal_Int32 OObjectOutputStream::createMark(void) 1175 throw (IOException, RuntimeException) 1176 { 1177 connectToMarkable(); // throws an exception, if a markable is not connected ! 1178 1179 return m_rMarkable->createMark(); 1180 } 1181 1182 void OObjectOutputStream::deleteMark(sal_Int32 Mark) 1183 throw (IOException, IllegalArgumentException, RuntimeException) 1184 { 1185 if( ! m_bValidMarkable ) 1186 { 1187 throw NotConnectedException(); 1188 } 1189 m_rMarkable->deleteMark( Mark ); 1190 } 1191 1192 void OObjectOutputStream::jumpToMark(sal_Int32 nMark) 1193 throw (IOException, IllegalArgumentException, RuntimeException) 1194 { 1195 if( ! m_bValidMarkable ) 1196 { 1197 throw NotConnectedException(); 1198 } 1199 m_rMarkable->jumpToMark( nMark ); 1200 } 1201 1202 1203 void OObjectOutputStream::jumpToFurthest(void) 1204 throw (IOException, RuntimeException) 1205 { 1206 connectToMarkable(); 1207 m_rMarkable->jumpToFurthest(); 1208 } 1209 1210 sal_Int32 OObjectOutputStream::offsetToMark(sal_Int32 nMark) 1211 throw (IOException, IllegalArgumentException, RuntimeException) 1212 { 1213 if( ! m_bValidMarkable ) 1214 { 1215 throw NotConnectedException(); 1216 } 1217 return m_rMarkable->offsetToMark( nMark ); 1218 } 1219 1220 1221 1222 1223 Reference< XInterface > SAL_CALL OObjectOutputStream_CreateInstance( const Reference < XComponentContext > & ) 1224 throw(Exception) 1225 { 1226 OObjectOutputStream *p = new OObjectOutputStream; 1227 return Reference< XInterface > ( SAL_STATIC_CAST( OWeakObject * , p ) ); 1228 } 1229 1230 OUString OObjectOutputStream_getImplementationName() 1231 { 1232 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.ObjectOutputStream" ) ); 1233 } 1234 1235 Sequence<OUString> OObjectOutputStream_getSupportedServiceNames(void) 1236 { 1237 Sequence<OUString> aRet(1); 1238 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.ObjectOutputStream" ) ); 1239 return aRet; 1240 } 1241 1242 Sequence< Type > SAL_CALL OObjectOutputStream::getTypes(void) throw( RuntimeException ) 1243 { 1244 static OTypeCollection *pCollection = 0; 1245 if( ! pCollection ) 1246 { 1247 MutexGuard guard( Mutex::getGlobalMutex() ); 1248 if( ! pCollection ) 1249 { 1250 static OTypeCollection collection( 1251 getCppuType( (Reference< XMarkableStream > * ) 0 ), 1252 getCppuType( (Reference< XObjectOutputStream > * ) 0 ), 1253 ODataOutputStream::getTypes() ); 1254 pCollection = &collection; 1255 } 1256 } 1257 return (*pCollection).getTypes(); 1258 } 1259 1260 Sequence< sal_Int8 > SAL_CALL OObjectOutputStream::getImplementationId( ) throw( RuntimeException) 1261 { 1262 static OImplementationId *pId = 0; 1263 if( ! pId ) 1264 { 1265 MutexGuard guard( Mutex::getGlobalMutex() ); 1266 if( ! pId ) 1267 { 1268 static OImplementationId id( sal_False ); 1269 pId = &id; 1270 } 1271 } 1272 return (*pId).getImplementationId(); 1273 } 1274 1275 1276 // XServiceInfo 1277 OUString OObjectOutputStream::getImplementationName() throw () 1278 { 1279 return ODataInputStream_getImplementationName(); 1280 } 1281 1282 // XServiceInfo 1283 sal_Bool OObjectOutputStream::supportsService(const OUString& ServiceName) throw () 1284 { 1285 Sequence< OUString > aSNL = getSupportedServiceNames(); 1286 const OUString * pArray = aSNL.getConstArray(); 1287 1288 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 1289 if( pArray[i] == ServiceName ) 1290 return sal_True; 1291 1292 return sal_False; 1293 } 1294 1295 // XServiceInfo 1296 Sequence< OUString > OObjectOutputStream::getSupportedServiceNames(void) throw () 1297 { 1298 return OObjectOutputStream_getSupportedServiceNames(); 1299 } 1300 1301 1302 1303 1304 1305 class OObjectInputStream : 1306 public ODataInputStream, 1307 public XObjectInputStream, 1308 public XMarkableStream 1309 { 1310 public: 1311 OObjectInputStream( const Reference < XComponentContext > &r) 1312 : m_rSMgr( r->getServiceManager() ) 1313 , m_rCxt( r ) 1314 , m_bValidMarkable(sal_False) 1315 { 1316 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 1317 } 1318 ~OObjectInputStream(); 1319 1320 public: 1321 Any SAL_CALL queryInterface( const Type &type ) throw(); 1322 void SAL_CALL acquire() throw() { ODataInputStream::acquire(); } 1323 void SAL_CALL release() throw() { ODataInputStream::release(); } 1324 1325 public: // XInputStream 1326 virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) 1327 throw ( NotConnectedException, 1328 BufferSizeExceededException, 1329 RuntimeException) 1330 { return ODataInputStream::readBytes( aData , nBytesToRead ); } 1331 1332 virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) 1333 throw ( NotConnectedException, 1334 BufferSizeExceededException, 1335 RuntimeException) 1336 { return ODataInputStream::readSomeBytes( aData, nMaxBytesToRead ); } 1337 1338 virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) 1339 throw ( NotConnectedException, 1340 BufferSizeExceededException, 1341 RuntimeException) 1342 { ODataInputStream::skipBytes( nBytesToSkip ); } 1343 1344 virtual sal_Int32 SAL_CALL available(void) 1345 throw ( NotConnectedException, 1346 RuntimeException) 1347 { return ODataInputStream::available(); } 1348 1349 virtual void SAL_CALL closeInput(void) 1350 throw ( NotConnectedException, 1351 RuntimeException) 1352 { ODataInputStream::closeInput(); } 1353 1354 public: // XDataInputStream 1355 virtual sal_Int8 SAL_CALL readBoolean(void) throw (IOException, RuntimeException) 1356 { return ODataInputStream::readBoolean(); } 1357 virtual sal_Int8 SAL_CALL readByte(void) throw (IOException, RuntimeException) 1358 { return ODataInputStream::readByte(); } 1359 virtual sal_Unicode SAL_CALL readChar(void) throw (IOException, RuntimeException) 1360 { return ODataInputStream::readChar(); } 1361 virtual sal_Int16 SAL_CALL readShort(void) throw (IOException, RuntimeException) 1362 { return ODataInputStream::readShort(); } 1363 virtual sal_Int32 SAL_CALL readLong(void) throw (IOException, RuntimeException) 1364 { return ODataInputStream::readLong(); } 1365 virtual sal_Int64 SAL_CALL readHyper(void) throw (IOException, RuntimeException) 1366 { return ODataInputStream::readHyper(); } 1367 virtual float SAL_CALL readFloat(void) throw (IOException, RuntimeException) 1368 { return ODataInputStream::readFloat(); } 1369 virtual double SAL_CALL readDouble(void) throw (IOException, RuntimeException) 1370 { return ODataInputStream::readDouble(); } 1371 virtual OUString SAL_CALL readUTF(void) throw (IOException, RuntimeException) 1372 { return ODataInputStream::readUTF(); } 1373 1374 public: // XObjectInputStream 1375 virtual Reference< XPersistObject > SAL_CALL readObject( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); 1376 1377 public: // XMarkableStream 1378 virtual sal_Int32 SAL_CALL createMark(void) 1379 throw (IOException, RuntimeException); 1380 virtual void SAL_CALL deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException); 1381 virtual void SAL_CALL jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException); 1382 virtual void SAL_CALL jumpToFurthest(void) throw (IOException, RuntimeException); 1383 virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) 1384 throw (IOException, IllegalArgumentException, RuntimeException); 1385 1386 public: //XTypeProvider 1387 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL 1388 getTypes( ) throw(::com::sun::star::uno::RuntimeException); 1389 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL 1390 getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); 1391 1392 public: // XServiceInfo 1393 OUString SAL_CALL getImplementationName() throw (); 1394 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); 1395 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); 1396 1397 private: 1398 void connectToMarkable(); 1399 private: 1400 Reference < XMultiComponentFactory > m_rSMgr; 1401 Reference < XComponentContext > m_rCxt; 1402 sal_Bool m_bValidMarkable; 1403 Reference < XMarkableStream > m_rMarkable; 1404 vector < Reference< XPersistObject > > m_aPersistVector; 1405 1406 }; 1407 1408 OObjectInputStream::~OObjectInputStream() 1409 { 1410 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 1411 } 1412 1413 Any OObjectInputStream::queryInterface( const Type &aType ) throw () 1414 { 1415 Any a = ::cppu::queryInterface( 1416 aType , 1417 SAL_STATIC_CAST( XMarkableStream * , this ), 1418 SAL_STATIC_CAST( XObjectInputStream * , this ) ); 1419 if( a.hasValue() ) 1420 { 1421 return a; 1422 } 1423 1424 return ODataInputStream::queryInterface( aType ); 1425 1426 } 1427 1428 Reference< XPersistObject > OObjectInputStream::readObject() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 1429 { 1430 // check if chain contains a XMarkableStream 1431 connectToMarkable(); 1432 1433 Reference< XPersistObject > xLoadedObj; 1434 1435 // create Mark to skip newer versions 1436 sal_uInt32 nMark = m_rMarkable->createMark(); 1437 // length of the data 1438 sal_Int32 nLen = (sal_uInt16) ODataInputStream::readShort(); 1439 if( nLen < 0xc ) 1440 { 1441 throw WrongFormatException(); 1442 } 1443 1444 // read the object identifier 1445 sal_uInt32 nId = readLong(); 1446 1447 // the name of the persist model 1448 // MM ??? 1449 OUString aName = readUTF(); 1450 1451 // Read the length of the object 1452 sal_Int32 nObjLen = readLong(); 1453 if( ( 0 == nId && 0 != nObjLen ) ) 1454 { 1455 throw WrongFormatException(); 1456 } 1457 1458 // skip data of new version 1459 skipBytes( nLen - m_rMarkable->offsetToMark( nMark ) ); 1460 1461 sal_Bool bLoadSuccesfull = sal_True; 1462 if( nId ) 1463 { 1464 if( aName.getLength() ) 1465 { 1466 // load the object 1467 Reference< XInterface > x = m_rSMgr->createInstanceWithContext( aName, m_rCxt ); 1468 xLoadedObj = Reference< XPersistObject >( x, UNO_QUERY ); 1469 if( xLoadedObj.is() ) 1470 { 1471 sal_uInt32 nSize = m_aPersistVector.size(); 1472 if( nSize <= nId ) 1473 { 1474 // grow to the right size 1475 Reference< XPersistObject > xEmpty; 1476 m_aPersistVector.insert( m_aPersistVector.end(), (long)(nId - nSize + 1), xEmpty ); 1477 } 1478 1479 m_aPersistVector[nId] = xLoadedObj; 1480 xLoadedObj->read( Reference< XObjectInputStream >( 1481 SAL_STATIC_CAST( XObjectInputStream *, this ) ) ); 1482 } 1483 else 1484 { 1485 // no service with this name could be instantiated 1486 bLoadSuccesfull = sal_False; 1487 } 1488 } 1489 else { 1490 if( m_aPersistVector.size() < nId ) 1491 { 1492 // id unknown, load failure ! 1493 bLoadSuccesfull = sal_False; 1494 } 1495 else 1496 { 1497 // Object has alread been read, 1498 xLoadedObj = m_aPersistVector[nId]; 1499 } 1500 } 1501 } 1502 1503 // skip to the position behind the object 1504 skipBytes( nObjLen + nLen - m_rMarkable->offsetToMark( nMark ) ); 1505 m_rMarkable->deleteMark( nMark ); 1506 1507 if( ! bLoadSuccesfull ) 1508 { 1509 throw WrongFormatException(); 1510 } 1511 return xLoadedObj; 1512 } 1513 1514 1515 void OObjectInputStream::connectToMarkable() 1516 { 1517 if( ! m_bValidMarkable ) { 1518 if( ! m_bValidStream ) 1519 { 1520 throw NotConnectedException( ); 1521 } 1522 1523 // find the markable stream ! 1524 Reference< XInterface > rTry(m_input); 1525 while( sal_True ) { 1526 if( ! rTry.is() ) 1527 { 1528 throw NotConnectedException( ); 1529 } 1530 Reference< XMarkableStream > markable( rTry , UNO_QUERY ); 1531 if( markable.is() ) 1532 { 1533 m_rMarkable = markable; 1534 break; 1535 } 1536 Reference < XActiveDataSink > sink( rTry , UNO_QUERY ); 1537 rTry = sink; 1538 } 1539 m_bValidMarkable = sal_True; 1540 } 1541 } 1542 1543 sal_Int32 OObjectInputStream::createMark(void) throw (IOException, RuntimeException) 1544 { 1545 connectToMarkable(); // throws an exception, if a markable is not connected ! 1546 1547 return m_rMarkable->createMark(); 1548 } 1549 1550 void OObjectInputStream::deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException) 1551 { 1552 if( ! m_bValidMarkable ) 1553 { 1554 throw NotConnectedException(); 1555 } 1556 m_rMarkable->deleteMark( Mark ); 1557 } 1558 1559 void OObjectInputStream::jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException) 1560 { 1561 if( ! m_bValidMarkable ) 1562 { 1563 throw NotConnectedException(); 1564 } 1565 m_rMarkable->jumpToMark( nMark ); 1566 } 1567 void OObjectInputStream::jumpToFurthest(void) throw (IOException, RuntimeException) 1568 { 1569 connectToMarkable(); 1570 m_rMarkable->jumpToFurthest(); 1571 } 1572 1573 sal_Int32 OObjectInputStream::offsetToMark(sal_Int32 nMark) 1574 throw (IOException, IllegalArgumentException, RuntimeException) 1575 { 1576 if( ! m_bValidMarkable ) 1577 { 1578 throw NotConnectedException(); 1579 } 1580 return m_rMarkable->offsetToMark( nMark ); 1581 } 1582 1583 1584 Sequence< Type > SAL_CALL OObjectInputStream::getTypes(void) throw( RuntimeException ) 1585 { 1586 static OTypeCollection *pCollection = 0; 1587 if( ! pCollection ) 1588 { 1589 MutexGuard guard( Mutex::getGlobalMutex() ); 1590 if( ! pCollection ) 1591 { 1592 static OTypeCollection collection( 1593 getCppuType( (Reference< XMarkableStream > * ) 0 ), 1594 getCppuType( (Reference< XObjectInputStream > * ) 0 ), 1595 ODataInputStream::getTypes() ); 1596 pCollection = &collection; 1597 } 1598 } 1599 return (*pCollection).getTypes(); 1600 } 1601 1602 Sequence< sal_Int8 > SAL_CALL OObjectInputStream::getImplementationId( ) throw( RuntimeException) 1603 { 1604 static OImplementationId *pId = 0; 1605 if( ! pId ) 1606 { 1607 MutexGuard guard( Mutex::getGlobalMutex() ); 1608 if( ! pId ) 1609 { 1610 static OImplementationId id( sal_False ); 1611 pId = &id; 1612 } 1613 } 1614 return (*pId).getImplementationId(); 1615 } 1616 1617 1618 // XServiceInfo 1619 OUString OObjectInputStream::getImplementationName() throw () 1620 { 1621 return OObjectInputStream_getImplementationName(); 1622 } 1623 1624 // XServiceInfo 1625 sal_Bool OObjectInputStream::supportsService(const OUString& ServiceName) throw () 1626 { 1627 Sequence< OUString > aSNL = getSupportedServiceNames(); 1628 const OUString * pArray = aSNL.getConstArray(); 1629 1630 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 1631 if( pArray[i] == ServiceName ) 1632 return sal_True; 1633 1634 return sal_False; 1635 } 1636 1637 // XServiceInfo 1638 Sequence< OUString > OObjectInputStream::getSupportedServiceNames(void) throw () 1639 { 1640 return OObjectInputStream_getSupportedServiceNames(); 1641 } 1642 1643 1644 1645 1646 Reference< XInterface > SAL_CALL OObjectInputStream_CreateInstance( const Reference < XComponentContext > & rCtx ) throw(Exception) 1647 { 1648 OObjectInputStream *p = new OObjectInputStream( rCtx ); 1649 return Reference< XInterface> ( SAL_STATIC_CAST( OWeakObject *, p ) ); 1650 } 1651 1652 OUString OObjectInputStream_getImplementationName() 1653 { 1654 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.ObjectInputStream" ) ); 1655 } 1656 1657 Sequence<OUString> OObjectInputStream_getSupportedServiceNames(void) 1658 { 1659 Sequence<OUString> aRet(1); 1660 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.ObjectInputStream" ) ); 1661 return aRet; 1662 } 1663 1664 } 1665