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