LCOV - code coverage report
Current view: top level - tools/source/ref - pstm.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 109 257 42.4 %
Date: 2014-04-11 Functions: 18 35 51.4 %
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 <tools/debug.hxx>
      21             : #include <tools/pstm.hxx>
      22             : #include <rtl/strbuf.hxx>
      23             : 
      24             : #define STOR_NO_OPTIMIZE
      25             : 
      26        1102 : void SvClassManager::Register( sal_Int32 nClassId, SvCreateInstancePersist pFunc )
      27             : {
      28             : #ifdef DBG_UTIL
      29             :     SvCreateInstancePersist p;
      30             :     p = Get( nClassId );
      31             :     DBG_ASSERT( !p || p == pFunc, "register class with same id" );
      32             : #endif
      33        1102 :     aAssocTable.insert(Map::value_type(nClassId, pFunc));
      34        1102 : }
      35             : 
      36           0 : SvCreateInstancePersist SvClassManager::Get( sal_Int32 nClassId )
      37             : {
      38           0 :     Map::const_iterator i(aAssocTable.find(nClassId));
      39           0 :     return i == aAssocTable.end() ? 0 : i->second;
      40             : }
      41             : 
      42             : // SvRttiBase
      43       36388 : TYPEINIT0( SvRttiBase );
      44             : 
      45             : // SvPersistBaseMemberList
      46             : 
      47             : #define PERSIST_LIST_VER        (sal_uInt8)0
      48             : #define PERSIST_LIST_DBGUTIL    (sal_uInt8)0x80
      49             : 
      50        2241 : void TOOLS_DLLPUBLIC WritePersistListObjects(const SvPersistListWriteable& rList, SvPersistStream & rStm, bool bOnlyStreamed )
      51             : {
      52             : #ifdef STOR_NO_OPTIMIZE
      53        2241 :     rStm.WriteUChar( (sal_uInt8)(PERSIST_LIST_VER | PERSIST_LIST_DBGUTIL) );
      54        2241 :     sal_uInt32 nObjPos = rStm.WriteDummyLen();
      55             : #else
      56             :     sal_uInt8 bTmp = PERSIST_LIST_VER;
      57             :     rStm << bTmp;
      58             : #endif
      59        2241 :     sal_uInt32 nCountMember = rList.size();
      60        2241 :     sal_uIntPtr  nCountPos = rStm.Tell();
      61        2241 :     sal_uInt32 nWriteCount = 0;
      62        2241 :     rStm.WriteUInt32( nCountMember );
      63             :     // Don't change the list, as it causes side-effects while saving
      64       33113 :     for( sal_uIntPtr n = 0; n < nCountMember; n++ )
      65             :     {
      66       30872 :         SvPersistBase * pObj = rList.GetPersistBase( n );
      67       30872 :         if( !bOnlyStreamed || rStm.IsStreamed( pObj ) )
      68             :         { // Object should be stored
      69       30872 :             WriteSvPersistBase(rStm, pObj);
      70       30872 :             nWriteCount++;
      71             :         }
      72             :     }
      73        2241 :     if( nWriteCount != nCountMember )
      74             :     {
      75             :         // Didn't write all members, adjust count
      76           0 :         sal_uIntPtr nPos = rStm.Tell();
      77           0 :         rStm.Seek( nCountPos );
      78           0 :         rStm.WriteUInt32( nWriteCount );
      79           0 :         rStm.Seek( nPos );
      80             :     }
      81             : #ifdef STOR_NO_OPTIMIZE
      82        2241 :     rStm.WriteLen( nObjPos );
      83             : #endif
      84        2241 : }
      85             : 
      86           0 : void TOOLS_DLLPUBLIC ReadObjects( SvPersistListReadable& rLst, SvPersistStream & rStm )
      87             : {
      88             :     sal_uInt8 nVer;
      89           0 :     rStm.ReadUChar( nVer );
      90             : 
      91           0 :     if( (nVer & ~PERSIST_LIST_DBGUTIL) != PERSIST_LIST_VER )
      92             :     {
      93           0 :         rStm.SetError( SVSTREAM_GENERALERROR );
      94             :         OSL_FAIL( "persist list, false version" );
      95             :     }
      96             : 
      97           0 :     sal_uInt32 nObjLen(0), nObjPos(0);
      98           0 :     if( nVer & PERSIST_LIST_DBGUTIL )
      99           0 :         nObjLen = rStm.ReadLen( &nObjPos );
     100             : 
     101             :     sal_uInt32 nCount;
     102           0 :     rStm.ReadUInt32( nCount );
     103           0 :     for( sal_uIntPtr n = 0; n < nCount && rStm.GetError() == SVSTREAM_OK; n++ )
     104             :     {
     105             :         SvPersistBase * pObj;
     106           0 :         rStm >> pObj;
     107           0 :         if( pObj )
     108           0 :             rLst.push_back( pObj );
     109             :     }
     110             : #ifdef DBG_UTIL
     111             :             if( nObjLen + nObjPos != rStm.Tell() )
     112             :             {
     113             :                 OStringBuffer aStr("false list len: read = ");
     114             :                 aStr.append(static_cast<sal_Int64>(rStm.Tell() - nObjPos));
     115             :                 aStr.append(", should = ");
     116             :                 aStr.append(static_cast<sal_Int64>(nObjLen));
     117             :                 OSL_FAIL(aStr.getStr());
     118             :             }
     119             : #else
     120             :             (void)nObjLen;
     121             : #endif
     122           0 : }
     123             : 
     124             : /** Constructor
     125             : 
     126             :     @param rMgr       Stores factories for objects that can persisted
     127             :     @param pStream    This stream is used as the medium for PersistStream
     128             :     @param nStartIdxP Start value for object identifier (set > 0 )
     129             : 
     130             :     @warning Objects rMgr and pStream must not be manipulated while used in
     131             :              SvPersistStream. An Exception to this is pvStream
     132             :              (cf. <SvPersistStream::SetStream>).
     133             :     @see SvPersistStream::SetStream
     134             : */
     135         310 : SvPersistStream::SvPersistStream( SvClassManager & rMgr, SvStream * pStream, sal_uInt32 nStartIdxP )
     136             :     : rClassMgr( rMgr )
     137             :     , pStm( pStream )
     138             :     , aPUIdx( nStartIdxP )
     139             :     , nStartIdx( nStartIdxP )
     140             :     , pRefStm( NULL )
     141         310 :     , nFlags( 0 )
     142             : {
     143             :     DBG_ASSERT( nStartIdx != 0, "zero index not allowed" );
     144         310 :     bIsWritable = true;
     145         310 :     if( pStm )
     146             :     {
     147         302 :         SetVersion( pStm->GetVersion() );
     148         302 :         SetError( pStm->GetError() );
     149         302 :         SyncSvStream( pStm->Tell() );
     150             :     }
     151         310 : }
     152             : 
     153         620 : SvPersistStream::~SvPersistStream()
     154             : {
     155         310 :     SetStream( NULL );
     156         310 : }
     157             : 
     158             : /**
     159             : 
     160             :     @param pStream    This stream is used as the medium for PersistStream
     161             : 
     162             :     @warning pStream is used as the medium for PersistStream.
     163             :              It must not be manipulated while used in SvPersistStream.
     164             :              An Exception to this is pvStream (cf. <SvPersistStream::SetStream>).
     165             : */
     166         310 : void SvPersistStream::SetStream( SvStream * pStream )
     167             : {
     168         310 :     if( pStm != pStream )
     169             :     {
     170         302 :         if( pStm )
     171             :         {
     172         302 :             SyncSysStream();
     173         302 :             pStm->SetError( GetError() );
     174             :         }
     175         302 :         pStm = pStream;
     176             :     }
     177         310 :     if( pStm )
     178             :     {
     179           0 :         SetVersion( pStm->GetVersion() );
     180           0 :         SetError( pStm->GetError() );
     181           0 :         SyncSvStream( pStm->Tell() );
     182             :     }
     183         310 : }
     184             : 
     185           0 : void SvPersistStream::ResetError()
     186             : {
     187           0 :     SvStream::ResetError();
     188             :     DBG_ASSERT( pStm, "stream not set" );
     189           0 :     pStm->ResetError();
     190           0 : }
     191             : 
     192           0 : sal_uIntPtr SvPersistStream::GetData( void* pData, sal_uIntPtr nSize )
     193             : {
     194             :     DBG_ASSERT( pStm, "stream not set" );
     195           0 :     sal_uIntPtr nRet = pStm->Read( pData, nSize );
     196           0 :     SetError( pStm->GetError() );
     197           0 :     return nRet;
     198             : }
     199             : 
     200      716680 : sal_uIntPtr SvPersistStream::PutData( const void* pData, sal_uIntPtr nSize )
     201             : {
     202             :     DBG_ASSERT( pStm, "stream not set" );
     203      716680 :     sal_uIntPtr nRet = pStm->Write( pData, nSize );
     204      716680 :     SetError( pStm->GetError() );
     205      716680 :     return nRet;
     206             : }
     207             : 
     208       55780 : sal_uInt64 SvPersistStream::SeekPos(sal_uInt64 const nPos)
     209             : {
     210             :     DBG_ASSERT( pStm, "stream not set" );
     211       55780 :     sal_uInt64 nRet = pStm->Seek( nPos );
     212       55780 :     SetError( pStm->GetError() );
     213       55780 :     return nRet;
     214             : }
     215             : 
     216         302 : void SvPersistStream::FlushData()
     217             : {
     218         302 : }
     219             : 
     220       56941 : sal_uIntPtr SvPersistStream::GetIndex( SvPersistBase * pObj ) const
     221             : {
     222       56941 :     PersistBaseMap::const_iterator it = aPTable.find( pObj );
     223       56941 :     if( it == aPTable.end() )
     224             :     {
     225       25490 :         if ( pRefStm )
     226           0 :             return pRefStm->GetIndex( pObj );
     227             :         else
     228       25490 :             return 0;
     229             :     }
     230       31451 :     return it->second;
     231             : }
     232             : 
     233           0 : SvPersistBase * SvPersistStream::GetObject( sal_uIntPtr nIdx ) const
     234             : {
     235           0 :     if( nIdx >= nStartIdx )
     236           0 :         return aPUIdx.Get( nIdx );
     237           0 :     else if( pRefStm )
     238           0 :         return pRefStm->GetObject( nIdx );
     239           0 :     return NULL;
     240             : }
     241             : 
     242             : #define LEN_1           0x80
     243             : #define LEN_2           0x40
     244             : #define LEN_4           0x20
     245             : #define LEN_5           0x10
     246             : 
     247             : /** Reads a compressed word from the stream.
     248             : 
     249             :     For details on what format is used for compression, see
     250             :     <SvPersistStream::WriteCompressed>.
     251             : 
     252             :     @param rStm Source to read compressed data from
     253             : 
     254             :     @return Uncompressed word
     255             :     @see SvPersistStream::WriteCompressed
     256             : */
     257           0 : sal_uInt32 SvPersistStream::ReadCompressed( SvStream & rStm )
     258             : {
     259           0 :     sal_uInt32 nRet(0);
     260             :     sal_uInt8   nMask;
     261           0 :     rStm.ReadUChar( nMask );
     262           0 :     if( nMask & LEN_1 )
     263           0 :         nRet = ~LEN_1 & nMask;
     264           0 :     else if( nMask & LEN_2 )
     265             :     {
     266           0 :         nRet = ~LEN_2 & nMask;
     267           0 :         nRet <<= 8;
     268           0 :         rStm.ReadUChar( nMask );
     269           0 :         nRet |= nMask;
     270             :     }
     271           0 :     else if( nMask & LEN_4 )
     272             :     {
     273           0 :         nRet = ~LEN_4 & nMask;
     274           0 :         nRet <<= 8;
     275           0 :         rStm.ReadUChar( nMask );
     276           0 :         nRet |= nMask;
     277           0 :         nRet <<= 16;
     278             :         sal_uInt16 n;
     279           0 :         rStm.ReadUInt16( n );
     280           0 :         nRet |= n;
     281             :     }
     282           0 :     else if( nMask & LEN_5 )
     283             :     {
     284           0 :         if( nMask & 0x0F )
     285             :         {
     286           0 :             rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
     287             :             OSL_FAIL( "format error" );
     288             :         }
     289           0 :         rStm.ReadUInt32( nRet );
     290             :     }
     291             :     else
     292             :     {
     293           0 :         rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
     294             :         OSL_FAIL( "format error" );
     295             :     }
     296           0 :     return nRet;
     297             : }
     298             : 
     299             : /** Writes compressed stream
     300             : 
     301             :     @param rStm Source for writing compressed data
     302             :     @param nVal This value will be compressed and written
     303             : 
     304             :     nVal is compressed and written to stream using the following algorithm
     305             :     nVal < 0x80         =>  0x80        + nVal of size 1 Byte.
     306             :     nVal < 0x4000       =>  0x4000      + nVal of size 2 Byte.
     307             :     nVal < 0x20000000   =>  0x20000000  + nVal of size 4 Byte.
     308             :     nVal > 0x1FFFFFFF   =>  0x1000000000+ nVal of size 5 Byte.
     309             : 
     310             :     @see SvPersistStream::ReadCompressed
     311             : */
     312      127028 : void SvPersistStream::WriteCompressed( SvStream & rStm, sal_uInt32 nVal )
     313             : {
     314             : #ifdef STOR_NO_OPTIMIZE
     315      127028 :     if( nVal < 0x80 )
     316       73702 :         rStm.WriteUChar( (sal_uInt8)(LEN_1 | nVal) );
     317       53326 :     else if( nVal < 0x4000 )
     318             :     {
     319       49539 :         rStm.WriteUChar( (sal_uInt8)(LEN_2 | (nVal >> 8)) );
     320       49539 :         rStm.WriteUChar( (sal_uInt8)nVal );
     321             :     }
     322        3787 :     else if( nVal < 0x20000000 )
     323             :     {
     324             :         // highest sal_uInt8
     325        3787 :         rStm.WriteUChar( (sal_uInt8)(LEN_4 | (nVal >> 24)) );
     326             :         // 2nd highest sal_uInt8
     327        3787 :         rStm.WriteUChar( (sal_uInt8)(nVal >> 16) );
     328        3787 :         rStm.WriteUInt16( (sal_uInt16)(nVal) );
     329             :     }
     330             :     else
     331             : #endif
     332             :     {
     333           0 :         rStm.WriteUChar( (sal_uInt8)LEN_5 );
     334           0 :         rStm.WriteUInt32( nVal );
     335             :     }
     336      127028 : }
     337             : 
     338             : /** This method writes length value of 4 Bytes to the stream and returns the
     339             :     stream position.
     340             : 
     341             :     Example:
     342             :     @code
     343             :     sal_uInt32 nObjPos = rStm.WriteDummyLen();
     344             :     ...
     345             :     // write data
     346             :     ...
     347             :     rStm.WriteLen( nObjPos );
     348             :     @endcode
     349             : 
     350             :     @return Position of stream behind length value
     351             : 
     352             :     @see SvPersistStream::ReadLen
     353             :     @see SvPersistStream::WriteLen
     354             : */
     355       27731 : sal_uInt32 SvPersistStream::WriteDummyLen()
     356             : {
     357             : #ifdef DBG_UTIL
     358             :     sal_uInt32 nPos = Tell();
     359             : #endif
     360       27731 :     sal_uInt32 n0 = 0;
     361       27731 :     WriteUInt32( n0 ); // Because of Sun sp
     362             :     // Don't assert on stream error
     363             :     DBG_ASSERT( GetError() != SVSTREAM_OK
     364             :                   || (sizeof( sal_uInt32 ) == Tell() -nPos),
     365             :                 "No 4 byte as length parameter" );
     366       27731 :     return Tell();
     367             : }
     368             : 
     369             : /** Write difference between current position and nObjPos
     370             :     as sal_uInt32 to position nObjPos-4 in the stream.
     371             : 
     372             :     Afterwards, reset stream to old position.
     373             : 
     374             :     Example: Difference does not contain length value
     375             :     @code
     376             :     sal_uInt32 nObjPos = rStm.WriteDummyLen();
     377             :     ...
     378             :     // write data
     379             :     ...
     380             :     rStm.WriteLen( nObjPos );
     381             :     // write more data
     382             :     @endcode
     383             : 
     384             :     @param nObjPos Position+4, on which length is written to
     385             : 
     386             :     @see SvPersistStream::ReadLen
     387             :     @see SvPersistStream::WriteDummyLen
     388             : */
     389       27731 : void SvPersistStream::WriteLen( sal_uInt32 nObjPos )
     390             : {
     391       27731 :     sal_uInt32 nPos = Tell();
     392       27731 :     sal_uInt32 nLen = nPos - nObjPos;
     393             :     // Length in stream must be 4 Bytes
     394       27731 :     Seek( nObjPos - sizeof( sal_uInt32 ) );
     395             :     // write length
     396       27731 :     WriteUInt32( nLen );
     397       27731 :     Seek( nPos );
     398       27731 : }
     399             : 
     400             : /** Read a length value written to stream
     401             : 
     402             :     @param pTestPos Position of the stream after reading length. May be NULL.
     403             : 
     404             :     @see SvPersistStream::WriteDummyLen
     405             :     @see SvPersistStream::WriteLen
     406             : */
     407           0 : sal_uInt32 SvPersistStream::ReadLen( sal_uInt32 * pTestPos )
     408             : {
     409             :     sal_uInt32 nLen;
     410           0 :     ReadUInt32( nLen );
     411           0 :     if( pTestPos )
     412           0 :         *pTestPos = Tell();
     413           0 :     return nLen;
     414             : }
     415             : 
     416             : // File format backward-compatible
     417             : #ifdef STOR_NO_OPTIMIZE
     418             : #define P_VER       (sal_uInt8)0x00
     419             : #else
     420             : #define P_VER       (sal_uInt8)0x01
     421             : #endif
     422             : #define P_VER_MASK  (sal_uInt8)0x0F
     423             : #define P_ID_0      (sal_uInt8)0x80
     424             : #define P_OBJ       (sal_uInt8)0x40
     425             : #define P_DBGUTIL   (sal_uInt8)0x20
     426             : #define P_ID        (sal_uInt8)0x10
     427             : #ifdef STOR_NO_OPTIMIZE
     428             : #define P_STD   P_DBGUTIL
     429             : #else
     430             : #define P_STD   0
     431             : #endif
     432             : 
     433       56941 : static void WriteId
     434             : (
     435             :     SvStream & rStm,
     436             :     sal_uInt8 nHdr,
     437             :     sal_uInt32 nId,
     438             :     sal_uInt16 nClassId
     439             : )
     440             : {
     441             : #ifdef STOR_NO_OPTIMIZE
     442       56941 :     nHdr |= P_ID;
     443             : #endif
     444       56941 :     nHdr |= P_VER;
     445       56941 :     if( nHdr & P_ID )
     446             :     {
     447       56941 :         if( (nHdr & P_OBJ) || nId != 0 )
     448             :         { // Id set only for pointers or DBGUTIL
     449       56941 :             rStm.WriteUChar( (sal_uInt8)(nHdr) );
     450       56941 :             SvPersistStream::WriteCompressed( rStm, nId );
     451             :         }
     452             :         else
     453             :         { // NULL Pointer
     454           0 :             rStm.WriteUChar( (sal_uInt8)(nHdr | P_ID_0) );
     455       56941 :             return;
     456             :         }
     457             :     }
     458             :     else
     459           0 :         rStm.WriteUChar( nHdr );
     460             : 
     461       56941 :     if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) )
     462             :         // Objects always have a class id
     463             :         // Pointers only for DBG_UTIL and != NULL
     464       56941 :         SvPersistStream::WriteCompressed( rStm, nClassId );
     465             : }
     466             : 
     467           0 : static void ReadId
     468             : (
     469             :     SvStream & rStm,
     470             :     sal_uInt8 & nHdr,
     471             :     sal_uInt32 & nId,
     472             :     sal_uInt16 & nClassId
     473             : )
     474             : {
     475           0 :     nClassId = 0;
     476           0 :     rStm.ReadUChar( nHdr );
     477           0 :     if( nHdr & P_ID_0 )
     478           0 :         nId = 0;
     479             :     else
     480             :     {
     481           0 :         if( (nHdr & P_VER_MASK) == 0 )
     482             :         {
     483           0 :             if( (nHdr & P_DBGUTIL) || !(nHdr & P_OBJ) )
     484           0 :                 nId = SvPersistStream::ReadCompressed( rStm );
     485             :             else
     486           0 :                 nId = 0;
     487             :         }
     488           0 :         else if( nHdr & P_ID )
     489           0 :             nId = SvPersistStream::ReadCompressed( rStm );
     490             : 
     491           0 :         if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) )
     492           0 :             nClassId = (sal_uInt16)SvPersistStream::ReadCompressed( rStm );
     493             :     }
     494           0 : }
     495             : 
     496       25490 : void SvPersistStream::WriteObj
     497             : (
     498             :     sal_uInt8 nHdr,
     499             :     SvPersistBase * pObj
     500             : )
     501             : {
     502             : #ifdef STOR_NO_OPTIMIZE
     503       25490 :     sal_uInt32 nObjPos = 0;
     504       25490 :     if( nHdr & P_DBGUTIL )
     505             :         // remember position for length value
     506       25490 :         nObjPos = WriteDummyLen();
     507             : #endif
     508       25490 :     pObj->Save( *this );
     509             : #ifdef STOR_NO_OPTIMIZE
     510       25490 :     if( nHdr & P_DBGUTIL )
     511       25490 :         WriteLen( nObjPos );
     512             : #endif
     513       25490 : }
     514             : 
     515       56941 : SvPersistStream& SvPersistStream::WritePointer
     516             : (
     517             :     SvPersistBase * pObj
     518             : )
     519             : {
     520       56941 :     sal_uInt8 nP = P_STD;
     521             : 
     522       56941 :     if( pObj )
     523             :     {
     524       56941 :         sal_uIntPtr nId = GetIndex( pObj );
     525       56941 :         if( nId )
     526       31451 :             nP |= P_ID;
     527             :         else
     528             :         {
     529       25490 :             nId = aPUIdx.Insert( pObj );
     530       25490 :             aPTable[ pObj ] = nId;
     531       25490 :             nP |= P_OBJ;
     532             :         }
     533       56941 :         WriteId( *this, nP, nId, pObj->GetClassId() );
     534       56941 :         if( nP & P_OBJ )
     535       25490 :             WriteObj( nP, pObj );
     536             :     }
     537             :     else
     538             :     { // NULL Pointer
     539           0 :         WriteId( *this, nP | P_ID, 0, 0 );
     540             :     }
     541       56941 :     return *this;
     542             : }
     543             : 
     544           0 : sal_uInt32 SvPersistStream::ReadObj
     545             : (
     546             :     SvPersistBase * &   rpObj,
     547             :     bool                bRegister
     548             : )
     549             : {
     550             :     sal_uInt8   nHdr;
     551           0 :     sal_uInt32  nId = 0;
     552             :     sal_uInt16  nClassId;
     553             : 
     554           0 :     rpObj = NULL; // specification: 0 in case of error
     555           0 :     ReadId( *this, nHdr, nId, nClassId );
     556             : 
     557             :     // get version nummer through masking
     558           0 :     if( P_VER < (nHdr & P_VER_MASK) )
     559             :     {
     560           0 :         SetError( SVSTREAM_FILEFORMAT_ERROR );
     561             :         OSL_FAIL( "false version" );
     562             :     }
     563             : 
     564           0 :     if( !(nHdr & P_ID_0) && GetError() == SVSTREAM_OK )
     565             :     {
     566           0 :         if( P_OBJ & nHdr )
     567             :         { // read object, nId only set for P_DBGUTIL
     568             :             DBG_ASSERT( !(nHdr & P_DBGUTIL) || NULL == aPUIdx.Get( nId ),
     569             :                         "object already exist" );
     570           0 :             SvCreateInstancePersist pFunc = rClassMgr.Get( nClassId );
     571             : 
     572           0 :             sal_uInt32 nObjLen(0), nObjPos(0);
     573           0 :             if( nHdr & P_DBGUTIL )
     574           0 :                 nObjLen = ReadLen( &nObjPos );
     575           0 :             if( !pFunc )
     576             :             {
     577             : #ifdef DBG_UTIL
     578             :                 OStringBuffer aStr("no class with id: " );
     579             :                 aStr.append(static_cast<sal_Int32>(nClassId));
     580             :                 aStr.append(" registered");
     581             :                 DBG_WARNING(aStr.getStr());
     582             : #else
     583             :                 (void)nObjLen;
     584             : #endif
     585           0 :                 SetError( ERRCODE_IO_NOFACTORY );
     586           0 :                 return 0;
     587             :             }
     588           0 :             pFunc( &rpObj );
     589             :             // Save reference
     590           0 :             rpObj->AddRef();
     591             : 
     592           0 :             if( bRegister )
     593             :             {
     594             :                 // insert into table
     595           0 :                 sal_uIntPtr nNewId = aPUIdx.Insert( rpObj );
     596             :                 // in order to restore state after saving
     597           0 :                 aPTable[ rpObj ] = nNewId;
     598             :                 DBG_ASSERT( !(nHdr & P_DBGUTIL) || nId == nNewId,
     599             :                             "read write id conflict: not the same" );
     600             :             }
     601           0 :             rpObj->Load( *this );
     602             : #ifdef DBG_UTIL
     603             :             if( nObjLen + nObjPos != Tell() )
     604             :             {
     605             :                 OStringBuffer aStr("false object len: read = ");
     606             :                 aStr.append(static_cast<sal_Int64>((long)(Tell() - nObjPos)));
     607             :                 aStr.append(", should = ");
     608             :                 aStr.append(static_cast<sal_Int32>(nObjLen));
     609             :                 OSL_FAIL(aStr.getStr());
     610             :             }
     611             : #endif
     612           0 :             rpObj->RestoreNoDelete();
     613           0 :             rpObj->ReleaseRef();
     614             :         }
     615             :         else
     616             :         {
     617           0 :             rpObj = GetObject( nId );
     618             :             DBG_ASSERT( rpObj != NULL, "object does not exist" );
     619             :             DBG_ASSERT( rpObj->GetClassId() == nClassId, "class mismatch" );
     620             :         }
     621             :     }
     622           0 :     return nId;
     623             : }
     624             : 
     625           0 : SvPersistStream& SvPersistStream::ReadPointer
     626             : (
     627             :     SvPersistBase * & rpObj
     628             : )
     629             : {
     630           0 :     ReadObj( rpObj, true );
     631           0 :     return *this;
     632             : }
     633             : 
     634       56941 : SvPersistStream& WriteSvPersistBase
     635             : (
     636             :     SvPersistStream & rStm,
     637             :     SvPersistBase * pObj
     638             : )
     639             : {
     640       56941 :     return rStm.WritePointer( pObj );
     641             : }
     642             : 
     643           0 : SvPersistStream& operator >>
     644             : (
     645             :     SvPersistStream & rStm,
     646             :     SvPersistBase * & rpObj
     647             : )
     648             : {
     649           0 :     return rStm.ReadPointer( rpObj );
     650             : }
     651             : 
     652           0 : SvStream& WriteSvPersistStream
     653             : (
     654             :     SvStream & rStm,
     655             :     SvPersistStream & rThis
     656             : )
     657             : {
     658           0 :     SvStream * pOldStm = rThis.GetStream();
     659           0 :     rThis.SetStream( &rStm );
     660             : 
     661           0 :     sal_uInt8 bTmp = 0;
     662           0 :     rThis.WriteUChar( bTmp );    // Version
     663           0 :     sal_uInt32 nCount = (sal_uInt32)rThis.aPUIdx.Count();
     664           0 :     rThis.WriteUInt32( nCount );
     665           0 :     sal_uIntPtr aIndex = rThis.aPUIdx.FirstIndex();
     666           0 :     for( sal_uInt32 i = 0; i < nCount; i++ )
     667             :     {
     668           0 :         SvPersistBase * pEle = rThis.aPUIdx.Get(aIndex);
     669           0 :         sal_uInt8 nP = P_OBJ | P_ID | P_STD;
     670           0 :         WriteId( rThis, nP, aIndex, pEle->GetClassId() );
     671           0 :         rThis.WriteObj( nP, pEle );
     672           0 :         aIndex = rThis.aPUIdx.NextIndex( aIndex );
     673             :     }
     674           0 :     rThis.SetStream( pOldStm );
     675           0 :     return rStm;
     676             : }
     677             : 
     678           0 : SvStream& operator >>
     679             : (
     680             :     SvStream & rStm,
     681             :     SvPersistStream & rThis
     682             : )
     683             : {
     684           0 :     SvStream * pOldStm = rThis.GetStream();
     685           0 :     rThis.SetStream( &rStm );
     686             : 
     687             :     sal_uInt8 nVers;
     688           0 :     rThis.ReadUChar( nVers ); // Version
     689           0 :     if( 0 == nVers )
     690             :     {
     691           0 :         sal_uInt32 nCount = 0;
     692           0 :         rThis.ReadUInt32( nCount );
     693           0 :         for( sal_uInt32 i = 0; i < nCount; i++ )
     694             :         {
     695             :             SvPersistBase * pEle;
     696             :             // read, but don't insert into table
     697           0 :             sal_uIntPtr nId = rThis.ReadObj( pEle, false );
     698           0 :             if( rThis.GetError() )
     699           0 :                 break;
     700             : 
     701             :             // Id of object is never modified
     702           0 :             rThis.aPUIdx.Insert( nId, pEle );
     703           0 :             rThis.aPTable[ pEle ] = nId;
     704             :         }
     705             :     }
     706             :     else
     707           0 :         rThis.SetError( SVSTREAM_FILEFORMAT_ERROR );
     708             : 
     709           0 :     rThis.SetStream( pOldStm );
     710           0 :     return rStm;
     711             : }
     712             : 
     713             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10