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