| 677 | } |
| 678 | |
| 679 | bencode_item_t *bencode_dictionary_get_len(bencode_item_t *dict, const char *keystr, int keylen) { |
| 680 | bencode_item_t *key; |
| 681 | unsigned int bucket, i; |
| 682 | struct __bencode_hash *hash; |
| 683 | |
| 684 | if (!dict) |
| 685 | return NULL; |
| 686 | if (dict->type != BENCODE_DICTIONARY) |
| 687 | return NULL; |
| 688 | |
| 689 | /* try hash lookup first if possible */ |
| 690 | if (dict->value == 1) { |
| 691 | hash = (void *) dict->__buf; |
| 692 | i = bucket = __bencode_hash_str_len((const unsigned char *) keystr, keylen); |
| 693 | while (1) { |
| 694 | key = hash->buckets[i]; |
| 695 | if (!key) |
| 696 | return NULL; /* would be there, but isn't */ |
| 697 | assert(key->sibling != NULL); |
| 698 | if (__bencode_dictionary_key_match(key, keystr, keylen)) |
| 699 | return key->sibling; |
| 700 | i++; |
| 701 | if (i >= BENCODE_HASH_BUCKETS) |
| 702 | i = 0; |
| 703 | if (i == bucket) |
| 704 | break; /* fall back to regular lookup */ |
| 705 | } |
| 706 | } |
| 707 | |
| 708 | for (key = dict->child; key; key = key->sibling->sibling) { |
| 709 | assert(key->sibling != NULL); |
| 710 | if (__bencode_dictionary_key_match(key, keystr, keylen)) |
| 711 | return key->sibling; |
| 712 | } |
| 713 | |
| 714 | return NULL; |
| 715 | } |
| 716 | |
| 717 | void bencode_buffer_destroy_add(bencode_buffer_t *buf, free_func_t func, void *p) { |
| 718 | struct __bencode_free_list *li; |
no test coverage detected