forked from yaosj2k/dnsforwarder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
array.h
130 lines (115 loc) · 4.83 KB
/
array.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#ifndef ARRAY_H_INCLUDED
#define ARRAY_H_INCLUDED
#include "common.h"
typedef struct _Array{
/* All elements reside here */
char *Data;
/* Length of one element */
int32_t DataLength;
/* How many elements are there in this array. Always non-negative. */
int32_t Used;
/* How many rooms (one room one element) have been allocated.
* An Array, normally, grows up (towards high address). In this case,
* `Allocated' is non-negative.
* Typically, `Allocated' will never be less than `Used'. In most cases,
* `Allocated' is greater than `Used'. If they are equal, this means there
* is no left room for a new element, then we must allocate more
* space (realloc) just before adding new elements. The total allocated
* space is equal to `Allocated' times `DataLength'.
*
* If `Allocated' is negative, the array grows down (towards low address,
* like stack) and won't allocate new space. One uses this should guarantee
* there is enough space to hold all elements.
*/
int32_t Allocated;
}Array;
int Array_Init( __in Array *a,
__in int DataLength,
__in int InitialCount,
__in BOOL GrowsDown,
__in void *TheFirstAddress);
/* Description:
* Initialize an Array.
* Parameters:
* a : The Array to be initialized.
* DataLength : The length of one element.
* InitialCount : The number of initial allocated rooms.
* If the array grows down, this parameter will be ignored.
* GrowsDown : Whether it grows down.
* TheFirstAddress : (Only) For growing down array, the address of the first
* element (at the highist address). The address is the head
* address of the element, not the tail address.
* This parameter will be ignored for growing up array.
* Return value:
* 0 on success, a non-zero value otherwise.
*/
#define Array_IsEmpty(a_ptr) (((a_ptr) -> Used) == 0)
/* Description:
* Check if an Array is empty.
* Parameters:
* a_ptr : Pointer to an Array to be checked.
*/
#define Array_GetUsed(a_ptr) ((a_ptr) -> Used)
/* Description:
* Get `Used' of an Array.
* Parameters:
* a_ptr : Pointer to an Array to be gotten.
*/
void *Array_GetBySubscript(__in Array *a, __in int Subscript);
/* Description:
* Get an element by its subscript.
* Parameters:
* a : The Array to be gotten from.
* Subscript : The subscript of the element which will be gotten.
* For growing down array, the subscript is still non-negative.
* An element at higher address has a smaller subscript while an
* element at lower address has a bigger subscript.
* Return value:
* The address of the gotten element. NULL on failure.
*/
int Array_PushBack(__in Array *a, __in_opt const void *Data, __in_opt void *Boundary);
/* Description:
* Add an element to the end of an array. For growing down array, end means the
* element at the lowest address in an array.
* Parameters:
* a : The Array to be added in.
* Data : Data of newly added element. If this parameter is NULL, the newly
* added element only occupies a room without any useful data, we
* call this kind of element void element.
* Boundary : For growing down array, the upper boundary of the array. If there
* is no enough space inside the boundary, no new element will be
* added, and the function will return failure. If this parameter is
* NULL, no bounds checking will be done.
* This parameter will be ignored for growing up array.
* Return value:
* The subscript of the newly added element. Or a negative value on failure.
*/
void *Array_SetToSubscript(__in Array *a, __in int Subscript, __in void *Data);
/* Description:
* Set data of a element which has the subscript.
* There are two cases.
* Case 1 : `Subscript' is less than a->Used
* Simply set the data of a element which has the subscript.
* Case 2 : `Subscript' is greater than or equal to a->Used
* Add some new void elements so as to let `Subscript' be less than a->Used,
* then, set the data of a element which has the subscript.
* Parameters:
* a : The Array of which an element's data is to be set.
* Subscript : Subscript of the element to be operated.
* Data : Data to be set to.
* Return value:
* The address of the operated element. Or NULL on failure.
*/
#define Array_Clear(a_ptr) ((a_ptr) -> Used = 0)
/* Description:
* Remove all elements, but their rooms are still there.
* Parameters:
* a_ptr : Pointer to the Array to be cleared.
*/
void Array_Free(__in Array *a);
/* Description:
* Free an initialized Array.
* Parameters:
* a : The Array to be freed.
*/
#endif // ARRAY_H_INCLUDED