3
benc_dict_entry_t * benc_dict_entry_new(benc_dict_entry_t *next, benc_bstr_t *k, bobj_t *v);
4
bobj_t * benc_dict_entry_free_return_val(benc_dict_entry_t *d);
6
void benc_dict_free(benc_dict_entry_t *head)
8
benc_dict_entry_t *curr = head;
9
benc_dict_entry_t *tmp;
13
bobj_t *val = benc_dict_entry_free_return_val(curr);
19
size_t benc_dict_repsize(benc_dict_entry_t *head)
22
benc_dict_entry_t *curr = head;
25
repsize += benc_bstr_repsize(curr->key);
26
repsize += bobj_repsize(curr->val);
32
void benc_dict_encode(bbuf_t *b, benc_dict_entry_t *head)
34
benc_dict_entry_t *curr = head;
38
benc_bstr_encode(b, curr->key);
39
bobj_encode(b, curr->val);
45
bool benc_dict_decode(bbuf_t *b, benc_dict_entry_t **head_p)
48
benc_dict_entry_t **prev_p, *curr;
50
while (*(b->ptr) != 'e')
52
benc_bstr_t *key = NULL;
53
if (!benc_bstr_decode(b, &key))
55
BENC_LOG_EXCEPTION("couldn't read dict key");
58
bobj_t *val = bdec_mem(b);
61
BENC_LOG_EXCEPTION("couldn't read dict value");
64
curr = benc_dict_entry_new(NULL, key, val);
66
prev_p = &(curr->next);
73
int benc_dict_print(struct Writer* writer,
75
benc_dict_entry_t* head)
77
char* thirtyTwoSpaces = " ";
79
#define PAD(padSpaces) \
80
while (32 < padSpaces + padCounter) { \
81
writer->write(thirtyTwoSpaces, 32, writer); \
84
writer->write(thirtyTwoSpaces, padSpaces - padCounter, writer)
86
writer->write("{\n", 2, writer);
88
benc_dict_entry_t* entry = head;
89
while (entry != NULL) {
90
PAD(padSpaceCount + 2);
91
benc_bstr_print(writer, entry->key);
92
writer->write(" : ", 3, writer);
93
benc_bobj_print(writer, padSpaceCount + 2, entry->val);
96
writer->write(",\n", 2, writer);
100
writer->write("\n", 1, writer);
102
return writer->write("}", 1, writer);
107
/** @see bencode.h */
108
int benc_dict_serialize(struct Writer* writer,
109
benc_dict_entry_t* head)
111
benc_dict_entry_t* entry = head;
112
writer->write("d", 1, writer);
113
while (entry != NULL)
115
benc_bstr_serialize(writer, entry->key);
116
bobj_serialize(writer, entry->val);
119
return writer->write("e", 1, writer);
122
/** @see bencode.h */
123
int benc_dict_parse(struct Reader* reader,
124
struct MemAllocator* allocator,
125
benc_dict_entry_t** headPointer)
127
#define OUT_OF_SPACE_TO_WRITE -1
128
#define OUT_OF_CONTENT_TO_READ -2
129
#define UNPARSABLE -3
132
if (reader->read(&nextChar, 1, reader) < 0) {
133
return OUT_OF_CONTENT_TO_READ;
135
if (nextChar != 'd') {
136
/* Not a dictionary. */
142
benc_dict_entry_t* entryPointer;
143
benc_dict_entry_t* lastEntryPointer = NULL;
147
/* Peek at the next char. */
148
if (reader->read(&nextChar, 0, reader) < 0) {
149
/* Ran over read buffer. */
150
return OUT_OF_CONTENT_TO_READ;
152
if (nextChar == 'e') {
153
/* Got to the end. */
157
/* Get key and value. */
158
ret = benc_bstr_parse(reader, allocator, &key);
162
ret = bobj_parse(reader, allocator, &value);
167
/* Allocate the entry. */
168
entryPointer = allocator->malloc(sizeof(benc_dict_entry_t), allocator);
169
if (entryPointer == NULL) {
170
return OUT_OF_SPACE_TO_WRITE;
173
entryPointer->next = lastEntryPointer;
174
entryPointer->key = key;
175
entryPointer->val = value;
176
lastEntryPointer = entryPointer;
179
/* We got an 'e', leave the pointer on the next char after it. */
180
reader->skip(1, reader);
182
*headPointer = lastEntryPointer;
186
#undef OUT_OF_SPACE_TO_WRITE
187
#undef OUT_OF_CONTENT_TO_READ
191
benc_dict_entry_t * benc_dict_entry_new(benc_dict_entry_t *next, benc_bstr_t *key, bobj_t *val)
193
benc_dict_entry_t *d = (benc_dict_entry_t *)malloc(sizeof(benc_dict_entry_t));
200
bobj_t * benc_dict_entry_free_return_val(benc_dict_entry_t *d)
202
bobj_t *val = d->val;
203
benc_bstr_free(d->key);
208
bobj_t * bobj_dict_new()
210
bobj_t *obj = bobj_new(BENC_DICT);
215
bobj_t * bobj_dict_lookup(bobj_t *obj, benc_bstr_t *key)
217
if (obj == NULL || key == NULL || obj->type != BENC_DICT) {
220
benc_dict_entry_t *curr = obj->as.dict;
223
if (0 == benc_bstr_compare(key, curr->key))
235
bool bobj_dict_insert(bobj_t *obj, benc_bstr_t *key, bobj_t *val)
237
benc_dict_entry_t **prev_p = &(obj->as.dict);
238
benc_dict_entry_t *curr = obj->as.dict;
241
int cmp = benc_bstr_compare(key, curr->key);
248
BENC_LOG_EXCEPTION("dict already contains this key");
252
prev_p = &(curr->next);
256
*prev_p = benc_dict_entry_new(curr, key, val);
260
bobj_t * bobj_dict_remove(bobj_t *obj, benc_bstr_t *key)
262
benc_dict_entry_t **prev_p = &(obj->as.dict);
263
benc_dict_entry_t *curr = obj->as.dict;
266
if (0 == benc_bstr_compare(key, curr->key))
268
*prev_p = curr->next;
269
return benc_dict_entry_free_return_val(curr);
272
prev_p = &(curr->next);
276
BENC_LOG_EXCEPTION("key not found");