117fd14ceSopenharmony_ci/*
217fd14ceSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
317fd14ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
417fd14ceSopenharmony_ci * you may not use this file except in compliance with the License.
517fd14ceSopenharmony_ci * You may obtain a copy of the License at
617fd14ceSopenharmony_ci *
717fd14ceSopenharmony_ci *    http://www.apache.org/licenses/LICENSE-2.0
817fd14ceSopenharmony_ci *
917fd14ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1017fd14ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1117fd14ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1217fd14ceSopenharmony_ci * See the License for the specific language governing permissions and
1317fd14ceSopenharmony_ci * limitations under the License.
1417fd14ceSopenharmony_ci */
1517fd14ceSopenharmony_ci
1617fd14ceSopenharmony_ci#ifndef HC_TLV_PARSER_H
1717fd14ceSopenharmony_ci#define HC_TLV_PARSER_H
1817fd14ceSopenharmony_ci
1917fd14ceSopenharmony_ci#include <hc_parcel.h>
2017fd14ceSopenharmony_ci#include <hc_vector.h>
2117fd14ceSopenharmony_ci#include <hc_string.h>
2217fd14ceSopenharmony_ci
2317fd14ceSopenharmony_ci#ifdef __cplusplus
2417fd14ceSopenharmony_ciextern "C" {
2517fd14ceSopenharmony_ci#endif
2617fd14ceSopenharmony_ci
2717fd14ceSopenharmony_ci#define USE_DEFAULT_TAG 0xFFFF
2817fd14ceSopenharmony_ci#define TLV_FAIL (-1)
2917fd14ceSopenharmony_ci#define NO_REVERT 0
3017fd14ceSopenharmony_ci#define NEED_REVERT 1
3117fd14ceSopenharmony_ci#define MAX_TOTOL_LEN (100 * 1024 * 1024)
3217fd14ceSopenharmony_ci
3317fd14ceSopenharmony_citypedef struct TlvBaseT {
3417fd14ceSopenharmony_ci    unsigned short tag;
3517fd14ceSopenharmony_ci    unsigned short length;
3617fd14ceSopenharmony_ci    unsigned short checkTag;
3717fd14ceSopenharmony_ci    unsigned short hasValue;
3817fd14ceSopenharmony_ci    int32_t (*parse)(struct TlvBaseT *, HcParcel *, HcBool);
3917fd14ceSopenharmony_ci    int32_t (*getlen)(struct TlvBaseT *);
4017fd14ceSopenharmony_ci    int32_t (*encode)(struct TlvBaseT *, HcParcel *);
4117fd14ceSopenharmony_ci    void (*deinit)(struct TlvBaseT *);
4217fd14ceSopenharmony_ci} TlvBase;
4317fd14ceSopenharmony_ci
4417fd14ceSopenharmony_ci#define DECLARE_TLV_STRUCT(x) \
4517fd14ceSopenharmony_ci    TlvBase base; \
4617fd14ceSopenharmony_ci    unsigned int offsetCount; \
4717fd14ceSopenharmony_ci    unsigned int offset[x];
4817fd14ceSopenharmony_ci
4917fd14ceSopenharmony_ciunsigned short GetTag(unsigned short checkTag, unsigned short defaultTag);
5017fd14ceSopenharmony_ci
5117fd14ceSopenharmony_ci#define BEGIN_TLV_STRUCT_DEFINE(TlvS, CheckTag) \
5217fd14ceSopenharmony_civoid Init##TlvS(TlvS *tlv, unsigned short checkTag) \
5317fd14ceSopenharmony_ci{ \
5417fd14ceSopenharmony_ci    typedef TlvS TlvStructType; \
5517fd14ceSopenharmony_ci    unsigned int index = 0; \
5617fd14ceSopenharmony_ci    (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
5717fd14ceSopenharmony_ci    tlv->base.checkTag = GetTag(checkTag, CheckTag);
5817fd14ceSopenharmony_ci
5917fd14ceSopenharmony_ci#define TLV_MEMBER_OPTION(TlvMember, TlvMemberName, CheckTag) \
6017fd14ceSopenharmony_ci    Init##TlvMember(&tlv->TlvMemberName, CheckTag); \
6117fd14ceSopenharmony_ci    tlv->TlvMemberName.base.option = 1; \
6217fd14ceSopenharmony_ci    tlv->offset[index++] = offsetof(TlvStructType, TlvMemberName);
6317fd14ceSopenharmony_ci
6417fd14ceSopenharmony_ci#define TLV_MEMBER(TlvMember, TlvMemberName, CheckTag) \
6517fd14ceSopenharmony_ci    Init##TlvMember(&tlv->TlvMemberName, CheckTag); \
6617fd14ceSopenharmony_ci    tlv->offset[index++] = offsetof(TlvStructType, TlvMemberName);
6717fd14ceSopenharmony_ci
6817fd14ceSopenharmony_ci#define END_TLV_STRUCT_DEFINE(void) \
6917fd14ceSopenharmony_ci    tlv->offsetCount = index; \
7017fd14ceSopenharmony_ci    tlv->base.parse = ParseTlvStruct; \
7117fd14ceSopenharmony_ci    tlv->base.getlen = GetLenTlvStruct; \
7217fd14ceSopenharmony_ci    tlv->base.encode = EncodeTlvStruct; \
7317fd14ceSopenharmony_ci    tlv->base.deinit = DeinitTlvStruct; \
7417fd14ceSopenharmony_ci}
7517fd14ceSopenharmony_ci
7617fd14ceSopenharmony_ci#define DECLARE_TLV_FIX_LENGTH_TYPE(TlvName, TypeName) \
7717fd14ceSopenharmony_citypedef struct \
7817fd14ceSopenharmony_ci{ \
7917fd14ceSopenharmony_ci    TlvBase base; \
8017fd14ceSopenharmony_ci    TypeName data; \
8117fd14ceSopenharmony_ci} TlvName;
8217fd14ceSopenharmony_ci
8317fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvInt32, int)
8417fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvInt16, short)
8517fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvInt8, char)
8617fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvUint32, uint32_t)
8717fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvUint16, uint16_t)
8817fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvUint8, uint8_t)
8917fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvUint64, uint64_t)
9017fd14ceSopenharmony_ciDECLARE_TLV_FIX_LENGTH_TYPE(TlvInt64, uint64_t)
9117fd14ceSopenharmony_ci
9217fd14ceSopenharmony_ci#define DEFINE_TLV_FIX_LENGTH_TYPE(TlvName, Revert) \
9317fd14ceSopenharmony_ciint32_t ParseTlv##TlvName(TlvBase *tlv, HcParcel *parcel, HcBool strict) \
9417fd14ceSopenharmony_ci{ \
9517fd14ceSopenharmony_ci    (void)strict; \
9617fd14ceSopenharmony_ci    TlvName *realTlv = (TlvName *)(tlv); \
9717fd14ceSopenharmony_ci    HcBool readRet = HC_FALSE; \
9817fd14ceSopenharmony_ci    if (tlv->length != sizeof(realTlv->data)) \
9917fd14ceSopenharmony_ci    { \
10017fd14ceSopenharmony_ci        return TLV_FAIL; \
10117fd14ceSopenharmony_ci    } \
10217fd14ceSopenharmony_ci\
10317fd14ceSopenharmony_ci    if (Revert) \
10417fd14ceSopenharmony_ci    { \
10517fd14ceSopenharmony_ci        readRet = ParcelReadRevert(parcel, &realTlv->data, sizeof(realTlv->data)); \
10617fd14ceSopenharmony_ci    } else { \
10717fd14ceSopenharmony_ci        readRet = ParcelRead(parcel, &realTlv->data, sizeof(realTlv->data)); \
10817fd14ceSopenharmony_ci    } \
10917fd14ceSopenharmony_ci    if (readRet) \
11017fd14ceSopenharmony_ci    { \
11117fd14ceSopenharmony_ci        return tlv->length; \
11217fd14ceSopenharmony_ci    } else { \
11317fd14ceSopenharmony_ci        return TLV_FAIL; \
11417fd14ceSopenharmony_ci    } \
11517fd14ceSopenharmony_ci} \
11617fd14ceSopenharmony_ci\
11717fd14ceSopenharmony_ciint32_t GetLenTlv##TlvName(TlvBase *tlv) \
11817fd14ceSopenharmony_ci{ \
11917fd14ceSopenharmony_ci    TlvName *realTlv = (TlvName *)(tlv); \
12017fd14ceSopenharmony_ci    return (int32_t)sizeof(realTlv->data); \
12117fd14ceSopenharmony_ci} \
12217fd14ceSopenharmony_ci\
12317fd14ceSopenharmony_ciint32_t EncodeTlv##TlvName(TlvBase *tlv, HcParcel *parcel) \
12417fd14ceSopenharmony_ci{ \
12517fd14ceSopenharmony_ci    HcBool writeRet = HC_FALSE; \
12617fd14ceSopenharmony_ci    TlvName *realTlv = (TlvName *)(tlv); \
12717fd14ceSopenharmony_ci    if (Revert) \
12817fd14ceSopenharmony_ci    { \
12917fd14ceSopenharmony_ci        writeRet = ParcelWriteRevert(parcel, &realTlv->data, sizeof(realTlv->data)); \
13017fd14ceSopenharmony_ci    } else { \
13117fd14ceSopenharmony_ci        writeRet = ParcelWrite(parcel, &realTlv->data, sizeof(realTlv->data)); \
13217fd14ceSopenharmony_ci    } \
13317fd14ceSopenharmony_ci    if (writeRet) \
13417fd14ceSopenharmony_ci    { \
13517fd14ceSopenharmony_ci        return sizeof(realTlv->data); \
13617fd14ceSopenharmony_ci    } else { \
13717fd14ceSopenharmony_ci        return TLV_FAIL; \
13817fd14ceSopenharmony_ci    } \
13917fd14ceSopenharmony_ci} \
14017fd14ceSopenharmony_ci\
14117fd14ceSopenharmony_ciDECLARE_TLV_PARSE_FUNC(TlvName, ParseTlv##TlvName, GetLenTlv##TlvName, EncodeTlv##TlvName);
14217fd14ceSopenharmony_ci
14317fd14ceSopenharmony_civoid DeinitTlvFixMember(TlvBase *tlv);
14417fd14ceSopenharmony_ci
14517fd14ceSopenharmony_ci#define DECLARE_TLV_PARSE_FUNC(TlvName, TlvParseFunc, TlvGetLenFunc, TlvEncodeFunc) \
14617fd14ceSopenharmony_civoid Init##TlvName(TlvName *tlv, unsigned short checkTag) \
14717fd14ceSopenharmony_ci{ \
14817fd14ceSopenharmony_ci    (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
14917fd14ceSopenharmony_ci    tlv->base.parse = TlvParseFunc; \
15017fd14ceSopenharmony_ci    tlv->base.getlen = TlvGetLenFunc; \
15117fd14ceSopenharmony_ci    tlv->base.encode = TlvEncodeFunc; \
15217fd14ceSopenharmony_ci    tlv->base.deinit = DeinitTlvFixMember; \
15317fd14ceSopenharmony_ci    tlv->base.checkTag = checkTag; \
15417fd14ceSopenharmony_ci}
15517fd14ceSopenharmony_ci
15617fd14ceSopenharmony_ci#define TLV_INIT(TlvName, TlvData) Init##TlvName(TlvData, USE_DEFAULT_TAG);
15717fd14ceSopenharmony_ci
15817fd14ceSopenharmony_ci#define TLV_DEINIT(TlvData) TlvData.base.deinit((TlvBase *)(&TlvData));
15917fd14ceSopenharmony_citypedef struct {
16017fd14ceSopenharmony_ci    TlvBase base;
16117fd14ceSopenharmony_ci    unsigned int offsetCount;
16217fd14ceSopenharmony_ci    unsigned int offset[0];
16317fd14ceSopenharmony_ci} TlvOffsetExample;
16417fd14ceSopenharmony_ci
16517fd14ceSopenharmony_ciHcBool ParseTlvHead(TlvBase *tlv, HcParcel *parcel);
16617fd14ceSopenharmony_ciint32_t ParseTlvNode(TlvBase *tlv, HcParcel *parcel, HcBool strict);
16717fd14ceSopenharmony_ciint32_t GetlenTlvNode(TlvBase *tlv);
16817fd14ceSopenharmony_civoid DeinitTlvNode(TlvBase *tlv);
16917fd14ceSopenharmony_ci
17017fd14ceSopenharmony_ciint32_t ParseTlvStruct(TlvBase *tlv, HcParcel *parcel, HcBool strict);
17117fd14ceSopenharmony_ciint32_t EncodeTlvStruct(TlvBase *tlv, HcParcel *parcel);
17217fd14ceSopenharmony_ciint32_t GetLenTlvStruct(TlvBase *tlv);
17317fd14ceSopenharmony_civoid DeinitTlvStruct(TlvBase *tlv);
17417fd14ceSopenharmony_ciint32_t EncodeTlvNode(TlvBase *tlv, HcParcel *parcel, HcBool isRoot);
17517fd14ceSopenharmony_ciHcBool DecodeTlvMessage(TlvBase *msg, HcParcel *parcel, HcBool strict);
17617fd14ceSopenharmony_ciHcBool EncodeTlvMessage(TlvBase *msg, HcParcel *parcel);
17717fd14ceSopenharmony_ci
17817fd14ceSopenharmony_citypedef struct {
17917fd14ceSopenharmony_ci    TlvBase base;
18017fd14ceSopenharmony_ci    HcParcel data;
18117fd14ceSopenharmony_ci} TlvBuffer;
18217fd14ceSopenharmony_ci
18317fd14ceSopenharmony_civoid InitTlvBuffer(TlvBuffer *tlv, unsigned short checkTag);
18417fd14ceSopenharmony_ciint32_t ParseTlvBuffer(TlvBase *tlv, HcParcel *parcel, HcBool strict);
18517fd14ceSopenharmony_ciint32_t GetlenTlvBuffer(TlvBase *tlv);
18617fd14ceSopenharmony_ciint32_t EncodeTlvBuffer(TlvBase *tlv, HcParcel *parcel);
18717fd14ceSopenharmony_civoid DeinitTlvBuffer(TlvBase *tlv);
18817fd14ceSopenharmony_ci
18917fd14ceSopenharmony_citypedef struct {
19017fd14ceSopenharmony_ci    TlvBase base;
19117fd14ceSopenharmony_ci    HcString data;
19217fd14ceSopenharmony_ci} TlvString;
19317fd14ceSopenharmony_ci
19417fd14ceSopenharmony_civoid InitTlvString(TlvString *tlv, unsigned short checkTag);
19517fd14ceSopenharmony_ciint32_t ParseTlvString(TlvBase *tlv, HcParcel *parcel, HcBool strict);
19617fd14ceSopenharmony_ciint32_t GetlenTlvString(TlvBase *tlv);
19717fd14ceSopenharmony_ciint32_t EncodeTlvString(TlvBase *tlv, HcParcel *parcel);
19817fd14ceSopenharmony_civoid DeinitTlvString(TlvBase *tlv);
19917fd14ceSopenharmony_ci
20017fd14ceSopenharmony_ci#define DECLEAR_INIT_FUNC(TlvStruct) \
20117fd14ceSopenharmony_civoid Init##TlvStruct(TlvStruct *tlv, unsigned short checkTag);
20217fd14ceSopenharmony_ci
20317fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvUint64)
20417fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvUint32)
20517fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvUint16)
20617fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvUint8)
20717fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvInt64)
20817fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvInt32)
20917fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvInt16)
21017fd14ceSopenharmony_ciDECLEAR_INIT_FUNC(TlvInt8)
21117fd14ceSopenharmony_ci
21217fd14ceSopenharmony_ci#define DECLARE_TLV_VECTOR(TlvVecName, TlvVecElement) \
21317fd14ceSopenharmony_ciDECLARE_HC_VECTOR(Vec##TlvVecName, TlvVecElement) \
21417fd14ceSopenharmony_citypedef struct { \
21517fd14ceSopenharmony_ci    TlvBase base; \
21617fd14ceSopenharmony_ci    Vec##TlvVecName data; \
21717fd14ceSopenharmony_ci} TlvVecName; \
21817fd14ceSopenharmony_civoid DeinitTlv##TlvVecName(TlvBase *tlv); \
21917fd14ceSopenharmony_civoid Init##TlvVecName(TlvVecName *tlv, unsigned short checkTag);
22017fd14ceSopenharmony_ci
22117fd14ceSopenharmony_ci#define IMPLEMENT_TLV_VECTOR(TlvVecName, TlvElementName, VecAllocCount) \
22217fd14ceSopenharmony_ciIMPLEMENT_HC_VECTOR(Vec##TlvVecName, TlvElementName, VecAllocCount) \
22317fd14ceSopenharmony_ciint32_t ParseTlv##TlvVecName(TlvBase *tlv, HcParcel *parcel, HcBool strict) \
22417fd14ceSopenharmony_ci{ \
22517fd14ceSopenharmony_ci    TlvVecName *realTlv = (TlvVecName *)(tlv); \
22617fd14ceSopenharmony_ci    uint32_t count = 0; \
22717fd14ceSopenharmony_ci    if (!ParcelReadUint32(parcel, &count)) { \
22817fd14ceSopenharmony_ci        return TLV_FAIL; \
22917fd14ceSopenharmony_ci    } \
23017fd14ceSopenharmony_ci    int32_t totalLen = sizeof(count); \
23117fd14ceSopenharmony_ci    uint32_t index = 0; \
23217fd14ceSopenharmony_ci    for (index = 0; index < count; ++index) { \
23317fd14ceSopenharmony_ci        TlvElementName tlvElement; \
23417fd14ceSopenharmony_ci        TlvElementName *curElement = realTlv->data.pushBack(&realTlv->data, &tlvElement); \
23517fd14ceSopenharmony_ci        if (curElement == NULL) { \
23617fd14ceSopenharmony_ci            return TLV_FAIL; \
23717fd14ceSopenharmony_ci        } \
23817fd14ceSopenharmony_ci        TLV_INIT(TlvElementName, curElement); \
23917fd14ceSopenharmony_ci\
24017fd14ceSopenharmony_ci        int32_t elementLen = ParseTlvNode((TlvBase *)curElement, parcel, strict); \
24117fd14ceSopenharmony_ci        if (elementLen < 0) { \
24217fd14ceSopenharmony_ci            return TLV_FAIL; \
24317fd14ceSopenharmony_ci        } \
24417fd14ceSopenharmony_ci        totalLen += elementLen; \
24517fd14ceSopenharmony_ci        if (totalLen >= MAX_TOTOL_LEN) { \
24617fd14ceSopenharmony_ci            return TLV_FAIL; \
24717fd14ceSopenharmony_ci        } \
24817fd14ceSopenharmony_ci    } \
24917fd14ceSopenharmony_ci\
25017fd14ceSopenharmony_ci    return totalLen; \
25117fd14ceSopenharmony_ci} \
25217fd14ceSopenharmony_ci\
25317fd14ceSopenharmony_ciint32_t EncodeTlv##TlvVecName(TlvBase *tlv, HcParcel *parcel) \
25417fd14ceSopenharmony_ci{ \
25517fd14ceSopenharmony_ci    TlvVecName *realTlv = (TlvVecName *)(tlv); \
25617fd14ceSopenharmony_ci    uint32_t index = 0; \
25717fd14ceSopenharmony_ci    TlvElementName *element = NULL; \
25817fd14ceSopenharmony_ci    int32_t totalLen = 4; \
25917fd14ceSopenharmony_ci    uint32_t count = realTlv->data.size(&realTlv->data); \
26017fd14ceSopenharmony_ci    if (!ParcelWriteUint32(parcel, count)) { \
26117fd14ceSopenharmony_ci        return TLV_FAIL; \
26217fd14ceSopenharmony_ci    } \
26317fd14ceSopenharmony_ci\
26417fd14ceSopenharmony_ci    FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
26517fd14ceSopenharmony_ci        if (element != NULL) { \
26617fd14ceSopenharmony_ci            int32_t len = EncodeTlvNode((TlvBase *)element, parcel, HC_FALSE); \
26717fd14ceSopenharmony_ci            totalLen += len; \
26817fd14ceSopenharmony_ci            if (totalLen >= MAX_TOTOL_LEN) { \
26917fd14ceSopenharmony_ci                return TLV_FAIL; \
27017fd14ceSopenharmony_ci            } \
27117fd14ceSopenharmony_ci        } \
27217fd14ceSopenharmony_ci    } \
27317fd14ceSopenharmony_ci    return totalLen; \
27417fd14ceSopenharmony_ci} \
27517fd14ceSopenharmony_ciint32_t GetLenTlv##TlvVecName(TlvBase *tlv) \
27617fd14ceSopenharmony_ci{ \
27717fd14ceSopenharmony_ci    TlvVecName *realTlv = (TlvVecName *)(tlv); \
27817fd14ceSopenharmony_ci    uint32_t index = 0; \
27917fd14ceSopenharmony_ci    TlvElementName *element = NULL; \
28017fd14ceSopenharmony_ci    int32_t totalLen = sizeof(int32_t); \
28117fd14ceSopenharmony_ci    FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
28217fd14ceSopenharmony_ci        if (element != NULL) { \
28317fd14ceSopenharmony_ci            totalLen += GetlenTlvNode((TlvBase *)element); \
28417fd14ceSopenharmony_ci            if (totalLen >= MAX_TOTOL_LEN) { \
28517fd14ceSopenharmony_ci                return TLV_FAIL; \
28617fd14ceSopenharmony_ci            } \
28717fd14ceSopenharmony_ci        } else { \
28817fd14ceSopenharmony_ci            return TLV_FAIL; \
28917fd14ceSopenharmony_ci        } \
29017fd14ceSopenharmony_ci    } \
29117fd14ceSopenharmony_ci    return totalLen; \
29217fd14ceSopenharmony_ci} \
29317fd14ceSopenharmony_ci\
29417fd14ceSopenharmony_civoid DeinitTlv##TlvVecName(TlvBase *tlv) \
29517fd14ceSopenharmony_ci{ \
29617fd14ceSopenharmony_ci    TlvVecName *realTlv = (TlvVecName *)(tlv); \
29717fd14ceSopenharmony_ci    uint32_t index = 0; \
29817fd14ceSopenharmony_ci    TlvElementName *element = NULL; \
29917fd14ceSopenharmony_ci    FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
30017fd14ceSopenharmony_ci        if (element != NULL) { \
30117fd14ceSopenharmony_ci            TLV_DEINIT((*element)); \
30217fd14ceSopenharmony_ci        } \
30317fd14ceSopenharmony_ci    } \
30417fd14ceSopenharmony_ci    DESTROY_HC_VECTOR(Vec##TlvVecName, &((TlvVecName *)tlv)->data); \
30517fd14ceSopenharmony_ci} \
30617fd14ceSopenharmony_ci\
30717fd14ceSopenharmony_civoid Init##TlvVecName(TlvVecName *tlv, unsigned short checkTag) \
30817fd14ceSopenharmony_ci{ \
30917fd14ceSopenharmony_ci    (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
31017fd14ceSopenharmony_ci    tlv->base.parse = ParseTlv##TlvVecName; \
31117fd14ceSopenharmony_ci    tlv->base.encode = EncodeTlv##TlvVecName; \
31217fd14ceSopenharmony_ci    tlv->base.getlen = GetLenTlv##TlvVecName; \
31317fd14ceSopenharmony_ci    tlv->base.deinit = DeinitTlv##TlvVecName; \
31417fd14ceSopenharmony_ci    tlv->base.checkTag = checkTag; \
31517fd14ceSopenharmony_ci    tlv->data = CREATE_HC_VECTOR(Vec##TlvVecName); \
31617fd14ceSopenharmony_ci}
31717fd14ceSopenharmony_ci
31817fd14ceSopenharmony_ci#ifdef __cplusplus
31917fd14ceSopenharmony_ci}
32017fd14ceSopenharmony_ci#endif
32117fd14ceSopenharmony_ci#endif
322