/* * Copyright (c) Microsoft Corporation * SPDX-License-Identifier: MIT */ #pragma once #include #include #include typedef enum class _tlv_type { BLOB, UINT, INT, STRING, SEQUENCE } tlv_type_t; typedef struct _tlv_type_length_value { uint16_t type : 16; uint16_t length : 16; unsigned char value[1]; } tlv_type_length_value_t; typedef std::vector> tlv_sequence; template inline std::vector tlv_pack(const data_type_t& data) { tlv_type_length_value_t* header; std::vector retval; if constexpr (std::is_same::value) { retval.resize(offsetof(tlv_type_length_value_t, value)); for (const auto& v : data) { retval.insert(retval.end(), v.begin(), v.end()); } header = reinterpret_cast(retval.data()); header->type = static_cast(tlv_type_t::SEQUENCE); header->length = retval.size(); } else if constexpr (std::is_same>::value) { retval.resize(offsetof(tlv_type_length_value_t, value)); retval.insert(retval.end(), data.begin(), data.end()); header = reinterpret_cast(retval.data()); header->type = static_cast(tlv_type_t::BLOB); header->length = retval.size(); } else if constexpr (std::is_same::value) { size_t string_length = strlen(data); retval.resize(offsetof(tlv_type_length_value_t, value) + string_length); header = reinterpret_cast(retval.data()); header->type = static_cast(tlv_type_t::STRING); header->length = retval.size(); memcpy(header->value, data, string_length); } else { retval.resize(offsetof(tlv_type_length_value_t, value) + sizeof(data)); header = reinterpret_cast(retval.data()); header->type = static_cast(tlv_type_t::UINT); header->length = retval.size(); memcpy(header->value, &data, sizeof(data)); } return retval; } inline const tlv_type_length_value_t* tlv_next(const tlv_type_length_value_t* current_tlv) { return reinterpret_cast( reinterpret_cast(current_tlv) + current_tlv->length); } inline const tlv_type_length_value_t* tlv_child(const tlv_type_length_value_t* current_tlv) { return reinterpret_cast(current_tlv->value); } template inline inner_type tlv_value(const tlv_type_length_value_t* tlv) { if constexpr (std::is_same::value) { std::string value; value.insert( 0, reinterpret_cast(tlv->value), tlv->length - offsetof(tlv_type_length_value_t, value)); return value; } else { return *reinterpret_cast(tlv->value); } }