00001 #include "niml_private.h"
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 NI_element * make_empty_data_element( header_stuff *hs )
00016 {
00017    NI_element *nel ;
00018    int ii , qq ;
00019 
00020    if( hs == NULL || hs->name == NULL ) return NULL ;
00021 
00022 #ifdef NIML_DEBUG
00023 NI_dpr("ENTER make_empty_data_element\n") ;
00024 #endif
00025 
00026    nel = NI_malloc(NI_element, sizeof(NI_element) ) ;
00027 
00028    nel->type = NI_ELEMENT_TYPE ;
00029 
00030    nel->outmode = -1 ;   
00031 
00032    
00033 
00034    nel->name = hs->name ; hs->name = NULL ;
00035 
00036    nel->attr_num = hs->nattr ;
00037 
00038    if( nel->attr_num > 0 ){
00039       nel->attr_lhs = hs->lhs ; hs->lhs = NULL ;
00040       nel->attr_rhs = hs->rhs ; hs->rhs = NULL ;
00041    } else {
00042       nel->attr_lhs = nel->attr_rhs = NULL ;
00043    }
00044 
00045    
00046 
00047    nel->vec_num = 0 ;
00048    nel->vec_len = 0 ;
00049    nel->vec_typ = NULL ;
00050    nel->vec     = NULL ;
00051 
00052    nel->vec_filled = 0 ;  
00053 
00054    nel->vec_rank        = 0 ;
00055    nel->vec_axis_len    = NULL ;
00056    nel->vec_axis_delta  = NULL ;
00057    nel->vec_axis_origin = NULL ;
00058    nel->vec_axis_unit   = NULL ;
00059    nel->vec_axis_label  = NULL ;
00060 
00061    if( !hs->empty ){  
00062 
00063      
00064 
00065      ii = string_index( "ni_type" , nel->attr_num , nel->attr_lhs ) ;
00066 
00067      if( ii >= 0 && nel->attr_rhs[ii] != NULL ){
00068        int_array *iar = decode_type_string( nel->attr_rhs[ii] ) ;
00069        if( iar != NULL ){
00070          nel->vec_num = iar->num ;  
00071          nel->vec_typ = iar->ar ;   
00072          NI_free(iar) ;             
00073        }
00074      }
00075 
00076      
00077 
00078      ii = string_index( "ni_dimen" , nel->attr_num , nel->attr_lhs ) ;
00079 
00080      if( ii >= 0 && nel->attr_rhs[ii] != NULL ){
00081         int_array *dar = decode_dimen_string( nel->attr_rhs[ii] ) ;
00082         if( dar != NULL && dar->num > 0 ){
00083            int nd=dar->num , qq,pp ;
00084            
00085            for( qq=1,pp=0 ; pp < nd ; pp++ ) qq *= dar->ar[pp] ;
00086            nel->vec_len      = qq ;      
00087            nel->vec_rank     = nd ;      
00088            nel->vec_axis_len = dar->ar ; 
00089            NI_free(dar) ;                
00090            if( nel->vec_len == 0 )       
00091              nel->vec_rank = 1 ;
00092         }
00093      }
00094 
00095      
00096 
00097      ii = string_index( "ni_delta" , nel->attr_num , nel->attr_lhs ) ;
00098      if( ii >= 0 && nel->vec_rank > 0 ){
00099         NI_str_array *sar = NI_decode_string_list( nel->attr_rhs[ii] , NULL ) ;
00100         if( sar != NULL && sar->num > 0 ){
00101            int ns=sar->num , nd=nel->vec_rank , pp ;
00102            nel->vec_axis_delta = NI_malloc(float,sizeof(float)*nd) ;
00103            if( nd > ns ) nd = ns ;
00104            for( pp=0 ; pp < nd ; pp++ )
00105              sscanf( sar->str[pp] , "%f" , nel->vec_axis_delta+pp ) ;
00106            NI_delete_str_array(sar) ;
00107         }
00108      }
00109 
00110      
00111 
00112      ii = string_index( "ni_origin" , nel->attr_num , nel->attr_lhs ) ;
00113      if( ii >= 0 && nel->vec_rank > 0 ){
00114         NI_str_array *sar = NI_decode_string_list( nel->attr_rhs[ii] , NULL ) ;
00115         if( sar != NULL && sar->num > 0 ){
00116            int ns=sar->num , nd=nel->vec_rank , pp ;
00117            nel->vec_axis_origin = NI_malloc(float,sizeof(float)*nd) ;
00118            if( nd > ns ) nd = ns ;
00119            for( pp=0 ; pp < nd ; pp++ )
00120              sscanf( sar->str[pp] , "%f" , nel->vec_axis_origin+pp ) ;
00121            NI_delete_str_array(sar) ;
00122         }
00123      }
00124 
00125      
00126 
00127      ii = string_index( "ni_units" , nel->attr_num , nel->attr_lhs ) ;
00128      if( ii >= 0 && nel->vec_rank > 0 ){
00129         NI_str_array *sar = NI_decode_string_list( nel->attr_rhs[ii] , NULL ) ;
00130         if( sar != NULL && sar->num > 0 ){
00131            int ns=sar->num , nd=nel->vec_rank , pp ;
00132            nel->vec_axis_unit = NI_malloc(char*,sizeof(char *)*nd) ;
00133            if( nd > ns ) nd = ns ;
00134            for( pp=0 ; pp < nd ; pp++ )
00135              nel->vec_axis_unit[pp] = NI_strdup(sar->str[pp]) ;
00136            NI_delete_str_array(sar) ;
00137         }
00138      }
00139 
00140      
00141 
00142      ii = string_index( "ni_axes" , nel->attr_num , nel->attr_lhs ) ;
00143      if( ii >= 0 && nel->vec_rank > 0 ){
00144         NI_str_array *sar = NI_decode_string_list( nel->attr_rhs[ii] , NULL ) ;
00145         if( sar != NULL && sar->num > 0 ){
00146            int ns=sar->num , nd=nel->vec_rank , pp ;
00147            nel->vec_axis_label = NI_malloc(char*,sizeof(char *)*nd) ;
00148            if( nd > ns ) nd = ns ;
00149            for( pp=0 ; pp < nd ; pp++ )
00150              nel->vec_axis_label[pp] = NI_strdup(sar->str[pp]) ;
00151            NI_delete_str_array(sar) ;
00152         }
00153      }
00154 
00155      
00156      
00157 
00158      if( nel->vec_num == 0 ){                    
00159         nel->vec_num    = 1 ;
00160         nel->vec_typ    = NI_malloc(int,sizeof(int)) ;
00161         nel->vec_typ[0] = NI_BYTE ;
00162      }
00163 
00164      if( nel->vec_rank == 0 ){                  
00165         nel->vec_len         = 0 ;
00166         nel->vec_rank        = 1 ;
00167         nel->vec_axis_len    = NI_malloc(int, sizeof(int)) ;
00168         nel->vec_axis_len[0] = 1 ;
00169      }
00170 
00171      
00172 
00173      nel->vec = NI_malloc(void*, sizeof(void *)*nel->vec_num ) ;
00174 
00175      
00176 
00177      if( nel->vec_len > 0 ){
00178        for( ii=0 ; ii < nel->vec_num ; ii++ )
00179          nel->vec[ii] = NI_malloc(void,
00180                                   NI_type_size(nel->vec_typ[ii])*nel->vec_len) ;
00181      } else {
00182        for( ii=0 ; ii < nel->vec_num ; ii++ )
00183          nel->vec[ii] = NULL ;
00184      }
00185 
00186    } 
00187 
00188    return nel ;
00189 }
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 NI_group * make_empty_group_element( header_stuff *hs )
00198 {
00199    NI_group *ngr ;
00200    int ii , qq ;
00201 
00202    if( hs == NULL || hs->name == NULL ) return NULL ;
00203 
00204    ngr = NI_malloc(NI_group, sizeof(NI_group) ) ;
00205 
00206    ngr->type = NI_GROUP_TYPE ;
00207 
00208    ngr->name = hs->name ; hs->name = NULL ;  
00209 
00210    ngr->outmode = -1 ;   
00211 
00212    
00213 
00214    ngr->attr_num = hs->nattr ;
00215 
00216    if( ngr->attr_num > 0 ){
00217      ngr->attr_lhs = hs->lhs ; hs->lhs = NULL ;
00218      ngr->attr_rhs = hs->rhs ; hs->rhs = NULL ;
00219    } else {
00220      ngr->attr_lhs = ngr->attr_rhs = NULL ;
00221    }
00222 
00223    
00224 
00225    ngr->part_num = 0 ;
00226    ngr->part_typ = NULL ;
00227    ngr->part     = NULL ;
00228 
00229    return ngr ;
00230 }
00231 
00232 
00233 
00234 
00235 
00236 
00237 int NI_type_size( int tval )
00238 {
00239    int ii = NI_rowtype_code_to_size( tval ) ;
00240    return (ii > 0) ? ii : 0 ;
00241 }
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 int NI_element_type( void *nini )
00255 {
00256    NI_element *nel = (NI_element *) nini ;
00257    NI_group   *ngr = (NI_group *)   nini ;
00258    NI_procins *npi = (NI_procins *) nini ;  
00259 
00260    if( nini == NULL ) return -1 ;
00261 
00262    if( nel->type == NI_ELEMENT_TYPE ) return NI_ELEMENT_TYPE ;
00263    if( ngr->type == NI_GROUP_TYPE   ) return NI_GROUP_TYPE   ;
00264    if( npi->type == NI_PROCINS_TYPE ) return NI_PROCINS_TYPE ;
00265 
00266    return -1 ;
00267 }
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 char * NI_element_name( void *nini )
00276 {
00277    NI_element *nel = (NI_element *) nini ;
00278    NI_group   *ngr = (NI_group *)   nini ;
00279    NI_procins *npi = (NI_procins *) nini ;
00280 
00281    if( nini == NULL ) return NULL ;
00282 
00283    if( nel->type == NI_ELEMENT_TYPE ) return nel->name ;
00284    if( ngr->type == NI_GROUP_TYPE   ) return ngr->name ;
00285    if( npi->type == NI_PROCINS_TYPE ) return npi->name ;
00286 
00287    return NULL ;
00288 }
00289 
00290 
00291 
00292 
00293 
00294 void NI_free_element( void *nini )
00295 {
00296    int ii , tt=NI_element_type(nini) , jj ;
00297 
00298    if( tt < 0 ) return ; 
00299 
00300    
00301 
00302    if( tt == NI_ELEMENT_TYPE ){
00303       NI_element *nel = (NI_element *)nini ;
00304 
00305       NI_free(nel->name) ;
00306       for( ii=0 ; ii < nel->attr_num ; ii++ ){
00307          NI_free( nel->attr_lhs[ii] ) ;
00308          NI_free( nel->attr_rhs[ii] ) ;
00309       }
00310       NI_free( nel->attr_lhs ) ;
00311       NI_free( nel->attr_rhs ) ;
00312 
00313       
00314 
00315       if( nel->vec != NULL )
00316         for( ii=0 ; ii < nel->vec_num ; ii++ )
00317            NI_free_column( NI_rowtype_find_code(nel->vec_typ[ii]) ,
00318                            nel->vec_len , nel->vec[ii]             ) ;
00319 
00320       NI_free( nel->vec_typ  ) ;
00321       NI_free( nel->vec ) ;
00322 
00323       NI_free(nel->vec_axis_len) ;
00324       NI_free(nel->vec_axis_delta) ;
00325       NI_free(nel->vec_axis_origin) ;
00326       NI_free(nel->vec_axis_unit) ;
00327       NI_free(nel->vec_axis_label) ;
00328 
00329       NI_free( nel ) ;
00330 
00331    
00332 
00333    } else if( tt == NI_GROUP_TYPE ){
00334       NI_group *ngr = (NI_group *)nini ;
00335 
00336       for( ii=0 ; ii < ngr->attr_num ; ii++ ){
00337         NI_free( ngr->attr_lhs[ii] ) ;
00338         NI_free( ngr->attr_rhs[ii] ) ;
00339       }
00340       NI_free( ngr->attr_lhs ) ;
00341       NI_free( ngr->attr_rhs ) ;
00342 
00343       if( ngr->part != NULL ){
00344         for( ii=0 ; ii < ngr->part_num ; ii++ )
00345           NI_free_element( ngr->part[ii] ) ;     
00346       }
00347 
00348       NI_free( ngr->part_typ ) ;
00349       NI_free( ngr->part ) ;
00350       NI_free( ngr->name ) ;    
00351       NI_free( ngr ) ;
00352 
00353    
00354 
00355    } else if( tt == NI_PROCINS_TYPE ){
00356       NI_procins *npi = (NI_procins *)nini ;
00357 
00358       for( ii=0 ; ii < npi->attr_num ; ii++ ){
00359         NI_free( npi->attr_lhs[ii] ) ;
00360         NI_free( npi->attr_rhs[ii] ) ;
00361       }
00362       NI_free( npi->attr_lhs ) ;
00363       NI_free( npi->attr_rhs ) ;
00364 
00365       NI_free( npi->name ) ;    
00366       NI_free( npi ) ;
00367    }
00368 
00369    return ;
00370 }
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 NI_element * NI_new_data_element( char *name , int veclen )
00385 {
00386    NI_element *nel ;
00387 
00388    if( name == NULL || name[0] == '\0' || veclen < 0 ) return NULL ;
00389 
00390    nel = NI_malloc(NI_element, sizeof(NI_element) ) ;
00391 
00392    nel->type = NI_ELEMENT_TYPE ;  
00393 
00394    nel->outmode = -1 ;   
00395 
00396    nel->name = NI_strdup(name) ;
00397    nel->attr_num = 0 ;
00398    nel->attr_lhs = nel->attr_rhs = NULL ;  
00399 
00400    nel->vec_num = 0 ;                      
00401    nel->vec_typ = NULL ;
00402    nel->vec     = NULL ;
00403 
00404    if( veclen == 0 ){                      
00405      nel->vec_len      = 0 ;
00406      nel->vec_filled   = 0 ;
00407      nel->vec_rank     = 0 ;
00408      nel->vec_axis_len = NULL ;
00409    } else {                                
00410      nel->vec_len         = veclen ;       
00411      nel->vec_filled      = veclen ;
00412      nel->vec_rank        = 1 ;
00413      nel->vec_axis_len    = NI_malloc(int, sizeof(int)) ;
00414      nel->vec_axis_len[0] = veclen ;
00415    }
00416 
00417    nel->vec_axis_delta  = NULL ;
00418    nel->vec_axis_origin = NULL ;
00419    nel->vec_axis_unit   = NULL ;
00420    nel->vec_axis_label  = NULL ;
00421 
00422    return nel ;
00423 }
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 void NI_add_column( NI_element *nel , int typ , void *arr )
00443 {
00444    int nn ;
00445    NI_rowtype *rt ;
00446 
00447    
00448 
00449    if( nel == NULL || nel->vec_len <= 0 )            return ;
00450    if( nel->type != NI_ELEMENT_TYPE )                return ;
00451    rt = NI_rowtype_find_code(typ) ; if( rt == NULL ) return ;
00452 
00453    
00454 
00455    nn = nel->vec_num ;
00456 
00457    
00458 
00459    nel->vec_typ     = NI_realloc( nel->vec_typ, int, sizeof(int)*(nn+1) ) ;
00460    nel->vec_typ[nn] = typ ;
00461 
00462    
00463 
00464    nel->vec = NI_realloc( nel->vec , void*, sizeof(void *)*(nn+1) ) ;
00465    if( arr != NULL )
00466      nel->vec[nn] = NI_copy_column( rt , nel->vec_len , arr ) ;
00467    else
00468      nel->vec[nn] = NI_malloc(void, rt->size * nel->vec_len ) ;
00469 
00470    
00471 
00472    nel->vec_num = nn+1 ;
00473    return ;
00474 }
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 void NI_alter_veclen( NI_element *nel , int newlen )
00486 {
00487    int oldlen , ii ;
00488    NI_rowtype *rt ;
00489    char *pt ;
00490 
00491    if( nel          == NULL || nel->type != NI_ELEMENT_TYPE ) return ;
00492    if( nel->vec_len <= 0    || newlen    <= 0               ) return ;
00493 
00494    if( nel->vec_num == 0 ){                       
00495      nel->vec_len = nel->vec_filled = newlen; return;
00496    }
00497 
00498    oldlen = nel->vec_len ; if( oldlen == newlen ) return ;
00499 
00500    for( ii=0 ; ii < nel->vec_num ; ii++ ){
00501      rt = NI_rowtype_find_code( nel->vec_typ[ii] ) ;
00502      nel->vec[ii] = NI_realloc( nel->vec[ii] , void , rt->size * newlen ) ;
00503      if( oldlen < newlen ){
00504        pt = ((char *)nel->vec[ii]) + (rt->size * oldlen) ; 
00505        memset( pt , 0 , (newlen-oldlen)*rt->size ) ;       
00506      }
00507    }
00508 
00509    nel->vec_len = nel->vec_filled = newlen ; return ;
00510 }
00511 
00512 
00513 
00514 
00515 
00516 
00517 void NI_add_column_stride( NI_element *nel, int typ, void *arr, int stride )
00518 {
00519    int nn , ii ;
00520    NI_rowtype *rt ;
00521    char *idat ;
00522 
00523    
00524 
00525    if( nel == NULL || nel->vec_len <= 0 )            return ;
00526    if( nel->type != NI_ELEMENT_TYPE )                return ;
00527    rt = NI_rowtype_find_code(typ) ; if( rt == NULL ) return ;
00528 
00529    
00530 
00531    NI_add_column( nel , typ , NULL ) ;
00532    if( arr == NULL ) return ;          
00533 
00534    
00535 
00536    nn   = nel->vec_num-1 ;
00537    idat = (char *) arr ;
00538 
00539    for( ii=0 ; ii < nel->vec_len ; ii++ )
00540      NI_insert_value( nel , ii , nn , idat + (ii*stride*rt->size) ) ;
00541 
00542    return ;
00543 }
00544 
00545 
00546 
00547 
00548 
00549 
00550 void NI_fill_column_stride( NI_element *nel, int typ,
00551                             void *arr, int nn, int stride )
00552 {
00553    int  ii , nf;
00554    NI_rowtype *rt ;
00555    char *idat ;
00556 
00557    
00558 
00559    if( nel == NULL || nel->vec_len <= 0 )            return ;
00560    if( nel->type != NI_ELEMENT_TYPE )                return ;
00561    rt = NI_rowtype_find_code(typ) ; if( rt == NULL ) return ;
00562 
00563    
00564 
00565    if( arr == NULL )                                 return ;
00566    if( nel->vec[nn] == NULL )                        return ;
00567    if( nn < 0 || nn >= nel->vec_num )                return ;
00568    if( typ != nel->vec_typ[nn] )                     return ;
00569 
00570    
00571 
00572    if( nel->vec_filled > 0 && nel->vec_filled <= nel->vec_len )
00573      nf = nel->vec_filled ;
00574    else
00575      nf = nel->vec_len ;
00576 
00577    idat = (char *) arr ;
00578 
00579    for( ii=0 ; ii < nf ; ii++ )
00580      NI_insert_value( nel , ii , nn , idat + (ii*stride*rt->size) ) ;
00581 
00582    return ;
00583 }
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 void NI_insert_value( NI_element *nel, int row, int col, void *dat )
00608 {
00609    NI_rowtype *rt ;
00610    char *cdat , *idat=(char *)dat , *qpt ;
00611    int jj , kk ;
00612 
00613    
00614 
00615    if( nel == NULL || idat == NULL        ) return ;
00616    if( nel->type    != NI_ELEMENT_TYPE    ) return ;
00617    if( nel->vec_len <= 0                  ) return ;
00618    if( row < 0     || row >= nel->vec_len ) return ;
00619    if( col < 0     || col >= nel->vec_num ) return ;
00620 
00621    rt = NI_rowtype_find_code( nel->vec_typ[col] ) ;
00622    if( rt == NULL )                         return ;
00623 
00624    cdat = (char *) nel->vec[col] ;   
00625    cdat = cdat + rt->size * row ;    
00626 
00627    
00628 
00629    memcpy( cdat , idat , rt->size ) ;
00630 
00631    
00632 
00633    if( ROWTYPE_is_varsize(rt) ){
00634      for( jj=0 ; jj < rt->part_num ; jj++ ){            
00635 
00636        if( rt->part_typ[jj] == NI_STRING ){               
00637          char **apt = (char **)(cdat+rt->part_off[jj]) ;   
00638          qpt = NI_strdup(*apt) ; *apt = qpt ;
00639 
00640        } else if( rt->part_dim[jj] >= 0 ){                
00641          char **apt = (char **)(cdat+rt->part_off[jj]) ;   
00642          if( *apt != NULL ){
00643            kk  = ROWTYPE_part_dimen(rt,cdat,jj) * rt->part_rtp[jj]->size ;
00644            qpt = NI_malloc(char, kk) ; memcpy(qpt,*apt,kk) ; *apt = qpt ;
00645          }
00646        }
00647      }
00648    }
00649 
00650    return ;
00651 }
00652 
00653 
00654 
00655 void NI_insert_string( NI_element *nel, int row, int col, char *str )
00656 {
00657    if( nel == NULL || str == NULL         ) return ;
00658    if( nel->type   != NI_ELEMENT_TYPE     ) return ;
00659    if( row < 0     || row >= nel->vec_len ) return ;
00660    if( col < 0     || col >= nel->vec_num ) return ;
00661    if( nel->vec_typ[col] != NI_STRING     ) return ;
00662 
00663    NI_insert_value( nel , row,col , &str ); return ;
00664 }
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 void NI_set_attribute( void *nini , char *attname , char *attvalue )
00673 {
00674    int nn , tt=NI_element_type(nini) ;
00675 
00676    if( tt < 0 || attname == NULL || attname[0] == '\0' ) return ;
00677 
00678    
00679 
00680    if( tt == NI_ELEMENT_TYPE ){
00681       NI_element *nel = (NI_element *) nini ;
00682 
00683       
00684 
00685       for( nn=0 ; nn < nel->attr_num ; nn++ )
00686          if( strcmp(nel->attr_lhs[nn],attname) == 0 ) break ;
00687 
00688       
00689 
00690       if( nn == nel->attr_num ){
00691         nel->attr_lhs = NI_realloc( nel->attr_lhs, char*, sizeof(char *)*(nn+1) );
00692         nel->attr_rhs = NI_realloc( nel->attr_rhs, char*, sizeof(char *)*(nn+1) );
00693         nel->attr_num = nn+1 ;
00694       } else {
00695         NI_free(nel->attr_lhs[nn]) ;  
00696         NI_free(nel->attr_rhs[nn]) ;
00697       }
00698 
00699       nel->attr_lhs[nn] = NI_strdup(attname) ;
00700       nel->attr_rhs[nn] = NI_strdup(attvalue);
00701 
00702    
00703 
00704    } else if( tt == NI_GROUP_TYPE ){
00705       NI_group *ngr = (NI_group *) nini ;
00706 
00707       for( nn=0 ; nn < ngr->attr_num ; nn++ )
00708          if( strcmp(ngr->attr_lhs[nn],attname) == 0 ) break ;
00709 
00710       if( nn == ngr->attr_num ){
00711         ngr->attr_lhs = NI_realloc( ngr->attr_lhs, char*, sizeof(char *)*(nn+1) );
00712         ngr->attr_rhs = NI_realloc( ngr->attr_rhs, char*, sizeof(char *)*(nn+1) );
00713         ngr->attr_num = nn+1 ;
00714       } else {
00715         NI_free(ngr->attr_lhs[nn]) ;
00716         NI_free(ngr->attr_rhs[nn]) ;
00717       }
00718 
00719       ngr->attr_lhs[nn] = NI_strdup(attname) ;
00720       ngr->attr_rhs[nn] = NI_strdup(attvalue);
00721 
00722    
00723 
00724    } else if( tt == NI_PROCINS_TYPE ){
00725       NI_procins *npi = (NI_procins *) nini ;
00726 
00727       for( nn=0 ; nn < npi->attr_num ; nn++ )
00728         if( strcmp(npi->attr_lhs[nn],attname) == 0 ) break ;
00729 
00730       if( nn == npi->attr_num ){
00731         npi->attr_lhs = NI_realloc( npi->attr_lhs, char*, sizeof(char *)*(nn+1) );
00732         npi->attr_rhs = NI_realloc( npi->attr_rhs, char*, sizeof(char *)*(nn+1) );
00733         npi->attr_num = nn+1 ;
00734       } else {
00735         NI_free(npi->attr_lhs[nn]) ;
00736         NI_free(npi->attr_rhs[nn]) ;
00737       }
00738 
00739       npi->attr_lhs[nn] = NI_strdup(attname) ;
00740       npi->attr_rhs[nn] = NI_strdup(attvalue);
00741    }
00742 
00743    return ;
00744 }
00745 
00746 
00747 
00748 
00749 
00750 
00751 
00752 
00753 
00754 
00755 char * NI_get_attribute( void *nini , char *attname )
00756 {
00757    int nn , tt=NI_element_type(nini) ;
00758    static char *zorkon = "\0" ;
00759 
00760    if( tt < 0 || attname == NULL || attname[0] == '\0' ) return NULL ;
00761 
00762    
00763 
00764    if( tt == NI_ELEMENT_TYPE ){
00765       NI_element *nel = (NI_element *) nini ;
00766 
00767       for( nn=0 ; nn < nel->attr_num ; nn++ )
00768          if( strcmp(nel->attr_lhs[nn],attname) == 0 ) break ;
00769 
00770       if( nn == nel->attr_num ) return NULL ;
00771 
00772       if( nel->attr_rhs[nn] == NULL ) return zorkon ;
00773 
00774       return nel->attr_rhs[nn] ;
00775 
00776    
00777 
00778    } else if( tt == NI_GROUP_TYPE ){
00779       NI_group *ngr = (NI_group *) nini ;
00780 
00781       for( nn=0 ; nn < ngr->attr_num ; nn++ )
00782          if( strcmp(ngr->attr_lhs[nn],attname) == 0 ) break ;
00783 
00784       if( nn == ngr->attr_num ) return NULL ;
00785 
00786       if( ngr->attr_rhs[nn] == NULL ) return zorkon ;
00787 
00788       return ngr->attr_rhs[nn] ;
00789 
00790    
00791 
00792    } else if( tt == NI_PROCINS_TYPE ){
00793       NI_procins *npi = (NI_procins *) nini ;
00794 
00795       for( nn=0 ; nn < npi->attr_num ; nn++ )
00796         if( strcmp(npi->attr_lhs[nn],attname) == 0 ) break ;
00797 
00798       if( nn == npi->attr_num ) return NULL ;
00799 
00800       if( npi->attr_rhs[nn] == NULL ) return zorkon ;
00801 
00802       return npi->attr_rhs[nn] ;
00803    }
00804 
00805    return NULL ; 
00806 }
00807 
00808 
00809 
00810 
00811 
00812 void NI_set_dimen( NI_element *nel , int rank , int *nd )
00813 {
00814    int ii , ntot ;
00815 
00816    if( nel == NULL || nel->type != NI_ELEMENT_TYPE ||
00817        rank < 1    || nd == NULL                     ) return ; 
00818 
00819    for( ntot=1,ii=0 ; ii < rank ; ii++ ){
00820       if( nd[ii] <= 0 ) return ;                                
00821       ntot *= nd[ii] ;
00822    }
00823    if( ntot != nel->vec_len ) return ;                          
00824 
00825    nel->vec_rank = rank ;
00826    nel->vec_axis_len = NI_realloc( nel->vec_axis_len, int, sizeof(int)*rank ) ;
00827    memcpy( nel->vec_axis_len , nd , sizeof(int)*rank ) ;
00828    return ;
00829 }
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 void NI_set_delta( NI_element *nel , float *del )
00838 {
00839    if( nel == NULL       || nel->type != NI_ELEMENT_TYPE ||
00840        nel->vec_rank < 1 || del == NULL                    ) return ;
00841 
00842    nel->vec_axis_delta = NI_realloc( nel->vec_axis_delta , float,
00843                                      nel->vec_rank * sizeof(float) ) ;
00844    memcpy( nel->vec_axis_delta , del , nel->vec_rank * sizeof(float) ) ;
00845    return ;
00846 }
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 void NI_set_origin( NI_element *nel , float *org )
00855 {
00856    if( nel == NULL       || nel->type != NI_ELEMENT_TYPE ||
00857        nel->vec_rank < 1 || org == NULL                    ) return ;
00858 
00859    nel->vec_axis_origin = NI_realloc( nel->vec_axis_origin , float,
00860                                       nel->vec_rank * sizeof(float) ) ;
00861    memcpy( nel->vec_axis_origin , org , nel->vec_rank * sizeof(float) ) ;
00862    return ;
00863 }
00864 
00865 
00866 
00867 
00868 
00869 
00870 
00871 void NI_set_units( NI_element *nel , char **units )
00872 {
00873    int ii ;
00874 
00875    if( nel == NULL       || nel->type != NI_ELEMENT_TYPE ||
00876        nel->vec_rank < 1 || units == NULL                  ) return ;
00877 
00878    nel->vec_axis_unit = NI_realloc( nel->vec_axis_unit , char*,
00879                                     nel->vec_rank * sizeof(char *) ) ;
00880    for( ii=0 ; ii < nel->vec_rank ; ii++ )
00881       nel->vec_axis_unit[ii] = NI_strdup( units[ii] ) ;
00882    return ;
00883 }
00884 
00885 
00886 
00887 
00888 
00889 
00890 
00891 void NI_set_axes( NI_element *nel , char **ax )
00892 {
00893    int ii ;
00894 
00895    if( nel == NULL       || nel->type != NI_ELEMENT_TYPE ||
00896        nel->vec_rank < 1 || ax == NULL                     ) return ;
00897 
00898    nel->vec_axis_label = NI_realloc( nel->vec_axis_label , char*,
00899                                      nel->vec_rank * sizeof(char *) ) ;
00900    for( ii=0 ; ii < nel->vec_rank ; ii++ )
00901       nel->vec_axis_label[ii] = NI_strdup( ax[ii] ) ;
00902    return ;
00903 }
00904 
00905 
00906 
00907 
00908 
00909 NI_procins * NI_new_processing_instruction( char *name )
00910 {
00911    NI_procins *npi ;
00912 
00913    if( name == NULL || name[0] == '\0' ) return NULL ;
00914 
00915    npi = NI_malloc(NI_procins,sizeof(NI_procins)) ;
00916 
00917    npi->type = NI_PROCINS_TYPE ;
00918    npi->name = NI_strdup(name) ;
00919 
00920    npi->attr_num = 0 ;
00921    npi->attr_lhs = npi->attr_rhs = NULL ;
00922 
00923    return npi ;
00924 }
00925 
00926 
00927 
00928 
00929 
00930 NI_group * NI_new_group_element(void)
00931 {
00932    NI_group *ngr ;
00933 
00934    ngr = NI_malloc(NI_group, sizeof(NI_group) ) ;
00935 
00936    ngr->type = NI_GROUP_TYPE ;
00937 
00938    ngr->outmode = -1 ;   
00939 
00940    ngr->attr_num = 0 ;
00941    ngr->attr_lhs = ngr->attr_rhs = NULL ;
00942 
00943    ngr->part_num = 0 ;
00944    ngr->part_typ = NULL ;
00945    ngr->part     = NULL ;
00946    ngr->name     = NULL ;  
00947 
00948    return ngr ;
00949 }
00950 
00951 
00952 
00953 
00954 
00955 void NI_add_to_group( NI_group *ngr , void *nini )
00956 {
00957    int nn , tt=NI_element_type(nini) ;
00958 
00959    if( ngr == NULL || ngr->type != NI_GROUP_TYPE || tt < 0 ) return ;
00960 
00961    nn = ngr->part_num ;
00962 
00963    ngr->part_typ     = NI_realloc( ngr->part_typ , int, sizeof(int)*(nn+1) ) ;
00964    ngr->part_typ[nn] = tt ;
00965    ngr->part         = NI_realloc( ngr->part , void*, sizeof(void *)*(nn+1) );
00966    ngr->part[nn]     = nini ;
00967    ngr->part_num     = nn+1 ;
00968    return ;
00969 }
00970 
00971 
00972 
00973 
00974 
00975 
00976 void NI_remove_from_group( NI_group *ngr , void *nini )  
00977 {
00978    int ii , nn , jj ;
00979 
00980    if( ngr == NULL || ngr->type != NI_GROUP_TYPE || nini == NULL ) return ;
00981 
00982    nn = ngr->part_num ;
00983    for( ii=0 ; ii < nn ; ii++ )       
00984      if( nini == ngr->part[ii] ) break ;
00985    if( ii == nn ) return ;            
00986 
00987    for( jj=ii+1 ; jj < nn ; jj++ ){   
00988      ngr->part_typ[jj-1] = ngr->part_typ[jj] ;
00989      ngr->part    [jj-1] = ngr->part    [jj] ;
00990    }
00991    ngr->part[nn-1] = NULL ;    
00992    ngr->part_num -- ;          
00993    return ;
00994 }
00995 
00996 
00997 
00998 
00999 
01000 void NI_rename_group( NI_group *ngr , char *nam )
01001 {
01002    if( ngr == NULL || ngr->type != NI_GROUP_TYPE ) return ;
01003    NI_free( ngr->name ) ;
01004    ngr->name = NI_strdup(nam) ;
01005    return ;
01006 }
01007 
01008 
01009 
01010 
01011 
01012 
01013 
01014 
01015 
01016 
01017 
01018 
01019 
01020 
01021 
01022 
01023 int NI_search_group_shallow( NI_group *ngr , char *enam , void ***nipt )
01024 {
01025    void **nelar=NULL , *nini ;
01026    int ii , nn=0 ;
01027    char *nm ;
01028 
01029    if( ngr  == NULL || ngr->type != NI_GROUP_TYPE    ) return 0 ;
01030    if( enam == NULL || *enam == '\0' || nipt == NULL ) return 0 ;
01031    if( ngr->part_num == 0                            ) return 0 ;
01032 
01033    for( ii=0 ; ii < ngr->part_num ; ii++ ){
01034      nini = ngr->part[ii] ;
01035      nm   = NI_element_name( nini ) ;
01036      if( nm != NULL && strcmp(nm,enam) == 0 ){
01037        nelar = (void **) NI_realloc(nelar,void*,nn+1) ;
01038        nelar[nn++] = nini ;
01039      }
01040    }
01041 
01042    if( nn > 0 ) *nipt = nelar ;
01043    return nn ;
01044 }
01045 
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054 
01055 
01056 
01057 
01058 
01059 
01060 
01061 
01062 
01063 
01064 int NI_search_group_deep( NI_group *ngr , char *enam , void ***nipt )
01065 {
01066    void **nelar=NULL , *nini ;
01067    int ii , nn=0 ;
01068    char *nm ;
01069 
01070    if( ngr  == NULL || ngr->type != NI_GROUP_TYPE    ) return 0 ;
01071    if( enam == NULL || *enam == '\0' || nipt == NULL ) return 0 ;
01072    if( ngr->part_num == 0                            ) return 0 ;
01073 
01074    for( ii=0 ; ii < ngr->part_num ; ii++ ){
01075      nini = ngr->part[ii] ;
01076      nm   = NI_element_name( nini ) ;
01077      if( nm != NULL && strcmp(nm,enam) == 0 ){
01078        nelar = (void **) NI_realloc(nelar,void*,nn+1) ;
01079        nelar[nn++] = nini ;
01080      }
01081      if( NI_element_type(nini) == NI_GROUP_TYPE ){  
01082        int nsub , jj ; void **esub ;
01083        nsub = NI_search_group_deep( nini , enam , &esub ) ;
01084        if( nsub > 0 ){
01085          nelar = (void **) NI_realloc(nelar,void*,nn+nsub) ;
01086          for( jj=0 ; jj < nsub ; jj++ ) nelar[nn++] = esub[jj] ;
01087          NI_free(esub) ;
01088        }
01089      }
01090    }
01091 
01092    if( nn > 0 ) *nipt = nelar ;
01093    return nn ;
01094 }