diff options
Diffstat (limited to 'internal/xmpmeta/xml/utils.cc')
-rw-r--r-- | internal/xmpmeta/xml/utils.cc | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/internal/xmpmeta/xml/utils.cc b/internal/xmpmeta/xml/utils.cc new file mode 100644 index 0000000..87bf0b1 --- /dev/null +++ b/internal/xmpmeta/xml/utils.cc @@ -0,0 +1,77 @@ +#include "xmpmeta/xml/utils.h" + +#include "android-base/logging.h" +#include "base/port.h" +#include "xmpmeta/xml/const.h" +#include "xmpmeta/xml/search.h" + +namespace photos_editing_formats { +namespace xml { + +xmlNodePtr GetFirstDescriptionElement(const xmlDocPtr parent) { + return DepthFirstSearch(parent, XmlConst::RdfDescription()); +} + +xmlNodePtr GetFirstSeqElement(xmlDocPtr parent) { + // DepthFirstSearch will perform the null check. + return DepthFirstSearch(parent, XmlConst::RdfSeq()); +} + +// Returns the first rdf:Seq element found in the given node. +xmlNodePtr GetFirstSeqElement(xmlNodePtr parent) { + // DepthFirstSearch will perform the null check. + return DepthFirstSearch(parent, XmlConst::RdfSeq()); +} + +// Returns the ith (zero-indexed) element in the given node. +// {@code parent} is an rdf:Seq node. +xmlNodePtr GetElementAt(xmlNodePtr node, int index) { + if (node == nullptr || index < 0) { + LOG(ERROR) << "Node was null or index was negative"; + return nullptr; + } + const string node_name = FromXmlChar(node->name); + if (strcmp(node_name.c_str(), XmlConst::RdfSeq())) { + LOG(ERROR) << "Node is not an rdf:Seq node, was " << node_name; + return nullptr; + } + int i = 0; + for (xmlNodePtr child = node->children; child != nullptr && i <= index; + child = child->next) { + if (strcmp(FromXmlChar(child->name), XmlConst::RdfLi())) { + // This is not an rdf:li node. This can occur because the node's content + // is also treated as a node, and these should be ignored. + continue; + } + if (i == index) { + return child; + } + i++; + } + return nullptr; +} + +const string GetLiNodeContent(xmlNodePtr node) { + string value; + if (node == nullptr || strcmp(FromXmlChar(node->name), XmlConst::RdfLi())) { + LOG(ERROR) << "Node is null or is not an rdf:li node"; + return value; + } + xmlChar* node_content = xmlNodeGetContent(node); + value = FromXmlChar(node_content); + free(node_content); + return value; +} + +const string XmlDocToString(const xmlDocPtr doc) { + xmlChar* xml_doc_contents; + int doc_size = 0; + xmlDocDumpFormatMemoryEnc(doc, &xml_doc_contents, &doc_size, + XmlConst::EncodingStr(), 1); + const string xml_doc_string(FromXmlChar(xml_doc_contents)); + xmlFree(xml_doc_contents); + return xml_doc_string; +} + +} // namespace xml +} // namespace photos_editing_formats |