/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_io.hxx" // streams #include #include #include #include #include #include #include #include #include #include #include #include // OWeakObject #include #include #include #include #include #include using namespace ::cppu; using namespace ::osl; using namespace ::std; using namespace ::rtl; using namespace ::com::sun::star::io; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; #include "factreg.hxx" namespace io_stm { class ODataInputStream : public WeakImplHelper4 < XDataInputStream, XActiveDataSink, XConnectable, XServiceInfo > { public: ODataInputStream( ) : m_bValidStream( sal_False ) { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); } ~ODataInputStream(); public: // XInputStream virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException); virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException); virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException); virtual sal_Int32 SAL_CALL available(void) throw ( NotConnectedException, RuntimeException); virtual void SAL_CALL closeInput(void) throw ( NotConnectedException, RuntimeException); public: // XDataInputStream virtual sal_Int8 SAL_CALL readBoolean(void) throw (IOException, RuntimeException); virtual sal_Int8 SAL_CALL readByte(void) throw (IOException, RuntimeException); virtual sal_Unicode SAL_CALL readChar(void) throw (IOException, RuntimeException); virtual sal_Int16 SAL_CALL readShort(void) throw (IOException, RuntimeException); virtual sal_Int32 SAL_CALL readLong(void) throw (IOException, RuntimeException); virtual sal_Int64 SAL_CALL readHyper(void) throw (IOException, RuntimeException); virtual float SAL_CALL readFloat(void) throw (IOException, RuntimeException); virtual double SAL_CALL readDouble(void) throw (IOException, RuntimeException); virtual OUString SAL_CALL readUTF(void) throw (IOException, RuntimeException); public: // XActiveDataSink virtual void SAL_CALL setInputStream(const Reference< XInputStream > & aStream) throw (RuntimeException); virtual Reference< XInputStream > SAL_CALL getInputStream(void) throw (RuntimeException); public: // XConnectable virtual void SAL_CALL setPredecessor(const Reference < XConnectable >& aPredecessor) throw (RuntimeException); virtual Reference < XConnectable > SAL_CALL getPredecessor(void) throw (RuntimeException); virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) throw (RuntimeException); virtual Reference < XConnectable > SAL_CALL getSuccessor(void) throw (RuntimeException) ; public: // XServiceInfo OUString SAL_CALL getImplementationName() throw (); Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); protected: Reference < XConnectable > m_pred; Reference < XConnectable > m_succ; Reference < XInputStream > m_input; sal_Bool m_bValidStream; }; ODataInputStream::~ODataInputStream() { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); } // XInputStream sal_Int32 ODataInputStream::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { sal_Int32 nRead; if( m_bValidStream ) { nRead = m_input->readBytes( aData , nBytesToRead ); } else { throw NotConnectedException( ); } return nRead; } sal_Int32 ODataInputStream::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { sal_Int32 nRead; if( m_bValidStream ) { nRead = m_input->readSomeBytes( aData , nMaxBytesToRead ); } else { throw NotConnectedException( ); } return nRead; } void ODataInputStream::skipBytes(sal_Int32 nBytesToSkip) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { if( m_bValidStream ) { m_input->skipBytes( nBytesToSkip ); } else { throw NotConnectedException( ); } } sal_Int32 ODataInputStream::available(void) throw ( NotConnectedException, RuntimeException) { sal_Int32 nAvail; if( m_bValidStream ) { nAvail = m_input->available( ); } else { throw NotConnectedException( ); } return nAvail; } void ODataInputStream::closeInput(void ) throw ( NotConnectedException, RuntimeException) { if( m_bValidStream ) { m_input->closeInput( ); setInputStream( Reference< XInputStream > () ); setPredecessor( Reference < XConnectable >() ); setSuccessor( Reference < XConnectable >() ); m_bValidStream = sal_False; } else { throw NotConnectedException( ); } } //== XDataInputStream =========================================== // XDataInputStream sal_Int8 ODataInputStream::readBoolean(void) throw (IOException, RuntimeException) { return readByte(); } sal_Int8 ODataInputStream::readByte(void) throw (IOException, RuntimeException) { Sequence aTmp(1); if( 1 != readBytes( aTmp, 1 ) ) { throw UnexpectedEOFException(); } return aTmp.getArray()[0]; } sal_Unicode ODataInputStream::readChar(void) throw (IOException, RuntimeException) { Sequence aTmp(2); if( 2 != readBytes( aTmp, 2 ) ) { throw UnexpectedEOFException(); } const sal_uInt8 * pBytes = ( const sal_uInt8 * )aTmp.getConstArray(); return ((sal_Unicode)pBytes[0] << 8) + pBytes[1]; } sal_Int16 ODataInputStream::readShort(void) throw (IOException, RuntimeException) { Sequence aTmp(2); if( 2 != readBytes( aTmp, 2 ) ) { throw UnexpectedEOFException(); } const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray(); return ((sal_Int16)pBytes[0] << 8) + pBytes[1]; } sal_Int32 ODataInputStream::readLong(void) throw (IOException, RuntimeException) { Sequence aTmp(4); if( 4 != readBytes( aTmp, 4 ) ) { throw UnexpectedEOFException( ); } const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray(); return ((sal_Int32)pBytes[0] << 24) + ((sal_Int32)pBytes[1] << 16) + ((sal_Int32)pBytes[2] << 8) + pBytes[3]; } sal_Int64 ODataInputStream::readHyper(void) throw (IOException, RuntimeException) { Sequence aTmp(8); if( 8 != readBytes( aTmp, 8 ) ) { throw UnexpectedEOFException( ); } const sal_uInt8 * pBytes = ( const sal_uInt8 * ) aTmp.getConstArray(); return (((sal_Int64)pBytes[0]) << 56) + (((sal_Int64)pBytes[1]) << 48) + (((sal_Int64)pBytes[2]) << 40) + (((sal_Int64)pBytes[3]) << 32) + (((sal_Int64)pBytes[4]) << 24) + (((sal_Int64)pBytes[5]) << 16) + (((sal_Int64)pBytes[6]) << 8) + pBytes[7]; } float ODataInputStream::readFloat(void) throw (IOException, RuntimeException) { union { float f; sal_uInt32 n; } a; a.n = readLong(); return a.f; } double ODataInputStream::readDouble(void) throw (IOException, RuntimeException) { sal_uInt32 n = 1; union { double d; struct { sal_uInt32 n1; sal_uInt32 n2; } ad; } a; if( *(sal_uInt8 *)&n == 1 ) { // little endian a.ad.n2 = readLong(); a.ad.n1 = readLong(); } else { // big endian a.ad.n1 = readLong(); a.ad.n2 = readLong(); } return a.d; } OUString ODataInputStream::readUTF(void) throw (IOException, RuntimeException) { sal_uInt16 nShortLen = (sal_uInt16)readShort(); sal_Int32 nUTFLen; if( ((sal_uInt16)0xffff) == nShortLen ) { // is interpreted as a sign, that string is longer than 64k // incompatible to older XDataInputStream-routines, when strings are exactly 64k nUTFLen = readLong(); } else { nUTFLen = ( sal_Int32 ) nShortLen; } Sequence aBuffer( nUTFLen ); sal_Unicode * pStr = aBuffer.getArray(); sal_Int32 nCount = 0; sal_Int32 nStrLen = 0; while( nCount < nUTFLen ) { sal_uInt8 c = (sal_uInt8)readByte(); sal_uInt8 char2, char3; switch( c >> 4 ) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx nCount++; pStr[nStrLen++] = c; break; case 12: case 13: // 110x xxxx 10xx xxxx nCount += 2; if( ! ( nCount <= nUTFLen ) ) { throw WrongFormatException( ); } char2 = (sal_uInt8)readByte(); if( ! ( (char2 & 0xC0) == 0x80 ) ) { throw WrongFormatException( ); } pStr[nStrLen++] = (sal_Unicode(c & 0x1F) << 6) | (char2 & 0x3F); break; case 14: // 1110 xxxx 10xx xxxx 10xx xxxx nCount += 3; if( !( nCount <= nUTFLen) ) { throw WrongFormatException( ); } char2 = (sal_uInt8)readByte(); char3 = (sal_uInt8)readByte(); if( (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) ) { throw WrongFormatException( ); } pStr[nStrLen++] = (sal_Unicode(c & 0x0F) << 12) | (sal_Unicode(char2 & 0x3F) << 6) | (char3 & 0x3F); break; default: // 10xx xxxx, 1111 xxxx throw WrongFormatException(); //throw new UTFDataFormatException(); } } return OUString( pStr, nStrLen ); } // XActiveDataSource void ODataInputStream::setInputStream(const Reference< XInputStream > & aStream) throw (RuntimeException) { if( m_input != aStream ) { m_input = aStream; Reference < XConnectable > pred( m_input , UNO_QUERY ); setPredecessor( pred ); } m_bValidStream = m_input.is(); } Reference< XInputStream > ODataInputStream::getInputStream(void) throw (RuntimeException) { return m_input; } // XDataSink void ODataInputStream::setSuccessor( const Reference < XConnectable > &r ) throw (RuntimeException) { /// if the references match, nothing needs to be done if( m_succ != r ) { /// store the reference for later use m_succ = r; if( m_succ.is() ) { /// set this instance as the sink ! m_succ->setPredecessor( Reference< XConnectable > ( SAL_STATIC_CAST( XConnectable * , this ) ) ); } } } Reference < XConnectable > ODataInputStream::getSuccessor() throw (RuntimeException) { return m_succ; } // XDataSource void ODataInputStream::setPredecessor( const Reference < XConnectable > &r ) throw (RuntimeException) { if( r != m_pred ) { m_pred = r; if( m_pred.is() ) { m_pred->setSuccessor( Reference< XConnectable > ( SAL_STATIC_CAST( XConnectable * , this ) ) ); } } } Reference < XConnectable > ODataInputStream::getPredecessor() throw (RuntimeException) { return m_pred; } // XServiceInfo OUString ODataInputStream::getImplementationName() throw () { return ODataInputStream_getImplementationName(); } // XServiceInfo sal_Bool ODataInputStream::supportsService(const OUString& ServiceName) throw () { Sequence< OUString > aSNL = getSupportedServiceNames(); const OUString * pArray = aSNL.getConstArray(); for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) if( pArray[i] == ServiceName ) return sal_True; return sal_False; } // XServiceInfo Sequence< OUString > ODataInputStream::getSupportedServiceNames(void) throw () { return ODataInputStream_getSupportedServiceNames(); } /*** * * registration information * * ****/ Reference< XInterface > SAL_CALL ODataInputStream_CreateInstance( const Reference < XComponentContext > & ) throw( Exception) { ODataInputStream *p = new ODataInputStream; return Reference< XInterface > ( (OWeakObject * ) p ); } OUString ODataInputStream_getImplementationName() { return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.DataInputStream" ) ); } Sequence ODataInputStream_getSupportedServiceNames(void) { Sequence aRet(1); aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.DataInputStream" ) ); return aRet; } class ODataOutputStream : public WeakImplHelper4 < XDataOutputStream, XActiveDataSource, XConnectable, XServiceInfo > { public: ODataOutputStream() : m_bValidStream( sal_False ) { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); } ~ODataOutputStream(); public: // XOutputStream virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException); virtual void SAL_CALL flush(void) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException); virtual void SAL_CALL closeOutput(void) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException); public: // XDataOutputStream virtual void SAL_CALL writeBoolean(sal_Bool Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeByte(sal_Int8 Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeChar(sal_Unicode Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeShort(sal_Int16 Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeLong(sal_Int32 Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeHyper(sal_Int64 Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeFloat(float Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeDouble(double Value) throw (IOException, RuntimeException); virtual void SAL_CALL writeUTF(const OUString& Value) throw (IOException, RuntimeException); public: // XActiveDataSource virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream) throw (RuntimeException); virtual Reference < XOutputStream > SAL_CALL getOutputStream(void) throw (RuntimeException); public: // XConnectable virtual void SAL_CALL setPredecessor(const Reference < XConnectable >& aPredecessor) throw (RuntimeException); virtual Reference < XConnectable > SAL_CALL getPredecessor(void) throw (RuntimeException); virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) throw (RuntimeException); virtual Reference < XConnectable > SAL_CALL getSuccessor(void) throw (RuntimeException); public: // XServiceInfo OUString SAL_CALL getImplementationName() throw (); Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); protected: Reference < XConnectable > m_succ; Reference < XConnectable > m_pred; Reference< XOutputStream > m_output; sal_Bool m_bValidStream; }; ODataOutputStream::~ODataOutputStream() { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); } // XOutputStream void ODataOutputStream::writeBytes(const Sequence< sal_Int8 >& aData) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { if( m_bValidStream ) { m_output->writeBytes( aData ); } else { throw NotConnectedException( ); } } void ODataOutputStream::flush(void) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { if( m_bValidStream ) { m_output->flush(); } else { throw NotConnectedException(); } } void ODataOutputStream::closeOutput(void) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { if( m_bValidStream ) { m_output->closeOutput(); setOutputStream( Reference< XOutputStream > () ); setPredecessor( Reference < XConnectable >() ); setSuccessor( Reference < XConnectable >() ); } else { throw NotConnectedException(); } } // XDataOutputStream void ODataOutputStream::writeBoolean(sal_Bool Value) throw ( IOException, RuntimeException) { if( Value ) { writeByte( 1 ); } else { writeByte( 0 ); } } void ODataOutputStream::writeByte(sal_Int8 Value) throw ( IOException, RuntimeException) { Sequence aTmp( 1 ); aTmp.getArray()[0] = Value; writeBytes( aTmp ); } void ODataOutputStream::writeChar(sal_Unicode Value) throw ( IOException, RuntimeException) { Sequence aTmp( 2 ); sal_Int8 * pBytes = ( sal_Int8 * ) aTmp.getArray(); pBytes[0] = sal_Int8(Value >> 8); pBytes[1] = sal_Int8(Value); writeBytes( aTmp ); } void ODataOutputStream::writeShort(sal_Int16 Value) throw ( IOException, RuntimeException) { Sequence aTmp( 2 ); sal_Int8 * pBytes = aTmp.getArray(); pBytes[0] = sal_Int8(Value >> 8); pBytes[1] = sal_Int8(Value); writeBytes( aTmp ); } void ODataOutputStream::writeLong(sal_Int32 Value) throw ( IOException, RuntimeException) { Sequence aTmp( 4 ); sal_Int8 * pBytes = aTmp.getArray(); pBytes[0] = sal_Int8(Value >> 24); pBytes[1] = sal_Int8(Value >> 16); pBytes[2] = sal_Int8(Value >> 8); pBytes[3] = sal_Int8(Value); writeBytes( aTmp ); } void ODataOutputStream::writeHyper(sal_Int64 Value) throw ( IOException, RuntimeException) { Sequence aTmp( 8 ); sal_Int8 * pBytes = aTmp.getArray(); pBytes[0] = sal_Int8(Value >> 56); pBytes[1] = sal_Int8(Value >> 48); pBytes[2] = sal_Int8(Value >> 40); pBytes[3] = sal_Int8(Value >> 32); pBytes[4] = sal_Int8(Value >> 24); pBytes[5] = sal_Int8(Value >> 16); pBytes[6] = sal_Int8(Value >> 8); pBytes[7] = sal_Int8(Value); writeBytes( aTmp ); } void ODataOutputStream::writeFloat(float Value) throw ( IOException, RuntimeException) { union { float f; sal_uInt32 n; } a; a.f = Value; writeLong( a.n ); } void ODataOutputStream::writeDouble(double Value) throw ( IOException, RuntimeException) { sal_uInt32 n = 1; union { double d; struct { sal_uInt32 n1; sal_uInt32 n2; } ad; } a; a.d = Value; if( *(sal_Int8 *)&n == 1 ) { // little endian writeLong( a.ad.n2 ); writeLong( a.ad.n1 ); } else { // big endian writeLong( a.ad.n1 ); writeLong( a.ad.n2 ); } } void ODataOutputStream::writeUTF(const OUString& Value) throw ( IOException, RuntimeException) { sal_Int32 nStrLen = Value.getLength(); const sal_Unicode * pStr = Value.getStr(); sal_Int32 nUTFLen = 0; sal_Int32 i; for( i = 0 ; i < nStrLen ; i++ ) { sal_uInt16 c = pStr[i]; if( (c >= 0x0001) && (c <= 0x007F) ) { nUTFLen++; } else if( c > 0x07FF ) { nUTFLen += 3; } else { nUTFLen += 2; } } // compatibility mode for older implementations, where it was not possible // to write blocks bigger than 64 k. Note that there is a tradeoff. Blocks, // that are exactly 64k long can not be read by older routines when written // with these routines and the other way round !!!!! if( nUTFLen >= 0xFFFF ) { writeShort( (sal_Int16)-1 ); writeLong( nUTFLen ); } else { writeShort( ((sal_uInt16)nUTFLen) ); } for( i = 0 ; i < nStrLen ; i++ ) { sal_uInt16 c = pStr[i]; if( (c >= 0x0001) && (c <= 0x007F) ) { writeByte(sal_Int8(c)); } else if( c > 0x07FF ) { writeByte(sal_Int8(0xE0 | ((c >> 12) & 0x0F))); writeByte(sal_Int8(0x80 | ((c >> 6) & 0x3F))); writeByte(sal_Int8(0x80 | ((c >> 0) & 0x3F))); //written += 2; } else { writeByte(sal_Int8(0xC0 | ((c >> 6) & 0x1F))); writeByte(sal_Int8(0x80 | ((c >> 0) & 0x3F))); //written += 1; } } //written += strlen + 2; } // XActiveDataSource void ODataOutputStream::setOutputStream(const Reference< XOutputStream > & aStream) throw (RuntimeException) { if( m_output != aStream ) { m_output = aStream; m_bValidStream = m_output.is(); Reference < XConnectable > succ( m_output , UNO_QUERY ); setSuccessor( succ ); } } Reference< XOutputStream > ODataOutputStream::getOutputStream(void) throw (RuntimeException) { return m_output; } // XDataSink void ODataOutputStream::setSuccessor( const Reference < XConnectable > &r ) throw (RuntimeException) { /// if the references match, nothing needs to be done if( m_succ != r ) { /// store the reference for later use m_succ = r; if( m_succ.is() ) { /// set this instance as the sink ! m_succ->setPredecessor( Reference < XConnectable > ( SAL_STATIC_CAST( XConnectable * , this ) )); } } } Reference < XConnectable > ODataOutputStream::getSuccessor() throw (RuntimeException) { return m_succ; } // XDataSource void ODataOutputStream::setPredecessor( const Reference < XConnectable > &r ) throw (RuntimeException) { if( r != m_pred ) { m_pred = r; if( m_pred.is() ) { m_pred->setSuccessor( Reference< XConnectable > ( SAL_STATIC_CAST( XConnectable * , this ) )); } } } Reference < XConnectable > ODataOutputStream::getPredecessor() throw (RuntimeException) { return m_pred; } // XServiceInfo OUString ODataOutputStream::getImplementationName() throw () { return ODataOutputStream_getImplementationName(); } // XServiceInfo sal_Bool ODataOutputStream::supportsService(const OUString& ServiceName) throw () { Sequence< OUString > aSNL = getSupportedServiceNames(); const OUString * pArray = aSNL.getConstArray(); for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) if( pArray[i] == ServiceName ) return sal_True; return sal_False; } // XServiceInfo Sequence< OUString > ODataOutputStream::getSupportedServiceNames(void) throw () { return ODataOutputStream_getSupportedServiceNames(); } Reference< XInterface > SAL_CALL ODataOutputStream_CreateInstance( const Reference < XComponentContext > & ) throw(Exception) { ODataOutputStream *p = new ODataOutputStream; Reference< XInterface > xService = *p; return xService; } OUString ODataOutputStream_getImplementationName() { return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.DataOutputStream" ) ); } Sequence ODataOutputStream_getSupportedServiceNames(void) { Sequence aRet(1); aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.DataOutputStream" ) ); return aRet; } //-------------------------------------- struct equalObjectContainer_Impl { sal_Int32 operator()(const Reference< XInterface > & s1, const Reference< XInterface > & s2) const { return s1 == s2; } }; //----------------------------------------------------------------------------- struct hashObjectContainer_Impl { size_t operator()(const Reference< XInterface > & xRef) const { return (size_t)xRef.get(); } }; typedef hash_map < Reference< XInterface >, sal_Int32, hashObjectContainer_Impl, equalObjectContainer_Impl > ObjectContainer_Impl; /*--------------------------------------------- * * * * *--------------------------------------------*/ class OObjectOutputStream : public ODataOutputStream, public XObjectOutputStream, public XMarkableStream { public: OObjectOutputStream() : m_nMaxId(0) , m_bValidMarkable(sal_False) { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); } ~OObjectOutputStream(); public: Any SAL_CALL queryInterface( const Type &type ) throw (::com::sun::star::uno::RuntimeException); void SAL_CALL acquire() throw() { ODataOutputStream::acquire(); } void SAL_CALL release() throw() { ODataOutputStream::release(); } public: // XOutputStream virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { ODataOutputStream::writeBytes( aData ); } virtual void SAL_CALL flush(void) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { ODataOutputStream::flush(); } virtual void SAL_CALL closeOutput(void) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { ODataOutputStream::closeOutput(); } public: // XDataOutputStream virtual void SAL_CALL writeBoolean(sal_Bool Value) throw (IOException, RuntimeException) { ODataOutputStream::writeBoolean( Value ); } virtual void SAL_CALL writeByte(sal_Int8 Value) throw (IOException, RuntimeException) { ODataOutputStream::writeByte( Value ); } virtual void SAL_CALL writeChar(sal_Unicode Value) throw (IOException, RuntimeException) { ODataOutputStream::writeChar( Value ); } virtual void SAL_CALL writeShort(sal_Int16 Value) throw (IOException, RuntimeException) { ODataOutputStream::writeShort( Value ); } virtual void SAL_CALL writeLong(sal_Int32 Value) throw (IOException, RuntimeException) { ODataOutputStream::writeLong( Value ); } virtual void SAL_CALL writeHyper(sal_Int64 Value) throw (IOException, RuntimeException) { ODataOutputStream::writeHyper( Value ); } virtual void SAL_CALL writeFloat(float Value) throw (IOException, RuntimeException) { ODataOutputStream::writeFloat( Value ); } virtual void SAL_CALL writeDouble(double Value) throw (IOException, RuntimeException) { ODataOutputStream::writeDouble( Value ); } virtual void SAL_CALL writeUTF(const OUString& Value) throw (IOException, RuntimeException) { ODataOutputStream::writeUTF( Value );} // XObjectOutputStream virtual void SAL_CALL writeObject( const Reference< XPersistObject > & r ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); public: // XMarkableStream virtual sal_Int32 SAL_CALL createMark(void) throw (IOException, RuntimeException); virtual void SAL_CALL deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException); virtual void SAL_CALL jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException); virtual void SAL_CALL jumpToFurthest(void) throw (IOException, RuntimeException); virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException); public: //XTypeProvider virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); public: // XServiceInfo OUString SAL_CALL getImplementationName() throw (); Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); private: void connectToMarkable(); private: ObjectContainer_Impl m_mapObject; sal_Int32 m_nMaxId; Reference< XMarkableStream > m_rMarkable; sal_Bool m_bValidMarkable; }; OObjectOutputStream::~OObjectOutputStream() { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); } Any OObjectOutputStream::queryInterface( const Type &aType ) throw (::com::sun::star::uno::RuntimeException) { Any a = ::cppu::queryInterface( aType , SAL_STATIC_CAST( XMarkableStream * , this ), SAL_STATIC_CAST( XObjectOutputStream * , this ) ); if( a.hasValue() ) { return a; } return ODataOutputStream::queryInterface( aType ); } void OObjectOutputStream::writeObject( const Reference< XPersistObject > & xPObj ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { connectToMarkable(); sal_Bool bWriteObj = sal_False; // create Mark to write length of info sal_uInt32 nInfoLenMark = m_rMarkable->createMark(); // length of the info data (is later rewritten) OObjectOutputStream::writeShort( 0 ); // write the object identifier if( xPObj.is() ) { Reference< XInterface > rX( xPObj , UNO_QUERY ); ObjectContainer_Impl::const_iterator aIt = m_mapObject.find( rX ); if( aIt == m_mapObject.end() ) { // insert new object in hash table m_mapObject[ rX ] = ++m_nMaxId; ODataOutputStream::writeLong( m_nMaxId ); ODataOutputStream::writeUTF( xPObj->getServiceName() ); bWriteObj = sal_True; } else { ODataOutputStream::writeLong( (*aIt).second ); OUString aName; ODataOutputStream::writeUTF( aName ); } } else { ODataOutputStream::writeLong( 0 ); OUString aName; ODataOutputStream::writeUTF( aName ); } sal_uInt32 nObjLenMark = m_rMarkable->createMark(); ODataOutputStream::writeLong( 0 ); sal_Int32 nInfoLen = m_rMarkable->offsetToMark( nInfoLenMark ); m_rMarkable->jumpToMark( nInfoLenMark ); // write length of the info data ODataOutputStream::writeShort( (sal_Int16)nInfoLen ); // jump to the end of the stream m_rMarkable->jumpToFurthest(); if( bWriteObj ) xPObj->write( Reference< XObjectOutputStream > ( SAL_STATIC_CAST( XObjectOutputStream * , this ) ) ); sal_Int32 nObjLen = m_rMarkable->offsetToMark( nObjLenMark ) -4; m_rMarkable->jumpToMark( nObjLenMark ); // write length of the info data ODataOutputStream::writeLong( nObjLen ); // jump to the end of the stream m_rMarkable->jumpToFurthest(); m_rMarkable->deleteMark( nObjLenMark ); m_rMarkable->deleteMark( nInfoLenMark ); } void OObjectOutputStream::connectToMarkable(void) { if( ! m_bValidMarkable ) { if( ! m_bValidStream ) { throw NotConnectedException(); } // find the markable stream ! Reference< XInterface > rTry(m_output); while( sal_True ) { if( ! rTry.is() ) { throw NotConnectedException(); } Reference < XMarkableStream > markable( rTry , UNO_QUERY ); if( markable.is() ) { m_rMarkable = markable; break; } Reference < XActiveDataSource > source( rTry , UNO_QUERY ); rTry = source; } m_bValidMarkable = sal_True; } } sal_Int32 OObjectOutputStream::createMark(void) throw (IOException, RuntimeException) { connectToMarkable(); // throws an exception, if a markable is not connected ! return m_rMarkable->createMark(); } void OObjectOutputStream::deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException) { if( ! m_bValidMarkable ) { throw NotConnectedException(); } m_rMarkable->deleteMark( Mark ); } void OObjectOutputStream::jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException) { if( ! m_bValidMarkable ) { throw NotConnectedException(); } m_rMarkable->jumpToMark( nMark ); } void OObjectOutputStream::jumpToFurthest(void) throw (IOException, RuntimeException) { connectToMarkable(); m_rMarkable->jumpToFurthest(); } sal_Int32 OObjectOutputStream::offsetToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException) { if( ! m_bValidMarkable ) { throw NotConnectedException(); } return m_rMarkable->offsetToMark( nMark ); } Reference< XInterface > SAL_CALL OObjectOutputStream_CreateInstance( const Reference < XComponentContext > & ) throw(Exception) { OObjectOutputStream *p = new OObjectOutputStream; return Reference< XInterface > ( SAL_STATIC_CAST( OWeakObject * , p ) ); } OUString OObjectOutputStream_getImplementationName() { return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.ObjectOutputStream" ) ); } Sequence OObjectOutputStream_getSupportedServiceNames(void) { Sequence aRet(1); aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.ObjectOutputStream" ) ); return aRet; } Sequence< Type > SAL_CALL OObjectOutputStream::getTypes(void) throw( RuntimeException ) { static OTypeCollection *pCollection = 0; if( ! pCollection ) { MutexGuard guard( Mutex::getGlobalMutex() ); if( ! pCollection ) { static OTypeCollection collection( getCppuType( (Reference< XMarkableStream > * ) 0 ), getCppuType( (Reference< XObjectOutputStream > * ) 0 ), ODataOutputStream::getTypes() ); pCollection = &collection; } } return (*pCollection).getTypes(); } Sequence< sal_Int8 > SAL_CALL OObjectOutputStream::getImplementationId( ) throw( RuntimeException) { static OImplementationId *pId = 0; if( ! pId ) { MutexGuard guard( Mutex::getGlobalMutex() ); if( ! pId ) { static OImplementationId id( sal_False ); pId = &id; } } return (*pId).getImplementationId(); } // XServiceInfo OUString OObjectOutputStream::getImplementationName() throw () { return ODataInputStream_getImplementationName(); } // XServiceInfo sal_Bool OObjectOutputStream::supportsService(const OUString& ServiceName) throw () { Sequence< OUString > aSNL = getSupportedServiceNames(); const OUString * pArray = aSNL.getConstArray(); for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) if( pArray[i] == ServiceName ) return sal_True; return sal_False; } // XServiceInfo Sequence< OUString > OObjectOutputStream::getSupportedServiceNames(void) throw () { return OObjectOutputStream_getSupportedServiceNames(); } class OObjectInputStream : public ODataInputStream, public XObjectInputStream, public XMarkableStream { public: OObjectInputStream( const Reference < XComponentContext > &r) : m_rSMgr( r->getServiceManager() ) , m_rCxt( r ) , m_bValidMarkable(sal_False) { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); } ~OObjectInputStream(); public: Any SAL_CALL queryInterface( const Type &type ) throw(); void SAL_CALL acquire() throw() { ODataInputStream::acquire(); } void SAL_CALL release() throw() { ODataInputStream::release(); } public: // XInputStream virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { return ODataInputStream::readBytes( aData , nBytesToRead ); } virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { return ODataInputStream::readSomeBytes( aData, nMaxBytesToRead ); } virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw ( NotConnectedException, BufferSizeExceededException, RuntimeException) { ODataInputStream::skipBytes( nBytesToSkip ); } virtual sal_Int32 SAL_CALL available(void) throw ( NotConnectedException, RuntimeException) { return ODataInputStream::available(); } virtual void SAL_CALL closeInput(void) throw ( NotConnectedException, RuntimeException) { ODataInputStream::closeInput(); } public: // XDataInputStream virtual sal_Int8 SAL_CALL readBoolean(void) throw (IOException, RuntimeException) { return ODataInputStream::readBoolean(); } virtual sal_Int8 SAL_CALL readByte(void) throw (IOException, RuntimeException) { return ODataInputStream::readByte(); } virtual sal_Unicode SAL_CALL readChar(void) throw (IOException, RuntimeException) { return ODataInputStream::readChar(); } virtual sal_Int16 SAL_CALL readShort(void) throw (IOException, RuntimeException) { return ODataInputStream::readShort(); } virtual sal_Int32 SAL_CALL readLong(void) throw (IOException, RuntimeException) { return ODataInputStream::readLong(); } virtual sal_Int64 SAL_CALL readHyper(void) throw (IOException, RuntimeException) { return ODataInputStream::readHyper(); } virtual float SAL_CALL readFloat(void) throw (IOException, RuntimeException) { return ODataInputStream::readFloat(); } virtual double SAL_CALL readDouble(void) throw (IOException, RuntimeException) { return ODataInputStream::readDouble(); } virtual OUString SAL_CALL readUTF(void) throw (IOException, RuntimeException) { return ODataInputStream::readUTF(); } public: // XObjectInputStream virtual Reference< XPersistObject > SAL_CALL readObject( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); public: // XMarkableStream virtual sal_Int32 SAL_CALL createMark(void) throw (IOException, RuntimeException); virtual void SAL_CALL deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException); virtual void SAL_CALL jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException); virtual void SAL_CALL jumpToFurthest(void) throw (IOException, RuntimeException); virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException); public: //XTypeProvider virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); public: // XServiceInfo OUString SAL_CALL getImplementationName() throw (); Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); private: void connectToMarkable(); private: Reference < XMultiComponentFactory > m_rSMgr; Reference < XComponentContext > m_rCxt; sal_Bool m_bValidMarkable; Reference < XMarkableStream > m_rMarkable; vector < Reference< XPersistObject > > m_aPersistVector; }; OObjectInputStream::~OObjectInputStream() { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); } Any OObjectInputStream::queryInterface( const Type &aType ) throw () { Any a = ::cppu::queryInterface( aType , SAL_STATIC_CAST( XMarkableStream * , this ), SAL_STATIC_CAST( XObjectInputStream * , this ) ); if( a.hasValue() ) { return a; } return ODataInputStream::queryInterface( aType ); } Reference< XPersistObject > OObjectInputStream::readObject() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { // check if chain contains a XMarkableStream connectToMarkable(); Reference< XPersistObject > xLoadedObj; // create Mark to skip newer versions sal_uInt32 nMark = m_rMarkable->createMark(); // length of the data sal_Int32 nLen = (sal_uInt16) ODataInputStream::readShort(); if( nLen < 0xc ) { throw WrongFormatException(); } // read the object identifier sal_uInt32 nId = readLong(); // the name of the persist model // MM ??? OUString aName = readUTF(); // Read the length of the object sal_Int32 nObjLen = readLong(); if( ( 0 == nId && 0 != nObjLen ) ) { throw WrongFormatException(); } // skip data of new version skipBytes( nLen - m_rMarkable->offsetToMark( nMark ) ); sal_Bool bLoadSuccesfull = sal_True; if( nId ) { if( aName.getLength() ) { // load the object Reference< XInterface > x = m_rSMgr->createInstanceWithContext( aName, m_rCxt ); xLoadedObj = Reference< XPersistObject >( x, UNO_QUERY ); if( xLoadedObj.is() ) { sal_uInt32 nSize = m_aPersistVector.size(); if( nSize <= nId ) { // grow to the right size Reference< XPersistObject > xEmpty; m_aPersistVector.insert( m_aPersistVector.end(), (long)(nId - nSize + 1), xEmpty ); } m_aPersistVector[nId] = xLoadedObj; xLoadedObj->read( Reference< XObjectInputStream >( SAL_STATIC_CAST( XObjectInputStream *, this ) ) ); } else { // no service with this name could be instantiated bLoadSuccesfull = sal_False; } } else { if( m_aPersistVector.size() < nId ) { // id unknown, load failure ! bLoadSuccesfull = sal_False; } else { // Object has alread been read, xLoadedObj = m_aPersistVector[nId]; } } } // skip to the position behind the object skipBytes( nObjLen + nLen - m_rMarkable->offsetToMark( nMark ) ); m_rMarkable->deleteMark( nMark ); if( ! bLoadSuccesfull ) { throw WrongFormatException(); } return xLoadedObj; } void OObjectInputStream::connectToMarkable() { if( ! m_bValidMarkable ) { if( ! m_bValidStream ) { throw NotConnectedException( ); } // find the markable stream ! Reference< XInterface > rTry(m_input); while( sal_True ) { if( ! rTry.is() ) { throw NotConnectedException( ); } Reference< XMarkableStream > markable( rTry , UNO_QUERY ); if( markable.is() ) { m_rMarkable = markable; break; } Reference < XActiveDataSink > sink( rTry , UNO_QUERY ); rTry = sink; } m_bValidMarkable = sal_True; } } sal_Int32 OObjectInputStream::createMark(void) throw (IOException, RuntimeException) { connectToMarkable(); // throws an exception, if a markable is not connected ! return m_rMarkable->createMark(); } void OObjectInputStream::deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException) { if( ! m_bValidMarkable ) { throw NotConnectedException(); } m_rMarkable->deleteMark( Mark ); } void OObjectInputStream::jumpToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException) { if( ! m_bValidMarkable ) { throw NotConnectedException(); } m_rMarkable->jumpToMark( nMark ); } void OObjectInputStream::jumpToFurthest(void) throw (IOException, RuntimeException) { connectToMarkable(); m_rMarkable->jumpToFurthest(); } sal_Int32 OObjectInputStream::offsetToMark(sal_Int32 nMark) throw (IOException, IllegalArgumentException, RuntimeException) { if( ! m_bValidMarkable ) { throw NotConnectedException(); } return m_rMarkable->offsetToMark( nMark ); } Sequence< Type > SAL_CALL OObjectInputStream::getTypes(void) throw( RuntimeException ) { static OTypeCollection *pCollection = 0; if( ! pCollection ) { MutexGuard guard( Mutex::getGlobalMutex() ); if( ! pCollection ) { static OTypeCollection collection( getCppuType( (Reference< XMarkableStream > * ) 0 ), getCppuType( (Reference< XObjectInputStream > * ) 0 ), ODataInputStream::getTypes() ); pCollection = &collection; } } return (*pCollection).getTypes(); } Sequence< sal_Int8 > SAL_CALL OObjectInputStream::getImplementationId( ) throw( RuntimeException) { static OImplementationId *pId = 0; if( ! pId ) { MutexGuard guard( Mutex::getGlobalMutex() ); if( ! pId ) { static OImplementationId id( sal_False ); pId = &id; } } return (*pId).getImplementationId(); } // XServiceInfo OUString OObjectInputStream::getImplementationName() throw () { return OObjectInputStream_getImplementationName(); } // XServiceInfo sal_Bool OObjectInputStream::supportsService(const OUString& ServiceName) throw () { Sequence< OUString > aSNL = getSupportedServiceNames(); const OUString * pArray = aSNL.getConstArray(); for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) if( pArray[i] == ServiceName ) return sal_True; return sal_False; } // XServiceInfo Sequence< OUString > OObjectInputStream::getSupportedServiceNames(void) throw () { return OObjectInputStream_getSupportedServiceNames(); } Reference< XInterface > SAL_CALL OObjectInputStream_CreateInstance( const Reference < XComponentContext > & rCtx ) throw(Exception) { OObjectInputStream *p = new OObjectInputStream( rCtx ); return Reference< XInterface> ( SAL_STATIC_CAST( OWeakObject *, p ) ); } OUString OObjectInputStream_getImplementationName() { return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.ObjectInputStream" ) ); } Sequence OObjectInputStream_getSupportedServiceNames(void) { Sequence aRet(1); aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.ObjectInputStream" ) ); return aRet; } }