#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H
#define GRPC_CORE_LIB_TRANSPORT_METADATA_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/slice.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/useful.h"
extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata;
typedef struct grpc_mdelem grpc_mdelem;
typedef struct grpc_mdelem_data {
const grpc_slice key;
const grpc_slice value;
} grpc_mdelem_data;
#define GRPC_MDELEM_STORAGE_INTERNED_BIT 1
typedef enum {
GRPC_MDELEM_STORAGE_EXTERNAL = 0,
GRPC_MDELEM_STORAGE_INTERNED = GRPC_MDELEM_STORAGE_INTERNED_BIT,
GRPC_MDELEM_STORAGE_ALLOCATED = 2,
GRPC_MDELEM_STORAGE_STATIC = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT,
} grpc_mdelem_data_storage;
struct grpc_mdelem {
uintptr_t payload;
};
#define GRPC_MDELEM_DATA(md) ((grpc_mdelem_data*)((md).payload & ~(uintptr_t)3))
#define GRPC_MDELEM_STORAGE(md) \
((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3))
#ifdef __cplusplus
#define GRPC_MAKE_MDELEM(data, storage) \
(grpc_mdelem{((uintptr_t)(data)) | ((uintptr_t)storage)})
#else
#define GRPC_MAKE_MDELEM(data, storage) \
((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)})
#endif
#define GRPC_MDELEM_IS_INTERNED(md) \
((grpc_mdelem_data_storage)((md).payload & \
(uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
const grpc_slice& value);
grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata);
grpc_mdelem grpc_mdelem_create(
const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store);
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*));
void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*),
void* user_data);
#ifndef NDEBUG
#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__)
grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char* file, int line);
void grpc_mdelem_unref(grpc_mdelem md, const char* file, int line);
#else
#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s))
grpc_mdelem grpc_mdelem_ref(grpc_mdelem md);
void grpc_mdelem_unref(grpc_mdelem md);
#endif
#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key)
#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value)
#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL)
#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
#define GRPC_MDELEM_LENGTH(e) \
(GRPC_SLICE_LENGTH(GRPC_MDKEY((e))) + GRPC_SLICE_LENGTH(GRPC_MDVALUE((e))) + \
32)
#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
void grpc_mdctx_global_init(void);
void grpc_mdctx_global_shutdown();
#endif