xml_tinyxml2.cpp (2587B)
1 /* ReaPack: Package manager for REAPER 2 * Copyright (C) 2015-2025 Christian Fillion 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "xml.hpp" 19 20 #include <iterator> 21 22 #include <tinyxml2.h> 23 24 struct XmlDocument::Impl { tinyxml2::XMLDocument doc; }; 25 struct XmlNode::Impl { tinyxml2::XMLElement *node; }; 26 27 XmlDocument::XmlDocument(std::istream &stream) 28 : m_impl{std::make_unique<Impl>()} 29 { 30 std::string everything(std::istreambuf_iterator<char>(stream), {}); 31 m_impl->doc.Parse(everything.c_str(), everything.size()); 32 } 33 34 XmlDocument::XmlDocument(XmlDocument &&) = default; 35 XmlDocument::~XmlDocument() = default; 36 37 XmlDocument::operator bool() const 38 { 39 return m_impl->doc.ErrorID() == tinyxml2::XML_SUCCESS; 40 } 41 42 const char *XmlDocument::error() const 43 { 44 return !*this ? m_impl->doc.ErrorStr() : nullptr; 45 } 46 47 XmlNode XmlDocument::root() const 48 { 49 return m_impl->doc.RootElement(); 50 } 51 52 53 XmlNode::XmlNode(void *node) 54 : m_impl(new Impl{static_cast<tinyxml2::XMLElement *>(node)}) {} 55 XmlNode::XmlNode(const XmlNode ©) { *this = copy; } 56 XmlNode::~XmlNode() = default; 57 58 XmlNode &XmlNode::operator=(const XmlNode &other) 59 { 60 m_impl.reset(new Impl(*other.m_impl)); 61 return *this; 62 } 63 64 XmlNode::operator bool() const 65 { 66 return m_impl->node != nullptr; 67 } 68 69 const char *XmlNode::name() const 70 { 71 return m_impl->node->Value(); 72 } 73 74 XmlString XmlNode::attribute(const char *name) const 75 { 76 return m_impl->node->Attribute(name); 77 } 78 79 bool XmlNode::attribute(const char *name, int *output) const 80 { 81 return m_impl->node->QueryIntAttribute(name, output) == tinyxml2::XML_SUCCESS; 82 } 83 84 XmlString XmlNode::text() const 85 { 86 return m_impl->node->GetText(); 87 } 88 89 XmlNode XmlNode::firstChild(const char *element) const 90 { 91 return m_impl->node->FirstChildElement(element); 92 } 93 94 XmlNode XmlNode::nextSibling(const char *element) const 95 { 96 return m_impl->node->NextSiblingElement(element); 97 } 98 99 XmlString::XmlString(const void *str) : m_str(str) {} 100 XmlString::~XmlString() = default;