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

@@ -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);
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -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)