36 namespace externalize {
39 tinyxml2::XMLDocument document;
40 tinyxml2::XMLError load_error = document.Parse(xml.data(), xml.size());
41 if (load_error != tinyxml2::XML_SUCCESS) {
42 std::stringstream custom_message;
43 custom_message <<
"xml=" << xml <<
", tinyxml2 error=" << load_error
44 <<
", GetErrorStr1()=" << document.GetErrorStr1()
45 <<
", GetErrorStr2()=" << document.GetErrorStr2();
47 }
else if (!document.RootElement()) {
56 std::ostream &o = *ptr;
57 tinyxml2::XMLDocument doc;
59 tinyxml2::XMLElement* element = doc.NewElement(
get_tag_name());
61 o <<
"Out-of-memory during Externalizable::save_to_stream()";
64 doc.InsertFirstChild(element);
67 o <<
"Failed during Externalizable::save_to_stream(): " << error_stack;
70 tinyxml2::XMLPrinter printer;
76 tinyxml2::XMLDocument document;
81 tinyxml2::XMLError load_error = document.LoadFile(path.
c_str());
82 if (load_error != tinyxml2::XML_SUCCESS) {
83 std::stringstream custom_message;
84 custom_message <<
"problemtic file=" << path <<
", tinyxml2 error=" << load_error
85 <<
", GetErrorStr1()=" << document.GetErrorStr1()
86 <<
", GetErrorStr2()=" << document.GetErrorStr2();
88 }
else if (!document.RootElement()) {
98 tinyxml2::XMLDocument document;
99 tinyxml2::XMLElement* root = document.NewElement(
get_tag_name());
101 document.InsertFirstChild(root);
108 std::stringstream custom_message;
109 custom_message <<
"file=" << path <<
", folder=" << folder
118 tinyxml2::XMLPrinter xml_stream;
119 document.Print(&xml_stream);
120 const uint32_t non_aligned_size = xml_stream.CStrSize();
121 const uint32_t aligned_size = assorted::align<uint32_t, 1U << 12>(non_aligned_size);
124 if (xml_memory.is_null()) {
127 char* buffer =
reinterpret_cast<char*
>(xml_memory.get_block());
128 std::memcpy(buffer, xml_stream.CStr(), non_aligned_size);
129 std::memset(buffer + non_aligned_size,
'\n', aligned_size - non_aligned_size);
149 std::stringstream custom_message;
150 custom_message <<
"dest file=" << path <<
", src file=" << tmp_path
160 if (comment.size() > 0) {
161 tinyxml2::XMLComment* cm = element->GetDocument()->NewComment(comment.c_str());
163 tinyxml2::XMLNode* parent = element->Parent();
165 element->GetDocument()->InsertFirstChild(cm);
167 tinyxml2::XMLNode* previous = element->PreviousSibling();
169 parent->InsertAfterChild(previous, cm);
171 parent->InsertFirstChild(cm);
178 const std::string& comment) {
182 const std::string& comment) {
183 if (comment.size() > 0) {
184 tinyxml2::XMLComment* cm = parent->GetDocument()->NewComment(comment.c_str());
186 parent->InsertEndChild(cm);
192 tinyxml2::XMLElement** out) {
193 *out = parent->GetDocument()->NewElement(name.c_str());
195 parent->InsertEndChild(*out);
199 template <
typename T>
201 const std::string& tag,
const std::string& comment, T value) {
202 tinyxml2::XMLElement* element = parent->GetDocument()->NewElement(tag.c_str());
205 tinyxml_setter(element, value);
206 parent->InsertEndChild(element);
207 if (comment.size() > 0) {
209 tag +
" (type=" + assorted::get_pretty_type_name<T>() +
"): " + comment));
216 #define EXPLICIT_INSTANTIATION_ADD(x) template ErrorStack Externalizable::add_element< x > \
217 (tinyxml2::XMLElement* parent, const std::string& tag, const std::string& comment, x value)
223 tinyxml2::XMLElement* element = parent->GetDocument()->NewElement(tag.c_str());
225 parent->InsertEndChild(element);
231 template <
typename T>
233 T* out,
bool optional, T default_value) {
235 tinyxml2::XMLElement* element = parent->FirstChildElement(tag.c_str());
237 tinyxml2::XMLError xml_error = tinyxml_getter(element, out);
238 if (xml_error == tinyxml2::XML_SUCCESS) {
245 *out = default_value;
255 #define EXPLICIT_INSTANTIATION_GET(x) template ErrorStack Externalizable::get_element< x > \
256 (tinyxml2::XMLElement* parent, const std::string& tag, x * out, bool optional, x default_value)
261 std::string* out,
bool optional,
const char* default_value) {
262 return get_element<std::string>(parent, tag, out, optional, std::string(default_value));
265 template <
typename T>
267 std::vector<T> * out,
bool optional) {
270 for (tinyxml2::XMLElement* element = parent->FirstChildElement(tag.c_str());
271 element; element = element->NextSiblingElement(tag.c_str())) {
273 tinyxml2::XMLError xml_error = tinyxml_getter(element, &tmp);
274 if (xml_error == tinyxml2::XML_SUCCESS) {
280 if (out->size() == 0 && !optional) {
288 #define EXPLICIT_INSTANTIATION_GET_VECTOR(x) template ErrorStack Externalizable::get_element< x > \
289 (tinyxml2::XMLElement* parent, const std::string& tag, std::vector< x > * out, bool optional)
295 tinyxml2::XMLElement* element = parent->FirstChildElement(tag.c_str());
297 return child->
load(element);
Functor to help use tinyxml2's Element SetText().
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.
ErrorStack insert_comment_impl(tinyxml2::XMLElement *element, const std::string &comment)
static ErrorStack get_child_element(tinyxml2::XMLElement *parent, const std::string &tag, Externalizable *child, bool optional=false)
child Externalizable version
Represents an object that can be written to and read from files/bytes in XML format.
ErrorCode write(uint64_t desired_bytes, const foedus::memory::AlignedMemory &buffer)
Sequentially write the given amount of contents from the current position.
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
static ErrorStack add_child_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, const Externalizable &child)
child Externalizable version
0x0408 : "CONFIG : Failed to atomically rename the temporary file to destination." ...
bool close()
Close the file if not yet closed.
static ErrorStack append_comment(tinyxml2::XMLElement *parent, const std::string &comment)
Brings error stacktrace information as return value of functions.
ErrorStack save_to_file(const fs::Path &path) const
Atomically and durably writes out this object to the specified XML file.
void alloc(uint64_t size, uint64_t alignment, AllocType alloc_type, int numa_node) noexcept
Allocate a memory, releasing the current memory if exists.
ErrorCode open(bool read, bool write, bool append, bool create)
Tries to open the file for the specified volume.
static ErrorStack insert_comment(tinyxml2::XMLElement *element, const std::string &comment)
#define CHECK_OUTOFMEMORY(ptr)
This macro checks if ptr is nullptr, and if so exists with kErrorCodeOutofmemory error stack...
#define INSTANTIATE_ALL_TYPES(M)
A macro to explicitly instantiate the given template for all types we care.
0x0409 : "CONFIG : Failed to create a directory. Check permissions." .
0x0406 : "CONFIG : The file doesn't exist." .
0x0404 : "CONFIG : An invalid valud in the xml element." .
0x0401 : "CONFIG : Config file parsing failed. This usually means an invalid XML file." .
Functor to help use tinyxml2's Element QueryXxxText().
0x0407 : "CONFIG : Failed to write a configuration file." .
Analogue of boost::filesystem::path.
0x0403 : "CONFIG : The xml element is missing in the config file." .
static ErrorStack create_element(tinyxml2::XMLElement *parent, const std::string &name, tinyxml2::XMLElement **out)
bool durable_atomic_rename(const Path &old_path, const Path &new_path)
fsync() on source file before rename, then fsync() on the parent folder after rename.
bool create_directories(const Path &p, bool sync=false)
Recursive mkdir (mkdirs).
bool exists(const Path &p)
Returns if the file exists.
virtual const char * get_tag_name() const =0
Returns an XML tag name for this object as a root element.
const char * c_str() const
std::string os_error()
Thread-safe strerror(errno).
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.
Represents an I/O stream on one file without filesystem caching.
Represents one memory block aligned to actual OS/hardware pages.
std::string unique_name(uint64_t differentiator=0)
Equivalent to unique_path("%%%%-%%%%-%%%%-%%%%").
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.
0x0405 : "CONFIG : No root element in the xml." .
static ErrorStack get_element(tinyxml2::XMLElement *parent, const std::string &tag, T *out, bool optional=false, T value=0)
Only declaration in header.
#define ERROR_STACK_MSG(e, m)
Overload of ERROR_STACK(e) to receive a custom error message.
posix_memalign() and free().
virtual ErrorStack load(tinyxml2::XMLElement *element)=0
Reads the content of this object from the given XML element.
#define WRAP_ERROR_CODE(x)
Same as CHECK_ERROR(x) except it receives only an error code, thus more efficient.
bool fsync(const Path &path, bool sync_parent_directory=false)
Makes the content and metadata of the file durable all the way up to devices.
static ErrorStack add_element(tinyxml2::XMLElement *parent, const std::string &tag, const std::string &comment, T value)
Only declaration in header.
bool is_error() const
Returns if this return code is not kErrorCodeOk.