xref: /aoo42x/main/tools/source/ref/pstm.cxx (revision 89b56da7)
1*89b56da7SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*89b56da7SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*89b56da7SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*89b56da7SAndrew Rist  * distributed with this work for additional information
6*89b56da7SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*89b56da7SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*89b56da7SAndrew Rist  * "License"); you may not use this file except in compliance
9*89b56da7SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*89b56da7SAndrew Rist  *
11*89b56da7SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*89b56da7SAndrew Rist  *
13*89b56da7SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*89b56da7SAndrew Rist  * software distributed under the License is distributed on an
15*89b56da7SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*89b56da7SAndrew Rist  * KIND, either express or implied.  See the License for the
17*89b56da7SAndrew Rist  * specific language governing permissions and limitations
18*89b56da7SAndrew Rist  * under the License.
19*89b56da7SAndrew Rist  *
20*89b56da7SAndrew Rist  *************************************************************/
21*89b56da7SAndrew Rist 
22*89b56da7SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_tools.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir #include <tools/pstm.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #define STOR_NO_OPTIMIZE
31cdf0e10cSrcweir 
32cdf0e10cSrcweir /***********************************************************************/
33cdf0e10cSrcweir /************************************************************************
34cdf0e10cSrcweir |*	  SvClassManager::Register()
35cdf0e10cSrcweir *************************************************************************/
Register(sal_uInt16 nClassId,SvCreateInstancePersist pFunc)36cdf0e10cSrcweir void SvClassManager::Register( sal_uInt16 nClassId, SvCreateInstancePersist pFunc )
37cdf0e10cSrcweir {
38cdf0e10cSrcweir #ifdef DBG_UTIL
39cdf0e10cSrcweir 	SvCreateInstancePersist p;
40cdf0e10cSrcweir 	p = Get( nClassId );
41cdf0e10cSrcweir 	DBG_ASSERT( !p || p == pFunc, "register class with same id" );
42cdf0e10cSrcweir #endif
43cdf0e10cSrcweir     aAssocTable.insert(Map::value_type(nClassId, pFunc));
44cdf0e10cSrcweir }
45cdf0e10cSrcweir 
46cdf0e10cSrcweir /************************************************************************
47cdf0e10cSrcweir |*	  SvClassManager::Get()
48cdf0e10cSrcweir *************************************************************************/
Get(sal_uInt16 nClassId)49cdf0e10cSrcweir SvCreateInstancePersist SvClassManager::Get( sal_uInt16 nClassId )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     Map::const_iterator i(aAssocTable.find(nClassId));
52cdf0e10cSrcweir     return i == aAssocTable.end() ? 0 : i->second;
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
55cdf0e10cSrcweir /****************** SvRttiBase *******************************************/
56cdf0e10cSrcweir TYPEINIT0( SvRttiBase );
57cdf0e10cSrcweir 
58cdf0e10cSrcweir /****************** SvPersistBaseMemberList ******************************/
59cdf0e10cSrcweir 
SvPersistBaseMemberList()60cdf0e10cSrcweir SvPersistBaseMemberList::SvPersistBaseMemberList(){}
SvPersistBaseMemberList(sal_uInt16 nInitSz,sal_uInt16 nResize)61cdf0e10cSrcweir SvPersistBaseMemberList::SvPersistBaseMemberList(
62cdf0e10cSrcweir     sal_uInt16 nInitSz, sal_uInt16 nResize )
63cdf0e10cSrcweir     : SuperSvPersistBaseMemberList( nInitSz, nResize ){}
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #define PERSIST_LIST_VER		(sal_uInt8)0
66cdf0e10cSrcweir #define PERSIST_LIST_DBGUTIL	(sal_uInt8)0x80
67cdf0e10cSrcweir 
68cdf0e10cSrcweir /************************************************************************
69cdf0e10cSrcweir |*	  SvPersistBaseMemberList::WriteOnlyStreamedObjects()
70cdf0e10cSrcweir *************************************************************************/
WriteObjects(SvPersistStream & rStm,sal_Bool bOnlyStreamed) const71cdf0e10cSrcweir void SvPersistBaseMemberList::WriteObjects( SvPersistStream & rStm,
72cdf0e10cSrcweir 											sal_Bool bOnlyStreamed ) const
73cdf0e10cSrcweir {
74cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
75cdf0e10cSrcweir 	rStm << (sal_uInt8)(PERSIST_LIST_VER | PERSIST_LIST_DBGUTIL);
76cdf0e10cSrcweir 	sal_uInt32 nObjPos = rStm.WriteDummyLen();
77cdf0e10cSrcweir #else
78cdf0e10cSrcweir 	sal_uInt8 bTmp = PERSIST_LIST_VER;
79cdf0e10cSrcweir 	rStm << bTmp;
80cdf0e10cSrcweir #endif
81cdf0e10cSrcweir 	sal_uInt32 nCountMember = Count();
82cdf0e10cSrcweir 	sal_uIntPtr  nCountPos = rStm.Tell();
83cdf0e10cSrcweir 	sal_uInt32 nWriteCount = 0;
84cdf0e10cSrcweir 	rStm << nCountMember;
85cdf0e10cSrcweir 	//bloss die Liste nicht veraendern,
86cdf0e10cSrcweir 	//wegen Seiteneffekten beim Save
87cdf0e10cSrcweir 	for( sal_uIntPtr n = 0; n < nCountMember; n++ )
88cdf0e10cSrcweir 	{
89cdf0e10cSrcweir 		SvPersistBase * pObj = GetObject( n );
90cdf0e10cSrcweir 		if( !bOnlyStreamed || rStm.IsStreamed( pObj ) )
91cdf0e10cSrcweir 		{ // Objekt soll geschrieben werden
92cdf0e10cSrcweir 			rStm << GetObject( n );
93cdf0e10cSrcweir 			nWriteCount++;
94cdf0e10cSrcweir 		}
95cdf0e10cSrcweir 	}
96cdf0e10cSrcweir 	if( nWriteCount != nCountMember )
97cdf0e10cSrcweir 	{
98cdf0e10cSrcweir 		// nicht alle Objekte geschrieben, Count anpassen
99cdf0e10cSrcweir 		sal_uIntPtr nPos = rStm.Tell();
100cdf0e10cSrcweir 		rStm.Seek( nCountPos );
101cdf0e10cSrcweir 		rStm << nWriteCount;
102cdf0e10cSrcweir 		rStm.Seek( nPos );
103cdf0e10cSrcweir 	}
104cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
105cdf0e10cSrcweir 	rStm.WriteLen( nObjPos );
106cdf0e10cSrcweir #endif
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir /************************************************************************
110cdf0e10cSrcweir |*	  operator << ()
111cdf0e10cSrcweir *************************************************************************/
operator <<(SvPersistStream & rStm,const SvPersistBaseMemberList & rLst)112cdf0e10cSrcweir SvPersistStream& operator << ( SvPersistStream & rStm,
113cdf0e10cSrcweir 							   const SvPersistBaseMemberList & rLst )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir 	rLst.WriteObjects( rStm );
116cdf0e10cSrcweir 	return rStm;
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir /************************************************************************
120cdf0e10cSrcweir |*	  operator >> ()
121cdf0e10cSrcweir *************************************************************************/
operator >>(SvPersistStream & rStm,SvPersistBaseMemberList & rLst)122cdf0e10cSrcweir SvPersistStream& operator >> ( SvPersistStream & rStm,
123cdf0e10cSrcweir 							   SvPersistBaseMemberList & rLst )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir 	sal_uInt8 nVer;
126cdf0e10cSrcweir 	rStm >> nVer;
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 	if( (nVer & ~PERSIST_LIST_DBGUTIL) != PERSIST_LIST_VER )
129cdf0e10cSrcweir 	{
130cdf0e10cSrcweir 		rStm.SetError( SVSTREAM_GENERALERROR );
131cdf0e10cSrcweir 		DBG_ERROR( "persist list, false version" );
132cdf0e10cSrcweir 	}
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	sal_uInt32 nObjLen(0), nObjPos(0);
135cdf0e10cSrcweir 	if( nVer & PERSIST_LIST_DBGUTIL )
136cdf0e10cSrcweir 		nObjLen = rStm.ReadLen( &nObjPos );
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 	sal_uInt32 nCount;
139cdf0e10cSrcweir 	rStm >> nCount;
140cdf0e10cSrcweir 	for( sal_uIntPtr n = 0; n < nCount && rStm.GetError() == SVSTREAM_OK; n++ )
141cdf0e10cSrcweir 	{
142cdf0e10cSrcweir 		SvPersistBase * pObj;
143cdf0e10cSrcweir 		rStm >> pObj;
144cdf0e10cSrcweir 		if( pObj )
145cdf0e10cSrcweir 			rLst.Append( pObj );
146cdf0e10cSrcweir 	}
147cdf0e10cSrcweir #ifdef DBG_UTIL
148cdf0e10cSrcweir 			if( nObjLen + nObjPos != rStm.Tell() )
149cdf0e10cSrcweir 			{
150cdf0e10cSrcweir 				ByteString aStr( "false list len: read = " );
151cdf0e10cSrcweir 				aStr += ByteString::CreateFromInt32( (long)(rStm.Tell() - nObjPos) );
152cdf0e10cSrcweir 				aStr += ", should = ";
153cdf0e10cSrcweir 				aStr += ByteString::CreateFromInt64(nObjLen);
154cdf0e10cSrcweir 				DBG_ERROR( aStr.GetBuffer() );
155cdf0e10cSrcweir 			}
156cdf0e10cSrcweir #endif
157cdf0e10cSrcweir 	return rStm;
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir //=========================================================================
SvPersistStream(SvClassManager & rMgr,SvStream * pStream,sal_uInt32 nStartIdxP)161cdf0e10cSrcweir SvPersistStream::SvPersistStream
162cdf0e10cSrcweir (
163cdf0e10cSrcweir 	SvClassManager & rMgr,	/* Alle Factorys, deren Objekt geladen und
164cdf0e10cSrcweir 							   gespeichert werdn k"onnen */
165cdf0e10cSrcweir 	SvStream * pStream,		/* Dieser Stream wird als Medium genommen, auf
166cdf0e10cSrcweir 							   dem der PersistStream arbeitet */
167cdf0e10cSrcweir 	sal_uInt32 nStartIdxP		/* Ab diesem Index werden die Id's f"ur
168cdf0e10cSrcweir 							   die Objekte vergeben, er muss gr"osser
169cdf0e10cSrcweir 							   als Null sein. */
170cdf0e10cSrcweir )
171cdf0e10cSrcweir 	: rClassMgr( rMgr )
172cdf0e10cSrcweir 	, pStm( pStream )
173cdf0e10cSrcweir 	, aPUIdx( nStartIdxP )
174cdf0e10cSrcweir 	, nStartIdx( nStartIdxP )
175cdf0e10cSrcweir 	, pRefStm( NULL )
176cdf0e10cSrcweir 	, nFlags( 0 )
177cdf0e10cSrcweir /*	[Beschreibung]
178cdf0e10cSrcweir 
179cdf0e10cSrcweir 	Der Konstruktor der Klasse SvPersistStream. Die Objekte rMgr und
180cdf0e10cSrcweir 	pStream d"urfen nicht ver"andert werden, solange sie in einem
181cdf0e10cSrcweir 	SvPersistStream eingesetzt sind. Eine Aussnahme gibt es f"ur
182cdf0e10cSrcweir 	pStream (siehe <SvPersistStream::SetStream>).
183cdf0e10cSrcweir */
184cdf0e10cSrcweir {
185cdf0e10cSrcweir 	DBG_ASSERT( nStartIdx != 0, "zero index not allowed" );
186cdf0e10cSrcweir 	bIsWritable = sal_True;
187cdf0e10cSrcweir 	if( pStm )
188cdf0e10cSrcweir 	{
189cdf0e10cSrcweir 		SetVersion( pStm->GetVersion() );
190cdf0e10cSrcweir 		SetError( pStm->GetError() );
191cdf0e10cSrcweir 		SyncSvStream( pStm->Tell() );
192cdf0e10cSrcweir 	}
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir //=========================================================================
SvPersistStream(SvClassManager & rMgr,SvStream * pStream,const SvPersistStream & rPersStm)196cdf0e10cSrcweir SvPersistStream::SvPersistStream
197cdf0e10cSrcweir (
198cdf0e10cSrcweir 	SvClassManager & rMgr,	/* Alle Factorys, deren Objekt geladen und
199cdf0e10cSrcweir 							   gespeichert werdn k"onnen */
200cdf0e10cSrcweir 	SvStream * pStream,		/* Dieser Stream wird als Medium genommen, auf
201cdf0e10cSrcweir 							   dem der PersistStream arbeitet */
202cdf0e10cSrcweir 	const SvPersistStream & rPersStm
203cdf0e10cSrcweir 							/* Wenn PersistStream's verschachtelt werden,
204cdf0e10cSrcweir 							   dann ist dies der Parent-Stream. */
205cdf0e10cSrcweir )
206cdf0e10cSrcweir 	: rClassMgr( rMgr )
207cdf0e10cSrcweir 	, pStm( pStream )
208cdf0e10cSrcweir 	// Bereiche nicht ueberschneiden, deshalb nur groessere Indexe
209cdf0e10cSrcweir 	, aPUIdx( rPersStm.GetCurMaxIndex() +1 )
210cdf0e10cSrcweir 	, nStartIdx( rPersStm.GetCurMaxIndex() +1 )
211cdf0e10cSrcweir 	, pRefStm( &rPersStm )
212cdf0e10cSrcweir 	, nFlags( 0 )
213cdf0e10cSrcweir /*	[Beschreibung]
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 	Der Konstruktor der Klasse SvPersistStream. Die Objekte rMgr und
216cdf0e10cSrcweir 	pStream d"urfen nicht ver"andert werden, solange sie in einem
217cdf0e10cSrcweir 	SvPersistStream eingesetzt sind. Eine Aussnahme gibt es f"ur
218cdf0e10cSrcweir 	pStream (siehe <SvPersistStream::SetStream>).
219cdf0e10cSrcweir 	Durch diesen Konstruktor wird eine Hierarchiebildung unterst"utzt.
220cdf0e10cSrcweir 	Alle Objekte aus einer Hierarchie m"ussen erst geladen werden,
221cdf0e10cSrcweir 	wenn das erste aus dieser Hierarchie benutzt werden soll.
222cdf0e10cSrcweir */
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	bIsWritable = sal_True;
225cdf0e10cSrcweir 	if( pStm )
226cdf0e10cSrcweir 	{
227cdf0e10cSrcweir 		SetVersion( pStm->GetVersion() );
228cdf0e10cSrcweir 		SetError( pStm->GetError() );
229cdf0e10cSrcweir 		SyncSvStream( pStm->Tell() );
230cdf0e10cSrcweir 	}
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir //=========================================================================
~SvPersistStream()234cdf0e10cSrcweir SvPersistStream::~SvPersistStream()
235cdf0e10cSrcweir /*	[Beschreibung]
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	Der Detruktor ruft die Methode <SvPersistStream::SetStream>
238cdf0e10cSrcweir 	mit NULL.
239cdf0e10cSrcweir */
240cdf0e10cSrcweir {
241cdf0e10cSrcweir 	SetStream( NULL );
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir //=========================================================================
SetStream(SvStream * pStream)245cdf0e10cSrcweir void SvPersistStream::SetStream
246cdf0e10cSrcweir (
247cdf0e10cSrcweir 	SvStream * pStream	/* auf diesem Stream arbeitet der PersistStream */
248cdf0e10cSrcweir 
249cdf0e10cSrcweir )
250cdf0e10cSrcweir /*	[Beschreibung]
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	Es wird ein Medium (pStream) eingesetzt, auf dem PersistStream arbeitet.
253cdf0e10cSrcweir 	Dieses darf nicht von aussen modifiziert werden, solange es
254cdf0e10cSrcweir  	eingesetzt ist. Es sei denn, w"ahrend auf dem Medium gearbeitet
255cdf0e10cSrcweir 	wird, wird keine Methode von SvPersistStream gerufen, bevor
256cdf0e10cSrcweir 	nicht <SvPersistStream::SetStream> mit demselben Medium gerufen
257cdf0e10cSrcweir 	wurde.
258cdf0e10cSrcweir */
259cdf0e10cSrcweir {
260cdf0e10cSrcweir 	if( pStm != pStream )
261cdf0e10cSrcweir 	{
262cdf0e10cSrcweir 		if( pStm )
263cdf0e10cSrcweir 		{
264cdf0e10cSrcweir 			SyncSysStream();
265cdf0e10cSrcweir 			pStm->SetError( GetError() );
266cdf0e10cSrcweir 		}
267cdf0e10cSrcweir 		pStm = pStream;
268cdf0e10cSrcweir 	}
269cdf0e10cSrcweir 	if( pStm )
270cdf0e10cSrcweir 	{
271cdf0e10cSrcweir 		SetVersion( pStm->GetVersion() );
272cdf0e10cSrcweir 		SetError( pStm->GetError() );
273cdf0e10cSrcweir 		SyncSvStream( pStm->Tell() );
274cdf0e10cSrcweir 	}
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir //=========================================================================
IsA() const278cdf0e10cSrcweir sal_uInt16 SvPersistStream::IsA() const
279cdf0e10cSrcweir /*	[Beschreibung]
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 	Gibt den Identifier dieses Streamklasse zur"uck.
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 	[R"uckgabewert]
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	sal_uInt16		ID_PERSISTSTREAM wird zur"uckgegeben.
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 	[Querverweise]
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 	<SvStream::IsA>
291cdf0e10cSrcweir */
292cdf0e10cSrcweir {
293cdf0e10cSrcweir 	return ID_PERSISTSTREAM;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 
297cdf0e10cSrcweir /*************************************************************************
298cdf0e10cSrcweir |*	  SvPersistStream::ResetError()
299cdf0e10cSrcweir *************************************************************************/
ResetError()300cdf0e10cSrcweir void SvPersistStream::ResetError()
301cdf0e10cSrcweir {
302cdf0e10cSrcweir 	SvStream::ResetError();
303cdf0e10cSrcweir 	DBG_ASSERT( pStm, "stream not set" );
304cdf0e10cSrcweir 	pStm->ResetError();
305cdf0e10cSrcweir }
306cdf0e10cSrcweir 
307cdf0e10cSrcweir /*************************************************************************
308cdf0e10cSrcweir |*	  SvPersistStream::GetData()
309cdf0e10cSrcweir *************************************************************************/
GetData(void * pData,sal_uIntPtr nSize)310cdf0e10cSrcweir sal_uIntPtr SvPersistStream::GetData( void* pData, sal_uIntPtr nSize )
311cdf0e10cSrcweir {
312cdf0e10cSrcweir 	DBG_ASSERT( pStm, "stream not set" );
313cdf0e10cSrcweir 	sal_uIntPtr nRet = pStm->Read( pData, nSize );
314cdf0e10cSrcweir 	SetError( pStm->GetError() );
315cdf0e10cSrcweir 	return nRet;
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir /*************************************************************************
319cdf0e10cSrcweir |*	  SvPersistStream::PutData()
320cdf0e10cSrcweir *************************************************************************/
PutData(const void * pData,sal_uIntPtr nSize)321cdf0e10cSrcweir sal_uIntPtr SvPersistStream::PutData( const void* pData, sal_uIntPtr nSize )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir 	DBG_ASSERT( pStm, "stream not set" );
324cdf0e10cSrcweir 	sal_uIntPtr nRet = pStm->Write( pData, nSize );
325cdf0e10cSrcweir 	SetError( pStm->GetError() );
326cdf0e10cSrcweir 	return nRet;
327cdf0e10cSrcweir }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir /*************************************************************************
330cdf0e10cSrcweir |*	  SvPersistStream::Seek()
331cdf0e10cSrcweir *************************************************************************/
SeekPos(sal_uIntPtr nPos)332cdf0e10cSrcweir sal_uIntPtr SvPersistStream::SeekPos( sal_uIntPtr nPos )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir 	DBG_ASSERT( pStm, "stream not set" );
335cdf0e10cSrcweir 	sal_uIntPtr nRet = pStm->Seek( nPos );
336cdf0e10cSrcweir 	SetError( pStm->GetError() );
337cdf0e10cSrcweir 	return nRet;
338cdf0e10cSrcweir }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir /*************************************************************************
341cdf0e10cSrcweir |*	  SvPersistStream::FlushData()
342cdf0e10cSrcweir *************************************************************************/
FlushData()343cdf0e10cSrcweir void SvPersistStream::FlushData()
344cdf0e10cSrcweir {
345cdf0e10cSrcweir }
346cdf0e10cSrcweir 
347cdf0e10cSrcweir /*************************************************************************
348cdf0e10cSrcweir |*	  SvPersistStream::GetCurMaxIndex()
349cdf0e10cSrcweir *************************************************************************/
GetCurMaxIndex(const SvPersistUIdx & rIdx) const350cdf0e10cSrcweir sal_uIntPtr SvPersistStream::GetCurMaxIndex( const SvPersistUIdx & rIdx ) const
351cdf0e10cSrcweir {
352cdf0e10cSrcweir 	// const  bekomme ich nicht den hoechsten Index
353cdf0e10cSrcweir 	SvPersistUIdx * p = (SvPersistUIdx *)&rIdx;
354cdf0e10cSrcweir 	// alten merken
355cdf0e10cSrcweir 	sal_uIntPtr nCurIdx = p->GetCurIndex();
356cdf0e10cSrcweir 	p->Last();
357cdf0e10cSrcweir 	// Bereiche nicht ueberschneiden, deshalb nur groessere Indexe
358cdf0e10cSrcweir 	sal_uIntPtr nMaxIdx = p->GetCurIndex();
359cdf0e10cSrcweir 	// wieder herstellen
360cdf0e10cSrcweir 	p->Seek( nCurIdx );
361cdf0e10cSrcweir 	return nMaxIdx;
362cdf0e10cSrcweir }
363cdf0e10cSrcweir 
364cdf0e10cSrcweir /*************************************************************************
365cdf0e10cSrcweir |*	  SvPersistStream::GetIndex()
366cdf0e10cSrcweir *************************************************************************/
GetIndex(SvPersistBase * pObj) const367cdf0e10cSrcweir sal_uIntPtr SvPersistStream::GetIndex( SvPersistBase * pObj ) const
368cdf0e10cSrcweir {
369cdf0e10cSrcweir 	sal_uIntPtr nId = (sal_uIntPtr)aPTable.Get( (sal_uIntPtr)pObj );
370cdf0e10cSrcweir 	if( !nId && pRefStm )
371cdf0e10cSrcweir 		return pRefStm->GetIndex( pObj );
372cdf0e10cSrcweir 	return nId;
373cdf0e10cSrcweir }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir /*************************************************************************
376cdf0e10cSrcweir |*	  SvPersistStream::GetObject)
377cdf0e10cSrcweir *************************************************************************/
GetObject(sal_uIntPtr nIdx) const378cdf0e10cSrcweir SvPersistBase * SvPersistStream::GetObject( sal_uIntPtr nIdx ) const
379cdf0e10cSrcweir {
380cdf0e10cSrcweir 	if( nIdx >= nStartIdx )
381cdf0e10cSrcweir 		return aPUIdx.Get( nIdx );
382cdf0e10cSrcweir 	else if( pRefStm )
383cdf0e10cSrcweir 		return pRefStm->GetObject( nIdx );
384cdf0e10cSrcweir 	return NULL;
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir //=========================================================================
388cdf0e10cSrcweir #define LEN_1			0x80
389cdf0e10cSrcweir #define LEN_2			0x40
390cdf0e10cSrcweir #define LEN_4			0x20
391cdf0e10cSrcweir #define LEN_5			0x10
ReadCompressed(SvStream & rStm)392cdf0e10cSrcweir sal_uInt32 SvPersistStream::ReadCompressed
393cdf0e10cSrcweir (
394cdf0e10cSrcweir 	SvStream & rStm	/* Aus diesem Stream werden die komprimierten Daten
395cdf0e10cSrcweir 					   gelesen */
396cdf0e10cSrcweir )
397cdf0e10cSrcweir /*	[Beschreibung]
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 	Ein im Stream komprimiert abgelegtes Wort wird gelesen. In welchem
400cdf0e10cSrcweir 	Format komprimiert wird, siehe <SvPersistStream::WriteCompressed>.
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 	[R"uckgabewert]
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 	sal_uInt32		Das nicht komprimierte Wort wird zur"uckgegeben.
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 	[Querverweise]
407cdf0e10cSrcweir 
408cdf0e10cSrcweir */
409cdf0e10cSrcweir {
410cdf0e10cSrcweir 	sal_uInt32 nRet(0);
411cdf0e10cSrcweir 	sal_uInt8	nMask;
412cdf0e10cSrcweir 	rStm >> nMask;
413cdf0e10cSrcweir 	if( nMask & LEN_1 )
414cdf0e10cSrcweir 		nRet = ~LEN_1 & nMask;
415cdf0e10cSrcweir 	else if( nMask & LEN_2 )
416cdf0e10cSrcweir 	{
417cdf0e10cSrcweir 		nRet = ~LEN_2 & nMask;
418cdf0e10cSrcweir 		nRet <<= 8;
419cdf0e10cSrcweir 		rStm >> nMask;
420cdf0e10cSrcweir 		nRet |= nMask;
421cdf0e10cSrcweir 	}
422cdf0e10cSrcweir 	else if( nMask & LEN_4 )
423cdf0e10cSrcweir 	{
424cdf0e10cSrcweir 		nRet = ~LEN_4 & nMask;
425cdf0e10cSrcweir 		nRet <<= 8;
426cdf0e10cSrcweir 		rStm >> nMask;
427cdf0e10cSrcweir 		nRet |= nMask;
428cdf0e10cSrcweir 		nRet <<= 16;
429cdf0e10cSrcweir 		sal_uInt16 n;
430cdf0e10cSrcweir 		rStm >> n;
431cdf0e10cSrcweir 		nRet |= n;
432cdf0e10cSrcweir 	}
433cdf0e10cSrcweir 	else if( nMask & LEN_5 )
434cdf0e10cSrcweir 	{
435cdf0e10cSrcweir 		if( nMask & 0x0F )
436cdf0e10cSrcweir 		{
437cdf0e10cSrcweir 			rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
438cdf0e10cSrcweir 			DBG_ERROR( "format error" );
439cdf0e10cSrcweir 		}
440cdf0e10cSrcweir 		rStm >> nRet;
441cdf0e10cSrcweir 	}
442cdf0e10cSrcweir 	else
443cdf0e10cSrcweir 	{
444cdf0e10cSrcweir 		rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
445cdf0e10cSrcweir 		DBG_ERROR( "format error" );
446cdf0e10cSrcweir 	}
447cdf0e10cSrcweir 	return nRet;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
450cdf0e10cSrcweir //=========================================================================
WriteCompressed(SvStream & rStm,sal_uInt32 nVal)451cdf0e10cSrcweir void SvPersistStream::WriteCompressed
452cdf0e10cSrcweir (
453cdf0e10cSrcweir 	SvStream & rStm,/* Aus diesem Stream werden die komprimierten Daten
454cdf0e10cSrcweir 					   gelesen */
455cdf0e10cSrcweir 	sal_uInt32 nVal		/* Dieser Wert wird komprimiert geschrieben */
456cdf0e10cSrcweir )
457cdf0e10cSrcweir /*	[Beschreibung]
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 	Das "ubergebene Wort wird komprimiert und in den Stream
460cdf0e10cSrcweir  	geschrieben. Folgendermassen wir komprimiert.
461cdf0e10cSrcweir 	nVal < 0x80			=>	0x80 		+ nVal ist 1 Byte gross.
462cdf0e10cSrcweir 	nVal < 0x4000		=>	0x4000 		+ nVal ist 2 Byte gross.
463cdf0e10cSrcweir 	nVal < 0x20000000   =>	0x20000000	+ nVal ist 4 Byte gross.
464cdf0e10cSrcweir 	nVal > 0x1FFFFFFF   =>	0x1000000000+ nVal ist 5 Byte gross.
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 	[Querverweise]
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	<SvPersistStream::ReadCompressed>
469cdf0e10cSrcweir */
470cdf0e10cSrcweir {
471cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
472cdf0e10cSrcweir 	if( nVal < 0x80 )
473cdf0e10cSrcweir 		rStm << (sal_uInt8)(LEN_1 | nVal);
474cdf0e10cSrcweir 	else if( nVal < 0x4000 )
475cdf0e10cSrcweir 	{
476cdf0e10cSrcweir 		rStm << (sal_uInt8)(LEN_2 | (nVal >> 8));
477cdf0e10cSrcweir 		rStm << (sal_uInt8)nVal;
478cdf0e10cSrcweir 	}
479cdf0e10cSrcweir 	else if( nVal < 0x20000000 )
480cdf0e10cSrcweir 	{
481cdf0e10cSrcweir 		// hoechstes sal_uInt8
482cdf0e10cSrcweir 		rStm << (sal_uInt8)(LEN_4 | (nVal >> 24));
483cdf0e10cSrcweir 		// 2. hoechstes sal_uInt8
484cdf0e10cSrcweir 		rStm << (sal_uInt8)(nVal >> 16);
485cdf0e10cSrcweir 		rStm << (sal_uInt16)(nVal);
486cdf0e10cSrcweir 	}
487cdf0e10cSrcweir 	else
488cdf0e10cSrcweir #endif
489cdf0e10cSrcweir 	{
490cdf0e10cSrcweir 		rStm << (sal_uInt8)LEN_5;
491cdf0e10cSrcweir 		rStm << nVal;
492cdf0e10cSrcweir 	}
493cdf0e10cSrcweir }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir //=========================================================================
WriteDummyLen()496cdf0e10cSrcweir sal_uInt32 SvPersistStream::WriteDummyLen()
497cdf0e10cSrcweir /*	[Beschreibung]
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 	Die Methode schreibt 4 Byte in den Stream und gibt die Streamposition
500cdf0e10cSrcweir 	zur"uck.
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 	[R"uckgabewert]
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 	sal_uInt32		Die Position hinter der L"angenangabe wird zur"uckgegeben.
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 	[Beispiel]
507cdf0e10cSrcweir 
508cdf0e10cSrcweir 	sal_uInt32 nObjPos = rStm.WriteDummyLen();
509cdf0e10cSrcweir 	...
510cdf0e10cSrcweir 	// Daten schreiben
511cdf0e10cSrcweir 	...
512cdf0e10cSrcweir 	rStm.WriteLen( nObjPos );
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 	[Querverweise]
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 	<SvPersistStream::ReadLen>, <SvPersistStream::WriteLen>
517cdf0e10cSrcweir 
518cdf0e10cSrcweir */
519cdf0e10cSrcweir {
520cdf0e10cSrcweir #ifdef DBG_UTIL
521cdf0e10cSrcweir 	sal_uInt32 nPos = Tell();
522cdf0e10cSrcweir #endif
523cdf0e10cSrcweir 	sal_uInt32 n0 = 0;
524cdf0e10cSrcweir 	*this << n0; // wegen Sun sp
525cdf0e10cSrcweir 	// keine Assertion bei Streamfehler
526cdf0e10cSrcweir 	DBG_ASSERT( GetError() != SVSTREAM_OK
527cdf0e10cSrcweir 				  || (sizeof( sal_uInt32 ) == Tell() -nPos),
528cdf0e10cSrcweir 				"keine 4-Byte fuer Langenangabe" );
529cdf0e10cSrcweir 	return Tell();
530cdf0e10cSrcweir }
531cdf0e10cSrcweir 
532cdf0e10cSrcweir //=========================================================================
WriteLen(sal_uInt32 nObjPos)533cdf0e10cSrcweir void SvPersistStream::WriteLen
534cdf0e10cSrcweir (
535cdf0e10cSrcweir 	sal_uInt32 nObjPos	/* die Position + 4, an der die L"ange geschrieben
536cdf0e10cSrcweir 					   wird. */
537cdf0e10cSrcweir )
538cdf0e10cSrcweir /*	[Beschreibung]
539cdf0e10cSrcweir 
540cdf0e10cSrcweir 	Die Methode schreibt die Differenz zwischen der aktuellen und
541cdf0e10cSrcweir  	nObjPos als sal_uInt32 an die Position nObjPos -4 im Stream. Danach
542cdf0e10cSrcweir 	wird der Stream wieder auf die alte Position gestellt.
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 	[Beispiel]
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 	Die Differenz enth"alt nicht die L"angenangabe.
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 	sal_uInt32 nObjPos = rStm.WriteDummyLen();
549cdf0e10cSrcweir 	...
550cdf0e10cSrcweir 	// Daten schreiben
551cdf0e10cSrcweir 	...
552cdf0e10cSrcweir 	rStm.WriteLen( nObjPos );
553cdf0e10cSrcweir 	// weitere Daten schreiben
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 	[Querverweise]
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 	<SvPersistStream::ReadLen>, <SvPersistStream::WriteDummyLen>
558cdf0e10cSrcweir */
559cdf0e10cSrcweir {
560cdf0e10cSrcweir 	sal_uInt32 nPos = Tell();
561cdf0e10cSrcweir 	sal_uInt32 nLen = nPos - nObjPos;
562cdf0e10cSrcweir 	// die Laenge mu� im stream 4-Byte betragen
563cdf0e10cSrcweir 	Seek( nObjPos - sizeof( sal_uInt32 ) );
564cdf0e10cSrcweir 	// Laenge schreiben
565cdf0e10cSrcweir 	*this << nLen;
566cdf0e10cSrcweir 	Seek( nPos );
567cdf0e10cSrcweir }
568cdf0e10cSrcweir 
569cdf0e10cSrcweir //=========================================================================
ReadLen(sal_uInt32 * pTestPos)570cdf0e10cSrcweir sal_uInt32 SvPersistStream::ReadLen
571cdf0e10cSrcweir (
572cdf0e10cSrcweir 	sal_uInt32 * pTestPos	/* Die Position des Streams, nach dem Lesen der
573cdf0e10cSrcweir 						   L"ange, wird zur"uckgegeben. Es darf auch NULL
574cdf0e10cSrcweir 						   "ubergeben werden. */
575cdf0e10cSrcweir )
576cdf0e10cSrcweir /*	[Beschreibung]
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	Liest die L"ange die vorher mit <SvPersistStream::WriteDummyLen>
579cdf0e10cSrcweir 	und <SvPersistStream::WriteLen> geschrieben wurde.
580cdf0e10cSrcweir */
581cdf0e10cSrcweir {
582cdf0e10cSrcweir 	sal_uInt32 nLen;
583cdf0e10cSrcweir 	*this >> nLen;
584cdf0e10cSrcweir 	if( pTestPos )
585cdf0e10cSrcweir 		*pTestPos = Tell();
586cdf0e10cSrcweir 	return nLen;
587cdf0e10cSrcweir }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir //=========================================================================
590cdf0e10cSrcweir // Dateirormat abw"arts kompatibel
591cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
592cdf0e10cSrcweir #define P_VER		(sal_uInt8)0x00
593cdf0e10cSrcweir #else
594cdf0e10cSrcweir #define P_VER		(sal_uInt8)0x01
595cdf0e10cSrcweir #endif
596cdf0e10cSrcweir #define P_VER_MASK	(sal_uInt8)0x0F
597cdf0e10cSrcweir #define P_ID_0		(sal_uInt8)0x80
598cdf0e10cSrcweir #define P_OBJ		(sal_uInt8)0x40
599cdf0e10cSrcweir #define P_DBGUTIL	(sal_uInt8)0x20
600cdf0e10cSrcweir #define P_ID		(sal_uInt8)0x10
601cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
602cdf0e10cSrcweir #define P_STD	P_DBGUTIL
603cdf0e10cSrcweir #else
604cdf0e10cSrcweir #define P_STD	0
605cdf0e10cSrcweir #endif
606cdf0e10cSrcweir 
WriteId(SvStream & rStm,sal_uInt8 nHdr,sal_uInt32 nId,sal_uInt16 nClassId)607cdf0e10cSrcweir static void WriteId
608cdf0e10cSrcweir (
609cdf0e10cSrcweir 	SvStream & rStm,
610cdf0e10cSrcweir 	sal_uInt8 nHdr,
611cdf0e10cSrcweir 	sal_uInt32 nId,
612cdf0e10cSrcweir 	sal_uInt16 nClassId
613cdf0e10cSrcweir )
614cdf0e10cSrcweir {
615cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
616cdf0e10cSrcweir 	nHdr |= P_ID;
617cdf0e10cSrcweir #endif
618cdf0e10cSrcweir 	nHdr |= P_VER;
619cdf0e10cSrcweir 	if( nHdr & P_ID )
620cdf0e10cSrcweir 	{
621cdf0e10cSrcweir 		if( (nHdr & P_OBJ) || nId != 0 )
622cdf0e10cSrcweir 		{ // Id nur bei Zeiger, oder DBGUTIL
623cdf0e10cSrcweir 			rStm << (sal_uInt8)(nHdr);
624cdf0e10cSrcweir 			SvPersistStream::WriteCompressed( rStm, nId );
625cdf0e10cSrcweir 		}
626cdf0e10cSrcweir 		else
627cdf0e10cSrcweir 		{ // NULL Pointer
628cdf0e10cSrcweir 			rStm << (sal_uInt8)(nHdr | P_ID_0);
629cdf0e10cSrcweir 			return;
630cdf0e10cSrcweir 		}
631cdf0e10cSrcweir 	}
632cdf0e10cSrcweir 	else
633cdf0e10cSrcweir 		rStm << nHdr;
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 	if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) )
636cdf0e10cSrcweir 		// Objekte haben immer eine Klasse,
637cdf0e10cSrcweir 		// Pointer nur bei DBG_UTIL und != NULL
638cdf0e10cSrcweir 		SvPersistStream::WriteCompressed( rStm, nClassId );
639cdf0e10cSrcweir }
640cdf0e10cSrcweir 
641cdf0e10cSrcweir //=========================================================================
ReadId(SvStream & rStm,sal_uInt8 & nHdr,sal_uInt32 & nId,sal_uInt16 & nClassId)642cdf0e10cSrcweir static void ReadId
643cdf0e10cSrcweir (
644cdf0e10cSrcweir 	SvStream & rStm,
645cdf0e10cSrcweir 	sal_uInt8 & nHdr,
646cdf0e10cSrcweir 	sal_uInt32 & nId,
647cdf0e10cSrcweir 	sal_uInt16 & nClassId
648cdf0e10cSrcweir )
649cdf0e10cSrcweir {
650cdf0e10cSrcweir 	nClassId = 0;
651cdf0e10cSrcweir 	rStm >> nHdr;
652cdf0e10cSrcweir 	if( nHdr & P_ID_0 )
653cdf0e10cSrcweir 		nId = 0;
654cdf0e10cSrcweir 	else
655cdf0e10cSrcweir 	{
656cdf0e10cSrcweir 		if( (nHdr & P_VER_MASK) == 0 )
657cdf0e10cSrcweir 		{
658cdf0e10cSrcweir 			if( (nHdr & P_DBGUTIL) || !(nHdr & P_OBJ) )
659cdf0e10cSrcweir 				nId = SvPersistStream::ReadCompressed( rStm );
660cdf0e10cSrcweir 			else
661cdf0e10cSrcweir 				nId = 0;
662cdf0e10cSrcweir 		}
663cdf0e10cSrcweir 		else if( nHdr & P_ID )
664cdf0e10cSrcweir 			nId = SvPersistStream::ReadCompressed( rStm );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir 		if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) )
667cdf0e10cSrcweir 			nClassId = (sal_uInt16)SvPersistStream::ReadCompressed( rStm );
668cdf0e10cSrcweir 	}
669cdf0e10cSrcweir }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir //=========================================================================
WriteObj(sal_uInt8 nHdr,SvPersistBase * pObj)672cdf0e10cSrcweir void SvPersistStream::WriteObj
673cdf0e10cSrcweir (
674cdf0e10cSrcweir 	sal_uInt8 nHdr,
675cdf0e10cSrcweir 	SvPersistBase * pObj
676cdf0e10cSrcweir )
677cdf0e10cSrcweir {
678cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
679cdf0e10cSrcweir 	sal_uInt32 nObjPos = 0;
680cdf0e10cSrcweir 	if( nHdr & P_DBGUTIL )
681cdf0e10cSrcweir 		// Position fuer Laenge merken
682cdf0e10cSrcweir 		nObjPos = WriteDummyLen();
683cdf0e10cSrcweir #endif
684cdf0e10cSrcweir 	pObj->Save( *this );
685cdf0e10cSrcweir #ifdef STOR_NO_OPTIMIZE
686cdf0e10cSrcweir 	if( nHdr & P_DBGUTIL )
687cdf0e10cSrcweir 		WriteLen( nObjPos );
688cdf0e10cSrcweir #endif
689cdf0e10cSrcweir }
690cdf0e10cSrcweir 
691cdf0e10cSrcweir //=========================================================================
WritePointer(SvPersistBase * pObj)692cdf0e10cSrcweir SvPersistStream& SvPersistStream::WritePointer
693cdf0e10cSrcweir (
694cdf0e10cSrcweir 	SvPersistBase * pObj
695cdf0e10cSrcweir )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir 	sal_uInt8 nP = P_STD;
698cdf0e10cSrcweir 
699cdf0e10cSrcweir 	if( pObj )
700cdf0e10cSrcweir 	{
701cdf0e10cSrcweir 		sal_uIntPtr nId = GetIndex( pObj );
702cdf0e10cSrcweir 		if( nId )
703cdf0e10cSrcweir 			nP |= P_ID;
704cdf0e10cSrcweir 		else
705cdf0e10cSrcweir 		{
706cdf0e10cSrcweir 			nId = aPUIdx.Insert( pObj );
707cdf0e10cSrcweir 			aPTable.Insert( (sal_uIntPtr)pObj, (void *)nId );
708cdf0e10cSrcweir 			nP |= P_OBJ;
709cdf0e10cSrcweir 		}
710cdf0e10cSrcweir 		WriteId( *this, nP, nId, pObj->GetClassId() );
711cdf0e10cSrcweir 		if( nP & P_OBJ )
712cdf0e10cSrcweir 			WriteObj( nP, pObj );
713cdf0e10cSrcweir 	}
714cdf0e10cSrcweir 	else
715cdf0e10cSrcweir 	{ // NULL Pointer
716cdf0e10cSrcweir 		WriteId( *this, nP | P_ID, 0, 0 );
717cdf0e10cSrcweir 	}
718cdf0e10cSrcweir 	return *this;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir //=========================================================================
ReadObj(SvPersistBase * & rpObj,sal_Bool bRegister)722cdf0e10cSrcweir sal_uInt32 SvPersistStream::ReadObj
723cdf0e10cSrcweir (
724cdf0e10cSrcweir 	SvPersistBase * &	rpObj,
725cdf0e10cSrcweir 	sal_Bool				bRegister
726cdf0e10cSrcweir )
727cdf0e10cSrcweir {
728cdf0e10cSrcweir 	sal_uInt8	nHdr;
729cdf0e10cSrcweir 	sal_uInt32	nId = 0;
730cdf0e10cSrcweir 	sal_uInt16	nClassId;
731cdf0e10cSrcweir 
732cdf0e10cSrcweir 	rpObj = NULL;	// Spezifikation: Im Fehlerfall 0.
733cdf0e10cSrcweir 	ReadId( *this, nHdr, nId, nClassId );
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 	// reine Versionsnummer durch maskieren
736cdf0e10cSrcweir 	if( P_VER < (nHdr & P_VER_MASK) )
737cdf0e10cSrcweir 	{
738cdf0e10cSrcweir 		SetError( SVSTREAM_FILEFORMAT_ERROR );
739cdf0e10cSrcweir 		DBG_ERROR( "false version" );
740cdf0e10cSrcweir 	}
741cdf0e10cSrcweir 
742cdf0e10cSrcweir 	if( !(nHdr & P_ID_0) && GetError() == SVSTREAM_OK )
743cdf0e10cSrcweir 	{
744cdf0e10cSrcweir 		if( P_OBJ & nHdr )
745cdf0e10cSrcweir 		{ // read object, nId nur bei P_DBGUTIL gesetzt
746cdf0e10cSrcweir 			DBG_ASSERT( !(nHdr & P_DBGUTIL) || NULL == aPUIdx.Get( nId ),
747cdf0e10cSrcweir 						"object already exist" );
748cdf0e10cSrcweir 			SvCreateInstancePersist pFunc = rClassMgr.Get( nClassId );
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 			sal_uInt32 nObjLen(0), nObjPos(0);
751cdf0e10cSrcweir 			if( nHdr & P_DBGUTIL )
752cdf0e10cSrcweir 				nObjLen = ReadLen( &nObjPos );
753cdf0e10cSrcweir 			if( !pFunc )
754cdf0e10cSrcweir 			{
755cdf0e10cSrcweir #ifdef DBG_UTIL
756cdf0e10cSrcweir 				ByteString aStr( "no class with id: " );
757cdf0e10cSrcweir 				aStr += ByteString::CreateFromInt32( nClassId );
758cdf0e10cSrcweir 				aStr += " registered";
759cdf0e10cSrcweir 				DBG_WARNING( aStr.GetBuffer() );
760cdf0e10cSrcweir #endif
761cdf0e10cSrcweir 				SetError( ERRCODE_IO_NOFACTORY );
762cdf0e10cSrcweir 				return 0;
763cdf0e10cSrcweir 			}
764cdf0e10cSrcweir 			pFunc( &rpObj );
765cdf0e10cSrcweir 			// Sichern
766cdf0e10cSrcweir 			rpObj->AddRef();
767cdf0e10cSrcweir 
768cdf0e10cSrcweir 			if( bRegister )
769cdf0e10cSrcweir 			{
770cdf0e10cSrcweir 				// unbedingt erst in Tabelle eintragen
771cdf0e10cSrcweir 				sal_uIntPtr nNewId = aPUIdx.Insert( rpObj );
772cdf0e10cSrcweir 				// um den gleichen Zustand, wie nach dem Speichern herzustellen
773cdf0e10cSrcweir 				aPTable.Insert( (sal_uIntPtr)rpObj, (void *)nNewId );
774cdf0e10cSrcweir 				DBG_ASSERT( !(nHdr & P_DBGUTIL) || nId == nNewId,
775cdf0e10cSrcweir 							"read write id conflict: not the same" );
776cdf0e10cSrcweir 			}
777cdf0e10cSrcweir 			// und dann Laden
778cdf0e10cSrcweir 			rpObj->Load( *this );
779cdf0e10cSrcweir #ifdef DBG_UTIL
780cdf0e10cSrcweir 			if( nObjLen + nObjPos != Tell() )
781cdf0e10cSrcweir 			{
782cdf0e10cSrcweir 				ByteString aStr( "false object len: read = " );
783cdf0e10cSrcweir 				aStr += ByteString::CreateFromInt32( (long)(Tell() - nObjPos) );
784cdf0e10cSrcweir 				aStr += ", should = ";
785cdf0e10cSrcweir 				aStr += ByteString::CreateFromInt32( nObjLen );
786cdf0e10cSrcweir 				DBG_ERROR( aStr.GetBuffer() );
787cdf0e10cSrcweir 			}
788cdf0e10cSrcweir #endif
789cdf0e10cSrcweir 			rpObj->RestoreNoDelete();
790cdf0e10cSrcweir 			rpObj->ReleaseRef();
791cdf0e10cSrcweir 		}
792cdf0e10cSrcweir 		else
793cdf0e10cSrcweir 		{
794cdf0e10cSrcweir 			rpObj = GetObject( nId );
795cdf0e10cSrcweir 			DBG_ASSERT( rpObj != NULL, "object does not exist" );
796cdf0e10cSrcweir 			DBG_ASSERT( rpObj->GetClassId() == nClassId, "class mismatch" );
797cdf0e10cSrcweir 		}
798cdf0e10cSrcweir 	}
799cdf0e10cSrcweir 	return nId;
800cdf0e10cSrcweir }
801cdf0e10cSrcweir 
802cdf0e10cSrcweir //=========================================================================
ReadPointer(SvPersistBase * & rpObj)803cdf0e10cSrcweir SvPersistStream& SvPersistStream::ReadPointer
804cdf0e10cSrcweir (
805cdf0e10cSrcweir 	SvPersistBase * & rpObj
806cdf0e10cSrcweir )
807cdf0e10cSrcweir {
808cdf0e10cSrcweir 	ReadObj( rpObj, sal_True );
809cdf0e10cSrcweir 	return *this;
810cdf0e10cSrcweir }
811cdf0e10cSrcweir 
812cdf0e10cSrcweir //=========================================================================
operator <<(SvPersistStream & rStm,SvPersistBase * pObj)813cdf0e10cSrcweir SvPersistStream& operator <<
814cdf0e10cSrcweir (
815cdf0e10cSrcweir 	SvPersistStream & rStm,
816cdf0e10cSrcweir 	SvPersistBase * pObj
817cdf0e10cSrcweir )
818cdf0e10cSrcweir {
819cdf0e10cSrcweir 	return rStm.WritePointer( pObj );
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
822cdf0e10cSrcweir //=========================================================================
operator >>(SvPersistStream & rStm,SvPersistBase * & rpObj)823cdf0e10cSrcweir SvPersistStream& operator >>
824cdf0e10cSrcweir (
825cdf0e10cSrcweir 	SvPersistStream & rStm,
826cdf0e10cSrcweir 	SvPersistBase * & rpObj
827cdf0e10cSrcweir )
828cdf0e10cSrcweir {
829cdf0e10cSrcweir 	return rStm.ReadPointer( rpObj );
830cdf0e10cSrcweir }
831cdf0e10cSrcweir 
832cdf0e10cSrcweir //=========================================================================
operator <<(SvStream & rStm,SvPersistStream & rThis)833cdf0e10cSrcweir SvStream& operator <<
834cdf0e10cSrcweir (
835cdf0e10cSrcweir 	SvStream & rStm,
836cdf0e10cSrcweir 	SvPersistStream & rThis
837cdf0e10cSrcweir )
838cdf0e10cSrcweir {
839cdf0e10cSrcweir 	SvStream * pOldStm = rThis.GetStream();
840cdf0e10cSrcweir 	rThis.SetStream( &rStm );
841cdf0e10cSrcweir 
842cdf0e10cSrcweir 	sal_uInt8 bTmp = 0;
843cdf0e10cSrcweir 	rThis << bTmp;    // Version
844cdf0e10cSrcweir 	sal_uInt32 nCount = (sal_uInt32)rThis.aPUIdx.Count();
845cdf0e10cSrcweir 	rThis << nCount;
846cdf0e10cSrcweir 	SvPersistBase * pEle = rThis.aPUIdx.First();
847cdf0e10cSrcweir 	for( sal_uInt32 i = 0; i < nCount; i++ )
848cdf0e10cSrcweir 	{
849cdf0e10cSrcweir 		sal_uInt8 nP = P_OBJ | P_ID | P_STD;
850cdf0e10cSrcweir 		WriteId( rThis, nP, rThis.aPUIdx.GetCurIndex(),
851cdf0e10cSrcweir 						pEle->GetClassId() );
852cdf0e10cSrcweir 		rThis.WriteObj( nP, pEle );
853cdf0e10cSrcweir 		pEle = rThis.aPUIdx.Next();
854cdf0e10cSrcweir 	}
855cdf0e10cSrcweir 	rThis.SetStream( pOldStm );
856cdf0e10cSrcweir 	return rStm;
857cdf0e10cSrcweir }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir //=========================================================================
operator >>(SvStream & rStm,SvPersistStream & rThis)860cdf0e10cSrcweir SvStream& operator >>
861cdf0e10cSrcweir (
862cdf0e10cSrcweir 	SvStream & rStm,
863cdf0e10cSrcweir 	SvPersistStream & rThis
864cdf0e10cSrcweir )
865cdf0e10cSrcweir {
866cdf0e10cSrcweir 	SvStream * pOldStm = rThis.GetStream();
867cdf0e10cSrcweir 	rThis.SetStream( &rStm );
868cdf0e10cSrcweir 
869cdf0e10cSrcweir 	sal_uInt8 nVers;
870cdf0e10cSrcweir 	rThis >> nVers;    // Version
871cdf0e10cSrcweir 	if( 0 == nVers )
872cdf0e10cSrcweir 	{
873cdf0e10cSrcweir 		sal_uInt32 nCount = 0;
874cdf0e10cSrcweir 		rThis >> nCount;
875cdf0e10cSrcweir 		for( sal_uInt32 i = 0; i < nCount; i++ )
876cdf0e10cSrcweir 		{
877cdf0e10cSrcweir 			SvPersistBase * pEle;
878cdf0e10cSrcweir 			// Lesen, ohne in die Tabellen einzutragen
879cdf0e10cSrcweir 			sal_uInt32 nId = rThis.ReadObj( pEle, sal_False );
880cdf0e10cSrcweir 			if( rThis.GetError() )
881cdf0e10cSrcweir 				break;
882cdf0e10cSrcweir 
883cdf0e10cSrcweir 			// Die Id eines Objektes wird nie modifiziert
884cdf0e10cSrcweir 			rThis.aPUIdx.Insert( nId, pEle );
885cdf0e10cSrcweir 			rThis.aPTable.Insert( (sal_uIntPtr)pEle, (void *)nId );
886cdf0e10cSrcweir 		}
887cdf0e10cSrcweir 	}
888cdf0e10cSrcweir 	else
889cdf0e10cSrcweir 		rThis.SetError( SVSTREAM_FILEFORMAT_ERROR );
890cdf0e10cSrcweir 
891cdf0e10cSrcweir 	rThis.SetStream( pOldStm );
892cdf0e10cSrcweir 	return rStm;
893cdf0e10cSrcweir }
894cdf0e10cSrcweir 
895cdf0e10cSrcweir //=========================================================================
InsertObj(SvPersistBase * pObj)896cdf0e10cSrcweir sal_uIntPtr SvPersistStream::InsertObj( SvPersistBase * pObj )
897cdf0e10cSrcweir {
898cdf0e10cSrcweir 	sal_uIntPtr nId = aPUIdx.Insert( pObj );
899cdf0e10cSrcweir 	aPTable.Insert( (sal_uIntPtr)pObj, (void *)nId );
900cdf0e10cSrcweir 	return nId;
901cdf0e10cSrcweir }
902cdf0e10cSrcweir 
903cdf0e10cSrcweir //=========================================================================
RemoveObj(SvPersistBase * pObj)904cdf0e10cSrcweir sal_uIntPtr SvPersistStream::RemoveObj( SvPersistBase * pObj )
905cdf0e10cSrcweir {
906cdf0e10cSrcweir 	sal_uIntPtr nIdx = GetIndex( pObj );
907cdf0e10cSrcweir 	aPUIdx.Remove( nIdx );
908cdf0e10cSrcweir 	aPTable.Remove( (sal_uIntPtr)pObj );
909cdf0e10cSrcweir 	return nIdx;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir 
912