OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
FlexArray.c
Go to the documentation of this file.
1
8#include <Uefi.h>
9#include <Library/BaseMemoryLib.h>
10#include <Library/BaseOverflowLib.h>
11#include <Library/MemoryAllocationLib.h>
14
15#define INITIAL_NUM_ITEMS (8)
16
17VOID
19 IN VOID *Item
20 )
21{
22 ASSERT (Item != NULL);
23
24 if (*(VOID **)Item != NULL) {
25 FreePool (*(VOID **)Item);
26 *(VOID **)Item = NULL;
27 }
28}
29
32 IN CONST UINTN ItemSize,
33 IN CONST OC_FLEX_ARRAY_FREE_ITEM FreeItem OPTIONAL
34 )
35{
36 OC_FLEX_ARRAY *FlexArray;
37
38 ASSERT (ItemSize > 0);
39
40 FlexArray = AllocateZeroPool (sizeof (OC_FLEX_ARRAY));
41 if (FlexArray != NULL) {
42 FlexArray->ItemSize = ItemSize;
43 FlexArray->FreeItem = FreeItem;
44 }
45
46 DEBUG ((OC_TRACE_FLEX, "FLEX: Init %p %u\n", FlexArray, ItemSize));
47
48 return FlexArray;
49}
50
59STATIC
60VOID *
62 IN CONST OC_FLEX_ARRAY *FlexArray,
63 IN CONST UINTN Index
64 )
65{
66 VOID *Item;
67
68 ASSERT (FlexArray != NULL);
69 ASSERT (Index < FlexArray->Count);
70 ASSERT (FlexArray->Items != NULL);
71
72 Item = ((UINT8 *)FlexArray->Items) + Index * FlexArray->ItemSize;
73
74 return Item;
75}
76
84STATIC
85VOID *
87 IN OUT OC_FLEX_ARRAY *FlexArray
88 )
89{
90 VOID *TmpBuffer;
91 UINTN NewSize;
92 VOID *Item;
93
94 ASSERT (FlexArray != NULL);
95
96 if (FlexArray->Items == NULL) {
97 FlexArray->AllocatedCount = INITIAL_NUM_ITEMS;
98 if (BaseOverflowMulUN (FlexArray->AllocatedCount, FlexArray->ItemSize, &NewSize)) {
99 return NULL;
100 }
101
102 FlexArray->Count = 1;
103 FlexArray->Items = AllocatePool (NewSize);
104 if (FlexArray->Items == NULL) {
105 return NULL;
106 }
107 } else {
108 ASSERT (FlexArray->AllocatedCount > 0);
109 ASSERT (FlexArray->Count <= FlexArray->AllocatedCount);
110 ++(FlexArray->Count);
111 if (FlexArray->Count > FlexArray->AllocatedCount) {
112 if (BaseOverflowMulUN (FlexArray->AllocatedCount * FlexArray->ItemSize, 2, &NewSize)) {
113 return NULL;
114 }
115
116 TmpBuffer = ReallocatePool (
117 FlexArray->AllocatedCount * FlexArray->ItemSize,
118 NewSize,
119 FlexArray->Items
120 );
121 if (TmpBuffer == NULL) {
122 return NULL;
123 }
124
125 FlexArray->Items = TmpBuffer;
126 FlexArray->AllocatedCount = FlexArray->AllocatedCount * 2;
127 }
128 }
129
130 Item = InternalFlexArrayItemAt (FlexArray, FlexArray->Count - 1);
131
132 return Item;
133}
134
135VOID *
137 IN OUT OC_FLEX_ARRAY *FlexArray
138 )
139{
140 VOID *Item;
141
142 ASSERT (FlexArray != NULL);
143
144 Item = InternalFlexArrayAddItem (FlexArray);
145
146 if (Item != NULL) {
147 ZeroMem (Item, FlexArray->ItemSize);
148 }
149
150 DEBUG ((OC_TRACE_FLEX, "FLEX: Add %p %p\n", FlexArray, Item));
151
152 return Item;
153}
154
155VOID *
157 IN OUT OC_FLEX_ARRAY *FlexArray,
158 IN CONST UINTN InsertIndex
159 )
160{
161 VOID *Item;
162 VOID *Dest;
163
164 ASSERT (FlexArray != NULL);
165 ASSERT (InsertIndex <= FlexArray->Count);
166
167 if (InsertIndex == FlexArray->Count) {
168 return OcFlexArrayAddItem (FlexArray);
169 }
170
171 Item = InternalFlexArrayAddItem (FlexArray);
172
173 if (Item == NULL) {
174 return Item;
175 }
176
177 Item = InternalFlexArrayItemAt (FlexArray, InsertIndex);
178 Dest = InternalFlexArrayItemAt (FlexArray, InsertIndex + 1);
179 CopyMem (Dest, Item, (FlexArray->Count - InsertIndex) * FlexArray->ItemSize);
180
181 ZeroMem (Item, FlexArray->ItemSize);
182
183 DEBUG ((OC_TRACE_FLEX, "FLEX: Insert %p %p\n", FlexArray, Item));
184
185 return Item;
186}
187
188VOID *
190 IN CONST OC_FLEX_ARRAY *FlexArray,
191 IN CONST UINTN Index
192 )
193{
194 VOID *Item;
195
196 //
197 // Repeat these checks here and in internal ItemAt for easier debugging if they fail.
198 //
199 ASSERT (FlexArray != NULL);
200 ASSERT (Index < FlexArray->Count);
201 ASSERT (FlexArray->Items != NULL);
202
203 Item = InternalFlexArrayItemAt (FlexArray, Index);
204
205 DEBUG ((OC_TRACE_FLEX, "FLEX: At %p %p\n", FlexArray, Item));
206
207 return Item;
208}
209
210VOID
212 IN OC_FLEX_ARRAY **FlexArray
213 )
214{
215 UINTN Index;
216
217 DEBUG ((OC_TRACE_FLEX, "FLEX: Free %p\n", FlexArray));
218
219 ASSERT (FlexArray != NULL);
220
221 if (*FlexArray != NULL) {
222 if ((*FlexArray)->Items != NULL) {
223 if ((*FlexArray)->FreeItem != NULL) {
224 for (Index = 0; Index < (*FlexArray)->Count; Index++) {
225 (*FlexArray)->FreeItem (InternalFlexArrayItemAt (*FlexArray, Index));
226 }
227 }
228
229 FreePool ((*FlexArray)->Items);
230 }
231
232 FreePool (*FlexArray);
233 *FlexArray = NULL;
234 }
235}
236
237VOID
239 IN OUT OC_FLEX_ARRAY *FlexArray,
240 IN CONST BOOLEAN FreeItem
241 )
242{
243 DEBUG ((OC_TRACE_FLEX, "FLEX: Discard %p %u\n", FlexArray, FreeItem));
244
245 ASSERT (FlexArray != NULL);
246 ASSERT (FlexArray->Items != NULL);
247 ASSERT (FlexArray->Count > 0);
248
249 if (FreeItem && (FlexArray->FreeItem != NULL)) {
250 FlexArray->FreeItem (InternalFlexArrayItemAt (FlexArray, FlexArray->Count - 1));
251 }
252
253 --FlexArray->Count;
254}
255
256VOID
258 IN OC_FLEX_ARRAY **FlexArray,
259 IN VOID **Items,
260 IN UINTN *Count
261 )
262{
263 DEBUG ((OC_TRACE_FLEX, "FLEX: FreeContainer %p\n", FlexArray));
264
265 if ((FlexArray == NULL) || (*FlexArray == NULL)) {
266 ASSERT (FALSE);
267 *Items = NULL;
268 *Count = 0;
269 } else {
270 *Items = (*FlexArray)->Items;
271 *Count = (*FlexArray)->Count;
272 if ((*Count == 0) && (*Items != NULL)) {
273 FreePool (*Items);
274 *Items = NULL;
275 }
276
277 FreePool (*FlexArray);
278 *FlexArray = NULL;
279 }
280}
VOID * OcFlexArrayInsertItem(IN OUT OC_FLEX_ARRAY *FlexArray, IN CONST UINTN InsertIndex)
Definition FlexArray.c:156
STATIC VOID * InternalFlexArrayItemAt(IN CONST OC_FLEX_ARRAY *FlexArray, IN CONST UINTN Index)
Definition FlexArray.c:61
OC_FLEX_ARRAY * OcFlexArrayInit(IN CONST UINTN ItemSize, IN CONST OC_FLEX_ARRAY_FREE_ITEM FreeItem OPTIONAL)
Definition FlexArray.c:31
VOID OcFlexArrayFreePointerItem(IN VOID *Item)
Definition FlexArray.c:18
STATIC VOID * InternalFlexArrayAddItem(IN OUT OC_FLEX_ARRAY *FlexArray)
Definition FlexArray.c:86
VOID * OcFlexArrayAddItem(IN OUT OC_FLEX_ARRAY *FlexArray)
Definition FlexArray.c:136
VOID * OcFlexArrayItemAt(IN CONST OC_FLEX_ARRAY *FlexArray, IN CONST UINTN Index)
Definition FlexArray.c:189
VOID OcFlexArrayDiscardItem(IN OUT OC_FLEX_ARRAY *FlexArray, IN CONST BOOLEAN FreeItem)
Definition FlexArray.c:238
VOID OcFlexArrayFree(IN OC_FLEX_ARRAY **FlexArray)
Definition FlexArray.c:211
VOID OcFlexArrayFreeContainer(IN OC_FLEX_ARRAY **FlexArray, IN VOID **Items, IN UINTN *Count)
Definition FlexArray.c:257
#define INITIAL_NUM_ITEMS
Definition FlexArray.c:15
VOID(* OC_FLEX_ARRAY_FREE_ITEM)(IN VOID *Item)
#define OC_TRACE_FLEX
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55
OC_FLEX_ARRAY_FREE_ITEM FreeItem