LCOV - code coverage report
Current view: top level - io/source/stm - odata.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 283 547 51.7 %
Date: 2015-06-13 12:38:46 Functions: 78 116 67.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11