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_VECTOR_H
1717fd14ceSopenharmony_ci#define HC_VECTOR_H
1817fd14ceSopenharmony_ci
1917fd14ceSopenharmony_ci#include "hc_parcel.h"
2017fd14ceSopenharmony_ci#include "securec.h"
2117fd14ceSopenharmony_ci
2217fd14ceSopenharmony_ci/*
2317fd14ceSopenharmony_ci * Use DECLARE_HC_VECTOR to declare the vector in the head/src file.
2417fd14ceSopenharmony_ci * @para ClassName: the name of the vector-class/vector-struct
2517fd14ceSopenharmony_ci * @para Element: the type of the vector element
2617fd14ceSopenharmony_ci * @for example:
2717fd14ceSopenharmony_ci * DECLARE_HC_VECTOR(IntVec, int)
2817fd14ceSopenharmony_ci */
2917fd14ceSopenharmony_ci#define DECLARE_HC_VECTOR(ClassName, Element) \
3017fd14ceSopenharmony_citypedef struct V##ClassName{ \
3117fd14ceSopenharmony_ci    Element* (*pushBack)(struct V##ClassName*, const Element*); \
3217fd14ceSopenharmony_ci    Element* (*pushBackT)(struct V##ClassName*, Element); \
3317fd14ceSopenharmony_ci    HcBool (*popFront)(struct V##ClassName*, Element*); \
3417fd14ceSopenharmony_ci    HcBool (*eraseElement)(struct V##ClassName*, Element*, uint32_t index); \
3517fd14ceSopenharmony_ci    uint32_t (*size)(const struct V##ClassName*); \
3617fd14ceSopenharmony_ci    Element (*get)(const struct V##ClassName*, uint32_t index); \
3717fd14ceSopenharmony_ci    Element* (*getp)(const struct V##ClassName*, uint32_t index); \
3817fd14ceSopenharmony_ci    void (*clear)(struct V##ClassName*); \
3917fd14ceSopenharmony_ci    HcParcel parcel; \
4017fd14ceSopenharmony_ci} ClassName;
4117fd14ceSopenharmony_ci
4217fd14ceSopenharmony_ci/*
4317fd14ceSopenharmony_ci * Use IMPLEMENT_HC_VECTOR to implement the vector in the source file.
4417fd14ceSopenharmony_ci * @para ClassName: the name of the vector-class/vector-struct
4517fd14ceSopenharmony_ci * @para Element: the type of the vector element
4617fd14ceSopenharmony_ci * @para allocCount: the minimum alloc count
4717fd14ceSopenharmony_ci * @for example:
4817fd14ceSopenharmony_ci * IMPLEMENT_HC_VECTOR(IntVec, int)
4917fd14ceSopenharmony_ci */
5017fd14ceSopenharmony_ci#define IMPLEMENT_HC_VECTOR(ClassName, Element, allocCount) \
5117fd14ceSopenharmony_ciElement* VPushBack##ClassName(ClassName* obj, const Element *e) { \
5217fd14ceSopenharmony_ci    if (obj == NULL || e == NULL) { \
5317fd14ceSopenharmony_ci        return NULL; \
5417fd14ceSopenharmony_ci    } \
5517fd14ceSopenharmony_ci      \
5617fd14ceSopenharmony_ci    if (ParcelWrite(&obj->parcel, e, sizeof(Element))) { \
5717fd14ceSopenharmony_ci        uint32_t size = obj->size(obj); \
5817fd14ceSopenharmony_ci        return obj->getp(obj, size - 1); \
5917fd14ceSopenharmony_ci    } else { \
6017fd14ceSopenharmony_ci        return NULL; \
6117fd14ceSopenharmony_ci    } \
6217fd14ceSopenharmony_ci} \
6317fd14ceSopenharmony_ciElement* VPushBackT##ClassName(ClassName* obj, Element e) { \
6417fd14ceSopenharmony_ci    if (obj == NULL) { \
6517fd14ceSopenharmony_ci        return NULL; \
6617fd14ceSopenharmony_ci    } \
6717fd14ceSopenharmony_ci      \
6817fd14ceSopenharmony_ci    if (ParcelWrite(&obj->parcel, &e, sizeof(Element))) { \
6917fd14ceSopenharmony_ci        uint32_t size = obj->size(obj); \
7017fd14ceSopenharmony_ci        return obj->getp(obj, size - 1); \
7117fd14ceSopenharmony_ci    } else { \
7217fd14ceSopenharmony_ci        return NULL; \
7317fd14ceSopenharmony_ci    } \
7417fd14ceSopenharmony_ci} \
7517fd14ceSopenharmony_ciHcBool VPopFront##ClassName(ClassName* obj, Element* e) { \
7617fd14ceSopenharmony_ci        if (NULL == obj || NULL == e) { \
7717fd14ceSopenharmony_ci            return HC_FALSE; \
7817fd14ceSopenharmony_ci        } \
7917fd14ceSopenharmony_ci        if (obj->size(obj) > 0) { \
8017fd14ceSopenharmony_ci            return ParcelRead(&obj->parcel, e, sizeof(Element)); \
8117fd14ceSopenharmony_ci        } else { \
8217fd14ceSopenharmony_ci            return HC_FALSE; \
8317fd14ceSopenharmony_ci        } \
8417fd14ceSopenharmony_ci} \
8517fd14ceSopenharmony_ciHcBool VErase##ClassName(ClassName* obj, Element* e, uint32_t index) { \
8617fd14ceSopenharmony_ci        if (NULL == obj || NULL == e || index + 1 > obj->size(obj)) { \
8717fd14ceSopenharmony_ci            return HC_FALSE; \
8817fd14ceSopenharmony_ci        } \
8917fd14ceSopenharmony_ci        if (obj->size(obj) > 0) { \
9017fd14ceSopenharmony_ci            return ParcelEraseBlock(&obj->parcel, index * sizeof(Element), sizeof(Element), e); \
9117fd14ceSopenharmony_ci        } else { \
9217fd14ceSopenharmony_ci            return HC_FALSE; \
9317fd14ceSopenharmony_ci        } \
9417fd14ceSopenharmony_ci} \
9517fd14ceSopenharmony_ciuint32_t VSize##ClassName(const ClassName* obj) \
9617fd14ceSopenharmony_ci{ \
9717fd14ceSopenharmony_ci    if (NULL == obj) { \
9817fd14ceSopenharmony_ci        return 0; \
9917fd14ceSopenharmony_ci    } \
10017fd14ceSopenharmony_ci    return GetParcelDataSize(&obj->parcel) / sizeof(Element); \
10117fd14ceSopenharmony_ci} \
10217fd14ceSopenharmony_ciElement VGet##ClassName(const ClassName* obj, uint32_t index) \
10317fd14ceSopenharmony_ci{ \
10417fd14ceSopenharmony_ci    Element e; \
10517fd14ceSopenharmony_ci    (void)memset_s(&e, sizeof(e), 0, sizeof(e)); \
10617fd14ceSopenharmony_ci    if (NULL != obj) { \
10717fd14ceSopenharmony_ci        if (index < obj->size(obj)) { \
10817fd14ceSopenharmony_ci            if (GetParcelData(&obj->parcel)) { \
10917fd14ceSopenharmony_ci                return *((Element*)(GetParcelData(&obj->parcel)) + index); \
11017fd14ceSopenharmony_ci            } else { \
11117fd14ceSopenharmony_ci                return e; \
11217fd14ceSopenharmony_ci            } \
11317fd14ceSopenharmony_ci        } \
11417fd14ceSopenharmony_ci    } \
11517fd14ceSopenharmony_ci    (void)memset_s(&e, sizeof(e), 0, sizeof(e)); \
11617fd14ceSopenharmony_ci    return e; \
11717fd14ceSopenharmony_ci} \
11817fd14ceSopenharmony_ciElement* VGetPointer##ClassName(const ClassName* obj, uint32_t index) \
11917fd14ceSopenharmony_ci{ \
12017fd14ceSopenharmony_ci    if (NULL != obj) { \
12117fd14ceSopenharmony_ci        if (index < obj->size(obj)) { \
12217fd14ceSopenharmony_ci            if (GetParcelData(&obj->parcel)) { \
12317fd14ceSopenharmony_ci                return ((Element*)(GetParcelData(&obj->parcel)) + index); \
12417fd14ceSopenharmony_ci            } else { \
12517fd14ceSopenharmony_ci                return NULL; \
12617fd14ceSopenharmony_ci            } \
12717fd14ceSopenharmony_ci        } \
12817fd14ceSopenharmony_ci    } \
12917fd14ceSopenharmony_ci    return NULL; \
13017fd14ceSopenharmony_ci} \
13117fd14ceSopenharmony_civoid VClear##ClassName(ClassName* obj) \
13217fd14ceSopenharmony_ci{ \
13317fd14ceSopenharmony_ci    if (NULL != obj) { \
13417fd14ceSopenharmony_ci        ClearParcel(&obj->parcel); \
13517fd14ceSopenharmony_ci    } \
13617fd14ceSopenharmony_ci} \
13717fd14ceSopenharmony_ciClassName Create##ClassName(void) \
13817fd14ceSopenharmony_ci{ \
13917fd14ceSopenharmony_ci    ClassName obj; \
14017fd14ceSopenharmony_ci    obj.pushBack = VPushBack##ClassName; \
14117fd14ceSopenharmony_ci    obj.pushBackT = VPushBackT##ClassName; \
14217fd14ceSopenharmony_ci    obj.popFront = VPopFront##ClassName; \
14317fd14ceSopenharmony_ci    obj.clear = VClear##ClassName; \
14417fd14ceSopenharmony_ci    obj.eraseElement = VErase##ClassName; \
14517fd14ceSopenharmony_ci    obj.size = VSize##ClassName; \
14617fd14ceSopenharmony_ci    obj.get = VGet##ClassName; \
14717fd14ceSopenharmony_ci    obj.getp = VGetPointer##ClassName; \
14817fd14ceSopenharmony_ci    obj.parcel = CreateParcel(0, sizeof(Element) * allocCount); \
14917fd14ceSopenharmony_ci    return obj; \
15017fd14ceSopenharmony_ci} \
15117fd14ceSopenharmony_civoid Destroy##ClassName(ClassName* obj) \
15217fd14ceSopenharmony_ci{ \
15317fd14ceSopenharmony_ci    if (NULL != obj) { \
15417fd14ceSopenharmony_ci        DeleteParcel(&obj->parcel); \
15517fd14ceSopenharmony_ci    } \
15617fd14ceSopenharmony_ci}
15717fd14ceSopenharmony_ci
15817fd14ceSopenharmony_ci/* Use these two macros to create and destroy vector */
15917fd14ceSopenharmony_ci#define CREATE_HC_VECTOR(classname) Create##classname()
16017fd14ceSopenharmony_ci#define DESTROY_HC_VECTOR(classname, obj) Destroy##classname(obj)
16117fd14ceSopenharmony_ci
16217fd14ceSopenharmony_ci#define FOR_EACH_HC_VECTOR(vec, index, iter) for (index = 0; index < (vec).size(&(vec)) && \
16317fd14ceSopenharmony_ci    (iter = (vec).getp(&(vec), index)); ++index)
16417fd14ceSopenharmony_ci
16517fd14ceSopenharmony_ci#define HC_VECTOR_PUSHBACK(obj, element) (obj)->pushBack((obj), (element))
16617fd14ceSopenharmony_ci#define HC_VECTOR_POPFRONT(obj, element) (obj)->popFront((obj), (element))
16717fd14ceSopenharmony_ci#define HC_VECTOR_POPELEMENT(obj, element, index) (obj)->eraseElement((obj), (element), (index))
16817fd14ceSopenharmony_ci#define HC_VECTOR_SIZE(obj) (obj)->size(obj)
16917fd14ceSopenharmony_ci#define HC_VECTOR_GET(obj, index) (obj)->get((obj), (index))
17017fd14ceSopenharmony_ci#define HC_VECTOR_GETP(_obj, _index) (_obj)->getp((_obj), (_index))
17117fd14ceSopenharmony_ci
17217fd14ceSopenharmony_ci#endif
173