1 /*
2  * Copyright (c) 2020 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 #include "common.h"
16 #include <securec.h>
17 #include "memory_adapter.h"
18 
19 #define GROW_STEP 4
VECTOR_Make(VECTOR_Key key,VECTOR_Compare compare)20 Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare)
21 {
22     Vector vector = {0, 0, 0, NULL, key, compare};
23     return vector;
24 }
25 
VECTOR_Clear(Vector * vector)26 void VECTOR_Clear(Vector *vector)
27 {
28     if (vector == NULL) {
29         return;
30     }
31     if (vector->data == NULL) {
32         return;
33     }
34     SAMGR_Free(vector->data);
35     vector->max = 0;
36     vector->top = 0;
37     vector->free = 0;
38     vector->data = NULL;
39 }
40 
VECTOR_Add(Vector * vector,void * element)41 int16 VECTOR_Add(Vector *vector, void *element)
42 {
43     if (vector == NULL || element == NULL) {
44         return INVALID_INDEX;
45     }
46 
47     if (vector->top >= vector->max) {
48         int16 i;
49         // use released data elements preferentially
50         for (i = vector->top - (int16)1; i >= 0; --i) {
51             if (vector->data[i] == NULL) {
52                 vector->data[i] = element;
53                 vector->free--;
54                 return i;
55             }
56         }
57 
58         if (vector->max + GROW_STEP < 0) {
59             return INVALID_INDEX;
60         }
61 
62         void **data = (void **)SAMGR_Malloc(sizeof(void *) * (vector->max + GROW_STEP));
63         if (data == NULL) {
64             return INVALID_INDEX;
65         }
66 
67         if (vector->data != NULL) {
68             // data's length is bigger than vector->data's length and only copy vector->data's length's memory;
69             // no need to check return value
70             (void)memcpy_s(data, sizeof(void *) * (vector->max + GROW_STEP),
71                            vector->data, sizeof(void *) * vector->max);
72             SAMGR_Free(vector->data);
73         }
74         vector->data = data;
75         vector->max += GROW_STEP;
76     }
77 
78     vector->data[vector->top] = element;
79     return vector->top++;
80 }
81 
VECTOR_At(Vector * vector,int16 index)82 void *VECTOR_At(Vector *vector, int16 index)
83 {
84     if (vector == NULL || vector->top <= index || index < 0) {
85         return NULL;
86     }
87 
88     return vector->data[index];
89 }
90 
VECTOR_Swap(Vector * vector,int16 index,void * element)91 void *VECTOR_Swap(Vector *vector, int16 index, void *element)
92 {
93     if (vector == NULL || vector->top <= index || index < 0) {
94         return NULL;
95     }
96     if (element == NULL) {
97         vector->free++;
98     }
99     void *oldElement = vector->data[index];
100     vector->data[index] = element;
101     return oldElement;
102 }
103 
VECTOR_Find(Vector * vector,const void * element)104 int16 VECTOR_Find(Vector *vector, const void *element)
105 {
106     if (vector == NULL || element == NULL) {
107         return INVALID_INDEX;
108     }
109     return VECTOR_FindByKey(vector, (vector->key == NULL) ? element : vector->key(element));
110 }
111 
VECTOR_FindByKey(Vector * vector,const void * key)112 int16 VECTOR_FindByKey(Vector *vector, const void *key)
113 {
114     if (vector == NULL || key == NULL) {
115         return INVALID_INDEX;
116     }
117 
118     int16 i;
119     for (i = 0; i < vector->top; ++i) {
120         if (vector->data[i] == NULL) {
121             continue;
122         }
123 
124         void *first = (vector->key != NULL) ? vector->key(vector->data[i]) : vector->data[i];
125         if (first == key) {
126             return i;
127         }
128 
129         if (vector->compare == NULL || first == NULL) {
130             continue;
131         }
132 
133         if (vector->compare(first, key) == 0) {
134             return i;
135         }
136     }
137     return INVALID_INDEX;
138 }
139 
VECTOR_Size(Vector * vector)140 int16 VECTOR_Size(Vector *vector)
141 {
142     if (vector == NULL) {
143         return INVALID_INDEX;
144     }
145     return vector->top;
146 }
147 
VECTOR_Num(Vector * vector)148 int16 VECTOR_Num(Vector *vector)
149 {
150     if (vector == NULL) {
151         return INVALID_INDEX;
152     }
153     return vector->top - vector->free;
154 }
155