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 <stdlib.h> 8bcdc6a3bSJan Kneschke #include <limits.h> 9bcdc6a3bSJan Kneschke 10bcdc6a3bSJan Kneschke #include <errno.h> 11bcdc6a3bSJan Kneschke #include <assert.h> 12bcdc6a3bSJan Kneschke 13224bf545SStefan Bühler #define ARRAY_NOT_FOUND ((size_t)(-1)) 14224bf545SStefan Bühler 15bcdc6a3bSJan Kneschke array *array_init(void) { 16bcdc6a3bSJan Kneschke array *a; 17bcdc6a3bSJan Kneschke 18bcdc6a3bSJan Kneschke a = calloc(1, sizeof(*a)); 1907dd0bd0SStefan Bühler force_assert(a); 20bcdc6a3bSJan Kneschke 21bcdc6a3bSJan Kneschke return a; 22bcdc6a3bSJan Kneschke } 23bcdc6a3bSJan Kneschke 246e78c2c8SJan Kneschke array *array_init_array(array *src) { 256e78c2c8SJan Kneschke size_t i; 266e78c2c8SJan Kneschke array *a = array_init(); 276e78c2c8SJan Kneschke 286f208cfdSStefan Bühler if (0 == src->size) return a; 296f208cfdSStefan Bühler 306e78c2c8SJan Kneschke a->used = src->used; 316e78c2c8SJan Kneschke a->size = src->size; 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 51bcdc6a3bSJan Kneschke for (i = 0; i < a->size; i++) { 52bcdc6a3bSJan Kneschke if (a->data[i]) a->data[i]->free(a->data[i]); 53bcdc6a3bSJan Kneschke } 54bcdc6a3bSJan Kneschke 55bcdc6a3bSJan Kneschke if (a->data) free(a->data); 56bcdc6a3bSJan Kneschke if (a->sorted) free(a->sorted); 57bcdc6a3bSJan Kneschke 58bcdc6a3bSJan Kneschke free(a); 59bcdc6a3bSJan Kneschke } 60bcdc6a3bSJan Kneschke 61bcdc6a3bSJan Kneschke void array_reset(array *a) { 62bcdc6a3bSJan Kneschke size_t i; 63bcdc6a3bSJan Kneschke if (!a) return; 64bcdc6a3bSJan Kneschke 65bcdc6a3bSJan Kneschke for (i = 0; i < a->used; i++) { 66bcdc6a3bSJan Kneschke a->data[i]->reset(a->data[i]); 67bcdc6a3bSJan Kneschke } 68bcdc6a3bSJan Kneschke 69bcdc6a3bSJan Kneschke a->used = 0; 708d8ae9cbSStefan Bühler a->unique_ndx = 0; 71bcdc6a3bSJan Kneschke } 72bcdc6a3bSJan Kneschke 738073d5feSJan Kneschke data_unset *array_pop(array *a) { 748073d5feSJan Kneschke data_unset *du; 758073d5feSJan Kneschke 7607dd0bd0SStefan Bühler force_assert(a->used != 0); 778073d5feSJan Kneschke 788073d5feSJan Kneschke a->used --; 798073d5feSJan Kneschke du = a->data[a->used]; 808d8ae9cbSStefan Bühler force_assert(a->sorted[a->used] == a->used); /* only works on "simple" lists */ 818073d5feSJan Kneschke a->data[a->used] = NULL; 828073d5feSJan Kneschke 838073d5feSJan Kneschke return du; 848073d5feSJan Kneschke } 858073d5feSJan Kneschke 86224bf545SStefan Bühler /* returns index of element or ARRAY_NOT_FOUND 87224bf545SStefan Bühler * if rndx != NULL it stores the position in a->sorted[] where the key needs 88224bf545SStefan Bühler * to be inserted 89224bf545SStefan Bühler */ 902496c1afSGlenn Strauss static size_t array_get_index(const array *a, const char *key, size_t keylen, size_t *rndx) { 91224bf545SStefan Bühler /* invariant: [lower-1] < key < [upper] 92224bf545SStefan Bühler * "virtual elements": [-1] = -INFTY, [a->used] = +INFTY 93224bf545SStefan Bühler * also an invariant: 0 <= lower <= upper <= a->used 94224bf545SStefan Bühler */ 95224bf545SStefan Bühler size_t lower = 0, upper = a->used; 96224bf545SStefan Bühler force_assert(upper <= SSIZE_MAX); /* (lower + upper) can't overflow */ 97bcdc6a3bSJan Kneschke 98224bf545SStefan Bühler while (lower != upper) { 99224bf545SStefan Bühler size_t probe = (lower + upper) / 2; 100224bf545SStefan Bühler int cmp = buffer_caseless_compare(key, keylen, CONST_BUF_LEN(a->data[a->sorted[probe]]->key)); 101224bf545SStefan Bühler assert(lower < upper); /* from loop invariant (lower <= upper) + (lower != upper) */ 102224bf545SStefan Bühler assert((lower <= probe) && (probe < upper)); /* follows from lower < upper */ 103bcdc6a3bSJan Kneschke 104bcdc6a3bSJan Kneschke if (cmp == 0) { 105bcdc6a3bSJan Kneschke /* found */ 106224bf545SStefan Bühler if (rndx) *rndx = probe; 107224bf545SStefan Bühler return a->sorted[probe]; 108bcdc6a3bSJan Kneschke } else if (cmp < 0) { 109224bf545SStefan Bühler /* key < [probe] */ 110224bf545SStefan Bühler upper = probe; /* still: lower <= upper */ 111bcdc6a3bSJan Kneschke } else { 112224bf545SStefan Bühler /* key > [probe] */ 113224bf545SStefan Bühler lower = probe + 1; /* still: lower <= upper */ 114bcdc6a3bSJan Kneschke } 115bcdc6a3bSJan Kneschke } 116bcdc6a3bSJan Kneschke 117224bf545SStefan Bühler /* not found: [lower-1] < key < [upper] = [lower] ==> insert at [lower] */ 118224bf545SStefan Bühler if (rndx) *rndx = lower; 119224bf545SStefan Bühler return ARRAY_NOT_FOUND; 120bcdc6a3bSJan Kneschke } 121bcdc6a3bSJan Kneschke 1222496c1afSGlenn Strauss data_unset *array_get_element_klen(const array *a, const char *key, size_t klen) { 123224bf545SStefan Bühler size_t ndx; 124224bf545SStefan Bühler force_assert(NULL != key); 125bcdc6a3bSJan Kneschke 12686bb8be2SGlenn Strauss if (ARRAY_NOT_FOUND != (ndx = array_get_index(a, key, klen, NULL))) { 127224bf545SStefan Bühler /* found, return it */ 128bcdc6a3bSJan Kneschke return a->data[ndx]; 129bcdc6a3bSJan Kneschke } 130bcdc6a3bSJan Kneschke 131bcdc6a3bSJan Kneschke return NULL; 132bcdc6a3bSJan Kneschke } 133bcdc6a3bSJan Kneschke 13486bb8be2SGlenn Strauss data_unset *array_extract_element_klen(array *a, const char *key, size_t klen) { 13568e4a416SStefan Bühler size_t ndx, pos; 13668e4a416SStefan Bühler force_assert(NULL != key); 13768e4a416SStefan Bühler 13886bb8be2SGlenn Strauss if (ARRAY_NOT_FOUND != (ndx = array_get_index(a, key, klen, &pos))) { 13968e4a416SStefan Bühler /* found */ 14068e4a416SStefan Bühler const size_t last_ndx = a->used - 1; 14168e4a416SStefan Bühler data_unset *entry = a->data[ndx]; 14268e4a416SStefan Bühler 14368e4a416SStefan Bühler /* now we need to swap it with the last element (if it isn't already the last element) */ 14468e4a416SStefan Bühler if (ndx != last_ndx) { 14568e4a416SStefan Bühler /* to swap we also need to modify the index in a->sorted - find pos of last_elem there */ 14668e4a416SStefan Bühler size_t last_elem_pos; 14768e4a416SStefan Bühler /* last element must be present at the expected position */ 14868e4a416SStefan Bühler force_assert(last_ndx == array_get_index(a, CONST_BUF_LEN(a->data[last_ndx]->key), &last_elem_pos)); 14968e4a416SStefan Bühler 15068e4a416SStefan Bühler /* move entry from last_ndx to ndx */ 15168e4a416SStefan Bühler a->data[ndx] = a->data[last_ndx]; 15268e4a416SStefan Bühler a->data[last_ndx] = NULL; 15368e4a416SStefan Bühler 15468e4a416SStefan Bühler /* fix index entry for moved entry */ 15568e4a416SStefan Bühler a->sorted[last_elem_pos] = ndx; 15668e4a416SStefan Bühler } else { 15768e4a416SStefan Bühler a->data[ndx] = NULL; 15868e4a416SStefan Bühler } 15968e4a416SStefan Bühler 16068e4a416SStefan Bühler /* remove entry in a->sorted: move everything after pos one step to the left */ 16168e4a416SStefan Bühler if (pos != last_ndx) { 16268e4a416SStefan Bühler memmove(a->sorted + pos, a->sorted + pos + 1, (last_ndx - pos) * sizeof(*a->sorted)); 16368e4a416SStefan Bühler } 16468e4a416SStefan Bühler a->sorted[last_ndx] = ARRAY_NOT_FOUND; 16568e4a416SStefan Bühler --a->used; 16668e4a416SStefan Bühler 16768e4a416SStefan Bühler return entry; 16868e4a416SStefan Bühler } 16968e4a416SStefan Bühler 17068e4a416SStefan Bühler return NULL; 17168e4a416SStefan Bühler } 17268e4a416SStefan Bühler 173*a7c27c9fSGlenn Strauss static data_unset *array_get_unused_element(array *a, data_type_t t) { 174bcdc6a3bSJan Kneschke data_unset *ds = NULL; 17512f375f3SStefan Bühler unsigned int i; 176bcdc6a3bSJan Kneschke 17712f375f3SStefan Bühler for (i = a->used; i < a->size; i++) { 17812f375f3SStefan Bühler if (a->data[i] && a->data[i]->type == t) { 17912f375f3SStefan Bühler ds = a->data[i]; 180bcdc6a3bSJan Kneschke 18112f375f3SStefan Bühler /* make empty slot at a->used for next insert */ 18212f375f3SStefan Bühler a->data[i] = a->data[a->used]; 183bcdc6a3bSJan Kneschke a->data[a->used] = NULL; 184bcdc6a3bSJan Kneschke 185bcdc6a3bSJan Kneschke return ds; 186bcdc6a3bSJan Kneschke } 18712f375f3SStefan Bühler } 18812f375f3SStefan Bühler 18912f375f3SStefan Bühler return NULL; 19012f375f3SStefan Bühler } 191bcdc6a3bSJan Kneschke 1924f4d40f3SStefan Bühler void array_set_key_value(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) { 193*a7c27c9fSGlenn Strauss data_string *ds; 1944f4d40f3SStefan Bühler 195*a7c27c9fSGlenn Strauss if (NULL != (ds = (data_string *)array_get_element_klen(hdrs, key, key_len))) { 196*a7c27c9fSGlenn Strauss buffer_copy_string_len(ds->value, value, val_len); 1974f4d40f3SStefan Bühler return; 1984f4d40f3SStefan Bühler } 1994f4d40f3SStefan Bühler 200*a7c27c9fSGlenn Strauss array_insert_key_value(hdrs, key, key_len, value, val_len); 2014f4d40f3SStefan Bühler } 2024f4d40f3SStefan Bühler 203*a7c27c9fSGlenn Strauss void array_insert_key_value(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) { 204*a7c27c9fSGlenn Strauss data_string *ds; 205*a7c27c9fSGlenn Strauss 206*a7c27c9fSGlenn Strauss if (NULL == (ds = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) { 207*a7c27c9fSGlenn Strauss ds = data_string_init(); 208*a7c27c9fSGlenn Strauss } 209*a7c27c9fSGlenn Strauss 210*a7c27c9fSGlenn Strauss buffer_copy_string_len(ds->key, key, key_len); 211*a7c27c9fSGlenn Strauss buffer_copy_string_len(ds->value, value, val_len); 212*a7c27c9fSGlenn Strauss array_insert_unique(hdrs, (data_unset *)ds); 213*a7c27c9fSGlenn Strauss } 214*a7c27c9fSGlenn Strauss 215*a7c27c9fSGlenn Strauss void array_insert_value(array *hdrs, const char *value, size_t val_len) { 216*a7c27c9fSGlenn Strauss data_string *ds; 217*a7c27c9fSGlenn Strauss 218*a7c27c9fSGlenn Strauss if (NULL == (ds = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) { 219*a7c27c9fSGlenn Strauss ds = data_string_init(); 220*a7c27c9fSGlenn Strauss } 221*a7c27c9fSGlenn Strauss 222*a7c27c9fSGlenn Strauss buffer_copy_string_len(ds->value, value, val_len); 223*a7c27c9fSGlenn Strauss array_insert_unique(hdrs, (data_unset *)ds); 2244f4d40f3SStefan Bühler } 2254f4d40f3SStefan Bühler 2268d8ae9cbSStefan Bühler /* if entry already exists return pointer to existing entry, otherwise insert entry and return NULL */ 227be121a63SStefan Bühler static data_unset **array_find_or_insert(array *a, data_unset *entry) { 228224bf545SStefan Bühler size_t ndx, pos, j; 229bcdc6a3bSJan Kneschke 230bcdc6a3bSJan Kneschke /* generate unique index if neccesary */ 231be121a63SStefan Bühler if (buffer_is_empty(entry->key) || entry->is_index_key) { 232be121a63SStefan Bühler buffer_copy_int(entry->key, a->unique_ndx++); 233be121a63SStefan Bühler entry->is_index_key = 1; 2348d8ae9cbSStefan Bühler force_assert(0 != a->unique_ndx); /* must not wrap or we'll get problems */ 235bcdc6a3bSJan Kneschke } 236bcdc6a3bSJan Kneschke 237be121a63SStefan Bühler /* try to find the entry */ 238224bf545SStefan Bühler if (ARRAY_NOT_FOUND != (ndx = array_get_index(a, CONST_BUF_LEN(entry->key), &pos))) { 2398d8ae9cbSStefan Bühler /* found collision, return it */ 2408d8ae9cbSStefan Bühler return &a->data[ndx]; 241bcdc6a3bSJan Kneschke } 242bcdc6a3bSJan Kneschke 243bcdc6a3bSJan Kneschke /* insert */ 244bcdc6a3bSJan Kneschke 245224bf545SStefan Bühler /* there couldn't possibly be enough memory to store so many entries */ 246224bf545SStefan Bühler force_assert(a->used + 1 <= SSIZE_MAX); 247bcdc6a3bSJan Kneschke 248bcdc6a3bSJan Kneschke if (a->size == 0) { 249bcdc6a3bSJan Kneschke a->size = 16; 250bcdc6a3bSJan Kneschke a->data = malloc(sizeof(*a->data) * a->size); 251bcdc6a3bSJan Kneschke a->sorted = malloc(sizeof(*a->sorted) * a->size); 25207dd0bd0SStefan Bühler force_assert(a->data); 25307dd0bd0SStefan Bühler force_assert(a->sorted); 254bcdc6a3bSJan Kneschke for (j = a->used; j < a->size; j++) a->data[j] = NULL; 255bcdc6a3bSJan Kneschke } else if (a->size == a->used) { 256bcdc6a3bSJan Kneschke a->size += 16; 257bcdc6a3bSJan Kneschke a->data = realloc(a->data, sizeof(*a->data) * a->size); 258bcdc6a3bSJan Kneschke a->sorted = realloc(a->sorted, sizeof(*a->sorted) * a->size); 25907dd0bd0SStefan Bühler force_assert(a->data); 26007dd0bd0SStefan Bühler force_assert(a->sorted); 261bcdc6a3bSJan Kneschke for (j = a->used; j < a->size; j++) a->data[j] = NULL; 262bcdc6a3bSJan Kneschke } 263bcdc6a3bSJan Kneschke 264224bf545SStefan Bühler ndx = a->used; 265bcdc6a3bSJan Kneschke 26612f375f3SStefan Bühler /* make sure there is nothing here */ 26712f375f3SStefan Bühler if (a->data[ndx]) a->data[ndx]->free(a->data[ndx]); 26812f375f3SStefan Bühler 269be121a63SStefan Bühler a->data[a->used++] = entry; 270bcdc6a3bSJan Kneschke 2718d8ae9cbSStefan Bühler /* move everything one step to the right */ 272bcdc6a3bSJan Kneschke if (pos != ndx) { 273bcdc6a3bSJan Kneschke memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted)); 274bcdc6a3bSJan Kneschke } 275bcdc6a3bSJan Kneschke 276bcdc6a3bSJan Kneschke /* insert */ 277bcdc6a3bSJan Kneschke a->sorted[pos] = ndx; 278bcdc6a3bSJan Kneschke 2798d8ae9cbSStefan Bühler return NULL; 2808d8ae9cbSStefan Bühler } 2818d8ae9cbSStefan Bühler 2828d8ae9cbSStefan Bühler /* replace or insert data (free existing entry) */ 2838d8ae9cbSStefan Bühler void array_replace(array *a, data_unset *entry) { 2848d8ae9cbSStefan Bühler data_unset **old; 2858d8ae9cbSStefan Bühler 2868d8ae9cbSStefan Bühler force_assert(NULL != entry); 2878d8ae9cbSStefan Bühler if (NULL != (old = array_find_or_insert(a, entry))) { 2888d8ae9cbSStefan Bühler force_assert(*old != entry); 2898d8ae9cbSStefan Bühler (*old)->free(*old); 2908d8ae9cbSStefan Bühler *old = entry; 2918d8ae9cbSStefan Bühler } 2928d8ae9cbSStefan Bühler } 2938d8ae9cbSStefan Bühler 2948d8ae9cbSStefan Bühler void array_insert_unique(array *a, data_unset *entry) { 2958d8ae9cbSStefan Bühler data_unset **old; 2968d8ae9cbSStefan Bühler 2978d8ae9cbSStefan Bühler force_assert(NULL != entry); 2988d8ae9cbSStefan Bühler if (NULL != (old = array_find_or_insert(a, entry))) { 2998d8ae9cbSStefan Bühler force_assert((*old)->type == entry->type); 3008d8ae9cbSStefan Bühler entry->insert_dup(*old, entry); 3018d8ae9cbSStefan Bühler } 302bcdc6a3bSJan Kneschke } 303bcdc6a3bSJan Kneschke 304bd77abe0SGlenn Strauss int array_is_vlist(array *a) { 305bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 306bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 307bd77abe0SGlenn Strauss if (!du->is_index_key || du->type != TYPE_STRING) return 0; 308bd77abe0SGlenn Strauss } 309bd77abe0SGlenn Strauss return 1; 310bd77abe0SGlenn Strauss } 311bd77abe0SGlenn Strauss 312bd77abe0SGlenn Strauss int array_is_kvany(array *a) { 313bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 314bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 315bd77abe0SGlenn Strauss if (du->is_index_key) return 0; 316bd77abe0SGlenn Strauss } 317bd77abe0SGlenn Strauss return 1; 318bd77abe0SGlenn Strauss } 319bd77abe0SGlenn Strauss 320bd77abe0SGlenn Strauss int array_is_kvarray(array *a) { 321bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 322bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 323bd77abe0SGlenn Strauss if (du->is_index_key || du->type != TYPE_ARRAY) return 0; 324bd77abe0SGlenn Strauss } 325bd77abe0SGlenn Strauss return 1; 326bd77abe0SGlenn Strauss } 327bd77abe0SGlenn Strauss 328bd77abe0SGlenn Strauss int array_is_kvstring(array *a) { 329bd77abe0SGlenn Strauss for (size_t i = 0; i < a->used; ++i) { 330bd77abe0SGlenn Strauss data_unset *du = a->data[i]; 331bd77abe0SGlenn Strauss if (du->is_index_key || du->type != TYPE_STRING) return 0; 332bd77abe0SGlenn Strauss } 333bd77abe0SGlenn Strauss return 1; 334bd77abe0SGlenn Strauss } 335bd77abe0SGlenn Strauss 336a46bc4f5SGlenn Strauss 337a46bc4f5SGlenn Strauss 338a46bc4f5SGlenn Strauss #include <stdio.h> 339a46bc4f5SGlenn Strauss 3409e75ba00SJan Kneschke void array_print_indent(int depth) { 3419e75ba00SJan Kneschke int i; 3429e75ba00SJan Kneschke for (i = 0; i < depth; i ++) { 343dd0abe5aSJan Kneschke fprintf(stdout, " "); 3449e75ba00SJan Kneschke } 3459e75ba00SJan Kneschke } 3469e75ba00SJan Kneschke 3476044dbc5SmOo size_t array_get_max_key_length(array *a) { 3486044dbc5SmOo size_t maxlen, i; 3496044dbc5SmOo 3506044dbc5SmOo maxlen = 0; 3516044dbc5SmOo for (i = 0; i < a->used; i ++) { 3526044dbc5SmOo data_unset *du = a->data[i]; 35386bb8be2SGlenn Strauss size_t len = buffer_string_length(du->key); 3546044dbc5SmOo 3556044dbc5SmOo if (len > maxlen) { 3566044dbc5SmOo maxlen = len; 3576044dbc5SmOo } 3586044dbc5SmOo } 3596044dbc5SmOo return maxlen; 3606044dbc5SmOo } 3616044dbc5SmOo 3629e75ba00SJan Kneschke int array_print(array *a, int depth) { 363bcdc6a3bSJan Kneschke size_t i; 3646044dbc5SmOo size_t maxlen; 3656044dbc5SmOo int oneline = 1; 366bcdc6a3bSJan Kneschke 3676044dbc5SmOo if (a->used > 5) { 3686044dbc5SmOo oneline = 0; 3696044dbc5SmOo } 3706044dbc5SmOo for (i = 0; i < a->used && oneline; i++) { 3716044dbc5SmOo data_unset *du = a->data[i]; 372f387d898SmOo if (!du->is_index_key) { 3736044dbc5SmOo oneline = 0; 3746044dbc5SmOo break; 3756044dbc5SmOo } 3766044dbc5SmOo switch (du->type) { 3776044dbc5SmOo case TYPE_INTEGER: 3786044dbc5SmOo case TYPE_STRING: 3796044dbc5SmOo break; 3806044dbc5SmOo default: 3816044dbc5SmOo oneline = 0; 3826044dbc5SmOo break; 3836044dbc5SmOo } 3846044dbc5SmOo } 3856044dbc5SmOo if (oneline) { 386dd0abe5aSJan Kneschke fprintf(stdout, "("); 387bcdc6a3bSJan Kneschke for (i = 0; i < a->used; i++) { 3886044dbc5SmOo data_unset *du = a->data[i]; 3896044dbc5SmOo if (i != 0) { 390dd0abe5aSJan Kneschke fprintf(stdout, ", "); 3916044dbc5SmOo } 3926044dbc5SmOo du->print(du, depth + 1); 3936044dbc5SmOo } 394dd0abe5aSJan Kneschke fprintf(stdout, ")"); 3956044dbc5SmOo return 0; 3966044dbc5SmOo } 3976044dbc5SmOo 3986044dbc5SmOo maxlen = array_get_max_key_length(a); 399dd0abe5aSJan Kneschke fprintf(stdout, "(\n"); 4006044dbc5SmOo for (i = 0; i < a->used; i++) { 4016044dbc5SmOo data_unset *du = a->data[i]; 4028b07d57dSJan Kneschke array_print_indent(depth + 1); 403f387d898SmOo if (!du->is_index_key) { 4046044dbc5SmOo int j; 4056044dbc5SmOo 4066044dbc5SmOo if (i && (i % 5) == 0) { 407acad2c90SGlenn Strauss fprintf(stdout, "# %zu\n", i); 4086044dbc5SmOo array_print_indent(depth + 1); 4096044dbc5SmOo } 410dd0abe5aSJan Kneschke fprintf(stdout, "\"%s\"", du->key->ptr); 41186bb8be2SGlenn Strauss for (j = maxlen - buffer_string_length(du->key); j > 0; j--) { 412dd0abe5aSJan Kneschke fprintf(stdout, " "); 4136044dbc5SmOo } 414dd0abe5aSJan Kneschke fprintf(stdout, " => "); 4156044dbc5SmOo } 4166044dbc5SmOo du->print(du, depth + 1); 417dd0abe5aSJan Kneschke fprintf(stdout, ",\n"); 4186044dbc5SmOo } 4196044dbc5SmOo if (!(i && (i - 1 % 5) == 0)) { 4206044dbc5SmOo array_print_indent(depth + 1); 421acad2c90SGlenn Strauss fprintf(stdout, "# %zu\n", i); 422bcdc6a3bSJan Kneschke } 4238b07d57dSJan Kneschke array_print_indent(depth); 424dd0abe5aSJan Kneschke fprintf(stdout, ")"); 425bcdc6a3bSJan Kneschke 426bcdc6a3bSJan Kneschke return 0; 427bcdc6a3bSJan Kneschke } 428bcdc6a3bSJan Kneschke 429bcdc6a3bSJan Kneschke #ifdef DEBUG_ARRAY 430bcdc6a3bSJan Kneschke int main (int argc, char **argv) { 431bcdc6a3bSJan Kneschke array *a; 432bcdc6a3bSJan Kneschke data_string *ds; 433bcdc6a3bSJan Kneschke 434bcdc6a3bSJan Kneschke UNUSED(argc); 435bcdc6a3bSJan Kneschke UNUSED(argv); 436bcdc6a3bSJan Kneschke 437bcdc6a3bSJan Kneschke a = array_init(); 438bcdc6a3bSJan Kneschke 439bcdc6a3bSJan Kneschke ds = data_string_init(); 44052861d77SStefan Bühler buffer_copy_string_len(ds->key, CONST_STR_LEN("abc")); 44152861d77SStefan Bühler buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag")); 442bcdc6a3bSJan Kneschke 443bcdc6a3bSJan Kneschke array_insert_unique(a, (data_unset *)ds); 444bcdc6a3bSJan Kneschke 445bcdc6a3bSJan Kneschke ds = data_string_init(); 44652861d77SStefan Bühler buffer_copy_string_len(ds->key, CONST_STR_LEN("abc")); 44752861d77SStefan Bühler buffer_copy_string_len(ds->value, CONST_STR_LEN("hameplman")); 448bcdc6a3bSJan Kneschke 449bcdc6a3bSJan Kneschke array_insert_unique(a, (data_unset *)ds); 450bcdc6a3bSJan Kneschke 451bcdc6a3bSJan Kneschke ds = data_string_init(); 45252861d77SStefan Bühler buffer_copy_string_len(ds->key, CONST_STR_LEN("123")); 45352861d77SStefan Bühler buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag")); 454bcdc6a3bSJan Kneschke 455bcdc6a3bSJan Kneschke array_insert_unique(a, (data_unset *)ds); 456bcdc6a3bSJan Kneschke 4579e75ba00SJan Kneschke array_print(a, 0); 458bcdc6a3bSJan Kneschke 459bcdc6a3bSJan Kneschke array_free(a); 460bcdc6a3bSJan Kneschke 461bcdc6a3bSJan Kneschke fprintf(stderr, "%d\n", 462bcdc6a3bSJan Kneschke buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type"))); 463bcdc6a3bSJan Kneschke 464bcdc6a3bSJan Kneschke return 0; 465bcdc6a3bSJan Kneschke } 466bcdc6a3bSJan Kneschke #endif 467