Files
h30013885 28ccf8e089 Fix codex.
Signed-off-by: heyinshen <heyinshen1@huawei.com>
2022-04-28 22:55:23 +08:00

173 lines
5.8 KiB
C

/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HC_VECTOR_H
#define HC_VECTOR_H
#include "hc_parcel.h"
#include "securec.h"
/*
* Use DECLARE_HC_VECTOR to declare the vector in the head/src file.
* @para ClassName: the name of the vector-class/vector-struct
* @para Element: the type of the vector element
* @for example:
* DECLARE_HC_VECTOR(IntVec, int)
*/
#define DECLARE_HC_VECTOR(ClassName, Element) \
typedef struct V##ClassName{ \
Element* (*pushBack)(struct V##ClassName*, const Element*); \
Element* (*pushBackT)(struct V##ClassName*, Element); \
HcBool (*popFront)(struct V##ClassName*, Element*); \
HcBool (*eraseElement)(struct V##ClassName*, Element*, uint32_t index); \
uint32_t (*size)(const struct V##ClassName*); \
Element (*get)(const struct V##ClassName*, uint32_t index); \
Element* (*getp)(const struct V##ClassName*, uint32_t index); \
void (*clear)(struct V##ClassName*); \
HcParcel parcel; \
} ClassName;
/*
* Use IMPLEMENT_HC_VECTOR to implement the vector in the source file.
* @para ClassName: the name of the vector-class/vector-struct
* @para Element: the type of the vector element
* @para allocCount: the minimum alloc count
* @for example:
* IMPLEMENT_HC_VECTOR(IntVec, int)
*/
#define IMPLEMENT_HC_VECTOR(ClassName, Element, allocCount) \
Element* VPushBack##ClassName(ClassName* obj, const Element *e) { \
if (obj == NULL || e == NULL) { \
return NULL; \
} \
\
if (ParcelWrite(&obj->parcel, e, sizeof(Element))) { \
uint32_t size = obj->size(obj); \
return obj->getp(obj, size-1); \
} else { \
return NULL; \
} \
} \
Element* VPushBackT##ClassName(ClassName* obj, Element e) { \
if (obj == NULL) { \
return NULL; \
} \
\
if (ParcelWrite(&obj->parcel, &e, sizeof(Element))) { \
uint32_t size = obj->size(obj); \
return obj->getp(obj, size-1); \
} else { \
return NULL; \
} \
} \
HcBool VPopFront##ClassName(ClassName* obj, Element* e) { \
if (NULL == obj || NULL == e) { \
return HC_FALSE; \
} \
if (obj->size(obj) > 0) { \
return ParcelRead(&obj->parcel, e, sizeof(Element)); \
} else { \
return HC_FALSE; \
} \
} \
HcBool VErase##ClassName(ClassName* obj, Element* e, uint32_t index) { \
if (NULL == obj || NULL == e || index + 1 > obj->size(obj)) { \
return HC_FALSE; \
} \
if (obj->size(obj) > 0) { \
return ParcelEraseBlock(&obj->parcel, index*sizeof(Element), sizeof(Element), e); \
} else { \
return HC_FALSE; \
} \
} \
uint32_t VSize##ClassName(const ClassName* obj) \
{ \
if (NULL == obj) { \
return 0; \
} \
return GetParcelDataSize(&obj->parcel) / sizeof(Element); \
} \
Element VGet##ClassName(const ClassName* obj, uint32_t index) \
{ \
Element e; \
(void)memset_s(&e, sizeof(e), 0, sizeof(e)); \
if (NULL != obj) { \
if (index < obj->size(obj)) { \
if (GetParcelData(&obj->parcel)) { \
return *((Element*)(GetParcelData(&obj->parcel)) + index); \
} else { \
return e; \
} \
} \
} \
(void)memset_s(&e, sizeof(e), 0, sizeof(e)); \
return e; \
} \
Element* VGetPointer##ClassName(const ClassName* obj, uint32_t index) \
{ \
if (NULL != obj) { \
if (index < obj->size(obj)) { \
if (GetParcelData(&obj->parcel)) { \
return ((Element*)(GetParcelData(&obj->parcel)) + index); \
} else { \
return NULL; \
} \
} \
} \
return NULL; \
} \
void VClear##ClassName(ClassName* obj) \
{ \
if (NULL != obj) { \
ClearParcel(&obj->parcel); \
} \
} \
ClassName Create##ClassName(void) \
{ \
ClassName obj; \
obj.pushBack = VPushBack##ClassName; \
obj.pushBackT = VPushBackT##ClassName; \
obj.popFront = VPopFront##ClassName; \
obj.clear = VClear##ClassName; \
obj.eraseElement = VErase##ClassName; \
obj.size = VSize##ClassName; \
obj.get = VGet##ClassName; \
obj.getp = VGetPointer##ClassName; \
obj.parcel = CreateParcel(0, sizeof(Element) * allocCount); \
return obj; \
} \
void Destroy##ClassName(ClassName* obj) \
{ \
if (NULL != obj) { \
DeleteParcel(&obj->parcel); \
} \
}
/* Use these two macros to create and destroy vector */
#define CREATE_HC_VECTOR(classname) Create##classname()
#define DESTROY_HC_VECTOR(classname, obj) Destroy##classname(obj)
#define FOR_EACH_HC_VECTOR(vec, index, iter) for (index = 0; index < (vec).size(&(vec)) && \
(iter = (vec).getp(&(vec), index)); ++index)
#define HC_VECTOR_PUSHBACK(obj, element) (obj)->pushBack((obj), (element))
#define HC_VECTOR_POPFRONT(obj, element) (obj)->popFront((obj), (element))
#define HC_VECTOR_POPELEMENT(obj, element, index) (obj)->eraseElement((obj), (element), (index))
#define HC_VECTOR_SIZE(obj) (obj)->size(obj)
#define HC_VECTOR_GET(obj, index) (obj)->get((obj), (index))
#define HC_VECTOR_GETP(_obj, _index) (_obj)->getp((_obj), (_index))
#endif