0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
644
|
4 * Copyright (C) Nginx, Inc.
|
0
|
5 */
|
|
6
|
|
7
|
|
8 #include <ngx_config.h>
|
|
9 #include <ngx_core.h>
|
|
10
|
|
11
|
154
|
12 ngx_array_t *
|
|
13 ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
|
0
|
14 {
|
|
15 ngx_array_t *a;
|
|
16
|
50
|
17 a = ngx_palloc(p, sizeof(ngx_array_t));
|
|
18 if (a == NULL) {
|
34
|
19 return NULL;
|
|
20 }
|
0
|
21
|
50
|
22 a->elts = ngx_palloc(p, n * size);
|
|
23 if (a->elts == NULL) {
|
34
|
24 return NULL;
|
|
25 }
|
|
26
|
0
|
27 a->nelts = 0;
|
34
|
28 a->size = size;
|
0
|
29 a->nalloc = n;
|
34
|
30 a->pool = p;
|
0
|
31
|
|
32 return a;
|
|
33 }
|
|
34
|
|
35
|
154
|
36 void
|
|
37 ngx_array_destroy(ngx_array_t *a)
|
0
|
38 {
|
|
39 ngx_pool_t *p;
|
|
40
|
|
41 p = a->pool;
|
|
42
|
382
|
43 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
|
44 p->d.last -= a->size * a->nalloc;
|
0
|
45 }
|
|
46
|
382
|
47 if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
|
48 p->d.last = (u_char *) a;
|
0
|
49 }
|
|
50 }
|
|
51
|
|
52
|
154
|
53 void *
|
|
54 ngx_array_push(ngx_array_t *a)
|
0
|
55 {
|
|
56 void *elt, *new;
|
34
|
57 size_t size;
|
0
|
58 ngx_pool_t *p;
|
|
59
|
|
60 if (a->nelts == a->nalloc) {
|
34
|
61
|
|
62 /* the array is full */
|
|
63
|
|
64 size = a->size * a->nalloc;
|
|
65
|
0
|
66 p = a->pool;
|
|
67
|
382
|
68 if ((u_char *) a->elts + size == p->d.last
|
|
69 && p->d.last + a->size <= p->d.end)
|
0
|
70 {
|
34
|
71 /*
|
|
72 * the array allocation is the last in the pool
|
|
73 * and there is space for new allocation
|
|
74 */
|
|
75
|
382
|
76 p->d.last += a->size;
|
0
|
77 a->nalloc++;
|
|
78
|
|
79 } else {
|
34
|
80 /* allocate a new array */
|
0
|
81
|
50
|
82 new = ngx_palloc(p, 2 * size);
|
|
83 if (new == NULL) {
|
34
|
84 return NULL;
|
|
85 }
|
|
86
|
|
87 ngx_memcpy(new, a->elts, size);
|
0
|
88 a->elts = new;
|
|
89 a->nalloc *= 2;
|
|
90 }
|
|
91 }
|
|
92
|
34
|
93 elt = (u_char *) a->elts + a->size * a->nelts;
|
0
|
94 a->nelts++;
|
|
95
|
|
96 return elt;
|
|
97 }
|
34
|
98
|
|
99
|
154
|
100 void *
|
|
101 ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
34
|
102 {
|
|
103 void *elt, *new;
|
|
104 size_t size;
|
|
105 ngx_uint_t nalloc;
|
|
106 ngx_pool_t *p;
|
|
107
|
|
108 size = n * a->size;
|
|
109
|
|
110 if (a->nelts + n > a->nalloc) {
|
|
111
|
|
112 /* the array is full */
|
|
113
|
|
114 p = a->pool;
|
|
115
|
382
|
116 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
|
117 && p->d.last + size <= p->d.end)
|
34
|
118 {
|
|
119 /*
|
|
120 * the array allocation is the last in the pool
|
|
121 * and there is space for new allocation
|
|
122 */
|
|
123
|
382
|
124 p->d.last += size;
|
34
|
125 a->nalloc += n;
|
|
126
|
|
127 } else {
|
|
128 /* allocate a new array */
|
|
129
|
|
130 nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
|
131
|
50
|
132 new = ngx_palloc(p, nalloc * a->size);
|
|
133 if (new == NULL) {
|
34
|
134 return NULL;
|
|
135 }
|
|
136
|
|
137 ngx_memcpy(new, a->elts, a->nelts * a->size);
|
|
138 a->elts = new;
|
|
139 a->nalloc = nalloc;
|
|
140 }
|
|
141 }
|
|
142
|
|
143 elt = (u_char *) a->elts + a->size * a->nelts;
|
|
144 a->nelts += n;
|
|
145
|
|
146 return elt;
|
|
147 }
|