18abd06a7SGlenn Strauss #include "first.h" 28abd06a7SGlenn Strauss 322e8b456SStefan Bühler #include "array.h" 422e8b456SStefan Bühler #include "buffer.h" 522e8b456SStefan Bühler 6bcdc6a3bSJan Kneschke #include <string.h> 7bcdc6a3bSJan Kneschke #include <stdio.h> 8bcdc6a3bSJan Kneschke #include <stdlib.h> 9bcdc6a3bSJan Kneschke #include <limits.h> 10bcdc6a3bSJan Kneschke 11bcdc6a3bSJan Kneschke #include <errno.h> 12bcdc6a3bSJan Kneschke #include <assert.h> 13bcdc6a3bSJan Kneschke 14224bf545SStefan Bühler #define ARRAY_NOT_FOUND ((size_t)(-1)) 15224bf545SStefan Bühler 16bcdc6a3bSJan Kneschke array *array_init(void) { 17bcdc6a3bSJan Kneschke array *a; 18bcdc6a3bSJan Kneschke 19bcdc6a3bSJan Kneschke a = calloc(1, sizeof(*a)); 2007dd0bd0SStefan Bühler force_assert(a); 21bcdc6a3bSJan Kneschke 22bcdc6a3bSJan Kneschke return a; 23bcdc6a3bSJan Kneschke } 24bcdc6a3bSJan Kneschke 256e78c2c8SJan Kneschke array *array_init_array(array *src) { 266e78c2c8SJan Kneschke size_t i; 276e78c2c8SJan Kneschke array *a = array_init(); 286e78c2c8SJan Kneschke 296f208cfdSStefan Bühler if (0 == src->size) return a; 306f208cfdSStefan Bühler 316e78c2c8SJan Kneschke a->used = src->used; 326e78c2c8SJan Kneschke a->size = src->size; 336e78c2c8SJan Kneschke a->unique_ndx = src->unique_ndx; 346e78c2c8SJan Kneschke 356e78c2c8SJan Kneschke a->data = malloc(sizeof(*src->data) * src->size); 36566cf8deSStefan Bühler force_assert(NULL != a->data); 376e78c2c8SJan Kneschke for (i = 0; i < src->size; i++) { 386e78c2c8SJan Kneschke if (src->data[i]) a->data[i] = src->data[i]->copy(src->data[i]); 396e78c2c8SJan Kneschke else a->data[i] = NULL; 406e78c2c8SJan Kneschke } 416e78c2c8SJan Kneschke 426e78c2c8SJan Kneschke a->sorted = malloc(sizeof(*src->sorted) * src->size); 43566cf8deSStefan Bühler force_assert(NULL != a->sorted); 446e78c2c8SJan Kneschke memcpy(a->sorted, src->sorted, sizeof(*src->sorted) * src->size); 456e78c2c8SJan Kneschke return a; 466e78c2c8SJan Kneschke } 476e78c2c8SJan Kneschke 48bcdc6a3bSJan Kneschke void array_free(array *a) { 49bcdc6a3bSJan Kneschke size_t i; 50bcdc6a3bSJan Kneschke if (!a) return; 51bcdc6a3bSJan Kneschke 52bcdc6a3bSJan Kneschke for (i = 0; i < a->size; i++) { 53bcdc6a3bSJan Kneschke if (a->data[i]) a->data[i]->free(a->data[i]); 54bcdc6a3bSJan Kneschke } 55bcdc6a3bSJan Kneschke 56bcdc6a3bSJan Kneschke if (a->data) free(a->data); 57bcdc6a3bSJan Kneschke if (a->sorted) free(a->sorted); 58bcdc6a3bSJan Kneschke 59bcdc6a3bSJan Kneschke free(a); 60bcdc6a3bSJan Kneschke } 61bcdc6a3bSJan Kneschke 62bcdc6a3bSJan Kneschke void array_reset(array *a) { 63bcdc6a3bSJan Kneschke size_t i; 64bcdc6a3bSJan Kneschke if (!a) return; 65bcdc6a3bSJan Kneschke 66bcdc6a3bSJan Kneschke for (i = 0; i < a->used; i++) { 67bcdc6a3bSJan Kneschke a->data[i]->reset(a->data[i]); 68bcdc6a3bSJan Kneschke } 69bcdc6a3bSJan Kneschke 70bcdc6a3bSJan Kneschke a->used = 0; 718d8ae9cbSStefan Bühler a->unique_ndx = 0; 72bcdc6a3bSJan Kneschke } 73bcdc6a3bSJan Kneschke 748073d5feSJan Kneschke data_unset *array_pop(array *a) { 758073d5feSJan Kneschke data_unset *du; 768073d5feSJan Kneschke 7707dd0bd0SStefan Bühler force_assert(a->used != 0); 788073d5feSJan Kneschke 798073d5feSJan Kneschke a->used --; 808073d5feSJan Kneschke du = a->data[a->used]; 818d8ae9cbSStefan Bühler force_assert(a->sorted[a->used] == a->used); /* only works on "simple" lists */ 828073d5feSJan Kneschke a->data[a->used] = NULL; 838073d5feSJan Kneschke 848073d5feSJan Kneschke return du; 858073d5feSJan Kneschke } 868073d5feSJan Kneschke 87224bf545SStefan Bühler /* returns index of element or ARRAY_NOT_FOUND 88224bf545SStefan Bühler * if rndx != NULL it stores the position in a->sorted[] where the key needs 89224bf545SStefan Bühler * to be inserted 90224bf545SStefan Bühler */ 91224bf545SStefan Bühler static size_t array_get_index(array *a, const char *key, size_t keylen, size_t *rndx) { 92224bf545SStefan Bühler /* invariant: [lower-1] < key < [upper] 93224bf545SStefan Bühler * "virtual elements": [-1] = -INFTY, [a->used] = +INFTY 94224bf545SStefan Bühler * also an invariant: 0 <= lower <= upper <= a->used 95224bf545SStefan Bühler */ 96224bf545SStefan Bühler size_t lower = 0, upper = a->used; 97224bf545SStefan Bühler force_assert(upper <= SSIZE_MAX); /* (lower + upper) can't overflow */ 98bcdc6a3bSJan Kneschke 99224bf545SStefan Bühler while (lower != upper) { 100224bf545SStefan Bühler size_t probe = (lower + upper) / 2; 101224bf545SStefan Bühler int cmp = buffer_caseless_compare(key, keylen, CONST_BUF_LEN(a->data[a->sorted[probe]]->key)); 102224bf545SStefan Bühler assert(lower < upper); /* from loop invariant (lower <= upper) + (lower != upper) */ 103224bf545SStefan Bühler assert((lower <= probe) && (probe < upper)); /* follows from lower < upper */ 104bcdc6a3bSJan Kneschke 105bcdc6a3bSJan Kneschke if (cmp == 0) { 106bcdc6a3bSJan Kneschke /* found */ 107224bf545SStefan Bühler if (rndx) *rndx = probe; 108224bf545SStefan Bühler return a->sorted[probe]; 109bcdc6a3bSJan Kneschke } else if (cmp < 0) { 110224bf545SStefan Bühler /* key < [probe] */ 111224bf545SStefan Bühler upper = probe; /* still: lower <= upper */ 112bcdc6a3bSJan Kneschke } else { 113224bf545SStefan Bühler /* key > [probe] */ 114224bf545SStefan Bühler lower = probe + 1; /* still: lower <= upper */ 115bcdc6a3bSJan Kneschke } 116bcdc6a3bSJan Kneschke } 117bcdc6a3bSJan Kneschke 118224bf545SStefan Bühler /* not found: [lower-1] < key < [upper] = [lower] ==> insert at [lower] */ 119224bf545SStefan Bühler if (rndx) *rndx = lower; 120224bf545SStefan Bühler return ARRAY_NOT_FOUND; 121bcdc6a3bSJan Kneschke } 122bcdc6a3bSJan Kneschke 123bcdc6a3bSJan Kneschke data_unset *array_get_element(array *a, const char *key) { 124224bf545SStefan Bühler size_t ndx; 125224bf545SStefan Bühler force_assert(NULL != key); 126bcdc6a3bSJan Kneschke 127224bf545SStefan Bühler if (ARRAY_NOT_FOUND != (ndx = array_get_index(a, key, strlen(key), NULL))) { 128224bf545SStefan Bühler /* found, return it */ 129bcdc6a3bSJan Kneschke return a->data[ndx]; 130bcdc6a3bSJan Kneschke } 131bcdc6a3bSJan Kneschke 132bcdc6a3bSJan Kneschke return NULL; 133bcdc6a3bSJan Kneschke } 134bcdc6a3bSJan Kneschke 13568e4a416SStefan Bühler data_unset *array_extract_element(array *a, const char *key) { 13668e4a416SStefan Bühler size_t ndx, pos; 13768e4a416SStefan Bühler force_assert(NULL != key); 13868e4a416SStefan Bühler 13968e4a416SStefan Bühler if (ARRAY_NOT_FOUND != (ndx = array_get_index(a, key, strlen(key), &pos))) { 14068e4a416SStefan Bühler /* found */ 14168e4a416SStefan Bühler const size_t last_ndx = a->used - 1; 14268e4a416SStefan Bühler data_unset *entry = a->data[ndx]; 14368e4a416SStefan Bühler 14468e4a416SStefan Bühler /* now we need to swap it with the last element (if it isn't already the last element) */ 14568e4a416SStefan Bühler if (ndx != last_ndx) { 14668e4a416SStefan Bühler /* to swap we also need to modify the index in a->sorted - find pos of last_elem there */ 14768e4a416SStefan Bühler size_t last_elem_pos; 14868e4a416SStefan Bühler /* last element must be present at the expected position */ 14968e4a416SStefan Bühler force_assert(last_ndx == array_get_index(a, CONST_BUF_LEN(a->data[last_ndx]->key), &last_elem_pos)); 15068e4a416SStefan Bühler 15168e4a416SStefan Bühler /* move entry from last_ndx to ndx */ 15268e4a416SStefan Bühler a->data[ndx] = a->data[last_ndx]; 15368e4a416SStefan Bühler a->data[last_ndx] = NULL; 15468e4a416SStefan Bühler 15568e4a416SStefan Bühler /* fix index entry for moved entry */ 15668e4a416SStefan Bühler a->sorted[last_elem_pos] = ndx; 15768e4a416SStefan Bühler } else { 15868e4a416SStefan Bühler a->data[ndx] = NULL; 15968e4a416SStefan Bühler } 16068e4a416SStefan Bühler 16168e4a416SStefan Bühler /* remove entry in a->sorted: move everything after pos one step to the left */ 16268e4a416SStefan Bühler if (pos != last_ndx) { 16368e4a416SStefan Bühler memmove(a->sorted + pos, a->sorted + pos + 1, (last_ndx - pos) * sizeof(*a->sorted)); 16468e4a416SStefan Bühler } 16568e4a416SStefan Bühler a->sorted[last_ndx] = ARRAY_NOT_FOUND; 16668e4a416SStefan Bühler --a->used; 16768e4a416SStefan Bühler 16868e4a416SStefan Bühler return entry; 16968e4a416SStefan Bühler } 17068e4a416SStefan Bühler 17168e4a416SStefan Bühler return NULL; 17268e4a416SStefan Bühler } 17368e4a416SStefan Bühler 174bcdc6a3bSJan Kneschke data_unset *array_get_unused_element(array *a, data_type_t t) { 175bcdc6a3bSJan Kneschke data_unset *ds = NULL; 17612f375f3SStefan Bühler unsigned int i; 177bcdc6a3bSJan Kneschke 17812f375f3SStefan Bühler for (i = a->used; i < a->size; i++) { 17912f375f3SStefan Bühler if (a->data[i] && a->data[i]->type == t) { 18012f375f3SStefan Bühler ds = a->data[i]; 181bcdc6a3bSJan Kneschke 18212f375f3SStefan Bühler /* make empty slot at a->used for next insert */ 18312f375f3SStefan Bühler a->data[i] = a->data[a->used]; 184bcdc6a3bSJan Kneschke a->data[a->used] = NULL; 185bcdc6a3bSJan Kneschke 186bcdc6a3bSJan Kneschke return ds; 187bcdc6a3bSJan Kneschke } 18812f375f3SStefan Bühler } 18912f375f3SStefan Bühler 19012f375f3SStefan Bühler return NULL; 19112f375f3SStefan Bühler } 192bcdc6a3bSJan Kneschke 1934f4d40f3SStefan Bühler void array_set_key_value(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) { 1944f4d40f3SStefan Bühler data_string *ds_dst; 1954f4d40f3SStefan Bühler 1964f4d40f3SStefan Bühler if (NULL != (ds_dst = (data_string *)array_get_element(hdrs, key))) { 1974f4d40f3SStefan Bühler buffer_copy_string_len(ds_dst->value, value, val_len); 1984f4d40f3SStefan Bühler return; 1994f4d40f3SStefan Bühler } 2004f4d40f3SStefan Bühler 2014f4d40f3SStefan Bühler if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) { 2024f4d40f3SStefan Bühler ds_dst = data_string_init(); 2034f4d40f3SStefan Bühler } 2044f4d40f3SStefan Bühler 2054f4d40f3SStefan Bühler buffer_copy_string_len(ds_dst->key, key, key_len); 2064f4d40f3SStefan Bühler buffer_copy_string_len(ds_dst->value, value, val_len); 2074f4d40f3SStefan Bühler array_insert_unique(hdrs, (data_unset *)ds_dst); 2084f4d40f3SStefan Bühler } 2094f4d40f3SStefan Bühler 2108d8ae9cbSStefan Bühler /* if entry already exists return pointer to existing entry, otherwise insert entry and return NULL */ 211be121a63SStefan Bühler static data_unset **array_find_or_insert(array *a, data_unset *entry) { 212224bf545SStefan Bühler size_t ndx, pos, j; 213bcdc6a3bSJan Kneschke 214bcdc6a3bSJan Kneschke /* generate unique index if neccesary */ 215be121a63SStefan Bühler if (buffer_is_empty(entry->key) || entry->is_index_key) { 216be121a63SStefan Bühler buffer_copy_int(entry->key, a->unique_ndx++); 217be121a63SStefan Bühler entry->is_index_key = 1; 2188d8ae9cbSStefan Bühler force_assert(0 != a->unique_ndx); /* must not wrap or we'll get problems */ 219bcdc6a3bSJan Kneschke } 220bcdc6a3bSJan Kneschke 221be121a63SStefan Bühler /* try to find the entry */ 222224bf545SStefan Bühler if (ARRAY_NOT_FOUND != (ndx = array_get_index(a, CONST_BUF_LEN(entry->key), &pos))) { 2238d8ae9cbSStefan Bühler /* found collision, return it */ 2248d8ae9cbSStefan Bühler return &a->data[ndx]; 225bcdc6a3bSJan Kneschke } 226bcdc6a3bSJan Kneschke 227bcdc6a3bSJan Kneschke /* insert */ 228bcdc6a3bSJan Kneschke 229224bf545SStefan Bühler /* there couldn't possibly be enough memory to store so many entries */ 230224bf545SStefan Bühler force_assert(a->used + 1 <= SSIZE_MAX); 231bcdc6a3bSJan Kneschke 232bcdc6a3bSJan Kneschke if (a->size == 0) { 233bcdc6a3bSJan Kneschke a->size = 16; 234bcdc6a3bSJan Kneschke a->data = malloc(sizeof(*a->data) * a->size); 235bcdc6a3bSJan Kneschke a->sorted = malloc(sizeof(*a->sorted) * a->size); 23607dd0bd0SStefan Bühler force_assert(a->data); 23707dd0bd0SStefan Bühler force_assert(a->sorted); 238bcdc6a3bSJan Kneschke for (j = a->used; j < a->size; j++) a->data[j] = NULL; 239bcdc6a3bSJan Kneschke } else if (a->size == a->used) { 240bcdc6a3bSJan Kneschke a->size += 16; 241bcdc6a3bSJan Kneschke a->data = realloc(a->data, sizeof(*a->data) * a->size); 242bcdc6a3bSJan Kneschke a->sorted = realloc(a->sorted, sizeof(*a->sorted) * a->size); 24307dd0bd0SStefan Bühler force_assert(a->data); 24407dd0bd0SStefan Bühler force_assert(a->sorted); 245bcdc6a3bSJan Kneschke for (j = a->used; j < a->size; j++) a->data[j] = NULL; 246bcdc6a3bSJan Kneschke } 247bcdc6a3bSJan Kneschke 248224bf545SStefan Bühler ndx = a->used; 249bcdc6a3bSJan Kneschke 25012f375f3SStefan Bühler /* make sure there is nothing here */ 25112f375f3SStefan Bühler if (a->data[ndx]) a->data[ndx]->free(a->data[ndx]); 25212f375f3SStefan Bühler 253be121a63SStefan Bühler a->data[a->used++] = entry; 254bcdc6a3bSJan Kneschke 2558d8ae9cbSStefan Bühler /* move everything one step to the right */ 256bcdc6a3bSJan Kneschke if (pos != ndx) { 257bcdc6a3bSJan Kneschke memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted)); 258bcdc6a3bSJan Kneschke } 259bcdc6a3bSJan Kneschke 260bcdc6a3bSJan Kneschke /* insert */ 261bcdc6a3bSJan Kneschke a->sorted[pos] = ndx; 262bcdc6a3bSJan Kneschke 2638d8ae9cbSStefan Bühler return NULL; 2648d8ae9cbSStefan Bühler } 2658d8ae9cbSStefan Bühler 2668d8ae9cbSStefan Bühler /* replace or insert data (free existing entry) */ 2678d8ae9cbSStefan Bühler void array_replace(array *a, data_unset *entry) { 2688d8ae9cbSStefan Bühler data_unset **old; 2698d8ae9cbSStefan Bühler 2708d8ae9cbSStefan Bühler force_assert(NULL != entry); 2718d8ae9cbSStefan Bühler if (NULL != (old = array_find_or_insert(a, entry))) { 2728d8ae9cbSStefan Bühler force_assert(*old != entry); 2738d8ae9cbSStefan Bühler (*old)->free(*old); 2748d8ae9cbSStefan Bühler *old = entry; 2758d8ae9cbSStefan Bühler } 2768d8ae9cbSStefan Bühler } 2778d8ae9cbSStefan Bühler 2788d8ae9cbSStefan Bühler void array_insert_unique(array *a, data_unset *entry) { 2798d8ae9cbSStefan Bühler data_unset **old; 2808d8ae9cbSStefan Bühler 2818d8ae9cbSStefan Bühler force_assert(NULL != entry); 2828d8ae9cbSStefan Bühler if (NULL != (old = array_find_or_insert(a, entry))) { 2838d8ae9cbSStefan Bühler force_assert((*old)->type == entry->type); 2848d8ae9cbSStefan Bühler entry->insert_dup(*old, entry); 2858d8ae9cbSStefan Bühler } 286bcdc6a3bSJan Kneschke } 287bcdc6a3bSJan Kneschke 288*bd77abe0SGlenn Strauss int array_is_vlist(array *a) { 289*bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 290*bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 291*bd77abe0SGlenn Strauss if (!du->is_index_key || du->type != TYPE_STRING) return 0; 292*bd77abe0SGlenn Strauss } 293*bd77abe0SGlenn Strauss return 1; 294*bd77abe0SGlenn Strauss } 295*bd77abe0SGlenn Strauss 296*bd77abe0SGlenn Strauss int array_is_kvany(array *a) { 297*bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 298*bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 299*bd77abe0SGlenn Strauss if (du->is_index_key) return 0; 300*bd77abe0SGlenn Strauss } 301*bd77abe0SGlenn Strauss return 1; 302*bd77abe0SGlenn Strauss } 303*bd77abe0SGlenn Strauss 304*bd77abe0SGlenn Strauss int array_is_kvarray(array *a) { 305*bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 306*bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 307*bd77abe0SGlenn Strauss if (du->is_index_key || du->type != TYPE_ARRAY) return 0; 308*bd77abe0SGlenn Strauss } 309*bd77abe0SGlenn Strauss return 1; 310*bd77abe0SGlenn Strauss } 311*bd77abe0SGlenn Strauss 312*bd77abe0SGlenn Strauss int array_is_kvstring(array *a) { 313*bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 314*bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 315*bd77abe0SGlenn Strauss if (du->is_index_key || du->type != TYPE_STRING) return 0; 316*bd77abe0SGlenn Strauss } 317*bd77abe0SGlenn Strauss return 1; 318*bd77abe0SGlenn Strauss } 319*bd77abe0SGlenn Strauss 3209e75ba00SJan Kneschke void array_print_indent(int depth) { 3219e75ba00SJan Kneschke int i; 3229e75ba00SJan Kneschke for (i = 0; i < depth; i ++) { 323dd0abe5aSJan Kneschke fprintf(stdout, " "); 3249e75ba00SJan Kneschke } 3259e75ba00SJan Kneschke } 3269e75ba00SJan Kneschke 3276044dbc5SmOo size_t array_get_max_key_length(array *a) { 3286044dbc5SmOo size_t maxlen, i; 3296044dbc5SmOo 3306044dbc5SmOo maxlen = 0; 3316044dbc5SmOo for (i = 0; i < a->used; i ++) { 3326044dbc5SmOo data_unset *du = a->data[i]; 3336044dbc5SmOo size_t len = strlen(du->key->ptr); 3346044dbc5SmOo 3356044dbc5SmOo if (len > maxlen) { 3366044dbc5SmOo maxlen = len; 3376044dbc5SmOo } 3386044dbc5SmOo } 3396044dbc5SmOo return maxlen; 3406044dbc5SmOo } 3416044dbc5SmOo 3429e75ba00SJan Kneschke int array_print(array *a, int depth) { 343bcdc6a3bSJan Kneschke size_t i; 3446044dbc5SmOo size_t maxlen; 3456044dbc5SmOo int oneline = 1; 346bcdc6a3bSJan Kneschke 3476044dbc5SmOo if (a->used > 5) { 3486044dbc5SmOo oneline = 0; 3496044dbc5SmOo } 3506044dbc5SmOo for (i = 0; i < a->used && oneline; i++) { 3516044dbc5SmOo data_unset *du = a->data[i]; 352f387d898SmOo if (!du->is_index_key) { 3536044dbc5SmOo oneline = 0; 3546044dbc5SmOo break; 3556044dbc5SmOo } 3566044dbc5SmOo switch (du->type) { 3576044dbc5SmOo case TYPE_INTEGER: 3586044dbc5SmOo case TYPE_STRING: 3596044dbc5SmOo break; 3606044dbc5SmOo default: 3616044dbc5SmOo oneline = 0; 3626044dbc5SmOo break; 3636044dbc5SmOo } 3646044dbc5SmOo } 3656044dbc5SmOo if (oneline) { 366dd0abe5aSJan Kneschke fprintf(stdout, "("); 367bcdc6a3bSJan Kneschke for (i = 0; i < a->used; i++) { 3686044dbc5SmOo data_unset *du = a->data[i]; 3696044dbc5SmOo if (i != 0) { 370dd0abe5aSJan Kneschke fprintf(stdout, ", "); 3716044dbc5SmOo } 3726044dbc5SmOo du->print(du, depth + 1); 3736044dbc5SmOo } 374dd0abe5aSJan Kneschke fprintf(stdout, ")"); 3756044dbc5SmOo return 0; 3766044dbc5SmOo } 3776044dbc5SmOo 3786044dbc5SmOo maxlen = array_get_max_key_length(a); 379dd0abe5aSJan Kneschke fprintf(stdout, "(\n"); 3806044dbc5SmOo for (i = 0; i < a->used; i++) { 3816044dbc5SmOo data_unset *du = a->data[i]; 3828b07d57dSJan Kneschke array_print_indent(depth + 1); 383f387d898SmOo if (!du->is_index_key) { 3846044dbc5SmOo int j; 3856044dbc5SmOo 3866044dbc5SmOo if (i && (i % 5) == 0) { 387acad2c90SGlenn Strauss fprintf(stdout, "# %zu\n", i); 3886044dbc5SmOo array_print_indent(depth + 1); 3896044dbc5SmOo } 390dd0abe5aSJan Kneschke fprintf(stdout, "\"%s\"", du->key->ptr); 3916044dbc5SmOo for (j = maxlen - strlen(du->key->ptr); j > 0; j --) { 392dd0abe5aSJan Kneschke fprintf(stdout, " "); 3936044dbc5SmOo } 394dd0abe5aSJan Kneschke fprintf(stdout, " => "); 3956044dbc5SmOo } 3966044dbc5SmOo du->print(du, depth + 1); 397dd0abe5aSJan Kneschke fprintf(stdout, ",\n"); 3986044dbc5SmOo } 3996044dbc5SmOo if (!(i && (i - 1 % 5) == 0)) { 4006044dbc5SmOo array_print_indent(depth + 1); 401acad2c90SGlenn Strauss fprintf(stdout, "# %zu\n", i); 402bcdc6a3bSJan Kneschke } 4038b07d57dSJan Kneschke array_print_indent(depth); 404dd0abe5aSJan Kneschke fprintf(stdout, ")"); 405bcdc6a3bSJan Kneschke 406bcdc6a3bSJan Kneschke return 0; 407bcdc6a3bSJan Kneschke } 408bcdc6a3bSJan Kneschke 409bcdc6a3bSJan Kneschke #ifdef DEBUG_ARRAY 410bcdc6a3bSJan Kneschke int main (int argc, char **argv) { 411bcdc6a3bSJan Kneschke array *a; 412bcdc6a3bSJan Kneschke data_string *ds; 413bcdc6a3bSJan Kneschke 414bcdc6a3bSJan Kneschke UNUSED(argc); 415bcdc6a3bSJan Kneschke UNUSED(argv); 416bcdc6a3bSJan Kneschke 417bcdc6a3bSJan Kneschke a = array_init(); 418bcdc6a3bSJan Kneschke 419bcdc6a3bSJan Kneschke ds = data_string_init(); 42052861d77SStefan Bühler buffer_copy_string_len(ds->key, CONST_STR_LEN("abc")); 42152861d77SStefan Bühler buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag")); 422bcdc6a3bSJan Kneschke 423bcdc6a3bSJan Kneschke array_insert_unique(a, (data_unset *)ds); 424bcdc6a3bSJan Kneschke 425bcdc6a3bSJan Kneschke ds = data_string_init(); 42652861d77SStefan Bühler buffer_copy_string_len(ds->key, CONST_STR_LEN("abc")); 42752861d77SStefan Bühler buffer_copy_string_len(ds->value, CONST_STR_LEN("hameplman")); 428bcdc6a3bSJan Kneschke 429bcdc6a3bSJan Kneschke array_insert_unique(a, (data_unset *)ds); 430bcdc6a3bSJan Kneschke 431bcdc6a3bSJan Kneschke ds = data_string_init(); 43252861d77SStefan Bühler buffer_copy_string_len(ds->key, CONST_STR_LEN("123")); 43352861d77SStefan Bühler buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag")); 434bcdc6a3bSJan Kneschke 435bcdc6a3bSJan Kneschke array_insert_unique(a, (data_unset *)ds); 436bcdc6a3bSJan Kneschke 4379e75ba00SJan Kneschke array_print(a, 0); 438bcdc6a3bSJan Kneschke 439bcdc6a3bSJan Kneschke array_free(a); 440bcdc6a3bSJan Kneschke 441bcdc6a3bSJan Kneschke fprintf(stderr, "%d\n", 442bcdc6a3bSJan Kneschke buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type"))); 443bcdc6a3bSJan Kneschke 444bcdc6a3bSJan Kneschke return 0; 445bcdc6a3bSJan Kneschke } 446bcdc6a3bSJan Kneschke #endif 447