1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <boost/unordered_map.hpp>
23 #include "tools/toolsdllapi.h"
24 #include <tools/unqidx.hxx>
25 #include <tools/ref.hxx>
26 #include <tools/rtti.hxx>
27 #include <tools/stream.hxx>
30 #define ERRCODE_IO_NOFACTORY ERRCODE_IO_WRONGFORMAT
34 typedef void * (*SvCreateInstancePersist
)( SvPersistBase
** );
36 #define SV_CLASS_REGISTER( Class ) \
37 Register( Class::StaticClassId(), Class::CreateInstance )
39 class TOOLS_DLLPUBLIC SvClassManager
41 typedef boost::unordered_map
<sal_Int32
, SvCreateInstancePersist
> Map
;
45 void Register( sal_Int32 nClassId
, SvCreateInstancePersist pFunc
);
46 SvCreateInstancePersist
Get( sal_Int32 nClassId
);
49 class TOOLS_DLLPUBLIC SvRttiBase
: public SvRefBase
54 SV_DECL_IMPL_REF(SvRttiBase
)
56 #define SV_DECL_PERSIST( Class, CLASS_ID ) \
58 static sal_Int32 StaticClassId() { return CLASS_ID; } \
59 static void * CreateInstance( SvPersistBase ** ppBase ); \
60 friend SvPersistStream& operator >> ( SvPersistStream & rStm, \
62 virtual sal_Int32 GetClassId() const; \
63 virtual void Load( SvPersistStream & ); \
64 virtual void Save( SvPersistStream & );
66 #define SV_DECL_PERSIST1( Class, Super1, CLASS_ID ) \
67 SV_DECL_PERSIST( Class, CLASS_ID )
69 #define PRV_SV_IMPL_PERSIST( Class ) \
70 void * Class::CreateInstance( SvPersistBase ** ppBase )\
72 Class * p = new Class(); \
76 sal_Int32 Class::GetClassId() const \
77 { return StaticClassId(); } \
78 SvPersistStream& operator >> (SvPersistStream & rStm, Class *& rpObj)\
80 SvPersistBase * pObj; \
82 rpObj = PTR_CAST( Class, pObj ); \
86 #define SV_IMPL_PERSIST1( Class, Super1 ) \
87 TYPEINIT1( Class, Super1 ) \
88 PRV_SV_IMPL_PERSIST( Class )
90 class SvPersistStream
;
92 class SvPersistBase
: public SvRttiBase
95 virtual sal_Int32
GetClassId() const = 0;
96 virtual void Load( SvPersistStream
& ) = 0;
97 virtual void Save( SvPersistStream
& ) = 0;
98 TOOLS_DLLPUBLIC
friend SvPersistStream
& operator >> ( SvPersistStream
& rStm
,
99 SvPersistBase
*& rpObj
);
101 SV_DECL_IMPL_REF(SvPersistBase
)
103 class SvPersistListWriteable
106 virtual ~SvPersistListWriteable() {}
107 virtual size_t size() const = 0;
108 virtual SvPersistBase
* GetPersistBase(size_t idx
) const = 0;
111 class SvPersistListReadable
114 virtual ~SvPersistListReadable() {}
115 virtual void push_back(SvPersistBase
* p
) = 0;
118 void TOOLS_DLLPUBLIC
WritePersistListObjects(const SvPersistListWriteable
& rList
, SvPersistStream
& rStm
, bool bOnlyStreamed
= false );
120 void TOOLS_DLLPUBLIC
ReadObjects( SvPersistListReadable
& rLst
, SvPersistStream
& rStm
);
122 // <T> has to be a subtype of "SvPersistBase*"
124 class SvDeclPersistList
: public SvRefMemberList
<T
>,
125 public SvPersistListWriteable
,
126 public SvPersistListReadable
129 // implement the reader/writer adapter methods
130 size_t size() const { return SvRefMemberList
<T
>::size(); }
131 SvPersistBase
* GetPersistBase(size_t idx
) const { return SvRefMemberList
<T
>::operator[](idx
); }
132 void push_back(SvPersistBase
* p
) { SvRefMemberList
<T
>::push_back(static_cast<T
>(p
)); }
133 void WriteObjects(SvPersistStream
& rStm
, bool bOnlyStreamed
) const { WritePersistListObjects(*this, rStm
, bOnlyStreamed
); }
137 SvPersistStream
& operator << (SvPersistStream
&rStm
, const SvDeclPersistList
<T
> &rLst
)
139 WritePersistListObjects( rLst
, rStm
);
144 SvPersistStream
& operator >> (SvPersistStream
&rStm
, SvDeclPersistList
<T
> &rLst
)
146 ReadObjects( rLst
, rStm
);
150 typedef UniqueIndex
<SvPersistBase
> SvPersistUIdx
;
151 typedef std::map
<SvPersistBase
*, sal_uIntPtr
> PersistBaseMap
;
155 /** Persistent Stream
157 This class provides accessor to storing and loading runtime objects.
158 All dependent objects have to be stored as well.
159 In order to load objects automatically, every object class must
160 provide a Factory method to read an object from stream.
161 The list of all classes is stored in a <SvClassManager> object
162 and is sent to SvPersistStream upon initialization.
163 By using the Method SvPersistStream::WriteCompressed and
164 SvPersistStream::ReadCompressed, compressed sal_uInt32 values may be
165 written to / read from the Stream.
166 Several helper methods exists for writing and reading
167 object lengths to the stream: SvPersistStream::WriteDummyLen,
168 SvPersistStream::WriteLen and SvPersistStream::ReadLen.
172 One example is described in the constructor.
173 Assume a ring-like dependency, where A referenes B,
174 B itself references C, and C references to both D and A.
176 The order of the objects upon saving and loading does not matter,
177 as long objects are loaded in the same order they were stored.
180 A,B,C,D A,B,C,D correct
181 B,A,C,D B,A,C,D correct
182 C,A,B,D A,B,C,D wrong
185 @note The file formats DBG_UTIL and !DBG_UTIL differ, but we can read from
188 class TOOLS_DLLPUBLIC SvPersistStream
: public SvStream
190 SvClassManager
& rClassMgr
;
192 PersistBaseMap aPTable
; // reversed pointer and key
193 SvPersistUIdx aPUIdx
;
194 sal_uIntPtr nStartIdx
;
195 const SvPersistStream
* pRefStm
;
198 virtual sal_uIntPtr
GetData( void* pData
, sal_uIntPtr nSize
);
199 virtual sal_uIntPtr
PutData( const void* pData
, sal_uIntPtr nSize
);
200 virtual sal_uIntPtr
SeekPos( sal_uIntPtr nPos
);
201 virtual void FlushData();
204 void WriteObj( sal_uInt8 nHdr
, SvPersistBase
* pObj
);
205 sal_uInt32
ReadObj( SvPersistBase
* & rpObj
, sal_Bool bRegister
);
208 sal_Bool
IsStreamed( SvPersistBase
* pObj
) const
209 { return 0 != GetIndex( pObj
); }
210 virtual void ResetError();
212 SvPersistStream( SvClassManager
&, SvStream
* pStream
,
213 sal_uInt32 nStartIdx
= 1 );
216 void SetStream( SvStream
* pStream
);
217 SvStream
* GetStream() const { return pStm
; }
218 virtual sal_uInt16
IsA() const;
220 SvPersistBase
* GetObject( sal_uIntPtr nIdx
) const;
221 sal_uIntPtr
GetIndex( SvPersistBase
* ) const;
223 void SetContextFlags( sal_uInt32 n
) { nFlags
= n
; }
224 sal_uInt32
GetContextFlags() const { return nFlags
; }
226 static void WriteCompressed( SvStream
& rStm
, sal_uInt32 nVal
);
227 static sal_uInt32
ReadCompressed( SvStream
& rStm
);
229 sal_uInt32
WriteDummyLen();
230 void WriteLen( sal_uInt32 nLenPos
);
231 sal_uInt32
ReadLen( sal_uInt32
* pTestPos
);
233 SvPersistStream
& WritePointer( SvPersistBase
* pObj
);
234 SvPersistStream
& ReadPointer( SvPersistBase
* & rpObj
);
235 TOOLS_DLLPUBLIC
friend SvPersistStream
& operator << (SvPersistStream
&, SvPersistBase
*);
236 TOOLS_DLLPUBLIC
friend SvPersistStream
& operator >> (SvPersistStream
&, SvPersistBase
* &);
238 // Objects maintain their IDs while storing and loading to/from stream
239 friend SvStream
& operator >> ( SvStream
&, SvPersistStream
& );
240 friend SvStream
& operator << ( SvStream
&, SvPersistStream
& );
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */