blob: d1cf06150ba9e68e3b1dd27e9418417b733ef368 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TRUNKS_TPM_STRUCTURE_PARSER_H_
#define TRUNKS_TPM_STRUCTURE_PARSER_H_
#include <string>
#include "trunks/tpm_generated.h"
#include "trunks/trunks_export.h"
// HOW TO USE: See the comment of the class `TpmStructureParser`.
namespace trunks {
// Internal implementation of the arbitrary parser.
// DO NOT USE ANYTHING INSIDE DIRECTLY.
namespace internal {
template <typename Type>
class TRUNKS_EXPORT TpmStructureSingleParserImpl {
public:
explicit TpmStructureSingleParserImpl(std::string& payload)
: payload_(payload) {}
TPM_RC Parse(Type& out) const;
private:
std::string& payload_;
};
template <typename... Types>
class TRUNKS_EXPORT TpmStructureParserImpl;
template <typename FirstType, typename... Types>
class TRUNKS_EXPORT TpmStructureParserImpl<FirstType, Types...> {
public:
explicit TpmStructureParserImpl(std::string& payload) : payload_(payload) {}
TPM_RC Parse(FirstType& first_out, Types&... outs) const {
TPM_RC rc =
TpmStructureSingleParserImpl<FirstType>(payload_).Parse(first_out);
if (rc) {
return rc;
}
return TpmStructureParserImpl<Types...>(payload_).Parse(outs...);
}
private:
std::string& payload_;
};
template <>
class TRUNKS_EXPORT TpmStructureParserImpl<> {
public:
explicit TpmStructureParserImpl(std::string& /*payload*/) {}
TPM_RC Parse() const { return TPM_RC_SUCCESS; }
};
} // namespace internal
// A parser class that provides the unified `Parse()` interface that deisnged to
// unify the `trunks::Parse_TYPE(std::string*,TYPE*,std::string*)`.
// For the example of the parser, see the unittests.
// For the example of adding a supported type for parsing, seethe macro
// `__TRUNKS_TPM_STRUCTURE_PARSER_DEFINE_PARSE_SINGLE` in the source file.
class TRUNKS_EXPORT TpmStructureParser {
public:
// Copies `payload` into `payload_` for further use.
explicit TpmStructureParser(const std::string& payload);
// Consumes `payload_` and parses it into `outs...` in sequence.
template <typename... Types>
TPM_RC Parse(Types&... outs) {
return internal::TpmStructureParserImpl<Types...>(payload_).Parse(outs...);
}
// Gets the current `payload_`. It is useful to check there is unexpected
// leftover, for example.
std::string payload() { return payload_; }
private:
std::string payload_;
};
} // namespace trunks
#endif // TRUNKS_TPM_STRUCTURE_PARSER_H_