]> git.saurik.com Git - wxWidgets.git/blame - src/common/objstrm.cpp
static wxFile::Access() added
[wxWidgets.git] / src / common / objstrm.cpp
CommitLineData
6d44bf31
GL
1/////////////////////////////////////////////////////////////////////////////
2// Name: objstrm.cpp
3// Purpose: wxObjectStream classes
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 16/07/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Guilhem Lavaux
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11#ifdef __GNUG__
12#pragma implementation "objstrm.h"
13#endif
14
15#include "wx/object.h"
16#include "wx/objstrm.h"
17#include "wx/datstrm.h"
18
19#define WXOBJ_BEGIN "OBEGIN"
20#define WXOBJ_BEG_LEN 6
21
7a4b9130
GL
22#define TAG_EMPTY_OBJECT "NULL"
23
6d44bf31
GL
24// ----------------------------------------------------------------------------
25// wxObjectOutputStream
26// ----------------------------------------------------------------------------
27
28wxObjectOutputStream::wxObjectOutputStream(wxOutputStream& s)
29 : wxFilterOutputStream(s)
30{
31 m_saving = FALSE;
32}
33
34wxString wxObjectOutputStream::GetObjectName(wxObject *obj)
35{
36 wxString name;
37
38 name.Printf("%x", (unsigned long)obj);
39 return name;
40}
41
42void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo& info)
43{
44 wxDataOutputStream data_s(*this);
45
46 Write(WXOBJ_BEGIN, WXOBJ_BEG_LEN);
7a4b9130
GL
47
48 if (info.object) {
49 data_s.WriteString(info.object->GetClassInfo()->GetClassName());
50 } else {
51 data_s.WriteString(TAG_EMPTY_OBJECT);
52 }
53
6d44bf31 54 data_s.WriteString(GetObjectName(info.object));
7a4b9130 55
6d44bf31
GL
56 // I assume an object will not have millions of children
57 data_s.Write8(info.children.Number());
58}
59
1eac776c 60void wxObjectOutputStream::AddChild(wxObject *obj)
6d44bf31
GL
61{
62 wxObjectStreamInfo *info;
63
64 if (!FirstStage())
65 return;
66
67 info = new wxObjectStreamInfo;
68 info->n_children = 0;
69 info->object = obj;
7a4b9130 70 info->parent = m_current_info; // Not useful here.
6d44bf31
GL
71 m_current_info->n_children++;
72 m_current_info->children.Append(info);
73}
74
75void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo *info)
76{
77 wxNode *node;
78
79 m_current_info = info;
80 // First stage: get children of obj
7a4b9130
GL
81 if (info->object)
82 info->object->StoreObject(*this);
6d44bf31
GL
83
84 // Prepare and write the sub-entry about the child obj.
85 WriteObjectDef(*info);
86
87 node = info->children.First();
88
89 while (node) {
90 ProcessObjectDef((wxObjectStreamInfo *)node->Data());
91 node = node->Next();
92 }
93}
94
95void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo *info)
96{
97 wxNode *node = info->children.First();
98
99 m_current_info = info;
100
7a4b9130
GL
101 if (info->object)
102 info->object->StoreObject(*this);
6d44bf31
GL
103
104 while (node) {
105 ProcessObjectData((wxObjectStreamInfo *)node->Data());
106 node = node->Next();
107 }
108}
109
110bool wxObjectOutputStream::SaveObject(wxObject& obj)
111{
112 wxObjectStreamInfo info;
113
114 if (m_saving)
115 return FALSE;
116
117 m_saving = TRUE;
118
119 // First stage
120 m_stage = 0;
121 info.object = &obj;
122 info.n_children = 0;
123 ProcessObjectDef(&info);
124
125 m_stage = 1;
126 ProcessObjectData(&info);
127
128 info.children.Clear();
129
130 m_saving = FALSE;
131
132 return TRUE;
133}
134
135// ----------------------------------------------------------------------------
136// wxObjectInputStream
137// ----------------------------------------------------------------------------
138
139wxObjectInputStream::wxObjectInputStream(wxInputStream& s)
140 : wxFilterInputStream(s)
141{
142}
143
144wxObject *wxObjectInputStream::SolveName(const wxString& name) const
145{
146 wxNode *node = m_solver.First();
147 wxObjectStreamInfo *info;
148
149 while (node) {
150 info = (wxObjectStreamInfo *)node->Data();
151 if (info->object_name == name)
152 return info->object;
153
154 node = node->Next();
155 }
156 return NULL;
157}
158
7a4b9130
GL
159wxObject *wxObjectInputStream::GetParent() const
160{
161 if (!m_current_info->parent)
162 return NULL;
163
164 return m_current_info->parent->object;
165}
166
6d44bf31
GL
167wxObject *wxObjectInputStream::GetChild(int no) const
168{
7a4b9130
GL
169 wxNode *node = m_current_info->children.Nth(m_current_info->children_removed+no);
170 wxObjectStreamInfo *info;
171
172 if (!node)
173 return NULL;
174
175 info = (wxObjectStreamInfo *)node->Data();
176
177 return info->object;
178}
179
180void wxObjectInputStream::RemoveChildren(int nb)
181{
182 m_current_info->children_removed += nb;
6d44bf31
GL
183}
184
185bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo *info)
186{
187 wxDataInputStream data_s(*this);
188 char sig[WXOBJ_BEG_LEN+1];
7a4b9130 189 wxString class_name;
6d44bf31
GL
190
191 Read(sig, WXOBJ_BEG_LEN);
192 sig[WXOBJ_BEG_LEN] = 0;
193 if (wxString(sig) != WXOBJ_BEGIN)
194 return FALSE;
7a4b9130
GL
195
196 class_name = data_s.ReadString();
197 printf("class_name = %s\n", WXSTRINGCAST class_name);
198 if (class_name == TAG_EMPTY_OBJECT)
199 info->object = NULL;
200 else
201 info->object = wxCreateDynamicObject( WXSTRINGCAST class_name);
6d44bf31 202 info->object_name = data_s.ReadString();
7a4b9130 203 printf("object_name = %s\n", WXSTRINGCAST info->object_name);
6d44bf31 204 info->n_children = data_s.Read8();
7a4b9130
GL
205 info->children_removed = 0;
206 printf("n_children = %d\n", info->n_children);
6d44bf31
GL
207
208 return TRUE;
209}
210
211wxObjectStreamInfo *wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo *parent)
212{
213 wxObjectStreamInfo *info, *c_info;
214 int c;
215
216 info = new wxObjectStreamInfo;
217 info->parent = parent;
218 info->children.DeleteContents(TRUE);
219
220 m_solver.Append(info);
221
222 if (!ReadObjectDef(info))
223 return NULL;
224
225 for (c=0;c<info->n_children;c++) {
226 c_info = ProcessObjectDef(info);
227 if (!c_info)
228 return NULL;
229 info->children.Append(c_info);
230 }
231
232 return info;
233}
234
235void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo *info)
236{
237 wxNode *node = info->children.First();
238 wxObjectStreamInfo *c_info;
239
240 m_current_info = info;
241
7a4b9130
GL
242 if (info->object)
243 info->object->LoadObject(*this);
6d44bf31 244 while (node) {
7a4b9130 245 ProcessObjectData((wxObjectStreamInfo *)node->Data());
6d44bf31
GL
246 node = node->Next();
247 }
248}
249
250wxObject *wxObjectInputStream::LoadObject()
251{
252 wxObjectStreamInfo *info;
253 wxObject *object;
254
255 info = ProcessObjectDef(NULL);
256 if (!info)
257 return NULL;
258 ProcessObjectData(info);
259
260 object = info->object;
261
262 delete info; // It's magic ! The whole tree is destroyed.
263
264 return object;
265}