/*----------------------------------------------------------------------------*/ /* 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 */ /* . */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Includes */ /*----------------------------------------------------------------------------*/ #define _LIBNODE_C_ #include #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( "Manager called with an undefined command: (%d)", Command); return( NDS_ERRAPI); } } LG_LOG_ERROR( "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( "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( "Manager called with an undefined command: (%d)", Command); return( NDS_ERRAPI); } } LG_LOG_ERROR( "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( "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( "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( "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( "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( "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( "Can't print OpenStruct info"); return( NDS_KO); } } if( ( status = ND_DataStruct_Close_I( NDG_Base.OpenStruct_Ptr)) != NDS_OK) { LG_LOG_ERROR( "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( "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( "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( "Can't add value"); return( NDS_KO); } if( ( status = ND_Index_Node_Next_Get_I( &node_ptr, node_ptr)) != NDS_OK) { LG_LOG_ERROR( "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( "Index is not closed"); return( NDS_ERRAPI); } if( ( Root_Ptr->Index_Open_Count == 0) && ( Index_Id != NDD_INDEX_PRIMARY)) { LG_LOG_ERROR( "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 data 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_Id handler_id; NDT_Handler handler_target_tab[ NDD_HANDLER_NB]; NDT_Root *root_tmp_ptr; if( Handler_Tab == NULL) { Handler_Tab = NDG_Handler_Tab_Default; } memcpy( &handler_target_tab, Handler_Tab, NDD_HANDLER_TAB_SIZE); /* Init Manager handler */ 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); } } // // if( ND_DATASTRUCT_STATUS_TEMPORARY_IS( root_tmp_ptr)) // { // /* Root Alloc */ // // if( ( status = ND_Allocator_Exec_I( (void **)Root_Ptr_Ptr, root_tmp_ptr, root_tmp_ptr->Root_Size, root_tmp_ptr->Handler_Tab[ NDD_HANDLER_ID_ALLOC].Name, (NDT_Allocator *)root_tmp_ptr->Handler_Tab[ NDD_HANDLER_ID_ALLOC].Ptr, User_Ptr)) != NDS_OK) // { // return( status); // } // // // /* Root Tmp copy and free */ // // memcpy( *Root_Ptr_Ptr, root_tmp_ptr, root_tmp_ptr->Root_Size); // ( *Root_Ptr_Ptr)->Status = NDD_DATASTRUCT_STATUS_VALID; // // free( root_tmp_ptr); // } // else // { // *Root_Ptr_Ptr = root_tmp_ptr; // } /* Call init handler */ if( ( status = ND_Handler_Init_Exec_I( &root_tmp_ptr, Name, Index_Nb, Type_Ptr, handler_target_tab, Own_Value, User_Ptr, handler_target_tab[ NDD_HANDLER_ID_INIT].Name, ( NDT_Handler_Init *)handler_target_tab[ NDD_HANDLER_ID_INIT].Ptr)) == NDS_OK) { *Root_Ptr_Ptr = root_tmp_ptr; /* Call open handler */ status = ND_Handler_Open_Exec_I( Root_Ptr_Ptr, root_tmp_ptr, Open_Mode, root_tmp_ptr->Handler_Tab[ NDD_HANDLER_ID_OPEN].Name, ( NDT_Handler_Open *)root_tmp_ptr->Handler_Tab[ NDD_HANDLER_ID_OPEN].Ptr); free( root_tmp_ptr); } return( status); } /*----------------------------------------------------------------------------*/ /* 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( "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( "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( "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( "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( "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édure de vérification */ if( *Detected_Nb_Ptr == 0) { LG_LOG_INFO( "No error detected in the node structure (%p:%d)", Root_Ptr, Index_Id); } else { LG_LOG_INFO( "%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( "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( "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( "%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( "%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( ""); } 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( "%sRoot: (%s%p)\tName: [%s]\tIndex Nb: (%d)\tIndex Open Count: (%d)\tRoot_Size: (%ld)\tStatus: [%s]", offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr, Root_Ptr->Name, Root_Ptr->Index_Nb, Root_Ptr->Index_Open_Count, Root_Ptr->Root_Size, NDD_DATASTRUCT_STATUS_VALUE_ASCII_GET( Root_Ptr->Status)); LG_LOG_INFO( "%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( "%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( "%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( ""); } 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( "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 à la valeur de réfé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( "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ère l'adresse du lien entre le noeud à supprimer et son père */ if( Node_Ptr->Parent) { /* Cas géné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 à supprimer dans un pointeur de sauvegarde pour pouvoir le récupérer au cas où la procédure serait interrompue (recovery). */ root_ptr->Index_Tab[index_id].Save = Left_Node_Ptr; /* On remplace le noeud supprimé 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é 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 à jour des informations de profondeur : trop coû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( "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é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( "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( "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é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é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)); } /*----------------------------------------------------------------------------*/ /* Allocate a temporary root node */ /*----------------------------------------------------------------------------*/ /* (O) Root_Tmp_Ptr_Ptr: Data structure pointer address */ /*----------------------------------------------------------------------------*/ NDT_Status ND_Root_Tmp_Alloc( NDT_Root **Root_Tmp_Ptr_Ptr, size_t Root_Extra_Size, NDT_DataStruct_Name Name, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Handler *Handler_Tab, short Own_Value, void *User_Ptr) { NDT_Status status; size_t root_size; NDT_Index_Id index_id; /* Root Tmp Alloc */ root_size = sizeof( NDT_Root) + sizeof( NDT_Index) * (Index_Nb - 1) + Root_Extra_Size; if( ( *Root_Tmp_Ptr_Ptr = malloc( root_size)) == NULL) { LG_LOG_ERROR( "Can't allocate memory for data structure: [%s]", Name); return( NDS_ERRMEM); } ND_STR_CPY( ( *Root_Tmp_Ptr_Ptr)->Name, Name, NDD_DATASTRUCT_NAME_SIZE); ( *Root_Tmp_Ptr_Ptr)->Root_Size = root_size; ( *Root_Tmp_Ptr_Ptr)->Status = NDD_DATASTRUCT_STATUS_TEMPORARY; memcpy( ( *Root_Tmp_Ptr_Ptr)->Handler_Tab, Handler_Tab, NDD_HANDLER_TAB_SIZE); ( *Root_Tmp_Ptr_Ptr)->Own_Value = Own_Value; ( *Root_Tmp_Ptr_Ptr)->User_Ptr = User_Ptr; ( *Root_Tmp_Ptr_Ptr)->Index_Nb = Index_Nb; ( *Root_Tmp_Ptr_Ptr)->Index_Open_Count = 0; /* Index init */ for( index_id = 0; index_id < Index_Nb; index_id++) { if( ( Type_Ptr[ index_id] & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_OPENED) { if( ( status = ND_Index_Open_I( ( *Root_Tmp_Ptr_Ptr), index_id, Type_Ptr[ index_id])) != NDS_OK) { LG_LOG_ERROR( "Index open error"); return( status); } } else { if( ( status = ND_Index_Clear( ( *Root_Tmp_Ptr_Ptr), index_id)) != NDS_OK) { LG_LOG_ERROR( "Index cleaning error"); return( status); } ( *Root_Tmp_Ptr_Ptr)->Index_Tab[ index_id].Type = NDD_INDEX_STATUS_CLOSED; } } return( NDS_OK); } /*----------------------------------------------------------------------------*/ /* 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( "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( "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( "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( "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_Extra_Size_Ptr: Pointer on the extra root size */ /* (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_Tmp_Ptr_Ptr, NDT_DataStruct_Name Name, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Handler *Handler_Tab, short Own_Value, void *User_Ptr, NDT_Handler_Name Handler_Init_Name, NDT_Handler_Init *Handler_Init_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_Tmp_Ptr_Ptr, Name, Index_Nb, Type_Ptr, Handler_Tab, Own_Value, User_Ptr)); } /*----------------------------------------------------------------------------*/ /* Execute an init handler function */ /*----------------------------------------------------------------------------*/ /* (O) Root_Extra_Size_Ptr: Pointer on the extra root size */ /* (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_Tmp_Ptr_Ptr, NDT_DataStruct_Name Name, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Handler *Handler_Tab, short Own_Value, void *User_Ptr, NDT_Handler_Name Handler_Init_Name, NDT_Handler_Init *Handler_Init_Ptr) { ND_LIBNODE_OPEN_CHECK(); ND_HANDLER_NOT_NULL_CHECK( Handler_Init_Name, Handler_Init_Ptr); return( ND_Handler_Init_Exec_I( Root_Tmp_Ptr_Ptr, Name, Index_Nb, Type_Ptr, Handler_Tab, Own_Value, User_Ptr, Handler_Init_Name, Handler_Init_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_Ptr, NDT_Root *Root_Tmp_Ptr, NDT_Open_Flag Open_Mode, NDT_Handler_Name Handler_Open_Name, NDT_Handler_Open *Handler_Open_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_Ptr, Root_Tmp_Ptr, Open_Mode)); } /*----------------------------------------------------------------------------*/ /* 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_Ptr, NDT_Root *Root_Tmp_Ptr, NDT_Open_Flag Open_Mode, NDT_Handler_Name Handler_Open_Name, NDT_Handler_Open *Handler_Open_Ptr) { ND_LIBNODE_OPEN_CHECK(); ND_HANDLER_NOT_NULL_CHECK( Handler_Open_Name, Handler_Open_Ptr); return( ND_Handler_Open_Exec_I( Root_Ptr_Ptr, Root_Tmp_Ptr, Open_Mode, Handler_Open_Name, Handler_Open_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( "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( "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( "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_Extra_Size_Ptr: Pointer on the extra root size */ /* (I) User_Ptr: User pointer */ /*----------------------------------------------------------------------------*/ NDT_Status ND_Handler_Init_Default( NDT_Root **Root_Tmp_Ptr_Ptr, NDT_DataStruct_Name Name, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Handler *Handler_Tab, short Own_Value, void *User_Ptr) { return( ND_Root_Tmp_Alloc( Root_Tmp_Ptr_Ptr, 0L, Name, Index_Nb, Type_Ptr, Handler_Tab, Own_Value, User_Ptr)); } /*----------------------------------------------------------------------------*/ /* 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_Ptr, NDT_Root *Root_Tmp_Ptr, NDT_Open_Flag Open_Mode) { NDT_Status status; /* Root Alloc */ if( ( status = ND_Allocator_Exec_I( (void **)Root_Ptr_Ptr, Root_Tmp_Ptr, Root_Tmp_Ptr->Root_Size, Root_Tmp_Ptr->Handler_Tab[ NDD_HANDLER_ID_ALLOC].Name, (NDT_Allocator *)Root_Tmp_Ptr->Handler_Tab[ NDD_HANDLER_ID_ALLOC].Ptr, NULL)) != NDS_OK) { return( status); } /* Root Tmp copy and free */ memcpy( *Root_Ptr_Ptr, Root_Tmp_Ptr, Root_Tmp_Ptr->Root_Size); ( *Root_Ptr_Ptr)->Status = NDD_DATASTRUCT_STATUS_VALID; /* To be removed... */ ND_STR_CPY( ( *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_STR_CPY( ( *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_STR_CPY( ( *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; 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 été trouvé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( "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( "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 à 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éation d'une nouvelle structure de données */ /*----------------------------------------------------------------------------*/ /* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */ /* (I) Type: type de la structure.de donné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ées utiles à l'allocateur */ /* (I) Own_Value : indique si la structure est proprié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); } /*----------------------------------------------------------------------------*/ /* Désallocation de la racine d'une structure de donnée */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine à 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 à une liste chaînée */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la liste */ /* (I) New_Node : pointeur sur le noeud à 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é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ée peut être orientée de 2 manières : - FIFO : un noeud sera inséré APRES un noeud de même valeur (par défaut) - FILO : un noeud sera inséré AVANT un noeud de même valeur */ if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id)) { /* Pour une liste triée orienté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ère avant le noeud courant si le nouveau noeud est de valeur inférieure ou é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 été inséré */ 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ée orienté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ère après le noeud courant si le nouveau noeud est de valeur strictement supérieure ou é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 été inséré */ 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( "Unknown list type: (%d)", Root_Ptr->Index_Tab[Index_Id].Type); return( NDS_ERRAPI); } /*----------------------------------------------------------------------------*/ /* Ajout d'une nouvelle valeur à une liste */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la liste */ /* (I) Value : pointeur sur la valeur à 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 à un arbre binaire */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de l'arbre */ /* (I) Value : pointeur sur la valeur à 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 à rechercher */ /* (I) Data : pointeur de donné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ées, la recherche peut être optimisé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à dépassé la valeur recherchée */ return( NULL); } case NDS_GREATER: { node_ptr = node_ptr->Right; break; } } } } else { /* Pour les listes non trié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 à rechercher */ /* (I) Data : pointeur de donné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é */ 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é aprè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é 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 à 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înée */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine du la structure à 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 à 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 à 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 éventuellement à 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 à 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 à 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 à un arbre */ /*--------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de l'arbre */ /* (I) Node : pointeur sur le noeud à 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 à 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 à 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 à 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é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( "Incorrect return code from the manager: (%d)", rc); return( 0); } } } /*--------------------------------------------------------------------------*/ /* Ordonne une liste chaînée : */ /*--------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la liste à 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 à 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 à 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è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è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é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é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 à vérifier si l'on trouve le même nombre de noeuds en parcourant la liste de droite à gauche, puis de gauche à 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 été mis à 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( "\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 à 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( "\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( "\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( "\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 à 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( "\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( "\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( "\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é 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( "\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( "\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ées aux noeuds */ ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); /* On met à 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( "\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édure ND_Node_Remove n'a pas été jusqu'à son terme). */ if( Root_Ptr->Index_Tab[Index_Id].Save) { NDT_Node *node_ptr; /* On attache le noeud contenu dans 'Save' à l'arbre s'il n'existe pas déjà */ 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( "\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( "\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( "\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( "\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( "\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( "Sigaction (Add SIGBUS Hdl) rc: (%d) errno: (%d)", rc, errno); return( NDS_KO); } if( ( rc = sigaction( SIGSEGV, &act, &oact_segv)) != 0) { LG_LOG_ERROR( "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( "Sigaction (Remove SIGBUS Hdl) rc: (%d) errno: (%d)", rc, errno); return( NDS_KO); } if( ( rc = sigaction( SIGSEGV, &oact_segv, &act)) != 0) { LG_LOG_ERROR( "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( "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( "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 }