/* * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef RTC_BASE_EXPERIMENTS_STRUCT_PARAMETERS_PARSER_H_ #define RTC_BASE_EXPERIMENTS_STRUCT_PARAMETERS_PARSER_H_ #include #include #include #include #include #include #include "absl/memory/memory.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/string_encode.h" namespace webrtc { namespace struct_parser_impl { struct TypedMemberParser { public: bool (*parse)(const absl::string_view src, void* target); void (*encode)(const void* src, std::string* target); }; struct MemberParameter { const char* key; void* member_ptr; TypedMemberParser parser; }; template class TypedParser { public: static bool Parse(absl::string_view src, void* target); static void Encode(const void* src, std::string* target); }; // Instantiated in cc file to avoid duplication during compile. Add additional // parsers as needed. Generally, try to use these suggested types even if the // context where the value is used might require a different type. For instance, // a size_t representing a packet size should use an int parameter as there's no // need to support packet sizes larger than INT32_MAX. extern template class TypedParser; extern template class TypedParser; extern template class TypedParser; extern template class TypedParser; extern template class TypedParser>; extern template class TypedParser>; extern template class TypedParser>; extern template class TypedParser; extern template class TypedParser; extern template class TypedParser; extern template class TypedParser>; extern template class TypedParser>; extern template class TypedParser>; template void AddMembers(MemberParameter* out, const char* key, T* member) { *out = MemberParameter{ key, member, TypedMemberParser{&TypedParser::Parse, &TypedParser::Encode}}; } template void AddMembers(MemberParameter* out, const char* key, T* member, Args... args) { AddMembers(out, key, member); AddMembers(++out, args...); } } // namespace struct_parser_impl class StructParametersParser { public: template static std::unique_ptr Create(const char* first_key, T* first_member, Args... args) { std::vector members( sizeof...(args) / 2 + 1); struct_parser_impl::AddMembers(&members.front(), std::move(first_key), first_member, args...); return absl::WrapUnique(new StructParametersParser(std::move(members))); } void Parse(absl::string_view src); std::string Encode() const; private: explicit StructParametersParser( std::vector members); std::vector members_; }; } // namespace webrtc #endif // RTC_BASE_EXPERIMENTS_STRUCT_PARAMETERS_PARSER_H_