/* * 'compile' the shape and len of a variable * Formerly NC_var_shape(var, dims) */ int NC_var_shape(NC_var *varp, const NC_dimarray *dims) { size_t *shp, *op; off_t *dsp; int *ip; const NC_dim *dimp; off_t product = 1; varp->xsz = ncx_szof(varp->type); if(varp->ndims == 0) { goto out; } /* * use the user supplied dimension indices * to determine the shape */ for(ip = varp->dimids, op = varp->shape ; ip < &varp->dimids[varp->ndims]; ip++, op++) { if(*ip < 0 || (size_t) (*ip) >= ((dims != NULL) ? dims->nelems : 1) ) return NC_EBADDIM; dimp = elem_NC_dimarray(dims, (size_t)*ip); *op = dimp->size; if(*op == NC_UNLIMITED && ip != varp->dimids) return NC_EUNLIMPOS; } /* * Compute the dsizes */ /* ndims is > 0 here */ for(shp = varp->shape + varp->ndims -1, dsp = varp->dsizes + varp->ndims -1; shp >= varp->shape; shp--, dsp--) { if(!(shp == varp->shape && IS_RECVAR(varp))) { if( (off_t)(*shp) <= OFF_T_MAX / product ) { product *= *shp; } else { product = OFF_T_MAX ; } } *dsp = product; } out : if( varp->xsz <= (X_UINT_MAX - 1) / product ) /* if integer multiply will not overflow */ { varp->len = product * varp->xsz; switch(varp->type) { case NC_BYTE : case NC_CHAR : case NC_SHORT : if( varp->len%4 != 0 ) { varp->len += 4 - varp->len%4; /* round up */ /* *dsp += 4 - *dsp%4; */ } break; default: /* already aligned */ break; } } else { /* OK for last var to be "too big", indicated by this special len */ varp->len = X_UINT_MAX; } #if 0 arrayp("\tshape", varp->ndims, varp->shape); arrayp("\tdsizes", varp->ndims, varp->dsizes); #endif return NC_NOERR; }
/* * 'compile' the shape and len of a variable * Formerly NC_var_shape(var, dims) */ int NC_var_shape(NC_var *varp, const NC_dimarray *dims) { size_t *shp, *dsp, *op; int *ip; const NC_dim *dimp; size_t product = 1; varp->xsz = ncx_szof(varp->type); if(varp->ndims == 0) { goto out; } /* * use the user supplied dimension indices * to determine the shape */ for(ip = varp->dimids, op = varp->shape ; ip < &varp->dimids[varp->ndims]; ip++, op++) { if(*ip < 0 || (size_t) (*ip) >= ((dims != NULL) ? dims->nelems : 1) ) return NC_EBADDIM; dimp = elem_NC_dimarray(dims, (size_t)*ip); *op = dimp->size; if(*op == NC_UNLIMITED && ip != varp->dimids) return NC_EUNLIMPOS; } /* * Compute the dsizes */ /* ndims is > 0 here */ for(shp = varp->shape + varp->ndims -1, dsp = varp->dsizes + varp->ndims -1; shp >= varp->shape; shp--, dsp--) { if(!(shp == varp->shape && IS_RECVAR(varp))) product *= *shp; *dsp = product; } out : varp->len = product * varp->xsz; switch(varp->type) { case NC_BYTE : case NC_CHAR : case NC_SHORT : if( varp->len%4 != 0 ) { varp->len += 4 - varp->len%4; /* round up */ /* *dsp += 4 - *dsp%4; */ } break; default: /* already aligned */ break; } #if 0 arrayp("\tshape", varp->ndims, varp->shape); arrayp("\tdsizes", varp->ndims, varp->dsizes); #endif return NC_NOERR; }
/* * set varp->xsz, varp->shape and varp->len of a variable */ int ncmpii_NC_var_shape64(NC *ncp, NC_var *varp, const NC_dimarray *dims) { int i; MPI_Offset product = 1; /* set the size of 1 element */ varp->xsz = ncx_szof(varp->type); if (varp->ndims == 0) goto out; /* * use the user supplied dimension indices to determine the shape */ for (i=0; i<varp->ndims; i++) { const NC_dim *dimp; if (varp->dimids[i] < 0) return NC_EBADDIM; if (varp->dimids[i] >= ((dims != NULL) ? dims->ndefined : 1)) return NC_EBADDIM; /* get the pointer to the dim object */ dimp = ncmpii_elem_NC_dimarray(dims, varp->dimids[i]); varp->shape[i] = dimp->size; /* check for record variable, only the highest dimension can * be unlimited */ if (varp->shape[i] == NC_UNLIMITED && i != 0) return NC_EUNLIMPOS; } /* * compute the dsizes, the right to left product of shape */ product = 1; if (varp->ndims == 1) { if (varp->shape[0] == NC_UNLIMITED) varp->dsizes[0] = 1; else { varp->dsizes[0] = varp->shape[0]; product = varp->shape[0]; } } else { /* varp->ndims > 1 */ varp->dsizes[varp->ndims-1] = varp->shape[varp->ndims-1]; product = varp->shape[varp->ndims-1]; for (i=varp->ndims-2; i>=0; i--) { if (varp->shape[i] != NC_UNLIMITED) product *= varp->shape[i]; varp->dsizes[i] = product; } } out : /* * For CDF-1 and CDF-2 formats, the total number of array elements * cannot exceed 2^32 */ if (! fIsSet(ncp->flags, NC_64BIT_DATA) && product >= X_UINT_MAX) return NC_EVARSIZE; /* * align variable size to 4 byte boundary, required by all netcdf file * formats */ varp->len = product * varp->xsz; if (varp->len % 4 > 0) varp->len += 4 - varp->len % 4; /* round up */ return NC_NOERR; }
/* * 'compile' the shape and len of a variable * Formerly NC_var_shape(var, dims) */ int NC_var_shape(NC_var *varp, const NC_dimarray *dims) { size_t *shp, *op; off_t *dsp; int *ip = NULL; const NC_dim *dimp; off_t product = 1; varp->xsz = ncx_szof(varp->type); if(varp->ndims == 0 || varp->dimids == NULL) { goto out; } /* * use the user supplied dimension indices * to determine the shape */ for(ip = varp->dimids, op = varp->shape ; ip < &varp->dimids[varp->ndims]; ip++, op++) { if(*ip < 0 || (size_t) (*ip) >= ((dims != NULL) ? dims->nelems : 1) ) return NC_EBADDIM; dimp = elem_NC_dimarray(dims, (size_t)*ip); *op = dimp->size; if(*op == NC_UNLIMITED && ip != varp->dimids) return NC_EUNLIMPOS; } /* * Compute the dsizes */ /* ndims is > 0 here */ for(shp = varp->shape + varp->ndims -1, dsp = varp->dsizes + varp->ndims -1; shp >= varp->shape; shp--, dsp--) { /*if(!(shp == varp->shape && IS_RECVAR(varp)))*/ if( shp != NULL && (shp != varp->shape || !IS_RECVAR(varp))) { if( ((off_t)(*shp)) <= OFF_T_MAX / product ) { product *= (*shp > 0 ? *shp : 1); } else { product = OFF_T_MAX ; } } *dsp = product; } out : /* No variable size can be > X_INT64_MAX - 3 */ if (0 == NC_check_vlen(varp, X_INT64_MAX-3)) return NC_EVARSIZE; /* * For CDF-1 and CDF-2 formats, the total number of array elements * cannot exceed 2^32, unless this variable is the last fixed-size * variable, there is no record variable, and the file starting * offset of this variable is less than 2GiB. * This will be checked in NC_check_vlens() during NC_endef() */ varp->len = product * varp->xsz; if (varp->len % 4 > 0) varp->len += 4 - varp->len % 4; /* round up */ #if 0 arrayp("\tshape", varp->ndims, varp->shape); arrayp("\tdsizes", varp->ndims, varp->dsizes); #endif return NC_NOERR; }