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