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