Don't keep compiling/run if something failed.
[kdevelopdvcssupport.git] / plugins / teamwork / serializationutils.h
blob9c01ad465ffddc9a8d03bfe3ab9c049947a65dca
1 /***************************************************************************
2 Copyright 2006 David Nolden <david.nolden.kdevelop@art-master.de>
3 ***************************************************************************/
5 /***************************************************************************
6 * *
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. *
11 * *
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;
27 #else
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;
32 #endif
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>
41 #include "nvp.h"
43 #include <QString>
44 #include <QDomDocument>
45 #include <QDomNode>
46 #include <QTextStream>
48 ///All these functions throw QString's as error-descriptions on error
50 template <class Type>
51 void xmlTextDeserialize( QString& buffer, Type& object ) throw( QString ) {
52 QByteArray bufLocal = buffer.toUtf8().data();
53 std::istringstream str;
54 str.str( bufLocal.data() );
55 try {
56 XmlIArchive arch( str );
57 arch & object;
58 } catch ( std::exception & exc ) {
59 throw QString( "exception occurred while deserialization: " ) + exc.what();
63 template <class Type>
64 void xmlTextSerialize( QString& buffer, Type& object ) throw( QString ) {
65 buffer.clear();
67 std::ostringstream str;
69 try {
70 XmlOArchive arch( str );
72 arch & object;
73 } catch ( std::exception & exc ) {
74 throw QString( "exception occurred while serialization: " ) + exc.what();
77 buffer = str.str().c_str();
80 template <class Type>
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;
102 if( !type.isText() )
103 typeText = header.firstChild();*/
105 if ( headerText.isNull() /*|| typeText.isNull()*/ || !headerText.isText() /*|| !typeText.isText()*/ )
106 throw QString( "header- or type-elements have wrong type" );
108 QString text;
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 ) {
124 QString buf;
125 xmlTextSerialize( buf, object );
126 if ( buf.isEmpty() )
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
178 QString buffer;
179 xmlTextSerialize( buffer, object );
180 if ( buffer.isEmpty() )
181 throw QString( "deserialized buffer is empty" );
182 containerNode.appendChild( domDoc.createTextNode( buffer ) );
183 #else
185 xmlSerialize( containerNode, object, item );
187 #endif
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();
203 if ( node.isNull() )
204 throw "the container-node of name \"" + item + "\" does not contain the correct data";
206 QString 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 );
216 #else
218 xmlDeserialize( containerNode, object );
220 #endif
224 #endif
226 // kate: space-indent on; indent-width 2; tab-width 2; replace-tabs on