#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_WEB_BUNDLE_PARSER_H_
#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_WEB_BUNDLE_PARSER_H_
#include <memory>
#include <optional>
#include "base/containers/flat_map.h"
#include "base/files/file.h"
#include "base/functional/callback.h"
#include "components/web_package/mojom/web_bundle_parser.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "url/gurl.h"
namespace data_decoder {
class DataSourceCreatingStrategy {
public:
virtual ~DataSourceCreatingStrategy() {}
virtual base::expected<void, std::string> ExpectReady() const = 0;
virtual mojo::PendingRemote<web_package::mojom::BundleDataSource>
CreateDataSource(web_package::mojom::WebBundleParserFactory* binder) = 0;
virtual void Close(base::OnceClosure callback) = 0;
};
class SafeWebBundleParser {
public:
static std::unique_ptr<DataSourceCreatingStrategy> GetFileStrategy(
base::File file);
SafeWebBundleParser(
std::optional<GURL> base_url,
std::unique_ptr<DataSourceCreatingStrategy> data_source_creator);
SafeWebBundleParser(const SafeWebBundleParser&) = delete;
SafeWebBundleParser& operator=(const SafeWebBundleParser&) = delete;
~SafeWebBundleParser();
void ParseIntegrityBlock(
web_package::mojom::WebBundleParser::ParseIntegrityBlockCallback
callback);
void ParseMetadata(
std::optional<uint64_t> offset,
web_package::mojom::WebBundleParser::ParseMetadataCallback callback);
void ParseResponse(
uint64_t response_offset,
uint64_t response_length,
web_package::mojom::WebBundleParser::ParseResponseCallback callback);
void Close(base::OnceClosure callback);
private:
web_package::mojom::WebBundleParserFactory* GetFactory();
void OnDisconnect();
void OnIntegrityBlockParsed(
web_package::mojom::BundleIntegrityBlockPtr integrity_block,
web_package::mojom::BundleIntegrityBlockParseErrorPtr error);
void OnMetadataParsed(web_package::mojom::BundleMetadataPtr metadata,
web_package::mojom::BundleMetadataParseErrorPtr error);
void OnResponseParsed(size_t callback_id,
web_package::mojom::BundleResponsePtr response,
web_package::mojom::BundleResponseParseErrorPtr error);
base::expected<void, std::string> ConnectIfNecessary();
void CloseDataSourceCreator();
void ReplyClosed();
struct Connection {
Connection();
~Connection();
DataDecoder data_decoder_;
mojo::Remote<web_package::mojom::WebBundleParserFactory> factory_;
mojo::Remote<web_package::mojom::WebBundleParser> parser_;
};
bool is_connected() const { return connection_.get(); }
std::unique_ptr<Connection> connection_;
std::unique_ptr<DataSourceCreatingStrategy> data_source_creator_;
web_package::mojom::WebBundleParser::ParseIntegrityBlockCallback
integrity_block_callback_;
web_package::mojom::WebBundleParser::ParseMetadataCallback metadata_callback_;
base::flat_map<size_t,
web_package::mojom::WebBundleParser::ParseResponseCallback>
response_callbacks_;
base::OnceClosure close_callback_;
size_t response_callback_next_id_ = 0;
std::optional<GURL> base_url_;
base::WeakPtrFactory<SafeWebBundleParser> weak_factory_{this};
};
}
#endif