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  

dim.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright 1996, University Corporation for Atmospheric Research
00003  *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
00004  */
00005 
00006 #include "nc.h"
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <assert.h>
00010 #include "ncx.h"
00011 #include "fbits.h"
00012 
00013 /*
00014  * Free dim
00015  * Formerly
00016 NC_free_dim(dim)
00017  */
00018 void
00019 free_NC_dim(NC_dim *dimp)
00020 {
00021         if(dimp == NULL)
00022                 return;
00023         free_NC_string(dimp->name);
00024         free(dimp);
00025 }
00026 
00027 
00028 NC_dim *
00029 new_x_NC_dim(NC_string *name)
00030 {
00031         NC_dim *dimp;
00032 
00033         dimp = (NC_dim *) malloc(sizeof(NC_dim));
00034         if(dimp == NULL)
00035                 return NULL;
00036 
00037         dimp->name = name;
00038         dimp->size = 0;
00039 
00040         return(dimp);
00041 }
00042 
00043 
00044 /*
00045  * Formerly
00046 NC_new_dim(const char *name, long size)
00047  */
00048 static NC_dim *
00049 new_NC_dim(const char *name, size_t size)
00050 {
00051         NC_string *strp;
00052         NC_dim *dimp;
00053 
00054         strp = new_NC_string(strlen(name), name);
00055         if(strp == NULL)
00056                 return NULL;
00057 
00058         dimp = new_x_NC_dim(strp);
00059         if(dimp == NULL)
00060         {
00061                 free_NC_string(strp);
00062                 return NULL;
00063         }
00064 
00065         dimp->size = size;
00066 
00067         return(dimp);
00068 }
00069 
00070 
00071 static NC_dim *
00072 dup_NC_dim(const NC_dim *dimp)
00073 {
00074         return new_NC_dim(dimp->name->cp, dimp->size);
00075 }
00076 
00077 /*
00078  * Step thru NC_DIMENSION array, seeking the UNLIMITED dimension.
00079  * Return dimid or -1 on not found.
00080  * *dimpp is set to the appropriate NC_dim.
00081  * The loop structure is odd. In order to parallelize,
00082  * we moved a clearer 'break' inside the loop body to the loop test.
00083  */
00084 int
00085 find_NC_Udim(const NC_dimarray *ncap, NC_dim **dimpp)
00086 {
00087         assert(ncap != NULL);
00088 
00089         if(ncap->nelems == 0)
00090                 return -1;
00091 
00092         {
00093         int dimid = 0;
00094         NC_dim **loc = ncap->value;
00095 
00096         for(; (size_t) dimid < ncap->nelems
00097                          && (*loc)->size != NC_UNLIMITED; dimid++, loc++)
00098         {
00099                 /*EMPTY*/
00100         }
00101         if(dimid >= ncap->nelems)
00102                 return(-1); /* not found */
00103         /* else, normal return */
00104         if(dimpp != NULL)
00105                 *dimpp = *loc;
00106         return dimid;
00107         }
00108 }
00109 
00110 
00111 /*
00112  * Step thru NC_DIMENSION array, seeking match on name.
00113  * Return dimid or -1 on not found.
00114  * *dimpp is set to the appropriate NC_dim.
00115  * The loop structure is odd. In order to parallelize,
00116  * we moved a clearer 'break' inside the loop body to the loop test.
00117  */
00118 static int
00119 NC_finddim(const NC_dimarray *ncap, const char *name, NC_dim **dimpp)
00120 {
00121 
00122         assert(ncap != NULL);
00123 
00124         if(ncap->nelems == 0)
00125                 return -1;
00126 
00127         {
00128         size_t slen = strlen(name);
00129         int dimid = 0;
00130         NC_dim **loc = (NC_dim **) ncap->value;
00131 
00132         for(; (size_t) dimid < ncap->nelems
00133                         && (strlen((*loc)->name->cp) != slen
00134                                 || strncmp((*loc)->name->cp, name, slen) != 0);
00135                  dimid++, loc++)
00136         {
00137                 /*EMPTY*/
00138         }
00139         if(dimid >= ncap->nelems)
00140                 return(-1); /* not found */
00141         /* else, normal return */
00142         if(dimpp != NULL)
00143                         *dimpp = *loc;
00144         return(dimid);
00145         }
00146 }
00147 
00148 
00149 /* dimarray */
00150 
00151 
00152 /*
00153  * Free the stuff "in" (referred to by) an NC_dimarray.
00154  * Leaves the array itself allocated.
00155  */
00156 void
00157 free_NC_dimarrayV0(NC_dimarray *ncap)
00158 {
00159         assert(ncap != NULL);
00160 
00161         if(ncap->nelems == 0)
00162                 return;
00163 
00164         assert(ncap->value != NULL);
00165 
00166         {
00167                 NC_dim **dpp = ncap->value;
00168                 NC_dim *const *const end = &dpp[ncap->nelems];
00169                 for( /*NADA*/; dpp < end; dpp++)
00170                 {
00171                         free_NC_dim(*dpp);
00172                         *dpp = NULL;
00173                 }
00174         }
00175         ncap->nelems = 0;
00176 }
00177 
00178 
00179 /*
00180  * Free NC_dimarray values.
00181  * formerly
00182 NC_free_array()
00183  */
00184 void
00185 free_NC_dimarrayV(NC_dimarray *ncap)
00186 {
00187         assert(ncap != NULL);
00188         
00189         if(ncap->nalloc == 0)
00190                 return;
00191 
00192         assert(ncap->value != NULL);
00193 
00194         free_NC_dimarrayV0(ncap);
00195 
00196         free(ncap->value);
00197         ncap->value = NULL;
00198         ncap->nalloc = 0;
00199 }
00200 
00201 
00202 int
00203 dup_NC_dimarrayV(NC_dimarray *ncap, const NC_dimarray *ref)
00204 {
00205         int status = NC_NOERR;
00206 
00207         assert(ref != NULL);
00208         assert(ncap != NULL);
00209 
00210         if(ref->nelems != 0)
00211         {
00212                 const size_t sz = ref->nelems * sizeof(NC_dim *);
00213                 ncap->value = (NC_dim **) malloc(sz);
00214                 if(ncap->value == NULL)
00215                         return NC_ENOMEM;
00216                 (void) memset(ncap->value, 0, sz);
00217                 ncap->nalloc = ref->nelems;
00218         }
00219 
00220         ncap->nelems = 0;
00221         {
00222                 NC_dim **dpp = ncap->value;
00223                 const NC_dim **drpp = (const NC_dim **)ref->value;
00224                 NC_dim *const *const end = &dpp[ref->nelems];
00225                 for( /*NADA*/; dpp < end; drpp++, dpp++, ncap->nelems++)
00226                 {
00227                         *dpp = dup_NC_dim(*drpp);
00228                         if(*dpp == NULL)
00229                         {
00230                                 status = NC_ENOMEM;
00231                                 break;
00232                         }
00233                 }
00234         }
00235 
00236         if(status != NC_NOERR)
00237         {
00238                 free_NC_dimarrayV(ncap);
00239                 return status;
00240         }
00241 
00242         assert(ncap->nelems == ref->nelems);
00243 
00244         return NC_NOERR;
00245 }
00246 
00247 
00248 /*
00249  * Add a new handle on the end of an array of handles
00250  * Formerly
00251 NC_incr_array(array, tail)
00252  */
00253 static int
00254 incr_NC_dimarray(NC_dimarray *ncap, NC_dim *newelemp)
00255 {
00256         NC_dim **vp;
00257 
00258         assert(ncap != NULL);
00259 
00260         if(ncap->nalloc == 0)
00261         {
00262                 assert(ncap->nelems == 0);
00263                 vp = (NC_dim **) malloc(NC_ARRAY_GROWBY * sizeof(NC_dim *));
00264                 if(vp == NULL)
00265                         return NC_ENOMEM;
00266                 ncap->value = vp;
00267                 ncap->nalloc = NC_ARRAY_GROWBY;
00268         }
00269         else if(ncap->nelems +1 > ncap->nalloc)
00270         {
00271                 vp = (NC_dim **) realloc(ncap->value,
00272                         (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_dim *));
00273                 if(vp == NULL)
00274                         return NC_ENOMEM;
00275                 ncap->value = vp;
00276                 ncap->nalloc += NC_ARRAY_GROWBY;
00277         }
00278 
00279         if(newelemp != NULL)
00280         {
00281                 ncap->value[ncap->nelems] = newelemp;
00282                 ncap->nelems++;
00283         }
00284         return NC_NOERR;
00285 }
00286 
00287 
00288 NC_dim *
00289 elem_NC_dimarray(const NC_dimarray *ncap, size_t elem)
00290 {
00291         assert(ncap != NULL);
00292                 /* cast needed for braindead systems with signed size_t */
00293         if(ncap->nelems == 0 || (unsigned long) elem >= ncap->nelems)
00294                 return NULL;
00295 
00296         assert(ncap->value != NULL);
00297 
00298         return ncap->value[elem];
00299 }
00300 
00301 
00302 /* Public */
00303 
00304 int
00305 nc_def_dim(int ncid, const char *name, size_t size, int *dimidp)
00306 {
00307         int status;
00308         NC *ncp;
00309         int dimid;
00310         NC_dim *dimp;
00311 
00312         status = NC_check_id(ncid, &ncp); 
00313         if(status != NC_NOERR)
00314                 return status;
00315 
00316         if(!NC_indef(ncp))
00317                 return NC_ENOTINDEFINE;
00318 
00319         status = NC_check_name(name);
00320         if(status != NC_NOERR)
00321                 return status;
00322 
00323                 /* cast needed for braindead systems with signed size_t */
00324         if((unsigned long) size > X_INT_MAX) /* Backward compat */
00325                 return NC_EINVAL;
00326 
00327         if(size == NC_UNLIMITED)
00328         {
00329                 dimid = find_NC_Udim(&ncp->dims, &dimp);
00330                 if(dimid != -1)
00331                 {
00332                         assert(dimid != -1);
00333                         return NC_EUNLIMIT;
00334                 }
00335         }
00336 
00337         if(ncp->dims.nelems >= NC_MAX_DIMS)
00338                 return NC_EMAXDIMS;
00339 
00340         dimid = NC_finddim(&ncp->dims, name, &dimp);
00341         if(dimid != -1)
00342                 return NC_ENAMEINUSE;
00343         
00344         dimp = new_NC_dim(name, size);
00345         if(dimp == NULL)
00346                 return NC_ENOMEM;
00347         status = incr_NC_dimarray(&ncp->dims, dimp);
00348         if(status != NC_NOERR)
00349         {
00350                 free_NC_dim(dimp);
00351                 return status;
00352         }
00353 
00354         if(dimidp != NULL)
00355                 *dimidp = (int)ncp->dims.nelems -1;
00356         return NC_NOERR;
00357 }
00358 
00359 
00360 int
00361 nc_inq_dimid(int ncid, const char *name, int *dimid_ptr)
00362 {
00363         int status;
00364         NC *ncp;
00365         int dimid;
00366 
00367         status = NC_check_id(ncid, &ncp); 
00368         if(status != NC_NOERR)
00369                 return status;
00370 
00371         dimid = NC_finddim(&ncp->dims, name, NULL);
00372 
00373         if(dimid == -1)
00374                 return NC_EBADDIM;
00375 
00376         *dimid_ptr = dimid;
00377         return NC_NOERR;
00378 }
00379 
00380 
00381 int
00382 nc_inq_dim(int ncid, int dimid, char *name, size_t *sizep)
00383 {
00384         int status;
00385         NC *ncp;
00386         NC_dim *dimp;
00387 
00388         status = NC_check_id(ncid, &ncp); 
00389         if(status != NC_NOERR)
00390                 return status;
00391 
00392         dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid);
00393         if(dimp == NULL)
00394                 return NC_EBADDIM;
00395 
00396         if(name != NULL)
00397         {
00398                 (void)strncpy(name, dimp->name->cp, 
00399                         dimp->name->nchars);
00400                 name[dimp->name->nchars] = 0;
00401         }
00402         if(sizep != 0)
00403         {
00404                 if(dimp->size == NC_UNLIMITED)
00405                         *sizep = NC_get_numrecs(ncp);
00406                 else
00407                         *sizep = dimp->size;    
00408         }
00409         return NC_NOERR;
00410 }
00411 
00412 
00413 int 
00414 nc_inq_dimname(int ncid, int dimid, char *name)
00415 {
00416         int status;
00417         NC *ncp;
00418         NC_dim *dimp;
00419 
00420         status = NC_check_id(ncid, &ncp); 
00421         if(status != NC_NOERR)
00422                 return status;
00423 
00424         dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid);
00425         if(dimp == NULL)
00426                 return NC_EBADDIM;
00427 
00428         if(name != NULL)
00429         {
00430                 (void)strncpy(name, dimp->name->cp, 
00431                         dimp->name->nchars);
00432                 name[dimp->name->nchars] = 0;
00433         }
00434 
00435         return NC_NOERR;
00436 }
00437 
00438 
00439 int 
00440 nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
00441 {
00442         int status;
00443         NC *ncp;
00444         NC_dim *dimp;
00445 
00446         status = NC_check_id(ncid, &ncp); 
00447         if(status != NC_NOERR)
00448                 return status;
00449 
00450         dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid);
00451         if(dimp == NULL)
00452                 return NC_EBADDIM;
00453 
00454         if(lenp != 0)
00455         {
00456                 if(dimp->size == NC_UNLIMITED)
00457                         *lenp = NC_get_numrecs(ncp);
00458                 else
00459                         *lenp = dimp->size;     
00460         }
00461         return NC_NOERR;
00462 }
00463 
00464 
00465 int
00466 nc_rename_dim( int ncid, int dimid, const char *newname)
00467 {
00468         int status;
00469         NC *ncp;
00470         int existid;
00471         NC_dim *dimp;
00472 
00473         status = NC_check_id(ncid, &ncp); 
00474         if(status != NC_NOERR)
00475                 return status;
00476 
00477         if(NC_readonly(ncp))
00478                 return NC_EPERM;
00479 
00480         status = NC_check_name(newname);
00481         if(status != NC_NOERR)
00482                 return status;
00483 
00484         existid = NC_finddim(&ncp->dims, newname, &dimp);
00485         if(existid != -1)
00486                 return NC_ENAMEINUSE;
00487 
00488         dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid);
00489         if(dimp == NULL)
00490                 return NC_EBADDIM;
00491 
00492         if(NC_indef(ncp))
00493         {
00494                 NC_string *old = dimp->name;
00495                 NC_string *newStr = new_NC_string(strlen(newname), newname);
00496                 if(newStr == NULL)
00497                         return NC_ENOMEM;
00498                 dimp->name = newStr;
00499                 free_NC_string(old);
00500                 return NC_NOERR;
00501         }
00502 
00503         /* else, not in define mode */
00504 
00505         status = set_NC_string(dimp->name, newname);
00506         if(status != NC_NOERR)
00507                 return status;
00508 
00509         set_NC_hdirty(ncp);
00510 
00511         if(NC_doHsync(ncp))
00512         {
00513                 status = NC_sync(ncp);
00514                 if(status != NC_NOERR)
00515                         return status;
00516         }
00517 
00518         return NC_NOERR;
00519 }
 

Powered by Plone

This site conforms to the following standards: