#ifndef PHSTBDBG__TREE_H    /** Multi-include protection.   <FILENAME>_H */
#define PHSTBDBG_TREE_H


/*****************************************************************************/
/* Copyright (c) 2009 NXP B.V.                                               */
/*                                                                           */
/* 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, using               */
/* version 2.1 of the License.                                               */
/*                                                                           */
/* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   */
/*                                                                           */
/*****************************************************************************/
/**
    @file   phStbDbg.h
    @brief  Tree datastructure

@b  Component:  phStbDbg

*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
  1 20081107    batelaan    Initial
  2 20090120    batelaan    Update file copyright/license text
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/


/*******************
* INCLUDE FILES    *
********************/

#include <tmNxTypes.h>

/**************************************************************************
* EXPORTED MACROS                          PH_STBDBG_<_WORD>+        *
***************************************************************************/

/** New node was created (not really an error). */
#define PH_STBDBG_TREE_ERR_NODE_CREATED 1

/** Allocator failed to allocate memory. */
#define PH_STBDBG_TREE_ERR_ALLOCATOR 2

/** Node not found. */
#define PH_STBDBG_TREE_ERR_NODE_NOT_FOUND 3

/** Node is a leaf. */
#define PH_STBDBG_TREE_ERR_NODE_LEAF 4

/** Node is not a leaf. */
#define PH_STBDBG_TREE_ERR_NODE_NOT_LEAF 5

/** Value is NULL. */
#define PH_STBDBG_TREE_ERR_NULL_VALUE 6

/** Payloadsize parameter is too small. */
#define PH_STBDBG_TREE_ERR_PAYLOADSIZE_TOO_SMALL 7

/** Only leaf nodes can have a value associated with them.
    Used in ::phStbDbg_TreeSetup_t.
*/
#define PH_STBDBG_TREE_VALUE_ON_LEAF_ONLY (1U<<0)

/** Tree iteration finished, no more nodes available. */
#define PH_STBDBG_TREE_ERR_FINISHED 6

/*********************************************************************
* EXPORTED TYPEDEFS                      [p]phStbDbg_<Word>+_t  *
**********************************************************************/

typedef enum phStbDbg_TreeOrder {
    phStbDbg_TreeOrder_LeafOnly
} phStbDbg_TreeOrder_t;

/** Type of function to construct (allocate) a node.
    The node will be deallocated using
    ::phStbDbg_TreeNodeDestuctor_t
    @param size @b IN The size of total node. Must be able to fit a ::phStbDbg_TreeNodeBase_t
    plus whatever payload data (minimum is a char *).
    @see PH_STBDBG_TREE_ERR_PAYLOADSIZE_TOO_SMALL
*/
typedef void *(phStbDbg_TreeNodeAllocator_t)(
    size_t size);

/** Type of function to destructs a node. The node will have been allocated using
    ::phStbDbg_TreeNodeAllocator_t
    @param node @b IN The node to destruct.
*/
typedef void (phStbDbg_TreeNodeDeallocator_t)(
    void *node);

typedef struct phStbDbg_TreeSetup {
    unsigned int flags;
    phStbDbg_TreeNodeAllocator_t *allocator;
    phStbDbg_TreeNodeDeallocator_t *deallocator;
} phStbDbg_TreeSetup_t;

/** Tree node. */
typedef struct phStbDbg_TreeNodeBase {
    phStbDbg_TreeSetup_t *setup;
    /** Parent node. */
    struct phStbDbg_TreeNode *parent;
    /** Next sibbling node. */
    struct phStbDbg_TreeNode *next;
    /** First child node. */
    struct phStbDbg_TreeNode *children;
    /** Name of this node amongst its sibblings. */
    char *name;
} phStbDbg_TreeNodeBase_t;

/** Tree node. */
typedef struct phStbDbg_TreeNode {
    phStbDbg_TreeNodeBase_t base;
    /** Default payload. */
    char *value;
} phStbDbg_TreeNode_t;

/**************************************************************************
* EXPORTED DATA                     g[k|p|kp|pk|kpk]phStbDbg_<Word>+ *
***************************************************************************/

/****************************************************************************
* EXPORTED FUNCTION PROTOTYPES                    phStbDbg[_<Word>+]   *
*****************************************************************************/

#ifdef __cplusplus
extern "C"
{
#endif

/******************************************************************************/
/** Create a new tree with a root node only.
    The root node will be named "/".
    @param setup @b IN General information about how this tree should behave.
    @param payloadSize @b IN Size of payload data for the root node.
    @param value @b IN Value of the root node.
    @param  pRoot @b OUT Resultant root node.
    @retval TM_OK Success.
    @retval PH_STBDBG_TREE_ERR_ALLOCATOR Allocator function (see ::phStbDbg_TreeSetup_t)
    returned an error.
    @retval PH_STBDBG_TREE_ERR_PAYLOADSIZE_TOO_SMALL
*/
extern tmErrorCode_t phStbDbg_TreeCreate(
    const phStbDbg_TreeSetup_t *setup,
    size_t payloadSize,
    const char *value,
    const phStbDbg_TreeNode_t **pRoot);

/** Lookup an existing node in the tree.
    @param root @b IN Root of the tree. See phStbDbg_TreeCreate().
    @param path @b IN Path name of the node, for example,
    "a/b/c". Starting slash is optional.
    @param  pNode @b OUT Result node.
    @retval TM_OK Success.
    @retval PH_STBDBG_TREE_ERR_NODE_NOT_FOUND Node not found.
*/
extern tmErrorCode_t phStbDbg_TreeGetNode(
    const phStbDbg_TreeNode_t *root,
    const char *path,
    const phStbDbg_TreeNode_t **pNode);

/** Lookup an existing node in the tree, or create it if it does not exist,
    or any of its ancestors.
    @param root @b IN Root of the tree. See phStbDbg_TreeCreate().
    @param path @b IN Path name of the node, for example,
    "a/b/c". Starting slash is optional.
    @param payloadSize @b IN Size of payload data for nodes if any are created.
    @param value @b IN Value of a new node if created.
    @param pNode @b OUT Result node.
    @retval TM_OK Success, existing node was returned.
    @retval PH_STBDBG_TREE_ERR_NODE_CREATED One or more new nodes were created. Not really an error.
    @retval PH_STBDBG_TREE_ERR_ALLOCATOR Allocator function (see ::phStbDbg_TreeSetup_t) failed.
    @retval PH_STBDBG_TREE_ERR_NODE_LEAF Trying to make a sub-node of a leaf node.
    @retval PH_STBDBG_TREE_ERR_PAYLOADSIZE_TOO_SMALL
*/
extern tmErrorCode_t phStbDbg_TreeGetOrCreateNode(
    const phStbDbg_TreeNode_t *root,
    const char *path,
    size_t payloadSize,
    const phStbDbg_TreeNode_t **pNode,
    const char *value);

/** Return the root node of a tree.
    @param node @b IN A node in a tree.
    @return Root node of the tree.
*/
extern phStbDbg_TreeNode_t *phStbDbg_TreeGetRoot(
    const phStbDbg_TreeNode_t *node);

/** Return a successor node.
    @param root @b IN Root of the tree. See phStbDbg_TreeCreate().
    @param node @b IN A node in a tree whose successor should be returned.
    @param order @b IN Order in which nodes should be returned.
    @retval NULL No more successor nodes.
    @retval Successor node address.
*/
extern phStbDbg_TreeNode_t *phStbDbg_TreeNextNode(
    const phStbDbg_TreeNode_t *node,
    phStbDbg_TreeOrder_t order);

/** Get the full path name of a node.
    Pathnames are names of nodes separated by a "/".
    @param node @b IN A node in a tree whose successor should be returned.
    @param path @b OUT Storage for the node path name.
*/
extern tmErrorCode_t phStbDbg_TreeGetNodePath(
    const phStbDbg_TreeNode_t *node,
    char *path);



/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/******************************************************************************/
#ifdef __cplusplus
}
#endif

#endif /* PHSTBDBG_TREE_H      Do not add any thing below this line */
