xref: /lighttpd1.4/src/array.c (revision be121a63)
122e8b456SStefan Bühler #include "array.h"
222e8b456SStefan Bühler #include "buffer.h"
322e8b456SStefan Bühler 
4bcdc6a3bSJan Kneschke #include <string.h>
5bcdc6a3bSJan Kneschke #include <stdio.h>
6bcdc6a3bSJan Kneschke #include <stdlib.h>
7bcdc6a3bSJan Kneschke #include <limits.h>
8bcdc6a3bSJan Kneschke 
9bcdc6a3bSJan Kneschke #include <errno.h>
10bcdc6a3bSJan Kneschke #include <assert.h>
11bcdc6a3bSJan Kneschke 
12bcdc6a3bSJan Kneschke array *array_init(void) {
13bcdc6a3bSJan Kneschke 	array *a;
14bcdc6a3bSJan Kneschke 
15bcdc6a3bSJan Kneschke 	a = calloc(1, sizeof(*a));
1607dd0bd0SStefan Bühler 	force_assert(a);
17bcdc6a3bSJan Kneschke 
18bcdc6a3bSJan Kneschke 	a->next_power_of_2 = 1;
19bcdc6a3bSJan Kneschke 
20bcdc6a3bSJan Kneschke 	return a;
21bcdc6a3bSJan Kneschke }
22bcdc6a3bSJan Kneschke 
236e78c2c8SJan Kneschke array *array_init_array(array *src) {
246e78c2c8SJan Kneschke 	size_t i;
256e78c2c8SJan Kneschke 	array *a = array_init();
266e78c2c8SJan Kneschke 
276f208cfdSStefan Bühler 	if (0 == src->size) return a;
286f208cfdSStefan Bühler 
296e78c2c8SJan Kneschke 	a->used = src->used;
306e78c2c8SJan Kneschke 	a->size = src->size;
316e78c2c8SJan Kneschke 	a->next_power_of_2 = src->next_power_of_2;
326e78c2c8SJan Kneschke 	a->unique_ndx = src->unique_ndx;
336e78c2c8SJan Kneschke 
346e78c2c8SJan Kneschke 	a->data = malloc(sizeof(*src->data) * src->size);
35566cf8deSStefan Bühler 	force_assert(NULL != a->data);
366e78c2c8SJan Kneschke 	for (i = 0; i < src->size; i++) {
376e78c2c8SJan Kneschke 		if (src->data[i]) a->data[i] = src->data[i]->copy(src->data[i]);
386e78c2c8SJan Kneschke 		else a->data[i] = NULL;
396e78c2c8SJan Kneschke 	}
406e78c2c8SJan Kneschke 
416e78c2c8SJan Kneschke 	a->sorted = malloc(sizeof(*src->sorted) * src->size);
42566cf8deSStefan Bühler 	force_assert(NULL != a->sorted);
436e78c2c8SJan Kneschke 	memcpy(a->sorted, src->sorted, sizeof(*src->sorted) * src->size);
446e78c2c8SJan Kneschke 	return a;
456e78c2c8SJan Kneschke }
466e78c2c8SJan Kneschke 
47bcdc6a3bSJan Kneschke void array_free(array *a) {
48bcdc6a3bSJan Kneschke 	size_t i;
49bcdc6a3bSJan Kneschke 	if (!a) return;
50bcdc6a3bSJan Kneschke 
518b07d57dSJan Kneschke 	if (!a->is_weakref) {
52bcdc6a3bSJan Kneschke 		for (i = 0; i < a->size; i++) {
53bcdc6a3bSJan Kneschke 			if (a->data[i]) a->data[i]->free(a->data[i]);
54bcdc6a3bSJan Kneschke 		}
558b07d57dSJan Kneschke 	}
56bcdc6a3bSJan Kneschke 
57bcdc6a3bSJan Kneschke 	if (a->data) free(a->data);
58bcdc6a3bSJan Kneschke 	if (a->sorted) free(a->sorted);
59bcdc6a3bSJan Kneschke 
60bcdc6a3bSJan Kneschke 	free(a);
61bcdc6a3bSJan Kneschke }
62bcdc6a3bSJan Kneschke 
63bcdc6a3bSJan Kneschke void array_reset(array *a) {
64bcdc6a3bSJan Kneschke 	size_t i;
65bcdc6a3bSJan Kneschke 	if (!a) return;
66bcdc6a3bSJan Kneschke 
678b07d57dSJan Kneschke 	if (!a->is_weakref) {
68bcdc6a3bSJan Kneschke 		for (i = 0; i < a->used; i++) {
69bcdc6a3bSJan Kneschke 			a->data[i]->reset(a->data[i]);
70bcdc6a3bSJan Kneschke 		}
718b07d57dSJan Kneschke 	}
72bcdc6a3bSJan Kneschke 
73bcdc6a3bSJan Kneschke 	a->used = 0;
748d8ae9cbSStefan Bühler 	a->unique_ndx = 0;
75bcdc6a3bSJan Kneschke }
76bcdc6a3bSJan Kneschke 
778073d5feSJan Kneschke data_unset *array_pop(array *a) {
788073d5feSJan Kneschke 	data_unset *du;
798073d5feSJan Kneschke 
8007dd0bd0SStefan Bühler 	force_assert(a->used != 0);
818073d5feSJan Kneschke 
828073d5feSJan Kneschke 	a->used --;
838073d5feSJan Kneschke 	du = a->data[a->used];
848d8ae9cbSStefan Bühler 	force_assert(a->sorted[a->used] == a->used); /* only works on "simple" lists */
858073d5feSJan Kneschke 	a->data[a->used] = NULL;
868073d5feSJan Kneschke 
878073d5feSJan Kneschke 	return du;
888073d5feSJan Kneschke }
898073d5feSJan Kneschke 
90bcdc6a3bSJan Kneschke static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) {
91bcdc6a3bSJan Kneschke 	int ndx = -1;
92bcdc6a3bSJan Kneschke 	int i, pos = 0;
93bcdc6a3bSJan Kneschke 
94bcdc6a3bSJan Kneschke 	if (key == NULL) return -1;
95bcdc6a3bSJan Kneschke 
96bcdc6a3bSJan Kneschke 	/* try to find the string */
97bcdc6a3bSJan Kneschke 	for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) {
98bcdc6a3bSJan Kneschke 		int cmp;
99bcdc6a3bSJan Kneschke 
100bcdc6a3bSJan Kneschke 		if (pos < 0) {
101bcdc6a3bSJan Kneschke 			pos += i;
102bcdc6a3bSJan Kneschke 		} else if (pos >= (int)a->used) {
103bcdc6a3bSJan Kneschke 			pos -= i;
104bcdc6a3bSJan Kneschke 		} else {
105ad3e93eaSStefan Bühler 			cmp = buffer_caseless_compare(key, keylen, CONST_BUF_LEN(a->data[a->sorted[pos]]->key));
106bcdc6a3bSJan Kneschke 
107bcdc6a3bSJan Kneschke 			if (cmp == 0) {
108bcdc6a3bSJan Kneschke 				/* found */
109bcdc6a3bSJan Kneschke 				ndx = a->sorted[pos];
110bcdc6a3bSJan Kneschke 				break;
111bcdc6a3bSJan Kneschke 			} else if (cmp < 0) {
112bcdc6a3bSJan Kneschke 				pos -= i;
113bcdc6a3bSJan Kneschke 			} else {
114bcdc6a3bSJan Kneschke 				pos += i;
115bcdc6a3bSJan Kneschke 			}
116bcdc6a3bSJan Kneschke 		}
117bcdc6a3bSJan Kneschke 		if (i == 0) break;
118bcdc6a3bSJan Kneschke 	}
119bcdc6a3bSJan Kneschke 
120bcdc6a3bSJan Kneschke 	if (rndx) *rndx = pos;
121bcdc6a3bSJan Kneschke 
122bcdc6a3bSJan Kneschke 	return ndx;
123bcdc6a3bSJan Kneschke }
124bcdc6a3bSJan Kneschke 
125bcdc6a3bSJan Kneschke data_unset *array_get_element(array *a, const char *key) {
126bcdc6a3bSJan Kneschke 	int ndx;
127bcdc6a3bSJan Kneschke 
128ad3e93eaSStefan Bühler 	if (-1 != (ndx = array_get_index(a, key, strlen(key), NULL))) {
129bcdc6a3bSJan Kneschke 		/* found, leave here */
130bcdc6a3bSJan Kneschke 
131bcdc6a3bSJan Kneschke 		return a->data[ndx];
132bcdc6a3bSJan Kneschke 	}
133bcdc6a3bSJan Kneschke 
134bcdc6a3bSJan Kneschke 	return NULL;
135bcdc6a3bSJan Kneschke }
136bcdc6a3bSJan Kneschke 
137bcdc6a3bSJan Kneschke data_unset *array_get_unused_element(array *a, data_type_t t) {
138bcdc6a3bSJan Kneschke 	data_unset *ds = NULL;
13912f375f3SStefan Bühler 	unsigned int i;
140bcdc6a3bSJan Kneschke 
14112f375f3SStefan Bühler 	for (i = a->used; i < a->size; i++) {
14212f375f3SStefan Bühler 		if (a->data[i] && a->data[i]->type == t) {
14312f375f3SStefan Bühler 			ds = a->data[i];
144bcdc6a3bSJan Kneschke 
14512f375f3SStefan Bühler 			/* make empty slot at a->used for next insert */
14612f375f3SStefan Bühler 			a->data[i] = a->data[a->used];
147bcdc6a3bSJan Kneschke 			a->data[a->used] = NULL;
148bcdc6a3bSJan Kneschke 
149bcdc6a3bSJan Kneschke 			return ds;
150bcdc6a3bSJan Kneschke 		}
15112f375f3SStefan Bühler 	}
15212f375f3SStefan Bühler 
15312f375f3SStefan Bühler 	return NULL;
15412f375f3SStefan Bühler }
155bcdc6a3bSJan Kneschke 
1564f4d40f3SStefan Bühler void array_set_key_value(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
1574f4d40f3SStefan Bühler 	data_string *ds_dst;
1584f4d40f3SStefan Bühler 
1594f4d40f3SStefan Bühler 	if (NULL != (ds_dst = (data_string *)array_get_element(hdrs, key))) {
1604f4d40f3SStefan Bühler 		buffer_copy_string_len(ds_dst->value, value, val_len);
1614f4d40f3SStefan Bühler 		return;
1624f4d40f3SStefan Bühler 	}
1634f4d40f3SStefan Bühler 
1644f4d40f3SStefan Bühler 	if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
1654f4d40f3SStefan Bühler 		ds_dst = data_string_init();
1664f4d40f3SStefan Bühler 	}
1674f4d40f3SStefan Bühler 
1684f4d40f3SStefan Bühler 	buffer_copy_string_len(ds_dst->key, key, key_len);
1694f4d40f3SStefan Bühler 	buffer_copy_string_len(ds_dst->value, value, val_len);
1704f4d40f3SStefan Bühler 	array_insert_unique(hdrs, (data_unset *)ds_dst);
1714f4d40f3SStefan Bühler }
1724f4d40f3SStefan Bühler 
1738d8ae9cbSStefan Bühler /* if entry already exists return pointer to existing entry, otherwise insert entry and return NULL */
174*be121a63SStefan Bühler static data_unset **array_find_or_insert(array *a, data_unset *entry) {
175bcdc6a3bSJan Kneschke 	int ndx = -1;
176bcdc6a3bSJan Kneschke 	int pos = 0;
177bcdc6a3bSJan Kneschke 	size_t j;
178bcdc6a3bSJan Kneschke 
179bcdc6a3bSJan Kneschke 	/* generate unique index if neccesary */
180*be121a63SStefan Bühler 	if (buffer_is_empty(entry->key) || entry->is_index_key) {
181*be121a63SStefan Bühler 		buffer_copy_int(entry->key, a->unique_ndx++);
182*be121a63SStefan Bühler 		entry->is_index_key = 1;
1838d8ae9cbSStefan Bühler 		force_assert(0 != a->unique_ndx); /* must not wrap or we'll get problems */
184bcdc6a3bSJan Kneschke 	}
185bcdc6a3bSJan Kneschke 
186*be121a63SStefan Bühler 	/* try to find the entry */
187*be121a63SStefan Bühler 	if (-1 != (ndx = array_get_index(a, CONST_BUF_LEN(entry->key), &pos))) {
1888d8ae9cbSStefan Bühler 		/* found collision, return it */
1898d8ae9cbSStefan Bühler 		return &a->data[ndx];
190bcdc6a3bSJan Kneschke 	}
191bcdc6a3bSJan Kneschke 
192bcdc6a3bSJan Kneschke 	/* insert */
193bcdc6a3bSJan Kneschke 
1948d8ae9cbSStefan Bühler 	/* there is no good error handling for hitting this limit
1958d8ae9cbSStefan Bühler 	 * (we can't handle more then INT_MAX entries: see array_get_index())
1968d8ae9cbSStefan Bühler 	 */
1978d8ae9cbSStefan Bühler 	force_assert(a->used + 1 <= INT_MAX);
198bcdc6a3bSJan Kneschke 
199bcdc6a3bSJan Kneschke 	if (a->size == 0) {
200bcdc6a3bSJan Kneschke 		a->size   = 16;
201bcdc6a3bSJan Kneschke 		a->data   = malloc(sizeof(*a->data)     * a->size);
202bcdc6a3bSJan Kneschke 		a->sorted = malloc(sizeof(*a->sorted)   * a->size);
20307dd0bd0SStefan Bühler 		force_assert(a->data);
20407dd0bd0SStefan Bühler 		force_assert(a->sorted);
205bcdc6a3bSJan Kneschke 		for (j = a->used; j < a->size; j++) a->data[j] = NULL;
206bcdc6a3bSJan Kneschke 	} else if (a->size == a->used) {
207bcdc6a3bSJan Kneschke 		a->size  += 16;
208bcdc6a3bSJan Kneschke 		a->data   = realloc(a->data,   sizeof(*a->data)   * a->size);
209bcdc6a3bSJan Kneschke 		a->sorted = realloc(a->sorted, sizeof(*a->sorted) * a->size);
21007dd0bd0SStefan Bühler 		force_assert(a->data);
21107dd0bd0SStefan Bühler 		force_assert(a->sorted);
212bcdc6a3bSJan Kneschke 		for (j = a->used; j < a->size; j++) a->data[j] = NULL;
213bcdc6a3bSJan Kneschke 	}
214bcdc6a3bSJan Kneschke 
215bcdc6a3bSJan Kneschke 	ndx = (int) a->used;
216bcdc6a3bSJan Kneschke 
21712f375f3SStefan Bühler 	/* make sure there is nothing here */
21812f375f3SStefan Bühler 	if (a->data[ndx]) a->data[ndx]->free(a->data[ndx]);
21912f375f3SStefan Bühler 
220*be121a63SStefan Bühler 	a->data[a->used++] = entry;
221bcdc6a3bSJan Kneschke 
222bcdc6a3bSJan Kneschke 	if (pos != ndx &&
223bcdc6a3bSJan Kneschke 	    ((pos < 0) ||
224*be121a63SStefan Bühler 	     buffer_caseless_compare(CONST_BUF_LEN(entry->key), CONST_BUF_LEN(a->data[a->sorted[pos]]->key)) > 0)) {
225bcdc6a3bSJan Kneschke 		pos++;
226bcdc6a3bSJan Kneschke 	}
227bcdc6a3bSJan Kneschke 
2288d8ae9cbSStefan Bühler 	/* move everything one step to the right */
229bcdc6a3bSJan Kneschke 	if (pos != ndx) {
230bcdc6a3bSJan Kneschke 		memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted));
231bcdc6a3bSJan Kneschke 	}
232bcdc6a3bSJan Kneschke 
233bcdc6a3bSJan Kneschke 	/* insert */
234bcdc6a3bSJan Kneschke 	a->sorted[pos] = ndx;
235bcdc6a3bSJan Kneschke 
236bcdc6a3bSJan Kneschke 	if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1;
237bcdc6a3bSJan Kneschke 
2388d8ae9cbSStefan Bühler 	return NULL;
2398d8ae9cbSStefan Bühler }
2408d8ae9cbSStefan Bühler 
2418d8ae9cbSStefan Bühler /* replace or insert data (free existing entry) */
2428d8ae9cbSStefan Bühler void array_replace(array *a, data_unset *entry) {
2438d8ae9cbSStefan Bühler 	data_unset **old;
2448d8ae9cbSStefan Bühler 
2458d8ae9cbSStefan Bühler 	force_assert(NULL != entry);
2468d8ae9cbSStefan Bühler 	if (NULL != (old = array_find_or_insert(a, entry))) {
2478d8ae9cbSStefan Bühler 		force_assert(*old != entry);
2488d8ae9cbSStefan Bühler 		(*old)->free(*old);
2498d8ae9cbSStefan Bühler 		*old = entry;
2508d8ae9cbSStefan Bühler 	}
2518d8ae9cbSStefan Bühler }
2528d8ae9cbSStefan Bühler 
2538d8ae9cbSStefan Bühler void array_insert_unique(array *a, data_unset *entry) {
2548d8ae9cbSStefan Bühler 	data_unset **old;
2558d8ae9cbSStefan Bühler 
2568d8ae9cbSStefan Bühler 	force_assert(NULL != entry);
2578d8ae9cbSStefan Bühler 	if (NULL != (old = array_find_or_insert(a, entry))) {
2588d8ae9cbSStefan Bühler 		force_assert((*old)->type == entry->type);
2598d8ae9cbSStefan Bühler 		entry->insert_dup(*old, entry);
2608d8ae9cbSStefan Bühler 	}
261bcdc6a3bSJan Kneschke }
262bcdc6a3bSJan Kneschke 
2639e75ba00SJan Kneschke void array_print_indent(int depth) {
2649e75ba00SJan Kneschke 	int i;
2659e75ba00SJan Kneschke 	for (i = 0; i < depth; i ++) {
266dd0abe5aSJan Kneschke 		fprintf(stdout, "    ");
2679e75ba00SJan Kneschke 	}
2689e75ba00SJan Kneschke }
2699e75ba00SJan Kneschke 
2706044dbc5SmOo size_t array_get_max_key_length(array *a) {
2716044dbc5SmOo 	size_t maxlen, i;
2726044dbc5SmOo 
2736044dbc5SmOo 	maxlen = 0;
2746044dbc5SmOo 	for (i = 0; i < a->used; i ++) {
2756044dbc5SmOo 		data_unset *du = a->data[i];
2766044dbc5SmOo 		size_t len = strlen(du->key->ptr);
2776044dbc5SmOo 
2786044dbc5SmOo 		if (len > maxlen) {
2796044dbc5SmOo 			maxlen = len;
2806044dbc5SmOo 		}
2816044dbc5SmOo 	}
2826044dbc5SmOo 	return maxlen;
2836044dbc5SmOo }
2846044dbc5SmOo 
2859e75ba00SJan Kneschke int array_print(array *a, int depth) {
286bcdc6a3bSJan Kneschke 	size_t i;
2876044dbc5SmOo 	size_t maxlen;
2886044dbc5SmOo 	int oneline = 1;
289bcdc6a3bSJan Kneschke 
2906044dbc5SmOo 	if (a->used > 5) {
2916044dbc5SmOo 		oneline = 0;
2926044dbc5SmOo 	}
2936044dbc5SmOo 	for (i = 0; i < a->used && oneline; i++) {
2946044dbc5SmOo 		data_unset *du = a->data[i];
295f387d898SmOo 		if (!du->is_index_key) {
2966044dbc5SmOo 			oneline = 0;
2976044dbc5SmOo 			break;
2986044dbc5SmOo 		}
2996044dbc5SmOo 		switch (du->type) {
3006044dbc5SmOo 			case TYPE_INTEGER:
3016044dbc5SmOo 			case TYPE_STRING:
3026044dbc5SmOo 			case TYPE_COUNT:
3036044dbc5SmOo 				break;
3046044dbc5SmOo 			default:
3056044dbc5SmOo 				oneline = 0;
3066044dbc5SmOo 				break;
3076044dbc5SmOo 		}
3086044dbc5SmOo 	}
3096044dbc5SmOo 	if (oneline) {
310dd0abe5aSJan Kneschke 		fprintf(stdout, "(");
311bcdc6a3bSJan Kneschke 		for (i = 0; i < a->used; i++) {
3126044dbc5SmOo 			data_unset *du = a->data[i];
3136044dbc5SmOo 			if (i != 0) {
314dd0abe5aSJan Kneschke 				fprintf(stdout, ", ");
3156044dbc5SmOo 			}
3166044dbc5SmOo 			du->print(du, depth + 1);
3176044dbc5SmOo 		}
318dd0abe5aSJan Kneschke 		fprintf(stdout, ")");
3196044dbc5SmOo 		return 0;
3206044dbc5SmOo 	}
3216044dbc5SmOo 
3226044dbc5SmOo 	maxlen = array_get_max_key_length(a);
323dd0abe5aSJan Kneschke 	fprintf(stdout, "(\n");
3246044dbc5SmOo 	for (i = 0; i < a->used; i++) {
3256044dbc5SmOo 		data_unset *du = a->data[i];
3268b07d57dSJan Kneschke 		array_print_indent(depth + 1);
327f387d898SmOo 		if (!du->is_index_key) {
3286044dbc5SmOo 			int j;
3296044dbc5SmOo 
3306044dbc5SmOo 			if (i && (i % 5) == 0) {
331dd0abe5aSJan Kneschke 				fprintf(stdout, "# %zd\n", i);
3326044dbc5SmOo 				array_print_indent(depth + 1);
3336044dbc5SmOo 			}
334dd0abe5aSJan Kneschke 			fprintf(stdout, "\"%s\"", du->key->ptr);
3356044dbc5SmOo 			for (j = maxlen - strlen(du->key->ptr); j > 0; j --) {
336dd0abe5aSJan Kneschke 				fprintf(stdout, " ");
3376044dbc5SmOo 			}
338dd0abe5aSJan Kneschke 			fprintf(stdout, " => ");
3396044dbc5SmOo 		}
3406044dbc5SmOo 		du->print(du, depth + 1);
341dd0abe5aSJan Kneschke 		fprintf(stdout, ",\n");
3426044dbc5SmOo 	}
3436044dbc5SmOo 	if (!(i && (i - 1 % 5) == 0)) {
3446044dbc5SmOo 		array_print_indent(depth + 1);
345dd0abe5aSJan Kneschke 		fprintf(stdout, "# %zd\n", i);
346bcdc6a3bSJan Kneschke 	}
3478b07d57dSJan Kneschke 	array_print_indent(depth);
348dd0abe5aSJan Kneschke 	fprintf(stdout, ")");
349bcdc6a3bSJan Kneschke 
350bcdc6a3bSJan Kneschke 	return 0;
351bcdc6a3bSJan Kneschke }
352bcdc6a3bSJan Kneschke 
353bcdc6a3bSJan Kneschke #ifdef DEBUG_ARRAY
354bcdc6a3bSJan Kneschke int main (int argc, char **argv) {
355bcdc6a3bSJan Kneschke 	array *a;
356bcdc6a3bSJan Kneschke 	data_string *ds;
357bcdc6a3bSJan Kneschke 	data_count *dc;
358bcdc6a3bSJan Kneschke 
359bcdc6a3bSJan Kneschke 	UNUSED(argc);
360bcdc6a3bSJan Kneschke 	UNUSED(argv);
361bcdc6a3bSJan Kneschke 
362bcdc6a3bSJan Kneschke 	a = array_init();
363bcdc6a3bSJan Kneschke 
364bcdc6a3bSJan Kneschke 	ds = data_string_init();
36552861d77SStefan Bühler 	buffer_copy_string_len(ds->key, CONST_STR_LEN("abc"));
36652861d77SStefan Bühler 	buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag"));
367bcdc6a3bSJan Kneschke 
368bcdc6a3bSJan Kneschke 	array_insert_unique(a, (data_unset *)ds);
369bcdc6a3bSJan Kneschke 
370bcdc6a3bSJan Kneschke 	ds = data_string_init();
37152861d77SStefan Bühler 	buffer_copy_string_len(ds->key, CONST_STR_LEN("abc"));
37252861d77SStefan Bühler 	buffer_copy_string_len(ds->value, CONST_STR_LEN("hameplman"));
373bcdc6a3bSJan Kneschke 
374bcdc6a3bSJan Kneschke 	array_insert_unique(a, (data_unset *)ds);
375bcdc6a3bSJan Kneschke 
376bcdc6a3bSJan Kneschke 	ds = data_string_init();
37752861d77SStefan Bühler 	buffer_copy_string_len(ds->key, CONST_STR_LEN("123"));
37852861d77SStefan Bühler 	buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag"));
379bcdc6a3bSJan Kneschke 
380bcdc6a3bSJan Kneschke 	array_insert_unique(a, (data_unset *)ds);
381bcdc6a3bSJan Kneschke 
382bcdc6a3bSJan Kneschke 	dc = data_count_init();
38352861d77SStefan Bühler 	buffer_copy_string_len(dc->key, CONST_STR_LEN("def"));
384bcdc6a3bSJan Kneschke 
385bcdc6a3bSJan Kneschke 	array_insert_unique(a, (data_unset *)dc);
386bcdc6a3bSJan Kneschke 
387bcdc6a3bSJan Kneschke 	dc = data_count_init();
38852861d77SStefan Bühler 	buffer_copy_string_len(dc->key, CONST_STR_LEN("def"));
389bcdc6a3bSJan Kneschke 
390bcdc6a3bSJan Kneschke 	array_insert_unique(a, (data_unset *)dc);
391bcdc6a3bSJan Kneschke 
3929e75ba00SJan Kneschke 	array_print(a, 0);
393bcdc6a3bSJan Kneschke 
394bcdc6a3bSJan Kneschke 	array_free(a);
395bcdc6a3bSJan Kneschke 
396bcdc6a3bSJan Kneschke 	fprintf(stderr, "%d\n",
397bcdc6a3bSJan Kneschke 	       buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type")));
398bcdc6a3bSJan Kneschke 
399bcdc6a3bSJan Kneschke 	return 0;
400bcdc6a3bSJan Kneschke }
401bcdc6a3bSJan Kneschke #endif
402