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