Update ooo320-m1
[ooovba.git] / io / source / stm / odata.cxx
blobbd141bed2b38fb260104510162b3aec7ac60cd2c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: odata.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_io.hxx"
35 // streams
36 #include <hash_map>
37 #include <vector>
39 #include <com/sun/star/io/XObjectInputStream.hpp>
40 #include <com/sun/star/io/XObjectOutputStream.hpp>
41 #include <com/sun/star/io/XActiveDataSource.hpp>
42 #include <com/sun/star/io/XActiveDataSink.hpp>
43 #include <com/sun/star/io/XMarkableStream.hpp>
44 #include <com/sun/star/io/XConnectable.hpp>
45 #include <com/sun/star/io/UnexpectedEOFException.hpp>
46 #include <com/sun/star/io/WrongFormatException.hpp>
47 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <cppuhelper/weak.hxx> // OWeakObject
50 #include <cppuhelper/factory.hxx>
51 #include <cppuhelper/implbase4.hxx>
52 #include <cppuhelper/typeprovider.hxx>
53 #include <cppuhelper/queryinterface.hxx>
55 #include <osl/mutex.hxx>
57 #include <string.h>
60 using namespace ::cppu;
61 using namespace ::osl;
62 using namespace ::std;
63 using namespace ::rtl;
64 using namespace ::com::sun::star::io;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::lang;
68 #include "factreg.hxx"
70 namespace io_stm {
72 class ODataInputStream :
73 public WeakImplHelper4 <
74 XDataInputStream,
75 XActiveDataSink,
76 XConnectable,
77 XServiceInfo
80 public:
81 ODataInputStream( )
82 : m_bValidStream( sal_False )
84 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
87 ~ODataInputStream();
88 public: // XInputStream
89 virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
90 throw ( NotConnectedException,
91 BufferSizeExceededException,
92 RuntimeException);
93 virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
94 throw ( NotConnectedException,
95 BufferSizeExceededException,
96 RuntimeException);
97 virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw ( NotConnectedException,
98 BufferSizeExceededException,
99 RuntimeException);
100 virtual sal_Int32 SAL_CALL available(void) throw ( NotConnectedException,
101 RuntimeException);
102 virtual void SAL_CALL closeInput(void) throw ( NotConnectedException,
103 RuntimeException);
105 public: // XDataInputStream
106 virtual sal_Int8 SAL_CALL readBoolean(void) throw (IOException, RuntimeException);
107 virtual sal_Int8 SAL_CALL readByte(void) throw (IOException, RuntimeException);
108 virtual sal_Unicode SAL_CALL readChar(void) throw (IOException, RuntimeException);
109 virtual sal_Int16 SAL_CALL readShort(void) throw (IOException, RuntimeException);
110 virtual sal_Int32 SAL_CALL readLong(void) throw (IOException, RuntimeException);
111 virtual sal_Int64 SAL_CALL readHyper(void) throw (IOException, RuntimeException);
112 virtual float SAL_CALL readFloat(void) throw (IOException, RuntimeException);
113 virtual double SAL_CALL readDouble(void) throw (IOException, RuntimeException);
114 virtual OUString SAL_CALL readUTF(void) throw (IOException, RuntimeException);
118 public: // XActiveDataSink
119 virtual void SAL_CALL setInputStream(const Reference< XInputStream > & aStream)
120 throw (RuntimeException);
121 virtual Reference< XInputStream > SAL_CALL getInputStream(void) throw (RuntimeException);
123 public: // XConnectable
124 virtual void SAL_CALL setPredecessor(const Reference < XConnectable >& aPredecessor) throw (RuntimeException);
125 virtual Reference < XConnectable > SAL_CALL getPredecessor(void) throw (RuntimeException);
126 virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) throw (RuntimeException);
127 virtual Reference < XConnectable > SAL_CALL getSuccessor(void) throw (RuntimeException) ;
130 public: // XServiceInfo
131 OUString SAL_CALL getImplementationName() throw ();
132 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw ();
133 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw ();
135 protected:
137 Reference < XConnectable > m_pred;
138 Reference < XConnectable > m_succ;
139 Reference < XInputStream > m_input;
140 sal_Bool m_bValidStream;
143 ODataInputStream::~ODataInputStream()
145 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
148 // XInputStream
149 sal_Int32 ODataInputStream::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
150 throw ( NotConnectedException,
151 BufferSizeExceededException,
152 RuntimeException)
154 sal_Int32 nRead;
156 if( m_bValidStream )
158 nRead = m_input->readBytes( aData , nBytesToRead );
160 else
162 throw NotConnectedException( );
165 return nRead;
168 sal_Int32 ODataInputStream::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
169 throw ( NotConnectedException,
170 BufferSizeExceededException,
171 RuntimeException)
173 sal_Int32 nRead;
174 if( m_bValidStream ) {
175 nRead = m_input->readSomeBytes( aData , nMaxBytesToRead );
177 else {
178 throw NotConnectedException( );
181 return nRead;
183 void ODataInputStream::skipBytes(sal_Int32 nBytesToSkip)
184 throw ( NotConnectedException,
185 BufferSizeExceededException,
186 RuntimeException)
188 if( m_bValidStream ) {
189 m_input->skipBytes( nBytesToSkip );
191 else
193 throw NotConnectedException( );
198 sal_Int32 ODataInputStream::available(void)
199 throw ( NotConnectedException,
200 RuntimeException)
202 sal_Int32 nAvail;
204 if( m_bValidStream )
206 nAvail = m_input->available( );
208 else
210 throw NotConnectedException( );
212 return nAvail;
215 void ODataInputStream::closeInput(void )
216 throw ( NotConnectedException,
217 RuntimeException)
219 if( m_bValidStream ) {
220 m_input->closeInput( );
221 setInputStream( Reference< XInputStream > () );
222 setPredecessor( Reference < XConnectable >() );
223 setSuccessor( Reference < XConnectable >() );
224 m_bValidStream = sal_False;
226 else
228 throw NotConnectedException( );
235 //== XDataInputStream ===========================================
237 // XDataInputStream
238 sal_Int8 ODataInputStream::readBoolean(void) throw (IOException, RuntimeException)
240 return readByte();
243 sal_Int8 ODataInputStream::readByte(void) throw (IOException, RuntimeException)
245 Sequence<sal_Int8> aTmp(1);
246 if( 1 != readBytes( aTmp, 1 ) )
248 throw UnexpectedEOFException();
250 return aTmp.getArray()[0];
253 sal_Unicode ODataInputStream::readChar(void) throw (IOException, RuntimeException)
255 Sequence<sal_Int8> aTmp(2);
256 if( 2 != readBytes( aTmp, 2 ) )
258 throw UnexpectedEOFException();
261 const sal_uInt8 * pBytes = ( const sal_uInt8 * )aTmp.getConstArray();
262 return ((sal_Unicode)pBytes[0] << 8) + pBytes[1];
265 sal_Int16 ODataInputStream::readShort(void) throw (IOException, RuntimeException)
267 Sequence<sal_Int8> aTmp(2);
268 if( 2 != readBytes( aTmp, 2 ) )
270 throw UnexpectedEOFException();
273 const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray();
274 return ((sal_Int16)pBytes[0] << 8) + pBytes[1];
278 sal_Int32 ODataInputStream::readLong(void) throw (IOException, RuntimeException)
280 Sequence<sal_Int8> aTmp(4);
281 if( 4 != readBytes( aTmp, 4 ) )
283 throw UnexpectedEOFException( );
286 const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray();
287 return ((sal_Int32)pBytes[0] << 24) + ((sal_Int32)pBytes[1] << 16) + ((sal_Int32)pBytes[2] << 8) + pBytes[3];
291 sal_Int64 ODataInputStream::readHyper(void) throw (IOException, RuntimeException)
293 Sequence<sal_Int8> aTmp(8);
294 if( 8 != readBytes( aTmp, 8 ) )
296 throw UnexpectedEOFException( );
299 const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray();
300 return
301 (((sal_Int64)pBytes[0]) << 56) +
302 (((sal_Int64)pBytes[1]) << 48) +
303 (((sal_Int64)pBytes[2]) << 40) +
304 (((sal_Int64)pBytes[3]) << 32) +
305 (((sal_Int64)pBytes[4]) << 24) +
306 (((sal_Int64)pBytes[5]) << 16) +
307 (((sal_Int64)pBytes[6]) << 8) +
308 pBytes[7];
311 float ODataInputStream::readFloat(void) throw (IOException, RuntimeException)
313 union { float f; sal_uInt32 n; } a;
314 a.n = readLong();
315 return a.f;
318 double ODataInputStream::readDouble(void) throw (IOException, RuntimeException)
320 sal_uInt32 n = 1;
321 union { double d; struct { sal_uInt32 n1; sal_uInt32 n2; } ad; } a;
322 if( *(sal_uInt8 *)&n == 1 )
324 // little endian
325 a.ad.n2 = readLong();
326 a.ad.n1 = readLong();
328 else
330 // big endian
331 a.ad.n1 = readLong();
332 a.ad.n2 = readLong();
334 return a.d;
337 OUString ODataInputStream::readUTF(void) throw (IOException, RuntimeException)
339 sal_uInt16 nShortLen = (sal_uInt16)readShort();
340 sal_Int32 nUTFLen;
342 if( ((sal_uInt16)0xffff) == nShortLen )
344 // is interpreted as a sign, that string is longer than 64k
345 // incompatible to older XDataInputStream-routines, when strings are exactly 64k
346 nUTFLen = readLong();
348 else
350 nUTFLen = ( sal_Int32 ) nShortLen;
353 Sequence<sal_Unicode> aBuffer( nUTFLen );
354 sal_Unicode * pStr = aBuffer.getArray();
356 sal_Int32 nCount = 0;
357 sal_Int32 nStrLen = 0;
358 while( nCount < nUTFLen )
360 sal_uInt8 c = (sal_uInt8)readByte();
361 sal_uInt8 char2, char3;
362 switch( c >> 4 )
364 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
365 // 0xxxxxxx
366 nCount++;
367 pStr[nStrLen++] = c;
368 break;
370 case 12: case 13:
371 // 110x xxxx 10xx xxxx
372 nCount += 2;
373 if( ! ( nCount <= nUTFLen ) )
375 throw WrongFormatException( );
378 char2 = (sal_uInt8)readByte();
379 if( ! ( (char2 & 0xC0) == 0x80 ) )
381 throw WrongFormatException( );
384 pStr[nStrLen++] = (sal_Unicode(c & 0x1F) << 6) | (char2 & 0x3F);
385 break;
387 case 14:
388 // 1110 xxxx 10xx xxxx 10xx xxxx
389 nCount += 3;
390 if( !( nCount <= nUTFLen) )
392 throw WrongFormatException( );
395 char2 = (sal_uInt8)readByte();
396 char3 = (sal_uInt8)readByte();
398 if( (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) ) {
399 throw WrongFormatException( );
401 pStr[nStrLen++] = (sal_Unicode(c & 0x0F) << 12) |
402 (sal_Unicode(char2 & 0x3F) << 6) |
403 (char3 & 0x3F);
404 break;
406 default:
407 // 10xx xxxx, 1111 xxxx
408 throw WrongFormatException();
409 //throw new UTFDataFormatException();
412 return OUString( pStr, nStrLen );
417 // XActiveDataSource
418 void ODataInputStream::setInputStream(const Reference< XInputStream > & aStream)
419 throw (RuntimeException)
422 if( m_input != aStream ) {
423 m_input = aStream;
425 Reference < XConnectable > pred( m_input , UNO_QUERY );
426 setPredecessor( pred );
429 m_bValidStream = m_input.is();
432 Reference< XInputStream > ODataInputStream::getInputStream(void) throw (RuntimeException)
434 return m_input;
439 // XDataSink
440 void ODataInputStream::setSuccessor( const Reference < XConnectable > &r ) throw (RuntimeException)
442 /// if the references match, nothing needs to be done
443 if( m_succ != r ) {
444 /// store the reference for later use
445 m_succ = r;
447 if( m_succ.is() ) {
448 /// set this instance as the sink !
449 m_succ->setPredecessor( Reference< XConnectable > (
450 SAL_STATIC_CAST( XConnectable * , this ) ) );
455 Reference < XConnectable > ODataInputStream::getSuccessor() throw (RuntimeException)
457 return m_succ;
461 // XDataSource
462 void ODataInputStream::setPredecessor( const Reference < XConnectable > &r )
463 throw (RuntimeException)
465 if( r != m_pred ) {
466 m_pred = r;
467 if( m_pred.is() ) {
468 m_pred->setSuccessor( Reference< XConnectable > (
469 SAL_STATIC_CAST( XConnectable * , this ) ) );
473 Reference < XConnectable > ODataInputStream::getPredecessor() throw (RuntimeException)
475 return m_pred;
478 // XServiceInfo
479 OUString ODataInputStream::getImplementationName() throw ()
481 return ODataInputStream_getImplementationName();
484 // XServiceInfo
485 sal_Bool ODataInputStream::supportsService(const OUString& ServiceName) throw ()
487 Sequence< OUString > aSNL = getSupportedServiceNames();
488 const OUString * pArray = aSNL.getConstArray();
490 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
491 if( pArray[i] == ServiceName )
492 return sal_True;
494 return sal_False;
497 // XServiceInfo
498 Sequence< OUString > ODataInputStream::getSupportedServiceNames(void) throw ()
500 return ODataInputStream_getSupportedServiceNames();
503 /***
505 * registration information
508 ****/
510 Reference< XInterface > SAL_CALL ODataInputStream_CreateInstance( const Reference < XComponentContext > & ) throw( Exception)
512 ODataInputStream *p = new ODataInputStream;
513 return Reference< XInterface > ( (OWeakObject * ) p );
516 OUString ODataInputStream_getImplementationName()
518 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.DataInputStream" ) );
521 Sequence<OUString> ODataInputStream_getSupportedServiceNames(void)
523 Sequence<OUString> aRet(1);
524 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.DataInputStream" ) );
525 return aRet;
531 class ODataOutputStream :
532 public WeakImplHelper4 <
533 XDataOutputStream,
534 XActiveDataSource,
535 XConnectable,
536 XServiceInfo >
538 public:
539 ODataOutputStream()
540 : m_bValidStream( sal_False )
542 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
544 ~ODataOutputStream();
546 public: // XOutputStream
547 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
548 throw ( NotConnectedException,
549 BufferSizeExceededException,
550 RuntimeException);
551 virtual void SAL_CALL flush(void)
552 throw ( NotConnectedException,
553 BufferSizeExceededException,
554 RuntimeException);
555 virtual void SAL_CALL closeOutput(void)
556 throw ( NotConnectedException,
557 BufferSizeExceededException,
558 RuntimeException);
560 public: // XDataOutputStream
561 virtual void SAL_CALL writeBoolean(sal_Bool Value) throw (IOException, RuntimeException);
562 virtual void SAL_CALL writeByte(sal_Int8 Value) throw (IOException, RuntimeException);
563 virtual void SAL_CALL writeChar(sal_Unicode Value) throw (IOException, RuntimeException);
564 virtual void SAL_CALL writeShort(sal_Int16 Value) throw (IOException, RuntimeException);
565 virtual void SAL_CALL writeLong(sal_Int32 Value) throw (IOException, RuntimeException);
566 virtual void SAL_CALL writeHyper(sal_Int64 Value) throw (IOException, RuntimeException);
567 virtual void SAL_CALL writeFloat(float Value) throw (IOException, RuntimeException);
568 virtual void SAL_CALL writeDouble(double Value) throw (IOException, RuntimeException);
569 virtual void SAL_CALL writeUTF(const OUString& Value) throw (IOException, RuntimeException);
571 public: // XActiveDataSource
572 virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream)
573 throw (RuntimeException);
574 virtual Reference < XOutputStream > SAL_CALL getOutputStream(void) throw (RuntimeException);
576 public: // XConnectable
577 virtual void SAL_CALL setPredecessor(const Reference < XConnectable >& aPredecessor)
578 throw (RuntimeException);
579 virtual Reference < XConnectable > SAL_CALL getPredecessor(void)
580 throw (RuntimeException);
581 virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor)
582 throw (RuntimeException);
583 virtual Reference < XConnectable > SAL_CALL getSuccessor(void)
584 throw (RuntimeException);
586 public: // XServiceInfo
587 OUString SAL_CALL getImplementationName() throw ();
588 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw ();
589 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw ();
591 protected:
592 Reference < XConnectable > m_succ;
593 Reference < XConnectable > m_pred;
594 Reference< XOutputStream > m_output;
595 sal_Bool m_bValidStream;
598 ODataOutputStream::~ODataOutputStream()
600 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
604 // XOutputStream
605 void ODataOutputStream::writeBytes(const Sequence< sal_Int8 >& aData)
606 throw ( NotConnectedException,
607 BufferSizeExceededException,
608 RuntimeException)
610 if( m_bValidStream )
612 m_output->writeBytes( aData );
614 else {
615 throw NotConnectedException( );
619 void ODataOutputStream::flush(void)
620 throw ( NotConnectedException,
621 BufferSizeExceededException,
622 RuntimeException)
624 if( m_bValidStream )
626 m_output->flush();
628 else
630 throw NotConnectedException();
636 void ODataOutputStream::closeOutput(void)
637 throw ( NotConnectedException,
638 BufferSizeExceededException,
639 RuntimeException)
641 if( m_bValidStream )
643 m_output->closeOutput();
644 setOutputStream( Reference< XOutputStream > () );
645 setPredecessor( Reference < XConnectable >() );
646 setSuccessor( Reference < XConnectable >() );
648 else
650 throw NotConnectedException();
654 // XDataOutputStream
655 void ODataOutputStream::writeBoolean(sal_Bool Value)
656 throw ( IOException,
657 RuntimeException)
659 if( Value )
661 writeByte( 1 );
663 else
665 writeByte( 0 );
670 void ODataOutputStream::writeByte(sal_Int8 Value)
671 throw ( IOException,
672 RuntimeException)
674 Sequence<sal_Int8> aTmp( 1 );
675 aTmp.getArray()[0] = Value;
676 writeBytes( aTmp );
679 void ODataOutputStream::writeChar(sal_Unicode Value)
680 throw ( IOException,
681 RuntimeException)
683 Sequence<sal_Int8> aTmp( 2 );
684 sal_Int8 * pBytes = ( sal_Int8 * ) aTmp.getArray();
685 pBytes[0] = sal_Int8(Value >> 8);
686 pBytes[1] = sal_Int8(Value);
687 writeBytes( aTmp );
691 void ODataOutputStream::writeShort(sal_Int16 Value)
692 throw ( IOException,
693 RuntimeException)
695 Sequence<sal_Int8> aTmp( 2 );
696 sal_Int8 * pBytes = aTmp.getArray();
697 pBytes[0] = sal_Int8(Value >> 8);
698 pBytes[1] = sal_Int8(Value);
699 writeBytes( aTmp );
702 void ODataOutputStream::writeLong(sal_Int32 Value)
703 throw ( IOException,
704 RuntimeException)
706 Sequence<sal_Int8> aTmp( 4 );
707 sal_Int8 * pBytes = aTmp.getArray();
708 pBytes[0] = sal_Int8(Value >> 24);
709 pBytes[1] = sal_Int8(Value >> 16);
710 pBytes[2] = sal_Int8(Value >> 8);
711 pBytes[3] = sal_Int8(Value);
712 writeBytes( aTmp );
715 void ODataOutputStream::writeHyper(sal_Int64 Value)
716 throw ( IOException,
717 RuntimeException)
719 Sequence<sal_Int8> aTmp( 8 );
720 sal_Int8 * pBytes = aTmp.getArray();
721 pBytes[0] = sal_Int8(Value >> 56);
722 pBytes[1] = sal_Int8(Value >> 48);
723 pBytes[2] = sal_Int8(Value >> 40);
724 pBytes[3] = sal_Int8(Value >> 32);
725 pBytes[4] = sal_Int8(Value >> 24);
726 pBytes[5] = sal_Int8(Value >> 16);
727 pBytes[6] = sal_Int8(Value >> 8);
728 pBytes[7] = sal_Int8(Value);
729 writeBytes( aTmp );
733 void ODataOutputStream::writeFloat(float Value)
734 throw ( IOException,
735 RuntimeException)
737 union { float f; sal_uInt32 n; } a;
738 a.f = Value;
739 writeLong( a.n );
742 void ODataOutputStream::writeDouble(double Value)
743 throw ( IOException,
744 RuntimeException)
746 sal_uInt32 n = 1;
747 union { double d; struct { sal_uInt32 n1; sal_uInt32 n2; } ad; } a;
748 a.d = Value;
749 if( *(sal_Int8 *)&n == 1 )
751 // little endian
752 writeLong( a.ad.n2 );
753 writeLong( a.ad.n1 );
755 else
757 // big endian
758 writeLong( a.ad.n1 );
759 writeLong( a.ad.n2 );
763 void ODataOutputStream::writeUTF(const OUString& Value)
764 throw ( IOException,
765 RuntimeException)
767 sal_Int32 nStrLen = Value.getLength();
768 const sal_Unicode * pStr = Value.getStr();
769 sal_Int32 nUTFLen = 0;
770 sal_Int32 i;
772 for( i = 0 ; i < nStrLen ; i++ )
774 sal_uInt16 c = pStr[i];
775 if( (c >= 0x0001) && (c <= 0x007F) )
777 nUTFLen++;
779 else if( c > 0x07FF )
781 nUTFLen += 3;
783 else
785 nUTFLen += 2;
790 // compatibility mode for older implementations, where it was not possible
791 // to write blocks bigger than 64 k. Note that there is a tradeoff. Blocks,
792 // that are exactly 64k long can not be read by older routines when written
793 // with these routines and the other way round !!!!!
794 if( nUTFLen >= 0xFFFF ) {
795 writeShort( (sal_Int16)-1 );
796 writeLong( nUTFLen );
798 else {
799 writeShort( ((sal_uInt16)nUTFLen) );
801 for( i = 0 ; i < nStrLen ; i++ )
803 sal_uInt16 c = pStr[i];
804 if( (c >= 0x0001) && (c <= 0x007F) )
806 writeByte(sal_Int8(c));
808 else if( c > 0x07FF )
810 writeByte(sal_Int8(0xE0 | ((c >> 12) & 0x0F)));
811 writeByte(sal_Int8(0x80 | ((c >> 6) & 0x3F)));
812 writeByte(sal_Int8(0x80 | ((c >> 0) & 0x3F)));
813 //written += 2;
815 else
817 writeByte(sal_Int8(0xC0 | ((c >> 6) & 0x1F)));
818 writeByte(sal_Int8(0x80 | ((c >> 0) & 0x3F)));
819 //written += 1;
822 //written += strlen + 2;
825 // XActiveDataSource
826 void ODataOutputStream::setOutputStream(const Reference< XOutputStream > & aStream)
827 throw (RuntimeException)
829 if( m_output != aStream ) {
830 m_output = aStream;
831 m_bValidStream = m_output.is();
833 Reference < XConnectable > succ( m_output , UNO_QUERY );
834 setSuccessor( succ );
838 Reference< XOutputStream > ODataOutputStream::getOutputStream(void)
839 throw (RuntimeException)
841 return m_output;
847 // XDataSink
848 void ODataOutputStream::setSuccessor( const Reference < XConnectable > &r )
849 throw (RuntimeException)
851 /// if the references match, nothing needs to be done
852 if( m_succ != r )
854 /// store the reference for later use
855 m_succ = r;
857 if( m_succ.is() )
859 /// set this instance as the sink !
860 m_succ->setPredecessor( Reference < XConnectable > (
861 SAL_STATIC_CAST( XConnectable * , this ) ));
865 Reference < XConnectable > ODataOutputStream::getSuccessor() throw (RuntimeException)
867 return m_succ;
871 // XDataSource
872 void ODataOutputStream::setPredecessor( const Reference < XConnectable > &r ) throw (RuntimeException)
874 if( r != m_pred ) {
875 m_pred = r;
876 if( m_pred.is() ) {
877 m_pred->setSuccessor( Reference< XConnectable > (
878 SAL_STATIC_CAST( XConnectable * , this ) ));
882 Reference < XConnectable > ODataOutputStream::getPredecessor() throw (RuntimeException)
884 return m_pred;
889 // XServiceInfo
890 OUString ODataOutputStream::getImplementationName() throw ()
892 return ODataOutputStream_getImplementationName();
895 // XServiceInfo
896 sal_Bool ODataOutputStream::supportsService(const OUString& ServiceName) throw ()
898 Sequence< OUString > aSNL = getSupportedServiceNames();
899 const OUString * pArray = aSNL.getConstArray();
901 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
902 if( pArray[i] == ServiceName )
903 return sal_True;
905 return sal_False;
908 // XServiceInfo
909 Sequence< OUString > ODataOutputStream::getSupportedServiceNames(void) throw ()
911 return ODataOutputStream_getSupportedServiceNames();
917 Reference< XInterface > SAL_CALL ODataOutputStream_CreateInstance( const Reference < XComponentContext > & ) throw(Exception)
919 ODataOutputStream *p = new ODataOutputStream;
920 Reference< XInterface > xService = *p;
921 return xService;
925 OUString ODataOutputStream_getImplementationName()
927 return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.DataOutputStream" ) );
930 Sequence<OUString> ODataOutputStream_getSupportedServiceNames(void)
932 Sequence<OUString> aRet(1);
933 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.DataOutputStream" ) );
934 return aRet;
937 //--------------------------------------
938 struct equalObjectContainer_Impl
940 sal_Int32 operator()(const Reference< XInterface > & s1,
941 const Reference< XInterface > & s2) const
943 return s1 == s2;
947 //-----------------------------------------------------------------------------
948 struct hashObjectContainer_Impl
950 size_t operator()(const Reference< XInterface > & xRef) const
952 return (size_t)xRef.get();
956 typedef hash_map
958 Reference< XInterface >,
959 sal_Int32,
960 hashObjectContainer_Impl,
961 equalObjectContainer_Impl
962 > ObjectContainer_Impl;
964 /*---------------------------------------------
969 *--------------------------------------------*/
970 class OObjectOutputStream :
971 public ODataOutputStream,
972 public XObjectOutputStream,
973 public XMarkableStream
975 public:
976 OObjectOutputStream()
977 : m_nMaxId(0) ,
978 m_bValidMarkable(sal_False)
980 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
983 ~OObjectOutputStream();
985 public:
986 Any SAL_CALL queryInterface( const Type &type ) throw (::com::sun::star::uno::RuntimeException);
987 void SAL_CALL acquire() throw() { ODataOutputStream::acquire(); }
988 void SAL_CALL release() throw() { ODataOutputStream::release(); }
990 public:
991 // XOutputStream
992 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
993 throw ( NotConnectedException,
994 BufferSizeExceededException,
995 RuntimeException)
996 { ODataOutputStream::writeBytes( aData ); }
998 virtual void SAL_CALL flush(void)
999 throw ( NotConnectedException,
1000 BufferSizeExceededException,
1001 RuntimeException)
1002 { ODataOutputStream::flush(); }
1004 virtual void SAL_CALL closeOutput(void)
1005 throw ( NotConnectedException,
1006 BufferSizeExceededException,
1007 RuntimeException)
1008 { ODataOutputStream::closeOutput(); }
1010 public:
1011 // XDataOutputStream
1012 virtual void SAL_CALL writeBoolean(sal_Bool Value) throw (IOException, RuntimeException)
1013 { ODataOutputStream::writeBoolean( Value ); }
1014 virtual void SAL_CALL writeByte(sal_Int8 Value) throw (IOException, RuntimeException)
1015 { ODataOutputStream::writeByte( Value ); }
1016 virtual void SAL_CALL writeChar(sal_Unicode Value) throw (IOException, RuntimeException)
1017 { ODataOutputStream::writeChar( Value ); }
1018 virtual void SAL_CALL writeShort(sal_Int16 Value) throw (IOException, RuntimeException)
1019 { ODataOutputStream::writeShort( Value ); }
1020 virtual void SAL_CALL writeLong(sal_Int32 Value) throw (IOException, RuntimeException)
1021 { ODataOutputStream::writeLong( Value ); }
1022 virtual void SAL_CALL writeHyper(sal_Int64 Value) throw (IOException, RuntimeException)
1023 { ODataOutputStream::writeHyper( Value ); }
1024 virtual void SAL_CALL writeFloat(float Value) throw (IOException, RuntimeException)
1025 { ODataOutputStream::writeFloat( Value ); }
1026 virtual void SAL_CALL writeDouble(double Value) throw (IOException, RuntimeException)
1027 { ODataOutputStream::writeDouble( Value ); }
1028 virtual void SAL_CALL writeUTF(const OUString& Value) throw (IOException, RuntimeException)
1029 { ODataOutputStream::writeUTF( Value );}
1031 // XObjectOutputStream
1032 virtual void SAL_CALL writeObject( const Reference< XPersistObject > & r ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
1034 public: // XMarkableStream
1035 virtual sal_Int32 SAL_CALL createMark(void) throw (IOException, RuntimeException);
1036 virtual void SAL_CALL deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException);
1037 virtual void SAL_CALL jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException);
1038 virtual void SAL_CALL jumpToFurthest(void) throw (IOException, RuntimeException);
1039 virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark)
1040 throw (IOException, IllegalArgumentException, RuntimeException);
1042 public: //XTypeProvider
1043 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
1044 getTypes( ) throw(::com::sun::star::uno::RuntimeException);
1045 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
1046 getImplementationId( ) throw(::com::sun::star::uno::RuntimeException);
1048 public: // XServiceInfo
1049 OUString SAL_CALL getImplementationName() throw ();
1050 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw ();
1051 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw ();
1053 private:
1054 void connectToMarkable();
1055 private:
1056 ObjectContainer_Impl m_mapObject;
1057 sal_Int32 m_nMaxId;
1058 Reference< XMarkableStream > m_rMarkable;
1059 sal_Bool m_bValidMarkable;
1062 OObjectOutputStream::~OObjectOutputStream()
1064 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1067 Any OObjectOutputStream::queryInterface( const Type &aType ) throw (::com::sun::star::uno::RuntimeException)
1069 Any a = ::cppu::queryInterface(
1070 aType ,
1071 SAL_STATIC_CAST( XMarkableStream * , this ),
1072 SAL_STATIC_CAST( XObjectOutputStream * , this ) );
1073 if( a.hasValue() )
1075 return a;
1078 return ODataOutputStream::queryInterface( aType );
1081 void OObjectOutputStream::writeObject( const Reference< XPersistObject > & xPObj ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
1084 connectToMarkable();
1085 sal_Bool bWriteObj = sal_False;
1086 // create Mark to write length of info
1087 sal_uInt32 nInfoLenMark = m_rMarkable->createMark();
1089 // length of the info data (is later rewritten)
1090 OObjectOutputStream::writeShort( 0 );
1092 // write the object identifier
1093 if( xPObj.is() )
1095 Reference< XInterface > rX( xPObj , UNO_QUERY );
1097 ObjectContainer_Impl::const_iterator aIt
1098 = m_mapObject.find( rX );
1099 if( aIt == m_mapObject.end() )
1101 // insert new object in hash table
1102 m_mapObject[ rX ] = ++m_nMaxId;
1103 ODataOutputStream::writeLong( m_nMaxId );
1104 ODataOutputStream::writeUTF( xPObj->getServiceName() );
1105 bWriteObj = sal_True;
1107 else
1109 ODataOutputStream::writeLong( (*aIt).second );
1110 OUString aName;
1111 ODataOutputStream::writeUTF( aName );
1114 else
1116 ODataOutputStream::writeLong( 0 );
1117 OUString aName;
1118 ODataOutputStream::writeUTF( aName );
1121 sal_uInt32 nObjLenMark = m_rMarkable->createMark();
1122 ODataOutputStream::writeLong( 0 );
1124 sal_Int32 nInfoLen = m_rMarkable->offsetToMark( nInfoLenMark );
1125 m_rMarkable->jumpToMark( nInfoLenMark );
1126 // write length of the info data
1127 ODataOutputStream::writeShort( (sal_Int16)nInfoLen );
1128 // jump to the end of the stream
1129 m_rMarkable->jumpToFurthest();
1131 if( bWriteObj )
1132 xPObj->write( Reference< XObjectOutputStream > (
1133 SAL_STATIC_CAST( XObjectOutputStream * , this ) ) );
1135 sal_Int32 nObjLen = m_rMarkable->offsetToMark( nObjLenMark ) -4;
1136 m_rMarkable->jumpToMark( nObjLenMark );
1137 // write length of the info data
1138 ODataOutputStream::writeLong( nObjLen );
1139 // jump to the end of the stream
1140 m_rMarkable->jumpToFurthest();
1142 m_rMarkable->deleteMark( nObjLenMark );
1143 m_rMarkable->deleteMark( nInfoLenMark );
1148 void OObjectOutputStream::connectToMarkable(void)
1150 if( ! m_bValidMarkable ) {
1151 if( ! m_bValidStream )
1153 throw NotConnectedException();
1156 // find the markable stream !
1157 Reference< XInterface > rTry(m_output);
1158 while( sal_True ) {
1159 if( ! rTry.is() )
1161 throw NotConnectedException();
1163 Reference < XMarkableStream > markable( rTry , UNO_QUERY );
1164 if( markable.is() )
1166 m_rMarkable = markable;
1167 break;
1169 Reference < XActiveDataSource > source( rTry , UNO_QUERY );
1170 rTry = source;
1172 m_bValidMarkable = sal_True;
1177 sal_Int32 OObjectOutputStream::createMark(void)
1178 throw (IOException, RuntimeException)
1180 connectToMarkable(); // throws an exception, if a markable is not connected !
1182 return m_rMarkable->createMark();
1185 void OObjectOutputStream::deleteMark(sal_Int32 Mark)
1186 throw (IOException, IllegalArgumentException, RuntimeException)
1188 if( ! m_bValidMarkable )
1190 throw NotConnectedException();
1192 m_rMarkable->deleteMark( Mark );
1195 void OObjectOutputStream::jumpToMark(sal_Int32 nMark)
1196 throw (IOException, IllegalArgumentException, RuntimeException)
1198 if( ! m_bValidMarkable )
1200 throw NotConnectedException();
1202 m_rMarkable->jumpToMark( nMark );
1206 void OObjectOutputStream::jumpToFurthest(void)
1207 throw (IOException, RuntimeException)
1209 connectToMarkable();
1210 m_rMarkable->jumpToFurthest();
1213 sal_Int32 OObjectOutputStream::offsetToMark(sal_Int32 nMark)
1214 throw (IOException, IllegalArgumentException, RuntimeException)
1216 if( ! m_bValidMarkable )
1218 throw NotConnectedException();
1220 return m_rMarkable->offsetToMark( nMark );
1226 Reference< XInterface > SAL_CALL OObjectOutputStream_CreateInstance( const Reference < XComponentContext > & )
1227 throw(Exception)
1229 OObjectOutputStream *p = new OObjectOutputStream;
1230 return Reference< XInterface > ( SAL_STATIC_CAST( OWeakObject * , p ) );
1233 OUString OObjectOutputStream_getImplementationName()
1235 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.ObjectOutputStream" ) );
1238 Sequence<OUString> OObjectOutputStream_getSupportedServiceNames(void)
1240 Sequence<OUString> aRet(1);
1241 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.ObjectOutputStream" ) );
1242 return aRet;
1245 Sequence< Type > SAL_CALL OObjectOutputStream::getTypes(void) throw( RuntimeException )
1247 static OTypeCollection *pCollection = 0;
1248 if( ! pCollection )
1250 MutexGuard guard( Mutex::getGlobalMutex() );
1251 if( ! pCollection )
1253 static OTypeCollection collection(
1254 getCppuType( (Reference< XMarkableStream > * ) 0 ),
1255 getCppuType( (Reference< XObjectOutputStream > * ) 0 ),
1256 ODataOutputStream::getTypes() );
1257 pCollection = &collection;
1260 return (*pCollection).getTypes();
1263 Sequence< sal_Int8 > SAL_CALL OObjectOutputStream::getImplementationId( ) throw( RuntimeException)
1265 static OImplementationId *pId = 0;
1266 if( ! pId )
1268 MutexGuard guard( Mutex::getGlobalMutex() );
1269 if( ! pId )
1271 static OImplementationId id( sal_False );
1272 pId = &id;
1275 return (*pId).getImplementationId();
1279 // XServiceInfo
1280 OUString OObjectOutputStream::getImplementationName() throw ()
1282 return ODataInputStream_getImplementationName();
1285 // XServiceInfo
1286 sal_Bool OObjectOutputStream::supportsService(const OUString& ServiceName) throw ()
1288 Sequence< OUString > aSNL = getSupportedServiceNames();
1289 const OUString * pArray = aSNL.getConstArray();
1291 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1292 if( pArray[i] == ServiceName )
1293 return sal_True;
1295 return sal_False;
1298 // XServiceInfo
1299 Sequence< OUString > OObjectOutputStream::getSupportedServiceNames(void) throw ()
1301 return OObjectOutputStream_getSupportedServiceNames();
1308 class OObjectInputStream :
1309 public ODataInputStream,
1310 public XObjectInputStream,
1311 public XMarkableStream
1313 public:
1314 OObjectInputStream( const Reference < XComponentContext > &r)
1315 : m_rSMgr( r->getServiceManager() )
1316 , m_rCxt( r )
1317 , m_bValidMarkable(sal_False)
1319 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
1321 ~OObjectInputStream();
1323 public:
1324 Any SAL_CALL queryInterface( const Type &type ) throw();
1325 void SAL_CALL acquire() throw() { ODataInputStream::acquire(); }
1326 void SAL_CALL release() throw() { ODataInputStream::release(); }
1328 public: // XInputStream
1329 virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
1330 throw ( NotConnectedException,
1331 BufferSizeExceededException,
1332 RuntimeException)
1333 { return ODataInputStream::readBytes( aData , nBytesToRead ); }
1335 virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
1336 throw ( NotConnectedException,
1337 BufferSizeExceededException,
1338 RuntimeException)
1339 { return ODataInputStream::readSomeBytes( aData, nMaxBytesToRead ); }
1341 virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip)
1342 throw ( NotConnectedException,
1343 BufferSizeExceededException,
1344 RuntimeException)
1345 { ODataInputStream::skipBytes( nBytesToSkip ); }
1347 virtual sal_Int32 SAL_CALL available(void)
1348 throw ( NotConnectedException,
1349 RuntimeException)
1350 { return ODataInputStream::available(); }
1352 virtual void SAL_CALL closeInput(void)
1353 throw ( NotConnectedException,
1354 RuntimeException)
1355 { ODataInputStream::closeInput(); }
1357 public: // XDataInputStream
1358 virtual sal_Int8 SAL_CALL readBoolean(void) throw (IOException, RuntimeException)
1359 { return ODataInputStream::readBoolean(); }
1360 virtual sal_Int8 SAL_CALL readByte(void) throw (IOException, RuntimeException)
1361 { return ODataInputStream::readByte(); }
1362 virtual sal_Unicode SAL_CALL readChar(void) throw (IOException, RuntimeException)
1363 { return ODataInputStream::readChar(); }
1364 virtual sal_Int16 SAL_CALL readShort(void) throw (IOException, RuntimeException)
1365 { return ODataInputStream::readShort(); }
1366 virtual sal_Int32 SAL_CALL readLong(void) throw (IOException, RuntimeException)
1367 { return ODataInputStream::readLong(); }
1368 virtual sal_Int64 SAL_CALL readHyper(void) throw (IOException, RuntimeException)
1369 { return ODataInputStream::readHyper(); }
1370 virtual float SAL_CALL readFloat(void) throw (IOException, RuntimeException)
1371 { return ODataInputStream::readFloat(); }
1372 virtual double SAL_CALL readDouble(void) throw (IOException, RuntimeException)
1373 { return ODataInputStream::readDouble(); }
1374 virtual OUString SAL_CALL readUTF(void) throw (IOException, RuntimeException)
1375 { return ODataInputStream::readUTF(); }
1377 public: // XObjectInputStream
1378 virtual Reference< XPersistObject > SAL_CALL readObject( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
1380 public: // XMarkableStream
1381 virtual sal_Int32 SAL_CALL createMark(void)
1382 throw (IOException, RuntimeException);
1383 virtual void SAL_CALL deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException);
1384 virtual void SAL_CALL jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException);
1385 virtual void SAL_CALL jumpToFurthest(void) throw (IOException, RuntimeException);
1386 virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark)
1387 throw (IOException, IllegalArgumentException, RuntimeException);
1389 public: //XTypeProvider
1390 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
1391 getTypes( ) throw(::com::sun::star::uno::RuntimeException);
1392 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
1393 getImplementationId( ) throw(::com::sun::star::uno::RuntimeException);
1395 public: // XServiceInfo
1396 OUString SAL_CALL getImplementationName() throw ();
1397 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw ();
1398 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw ();
1400 private:
1401 void connectToMarkable();
1402 private:
1403 Reference < XMultiComponentFactory > m_rSMgr;
1404 Reference < XComponentContext > m_rCxt;
1405 sal_Bool m_bValidMarkable;
1406 Reference < XMarkableStream > m_rMarkable;
1407 vector < Reference< XPersistObject > > m_aPersistVector;
1411 OObjectInputStream::~OObjectInputStream()
1413 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1416 Any OObjectInputStream::queryInterface( const Type &aType ) throw ()
1418 Any a = ::cppu::queryInterface(
1419 aType ,
1420 SAL_STATIC_CAST( XMarkableStream * , this ),
1421 SAL_STATIC_CAST( XObjectInputStream * , this ) );
1422 if( a.hasValue() )
1424 return a;
1427 return ODataInputStream::queryInterface( aType );
1431 Reference< XPersistObject > OObjectInputStream::readObject() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
1433 // check if chain contains a XMarkableStream
1434 connectToMarkable();
1436 Reference< XPersistObject > xLoadedObj;
1438 // create Mark to skip newer versions
1439 sal_uInt32 nMark = m_rMarkable->createMark();
1440 // length of the data
1441 sal_Int32 nLen = (sal_uInt16) ODataInputStream::readShort();
1442 if( nLen < 0xc )
1444 throw WrongFormatException();
1447 // read the object identifier
1448 sal_uInt32 nId = readLong();
1450 // the name of the persist model
1451 // MM ???
1452 OUString aName = readUTF();
1454 // Read the length of the object
1455 sal_Int32 nObjLen = readLong();
1456 if( ( 0 == nId && 0 != nObjLen ) )
1458 throw WrongFormatException();
1461 // skip data of new version
1462 skipBytes( nLen - m_rMarkable->offsetToMark( nMark ) );
1464 sal_Bool bLoadSuccesfull = sal_True;
1465 if( nId )
1467 if( aName.getLength() )
1469 // load the object
1470 Reference< XInterface > x = m_rSMgr->createInstanceWithContext( aName, m_rCxt );
1471 xLoadedObj = Reference< XPersistObject >( x, UNO_QUERY );
1472 if( xLoadedObj.is() )
1474 sal_uInt32 nSize = m_aPersistVector.size();
1475 if( nSize <= nId )
1477 // grow to the right size
1478 Reference< XPersistObject > xEmpty;
1479 m_aPersistVector.insert( m_aPersistVector.end(), (long)(nId - nSize + 1), xEmpty );
1482 m_aPersistVector[nId] = xLoadedObj;
1483 xLoadedObj->read( Reference< XObjectInputStream >(
1484 SAL_STATIC_CAST( XObjectInputStream *, this ) ) );
1486 else
1488 // no service with this name could be instantiated
1489 bLoadSuccesfull = sal_False;
1492 else {
1493 if( m_aPersistVector.size() < nId )
1495 // id unknown, load failure !
1496 bLoadSuccesfull = sal_False;
1498 else
1500 // Object has alread been read,
1501 xLoadedObj = m_aPersistVector[nId];
1506 // skip to the position behind the object
1507 skipBytes( nObjLen + nLen - m_rMarkable->offsetToMark( nMark ) );
1508 m_rMarkable->deleteMark( nMark );
1510 if( ! bLoadSuccesfull )
1512 throw WrongFormatException();
1514 return xLoadedObj;
1518 void OObjectInputStream::connectToMarkable()
1520 if( ! m_bValidMarkable ) {
1521 if( ! m_bValidStream )
1523 throw NotConnectedException( );
1526 // find the markable stream !
1527 Reference< XInterface > rTry(m_input);
1528 while( sal_True ) {
1529 if( ! rTry.is() )
1531 throw NotConnectedException( );
1533 Reference< XMarkableStream > markable( rTry , UNO_QUERY );
1534 if( markable.is() )
1536 m_rMarkable = markable;
1537 break;
1539 Reference < XActiveDataSink > sink( rTry , UNO_QUERY );
1540 rTry = sink;
1542 m_bValidMarkable = sal_True;
1546 sal_Int32 OObjectInputStream::createMark(void) throw (IOException, RuntimeException)
1548 connectToMarkable(); // throws an exception, if a markable is not connected !
1550 return m_rMarkable->createMark();
1553 void OObjectInputStream::deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException)
1555 if( ! m_bValidMarkable )
1557 throw NotConnectedException();
1559 m_rMarkable->deleteMark( Mark );
1562 void OObjectInputStream::jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException)
1564 if( ! m_bValidMarkable )
1566 throw NotConnectedException();
1568 m_rMarkable->jumpToMark( nMark );
1570 void OObjectInputStream::jumpToFurthest(void) throw (IOException, RuntimeException)
1572 connectToMarkable();
1573 m_rMarkable->jumpToFurthest();
1576 sal_Int32 OObjectInputStream::offsetToMark(sal_Int32 nMark)
1577 throw (IOException, IllegalArgumentException, RuntimeException)
1579 if( ! m_bValidMarkable )
1581 throw NotConnectedException();
1583 return m_rMarkable->offsetToMark( nMark );
1587 Sequence< Type > SAL_CALL OObjectInputStream::getTypes(void) throw( RuntimeException )
1589 static OTypeCollection *pCollection = 0;
1590 if( ! pCollection )
1592 MutexGuard guard( Mutex::getGlobalMutex() );
1593 if( ! pCollection )
1595 static OTypeCollection collection(
1596 getCppuType( (Reference< XMarkableStream > * ) 0 ),
1597 getCppuType( (Reference< XObjectInputStream > * ) 0 ),
1598 ODataInputStream::getTypes() );
1599 pCollection = &collection;
1602 return (*pCollection).getTypes();
1605 Sequence< sal_Int8 > SAL_CALL OObjectInputStream::getImplementationId( ) throw( RuntimeException)
1607 static OImplementationId *pId = 0;
1608 if( ! pId )
1610 MutexGuard guard( Mutex::getGlobalMutex() );
1611 if( ! pId )
1613 static OImplementationId id( sal_False );
1614 pId = &id;
1617 return (*pId).getImplementationId();
1621 // XServiceInfo
1622 OUString OObjectInputStream::getImplementationName() throw ()
1624 return OObjectInputStream_getImplementationName();
1627 // XServiceInfo
1628 sal_Bool OObjectInputStream::supportsService(const OUString& ServiceName) throw ()
1630 Sequence< OUString > aSNL = getSupportedServiceNames();
1631 const OUString * pArray = aSNL.getConstArray();
1633 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1634 if( pArray[i] == ServiceName )
1635 return sal_True;
1637 return sal_False;
1640 // XServiceInfo
1641 Sequence< OUString > OObjectInputStream::getSupportedServiceNames(void) throw ()
1643 return OObjectInputStream_getSupportedServiceNames();
1649 Reference< XInterface > SAL_CALL OObjectInputStream_CreateInstance( const Reference < XComponentContext > & rCtx ) throw(Exception)
1651 OObjectInputStream *p = new OObjectInputStream( rCtx );
1652 return Reference< XInterface> ( SAL_STATIC_CAST( OWeakObject *, p ) );
1655 OUString OObjectInputStream_getImplementationName()
1657 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.ObjectInputStream" ) );
1660 Sequence<OUString> OObjectInputStream_getSupportedServiceNames(void)
1662 Sequence<OUString> aRet(1);
1663 aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.ObjectInputStream" ) );
1664 return aRet;