QMCPACK
libxmldefs.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #ifndef ESTOOLS_OHMMS_LIBXML_DEF_H
18 #define ESTOOLS_OHMMS_LIBXML_DEF_H
19 #include <iostream>
20 #include <sstream>
21 #include <iomanip>
22 #include <iosfwd>
23 #include <string>
24 #include <vector>
25 #include <algorithm>
26 #include "XMLParsingString.h"
27 #include "string_utils.h"
28 
29 /**\file libxmldefs.h
30  *\brief A collection of put/get functions to read from or write to a xmlNode defined in libxml2.
31  *
32  */
33 /*!\brief assign a value from a node. Use specialization for classes.
34  *\param a reference to a value to be assigned
35  *\param cur current node
36  *\return true if successful
37  *
38  *If operator >> is implemented for a class, no specialization is required.
39  *For instance, no specialization is necessary for intrinsic data types.
40  *A simle class that reads the temperature from a xml node
41  *
42  <parameter name="temperature" condition="K">100</parameter>
43  *
44  \code
45  struct A: public OhmmsElementBase {
46 
47  double Temperature;
48 
49  bool put(xmlNodePtr cur) {
50  putContent(Temperature,cur);
51  }
52  };
53  \endcode
54  */
55 
56 /** xmlChar* to char* cast
57  * certainly not typesafe but at this interface between libxml and c++
58  * well it beats c style casts and might be more correct than a reinterpret.
59  *
60  * This is fine with UTF-8 bytes going into a std::string.
61  */
62 inline char* castXMLCharToChar(xmlChar* c) { return static_cast<char*>(static_cast<void*>(c)); }
63 
64 /** unsafe const xmlChar* to const char* cast
65  */
66 inline const char* castXMLCharToChar(const xmlChar* c) { return static_cast<const char*>(static_cast<const void*>(c)); }
67 
68 /** unsafe char* to xmlChar* cast
69  */
70 inline xmlChar* castCharToXMLChar(char* c) { return static_cast<xmlChar*>(static_cast<void*>(c)); }
71 
72 /** unsafe const char* to const xmlChar* cast
73  */
74 inline const xmlChar* castCharToXMLChar(const char* c)
75 {
76  return static_cast<const xmlChar*>(static_cast<const void*>(c));
77 }
78 
79 std::string getNodeName(xmlNodePtr cur);
80 
81 /** replaces a's value with the first "element" in the "string"
82  * returned by XMLNodeString{cur}.
83  * but if that string is empty then then doesn't touch a.
84  * See documentation of the interaction between operator>>
85  * streams and the FormattedInputFunction requirement in the c++ standard.
86  */
87 template<class T>
88 bool putContent(T& a, xmlNodePtr cur)
89 {
90  std::istringstream stream(XMLNodeString{cur});
91  stream >> a;
92  return !stream.fail();
93 }
94 
95 template<class IT>
96 bool putContent(IT first, IT last, xmlNodePtr cur)
97 {
98  std::istringstream stream(XMLNodeString{cur});
99  bool success = true;
100  while (success && first != last)
101  {
102  stream >> *first++;
103  success = !stream.fail();
104  }
105  return success;
106 }
107 
108 /*!\fn bool getContent(const T& a, xmlNodePtr cur)
109  *\brief write a value to a node.
110  *\param a reference to a value to be copied to a node
111  *\param cur current node to which a content is copied
112  *\return true if successful
113  *
114  *Use specialization for classes. If operator << is implemented for a
115  *class, no specialization is required. For instance, no
116  *specialization is necessary for intrinsic data types.
117  */
118 template<class T>
119 bool getContent(const T& a, xmlNodePtr cur)
120 {
121  if (cur->children == NULL)
122  return false;
123  std::stringstream s;
124  s.setf(std::ios::scientific, std::ios::floatfield);
125  s.precision(10);
126  s << a;
127  const XMLNodeString node_string(s.str());
128  node_string.setXMLNodeContent(cur);
129  return true;
130 }
131 
132 /** assign std::vector<T> from a node. Create a temporary vector and make assignment.
133  *\param a reference std::vector<T>
134  *\param cur current node to which a content is copied
135  *\return true if successful
136  *
137  *Specialization for std::vector<T> with data types T with operator >>,
138  *e.g., std::vector<double>
139  */
140 template<class T>
141 inline bool putContent(std::vector<T>& a, const xmlNodePtr cur)
142 {
143  if (cur->children == NULL)
144  return false;
145  a = qmcplusplus::convertStrToVec<T>(XMLNodeString{cur});
146  return true;
147 }
148 
149 /** write std::vector<T> to node. Each element is separated by a space.
150  *\param a reference std::vector<T>
151  *\param cur current node to which a content is copied
152  *\return true if successful
153  *
154  *Specialization for std::vector<T> with data types T with operator <<.
155  *This function is only for testing/debugging and will not perform
156  *well for large vectors. Use HDF5 library for the real data.
157  */
158 template<class T>
159 inline bool getContent(const std::vector<T>& a, xmlNodePtr cur)
160 {
161  std::stringstream s;
162  s.precision(10);
163  for (int i = 0; i < a.size(); i++)
164  s << ' ' << a[i];
165  const XMLNodeString node_string(s.str());
166  node_string.setXMLNodeContent(cur);
167  return true;
168 }
169 
170 /** process through all the children of an XML element
171  * F is a lambda or functor
172  * void F/[](const std::string& cname, const xmlNodePtr element) {...}
173  */
174 template<class F>
175 void processChildren(const xmlNodePtr cur, const F& functor)
176 {
177  xmlNodePtr element = cur->children;
178  while (element != NULL)
179  {
180  std::string cname((const char*)(element->name));
181  functor(cname, element);
182  element = element->next;
183  }
184 }
185 
186 #endif
std::string getNodeName(xmlNodePtr cur)
Definition: libxmldefs.cpp:15
XMLNodeString convert xmlNode contents into a std::string XMLAttrString convert one xmlNode attribute...
void setXMLNodeContent(xmlNodePtr cur) const
write a string to an xmlNode
char * castXMLCharToChar(xmlChar *c)
assign a value from a node. Use specialization for classes.
Definition: libxmldefs.h:62
bool putContent(T &a, xmlNodePtr cur)
replaces a&#39;s value with the first "element" in the "string" returned by XMLNodeString{cur}.
Definition: libxmldefs.h:88
convert xmlNode contents into a std::string
bool getContent(const T &a, xmlNodePtr cur)
write a value to a node.
Definition: libxmldefs.h:119
void processChildren(const xmlNodePtr cur, const F &functor)
process through all the children of an XML element F is a lambda or functor void F/[](const std::stri...
Definition: libxmldefs.h:175
xmlChar * castCharToXMLChar(char *c)
unsafe char* to xmlChar* cast
Definition: libxmldefs.h:70