]>
git.saurik.com Git - wxWidgets.git/blob - src/common/objstrm.cpp
6f6c6e607f8942ddc02d2b6da1595d64ad29d1f2
   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 // For compilers that support precompilation, includes "wx.h". 
  16 #include "wx/wxprec.h" 
  29 #include "wx/object.h" 
  30 #include "wx/objstrm.h" 
  31 #include "wx/datstrm.h" 
  33 #define WXOBJ_BEGIN "OBEGIN" 
  34 #define WXOBJ_BEG_LEN 6 
  36 #define TAG_EMPTY_OBJECT "NULL" 
  37 #define TAG_DUPLICATE_OBJECT "DUPLIC" 
  39 // ---------------------------------------------------------------------------- 
  40 // wxObjectOutputStream 
  41 // ---------------------------------------------------------------------------- 
  43 wxObjectOutputStream::wxObjectOutputStream(wxOutputStream
& s
) 
  44   : wxFilterOutputStream(s
) 
  49 wxString 
wxObjectOutputStream::GetObjectName(wxObject 
*obj
) 
  53   name
.Printf(_T("%x"), (unsigned long)obj
); 
  57 void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo
& info
) 
  59   wxDataOutputStream 
data_s(*this);  
  61   Write(WXOBJ_BEGIN
, WXOBJ_BEG_LEN
); 
  64     data_s
.WriteString(TAG_DUPLICATE_OBJECT
); 
  65     data_s
.WriteString(GetObjectName(info
.object
)); 
  66     wxPrintf(_T("info.object (dup %s)\n"), info
.object
->GetClassInfo()->GetClassName()); 
  71     data_s
.WriteString(info
.object
->GetClassInfo()->GetClassName()); 
  72     wxPrintf(_T("info.object (%s)\n"), info
.object
->GetClassInfo()->GetClassName()); 
  74     data_s
.WriteString(TAG_EMPTY_OBJECT
); 
  75     wxPrintf(_T("info.object (NULL)\n")); 
  79   data_s
.WriteString(GetObjectName(info
.object
)); 
  81   // I assume an object will not have millions of children 
  82   // Hmmm ... it could have (for example wxGrid) 
  83   data_s
.Write32(info
.children
.Number()); 
  86 void wxObjectOutputStream::AddChild(wxObject 
*obj
) 
  88   wxObjectStreamInfo 
*info
; 
  93   info 
= new wxObjectStreamInfo
; 
  95   if (m_saved_objs
.Member(obj
) != NULL
) { 
  96     info
->duplicate 
= TRUE
; 
  98     info
->duplicate 
= FALSE
; 
  99     m_saved_objs
.Append(obj
); 
 102     info
->duplicate 
= FALSE
; 
 104   info
->n_children 
= 0; 
 106   info
->parent 
= m_current_info
; // Not useful here. 
 107   m_current_info
->n_children
++; 
 108   m_current_info
->children
.Append(info
); 
 111 void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo 
*info
) 
 115   m_current_info 
= info
; 
 116   // First stage: get children of obj 
 117   if (info
->object 
&& !info
->duplicate
) 
 118     info
->object
->StoreObject(*this); 
 120   // Prepare and write the sub-entry about the child obj. 
 121   WriteObjectDef(*info
); 
 123   node 
= info
->children
.First(); 
 126     ProcessObjectDef((wxObjectStreamInfo 
*)node
->Data()); 
 131 void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo 
*info
) 
 133   wxNode 
*node 
= info
->children
.First(); 
 135   m_current_info 
= info
; 
 137   if (info
->object 
&& !info
->duplicate
) 
 138     info
->object
->StoreObject(*this); 
 141     ProcessObjectData((wxObjectStreamInfo 
*)node
->Data()); 
 146 bool wxObjectOutputStream::SaveObject(wxObject
& obj
) 
 148   wxObjectStreamInfo info
; 
 159   info
.duplicate 
= FALSE
; 
 160   ProcessObjectDef(&info
); 
 163   ProcessObjectData(&info
); 
 165   info
.children
.Clear(); 
 166   m_saved_objs
.Clear(); 
 173 // ---------------------------------------------------------------------------- 
 174 // wxObjectInputStream 
 175 // ---------------------------------------------------------------------------- 
 177 wxObjectInputStream::wxObjectInputStream(wxInputStream
& s
) 
 178   : wxFilterInputStream(s
) 
 180   m_secondcall 
= FALSE
; 
 183 wxObject 
*wxObjectInputStream::SolveName(const wxString
& name
) const 
 185   wxNode 
*node 
= m_solver
.First(); 
 186   wxObjectStreamInfo 
*info
; 
 189     info 
= (wxObjectStreamInfo 
*)node
->Data(); 
 190     if (info
->object_name 
== name
) 
 195   return (wxObject 
*) NULL
; 
 198 wxObject 
*wxObjectInputStream::GetParent() const 
 200   if (!m_current_info
->parent
) 
 201     return (wxObject 
*) NULL
; 
 203   return m_current_info
->parent
->object
; 
 206 wxObject 
*wxObjectInputStream::GetChild() 
 208   wxObject 
*obj 
= GetChild(0); 
 210   m_current_info
->children_removed
++; 
 215 wxObject 
*wxObjectInputStream::GetChild(int no
) const 
 218   wxObjectStreamInfo 
*info
; 
 220   if (m_current_info
->children_removed 
>= m_current_info
->n_children
) 
 221     return (wxObject 
*) NULL
; 
 223   node 
= m_current_info
->children
.Nth(m_current_info
->children_removed
+no
); 
 226     return (wxObject 
*) NULL
; 
 228   info 
= (wxObjectStreamInfo 
*)node
->Data(); 
 233 void wxObjectInputStream::RemoveChildren(int nb
) 
 235   m_current_info
->children_removed 
+= nb
; 
 238 bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo 
*info
) 
 240   wxDataInputStream 
data_s(*this); 
 241   char sig
[WXOBJ_BEG_LEN
+1]; 
 244   Read(sig
, WXOBJ_BEG_LEN
); 
 245   sig
[WXOBJ_BEG_LEN
] = 0; 
 246   if (wxString(sig
) != WXOBJ_BEGIN
) 
 249   class_name 
= data_s
.ReadString(); 
 250   info
->children_removed 
= 0; 
 251   info
->n_children 
= 0; 
 253   if (class_name 
== TAG_EMPTY_OBJECT
) 
 254     info
->object 
= (wxObject 
*) NULL
; 
 255   else if (class_name 
== TAG_DUPLICATE_OBJECT
) { 
 256     info
->object_name 
= data_s
.ReadString(); 
 257     info
->object 
= SolveName(info
->object_name
); 
 259     info
->object_name 
= data_s
.ReadString(); 
 260     info
->object 
= wxCreateDynamicObject( WXSTRINGCAST class_name
); 
 261     info
->n_children 
= data_s
.Read32(); 
 266 wxObjectStreamInfo 
*wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo 
*parent
) 
 268   wxObjectStreamInfo 
*info
, *c_info
; 
 271   info 
= new wxObjectStreamInfo
; 
 272   info
->parent 
= parent
; 
 273   info
->children
.DeleteContents(TRUE
); 
 275   m_solver
.Append(info
); 
 277   if (!ReadObjectDef(info
)) 
 278     return (wxObjectStreamInfo 
*) NULL
; 
 280   for (c
=0;c
<info
->n_children
;c
++) { 
 281     c_info 
= ProcessObjectDef(info
); 
 283       return (wxObjectStreamInfo 
*) NULL
; 
 284     info
->children
.Append(c_info
); 
 290 void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo 
*info
) 
 292   wxNode 
*node 
= info
->children
.First(); 
 294   m_current_info 
= info
; 
 297     info
->object
->LoadObject(*this); 
 299     ProcessObjectData((wxObjectStreamInfo 
*)node
->Data()); 
 303   m_current_info 
= info
; 
 307     info
->object
->LoadObject(*this); 
 308     m_secondcall 
= FALSE
; 
 312 wxObject 
*wxObjectInputStream::LoadObject() 
 314   wxObjectStreamInfo 
*info
; 
 317   info 
= ProcessObjectDef((wxObjectStreamInfo 
*) NULL
); 
 319     return (wxObject 
*) NULL
; 
 320   ProcessObjectData(info
); 
 322   object 
= info
->object
; 
 324   delete info
; // It's magic ! The whole tree is destroyed.