/*
 * Copyright (c) 2004-2005 Endace Technology Ltd, Hamilton, New Zealand.
 * All rights reserved.
 *
 * This source code is proprietary to Endace Technology Limited and no part
 * of it may be redistributed, published or disclosed except as outlined in
 * the written contract supplied with this product.
 *
 * $Id: negation_tree.h 6096 2007-01-19 02:59:08Z lipi $
 */

#ifndef NEGATION_TREE_H
#define NEGATION_TREE_H

/* C Standard Library headers. */
#include <stdio.h>

#if defined (__linux__) || defined(__FreeBSD__) || (defined(__APPLE__) && defined(__ppc__)) || (defined(__SVR4) && defined(__sun))
#include <inttypes.h>
#elif defined (_WIN32)
#include "wintypedefs.h"
#endif


#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * \file
 * \brief Negation-tree functions [to be excluded from API]
 *
 * Special purpose data structure.  Use negation_tree_add() to add a
 * set of IP addresses (in host byte order) one at a time.  When
 * finished, call negation_tree_get_list() to retrieve a linked list
 * of ternary IP addresses that are NOT in the given set.
 */

typedef struct NegationTree_ NegationTree_;
typedef NegationTree_* NegationTreePtr; /* Type-safe opaque pointer. */

/**
 * Structure representing an element of the linked list of ternary
 * addresses
 */
typedef struct NegationTreeListNode
{
	uint32_t value; /**< address */
	uint32_t mask; /**< zeroes indicate don't-care */
	struct NegationTreeListNode* next; /**< next element in the list */

} NegationTreeListNode, *NegationTreeListNodePtr;


/**
 * Initialize negation tree
 *
 * Allocate memory for the root node and create its children (left and right).
 *
 * \return  pointer to the header of the tree
 */
NegationTreePtr negation_tree_init(void);

/**
 * Dispose entire negation tree
 *
 * \param  pointer to the tree-header
 */
void negation_tree_dispose(NegationTreePtr tree);

/**
 * Add a node to the negation tree
 *
 * Insert a new node with the given address/mask into the
 * tree. Traverse the tree to find the point of insertion, create
 * nodes and/or dispose unsued (don't-care) subtrees as necessary.
 * This will result in a tree containing the relevant NON-MATCHING
 * addresses only.
 *
 * The don't-care bits must start from the LSB and form a continuous
 * region. TODO: implement explicit check for this
 *
 * \param tree     pointer to the header of negation tree
 * \param address  IP address belongin to the node
 * \param mask     mask of don't care bits (zeroes indicate don't-care)
 */
void negation_tree_add(NegationTreePtr tree, uint32_t address, uint32_t mask);

/**
 * Display entire negation tree by printing the address belonging to
 * each node, using '-' for the don't-care bits.
 *
 * \param tree     pointer to the header of the tree
 * \param outfile  pointer to file descriptor to print to
 */void negation_tree_display_paths(NegationTreePtr tree, FILE* outfile);

/**
 * Get the list of addreses in the negation tree. The returned list
 * starts with the most specific nodes, i.e. nodes with the least
 * amount of don't-care bits.
 *
 * \param tree  pointer to the header of the tree
 * 
 * \return pointer to the list of nodes
 */
NegationTreeListNodePtr negation_tree_get_list(NegationTreePtr tree);


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* NEGATION_TREE_H */
