xref: /trunk/main/tools/inc/tools/pstm.hxx (revision 8b851043)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _PSTM_HXX
24 #define _PSTM_HXX
25 
26 #include <hash_map>
27 #include "tools/toolsdllapi.h"
28 
29 #ifndef _TABLE_HXX
30 #include <tools/table.hxx>
31 #endif
32 
33 #ifndef _INQIDX_HXX
34 #include <tools/unqidx.hxx>
35 #endif
36 #include <tools/ref.hxx>
37 #include <tools/rtti.hxx>
38 #include <tools/stream.hxx>
39 
40 #define ERRCODE_IO_NOFACTORY ERRCODE_IO_WRONGFORMAT
41 
42 /*************************************************************************
43 *************************************************************************/
44 class SvPersistBase;
45 typedef void * (*SvCreateInstancePersist)( SvPersistBase ** );
46 #define SV_CLASS_REGISTER( Class )                          \
47     Register( Class::StaticClassId(), Class::CreateInstance )
48 
49 class TOOLS_DLLPUBLIC SvClassManager
50 {
51     typedef std::hash_map< sal_uInt16, SvCreateInstancePersist > Map;
52     Map aAssocTable;
53 public:
54     void        Register( sal_uInt16 nClassId, SvCreateInstancePersist pFunc );
55     SvCreateInstancePersist Get( sal_uInt16 nClassId );
56 };
57 
58 /************************** S v R t t i B a s e **************************/
59 
60 class TOOLS_DLLPUBLIC SvRttiBase : public SvRefBase
61 {
62 public:
63             TYPEINFO();
64 };
65 SV_DECL_IMPL_REF(SvRttiBase)
66 
67 /*************************************************************************/
68 #define SV_DECL_PERSIST( Class, CLASS_ID )                          \
69     TYPEINFO();                                                     \
70     static  sal_uInt16  StaticClassId() { return CLASS_ID; }            \
71     static  void *  CreateInstance( SvPersistBase ** ppBase );      \
72     friend SvPersistStream& operator >> ( SvPersistStream & rStm,   \
73                                           Class *& rpObj);          \
74     virtual sal_uInt16  GetClassId() const;                             \
75     virtual void    Load( SvPersistStream & );                      \
76     virtual void    Save( SvPersistStream & );
77 
78 #define SV_DECL_PERSIST1( Class, Super1, CLASS_ID )                 \
79     SV_DECL_PERSIST( Class, CLASS_ID )
80 
81 #define PRV_SV_IMPL_PERSIST( Class )                                \
82     void *          Class::CreateInstance( SvPersistBase ** ppBase )\
83                     {                                               \
84                         Class * p = new Class();                    \
85                         *ppBase = p;                                \
86                         return p;                                   \
87                     }                                               \
88     sal_uInt16          Class::GetClassId() const                       \
89                     { return StaticClassId(); }                     \
90     SvPersistStream& operator >> (SvPersistStream & rStm, Class *& rpObj)\
91                     {                                               \
92                         SvPersistBase * pObj;                       \
93                         rStm >> pObj;                               \
94                         rpObj = PTR_CAST( Class, pObj );            \
95                         return rStm;                                \
96                     }
97 
98 #define SV_IMPL_PERSIST( Class )                                    \
99     TYPEINIT0( Class )                                              \
100     PRV_SV_IMPL_PERSIST( Class )
101 
102 #define SV_IMPL_PERSIST1( Class, Super1 )                           \
103     TYPEINIT1( Class, Super1 )                                      \
104     PRV_SV_IMPL_PERSIST( Class )
105 
106 /*************************************************************************/
107 class SvPersistStream;
108 class SvPersistBase : public SvRttiBase
109 {
110 public:
111     virtual sal_uInt16  GetClassId() const = 0;
112     virtual void    Load( SvPersistStream & ) = 0;
113     virtual void    Save( SvPersistStream & ) = 0;
114     TOOLS_DLLPUBLIC friend SvPersistStream& operator >> ( SvPersistStream & rStm,
115                                           SvPersistBase *& rpObj );
116 };
117 SV_DECL_IMPL_REF(SvPersistBase)
118 
119 /*************************************************************************/
120 // Damit die Liste, anders benannt wird
121 typedef SvPersistBase SuperSvPersistBase;
122 SV_DECL_REF_LIST_VISIBILITY(SuperSvPersistBase,SuperSvPersistBase*,TOOLS_DLLPUBLIC)
123 SV_IMPL_REF_LIST(SuperSvPersistBase,SuperSvPersistBase*)
124 
125 class TOOLS_DLLPUBLIC SvPersistBaseMemberList : public SuperSvPersistBaseMemberList
126 {
127 public:
128     SvPersistBaseMemberList();
129     SvPersistBaseMemberList(sal_uInt16 nInitSz, sal_uInt16 nResize );
130 
131     void   WriteObjects( SvPersistStream &, sal_Bool bOnlyStreamedObj = sal_False ) const;
132     TOOLS_DLLPUBLIC friend SvPersistStream& operator << (SvPersistStream &, const SvPersistBaseMemberList &);
133     TOOLS_DLLPUBLIC friend SvPersistStream& operator >> (SvPersistStream &, SvPersistBaseMemberList &);
134 };
135 
136 /*************************************************************************/
137 #define SV_DECL_PERSIST_LIST(ClassName,EntryName)\
138 class ClassName##MemberList : public SvPersistBaseMemberList\
139 {\
140 public:\
141     PRV_SV_DECL_MEMBER_LIST(ClassName,EntryName)\
142 };
143 
144 #define SV_IMPL_PERSIST_LIST(ClassName,EntryName)\
145     PRV_SV_IMPL_MEMBER_LIST(ClassName,EntryName,SvPersistBaseMemberList)
146 
147 #define SV_DECL_IMPL_PERSIST_LIST(ClassName,EntryName)\
148 SV_DECL_PERSIST_LIST(ClassName,EntryName)\
149 SV_IMPL_PERSIST_LIST(ClassName,EntryName)
150 
151 //#if 0 // _SOLAR__PRIVATE
152 DECLARE_UNIQUEINDEX( SvPersistUIdx,SvPersistBase *)
153 //#else
154 //typedef UniqueIndex SvPersistUIdx;
155 //#endif
156 
157 //=========================================================================
158 class SvStream;
159 class TOOLS_DLLPUBLIC SvPersistStream : public SvStream
160 /*	[Beschreibung]
161 
162 	Mit dieser Klasse k"onnen Laufzeit Objektstrukturen gespeichert
163 	und geladen werden. Es m"ussen immer alle beteiligten Objekte
164 	gespeichert oder geladen werden. Um die Objekte automatisch
165 	laden zu k"onnen, wird eine Factory f"ur jede Klasse von Objekten,
166 	die im Stream vorkommen k"onnen, ben"otigt. Die Liste aller Klassen
167 	wird in einem <SvClassManager> Objekt gespeichert und dem
168  	SvPersistStream "ubergeben, wenn er erzeugt wird.
169 	Weiterhin wird die M"oglichkeit geboten sal_uInt32 Werte komprimiert
170 	zu schreiben und zu lesen (<SvPersistStream::WriteCompressed>,
171 	<SvPersistStream::ReadCompressed>).
172 	Es gibt auch die drei Hilfsmethoden <SvPersistStream::WriteDummyLen>,
173 	<SvPersistStream::WriteLen> und <SvPersistStream::ReadLen> um eine
174 	L"ange vor das Objekt zu schreiben.
175 
176 	[Beispiel]
177 
178 	Ein konkretes Beispiel ist im Konstruktor beschrieben.
179 	Objekt A verweist auf B, dieses auf C und das wieder auf A.
180 	C verweist auf D.
181 
182 	Die Reihenfolge beim Speichern und Laden ist egal, sie muss nur
183 	gleich sein:
184 	Speichern:		Laden:
185 	A,B,C,D			A,B,C,D     richtig
186 	B,A,C,D			B,A,C,D     richtig
187 	C,A,B,D			A,B,C,D     falsch
188 	A,B,C,D			A,B,C		falsch
189 
190 	[Anmerkung]
191 
192 	Das Dateiformat zwischen DBG_UTIL und !DBG_UTIL ist unterschiedlich,
193 	kann aber von beiden Versionen gelesen werden.
194 */
195 {
196     SvClassManager &        rClassMgr;
197     SvStream *              pStm;
198     Table                   aPTable; // Pointer und Key gedreht
199     SvPersistUIdx           aPUIdx;
200     sal_uIntPtr                   nStartIdx;
201     const SvPersistStream * pRefStm;
202     sal_uInt32                  nFlags;
203 
204     virtual sal_uIntPtr       GetData( void* pData, sal_uIntPtr nSize );
205     virtual sal_uIntPtr       PutData( const void* pData, sal_uIntPtr nSize );
206     virtual sal_uIntPtr       SeekPos( sal_uIntPtr nPos );
207     virtual void        FlushData();
208 protected:
209     sal_uIntPtr               GetCurMaxIndex( const SvPersistUIdx & ) const;
GetCurMaxIndex() const210     sal_uIntPtr               GetCurMaxIndex() const
211                         { return GetCurMaxIndex( aPUIdx ); }
212 
213     void				WriteObj( sal_uInt8 nHdr, SvPersistBase * pObj );
214     sal_uInt32  			ReadObj( SvPersistBase * & rpObj,
215 								sal_Bool bRegister );
216 public:
IsStreamed(SvPersistBase * pObj) const217     sal_Bool                IsStreamed( SvPersistBase * pObj ) const
218                         { return 0 != GetIndex( pObj ); }
219     virtual void        ResetError();
220 
221                         SvPersistStream( SvClassManager &, SvStream * pStream,
222                                          sal_uInt32 nStartIdx = 1 );
223                         SvPersistStream( SvClassManager &, SvStream * pStream,
224                                          const SvPersistStream & rPersStm );
225                         ~SvPersistStream();
226 
227 	void                SetStream( SvStream * pStream );
GetStream() const228     SvStream *			GetStream() const { return pStm; }
229 	virtual sal_uInt16		IsA() const;
230 
231     SvPersistBase *     GetObject( sal_uIntPtr nIdx ) const;
232     sal_uIntPtr               GetIndex( SvPersistBase * ) const;
233 
SetContextFlags(sal_uInt32 n)234     void                SetContextFlags( sal_uInt32 n ) { nFlags = n; }
GetContextFlags() const235     sal_uInt32              GetContextFlags() const { return nFlags; }
236 
237     static void         WriteCompressed( SvStream & rStm, sal_uInt32 nVal );
238     static sal_uInt32       ReadCompressed( SvStream & rStm );
239 
240     sal_uInt32              WriteDummyLen();
241     void                WriteLen( sal_uInt32 nLenPos );
242     sal_uInt32              ReadLen( sal_uInt32 * pTestPos );
243 
244     SvPersistStream&    WritePointer( SvPersistBase * pObj );
245     SvPersistStream&    ReadPointer( SvPersistBase * & rpObj );
246     TOOLS_DLLPUBLIC friend SvPersistStream& operator << (SvPersistStream &, SvPersistBase *);
247     TOOLS_DLLPUBLIC friend SvPersistStream& operator >> (SvPersistStream &, SvPersistBase * &);
248 
249 						// Objekte halten ihre Id's w"ahrend geladen und
250 						// gespeichert werden.
251     friend SvStream& operator >> ( SvStream &, SvPersistStream & );
252     friend SvStream& operator << ( SvStream &, SvPersistStream & );
253     sal_uIntPtr   			InsertObj( SvPersistBase * );
254     sal_uIntPtr   			RemoveObj( SvPersistBase * );
255 };
256 
257 #endif // _PSTM_HXX
258