/*----------------------------------------------------------------------------*/ /* libdatastr.c */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* This file is part of LibDataStr. */ /* */ /* LibDataStr 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. */ /* */ /* LibDataStr 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 LibDataStr. If not, see */ /* . */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Includes */ /*----------------------------------------------------------------------------*/ #define _LIBDATASTR_C_ /* Utilisation des API sans vérification des arguments */ #define ND_MODE 1 #define SM_MODE 1 #include //VER_INFO_EXPORT (libdatastr,"$Revision: 1.1 $", "$Name: $",__FILE__,"$Author: smas $") /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* FONCTIONS PUBLIQUES */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* FONCTIONS OPTIMISATION MAXIMALE (DS_MODE = 2) */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Library instance initialisation */ /*----------------------------------------------------------------------------*/ /* (I) Instance: Library instance id */ /* (I) Context: Context name */ /* (I) Debug_Mode: Open library in debug mode */ /*----------------------------------------------------------------------------*/ DST_Status DS_Library_Open_I ( int Instance, const char *Context, DST_Flags Debug_Mode ) { DST_Status rc; LGT_Status lg_status; SMT_Status sm_status; NDT_Status nd_status; int sm_debug_flag = SMD_DEBUG_NONE; NDT_Index_Type index_type = ( NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED); /* Définition du mode debug */ if( Debug_Mode & DSD_DEBUG) { DS_stderr = stderr; sm_debug_flag = SMD_DEBUG; } else if( Debug_Mode & DSD_DEBUG_ALL) { DS_stderr = stderr; sm_debug_flag = SMD_DEBUG_ALL; } 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( DSS_KO); } /* Ouverture de la librairie LIBSHMEM */ if( ( sm_status = SM_Library_Open( Instance, Context, SMD_OPEN | sm_debug_flag)) != SMS_OK) { LG_LOG_ERROR_1( "Unable to open the LibShMem library: (%d)", sm_status); return( DSS_KO); } /* Lors de la première ouverture de la librairie LIBDATASTR, on crée une structure locale permettant de référencer les data structures ouvertes. */ if( DS_Open_Counter == 0) { if( ( nd_status = ND_DataStruct_Open( &OpenedDS_List, 1, &index_type, "DS_OpenedDS_List_Manager", NULL, NULL, NULL, NULL, NULL, TRUE, NULL)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to create the opened data structure list: (%d)", nd_status); SM_Library_Close (SMD_CLOSE); return( DSS_KO); } } DS_Open_Counter++; return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Fermeture de l'instance de la librairie */ /*----------------------------------------------------------------------------*/ DST_Status DS_Library_Close_I( void) { NDT_Status nd_status; SMT_Status sm_status; LGT_Status lg_status; /* A la dernière fermeture de la librairie LIBDATASTR, on détruit la structure locale qui référence les data structures ouvertes. */ if( DS_Open_Counter == 1) { if( ( nd_status = ND_DataStruct_Close( OpenedDS_List)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to close the opened data structure list: (%d)", nd_status); return( DSS_KO); } } /* Fermeture de la librairie LIBSHMEM */ if( ( sm_status = SM_Library_Close( SMD_CLOSE)) != SMS_OK) { LG_LOG_ERROR_1( "Unable to close the LibShMem library: (%d)", sm_status); return( DSS_KO); } DS_Open_Counter--; if( ( lg_status = LG_Library_Close( false)) != LGS_OK) { fprintf( stderr, "Can't close LibLog library: (%d)\n", lg_status); return( DSS_KO); } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Définition de la sortie standard des messages d'erreur de la librairie */ /*----------------------------------------------------------------------------*/ /* (I) Out : flux de sortie des messages d'erreur */ /*----------------------------------------------------------------------------*/ DST_Status DS_Library_Stderr_Set_I( FILE *Out) { DS_stderr = Out; return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Création / ouverture d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (O) Root : adresse du pointeur sur la racine de la structure */ /* (I) DS_Name : nom de la structure */ /* (I) Type : type de la structure de données */ /* (I) Manager_FileName : nom du fichier qui définit les fonctions manager */ /* (I) Segment_Size : taille ds segments du heap sous-jacent */ /* (I) Open_Mode : mode d'ouverture de la structure */ /* (I) Own_Value : indique si la structure possède ses valeurs */ /*----------------------------------------------------------------------------*/ //ND_DataStruct_Open( &OpenedDS_List, 1, &index_type, "DS_OpenedDS_List_Manager", NULL, NULL, NULL, NULL, NULL, TRUE, NULL)) != NDS_OK) //DST_Status DS_DataStruct_Open_I( NDT_Root **Root, const char *DS_Name, NDT_DataStruct_Type Type, const char *Manager_FileName, size_t Segment_Size, DST_Flags Open_Mode, int Own_Values); DST_Status DS_DataStruct_Open_I( NDT_Root **Root_Ptr_Ptr, char *DS_Name, NDT_Index_Nb Index_Nb, NDT_Index_Type *Index_Type_Tab, char *Manager_Name, size_t Segment_Size, DST_Flags Open_Mode, short Own_Value) { DST_Status status; SMT_Status sm_status; NDT_Status nd_status; SMT_Heap *heap_ptr; SMT_DSH *dsh_ptr; int locked, mode; DST_RootDesc *rootdesc_ptr, rootdesc_tmp; DST_DataStruct *opened_datastruct_ptr; char prefixed_name[ DSD_NAME_SIZE]; union semun Sem_Ctl; DS_Name_Prefix( prefixed_name, DS_Name); *Root_Ptr_Ptr = NULL; /* On définit ce qu'on va faire en fonction du mode d'ouverture demandé et de ce qui existe déjà ou non */ if( SM_Heap_Exist( prefixed_name) == SMS_YES) { if( DSD_MSK_OPEN( Open_Mode)) mode = 2; else if( DSD_MSK_NEW( Open_Mode)) mode = 1; else { LG_LOG_ERROR_1( "The data structure: [%s] already exists and (Flags & DSD_OPEN & DSD_NEW) is false", DS_Name); return( DSS_ERRAPI); } } else if( DSD_MSK_CREATE( Open_Mode)) mode = 3; else { LG_LOG_ERROR_1( "The data structure: [%s] does no exist and (Flags & DSD_CREATE) is false", DS_Name); return( DSS_ERRAPI); } LG_LOG_TRACE_1( LGD_LOG_LEVEL_DEFAULT, "Creation Mode:(%d)", mode); switch( mode) { case 1: { /*--------------- Création d'une nouvelle data structure dans un heap existant -------------*/ /* Ouverture du heap en écriture */ if( ( status = SM_Heap_Open( prefixed_name, &heap_ptr, 0, ( SMD_OPEN | SMD_WRITE), &locked)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to open the data structure heap: [%s] for writing, status: (%d)", prefixed_name, sm_status); return( SMS_KO); } /* Création de la node structure */ strncpy( rootdesc_tmp.Heap_Name, prefixed_name, DSD_NAME_LEN); rootdesc_tmp.Heap_Name[ DSD_NAME_LEN] = '\0'; if( ( nd_status = ND_DataStruct_Open( Root_Ptr_Ptr, Index_Nb, Index_Type_Tab, Manager_Name, NULL, "DS_DataStruct_Alloc", NULL, "DS_DataStruct_Free", NULL, Own_Value, &rootdesc_tmp)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to create a new node structure in the existing heap: [%s], status: (%d)", heap_ptr->Name, nd_status); if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } *Root_Ptr_Ptr = NULL; return( SMS_KO); } /* Allocation de mémoire pour la description de la nouvelle data structure */ if( ( status = DS_DataStruct_Alloc( (void **)( &rootdesc_ptr), sizeof( DST_RootDesc), &rootdesc_tmp)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to allocate memory for the data structure description for new heap: [%s], status: (%d)", heap_ptr->Name, status); /* Strange: why end the heap here ? if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } */ if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } *Root_Ptr_Ptr = NULL; return( status); } strncpy( rootdesc_ptr->Heap_Name, prefixed_name, DSD_NAME_LEN); rootdesc_ptr->Heap_Name[ DSD_NAME_LEN] = '\0'; rootdesc_ptr->Manager_Name = ( *Root_Ptr_Ptr)->Manager_Name; /* On indique que la structure n'est pas propriétaire de son heap */ rootdesc_ptr->Heap_Owner = FALSE; /* On indique que la structure est valide */ rootdesc_ptr->Valid = TRUE; /* On rattache la desription de la data structure à la racine */ ( *Root_Ptr_Ptr)->User_Ptr = rootdesc_ptr; /* Déverrouillage du heap */ if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); return( DSS_KO); } } return( DSS_OK); } case 2: { /*--------------- Ouverture d'une data structure existante ------------------*/ /* Si la structure a déjà été ouverte, on ne recommence pas */ if( ( status = DS_DataStruct_IsOpen( Root_Ptr_Ptr, DS_Name)) != DSS_OK) { LG_LOG_ERROR_2( "Unable test data structure: [%s] state, status: (%d)", DS_Name, status); return( status); } else { if( *Root_Ptr_Ptr != NULL) { return( DSS_OK); } } /* Accès au heap sous-jacent en lecture */ if( ( status = SM_Heap_Open( prefixed_name, &heap_ptr, 0, ( SMD_OPEN | SMD_READ), &locked)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to open the data structure heap: [%s] for reading, status: (%d)", heap_ptr->Name, status); if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } *Root_Ptr_Ptr = NULL; return( status); } dsh_ptr = heap_ptr->MHH->DSR->Index_Tab[ NDD_INDEX_PRIMARY].Head->Value; /* La racine de la structure se trouve dans le premier chunk du premier segment du heap */ *Root_Ptr_Ptr = (NDT_Root *)( ( size_t)( dsh_ptr->Start) + sizeof( NDT_Node) + sizeof( SMT_Chunk)); /* Chargement des fonctions manager de la structure */ rootdesc_ptr = (*Root_Ptr_Ptr)->User_Ptr; if( !rootdesc_ptr) { LG_LOG_ERROR_1( "Data structure [%s] has no description defined", DS_Name); if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } *Root_Ptr_Ptr = NULL; return( DSS_ERRAPI); } /* if( !RootDesc->Manager_Name || !dlopen (( const char *)(RootDesc->Manager_FileName), RTLD_LAZY | RTLD_GLOBAL)) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Open : unable to load the manager file %s of data structure \"%s\" (%s)", RootDesc->Manager_FileName == NULL ? "undefined" : (char *)(RootDesc->Manager_FileName), DS_Name, dlerror ()); DS_Error_Print (); if (Locked == TRUE) SM_Heap_Unlock (Heap); *Root = NULL; return DSS_ERRDLL; } */ break; } case 3: { /*--------------- Création d'une nouvelle structure de données dans un nouveau heap -----------------*/ if( !Manager_Name) { LG_LOG_ERROR_0( "The manager name is undefined"); return( DSS_ERRAPI); } /* Création d'un nouveau heap */ if( ( sm_status = SM_Heap_Open( prefixed_name, &heap_ptr, Segment_Size, ( SMD_CREATE | SMD_WRITE), &locked)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to create a heap for the data structure [%s], status: (%d)", DS_Name, sm_status); return( sm_status); } /* Création de la structure de données dans le heap */ strncpy( rootdesc_tmp.Heap_Name, prefixed_name, DSD_NAME_LEN); rootdesc_tmp.Heap_Name[ DSD_NAME_LEN] = '\0'; if( ( nd_status = ND_DataStruct_Open( Root_Ptr_Ptr, Index_Nb, Index_Type_Tab, Manager_Name, NULL, "DS_DataStruct_Alloc", NULL, "DS_DataStruct_Free", NULL, Own_Value, &rootdesc_tmp)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to create a new node structure in new heap: [%s], status: (%d)", heap_ptr->Name, nd_status); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } *Root_Ptr_Ptr = NULL; return( SMS_KO); } /* Allocation de mémoire pour la description de la structure */ if( ( status = DS_DataStruct_Alloc( (void **)( &rootdesc_ptr), sizeof( DST_RootDesc), &rootdesc_tmp)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to allocate memory for the data structure description for new heap: [%s], status: (%d)", heap_ptr->Name, status); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } *Root_Ptr_Ptr = NULL; return( status); } strncpy( rootdesc_ptr->Heap_Name, prefixed_name, DSD_NAME_LEN); rootdesc_ptr->Heap_Name[ DSD_NAME_LEN] = '\0'; rootdesc_ptr->Manager_Name = ( *Root_Ptr_Ptr)->Manager_Name; /* On indique que la structure est propriétaire du heap */ rootdesc_ptr->Heap_Owner = TRUE; /* On indique que la structure est valide */ rootdesc_ptr->Valid = TRUE; /* On rattache la desription de la data structure à la racine */ ( *Root_Ptr_Ptr)->User_Ptr = rootdesc_ptr; /* On crée un sémaphore pour compter le nombre de processus qui ouvrent la structure */ if( ( status = DS_Semaphore_Create( *Root_Ptr_Ptr)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to create a semaphore for the data structure: [%s], status: (%d)", DS_Name, status); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } *Root_Ptr_Ptr = NULL; return( status); } break; } default: { break; } } /* On incrémente le sémaphore qui compte le nombre de processus qui ouvrent la structure */ if( ( status = DS_Semaphore_Operate( rootdesc_ptr->OpenSemId, DS_SemOp_Open, 1)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to incremente the semaphore of data structure: [%s], status: (%d)", DS_Name, status); if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } if( mode == 3) { semctl( rootdesc_ptr->OpenSemId, 0, IPC_RMID, Sem_Ctl); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } } else { DS_Semaphore_Operate( rootdesc_ptr->OpenSemId, DS_SemOp_Close, 1); } *Root_Ptr_Ptr = NULL; return( status); } /* On ajoute la data structure à la liste des structures ouvertes par le processus courant */ if( ( nd_status = ND_Value_Alloc( (void **)&opened_datastruct_ptr, OpenedDS_List, DS_Name, *Root_Ptr_Ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to alloc a new opened data structure element: [%s], status: (%d)", DS_Name, nd_status); if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } if( mode == 3) { semctl( rootdesc_ptr->OpenSemId, 0, IPC_RMID, Sem_Ctl); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } } else { DS_Semaphore_Operate( rootdesc_ptr->OpenSemId, DS_SemOp_Close, 1); } *Root_Ptr_Ptr = NULL; return( DSS_KO); } if( ( nd_status = ND_DataStruct_Value_Add( OpenedDS_List, (void *)opened_datastruct_ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to add an new data structure element: [%s] to the opened structure list, status: (%d)", DS_Name, status); if( ( nd_status = ND_Value_Free( OpenedDS_List, (void *)opened_datastruct_ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to free a new opened data structure element: [%s], status: (%d)", DS_Name, nd_status); } if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } if( mode == 3) { semctl( rootdesc_ptr->OpenSemId, 0, IPC_RMID, Sem_Ctl); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } } else { DS_Semaphore_Operate( rootdesc_ptr->OpenSemId, DS_SemOp_Close, 1); } *Root_Ptr_Ptr = NULL; return( DSS_KO); } /* Déverrouillage du heap */ if( locked == TRUE) { if( sm_status = ( SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", prefixed_name, sm_status); if( ( nd_status = ND_DataStruct_Value_Remove( OpenedDS_List, opened_datastruct_ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to remove a data structure element: [%s] to the opened structure list, status: (%d)", DS_Name, status); } if( ( nd_status = ND_Value_Free( OpenedDS_List, opened_datastruct_ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to free a new opened data structure element: [%s], status: (%d)", DS_Name, nd_status); } if( mode == 3) { semctl( rootdesc_ptr->OpenSemId, 0, IPC_RMID, Sem_Ctl); if( ( sm_status = SM_Heap_End( prefixed_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", prefixed_name, sm_status); } } else { DS_Semaphore_Operate( rootdesc_ptr->OpenSemId, DS_SemOp_Close, 1); } *Root_Ptr_Ptr = NULL; return( DSS_KO); } } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Verrouillage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /* (I) Lock_Mode : type de verrou à poser sur la structure */ /* (O) Locked : verrou effectif (TRUE ou FALSE) */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Lock_I( NDT_Root *Root_Ptr, DST_Flags Lock_Mode, int *Locked ) { char *Heap_Name = ( (DST_RootDesc *)( Root_Ptr->User_Ptr))->Heap_Name; SMT_Status sm_status; SMT_Heap *heap_ptr; /* Réouverture du heap sous-jacent (rafraîchissement des segments) + verrouillage */ if( ( sm_status = SM_Heap_Open( Heap_Name, &heap_ptr, 0, ( SMD_OPEN | Lock_Mode), Locked)) != SMS_OK) { LG_LOG_ERROR_3( "Unable to reopen the data structure heap: [%s] for [%s], status: (%d)", Heap_Name, (DSD_MSK_READ( Lock_Mode) ? "reading" : "writing"), sm_status); return( DSS_KO); } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Déverrouillage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Unlock_I( NDT_Root *Root_Ptr) { char *Heap_Name = ( (DST_RootDesc *)( Root_Ptr->User_Ptr))->Heap_Name; SMT_Status sm_status; SMT_Heap *heap_ptr; if( ( sm_status = SM_Heap_IsOpen( Heap_Name, &heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to check if heap: [%s] is open, status: (%d)", Heap_Name, sm_status); return( DSS_KO); } else { if( heap_ptr == NULL) { LG_LOG_ERROR_1( "Data structure heap: [%s] is not open", Heap_Name); return( DSS_KO); } } if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", Heap_Name, sm_status); return( DSS_KO); } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Fermeture d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à fermer */ /* (I) Close_Mode : mode de fermeture de la structure (destruction ou non) */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Close_I( NDT_Root *Root_Ptr, DST_Flags Close_Mode) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); DST_Status status; NDT_Status nd_status; SMT_Status sm_status; SMT_Heap *heap_ptr; char heap_name[ DSD_NAME_SIZE], *ds_name; DST_DataStruct to_remove, *opened_datastruct_ptr; union semun sem_ctl; strcpy( heap_name, RootDesc_Ptr->Heap_Name); ds_name = strstr( heap_name, DS_PREFIX); if( ds_name) ds_name += strlen( DS_PREFIX) + 1; else ds_name = heap_name; if( Close_Mode == DSD_DESTROY) /* Destruction de la data structure */ { /* La data structure est-elle propriétaire du heap sous-jacent ? */ if( RootDesc_Ptr->Heap_Owner == TRUE) { /* On vérifie qu'aucun autre processus n'a ouvert la data structure */ if( ( status = DS_Semaphore_Operate( RootDesc_Ptr->OpenSemId, DS_SemOp_Destroy, 2)) != DSS_OK) { LG_LOG_ERROR_1( "Unable to destroy the data structure: [%s] because it is opened by another process", ds_name); return( status); } /* On supprime la structure proprement (toutes les valeurs sont supprimées les unes après les autres) */ if( ( nd_status = ND_DataStruct_Close( Root_Ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to close the node structure of data structure: [%s], status: (%d)", ds_name, nd_status); return( DSS_KO); } /* Suppression du sémaphore */ semctl( RootDesc_Ptr->OpenSemId, 0, IPC_RMID, sem_ctl); /* On supprime maintenant le heap */ if( ( sm_status = SM_Heap_End( heap_name)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to remove the heap: [%s], status: (%d)", heap_name, sm_status); return( DSS_KO); } } else { /* Dans le cas où la data structure n'est pas propriétaire du heap sous-jacent, on ne peut pas garantir qu'aucun autre processus ne l'a ouverte. On la supprime donc sans contrôle. */ if( ( nd_status = ND_DataStruct_Close( Root_Ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to close the node structure of data structure: [%s], status: (%d)", ds_name, nd_status); return( DSS_KO); } if( ( status = DS_DataStruct_Free( RootDesc_Ptr, (void *)RootDesc_Ptr)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to free data structure: [%s], status: (%d)", ds_name, status); } return( status); } } else /* Fermeture simple de la data structure */ { /* On décrémente le sémaphore qui compte le nombre de processus ayant ouvert la data structure */ if( ( status = DS_Semaphore_Operate( RootDesc_Ptr->OpenSemId, DS_SemOp_Close, 1)) != DSS_OK) { LG_LOG_ERROR_1( "Unable to decremente the semaphore of data structure: [%s]", ds_name); return( status); } /* Fermeture simple du heap */ if( ( sm_status = SM_Heap_IsOpen( heap_name, &heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to check if heap: [%s] is open, status: (%d)", heap_name, sm_status); return( DSS_KO); } else { if( heap_ptr != NULL) { if( ( sm_status = SM_Heap_Close( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to close heap: [%s], status: (%d)", heap_name, sm_status); return( DSS_KO); } } } } /* Suppression de la data structure de la liste des structures ouvertes */ strncpy( to_remove.Name, ds_name, DSD_NAME_LEN); if( ( ( nd_status = ND_DataStruct_Value_Find( ( void **)&opened_datastruct_ptr, OpenedDS_List, &to_remove)) != NDS_OK) || ( opened_datastruct_ptr == NULL)) { LG_LOG_ERROR_2( "Unable to find data struct element: [%s] from opened structure list, status: (%d)", ds_name, nd_status); return( DSS_KO); } else { if( ( nd_status = ND_DataStruct_Value_Remove( OpenedDS_List, opened_datastruct_ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to remove data struct element: [%s] from opened structure list, status: (%d)", ds_name, nd_status); return( DSS_KO); } else { if( ( nd_status = ND_Value_Free( OpenedDS_List, opened_datastruct_ptr)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to free data struct element: [%s] from opened structure list, status: (%d)", ds_name, nd_status); return( DSS_KO); } } } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Destroy all data of a data structure */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /*----------------------------------------------------------------------------*/ NDT_Status DS_DataStruct_Flush_I( NDT_Root *Root_Ptr) { NDT_Status nd_status; if( ( nd_status = ND_DataStruct_Flush_I( Root_Ptr)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to flush datastructure, status: (%d)", nd_status); return( DSS_KO); } else { return( DSS_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 */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Check_I( NDT_Root *Root_Ptr, int *Error_Detected_Nb_Ptr, int *Error_Corrected_Nb_Ptr, FILE *Out) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); char *Heap_Name = RootDesc_Ptr->Heap_Name; DST_Status status, status2; SMT_Status sm_status; NDT_Status nd_status; SMT_Heap *heap_ptr; int locked; DST_Flags previous_lock; /* On sauvegarde l'état de verrouillage précédent */ if( ( sm_status = SM_Heap_IsOpen( Heap_Name, &heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to check if heap: [%s] is open, status: (%d)", Heap_Name, sm_status); return( DSS_KO); } else { if( heap_ptr == NULL) { LG_LOG_ERROR_1( "Data structure heap: [%s] is not open", Heap_Name); return( DSS_KO); } } previous_lock = heap_ptr->Lock_Mode; /* Verrouillage de la data structure en écriture */ if( ( status = DS_DataStruct_Lock_I( Root_Ptr, SMD_WRITE, &locked)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to lock the data structure: [%s] for writing, status : (%s)", Heap_Name, status); return( SMS_OK); } /* Vérification du heap sous-jacent à la data structure */ if( ( sm_status = SM_Heap_Check( heap_ptr, Error_Detected_Nb_Ptr, Error_Corrected_Nb_Ptr, Out)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to check the heap: [%s] for writing, status : (%s)", Heap_Name, sm_status); status= DSS_KO; } else { /* Vérification de la structure de noeuds */ LG_LOG_INFO_0( "Checking the node structure..."); if( ( nd_status = ND_DataStruct_Check( Root_Ptr, Error_Detected_Nb_Ptr, Error_Corrected_Nb_Ptr, Out)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to check the data structure: [%s], status: (%d)", Heap_Name, nd_status); status = DSS_KO; } else { /* On valide ou invalide la structure selon le résultat */ if( *Error_Corrected_Nb_Ptr == *Error_Detected_Nb_Ptr) { RootDesc_Ptr->Valid = TRUE; } else { RootDesc_Ptr->Valid = FALSE; } /* Affichage du résultat de la procédure de vérification */ if( *Error_Detected_Nb_Ptr) { if( *Error_Corrected_Nb_Ptr < *Error_Detected_Nb_Ptr) { LG_LOG_ERROR_2( "Error(s) detected: (%d) corected: (%d)", *Error_Detected_Nb_Ptr, *Error_Corrected_Nb_Ptr); status = SMS_KO; } else { LG_LOG_WARNING_2( "Error(s) detected: (%d) corected: (%d)", *Error_Detected_Nb_Ptr, *Error_Corrected_Nb_Ptr); status = SMS_OK; } } else { LG_LOG_INFO_0( "No error detected in the data structure"); status = SMS_OK; } } } /* Retour au mode de verrouillage précédent */ if( previous_lock == SMD_UNDEF) { if( ( status2 = DS_DataStruct_Unlock_I( Root_Ptr)) != DSS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure: [%s], status: (%d)", Heap_Name, status2); status = status2; } } else { if( ( status2 = DS_DataStruct_Lock_I( Root_Ptr, previous_lock, &locked)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to lock the data structure: [%s], status: (%d)", Heap_Name, status2); status = status2; } } return( status); } /*----------------------------------------------------------------------------*/ /* Convert a data structure indexe types */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /* (I) Index_Type_Ptr: Array of index type (List, tree, ...) */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Convert_I( NDT_Root *Root_Ptr, NDT_Index_Type *Index_Type_Ptr) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); DST_Status status; NDT_Status nd_status; /* On vérifie que la data structure est valide */ DS_STRUCT_VALID_CHECK( Root_Ptr, RootDesc_Ptr); /* On rend la structure invalide le temps de sa conversion */ RootDesc_Ptr->Valid = FALSE; /* Conversion de la node structure */ if( ( nd_status = ND_DataStruct_Convert( Root_Ptr, Index_Type_Ptr)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to convert the node structure, status: (%d)", nd_status); return( DSS_KO); } else { /* On rend la structure à nouveau valide */ RootDesc_Ptr->Valid = TRUE; return( DSS_OK); } } /*----------------------------------------------------------------------------*/ /* Reorganise a data structure indexes: */ /* - Sort a non-sorted list */ /* - Rebalance a non auto-balanced tree */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Reorg_I( NDT_Root *Root_Ptr) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); DST_Status status; NDT_Status nd_status; /* On vérifie que la data structure est valide */ DS_STRUCT_VALID_CHECK( Root_Ptr, RootDesc_Ptr); /* On rend la structure invalide, le temps de sa réorganisation */ RootDesc_Ptr->Valid = FALSE; /* Réorganisation de la node structure */ if( ( nd_status = ND_DataStruct_Reorg( Root_Ptr)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to reorg the node structure, status: (%d)", nd_status); return( DSS_KO); } else { /* On rend la structure à nouveau valide */ RootDesc_Ptr->Valid = TRUE; return( DSS_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 */ /*----------------------------------------------------------------------------*/ DST_Status DS_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) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); DST_Status status; NDT_Status nd_status; LG_LOG_INFO_5( "DatatStruct Heap_Name: [%s] Manager_Name: [%s] OpenSemId: (%d) Heap_Owner: [%s] Valid: [%s]", RootDesc_Ptr->Heap_Name, RootDesc_Ptr->Manager_Name, RootDesc_Ptr->OpenSemId, DSD_BOOL_VALUE_ASCII_GET( RootDesc_Ptr->Heap_Owner), DSD_BOOL_VALUE_ASCII_GET( RootDesc_Ptr->Valid)); /* On vérifie que la data structure est valide */ DS_STRUCT_VALID_CHECK( Root_Ptr, RootDesc_Ptr); /* Affichage des informations sur la structure */ if( ( nd_status = ND_DataStruct_Info_Print( Out, Root_Ptr, Recursive_Mode, Recursive_Depth, Recursive_Offset)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to print info about the data structure: (%d)", nd_status); return( DSS_KO); } /* Opened DS Print */ if( ( nd_status = ND_DataStruct_Info_Print( Out, OpenedDS_List, Recursive_Mode, Recursive_Depth, Recursive_Offset)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to print info about the data structure: (%d)", nd_status); return( DSS_KO); } if( ( nd_status = ND_DataStruct_Value_Print( Out, OpenedDS_List, Recursive_Mode, Recursive_Depth, Recursive_Offset)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to print values about the data structure: (%d)", nd_status); return( DSS_KO); } /* Dump SM */ SM_Library_Dump( stderr); return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Parcours de tous les noeuds d'une structure de données et exécution d'une */ /* commande sur chacun d'eux */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à parcourir*/ /* (I) Command : commande à exécuter sur chaque noeud traversé */ /* (I) Data : pointeur de données utilisateur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Traverse_I ( NDT_Root * Root, NDT_Command Command, void * Data ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int nb_detected, nb_corrected; /* On vérifie la structure */ /* nb_detected = nb_corrected = 0; if( ( status = DS_DataStruct_Check_L( Root_Ptr, &nb_detected, &nb_corrected, DS_stderr)) != DSS_OK) { LG_LOG_ERROR_0( "Unable to check the data structure"); return( status); } } /* On rend éventuellement la structure invalide le temps de sa traversée */ /* switch ((int)Command) { case NDD_CMD_PRINT_VALUE: break; default: RootDesc->Valid = FALSE; break; } /* Traversée de la node structure */ /* rc = ND_DataStruct_Traverse (Root, Command, Data); if (rc != NDS_OK) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Traverse : unable to traverse the node structure "); DS_Error_Print (); if (!DS_ERROR(rc)) RootDesc->Valid = TRUE; return rc; } /* On rend la structure valide */ /* RootDesc->Valid = TRUE; return DSS_OK; } /*----------------------------------------------------------------------------*/ /* Affichage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à afficher */ /* (I) Out : flux de sortie */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Print_I ( NDT_Root * Root, FILE * Out ) { return DS_DataStruct_Traverse_I (Root, NDD_CMD_PRINT_VALUE, Out); } /*----------------------------------------------------------------------------*/ /* Add a new value to a data structure */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /* (I) Value_Ptr: Value pointer */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Value_Add_I( NDT_Root *Root_Ptr, void *Value_Ptr) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); DST_Status status; NDT_Status nd_status; /* On vérifie que la data structure est valide */ DS_STRUCT_VALID_CHECK( Root_Ptr, RootDesc_Ptr); /* On rend la structure invalide le temps de l'ajout */ RootDesc_Ptr->Valid = FALSE; /* Ajout de la valeur */ if( ( nd_status = ND_DataStruct_Value_Add( Root_Ptr, Value_Ptr)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to add a value to the data structure: (%d)", nd_status); // if (!DS_ERROR(rc)) RootDesc->Valid = TRUE; return( DSS_KO); } /* On rend la structure à nouveau valide */ RootDesc_Ptr->Valid = TRUE; return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Suppression du premier noeud correspondant à une valeur donnée */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Reference_Value : pointeur sur la valeur de référence */ /* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimée */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Remove_I ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Value_Remove : unable to check the data structure"); DS_Error_Print (); return rc; } } /* On rend la structure invalide le temps de la suppression de valeur */ /* RootDesc->Valid = FALSE; /* Suppression du noeud correspondant à la valeur de référence */ /* rc = ND_Value_Remove (Root, Reference_Value, Removed_Value); if (rc != NDS_OK) { sprintf (DS_Error_Msg, "Error DS_Value_Remove : unable to remove a value from the data structure"); DS_Error_Print (); if (!DS_ERROR(rc)) RootDesc->Valid = TRUE; return rc; } /* On rend la structure à nouveau valide */ /* RootDesc->Valid = TRUE; return DSS_OK; } /*----------------------------------------------------------------------------*/ /* 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 */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Value_Print_I( FILE *Out_Ptr, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); DST_Status status; NDT_Status nd_status; va_list user_args; va_start( user_args, Recursive_Offset); /* On vérifie que la data structure est valide */ DS_STRUCT_VALID_CHECK( Root_Ptr, RootDesc_Ptr); /* Affichage de la node structure */ if( ( nd_status = ND_DataStruct_Value_Print_VI( Out_Ptr, Root_Ptr, Recursive_Mode, Recursive_Depth, Recursive_Offset, &user_args)) != NDS_OK) { LG_LOG_ERROR_1( "Unable to dump the node structure: (%d)", nd_status); status = DSS_KO; } else { status = DSS_OK; } va_end( user_args); return( status); } /*----------------------------------------------------------------------------*/ /* 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 DS_Index_Open_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Index_Type) { NDT_Status nd_status; if( ( nd_status = ND_Index_Open_I( Root_Ptr, Index_Id, Index_Type)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to open index: (%d), status: (%d)", Index_Id, nd_status); return( DSS_KO); } else { return( DSS_OK); } } /*----------------------------------------------------------------------------*/ /* Remove an Index */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /* (I) Index_Id: Id of the index */ /*----------------------------------------------------------------------------*/ NDT_Status DS_Index_Close_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { NDT_Status nd_status; if( ( nd_status = ND_Index_Close_I( Root_Ptr, Index_Id)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to close index: (%d), status: (%d)", Index_Id, nd_status); return( DSS_KO); } else { return( DSS_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 DS_Index_Convert_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Index_Type) { NDT_Status nd_status; if( ( nd_status = ND_Index_Convert_I( Root_Ptr, Index_Id, Index_Type)) != NDS_OK) { LG_LOG_ERROR_2( "Unable to convert index: (%d), status: (%d)", Index_Id, nd_status); return( DSS_KO); } else { return( DSS_OK); } } /*----------------------------------------------------------------------------*/ /* Récupération du premier noeud d'une structure */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine dont on cherche le premier noeud */ /* (O) Node : pointeur sur le noeud à récupérer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_First_Get_I ( NDT_Root * Root, NDT_Node ** Node ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_First_Get : unable to check the data structure"); DS_Error_Print (); return rc; } } /* Récupération du premier noeud */ /* rc = ND_Node_First_Get (Root, Node); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du dernier noeud d'une structure */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine dont on cherche le dernier noeud */ /* (O) Node : pointeur sur le noeud à récupérer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Last_Get_I ( NDT_Root * Root, NDT_Node ** Node ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Last_Get : unable to check the data structure"); DS_Error_Print (); return rc; } } /* Récupération du dernier noeud */ /* rc = ND_Node_Last_Get (Root, Node); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du noeud suivant */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le suivant */ /* (O) Next_Node : pointeur sur le noeud suivant */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Next_Get_I ( NDT_Node * Node, NDT_Node ** Next_Node ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Node->Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Node->Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Next_Get : unable to check the data structure"); DS_Error_Print (); return rc; } } /* Récupération du noeud suivant */ /* rc = ND_Node_Next_Get (Node, Next_Node); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du noeud précédant */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le précédant */ /* (O) Prev_Node : pointeur sur le noeud précédant */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Previous_Get_I ( NDT_Node * Node, NDT_Node ** Prev_Node ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Node->Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Node->Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Previous_Get : unable to check the data structure"); DS_Error_Print (); return rc; } } /* Récupération du noeud précédent */ /* rc = ND_Node_Previous_Get (Node, Prev_Node); return rc; } /*----------------------------------------------------------------------------*/ /* Ajout d'un noeud à une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Node : pointeur sur le noeud à ajouter */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Add_I ( NDT_Root * Root, NDT_Node * Node ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User); /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Add : unable to check the data structure"); DS_Error_Print (); return rc; } } /* On rend la structure invalide le temps de l'ajout */ /* RootDesc->Valid = FALSE; /* Ajout du noeud */ /* rc = ND_Node_Add (Root, Node); if (rc != NDS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Add : unable to add a node to the data structure"); DS_Error_Print (); if (!DS_ERROR(rc)) RootDesc->Valid = TRUE; return rc; } /* On rend la structure à nouveau valide */ /* RootDesc->Valid = TRUE; return DSS_OK; } /*----------------------------------------------------------------------------*/ /* Suppression d'un noeud dans une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud à supprimer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Remove_I ( NDT_Node * Node ) { DST_Status rc; NDT_Root * Root; DST_RootDesc * RootDesc = (DST_RootDesc *)(Node->Root->User); Root = Node->Root; /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Remove : unable to check the data structure"); DS_Error_Print (); return rc; } } /* On rend la structure invalide le temps de la suppression du noeud */ /* RootDesc->Valid = FALSE; /* Suppression dans la node structure */ /* rc = ND_Node_Remove (Node); if (rc != NDS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Remove : unable to remove a node from the structure"); DS_Error_Print (); if (!DS_ERROR(rc)) RootDesc->Valid = TRUE; return rc; } /* On rend la structure à nouveau valide */ /* RootDesc->Valid = TRUE; return DSS_OK; } /*----------------------------------------------------------------------------*/ /* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de l'abre */ /* (O) Node : adresse du pointeur sur le noeud à récuperer */ /* (I) Value : pointeur sur la valeur à rechercher */ /* (I) Data : pointeur de données */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Find_I ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data ) { DST_Status rc; DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User); *Node = NULL; /* On vérifie que la data structure est valide */ /* if (RootDesc->Valid == FALSE) { int Nb_Detected, Nb_Corrected; /* On vérifie la structure */ /* Nb_Detected = Nb_Corrected = 0; rc = DS_DataStruct_Check_L (Root, &Nb_Detected, &Nb_Corrected, DS_stderr); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Find : unable to check the data structure"); DS_Error_Print (); return rc; } } /* Recherche dans la node structure */ /* rc = ND_Node_Find (Root, Node, Value, Data); return rc; } /*----------------------------------------------------------------------------*/ /* Allocation d'une valeur d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (O) Value : adresse d'un pointeur sur la valeur à allouer */ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) ... : arguments relatifs à l'allocation de la valeur */ /*----------------------------------------------------------------------------*/ DST_Status DS_Value_Alloc_I( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, ... ) { DST_Status status; NDT_Status nd_status; va_list user_args; /* Récupération des arguments pour l'allocation de la valeur */ va_start( user_args, Root_Ptr); /* Appel du manager */ if( ( nd_status = ND_Manager_Exec( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, &user_args)) != NDS_OK) { LG_LOG_ERROR_1( "Unnable to alloc a new value: (%d)", nd_status); status = DSS_KO; } else { status = DSS_OK; } va_end( user_args); return( status); } /*----------------------------------------------------------------------------*/ /* Désallocation d'une valeur d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Value : pointeur sur la valeur à désallouer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Free_I ( NDT_Root * Root, void * Value ) { return ND_Value_Free (Root, Value); } /*----------------------------------------------------------------------------*/ /* Allocation de mémoire pour une structure de données : */ /*----------------------------------------------------------------------------*/ /* (O) Ptr : adresse du pointeur sur la zone de données allouée */ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Size : taille mémoire à allouer */ /*----------------------------------------------------------------------------*/ DST_Status DS_Alloc_I( void **Ptr_Ptr, NDT_Root *Root_Ptr, size_t Size) { return( DS_DataStruct_Alloc( Ptr_Ptr, Size, Root_Ptr->User_Ptr)); } /*----------------------------------------------------------------------------*/ /* Désallocation d'une ressource pour une structure de données : */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Ptr : pointeur sur la zone à désallouer */ /*----------------------------------------------------------------------------*/ DST_Status DS_Free_I( NDT_Root *Root_Ptr, void *Ptr) { return( DS_DataStruct_Free( Ptr, Root_Ptr->User_Ptr)); } /*----------------------------------------------------------------------------*/ /* FONCTIONS OPTIMISATION MOYENNE (DS_MODE = 1) */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Ouverture d'une instance de la librairie */ /*----------------------------------------------------------------------------*/ /* (I) Instance : numéro de l'instance de la librairie */ /* (I) Context : nom du contexte */ /* (I) Debug_Mode : mode d'affichage des messages d'erreur */ /*----------------------------------------------------------------------------*/ DST_Status DS_Library_Open_L( int Instance, const char *Context, DST_Flags Debug_Mode) { return( DS_Library_Open_I( Instance, Context, Debug_Mode)); } /*----------------------------------------------------------------------------*/ /* Fermeture de l'instance de la librairie */ /*----------------------------------------------------------------------------*/ DST_Status DS_Library_Close_L( void) { return DS_Library_Close_I(); } /*----------------------------------------------------------------------------*/ /* Définition de la sortie standard des messages d'erreur de la librairie */ /*----------------------------------------------------------------------------*/ /* (I) Out : flux de sortie des messages d'erreur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Library_Stderr_Set_L ( FILE * Out ) { return DS_Library_Stderr_Set_I (Out); } /*----------------------------------------------------------------------------*/ /* Création / ouverture d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) DS_Name : nom de la structure */ /* (O) Root : adresse du pointeur sur la racine de la structure */ /* (I) Type : type de la structure de données */ /* (I) Manager_FileName : nom du fichier qui définit les fonctions manager */ /* (I) Segment_Size : taille ds segments du heap sous-jacent */ /* (I) Open_Mode : mode d'ouverture de la structure */ /* (I) Own_Values : indique si la structure possède ses valeurs */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Open_L ( const char * DS_Name, NDT_Root ** Root, \ NDT_DataStruct_Type Type, const char * Manager_FileName, \ size_t Segment_Size, DST_Flags Open_Mode, int Own_Values ) { return DS_DataStruct_Open_I (DS_Name, Root, Type, Manager_FileName, Segment_Size, Open_Mode, Own_Values); } /*----------------------------------------------------------------------------*/ /* Verrouillage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /* (I) Lock_Mode : type de verrou à poser sur la structure */ /* (O) Locked : verrou effectif (TRUE ou FALSE) */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Lock_L ( NDT_Root * Root, DST_Flags Lock_Mode, int * Locked ) { return DS_DataStruct_Lock_I (Root, Lock_Mode, Locked); } /*----------------------------------------------------------------------------*/ /* Déverrouillage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Unlock_L ( NDT_Root * Root ) { return DS_DataStruct_Unlock_I (Root); } /*----------------------------------------------------------------------------*/ /* Fermeture d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à fermer */ /* (I) Close_Mode : mode de fermeture de la structure (destruction ou non) */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Close_L ( NDT_Root * Root, DST_Flags Close_Mode ) { return DS_DataStruct_Close_I (Root, Close_Mode); } /*----------------------------------------------------------------------------*/ /* Destroy all data of a data structure */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /*----------------------------------------------------------------------------*/ /* NDT_Status DS_DataStruct_Flush_L( NDT_Root *Root_Ptr) { DS_DataStruct_Flush_L( NDT_Root *Root_Ptr) } /*----------------------------------------------------------------------------*/ /* 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 */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Check_L( NDT_Root *Root_Ptr, int *Error_Detected_Nb_Ptr, int *Error_Corrected_Nb_Ptr, FILE *Out) { return( DS_DataStruct_Check_L( Root_Ptr, Error_Detected_Nb_Ptr, Error_Corrected_Nb_Ptr, Out)); } /*----------------------------------------------------------------------------*/ /* Convert a data structure indexe types */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /* (I) Index_Type_Ptr: Array of index type (List, tree, ...) */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Convert_L ( NDT_Root * Root, NDT_DataStruct_Type Target_Type ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en écriture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_WRITE, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Convert : unable to lock the data structure for writing"); DS_Error_Print (); return rc; } rc = DS_DataStruct_Convert_I (Root, Target_Type); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Reorganise a data structure indexes: */ /* - Sort a non-sorted list */ /* - Rebalance a non auto-balanced tree */ /*----------------------------------------------------------------------------*/ /* (I) Root_Ptr: Data structure pointer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Reorg_L ( NDT_Root * Root ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en écriture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_WRITE, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Reorg : unable to lock the data structure for writing"); DS_Error_Print (); return rc; } rc = DS_DataStruct_Reorg_I (Root); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Affiche les informations d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root: pointeur sur la racine de la structure de données */ /* (I) Out : flux de sortie de l'affichage */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Info_Print_L ( NDT_Root * Root, FILE * Out ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Info_Print : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_DataStruct_Info_Print_I (Root, Out); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Parcours de tous les noeuds d'une structure de données et exécution d'une */ /* commande sur chacun d'eux */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à parcourir*/ /* (I) Command : commande à exécuter sur chaque noeud traversé */ /* (I) Data : pointeur de données utilisateur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Traverse_L ( NDT_Root * Root, NDT_Command Command, void * Data ) { DST_Status rc; SMT_Flags Lock_Mode; int Locked; /* Définition du mode de verrouillage de la data structure selon le type de commande */ /* switch ((int)Command) { case NDD_CMD_PRINT_VALUE: Lock_Mode = SMD_READ; break; case NDD_CMD_DELETE_VALUE: default: Lock_Mode = SMD_WRITE; break; } /* Verrouillage de la data structure */ /* rc = DS_DataStruct_Lock_I (Root, Lock_Mode, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Traverse : unable to lock the data structure for %s", Lock_Mode == SMD_WRITE ? "writing" : "reading"); DS_Error_Print (); return rc; } rc = DS_DataStruct_Traverse_I (Root, Command, Data); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Affichage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à afficher */ /* (I) Out : flux de sortie */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Print_L ( NDT_Root * Root, FILE * Out ) { return DS_DataStruct_Traverse_L (Root, NDD_CMD_PRINT_VALUE, Out); } /*----------------------------------------------------------------------------*/ /* Affiche la structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /* (I) Out : flux de sortie */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Dump_L ( NDT_Root * Root, FILE * Out ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Dump : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_DataStruct_Dump_I (Root, Out); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du premier noeud d'une structure */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine dont on cherche le premier noeud */ /* (O) Node : pointeur sur le noeud à récupérer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_First_Get_L ( NDT_Root * Root, NDT_Node ** Node ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_First_Get : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_Node_First_Get_I (Root, Node); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du dernier noeud d'une structure */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine dont on cherche le dernier noeud */ /* (O) Node : pointeur sur le noeud à récupérer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Last_Get_L ( NDT_Root * Root, NDT_Node ** Node ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Last_Get : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_Node_Last_Get_I (Root, Node); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du noeud suivant */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le suivant */ /* (O) Next_Node : pointeur sur le noeud suivant */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Next_Get_L ( NDT_Node * Node, NDT_Node ** Next_Node ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Node->Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Next_Get : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_Node_Next_Get_I (Node, Next_Node); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Node->Root); return rc; } /*----------------------------------------------------------------------------*/ /* Récupération du noeud précédant */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le précédant */ /* (O) Prev_Node : pointeur sur le noeud précédant */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Previous_Get_L ( NDT_Node * Node, NDT_Node ** Prev_Node ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Node->Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Previous_Get : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_Node_Previous_Get_I (Node, Prev_Node); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Node->Root); return rc; } /*----------------------------------------------------------------------------*/ /* Ajout d'un noeud à une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Node : pointeur sur le noeud à ajouter */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Add_L ( NDT_Root * Root, NDT_Node * Node ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en écriture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_WRITE, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Add : unable to lock the data structure for writing"); DS_Error_Print (); return rc; } rc = DS_Node_Add_I (Root, Node); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Suppression d'un noeud dans une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud à supprimer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Remove_L ( NDT_Node * Node ) { DST_Status rc; int Locked; NDT_Root * Root = Node->Root; /* Verrouillage de la data structure en écriture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_WRITE, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Remove : unable to lock the data structure for writing"); DS_Error_Print (); return rc; } rc = DS_Node_Remove_I (Node); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de l'abre */ /* (O) Node : adresse du pointeur sur le noeud à récuperer */ /* (I) Value : pointeur sur la valeur à rechercher */ /* (I) Data : pointeur de données */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Find_L ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en lecture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_READ, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Node_Find : unable to lock the data structure for reading"); DS_Error_Print (); return rc; } rc = DS_Node_Find_I (Root, Node, Value, Data); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Allocation d'une valeur d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (O) Value : adresse d'un pointeur sur la valeur à allouer */ /* (I) ... : arguments relatifs à l'allocation de la valeur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Alloc_L ( NDT_Root * Root, void ** Value, ... ) { DST_Status rc; va_list Args; /* Récupération des arguments pour l'allocation de la valeur */ /* va_start (Args, Value); /* Appel du manager */ /* rc = ND_Manager_Exec (Root->Manager, NDD_CMD_MAKE_VALUE, Root, Value, Args); va_end (Args); return rc; } /*----------------------------------------------------------------------------*/ /* Ajout d'une valeur à une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Value : pointeur sur la valeur à ajouter à la structure de données */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Add_L ( NDT_Root * Root, void * Value ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en écriture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_WRITE, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Value_Add : unable to lock the data structure for writing"); DS_Error_Print (); return rc; } /* Ajout de la valeur */ /* rc = DS_Value_Add_I (Root, Value); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return rc; } /*----------------------------------------------------------------------------*/ /* Suppression du premier noeud correspondant à une valeur donnée */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Reference_Value : pointeur sur la valeur de référence */ /* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimée */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Remove_L ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value ) { DST_Status rc; int Locked; /* Verrouillage de la data structure en écriture */ /* rc = DS_DataStruct_Lock_I (Root, SMD_WRITE, &Locked); if (rc != DSS_OK) { sprintf (DS_Error_Msg, "Error DS_Value_Remove : unable to lock the data structure for writing"); DS_Error_Print (); return rc; } rc = DS_Value_Remove_I (Root, Reference_Value, Removed_Value); /* Déverrouillage de la data structure si besoin */ /* if (Locked == TRUE) DS_DataStruct_Unlock_I (Root); return DSS_OK; } /*----------------------------------------------------------------------------*/ /* Désallocation d'une valeur d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Value : pointeur sur la valeur à désallouer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Free_L ( NDT_Root * Root, void * Value ) { return ND_Value_Free (Root, Value); } /*----------------------------------------------------------------------------*/ /* Allocation de mémoire pour une structure de données : */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Size : taille mémoire à allouer */ /* (O) Ptr : adresse du pointeur sur la zone de données allouée */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Alloc_L ( NDT_Root * Root, size_t Size, void ** Ptr ) { return DS_DataStruct_Alloc (Size, Ptr, Root->User); } /*----------------------------------------------------------------------------*/ /* Désallocation d'une ressource pour une structure de données : */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Ptr : pointeur sur la zone à désallouer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Free_L ( NDT_Root * Root, void * Ptr ) { return DS_DataStruct_Free (Ptr, Root->User); } /*----------------------------------------------------------------------------*/ /* FONCTIONS SECURISEES (DS_MODE = 0) */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Ouverture d'une instance de la librairie */ /*----------------------------------------------------------------------------*/ /* (I) Instance : numéro de l'instance de la librairie */ /* (I) Context : nom du contexte */ /* (I) Debug_Mode : mode d'affichage des messages d'erreur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Library_Open_CL ( int Instance, const char * Context, DST_Flags Debug_Mode ) { return DS_Library_Open_I (Instance, Context, Debug_Mode ); } /*----------------------------------------------------------------------------*/ /* Fermeture de l'instance de la librairie */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Library_Close_CL ( void ) { return DS_Library_Close_I (); } /*----------------------------------------------------------------------------*/ /* Définition de la sortie standard des messages d'erreur de la librairie */ /*----------------------------------------------------------------------------*/ /* (I) Out : flux de sortie des messages d'erreur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Library_Stderr_Set_CL ( FILE * Out ) { return DS_Library_Stderr_Set_I (Out); } /*----------------------------------------------------------------------------*/ /* Création / ouverture d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) DS_Name : nom de la structure */ /* (O) Root : adresse du pointeur sur la racine de la structure */ /* (I) Type : type de la structure de données */ /* (I) Manager_FileName : nom du fichier qui définit les fonctions manager */ /* (I) Segment_Size : taille ds segments du heap sous-jacent */ /* (I) Open_Mode : mode d'ouverture de la structure */ /* (I) Own_Values : indique si la structure possède ses valeurs */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Open_CL ( const char * DS_Name, NDT_Root ** Root, \ NDT_DataStruct_Type Type, const char * Manager_FileName, \ size_t Segment_Size, DST_Flags Open_Mode, int Own_Values ) { if (!DS_Name) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Open : the data structure name is undefined"); DS_Error_Print (); return DSS_ERRAPI; } if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Open : the root address is null"); DS_Error_Print (); return DSS_ERRAPI; } if (Open_Mode & (DSD_CREATE | DSD_NEW) && !Manager_FileName) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Open : the manager file name must be defined in creation mode"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Open_I (DS_Name, Root, Type, Manager_FileName, Segment_Size, Open_Mode, Own_Values); } /*----------------------------------------------------------------------------*/ /* Verrouillage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /* (I) Lock_Mode : type de verrou à poser sur la structure */ /* (O) Locked : verrou effectif (TRUE ou FALSE) */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Lock_CL ( NDT_Root * Root, DST_Flags Lock_Mode, int * Locked ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Lock : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Locked) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Lock : the lock indicator address is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Lock_I (Root, Lock_Mode, Locked); } /*----------------------------------------------------------------------------*/ /* Déverrouillage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Unlock_CL ( NDT_Root * Root ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Unlock : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Unlock_I (Root); } /*----------------------------------------------------------------------------*/ /* Fermeture d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à fermer */ /* (I) Close_Mode : mode de fermeture de la structure (destruction ou non) */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Close_CL ( NDT_Root * Root, DST_Flags Close_Mode ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Close : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Close_I (Root, Close_Mode); } /*----------------------------------------------------------------------------*/ /* Affiche les informations d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root: pointeur sur la racine de la structure de données */ /* (I) Out : flux de sortie de l'affichage */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Info_Print_CL ( NDT_Root * Root, FILE * Out ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Info_Print : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Out) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Info_Print : the out stream is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Info_Print_L (Root, Out); } /*----------------------------------------------------------------------------*/ /* Réorganisation d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à réorganiser */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Reorg_CL ( NDT_Root * Root ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Reorg : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Reorg_L (Root); } /*----------------------------------------------------------------------------*/ /* Parcours de tous les noeuds d'une structure de données et exécution d'une */ /* commande sur chacun d'eux */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à parcourir*/ /* (I) Command : commande à exécuter sur chaque noeud traversé */ /* (I) Data : pointeur de données utilisateur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Traverse_CL ( NDT_Root * Root, NDT_Command Command, void * Data ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Traverse : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Traverse_L (Root, Command, Data); } /*----------------------------------------------------------------------------*/ /* Conversion d'une structure de données d'un type en un autre */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Target_Type : type de structure cible */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Convert_CL ( NDT_Root * Root, NDT_DataStruct_Type Target_Type ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Convert : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Convert_L (Root, Target_Type); } /*----------------------------------------------------------------------------*/ /* Affichage d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données à afficher */ /* (I) Out : flux de sortie */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Print_CL ( NDT_Root * Root, FILE * Out ) { return DS_DataStruct_Traverse_CL (Root, NDD_CMD_PRINT_VALUE, Out); } /*----------------------------------------------------------------------------*/ /* Fonction de vérification / réparation d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /* (O) Nb_Detected : pointeur sur le nombre d'erreurs détectées */ /* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrigées */ /* (I) Out : flux de sortie du rapport */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Check_CL ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) { if (!Root) { sprintf (DS_Error_Msg, "Error : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Nb_Detected || !Nb_Corrected) { sprintf (DS_Error_Msg, "Error : one of the error number address is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Out) { sprintf (DS_Error_Msg, "Error : the out stream is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Check_I (Root, Nb_Detected, Nb_Corrected, Out); } /*----------------------------------------------------------------------------*/ /* Affiche la structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure */ /* (I) Out : flux de sortie */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_DataStruct_Dump_CL ( NDT_Root * Root, FILE * Out ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Dump : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Out) { sprintf (DS_Error_Msg, "Error DS_DataStruct_Dump : the out stream is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_DataStruct_Dump_L (Root, Out); } /*----------------------------------------------------------------------------*/ /* Récupération du premier noeud d'une structure */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine dont on cherche le premier noeud */ /* (O) First_Node : adresse d'un pointeur sur le premier noeud à récupérer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_First_Get_CL ( NDT_Root * Root, NDT_Node ** First_Node ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Node_First_Get : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!First_Node) { sprintf (DS_Error_Msg, "Error DS_Node_First_Get : the first node address is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_First_Get_L (Root, First_Node); } /*----------------------------------------------------------------------------*/ /* Récupération du dernier noeud d'une structure */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la data structure */ /* (O) Last_Node : adresse d'un pointeur sur le dernier noeud */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Last_Get_CL ( NDT_Root * Root, NDT_Node ** Last_Node ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Node_Last_Get : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Last_Node) { sprintf (DS_Error_Msg, "Error DS_Node_Last_Get : the last node address is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_Last_Get_L (Root, Last_Node); } /*----------------------------------------------------------------------------*/ /* Récupération du noeud suivant */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le suivant */ /* (O) Next_Node : pointeur sur le noeud suivant */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Next_Get_CL ( NDT_Node * Node, NDT_Node ** Next_Node ) { if (!Node) { sprintf (DS_Error_Msg, "Error DS_Node_Next_Get : the node is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Next_Node) { sprintf (DS_Error_Msg, "Error DS_Node_Next_Get : the next node address is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_Next_Get_L (Node, Next_Node); } /*----------------------------------------------------------------------------*/ /* Récupération du noeud précédant */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le précédant */ /* (O) Prev_Node : pointeur sur le noeud précédant */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Previous_Get_CL ( NDT_Node * Node, NDT_Node ** Prev_Node ) { if (!Node) { sprintf (DS_Error_Msg, "Error DS_Node_Previous_Get : the node is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Prev_Node) { sprintf (DS_Error_Msg, "Error DS_Node_Previous_Get : the previous node address is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_Previous_Get_L (Node, Prev_Node); } /*----------------------------------------------------------------------------*/ /* Ajout d'un noeud à une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Node : pointeur sur le noeud à ajouter */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Add_CL ( NDT_Root * Root, NDT_Node * Node ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Node_Add : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Node) { sprintf (DS_Error_Msg, "Error DS_Node_Add : the node is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_Add_L (Root, Node); } /*----------------------------------------------------------------------------*/ /* Suppression d'un noeud dans une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud à supprimer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Remove_CL ( NDT_Node * Node ) { if (!Node) { sprintf (DS_Error_Msg, "Error DS_Node_Remove : the node is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_Remove_L (Node); } /*----------------------------------------------------------------------------*/ /* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de l'abre */ /* (O) Node : adresse du pointeur sur le noeud à récuperer */ /* (I) Value : pointeur sur la valeur à rechercher */ /* (I) Data : pointeur de données */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Node_Find_CL ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Node_Find : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Node) { sprintf (DS_Error_Msg, "Error DS_Node_Find : the node address is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Value) { sprintf (DS_Error_Msg, "Error DS_Node_Find : the value is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Node_Find_L (Root, Node, Value, Data); } /*----------------------------------------------------------------------------*/ /* Allocation d'une valeur d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (O) Value : adresse d'un pointeur sur la valeur à allouer */ /* (I) ... : arguments relatifs à l'allocation de la valeur */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Alloc_CL ( NDT_Root * Root, void ** Value, ... ) { DST_Status rc; va_list Args; if (!Root) { sprintf (DS_Error_Msg, "Error DS_Value_Alloc : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Value) { sprintf (DS_Error_Msg, "Error DS_Value_Alloc : the value address is null"); DS_Error_Print (); return DSS_ERRAPI; } /* Récupération des arguments pour l'allocation de la valeur */ /* va_start (Args, Value); /* Appel du manager */ /* rc = ND_Manager_Exec (Root->Manager, NDD_CMD_MAKE_VALUE, Root, Value, Args); va_end (Args); return rc; } /*----------------------------------------------------------------------------*/ /* Ajout d'une valeur à une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Value : pointeur sur la valeur à ajouter à la structure de données */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Add_CL ( NDT_Root * Root, void * Value ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Value_Add : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Value) { sprintf (DS_Error_Msg, "Error DS_Value_Add : the value is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Value_Add_L (Root, Value); } /*----------------------------------------------------------------------------*/ /* Suppression du premier noeud correspondant à une valeur donnée */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Reference_Value : pointeur sur la valeur de référence */ /* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimée */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Remove_CL ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Value_Remove : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Reference_Value) { sprintf (DS_Error_Msg, "Error DS_Value_Remove : the reference value is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Removed_Value) { sprintf (DS_Error_Msg, "Error DS_Value_Remove : the removed value adress is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Value_Remove_L (Root, Reference_Value, Removed_Value); } /*----------------------------------------------------------------------------*/ /* Désallocation d'une valeur d'une structure de données */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Value : pointeur sur la valeur à désallouer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Value_Free_CL ( NDT_Root * Root, void * Value ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Value_Free : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Value) { sprintf (DS_Error_Msg, "Error DS_Value_Free : the value is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Value_Free_L (Root, Value); } /*----------------------------------------------------------------------------*/ /* Allocation de mémoire pour une structure de données : */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Size : taille mémoire à allouer */ /* (O) Ptr : adresse du pointeur sur la zone de données allouée */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Alloc_CL ( NDT_Root * Root, size_t Size, void ** Ptr ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Alloc : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (Size <= 0) { sprintf (DS_Error_Msg, "Error DS_Alloc : the allocation size must be > 0"); DS_Error_Print (); return DSS_ERRAPI; } if (!Ptr) { sprintf (DS_Error_Msg, "Error DS_Alloc : the data pointer address is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Alloc_L (Root, Size, Ptr); } /*----------------------------------------------------------------------------*/ /* Désallocation d'une ressource pour une structure de données : */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Ptr : pointeur sur la zone à désallouer */ /*----------------------------------------------------------------------------*/ /* DST_Status DS_Free_CL ( NDT_Root * Root, void * Ptr ) { if (!Root) { sprintf (DS_Error_Msg, "Error DS_Free : the structure root is null"); DS_Error_Print (); return DSS_ERRAPI; } if (!Ptr) { sprintf (DS_Error_Msg, "Error DS_Free : the data pointer is null"); DS_Error_Print (); return DSS_ERRAPI; } return DS_Free_L (Root, Ptr); } /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* FONCTIONS PRIVEES */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Teste si une data structure a déjà été ouverte par le processus courant : */ /*----------------------------------------------------------------------------*/ /* (I) DS_Name : nom de la data structure */ /* (O) Root : adresse du pointeur sur la racine de la structure */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_IsOpen( NDT_Root **Root_Ptr_Ptr, char *DS_Name) { NDT_Status nd_status; DST_DataStruct to_find, *found_ptr; strncpy( to_find.Name, DS_Name, DSD_NAME_LEN); if( ( nd_status = ND_DataStruct_Value_Find( (void **)&found_ptr, OpenedDS_List, &to_find)) != NDS_OK) { LG_LOG_ERROR_2( "Can't lookup for opened data structure: [%s], status: (%d)", DS_Name, nd_status); return( DSS_KO); } else { if( found_ptr == NULL) { LG_LOG_TRACE_1( LGD_LOG_LEVEL_DEFAULT, "Data structure: [%s] not found", DS_Name); *Root_Ptr_Ptr = NULL; } else { LG_LOG_TRACE_1( LGD_LOG_LEVEL_DEFAULT, "Data structure: [%s] found", DS_Name); *Root_Ptr_Ptr = found_ptr->Root_Ptr; } } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Fonction d'allocation attachée à une structure de données : */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Alloc( void **Ptr_Ptr, size_t Size, void *Data_Ptr) { DST_Status status; SMT_Status sm_status; SMT_Heap *heap_ptr; int locked; DST_RootDesc *RootDesc = (DST_RootDesc *)Data_Ptr; // char *heap_name = RootDesc->Heap_Name; if( ( sm_status = SM_Heap_IsOpen( RootDesc->Heap_Name, &heap_ptr)) != SMS_YES) { LG_LOG_ERROR_1( "The data structure heap: [%s] is not open", RootDesc->Heap_Name); return( DSS_OK); } /* Verrouillage du heap en écriture */ if( ( sm_status = SM_Heap_Lock( heap_ptr, SMD_WRITE, &locked)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to lock the data structure heap: [%s] for writing, status: (%d)", RootDesc->Heap_Name, sm_status); return( DSS_OK); } /* Allocation du chunk */ if( ( sm_status = SM_Chunk_Alloc( heap_ptr, Size, Ptr_Ptr)) != SMS_OK) { LG_LOG_ERROR_3( "Unable to alloc size: (%d) in the heap: [%s] for writing, status: (%d)", Size, RootDesc->Heap_Name, sm_status); if( locked == TRUE) SM_Heap_Unlock( heap_ptr); return( DSS_KO); } /* Déverrouillage de la data structure si besoin */ if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); } } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Fonction de désallocation attachée à une structure de données : */ /*----------------------------------------------------------------------------*/ DST_Status DS_DataStruct_Free( void *Ptr, void *Data_Ptr) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)Data_Ptr; char *Heap_Name = RootDesc_Ptr->Heap_Name; DST_Status status; SMT_Status sm_status; SMT_Heap *heap_ptr; int locked; if( ( sm_status = SM_Heap_IsOpen( Heap_Name, &heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to check if heap: [%s] is open, status: (%d)", Heap_Name, sm_status); return( DSS_KO); } else { if( heap_ptr == NULL) { LG_LOG_ERROR_1( "DatatStructure heap: [%s] is not open", Heap_Name); return( DSS_KO); } } /* Verrouillage de la data structure en écriture */ if( ( sm_status = SM_Heap_Lock( heap_ptr, SMD_WRITE, &locked)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to lock the data structure heap: [%s] for writing, status: (%d)", heap_ptr->Name, sm_status); return( DSS_KO); } /* Désallocation du chunk */ if( ( sm_status = SM_Chunk_Free( heap_ptr, Ptr)) != SMS_OK) { LG_LOG_ERROR_3( "Unable to free a chuck: [%p] from the datastructure heap: [%s], status: [%s]", Ptr, heap_ptr->Name, sm_status); status = DSS_KO; } else { status = DSS_OK; } /* Déverrouillage de la data structure si besoin */ if( locked == TRUE) { if( ( sm_status = SM_Heap_Unlock( heap_ptr)) != SMS_OK) { LG_LOG_ERROR_2( "Unable to unlock the data structure heap: [%s], status: (%d)", heap_ptr->Name, sm_status); status = DSS_KO; } } return( status); } /*----------------------------------------------------------------------------*/ /* Routine d'affichage d'un message d'erreur */ /*----------------------------------------------------------------------------*/ /* void DS_Error_Print ( void ) { if (DS_stderr) fprintf (DS_stderr, "%s\n", DS_Error_Msg); } /*----------------------------------------------------------------------------*/ /* Pour préfixer les noms de heap avec l'identifiant de la librairie */ /*----------------------------------------------------------------------------*/ DST_Status DS_Name_Prefix( char *Prefixed_Name_Ptr, const char *Unprefixed_Name_Ptr) { snprintf( Prefixed_Name_Ptr, DSD_NAME_SIZE, "%s/%s", DS_PREFIX, Unprefixed_Name_Ptr); return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Création d'un sémaphore pour gérer l'ouverture d'une data structure */ /*----------------------------------------------------------------------------*/ DST_Status DS_Semaphore_Create ( NDT_Root *Root_Ptr) { DST_RootDesc *RootDesc_Ptr = (DST_RootDesc *)( Root_Ptr->User_Ptr); union semun sem_ctl; /* Création du sémaphore */ RootDesc_Ptr->OpenSemId = semget( IPC_PRIVATE, 1, ( 0777 | IPC_CREAT | IPC_EXCL)); if( RootDesc_Ptr->OpenSemId == -1) { switch( errno) { case ENOMEM: { LG_LOG_ERROR_0( "Not enough memory to create a new semaphore"); break; } case ENOSPC: { LG_LOG_ERROR_0( "The number of semaphores would exceeds the system-imposed limit"); break; } default: { LG_LOG_ERROR_1( "Unknown error: (%d) while creating a semaphore", errno); break; } } return( DSS_ERRSEM); } /* Initialisation du sémaphore à 0 */ sem_ctl.val = 0; if( semctl( RootDesc_Ptr->OpenSemId, 0, SETVAL, sem_ctl)) { LG_LOG_ERROR_1( "Unable to initialize the value of the semaphore: (%x)", RootDesc_Ptr->OpenSemId); semctl( RootDesc_Ptr->OpenSemId, 0, IPC_RMID, sem_ctl); return( DSS_ERRSEM); } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Opération sur un sémaphore */ /*----------------------------------------------------------------------------*/ DST_Status DS_Semaphore_Operate( int SemId, struct sembuf *Operations, unsigned int Nb_Oper) { if( semop( SemId, Operations, Nb_Oper) == -1) { switch( errno) { case EAGAIN: { LG_LOG_ERROR_0( "The operation would result in suspension of the calling process but the operations have been defined in no wait mode"); break; } case EACCES: { LG_LOG_ERROR_1( "Current process is not allowed to operate on semaphore: (%x)", SemId); break; } case EIDRM: { LG_LOG_ERROR_1( "Semaphore: (%x) does not exist", SemId); break; } case EINTR: { LG_LOG_ERROR_1( "A signal was received while operating on semaphore: (%x)", SemId); return( DSS_ERRSIG); } case EINVAL: { LG_LOG_ERROR_1( "The semaphore key: (%x) is incorrect or the number of operations which can be done in UNDO mode exceeds the system-imposed limit", SemId); break; } case ENOSPC: { LG_LOG_ERROR_0( "The maximum number of process which can operate on semaphore in UNDO mode has been reached"); break; } case ERANGE: { LG_LOG_ERROR_1( "The value of semaphore: (%x) has reached the system-imposed limit", SemId); break; } default: { LG_LOG_ERROR_2( "Unknown error: (%d) while operating on semaphore: (%x)", errno, SemId); break; } } return( DSS_ERRSEM); } return( DSS_OK); } /*----------------------------------------------------------------------------*/ /* Fonction manager de la liste des DS ouvertes */ /*----------------------------------------------------------------------------*/ NDT_Status DS_OpenedDS_List_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; LG_LOG_TRACE_1( LGD_LOG_LEVEL_DEFAULT, "Manager command: (%d) called", Command); 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 = "OpenedDS_List_Manager 2.0"; 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); */ ND_VA_ARG_GET( Opened_DataStruct_Ptr_Ptr, *Args_Ptr, DST_DataStruct **); ND_VA_LIST_OPEN( user_args, *Args_Ptr); ND_VA_ARG_GET( DS_Name, user_args, char *); ND_VA_ARG_GET( Root_Ptr, user_args, NDT_Root *); ND_VA_LIST_CLOSE( user_args); Command_Name = "NDD_CMD_VALUE_ALLOC"; LG_LOG_TRACE_1( LGD_LOG_LEVEL_DEFAULT, "Command: [%s] called", Command_Name); if( ( *Opened_DataStruct_Ptr_Ptr = ( DST_DataStruct *)malloc( sizeof( DST_DataStruct))) == NULL) { LG_LOG_ERROR_1( "Can't allocate value zise: (%d)", sizeof( DST_DataStruct)); return( DSS_KO); } else { strncpy( ( *Opened_DataStruct_Ptr_Ptr)->Name, DS_Name, DSD_NAME_LEN); ( *Opened_DataStruct_Ptr_Ptr)->Root_Ptr = Root_Ptr; LG_LOG_TRACE_2( LGD_LOG_LEVEL_DEFAULT, "Allocate new DS: Name: [%s] Root_Ptr: (%p)", DS_Name, Root_Ptr); return( DSS_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); */ ND_VA_ARG_GET( Opened_DataStruct_Ptr, *Args_Ptr, DST_DataStruct *); Command_Name = "NDD_CMD_VALUE_FREE"; LG_LOG_TRACE_1( LGD_LOG_LEVEL_DEFAULT, "Command: [%s] called", Command_Name); free( Opened_DataStruct_Ptr); /* DS_Free( Root_Ptr, 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); */ ND_VA_ARG_GET( DataStruct1_Ptr, *Args_Ptr, DST_DataStruct *); ND_VA_ARG_GET( DataStruct2_Ptr, *Args_Ptr, DST_DataStruct *); int comp; Command_Name = "NDD_CMD_VALUE_COMP"; switch( Index_Id) { case 0: { comp = strcmp( DataStruct1_Ptr->Name, DataStruct2_Ptr->Name); if( comp < 0) { return( NDS_LOWER); } else { if( comp > 0) { return( NDS_GREATER); } else { return( NDS_EQUAL); } } } default: { LG_LOG_ERROR_1( "Unknown comp index: (%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; */ 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); DST_DataStruct *DataStruct_Ptr = (DST_DataStruct *)Node_Ptr->Value; Command_Name = "NDD_CMD_VALUE_PRINT"; LG_LOG_INFO_2( "Name: [%s] Root: (%p)", DataStruct_Ptr->Name, DataStruct_Ptr->Root_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); */ 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); Command_Name = "NDD_CMD_INFO_PRINT"; return( NDS_OK); } case NDD_CMD_USER_TRAVERSE: { /* ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); ND_VA_LIST_OPEN( user_args, *Args_Ptr); ND_VA_ARG_GET( user_data, user_args, user_type); ND_VA_ARG_GET( ..., user_args, ...); ND_VA_LIST_CLOSE( user_args); void *Value_Ptr = Node_Ptr->Value; */ Command_Name = "NDD_CMD_USER_TRAVERSE"; /* return( NDS_OK); */ } default: { LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command); return( NDS_ERRAPI); } } LG_LOG_ERROR_2( "Manager internal error with command: (%d) name: [%s]", Command, Command_Name); return( NDS_OK); }