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

Generated by: LCOV version 1.10