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