]>
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
));
52 printf("info.object (dup %s)\n", info
.object
->GetClassInfo()->GetClassName());
57 data_s
.WriteString(info
.object
->GetClassInfo()->GetClassName());
58 printf("info.object (%s)\n", info
.object
->GetClassInfo()->GetClassName());
60 data_s
.WriteString(TAG_EMPTY_OBJECT
);
61 printf("info.object (NULL)\n");
65 data_s
.WriteString(GetObjectName(info
.object
));
67 // I assume an object will not have millions of children
68 // Hmmm ... it could have (for example wxGrid)
69 data_s
.Write32(info
.children
.Number());
72 void wxObjectOutputStream::AddChild(wxObject
*obj
)
74 wxObjectStreamInfo
*info
;
79 info
= new wxObjectStreamInfo
;
81 if (m_saved_objs
.Member(obj
) != NULL
) {
82 info
->duplicate
= TRUE
;
84 info
->duplicate
= FALSE
;
85 m_saved_objs
.Append(obj
);
88 info
->duplicate
= FALSE
;
92 info
->parent
= m_current_info
; // Not useful here.
93 m_current_info
->n_children
++;
94 m_current_info
->children
.Append(info
);
97 void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo
*info
)
101 m_current_info
= info
;
102 // First stage: get children of obj
103 if (info
->object
&& !info
->duplicate
)
104 info
->object
->StoreObject(*this);
106 // Prepare and write the sub-entry about the child obj.
107 WriteObjectDef(*info
);
109 node
= info
->children
.First();
112 ProcessObjectDef((wxObjectStreamInfo
*)node
->Data());
117 void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo
*info
)
119 wxNode
*node
= info
->children
.First();
121 m_current_info
= info
;
123 if (info
->object
&& !info
->duplicate
)
124 info
->object
->StoreObject(*this);
127 ProcessObjectData((wxObjectStreamInfo
*)node
->Data());
132 bool wxObjectOutputStream::SaveObject(wxObject
& obj
)
134 wxObjectStreamInfo info
;
145 info
.duplicate
= FALSE
;
146 ProcessObjectDef(&info
);
149 ProcessObjectData(&info
);
151 info
.children
.Clear();
152 m_saved_objs
.Clear();
159 // ----------------------------------------------------------------------------
160 // wxObjectInputStream
161 // ----------------------------------------------------------------------------
163 wxObjectInputStream::wxObjectInputStream(wxInputStream
& s
)
164 : wxFilterInputStream(s
)
168 wxObject
*wxObjectInputStream::SolveName(const wxString
& name
) const
170 wxNode
*node
= m_solver
.First();
171 wxObjectStreamInfo
*info
;
174 info
= (wxObjectStreamInfo
*)node
->Data();
175 if (info
->object_name
== name
)
180 return (wxObject
*) NULL
;
183 wxObject
*wxObjectInputStream::GetParent() const
185 if (!m_current_info
->parent
)
186 return (wxObject
*) NULL
;
188 return m_current_info
->parent
->object
;
191 wxObject
*wxObjectInputStream::GetChild()
193 wxObject
*obj
= GetChild(0);
195 m_current_info
->children_removed
++;
200 wxObject
*wxObjectInputStream::GetChild(int no
) const
203 wxObjectStreamInfo
*info
;
205 if (m_current_info
->children_removed
>= m_current_info
->n_children
)
206 return (wxObject
*) NULL
;
208 node
= m_current_info
->children
.Nth(m_current_info
->children_removed
+no
);
211 return (wxObject
*) NULL
;
213 info
= (wxObjectStreamInfo
*)node
->Data();
218 void wxObjectInputStream::RemoveChildren(int nb
)
220 m_current_info
->children_removed
+= nb
;
223 bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo
*info
)
225 wxDataInputStream
data_s(*this);
226 char sig
[WXOBJ_BEG_LEN
+1];
229 Read(sig
, WXOBJ_BEG_LEN
);
230 sig
[WXOBJ_BEG_LEN
] = 0;
231 if (wxString(sig
) != WXOBJ_BEGIN
)
234 class_name
= data_s
.ReadString();
235 info
->children_removed
= 0;
236 info
->n_children
= 0;
238 if (class_name
== TAG_EMPTY_OBJECT
)
239 info
->object
= (wxObject
*) NULL
;
240 else if (class_name
== TAG_DUPLICATE_OBJECT
) {
241 info
->object_name
= data_s
.ReadString();
242 info
->object
= SolveName(info
->object_name
);
244 info
->object_name
= data_s
.ReadString();
245 info
->object
= wxCreateDynamicObject( WXSTRINGCAST class_name
);
246 info
->n_children
= data_s
.Read32();
251 wxObjectStreamInfo
*wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo
*parent
)
253 wxObjectStreamInfo
*info
, *c_info
;
256 info
= new wxObjectStreamInfo
;
257 info
->parent
= parent
;
258 info
->children
.DeleteContents(TRUE
);
260 m_solver
.Append(info
);
262 if (!ReadObjectDef(info
))
263 return (wxObjectStreamInfo
*) NULL
;
265 for (c
=0;c
<info
->n_children
;c
++) {
266 c_info
= ProcessObjectDef(info
);
268 return (wxObjectStreamInfo
*) NULL
;
269 info
->children
.Append(c_info
);
275 void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo
*info
)
277 wxNode
*node
= info
->children
.First();
279 m_current_info
= info
;
282 info
->object
->LoadObject(*this);
284 ProcessObjectData((wxObjectStreamInfo
*)node
->Data());
288 m_current_info
= info
;
292 info
->object
->LoadObject(*this);
293 m_secondcall
= FALSE
;
297 wxObject
*wxObjectInputStream::LoadObject()
299 wxObjectStreamInfo
*info
;
302 info
= ProcessObjectDef((wxObjectStreamInfo
*) NULL
);
304 return (wxObject
*) NULL
;
305 ProcessObjectData(info
);
307 object
= info
->object
;
309 delete info
; // It's magic ! The whole tree is destroyed.