/* Read a NC_dim from the header */ static int v1h_get_NC_dim(v1hs *gsp, NC_dim **dimpp) { int status; NC_string *ncstrp; NC_dim *dimp; status = v1h_get_NC_string(gsp, &ncstrp); if(status != ENOERR) return status; dimp = new_x_NC_dim(ncstrp); if(dimp == NULL) { status = NC_ENOMEM; goto unwind_name; } status = v1h_get_size_t(gsp, &dimp->size); if(status != ENOERR) { free_NC_dim(dimp); /* frees name */ return status; } *dimpp = dimp; return ENOERR; unwind_name: free_NC_string(ncstrp); return status; }
/* Read a NC_dimarray from the header */ static int v1h_get_NC_dimarray(v1hs *gsp, NC_dimarray *ncap) { int status; NCtype type = NC_UNSPECIFIED; assert(gsp != NULL && gsp->pos != NULL); assert(ncap != NULL); assert(ncap->value == NULL); status = v1h_get_NCtype(gsp, &type); if(status != NC_NOERR) return status; status = v1h_get_size_t(gsp, &ncap->nelems); if(status != NC_NOERR) return status; if(ncap->nelems == 0) return NC_NOERR; /* else */ if(type != NC_DIMENSION) return EINVAL; ncap->value = (NC_dim **) malloc(ncap->nelems * sizeof(NC_dim *)); if(ncap->value == NULL) return NC_ENOMEM; ncap->nalloc = ncap->nelems; ncap->hashmap = NC_hashmapCreate(ncap->nelems); { NC_dim **dpp = ncap->value; NC_dim *const *const end = &dpp[ncap->nelems]; for( /*NADA*/; dpp < end; dpp++) { status = v1h_get_NC_dim(gsp, dpp); if(status) { ncap->nelems = (size_t)(dpp - ncap->value); free_NC_dimarrayV(ncap); return status; } { int dimid = (size_t)(dpp - ncap->value); NC_hashmapAddDim(ncap, dimid, (*dpp)->name->cp); } } } return NC_NOERR; }
/* Read a NC_vararray from the header */ static int v1h_get_NC_vararray(v1hs *gsp, NC_vararray *ncap) { int status; NCtype type = NC_UNSPECIFIED; assert(gsp != NULL && gsp->pos != NULL); assert(ncap != NULL); assert(ncap->value == NULL); status = v1h_get_NCtype(gsp, &type); if(status != ENOERR) return status; status = v1h_get_size_t(gsp, &ncap->nelems); if(status != ENOERR) return status; if(ncap->nelems == 0) return ENOERR; /* else */ if(type != NC_VARIABLE) return EINVAL; ncap->value = (NC_var **) malloc(ncap->nelems * sizeof(NC_var *)); if(ncap->value == NULL) return NC_ENOMEM; ncap->nalloc = ncap->nelems; { NC_var **vpp = ncap->value; NC_var *const *const end = &vpp[ncap->nelems]; for( /*NADA*/; vpp < end; vpp++) { status = v1h_get_NC_var(gsp, vpp); if(status) { ncap->nelems = (size_t)(vpp - ncap->value); free_NC_vararrayV(ncap); return status; } } } return ENOERR; }
/* Read a NC_attr from the header */ static int v1h_get_NC_attr(v1hs *gsp, NC_attr **attrpp) { NC_string *strp; int status; nc_type type; size_t nelems; NC_attr *attrp; status = v1h_get_NC_string(gsp, &strp); if(status != ENOERR) return status; status = v1h_get_nc_type(gsp, &type); if(status != ENOERR) goto unwind_name; status = v1h_get_size_t(gsp, &nelems); if(status != ENOERR) goto unwind_name; attrp = new_x_NC_attr(strp, type, nelems); if(attrp == NULL) { status = NC_ENOMEM; goto unwind_name; } status = v1h_get_NC_attrV(gsp, attrp); if(status != ENOERR) { free_NC_attr(attrp); /* frees strp */ return status; } *attrpp = attrp; return ENOERR; unwind_name: free_NC_string(strp); return status; }
/* Read a NC_string from the header */ static int v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp) { int status; size_t nchars = 0; NC_string *ncstrp; status = v1h_get_size_t(gsp, &nchars); if(status != ENOERR) return status; ncstrp = new_NC_string(nchars, NULL); if(ncstrp == NULL) { return NC_ENOMEM; } #if 0 /* assert(ncstrp->nchars == nchars || ncstrp->nchars - nchars < X_ALIGN); */ assert(ncstrp->nchars % X_ALIGN == 0); status = check_v1hs(gsp, ncstrp->nchars); #else status = check_v1hs(gsp, _RNDUP(ncstrp->nchars, X_ALIGN)); #endif if(status != ENOERR) goto unwind_alloc; status = ncx_pad_getn_text((const void **)(&gsp->pos), nchars, ncstrp->cp); if(status != ENOERR) goto unwind_alloc; *ncstrpp = ncstrp; return ENOERR; unwind_alloc: free_NC_string(ncstrp); return status; }
/* Read a NC_var from the header */ static int v1h_get_NC_var(v1hs *gsp, NC_var **varpp) { NC_string *strp; int status; size_t ndims; NC_var *varp; status = v1h_get_NC_string(gsp, &strp); if(status != ENOERR) return status; status = v1h_get_size_t(gsp, &ndims); if(status != ENOERR) goto unwind_name; varp = new_x_NC_var(strp, ndims); if(varp == NULL) { status = NC_ENOMEM; goto unwind_name; } if (gsp->version == 5) { status = check_v1hs(gsp, ncx_len_int64(ndims)); if(status != ENOERR) goto unwind_alloc; status = ncx_getn_longlong_int((const void **)(&gsp->pos), ndims, varp->dimids); if(status != ENOERR) goto unwind_alloc; } else { status = check_v1hs(gsp, ncx_len_int(ndims)); if(status != ENOERR) goto unwind_alloc; status = ncx_getn_int_int((const void **)(&gsp->pos), ndims, varp->dimids); if(status != ENOERR) goto unwind_alloc; } status = v1h_get_NC_attrarray(gsp, &varp->attrs); if(status != ENOERR) goto unwind_alloc; status = v1h_get_nc_type(gsp, &varp->type); if(status != ENOERR) goto unwind_alloc; status = v1h_get_size_t(gsp, &varp->len); if(status != ENOERR) goto unwind_alloc; status = check_v1hs(gsp, gsp->version == 1 ? 4 : 8); if(status != ENOERR) goto unwind_alloc; status = ncx_get_off_t((const void **)&gsp->pos, &varp->begin, gsp->version == 1 ? 4 : 8); if(status != ENOERR) goto unwind_alloc; *varpp = varp; return ENOERR; unwind_alloc: free_NC_var(varp); /* frees name */ return status; unwind_name: free_NC_string(strp); return status; }