1 /***************************************************************************
2 Copyright 2006 David Nolden <david.nolden.kdevelop@art-master.de>
3 ***************************************************************************/
5 /***************************************************************************
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 ***************************************************************************/
14 #ifndef SERIALIZATION_UTILS_H
15 #define SERIALIZATION_UTILS_H
17 ///Unfortunately it seems that boost doesn't like the things that Qt syntactically does to the xml-syntax.
18 ///It fails to load logically same documents when they come from QDom, so we embed the data as simple text into the xml-document.
20 #define XML_USE_TEXT_ARCHIVE
22 #ifdef XML_USE_TEXT_ARCHIVE
23 #include <boost/archive/polymorphic_text_iarchive.hpp>
24 #include <boost/archive/polymorphic_text_oarchive.hpp>
25 typedef boost::archive::polymorphic_text_iarchive XmlIArchive
;
26 typedef boost::archive::polymorphic_text_oarchive XmlOArchive
;
28 #include <boost/archive/polymorphic_xml_iarchive.hpp>
29 #include <boost/archive/polymorphic_xml_oarchive.hpp>
30 typedef boost::archive::polymorphic_xml_iarchive XmlIArchive
;
31 typedef boost::archive::polymorphic_xml_oarchive XmlOArchive
;
34 #include <boost/serialization/extended_type_info_typeid.hpp>
35 #include <boost/serialization/base_object.hpp>
36 //#include <boost/serialization/extended_type_info.hpp>
37 #include <boost/serialization/utility.hpp>
38 #include <boost/serialization/list.hpp>
39 #include <boost/serialization/vector.hpp>
40 #include <boost/serialization/level.hpp>
44 #include <QDomDocument>
46 #include <QTextStream>
48 ///All these functions throw QString's as error-descriptions on error
51 void xmlTextDeserialize( QString
& buffer
, Type
& object
) throw( QString
) {
52 QByteArray bufLocal
= buffer
.toUtf8().data();
53 std::istringstream str
;
54 str
.str( bufLocal
.data() );
56 XmlIArchive
arch( str
);
58 } catch ( std::exception
& exc
) {
59 throw QString( "exception occurred while deserialization: " ) + exc
.what();
64 void xmlTextSerialize( QString
& buffer
, Type
& object
) throw( QString
) {
67 std::ostringstream str
;
70 XmlOArchive
arch( str
);
73 } catch ( std::exception
& exc
) {
74 throw QString( "exception occurred while serialization: " ) + exc
.what();
77 buffer
= str
.str().c_str();
81 void xmlDeserialize( QDomNode
& node
, Type
& object
) throw( QString
) {
82 QDomNode header
= node
.namedItem( "header" );
83 ///QDomNode type = node.namedItem( "doctype" );
84 QDomNode serializationNode
= node
.namedItem( "boost_serialization" );
85 if ( header
.isNull() )
86 throw QString( "document does not contain header" );
87 /* if( type.isNull() )
88 throw QString( "document does not contain type" );*/
89 if ( serializationNode
.isNull() )
90 throw QString( "document does not contain serialization-node" );
91 if ( !header
.isElement() && !header
.isText() )
92 throw QString( "header is no element" );
93 /*if( type.isElement() && !type.isText() )
94 throw QString( "type is no element" );*/
95 /* if( serializationNode.isElement() )
96 throw QString( "serialization-node is no element" );*/
98 QDomNode headerText
= header
;
99 if ( !header
.isText() )
100 headerText
= header
.firstChild();
101 /*QDomNode typeText = type;
103 typeText = header.firstChild();*/
105 if ( headerText
.isNull() /*|| typeText.isNull()*/ || !headerText
.isText() /*|| !typeText.isText()*/ )
106 throw QString( "header- or type-elements have wrong type" );
110 QTextStream
stream( &text
);
111 serializationNode
.save( stream
, 1 );
114 //text = headerText.data() +"\n" + typeText.data() + "\n" + text;
115 if ( text
.isEmpty() )
116 throw QString( "text is empty" );
117 text
= "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n <!DOCTYPE boost_serialization>\n" + text
;
118 cout
<< "deserializing: " << endl
<< text
.toUtf8().data();
119 xmlTextDeserialize( text
, object
);
122 template <class Type
>
123 void xmlSerialize( QDomNode
& container
, Type
& object
, const QString
& nodeName
= "" ) throw( QString
) {
125 xmlTextSerialize( buf
, object
);
127 throw QString( "serialized buffer is empty" );
129 QDomDocument
doc( nodeName
);
130 doc
.setContent( buf
);
132 QDomNode header
= doc
.firstChild();
133 QDomDocumentType type
= doc
.doctype();
134 QString headerText
, typeText
;
136 cout
<< "full serialized data: \n" << buf
.toUtf8().data() << endl
;
139 QTextStream
stream( &headerText
);
140 header
.save( stream
, 1 );
143 QTextStream
stream( &typeText
);
144 type
.save( stream
, 1 );
147 QDomDocument domDoc
= container
.ownerDocument();
148 QDomElement storedHeaderNode
= domDoc
.createElement( "header" );
149 QDomElement storedTypeNode
= domDoc
.createElement( "doctype" );
150 storedHeaderNode
.appendChild( domDoc
.createTextNode( headerText
+ "\n" + typeText
) );
151 storedTypeNode
.appendChild( domDoc
.createTextNode( typeText
) );
153 container
.appendChild( storedHeaderNode
);
154 // container.appendChild( storedTypeNode );
155 container
.appendChild( doc
.firstChildElement().cloneNode() ); ///While serialization, there is one "boost_serialization"-child created. Only that should be exported.
158 /**This deletes the previous element of the given name, and replaces it with a new one containing the data.
159 *the given object-type must already be a name-value-pair(see NVP(...) )
160 * Errors are thrown as QString
163 template <class Type
>
164 void xmlSerializeToElementItem( QDomElement
* el
, const QString
& item
, Type
& object
) throw( QString
) {
165 QDomDocument domDoc
= el
->ownerDocument();
167 QDomNode containerNode
= el
->namedItem( item
);
169 if ( !containerNode
.isNull() )
170 el
->removeChild( containerNode
);
173 QDomElement containerNode
= domDoc
.createElement( item
);
174 el
->appendChild( containerNode
);
176 #ifdef XML_USE_TEXT_ARCHIVE
179 xmlTextSerialize( buffer
, object
);
180 if ( buffer
.isEmpty() )
181 throw QString( "deserialized buffer is empty" );
182 containerNode
.appendChild( domDoc
.createTextNode( buffer
) );
185 xmlSerialize( containerNode
, object
, item
);
190 /**is invoked the same way as xmlSerializeToElementItem(...)
191 * Errors are thrown as QString
194 template <class Type
>
195 void xmlDeserializeFromElementItem( const QDomElement
* el
, const QString
& item
, Type
& object
) throw( QString
) {
196 QDomNode containerNode
= el
->namedItem( item
);
197 if ( containerNode
.isNull() )
198 throw "container-node of name \"" + item
+ "\" is missing";
200 #ifdef XML_USE_TEXT_ARCHIVE
202 QDomNode node
= containerNode
.firstChild();
204 throw "the container-node of name \"" + item
+ "\" does not contain the correct data";
208 QDomText textNode
= node
.toText();
209 if ( textNode
.isNull() )
210 throw "the container-node of name \"" + item
+ "\" does not contain the correct data";
212 data
= textNode
.data();
213 if ( data
.isEmpty() )
214 throw QString( "stored data is empty" );
215 xmlTextDeserialize( data
, object
);
218 xmlDeserialize( containerNode
, object
);
226 // kate: space-indent on; indent-width 2; tab-width 2; replace-tabs on