blob: 9edf46bf09df5dc13155a11274ded375f4828017 [file] [log] [blame]
//===-- XML.h ---------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_HOST_XML_H
#define LLDB_HOST_XML_H
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_LIBXML2
#include <libxml/xmlreader.h>
#endif
#include <functional>
#include <string>
#include <vector>
#include "llvm/ADT/StringRef.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
#if LLDB_ENABLE_LIBXML2
typedef xmlNodePtr XMLNodeImpl;
typedef xmlDocPtr XMLDocumentImpl;
#else
typedef void *XMLNodeImpl;
typedef void *XMLDocumentImpl;
#endif
class XMLNode;
typedef std::vector<std::string> NamePath;
typedef std::function<bool(const XMLNode &node)> NodeCallback;
typedef std::function<bool(const llvm::StringRef &name,
const llvm::StringRef &value)>
AttributeCallback;
class XMLNode {
public:
XMLNode();
XMLNode(XMLNodeImpl node);
~XMLNode();
explicit operator bool() const { return IsValid(); }
void Clear();
bool IsValid() const;
bool IsElement() const;
llvm::StringRef GetName() const;
bool GetElementText(std::string &text) const;
bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value = 0,
int base = 0) const;
bool GetElementTextAsFloat(double &value, double fail_value = 0.0) const;
bool NameIs(const char *name) const;
XMLNode GetParent() const;
XMLNode GetSibling() const;
XMLNode GetChild() const;
llvm::StringRef GetAttributeValue(const char *name,
const char *fail_value = nullptr) const;
bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value,
uint64_t fail_value = 0, int base = 0) const;
XMLNode FindFirstChildElementWithName(const char *name) const;
XMLNode GetElementForPath(const NamePath &path);
// Iterate through all sibling nodes of any type
void ForEachSiblingNode(NodeCallback const &callback) const;
// Iterate through only the sibling nodes that are elements
void ForEachSiblingElement(NodeCallback const &callback) const;
// Iterate through only the sibling nodes that are elements and whose name
// matches \a name.
void ForEachSiblingElementWithName(const char *name,
NodeCallback const &callback) const;
void ForEachChildNode(NodeCallback const &callback) const;
void ForEachChildElement(NodeCallback const &callback) const;
void ForEachChildElementWithName(const char *name,
NodeCallback const &callback) const;
void ForEachAttribute(AttributeCallback const &callback) const;
protected:
XMLNodeImpl m_node = nullptr;
};
class XMLDocument {
public:
XMLDocument();
~XMLDocument();
explicit operator bool() const { return IsValid(); }
bool IsValid() const;
void Clear();
bool ParseFile(const char *path);
bool ParseMemory(const char *xml, size_t xml_length,
const char *url = "untitled.xml");
// If \a name is nullptr, just get the root element node, else only return a
// value XMLNode if the name of the root element matches \a name.
XMLNode GetRootElement(const char *required_name = nullptr);
llvm::StringRef GetErrors() const;
static void ErrorCallback(void *ctx, const char *format, ...);
static bool XMLEnabled();
protected:
XMLDocumentImpl m_document = nullptr;
StreamString m_errors;
};
class ApplePropertyList {
public:
ApplePropertyList();
ApplePropertyList(const char *path);
~ApplePropertyList();
bool ParseFile(const char *path);
llvm::StringRef GetErrors() const;
explicit operator bool() const { return IsValid(); }
bool IsValid() const;
XMLNode GetValueNode(const char *key) const;
bool GetValueAsString(const char *key, std::string &value) const;
StructuredData::ObjectSP GetStructuredData();
protected:
// Using a node returned from GetValueNode() extract its value as a string
// (if possible). Array and dictionary nodes will return false as they have
// no string value. Boolean nodes will return true and \a value will be
// "true" or "false" as the string value comes from the element name itself.
// All other nodes will return the text content of the XMLNode.
static bool ExtractStringFromValueNode(const XMLNode &node,
std::string &value);
XMLDocument m_xml_doc;
XMLNode m_dict_node;
};
} // namespace lldb_private
#endif // LLDB_HOST_XML_H