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