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