libfoedus-core
FOEDUS Core Library
externalizable.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Hewlett-Packard Development Company, LP.
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details. You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * HP designates this particular file as subject to the "Classpath" exception
16  * as provided by HP in the LICENSE.txt file that accompanied this code.
17  */
18 #ifndef FOEDUS_EXTERNALIZE_EXTERNALIZABLE_HPP_
19 #define FOEDUS_EXTERNALIZE_EXTERNALIZABLE_HPP_
20 #include <stdint.h>
21 
22 #include <iosfwd>
23 #include <string>
24 #include <vector>
25 
26 #include "foedus/cxx11.hpp"
27 #include "foedus/error_stack.hpp"
30 #include "foedus/fs/fwd.hpp"
31 
32 // forward declarations for tinyxml2. They should provide a header file for this...
33 namespace tinyxml2 {
34  class XMLDocument;
35  class XMLElement;
36  class XMLAttribute;
37  class XMLComment;
38  class XMLNode;
39  class XMLText;
40  class XMLDeclaration;
41  class XMLUnknown;
42  class XMLPrinter;
43 } // namespace tinyxml2
44 
45 namespace foedus {
46 namespace externalize {
60  virtual ErrorStack load(tinyxml2::XMLElement* element) = 0;
61 
72  virtual ErrorStack save(tinyxml2::XMLElement* element) const = 0;
73 
80  virtual const char* get_tag_name() const = 0;
81 
86  virtual void assign(const foedus::externalize::Externalizable *other) = 0;
87 
94  ErrorStack load_from_string(const std::string& xml);
95 
100  void save_to_stream(std::ostream* ptr) const;
101 
108  ErrorStack load_from_file(const fs::Path &path);
109 
118  ErrorStack save_to_file(const fs::Path &path) const;
119 
120  // convenience methods
121  static ErrorStack insert_comment(tinyxml2::XMLElement* element, const std::string& comment);
122  static ErrorStack append_comment(tinyxml2::XMLElement* parent, const std::string& comment);
123  static ErrorStack create_element(tinyxml2::XMLElement* parent, const std::string& name,
124  tinyxml2::XMLElement** out);
125 
129  template <typename T>
130  static ErrorStack add_element(tinyxml2::XMLElement* parent, const std::string& tag,
131  const std::string& comment, T value);
132 
133  template <uint MAXLEN, typename CHAR>
135  tinyxml2::XMLElement* parent,
136  const std::string& tag,
137  const std::string& comment,
139  return add_element< std::string >(parent, tag, comment, value.str());
140  }
141 
143  template <typename T>
144  static ErrorStack add_element(tinyxml2::XMLElement* parent, const std::string& tag,
145  const std::string& comment, const std::vector< T >& value) {
146  if (comment.size() > 0) {
148  tag + " (type=" + assorted::get_pretty_type_name< std::vector< T > >()
149  + "): " + comment));
150  }
151  for (std::size_t i = 0; i < value.size(); ++i) {
152  CHECK_ERROR(add_element(parent, tag, "", value[i]));
153  }
154  return kRetOk;
155  }
156 
158  template <typename ENUM>
159  static ErrorStack add_enum_element(tinyxml2::XMLElement* parent, const std::string& tag,
160  const std::string& comment, ENUM value) {
161  return add_element(parent, tag, comment, static_cast<int64_t>(value));
162  }
163 
165  static ErrorStack add_child_element(tinyxml2::XMLElement* parent, const std::string& tag,
166  const std::string& comment, const Externalizable& child);
167 
171  template <typename T>
172  static ErrorStack get_element(tinyxml2::XMLElement* parent, const std::string& tag,
173  T* out, bool optional = false, T value = 0);
175  static ErrorStack get_element(tinyxml2::XMLElement* parent, const std::string& tag,
176  std::string* out, bool optional = false, const char* value = "");
177  template <uint MAXLEN, typename CHAR>
179  tinyxml2::XMLElement* parent,
180  const std::string& tag,
182  bool optional = false,
184  std::string tmp_out;
185  CHECK_ERROR(get_element(parent, tag, &tmp_out, optional, value.str().c_str()));
186  out->assign(tmp_out.data(), tmp_out.size());
187  return kRetOk;
188  }
189 
191  template <typename ENUM>
192  static ErrorStack get_enum_element(tinyxml2::XMLElement* parent, const std::string& tag,
193  ENUM* out, bool optional = false, ENUM default_value = static_cast<ENUM>(0)) {
194  // enum might be signged or unsigned, 1 byte, 2 byte, or 4 byte.
195  // But surely it won't exceed int64_t range.
196  int64_t tmp;
197  CHECK_ERROR(get_element<int64_t>(parent, tag, &tmp, optional, default_value));
198  if (static_cast<int64_t>(static_cast<ENUM>(tmp)) != tmp) {
199  return ERROR_STACK_MSG(kErrorCodeConfValueOutofrange, tag.c_str());
200  }
201  *out = static_cast<ENUM>(tmp);
202  return kRetOk;
203  }
204 
209  template <typename T>
210  static ErrorStack get_element(tinyxml2::XMLElement* parent, const std::string& tag,
211  std::vector< T >* out, bool optional = false);
212 
214  static ErrorStack get_child_element(tinyxml2::XMLElement* parent, const std::string& tag,
215  Externalizable* child, bool optional = false);
216 };
217 
218 } // namespace externalize
219 } // namespace foedus
220 
221 // A bit tricky to get "a" from a in C macro.
222 #define EX_QUOTE(str) #str
223 #define EX_EXPAND(str) EX_QUOTE(str)
224 
234 #define EXTERNALIZE_SAVE_ELEMENT(element, attribute, comment) \
235  CHECK_ERROR(add_element(element, EX_EXPAND(attribute), comment, attribute))
236 
243 #define EXTERNALIZE_SAVE_ENUM_ELEMENT(element, attribute, comment) \
244  CHECK_ERROR(add_enum_element(element, EX_EXPAND(attribute), comment, attribute))
245 
254 #define EXTERNALIZE_LOAD_ELEMENT(element, attribute) \
255  CHECK_ERROR(get_element(element, EX_EXPAND(attribute), & attribute))
256 
264 #define EXTERNALIZE_LOAD_ELEMENT_OPTIONAL(element, attribute, default_value) \
265  CHECK_ERROR(get_element(element, EX_EXPAND(attribute), & attribute, true, default_value))
266 
274 #define EXTERNALIZE_LOAD_ENUM_ELEMENT(element, attribute) \
275  CHECK_ERROR(get_enum_element(element, EX_EXPAND(attribute), & attribute))
276 
283 #define EXTERNALIZE_LOAD_ENUM_ELEMENT_OPTIONAL(element, attribute, default_value) \
284  CHECK_ERROR(get_enum_element(element, EX_EXPAND(attribute), & attribute, true, default_value))
285 
294 #define EXTERNALIZABLE(clazz) \
295  ErrorStack load(tinyxml2::XMLElement* element) CXX11_OVERRIDE;\
296  ErrorStack save(tinyxml2::XMLElement* element) const CXX11_OVERRIDE;\
297  const char* get_tag_name() const CXX11_OVERRIDE { return EX_EXPAND(clazz); }\
298  void assign(const foedus::externalize::Externalizable *other) CXX11_OVERRIDE {\
299  *this = *dynamic_cast< const clazz * >(other);\
300  }\
301  friend std::ostream& operator<<(std::ostream& o, const clazz & v) {\
302  v.save_to_stream(&o);\
303  return o;\
304  }
305 
306 #endif // FOEDUS_EXTERNALIZE_EXTERNALIZABLE_HPP_
ErrorStack load_from_string(const std::string &xml)
Load the content of this object from the given XML string.
void save_to_stream(std::ostream *ptr) const
Invokes save() and directs the resulting XML text to the given stream.
static ErrorStack get_child_element(tinyxml2::XMLElement *parent, const std::string &tag, Externalizable *child, bool optional=false)
child Externalizable version
Forward declarations of classes in filesystem package.
Represents an object that can be written to and read from files/bytes in XML format.
static ErrorStack add_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, const std::vector< T > &value)
vector version
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
static ErrorStack add_child_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, const Externalizable &child)
child Externalizable version
static ErrorStack append_comment(tinyxml2::XMLElement *parent, const std::string &comment)
Brings error stacktrace information as return value of functions.
Definition: error_stack.hpp:81
ErrorStack save_to_file(const fs::Path &path) const
Atomically and durably writes out this object to the specified XML file.
static ErrorStack insert_comment(tinyxml2::XMLElement *element, const std::string &comment)
static ErrorStack add_enum_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, ENUM value)
enum version
static ErrorStack add_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, const assorted::FixedString< MAXLEN, CHAR > &value)
Analogue of boost::filesystem::path.
Definition: path.hpp:37
static ErrorStack create_element(tinyxml2::XMLElement *parent, const std::string &name, tinyxml2::XMLElement **out)
void assign(const FixedString< MAXLEN2, CHAR > &other) noexcept
Assign operator for all FixedString objects.
std::basic_string< CHAR > str() const
Convert to a std::string object.
virtual const char * get_tag_name() const =0
Returns an XML tag name for this object as a root element.
virtual void assign(const foedus::externalize::Externalizable *other)=0
Polymorphic assign operator.
virtual ErrorStack save(tinyxml2::XMLElement *element) const =0
Writes the content of this object to the given XML element.
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
ErrorStack load_from_file(const fs::Path &path)
Load the content of this object from the specified XML file.
const ErrorStack kRetOk
Normal return value for no-error case.
static ErrorStack get_element(tinyxml2::XMLElement *parent, const std::string &tag, T *out, bool optional=false, T value=0)
Only declaration in header.
0x0402 : "CONFIG : Configuration value out of range." .
Definition: error_code.hpp:148
#define ERROR_STACK_MSG(e, m)
Overload of ERROR_STACK(e) to receive a custom error message.
An embedded string object of fixed max-length, which uses no external memory.
std::string get_pretty_type_name()
Returns the name of the C++ type as readable as possible.
static ErrorStack get_enum_element(tinyxml2::XMLElement *parent, const std::string &tag, ENUM *out, bool optional=false, ENUM default_value=static_cast< ENUM >(0))
enum version
virtual ErrorStack load(tinyxml2::XMLElement *element)=0
Reads the content of this object from the given XML element.
static ErrorStack add_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, T value)
Only declaration in header.
static ErrorStack get_element(tinyxml2::XMLElement *parent, const std::string &tag, assorted::FixedString< MAXLEN, CHAR > *out, bool optional=false, const assorted::FixedString< MAXLEN, CHAR > &value=assorted::FixedString< MAXLEN, CHAR >())