blob: ca43f2e878a81299e44359c669ad885a8ac559da [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_XML_PARSER_H_
#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_XML_PARSER_H_
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/optional.h"
#include "base/token.h"
namespace base {
class Value;
}
namespace service_manager {
class Connector;
}
namespace data_decoder {
// Callback invoked when parsing with ParseXml has finished.
// |value| contains the base::Value dictionary structure representing the parsed
// XML. See xml_parser.mojom for an example.
// If the parsing failed, |error| contains an error message and |value| is null.
using XmlParserCallback =
base::OnceCallback<void(std::unique_ptr<base::Value> value,
const base::Optional<std::string>& error)>;
// Parses |unsafe_xml| using the data_decoder service which, whenever feasible,
// will be run in an isolated sandboxed process. Invokes |callback| when
// done. The XML document is transformed into a base::Value dictionary
// structure, with special keys holding the tag name and child nodes.
// See xml_parser.mojom for details on the format.
// |connector| is the Connector to use when connecting to the data_decoder
// service. This should be retrieved from whichever service is requesting the
// decode operation.
// If |batch_id| is non-empty, the system may batch this parse request with
// other parse requests using the same |batch_id| in an effort to amortize the
// overhead of a single request. The trade-off is that batch requests may not be
// well-isolated from each other, so this should be used with appropriate
// caution.
void ParseXml(service_manager::Connector* connector,
const std::string& unsafe_xml,
XmlParserCallback callback,
const base::Token& batch_id = base::Token{});
// Below are convenience methods for handling the elements returned by
// ParseXml().
// Returns all the children of |element|.
const base::Value* GetXmlElementChildren(const base::Value& element);
// Returns the qualified name |name_space|:|name| or simply |name| if
// |name_space| is empty.
std::string GetXmlQualifiedName(const std::string& name_space,
const std::string& name);
// Returns true if |element| is an XML element with a tag name |name|, false
// otherwise.
bool IsXmlElementNamed(const base::Value& element, const std::string& name);
// Returns true if |element| is an XML element with a type |type|, false
// otherwise. Valid types are data_decoder::mojom::XmlParser::kElementType,
// kTextNodeType or kCDataNodeType.
bool IsXmlElementOfType(const base::Value& element, const std::string& type);
// Sets |name| with the tag name of |element| and returns true.
// Returns false if |element| does not represent a node with a tag or is not a
// valid XML element.
bool GetXmlElementTagName(const base::Value& element, std::string* name);
// Sets |text| with the text of |element| and returns true.
// Returns false if |element| does not contain any text (if it's not a text or
// CData node).
bool GetXmlElementText(const base::Value& element, std::string* text);
// If a namespace with a URI |namespace_uri| is defined in |element|, sets the
// prefix for that namespace in |prefix| and returns true.
// Returns false if no such namespace was found.
// Note that for the default namespace, the prefix is set to the empty string
// and the function returns true.
bool GetXmlElementNamespacePrefix(const base::Value& element,
const std::string& namespace_uri,
std::string* prefix);
// Returns the number of children of |element| named |name|.
int GetXmlElementChildrenCount(const base::Value& element,
const std::string& name);
// Returns the first child of |element| with the type |type|, or null if there
// are no children with that type.
// |type| are data_decoder::mojom::XmlParser::kElementType, kTextNodeType or
// kCDataNodeType.
const base::Value* GetXmlElementChildWithType(const base::Value& element,
const std::string& type);
// Returns the first child of |element| with the tag |tag|, or null if there
// are no children with that tag.
const base::Value* GetXmlElementChildWithTag(const base::Value& element,
const std::string& tag);
// Populates |children| with all the children of |element| with the tag |tag|.
// Returns true if such elements were found, false otherwise.
bool GetAllXmlElementChildrenWithTag(const base::Value& element,
const std::string& tag,
std::vector<const base::Value*>* children);
// Returns the value of the element path |path| starting at |element|, or null
// if any element in |path| is missing. Note that if there are more than one
// element matching any part of the path, the first one is used and
// |unique_path| is set to false. It is set to true otherwise and can be null if
// not needed.
const base::Value* FindXmlElementPath(
const base::Value& element,
std::initializer_list<base::StringPiece> path,
bool* unique_path);
// Returns the value of the attribute named |attribute_name| in |element|, or
// an empty string if there is no such attribute.
std::string GetXmlElementAttribute(const base::Value& element,
const std::string& attribute_name);
} // namespace data_decoder
#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_XML_PARSER_H_