• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HC_VECTOR_H
17 #define HC_VECTOR_H
18 
19 #include "hc_parcel.h"
20 #include "securec.h"
21 
22 /*
23  * Use DECLARE_HC_VECTOR to declare the vector in the head/src file.
24  * @para ClassName: the name of the vector-class/vector-struct
25  * @para Element: the type of the vector element
26  * @for example:
27  * DECLARE_HC_VECTOR(IntVec, int)
28  */
29 #define DECLARE_HC_VECTOR(ClassName, Element) \
30 typedef struct V##ClassName{ \
31     Element* (*pushBack)(struct V##ClassName*, const Element*); \
32     Element* (*pushBackT)(struct V##ClassName*, Element); \
33     HcBool (*popFront)(struct V##ClassName*, Element*); \
34     HcBool (*eraseElement)(struct V##ClassName*, Element*, uint32_t index); \
35     uint32_t (*size)(const struct V##ClassName*); \
36     Element (*get)(const struct V##ClassName*, uint32_t index); \
37     Element* (*getp)(const struct V##ClassName*, uint32_t index); \
38     void (*clear)(struct V##ClassName*); \
39     HcParcel parcel; \
40 } ClassName;
41 
42 /*
43  * Use IMPLEMENT_HC_VECTOR to implement the vector in the source file.
44  * @para ClassName: the name of the vector-class/vector-struct
45  * @para Element: the type of the vector element
46  * @para allocCount: the minimum alloc count
47  * @for example:
48  * IMPLEMENT_HC_VECTOR(IntVec, int)
49  */
50 #define IMPLEMENT_HC_VECTOR(ClassName, Element, allocCount) \
51 Element* VPushBack##ClassName(ClassName* obj, const Element *e) { \
52     if (obj == NULL || e == NULL) { \
53         return NULL; \
54     } \
55       \
56     if (ParcelWrite(&obj->parcel, e, sizeof(Element))) { \
57         uint32_t size = obj->size(obj); \
58         return obj->getp(obj, size - 1); \
59     } else { \
60         return NULL; \
61     } \
62 } \
63 Element* VPushBackT##ClassName(ClassName* obj, Element e) { \
64     if (obj == NULL) { \
65         return NULL; \
66     } \
67       \
68     if (ParcelWrite(&obj->parcel, &e, sizeof(Element))) { \
69         uint32_t size = obj->size(obj); \
70         return obj->getp(obj, size - 1); \
71     } else { \
72         return NULL; \
73     } \
74 } \
75 HcBool VPopFront##ClassName(ClassName* obj, Element* e) { \
76         if (NULL == obj || NULL == e) { \
77             return HC_FALSE; \
78         } \
79         if (obj->size(obj) > 0) { \
80             return ParcelRead(&obj->parcel, e, sizeof(Element)); \
81         } else { \
82             return HC_FALSE; \
83         } \
84 } \
85 HcBool VErase##ClassName(ClassName* obj, Element* e, uint32_t index) { \
86         if (NULL == obj || NULL == e || index + 1 > obj->size(obj)) { \
87             return HC_FALSE; \
88         } \
89         if (obj->size(obj) > 0) { \
90             return ParcelEraseBlock(&obj->parcel, index * sizeof(Element), sizeof(Element), e); \
91         } else { \
92             return HC_FALSE; \
93         } \
94 } \
95 uint32_t VSize##ClassName(const ClassName* obj) \
96 { \
97     if (NULL == obj) { \
98         return 0; \
99     } \
100     return GetParcelDataSize(&obj->parcel) / sizeof(Element); \
101 } \
102 Element VGet##ClassName(const ClassName* obj, uint32_t index) \
103 { \
104     Element e; \
105     (void)memset_s(&e, sizeof(e), 0, sizeof(e)); \
106     if (NULL != obj) { \
107         if (index < obj->size(obj)) { \
108             if (GetParcelData(&obj->parcel)) { \
109                 return *((Element*)(GetParcelData(&obj->parcel)) + index); \
110             } else { \
111                 return e; \
112             } \
113         } \
114     } \
115     (void)memset_s(&e, sizeof(e), 0, sizeof(e)); \
116     return e; \
117 } \
118 Element* VGetPointer##ClassName(const ClassName* obj, uint32_t index) \
119 { \
120     if (NULL != obj) { \
121         if (index < obj->size(obj)) { \
122             if (GetParcelData(&obj->parcel)) { \
123                 return ((Element*)(GetParcelData(&obj->parcel)) + index); \
124             } else { \
125                 return NULL; \
126             } \
127         } \
128     } \
129     return NULL; \
130 } \
131 void VClear##ClassName(ClassName* obj) \
132 { \
133     if (NULL != obj) { \
134         ClearParcel(&obj->parcel); \
135     } \
136 } \
137 ClassName Create##ClassName(void) \
138 { \
139     ClassName obj; \
140     obj.pushBack = VPushBack##ClassName; \
141     obj.pushBackT = VPushBackT##ClassName; \
142     obj.popFront = VPopFront##ClassName; \
143     obj.clear = VClear##ClassName; \
144     obj.eraseElement = VErase##ClassName; \
145     obj.size = VSize##ClassName; \
146     obj.get = VGet##ClassName; \
147     obj.getp = VGetPointer##ClassName; \
148     obj.parcel = CreateParcel(0, sizeof(Element) * allocCount); \
149     return obj; \
150 } \
151 void Destroy##ClassName(ClassName* obj) \
152 { \
153     if (NULL != obj) { \
154         DeleteParcel(&obj->parcel); \
155     } \
156 }
157 
158 /* Use these two macros to create and destroy vector */
159 #define CREATE_HC_VECTOR(classname) Create##classname()
160 #define DESTROY_HC_VECTOR(classname, obj) Destroy##classname(obj)
161 
162 #define FOR_EACH_HC_VECTOR(vec, index, iter) for (index = 0; index < (vec).size(&(vec)) && \
163     (iter = (vec).getp(&(vec), index)); ++index)
164 
165 #define HC_VECTOR_PUSHBACK(obj, element) (obj)->pushBack((obj), (element))
166 #define HC_VECTOR_POPFRONT(obj, element) (obj)->popFront((obj), (element))
167 #define HC_VECTOR_POPELEMENT(obj, element, index) (obj)->eraseElement((obj), (element), (index))
168 #define HC_VECTOR_SIZE(obj) (obj)->size(obj)
169 #define HC_VECTOR_GET(obj, index) (obj)->get((obj), (index))
170 #define HC_VECTOR_GETP(_obj, _index) (_obj)->getp((_obj), (_index))
171 
172 #endif
173