5983 lines
208 KiB
C
5983 lines
208 KiB
C
/*----------------------------------------------------------------------------*/
|
||
/* libnode.c */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* This file is part of LibNode */
|
||
/* */
|
||
/* LibNode 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 3 of the License, or */
|
||
/* (at your option) any later version. */
|
||
/* */
|
||
/* LibNode 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 LibNode. If not, see */
|
||
/* <https://www.gnu.org/licenses/>. */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Includes */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
#define _LIBNODE_C_
|
||
|
||
#include <libnode.h>
|
||
|
||
#ifdef _LIBVER_SUPPORT
|
||
//VER_INFO_EXPORT( libnode, "$Revision: 2.17 $", "$Name: libnode-2_2_0-1 $", __FILE__, "$Author: agibert $")
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Node Manager Template */
|
||
/*----------------------------------------------------------------------------*/
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Default_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.17 $ $Name: libnode-2_2_0-1 $ $Date: 2010/06/06 21:26:31 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch(Cmd)
|
||
{
|
||
/*
|
||
case NDT_CMD_SOME_USER_CMD:
|
||
{
|
||
*Reply_Index_Id_Ptr = 0;
|
||
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
|
||
break;
|
||
}
|
||
|
||
...
|
||
*/
|
||
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
/*
|
||
if( ( *Value_Ptr_Ptr = (void *)malloc( sizeof(void))) == NULL)
|
||
{
|
||
return(NDS_ERRMEM);
|
||
}
|
||
else
|
||
{
|
||
...
|
||
|
||
return( NDS_OK);
|
||
}
|
||
*/
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
/*
|
||
free( Value_Ptr);
|
||
|
||
return( NDS_OK);
|
||
*/
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
/*
|
||
switch( Index_Id)
|
||
{
|
||
case 0:
|
||
{
|
||
int rc;
|
||
|
||
|
||
rc = strcmp( Value1_Ptr->..., Value2_Ptr->...);
|
||
|
||
if( rc < 0)
|
||
{
|
||
return(NDS_LOWER);
|
||
}
|
||
else
|
||
{
|
||
if( rc > 0)
|
||
{
|
||
return(NDS_GREATER);
|
||
}
|
||
else
|
||
{
|
||
return(NDS_EQUAL);
|
||
}
|
||
}
|
||
}
|
||
|
||
case 1:
|
||
{
|
||
int val1 = atoi(Value1_Ptr->...);
|
||
int val2 = atoi(Value2_Ptr->...);
|
||
|
||
|
||
if( val1 < val2)
|
||
{
|
||
return(NDS_LOWER);
|
||
}
|
||
else
|
||
{
|
||
if( val1 > val2)
|
||
{
|
||
return(NDS_GREATER);
|
||
}
|
||
else
|
||
{
|
||
return(NDS_EQUAL);
|
||
}
|
||
}
|
||
}
|
||
|
||
case 2:
|
||
{
|
||
...
|
||
}
|
||
|
||
default:
|
||
{
|
||
printf( "Unknown COMP idx (%d) !\n", Index_Id);
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
*/
|
||
return( NDS_OK);
|
||
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
/*
|
||
return( NDS_OK);
|
||
*/
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
/*
|
||
return( NDS_OK);
|
||
*/
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
|
||
/*
|
||
fprintf( Out, "...\n", Value_Ptr->..., ...);
|
||
|
||
return( NDS_OK);
|
||
*/
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
/*
|
||
return( NDS_OK);
|
||
*/
|
||
}
|
||
|
||
case NDD_CMD_USER_TRAVERSE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_USER_TRAVERSE";
|
||
|
||
/*
|
||
return( NDS_OK);
|
||
*/
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_2( "Manager internal error with command: (%d) name: [%s]", Command, Command_Name);
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* OpenStruct Manager */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_OpenStruct_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.17 $ $Name: libnode-2_2_0-1 $ $Date: 2010/06/06 21:26:31 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch(Cmd)
|
||
{
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
switch( Index_Id)
|
||
{
|
||
case 0:
|
||
{
|
||
if( Value1_Ptr < Value2_Ptr)
|
||
{
|
||
return(NDS_LOWER);
|
||
}
|
||
else
|
||
{
|
||
if( Value1_Ptr > Value2_Ptr)
|
||
{
|
||
return(NDS_GREATER);
|
||
}
|
||
else
|
||
{
|
||
return(NDS_EQUAL);
|
||
}
|
||
}
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown COMP idx: (%d)", Index_Id);
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
return( ND_DataStruct_Info_Print_I( Out, (NDT_Root *)Value_Ptr, Recursive_Mode, --Recursive_Depth, ++Recursive_Offset));
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_2( "Manager internal error with command: (%d) name: [%s]", Command, Command_Name);
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/*----------------------------------------------------------------------------*/
|
||
/* FONCTIONS PUBLIQUES */
|
||
/*----------------------------------------------------------------------------*/
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Library initialisation */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Debug_Mode: Open library in debug mode */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Library_Open_I( int Debug_Mode)
|
||
{
|
||
LGT_Status lg_status;
|
||
|
||
|
||
NDG_Base.Debug_Mode = Debug_Mode;
|
||
NDG_Base.Open_Status = NDD_TRUE;
|
||
|
||
if( Debug_Mode == NDD_TRUE)
|
||
{
|
||
ND_Library_StdErr_Set_I( stderr);
|
||
}
|
||
|
||
if( ( lg_status = LG_Library_Open( LGD_LOG_WRITER_DEFAULT, false)) != LGS_OK)
|
||
{
|
||
fprintf( stderr, "Can't open LibLog library: (%d)\n", lg_status);
|
||
return( -1);
|
||
}
|
||
|
||
|
||
#if !defined(_WIN32)
|
||
if( ( NDG_Base.DL_Ptr = dlopen( NULL, ( RTLD_NOW | RTLD_GLOBAL))) == NULL)
|
||
{
|
||
LG_LOG_ERROR_1( "Can't dlopen: [%s]", dlerror());
|
||
|
||
return( NDS_KO);
|
||
}
|
||
#endif
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Library initialisation */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Debug_Mode: Open library in debug mode */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Library_Open_C( int Debug_Mode)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
if( NDG_Base.Open_Status != NDD_FALSE)
|
||
{
|
||
LG_LOG_ERROR_0( "Library is not closed");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
else
|
||
{
|
||
if( Debug_Mode == NDD_TRUE)
|
||
{
|
||
if( ( status = ND_DataStruct_Open_I( &(NDG_Base.OpenStruct_Ptr), "OpenStruct", ND_OPEN_FLAG_CREATE, 1, NDG_Base.OpenStruct_Index_Type, "ND_OpenStruct_Manager", ND_OpenStruct_Manager, NULL, 0, NULL)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't open OpenStruct");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
}
|
||
|
||
return( ND_Library_Open_I( Debug_Mode));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Library deinitialisation */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Library_Close_I( void)
|
||
{
|
||
NDT_Symbol *Symbol, *Next_Symbol;
|
||
LGT_Status lg_status;
|
||
|
||
|
||
/* D<>sallocation de la table des symboles locale */
|
||
|
||
Symbol = NDG_Base.Symbol_First_Ptr;
|
||
|
||
while( Symbol)
|
||
{
|
||
Next_Symbol = Symbol->Next;
|
||
free( Symbol->Name);
|
||
free( Symbol);
|
||
Symbol = Next_Symbol;
|
||
}
|
||
|
||
NDG_Base.Symbol_First_Ptr = (NDT_Symbol *)NULL;
|
||
|
||
#if !defined(_WIN32)
|
||
if( dlclose( NDG_Base.DL_Ptr) != 0)
|
||
{
|
||
LG_LOG_ERROR_1( "Can't dlclose: [%s]", dlerror());
|
||
|
||
return( NDS_KO);
|
||
}
|
||
#endif
|
||
|
||
NDG_Base.Open_Status = NDD_FALSE;
|
||
|
||
if( ( lg_status = LG_Library_Close( false)) != LGS_OK)
|
||
{
|
||
fprintf( stderr, "Can't close LibLog library: (%d)\n", lg_status);
|
||
return( NDS_KO);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Library deinitialisation */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Library_Close_C( void)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
if( ( NDG_Base.Debug_Mode == NDD_TRUE) && ( NDG_Base.Err_Stream != NULL))
|
||
{
|
||
if( NDG_Base.OpenStruct_Ptr->Index_Tab[NDD_INDEX_PRIMARY].Node_Number > 0)
|
||
{
|
||
LG_LOG_ERROR_0( "Unclosed DataStruct:");
|
||
|
||
if( ( status = ND_DataStruct_Info_Print_I( NDG_Base.Err_Stream, NDG_Base.OpenStruct_Ptr, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't print OpenStruct info");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
if( ( status = ND_DataStruct_Close_I( NDG_Base.OpenStruct_Ptr)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't close OpenStruct");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
return( ND_Library_Close_I());
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Library Standard Error output setup */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: StdErr output stream */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Library_StdErr_Set_I( FILE *Out)
|
||
{
|
||
NDG_Base.Err_Stream = Out;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Library Standard Error output setup */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: StdErr output stream */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Library_StdErr_Set_C( FILE *Out)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
return( ND_Library_StdErr_Set_I( Out));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Create a new index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Index_Type: Index type (List, tree, ...) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Open_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Type)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
if( ( status = ND_Index_Clear( Root_Ptr, Index_Id)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Index cleaning error");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Type = Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_OPENED ;
|
||
|
||
Root_Ptr->Index_Open_Count++;
|
||
|
||
if( Index_Id != NDD_INDEX_PRIMARY)
|
||
{
|
||
if( ( status = ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, NDD_INDEX_PRIMARY)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't get first primary index node");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
while( node_ptr != NULL)
|
||
{
|
||
if( ( status = ND_Index_Value_Add_I( Root_Ptr, Index_Id, node_ptr->Value)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't add value");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
if( ( status = ND_Index_Node_Next_Get_I( &node_ptr, node_ptr)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't get next node");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Create a new index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Index_Type: Index type (List, tree, ...) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Open_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Type)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
if( !ND_INDEX_STATUS_CLOSED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
LG_LOG_ERROR_0( "Index is not closed");
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
if( ( Root_Ptr->Index_Open_Count == 0) && ( Index_Id != NDD_INDEX_PRIMARY))
|
||
{
|
||
LG_LOG_ERROR_0( "Fist opened index should be the primary");
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
return( ND_Index_Open_I( Root_Ptr, Index_Id, Type));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Create a new data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Pointer adress of the new sata structure */
|
||
/* (I) DataStruct_Name: Name of the data structure */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Index_Nb: Number of index */
|
||
/* (I) Index_Type_Ptr: Array of Index type (List, tree, ...) */
|
||
/* (I) Manager_Name: Manager function name */
|
||
/* (I) Manager_Ptr: Manager function pointer */
|
||
/* (I) Handlers_Ptr: Pointer to the data structure handlers */
|
||
/* (I) Own_Value: Flag indicating if the structure is the node owner */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Open_I( NDT_Root **Root_Ptr_Ptr, NDT_DataStruct_Name Name, NDT_Open_Flag Open_Mode, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr,
|
||
NDT_Manager_Name Manager_Name, NDT_Manager *Manager_Ptr, NDT_Handler *Handler_Tab, short Own_Value, void *User_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Handler handler_target_tab[ NDD_HANDLER_NB];
|
||
NDT_Handler_Id handler_id;
|
||
size_t root_extra_size;
|
||
|
||
|
||
if( Handler_Tab == NULL)
|
||
{
|
||
Handler_Tab = NDG_Handler_Tab_Default;
|
||
}
|
||
|
||
memcpy( &handler_target_tab, Handler_Tab, NDD_HANDLER_TAB_SIZE);
|
||
|
||
|
||
/* Valeurs par d<>faut des fonctions d'allocation et de d<>sallocation */
|
||
|
||
if( Manager_Name != NULL)
|
||
{
|
||
NDD_HANDLER_SET( handler_target_tab[ NDD_HANDLER_ID_MANAGER], Manager_Name, Manager_Ptr);
|
||
}
|
||
else
|
||
{
|
||
if( Manager_Ptr != NULL)
|
||
{
|
||
NDD_HANDLER_SET( handler_target_tab[ NDD_HANDLER_ID_MANAGER], "", Manager_Ptr);
|
||
}
|
||
}
|
||
|
||
|
||
/* Complete with default handlers */
|
||
|
||
for( handler_id = 0; handler_id < NDD_HANDLER_ID_NB; handler_id++)
|
||
{
|
||
if( ( strlen( handler_target_tab[ handler_id].Name) == 0) && ( handler_target_tab[ handler_id].Ptr == NULL))
|
||
{
|
||
NDD_HANDLER_SET( handler_target_tab[ handler_id], NDG_Handler_Tab_Default[ handler_id].Name, NDG_Handler_Tab_Default[ handler_id].Ptr);
|
||
}
|
||
}
|
||
|
||
|
||
/* Call init function */
|
||
|
||
*Root_Ptr_Ptr = NULL;
|
||
|
||
if( ( status = ND_Handler_Init_Exec_I( Root_Ptr_Ptr, &root_extra_size, Name, Open_Mode, handler_target_tab, handler_target_tab[ NDD_HANDLER_ID_INIT].Name, ( NDT_Handler_Init *)handler_target_tab[ NDD_HANDLER_ID_INIT].Ptr, User_Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
|
||
if( ( *Root_Ptr_Ptr != NULL) && ( status = ND_Node_Root_Alloc( Root_Ptr_Ptr, Name, Index_Nb, Type_Ptr, handler_target_tab, root_extra_size, Own_Value, User_Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
|
||
/* Call Open function */
|
||
|
||
if( ( status = ND_Handler_Open_Exec_I( *Root_Ptr_Ptr, Open_Mode, handler_target_tab[ NDD_HANDLER_ID_OPEN].Name, ( NDT_Handler_Open *)handler_target_tab[ NDD_HANDLER_ID_OPEN].Ptr, User_Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Create a new data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Pointer adress of the new sata structure */
|
||
/* (I) Index_Nb: Number of index */
|
||
/* (I) Index_Type_Ptr: Array of Index type (List, tree, ...) */
|
||
/* (I) Manager_Name: Manager function name */
|
||
/* (I) Manager_Ptr: Manager function pointer */
|
||
/* (I) Allocator_Name: Value allocator function name */
|
||
/* (I) Allocator_Ptr: Value allocator function pointer */
|
||
/* (I) Deallocator_Name: Value deallocator function name */
|
||
/* (I) Deallocator_Ptr: Value deallocator function pointer */
|
||
/* (I) Own_Value: Flag indicating if the structure is the node owner */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Open_C( NDT_Root **Root_Ptr_Ptr, NDT_DataStruct_Name Name, NDT_Open_Flag Open_Mode, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Manager_Name Manager_Name, NDT_Manager *Manager_Ptr,
|
||
NDT_Handler *Handler_Tab, short Own_Value, void *User_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
if( ( status = ND_DataStruct_Open_I( Root_Ptr_Ptr, Name, Open_Mode, Index_Nb, Type_Ptr, Manager_Name, Manager_Ptr, Handler_Tab, Own_Value, User_Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
if( ( NDG_Base.Debug_Mode == NDD_TRUE) && ( Manager_Ptr != NULL) && ( NDG_Base.Open_Status == NDD_TRUE))
|
||
{
|
||
if( ( status = ND_DataStruct_Value_Add_I( NDG_Base.OpenStruct_Ptr, (void **)*Root_Ptr_Ptr)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't add value in OpenStruct");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove an Index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Close_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
if( ( Root_Ptr->Index_Open_Count != 1) && ( Index_Id == NDD_INDEX_PRIMARY))
|
||
{
|
||
LG_LOG_ERROR_0( "The primary should be the last closed");
|
||
|
||
return(NDS_ERRAPI);
|
||
}
|
||
|
||
status = ND_Index_Flush_I( Root_Ptr, Index_Id);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
Root_Ptr->Index_Tab[ Index_Id].Type = Root_Ptr->Index_Tab[ Index_Id].Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_CLOSED;
|
||
|
||
Root_Ptr->Index_Open_Count--;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove an Index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Close_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
if( !ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
LG_LOG_ERROR_0( "Index is not opened");
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
return( ND_Index_Close_I( Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Destroy a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Close_I( NDT_Root *Root_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
status = ND_DataStruct_Flush_I( Root_Ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
return( ND_Node_Root_Free( Root_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Destroy a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Close_C( NDT_Root *Root_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
if( ( status = ND_DataStruct_Close_I( Root_Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
if( NDG_Base.Debug_Mode == NDD_TRUE)
|
||
{
|
||
if( ( status = ND_DataStruct_Value_Remove_I( NDG_Base.OpenStruct_Ptr, (void *)Root_Ptr)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Can't remove value from OpenStruct");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove an Index (Private API ?) */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Flush_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Node *Node_Ptr, *Next_Node_Ptr;
|
||
|
||
|
||
ND_Index_Node_First_Get_I( &Node_Ptr, Root_Ptr, Index_Id);
|
||
|
||
while( Node_Ptr)
|
||
{
|
||
Next_Node_Ptr = NULL;
|
||
ND_Index_Node_Next_Get_I( &Next_Node_Ptr, Node_Ptr);
|
||
|
||
if( Index_Id == NDD_INDEX_PRIMARY)
|
||
{
|
||
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, NDD_CMD_VALUE_FREE, Node_Ptr->Value);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
else
|
||
{
|
||
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, NDD_CMD_VALUE_REMOVE, Node_Ptr->Value);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
|
||
status = ND_Index_Node_Remove_I( Node_Ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
status = ND_Node_Free( Root_Ptr, Node_Ptr);
|
||
if (ND_ERROR( status)) return( status);
|
||
|
||
Node_Ptr = Next_Node_Ptr;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove an Index (Private API ?) */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Flush_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_Index_Flush_I( Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Destroy all data of a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Flush_I( NDT_Root *Root_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id index_id;
|
||
|
||
|
||
for( index_id = ( Root_Ptr->Index_Nb - 1); index_id >= 0 ; index_id--)
|
||
{
|
||
status = ND_Index_Flush_I( Root_Ptr, index_id);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Destroy all data of a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Flush_C( NDT_Root *Root_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return ND_DataStruct_Flush_I( Root_Ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Check & repare a data structure index: */
|
||
/* - Check & fix node links */
|
||
/* - Update data structure statistics */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (O) Error_Dectected_Nb_Ptr: Number of error detected pointer */
|
||
/* (O) Error_Corrected_Nb_Ptr: Number of error corected pointer */
|
||
/* (I) Out: Output stream */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Check_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Detected_Nb_Ptr, int *Corrected_Nb_Ptr, FILE *Out)
|
||
{
|
||
*Detected_Nb_Ptr = 0;
|
||
*Corrected_Nb_Ptr = 0;
|
||
|
||
|
||
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
|
||
{
|
||
ND_List_Check( Root_Ptr, Index_Id, Detected_Nb_Ptr, Corrected_Nb_Ptr, Out);
|
||
}
|
||
else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
|
||
{
|
||
ND_Tree_Check( Root_Ptr, Index_Id, Detected_Nb_Ptr, Corrected_Nb_Ptr, Out);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_3( "Unknown structure type: (%d) in structure: (%p:%d)\n", Root_Ptr->Index_Tab[Index_Id].Type, Root_Ptr, Index_Id);
|
||
|
||
(*Detected_Nb_Ptr)++;
|
||
return( NDS_OK);
|
||
}
|
||
|
||
/* Affichage du r<>sultat de la proc<6F>dure de v<>rification */
|
||
|
||
if( *Detected_Nb_Ptr == 0)
|
||
{
|
||
LG_LOG_INFO_2( "No error detected in the node structure (%p:%d)", Root_Ptr, Index_Id);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_INFO_4( "%d/%d error(s) corrected in the node structure (%p:%d)\n", *Corrected_Nb_Ptr, *Detected_Nb_Ptr, Root_Ptr, Index_Id);
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Check & repare a data structure index: */
|
||
/* - Check & fix node links */
|
||
/* - Update data structure statistics */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (O) Error_Dectected_Nb_Ptr: Number of error detected pointer */
|
||
/* (O) Error_Corrected_Nb_Ptr: Number of error corected pointer */
|
||
/* (I) Out: Output stream */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Check_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Out, "Stream descriptor");
|
||
|
||
return( ND_Index_Check_I( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Check & repare a datat structure: */
|
||
/* - Check & fix node links */
|
||
/* - Update data structure statistics */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (O) Error_Dectected_Nb_Ptr: Number of error detected pointer */
|
||
/* (O) Error_Corrected_Nb_Ptr: Number of error corected pointer */
|
||
/* (I) Out: Output stream */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Check_I( NDT_Root *Root_Ptr, int *Error_Detected_Nb_Ptr, int *Error_Corrected_Nb_Ptr, FILE *Out)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id index_id;
|
||
int index_error_detected_nb, index_error_corrected_nb;
|
||
|
||
|
||
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
|
||
{
|
||
status = ND_Index_Check_I( Root_Ptr, index_id, &index_error_detected_nb, &index_error_corrected_nb, Out);
|
||
if( ND_ERROR(status)) return(status);
|
||
|
||
*Error_Detected_Nb_Ptr = *Error_Detected_Nb_Ptr + index_error_detected_nb;
|
||
*Error_Corrected_Nb_Ptr = *Error_Corrected_Nb_Ptr + index_error_corrected_nb;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Check & repare a datat structure: */
|
||
/* - Check & fix node links */
|
||
/* - Update data structure statistics */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (O) Error_Dectected_Nb_Ptr: Number of error detected pointer */
|
||
/* (O) Error_Corrected_Nb_Ptr: Number of error corected pointer */
|
||
/* (I) Out: Output stream */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Check_C( NDT_Root *Root_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Out, "Stream descriptor");
|
||
|
||
return( ND_DataStruct_Check_I( Root_Ptr, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Convert a data structure index to another type */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Index_Type: Index type (List, tree, ...) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Convert_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Target_Type)
|
||
{
|
||
NDT_Status rc;
|
||
|
||
|
||
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
switch( Root_Ptr->Index_Tab[Index_Id].Type & NDD_INDEX_TYPE_MSK)
|
||
{
|
||
case NDD_INDEX_TYPE_LIST:
|
||
{
|
||
|
||
switch( Target_Type & ( NDD_INDEX_TYPE_MSK | NDD_INDEX_SUBTYPE_MSK))
|
||
{
|
||
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED):
|
||
{
|
||
rc = ND_List_Sort( Root_Ptr, Index_Id);
|
||
if( ND_ERROR( rc)) return( rc);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
|
||
|
||
return( rc);
|
||
}
|
||
|
||
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO):
|
||
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_LIFO):
|
||
{
|
||
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED):
|
||
case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_UNBALANCED):
|
||
{
|
||
rc = ND_List_Sort( Root_Ptr, Index_Id);
|
||
if( rc != NDS_OK) return( rc);
|
||
|
||
rc = ND_Tree_Make( Root_Ptr, Index_Id);
|
||
if( ND_ERROR( rc)) return( rc);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
|
||
|
||
return( rc);
|
||
}
|
||
|
||
default:
|
||
{
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
case NDD_INDEX_TYPE_TREE:
|
||
{
|
||
switch( Target_Type & ( NDD_INDEX_TYPE_MSK | NDD_INDEX_SUBTYPE_MSK))
|
||
{
|
||
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED):
|
||
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO):
|
||
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_LIFO):
|
||
{
|
||
|
||
rc = ND_List_Make( Root_Ptr, Index_Id);
|
||
if( ND_ERROR( rc)) return( rc);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
|
||
|
||
return( rc);
|
||
}
|
||
|
||
default:
|
||
{
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown structure type: (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Convert a data structure index to another type */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Index_Type: Index type (List, tree, ...) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Convert_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Target_Type)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_Index_Convert_I( Root_Ptr, Index_Id, Target_Type));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Convert a data structure indexe types */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Type_Ptr: Array of index type (List, tree, ...) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Convert_I( NDT_Root *Root_Ptr, NDT_Index_Type *Index_Type_Ptr)
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Index_Nb idx;
|
||
|
||
|
||
for( idx = 0; idx < Root_Ptr->Index_Nb; idx++)
|
||
{
|
||
rc = ND_Index_Convert_I( Root_Ptr, idx, Index_Type_Ptr[idx]);
|
||
if( ND_ERROR( rc)) return rc;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Convert a data structure indexe types */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Type_Ptr: Array of index type (List, tree, ...) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Convert_C( NDT_Root *Root_Ptr, NDT_Index_Type *Index_Type_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Index_Type_Ptr, "Index type");
|
||
|
||
return( ND_DataStruct_Convert_I( Root_Ptr, Index_Type_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Reorganise a data structure index: */
|
||
/* - Sort a non-sorted list */
|
||
/* - Rebalance a non auto-balanced tree */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Reorg_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
if( ( status = ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)))
|
||
{
|
||
if ( !ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
if( ( status = ND_List_Sort( Root_Ptr, Index_Id)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
|
||
{
|
||
if( ( status = ND_Tree_Equalize( Root_Ptr, Index_Id)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_3( "Unknown structure type: (%d) in structure: (%p:%d)\n", Root_Ptr->Index_Tab[Index_Id].Type, Root_Ptr, Index_Id);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Reorganise a data structure index: */
|
||
/* - Sort a non-sorted list */
|
||
/* - Rebalance a non auto-balanced tree */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Reorg_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_Index_Reorg_I( Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Reorganise a data structure indexes: */
|
||
/* - Sort a non-sorted list */
|
||
/* - Rebalance a non auto-balanced tree */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Reorg_I( NDT_Root *Root_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id index_id;
|
||
|
||
|
||
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
|
||
{
|
||
status = ND_Index_Reorg_I( Root_Ptr, index_id);
|
||
if( ND_ERROR( status)) return status;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Reorganise a data structure indexes: */
|
||
/* - Sort a non-sorted list */
|
||
/* - Rebalance a non auto-balanced tree */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Reorg_C( NDT_Root *Root_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_DataStruct_Reorg_I( Root_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure index & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Traverse_VI( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Node *Node_Ptr, *Next_Node_Ptr;
|
||
|
||
|
||
ND_Index_Node_First_Get_I( &Node_Ptr, Root_Ptr, Index_Id);
|
||
|
||
while( Node_Ptr)
|
||
{
|
||
Next_Node_Ptr = NULL;
|
||
ND_Index_Node_Next_Get_I( &Next_Node_Ptr, Node_Ptr);
|
||
|
||
switch (Command)
|
||
{
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
|
||
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Node_Ptr->Value, Args_Ptr);
|
||
if (ND_ERROR( rc)) return rc;
|
||
|
||
rc = ND_Index_Node_Remove_I( Node_Ptr);
|
||
if( ND_ERROR( rc)) return rc;
|
||
|
||
rc = ND_Node_Free( Root_Ptr, Node_Ptr);
|
||
if (ND_ERROR(rc)) return rc;
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Next_Node_Ptr, Args_Ptr);
|
||
if (ND_ERROR( rc)) return rc;
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
Node_Ptr = Next_Node_Ptr;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure index & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Traverse_VC( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_Index_Traverse_VI( Root_Ptr, Index_Id, Command, Args_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure index & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Traverse_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list args;
|
||
NDT_Node *Node_Ptr, *Next_Node_Ptr;
|
||
|
||
|
||
va_start( args, Command);
|
||
|
||
ND_Index_Node_First_Get_I( &Node_Ptr, Root_Ptr, Index_Id);
|
||
|
||
status = NDS_OK;
|
||
|
||
while( Node_Ptr)
|
||
{
|
||
Next_Node_Ptr = NULL;
|
||
ND_Index_Node_Next_Get_I( &Next_Node_Ptr, Node_Ptr);
|
||
|
||
switch (Command)
|
||
{
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
|
||
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Node_Ptr->Value, &args);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
status = ND_Index_Node_Remove_I( Node_Ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
status = ND_Node_Free( Root_Ptr, Node_Ptr);
|
||
if (ND_ERROR( status)) return( status);
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Next_Node_Ptr, &args);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
Node_Ptr = Next_Node_Ptr;
|
||
}
|
||
|
||
va_end( args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure index & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Traverse_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
va_start( args, Command);
|
||
|
||
status = ND_Index_Traverse_VI( Root_Ptr, Index_Id, Command, &args);
|
||
|
||
va_end( args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Traverse_VI( NDT_Root *Root_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id new_index;
|
||
NDT_Command new_cmd;
|
||
|
||
|
||
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, Command, NULL);
|
||
if( ND_ERROR(status)) return( status);
|
||
|
||
return( ND_Index_Traverse_VI( Root_Ptr, new_index, new_cmd, Args_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Traverse_VC( NDT_Root *Root_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_DataStruct_Traverse_VI( Root_Ptr, Command, Args_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Traverse_I( NDT_Root *Root_Ptr, NDT_Command Command, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list args;
|
||
NDT_Index_Id new_index;
|
||
NDT_Command new_cmd;
|
||
|
||
|
||
va_start( args, Command);
|
||
|
||
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, Command, NULL);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
status = ND_Index_Traverse_VI( Root_Ptr, new_index, new_cmd, &args);
|
||
|
||
va_end( args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Traverse a data structure & execute a command on each node */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Traverse_C( NDT_Root *Root_Ptr, NDT_Command Command, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
va_start( args, Command);
|
||
|
||
status = ND_DataStruct_Traverse_VI( Root_Ptr, Command, &args);
|
||
|
||
va_end( args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print data structure index information */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Info_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
|
||
{
|
||
NDT_Status status;
|
||
char offset[255];
|
||
|
||
|
||
if( ND_RECURSIVE_PARENT_IS( Recursive_Mode))
|
||
{
|
||
memset( offset, ' ', Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET);
|
||
offset[Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET] = '\0';
|
||
/*
|
||
fprintf( Out, "%s Index Id: (%d)\tType: (%#06x) [%s:%s:%s]\tNode Nb: (%ld)\tHead: (%s%p)\tTail: (%s%p)\n%s Min Depth: (%ld)\tMax Depth: (%ld)\tMax Dif: (%ld)\tNb Equ: (%ld)\tSave: (%s%p)\n\n",
|
||
offset, Index_Id, Root_Ptr->Index_Tab[Index_Id].Type, ND_INDEX_STATUS_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_TYPE_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_SUBTYPE_ASCII_GET( Root_Ptr, Index_Id),
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Head, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Tail,
|
||
offset, Root_Ptr->Index_Tab[Index_Id].Min_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Dif, Root_Ptr->Index_Tab[Index_Id].Nb_Equ,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Save);
|
||
*/
|
||
|
||
LG_LOG_INFO_11( "%s Index Id: (%d)\tType: (%#06x) [%s:%s:%s]\tNode Nb: (%ld)\tHead: (%s%p)\tTail: (%s%p)",
|
||
offset, Index_Id, Root_Ptr->Index_Tab[Index_Id].Type, ND_INDEX_STATUS_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_TYPE_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_SUBTYPE_ASCII_GET( Root_Ptr, Index_Id),
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Head, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Tail);
|
||
LG_LOG_INFO_7( "%s Min Depth: (%ld)\tMax Depth: (%ld)\tMax Dif: (%ld)\tNb Equ: (%ld)\tSave: (%s%p)",
|
||
offset, Root_Ptr->Index_Tab[Index_Id].Min_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Dif, Root_Ptr->Index_Tab[Index_Id].Nb_Equ,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Save);
|
||
LG_LOG_INFO_0( "");
|
||
}
|
||
|
||
if( ND_RECURSIVE_CHILD_IS( Recursive_Mode))
|
||
{
|
||
status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_INFO_PRINT, Out, NDD_RECURSIVE_MODE_PARENT_CHILD, Recursive_Depth, Recursive_Offset);
|
||
}
|
||
else
|
||
{
|
||
status = NDS_OK;
|
||
}
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print data structure index information */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Info_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Out, "Stream descriptor");
|
||
|
||
return( ND_Index_Info_Print_I( Out, Root_Ptr, Index_Id, Recursive_Mode, Recursive_Depth, Recursive_Offset));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print data structure information */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Info_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Nb idx;
|
||
NDT_Version_Name version_name;
|
||
char offset[255];
|
||
|
||
|
||
if( ND_RECURSIVE_PARENT_IS( Recursive_Mode))
|
||
{
|
||
memset( offset, ' ', Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET);
|
||
offset[ Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET] = '\0';
|
||
|
||
if( ( status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_MANAGER_VERSION, &version_name)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
/*
|
||
fprintf( Out, "%sRoot: (%s%p)\tIndex Nb: (%d)\tIndex Open Count: (%d)\tManager: (%s%p) [%s]\n%sAllocator: (%s%p) [%s]\tDeallocator: (%s%p) [%s]\tUser: (%s%p)\n%sManager Version: [%s]\n\n",
|
||
offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr, Root_Ptr->Index_Nb, Root_Ptr->Index_Open_Count, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Manager_Ptr, Root_Ptr->Manager_Name,
|
||
offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Allocator_Ptr, Root_Ptr->Allocator_Name, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Deallocator_Ptr, Root_Ptr->Deallocator_Name, NDD_PRINTF_PTR_PREFIX, Root_Ptr->User_Ptr,
|
||
offset, version_name);
|
||
*/
|
||
|
||
LG_LOG_INFO_7( "%sRoot: (%s%p)\tName: [%s]\tIndex Nb: (%d)\tIndex Open Count: (%d)\tRoot_Size: (%ld)",
|
||
offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr, Root_Ptr->Name, Root_Ptr->Index_Nb, Root_Ptr->Index_Open_Count, Root_Ptr->Root_Size);
|
||
|
||
LG_LOG_INFO_13( "%sManager: (%s%p) [%s]\tInit: (%s%p) [%s]\tAlloc: (%s%p) [%s]\tFree: (%s%p) [%s]", offset,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_MANAGER].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_MANAGER].Name,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_INIT ].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_INIT ].Name,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_ALLOC ].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_ALLOC ].Name,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_FREE ].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_FREE ].Name);
|
||
|
||
LG_LOG_INFO_13( "%sOpen: (%s%p) [%s]\tClose: (%s%p) [%s]\tLock: (%s%p) [%s]\tUnlock: (%s%p) [%s]", offset,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_OPEN ].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_OPEN ].Name,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_CLOSE ].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_CLOSE ].Name,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_LOCK ].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_LOCK ].Name,
|
||
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_UNLOCK].Ptr, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_UNLOCK].Name);
|
||
|
||
LG_LOG_INFO_4( "%sUser: (%s%p)\tManager Version: [%s]",
|
||
offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr->User_Ptr, version_name);
|
||
|
||
if( ( status = ND_Handler_Info_Exec_I( Root_Ptr, Recursive_Offset, Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_INFO].Name, ( NDT_Handler_Info *)Root_Ptr->Handler_Tab[ NDD_HANDLER_ID_INFO].Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
LG_LOG_INFO_0( "");
|
||
}
|
||
|
||
if( ND_RECURSIVE_CHILD_IS( Recursive_Mode))
|
||
{
|
||
for( idx = NDD_INDEX_PRIMARY; idx < Root_Ptr->Index_Nb; idx++)
|
||
{
|
||
status = ND_Index_Info_Print_I( Out, Root_Ptr, idx, NDD_RECURSIVE_MODE_PARENT, 0, Recursive_Offset);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
|
||
return( ND_Index_Info_Print_I( Out, Root_Ptr, NDD_INDEX_PRIMARY, NDD_RECURSIVE_MODE_CHILD, Recursive_Depth, Recursive_Offset));
|
||
}
|
||
else
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print data structure information */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Info_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Out, "Stream descriptor");
|
||
|
||
return( ND_DataStruct_Info_Print_I( Out, Root_Ptr, Recursive_Mode, Recursive_Depth, Recursive_Offset));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Alloc memory unsing data structure allocator - Manager function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Memory_Ptr_Ptr: Memory pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Alloc_I( void **Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, void *Data_Ptr)
|
||
{
|
||
return( ND_Allocator_Exec_I( Ptr_Ptr, Root_Ptr, Size, Root_Ptr->Allocator_Name, Root_Ptr->Allocator_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Alloc memory unsing data structure allocator - Manager function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Memory_Ptr_Ptr: Memory pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Alloc_C( void **Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, void *Data_Ptr)
|
||
{
|
||
return( ND_Allocator_Exec_I( Ptr_Ptr, Root_Ptr, Size, Root_Ptr->Allocator_Name, Root_Ptr->Allocator_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Free memory unsing data structure allocator - Manager function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Memory_Ptr: Memory pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Free_I( void *Ptr, NDT_Root *Root_Ptr, void *Data_Ptr)
|
||
{
|
||
return( ND_Deallocator_Exec_I( Ptr, Root_Ptr, Root_Ptr->Deallocator_Name, Root_Ptr->Deallocator_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Free memory unsing data structure allocator - Manager function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Memory_Ptr: Memory pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Allocator_Name: Value deallocator function name */
|
||
/* (I) Allocator_Ptr: Value deallocator function pointer */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Free_C( void *Ptr, NDT_Root *Root_Ptr, void *Data_Ptr)
|
||
{
|
||
return( ND_Deallocator_Exec_I( Ptr, Root_Ptr, Root_Ptr->Deallocator_Name, Root_Ptr->Deallocator_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Add a new value to a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Add_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
|
||
{
|
||
status = ND_List_Value_Add( Root_Ptr, Index_Id, Value_Ptr);
|
||
if(ND_ERROR( status)) return( status);
|
||
}
|
||
else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
|
||
{
|
||
status = ND_Tree_Value_Add( Root_Ptr, Index_Id, Value_Ptr);
|
||
if(ND_ERROR( status)) return( status);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown structure type: (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Add a new value to a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Add_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
return( ND_Index_Value_Add_I( Root_Ptr, Index_Id, Value_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Add a new value to a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Add_I( NDT_Root *Root_Ptr, void *Value_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id index_id;
|
||
|
||
|
||
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
|
||
{
|
||
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, index_id))
|
||
{
|
||
status = ND_Index_Value_Add_I( Root_Ptr, index_id, Value_Ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Add a new value to a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Add_C( NDT_Root *Root_Ptr, void *Value_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
return( ND_DataStruct_Value_Add_I( Root_Ptr, Value_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove the first matching value from a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Remove_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
/* Recherche du premier noeud correspondant <20> la valeur de r<>f<EFBFBD>rence */
|
||
|
||
status = ND_Index_Node_Find_I( &node_ptr, Root_Ptr, Index_Id, Value_Ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
if( !node_ptr) return( NDS_OK);
|
||
|
||
/* manager call */
|
||
|
||
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_REMOVE, Value_Ptr);
|
||
if (ND_ERROR( status)) return( status);
|
||
|
||
/* Retrait du noeud de la structure */
|
||
|
||
status = ND_Index_Node_Remove_I( node_ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
|
||
/* D<>sallocation du noeud */
|
||
|
||
status = ND_Node_Free( Root_Ptr, node_ptr);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove the first matching value from a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Remove_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
return( ND_Index_Value_Remove_I( Root_Ptr, Index_Id, Value_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove the first matching value from a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Remove_I( NDT_Root *Root_Ptr, void *Value_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id index_id;
|
||
|
||
|
||
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
|
||
{
|
||
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, index_id))
|
||
{
|
||
status = ND_Index_Value_Remove_I( Root_Ptr, index_id, Value_Ptr);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove the first matching value from a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Remove_C( NDT_Root *Root_Ptr, void *Value_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
return( ND_DataStruct_Value_Remove_I( Root_Ptr, Value_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print all the data structure index values */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Print_VI( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, Args_Ptr);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print all the data structure index values */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
|
||
|
||
va_start( user_args, Recursive_Offset);
|
||
|
||
status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print all the data structure index values */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Value_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Out, "Stream descriptor");
|
||
|
||
va_start( user_args, Recursive_Offset);
|
||
|
||
status = ND_Index_Value_Print_VI( Out, Root_Ptr, Index_Id, Recursive_Mode, Recursive_Depth, Recursive_Offset, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print all the data structure values */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Print_VI( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, va_list *User_Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
status = ND_DataStruct_Traverse_I( Root_Ptr, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, User_Args_Ptr);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print all the data structure values */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
|
||
|
||
va_start( user_args, Recursive_Offset);
|
||
|
||
status = ND_DataStruct_Traverse_I( Root_Ptr, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Print all the data structure values */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Stream: Output stream */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Mode: Child or Parent */
|
||
/* (I) Recursive_Depth: Curent recursion depth */
|
||
/* (I) Recursive_Offset: Curent print out offset */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Out, "Stream descriptor");
|
||
|
||
va_start( user_args, Recursive_Offset);
|
||
|
||
|
||
status = ND_DataStruct_Value_Print_VI( Out, Root_Ptr, Recursive_Mode, Recursive_Depth, Recursive_Offset, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Add a new node to a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Add_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr )
|
||
{
|
||
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)) return ND_List_Node_Add( Root_Ptr, Index_Id, Node_Ptr);
|
||
else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id)) return ND_Tree_Node_Add( Root_Ptr, Index_Id, Node_Ptr);
|
||
else
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Add a new node to a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Add_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Node_Ptr, "Node");
|
||
|
||
return( ND_Index_Node_Add_I( Root_Ptr, Index_Id, Node_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove a node from a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Remove_I( NDT_Node *Node_Ptr)
|
||
{
|
||
NDT_Root *root_ptr;
|
||
NDT_Index_Id index_id;
|
||
|
||
|
||
root_ptr = Node_Ptr->Root;
|
||
index_id = Node_Ptr->Index;
|
||
|
||
if( ND_INDEX_TYPE_LIST_IS( root_ptr, index_id)) return ND_List_Node_Remove( Node_Ptr);
|
||
else if( ND_INDEX_TYPE_TREE_IS( root_ptr, index_id))
|
||
{
|
||
NDT_Node **tmp_ptr_ptr;
|
||
|
||
/* On r<>cup<75>re l'adresse du lien entre le noeud <20> supprimer et son p<>re */
|
||
|
||
if( Node_Ptr->Parent)
|
||
{
|
||
/* Cas g<>n<EFBFBD>ral */
|
||
|
||
if( Node_Ptr == Node_Ptr->Parent->Left) tmp_ptr_ptr = &(Node_Ptr->Parent->Left);
|
||
else tmp_ptr_ptr = &(Node_Ptr->Parent->Right);
|
||
}
|
||
else
|
||
{
|
||
/* Cas du noeud racine */
|
||
|
||
tmp_ptr_ptr = NULL;
|
||
}
|
||
|
||
if( Node_Ptr->Right)
|
||
{
|
||
NDT_Node *Right_Node_Ptr = Node_Ptr->Right;
|
||
NDT_Node *Left_Node_Ptr = Node_Ptr->Left;
|
||
NDT_Node *First_Node_Ptr;
|
||
|
||
/*
|
||
On sauve le fils gauche du noeud <20> supprimer dans un pointeur de
|
||
sauvegarde pour pouvoir le r<>cup<75>rer au cas o<> la proc<6F>dure serait
|
||
interrompue (recovery).
|
||
*/
|
||
|
||
root_ptr->Index_Tab[index_id].Save = Left_Node_Ptr;
|
||
|
||
/* On remplace le noeud supprim<69> par son sous-arbre droit */
|
||
|
||
if( !tmp_ptr_ptr) root_ptr->Index_Tab[index_id].Head = root_ptr->Index_Tab[index_id].Tail = Node_Ptr->Right;
|
||
else *tmp_ptr_ptr = Node_Ptr->Right;
|
||
|
||
Right_Node_Ptr->Parent = Node_Ptr->Parent;
|
||
|
||
/* On attache le sous-arbre gauche au premier noeud du sous-arbre droit */
|
||
|
||
if( root_ptr->Index_Tab[index_id].Save)
|
||
{
|
||
First_Node_Ptr = ND_Tree_Node_First_Recursive_Get(Right_Node_Ptr);
|
||
|
||
First_Node_Ptr->Left = root_ptr->Index_Tab[index_id].Save;
|
||
|
||
root_ptr->Index_Tab[index_id].Save->Parent = First_Node_Ptr;
|
||
|
||
root_ptr->Index_Tab[index_id].Save = NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* On remplace le noeud supprim<69> par son sous-arbre gauche */
|
||
|
||
if( !tmp_ptr_ptr) root_ptr->Index_Tab[index_id].Head = root_ptr->Index_Tab[index_id].Tail = Node_Ptr->Left;
|
||
else *tmp_ptr_ptr = Node_Ptr->Left;
|
||
|
||
if( Node_Ptr->Left) Node_Ptr->Left->Parent = Node_Ptr->Parent;
|
||
}
|
||
|
||
root_ptr->Index_Tab[index_id].Node_Number--;
|
||
|
||
/* Pas de mise <20> jour des informations de profondeur : trop co<63>teux */
|
||
|
||
Node_Ptr->Root = NULL;
|
||
Node_Ptr->Index = NDD_INDEX_UNKNOWN;
|
||
Node_Ptr->Left = NULL;
|
||
Node_Ptr->Right = NULL;
|
||
Node_Ptr->Parent = NULL;
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown structure type (%d)", root_ptr->Index_Tab[index_id].Type);
|
||
|
||
return(NDS_ERRAPI);
|
||
}
|
||
|
||
return(NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Remove a node from a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Remove_C( NDT_Node *Node_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Node_Ptr, "Node");
|
||
|
||
return( ND_Index_Node_Remove_I( Node_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the first node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_First_Get_I( NDT_Node **First_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
*First_Node_Ptr_Ptr = NULL;
|
||
|
||
if( ND_INDEX_TYPE_LIST_IS(Root_Ptr, Index_Id)) *First_Node_Ptr_Ptr = (Root_Ptr->Index_Tab)[Index_Id].Head;
|
||
|
||
else if( ND_INDEX_TYPE_TREE_IS(Root_Ptr, Index_Id)) *First_Node_Ptr_Ptr = ND_Tree_Node_First_Recursive_Get( Root_Ptr->Index_Tab[Index_Id].Head);
|
||
|
||
// if(!*First_Node_Ptr_Ptr) return(NDS_KO);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the first node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_First_Get_C( NDT_Node **First_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_Index_Node_First_Get_I( First_Node_Ptr_Ptr, Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the last node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Last_Get_I ( NDT_Node **Last_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
*Last_Node_Ptr_Ptr = NULL;
|
||
|
||
if( ND_INDEX_TYPE_LIST_IS(Root_Ptr, Index_Id)) *Last_Node_Ptr_Ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
|
||
|
||
else if( ND_INDEX_TYPE_TREE_IS(Root_Ptr, Index_Id)) *Last_Node_Ptr_Ptr = ND_Tree_Node_Last_Recursive_Get( Root_Ptr->Index_Tab[Index_Id].Head);
|
||
|
||
// if(!*Last_Node_Ptr_Ptr) return(NDS_KO);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* R<>cup<75>ration du dernier noeud d'une structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine dont on cherche le dernier noeud */
|
||
/* (O) Last_Node : adresse du pointeur sur le premier noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Last_Get_C( NDT_Node **Last_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
return( ND_Index_Node_Last_Get_I( Last_Node_Ptr_Ptr, Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the next node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Next_Get_I ( NDT_Node **Next_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
|
||
{
|
||
if( ND_INDEX_TYPE_LIST_IS( Node_Ptr->Root, Node_Ptr->Index))
|
||
{
|
||
*Next_Node_Ptr_Ptr = Node_Ptr->Right;
|
||
}
|
||
else if( ND_INDEX_TYPE_TREE_IS( Node_Ptr->Root, Node_Ptr->Index))
|
||
{
|
||
if( !Node_Ptr->Right)
|
||
{
|
||
*Next_Node_Ptr_Ptr = ND_Tree_Parent_Next_Recursive_Get(Node_Ptr);
|
||
}
|
||
else
|
||
{
|
||
*Next_Node_Ptr_Ptr = ND_Tree_Node_First_Recursive_Get(Node_Ptr->Right);
|
||
}
|
||
}
|
||
|
||
// if(!*Next_Node_Ptr_Ptr) return(NDS_KO);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the next node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Next_Get_C( NDT_Node **Next_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Node_Ptr, "Node");
|
||
|
||
return( ND_Index_Node_Next_Get_I( Next_Node_Ptr_Ptr, Node_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the previous node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Previous_Get_I( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
|
||
{
|
||
if( ND_INDEX_TYPE_LIST_IS( Node_Ptr->Root, Node_Ptr->Index)) *Prev_Node_Ptr_Ptr = Node_Ptr->Left;
|
||
|
||
if( ND_INDEX_TYPE_TREE_IS( Node_Ptr->Root, Node_Ptr->Index))
|
||
{
|
||
if( !Node_Ptr->Left)
|
||
{
|
||
*Prev_Node_Ptr_Ptr = ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr);
|
||
}
|
||
else
|
||
{
|
||
*Prev_Node_Ptr_Ptr = ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Left);
|
||
}
|
||
}
|
||
|
||
// if( !*Prev_Node_Ptr_Ptr) return( NDS_KO);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the previous node of a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Previous_Get_C( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Node_Ptr, "Node");
|
||
|
||
return( ND_Index_Node_Previous_Get_I( Prev_Node_Ptr_Ptr, Node_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a node from a value in a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Find_VI( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *Args_Ptr)
|
||
{
|
||
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
|
||
{
|
||
*Node_Ptr_Ptr = ND_List_Node_Find( Root_Ptr, Index_Id, Value_Ptr, Args_Ptr);
|
||
}
|
||
else if ( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
|
||
{
|
||
*Node_Ptr_Ptr = ND_Tree_Node_Find( Root_Ptr, Index_Id, Value_Ptr, Args_Ptr);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a node from a value in a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Find_VC( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
status = ND_Index_Node_Find_VI( Node_Ptr_Ptr, Root_Ptr, Index_Id, Value_Ptr, Args_Ptr);
|
||
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a node from a value in a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Find_I( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, ...)
|
||
{
|
||
va_list user_args;
|
||
NDT_Status status;
|
||
|
||
|
||
va_start( user_args, Value_Ptr);
|
||
|
||
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
|
||
{
|
||
*Node_Ptr_Ptr = ND_List_Node_Find( Root_Ptr, Index_Id, Value_Ptr, &user_args);
|
||
status = NDS_OK;
|
||
}
|
||
else if ( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
|
||
{
|
||
*Node_Ptr_Ptr = ND_Tree_Node_Find( Root_Ptr, Index_Id, Value_Ptr, &user_args);
|
||
status = NDS_OK;
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
|
||
status = NDS_KO;
|
||
}
|
||
|
||
va_end( user_args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a node from a value in a data structure index */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Node_Ptr_Ptr: Node pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Node_Find_C( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
va_start( user_args, Value_Ptr);
|
||
|
||
status = ND_Index_Node_Find_VI( Node_Ptr_Ptr, Root_Ptr, Index_Id, Value_Ptr, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a value in a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address found */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Find_VI( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Index_Id new_index;
|
||
NDT_Command new_cmd;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, NDD_CMD_VALUE_FIND, Ref_Value_Ptr);
|
||
if( ND_ERROR(status)) return( status);
|
||
|
||
status = ND_Index_Node_Find_VI( &node_ptr, Root_Ptr, new_index, Ref_Value_Ptr, Args_Ptr);
|
||
if( ND_ERROR(status)) return( status);
|
||
|
||
if( node_ptr != NULL)
|
||
{
|
||
*Value_Ptr_Ptr = node_ptr->Value;
|
||
}
|
||
else
|
||
{
|
||
*Value_Ptr_Ptr = NULL;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a value in a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address found */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Find_VC( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Ref_Value_Ptr, "Ref value");
|
||
|
||
status = ND_DataStruct_Value_Find_VI( Value_Ptr_Ptr, Root_Ptr, Ref_Value_Ptr, Args_Ptr);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a value in a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address found */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Find_I( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
NDT_Index_Id new_index;
|
||
NDT_Command new_cmd;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
va_start( user_args, Ref_Value_Ptr);
|
||
|
||
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, NDD_CMD_VALUE_FIND, Ref_Value_Ptr);
|
||
if( ND_ERROR(status)) return( status);
|
||
|
||
status = ND_Index_Node_Find_VI( &node_ptr, Root_Ptr, new_index, Ref_Value_Ptr, &user_args);
|
||
if( ND_ERROR(status)) return( status);
|
||
|
||
if( node_ptr != NULL)
|
||
{
|
||
*Value_Ptr_Ptr = node_ptr->Value;
|
||
}
|
||
else
|
||
{
|
||
*Value_Ptr_Ptr = NULL;
|
||
}
|
||
|
||
va_end( user_args);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Find a value in a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address found */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Ref_Value_Ptr: Reference value pointer to search */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_DataStruct_Value_Find_C( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list user_args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Ref_Value_Ptr, "Ref value");
|
||
|
||
va_start( user_args, Ref_Value_Ptr);
|
||
|
||
status = ND_DataStruct_Value_Find_VI( Value_Ptr_Ptr, Root_Ptr, Ref_Value_Ptr, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return(status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the root node of a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Data structure pointer address */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Node_Root_Get_I( NDT_Root **Root_Ptr_Ptr, NDT_Node *Node_Ptr)
|
||
{
|
||
*Root_Ptr_Ptr = Node_Ptr->Root;
|
||
|
||
return NDS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Get the root node of a data structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Data structure pointer address */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Node_Root_Get_C( NDT_Root **Root_Ptr_Ptr, NDT_Node *Node_Ptr )
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Node_Ptr, "Node");
|
||
|
||
return( ND_Node_Root_Get_I( Root_Ptr_Ptr, Node_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Allocate a new value */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Value_Alloc_I( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, ...)
|
||
{
|
||
NDT_Status rc;
|
||
va_list user_args;
|
||
|
||
|
||
/* R<>cup<75>ration des arguments pour l'allocation de la valeur */
|
||
|
||
va_start( user_args, Root_Ptr);
|
||
|
||
/* Appel du manager */
|
||
|
||
rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( rc);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Allocate a new value */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Value_Alloc_C( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, ...)
|
||
{
|
||
NDT_Status rc;
|
||
va_list user_args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
/* R<>cup<75>ration des arguments pour l'allocation de la valeur */
|
||
|
||
va_start( user_args, Root_Ptr);
|
||
|
||
/* Appel du manager */
|
||
|
||
rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, &user_args);
|
||
|
||
va_end( user_args);
|
||
|
||
return( rc);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Deallocate a value */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Value_Free_I( NDT_Root *Root_Ptr, void *Value_Ptr)
|
||
{
|
||
return( ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_FREE, Value_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Deallocate a value */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Value_Free_C( NDT_Root *Root_Ptr, void *Value_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
ND_NOT_NULL_CHECK( Value_Ptr, "Value");
|
||
|
||
/* Appel du manager */
|
||
|
||
return( ND_Value_Free_I( Root_Ptr, Value_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a manager command */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Manager_Exec_VI( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
NDT_Manager *manager_ptr;
|
||
|
||
|
||
if( Root_Ptr->Manager_Ptr != NULL)
|
||
{
|
||
manager_ptr = Root_Ptr->Manager_Ptr;
|
||
}
|
||
else
|
||
{
|
||
if( ND_Symbol_Find( (void **)&manager_ptr, Root_Ptr->Manager_Name) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Cant't find manger function");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
status = manager_ptr( Root_Ptr, Index_Id, Node_Ptr, Command, Args_Ptr);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a manager command */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Manager_Exec_VC( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
if( !Root_Ptr->Manager_Ptr || !*(Root_Ptr->Manager_Ptr))
|
||
{
|
||
LG_LOG_ERROR_0( "Undefined function name");
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
status = ND_Manager_Exec_VI( Root_Ptr, Index_Id, Node_Ptr, Command, Args_Ptr);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a manager command */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Manager_Exec_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list args;
|
||
NDT_Manager *manager_ptr;
|
||
|
||
|
||
va_start( args, Command);
|
||
|
||
if( Root_Ptr->Manager_Ptr != NULL)
|
||
{
|
||
manager_ptr = Root_Ptr->Manager_Ptr;
|
||
}
|
||
else
|
||
{
|
||
if( ND_Symbol_Find( (void **)&manager_ptr, Root_Ptr->Manager_Name) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Cant't find manger function");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
status = manager_ptr( Root_Ptr, Index_Id, Node_Ptr, Command, &args);
|
||
|
||
va_end( args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a manager command */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Index_Id: Id of the index */
|
||
/* (I) Node_Ptr: Node pointer */
|
||
/* (I) Command: Manager command */
|
||
/* (I) ...: User args */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Manager_Exec_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, ...)
|
||
{
|
||
NDT_Status status;
|
||
va_list args;
|
||
|
||
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
ND_NOT_NULL_CHECK( Root_Ptr, "Root structure");
|
||
|
||
va_start( args, Command);
|
||
|
||
if( !Root_Ptr->Manager_Ptr || !*(Root_Ptr->Manager_Ptr))
|
||
{
|
||
LG_LOG_ERROR_0( "Undefined function name");
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
status = ND_Manager_Exec_VI( Root_Ptr, Index_Id, Node_Ptr, Command, &args);
|
||
|
||
va_end( args);
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an init handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Pointer adress of the new data structure */
|
||
/* (O) Root_Extra_Size: Pointer on the extra root size */
|
||
/* (I) DataStruct_Name: Name of the data structure */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Handler_Tab: Pointer on the handler tab */
|
||
/* (I) Handler_Init_Name: Init handler function name */
|
||
/* (I) Handler_Init_Ptr: Init handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Init_Exec_I( NDT_Root **Root_Ptr_Ptr, size_t *Root_Extra_Size, NDT_DataStruct_Name Name, NDT_Open_Flag Open_Mode, NDT_Handler *Handler_Tab, NDT_Handler_Name Handler_Init_Name, NDT_Handler_Init *Handler_Init_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Init *handler_init_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_init_ptr, Handler_Init_Name, Handler_Init_Ptr);
|
||
|
||
return( handler_init_ptr( Root_Ptr_Ptr, Root_Extra_Size, Name, Open_Mode, Handler_Tab, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an init handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Pointer adress of the new data structure */
|
||
/* (O) Root_Extra_Size: Pointer on the extra root size */
|
||
/* (I) DataStruct_Name: Name of the data structure */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Handler_Tab: Pointer on the handler tab */
|
||
/* (I) Handler_Init_Name: Init handler function name */
|
||
/* (I) Handler_Init_Ptr: Init handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Init_Exec_C( NDT_Root **Root_Ptr_Ptr, size_t *Root_Extra_Size, NDT_DataStruct_Name Name, NDT_Open_Flag Open_Mode, NDT_Handler *Handler_Tab, NDT_Handler_Name Handler_Init_Name, NDT_Handler_Init *Handler_Init_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Init_Name, Handler_Init_Ptr);
|
||
|
||
return( ND_Handler_Init_Exec_I( Root_Ptr_Ptr, Root_Extra_Size, Name, Open_Mode, Handler_Tab, Handler_Init_Name, Handler_Init_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an alloc handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Memory_Ptr_Ptr: Memory pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) Handler_Alloc_Name: Alloc handler function name */
|
||
/* (I) Handler_Alloc_Ptr: Alloc handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Alloc_Exec_I( void **Memory_Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, NDT_Handler_Name Handler_Alloc_Name, NDT_Handler_Alloc *Handler_Alloc_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Alloc *handler_alloc_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_alloc_ptr, Handler_Alloc_Name, Handler_Alloc_Ptr);
|
||
|
||
return( handler_alloc_ptr( Memory_Ptr_Ptr, Root_Ptr, Size, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an alloc handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Memory_Ptr_Ptr: Memory pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) Handler_Alloc_Name: Alloc handler function name */
|
||
/* (I) Handler_Alloc_Ptr: Alloc handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Alloc_Exec_C( void **Memory_Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, NDT_Handler_Name Handler_Alloc_Name, NDT_Handler_Alloc *Handler_Alloc_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Alloc_Name, Handler_Alloc_Ptr);
|
||
|
||
return( ND_Handler_Alloc_Exec_I( Memory_Ptr_Ptr, Root_Ptr, Size, Handler_Alloc_Name, Handler_Alloc_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a free handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Memory_Ptr: Memory pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Handler_Free_Name: Free handler function name */
|
||
/* (I) Handler_Free_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Free_Exec_I( void *Memory_Ptr, NDT_Root *Root_Ptr, NDT_Handler_Name Handler_Free_Name, NDT_Handler_Free *Handler_Free_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Free *handler_free_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_free_ptr, Handler_Free_Name, Handler_Free_Ptr);
|
||
|
||
return( handler_free_ptr( Memory_Ptr, Root_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a free handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Memory_Ptr: Memory pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Handler_Free_Name: Free handler function name */
|
||
/* (I) Handler_Free_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Free_Exec_C( void *Memory_Ptr, NDT_Root *Root_Ptr, NDT_Handler_Name Handler_Free_Name, NDT_Handler_Free *Handler_Free_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Free_Name, Handler_Free_Ptr);
|
||
|
||
return( ND_Handler_Free_Exec_I( Memory_Ptr, Root_Ptr, Handler_Free_Name, Handler_Free_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an open handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Handler_Open_Name: Free handler function name */
|
||
/* (I) Handler_Open_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Open_Exec_I( NDT_Root *Root_Ptr, NDT_Open_Flag Open_Mode, NDT_Handler_Name Handler_Open_Name, NDT_Handler_Open *Handler_Open_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Open *handler_open_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_open_ptr, Handler_Open_Name, Handler_Open_Ptr);
|
||
|
||
return( handler_open_ptr( Root_Ptr, Open_Mode, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an open handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Handler_Open_Name: Free handler function name */
|
||
/* (I) Handler_Open_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Open_Exec_C( NDT_Root *Root_Ptr, NDT_Open_Flag Open_Mode, NDT_Handler_Name Handler_Open_Name, NDT_Handler_Open *Handler_Open_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Open_Name, Handler_Open_Ptr);
|
||
|
||
return( ND_Handler_Open_Exec_I( Root_Ptr, Open_Mode, Handler_Open_Name, Handler_Open_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a close handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Close_Mode: Close mode */
|
||
/* (I) Handler_Close_Name: Free handler function name */
|
||
/* (I) Handler_Close_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Close_Exec_I( NDT_Root *Root_Ptr, NDT_Close_Flag Close_Mode, NDT_Handler_Name Handler_Close_Name, NDT_Handler_Close *Handler_Close_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Close *handler_close_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_close_ptr, Handler_Close_Name, Handler_Close_Ptr);
|
||
|
||
return( handler_close_ptr( Root_Ptr, Close_Mode, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a close handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Close_Mode: Close mode */
|
||
/* (I) Handler_Close_Name: Free handler function name */
|
||
/* (I) Handler_Close_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Close_Exec_C( NDT_Root *Root_Ptr, NDT_Close_Flag Close_Mode, NDT_Handler_Name Handler_Close_Name, NDT_Handler_Close *Handler_Close_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Close_Name, Handler_Close_Ptr);
|
||
|
||
return( ND_Handler_Close_Exec_I( Root_Ptr, Close_Mode, Handler_Close_Name, Handler_Close_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an info handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Offset: Print line offset */
|
||
/* (I) Handler_Info_Name: Free handler function name */
|
||
/* (I) Handler_Info_Ptr: Free handler function pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Info_Exec_I( NDT_Root *Root_Ptr, NDT_Recursive_Offset Recursive_Offset, NDT_Handler_Name Handler_Info_Name, NDT_Handler_Info *Handler_Info_Ptr)
|
||
{
|
||
NDT_Handler_Info *handler_info_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_info_ptr, Handler_Info_Name, Handler_Info_Ptr);
|
||
|
||
return( handler_info_ptr( Root_Ptr, Recursive_Offset));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an info handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Offset: Print line offset */
|
||
/* (I) Handler_Info_Name: Free handler function name */
|
||
/* (I) Handler_Info_Ptr: Free handler function pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Info_Exec_C( NDT_Root *Root_Ptr, NDT_Recursive_Offset Recursive_Offset, NDT_Handler_Name Handler_Info_Name, NDT_Handler_Info *Handler_Info_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Info_Name, Handler_Info_Ptr);
|
||
|
||
return( ND_Handler_Info_Exec_I( Root_Ptr, Recursive_Offset, Handler_Info_Name, Handler_Info_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a lock handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Open_Mode: Lock mode */
|
||
/* (O) Locked_Ptr: Locked flag */
|
||
/* (I) Handler_Lock_Name: Free handler function name */
|
||
/* (I) Handler_Lock_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Lock_Exec_I( NDT_Root *Root_Ptr, NDT_Lock_Flag Lock_Mode, bool *Locked_Ptr, NDT_Handler_Name Handler_Lock_Name, NDT_Handler_Lock *Handler_Lock_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Lock *handler_lock_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_lock_ptr, Handler_Lock_Name, Handler_Lock_Ptr);
|
||
|
||
return( handler_lock_ptr( Root_Ptr, Lock_Mode, Locked_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a lock handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Open_Mode: Lock mode */
|
||
/* (O) Locked_Ptr: Locked flag */
|
||
/* (I) Handler_Lock_Name: Free handler function name */
|
||
/* (I) Handler_Lock_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Lock_Exec_C( NDT_Root *Root_Ptr, NDT_Lock_Flag Lock_Mode, bool *Locked_Ptr, NDT_Handler_Name Handler_Lock_Name, NDT_Handler_Lock *Handler_Lock_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Lock_Name, Handler_Lock_Ptr);
|
||
|
||
return( ND_Handler_Lock_Exec_I( Root_Ptr, Lock_Mode, Locked_Ptr, Handler_Lock_Name, Handler_Lock_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an unlock handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Handler_Unlock_Name: Free handler function name */
|
||
/* (I) Handler_Unlock_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Unlock_Exec_I( NDT_Root *Root_Ptr, NDT_Handler_Name Handler_Unlock_Name, NDT_Handler_Unlock *Handler_Unlock_Ptr, void *User_Ptr)
|
||
{
|
||
NDT_Handler_Unlock *handler_unlock_ptr;
|
||
|
||
|
||
ND_HANDLER_SYMBOL_FIND( handler_unlock_ptr, Handler_Unlock_Name, Handler_Unlock_Ptr);
|
||
|
||
return( handler_unlock_ptr( Root_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an unlock handler function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Handler_Unlock_Name: Free handler function name */
|
||
/* (I) Handler_Unlock_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Unlock_Exec_C( NDT_Root *Root_Ptr, NDT_Handler_Name Handler_Unlock_Name, NDT_Handler_Unlock *Handler_Unlock_Ptr, void *User_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Handler_Unlock_Name, Handler_Unlock_Ptr);
|
||
|
||
return( ND_Handler_Unlock_Exec_I( Root_Ptr, Handler_Unlock_Name, Handler_Unlock_Ptr, User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an allocator function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) Allocator_Name: Value allocator function name */
|
||
/* (I) Allocator_Ptr: Value allocator function pointer */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* to be deleted */
|
||
NDT_Status ND_Allocator_Exec_I( void **Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, NDT_Allocator_Name Allocator_Name, NDT_Allocator *Allocator_Ptr, void *Data_Ptr)
|
||
{
|
||
NDT_Allocator *allocator_ptr;
|
||
|
||
|
||
if( Allocator_Ptr != NULL)
|
||
{
|
||
allocator_ptr = Allocator_Ptr;
|
||
}
|
||
else
|
||
{
|
||
if( ND_Symbol_Find( (void **)&allocator_ptr, Allocator_Name) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Cant't find allocator function");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
return( allocator_ptr( Ptr_Ptr, Root_Ptr, Size, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute an allocator function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Value_Ptr_Ptr: Value pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) Allocator_Name: Value allocator function name */
|
||
/* (I) Allocator_Ptr: Value allocator function pointer */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* to be deleted */
|
||
NDT_Status ND_Allocator_Exec_C( void **Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, NDT_Allocator_Name Allocator_Name, NDT_Allocator *Allocator_Ptr, void *Data_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
ND_HANDLER_NOT_NULL_CHECK( Allocator_Name, Allocator_Ptr);
|
||
|
||
return( ND_Allocator_Exec_I( Ptr_Ptr, Root_Ptr, Size, Allocator_Name, Allocator_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a deallocator function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Allocator_Name: Value deallocator function name */
|
||
/* (I) Allocator_Ptr: Value deallocator function pointer */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* to be deleted */
|
||
NDT_Status ND_Deallocator_Exec_I( void *Ptr, NDT_Root *Root_Ptr, NDT_Deallocator_Name Deallocator_Name, NDT_Deallocator *Deallocator_Ptr, void *Data_Ptr)
|
||
{
|
||
NDT_Deallocator *deallocator_ptr;
|
||
|
||
|
||
if( Deallocator_Ptr != NULL)
|
||
{
|
||
deallocator_ptr = Deallocator_Ptr;
|
||
}
|
||
else
|
||
{
|
||
if( ND_Symbol_Find( (void **)&deallocator_ptr, Deallocator_Name) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Cant't find deallocator function");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
return( deallocator_ptr( Ptr, Root_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Execute a deallocator function */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Value_Ptr: Value pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Allocator_Name: Value deallocator function name */
|
||
/* (I) Allocator_Ptr: Value deallocator function pointer */
|
||
/* (I) Data_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* to be deleted */
|
||
NDT_Status ND_Deallocator_Exec_C( void *Ptr, NDT_Root *Root_Ptr, NDT_Deallocator_Name Deallocator_Name, NDT_Deallocator *Deallocator_Ptr, void *Data_Ptr)
|
||
{
|
||
ND_LIBNODE_OPEN_CHECK();
|
||
|
||
if( ( Deallocator_Name == NULL) && ( Deallocator_Ptr == NULL))
|
||
{
|
||
LG_LOG_ERROR_0( "Undefined function name");
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
return( ND_Deallocator_Exec_I( Ptr, Root_Ptr, Deallocator_Name, Deallocator_Ptr, Data_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/*----------------------------------------------------------------------------*/
|
||
/* PRIVATE FUNCTIONS */
|
||
/*----------------------------------------------------------------------------*/
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Init handler: */
|
||
/* - Return extra root size */
|
||
/* - Update handler tab */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root_Ptr_Ptr: Pointer adress of the new data structure */
|
||
/* (O) Root_Extra_Size: Pointer on the extra root size */
|
||
/* (I) DataStruct_Name: Name of the data structure */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Handler_Tab: Pointer on the handler tab */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Init_Default( NDT_Root **Root_Ptr_Ptr, size_t *Root_Extra_Size, NDT_DataStruct_Name Name, NDT_Open_Flag Open_Mode, NDT_Handler *Handler_Tab, void *User_Ptr)
|
||
{
|
||
*Root_Extra_Size = 0L;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Default alloc handler: */
|
||
/* malloc() function wrapper with NDT_Status return status */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Memory_Ptr_Ptr: Memory pointer address */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Size: Allocation size */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Alloc_Default( void **Memory_Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, void *User_Ptr)
|
||
{
|
||
*Memory_Ptr_Ptr = malloc( Size);
|
||
|
||
|
||
if( !*Memory_Ptr_Ptr) return( NDS_ERRMEM);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Default free handler: */
|
||
/* free() function wrapper with NDT_Status return status */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Memory_Ptr: Memory pointer */
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Free_Default( void *Memory_Ptr, NDT_Root *Root_Ptr, void *User_Ptr)
|
||
{
|
||
if( !Memory_Ptr) return( NDS_ERRAPI);
|
||
|
||
free( Memory_Ptr);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Default open handler */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Open_Mode: Open mode */
|
||
/* (I) Handler_Open_Name: Free handler function name */
|
||
/* (I) Handler_Open_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Open_Default( NDT_Root *Root_Ptr, NDT_Open_Flag Open_Mode, void *User_Ptr)
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Default close handler */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Close_Mode: Close mode */
|
||
/* (I) Handler_Close_Name: Free handler function name */
|
||
/* (I) Handler_Close_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Close_Default( NDT_Root *Root_Ptr, NDT_Close_Flag Close_Mode, void *User_Ptr)
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Default info handler */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Recursive_Offset: Print line offset */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Info_Default( NDT_Root *Root_Ptr, NDT_Recursive_Offset Recursive_Offset)
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Default lock handler */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Open_Mode: Lock mode */
|
||
/* (O) Locked_Ptr: Locked flag */
|
||
/* (I) Handler_Lock_Name: Free handler function name */
|
||
/* (I) Handler_Lock_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Lock_Default( NDT_Root *Root_Ptr, NDT_Lock_Flag Lock_Mode, bool *Locked_Ptr, void *User_Ptr)
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Defalt unlock handler */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root_Ptr: Data structure pointer */
|
||
/* (I) Handler_Unlock_Name: Free handler function name */
|
||
/* (I) Handler_Unlock_Ptr: Free handler function pointer */
|
||
/* (I) User_Ptr: User pointer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Handler_Unlock_Default( NDT_Root *Root_Ptr, void *User_Ptr)
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Symbol Lookup */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Symbol_Find( void **Ptr_Ptr, const char *Symbol_Name)
|
||
{
|
||
#if !defined(_WIN32)
|
||
NDT_Symbol *Symbol_Ptr;
|
||
|
||
|
||
/* Recherche du symbole dans la table des symboles locale */
|
||
|
||
Symbol_Ptr = NDG_Base.Symbol_First_Ptr;
|
||
|
||
while( Symbol_Ptr)
|
||
{
|
||
if( !strcmp( Symbol_Ptr->Name, Symbol_Name))
|
||
{
|
||
*Ptr_Ptr = Symbol_Ptr->Ptr;
|
||
return( NDS_OK);
|
||
}
|
||
else
|
||
{
|
||
Symbol_Ptr = Symbol_Ptr->Next;
|
||
}
|
||
}
|
||
|
||
|
||
/* Si le symbole n'a pas <20>t<EFBFBD> trouv<75>e dans la table des symboles locale, on l'y ajoute */
|
||
|
||
if( ( *Ptr_Ptr = dlsym( NDG_Base.DL_Ptr, (const char *)Symbol_Name)) == NULL)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to find: [%s] in symbol table: (%s)", Symbol_Name, dlerror());
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
Symbol_Ptr = (NDT_Symbol *)malloc( sizeof( NDT_Symbol));
|
||
if( Symbol_Ptr == NULL)
|
||
{
|
||
LG_LOG_ERROR_0( "No more memory");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
else
|
||
{
|
||
Symbol_Ptr->Name = strdup (Symbol_Name);
|
||
Symbol_Ptr->Ptr = *Ptr_Ptr;
|
||
Symbol_Ptr->Next = NDG_Base.Symbol_First_Ptr;
|
||
|
||
NDG_Base.Symbol_First_Ptr = Symbol_Ptr;
|
||
}
|
||
#endif
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Allocation d'un noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de la structure */
|
||
/* (O) Node : adresse du pointeur sur le nouveau noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Node_Alloc( NDT_Root *Root_Ptr, NDT_Node **Node_Ptr_Ptr )
|
||
{
|
||
NDT_Status rc;
|
||
|
||
|
||
rc = ND_Allocator_Exec_I( (void **)Node_Ptr_Ptr, Root_Ptr, sizeof(NDT_Node), Root_Ptr->Allocator_Name, Root_Ptr->Allocator_Ptr, Root_Ptr->User_Ptr);
|
||
if( ND_ERROR( rc)) return( rc);
|
||
|
||
(*Node_Ptr_Ptr)->Root = NULL;
|
||
(*Node_Ptr_Ptr)->Index = NDD_INDEX_UNKNOWN;
|
||
(*Node_Ptr_Ptr)->Parent = NULL;
|
||
(*Node_Ptr_Ptr)->Left = NULL;
|
||
(*Node_Ptr_Ptr)->Right = NULL;
|
||
(*Node_Ptr_Ptr)->Value = NULL;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* D<>sallocation d'un noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root: pointeur sur la racine de la structure */
|
||
/* (I) Node : pointeur sur le noeud <20> d<>truire */
|
||
/*----------------------------------------------------------------------------*/
|
||
NDT_Status ND_Node_Free( NDT_Root *Root_Ptr, NDT_Node *Node_Ptr)
|
||
{
|
||
return( ND_Deallocator_Exec_I( Node_Ptr, Root_Ptr, Root_Ptr->Deallocator_Name, Root_Ptr->Deallocator_Ptr, Root_Ptr->User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Cr<43>ation d'une nouvelle structure de donn<6E>es */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
|
||
/* (I) Type: type de la structure.de donn<6E>es (liste ou arbre binaire) */
|
||
/* (I) Allocator: pointeur vers la fonction d'allocation */
|
||
/* (I) Deallocator: pointeur vers la fonction de d<>sallocation */
|
||
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
|
||
/* (I) Own_Value : indique si la structure est propri<72>taire de ses valeurs */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Index_Clear( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_UNKNOWN;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = NULL;
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = NULL;
|
||
Root_Ptr->Index_Tab[Index_Id].Save = NULL;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG;
|
||
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Allocation d'une racine de structure de donn<6E>es */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (O) New_Root: adresse du pointeur sur la nouvelle racine */
|
||
/* (I) Type: type de la structure de donn<6E>es */
|
||
/* (I) Allocator: pointeur vers la fonction d'allocation */
|
||
/* (I) Deallocator: pointeur vers la fonction de d<>sallocation */
|
||
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
// NDT_Status ND_Node_Root_Alloc( NDT_Root **Root_Ptr_Ptr, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, char *Manager_Name, NDT_Manager *Manager_Ptr, char *Allocator_Name, NDT_Allocator *Allocator_Ptr, char *Deallocator_Name, NDT_Deallocator *Deallocator_Ptr, short Own_Value, void *Data_Ptr)
|
||
|
||
NDT_Status ND_Node_Root_Alloc( NDT_Root **Root_Ptr_Ptr, NDT_DataStruct_Name Name, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Handler *Handler_Tab, size_t Root_Extra_Size, short Own_Value, void *User_Ptr)
|
||
{
|
||
NDT_Status status;
|
||
size_t root_size;
|
||
NDT_Index_Id index_id;
|
||
|
||
|
||
root_size = sizeof( NDT_Root) + sizeof(NDT_Index) * (Index_Nb - 1) + Root_Extra_Size;
|
||
|
||
if( ( status = ND_Allocator_Exec_I( (void **)Root_Ptr_Ptr, NULL, root_size, Handler_Tab[ NDD_HANDLER_ID_ALLOC].Name, (NDT_Allocator *)Handler_Tab[ NDD_HANDLER_ID_ALLOC].Ptr, User_Ptr)) != NDS_OK)
|
||
{
|
||
return( status);
|
||
}
|
||
|
||
|
||
ND_STRCPY( ( *Root_Ptr_Ptr)->Name, Name, NDD_DATASTRUCT_NAME_SIZE);
|
||
|
||
( *Root_Ptr_Ptr)->Root_Size = root_size;
|
||
|
||
memcpy( &( ( *Root_Ptr_Ptr)->Handler_Tab), Handler_Tab, NDD_HANDLER_TAB_SIZE);
|
||
|
||
|
||
/* To be removed... */
|
||
ND_STRCPY( ( *Root_Ptr_Ptr)->Manager_Name, ( *Root_Ptr_Ptr)->Handler_Tab[ NDD_HANDLER_ID_MANAGER].Name, NDD_HANDLER_NAME_SIZE);
|
||
( *Root_Ptr_Ptr)->Manager_Ptr = (NDT_Manager *)( *Root_Ptr_Ptr)->Handler_Tab[ NDD_HANDLER_ID_MANAGER].Ptr;
|
||
|
||
ND_STRCPY( ( *Root_Ptr_Ptr)->Allocator_Name, ( *Root_Ptr_Ptr)->Handler_Tab[ NDD_HANDLER_ID_ALLOC].Name, NDD_HANDLER_NAME_SIZE);
|
||
( *Root_Ptr_Ptr)->Allocator_Ptr = (NDT_Allocator *)( *Root_Ptr_Ptr)->Handler_Tab[ NDD_HANDLER_ID_ALLOC].Ptr;
|
||
|
||
ND_STRCPY( ( *Root_Ptr_Ptr)->Deallocator_Name, ( *Root_Ptr_Ptr)->Handler_Tab[ NDD_HANDLER_ID_FREE].Name, NDD_HANDLER_NAME_SIZE);
|
||
( *Root_Ptr_Ptr)->Deallocator_Ptr = (NDT_Deallocator *)( *Root_Ptr_Ptr)->Handler_Tab[ NDD_HANDLER_ID_FREE].Ptr;
|
||
|
||
/*
|
||
if( strlen( Manager_Name) > NDD_MANAGER_NAME_LEN_MAX) return( NDS_ERRAPI);
|
||
strcpy( ( *Root_Ptr_Ptr)->Manager_Name, Manager_Name);
|
||
( *Root_Ptr_Ptr)->Manager_Ptr = Manager_Ptr;
|
||
|
||
if( strlen( Allocator_Name) > NDD_ALLOCATOR_NAME_LEN_MAX) return( NDS_ERRAPI);
|
||
strcpy( ( *Root_Ptr_Ptr)->Allocator_Name, Allocator_Name);
|
||
( *Root_Ptr_Ptr)->Allocator_Ptr = Allocator_Ptr;
|
||
|
||
if( strlen( Deallocator_Name) > NDD_DEALLOCATOR_NAME_LEN_MAX) return( NDS_ERRAPI);
|
||
strcpy( ( *Root_Ptr_Ptr)->Deallocator_Name, Deallocator_Name);
|
||
( *Root_Ptr_Ptr)->Deallocator_Ptr = Deallocator_Ptr;
|
||
*/
|
||
|
||
( *Root_Ptr_Ptr)->Own_Value = Own_Value;
|
||
( *Root_Ptr_Ptr)->User_Ptr = User_Ptr;
|
||
|
||
( *Root_Ptr_Ptr)->Index_Nb = Index_Nb;
|
||
( *Root_Ptr_Ptr)->Index_Open_Count = 0;
|
||
|
||
for( index_id = 0; index_id < Index_Nb; index_id++)
|
||
{
|
||
if( ( Type_Ptr[index_id] & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_OPENED)
|
||
{
|
||
status = ND_Index_Open_I( *Root_Ptr_Ptr, index_id, Type_Ptr[index_id]);
|
||
if( ND_ERROR( status)) return( status);
|
||
}
|
||
else
|
||
{
|
||
if( ( status = ND_Index_Clear( *Root_Ptr_Ptr, index_id)) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Index cleaning error");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
( *Root_Ptr_Ptr)->Index_Tab[index_id].Type = NDD_INDEX_STATUS_CLOSED;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* D<>sallocation de la racine d'une structure de donn<6E>e */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine <20> d<>truire */
|
||
/*----------------------------------------------------------------------------*/
|
||
NDT_Status ND_Node_Root_Free( NDT_Root *Root_Ptr)
|
||
{
|
||
return( ND_Deallocator_Exec_I( Root_Ptr, NULL, Root_Ptr->Deallocator_Name, Root_Ptr->Deallocator_Ptr, Root_Ptr->User_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Ajout d'un noeud <20> une liste cha<68>n<EFBFBD>e */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de la liste */
|
||
/* (I) New_Node : pointeur sur le noeud <20> ajouter */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_List_Node_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *New_Node_Ptr)
|
||
{
|
||
/* Ajout dans une liste tri<72>e */
|
||
|
||
if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
NDT_Node *node_ptr;
|
||
NDT_Status rc;
|
||
|
||
|
||
New_Node_Ptr->Root = Root_Ptr;
|
||
New_Node_Ptr->Index = Index_Id;
|
||
New_Node_Ptr->Parent = New_Node_Ptr->Left = New_Node_Ptr->Right = NULL;
|
||
|
||
/*
|
||
Une liste tri<72>e peut <20>tre orient<6E>e de 2 mani<6E>res :
|
||
|
||
- FIFO : un noeud sera ins<6E>r<EFBFBD> APRES un noeud de m<>me valeur (par d<>faut)
|
||
- FILO : un noeud sera ins<6E>r<EFBFBD> AVANT un noeud de m<>me valeur
|
||
*/
|
||
|
||
if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id))
|
||
{
|
||
/* Pour une liste tri<72>e orient<6E>e FILO, on parcourt la liste en sens normal */
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
while( node_ptr)
|
||
{
|
||
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, node_ptr->Value, NULL);
|
||
|
||
if(rc == NDS_GREATER)
|
||
node_ptr = node_ptr->Right;
|
||
else
|
||
{
|
||
/* On ins<6E>re avant le noeud courant si le nouveau noeud est de valeur inf<6E>rieure ou <20>gale */
|
||
|
||
New_Node_Ptr->Left = node_ptr->Left;
|
||
New_Node_Ptr->Right = node_ptr;
|
||
|
||
if(!node_ptr->Left) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
|
||
else node_ptr->Left->Right = New_Node_Ptr;
|
||
|
||
node_ptr->Left = New_Node_Ptr;
|
||
node_ptr = NULL;
|
||
}
|
||
}
|
||
|
||
/* Insertion en queue de liste si le noeud n'a pas <20>t<EFBFBD> ins<6E>r<EFBFBD> */
|
||
|
||
if(!New_Node_Ptr->Left && !New_Node_Ptr->Right)
|
||
{
|
||
if( !Root_Ptr->Index_Tab[Index_Id].Tail) Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
|
||
else
|
||
{
|
||
Root_Ptr->Index_Tab[Index_Id].Tail->Right = New_Node_Ptr;
|
||
New_Node_Ptr->Left = Root_Ptr->Index_Tab[Index_Id].Tail;
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* Pour une liste tri<72>e orient<6E>e FIFO, on parcourt la liste dans le sens inverse */
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
|
||
while( node_ptr)
|
||
{
|
||
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, node_ptr->Value, NULL);
|
||
|
||
/* On ins<6E>re apr<70>s le noeud courant si le nouveau noeud est de valeur strictement sup<75>rieure ou <20>gale */
|
||
|
||
if( rc == NDS_LOWER) node_ptr = node_ptr->Left;
|
||
else
|
||
{
|
||
New_Node_Ptr->Left = node_ptr;
|
||
New_Node_Ptr->Right = node_ptr->Right;
|
||
|
||
if( !node_ptr->Right) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
|
||
else node_ptr->Right->Left = New_Node_Ptr;
|
||
|
||
node_ptr->Right = New_Node_Ptr;
|
||
node_ptr = NULL;
|
||
}
|
||
}
|
||
|
||
/* Insertion en t<>te de liste si le noeud n'a pas <20>t<EFBFBD> ins<6E>r<EFBFBD> */
|
||
|
||
if( !New_Node_Ptr->Left && !New_Node_Ptr->Right)
|
||
{
|
||
if( !Root_Ptr->Index_Tab[Index_Id].Head) Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
|
||
else
|
||
{
|
||
Root_Ptr->Index_Tab[Index_Id].Head->Left = New_Node_Ptr;
|
||
New_Node_Ptr->Right = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
|
||
}
|
||
}
|
||
}
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
else
|
||
{
|
||
/* FIFO = ajout en queue de liste */
|
||
|
||
if( ND_INDEX_SUBTYPE_FIFO_IS( Root_Ptr, Index_Id))
|
||
{
|
||
New_Node_Ptr->Root = Root_Ptr;
|
||
New_Node_Ptr->Index = Index_Id;
|
||
New_Node_Ptr->Parent = NULL;
|
||
New_Node_Ptr->Left = Root_Ptr->Index_Tab[Index_Id].Tail;
|
||
New_Node_Ptr->Right = NULL;
|
||
|
||
if( !Root_Ptr->Index_Tab[Index_Id].Head) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
|
||
else Root_Ptr->Index_Tab[Index_Id].Tail->Right = New_Node_Ptr;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
/* FILO = ajout en t<>te de liste */
|
||
|
||
if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id))
|
||
{
|
||
|
||
New_Node_Ptr->Root = Root_Ptr;
|
||
New_Node_Ptr->Index = Index_Id;
|
||
New_Node_Ptr->Parent = NULL;
|
||
New_Node_Ptr->Left = NULL;
|
||
New_Node_Ptr->Right = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
if( !Root_Ptr->Index_Tab[Index_Id].Tail) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
|
||
else Root_Ptr->Index_Tab[Index_Id].Head->Left = New_Node_Ptr;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_1( "Unknown list type: (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Ajout d'une nouvelle valeur <20> une liste */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de la liste */
|
||
/* (I) Value : pointeur sur la valeur <20> ajouter */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_List_Value_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
rc = ND_Node_Alloc( Root_Ptr, &node_ptr);
|
||
if( ND_ERROR(rc)) return(rc);
|
||
|
||
node_ptr->Value = Value_Ptr;
|
||
|
||
// return ND_List_Node_Add( Root, Node);
|
||
|
||
rc = ND_List_Node_Add( Root_Ptr, Index_Id, node_ptr);
|
||
if( ND_ERROR(rc))
|
||
{
|
||
return( rc);
|
||
}
|
||
else
|
||
{
|
||
return( ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_ADD, Value_Ptr, NULL));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Ajout d'un noeud <20> un arbre binaire */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de l'arbre */
|
||
/* (I) Value : pointeur sur la valeur <20> ajouter */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Tree_Value_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
rc = ND_Node_Alloc( Root_Ptr, &node_ptr);
|
||
if( ND_ERROR(rc)) return(rc);
|
||
|
||
node_ptr->Value = Value_Ptr;
|
||
|
||
// return ND_Tree_Node_Add( Root, Node);
|
||
|
||
rc = ND_Tree_Node_Add( Root_Ptr, Index_Id, node_ptr);
|
||
if( ND_ERROR(rc))
|
||
{
|
||
return( rc);
|
||
}
|
||
else
|
||
{
|
||
return ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_ADD, Value_Ptr, NULL);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Recherche une valeur dans une liste et retourne le noeud correspondant */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de la liste */
|
||
/* (I) Value : pointeur sur la valeur <20> rechercher */
|
||
/* (I) Data : pointeur de donn<6E>es */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Node *ND_List_Node_Find( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *User_Args_Ptr)
|
||
{
|
||
NDT_Node *node_ptr;
|
||
NDT_Status rc;
|
||
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
/* Pour les listes tri<72>es, la recherche peut <20>tre optimis<69>e */
|
||
|
||
while( node_ptr)
|
||
{
|
||
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, Value_Ptr, node_ptr->Value, User_Args_Ptr);
|
||
|
||
switch( rc)
|
||
{
|
||
case NDS_EQUAL:
|
||
{
|
||
return( node_ptr);
|
||
}
|
||
|
||
case NDS_LOWER:
|
||
{
|
||
/* Ce n'est pas a peine de continuer car on a d<>j<EFBFBD> d<>pass<73> la valeur recherch<63>e */
|
||
|
||
return( NULL);
|
||
}
|
||
|
||
case NDS_GREATER:
|
||
{
|
||
node_ptr = node_ptr->Right;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* Pour les listes non tri<72>es, il faut parcourir toute la liste */
|
||
|
||
while( node_ptr && ( ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, Value_Ptr, node_ptr->Value, User_Args_Ptr) != NDS_EQUAL))
|
||
{
|
||
node_ptr = node_ptr->Right;
|
||
}
|
||
}
|
||
|
||
return( node_ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de l'abre */
|
||
/* (I) Value : pointeur sur la valeur <20> rechercher */
|
||
/* (I) Data : pointeur de donn<6E>es */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------ Recursive Kernel ----------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Node_Recursive_Find( NDT_Node *Node_Ptr, void *Value_Ptr, va_list *User_Args_Ptr)
|
||
{
|
||
NDT_Status answer;
|
||
|
||
|
||
if( !Node_Ptr) return(NULL);
|
||
|
||
answer = ND_Manager_Exec_I( Node_Ptr->Root, Node_Ptr->Index, Node_Ptr, NDD_CMD_VALUE_COMP, Value_Ptr, Node_Ptr->Value, User_Args_Ptr);
|
||
|
||
/* Noeud trouv<75> */
|
||
|
||
if( answer == NDS_EQUAL) return(Node_Ptr);
|
||
|
||
/* Continuation de la recherche par appel r<>cursif */
|
||
|
||
if( answer == NDS_LOWER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Left, Value_Ptr, User_Args_Ptr));
|
||
|
||
if( answer == NDS_GREATER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Right, Value_Ptr, User_Args_Ptr));
|
||
|
||
return( NULL);
|
||
}
|
||
|
||
|
||
|
||
/*-------------------------------- main body -------------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Node_Find( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *User_Args_Ptr)
|
||
{
|
||
return( ND_Tree_Node_Recursive_Find( Root_Ptr->Index_Tab[Index_Id].Head, Value_Ptr, User_Args_Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Recherche du premier noeud parent situ<74> apr<70>s */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Parent_Next_Recursive_Get( NDT_Node *Node_Ptr)
|
||
{
|
||
if( !Node_Ptr->Parent) return( NULL);
|
||
|
||
if( Node_Ptr == Node_Ptr->Parent->Right) return( ND_Tree_Parent_Next_Recursive_Get( Node_Ptr->Parent));
|
||
|
||
return( Node_Ptr->Parent);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Recherche du premier noeud parent situ<74> avant */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Parent_Previous_Recursive_Get( NDT_Node *Node_Ptr)
|
||
{
|
||
if( !Node_Ptr->Parent) return( NULL);
|
||
|
||
if( Node_Ptr == Node_Ptr->Parent->Left) return( ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr->Parent));
|
||
|
||
return( Node_Ptr->Parent);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Supprime le noeud d'une liste */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud <20> supprimer */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_List_Node_Remove( NDT_Node *Node_Ptr)
|
||
{
|
||
if( !Node_Ptr->Left) Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Head = Node_Ptr->Right;
|
||
else Node_Ptr->Left->Right = Node_Ptr->Right;
|
||
|
||
if( !Node_Ptr->Right) Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Tail = Node_Ptr->Left;
|
||
else Node_Ptr->Right->Left = Node_Ptr->Left;
|
||
|
||
Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Node_Number--;
|
||
|
||
Node_Ptr->Root = NULL;
|
||
Node_Ptr->Index = NDD_INDEX_UNKNOWN;
|
||
Node_Ptr->Left = NULL;
|
||
Node_Ptr->Right = NULL;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Conversion d'un arbre en liste cha<68>n<EFBFBD>e */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine du la structure <20> convertir */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------- Recursive Kernel ---------------------------*/
|
||
|
||
NDT_Status ND_List_Recursive_Make( NDT_Node *Node_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
NDT_Node *right_node_ptr;
|
||
|
||
|
||
if( !Node_Ptr) return NDS_OK;
|
||
|
||
if( ND_List_Recursive_Make( Node_Ptr->Left, Root_Ptr, Index_Id) != NDS_OK) return NDS_KO;
|
||
|
||
right_node_ptr = Node_Ptr->Right;
|
||
|
||
if( ND_List_Node_Add( Root_Ptr, Index_Id, Node_Ptr) != NDS_OK) return NDS_KO;
|
||
|
||
return( ND_List_Recursive_Make( right_node_ptr, Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
/*--------------------------------- main body ------------------------------*/
|
||
|
||
NDT_Status ND_List_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = NULL;
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = NULL;
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF;
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG;
|
||
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO;
|
||
|
||
return( ND_List_Recursive_Make( node_ptr, Root_Ptr, Index_Id));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Conversion d'une structure en arbre binaire */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine du la structure <20> convertir */
|
||
/* (I) Type : type du futur arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------- Recursive Kernel ---------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Recursive_Make( long Depth, long Node_Number, NDT_Node *Node_Ptr )
|
||
{
|
||
long middle_pos, left_len, right_len, i;
|
||
NDT_Node *left_node_ptr, *middle_node_ptr, *right_node_ptr;
|
||
|
||
|
||
if( !Node_Ptr) return( NULL);
|
||
|
||
/* On calcule le milieu de la liste */
|
||
|
||
middle_pos = Node_Number / 2 + 1;
|
||
middle_node_ptr = Node_Ptr;
|
||
|
||
for( i = 1; i < middle_pos; i++) middle_node_ptr = middle_node_ptr->Right;
|
||
|
||
/* On coupe la liste en deux */
|
||
|
||
if( middle_node_ptr->Left)
|
||
{
|
||
middle_node_ptr->Left->Right = NULL;
|
||
left_node_ptr = Node_Ptr;
|
||
left_len = middle_pos - 1;
|
||
}
|
||
else
|
||
{
|
||
left_node_ptr = NULL;
|
||
left_len = 0;
|
||
}
|
||
|
||
if( middle_node_ptr->Right)
|
||
{
|
||
middle_node_ptr->Right->Left = NULL;
|
||
right_node_ptr = middle_node_ptr->Right;
|
||
right_len = Node_Number - middle_pos;
|
||
}
|
||
else
|
||
{
|
||
right_node_ptr = NULL;
|
||
right_len = 0;
|
||
}
|
||
|
||
/* Construction des sous-arbres */
|
||
|
||
middle_node_ptr->Left = ND_Tree_Recursive_Make( Depth + 1, left_len, left_node_ptr);
|
||
|
||
middle_node_ptr->Right = ND_Tree_Recursive_Make( Depth + 1, right_len, right_node_ptr);
|
||
|
||
if( middle_node_ptr->Left) middle_node_ptr->Left->Parent = middle_node_ptr;
|
||
|
||
if( middle_node_ptr->Right) middle_node_ptr->Right->Parent = middle_node_ptr;
|
||
|
||
/* Mise <20> jour des informations statistiques de la structure */
|
||
|
||
middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Node_Number++;
|
||
|
||
if( !middle_node_ptr->Left && !middle_node_ptr->Right)
|
||
{
|
||
/*
|
||
Si le noeud courant est une feuille, on met <20>ventuellement <20> jour
|
||
les longueurs minimale et maximale des branches de l'arbre
|
||
*/
|
||
|
||
if( Depth > middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Max_Depth)
|
||
{
|
||
middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Max_Depth = Depth;
|
||
}
|
||
|
||
if( Depth < middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Min_Depth)
|
||
{
|
||
middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Min_Depth = Depth;
|
||
}
|
||
}
|
||
|
||
return( middle_node_ptr);
|
||
}
|
||
|
||
|
||
|
||
/*--------------------------------- main body ------------------------------*/
|
||
|
||
NDT_Status ND_Tree_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id )
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Node *node_ptr;
|
||
long node_number;
|
||
|
||
|
||
if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
|
||
{
|
||
rc = ND_List_Sort( Root_Ptr, Index_Id);
|
||
if( ND_ERROR(rc)) return( rc);
|
||
}
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
node_number = Root_Ptr->Index_Tab[Index_Id].Node_Number;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = NULL;
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = NULL;
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF;
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG;
|
||
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0;
|
||
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED;
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = ND_Tree_Recursive_Make( 1, node_number, node_ptr);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
/* Equilibrage d'un arbre binaire */
|
||
/*--------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de l'arbre */
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Tree_Equalize( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Index_Type type;
|
||
long max_dif, nb_equ;
|
||
|
||
|
||
type = Root_Ptr->Index_Tab[Index_Id].Type;
|
||
max_dif = Root_Ptr->Index_Tab[Index_Id].Max_Dif;
|
||
nb_equ = Root_Ptr->Index_Tab[Index_Id].Nb_Equ;
|
||
|
||
rc = ND_List_Make( Root_Ptr, Index_Id);
|
||
if( ND_ERROR(rc)) return(rc);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED;
|
||
|
||
rc = ND_Tree_Make( Root_Ptr, Index_Id);
|
||
if( ND_ERROR(rc)) return(rc);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Type = type;
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Dif = max_dif;
|
||
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = nb_equ + 1;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
/* Retourne la profondeur de la plus grande branche <20> partir d'un noeud */
|
||
/*--------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud */
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
long ND_Tree_MaxDepth_Get( NDT_Node *Node_Ptr)
|
||
{
|
||
long Max_Left, Max_Right;
|
||
|
||
|
||
if( !Node_Ptr) return( 0);
|
||
|
||
Max_Left = ND_Tree_MaxDepth_Get( Node_Ptr->Left);
|
||
|
||
Max_Right = ND_Tree_MaxDepth_Get( Node_Ptr->Right);
|
||
|
||
return( NDD_MAX( Max_Left, Max_Right) + 1 );
|
||
}
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
/* Retourne la profondeur de la plus petite branche <20> partir d'un noeud */
|
||
/*--------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud */
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
long ND_Tree_MinDepth_Get( NDT_Node *Node_Ptr)
|
||
{
|
||
long Min_Left, Min_Right;
|
||
|
||
|
||
if( !Node_Ptr) return( 0);
|
||
|
||
Min_Left = ND_Tree_MinDepth_Get( Node_Ptr->Left);
|
||
|
||
Min_Right = ND_Tree_MinDepth_Get( Node_Ptr->Right);
|
||
|
||
return( NDD_MIN( Min_Left, Min_Right) + 1 );
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
/* Ajoute un noeud <20> un arbre */
|
||
/*--------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de l'arbre */
|
||
/* (I) Node : pointeur sur le noeud <20> ajouter */
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------ Recursive Kernel --------------------------*/
|
||
|
||
void ND_Tree_Node_Recursive_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Parent_Node, NDT_Node **Node_Ptr_Ptr, long Depth, NDT_Node *New_Node_Ptr )
|
||
{
|
||
if( *Node_Ptr_Ptr)
|
||
{
|
||
/* Appel r<>cursif */
|
||
|
||
if( ND_Manager_Exec_I( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, (*Node_Ptr_Ptr)->Value, NULL) == NDS_LOWER)
|
||
ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Left), Depth + 1, New_Node_Ptr);
|
||
else
|
||
ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Right), Depth + 1, New_Node_Ptr);
|
||
}
|
||
else
|
||
{
|
||
long Max_Depth, Min_Depth;
|
||
|
||
/* Rattachement du nouveau noeud <20> l'arbre */
|
||
|
||
New_Node_Ptr->Root = Root_Ptr;
|
||
New_Node_Ptr->Index = Index_Id;
|
||
New_Node_Ptr->Parent = Parent_Node;
|
||
|
||
*Node_Ptr_Ptr = New_Node_Ptr;
|
||
|
||
/* Mise <20> jour des informations statistiques de la structure */
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
|
||
|
||
Max_Depth = ND_Tree_MaxDepth_Get( New_Node_Ptr);
|
||
|
||
Min_Depth = ND_Tree_MinDepth_Get( New_Node_Ptr);
|
||
|
||
if( Max_Depth + Depth - 1 > Root_Ptr->Index_Tab[Index_Id].Max_Depth) Root_Ptr->Index_Tab[Index_Id].Max_Depth = Max_Depth + Depth - 1;
|
||
|
||
if( Min_Depth + Depth - 1 < Root_Ptr->Index_Tab[Index_Id].Min_Depth) Root_Ptr->Index_Tab[Index_Id].Min_Depth = Min_Depth + Depth - 1 ;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*-------------------------------- main body -------------------------------*/
|
||
|
||
NDT_Status ND_Tree_Node_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr)
|
||
{
|
||
ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, NULL, &(Root_Ptr->Index_Tab[Index_Id].Head), 1, Node_Ptr);
|
||
|
||
if( ND_INDEX_SUBTYPE_BALANCED_IS( Root_Ptr, Index_Id) && Root_Ptr->Index_Tab[Index_Id].Max_Depth - Root_Ptr->Index_Tab[Index_Id].Min_Depth > Root_Ptr->Index_Tab[Index_Id].Max_Dif)
|
||
return( ND_Tree_Equalize( Root_Ptr, Index_Id));
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Ajoute tous les noeud d'une liste <20> un arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Tree_Root : pointeur sur la racine de l'arbre */
|
||
/* (I) List_Root : pointeur sur la racine de la liste */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Tree_List_Add( NDT_Root *Tree_Root_Ptr, NDT_Index_Id Tree_Index_Id, NDT_Root *List_Root_Ptr, NDT_Index_Id List_Index_Id)
|
||
{
|
||
NDT_Status rc;
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
node_ptr = List_Root_Ptr->Index_Tab[List_Index_Id].Head;
|
||
|
||
while( node_ptr)
|
||
{
|
||
rc = ND_Tree_Node_Add( Tree_Root_Ptr, Tree_Index_Id, node_ptr);
|
||
if( ND_ERROR( rc)) return( rc);
|
||
node_ptr = node_ptr->Right;
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Affiche toutes les informations d'une structure de donn<6E>es */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de la structure */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------- Recursive Kernel ---------------------------*/
|
||
|
||
void ND_Tree_Recursive_Print( NDT_Node *Node_Ptr, long Depth, FILE *Out)
|
||
{
|
||
const int BRANCH_LEN = 4;
|
||
|
||
|
||
if( !Node_Ptr) return;
|
||
|
||
if( Node_Ptr->Right)
|
||
{
|
||
ND_Tree_Recursive_Print( Node_Ptr->Right, Depth + 1, Out);
|
||
fprintf( Out, "%*s/\n", (int)(Depth * BRANCH_LEN - 1), "");
|
||
}
|
||
|
||
fprintf( Out, "%*s (%p) ", (int)((Depth - 1) * BRANCH_LEN), "", Node_Ptr);
|
||
|
||
/* Affichage des toutes les informations (noeud et valeur) :
|
||
|
||
if( Node->Root) fprintf( Out, "Root=%p ", Node->Root);
|
||
if( Node->Parent) fprintf( Out, "Parent=%p ", Node->Parent);
|
||
if( Node->Left) fprintf( Out, "Left=%p ", Node->Left);
|
||
if( Node->Right) fprintf( Out, "Right=%p ", Node->Right);
|
||
|
||
fprintf( Out, "Value=[");
|
||
ND_Manager_Exec( Node->Root->Manager, NDD_CMD_PRINT_VALUE, Node->Value, Out);
|
||
fprintf( Out, "]\n");
|
||
*/
|
||
|
||
/* Affichage de la valeur seule : */
|
||
|
||
ND_Manager_Exec_I( Node_Ptr->Root, Node_Ptr->Index, Node_Ptr, NDD_CMD_VALUE_PRINT, Node_Ptr->Value, Out, NULL);
|
||
fprintf( Out, "\n");
|
||
|
||
if( Node_Ptr->Left)
|
||
{
|
||
fprintf( Out, "%*s\\\n", (int)( Depth * BRANCH_LEN - 1), "");
|
||
ND_Tree_Recursive_Print( Node_Ptr->Left, Depth + 1, Out);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Function de comparaison de noeuds (pour le quick sort) */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
int ND_Node_Compare( void **Node1_Ptr_Ptr, void **Node2_Ptr_Ptr)
|
||
{
|
||
NDT_Status rc;
|
||
|
||
|
||
rc = ND_Manager_Exec_I( ( ( NDT_Node *)( *Node1_Ptr_Ptr))->Root, ( ( NDT_Node *)(*Node1_Ptr_Ptr))->Index, *Node1_Ptr_Ptr, NDD_CMD_VALUE_COMP, ( (NDT_Node *) (*Node1_Ptr_Ptr))->Value, ( ( NDT_Node *)( *Node2_Ptr_Ptr))->Value, NULL);
|
||
|
||
switch( (int)rc)
|
||
{
|
||
case NDS_EQUAL: return( 0);
|
||
case NDS_LOWER: return( -1);
|
||
case NDS_GREATER: return( 1);
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Incorrect return code from the manager: (%d)", rc);
|
||
|
||
return( 0);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
/* Ordonne une liste cha<68>n<EFBFBD>e : */
|
||
/*--------------------------------------------------------------------------*/
|
||
/* (I) Root : pointeur sur la racine de la liste <20> trier */
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_List_Sort( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
|
||
{
|
||
int i;
|
||
NDT_Node *node_ptr;
|
||
void **tab;
|
||
|
||
|
||
if( Root_Ptr->Index_Tab[Index_Id].Node_Number < 2) return NDS_OK;
|
||
|
||
/* Allocation d'un tableau de pointeur de noeuds */
|
||
|
||
tab = (void **)malloc( Root_Ptr->Index_Tab[Index_Id].Node_Number * sizeof( NDT_Node *));
|
||
|
||
/* On remplit le tableau avec les noeuds de la structure <20> trier */
|
||
|
||
i = 0;
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
while( node_ptr)
|
||
{
|
||
tab[i] = node_ptr;
|
||
node_ptr = node_ptr->Right;
|
||
i++;
|
||
}
|
||
|
||
/* Tri du tableau de pointeurs de noeuds */
|
||
|
||
qsort( (void *)tab, (size_t)( Root_Ptr->Index_Tab[Index_Id].Node_Number), sizeof( NDT_Node *), ( int (*)( const void *, const void *))&ND_Node_Compare);
|
||
|
||
/* On met <20> jour les liens entre les noeuds */
|
||
|
||
for( i = 0; i < Root_Ptr->Index_Tab[Index_Id].Node_Number; i++)
|
||
{
|
||
node_ptr = (NDT_Node *)tab[i];
|
||
|
||
node_ptr->Left = (i ? (NDT_Node *)( tab[i - 1]) : NULL);
|
||
node_ptr->Right = (i != Root_Ptr->Index_Tab[Index_Id].Node_Number - 1 ? (NDT_Node *)( tab[i + 1]) : NULL);
|
||
}
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = (NDT_Node *)( tab[0]);
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = (NDT_Node *)( tab[Root_Ptr->Index_Tab[Index_Id].Node_Number - 1]);
|
||
|
||
/* D<>sallocation du tableau */
|
||
|
||
free(tab);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* R<>cup<75>re le premier noeud dans un sous-arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud racine du sous-arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Node_First_Recursive_Get( NDT_Node *Node_Ptr)
|
||
{
|
||
if( !Node_Ptr) return NULL;
|
||
|
||
if( !Node_Ptr->Left) return( Node_Ptr);
|
||
|
||
return( ND_Tree_Node_First_Recursive_Get( Node_Ptr->Left));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* R<>cup<75>re le dernier noeud dans un sous-arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
/* (I) Node : pointeur sur le noeud racine du sous-arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Node *ND_Tree_Node_Last_Recursive_Get( NDT_Node *Node_Ptr)
|
||
{
|
||
if( !Node_Ptr) return NULL;
|
||
|
||
if( !Node_Ptr->Right) return( Node_Ptr);
|
||
|
||
return ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Right);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Red<65>finition de la fonction malloc() avec retour de type NDT_Status */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Default_Allocator( void **Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size, void *Data_Ptr)
|
||
{
|
||
*Ptr_Ptr = malloc( Size);
|
||
|
||
|
||
if( !*Ptr_Ptr) return( NDS_ERRMEM);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Red<65>finition de la fonction free() avec retour de type NDT_Status */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Default_Deallocator( void *Ptr, NDT_Root *Root_Ptr, void *Data_Ptr)
|
||
{
|
||
if( !Ptr) return( NDS_ERRAPI);
|
||
|
||
free( Ptr);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Function de v<>rification d'une liste : */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
void ND_List_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
/* On v<>rifie les liens entre les noeuds */
|
||
|
||
ND_List_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
|
||
/* On v<>rifie les valeurs des noeuds */
|
||
|
||
ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Function de v<>rification et correction des liens entre noeuds d'une liste */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
void ND_List_Link_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
NDT_Node *node_ptr;
|
||
int left2right_node_number = 0;
|
||
int right2left_node_number = 0;
|
||
|
||
|
||
/*
|
||
On commence <20> v<>rifier si l'on trouve le m<>me nombre de noeuds
|
||
en parcourant la liste de droite <20> gauche, puis de gauche <20> droite
|
||
*/
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
while( node_ptr)
|
||
{
|
||
left2right_node_number++;
|
||
node_ptr = node_ptr->Right;
|
||
}
|
||
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
|
||
|
||
while( node_ptr)
|
||
{
|
||
right2left_node_number++;
|
||
node_ptr = node_ptr->Left;
|
||
}
|
||
|
||
/* Cas o<> tout est OK */
|
||
|
||
if( left2right_node_number == Root_Ptr->Index_Tab[Index_Id].Node_Number && left2right_node_number == right2left_node_number) return;
|
||
|
||
/* Cas o<> le nombre de noeuds n'a simplement pas <20>t<EFBFBD> mis <20> jour au niveau de la racine */
|
||
|
||
if( left2right_node_number == right2left_node_number)
|
||
{
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number = left2right_node_number;
|
||
|
||
LG_LOG_WARNING_2( "\t- number of node has been corrected on structure: (%p:%d)", Root_Ptr, Index_Id);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
return;
|
||
}
|
||
|
||
/* Cas o<> le parcours de gauche <20> droite est plus complet : il manque un lien 'Left' */
|
||
|
||
if( left2right_node_number > right2left_node_number)
|
||
{
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
|
||
|
||
while( node_ptr)
|
||
{
|
||
if( node_ptr->Right && ( node_ptr->Right->Left != node_ptr))
|
||
{
|
||
LG_LOG_WARNING_3( "\t- link 'Left' has been corrected on node: (%p) of structure: (%p:%d)", node_ptr->Right, Root_Ptr, Index_Id);
|
||
|
||
node_ptr->Right->Left = node_ptr;
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
if( !node_ptr->Right && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Tail))
|
||
{
|
||
LG_LOG_WARNING_2( "\t- link 'Tail' has been corrected on structure: (%p:%d)", Root_Ptr, Index_Id);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Tail = node_ptr;
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
node_ptr = node_ptr->Right;
|
||
}
|
||
|
||
if( Root_Ptr->Index_Tab[Index_Id].Node_Number != left2right_node_number)
|
||
{
|
||
LG_LOG_WARNING_2( "\t- number of node has been corrected on structure: (%p:%d)", Root_Ptr, Index_Id);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number = left2right_node_number;
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/* Cas o<> le parcours de droite <20> gauche est plus complet : il manque un lien 'Right' */
|
||
|
||
if( right2left_node_number > left2right_node_number)
|
||
{
|
||
node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
|
||
|
||
while( node_ptr)
|
||
{
|
||
if( node_ptr->Left && ( node_ptr->Left->Right != node_ptr))
|
||
{
|
||
LG_LOG_WARNING_3( "\t- link 'Right' has been corrected on node: (%p) of list: (%p:%d)", node_ptr->Left, Root_Ptr, Index_Id);
|
||
|
||
node_ptr->Left->Right = node_ptr;
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
if( !node_ptr->Left && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Head))
|
||
{
|
||
LG_LOG_WARNING_2( "\t- link 'Head' has been corrected on the structure root: (%p:%d)", Root_Ptr, Index_Id);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Head = node_ptr;
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
node_ptr = node_ptr->Left;
|
||
}
|
||
|
||
if( Root_Ptr->Index_Tab[Index_Id].Node_Number != right2left_node_number)
|
||
{
|
||
LG_LOG_WARNING_2( "\t- number of node has been corrected on structure: (%p:%d)", Root_Ptr, Index_Id);
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Node_Number = right2left_node_number;
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Function de v<>rification des valeurs des noeuds d'une liste */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
void ND_Value_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected, int *Nb_Corrected, FILE *Out)
|
||
{
|
||
NDT_Node *node_ptr, *next_node_ptr;
|
||
|
||
|
||
/* Chaque noeud sans valeur est purement et simplement supprim<69> de la liste */
|
||
|
||
ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, Index_Id);
|
||
|
||
while( node_ptr)
|
||
{
|
||
ND_Index_Node_Next_Get_I( &next_node_ptr, node_ptr);
|
||
|
||
if( !node_ptr->Value)
|
||
{
|
||
LG_LOG_WARNING_3( "\t- node: (%p) has been removed from structure (%p:%d) because no value is attached to it", node_ptr, Root_Ptr, Index_Id);
|
||
|
||
ND_Index_Node_Remove_I( node_ptr);
|
||
|
||
node_ptr = next_node_ptr;
|
||
|
||
(*Nb_Detected)++;
|
||
(*Nb_Corrected)++;
|
||
}
|
||
else if( ND_Address_Check( node_ptr->Value) != NDS_OK)
|
||
{
|
||
LG_LOG_WARNING_3( "\t- node %p has been removed from structure %p:%d because its value cannot be accessed", node_ptr, Root_Ptr, Index_Id);
|
||
|
||
ND_Index_Node_Remove_I( node_ptr);
|
||
|
||
node_ptr = next_node_ptr;
|
||
|
||
(*Nb_Detected)++;
|
||
(*Nb_Corrected)++;
|
||
}
|
||
else ND_Index_Node_Next_Get( &node_ptr, node_ptr);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Function de v<>rification d'un arbre : */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
void ND_Tree_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
/* On v<>rifie les liens entre les noeuds */
|
||
|
||
ND_Tree_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
|
||
/* On v<>rifie les valeurs attach<63>es aux noeuds */
|
||
|
||
ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
|
||
/* On met <20> jour les informations statistiques de la racine */
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Max_Depth = ND_Tree_MaxDepth_Get( Root_Ptr->Index_Tab[Index_Id].Head);
|
||
Root_Ptr->Index_Tab[Index_Id].Min_Depth = ND_Tree_MaxDepth_Get( Root_Ptr->Index_Tab[Index_Id].Head);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Function de v<>rification et correction des liens entre noeuds d'un arbre */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
void ND_Tree_Link_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
/* On v<>rifie les liens 'Parent' et les liens 'Root' de chaque noeud */
|
||
|
||
if( Root_Ptr->Index_Tab[Index_Id].Head)
|
||
{
|
||
if( Root_Ptr->Index_Tab[Index_Id].Head->Root != Root_Ptr)
|
||
{
|
||
Root_Ptr->Index_Tab[Index_Id].Head->Root = Root_Ptr;
|
||
|
||
LG_LOG_WARNING_3( "\t- link 'Root' has been corrected on node: (%p) of structure: (%p:%d)", Root_Ptr->Index_Tab[Index_Id].Head, Root_Ptr, Index_Id);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
ND_Tree_Link_Recursive_Check( Root_Ptr->Index_Tab[Index_Id].Head, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
}
|
||
|
||
/*
|
||
On v<>rifie si le lien 'Save' contient un noeud (cela signifie
|
||
que la proc<6F>dure ND_Node_Remove n'a pas <20>t<EFBFBD> jusqu'<27> son terme).
|
||
*/
|
||
|
||
if( Root_Ptr->Index_Tab[Index_Id].Save)
|
||
{
|
||
NDT_Node *node_ptr;
|
||
|
||
|
||
/* On attache le noeud contenu dans 'Save' <20> l'arbre s'il n'existe pas d<>j<EFBFBD> */
|
||
|
||
if( ND_Index_Node_Find_I( &node_ptr, Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save->Value, NULL) != NDS_OK)
|
||
{
|
||
ND_Index_Node_Add_I( Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save);
|
||
|
||
LG_LOG_WARNING_3( "\t- saved node: (%p) has been restored to structure: (%p:%d)", Root_Ptr->Index_Tab[Index_Id].Save, Root_Ptr, Index_Id);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
Root_Ptr->Index_Tab[Index_Id].Save = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*------------------------------ Recursive Kernel ----------------------------*/
|
||
|
||
void ND_Tree_Link_Recursive_Check( NDT_Node *Node_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
|
||
{
|
||
if( Node_Ptr->Left)
|
||
{
|
||
if( Node_Ptr->Left->Root != Node_Ptr->Root)
|
||
{
|
||
Node_Ptr->Left->Root = Node_Ptr->Root;
|
||
|
||
LG_LOG_WARNING_3( "\t- link 'Root' has been corrected on node: (%p) of structure: (%p:%d)", Node_Ptr->Left, Node_Ptr->Root, Node_Ptr->Index);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
if( Node_Ptr->Left->Parent != Node_Ptr)
|
||
{
|
||
Node_Ptr->Left->Parent = Node_Ptr;
|
||
|
||
LG_LOG_WARNING_3( "\t- link 'Parent' has been corrected on node: (%p) of structure: (%p:%d)", Node_Ptr->Left, Node_Ptr->Root, Node_Ptr->Index);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
/* Appel r<>cursif */
|
||
|
||
ND_Tree_Link_Recursive_Check( Node_Ptr->Left, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
}
|
||
|
||
if( Node_Ptr->Right)
|
||
{
|
||
if( Node_Ptr->Right->Root != Node_Ptr->Root)
|
||
{
|
||
Node_Ptr->Right->Root = Node_Ptr->Root;
|
||
|
||
LG_LOG_WARNING_3( "\t- link 'Root' has been corrected on node: (%p) of structure: (%p:%d)", Node_Ptr->Right, Node_Ptr->Root, Node_Ptr->Index);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
if( Node_Ptr->Right->Parent != Node_Ptr)
|
||
{
|
||
Node_Ptr->Right->Parent = Node_Ptr;
|
||
|
||
LG_LOG_WARNING_3( "\t- link 'Parent' has been corrected on node: (%p) of structure: (%p:%d)", Node_Ptr->Right, Node_Ptr->Root, Node_Ptr->Index);
|
||
|
||
(*Nb_Detected_Ptr)++;
|
||
(*Nb_Corrected_Ptr)++;
|
||
}
|
||
|
||
/* Appel r<>cursif */
|
||
|
||
ND_Tree_Link_Recursive_Check( Node_Ptr->Right, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Target address access try */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
NDT_Status ND_Address_Check( void *Address)
|
||
{
|
||
#if !defined(_WIN32)
|
||
NDT_Status status;
|
||
int rc;
|
||
int test;
|
||
struct sigaction act = {0}, oact_bus, oact_segv;
|
||
|
||
act.sa_handler = ND_Signal_Trap;
|
||
|
||
NDG_Base.Sig_Trapped = 0;
|
||
|
||
|
||
|
||
/* Trap SIGBUS and SIGSEGV */
|
||
|
||
if( ( rc = sigaction( SIGBUS, &act, &oact_bus)) != 0)
|
||
{
|
||
LG_LOG_ERROR_2( "Sigaction (Add SIGBUS Hdl) rc: (%d) errno: (%d)", rc, errno);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
if( ( rc = sigaction( SIGSEGV, &act, &oact_segv)) != 0)
|
||
{
|
||
LG_LOG_ERROR_2( "Sigaction (Add SIGSEGV Hdl) rc: (%d) errno: (%d)", rc, errno);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
|
||
|
||
/* Target address access try */
|
||
|
||
if( sigsetjmp( NDG_Base.SigLongJmp_Env, 1) == 0 )
|
||
{
|
||
test = *( (int *)Address);
|
||
|
||
status = NDS_OK;
|
||
}
|
||
else
|
||
{
|
||
status = NDS_KO;
|
||
}
|
||
|
||
|
||
|
||
/* Untrap SIGBUS and SIGSEGV */
|
||
|
||
if( ( rc = sigaction( SIGBUS, &oact_bus, &act)) != 0)
|
||
{
|
||
LG_LOG_ERROR_2( "Sigaction (Remove SIGBUS Hdl) rc: (%d) errno: (%d)", rc, errno);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
if( ( rc = sigaction( SIGSEGV, &oact_segv, &act)) != 0)
|
||
{
|
||
LG_LOG_ERROR_2( "Sigaction (Remove SIGSEGV Hdl) rc: (%d) errno: (%d)", rc, errno);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
return( status);
|
||
#else
|
||
NDT_Status status;
|
||
int test;
|
||
void (__cdecl *old_sigsegv_sighandler)(int);
|
||
|
||
|
||
NDG_Base.Sig_Trapped = 0;
|
||
|
||
|
||
|
||
/* Trap SIGSEGV */
|
||
|
||
if( ( old_sigsegv_sighandler = signal( SIGSEGV, ND_Signal_Trap)) == SIG_ERR)
|
||
{
|
||
LG_LOG_ERROR_1( "Signal (Add SIGSEGV Hdl) errno: (%d)", errno);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
|
||
|
||
/* Target address access try */
|
||
|
||
if( setjmp( NDG_Base.SigLongJmp_Env) == 0 )
|
||
{
|
||
test = *( (int *)Address);
|
||
|
||
status = NDS_OK;
|
||
}
|
||
else
|
||
{
|
||
status = NDS_KO;
|
||
}
|
||
|
||
|
||
|
||
/* Untrap SIGSEGV */
|
||
|
||
if( ( old_sigsegv_sighandler = signal( SIGSEGV, old_sigsegv_sighandler)) == SIG_ERR)
|
||
{
|
||
LG_LOG_ERROR_1( "Signal (Remove SIGSEGV Hdl) errno: (%d)", errno);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
return( status);
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Trap d'un signal */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
void ND_Signal_Trap( int Sig_Num)
|
||
{
|
||
NDG_Base.Sig_Trapped = Sig_Num;
|
||
|
||
#if !defined(_WIN32)
|
||
siglongjmp( NDG_Base.SigLongJmp_Env, 1);
|
||
#else
|
||
longjmp( NDG_Base.SigLongJmp_Env, 1);
|
||
#endif
|
||
}
|
||
|
||
|
||
|