My favorites | Sign in
Project Home Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/********************************************\
*
* Sire - Molecular Simulation Framework
*
* Copyright (C) 2009 Christopher Woods
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For full details of the license please see the COPYING file
* that should have come with this distribution.
*
* You can contact the authors via the developer's mailing list
* at http://siremol.org
*
\*********************************************/

#ifndef SIREN_XMLSTREAM_H
#define SIREN_XMLSTREAM_H

#include <QDomDocument>
#include <QDomElement>
#include <QStack>

#include "stream.h"

SIREN_BEGIN_HEADER

namespace Siren
{

/** This is a stream that saves/loads data to XML

@author Christopher Woods
*/
class SIREN_EXPORT XMLStream : public ImplementsHandle<XMLStream,Stream>
{
public:
XMLStream();

XMLStream(QIODevice *d);
XMLStream(QString *s, QIODevice::OpenMode mode);
XMLStream(const QString &s);

XMLStream(const XMLStream &other);

~XMLStream();

XMLStream& operator=(const XMLStream &other);

bool operator==(const XMLStream &other) const;
bool operator!=(const XMLStream &other) const;

XMLStream& operator&(bool &b);

XMLStream& operator&(qint8 &i);
XMLStream& operator&(quint8 &i);
XMLStream& operator&(quint16 &i);
XMLStream& operator&(qint16 &i);
XMLStream& operator&(quint32 &i);
XMLStream& operator&(qint32 &i);
XMLStream& operator&(quint64 &i);
XMLStream& operator&(qint64 &i);

XMLStream& operator&(float &f);
XMLStream& operator&(double &f);

uint hashCode() const;
QString toString() const;

protected:
void startItem(const QString &type_name);
int startArray(const QString &type_name, int count);
int startSet(const QString &type_name, int count);
int startMap(const QString &key_type, const QString &value_type,
int count, bool allow_duplicates);

void nextData(const char *data_name);
void nextBase();

void nextIndex(int i);

void nextEntry();

void nextKey();
void nextValue();

void endItem(const QString &type_name);
void endArray(const QString &type_name);
void endSet(const QString &type_name);
void endMap(const QString &key_type, const QString &value_type);

int readReference();
void createReference(int id);

void startTarget(int id);
void endTarget(int id);

int readStringReference();
void createStringReference(int id);

QString readString(int id);
void writeString(int id, const QString &text);

int readBlobReference();
void createBlobReference(int id);

QByteArray readBlob(int id);
void writeBlob(int id, const QByteArray &blob);

int readClassID(const QString &class_name, int &version);
void writeClassID(const QString &class_name, int id, int version);

QString peekNextType();

int readMagic();
void writeMagic(int magic);

private:
void throwLoadingError(const QString &error,
int error_line, int error_column) const;

template<class T>
void stream_integer(const QString &type, T &value);

template<class T>
void stream_float(const QString &type, T &value);

int startContainer(const QString &container_tag,
const QString &type_name, int count);

void endContainer(const QString &container_tag, const QString &type_name);

class Document
{
public:
Document();
~Document();

void initialiseDocument(bool is_saving);

void assertAttributeExists(QDomElement &tag,
const QString &value,
const QString &attribute);

void corrupted_data(const QString &error_string, QDomElement element);

void pushStack();
void popStack();

void startTarget(int id, bool is_saving);
void endTarget(int id);

void writeString(int id, const QString &string);
QString readString(int id);

void writeBlob(int id, const QByteArray &blob);
QByteArray readBlob(int id);

QDomElement createChild(const QString &tag_name);
QDomElement getChild(const QString &tag_name);

void startChild(QDomElement &child);
void endChild();

void startContainer(QDomElement &container);
void endContainer();

int getIntAttribute(QDomElement &element, const QString &attribute);

void createReference(QString tag_name, int id);
int readReference(QString tag_name);

int readClassID(const QString &class_name, int &version);
void writeClassID(const QString &class_name, int id, int version);

/** The DOM for the XML document being streamed */
QDomDocument dom;

/** The document root for this document */
QDomElement document_root;

/** The current element being processed - new elements
are created as children of this element */
QDomElement current_element;

/** A stack of elements - this allows us to temparily
jump to another part of the document - this is necessary
when we write shared objects to a <target> */
QStack<QDomElement> current_element_stack;

/** A stack of map entries that are still waiting for values
to be streamed */
QStack<QDomElement> entries_awaiting_values;

/** The current entry in a container being iterated over */
QDomElement container_iterator;

/** A stack of entries of containers being read */
QStack<QDomElement> container_iterator_stack;

/** The next item to be streamed must have the name 'next_name' */
QString next_name;
/** The next item to be streamed must have the index 'next_index' */
QString next_index;

/** The IO device to which this XML document will be written */
QIODevice *device;
/** The string to which this XML document will be written */
QString *string;

/** The version number of the Siren XML format */
int sirenml_version;

/** If true, then the next item is a base class */
bool next_is_base;

/** If true, then the next item is an entry in a set */
bool next_is_entry;

/** If true, then the next item is a key in a map */
bool next_is_key;

/** If true, then the next item is a value in a map */
bool next_is_value;

private:
QDomElement findTarget(const QString &targets, int id,
const QString &target, const QString &id_tag);

bool foundChild(QDomElement &element);

void clearNextState();

void missingChildError(const QString &tag_name, QString err=QString::null);

void assertCurrentIsContainer(QString container);
};

/** The document containing the XML */
boost::shared_ptr<Document> xml;
};

}

Q_DECLARE_METATYPE( Siren::XMLStream )

SIREN_EXPOSE_CLASS( Siren::XMLStream )

SIREN_END_HEADER

#endif

Change log

r1108 by chryswoods on Nov 25, 2009   Diff
I've updated the metatype system so that
it works fully for Primitive and Handle
types.
Now Number and String work (and
.getClass() works for them too!)

The only test failures from sirentest are
Logger, DataStream and XMLStream, who all
complain that I haven't yet written unit
tests for them!

Go to: 
Sign in to write a code review

Older revisions

r1104 by chryswoods on Nov 22, 2009   Diff
I've got the XML streaming class
almost working - the file
test/Siren/xmlstream.py demonstrates
it - it saves a few objects, but has
problems loading them back up
...
r1103 by chryswoods on Nov 21, 2009   Diff
I am making progress writing the
XMLStream class...

Siren is broken

r1102 by chryswoods on Nov 20, 2009   Diff
I've got Siren compiled and linked,
and have got (most) of the python
wrappers working.
The code works, to an extent, but
there are quite a few problems and
...
All revisions of this file

File info

Size: 8027 bytes, 263 lines
Powered by Google Project Hosting