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