#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2021 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_STORAGE_XML_XMLREADER_H #define NUCLEX_STORAGE_XML_XMLREADER_H #include "Nuclex/Storage/Config.h" #include "Nuclex/Storage/Reader.h" #include "Nuclex/Storage/Xml/XmlReadEvent.h" #include "Nuclex/Storage/Xml/XmlBinaryFormat.h" #include #include // for std::runtime_error namespace Nuclex { namespace Storage { namespace Xml { // ------------------------------------------------------------------------------------------- // /// Reads data using the XML format class XmlReader : Reader { #pragma region class AttributeScope /// Automatically leaves an attribute when the scope is destroyed public: class AttributeScope { /// Initializes a new attribute scope using the specified XML reader /// XML reader the attribute scope will use public: NUCLEX_STORAGE_API AttributeScope(XmlReader &reader) : reader(reader) {} /// Initializes a new attribute scope using the specified XML reader /// XML reader the attribute scope will use public: NUCLEX_STORAGE_API AttributeScope(const std::shared_ptr &reader) : reader(*reader.get()) {} /// Destroys the attribute scope and leaves the attribute again public: NUCLEX_STORAGE_API ~AttributeScope() { this->reader.LeaveAttribute(); } private: AttributeScope(const AttributeScope &) = delete; private: AttributeScope &operator =(const AttributeScope &) = delete; /// XML reader in which the scope will leave the current attribute private: XmlReader &reader; }; #pragma endregion // class AttributeScope /// Destroys the XML reader public: NUCLEX_STORAGE_API virtual ~XmlReader() {} /// Retrieves the currently selected binary data format /// The format in which binary data will be read public: virtual XmlBinaryFormat GetBinaryFormat() const = 0; /// Selects the binary data format to use for reading binary data /// Format in which binary data will be read public: virtual void SetBinaryFormat(XmlBinaryFormat binaryFormat) = 0; /// Reads from XML plaintext up until the next event is encountered /// The type of event encountered when parsing public: virtual XmlReadEvent Read() = 0; /// Retrieves the name of the last element that was entered or exited /// The name of the last element entered or exited public: virtual const std::string &GetElementName() const = 0; /// Counts the number of attributes in the current element /// The number of attributes present in the current element public: virtual std::size_t CountAttributes() const = 0; /// Retrieves the name of the attribute with the specified index /// Index of the attribue whose name will be looked up /// The name of the attribute with the specified index public: virtual const std::string &GetAttributeName(std::size_t index) const = 0; /// Enters the attribute with the specified name /// Name of the attribute that will be entered public: void EnterAttribute(const std::string &attributeName) { if(!TryEnterAttribute(attributeName)) { throw std::runtime_error( std::string("Attribute '") + attributeName + "' doesn't exist" ); } } /// Try to enter the attribute with the specified name /// Name of the attribute that will be entered /// True if the attribute existed and was entered, otherwise false public: virtual bool TryEnterAttribute(const std::string &attributeName) = 0; /// Leaves the currently entered attribute again public: virtual void LeaveAttribute() = 0; /// Retrieves the value of an attribute from the current element /// Name of the attribue whose value will be retrieved /// The value of the queried attribute public: template TValue GetAttributeValue( const std::string &attributeName ) { EnterAttribute(attributeName); { AttributeScope scope(*this); TValue value; Read(value); return value; } } /// Retrieves the value of an attribute from the current element /// Name of the attribue whose value will be retrieved /// /// Value that will be returned when the attribue doesn't exist /// /// The attribute's default value public: template TValue GetAttributeValue( const std::string &attributeName, const TValue &defaultValue ) { if(TryEnterAttribute(attributeName)) { AttributeScope scope(*this); TValue value; Read(value); return value; } else { return defaultValue; } } // Unhide the overloaded Read() methods in the base class // See http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9 using Reader::Read; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Storage::Xml #endif // NUCLEX_STORAGE_XML_XMLREADER_H