]>
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 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "objstrm.h"
15 #include "wx/object.h"
16 #include "wx/objstrm.h"
17 #include "wx/datstrm.h"
19 #define WXOBJ_BEGIN "OBEGIN"
20 #define WXOBJ_BEG_LEN 6
22 #define TAG_EMPTY_OBJECT "NULL"
23 #define TAG_DUPLICATE_OBJECT "DUPLIC"
25 // ----------------------------------------------------------------------------
26 // wxObjectOutputStream
27 // ----------------------------------------------------------------------------
29 wxObjectOutputStream::wxObjectOutputStream(wxOutputStream
& s
)
30 : wxFilterOutputStream(s
)
35 wxString
wxObjectOutputStream::GetObjectName(wxObject
*obj
)
39 name
.Printf("%x", (unsigned long)obj
);
43 void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo
& info
)
45 wxDataOutputStream
data_s(*this);
47 Write(WXOBJ_BEGIN
, WXOBJ_BEG_LEN
);
50 data_s
.WriteString(TAG_DUPLICATE_OBJECT
);
51 data_s
.WriteString(GetObjectName(info
.object
));
56 data_s
.WriteString(info
.object
->GetClassInfo()->GetClassName());
58 data_s
.WriteString(TAG_EMPTY_OBJECT
);
62 data_s
.WriteString(GetObjectName(info
.object
));
64 // I assume an object will not have millions of children
65 // Hmmm ... it could have (for example wxGrid)
66 data_s
.Write32(info
.children
.Number());
69 void wxObjectOutputStream::AddChild(wxObject
*obj
)
71 wxObjectStreamInfo
*info
;
76 info
= new wxObjectStreamInfo
;
78 if (m_saved_objs
.Member(obj
) != NULL
) {
79 info
->duplicate
= TRUE
;
81 info
->duplicate
= FALSE
;
82 m_saved_objs
.Append(obj
);
85 info
->duplicate
= FALSE
;
89 info
->parent
= m_current_info
; // Not useful here.
90 m_current_info
->n_children
++;
91 m_current_info
->children
.Append(info
);
94 void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo
*info
)
98 m_current_info
= info
;
99 // First stage: get children of obj
100 if (info
->object
&& !info
->duplicate
)
101 info
->object
->StoreObject(*this);
103 // Prepare and write the sub-entry about the child obj.
104 WriteObjectDef(*info
);
106 node
= info
->children
.First();
109 ProcessObjectDef((wxObjectStreamInfo
*)node
->Data());
114 void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo
*info
)
116 wxNode
*node
= info
->children
.First();
118 m_current_info
= info
;
120 if (info
->object
&& !info
->duplicate
)
121 info
->object
->StoreObject(*this);
124 ProcessObjectData((wxObjectStreamInfo
*)node
->Data());
129 bool wxObjectOutputStream::SaveObject(wxObject
& obj
)
131 wxObjectStreamInfo info
;
142 info
.duplicate
= FALSE
;
143 ProcessObjectDef(&info
);
146 ProcessObjectData(&info
);
148 info
.children
.Clear();
149 m_saved_objs
.Clear();
156 // ----------------------------------------------------------------------------
157 // wxObjectInputStream
158 // ----------------------------------------------------------------------------
160 wxObjectInputStream::wxObjectInputStream(wxInputStream
& s
)
161 : wxFilterInputStream(s
)
165 wxObject
*wxObjectInputStream::SolveName(const wxString
& name
) const
167 wxNode
*node
= m_solver
.First();
168 wxObjectStreamInfo
*info
;
171 info
= (wxObjectStreamInfo
*)node
->Data();
172 if (info
->object_name
== name
)
177 return (wxObject
*) NULL
;
180 wxObject
*wxObjectInputStream::GetParent() const
182 if (!m_current_info
->parent
)
183 return (wxObject
*) NULL
;
185 return m_current_info
->parent
->object
;
188 wxObject
*wxObjectInputStream::GetChild()
190 wxObject
*obj
= GetChild(0);
192 m_current_info
->children_removed
++;
197 wxObject
*wxObjectInputStream::GetChild(int no
) const
200 wxObjectStreamInfo
*info
;
202 if (m_current_info
->children_removed
>= m_current_info
->n_children
)
203 return (wxObject
*) NULL
;
205 node
= m_current_info
->children
.Nth(m_current_info
->children_removed
+no
);
208 return (wxObject
*) NULL
;
210 info
= (wxObjectStreamInfo
*)node
->Data();
215 void wxObjectInputStream::RemoveChildren(int nb
)
217 m_current_info
->children_removed
+= nb
;
220 bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo
*info
)
222 wxDataInputStream
data_s(*this);
223 char sig
[WXOBJ_BEG_LEN
+1];
226 Read(sig
, WXOBJ_BEG_LEN
);
227 sig
[WXOBJ_BEG_LEN
] = 0;
228 if (wxString(sig
) != WXOBJ_BEGIN
)
231 class_name
= data_s
.ReadString();
232 info
->children_removed
= 0;
234 if (class_name
== TAG_EMPTY_OBJECT
)
235 info
->object
= (wxObject
*) NULL
;
236 else if (class_name
== TAG_DUPLICATE_OBJECT
) {
237 info
->object_name
= data_s
.ReadString();
238 info
->object
= SolveName(info
->object_name
);
239 info
->n_children
= 0;
241 info
->object_name
= data_s
.ReadString();
242 info
->object
= wxCreateDynamicObject( WXSTRINGCAST class_name
);
243 info
->n_children
= data_s
.Read32();
248 wxObjectStreamInfo
*wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo
*parent
)
250 wxObjectStreamInfo
*info
, *c_info
;
253 info
= new wxObjectStreamInfo
;
254 info
->parent
= parent
;
255 info
->children
.DeleteContents(TRUE
);
257 m_solver
.Append(info
);
259 if (!ReadObjectDef(info
))
260 return (wxObjectStreamInfo
*) NULL
;
262 for (c
=0;c
<info
->n_children
;c
++) {
263 c_info
= ProcessObjectDef(info
);
265 return (wxObjectStreamInfo
*) NULL
;
266 info
->children
.Append(c_info
);
272 void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo
*info
)
274 wxNode
*node
= info
->children
.First();
276 m_current_info
= info
;
279 info
->object
->LoadObject(*this);
281 ProcessObjectData((wxObjectStreamInfo
*)node
->Data());
285 m_current_info
= info
;
289 info
->object
->LoadObject(*this);
290 m_secondcall
= FALSE
;
294 wxObject
*wxObjectInputStream::LoadObject()
296 wxObjectStreamInfo
*info
;
299 info
= ProcessObjectDef((wxObjectStreamInfo
*) NULL
);
301 return (wxObject
*) NULL
;
302 ProcessObjectData(info
);
304 object
= info
->object
;
306 delete info
; // It's magic ! The whole tree is destroyed.