/*
* Copyright 2009 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
* Lukas Kuklinek <lkuklinek@redhat.com>
*/
/*
* @file
* @internal
* @{
*/
#ifndef OSCAP_LIST_
#define OSCAP_LIST_
#include <stdlib.h>
#include <stdbool.h>
#include "util.h"
#include "public/oscap.h"
#include "public/oscap_text.h"
// list item dump function type
typedef void (*oscap_dump_func) ();
// generic comparison function type
typedef bool (*oscap_cmp_func) (void *, void *);
/*
* Linear linked list.
*/
struct oscap_list_item {
void *data;
struct oscap_list_item *next;
};
struct oscap_list {
struct oscap_list_item *first;
struct oscap_list_item *last;
size_t itemcount;
};
// FIXME: SCE engine uses these
struct oscap_list *oscap_list_new(void);
void oscap_create_lists(struct oscap_list **first, ...);
bool oscap_list_add(struct oscap_list *list, void *value);
bool oscap_list_push(struct oscap_list *list, void *value);
bool oscap_list_pop(struct oscap_list *list, oscap_destruct_func destructor);
bool oscap_list_remove(struct oscap_list *list, void *value, oscap_cmp_func compare, oscap_destruct_func destructor);
struct oscap_list *oscap_list_clone(const struct oscap_list * list, oscap_clone_func cloner);
void oscap_list_free(struct oscap_list *list, oscap_destruct_func destructor);
void oscap_list_free0(struct oscap_list *list);
void oscap_list_dump(struct oscap_list *list, oscap_dump_func dumper, int depth);
int oscap_list_get_itemcount(struct oscap_list *list);
bool oscap_list_contains(struct oscap_list *list, void *what, oscap_cmp_func compare);
struct oscap_list *oscap_list_destructive_join(struct oscap_list *list1, struct oscap_list *list2);
/* Linked List iterator. */
typedef bool(*oscap_filter_func) (void *, void *);
struct oscap_iterator {
struct oscap_list_item *cur;
struct oscap_list *list;
oscap_filter_func filter;
void *user_data;
};
// FIXME: SCE engine uses these
void *oscap_iterator_new(struct oscap_list *list);
void *oscap_iterator_new_filter(struct oscap_list *list, oscap_filter_func filter, void *user_data);
void *oscap_iterator_next(struct oscap_iterator *it);
size_t oscap_iterator_get_itemcount(const struct oscap_iterator *it);
bool oscap_iterator_has_more(struct oscap_iterator *it);
void oscap_iterator_reset(struct oscap_iterator *it);
void *oscap_iterator_detach(struct oscap_iterator *it);
void oscap_iterator_free(struct oscap_iterator *it);
void *oscap_list_find(struct oscap_list *list, void *what, oscap_cmp_func compare);
/**
* Iterate over an array, given an iterator.
* Execute @a code for each array member stored in @a val.
* It is NOT safe to use return or goto inside of the @a code,
* the iterator would not be freed properly.
*/
#define OSCAP_FOREACH_GENERIC(itype, vtype, val, init_val, code) \
{ \
struct itype##_iterator *val##_iter = (init_val); \
vtype val; \
while (itype##_iterator_has_more(val##_iter)) { \
val = itype##_iterator_next(val##_iter); \
code \
} \
itype##_iterator_free(val##_iter); \
}
/**
* Iterate over an array, given an iterator.
* @param type type of array elements (w/o the struct keyword)
* @param val name of an variable the member will be sequentially stored in
* @param init_val initial member value (i.e. an iterator pointing to the start element)
* @param code code to be executed for each element the iterator hits
* @see OSCAP_FOREACH_GENERIC
*/
#define OSCAP_FOREACH(type, val, init_val, code) \
OSCAP_FOREACH_GENERIC(type, struct type *, val, init_val, code)
/**
* Iterate over an array, given an iterator.
* It is generally not safe to use break, return or goto inside the loop
* (iterator wouldn't be properly freed otherwise).
* Two variables, named VAL and VAL_iter (substitute VAL for actual macro argument)
* will be added to current variable scope. You can free the iterator explicitly
* after previous unusual escape from the loop (e.g. using break).
* @param val name of an variable the string will be sequentially stored in
* @param init_val initial member value (i.e. an iterator pointing to the start element)
* @param code code to be executed for each string the iterator hits
*/
#define OSCAP_FOR_GENERIC(itype, vtype, val, init_val) \
vtype val = NULL; struct itype##_iterator *val##_iter = (init_val); \
while (itype##_iterator_has_more(val##_iter) \
? (val = itype##_iterator_next(val##_iter), true) \
: (itype##_iterator_free(val##_iter), val##_iter = NULL, false))
/**
* Iterate over an array, given an iterator.
* @param type type of array elements (w/o the struct keyword)
* @param val name of an variable the member will be sequentially stored in
* @param init_val initial member value (i.e. an iterator pointing to the start element)
* @see OSCAP_FOR_GENERIC
*/
#define OSCAP_FOR(type, val, init_val) OSCAP_FOR_GENERIC(type, struct type *, val, init_val)
/**
* Iterate over an array of strings, given an iterator.
* @param val name of an variable the member will be sequentially stored in
* @param init_val initial member value (i.e. an iterator pointing to the start element)
* @see OSCAP_FOR_GENERIC
*/
#define OSCAP_FOR_STR(val, init_val) OSCAP_FOR_GENERIC(oscap_string, const char *, val, init_val)
/*
* Hash table
*/
// Comparison function.
typedef int (*oscap_compare_func) (const char *, const char *);
// Hash table item.
struct oscap_htable_item {
struct oscap_htable_item *next; // Next item.
char *key; // Item key.
void *value; // Item value.
};
// Hash table.
struct oscap_htable {
size_t hsize; // Size of the hash table.
size_t itemcount; // Number of elements in the hash table.
struct oscap_htable_item **table; // The table itself.
oscap_compare_func cmp; // Funcion used to compare keys (e.g. strcmp).
};
/*
* Create a new hash table.
* @param cmp Pointer to a function used as the key comparator.
* @hsize Size of the hash table.
* @internal
* @return new hash table
*/
struct oscap_htable *oscap_htable_new1(oscap_compare_func cmp, size_t hsize);
/*
* Create a new hash table.
*
* The table will use strcmp() as the comparison function and will have default table size.
* @see oscap_htable_new1()
* @return new hash table
*/
struct oscap_htable *oscap_htable_new(void);
/*
* Do a Deep Copy of a hashtable and all of its items
*
* @return deep copy of hash table
*/
struct oscap_htable * oscap_htable_clone(const struct oscap_htable * table, oscap_clone_func cloner);
/*
* Add an item to the hash table.
* @return True on success, false if the key already exists.
*/
bool oscap_htable_add(struct oscap_htable *htable, const char *key, void *item);
/*
* Get a hash table item.
* @return An item, NULL if item with specified key is not present in the hash table.
*/
void *oscap_htable_get(struct oscap_htable *htable, const char *key);
void *oscap_htable_detach(struct oscap_htable *htable, const char *key);
void oscap_htable_dump(struct oscap_htable *htable, oscap_dump_func dumper, int depth);
/*
* Delete the hash table.
* @param htable Hash table to be deleted.
* @param destructor Function used to delete individual items.
*/
void oscap_htable_free(struct oscap_htable *htable, oscap_destruct_func destructor);
/*
* Dispose the hash table -- do not dispose individial items.
* @param htable Hash table to be deleted.
*/
void oscap_htable_free0(struct oscap_htable *htable);
/**
* Iterator through htable structure.
*/
struct oscap_htable_iterator;
/**
* Create new iterator through hash table. No ordering is defined for items.
* @param htable Hash table to iterate through.
* @return the iterator
*/
struct oscap_htable_iterator *oscap_htable_iterator_new(struct oscap_htable *htable);
/**
* Query if the given iterator has more hash table items.
* @param iterator iterator
* @return true is there is at least one more item.
*/
bool oscap_htable_iterator_has_more(struct oscap_htable_iterator *hit);
/**
* Get the next item from iterator. The behavior is undefined if the prior call
* of oscap_htable_iterator_has_more() returns false
* @param hit iterator
*/
const struct oscap_htable_item *oscap_htable_iterator_next(struct oscap_htable_iterator *hit);
/**
* Get the key of next item from the iterator. The behavior is undefined
* if the prior call of oscap_htable_iterator_has_more returns false.
* @param hit iterator
*/
const char *oscap_htable_iterator_next_key(struct oscap_htable_iterator *hit);
/**
* Get the value of next item from the iterator. The behavior is undefined
* if the prior call of oscap_htable_iterator_has_more returns false.
* @param hit iterator
*/
void *oscap_htable_iterator_next_value(struct oscap_htable_iterator *hit);
/**
* Get the key and value of next item from the iterator. The behavior is undefined
* if the prior call of oscap_htable_iterator_has_more returns false.
* @param hit iterator
* @param key pointer to pointer that will point towards the key pointer
* @param value pointer to pointer that will point towards the value pointer
*/
void oscap_htable_iterator_next_kv(struct oscap_htable_iterator *hit, const char **key, void **value);
/**
* Reset the hashtable iterator to the begin
* @param hit iterator
*/
void oscap_htable_iterator_reset(struct oscap_htable_iterator *hit);
/**
* Dispose the iterator
* @param hit the iterator to dispose
*/
void oscap_htable_iterator_free(struct oscap_htable_iterator *hit);
void oscap_print_depth(int depth);
#endif