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

Generated by: LCOV version 1.10