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  

attr.c

Go to the documentation of this file.
00001 /* Do not edit this file. It is produced from the corresponding .m4 source */
00002 /*
00003  *      Copyright 1996, University Corporation for Atmospheric Research
00004  *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
00005  */
00006 
00007 #include "nc.h"
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <assert.h>
00011 #include "ncx.h"
00012 #include "fbits.h"
00013 #include "rnd.h"
00014 
00015 
00016 /*
00017  * Free attr
00018  * Formerly
00019 NC_free_attr()
00020  */
00021 void
00022 free_NC_attr(NC_attr *attrp)
00023 {
00024 
00025         if(attrp == NULL)
00026                 return;
00027         free_NC_string(attrp->name);
00028         free(attrp);
00029 }
00030 
00031 
00032 /*
00033  * How much space will 'nelems' of 'type' take in
00034  *  external representation (as the values of an attribute)?
00035  */
00036 static size_t
00037 ncx_len_NC_attrV(nc_type type, size_t nelems)
00038 {
00039         switch(type) {
00040         case NC_BYTE:
00041         case NC_CHAR:
00042                 return ncx_len_char(nelems);
00043         case NC_SHORT:
00044                 return ncx_len_short(nelems);
00045         case NC_INT:
00046                 return ncx_len_int(nelems);
00047         case NC_FLOAT:
00048                 return ncx_len_float(nelems);
00049         case NC_DOUBLE:
00050                 return ncx_len_double(nelems);
00051         }
00052         /* default */
00053         assert("ncx_len_NC_attr bad type" == 0);
00054         return 0;
00055 }
00056 
00057 
00058 NC_attr *
00059 new_x_NC_attr(
00060         NC_string *strp,
00061         nc_type type,
00062         size_t nelems)
00063 {
00064         NC_attr *attrp;
00065         const size_t xsz = ncx_len_NC_attrV(type, nelems);
00066         size_t sz = M_RNDUP(sizeof(NC_attr));
00067 
00068         assert(!(xsz == 0 && nelems != 0));
00069 
00070         sz += xsz;
00071 
00072         attrp = (NC_attr *) malloc(sz);
00073         if(attrp == NULL )
00074                 return NULL;
00075 
00076         attrp->xsz = xsz;
00077 
00078         attrp->name = strp;
00079         attrp->type = type;
00080         attrp->nelems = nelems;
00081         if(xsz != 0)
00082                 attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr));
00083         else
00084                 attrp->xvalue = NULL;
00085 
00086         return(attrp);
00087 }
00088 
00089 
00090 /*
00091  * Formerly
00092 NC_new_attr(name,type,count,value)
00093  */
00094 static NC_attr *
00095 new_NC_attr(
00096         const char *name,
00097         nc_type type,
00098         size_t nelems)
00099 {
00100         NC_string *strp;
00101         NC_attr *attrp;
00102 
00103         assert(name != NULL && *name != 0);
00104 
00105         strp = new_NC_string(strlen(name), name);
00106         if(strp == NULL)
00107                 return NULL;
00108         
00109         attrp = new_x_NC_attr(strp, type, nelems);
00110         if(attrp == NULL)
00111         {
00112                 free_NC_string(strp);
00113                 return NULL;
00114         }
00115 
00116         return(attrp);
00117 }
00118 
00119 
00120 static NC_attr *
00121 dup_NC_attr(const NC_attr *rattrp)
00122 {
00123         NC_attr *attrp = new_NC_attr(rattrp->name->cp,
00124                  rattrp->type, rattrp->nelems);
00125         if(attrp == NULL)
00126                 return NULL;
00127         (void) memcpy(attrp->xvalue, rattrp->xvalue, rattrp->xsz);
00128         return attrp;
00129 }
00130 
00131 /* attrarray */
00132 
00133 /*
00134  * Free the stuff "in" (referred to by) an NC_attrarray.
00135  * Leaves the array itself allocated.
00136  */
00137 void
00138 free_NC_attrarrayV0(NC_attrarray *ncap)
00139 {
00140         assert(ncap != NULL);
00141 
00142         if(ncap->nelems == 0)
00143                 return;
00144 
00145         assert(ncap->value != NULL);
00146 
00147         {
00148                 NC_attr **app = ncap->value;
00149                 NC_attr *const *const end = &app[ncap->nelems];
00150                 for( /*NADA*/; app < end; app++)
00151                 {
00152                         free_NC_attr(*app);
00153                         *app = NULL;
00154                 }
00155         }
00156         ncap->nelems = 0;
00157 }
00158 
00159 
00160 /*
00161  * Free NC_attrarray values.
00162  * formerly
00163 NC_free_array()
00164  */
00165 void
00166 free_NC_attrarrayV(NC_attrarray *ncap)
00167 {
00168         assert(ncap != NULL);
00169         
00170         if(ncap->nalloc == 0)
00171                 return;
00172 
00173         assert(ncap->value != NULL);
00174 
00175         free_NC_attrarrayV0(ncap);
00176 
00177         free(ncap->value);
00178         ncap->value = NULL;
00179         ncap->nalloc = 0;
00180 }
00181 
00182 
00183 int
00184 dup_NC_attrarrayV(NC_attrarray *ncap, const NC_attrarray *ref)
00185 {
00186         int status = NC_NOERR;
00187 
00188         assert(ref != NULL);
00189         assert(ncap != NULL);
00190 
00191         if(ref->nelems != 0)
00192         {
00193                 const size_t sz = ref->nelems * sizeof(NC_attr *);
00194                 ncap->value = (NC_attr **) malloc(sz);
00195                 if(ncap->value == NULL)
00196                         return NC_ENOMEM;
00197 
00198                 (void) memset(ncap->value, 0, sz);
00199                 ncap->nalloc = ref->nelems;
00200         }
00201 
00202         ncap->nelems = 0;
00203         {
00204                 NC_attr **app = ncap->value;
00205                 const NC_attr **drpp = (const NC_attr **)ref->value;
00206                 NC_attr *const *const end = &app[ref->nelems];
00207                 for( /*NADA*/; app < end; drpp++, app++, ncap->nelems++)
00208                 {
00209                         *app = dup_NC_attr(*drpp);
00210                         if(*app == NULL)
00211                         {
00212                                 status = NC_ENOMEM;
00213                                 break;
00214                         }
00215                 }
00216         }
00217 
00218         if(status != NC_NOERR)
00219         {
00220                 free_NC_attrarrayV(ncap);
00221                 return status;
00222         }
00223 
00224         assert(ncap->nelems == ref->nelems);
00225 
00226         return NC_NOERR;
00227 }
00228 
00229 
00230 /*
00231  * Add a new handle on the end of an array of handles
00232  * Formerly
00233 NC_incr_array(array, tail)
00234  */
00235 static int
00236 incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp)
00237 {
00238         NC_attr **vp;
00239 
00240         assert(ncap != NULL);
00241 
00242         if(ncap->nalloc == 0)
00243         {
00244                 assert(ncap->nelems == 0);
00245                 vp = (NC_attr **) malloc(NC_ARRAY_GROWBY * sizeof(NC_attr *));
00246                 if(vp == NULL)
00247                         return NC_ENOMEM;
00248 
00249                 ncap->value = vp;
00250                 ncap->nalloc = NC_ARRAY_GROWBY;
00251         }
00252         else if(ncap->nelems +1 > ncap->nalloc)
00253         {
00254                 vp = (NC_attr **) realloc(ncap->value,
00255                         (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_attr *));
00256                 if(vp == NULL)
00257                         return NC_ENOMEM;
00258         
00259                 ncap->value = vp;
00260                 ncap->nalloc += NC_ARRAY_GROWBY;
00261         }
00262 
00263         if(newelemp != NULL)
00264         {
00265                 ncap->value[ncap->nelems] = newelemp;
00266                 ncap->nelems++;
00267         }
00268         return NC_NOERR;
00269 }
00270 
00271 
00272 NC_attr *
00273 elem_NC_attrarray(const NC_attrarray *ncap, size_t elem)
00274 {
00275         assert(ncap != NULL);
00276                 /* cast needed for braindead systems with signed size_t */
00277         if(ncap->nelems == 0 || (unsigned long) elem >= ncap->nelems)
00278                 return NULL;
00279 
00280         assert(ncap->value != NULL);
00281 
00282         return ncap->value[elem];
00283 }
00284 
00285 /* End attarray per se */
00286 
00287 /*
00288  * Given ncp and varid, return ptr to array of attributes
00289  *  else NULL on error
00290  */
00291 static NC_attrarray *
00292 NC_attrarray0( NC *ncp, int varid)
00293 {
00294         NC_attrarray *ap;
00295 
00296         if(varid == NC_GLOBAL) /* Global attribute, attach to cdf */
00297         {
00298                 ap = &ncp->attrs;
00299         }
00300         else if(varid >= 0 && (size_t) varid < ncp->vars.nelems)
00301         {
00302                 NC_var **vpp;
00303                 vpp = (NC_var **)ncp->vars.value;
00304                 vpp += varid;
00305                 ap = &(*vpp)->attrs;
00306         } else {
00307                 ap = NULL;
00308         }
00309         return(ap);
00310 }
00311 
00312 
00313 /*
00314  * Step thru NC_ATTRIBUTE array, seeking match on name.
00315  *  return match or NULL if Not Found.
00316  */
00317 NC_attr **
00318 NC_findattr(const NC_attrarray *ncap, const char *name)
00319 {
00320         NC_attr **attrpp;
00321         size_t attrid;
00322         size_t slen;
00323 
00324         assert(ncap != NULL);
00325 
00326         if(ncap->nelems == 0)
00327                 return NULL;
00328 
00329         attrpp = (NC_attr **) ncap->value;
00330 
00331         slen = strlen(name);
00332 
00333         for(attrid = 0; attrid < ncap->nelems; attrid++, attrpp++)
00334         {
00335                 if(strlen((*attrpp)->name->cp) == slen &&
00336                         strncmp((*attrpp)->name->cp, name, slen) == 0)
00337                 {
00338                         return(attrpp); /* Normal return */
00339                 }
00340         }
00341         return(NULL);
00342 }
00343 
00344 
00345 /*
00346  * Look up by ncid, varid and name, return NULL if not found
00347  */
00348 static int 
00349 NC_lookupattr(int ncid,
00350         int varid,
00351         const char *name, /* attribute name */
00352         NC_attr **attrpp) /* modified on return */
00353 {
00354         int status;
00355         NC *ncp;
00356         NC_attrarray *ncap;
00357         NC_attr **tmp;
00358 
00359         status = NC_check_id(ncid, &ncp);
00360         if(status != NC_NOERR)
00361                 return status;
00362 
00363         ncap = NC_attrarray0(ncp, varid);
00364         if(ncap == NULL)
00365                 return NC_ENOTVAR;
00366 
00367         tmp = NC_findattr(ncap, name);
00368         if(tmp == NULL)
00369                 return NC_ENOTATT;
00370 
00371         if(attrpp != NULL)
00372                 *attrpp = *tmp;
00373 
00374         return ENOERR;
00375 }
00376 
00377 /* Public */
00378 
00379 int
00380 nc_inq_attname(int ncid, int varid, int attnum, char *name)
00381 {
00382         int status;
00383         NC *ncp;
00384         NC_attrarray *ncap;
00385         NC_attr *attrp;
00386 
00387         status = NC_check_id(ncid, &ncp);
00388         if(status != NC_NOERR)
00389                 return status;
00390 
00391         ncap = NC_attrarray0(ncp, varid);
00392         if(ncap == NULL)
00393                 return NC_ENOTVAR;
00394 
00395         attrp = elem_NC_attrarray(ncap, (size_t)attnum);
00396         if(attrp == NULL)
00397                 return NC_ENOTATT;
00398 
00399         (void) strncpy(name, attrp->name->cp, attrp->name->nchars);
00400         name[attrp->name->nchars] = 0;
00401 
00402         return NC_NOERR;
00403 }
00404 
00405 
00406 int 
00407 nc_inq_attid(int ncid, int varid, const char *name, int *attnump)
00408 {
00409         int status;
00410         NC *ncp;
00411         NC_attrarray *ncap;
00412         NC_attr **attrpp;
00413 
00414         status = NC_check_id(ncid, &ncp);
00415         if(status != NC_NOERR)
00416                 return status;
00417 
00418         ncap = NC_attrarray0(ncp, varid);
00419         if(ncap == NULL)
00420                 return NC_ENOTVAR;
00421         
00422 
00423         attrpp = NC_findattr(ncap, name);
00424         if(attrpp == NULL)
00425                 return NC_ENOTATT;
00426 
00427         if(attnump != NULL)
00428                 *attnump = (int)(attrpp - ncap->value);
00429 
00430         return NC_NOERR;
00431 }
00432 
00433 int 
00434 nc_inq_atttype(int ncid, int varid, const char *name, nc_type *datatypep)
00435 {
00436         int status;
00437         NC_attr *attrp;
00438 
00439         status = NC_lookupattr(ncid, varid, name, &attrp);
00440         if(status != NC_NOERR)
00441                 return status;
00442 
00443         if(datatypep != NULL)
00444                 *datatypep = attrp->type;
00445 
00446         return NC_NOERR;
00447 }
00448 
00449 int 
00450 nc_inq_attlen(int ncid, int varid, const char *name, size_t *lenp)
00451 {
00452         int status;
00453         NC_attr *attrp;
00454 
00455         status = NC_lookupattr(ncid, varid, name, &attrp);
00456         if(status != NC_NOERR)
00457                 return status;
00458 
00459         if(lenp != NULL)
00460                 *lenp = attrp->nelems;
00461 
00462         return NC_NOERR;
00463 }
00464 
00465 int
00466 nc_inq_att(int ncid,
00467         int varid,
00468         const char *name, /* input, attribute name */
00469         nc_type *datatypep,
00470         size_t *lenp)
00471 {
00472         int status;
00473         NC_attr *attrp;
00474 
00475         status = NC_lookupattr(ncid, varid, name, &attrp);
00476         if(status != NC_NOERR)
00477                 return status;
00478 
00479         if(datatypep != NULL)
00480                 *datatypep = attrp->type;
00481         if(lenp != NULL)
00482                 *lenp = attrp->nelems;
00483 
00484         return NC_NOERR;
00485 }
00486 
00487 
00488 int
00489 nc_rename_att( int ncid, int varid, const char *name, const char *newname)
00490 {
00491         int status;
00492         NC *ncp;
00493         NC_attrarray *ncap;
00494         NC_attr **tmp;
00495         NC_attr *attrp;
00496         NC_string *newStr, *old;
00497 
00498                         /* sortof inline clone of NC_lookupattr() */
00499         status = NC_check_id(ncid, &ncp);
00500         if(status != NC_NOERR)
00501                 return status;
00502 
00503         if(NC_readonly(ncp))
00504                 return NC_EPERM;
00505 
00506         ncap = NC_attrarray0(ncp, varid);
00507         if(ncap == NULL)
00508                 return NC_ENOTVAR;
00509 
00510         status = NC_check_name(name);
00511         if(status != NC_NOERR)
00512                 return status;
00513 
00514         tmp = NC_findattr(ncap, name);
00515         if(tmp == NULL)
00516                 return NC_ENOTATT;
00517         attrp = *tmp;
00518                         /* end inline clone NC_lookupattr() */
00519 
00520         if(NC_findattr(ncap, newname) != NULL)
00521         {
00522                 /* name in use */
00523                 return NC_ENAMEINUSE;
00524         }
00525 
00526         old = attrp->name;
00527         if(NC_indef(ncp))
00528         {
00529                 newStr = new_NC_string(strlen(newname), newname);
00530                 if( newStr == NULL)
00531                         return NC_ENOMEM;
00532                 attrp->name = newStr;
00533                 free_NC_string(old);
00534                 return NC_NOERR;
00535         }
00536         /* else */
00537         status = set_NC_string(old, newname);
00538         if( status != NC_NOERR)
00539                 return status;
00540 
00541         set_NC_hdirty(ncp);
00542 
00543         if(NC_doHsync(ncp))
00544         {
00545                 status = NC_sync(ncp);
00546                 if(status != NC_NOERR)
00547                         return status;
00548         }
00549 
00550         return NC_NOERR;
00551 }
00552 
00553 
00554 int
00555 nc_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out, int ovarid)
00556 {
00557         int status;
00558         NC_attr *iattrp;
00559         NC *ncp;
00560         NC_attrarray *ncap;
00561         NC_attr **attrpp;
00562         NC_attr *old = NULL;
00563         NC_attr *attrp;
00564 
00565         status = NC_lookupattr(ncid_in, varid_in, name, &iattrp);
00566         if(status != NC_NOERR)
00567                 return status;
00568 
00569         status = NC_check_id(ncid_out, &ncp);
00570         if(status != NC_NOERR)
00571                 return status;
00572 
00573         if(NC_readonly(ncp))
00574                 return NC_EPERM;
00575 
00576         ncap = NC_attrarray0(ncp, ovarid);
00577         if(ncap == NULL)
00578                 return NC_ENOTVAR;
00579 
00580         attrpp = NC_findattr(ncap, name);
00581         if(attrpp != NULL) /* name in use */
00582         {
00583                 if(!NC_indef(ncp) )
00584                 {
00585                         attrp = *attrpp; /* convenience */
00586         
00587                         if(iattrp->xsz > attrp->xsz)
00588                                 return NC_ENOTINDEFINE;
00589                         /* else, we can reuse existing without redef */
00590                         
00591                         attrp->xsz = iattrp->xsz;
00592                         attrp->type = iattrp->type;
00593                         attrp->nelems = iattrp->nelems;
00594 
00595                         (void) memcpy(attrp->xvalue, iattrp->xvalue,
00596                                 iattrp->xsz);
00597                         
00598                         set_NC_hdirty(ncp);
00599 
00600                         if(NC_doHsync(ncp))
00601                         {
00602                                 status = NC_sync(ncp);
00603                                 if(status != NC_NOERR)
00604                                         return status;
00605                         }
00606 
00607                         return NC_NOERR;
00608                 }
00609                 /* else, redefine using existing array slot */
00610                 old = *attrpp;
00611         } 
00612         else
00613         {
00614                 if(!NC_indef(ncp))
00615                         return NC_ENOTINDEFINE;
00616 
00617                 if(ncap->nelems >= NC_MAX_ATTRS)
00618                         return NC_EMAXATTS;
00619         }
00620 
00621         attrp = new_NC_attr(name, iattrp->type, iattrp->nelems);
00622         if(attrp == NULL)
00623                 return NC_ENOMEM;
00624 
00625         (void) memcpy(attrp->xvalue, iattrp->xvalue,
00626                 iattrp->xsz);
00627 
00628         if(attrpp != NULL)
00629         {
00630                 assert(old != NULL);
00631                 *attrpp = attrp;
00632                 free_NC_attr(old);
00633         }
00634         else
00635         {
00636                 status = incr_NC_attrarray(ncap, attrp);
00637                 if(status != NC_NOERR)
00638                 {
00639                         free_NC_attr(attrp);
00640                         return status;
00641                 }
00642         }
00643 
00644         return NC_NOERR;
00645 }
00646 
00647 
00648 int
00649 nc_del_att(int ncid, int varid, const char *name)
00650 {
00651         int status;
00652         NC *ncp;
00653         NC_attrarray *ncap;
00654         NC_attr **attrpp;
00655         NC_attr *old = NULL;
00656         int attrid;
00657         size_t slen;
00658 
00659         status = NC_check_id(ncid, &ncp);
00660         if(status != NC_NOERR)
00661                 return status;
00662 
00663         if(!NC_indef(ncp))
00664                 return NC_ENOTINDEFINE;
00665 
00666         ncap = NC_attrarray0(ncp, varid);
00667         if(ncap == NULL)
00668                 return NC_ENOTVAR;
00669 
00670                         /* sortof inline NC_findattr() */
00671         slen = strlen(name);
00672 
00673         attrpp = (NC_attr **) ncap->value;
00674         for(attrid = 0; (size_t) attrid < ncap->nelems; attrid++, attrpp++)
00675         {
00676                 if( slen == (*attrpp)->name->nchars &&
00677                         strncmp(name, (*attrpp)->name->cp, slen) == 0)
00678                 {
00679                         old = *attrpp;
00680                         break;
00681                 }
00682         }
00683         if( (size_t) attrid == ncap->nelems )
00684                 return NC_ENOTATT;
00685                         /* end inline NC_findattr() */
00686 
00687         /* shuffle down */
00688         for(attrid++; (size_t) attrid < ncap->nelems; attrid++)
00689         {
00690                 *attrpp = *(attrpp + 1);
00691                 attrpp++;
00692         }
00693         *attrpp = NULL;
00694         /* decrement count */
00695         ncap->nelems--;
00696 
00697         free_NC_attr(old);
00698 
00699         return NC_NOERR;
00700 }
00701 
00702 
00703 static int
00704 ncx_pad_putn_Iuchar(void **xpp, size_t nelems, const uchar *tp, nc_type type)
00705 {
00706         switch(type) {
00707         case NC_CHAR:
00708                 return NC_ECHAR;
00709         case NC_BYTE:
00710                 return ncx_pad_putn_schar_uchar(xpp, nelems, tp);
00711         case NC_SHORT:
00712                 return ncx_pad_putn_short_uchar(xpp, nelems, tp);
00713         case NC_INT:
00714                 return ncx_putn_int_uchar(xpp, nelems, tp);
00715         case NC_FLOAT:
00716                 return ncx_putn_float_uchar(xpp, nelems, tp);
00717         case NC_DOUBLE:
00718                 return ncx_putn_double_uchar(xpp, nelems, tp);
00719         }
00720         assert("ncx_pad_putn_Iuchar invalid type" == 0);
00721         return NC_EBADTYPE;
00722 }
00723 
00724 static int
00725 ncx_pad_getn_Iuchar(const void **xpp, size_t nelems, uchar *tp, nc_type type)
00726 {
00727         switch(type) {
00728         case NC_CHAR:
00729                 return NC_ECHAR;
00730         case NC_BYTE:
00731                 return ncx_pad_getn_schar_uchar(xpp, nelems, tp);
00732         case NC_SHORT:
00733                 return ncx_pad_getn_short_uchar(xpp, nelems, tp);
00734         case NC_INT:
00735                 return ncx_getn_int_uchar(xpp, nelems, tp);
00736         case NC_FLOAT:
00737                 return ncx_getn_float_uchar(xpp, nelems, tp);
00738         case NC_DOUBLE:
00739                 return ncx_getn_double_uchar(xpp, nelems, tp);
00740         }
00741         assert("ncx_pad_getn_Iuchar invalid type" == 0);
00742         return NC_EBADTYPE;
00743 }
00744 
00745 
00746 static int
00747 ncx_pad_putn_Ischar(void **xpp, size_t nelems, const schar *tp, nc_type type)
00748 {
00749         switch(type) {
00750         case NC_CHAR:
00751                 return NC_ECHAR;
00752         case NC_BYTE:
00753                 return ncx_pad_putn_schar_schar(xpp, nelems, tp);
00754         case NC_SHORT:
00755                 return ncx_pad_putn_short_schar(xpp, nelems, tp);
00756         case NC_INT:
00757                 return ncx_putn_int_schar(xpp, nelems, tp);
00758         case NC_FLOAT:
00759                 return ncx_putn_float_schar(xpp, nelems, tp);
00760         case NC_DOUBLE:
00761                 return ncx_putn_double_schar(xpp, nelems, tp);
00762         }
00763         assert("ncx_pad_putn_Ischar invalid type" == 0);
00764         return NC_EBADTYPE;
00765 }
00766 
00767 static int
00768 ncx_pad_getn_Ischar(const void **xpp, size_t nelems, schar *tp, nc_type type)
00769 {
00770         switch(type) {
00771         case NC_CHAR:
00772                 return NC_ECHAR;
00773         case NC_BYTE:
00774                 return ncx_pad_getn_schar_schar(xpp, nelems, tp);
00775         case NC_SHORT:
00776                 return ncx_pad_getn_short_schar(xpp, nelems, tp);
00777         case NC_INT:
00778                 return ncx_getn_int_schar(xpp, nelems, tp);
00779         case NC_FLOAT:
00780                 return ncx_getn_float_schar(xpp, nelems, tp);
00781         case NC_DOUBLE:
00782                 return ncx_getn_double_schar(xpp, nelems, tp);
00783         }
00784         assert("ncx_pad_getn_Ischar invalid type" == 0);
00785         return NC_EBADTYPE;
00786 }
00787 
00788 
00789 static int
00790 ncx_pad_putn_Ishort(void **xpp, size_t nelems, const short *tp, nc_type type)
00791 {
00792         switch(type) {
00793         case NC_CHAR:
00794                 return NC_ECHAR;
00795         case NC_BYTE:
00796                 return ncx_pad_putn_schar_short(xpp, nelems, tp);
00797         case NC_SHORT:
00798                 return ncx_pad_putn_short_short(xpp, nelems, tp);
00799         case NC_INT:
00800                 return ncx_putn_int_short(xpp, nelems, tp);
00801         case NC_FLOAT:
00802                 return ncx_putn_float_short(xpp, nelems, tp);
00803         case NC_DOUBLE:
00804                 return ncx_putn_double_short(xpp, nelems, tp);
00805         }
00806         assert("ncx_pad_putn_Ishort invalid type" == 0);
00807         return NC_EBADTYPE;
00808 }
00809 
00810 static int
00811 ncx_pad_getn_Ishort(const void **xpp, size_t nelems, short *tp, nc_type type)
00812 {
00813         switch(type) {
00814         case NC_CHAR:
00815                 return NC_ECHAR;
00816         case NC_BYTE:
00817                 return ncx_pad_getn_schar_short(xpp, nelems, tp);
00818         case NC_SHORT:
00819                 return ncx_pad_getn_short_short(xpp, nelems, tp);
00820         case NC_INT:
00821                 return ncx_getn_int_short(xpp, nelems, tp);
00822         case NC_FLOAT:
00823                 return ncx_getn_float_short(xpp, nelems, tp);
00824         case NC_DOUBLE:
00825                 return ncx_getn_double_short(xpp, nelems, tp);
00826         }
00827         assert("ncx_pad_getn_Ishort invalid type" == 0);
00828         return NC_EBADTYPE;
00829 }
00830 
00831 
00832 static int
00833 ncx_pad_putn_Iint(void **xpp, size_t nelems, const int *tp, nc_type type)
00834 {
00835         switch(type) {
00836         case NC_CHAR:
00837                 return NC_ECHAR;
00838         case NC_BYTE:
00839                 return ncx_pad_putn_schar_int(xpp, nelems, tp);
00840         case NC_SHORT:
00841                 return ncx_pad_putn_short_int(xpp, nelems, tp);
00842         case NC_INT:
00843                 return ncx_putn_int_int(xpp, nelems, tp);
00844         case NC_FLOAT:
00845                 return ncx_putn_float_int(xpp, nelems, tp);
00846         case NC_DOUBLE:
00847                 return ncx_putn_double_int(xpp, nelems, tp);
00848         }
00849         assert("ncx_pad_putn_Iint invalid type" == 0);
00850         return NC_EBADTYPE;
00851 }
00852 
00853 static int
00854 ncx_pad_getn_Iint(const void **xpp, size_t nelems, int *tp, nc_type type)
00855 {
00856         switch(type) {
00857         case NC_CHAR:
00858                 return NC_ECHAR;
00859         case NC_BYTE:
00860                 return ncx_pad_getn_schar_int(xpp, nelems, tp);
00861         case NC_SHORT:
00862                 return ncx_pad_getn_short_int(xpp, nelems, tp);
00863         case NC_INT:
00864                 return ncx_getn_int_int(xpp, nelems, tp);
00865         case NC_FLOAT:
00866                 return ncx_getn_float_int(xpp, nelems, tp);
00867         case NC_DOUBLE:
00868                 return ncx_getn_double_int(xpp, nelems, tp);
00869         }
00870         assert("ncx_pad_getn_Iint invalid type" == 0);
00871         return NC_EBADTYPE;
00872 }
00873 
00874 
00875 static int
00876 ncx_pad_putn_Ilong(void **xpp, size_t nelems, const long *tp, nc_type type)
00877 {
00878         switch(type) {
00879         case NC_CHAR:
00880                 return NC_ECHAR;
00881         case NC_BYTE:
00882                 return ncx_pad_putn_schar_long(xpp, nelems, tp);
00883         case NC_SHORT:
00884                 return ncx_pad_putn_short_long(xpp, nelems, tp);
00885         case NC_INT:
00886                 return ncx_putn_int_long(xpp, nelems, tp);
00887         case NC_FLOAT:
00888                 return ncx_putn_float_long(xpp, nelems, tp);
00889         case NC_DOUBLE:
00890                 return ncx_putn_double_long(xpp, nelems, tp);
00891         }
00892         assert("ncx_pad_putn_Ilong invalid type" == 0);
00893         return NC_EBADTYPE;
00894 }
00895 
00896 static int
00897 ncx_pad_getn_Ilong(const void **xpp, size_t nelems, long *tp, nc_type type)
00898 {
00899         switch(type) {
00900         case NC_CHAR:
00901                 return NC_ECHAR;
00902         case NC_BYTE:
00903                 return ncx_pad_getn_schar_long(xpp, nelems, tp);
00904         case NC_SHORT:
00905                 return ncx_pad_getn_short_long(xpp, nelems, tp);
00906         case NC_INT:
00907                 return ncx_getn_int_long(xpp, nelems, tp);
00908         case NC_FLOAT:
00909                 return ncx_getn_float_long(xpp, nelems, tp);
00910         case NC_DOUBLE:
00911                 return ncx_getn_double_long(xpp, nelems, tp);
00912         }
00913         assert("ncx_pad_getn_Ilong invalid type" == 0);
00914         return NC_EBADTYPE;
00915 }
00916 
00917 
00918 static int
00919 ncx_pad_putn_Ifloat(void **xpp, size_t nelems, const float *tp, nc_type type)
00920 {
00921         switch(type) {
00922         case NC_CHAR:
00923                 return NC_ECHAR;
00924         case NC_BYTE:
00925                 return ncx_pad_putn_schar_float(xpp, nelems, tp);
00926         case NC_SHORT:
00927                 return ncx_pad_putn_short_float(xpp, nelems, tp);
00928         case NC_INT:
00929                 return ncx_putn_int_float(xpp, nelems, tp);
00930         case NC_FLOAT:
00931                 return ncx_putn_float_float(xpp, nelems, tp);
00932         case NC_DOUBLE:
00933                 return ncx_putn_double_float(xpp, nelems, tp);
00934         }
00935         assert("ncx_pad_putn_Ifloat invalid type" == 0);
00936         return NC_EBADTYPE;
00937 }
00938 
00939 static int
00940 ncx_pad_getn_Ifloat(const void **xpp, size_t nelems, float *tp, nc_type type)
00941 {
00942         switch(type) {
00943         case NC_CHAR:
00944                 return NC_ECHAR;
00945         case NC_BYTE:
00946                 return ncx_pad_getn_schar_float(xpp, nelems, tp);
00947         case NC_SHORT:
00948                 return ncx_pad_getn_short_float(xpp, nelems, tp);
00949         case NC_INT:
00950                 return ncx_getn_int_float(xpp, nelems, tp);
00951         case NC_FLOAT:
00952                 return ncx_getn_float_float(xpp, nelems, tp);
00953         case NC_DOUBLE:
00954                 return ncx_getn_double_float(xpp, nelems, tp);
00955         }
00956         assert("ncx_pad_getn_Ifloat invalid type" == 0);
00957         return NC_EBADTYPE;
00958 }
00959 
00960 
00961 static int
00962 ncx_pad_putn_Idouble(void **xpp, size_t nelems, const double *tp, nc_type type)
00963 {
00964         switch(type) {
00965         case NC_CHAR:
00966                 return NC_ECHAR;
00967         case NC_BYTE:
00968                 return ncx_pad_putn_schar_double(xpp, nelems, tp);
00969         case NC_SHORT:
00970                 return ncx_pad_putn_short_double(xpp, nelems, tp);
00971         case NC_INT:
00972                 return ncx_putn_int_double(xpp, nelems, tp);
00973         case NC_FLOAT:
00974                 return ncx_putn_float_double(xpp, nelems, tp);
00975         case NC_DOUBLE:
00976                 return ncx_putn_double_double(xpp, nelems, tp);
00977         }
00978         assert("ncx_pad_putn_Idouble invalid type" == 0);
00979         return NC_EBADTYPE;
00980 }
00981 
00982 static int
00983 ncx_pad_getn_Idouble(const void **xpp, size_t nelems, double *tp, nc_type type)
00984 {
00985         switch(type) {
00986         case NC_CHAR:
00987                 return NC_ECHAR;
00988         case NC_BYTE:
00989                 return ncx_pad_getn_schar_double(xpp, nelems, tp);
00990         case NC_SHORT:
00991                 return ncx_pad_getn_short_double(xpp, nelems, tp);
00992         case NC_INT:
00993                 return ncx_getn_int_double(xpp, nelems, tp);
00994         case NC_FLOAT:
00995                 return ncx_getn_float_double(xpp, nelems, tp);
00996         case NC_DOUBLE:
00997                 return ncx_getn_double_double(xpp, nelems, tp);
00998         }
00999         assert("ncx_pad_getn_Idouble invalid type" == 0);
01000         return NC_EBADTYPE;
01001 }
01002 
01003 
01004 
01005 int
01006 nc_put_att_text(int ncid, int varid, const char *name,
01007         size_t nelems, const char *value)
01008 {
01009         int status;
01010         NC *ncp;
01011         NC_attrarray *ncap;
01012         NC_attr **attrpp;
01013         NC_attr *old = NULL;
01014         NC_attr *attrp;
01015 
01016         status = NC_check_id(ncid, &ncp);
01017         if(status != NC_NOERR)
01018                 return status;
01019 
01020         if(NC_readonly(ncp))
01021                 return NC_EPERM;
01022 
01023         ncap = NC_attrarray0(ncp, varid);
01024         if(ncap == NULL)
01025                 return NC_ENOTVAR;
01026 
01027         status = NC_check_name(name);
01028         if(status != NC_NOERR)
01029                 return status;
01030 
01031                 /* cast needed for braindead systems with signed size_t */
01032         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01033                 return NC_EINVAL; /* Invalid nelems */
01034 
01035         if(nelems != 0 && value == NULL)
01036                 return NC_EINVAL; /* Null arg */
01037 
01038         attrpp = NC_findattr(ncap, name);
01039         if(attrpp != NULL) /* name in use */
01040         {
01041                 if(!NC_indef(ncp) )
01042                 {
01043                         const size_t xsz = ncx_len_NC_attrV(NC_CHAR, nelems);
01044                         attrp = *attrpp; /* convenience */
01045         
01046                         if(xsz > attrp->xsz)
01047                                 return NC_ENOTINDEFINE;
01048                         /* else, we can reuse existing without redef */
01049                         
01050                         attrp->xsz = xsz;
01051                         attrp->type = NC_CHAR;
01052                         attrp->nelems = nelems;
01053 
01054                         if(nelems != 0)
01055                         {
01056                                 void *xp = attrp->xvalue;
01057                                 status = ncx_pad_putn_text(&xp, nelems, value);
01058                                 if(status != NC_NOERR)
01059                                         return status;
01060                         }
01061                         
01062                         set_NC_hdirty(ncp);
01063 
01064                         if(NC_doHsync(ncp))
01065                         {
01066                                 status = NC_sync(ncp);
01067                                 if(status != NC_NOERR)
01068                                         return status;
01069                         }
01070 
01071                         return NC_NOERR;
01072                 }
01073                 /* else, redefine using existing array slot */
01074                 old = *attrpp;
01075         } 
01076         else
01077         {
01078                 if(!NC_indef(ncp))
01079                         return NC_ENOTINDEFINE;
01080 
01081                 if(ncap->nelems >= NC_MAX_ATTRS)
01082                         return NC_EMAXATTS;
01083         }
01084 
01085         attrp = new_NC_attr(name, NC_CHAR, nelems);
01086         if(attrp == NULL)
01087                 return NC_ENOMEM;
01088 
01089         if(nelems != 0)
01090         {
01091                 void *xp = attrp->xvalue;
01092                 status = ncx_pad_putn_text(&xp, nelems, value);
01093                 if(status != NC_NOERR)
01094                         return status;
01095         }
01096 
01097         if(attrpp != NULL)
01098         {
01099                 assert(old != NULL);
01100                 *attrpp = attrp;
01101                 free_NC_attr(old);
01102         }
01103         else
01104         {
01105                 status = incr_NC_attrarray(ncap, attrp);
01106                 if(status != NC_NOERR)
01107                 {
01108                         free_NC_attr(attrp);
01109                         return status;
01110                 }
01111         }
01112 
01113         return NC_NOERR;
01114 }
01115 
01116 
01117 int
01118 nc_get_att_text(int ncid, int varid, const char *name, char *str)
01119 {
01120         int status;
01121         NC_attr *attrp;
01122 
01123         status = NC_lookupattr(ncid, varid, name, &attrp);
01124         if(status != NC_NOERR)
01125                 return status;
01126 
01127         if(attrp->nelems == 0)
01128                 return NC_NOERR;
01129 
01130         if(attrp->type != NC_CHAR)
01131                 return NC_ECHAR;
01132 
01133         /* else */
01134         {
01135                 const void *xp = attrp->xvalue;
01136                 return ncx_pad_getn_text(&xp, attrp->nelems, str);
01137         }
01138 }
01139 
01140 
01141 
01142 
01143 int
01144 nc_put_att_schar(int ncid, int varid, const char *name,
01145         nc_type type, size_t nelems, const signed char *value)
01146 {
01147         int status;
01148         NC *ncp;
01149         NC_attrarray *ncap;
01150         NC_attr **attrpp;
01151         NC_attr *old = NULL;
01152         NC_attr *attrp;
01153 
01154         status = NC_check_id(ncid, &ncp);
01155         if(status != NC_NOERR)
01156                 return status;
01157 
01158         if(NC_readonly(ncp))
01159                 return NC_EPERM;
01160 
01161         ncap = NC_attrarray0(ncp, varid);
01162         if(ncap == NULL)
01163                 return NC_ENOTVAR;
01164 
01165         status = nc_cktype(type);
01166         if(status != NC_NOERR)
01167                 return status;
01168 
01169         if(type == NC_CHAR)
01170                 return NC_ECHAR;
01171 
01172                 /* cast needed for braindead systems with signed size_t */
01173         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01174                 return NC_EINVAL; /* Invalid nelems */
01175 
01176         if(nelems != 0 && value == NULL)
01177                 return NC_EINVAL; /* Null arg */
01178 
01179         attrpp = NC_findattr(ncap, name);
01180         if(attrpp != NULL) /* name in use */
01181         {
01182                 if(!NC_indef(ncp) )
01183                 {
01184                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
01185                         attrp = *attrpp; /* convenience */
01186         
01187                         if(xsz > attrp->xsz)
01188                                 return NC_ENOTINDEFINE;
01189                         /* else, we can reuse existing without redef */
01190                         
01191                         attrp->xsz = xsz;
01192                         attrp->type = type;
01193                         attrp->nelems = nelems;
01194 
01195                         if(nelems != 0)
01196                         {
01197                                 void *xp = attrp->xvalue;
01198                                 status = ncx_pad_putn_Ischar(&xp, nelems,
01199                                         value, type);
01200                         }
01201                         
01202                         set_NC_hdirty(ncp);
01203 
01204                         if(NC_doHsync(ncp))
01205                         {
01206                                 const int lstatus = NC_sync(ncp);
01207                                 /*
01208                                  * N.B.: potentially overrides NC_ERANGE
01209                                  * set by ncx_pad_putn_Ischar
01210                                  */
01211                                 if(lstatus != ENOERR)
01212                                         return lstatus;
01213                         }
01214 
01215                         return status;
01216                 }
01217                 /* else, redefine using existing array slot */
01218                 old = *attrpp;
01219         } 
01220         else
01221         {
01222                 if(!NC_indef(ncp))
01223                         return NC_ENOTINDEFINE;
01224 
01225                 if(ncap->nelems >= NC_MAX_ATTRS)
01226                         return NC_EMAXATTS;
01227         }
01228 
01229         status = NC_check_name(name);
01230         if(status != NC_NOERR)
01231                 return status;
01232 
01233         attrp = new_NC_attr(name, type, nelems);
01234         if(attrp == NULL)
01235                 return NC_ENOMEM;
01236 
01237         if(nelems != 0)
01238         {
01239                 void *xp = attrp->xvalue;
01240                 status = ncx_pad_putn_Ischar(&xp, nelems,
01241                         value, type);
01242         }
01243 
01244         if(attrpp != NULL)
01245         {
01246                 assert(old != NULL);
01247                 *attrpp = attrp;
01248                 free_NC_attr(old);
01249         }
01250         else
01251         {
01252                 const int lstatus = incr_NC_attrarray(ncap, attrp);
01253                 /*
01254                  * N.B.: potentially overrides NC_ERANGE
01255                  * set by ncx_pad_putn_Ischar
01256                  */
01257                 if(lstatus != NC_NOERR)
01258                 {
01259                         free_NC_attr(attrp);
01260                         return lstatus;
01261                 }
01262         }
01263 
01264         return status;
01265 }
01266 
01267 int
01268 nc_get_att_schar(int ncid, int varid, const char *name, signed char *tp)
01269 {
01270         int status;
01271         NC_attr *attrp;
01272 
01273         status = NC_lookupattr(ncid, varid, name, &attrp);
01274         if(status != NC_NOERR)
01275                 return status;
01276 
01277         if(attrp->nelems == 0)
01278                 return NC_NOERR;
01279 
01280         if(attrp->type == NC_CHAR)
01281                 return NC_ECHAR;
01282 
01283         {
01284         const void *xp = attrp->xvalue;
01285         return ncx_pad_getn_Ischar(&xp, attrp->nelems, tp, attrp->type);
01286         }
01287 }
01288 
01289 
01290 int
01291 nc_put_att_uchar(int ncid, int varid, const char *name,
01292         nc_type type, size_t nelems, const unsigned char *value)
01293 {
01294         int status;
01295         NC *ncp;
01296         NC_attrarray *ncap;
01297         NC_attr **attrpp;
01298         NC_attr *old = NULL;
01299         NC_attr *attrp;
01300 
01301         status = NC_check_id(ncid, &ncp);
01302         if(status != NC_NOERR)
01303                 return status;
01304 
01305         if(NC_readonly(ncp))
01306                 return NC_EPERM;
01307 
01308         ncap = NC_attrarray0(ncp, varid);
01309         if(ncap == NULL)
01310                 return NC_ENOTVAR;
01311 
01312         status = nc_cktype(type);
01313         if(status != NC_NOERR)
01314                 return status;
01315 
01316         if(type == NC_CHAR)
01317                 return NC_ECHAR;
01318 
01319                 /* cast needed for braindead systems with signed size_t */
01320         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01321                 return NC_EINVAL; /* Invalid nelems */
01322 
01323         if(nelems != 0 && value == NULL)
01324                 return NC_EINVAL; /* Null arg */
01325 
01326         attrpp = NC_findattr(ncap, name);
01327         if(attrpp != NULL) /* name in use */
01328         {
01329                 if(!NC_indef(ncp) )
01330                 {
01331                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
01332                         attrp = *attrpp; /* convenience */
01333         
01334                         if(xsz > attrp->xsz)
01335                                 return NC_ENOTINDEFINE;
01336                         /* else, we can reuse existing without redef */
01337                         
01338                         attrp->xsz = xsz;
01339                         attrp->type = type;
01340                         attrp->nelems = nelems;
01341 
01342                         if(nelems != 0)
01343                         {
01344                                 void *xp = attrp->xvalue;
01345                                 status = ncx_pad_putn_Iuchar(&xp, nelems,
01346                                         value, type);
01347                         }
01348                         
01349                         set_NC_hdirty(ncp);
01350 
01351                         if(NC_doHsync(ncp))
01352                         {
01353                                 const int lstatus = NC_sync(ncp);
01354                                 /*
01355                                  * N.B.: potentially overrides NC_ERANGE
01356                                  * set by ncx_pad_putn_Iuchar
01357                                  */
01358                                 if(lstatus != ENOERR)
01359                                         return lstatus;
01360                         }
01361 
01362                         return status;
01363                 }
01364                 /* else, redefine using existing array slot */
01365                 old = *attrpp;
01366         } 
01367         else
01368         {
01369                 if(!NC_indef(ncp))
01370                         return NC_ENOTINDEFINE;
01371 
01372                 if(ncap->nelems >= NC_MAX_ATTRS)
01373                         return NC_EMAXATTS;
01374         }
01375 
01376         status = NC_check_name(name);
01377         if(status != NC_NOERR)
01378                 return status;
01379 
01380         attrp = new_NC_attr(name, type, nelems);
01381         if(attrp == NULL)
01382                 return NC_ENOMEM;
01383 
01384         if(nelems != 0)
01385         {
01386                 void *xp = attrp->xvalue;
01387                 status = ncx_pad_putn_Iuchar(&xp, nelems,
01388                         value, type);
01389         }
01390 
01391         if(attrpp != NULL)
01392         {
01393                 assert(old != NULL);
01394                 *attrpp = attrp;
01395                 free_NC_attr(old);
01396         }
01397         else
01398         {
01399                 const int lstatus = incr_NC_attrarray(ncap, attrp);
01400                 /*
01401                  * N.B.: potentially overrides NC_ERANGE
01402                  * set by ncx_pad_putn_Iuchar
01403                  */
01404                 if(lstatus != NC_NOERR)
01405                 {
01406                         free_NC_attr(attrp);
01407                         return lstatus;
01408                 }
01409         }
01410 
01411         return status;
01412 }
01413 
01414 int
01415 nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *tp)
01416 {
01417         int status;
01418         NC_attr *attrp;
01419 
01420         status = NC_lookupattr(ncid, varid, name, &attrp);
01421         if(status != NC_NOERR)
01422                 return status;
01423 
01424         if(attrp->nelems == 0)
01425                 return NC_NOERR;
01426 
01427         if(attrp->type == NC_CHAR)
01428                 return NC_ECHAR;
01429 
01430         {
01431         const void *xp = attrp->xvalue;
01432         return ncx_pad_getn_Iuchar(&xp, attrp->nelems, tp, attrp->type);
01433         }
01434 }
01435 
01436 
01437 int
01438 nc_put_att_short(int ncid, int varid, const char *name,
01439         nc_type type, size_t nelems, const short *value)
01440 {
01441         int status;
01442         NC *ncp;
01443         NC_attrarray *ncap;
01444         NC_attr **attrpp;
01445         NC_attr *old = NULL;
01446         NC_attr *attrp;
01447 
01448         status = NC_check_id(ncid, &ncp);
01449         if(status != NC_NOERR)
01450                 return status;
01451 
01452         if(NC_readonly(ncp))
01453                 return NC_EPERM;
01454 
01455         ncap = NC_attrarray0(ncp, varid);
01456         if(ncap == NULL)
01457                 return NC_ENOTVAR;
01458 
01459         status = nc_cktype(type);
01460         if(status != NC_NOERR)
01461                 return status;
01462 
01463         if(type == NC_CHAR)
01464                 return NC_ECHAR;
01465 
01466                 /* cast needed for braindead systems with signed size_t */
01467         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01468                 return NC_EINVAL; /* Invalid nelems */
01469 
01470         if(nelems != 0 && value == NULL)
01471                 return NC_EINVAL; /* Null arg */
01472 
01473         attrpp = NC_findattr(ncap, name);
01474         if(attrpp != NULL) /* name in use */
01475         {
01476                 if(!NC_indef(ncp) )
01477                 {
01478                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
01479                         attrp = *attrpp; /* convenience */
01480         
01481                         if(xsz > attrp->xsz)
01482                                 return NC_ENOTINDEFINE;
01483                         /* else, we can reuse existing without redef */
01484                         
01485                         attrp->xsz = xsz;
01486                         attrp->type = type;
01487                         attrp->nelems = nelems;
01488 
01489                         if(nelems != 0)
01490                         {
01491                                 void *xp = attrp->xvalue;
01492                                 status = ncx_pad_putn_Ishort(&xp, nelems,
01493                                         value, type);
01494                         }
01495                         
01496                         set_NC_hdirty(ncp);
01497 
01498                         if(NC_doHsync(ncp))
01499                         {
01500                                 const int lstatus = NC_sync(ncp);
01501                                 /*
01502                                  * N.B.: potentially overrides NC_ERANGE
01503                                  * set by ncx_pad_putn_Ishort
01504                                  */
01505                                 if(lstatus != ENOERR)
01506                                         return lstatus;
01507                         }
01508 
01509                         return status;
01510                 }
01511                 /* else, redefine using existing array slot */
01512                 old = *attrpp;
01513         } 
01514         else
01515         {
01516                 if(!NC_indef(ncp))
01517                         return NC_ENOTINDEFINE;
01518 
01519                 if(ncap->nelems >= NC_MAX_ATTRS)
01520                         return NC_EMAXATTS;
01521         }
01522 
01523         status = NC_check_name(name);
01524         if(status != NC_NOERR)
01525                 return status;
01526 
01527         attrp = new_NC_attr(name, type, nelems);
01528         if(attrp == NULL)
01529                 return NC_ENOMEM;
01530 
01531         if(nelems != 0)
01532         {
01533                 void *xp = attrp->xvalue;
01534                 status = ncx_pad_putn_Ishort(&xp, nelems,
01535                         value, type);
01536         }
01537 
01538         if(attrpp != NULL)
01539         {
01540                 assert(old != NULL);
01541                 *attrpp = attrp;
01542                 free_NC_attr(old);
01543         }
01544         else
01545         {
01546                 const int lstatus = incr_NC_attrarray(ncap, attrp);
01547                 /*
01548                  * N.B.: potentially overrides NC_ERANGE
01549                  * set by ncx_pad_putn_Ishort
01550                  */
01551                 if(lstatus != NC_NOERR)
01552                 {
01553                         free_NC_attr(attrp);
01554                         return lstatus;
01555                 }
01556         }
01557 
01558         return status;
01559 }
01560 
01561 int
01562 nc_get_att_short(int ncid, int varid, const char *name, short *tp)
01563 {
01564         int status;
01565         NC_attr *attrp;
01566 
01567         status = NC_lookupattr(ncid, varid, name, &attrp);
01568         if(status != NC_NOERR)
01569                 return status;
01570 
01571         if(attrp->nelems == 0)
01572                 return NC_NOERR;
01573 
01574         if(attrp->type == NC_CHAR)
01575                 return NC_ECHAR;
01576 
01577         {
01578         const void *xp = attrp->xvalue;
01579         return ncx_pad_getn_Ishort(&xp, attrp->nelems, tp, attrp->type);
01580         }
01581 }
01582 
01583 
01584 int
01585 nc_put_att_int(int ncid, int varid, const char *name,
01586         nc_type type, size_t nelems, const int *value)
01587 {
01588         int status;
01589         NC *ncp;
01590         NC_attrarray *ncap;
01591         NC_attr **attrpp;
01592         NC_attr *old = NULL;
01593         NC_attr *attrp;
01594 
01595         status = NC_check_id(ncid, &ncp);
01596         if(status != NC_NOERR)
01597                 return status;
01598 
01599         if(NC_readonly(ncp))
01600                 return NC_EPERM;
01601 
01602         ncap = NC_attrarray0(ncp, varid);
01603         if(ncap == NULL)
01604                 return NC_ENOTVAR;
01605 
01606         status = nc_cktype(type);
01607         if(status != NC_NOERR)
01608                 return status;
01609 
01610         if(type == NC_CHAR)
01611                 return NC_ECHAR;
01612 
01613                 /* cast needed for braindead systems with signed size_t */
01614         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01615                 return NC_EINVAL; /* Invalid nelems */
01616 
01617         if(nelems != 0 && value == NULL)
01618                 return NC_EINVAL; /* Null arg */
01619 
01620         attrpp = NC_findattr(ncap, name);
01621         if(attrpp != NULL) /* name in use */
01622         {
01623                 if(!NC_indef(ncp) )
01624                 {
01625                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
01626                         attrp = *attrpp; /* convenience */
01627         
01628                         if(xsz > attrp->xsz)
01629                                 return NC_ENOTINDEFINE;
01630                         /* else, we can reuse existing without redef */
01631                         
01632                         attrp->xsz = xsz;
01633                         attrp->type = type;
01634                         attrp->nelems = nelems;
01635 
01636                         if(nelems != 0)
01637                         {
01638                                 void *xp = attrp->xvalue;
01639                                 status = ncx_pad_putn_Iint(&xp, nelems,
01640                                         value, type);
01641                         }
01642                         
01643                         set_NC_hdirty(ncp);
01644 
01645                         if(NC_doHsync(ncp))
01646                         {
01647                                 const int lstatus = NC_sync(ncp);
01648                                 /*
01649                                  * N.B.: potentially overrides NC_ERANGE
01650                                  * set by ncx_pad_putn_Iint
01651                                  */
01652                                 if(lstatus != ENOERR)
01653                                         return lstatus;
01654                         }
01655 
01656                         return status;
01657                 }
01658                 /* else, redefine using existing array slot */
01659                 old = *attrpp;
01660         } 
01661         else
01662         {
01663                 if(!NC_indef(ncp))
01664                         return NC_ENOTINDEFINE;
01665 
01666                 if(ncap->nelems >= NC_MAX_ATTRS)
01667                         return NC_EMAXATTS;
01668         }
01669 
01670         status = NC_check_name(name);
01671         if(status != NC_NOERR)
01672                 return status;
01673 
01674         attrp = new_NC_attr(name, type, nelems);
01675         if(attrp == NULL)
01676                 return NC_ENOMEM;
01677 
01678         if(nelems != 0)
01679         {
01680                 void *xp = attrp->xvalue;
01681                 status = ncx_pad_putn_Iint(&xp, nelems,
01682                         value, type);
01683         }
01684 
01685         if(attrpp != NULL)
01686         {
01687                 assert(old != NULL);
01688                 *attrpp = attrp;
01689                 free_NC_attr(old);
01690         }
01691         else
01692         {
01693                 const int lstatus = incr_NC_attrarray(ncap, attrp);
01694                 /*
01695                  * N.B.: potentially overrides NC_ERANGE
01696                  * set by ncx_pad_putn_Iint
01697                  */
01698                 if(lstatus != NC_NOERR)
01699                 {
01700                         free_NC_attr(attrp);
01701                         return lstatus;
01702                 }
01703         }
01704 
01705         return status;
01706 }
01707 
01708 int
01709 nc_get_att_int(int ncid, int varid, const char *name, int *tp)
01710 {
01711         int status;
01712         NC_attr *attrp;
01713 
01714         status = NC_lookupattr(ncid, varid, name, &attrp);
01715         if(status != NC_NOERR)
01716                 return status;
01717 
01718         if(attrp->nelems == 0)
01719                 return NC_NOERR;
01720 
01721         if(attrp->type == NC_CHAR)
01722                 return NC_ECHAR;
01723 
01724         {
01725         const void *xp = attrp->xvalue;
01726         return ncx_pad_getn_Iint(&xp, attrp->nelems, tp, attrp->type);
01727         }
01728 }
01729 
01730 
01731 int
01732 nc_put_att_long(int ncid, int varid, const char *name,
01733         nc_type type, size_t nelems, const long *value)
01734 {
01735         int status;
01736         NC *ncp;
01737         NC_attrarray *ncap;
01738         NC_attr **attrpp;
01739         NC_attr *old = NULL;
01740         NC_attr *attrp;
01741 
01742         status = NC_check_id(ncid, &ncp);
01743         if(status != NC_NOERR)
01744                 return status;
01745 
01746         if(NC_readonly(ncp))
01747                 return NC_EPERM;
01748 
01749         ncap = NC_attrarray0(ncp, varid);
01750         if(ncap == NULL)
01751                 return NC_ENOTVAR;
01752 
01753         status = nc_cktype(type);
01754         if(status != NC_NOERR)
01755                 return status;
01756 
01757         if(type == NC_CHAR)
01758                 return NC_ECHAR;
01759 
01760                 /* cast needed for braindead systems with signed size_t */
01761         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01762                 return NC_EINVAL; /* Invalid nelems */
01763 
01764         if(nelems != 0 && value == NULL)
01765                 return NC_EINVAL; /* Null arg */
01766 
01767         attrpp = NC_findattr(ncap, name);
01768         if(attrpp != NULL) /* name in use */
01769         {
01770                 if(!NC_indef(ncp) )
01771                 {
01772                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
01773                         attrp = *attrpp; /* convenience */
01774         
01775                         if(xsz > attrp->xsz)
01776                                 return NC_ENOTINDEFINE;
01777                         /* else, we can reuse existing without redef */
01778                         
01779                         attrp->xsz = xsz;
01780                         attrp->type = type;
01781                         attrp->nelems = nelems;
01782 
01783                         if(nelems != 0)
01784                         {
01785                                 void *xp = attrp->xvalue;
01786                                 status = ncx_pad_putn_Ilong(&xp, nelems,
01787                                         value, type);
01788                         }
01789                         
01790                         set_NC_hdirty(ncp);
01791 
01792                         if(NC_doHsync(ncp))
01793                         {
01794                                 const int lstatus = NC_sync(ncp);
01795                                 /*
01796                                  * N.B.: potentially overrides NC_ERANGE
01797                                  * set by ncx_pad_putn_Ilong
01798                                  */
01799                                 if(lstatus != ENOERR)
01800                                         return lstatus;
01801                         }
01802 
01803                         return status;
01804                 }
01805                 /* else, redefine using existing array slot */
01806                 old = *attrpp;
01807         } 
01808         else
01809         {
01810                 if(!NC_indef(ncp))
01811                         return NC_ENOTINDEFINE;
01812 
01813                 if(ncap->nelems >= NC_MAX_ATTRS)
01814                         return NC_EMAXATTS;
01815         }
01816 
01817         status = NC_check_name(name);
01818         if(status != NC_NOERR)
01819                 return status;
01820 
01821         attrp = new_NC_attr(name, type, nelems);
01822         if(attrp == NULL)
01823                 return NC_ENOMEM;
01824 
01825         if(nelems != 0)
01826         {
01827                 void *xp = attrp->xvalue;
01828                 status = ncx_pad_putn_Ilong(&xp, nelems,
01829                         value, type);
01830         }
01831 
01832         if(attrpp != NULL)
01833         {
01834                 assert(old != NULL);
01835                 *attrpp = attrp;
01836                 free_NC_attr(old);
01837         }
01838         else
01839         {
01840                 const int lstatus = incr_NC_attrarray(ncap, attrp);
01841                 /*
01842                  * N.B.: potentially overrides NC_ERANGE
01843                  * set by ncx_pad_putn_Ilong
01844                  */
01845                 if(lstatus != NC_NOERR)
01846                 {
01847                         free_NC_attr(attrp);
01848                         return lstatus;
01849                 }
01850         }
01851 
01852         return status;
01853 }
01854 
01855 int
01856 nc_get_att_long(int ncid, int varid, const char *name, long *tp)
01857 {
01858         int status;
01859         NC_attr *attrp;
01860 
01861         status = NC_lookupattr(ncid, varid, name, &attrp);
01862         if(status != NC_NOERR)
01863                 return status;
01864 
01865         if(attrp->nelems == 0)
01866                 return NC_NOERR;
01867 
01868         if(attrp->type == NC_CHAR)
01869                 return NC_ECHAR;
01870 
01871         {
01872         const void *xp = attrp->xvalue;
01873         return ncx_pad_getn_Ilong(&xp, attrp->nelems, tp, attrp->type);
01874         }
01875 }
01876 
01877 
01878 int
01879 nc_put_att_float(int ncid, int varid, const char *name,
01880         nc_type type, size_t nelems, const float *value)
01881 {
01882         int status;
01883         NC *ncp;
01884         NC_attrarray *ncap;
01885         NC_attr **attrpp;
01886         NC_attr *old = NULL;
01887         NC_attr *attrp;
01888 
01889         status = NC_check_id(ncid, &ncp);
01890         if(status != NC_NOERR)
01891                 return status;
01892 
01893         if(NC_readonly(ncp))
01894                 return NC_EPERM;
01895 
01896         ncap = NC_attrarray0(ncp, varid);
01897         if(ncap == NULL)
01898                 return NC_ENOTVAR;
01899 
01900         status = nc_cktype(type);
01901         if(status != NC_NOERR)
01902                 return status;
01903 
01904         if(type == NC_CHAR)
01905                 return NC_ECHAR;
01906 
01907                 /* cast needed for braindead systems with signed size_t */
01908         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
01909                 return NC_EINVAL; /* Invalid nelems */
01910 
01911         if(nelems != 0 && value == NULL)
01912                 return NC_EINVAL; /* Null arg */
01913 
01914         attrpp = NC_findattr(ncap, name);
01915         if(attrpp != NULL) /* name in use */
01916         {
01917                 if(!NC_indef(ncp) )
01918                 {
01919                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
01920                         attrp = *attrpp; /* convenience */
01921         
01922                         if(xsz > attrp->xsz)
01923                                 return NC_ENOTINDEFINE;
01924                         /* else, we can reuse existing without redef */
01925                         
01926                         attrp->xsz = xsz;
01927                         attrp->type = type;
01928                         attrp->nelems = nelems;
01929 
01930                         if(nelems != 0)
01931                         {
01932                                 void *xp = attrp->xvalue;
01933                                 status = ncx_pad_putn_Ifloat(&xp, nelems,
01934                                         value, type);
01935                         }
01936                         
01937                         set_NC_hdirty(ncp);
01938 
01939                         if(NC_doHsync(ncp))
01940                         {
01941                                 const int lstatus = NC_sync(ncp);
01942                                 /*
01943                                  * N.B.: potentially overrides NC_ERANGE
01944                                  * set by ncx_pad_putn_Ifloat
01945                                  */
01946                                 if(lstatus != ENOERR)
01947                                         return lstatus;
01948                         }
01949 
01950                         return status;
01951                 }
01952                 /* else, redefine using existing array slot */
01953                 old = *attrpp;
01954         } 
01955         else
01956         {
01957                 if(!NC_indef(ncp))
01958                         return NC_ENOTINDEFINE;
01959 
01960                 if(ncap->nelems >= NC_MAX_ATTRS)
01961                         return NC_EMAXATTS;
01962         }
01963 
01964         status = NC_check_name(name);
01965         if(status != NC_NOERR)
01966                 return status;
01967 
01968         attrp = new_NC_attr(name, type, nelems);
01969         if(attrp == NULL)
01970                 return NC_ENOMEM;
01971 
01972         if(nelems != 0)
01973         {
01974                 void *xp = attrp->xvalue;
01975                 status = ncx_pad_putn_Ifloat(&xp, nelems,
01976                         value, type);
01977         }
01978 
01979         if(attrpp != NULL)
01980         {
01981                 assert(old != NULL);
01982                 *attrpp = attrp;
01983                 free_NC_attr(old);
01984         }
01985         else
01986         {
01987                 const int lstatus = incr_NC_attrarray(ncap, attrp);
01988                 /*
01989                  * N.B.: potentially overrides NC_ERANGE
01990                  * set by ncx_pad_putn_Ifloat
01991                  */
01992                 if(lstatus != NC_NOERR)
01993                 {
01994                         free_NC_attr(attrp);
01995                         return lstatus;
01996                 }
01997         }
01998 
01999         return status;
02000 }
02001 
02002 int
02003 nc_get_att_float(int ncid, int varid, const char *name, float *tp)
02004 {
02005         int status;
02006         NC_attr *attrp;
02007 
02008         status = NC_lookupattr(ncid, varid, name, &attrp);
02009         if(status != NC_NOERR)
02010                 return status;
02011 
02012         if(attrp->nelems == 0)
02013                 return NC_NOERR;
02014 
02015         if(attrp->type == NC_CHAR)
02016                 return NC_ECHAR;
02017 
02018         {
02019         const void *xp = attrp->xvalue;
02020         return ncx_pad_getn_Ifloat(&xp, attrp->nelems, tp, attrp->type);
02021         }
02022 }
02023 
02024 
02025 int
02026 nc_put_att_double(int ncid, int varid, const char *name,
02027         nc_type type, size_t nelems, const double *value)
02028 {
02029         int status;
02030         NC *ncp;
02031         NC_attrarray *ncap;
02032         NC_attr **attrpp;
02033         NC_attr *old = NULL;
02034         NC_attr *attrp;
02035 
02036         status = NC_check_id(ncid, &ncp);
02037         if(status != NC_NOERR)
02038                 return status;
02039 
02040         if(NC_readonly(ncp))
02041                 return NC_EPERM;
02042 
02043         ncap = NC_attrarray0(ncp, varid);
02044         if(ncap == NULL)
02045                 return NC_ENOTVAR;
02046 
02047         status = nc_cktype(type);
02048         if(status != NC_NOERR)
02049                 return status;
02050 
02051         if(type == NC_CHAR)
02052                 return NC_ECHAR;
02053 
02054                 /* cast needed for braindead systems with signed size_t */
02055         if((unsigned long) nelems > X_INT_MAX) /* backward compat */
02056                 return NC_EINVAL; /* Invalid nelems */
02057 
02058         if(nelems != 0 && value == NULL)
02059                 return NC_EINVAL; /* Null arg */
02060 
02061         attrpp = NC_findattr(ncap, name);
02062         if(attrpp != NULL) /* name in use */
02063         {
02064                 if(!NC_indef(ncp) )
02065                 {
02066                         const size_t xsz = ncx_len_NC_attrV(type, nelems);
02067                         attrp = *attrpp; /* convenience */
02068         
02069                         if(xsz > attrp->xsz)
02070                                 return NC_ENOTINDEFINE;
02071                         /* else, we can reuse existing without redef */
02072                         
02073                         attrp->xsz = xsz;
02074                         attrp->type = type;
02075                         attrp->nelems = nelems;
02076 
02077                         if(nelems != 0)
02078                         {
02079                                 void *xp = attrp->xvalue;
02080                                 status = ncx_pad_putn_Idouble(&xp, nelems,
02081                                         value, type);
02082                         }
02083                         
02084                         set_NC_hdirty(ncp);
02085 
02086                         if(NC_doHsync(ncp))
02087                         {
02088                                 const int lstatus = NC_sync(ncp);
02089                                 /*
02090                                  * N.B.: potentially overrides NC_ERANGE
02091                                  * set by ncx_pad_putn_Idouble
02092                                  */
02093                                 if(lstatus != ENOERR)
02094                                         return lstatus;
02095                         }
02096 
02097                         return status;
02098                 }
02099                 /* else, redefine using existing array slot */
02100                 old = *attrpp;
02101         } 
02102         else
02103         {
02104                 if(!NC_indef(ncp))
02105                         return NC_ENOTINDEFINE;
02106 
02107                 if(ncap->nelems >= NC_MAX_ATTRS)
02108                         return NC_EMAXATTS;
02109         }
02110 
02111         status = NC_check_name(name);
02112         if(status != NC_NOERR)
02113                 return status;
02114 
02115         attrp = new_NC_attr(name, type, nelems);
02116         if(attrp == NULL)
02117                 return NC_ENOMEM;
02118 
02119         if(nelems != 0)
02120         {
02121                 void *xp = attrp->xvalue;
02122                 status = ncx_pad_putn_Idouble(&xp, nelems,
02123                         value, type);
02124         }
02125 
02126         if(attrpp != NULL)
02127         {
02128                 assert(old != NULL);
02129                 *attrpp = attrp;
02130                 free_NC_attr(old);
02131         }
02132         else
02133         {
02134                 const int lstatus = incr_NC_attrarray(ncap, attrp);
02135                 /*
02136                  * N.B.: potentially overrides NC_ERANGE
02137                  * set by ncx_pad_putn_Idouble
02138                  */
02139                 if(lstatus != NC_NOERR)
02140                 {
02141                         free_NC_attr(attrp);
02142                         return lstatus;
02143                 }
02144         }
02145 
02146         return status;
02147 }
02148 
02149 int
02150 nc_get_att_double(int ncid, int varid, const char *name, double *tp)
02151 {
02152         int status;
02153         NC_attr *attrp;
02154 
02155         status = NC_lookupattr(ncid, varid, name, &attrp);
02156         if(status != NC_NOERR)
02157                 return status;
02158 
02159         if(attrp->nelems == 0)
02160                 return NC_NOERR;
02161 
02162         if(attrp->type == NC_CHAR)
02163                 return NC_ECHAR;
02164 
02165         {
02166         const void *xp = attrp->xvalue;
02167         return ncx_pad_getn_Idouble(&xp, attrp->nelems, tp, attrp->type);
02168         }
02169 }
02170 
02171 
02172 
02173 /* deprecated, used to support the 2.x interface */
02174 int
02175 nc_put_att(
02176         int ncid,
02177         int varid,
02178         const char *name,
02179         nc_type type,
02180         size_t nelems,
02181         const void *value)
02182 {
02183         switch (type) {
02184         case NC_BYTE:
02185                 return nc_put_att_schar(ncid, varid, name, type, nelems,
02186                         (schar *)value);
02187         case NC_CHAR:
02188                 return nc_put_att_text(ncid, varid, name, nelems,
02189                         (char *)value);
02190         case NC_SHORT:
02191                 return nc_put_att_short(ncid, varid, name, type, nelems,
02192                         (short *)value);
02193         case NC_INT:
02194 #if (SIZEOF_INT >= X_SIZEOF_INT)
02195                 return nc_put_att_int(ncid, varid, name, type, nelems,
02196                         (int *)value);
02197 #elif SIZEOF_LONG == X_SIZEOF_INT
02198                 return nc_put_att_long(ncid, varid, name, type, nelems,
02199                         (long *)value);
02200 #endif
02201         case NC_FLOAT:
02202                 return nc_put_att_float(ncid, varid, name, type, nelems,
02203                         (float *)value);
02204         case NC_DOUBLE:
02205                 return nc_put_att_double(ncid, varid, name, type, nelems,
02206                         (double *)value);
02207         }
02208         return NC_EBADTYPE;
02209 }
02210 
02211 
02212 /* deprecated, used to support the 2.x interface */
02213 int
02214 nc_get_att(int ncid, int varid, const char *name, void *value)
02215 {
02216         int status;
02217         NC_attr *attrp;
02218 
02219         status = NC_lookupattr(ncid, varid, name, &attrp);
02220         if(status != NC_NOERR)
02221                 return status;
02222 
02223         switch (attrp->type) {
02224         case NC_BYTE:
02225                 return nc_get_att_schar(ncid, varid, name,
02226                         (schar *)value);
02227         case NC_CHAR:
02228                 return nc_get_att_text(ncid, varid, name,
02229                         (char *)value);
02230         case NC_SHORT:
02231                 return nc_get_att_short(ncid, varid, name,
02232                         (short *)value);
02233         case NC_INT:
02234 #if (SIZEOF_INT >= X_SIZEOF_INT)
02235                 return nc_get_att_int(ncid, varid, name,
02236                         (int *)value);
02237 #elif SIZEOF_LONG == X_SIZEOF_INT
02238                 return nc_get_att_long(ncid, varid, name,
02239                         (long *)value);
02240 #endif
02241         case NC_FLOAT:
02242                 return nc_get_att_float(ncid, varid, name,
02243                         (float *)value);
02244         case NC_DOUBLE:
02245                 return nc_get_att_double(ncid, varid, name,
02246                         (double *)value);
02247         }
02248         return NC_EBADTYPE;
02249 }
 

Powered by Plone

This site conforms to the following standards: