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_struct.c

Go to the documentation of this file.
00001 #include "niml_private.h"
00002 
00003 /*-----------------------------------------------------------*/
00004 /*! Holds the table of all registered structs. */
00005 
00006 static Htable *ni_struct_table=NULL ;
00007 
00008 /*-----------------------------------------------------------*/
00009 /*! Register a struct by its idcode (if it has one). */
00010 
00011 void NI_register_struct( void *ndd )
00012 {
00013    NI_struct *nd = (NI_struct *)ndd ;
00014    void *vp ;
00015 
00016    /* can't register without idcode */
00017 
00018    if( nd == NULL || nd->idcode == NULL ) return ;
00019 
00020    /* 1st time in ==> create hash table */
00021 
00022    if( ni_struct_table == NULL )
00023      ni_struct_table = new_Htable( 1031 ) ;
00024 
00025    /* see if it already is registered */
00026 
00027    vp = findin_Htable( nd->idcode , ni_struct_table ) ;
00028    if( vp != NULL ) return ;  /* duplicate entry */
00029 
00030    /* OK, add it to the table */
00031 
00032    addto_Htable( nd->idcode , nd , ni_struct_table ) ;
00033    return ;
00034 }
00035 
00036 /*-----------------------------------------------------------*/
00037 /*! Find a struct by its idcode. */
00038 
00039 void * NI_find_struct( char *idcode )
00040 {
00041    void *vp ;
00042    if( idcode == NULL ) return NULL ; /* nothing to do */
00043    vp = findin_Htable( idcode , ni_struct_table ) ;
00044    return vp ;
00045 }
00046 
00047 /*-----------------------------------------------------------*/
00048 /*! Remove a struct from the table. */
00049 
00050 void NI_unregister_struct( void *ndd )
00051 {
00052    NI_struct *nd = (NI_struct *)ndd ;
00053    if( nd == NULL || nd->idcode == NULL ) return ;
00054    removefrom_Htable( nd->idcode , ni_struct_table ) ;
00055    return ;
00056 }
00057 
00058 /*-----------------------------------------------------------*/
00059 /*! Return a copy of the pointer to the struct,
00060     also incrementing its reference counter.    */
00061 
00062 void * NI_pointto_struct( void *ndd )
00063 {
00064    NI_struct *nd = (NI_struct *)ndd ;
00065    if( nd == NULL ) return NULL ;
00066    nd->nref ++ ;
00067    return (void *)nd ;
00068 }
00069 
00070 /*-----------------------------------------------------------*/
00071 /* This macro does the basic stuff necessary to delete a
00072    struct from the hash table and from memory.  It is used
00073    at the very end of the NI_free_struct() function.
00074    Type specific code is also needed to delete any memory
00075    used by sub-structs or sub-arrays.
00076 -------------------------------------------------------------*/
00077 
00078 #undef  DELETE_STRUCT
00079 #define DELETE_STRUCT(nq)              \
00080  do{ NI_unregister_struct(nq);         \
00081      NI_free(nq->idcode) ;             \
00082      NI_free(nq->name)   ;             \
00083      NI_free(nq)         ; } while(0)
00084 
00085 /*-----------------------------------------------------------*/
00086 /*! Decrement the reference counter, and destroy the struct
00087     (recursively in some cases) if the counter goes to zero.
00088 -------------------------------------------------------------*/
00089 
00090 void NI_free_struct( void *ndd )
00091 {
00092    NI_struct *nd = (NI_struct *)ndd ;
00093    if( nd == NULL ) return ;
00094 
00095    /* decrementation */
00096 
00097    nd->nref -- ;
00098    if( nd->nref > 0 ) return ;      /* keep it */
00099 
00100    /* OK, blot it from the universe */
00101 
00102    switch( nd->type ){              /* N.B.: there is no default */
00103 
00104      case NI_STRUCT_TYPE:         /* These types have no sub-structs */
00105      case NI_FLOAT_ONE_TYPE:      /* or sub-arrays that need deleting */
00106      case NI_AFFINE_3DMAP_TYPE:
00107      case NI_RECT_DOMAIN_TYPE:
00108        DELETE_STRUCT(nd) ;
00109      break ;
00110 
00111      case NI_STATISTIC_TYPE:{
00112        NI_statistic *ns = (NI_statistic *)nd ;
00113        NI_index_t ii ;
00114        if( ns->param != NULL ){
00115          for( ii=0 ; ii < ns->param_num ; ii++ )
00116            NI_free_struct( ns->param[ii] ) ;    /* recursion */
00117          NI_free(ns->param) ;
00118        }
00119      }
00120      DELETE_STRUCT(nd) ;
00121      break ;
00122 
00123      case NI_VECTOR_TYPE:
00124      case NI_BYTE_VECTOR_TYPE:
00125      case NI_SHORT_VECTOR_TYPE:
00126      case NI_INT_VECTOR_TYPE:
00127      case NI_FLOAT_VECTOR_TYPE:
00128      case NI_DOUBLE_VECTOR_TYPE:
00129      case NI_COMPLEX_VECTOR_TYPE:
00130      case NI_RGB_VECTOR_TYPE:
00131      case NI_RGBA_VECTOR_TYPE:{
00132        NI_vector *nv = (NI_vector *)nd ;
00133        NI_free( nv->vec ) ;
00134        NI_free( nv->vec_range ) ;
00135        NI_free( nv->statistic ) ;
00136      }
00137      DELETE_STRUCT(nd) ;
00138      break ;
00139 
00140      case NI_STRING_VECTOR_TYPE:{
00141        NI_string_vector *nv = (NI_string_vector *)nd ;
00142        NI_index_t ii ;
00143        if( nv->vec != NULL ){
00144          for( ii=0 ; ii < nv->vec_len ; ii++ )
00145            NI_free( nv->vec[ii] ) ;
00146          NI_free( nv->vec ) ;
00147        }
00148        /* vec_range not used for string vectors */
00149        /* statistic not used for string vectors */
00150      }
00151      DELETE_STRUCT(nd) ;
00152      break ;
00153 
00154      case NI_POINTS_DOMAIN_TYPE:{
00155        NI_points_domain *np = (NI_points_domain *)nd ;
00156        NI_free( np->id ) ;
00157        NI_free( np->x  ) ;
00158        NI_free( np->y  ) ;
00159        NI_free( np->z  ) ;
00160      }
00161      DELETE_STRUCT(nd) ;
00162      break ;
00163 
00164      case NI_DATASET_TYPE:{
00165        NI_dataset *nn = (NI_dataset *)nd ;
00166        if( nn->vec != NULL ){
00167          NI_index_t nv , ii ;
00168          nv = NI_dataset_vecnum(nn) ;
00169          for( ii=0 ; ii < nv ; ii++ )
00170            NI_free_struct( nn->vec[ii] ) ;  /* recursion */
00171          NI_free( nn->vec ) ;
00172        }
00173        NI_free_struct( nn->domain ) ;       /* recursion */
00174      }
00175      DELETE_STRUCT(nd) ;
00176      break ;
00177 
00178    }
00179 
00180    return ;
00181 }
00182 
00183 /*-----------------------------------------------------------*/
00184 /* This macro copies the basic elements of a struct,
00185    from struct qold to struct qnew.  Of course, the new
00186    struct gets a new idcode.  This macro may be used after
00187    creating a new struct with NI_new(), for example.
00188 -------------------------------------------------------------*/
00189 
00190 #undef  COPY_BASIC_STRUCT
00191 #define COPY_BASIC_STRUCT(qnew,qold)               \
00192  do{ (qnew)->type = (qold)->type ;                 \
00193      (qnew)->nref = 1 ;                            \
00194      (qnew)->idcode = UNIQ_idcode() ;              \
00195      NI_register_struct( (qnew) ) ;                \
00196      (qnew)->name = NI_strdup((qold)->name) ;      \
00197  } while(0)
00198 
00199 /*-----------------------------------------------------------*/
00200 /* This macro makes a new struct of type TTYPE, copies
00201    the basic elements, and points ndnew to the new struct,
00202    for eventual return from NI_copy_struct().  This macro
00203    is used only in that function.
00204 -------------------------------------------------------------*/
00205 
00206 #undef DUPLICATE_STRUCT
00207 #define DUPLICATE_STRUCT(TTYPE)                    \
00208    TTYPE *nn = NI_new(TTYPE) ;                     \
00209    TTYPE *qq = (TTYPE *)nd ;                       \
00210    COPY_BASIC_STRUCT(nn,qq) ;                      \
00211    ndnew = (NI_struct *)nn
00212 
00213 /*-----------------------------------------------------------*/
00214 /*! Make a copy of a struct, as opposed to a new
00215     reference (which is what NI_pointto_struct() does).
00216 -------------------------------------------------------------*/
00217 
00218 void * NI_copy_struct( void *ndd )
00219 {
00220    NI_struct *nd = (NI_struct *)ndd ;
00221    NI_struct *ndnew=NULL ;
00222 
00223    if( nd == NULL ) return NULL ;  /* bad input :-( */
00224 
00225    switch( nd->type ){                 /* N.B.: there is no default */
00226 
00227      case NI_STRUCT_TYPE:{
00228        DUPLICATE_STRUCT(NI_struct) ;
00229      }
00230      break ;
00231 
00232      case NI_FLOAT_ONE_TYPE:{
00233        DUPLICATE_STRUCT(NI_float_one) ;
00234        nn->val = qq->val ;
00235      }
00236      break ;
00237 
00238      case NI_AFFINE_3DMAP_TYPE:{
00239        DUPLICATE_STRUCT(NI_affine_3dmap) ;
00240        nn->mat[0][0] = qq->mat[0][0]; nn->mat[0][1] = qq->mat[0][1];
00241        nn->mat[0][2] = qq->mat[0][2]; nn->mat[0][3] = qq->mat[0][3];
00242        nn->mat[1][0] = qq->mat[1][0]; nn->mat[1][1] = qq->mat[1][1];
00243        nn->mat[1][2] = qq->mat[1][2]; nn->mat[1][3] = qq->mat[1][3];
00244        nn->mat[2][0] = qq->mat[2][0]; nn->mat[2][1] = qq->mat[2][1];
00245        nn->mat[2][2] = qq->mat[2][2]; nn->mat[2][3] = qq->mat[2][3];
00246        nn->mat[3][0] = qq->mat[3][0]; nn->mat[3][1] = qq->mat[3][1];
00247        nn->mat[3][2] = qq->mat[3][2]; nn->mat[3][3] = qq->mat[3][3];
00248      }
00249      break ;
00250 
00251      case NI_RECT_DOMAIN_TYPE:{
00252        DUPLICATE_STRUCT(NI_rect_domain) ;
00253        nn->nx = qq->nx; nn->ny = qq->ny; nn->nz = qq->nz; nn->nt = qq->nt;
00254        nn->dx = qq->dx; nn->dy = qq->dy; nn->dz = qq->dz; nn->dt = qq->dt;
00255        nn->xo = qq->xo; nn->yo = qq->yo; nn->zo = qq->zo; nn->to = qq->to;
00256      }
00257      break ;
00258 
00259      case NI_STATISTIC_TYPE:{
00260        NI_index_t ii ;
00261        DUPLICATE_STRUCT(NI_statistic) ;
00262        nn->statcode = qq->statcode ;
00263        nn->param_num = qq->param_num ;
00264        if( qq->param != NULL ){
00265          nn->param = NI_malloc(NI_struct*, sizeof(NI_struct *)*nn->param_num) ;
00266          for( ii=0 ; ii < nn->param_num ; ii++ )
00267            nn->param[ii] = (NI_struct *)NI_copy_struct( qq->param[ii] ) ; /* recursion */
00268        } else {
00269          nn->param = NULL ;
00270        }
00271      }
00272      break ;
00273 
00274      case NI_VECTOR_TYPE:
00275      case NI_BYTE_VECTOR_TYPE:
00276      case NI_SHORT_VECTOR_TYPE:
00277      case NI_INT_VECTOR_TYPE:
00278      case NI_FLOAT_VECTOR_TYPE:
00279      case NI_DOUBLE_VECTOR_TYPE:
00280      case NI_COMPLEX_VECTOR_TYPE:
00281      case NI_RGB_VECTOR_TYPE:
00282      case NI_RGBA_VECTOR_TYPE:{
00283        NI_index_t ii ;
00284        DUPLICATE_STRUCT(NI_vector) ;
00285        nn->vec_len = qq->vec_len ;
00286        nn->vec_typ = qq->vec_typ ;
00287        if( qq->vec != NULL ){                                /* copy array */
00288          ii = nn->vec_len * NI_datatype_size(nn->vec_typ) ;
00289          nn->vec = NI_malloc(void, ii) ;
00290          memcpy( nn->vec , qq->vec , ii ) ;
00291        } else {
00292          nn->vec = NULL ;
00293        }
00294        if( qq->vec_range != NULL ){                          /* copy array */
00295          ii = 2 * NI_datatype_size(nn->vec_typ) ;
00296          nn->vec_range = NI_malloc(void, ii) ;
00297          memcpy( nn->vec_range , qq->vec_range , ii ) ;
00298        } else {
00299          nn->vec_range = NULL ;
00300        }
00301        nn->statistic = (NI_statistic *)NI_copy_struct( qq->statistic ) ;   /* recursion */
00302      }
00303      break ;
00304 
00305      case NI_STRING_VECTOR_TYPE:{
00306        NI_index_t ii ;
00307        DUPLICATE_STRUCT(NI_string_vector) ;
00308        nn->vec_len = qq->vec_len ;
00309        nn->vec_typ = qq->vec_typ ;
00310        if( qq->vec != NULL ){                                /* copy array */
00311          nn->vec = NI_malloc(char*, sizeof(char *)*nn->vec_len) ;
00312          for( ii=0 ; ii < nn->vec_len ; ii++ )
00313            nn->vec[ii] = NI_strdup(qq->vec[ii]) ;
00314        } else {
00315          nn->vec = NULL ;
00316        }
00317        nn->vec_range = NULL ;  /* string vectors don't use vec_range */
00318        nn->statistic = NULL ;
00319      }
00320      break ;
00321 
00322      case NI_POINTS_DOMAIN_TYPE:{
00323        NI_index_t ii ;
00324        DUPLICATE_STRUCT(NI_points_domain) ;
00325        nn->num_node = ii = qq->num_node ;
00326        if( qq->id != NULL ){                                 /* copy array */
00327          nn->id = NI_malloc(NI_index_t, ii*sizeof(NI_index_t)) ;
00328          memcpy( nn->id , qq->id , ii*sizeof(NI_index_t) ) ;
00329        }
00330        if( qq->x != NULL ){                                  /* copy array */
00331          nn->x = NI_malloc(float, ii*sizeof(float)) ;
00332          memcpy( nn->x , qq->x , ii*sizeof(float) ) ;
00333        }
00334        if( qq->y != NULL ){                                  /* copy array */
00335          nn->y = NI_malloc(float, ii*sizeof(float)) ;
00336          memcpy( nn->y , qq->y , ii*sizeof(float) ) ;
00337        }
00338        if( qq->z != NULL ){                                  /* copy array */
00339          nn->z = NI_malloc(float, ii*sizeof(float)) ;
00340          memcpy( nn->z , qq->z , ii*sizeof(float) ) ;
00341        }
00342        nn->seq = qq->seq; nn->seqbase = qq->seqbase; nn->sorted = qq->sorted;
00343      }
00344      break ;
00345 
00346      case NI_DATASET_TYPE:{
00347        DUPLICATE_STRUCT(NI_dataset) ;
00348        nn->num_node = qq->num_node ;
00349        nn->num_val  = qq->num_val  ;
00350        nn->order    = qq->order    ;
00351        if( qq->vec != NULL ){
00352          NI_index_t nv , ii ;
00353          nv = NI_dataset_vecnum(nn) ;
00354          nn->vec = NI_malloc(NI_vector*, sizeof(NI_vector *)*nv) ;
00355          for( ii=0 ; ii < nv ; ii++ )
00356            nn->vec[ii] = (NI_vector *)NI_copy_struct( qq->vec[ii] ) ;   /* recursion */
00357        } else {
00358          nn->vec = NULL ;
00359        }
00360        nn->domain = (NI_struct *)NI_copy_struct( qq->domain ) ;         /* recursion */
00361      }
00362      break ;
00363 
00364    }
00365 
00366    return (void *)ndnew ;
00367 }
00368 #undef DUPLICATE_STRUCT
 

Powered by Plone

This site conforms to the following standards: