upstream nginx-0.7.39
[nginx.git] / nginx / src / core / ngx_buf.c
1
2 /*
3  * Copyright (C) Igor Sysoev
4  */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9
10
11 ngx_buf_t *
12 ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
13 {
14     ngx_buf_t *b;
15
16     b = ngx_calloc_buf(pool);
17     if (b == NULL) {
18         return NULL;
19     }
20
21     b->start = ngx_palloc(pool, size);
22     if (b->start == NULL) {
23         return NULL;
24     }
25
26     /*
27      * set by ngx_calloc_buf():
28      *
29      *     b->file_pos = 0;
30      *     b->file_last = 0;
31      *     b->file = NULL;
32      *     b->shadow = NULL;
33      *     b->tag = 0;
34      *     and flags
35      */
36
37     b->pos = b->start;
38     b->last = b->start;
39     b->end = b->last + size;
40     b->temporary = 1;
41
42     return b;
43 }
44
45
46 ngx_chain_t *
47 ngx_alloc_chain_link(ngx_pool_t *pool)
48 {
49     ngx_chain_t  *cl;
50
51     cl = pool->chain;
52
53     if (cl) {
54         pool->chain = cl->next;
55         return cl;
56     }
57
58     cl = ngx_palloc(pool, sizeof(ngx_chain_t));
59     if (cl == NULL) {
60         return NULL;
61     }
62
63     return cl;
64 }
65
66
67 ngx_chain_t *
68 ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
69 {
70     u_char       *p;
71     ngx_int_t     i;
72     ngx_buf_t    *b;
73     ngx_chain_t  *chain, *cl, **ll;
74
75     p = ngx_palloc(pool, bufs->num * bufs->size);
76     if (p == NULL) {
77         return NULL;
78     }
79
80     ll = &chain;
81
82     for (i = 0; i < bufs->num; i++) {
83
84         b = ngx_calloc_buf(pool);
85         if (b == NULL) {
86             return NULL;
87         }
88
89         /*
90          * set by ngx_calloc_buf():
91          *
92          *     b->file_pos = 0;
93          *     b->file_last = 0;
94          *     b->file = NULL;
95          *     b->shadow = NULL;
96          *     b->tag = 0;
97          *     and flags
98          *
99          */
100
101         b->pos = p;
102         b->last = p;
103         b->temporary = 1;
104
105         b->start = p;
106         p += bufs->size;
107         b->end = p;
108
109         cl = ngx_alloc_chain_link(pool);
110         if (cl == NULL) {
111             return NULL;
112         }
113
114         cl->buf = b;
115         *ll = cl;
116         ll = &cl->next;
117     }
118
119     *ll = NULL;
120
121     return chain;
122 }
123
124
125 ngx_int_t
126 ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in)
127 {
128     ngx_chain_t  *cl, **ll;
129
130     ll = chain;
131
132     for (cl = *chain; cl; cl = cl->next) {
133         ll = &cl->next;
134     }
135
136     while (in) {
137         cl = ngx_alloc_chain_link(pool);
138         if (cl == NULL) {
139             return NGX_ERROR;
140         }
141
142         cl->buf = in->buf;
143         *ll = cl;
144         ll = &cl->next;
145         in = in->next;
146     }
147
148     *ll = NULL;
149
150     return NGX_OK;
151 }
152
153
154 ngx_chain_t *
155 ngx_chain_get_free_buf(ngx_pool_t *p, ngx_chain_t **free)
156 {
157     ngx_chain_t  *cl;
158
159     if (*free) {
160         cl = *free;
161         *free = cl->next;
162         cl->next = NULL;
163         return cl;
164     }
165
166     cl = ngx_alloc_chain_link(p);
167     if (cl == NULL) {
168         return NULL;
169     }
170
171     cl->buf = ngx_calloc_buf(p);
172     if (cl->buf == NULL) {
173         return NULL;
174     }
175
176     cl->next = NULL;
177
178     return cl;
179 }
180
181
182 void
183 ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
184     ngx_chain_t **out, ngx_buf_tag_t tag)
185 {
186     ngx_chain_t  *cl;
187
188     if (*busy == NULL) {
189         *busy = *out;
190
191     } else {
192         for (cl = *busy; cl->next; cl = cl->next) { /* void */ }
193
194         cl->next = *out;
195     }
196
197     *out = NULL;
198
199     while (*busy) {
200         if (ngx_buf_size((*busy)->buf) != 0) {
201             break;
202         }
203
204         if ((*busy)->buf->tag != tag) {
205             *busy = (*busy)->next;
206             continue;
207         }
208
209         (*busy)->buf->pos = (*busy)->buf->start;
210         (*busy)->buf->last = (*busy)->buf->start;
211
212         cl = *busy;
213         *busy = cl->next;
214         cl->next = *free;
215         *free = cl;
216     }
217 }