X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6d44bf31a6f0b4a261280e57842bbd53b5e26cd5..ee7841ab1340f9be2470c73ea632cc9aaa8290d3:/src/common/objstrm.cpp diff --git a/src/common/objstrm.cpp b/src/common/objstrm.cpp index 1d2b01d01a..e0156b200d 100644 --- a/src/common/objstrm.cpp +++ b/src/common/objstrm.cpp @@ -8,10 +8,20 @@ // Copyright: (c) 1998 Guilhem Lavaux // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// + #ifdef __GNUG__ -#pragma implementation "objstrm.h" + #pragma implementation "objstrm.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop #endif +#if wxUSE_SERIAL && wxUSE_STREAMS + #include "wx/object.h" #include "wx/objstrm.h" #include "wx/datstrm.h" @@ -19,6 +29,9 @@ #define WXOBJ_BEGIN "OBEGIN" #define WXOBJ_BEG_LEN 6 +#define TAG_EMPTY_OBJECT "NULL" +#define TAG_DUPLICATE_OBJECT "DUPLIC" + // ---------------------------------------------------------------------------- // wxObjectOutputStream // ---------------------------------------------------------------------------- @@ -33,7 +46,7 @@ wxString wxObjectOutputStream::GetObjectName(wxObject *obj) { wxString name; - name.Printf("%x", (unsigned long)obj); + name.Printf(wxT("%x"), (unsigned long)obj); return name; } @@ -42,13 +55,31 @@ void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo& info) wxDataOutputStream data_s(*this); Write(WXOBJ_BEGIN, WXOBJ_BEG_LEN); - data_s.WriteString(info.object->GetClassInfo()->GetClassName()); + + if (info.duplicate) { + data_s.WriteString(TAG_DUPLICATE_OBJECT); + data_s.WriteString(GetObjectName(info.object)); + wxPrintf(wxT("info.object (dup %s)\n"), info.object->GetClassInfo()->GetClassName()); + return; + } + + if (info.object) { + data_s.WriteString(info.object->GetClassInfo()->GetClassName()); + wxPrintf(wxT("info.object (%s)\n"), info.object->GetClassInfo()->GetClassName()); + } else { + data_s.WriteString(TAG_EMPTY_OBJECT); + wxPrintf(wxT("info.object (NULL)\n")); + return; + } + data_s.WriteString(GetObjectName(info.object)); + // I assume an object will not have millions of children - data_s.Write8(info.children.Number()); + // Hmmm ... it could have (for example wxGrid) + data_s.Write32(info.children.Number()); } -void wxObjectOutputStream::AddChildren(wxObject *obj) +void wxObjectOutputStream::AddChild(wxObject *obj) { wxObjectStreamInfo *info; @@ -56,9 +87,19 @@ void wxObjectOutputStream::AddChildren(wxObject *obj) return; info = new wxObjectStreamInfo; + + if (m_saved_objs.Member(obj) != NULL) { + info->duplicate = TRUE; + } else { + info->duplicate = FALSE; + m_saved_objs.Append(obj); + } + if (!obj) + info->duplicate = FALSE; + info->n_children = 0; info->object = obj; - info->parent = m_current_info->object; // Not useful here. + info->parent = m_current_info; // Not useful here. m_current_info->n_children++; m_current_info->children.Append(info); } @@ -69,7 +110,8 @@ void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo *info) m_current_info = info; // First stage: get children of obj - info->object->StoreObject(*this); + if (info->object && !info->duplicate) + info->object->StoreObject(*this); // Prepare and write the sub-entry about the child obj. WriteObjectDef(*info); @@ -88,7 +130,8 @@ void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo *info) m_current_info = info; - info->object->StoreObject(*this); + if (info->object && !info->duplicate) + info->object->StoreObject(*this); while (node) { ProcessObjectData((wxObjectStreamInfo *)node->Data()); @@ -109,12 +152,14 @@ bool wxObjectOutputStream::SaveObject(wxObject& obj) m_stage = 0; info.object = &obj; info.n_children = 0; + info.duplicate = FALSE; ProcessObjectDef(&info); m_stage = 1; ProcessObjectData(&info); info.children.Clear(); + m_saved_objs.Clear(); m_saving = FALSE; @@ -128,6 +173,7 @@ bool wxObjectOutputStream::SaveObject(wxObject& obj) wxObjectInputStream::wxObjectInputStream(wxInputStream& s) : wxFilterInputStream(s) { + m_secondcall = FALSE; } wxObject *wxObjectInputStream::SolveName(const wxString& name) const @@ -142,28 +188,74 @@ wxObject *wxObjectInputStream::SolveName(const wxString& name) const node = node->Next(); } - return NULL; + return (wxObject *) NULL; +} + +wxObject *wxObjectInputStream::GetParent() const +{ + if (!m_current_info->parent) + return (wxObject *) NULL; + + return m_current_info->parent->object; +} + +wxObject *wxObjectInputStream::GetChild() +{ + wxObject *obj = GetChild(0); + + m_current_info->children_removed++; + + return obj; } wxObject *wxObjectInputStream::GetChild(int no) const { - return m_current_info->children.Nth(no); + wxNode *node; + wxObjectStreamInfo *info; + + if (m_current_info->children_removed >= m_current_info->n_children) + return (wxObject *) NULL; + + node = m_current_info->children.Nth(m_current_info->children_removed+no); + + if (!node) + return (wxObject *) NULL; + + info = (wxObjectStreamInfo *)node->Data(); + + return info->object; +} + +void wxObjectInputStream::RemoveChildren(int nb) +{ + m_current_info->children_removed += nb; } bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo *info) { wxDataInputStream data_s(*this); char sig[WXOBJ_BEG_LEN+1]; + wxString class_name; Read(sig, WXOBJ_BEG_LEN); sig[WXOBJ_BEG_LEN] = 0; if (wxString(sig) != WXOBJ_BEGIN) return FALSE; - info->object = wxCreateDynamicObject((char *)data_s.ReadString()); - info->object_name = data_s.ReadString(); - info->n_children = data_s.Read8(); - info->children = wxList(); + class_name = data_s.ReadString(); + info->children_removed = 0; + info->n_children = 0; + + if (class_name == TAG_EMPTY_OBJECT) + info->object = (wxObject *) NULL; + else if (class_name == TAG_DUPLICATE_OBJECT) { + info->object_name = data_s.ReadString(); + info->object = SolveName(info->object_name); + } else { + info->object_name = data_s.ReadString(); + info->object = wxCreateDynamicObject( WXSTRINGCAST class_name); + info->n_children = data_s.Read32(); + } return TRUE; } @@ -179,12 +271,12 @@ wxObjectStreamInfo *wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo *pa m_solver.Append(info); if (!ReadObjectDef(info)) - return NULL; + return (wxObjectStreamInfo *) NULL; for (c=0;cn_children;c++) { c_info = ProcessObjectDef(info); if (!c_info) - return NULL; + return (wxObjectStreamInfo *) NULL; info->children.Append(c_info); } @@ -194,16 +286,23 @@ wxObjectStreamInfo *wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo *pa void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo *info) { wxNode *node = info->children.First(); - wxObjectStreamInfo *c_info; m_current_info = info; - info->object->LoadObject(*this); + if (info->object) + info->object->LoadObject(*this); while (node) { - c_info = (wxObjectStreamInfo *)node->Data(); - c_info->object->LoadObject(*this); + ProcessObjectData((wxObjectStreamInfo *)node->Data()); node = node->Next(); } + + m_current_info = info; + + if (info->recall) { + m_secondcall = TRUE; + info->object->LoadObject(*this); + m_secondcall = FALSE; + } } wxObject *wxObjectInputStream::LoadObject() @@ -211,9 +310,9 @@ wxObject *wxObjectInputStream::LoadObject() wxObjectStreamInfo *info; wxObject *object; - info = ProcessObjectDef(NULL); + info = ProcessObjectDef((wxObjectStreamInfo *) NULL); if (!info) - return NULL; + return (wxObject *) NULL; ProcessObjectData(info); object = info->object; @@ -222,3 +321,6 @@ wxObject *wxObjectInputStream::LoadObject() return object; } + +#endif // wxUSE_SERIAL && wxUSE_STREAMS +