]>
git.saurik.com Git - wxWidgets.git/blob - src/common/objstrm.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxObjectStream classes
4 // Author: Guilhem Lavaux
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "objstrm.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
23 #if wxUSE_SERIAL && wxUSE_STREAMS
25 #include "wx/object.h"
26 #include "wx/objstrm.h"
27 #include "wx/datstrm.h"
29 #define WXOBJ_BEGIN "OBEGIN"
30 #define WXOBJ_BEG_LEN 6
32 #define TAG_EMPTY_OBJECT "NULL"
33 #define TAG_DUPLICATE_OBJECT "DUPLIC"
35 // ----------------------------------------------------------------------------
36 // wxObjectOutputStream
37 // ----------------------------------------------------------------------------
39 wxObjectOutputStream::wxObjectOutputStream(wxOutputStream
& s
)
40 : wxFilterOutputStream(s
)
45 wxString
wxObjectOutputStream::GetObjectName(wxObject
*obj
)
49 name
.Printf(wxT("%x"), (unsigned long)obj
);
53 void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo
& info
)
55 wxDataOutputStream
data_s(*this);
57 Write(WXOBJ_BEGIN
, WXOBJ_BEG_LEN
);
60 data_s
.WriteString(TAG_DUPLICATE_OBJECT
);
61 data_s
.WriteString(GetObjectName(info
.object
));
62 wxPrintf(wxT("info.object (dup %s)\n"), info
.object
->GetClassInfo()->GetClassName());
67 data_s
.WriteString(info
.object
->GetClassInfo()->GetClassName());
68 wxPrintf(wxT("info.object (%s)\n"), info
.object
->GetClassInfo()->GetClassName());
70 data_s
.WriteString(TAG_EMPTY_OBJECT
);
71 wxPrintf(wxT("info.object (NULL)\n"));
75 data_s
.WriteString(GetObjectName(info
.object
));
77 // I assume an object will not have millions of children
78 // Hmmm ... it could have (for example wxGrid)
79 data_s
.Write32(info
.children
.Number());
82 void wxObjectOutputStream::AddChild(wxObject
*obj
)
84 wxObjectStreamInfo
*info
;
89 info
= new wxObjectStreamInfo
;
91 if (m_saved_objs
.Member(obj
) != NULL
) {
92 info
->duplicate
= TRUE
;
94 info
->duplicate
= FALSE
;
95 m_saved_objs
.Append(obj
);
98 info
->duplicate
= FALSE
;
100 info
->n_children
= 0;
102 info
->parent
= m_current_info
; // Not useful here.
103 m_current_info
->n_children
++;
104 m_current_info
->children
.Append(info
);
107 void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo
*info
)
111 m_current_info
= info
;
112 // First stage: get children of obj
113 if (info
->object
&& !info
->duplicate
)
114 info
->object
->StoreObject(*this);
116 // Prepare and write the sub-entry about the child obj.
117 WriteObjectDef(*info
);
119 node
= info
->children
.First();
122 ProcessObjectDef((wxObjectStreamInfo
*)node
->Data());
127 void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo
*info
)
129 wxNode
*node
= info
->children
.First();
131 m_current_info
= info
;
133 if (info
->object
&& !info
->duplicate
)
134 info
->object
->StoreObject(*this);
137 ProcessObjectData((wxObjectStreamInfo
*)node
->Data());
142 bool wxObjectOutputStream::SaveObject(wxObject
& obj
)
144 wxObjectStreamInfo info
;
155 info
.duplicate
= FALSE
;
156 ProcessObjectDef(&info
);
159 ProcessObjectData(&info
);
161 info
.children
.Clear();
162 m_saved_objs
.Clear();
169 // ----------------------------------------------------------------------------
170 // wxObjectInputStream
171 // ----------------------------------------------------------------------------
173 wxObjectInputStream::wxObjectInputStream(wxInputStream
& s
)
174 : wxFilterInputStream(s
)
176 m_secondcall
= FALSE
;
179 wxObject
*wxObjectInputStream::SolveName(const wxString
& name
) const
181 wxNode
*node
= m_solver
.First();
182 wxObjectStreamInfo
*info
;
185 info
= (wxObjectStreamInfo
*)node
->Data();
186 if (info
->object_name
== name
)
191 return (wxObject
*) NULL
;
194 wxObject
*wxObjectInputStream::GetParent() const
196 if (!m_current_info
->parent
)
197 return (wxObject
*) NULL
;
199 return m_current_info
->parent
->object
;
202 wxObject
*wxObjectInputStream::GetChild()
204 wxObject
*obj
= GetChild(0);
206 m_current_info
->children_removed
++;
211 wxObject
*wxObjectInputStream::GetChild(int no
) const
214 wxObjectStreamInfo
*info
;
216 if (m_current_info
->children_removed
>= m_current_info
->n_children
)
217 return (wxObject
*) NULL
;
219 node
= m_current_info
->children
.Nth(m_current_info
->children_removed
+no
);
222 return (wxObject
*) NULL
;
224 info
= (wxObjectStreamInfo
*)node
->Data();
229 void wxObjectInputStream::RemoveChildren(int nb
)
231 m_current_info
->children_removed
+= nb
;
234 bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo
*info
)
236 wxDataInputStream
data_s(*this);
237 char sig
[WXOBJ_BEG_LEN
+1];
240 Read(sig
, WXOBJ_BEG_LEN
);
241 sig
[WXOBJ_BEG_LEN
] = 0;
242 if (wxString(sig
) != WXOBJ_BEGIN
)
245 class_name
= data_s
.ReadString();
246 info
->children_removed
= 0;
247 info
->n_children
= 0;
249 if (class_name
== TAG_EMPTY_OBJECT
)
250 info
->object
= (wxObject
*) NULL
;
251 else if (class_name
== TAG_DUPLICATE_OBJECT
) {
252 info
->object_name
= data_s
.ReadString();
253 info
->object
= SolveName(info
->object_name
);
255 info
->object_name
= data_s
.ReadString();
256 info
->object
= wxCreateDynamicObject( WXSTRINGCAST class_name
);
257 info
->n_children
= data_s
.Read32();
262 wxObjectStreamInfo
*wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo
*parent
)
264 wxObjectStreamInfo
*info
, *c_info
;
267 info
= new wxObjectStreamInfo
;
268 info
->parent
= parent
;
269 info
->children
.DeleteContents(TRUE
);
271 m_solver
.Append(info
);
273 if (!ReadObjectDef(info
))
274 return (wxObjectStreamInfo
*) NULL
;
276 for (c
=0;c
<info
->n_children
;c
++) {
277 c_info
= ProcessObjectDef(info
);
279 return (wxObjectStreamInfo
*) NULL
;
280 info
->children
.Append(c_info
);
286 void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo
*info
)
288 wxNode
*node
= info
->children
.First();
290 m_current_info
= info
;
293 info
->object
->LoadObject(*this);
295 ProcessObjectData((wxObjectStreamInfo
*)node
->Data());
299 m_current_info
= info
;
303 info
->object
->LoadObject(*this);
304 m_secondcall
= FALSE
;
308 wxObject
*wxObjectInputStream::LoadObject()
310 wxObjectStreamInfo
*info
;
313 info
= ProcessObjectDef((wxObjectStreamInfo
*) NULL
);
315 return (wxObject
*) NULL
;
316 ProcessObjectData(info
);
318 object
= info
->object
;
320 delete info
; // It's magic ! The whole tree is destroyed.
325 #endif // wxUSE_SERIAL && wxUSE_STREAMS