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
// char const *
template<> const wxTypeInfo* wxGetTypeInfo( char const ** )
{
assert(0) ;
static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ;
return &s_typeInfo ;
}
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) ;
}
WX_ILLEGAL_TYPE_SPECIALIZATION( char const * )
WX_ILLEGAL_TYPE_SPECIALIZATION( char * )
WX_ILLEGAL_TYPE_SPECIALIZATION( unsigned char * )
WX_ILLEGAL_TYPE_SPECIALIZATION( int * )
WX_ILLEGAL_TYPE_SPECIALIZATION( bool * )
WX_ILLEGAL_TYPE_SPECIALIZATION( long * )
WX_ILLEGAL_TYPE_SPECIALIZATION( wxString * )
// ----------------------------------------------------------------------------
// 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
// for all built-in types

View File

@@ -21,8 +21,8 @@
#endif
#ifndef WX_PRECOMP
#include "wx/hash.h"
#include "wx/object.h"
#include "wx/hash.h"
#include "wx/object.h"
#endif
#include "wx/xml/xml.h"
@@ -37,41 +37,102 @@
using namespace std ;
// ----------------------------------------------------------------------------
// streaming xml out
// ----------------------------------------------------------------------------
struct wxWriter::wxWriterInternal
{
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() ;
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() ) ;
if ( cti )
{
const wxClassInfo* pci = cti->GetClassInfo() ;
wxxVariant value = pi->GetAccessor()->GetProperty(obj) ;
WriteComponent( pci->VariantToInstance( value ) , pci , onode , pi->GetName() , nextId ,
( cti->GetKind() == wxT_OBJECT ) , writtenObjects ) ;
if ( persister->BeforeWritePropertyAsObject( obj , ci , pi , value ) )
{
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
{
const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
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
{
wxXmlNode *pnode;
pnode = new wxXmlNode(wxXML_ELEMENT_NODE, pi->GetName() );
pi->GetAccessor()->WriteValue(pnode, obj ) ;
onode->AddChild(pnode);
wxxVariant value = pi->GetAccessor()->GetProperty(obj) ;
if ( persister->BeforeWriteProperty( obj , ci , pi , value ) )
{
DoWriteProperty( obj , ci , pi , value ) ;
}
}
}
}
@@ -80,54 +141,143 @@ void WriteComponentProperties( wxObject* obj , const wxClassInfo* ci , wxXmlNode
const wxClassInfo** parents = ci->GetParents() ;
for ( int i = 0 ; parents[i] ; ++ i )
{
WriteComponentProperties( obj , parents[i] , onode , nextId , writtenObjects , writtenProperties ) ;
WriteAllProperties( obj , parents[i] , persister , data ) ;
}
}
/*
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 wxWriter::GetObjectID(const wxObject *obj)
{
int nextid = 0 ; // 0 is the root element
map< wxObject* , int > writtenobjects ;
WriteComponent( obj , classInfo, parent, nodeName , nextid , false , writtenobjects ) ;
if ( !IsObjectKnown( obj ) )
return wxInvalidObjectID ;
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;
onode = new wxXmlNode(wxXML_ELEMENT_NODE, nodeName);
onode = new wxXmlNode(wxXML_ELEMENT_NODE, name);
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");
onode->AddChild(nullnode);
}
else
{
// if we have already written this object, just insert an id
// 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) ;
}
onode->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID ) );
}
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
as properties are always sought by typeinfo over all levels
and create params are always toplevel class only
Reading components has not to be extended for components
as properties are always sought by typeinfo over all levels
and create params are always toplevel class only
*/
int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
@@ -337,7 +487,7 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
wxPropertyAccessor *accessor )
{
return accessor->ReadValue(node) ;
return accessor->ReadValue(wxXmlGetContentFromNode( node ) ) ;
}
int wxXmlReader::ReadObject(wxDepersister *callbacks)
@@ -483,7 +633,7 @@ struct wxCodeDepersister::wxCodeDepersisterInternal
} ;
wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
: m_fp(out)
: m_fp(out)
{
m_data = new wxCodeDepersisterInternal ;
}