0
0
mirror of https://github.com/cjdelisle/cjdns synced 2025-10-06 00:32:50 +02:00
Files
cjdns/benc/Dict.h

214 lines
7.8 KiB
C

/* vim: set expandtab ts=4 sw=4: */
/*
* You may redistribute this program and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef Dict_H
#define Dict_H
#include "memory/Allocator.h"
#include "benc/Object.h"
#include "util/Linker.h"
Linker_require("benc/Dict.c")
typedef struct Dict_Entry Dict_Entry_t;
struct Dict_Entry {
Dict_Entry_t* next;
String* key;
Object* val;
};
/**
* Remove an entry from the dictionary.
*
* @param dictionary the dictionary to remove the entry from.
* @param key the key which the entry is entered under.
* @return 1 if there was an entry removed, 0 if there was not.
*/
int32_t Dict_remove(Dict* dictionary, const String* key);
/*----------------------- Size Functions -----------------------*/
/**
* Get the number of entries in a dictionary.
*
* @param a dictionary
* @return the number of entries in the dictionary or -1 if the dictionary argument is NULL.
*/
int32_t Dict_size(const Dict* dictionary);
/*----------------------- Walk the Dictionary -----------------------*/
#define Dict_forEach(_dict, _key) \
for (struct Dict_Entry* e = *_dict; e && (_key = e->key); e = e->next)
// CHECKFILES_IGNORE
/*----------------------- Dictionary Lookup Functions -----------------------*/
/**
* Lookup an integer value from a dictionary, if the value is not present
* or is not an integer type then NULL is returned.
*
* @param dictionary the dictionary to look the entry up in.
* @param key the key to look the entry up with.
* @return an integer which is in the dictionary under the given key or else NULL.
*/
int64_t* Dict_getInt(const Dict* dictionary, const String* key);
#define Dict_getIntC(getFromHere, key) Dict_getInt(getFromHere, String_CONST(key))
/**
* Lookup a string value from a dictionary, if the value is not present
* or is not a string type then NULL is returned.
*
* @param dictionary the dictionary to look the entry up in.
* @param key the key to look the entry up with.
* @return a string which is in the dictionary under the given key or else NULL.
*/
String* Dict_getString(const Dict* dictionary, const String* key);
#define Dict_getStringC(getFromHere, key) Dict_getString(getFromHere, String_CONST(key))
/**
* Lookup a dictionary value from another dictionary, if the value is not present
* or is not a dictionary type then NULL is returned.
*
* @param dictionary the dictionary to look the entry up in.
* @param key the key to look the entry up with.
* @return a dictionary which is in the dictionary under the given key or else NULL.
*/
Dict* Dict_getDict(const Dict* dictionary, const String* key);
#define Dict_getDictC(getFromHere, key) Dict_getDict(getFromHere, String_CONST(key))
/**
* Lookup a list value from a dictionary, if the value is not present
* or is not a list type then NULL is returned.
*
* @param dictionary the dictionary to look the entry up in.
* @param key the key to look the entry up with.
* @return a list which is in the dictionary under the given key or else NULL.
*/
List* Dict_getList(const Dict* dictionary, const String* key);
#define Dict_getListC(getFromHere, key) Dict_getList(getFromHere, String_CONST(key))
/*----------------------- Dictionary Put Functions -----------------------*/
/**
* Insert an integer into a dictionary.
*
* @param putIntoThis the dictionary to insert an entry into.
* @param key the reference key to use for putting the entry in the dictionary.
* @param value the integer to insert. int64_t is an alias to int64_t.
* @param allocator the means to get memory for storing the dictionary entry wrapper.
* @return if the key already exists in the dictionary then the value which was
* displaced by the put, otherwise NULL.
*/
Object* Dict_putInt(Dict* putIntoThis,
const String* key,
int64_t value,
struct Allocator* allocator);
#define Dict_putIntC(putHere, key, val, alloc) \
Dict_putInt(putHere, String_new(key, alloc), val, alloc)
/**
* Insert a String object into another dictionary.
* NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
*
* @param putIntoThis the dictionary to insert an entry into.
* @param key the reference key to use for putting the entry in the dictionary.
* @param value the string to insert.
* @param allocator the means to get memory for storing the dictionary entry wrapper.
* @return if the key already exists in the dictionary then the value which was
* displaced by the put, otherwise NULL.
*/
Object* Dict_putString(Dict* putIntoThis,
const String* key,
String* value,
struct Allocator* allocator);
#define Dict_putStringC(putHere, key, val, alloc) \
Dict_putString(putHere, String_new(key, alloc), val, alloc)
#define Dict_putStringCC(putHere, key, val, alloc) \
Dict_putStringC(putHere, key, String_new(val, alloc), alloc)
/**
* Insert a Dictionary object into another dictionary.
* NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
*
* @param putIntoThis the dictionary to insert an entry into.
* @param key the reference key to use for putting the entry in the dictionary.
* @param value the value to insert.
* @param allocator the memory allocator to use for getting memory for the entry.
* @return if the key already exists in the dictionary then the value which was
* displaced by the put, otherwise NULL.
*/
Object* Dict_putDict(Dict* putIntoThis,
const String* key,
Dict* value,
struct Allocator* allocator);
#define Dict_putDictC(putHere, key, val, alloc) \
Dict_putDict(putHere, String_new(key, alloc), val, alloc)
/**
* Insert a List object into a dictionary.
* NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
*
* @param putIntoThis the dictionary to insert an entry into.
* @param key the reference key to use for putting the entry in the dictionary.
* @param value the list to insert.
* @param allocator the memory allocator to use for getting memory for the entry.
* @return if the key already exists in the dictionary then the value which was
* displaced by the put, otherwise NULL.
*/
Object* Dict_putList(Dict* putIntoThis,
const String* key,
List* value,
struct Allocator* allocator);
#define Dict_putListC(putHere, key, val, alloc) \
Dict_putList(putHere, String_new(key, alloc), val, alloc)
/*----------------------- Constructors -----------------------*/
/**
* Create a new bencoded dictionary type.
*
* @param allocator the place to allocate the memory for storing the dictionary.
*/
Dict* Dict_new(struct Allocator* allocator);
/**
* Create a dictionary on the stack.
*
* @param entryKey the key which must be a string.
* @param value the value which must be an object.
* @param next another Dict, can be used to chain Dict_CONST() calls.
* @return a Dict. NOTE: This does *NOT* return a Dict*, just a Dict.
*/
#define Dict_CONST(entryKey, value, nextDict) \
(&(struct Dict_Entry) { \
.key = entryKey, \
.val = value, \
.next = nextDict \
})
#define Dict_OBJ(x) (&(Object) { .type = Object_DICT, .as.dictionary = x })
#endif