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