mirror of https://github.com/getdnsapi/getdns.git
the guts of the dict datatype are working, still need to complete the helper funcs
This commit is contained in:
parent
1ec3886604
commit
91990993ce
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Makefile. Generated from Makefile.in by configure.
|
||||
# common/Makefile. Generated from Makefile.in by configure.
|
||||
#
|
||||
|
||||
package = getdns
|
||||
|
|
|
@ -327,7 +327,31 @@ typedef struct getdns_bindata {
|
|||
size_t size;
|
||||
uint8_t *data;
|
||||
} getdns_bindata;
|
||||
typedef struct getdns_dict getdns_dict;
|
||||
|
||||
/**
|
||||
* this structure represents a single item in a dictionary type
|
||||
*/
|
||||
struct getdns_dict_item {
|
||||
char *key;
|
||||
getdns_data_type dtype;
|
||||
union {
|
||||
struct getdns_list *list;
|
||||
struct getdns_dict *dict;
|
||||
int n;
|
||||
struct getdns_bindata *bindata;
|
||||
} data;
|
||||
};
|
||||
|
||||
/**
|
||||
* getdns dictionary data type
|
||||
* Use helper functions getdns_dict_* to manipulate and iterate dictionaries
|
||||
* dict is implemented using the t*() functions for manipulating binary search
|
||||
* trees in the std library. The internal implementation may change so the
|
||||
* application should stick to the helper functions.
|
||||
*/
|
||||
typedef struct getdns_dict {
|
||||
void *rootp;
|
||||
} getdns_dict;
|
||||
|
||||
/**
|
||||
* translate an error code to a string value, not in the original api description
|
||||
|
@ -355,6 +379,10 @@ typedef struct getdns_list {
|
|||
int numinuse;
|
||||
struct getdns_list_item *items;
|
||||
} getdns_list;
|
||||
|
||||
/**
|
||||
* this structure represents a single item in a list
|
||||
*/
|
||||
struct getdns_list_item {
|
||||
int inuse;
|
||||
getdns_data_type dtype;
|
||||
|
@ -419,16 +447,64 @@ getdns_return_t getdns_list_get_bindata(struct getdns_list *this_list, size_t in
|
|||
*/
|
||||
getdns_return_t getdns_list_get_int(struct getdns_list *list, size_t index, uint32_t *answer);
|
||||
|
||||
/* Dicts: get the list of names, get the data_type of the
|
||||
value at a given name, and get the data at a given name */
|
||||
getdns_return_t getdns_dict_get_names(struct getdns_dict *this_dict, struct getdns_list **answer);
|
||||
/**
|
||||
* fetch a list of names from the dictionary, this list must be freed by the caller
|
||||
* via a call to getdns_list_destroy
|
||||
* @param dict dictionary from which to produce the list of names
|
||||
* @param **answer a pointer to the new list will be assigned to *answer
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid
|
||||
*/
|
||||
getdns_return_t getdns_dict_get_names(struct getdns_dict *dict, struct getdns_list **answer);
|
||||
/**
|
||||
* fetch the data type for the data associated with the specified name
|
||||
* @param dict dictionary from which to fetch the data type
|
||||
* @param name a name/key value to look up in the dictionary
|
||||
* @param *answer data type will be stored at this address
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist
|
||||
*/
|
||||
getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *name, getdns_data_type *answer);
|
||||
/**
|
||||
* fetch the dictionary associated with the specified name, the dictionary should
|
||||
* be free()'d by the caller via getdns_dict_destroy()
|
||||
* @param dict dictionary from which to fetch the dictionary
|
||||
* @param name a name/key value to look up in the dictionary
|
||||
* @param **answer a copy of the dictionary will be stored at this address
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist
|
||||
*/
|
||||
getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict **answer);
|
||||
/**
|
||||
* fetch the list associated with the specified name, the list should be free()'d
|
||||
* by the caller via getdns_list_destroy()
|
||||
* @param dict dictionary from which to fetch the list
|
||||
* @param name a name/key value to look up in the dictionary
|
||||
* @param **answer a copy of the list will be stored at this address
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist
|
||||
*/
|
||||
getdns_return_t getdns_dict_get_list(struct getdns_dict *this_dict, char *name, struct getdns_list **answer);
|
||||
/**
|
||||
* fetch the bindata associated with the specified name, the bindata should be
|
||||
* free()'d by the caller
|
||||
* @param dict dictionary from which to fetch the bindata
|
||||
* @param name a name/key value to look up in the dictionary
|
||||
* @param **answer a copy of the bindata will be stored at this address
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist
|
||||
*/
|
||||
getdns_return_t getdns_dict_get_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata **answer);
|
||||
/**
|
||||
* fetch the integer value associated with the specified name
|
||||
* @param dict dictionary from which to fetch the integer
|
||||
* @param name a name/key value to look up in the dictionary
|
||||
* @param *answer the integer will be stored at this address
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist
|
||||
*/
|
||||
getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name, uint32_t *answer);
|
||||
|
||||
|
||||
/**
|
||||
* create a new list with no items
|
||||
* @return pointer to an allocated list, NULL if insufficient memory
|
||||
|
@ -462,6 +538,15 @@ getdns_return_t getdns_list_set_dict(struct getdns_list *list, size_t index, str
|
|||
* @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if index is out of range, or list is NULL
|
||||
*/
|
||||
getdns_return_t getdns_list_set_list(struct getdns_list *list, size_t index, struct getdns_list *child_list);
|
||||
/**
|
||||
* assign the child_bindata to an item in a parent list, the parent list copies
|
||||
* the child data and will free the copy when the list is destroyed
|
||||
* @param list list contiaining the item to which child_list is to be assigned
|
||||
* @param index index of the item within list to which child_list is to be assigned
|
||||
* @param *child_bindata data to assign to the item
|
||||
* @return GETDNS_RETURN_GOOD on success
|
||||
* @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if index is out of range, or list is NULL
|
||||
*/
|
||||
getdns_return_t getdns_list_set_bindata(struct getdns_list *list, size_t index, struct getdns_bindata *child_bindata);
|
||||
/**
|
||||
* set the integrer value of the indexed item (zero based index)
|
||||
|
@ -470,9 +555,20 @@ getdns_return_t getdns_list_set_bindata(struct getdns_list *list, size_t index,
|
|||
*/
|
||||
getdns_return_t getdns_list_set_int(struct getdns_list *list, size_t index, uint32_t child_uint32);
|
||||
|
||||
/* Dicts: create, destroy, and set the data at a given name */
|
||||
struct getdns_dict * getdns_dict_create();
|
||||
/**
|
||||
* create a new dictionary with no items
|
||||
* @return pointer to an allocated dictionary, NULL if insufficient memory
|
||||
*/
|
||||
struct getdns_dict *getdns_dict_create();
|
||||
|
||||
/**
|
||||
* destroy a dictionary and all items within that dictionary
|
||||
* be aware that if you have fetched any data from the dictionary it will
|
||||
* no longer be available (you are likely to experience bad things if you try)
|
||||
* @return pointer to an allocated dictionary, NULL if insufficient memory
|
||||
*/
|
||||
void getdns_dict_destroy(struct getdns_dict *this_dict);
|
||||
|
||||
getdns_return_t getdns_dict_set_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict *child_dict);
|
||||
getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list);
|
||||
getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/**
|
||||
*
|
||||
* /brief getdns list management functions
|
||||
* getdns list management functions, note that the internal storage is
|
||||
* accomplished via the libc binary search tree implementation so your
|
||||
* pointer foo needs to be keen to digest some of the internal semantics
|
||||
*
|
||||
* This is the meat of the API
|
||||
* Originally taken from the getdns API description pseudo implementation.
|
||||
* Interfaces originally taken from the getdns API description pseudo implementation.
|
||||
*
|
||||
*/
|
||||
/* The MIT License (MIT)
|
||||
|
@ -28,37 +29,333 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <search.h>
|
||||
#include <string.h>
|
||||
#include <getdns_libevent.h>
|
||||
|
||||
/* stuff to make it compile pedantically */
|
||||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
|
||||
/*---------------------------------------- getdns_dict_cmp */
|
||||
/**
|
||||
* private function used by the t*() functions for managing binary trees
|
||||
* behaves similar to strcmp()
|
||||
* @param itemp1 pointer to pointer to getdns_dict_item to compare
|
||||
* @param itemp2 pointer to pointer to getdns_dict_item to compare
|
||||
* @return results of lexicographic comparison between item1->key and item2->key
|
||||
*/
|
||||
int
|
||||
getdns_dict_cmp(const void *item1, const void *item2)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if(item1 == NULL)
|
||||
{
|
||||
if(item2 == NULL)
|
||||
retval = 0;
|
||||
else
|
||||
retval = -1;
|
||||
}
|
||||
else if(item2 == NULL)
|
||||
retval = 1;
|
||||
else
|
||||
{
|
||||
retval = strcmp(((struct getdns_dict_item *) item1)->key
|
||||
, ((struct getdns_dict_item *) item2)->key);
|
||||
}
|
||||
|
||||
return retval;
|
||||
} /* getdns_dict_comp */
|
||||
|
||||
/*---------------------------------------- getdns_dict_find */
|
||||
/**
|
||||
* private function used to locate a key in a dictionary
|
||||
* @param dict dicitonary to search
|
||||
* @param key key to search for
|
||||
* @param addifnotfnd if TRUE then an item will be added if the key is not found
|
||||
* @return pointer to dictionary item, caller must not free storage associated with item
|
||||
* @return NULL if additnotfnd == FALSE and key is not in dictionary
|
||||
*/
|
||||
struct getdns_dict_item *
|
||||
getdns_dict_find(struct getdns_dict *dict, char *key, bool addifnotfnd)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
struct getdns_dict_item *newitem;
|
||||
struct getdns_dict_item *ret = NULL;
|
||||
|
||||
if(dict != NULL && key != NULL)
|
||||
{
|
||||
/* we try to find it first, if we do then clear the existing data */
|
||||
keyitem.key = key;
|
||||
keyitem.dtype = t_invalid;
|
||||
keyitem.data.n = 0;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(addifnotfnd == true && (item == NULL || *item == NULL))
|
||||
{
|
||||
/* tsearch will add a node automatically for us */
|
||||
newitem = (struct getdns_dict_item *) malloc(sizeof(struct getdns_dict_item));
|
||||
newitem->key = strdup(key);
|
||||
newitem->dtype = t_invalid;
|
||||
newitem->data.n = 0;
|
||||
item = tsearch(newitem, &(dict->rootp), getdns_dict_cmp);
|
||||
}
|
||||
if(item != NULL)
|
||||
ret = *item;
|
||||
}
|
||||
|
||||
return *item;
|
||||
} /* getdns_dict_set_int */
|
||||
|
||||
getdns_return_t getdns_dict_get_names(struct getdns_dict *this_dict, struct getdns_list **answer)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; }
|
||||
|
||||
getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *name, getdns_data_type *answer)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; }
|
||||
/*---------------------------------------- getdns_dict_get_data_type */
|
||||
getdns_return_t
|
||||
getdns_dict_get_data_type(struct getdns_dict *dict, char *name, getdns_data_type *answer)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict **answer)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; }
|
||||
if(dict != NULL && name != NULL && answer != NULL)
|
||||
{
|
||||
keyitem.key = name;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(item != NULL && *item != NULL)
|
||||
{
|
||||
*answer = (*item)->dtype;
|
||||
retval = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t getdns_dict_get_list(struct getdns_dict *this_dict, char *name, struct getdns_list **answer)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; }
|
||||
return retval;
|
||||
} /* getdns_dict_get_data_type */
|
||||
|
||||
getdns_return_t getdns_dict_get_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata **answer)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; }
|
||||
/*---------------------------------------- getdns_dict_get_dict */
|
||||
getdns_return_t
|
||||
getdns_dict_get_dict(struct getdns_dict *dict, char *name, struct getdns_dict **answer)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name, uint32_t *answer)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; }
|
||||
if(dict != NULL && name != NULL && answer != NULL)
|
||||
{
|
||||
keyitem.key = name;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(item != NULL && *item != NULL)
|
||||
{
|
||||
if((*item)->dtype != t_dict)
|
||||
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||
else
|
||||
{
|
||||
*answer = (*item)->data.dict;
|
||||
retval = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct getdns_dict * getdns_dict_create()
|
||||
{ return NULL; }
|
||||
return retval;
|
||||
} /* getdns_dict_get_dict */
|
||||
|
||||
void getdns_dict_destroy(struct getdns_dict *this_dict)
|
||||
{ UNUSED_PARAM(this_dict); }
|
||||
/*---------------------------------------- getdns_dict_get_list */
|
||||
getdns_return_t
|
||||
getdns_dict_get_list(struct getdns_dict *dict, char *name, struct getdns_list **answer)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
getdns_return_t getdns_dict_set_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict *child_dict)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_dict); return GETDNS_RETURN_GOOD; }
|
||||
if(dict != NULL && name != NULL && answer != NULL)
|
||||
{
|
||||
keyitem.key = name;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(item != NULL && *item != NULL)
|
||||
{
|
||||
if((*item)->dtype != t_list)
|
||||
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||
else
|
||||
{
|
||||
*answer = (*item)->data.list;
|
||||
retval = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
} /* getdns_dict_get_list */
|
||||
|
||||
/*---------------------------------------- getdns_dict_get_bindata */
|
||||
getdns_return_t
|
||||
getdns_dict_get_bindata(struct getdns_dict *dict, char *name, struct getdns_bindata **answer)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
if(dict != NULL && name != NULL && answer != NULL)
|
||||
{
|
||||
keyitem.key = name;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(item != NULL && *item != NULL)
|
||||
{
|
||||
if((*item)->dtype != t_bindata)
|
||||
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||
else
|
||||
{
|
||||
*answer = (*item)->data.bindata;
|
||||
retval = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
} /* getdns_dict_get_bindata */
|
||||
|
||||
/*---------------------------------------- getdns_dict_get_int */
|
||||
getdns_return_t
|
||||
getdns_dict_get_int(struct getdns_dict *dict, char *name, uint32_t *answer)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
if(dict != NULL && name != NULL && answer != NULL)
|
||||
{
|
||||
keyitem.key = name;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(item != NULL && *item != NULL)
|
||||
{
|
||||
if((*item)->dtype != t_int)
|
||||
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||
else
|
||||
{
|
||||
*answer = (*item)->data.n;
|
||||
retval = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
} /* getdns_dict_get_int */
|
||||
|
||||
/*---------------------------------------- getdns_dict_create */
|
||||
struct getdns_dict *
|
||||
getdns_dict_create()
|
||||
{
|
||||
struct getdns_dict *dict;
|
||||
|
||||
dict = (struct getdns_dict *) malloc(sizeof(struct getdns_dict));
|
||||
dict->rootp = NULL;
|
||||
|
||||
return dict;
|
||||
} /* getdns_dict_create */
|
||||
|
||||
/*---------------------------------------- getdns_dict_copy */
|
||||
/**
|
||||
* private function used to make a copy of a dict structure
|
||||
* @param srcdict the dictionary structure to copy
|
||||
* @return the address of the copy of the dictionary structure on success
|
||||
* @return NULL on error (out of memory, invalid srcdict)
|
||||
*/
|
||||
struct getdns_dict *
|
||||
getdns_dict_copy(struct getdns_dict *srcdict)
|
||||
{
|
||||
struct getdns_dict *newdict = NULL;
|
||||
|
||||
if(srcdict != NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return newdict;
|
||||
} /* getdns_dict_copy */
|
||||
|
||||
/*---------------------------------------- getdns_dict_item_free */
|
||||
/**
|
||||
* private function used to release storage associated with a dictionary item
|
||||
* @param all memory in this structure and its children will be freed
|
||||
* @return void
|
||||
*/
|
||||
void
|
||||
getdns_dict_item_free(struct getdns_dict_item *item)
|
||||
{
|
||||
if(item != NULL)
|
||||
{
|
||||
if(item->dtype == t_bindata)
|
||||
{
|
||||
if(item->data.bindata->size > 0)
|
||||
free(item->data.bindata->data);
|
||||
free(item->data.bindata);
|
||||
}
|
||||
else if(item->dtype == t_dict)
|
||||
{
|
||||
getdns_dict_destroy(item->data.dict);
|
||||
}
|
||||
else if(item->dtype == t_list)
|
||||
{
|
||||
getdns_list_destroy(item->data.list);
|
||||
}
|
||||
|
||||
if(item->key != NULL)
|
||||
free(item->key);
|
||||
free(item);
|
||||
}
|
||||
} /* getdns_dict_item_free */
|
||||
|
||||
/*---------------------------------------- getdns_dict_destroy */
|
||||
void
|
||||
getdns_dict_destroy(struct getdns_dict *dict)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item *item;
|
||||
|
||||
if(dict != NULL && dict->rootp != NULL)
|
||||
{
|
||||
while(dict->rootp != NULL)
|
||||
{
|
||||
item = *((struct getdns_dict_item **) dict->rootp);
|
||||
keyitem.key = item->key;
|
||||
tdelete(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
getdns_dict_item_free(item);
|
||||
}
|
||||
|
||||
free(dict);
|
||||
}
|
||||
|
||||
return;
|
||||
} /* getdns_dict_destroy */
|
||||
|
||||
/*---------------------------------------- getdns_dict_set_dict */
|
||||
getdns_return_t
|
||||
getdns_dict_set_dict(struct getdns_dict *dict, char *name, struct getdns_dict *child_dict)
|
||||
{
|
||||
struct getdns_dict_item keyitem;
|
||||
struct getdns_dict_item **item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
if(dict != NULL && name != NULL && child_dict != NULL)
|
||||
{
|
||||
/* we try to find it first, if we do then clear the existing data */
|
||||
keyitem.key = name;
|
||||
item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
if(item != NULL && *item != NULL)
|
||||
{
|
||||
getdns_dict_item_free(*item);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* tsearch will add a node automatically for us */
|
||||
item = tsearch(&keyitem, &(dict->rootp), getdns_dict_cmp);
|
||||
(*item)->key = strdup(keyitem.key);
|
||||
(*item)->dtype = t_dict;
|
||||
(*item)->data.dict = getdns_dict_copy(child_dict);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
} /* getdns_dict_set_dict */
|
||||
|
||||
getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_list); return GETDNS_RETURN_GOOD; }
|
||||
|
@ -66,8 +363,23 @@ getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name,
|
|||
getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_bindata); return GETDNS_RETURN_GOOD; }
|
||||
|
||||
getdns_return_t getdns_dict_set_int(struct getdns_dict *this_dict, char *name, uint32_t child_uint32)
|
||||
{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_uint32); return GETDNS_RETURN_GOOD; }
|
||||
/*---------------------------------------- getdns_dict_set_int */
|
||||
getdns_return_t
|
||||
getdns_dict_set_int(struct getdns_dict *dict, char *name, uint32_t child_uint32)
|
||||
{
|
||||
struct getdns_dict_item *item;
|
||||
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
|
||||
|
||||
item = getdns_dict_find(dict, name, true);
|
||||
if(dict != NULL && name != NULL)
|
||||
{
|
||||
item->dtype = t_int;
|
||||
item->data.n = child_uint32;
|
||||
retval = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
return retval;
|
||||
} /* getdns_dict_set_int */
|
||||
|
||||
char *
|
||||
getdns_pretty_print_dict(
|
||||
|
|
|
@ -19,7 +19,7 @@ CC=gcc
|
|||
CFLAGS=-Wall -g -I./ -I../common -I$(srcdir)/ -std=c99
|
||||
LDFLAGS=-L../common
|
||||
LDLIBS=-lgetdns
|
||||
PROGRAMS=tests_list
|
||||
PROGRAMS=tests_list tests_dict
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h .can .out .res
|
||||
|
||||
|
@ -29,16 +29,22 @@ PROGRAMS=tests_list
|
|||
.out.res:
|
||||
diff $< $(basename $<).can > $@
|
||||
|
||||
all: tests_list tests_list.res
|
||||
all: tests_list tests_list.res tests_dict tests_dict.res
|
||||
|
||||
tests_list: tests_list.o ../common/libgetdns.so testmessages.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $^
|
||||
|
||||
tests_dict: tests_dict.o ../common/libgetdns.so testmessages.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $^
|
||||
|
||||
# we want the library that was just built to be used in the tests
|
||||
# NOT one that is installed on the system
|
||||
tests_list.out : tests_list
|
||||
export DYLD_LIBRARY_PATH=../common; ./tests_list > tests_list.out
|
||||
|
||||
tests_dict.out : tests_dict
|
||||
export DYLD_LIBRARY_PATH=../common; ./tests_dict > tests_dict.out
|
||||
|
||||
clean:
|
||||
rm -f *.o *.out *.res $(PROGRAMS)
|
||||
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* \file
|
||||
* unit tests for getdns_dict helper routines, these should be used to
|
||||
* perform regression tests, output must be unchanged from canonical output
|
||||
* stored with the sources
|
||||
*/
|
||||
/* The MIT License (MIT)
|
||||
* Copyright (c) 2013 Verisign, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "testmessages.h"
|
||||
#include "getdns_core_only.h"
|
||||
|
||||
#define TSTMSGBUF 80
|
||||
|
||||
/*---------------------------------------- tst_intsetget */
|
||||
/**
|
||||
* test the int get and set routines
|
||||
*/
|
||||
void
|
||||
tst_intsetget(void)
|
||||
{
|
||||
char msg[TSTMSGBUF];
|
||||
char key[20];
|
||||
uint32_t ans_int;
|
||||
uint32_t newint;
|
||||
getdns_return_t retval;
|
||||
struct getdns_dict *dict = NULL;
|
||||
|
||||
tstmsg_case_begin("tst_intsetget");
|
||||
|
||||
dict = getdns_dict_create();
|
||||
|
||||
/* test int get function against empty list and with bogus params */
|
||||
|
||||
strcpy(key, "foo");
|
||||
|
||||
tstmsg_case_msg("getdns_dict_get_int() empty dict");
|
||||
retval = getdns_dict_get_int(NULL, key, &ans_int);
|
||||
sprintf(msg, "line %d: getdns_dict_get_int(NULL, key, &ans_int),retval = %d", __LINE__, retval);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
retval = getdns_dict_get_int(dict, key, NULL);
|
||||
sprintf(msg, "line %d: getdns_dict_get_int(dict, key, NULL),retval = %d", __LINE__, retval);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
tstmsg_case_msg("getdns_dict_get_int(dict, NULL, &ans_int)");
|
||||
retval = getdns_dict_get_int(dict, NULL, &ans_int);
|
||||
sprintf(msg, "line %d: getdns_dict_get_int,retval = %d", __LINE__, retval);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
tstmsg_case_msg("getdns_dict_get_int(dict, key, &ans_int)");
|
||||
retval = getdns_dict_get_int(dict, key, &ans_int);
|
||||
sprintf(msg, "line %d: getdns_list_get_int,retval = %d", __LINE__, retval);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
getdns_dict_destroy(dict);
|
||||
|
||||
/* TODO: test getdns_dict_set functions with bogus params */
|
||||
|
||||
/* test set and get legitimate use case */
|
||||
|
||||
dict = getdns_dict_create();
|
||||
|
||||
strcpy(key, "foo");
|
||||
newint = 42;
|
||||
|
||||
tstmsg_case_msg("getdns_dict_set_int(dict, key, newint)");
|
||||
retval = getdns_dict_set_int(dict, key, newint);
|
||||
sprintf(msg, "line %d: getdns_dict_set_int,retval=%d,key=%s,int=%d", __LINE__, retval, key, newint);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
tstmsg_case_msg("getdns_dict_get_int(dict, key, &ans_int)");
|
||||
retval = getdns_dict_get_int(dict, key, &ans_int);
|
||||
sprintf(msg, "line %d: getdns_dict_get_int,retval=%d,key=%s,int=%d", __LINE__, retval, key, ans_int);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
strcpy(key, "bar");
|
||||
newint = 52;
|
||||
tstmsg_case_msg("getdns_dict_set_int(dict, key, newint)");
|
||||
retval = getdns_dict_set_int(dict, key, newint);
|
||||
sprintf(msg, "line %d: getdns_dict_set_int,retval=%d,key=%s,int=%d", __LINE__, retval, key, newint);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
tstmsg_case_msg("getdns_dict_get_int(dict, key, &ans_int)");
|
||||
retval = getdns_dict_get_int(dict, key, &ans_int);
|
||||
sprintf(msg, "line %d: getdns_dict_get_int,retval=%d,key=%s,int=%d", __LINE__, retval, key, ans_int);
|
||||
tstmsg_case_msg(msg);
|
||||
|
||||
getdns_dict_destroy(dict);
|
||||
|
||||
tstmsg_case_end();
|
||||
|
||||
return;
|
||||
} /* tst_intsetget */
|
||||
|
||||
/*---------------------------------------- tst_create */
|
||||
/**
|
||||
* test the create, destroy and allocation functions
|
||||
*/
|
||||
void
|
||||
tst_create(void)
|
||||
{
|
||||
struct getdns_dict *dict = NULL;
|
||||
|
||||
/* make sure we can do a simple create/destroy first */
|
||||
|
||||
tstmsg_case_begin("tst_create");
|
||||
|
||||
tstmsg_case_msg("getdns_dict_create");
|
||||
dict = getdns_dict_create();
|
||||
|
||||
if(dict != NULL)
|
||||
{
|
||||
tstmsg_case_msg("getdns_dict_destroy(dict)");
|
||||
getdns_dict_destroy(dict);
|
||||
}
|
||||
|
||||
tstmsg_case_msg("getdns_dict_destroy(NULL)");
|
||||
getdns_dict_destroy(NULL);
|
||||
|
||||
tstmsg_case_end();
|
||||
|
||||
return;
|
||||
} /* tst_create */
|
||||
|
||||
/*---------------------------------------- main */
|
||||
/**
|
||||
* runs unit tests against list management routines
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
tstmsg_prog_begin("tests_dict");
|
||||
|
||||
tst_create();
|
||||
|
||||
tst_intsetget();
|
||||
|
||||
/*
|
||||
tst_listsetget();
|
||||
|
||||
tst_bindatasetget();
|
||||
|
||||
tstmsg_prog_end();
|
||||
*/
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
/* end tests_dict.c */
|
Loading…
Reference in New Issue