diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2018-05-09 00:09:55 +0200 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2018-05-09 00:09:55 +0200 |
commit | 9b623ea3943165fe7efb5e47a0b5b9452c1599e6 (patch) | |
tree | dde40e07e907ac6e0ca9ea32524f2cd4810d4be6 /zenXml/zenxml | |
parent | 9.7 (diff) | |
download | FreeFileSync-9b623ea3943165fe7efb5e47a0b5b9452c1599e6.tar.gz FreeFileSync-9b623ea3943165fe7efb5e47a0b5b9452c1599e6.tar.bz2 FreeFileSync-9b623ea3943165fe7efb5e47a0b5b9452c1599e6.zip |
9.8
Diffstat (limited to 'zenXml/zenxml')
-rwxr-xr-x | zenXml/zenxml/bind.h | 55 | ||||
-rwxr-xr-x | zenXml/zenxml/cvrt_struc.h | 8 | ||||
-rwxr-xr-x | zenXml/zenxml/cvrt_text.h | 1 | ||||
-rwxr-xr-x | zenXml/zenxml/dom.h | 111 | ||||
-rwxr-xr-x | zenXml/zenxml/io.h | 1 | ||||
-rwxr-xr-x | zenXml/zenxml/parser.h | 22 | ||||
-rwxr-xr-x | zenXml/zenxml/xml.h | 1 |
7 files changed, 115 insertions, 84 deletions
diff --git a/zenXml/zenxml/bind.h b/zenXml/zenxml/bind.h index f3cfa398..824c6cc6 100755 --- a/zenXml/zenxml/bind.h +++ b/zenXml/zenxml/bind.h @@ -12,6 +12,7 @@ #include "parser.h" #include "io.h" + namespace zen { /** @@ -167,17 +168,17 @@ public: in["elem3"](value3); // \endcode */ - XmlIn(const XmlDoc& doc) : log(std::make_shared<ErrorLog>()) { refList.push_back(&doc.root()); } + XmlIn(const XmlDoc& doc) : log_(std::make_shared<ErrorLog>()) { refList_.push_back(&doc.root()); } ///Construct an input proxy for a single XML element, may be nullptr /** \sa XmlIn(const XmlDoc& doc) */ - XmlIn(const XmlElement* element) : log(std::make_shared<ErrorLog>()) { refList.push_back(element); } + XmlIn(const XmlElement* element) : log_(std::make_shared<ErrorLog>()) { refList_.push_back(element); } ///Construct an input proxy for a single XML element /** \sa XmlIn(const XmlDoc& doc) */ - XmlIn(const XmlElement& element) : log(std::make_shared<ErrorLog>()) { refList.push_back(&element); } + XmlIn(const XmlElement& element) : log_(std::make_shared<ErrorLog>()) { refList_.push_back(&element); } ///Retrieve a handle to an XML child element for reading /** @@ -190,14 +191,14 @@ public: { std::vector<const XmlElement*> childList; - if (refIndex < refList.size()) + if (refIndex_ < refList_.size()) { - auto iterPair = refList[refIndex]->getChildren(name); + auto iterPair = refList_[refIndex_]->getChildren(name); std::for_each(iterPair.first, iterPair.second, [&](const XmlElement& child) { childList.push_back(&child); }); } - return XmlIn(childList, childList.empty() ? getChildNameFormatted(name) : std::string(), log); + return XmlIn(childList, childList.empty() ? getChildNameFormatted(name) : std::string(), log_); } ///Refer to next sibling element with the same name @@ -221,7 +222,7 @@ public: } \endcode */ - void next() { ++refIndex; } + void next() { ++refIndex_; } ///Read user data from the underlying XML element /** @@ -232,16 +233,16 @@ public: template <class T> bool operator()(T& value) const { - if (refIndex < refList.size()) + if (refIndex_ < refList_.size()) { - bool success = readStruc(*refList[refIndex], value); + bool success = readStruc(*refList_[refIndex_], value); if (!success) - log->notifyConversionError(getNameFormatted()); + log_->notifyConversionError(getNameFormatted()); return success; } else { - log->notifyMissingElement(getNameFormatted()); + log_->notifyMissingElement(getNameFormatted()); return false; } } @@ -267,22 +268,22 @@ public: template <class String, class T> bool attribute(const String& name, T& value) const { - if (refIndex < refList.size()) + if (refIndex_ < refList_.size()) { - bool success = refList[refIndex]->getAttribute(name, value); + bool success = refList_[refIndex_]->getAttribute(name, value); if (!success) - log->notifyMissingAttribute(getNameFormatted(), utfTo<std::string>(name)); + log_->notifyMissingAttribute(getNameFormatted(), utfTo<std::string>(name)); return success; } else { - log->notifyMissingElement(getNameFormatted()); + log_->notifyMissingElement(getNameFormatted()); return false; } } ///Return a pointer to the underlying Xml element, may be nullptr - const XmlElement* get() const { return refIndex < refList.size() ? refList[refIndex] : nullptr; } + const XmlElement* get() const { return refIndex_ < refList_.size() ? refList_[refIndex_] : nullptr; } ///Test whether the underlying XML element exists /** @@ -316,7 +317,7 @@ public: However be aware that the chain of connected proxy instances will be broken once you call XmlIn::get() to retrieve the underlying pointer. Errors that occur when working with this pointer are not logged by the original set of related instances. */ - bool errorsOccured() const { return !log->elementList().empty(); } + bool errorsOccured() const { return !log_->elementList().empty(); } ///Get a list of XML element and attribute names which failed to convert to user data. /** @@ -327,14 +328,14 @@ public: std::vector<String> getErrorsAs() const { std::vector<String> output; - const auto& elements = log->elementList(); + const auto& elements = log_->elementList(); std::transform(elements.begin(), elements.end(), std::back_inserter(output), [](const std::string& str) { return utfTo<String>(str); }); return output; } private: XmlIn(const std::vector<const XmlElement*>& siblingList, const std::string& elementNameFmt, const std::shared_ptr<ErrorLog>& sharedlog) : - refList(siblingList), formattedName(elementNameFmt), log(sharedlog) + refList_(siblingList), formattedName_(elementNameFmt), log_(sharedlog) { assert((!siblingList.empty() && elementNameFmt.empty()) || (siblingList.empty() && !elementNameFmt.empty())); } static std::string getNameFormatted(const XmlElement& elem) //"<Root> <Level1> <Level2>" @@ -344,13 +345,13 @@ private: std::string getNameFormatted() const { - if (refIndex < refList.size()) + if (refIndex_ < refList_.size()) { - assert(formattedName.empty()); - return getNameFormatted(*refList[refIndex]); + assert(formattedName_.empty()); + return getNameFormatted(*refList_[refIndex_]); } else - return formattedName; + return formattedName_; } std::string getChildNameFormatted(const std::string& childName) const @@ -379,10 +380,10 @@ private: std::set<std::string> usedElements; }; - std::vector<const XmlElement*> refList; //all sibling elements with same name (all pointers bound!) - size_t refIndex = 0; //this sibling's index in refList - std::string formattedName; //contains full and formatted element name if (and only if) refList is empty - std::shared_ptr<ErrorLog> log; //always bound + std::vector<const XmlElement*> refList_; //all sibling elements with same name (all pointers bound!) + size_t refIndex_ = 0; //this sibling's index in refList_ + std::string formattedName_; //contains full and formatted element name if (and only if) refList_ is empty + std::shared_ptr<ErrorLog> log_; //always bound }; } diff --git a/zenXml/zenxml/cvrt_struc.h b/zenXml/zenxml/cvrt_struc.h index 87687929..3a18ea73 100755 --- a/zenXml/zenxml/cvrt_struc.h +++ b/zenXml/zenxml/cvrt_struc.h @@ -9,6 +9,7 @@ #include "dom.h" + namespace zen { /** @@ -42,11 +43,6 @@ template <class T> void writeStruc(const T& value, XmlElement& output); - - - - - //------------------------------ implementation ------------------------------------- namespace impl_2384343 { @@ -140,7 +136,7 @@ struct ConvertElement<T, VALUE_TYPE_STL_CONTAINER> value.insert(value.end(), childVal); else success = false; - //should we support insertion of partially-loaded struct?? + //should we support insertion of partially-loaded struct?? } return success; } diff --git a/zenXml/zenxml/cvrt_text.h b/zenXml/zenxml/cvrt_text.h index 6ff1ec94..17444861 100755 --- a/zenXml/zenxml/cvrt_text.h +++ b/zenXml/zenxml/cvrt_text.h @@ -10,6 +10,7 @@ #include <zen/utf.h> #include <zen/string_tools.h> + namespace zen { /** diff --git a/zenXml/zenxml/dom.h b/zenXml/zenxml/dom.h index 09977f1d..c8959e4b 100755 --- a/zenXml/zenxml/dom.h +++ b/zenXml/zenxml/dom.h @@ -8,10 +8,12 @@ #define DOM_H_82085720723894567204564256 #include <string> +#include <list> #include <map> #include <zen/fixed_list.h> #include "cvrt_text.h" //"readText/writeText" + namespace zen { class XmlDoc; @@ -20,11 +22,11 @@ class XmlDoc; class XmlElement { public: - XmlElement() : parent_(nullptr) {} + XmlElement() {} //Construct an empty XML element template <class String> - explicit XmlElement(const String& name, XmlElement* parentElement = nullptr) : name_(utfTo<std::string>(name)), parent_(parentElement) {} + explicit XmlElement(const String& name, XmlElement* parent = nullptr) : name_(utfTo<std::string>(name)), parent_(parent) {} ///Retrieve the name of this XML element. /** @@ -60,8 +62,8 @@ public: template <class String, class T> bool getAttribute(const String& name, T& value) const { - auto it = attributes.find(utfTo<std::string>(name)); - return it == attributes.end() ? false : readText(it->second, value); + auto it = attributesSorted_.find(utfTo<std::string>(name)); + return it == attributesSorted_.end() ? false : readText(it->second->value, value); } ///Create or update an XML attribute. @@ -74,9 +76,19 @@ public: template <class String, class T> void setAttribute(const String& name, const T& value) { + std::string attrName = utfTo<std::string>(name); + std::string attrValue; writeText(value, attrValue); - attributes[utfTo<std::string>(name)] = attrValue; + + auto it = attributesSorted_.find(attrName); + if (it != attributesSorted_.end()) + it->second->value = std::move(attrValue); + else + { + auto itBack = attributes_.insert(attributes_.end(), { attrName, std::move(attrValue) }); + attributesSorted_.emplace(std::move(attrName), itBack); + } } ///Remove the attribute with the given name. @@ -84,7 +96,15 @@ public: \tparam String Arbitrary string-like type: e.g. std::string, wchar_t*, char[], wchar_t, wxString, MyStringClass, ... */ template <class String> - void removeAttribute(const String& name) { attributes.erase(utfTo<std::string>(name)); } + void removeAttribute(const String& name) + { + auto it = attributesSorted_.find(utfTo<std::string>(name)); + if (it != attributesSorted_.end()) + { + attributes_.erase(it->second); + attributesSorted_.erase(it); + } + } ///Create a new child element and return a reference to it. /** @@ -94,10 +114,10 @@ public: template <class String> XmlElement& addChild(const String& name) { - std::string utf8Name = utfTo<std::string>(name); - childElements.emplace_back(utf8Name, this); - XmlElement& newElement = childElements.back(); - childElementsSorted.emplace(utf8Name, &newElement); + std::string elemName = utfTo<std::string>(name); + childElements_.emplace_back(elemName, this); + XmlElement& newElement = childElements_.back(); + childElementsSorted_.emplace(std::move(elemName), &newElement); return newElement; } @@ -110,8 +130,8 @@ public: template <class String> const XmlElement* getChild(const String& name) const { - auto it = childElementsSorted.find(utfTo<std::string>(name)); - return it == childElementsSorted.end() ? nullptr : it->second; + auto it = childElementsSorted_.find(utfTo<std::string>(name)); + return it == childElementsSorted_.end() ? nullptr : it->second; } ///\sa getChild @@ -121,8 +141,8 @@ public: return const_cast<XmlElement*>(static_cast<const XmlElement*>(this)->getChild(name)); } - template < class IterTy, //underlying iterator type - class T, //target object type + template < class IterTy, //underlying iterator type + class T, //target object type class AccessPolicy > //access policy: see AccessPtrMap class PtrIter : public std::iterator<std::input_iterator_tag, T>, private AccessPolicy //get rid of shared_ptr indirection { @@ -159,11 +179,11 @@ public: \return A pair of STL begin/end iterators to access the child elements sequentially. */ template <class String> - std::pair<ChildIterConst2, ChildIterConst2> getChildren(const String& name) const { return childElementsSorted.equal_range(utfTo<std::string>(name)); } + std::pair<ChildIterConst2, ChildIterConst2> getChildren(const String& name) const { return childElementsSorted_.equal_range(utfTo<std::string>(name)); } ///\sa getChildren template <class String> - std::pair<ChildIter2, ChildIter2> getChildren(const String& name) { return childElementsSorted.equal_range(utfTo<std::string>(name)); } + std::pair<ChildIter2, ChildIter2> getChildren(const String& name) { return childElementsSorted_.equal_range(utfTo<std::string>(name)); } struct AccessListElement { @@ -183,41 +203,47 @@ public: \endcode \return A pair of STL begin/end iterators to access all child elements sequentially. */ - std::pair<ChildIterConst, ChildIterConst> getChildren() const { return std::make_pair(childElements.begin(), childElements.end()); } + std::pair<ChildIterConst, ChildIterConst> getChildren() const { return { childElements_.begin(), childElements_.end() }; } ///\sa getChildren - std::pair<ChildIter, ChildIter> getChildren() { return std::make_pair(childElements.begin(), childElements.end()); } + std::pair<ChildIter, ChildIter> getChildren() { return { childElements_.begin(), childElements_.end() }; } ///Get parent XML element, may be nullptr for root element XmlElement* parent() { return parent_; } ///Get parent XML element, may be nullptr for root element const XmlElement* parent() const { return parent_; } - using AttrIter = std::map<std::string, std::string>::const_iterator; + struct Attribute + { + std::string name; + std::string value; + }; + using AttrIter = std::list<Attribute>::const_iterator; /* -> disabled documentation extraction \brief Get all attributes associated with the element. \code auto iterPair = elem.getAttributes(); for (auto it = iterPair.first; it != iterPair.second; ++it) - std::cout << "name: " << it->first << " value: " << it->second << "\n"; + std::cout << "name: " << it->name << " value: " << it->value << "\n"; \endcode \return A pair of STL begin/end iterators to access all attributes sequentially as a list of name/value pairs of std::string. */ - std::pair<AttrIter, AttrIter> getAttributes() const { return std::make_pair(attributes.begin(), attributes.end()); } + std::pair<AttrIter, AttrIter> getAttributes() const { return { attributes_.begin(), attributes_.end() }; } //swap two elements while keeping references to parent. -> disabled documentation extraction void swapSubtree(XmlElement& other) { - name_ .swap(other.name_); - value_ .swap(other.value_); - attributes.swap(other.attributes); - childElements.swap(other.childElements); - childElementsSorted.swap(other.childElementsSorted); - //std::swap(parent_, other.parent_); -> parent is physical location; update children's parent reference instead: - for (XmlElement& child : childElements) + name_ .swap(other.name_); + value_ .swap(other.value_); + attributes_ .swap(other.attributes_); + attributesSorted_ .swap(other.attributesSorted_); + childElements_ .swap(other.childElements_); + childElementsSorted_.swap(other.childElementsSorted_); + + for (XmlElement& child : childElements_) child.parent_ = this; - for (XmlElement& child : other.childElements) + for (XmlElement& child : other.childElements_) child.parent_ = &other; } @@ -227,10 +253,13 @@ private: std::string name_; std::string value_; - std::map<std::string, std::string> attributes; - FixedList<XmlElement> childElements; //all child elements in order of creation - std::multimap<std::string, XmlElement*> childElementsSorted; //alternate key: sorted by element name - XmlElement* parent_; + + std::list<Attribute> attributes_; //attributes in order of creation + std::map<std::string, std::list<Attribute>::iterator> attributesSorted_; //alternate view: sorted by attribute name + + FixedList<XmlElement> childElements_; //child elements in order of creation + std::multimap<std::string, XmlElement*> childElementsSorted_; //alternate view: sorted by element name + XmlElement* parent_ = nullptr; }; @@ -247,7 +276,7 @@ class XmlDoc { public: ///Default constructor setting up an empty XML document with a standard declaration: <?xml version="1.0" encoding="UTF-8" ?> - XmlDoc() : version_("1.0"), encoding_("UTF-8"), rootElement("Root") {} + XmlDoc() {} XmlDoc(XmlDoc&& tmp) { swap(tmp); } XmlDoc& operator=(XmlDoc&& tmp) { swap(tmp); return *this; } @@ -258,12 +287,12 @@ public: \param rootName The name of the XML document's root element. */ template <class String> - XmlDoc(String rootName) : version_("1.0"), encoding_("UTF-8"), rootElement(rootName) {} + XmlDoc(String rootName) : root_(rootName) {} ///Get a const reference to the document's root element. - const XmlElement& root() const { return rootElement; } + const XmlElement& root() const { return root_; } ///Get a reference to the document's root element. - XmlElement& root() { return rootElement; } + XmlElement& root() { return root_; } ///Get the version used in the XML declaration. /** @@ -313,18 +342,18 @@ public: version_ .swap(other.version_); encoding_ .swap(other.encoding_); standalone_.swap(other.standalone_); - rootElement.swapSubtree(other.rootElement); + root_.swapSubtree(other.root_); } private: XmlDoc (const XmlDoc&) = delete; //not implemented, thanks to XmlElement::parent_ XmlDoc& operator=(const XmlDoc&) = delete; - std::string version_; - std::string encoding_; + std::string version_ { "1.0" }; + std::string encoding_{ "UTF-8" }; std::string standalone_; - XmlElement rootElement; + XmlElement root_{ "Root" }; }; } diff --git a/zenXml/zenxml/io.h b/zenXml/zenxml/io.h index 1361d865..6d5a21d5 100755 --- a/zenXml/zenxml/io.h +++ b/zenXml/zenxml/io.h @@ -13,6 +13,7 @@ #include <zen/utf.h> #include "error.h" + namespace zen { /** diff --git a/zenXml/zenxml/parser.h b/zenXml/zenxml/parser.h index bff2bb50..5c6a9ec2 100755 --- a/zenXml/zenxml/parser.h +++ b/zenXml/zenxml/parser.h @@ -73,7 +73,7 @@ XmlDoc parse(const std::string& stream); //throw XmlParsingError //---------------------------- implementation ---------------------------- //see: http://www.w3.org/TR/xml/ -namespace implementation +namespace impl { template <class Predicate> inline std::string normalize(const std::string& str, Predicate pred) //pred: unary function taking a char, return true if value shall be encoded as hex @@ -111,7 +111,9 @@ std::string normalize(const std::string& str, Predicate pred) //pred: unary func inline std::string normalizeName(const std::string& str) { - return normalize(str, [](char c) { return isWhiteSpace(c) || c == '=' || c == '/' || c == '\'' || c == '\"'; }); + const std::string nameFmt = normalize(str, [](char c) { return isWhiteSpace(c) || c == '=' || c == '/' || c == '\'' || c == '\"'; }); + assert(!nameFmt.empty()); + return nameFmt; } inline @@ -201,12 +203,12 @@ void serialize(const XmlElement& element, std::string& stream, auto attr = element.getAttributes(); for (auto it = attr.first; it != attr.second; ++it) - stream += ' ' + normalizeName(it->first) + "=\"" + normalizeAttribValue(it->second) + '\"'; + stream += ' ' + normalizeName(it->name) + "=\"" + normalizeAttribValue(it->value) + '\"'; - //no support for mixed-mode content auto iterPair = element.getChildren(); if (iterPair.first != iterPair.second) //structured element { + //no support for mixed-mode content stream += '>' + lineBreak; std::for_each(iterPair.first, iterPair.second, @@ -254,7 +256,7 @@ std::string serialize(const XmlDoc& doc, inline std::string serialize(const XmlDoc& doc, const std::string& lineBreak, - const std::string& indent) { return implementation::serialize(doc, lineBreak, indent); } + const std::string& indent) { return impl::serialize(doc, lineBreak, indent); } /* Grammar for XML parser @@ -280,7 +282,7 @@ pm-expression: element-list-expression */ -namespace implementation +namespace impl { struct Token { @@ -355,7 +357,7 @@ public: { std::string name(&*pos, nameEnd - pos); pos = nameEnd; - return implementation::denormalize(name); + return denormalize(name); } //unknown token @@ -371,7 +373,7 @@ public: }); std::string output(pos, it); pos = it; - return implementation::denormalize(output); + return denormalize(output); } std::string extractAttributeValue() @@ -385,7 +387,7 @@ public: }); std::string output(pos, it); pos = it; - return implementation::denormalize(output); + return denormalize(output); } size_t posRow() const //current row beginning with 0 @@ -575,7 +577,7 @@ private: inline XmlDoc parse(const std::string& stream) //throw XmlParsingError { - return implementation::XmlParser(stream).parse(); //throw XmlParsingError + return impl::XmlParser(stream).parse(); //throw XmlParsingError } } diff --git a/zenXml/zenxml/xml.h b/zenXml/zenxml/xml.h index e0035c2b..9510645a 100755 --- a/zenXml/zenxml/xml.h +++ b/zenXml/zenxml/xml.h @@ -9,6 +9,7 @@ #include "bind.h" + /// The zen::Xml namespace namespace zen {} |