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