Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

niml_registry.c

Go to the documentation of this file.
00001 #include "niml_private.h"
00002 
00003 #undef INLINE
00004 #ifdef __GNUC__
00005 # define INLINE inline
00006 #else
00007 # define INLINE /*nada*/
00008 #endif
00009 
00010 /*---------------------------------------------------------------*/
00011 /*! Struct to hold on registered entry of a (idcode,pointer,name) triple. */
00012 
00013 typedef struct {
00014   char   idc[32];    /*!< idcode string                        */
00015   char   ipt[32];    /*!< string representation of a pointer   */
00016   size_t vlen   ;    /*!< number of bytes stored in vpt        */
00017   int    flags  ;    /*!< various bit flags                    */
00018   void  *vpt    ;    /*!< the pointer to data (equiv to ipt)   */
00019   char *name    ;    /*!< arbitrary name associated with above */
00020 } registry_entry ;
00021 
00022 /* Some masks and macros for "flags" */
00023 
00024 #undef  NIREG_PRIVATE_MALLOC
00025 #define NIREG_PRIVATE_MALLOC (1<<0)
00026 
00027 #undef  NIREG_isprivate
00028 #define NIREG_isprivate(rr) (((rr)->flags & NIREG_PRIVATE_MALLOC) != 0)
00029 
00030 #undef  NIREG_free
00031 #define NIREG_free(rr)                                \
00032   do{ if( !NIREG_isprivate(rr) ) free( (rr)->vpt ) ;  \
00033       free((void *)(rr)->name) ;                      \
00034       free((void *)(rr)) ;                            \
00035   } while(0)
00036 
00037 /*---------------------------------------------------------------*/
00038 /* These Htables index registry_entry by idcode and pointer.     */
00039 
00040 static Htable *registry_htable_idc = NULL ;  /* index by idcode */
00041 static Htable *registry_htable_ipt = NULL ;  /* index by pointer */
00042 
00043 /*---------------------------------------------------------------*/
00044 /*! Convert pointer to a string representation. */
00045 
00046 static INLINE void vpt_to_char( void *vpt , char *cpt )
00047 {
00048    sprintf( cpt , "%p" , vpt ) ;
00049 }
00050 
00051 /*---------------------------------------------------------------*/
00052 /*! Convert string representation to a pointer;
00053     this is the inverse function to vpt_to_char(). */
00054 
00055 static INLINE void * char_to_vpt( char *cpt )
00056 {
00057    void *vpt=NULL  ;
00058    if( cpt == NULL ) return NULL ;
00059    sscanf(cpt,"%p",&vpt) ;
00060    return vpt ;
00061 }
00062 
00063 /*-------------------------------------------------------------------*/
00064 /*! Create the (empty) underlying hash tables
00065     for indexing the list of registry elements. */
00066 
00067 static void init_registry(void)
00068 {
00069    if( registry_htable_ipt == NULL ){
00070      registry_htable_idc = new_Htable(131) ;
00071      registry_htable_ipt = new_Htable(131) ;
00072    }
00073    return ;
00074 }
00075 
00076 /*-------------------------------------------------------------------*/
00077 /*! Allocate memory with calloc(),
00078     and associate it with a given idcode and name string.
00079     - Return is NULL is idcode is already used, or if calloc() fails.
00080     - If len=0, then 1 byte will be malloc-ed, but this special
00081       case is a flag that no data will actually be available at
00082       this location -- cf. functions NI_registry_idcode_to_len()
00083       and NI_registry_ptr_to_len.
00084     - If name==NULL, the empty string "\0" is actually stored.
00085 ---------------------------------------------------------------------*/
00086 
00087 void * NI_registry_malloc( char *idcode , char *name , size_t len )
00088 {
00089    void *vpt ;
00090    int   lll ;
00091    registry_entry *rent ;  /* pay this or be evicted */
00092 
00093    init_registry() ;       /* setup empty hash tables, if needed */
00094 
00095    if( idcode == NULL || *idcode == '\0' ) return NULL ;
00096 
00097    /* check to see if already have this idcode */
00098 
00099    vpt = findin_Htable( idcode , registry_htable_idc ) ;
00100    if( vpt != NULL ) return NULL ;               /* bad */
00101 
00102    /* allocate space for result of this function */
00103 
00104    lll = (len == 0) ? 4 : len ;
00105    vpt = calloc(1,lll) ;
00106    if( vpt == NULL ) return NULL ;               /* bad */
00107 
00108    if( len == 0 ){ char *cpt=(char *)vpt; *cpt = '\0'; }
00109 
00110    /* make the registry entry for this doohicky */
00111 
00112    rent = calloc(1,sizeof(registry_entry)) ;
00113    NI_strncpy( rent->idc , idcode , 32 ) ;               /* copy idcode */
00114    rent->vpt  = vpt ;                              /* copy data pointer */
00115    rent->vlen = len ;                                    /* save length */
00116    vpt_to_char( vpt , rent->ipt ) ;   /* string version of data pointer */
00117    if( name == NULL ) name = "\0" ;
00118    rent->name  = strdup(name) ;                            /* copy name */
00119    rent->flags = 0 ;                                      /* init flags */
00120 
00121    /* and index this new registry entry under the idcode and the pointer */
00122 
00123    addto_Htable( rent->idc , (void *)rent , registry_htable_idc ) ;
00124    addto_Htable( rent->ipt , (void *)rent , registry_htable_ipt ) ;
00125 
00126    return vpt ;   /* give the user the pointer he asked for */
00127 }
00128 
00129 /*-------------------------------------------------------------------*/
00130 /*! Associate a given pointer (non-NULL) with idcode and name string.
00131      - Return value is vpt if things are OK, NULL if they are not.
00132      - Not OK if vpt==NULL, or idcode is already in table.
00133      - If vpt is already in table, then it's old entry will.
00134        be lost and the new idcode will win (that is, you can't have
00135        two different idcodes associated with the same data pointer).
00136 ---------------------------------------------------------------------*/
00137 
00138 void * NI_registry_add( char *idcode , char *name , void *vpt )
00139 {
00140    void *xpt ;
00141    registry_entry *rent ;  /* pay this or be evicted */
00142 
00143    init_registry() ;       /* setup empty hash tables, if needed */
00144 
00145    if( idcode == NULL || *idcode == '\0' || vpt == NULL ) return NULL ;
00146 
00147    /* check to see if already have this idcode */
00148 
00149    xpt = findin_Htable( idcode , registry_htable_idc ) ;
00150    if( xpt != NULL ) return NULL ;  /* bad */
00151 
00152    /* make the registry entry for this doohicky */
00153 
00154    rent = calloc(1,sizeof(registry_entry)) ;
00155    NI_strncpy( rent->idc , idcode , 32 ) ;               /* copy idcode */
00156    rent->vpt  = vpt ;                              /* copy data pointer */
00157    rent->vlen = 0   ;                                     /* set length */
00158    vpt_to_char( vpt , rent->ipt ) ;   /* string version of data pointer */
00159    if( name == NULL ) name = "\0" ;
00160    rent->name  = strdup(name) ;                            /* copy name */
00161    rent->flags = NIREG_PRIVATE_MALLOC ;                   /* init flags */
00162 
00163    /* and index this new registry entry under the idcode and the pointer */
00164 
00165    addto_Htable( rent->idc , (void *)rent , registry_htable_idc ) ;
00166    addto_Htable( rent->ipt , (void *)rent , registry_htable_ipt ) ;
00167 
00168    return vpt ;   /* give the user the pointer he asked for */
00169 }
00170 
00171 /*-------------------------------------------------------------------*/
00172 /*! Like realloc(), but also updates the indexes.
00173     - However, you can't call this with vpt==NULL,
00174       since you aren't supplying an idcode.
00175     - Calling this with newlen==0 is like calling NI_registry_malloc()
00176       with len==0.
00177     - Calling this with an entry created via NI_registry_add()
00178       will return NULL, since that function is used for registering
00179       things that aren't to be malloc-ed by this library.
00180 ---------------------------------------------------------------------*/
00181 
00182 void * NI_registry_realloc( void *vpt , size_t newlen )
00183 {
00184    char ipt[32] ;
00185    void *vpt_new ;
00186    int lll ;
00187    registry_entry *rent ;
00188 
00189    if( vpt == NULL || registry_htable_ipt == NULL ) return NULL ;
00190 
00191    /* look up the pointer in the index */
00192 
00193    vpt_to_char( vpt , ipt ) ;
00194    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00195    if( rent == NULL          ) return NULL ;   /* not found!? */
00196    if( NIREG_isprivate(rent) ) return NULL ;   /* bad user */
00197 
00198    lll = (newlen == 0) ? 4 : newlen ;
00199    vpt_new = realloc( vpt , lll ) ;  /* get new allocation */
00200    if( vpt_new == NULL ) return NULL ;  /* bad */
00201    if( vpt_new == vpt  ) return vpt  ;  /* no change! */
00202 
00203    /* remove the pointer-based entry from the index,
00204       then make a new pointer index                 */
00205 
00206    removefrom_Htable( ipt , registry_htable_ipt ) ;
00207 
00208    rent->vpt  = vpt_new ;
00209    rent->vlen = newlen ;
00210    vpt_to_char( vpt , rent->ipt ) ;
00211    addto_Htable( rent->ipt , (void *)rent , registry_htable_ipt ) ;
00212 
00213    return vpt_new ;  /* give back the new pointer */
00214 }
00215 
00216 /*-------------------------------------------------------------------*/
00217 /*! For something added with NI_registry_add(), lets you replace
00218     the pointer with some other pointer.
00219 ---------------------------------------------------------------------*/
00220 
00221 void * NI_registry_replace( void *vpt , void *vpt_new )
00222 {
00223    char ipt[32] ;
00224    registry_entry *rent ;
00225 
00226    if( vpt == NULL || vpt_new == NULL ||
00227        registry_htable_ipt == NULL      ) return NULL ;
00228 
00229    if( vpt == vpt_new ) return vpt ;
00230 
00231    /* look up the pointer in the index */
00232 
00233    vpt_to_char( vpt , ipt ) ;
00234    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00235    if( rent == NULL ) return NULL ;   /* not found!? */
00236 
00237    if( !NIREG_isprivate(rent) ) free((void *)vpt) ;
00238 
00239    /* remove the pointer-based entry from the index,
00240       then make a new pointer index                 */
00241 
00242    removefrom_Htable( ipt , registry_htable_ipt ) ;
00243 
00244    rent->vpt  = vpt_new ;
00245    rent->vlen = 0 ;                   /* len is unknown here */
00246    vpt_to_char( vpt , rent->ipt ) ;
00247    addto_Htable( rent->ipt , (void *)rent , registry_htable_ipt ) ;
00248    rent->flags = NIREG_PRIVATE_MALLOC ;
00249 
00250    return vpt_new ;  /* give back the new pointer */
00251 }
00252 
00253 /*-------------------------------------------------------------------*/
00254 /* Like free() but also de-indexes the thing. */
00255 
00256 void NI_registry_free( void *vpt )
00257 {
00258    char ipt[32] ;
00259    registry_entry *rent ;
00260 
00261    if( vpt == NULL || registry_htable_ipt == NULL ) return ;
00262 
00263    /* look for the pointer in the index */
00264 
00265    vpt_to_char( vpt , ipt ) ;
00266    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00267    if( rent == NULL ) return ;   /* stupid users must be punished somehow */
00268 
00269    removefrom_Htable( rent->ipt , registry_htable_ipt ) ;
00270    removefrom_Htable( rent->idc , registry_htable_idc ) ;
00271    NIREG_free( rent ) ;
00272    return ;
00273 }
00274 
00275 /*-------------------------------------------------------------------*/
00276 /*! Given an idcode, get the data pointer that goes with it. */
00277 
00278 void * NI_registry_idcode_to_ptr( char *idcode )
00279 {
00280    registry_entry *rent ;
00281 
00282    rent = (registry_entry *) findin_Htable( idcode , registry_htable_idc ) ;
00283    if( rent == NULL ) return NULL ;
00284    return rent->vpt ;
00285 }
00286 
00287 /*-------------------------------------------------------------------*/
00288 /*! Given an idcode, get the data length that goes with it.
00289     Note that 0 is returned if the data ptr was setup with len=0
00290     *OR* if the idcode can't be found in the registry.
00291 ---------------------------------------------------------------------*/
00292 
00293 size_t NI_registry_idcode_to_len( char *idcode )
00294 {
00295    registry_entry *rent ;
00296 
00297    rent = (registry_entry *) findin_Htable( idcode , registry_htable_idc ) ;
00298    if( rent == NULL ) return 0 ;
00299    return rent->vlen ;
00300 }
00301 
00302 /*-------------------------------------------------------------------*/
00303 /*! Given a data pointer, get the data length that goes with it.
00304     Note that 0 is returned if the data ptr was setup with len=0
00305     *OR* if the data ptr can't be found in the registry.
00306 ---------------------------------------------------------------------*/
00307 
00308 size_t NI_registry_ptr_to_len( void *vpt )
00309 {
00310    char ipt[32] ;
00311    registry_entry *rent ;
00312 
00313    if( vpt == NULL || registry_htable_ipt == NULL ) return ;
00314 
00315    vpt_to_char( vpt , ipt ) ;
00316    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00317    if( rent == NULL ) return 0 ;
00318    return rent->vlen ;
00319 }
00320 
00321 /*-------------------------------------------------------------------*/
00322 /*! Given an idcode, get the name string that went with it.
00323     This is the pointer into the internal registry_entry struct, so
00324     don't modify it!
00325 ---------------------------------------------------------------------*/
00326 
00327 char * NI_registry_idcode_to_name( char *idcode )
00328 {
00329    registry_entry *rent ;
00330 
00331    rent = (registry_entry *) findin_Htable( idcode , registry_htable_idc ) ;
00332    if( rent == NULL ) return NULL ;
00333    return rent->name ;
00334 }
00335 
00336 /*-------------------------------------------------------------------*/
00337 /*! Given a data pointer, return a pointer to the idcode that
00338     corresponds.  Don't modify this!
00339 ---------------------------------------------------------------------*/
00340 
00341 char * NI_registry_ptr_to_idcode( void *vpt )
00342 {
00343    char ipt[32] ;
00344    registry_entry *rent ;
00345 
00346    if( vpt == NULL || registry_htable_ipt == NULL ) return ;
00347 
00348    vpt_to_char( vpt , ipt ) ;
00349    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00350    if( rent == NULL ) return ;
00351    return rent->idc ;
00352 }
00353 
00354 /*-------------------------------------------------------------------*/
00355 /*! Given a data pointer, get the name string that corresponds. */
00356 
00357 char * NI_registry_ptr_to_name( void *vpt )
00358 {
00359    char ipt[32] ;
00360    registry_entry *rent ;
00361 
00362    if( vpt == NULL || registry_htable_ipt == NULL ) return ;
00363 
00364    vpt_to_char( vpt , ipt ) ;
00365    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00366    if( rent == NULL ) return ;
00367    return rent->name ;
00368 }
00369 
00370 /*-------------------------------------------------------------------*/
00371 /*! Given an idcode, modify the name string that goes with it. */
00372 
00373 void NI_registry_idcode_altername( char *idcode , char *newname )
00374 {
00375    registry_entry *rent ;
00376 
00377    rent = (registry_entry *) findin_Htable( idcode , registry_htable_idc ) ;
00378    if( rent == NULL ) return ;
00379    free((void *)rent->name) ;
00380    if( newname == NULL ) newname = "\0" ;
00381    rent->name = strdup(newname) ;
00382    return ;
00383 }
00384 
00385 /*-------------------------------------------------------------------*/
00386 /*! Given a data pointer, alter the name string that goes with it. */
00387 
00388 void NI_registry_ptr_altername( void *vpt , char *newname )
00389 {
00390    char ipt[32] ;
00391    registry_entry *rent ;
00392 
00393    if( vpt == NULL || registry_htable_ipt == NULL ) return ;
00394 
00395    vpt_to_char( vpt , ipt ) ;
00396    rent = (registry_entry *) findin_Htable( ipt , registry_htable_ipt ) ;
00397    if( rent == NULL ) return ;
00398    free((void *)rent->name) ;
00399    if( newname == NULL ) newname = "\0" ;
00400    rent->name = strdup(newname) ;
00401    return ;
00402 }
 

Powered by Plone

This site conforms to the following standards: