LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / tools / source / xml / XmlWalker.cxx
blobc0e8a2abef48b0c50351be3c7a2b70b00f5e0f89
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <tools/stream.hxx>
11 #include <tools/XmlWalker.hxx>
13 #include <libxml/tree.h>
14 #include <libxml/parser.h>
15 #include <libxml/xmlstring.h>
16 #include <vector>
18 namespace tools
20 struct XmlWalkerImpl
22 XmlWalkerImpl()
23 : mpDocPtr(nullptr)
24 , mpRoot(nullptr)
25 , mpCurrent(nullptr)
29 xmlDocPtr mpDocPtr;
30 xmlNodePtr mpRoot;
31 xmlNodePtr mpCurrent;
33 std::vector<xmlNodePtr> mpStack;
36 XmlWalker::XmlWalker()
37 : mpImpl(std::make_unique<XmlWalkerImpl>())
41 XmlWalker::~XmlWalker()
43 if (mpImpl)
44 xmlFreeDoc(mpImpl->mpDocPtr);
47 bool XmlWalker::open(SvStream* pStream)
49 std::size_t nSize = pStream->remainingSize();
50 std::vector<sal_uInt8> aBuffer(nSize + 1);
51 pStream->ReadBytes(aBuffer.data(), nSize);
52 aBuffer[nSize] = 0;
53 mpImpl->mpDocPtr = xmlParseDoc(reinterpret_cast<xmlChar*>(aBuffer.data()));
54 if (mpImpl->mpDocPtr == nullptr)
55 return false;
56 mpImpl->mpRoot = xmlDocGetRootElement(mpImpl->mpDocPtr);
57 mpImpl->mpCurrent = mpImpl->mpRoot;
58 mpImpl->mpStack.push_back(mpImpl->mpCurrent);
59 return true;
62 OString XmlWalker::name() { return reinterpret_cast<const char*>(mpImpl->mpCurrent->name); }
64 OString XmlWalker::namespaceHref()
66 return reinterpret_cast<const char*>(mpImpl->mpCurrent->ns->href);
69 OString XmlWalker::namespacePrefix()
71 return reinterpret_cast<const char*>(mpImpl->mpCurrent->ns->prefix);
74 OString XmlWalker::content()
76 OString aContent;
77 if (mpImpl->mpCurrent->xmlChildrenNode != nullptr)
79 xmlChar* pContent
80 = xmlNodeListGetString(mpImpl->mpDocPtr, mpImpl->mpCurrent->xmlChildrenNode, 1);
81 aContent = OString(reinterpret_cast<const char*>(pContent));
82 xmlFree(pContent);
84 return aContent;
87 void XmlWalker::children()
89 mpImpl->mpStack.push_back(mpImpl->mpCurrent);
90 mpImpl->mpCurrent = mpImpl->mpCurrent->xmlChildrenNode;
93 void XmlWalker::parent()
95 mpImpl->mpCurrent = mpImpl->mpStack.back();
96 mpImpl->mpStack.pop_back();
99 OString XmlWalker::attribute(const OString& sName) const
101 xmlChar* xmlAttribute
102 = xmlGetProp(mpImpl->mpCurrent, reinterpret_cast<const xmlChar*>(sName.getStr()));
103 OString aAttributeContent(
104 xmlAttribute == nullptr ? "" : reinterpret_cast<const char*>(xmlAttribute));
105 xmlFree(xmlAttribute);
107 return aAttributeContent;
110 void XmlWalker::next() { mpImpl->mpCurrent = mpImpl->mpCurrent->next; }
112 bool XmlWalker::isValid() const { return mpImpl->mpCurrent != nullptr; }
114 } // end tools namespace
116 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */