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

Generated by: LCOV version 1.10