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