xti expansions, streaming code changes

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22711 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2003-08-08 20:51:55 +00:00
parent aa8d7c2f9b
commit 16776ad919
2 changed files with 503 additions and 494 deletions

View File

@@ -166,159 +166,18 @@ template<> const wxTypeInfo* wxGetTypeInfo( wxString * )
// this are compiler induced specialization which are never used anywhere // this are compiler induced specialization which are never used anywhere
// char const * WX_ILLEGAL_TYPE_SPECIALIZATION( char const * )
WX_ILLEGAL_TYPE_SPECIALIZATION( char * )
template<> const wxTypeInfo* wxGetTypeInfo( char const ** ) WX_ILLEGAL_TYPE_SPECIALIZATION( unsigned char * )
{ WX_ILLEGAL_TYPE_SPECIALIZATION( int * )
assert(0) ; WX_ILLEGAL_TYPE_SPECIALIZATION( bool * )
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ; WX_ILLEGAL_TYPE_SPECIALIZATION( long * )
return &s_typeInfo ; WX_ILLEGAL_TYPE_SPECIALIZATION( wxString * )
}
template<> void wxStringReadValue(const wxString & , const char* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , char const * const & )
{
assert(0) ;
}
// char *
template<> const wxTypeInfo* wxGetTypeInfo( char ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
template<> void wxStringReadValue(const wxString & , char* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , char * const & )
{
assert(0) ;
}
// unsigned char *
template<> const wxTypeInfo* wxGetTypeInfo( unsigned char ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
template<> void wxStringReadValue(const wxString & , unsigned char* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , unsigned char * const & )
{
assert(0) ;
}
// int *
template<> const wxTypeInfo* wxGetTypeInfo( int ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
template<> void wxStringReadValue(const wxString & , int* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , int * const & )
{
assert(0) ;
}
// bool *
template<> const wxTypeInfo* wxGetTypeInfo( bool ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
template<> void wxStringReadValue(const wxString & , bool* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , bool * const & )
{
assert(0) ;
}
// long *
template<> const wxTypeInfo* wxGetTypeInfo( long ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
template<> void wxStringReadValue(const wxString & , long* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , long * const & )
{
assert(0) ;
}
// wxString *
template<> const wxTypeInfo* wxGetTypeInfo( wxString ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
template<> void wxStringReadValue(const wxString & , wxString* & )
{
assert(0) ;
}
template<> void wxStringWriteValue(wxString & , wxString * const & )
{
assert(0) ;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// value streaming // value streaming
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// convenience function (avoids including xml headers in users code)
void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
{
node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
}
wxString wxXmlGetContentFromNode( wxXmlNode *node )
{
if ( node->GetChildren() )
return node->GetChildren()->GetContent() ;
else
return wxEmptyString ;
}
// streamer specializations // streamer specializations
// for all built-in types // for all built-in types

View File

@@ -21,8 +21,8 @@
#endif #endif
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/hash.h" #include "wx/hash.h"
#include "wx/object.h" #include "wx/object.h"
#endif #endif
#include "wx/xml/xml.h" #include "wx/xml/xml.h"
@@ -37,41 +37,102 @@
using namespace std ; using namespace std ;
// ---------------------------------------------------------------------------- struct wxWriter::wxWriterInternal
// streaming xml out {
// ---------------------------------------------------------------------------- map< const wxObject* , int > m_writtenObjects ;
int m_nextId ;
} ;
void WriteComponent(wxObject *Object, const wxClassInfo *classInfo, wxXmlNode *parent, const wxString& nodeName , int &nextId, bool embeddedObject, map< wxObject* , int > &writtenObjects ) ; wxWriter::wxWriter()
{
m_data = new wxWriterInternal ;
m_data->m_nextId = 0 ;
}
void WriteComponentProperties( wxObject* obj , const wxClassInfo* ci , wxXmlNode *onode , int &nextId, map< wxObject* , int > &writtenObjects, map< string , int > &writtenProperties) wxWriter::~wxWriter()
{
delete m_data ;
}
struct wxWriter::wxWriterInternalPropertiesData
{
map< string , int > m_writtenProperties ;
} ;
void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , const wxString &name )
{
if ( persister->BeforeWriteObject( object , classInfo , name ) )
{
int oid = m_data->m_nextId++ ;
m_data->m_writtenObjects[object] = oid ;
DoBeginWriteObject( object , classInfo , oid , name ) ;
wxWriterInternalPropertiesData data ;
WriteAllProperties( object , classInfo , persister , &data ) ;
DoEndWriteObject( object , classInfo , oid , name ) ;
}
}
void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data )
{ {
const wxPropertyInfo *pi = ci->GetFirstProperty() ; const wxPropertyInfo *pi = ci->GetFirstProperty() ;
while( pi ) while( pi )
{ {
if ( writtenProperties.find( pi->GetName() ) == writtenProperties.end() ) if ( data->m_writtenProperties.find( pi->GetName() ) == data->m_writtenProperties.end() )
{ {
writtenProperties[ pi->GetName() ] = 1 ; data->m_writtenProperties[ pi->GetName() ] = 1 ;
const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ; const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
if ( cti ) if ( cti )
{ {
const wxClassInfo* pci = cti->GetClassInfo() ; const wxClassInfo* pci = cti->GetClassInfo() ;
wxxVariant value = pi->GetAccessor()->GetProperty(obj) ; wxxVariant value = pi->GetAccessor()->GetProperty(obj) ;
WriteComponent( pci->VariantToInstance( value ) , pci , onode , pi->GetName() , nextId , if ( persister->BeforeWritePropertyAsObject( obj , ci , pi , value ) )
( cti->GetKind() == wxT_OBJECT ) , writtenObjects ) ; {
wxObject *vobj = pci->VariantToInstance( value ) ;
bool embeddedObject = cti->GetKind() == wxT_OBJECT ;
if ( vobj == NULL || IsObjectKnown( vobj ) )
{
DoWriteObjectReference( obj , ci , vobj , pci , GetObjectID(vobj) , pi ) ;
}
else
{
int oid = m_data->m_nextId++ ;
if ( !embeddedObject)
m_data->m_writtenObjects[vobj] = oid ;
DoBeginWriteParamAsObject( obj , ci , vobj , pci , oid , pi ) ;
if ( vobj != NULL )
{
wxWriterInternalPropertiesData data ;
WriteAllProperties( vobj , pci , persister , &data ) ;
}
DoEndWriteParamAsObject( obj , ci , vobj , pci , oid , pi ) ;
}
}
} }
else else
{ {
const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ; const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
if ( dti ) if ( dti )
{ {
// in which form should we stream out these ? const wxObject* sink = NULL ;
const wxHandlerInfo *handler = NULL ;
if ( persister->BeforeWriteDelegate( obj , ci , pi , sink , handler ) )
{
if ( sink != NULL && handler != NULL )
{
wxASSERT_MSG( IsObjectKnown( sink ) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
}
}
} }
else else
{ {
wxXmlNode *pnode; wxxVariant value = pi->GetAccessor()->GetProperty(obj) ;
pnode = new wxXmlNode(wxXML_ELEMENT_NODE, pi->GetName() ); if ( persister->BeforeWriteProperty( obj , ci , pi , value ) )
pi->GetAccessor()->WriteValue(pnode, obj ) ; {
onode->AddChild(pnode); DoWriteProperty( obj , ci , pi , value ) ;
}
} }
} }
} }
@@ -80,54 +141,143 @@ void WriteComponentProperties( wxObject* obj , const wxClassInfo* ci , wxXmlNode
const wxClassInfo** parents = ci->GetParents() ; const wxClassInfo** parents = ci->GetParents() ;
for ( int i = 0 ; parents[i] ; ++ i ) for ( int i = 0 ; parents[i] ; ++ i )
{ {
WriteComponentProperties( obj , parents[i] , onode , nextId , writtenObjects , writtenProperties ) ; WriteAllProperties( obj , parents[i] , persister , data ) ;
} }
} }
/* int wxWriter::GetObjectID(const wxObject *obj)
Writing Components does have to take inheritance into account, that's why we are iterating
over our parents as well
*/
void WriteComponent(wxObject *obj, const wxClassInfo *classInfo, wxXmlNode *parent, const wxString &nodeName)
{ {
int nextid = 0 ; // 0 is the root element if ( !IsObjectKnown( obj ) )
map< wxObject* , int > writtenobjects ; return wxInvalidObjectID ;
WriteComponent( obj , classInfo, parent, nodeName , nextid , false , writtenobjects ) ;
return m_data->m_writtenObjects[obj] ;
} }
void WriteComponent(wxObject *obj, const wxClassInfo *classInfo, wxXmlNode *parent, const wxString& nodeName , int &nextId, bool embeddedObject, map< wxObject* , int > &writtenObjects ) bool wxWriter::IsObjectKnown( const wxObject *obj )
{
return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ;
}
//
// XML Streaming
//
// convenience functions
void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
{
node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
}
wxString wxXmlGetContentFromNode( wxXmlNode *node )
{
if ( node->GetChildren() )
return node->GetChildren()->GetContent() ;
else
return wxEmptyString ;
}
struct wxXmlWriter::wxXmlWriterInternal
{
wxXmlNode *m_root ;
wxXmlNode *m_current ;
vector< wxXmlNode * > m_objectStack ;
} ;
wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode )
{
m_data = new wxXmlWriterInternal() ;
m_data->m_root = rootnode ;
m_data->m_current = rootnode ;
}
wxXmlWriter::~wxXmlWriter()
{
delete m_data ;
}
// start of writing the root object
void wxXmlWriter::DoBeginWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *classInfo, int objectID , const wxString &name )
{ {
map< string , int > writtenProperties ;
wxXmlNode *onode; wxXmlNode *onode;
onode = new wxXmlNode(wxXML_ELEMENT_NODE, name);
onode = new wxXmlNode(wxXML_ELEMENT_NODE, nodeName);
onode->AddProperty(wxString("class"), wxString(classInfo->GetClassName())); onode->AddProperty(wxString("class"), wxString(classInfo->GetClassName()));
if ( obj == NULL ) onode->AddProperty(wxString("id"), wxString::Format( "%d" , objectID ) );
m_data->m_current->AddChild(onode) ;
m_data->m_objectStack.push_back( m_data->m_current ) ;
m_data->m_current = onode ;
}
// end of writing the root object
void wxXmlWriter::DoEndWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *WXUNUSED(classInfo), int WXUNUSED(objectID) , const wxString &WXUNUSED(name) )
{
m_data->m_current = m_data->m_objectStack.back() ;
m_data->m_objectStack.pop_back() ;
}
// writes a property in the stream format
void wxXmlWriter::DoWriteProperty( const wxObject *WXUNUSED(obj), const wxClassInfo* WXUNUSED(classInfo) , const wxPropertyInfo *pi , wxxVariant &value )
{
wxXmlNode *pnode;
pnode = new wxXmlNode(wxXML_ELEMENT_NODE, pi->GetName() );
wxXmlAddContentToNode( pnode ,value.GetAsString() ) ;
m_data->m_current->AddChild(pnode);
}
void wxXmlWriter::DoBeginWriteParamAsObject(const wxObject *WXUNUSED(parentObject), const wxClassInfo *WXUNUSED(parentClassInfo), const wxObject *WXUNUSED(valueObject),
const wxClassInfo *valueObjectClassInfo, int valueObjectID , const wxPropertyInfo *propInfo )
{
wxXmlNode *onode;
onode = new wxXmlNode(wxXML_ELEMENT_NODE, propInfo->GetName());
onode->AddProperty(wxString("class"), wxString(valueObjectClassInfo->GetClassName()));
onode->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID ) );
m_data->m_current->AddChild(onode) ;
m_data->m_objectStack.push_back( m_data->m_current ) ;
m_data->m_current = onode ;
}
// insert an object reference to an already written object
void wxXmlWriter::DoWriteObjectReference(const wxObject *WXUNUSED(parentObject), const wxClassInfo *WXUNUSED(parentClassInfo), const wxObject *valueObject,
const wxClassInfo *valueObjectClassInfo, int valueObjectID , const wxPropertyInfo *propInfo )
{
wxXmlNode *onode;
onode = new wxXmlNode(wxXML_ELEMENT_NODE, propInfo->GetName());
onode->AddProperty(wxString("class"), wxString(valueObjectClassInfo->GetClassName()));
if ( valueObject == NULL )
{ {
wxXmlNode* nullnode = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, "null"); wxXmlNode* nullnode = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, "null");
onode->AddChild(nullnode); onode->AddChild(nullnode);
} }
else else
{ {
// if we have already written this object, just insert an id onode->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID ) );
// embedded objects have to be written out fully always, their address will be reused and is not a valid key
if ( !embeddedObject && (writtenObjects.find( obj ) != writtenObjects.end()) )
{
onode->AddProperty(wxString("id"), wxString::Format( "%d" , writtenObjects[obj] ) );
}
else
{
int id = nextId++ ;
if ( !embeddedObject )
writtenObjects[obj] = id ;
onode->AddProperty(wxString("id"), wxString::Format( "%d" , id ) );
WriteComponentProperties( obj , classInfo , onode , nextId , writtenObjects, writtenProperties) ;
}
} }
parent->AddChild(onode); m_data->m_current->AddChild(onode) ;
}
void wxXmlWriter::DoEndWriteParamAsObject(const wxObject *WXUNUSED(parentObject), const wxClassInfo *WXUNUSED(parentClassInfo), const wxObject *WXUNUSED(valueObject),
const wxClassInfo *WXUNUSED(valueObjectClassInfo), int WXUNUSED(valueObjectID) , const wxPropertyInfo *WXUNUSED(propInfo) )
{
m_data->m_current = m_data->m_objectStack.back() ;
m_data->m_objectStack.pop_back() ;
}
// writes a delegate in the stream format
void wxXmlWriter::DoWriteDelegate( const wxObject *WXUNUSED(object), const wxClassInfo* WXUNUSED(classInfo) , const wxPropertyInfo *pi ,
const wxObject *eventSink, int sinkObjectID , const wxClassInfo* WXUNUSED(eventSinkClassInfo) , const wxHandlerInfo* handlerInfo )
{
if ( eventSink != NULL && handlerInfo != NULL )
{
wxXmlNode *pnode;
pnode = new wxXmlNode(wxXML_ELEMENT_NODE, pi->GetName() );
wxString s ;
s.Printf(wxT("%d.%s"), sinkObjectID , handlerInfo->GetName() ) ;
wxXmlAddContentToNode( pnode ,s ) ;
m_data->m_current->AddChild(pnode);
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -172,9 +322,9 @@ bool wxReader::HasObjectClassInfo( int objectID )
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/* /*
Reading components has not to be extended for components Reading components has not to be extended for components
as properties are always sought by typeinfo over all levels as properties are always sought by typeinfo over all levels
and create params are always toplevel class only and create params are always toplevel class only
*/ */
int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks) int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
@@ -337,7 +487,7 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
wxxVariant wxXmlReader::ReadValue(wxXmlNode *node, wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
wxPropertyAccessor *accessor ) wxPropertyAccessor *accessor )
{ {
return accessor->ReadValue(node) ; return accessor->ReadValue(wxXmlGetContentFromNode( node ) ) ;
} }
int wxXmlReader::ReadObject(wxDepersister *callbacks) int wxXmlReader::ReadObject(wxDepersister *callbacks)
@@ -483,7 +633,7 @@ struct wxCodeDepersister::wxCodeDepersisterInternal
} ; } ;
wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out) wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
: m_fp(out) : m_fp(out)
{ {
m_data = new wxCodeDepersisterInternal ; m_data = new wxCodeDepersisterInternal ;
} }