Grid 0.7.0
XmlIO.h
Go to the documentation of this file.
1 /*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/serialisation/XmlIO.h
6
7 Copyright (C) 2015
8
9Author: Antonin Portelli <antonin.portelli@me.com>
10Author: Peter Boyle <paboyle@ph.ed.ac.uk>
11Author: paboyle <paboyle@ph.ed.ac.uk>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License along
24 with this program; if not, write to the Free Software Foundation, Inc.,
25 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26
27 See the full license in the file "LICENSE" in the top level distribution directory
28 *************************************************************************************/
29 /* END LEGAL */
30#ifndef GRID_SERIALISATION_XML_READER_H
31#define GRID_SERIALISATION_XML_READER_H
32
33#include <iostream>
34#include <iomanip>
35#include <fstream>
36#include <sstream>
37#include <math.h>
38#include <vector>
39#include <cassert>
40
41#include <Grid/pugixml/pugixml.h>
42#include <Grid/GridCore.h>
43
44namespace Grid
45{
46 void xmlCheckParse(const pugi::xml_parse_result &result, const std::string name);
47
48 class XmlWriter: public Writer<XmlWriter>
49 {
50 public:
51 XmlWriter(const std::string &fileName,std::string toplev = std::string("grid") );
52 virtual ~XmlWriter(void);
53 void push(const std::string &s);
54 void pushXmlString(const std::string &s);
55 void pop(void);
56 template <typename U>
57 void writeDefault(const std::string &s, const U &x);
58 template <typename U>
59 void writeDefault(const std::string &s, const std::vector<U> &x);
60 template <typename U>
61 void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
62 std::string docString(void);
63 std::string string(void);
64 private:
65 const std::string indent_{" "};
66 pugi::xml_document doc_;
67 pugi::xml_node node_;
68 std::string fileName_;
69 };
70
71 class XmlReader: public Reader<XmlReader>
72 {
73 public:
74 XmlReader(const std::string &fileName, const bool isBuffer = false,
75 std::string toplev = std::string("grid") );
76 virtual ~XmlReader(void) = default;
77 bool push(const std::string &s = "");
78 void pop(void);
79 bool nextElement(const std::string &s = "");
80 template <typename U>
81 void readDefault(const std::string &s, U &output);
82 template <typename U> void readDefault(const std::string &s, std::vector<U> &output);
83 template <typename U>
84 void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
85 void readCurrentSubtree(std::string &s);
86
87 private:
88 void checkParse(const pugi::xml_parse_result &result, const std::string name);
89 private:
90 const std::string indent_{" "};
91 pugi::xml_document doc_;
92 pugi::xml_node node_;
93 std::string fileName_;
94 };
95
96 template <>
97 struct isReader< XmlReader > {
98 static const bool value = true;
99 };
100
101 template <>
103 static const bool value = true;
104 };
105
106 // Writer template implementation ////////////////////////////////////////////
107 template <typename U>
108 void XmlWriter::writeDefault(const std::string &s, const U &x)
109 {
110 std::ostringstream os;
111
112 if (this->getPrecision())
113 {
114 os.precision(this->getPrecision());
115 }
116 if (isScientific())
117 {
118 os << std::scientific;
119 }
120 os << std::boolalpha << x;
121 pugi::xml_node leaf = node_.append_child(s.c_str());
122 leaf.append_child(pugi::node_pcdata).set_value(os.str().c_str());
123 }
124
125 template <typename U>
126 void XmlWriter::writeDefault(const std::string &s, const std::vector<U> &x)
127 {
128 push(s);
129 for( auto &u : x )
130 {
131 write("elem", u);
132 }
133 pop();
134 }
135
136 template <typename U>
137 void XmlWriter::writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements)
138 {
139 push(s);
140 size_t count = 1;
141 const int Rank = static_cast<int>( Dimensions.size() );
142 write("rank", Rank );
143 std::vector<size_t> MyIndex( Rank );
144 for( auto d : Dimensions ) {
145 write("dim", d);
146 count *= d;
147 }
148 assert( count == NumElements && "XmlIO : element count doesn't match dimensions" );
149 static const char sName[] = "tensor";
150 for( int i = 0 ; i < Rank ; i++ ) {
151 MyIndex[i] = 0;
152 push(sName);
153 }
154 while (NumElements--) {
155 write("elem", *pDataRowMajor++);
156 int i;
157 for( i = Rank - 1 ; i != -1 && ++MyIndex[i] == Dimensions[i] ; i-- )
158 MyIndex[i] = 0;
159 int Rollover = Rank - 1 - i;
160 for( i = 0 ; i < Rollover ; i++ )
161 pop();
162 for( i = 0 ; NumElements && i < Rollover ; i++ )
163 push(sName);
164 }
165 pop();
166 }
167
168 // Reader template implementation ////////////////////////////////////////////
169 template <> void XmlReader::readDefault(const std::string &s, std::string &output);
170 template <typename U>
171 void XmlReader::readDefault(const std::string &s, U &output)
172 {
173 std::string buf;
174
175 readDefault(s, buf);
176 fromString(output, buf);
177 }
178
179 template <typename U>
180 void XmlReader::readDefault(const std::string &s, std::vector<U> &output)
181 {
182 if (!push(s))
183 {
184 std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
185 std::cout << std::endl;
186 } else {
187 for(unsigned int i = 0; node_.child("elem"); )
188 {
189 output.resize(i + 1);
190 read("elem", output[i++]);
191 node_.child("elem").set_name("elem-done");
192 }
193 pop();
194 }
195 }
196
197 template <typename U>
198 void XmlReader::readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim)
199 {
200 if (!push(s))
201 {
202 std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
203 std::cout << std::endl;
204 } else {
205 static const char sName[] = "tensor";
206 static const char sNameDone[] = "tensor-done";
207 int Rank;
208 read("rank", Rank);
209 dim.resize( Rank );
210 size_t NumElements = 1;
211 for( auto &d : dim )
212 {
213 read("dim", d);
214 node_.child("dim").set_name("dim-done");
215 NumElements *= d;
216 }
217 buf.resize( NumElements );
218 std::vector<size_t> MyIndex( Rank );
219 for( int i = 0 ; i < Rank ; i++ ) {
220 MyIndex[i] = 0;
221 push(sName);
222 }
223
224 for( auto &x : buf )
225 {
226 NumElements--;
227 read("elem", x);
228 node_.child("elem").set_name("elem-done");
229 int i;
230 for( i = Rank - 1 ; i != -1 && ++MyIndex[i] == dim[i] ; i-- )
231 MyIndex[i] = 0;
232 int Rollover = Rank - 1 - i;
233 for( i = 0 ; i < Rollover ; i++ ) {
234 node_.set_name(sNameDone);
235 pop();
236 }
237 for( i = 0 ; NumElements && i < Rollover ; i++ )
238 push(sName);
239 }
240 pop();
241 }
242 }
243}
244#endif
GridLogger GridLogWarning(1, "Warning", GridLogColours, "YELLOW")
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
void fromString(U &output, const std::string &s)
Definition BaseIO.h:518
std::enable_if< std::is_base_of< Serializable, U >::value, void >::type read(const std::string &s, U &output)
Definition BaseIO.h:393
std::enable_if< std::is_base_of< Serializable, U >::value >::type write(const std::string &s, const U &output)
Definition BaseIO.h:260
unsigned int getPrecision(void)
Definition BaseIO.h:366
bool isScientific(void)
Definition BaseIO.h:354
pugi::xml_document doc_
Definition XmlIO.h:91
pugi::xml_node node_
Definition XmlIO.h:92
XmlReader(const std::string &fileName, const bool isBuffer=false, std::string toplev=std::string("grid"))
Definition XmlIO.cc:100
bool push(const std::string &s="")
Definition XmlIO.cc:135
void readCurrentSubtree(std::string &s)
Definition XmlIO.cc:164
void readDefault(const std::string &s, U &output)
Definition XmlIO.h:171
const std::string indent_
Definition XmlIO.h:90
void readMultiDim(const std::string &s, std::vector< U > &buf, std::vector< size_t > &dim)
Definition XmlIO.h:198
void checkParse(const pugi::xml_parse_result &result, const std::string name)
bool nextElement(const std::string &s="")
Definition XmlIO.cc:152
void pop(void)
Definition XmlIO.cc:147
virtual ~XmlReader(void)=default
std::string fileName_
Definition XmlIO.h:93
std::string docString(void)
Definition XmlIO.cc:85
void pop(void)
Definition XmlIO.cc:80
void writeDefault(const std::string &s, const U &x)
Definition XmlIO.h:108
XmlWriter(const std::string &fileName, std::string toplev=std::string("grid"))
Definition XmlIO.cc:45
void writeMultiDim(const std::string &s, const std::vector< size_t > &Dimensions, const U *pDataRowMajor, size_t NumElements)
Definition XmlIO.h:137
virtual ~XmlWriter(void)
Definition XmlIO.cc:55
std::string string(void)
Definition XmlIO.cc:92
std::string fileName_
Definition XmlIO.h:68
void pushXmlString(const std::string &s)
Definition XmlIO.cc:67
pugi::xml_node node_
Definition XmlIO.h:67
void push(const std::string &s)
Definition XmlIO.cc:62
pugi::xml_document doc_
Definition XmlIO.h:66
const std::string indent_
Definition XmlIO.h:65
void xmlCheckParse(const pugi::xml_parse_result &result, const std::string name)
static const bool value
Definition XmlIO.h:98
static const bool value
Definition XmlIO.h:103