int ncattinq( int ncid, int varid, const char* name, nc_type* datatype, int* len ) { size_t ll; const int status = nc_inq_att(ncid, varid, name, datatype, &ll); if(status != NC_NOERR) { nc_advise("ncattinq", status, "ncid %d; varid %d; attname \"%s\"", ncid, varid, name); return -1; } if(len != NULL) *len = (int) ll; return 1; }
/* If returned value 'retval' is 0, then returned value 'type' will hold * the type of the named attribute, and returned value 'attlen' will * hold the length of the named attribute. If returned value 'retval' * is NOT 0, then the specified variable did not have an attribute * named 'attname'. */ void R_nc_inq_att( int *ncid, int *varid, char **attname, int *type, int *attlen, int *retval ) { size_t s_attlen; nc_type nctype; *retval = nc_inq_att(*ncid, *varid, attname[0], &nctype, &s_attlen ); if( (*retval != 0) && (*retval != NC_ENOTATT)) REprintf( "Error in R_nc_inq_att: while looking for attribute %s, got error %s\n", attname[0], nc_strerror(*retval) ); if( *retval == 0 ) { *type = R_nc_nctype_to_Rtypecode(nctype); if( *type == -1 ) { if( nctype == NC_BYTE ) REprintf( "Error in R_nc_inq_att: not set up to handle attributes of type \"BYTE\"! Netcdf type code: %d Attribute name: %s\n", nctype, attname[0] ); else { REprintf( "Error in R_nc_inq_att: not set up to handle attributes of this type! Netcdf type code: %d Attribute name: %s\n", nctype, attname[0] ); *retval = -1; } } *attlen = (int)s_attlen; } }
static char * has_c_format_att( int ncid, /* netcdf id */ int varid /* variable id */ ) { nc_type cfmt_type; size_t cfmt_len; #define C_FMT_NAME "C_format" /* name of C format attribute */ #define MAX_CFMT_LEN 100 /* max length of C format attribute */ static char cfmt[MAX_CFMT_LEN]; /* we expect nc_inq_att to fail if there is no "C_format" attribute */ int nc_stat = nc_inq_att(ncid, varid, "C_format", &cfmt_type, &cfmt_len); switch(nc_stat) { case NC_NOERR: if (cfmt_type == NC_CHAR && cfmt_len != 0 && cfmt_len < MAX_CFMT_LEN) { int nc_stat = nc_get_att_text(ncid, varid, "C_format", cfmt); if(nc_stat != NC_NOERR) nc_advise("Getting 'C_format' attribute", nc_stat, ""); return &cfmt[0]; } break; case NC_ENOTATT: break; default: nc_advise("Inquiring about 'C_format' attribute", nc_stat, ""); break; } return 0; }
int avtNETCDFReaderBase::ReadCycleAttribute() { int cycle = 0; // // See if the global attribute cycle exists. If it does and is // an int, then return the first value of it as the cycle. // int status; nc_type atttype; size_t attsize; if((status = nc_inq_att(fileObject->GetFileHandle(), NC_GLOBAL, "Cycle", &atttype, &attsize)) == NC_NOERR) { if (atttype == NC_INT) { int *value = new int[attsize]; nc_get_att_int(fileObject->GetFileHandle(), NC_GLOBAL, "Cycle", value); cycle = value[0]; delete [] value; } } return cycle; }
/** * Static identifier to determine if the netcdf file is an ndfd forecast. * Uses netcdf c api * * @param fileName netcdf filename * * @return true if the forecast is a NCEP Dgex forecast */ bool ncepDgexSurfInitialization::identify( std::string fileName ) { bool identified = true; //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif int status, ncid, ndims, nvars, ngatts, unlimdimid; /* * Open the dataset */ status = nc_open( fileName.c_str(), 0, &ncid ); if ( status != NC_NOERR ) identified = false; /* * If we can't get simple data from the file, return false */ status = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid); if ( status != NC_NOERR ) identified = false; /* * Check the variable names, return false if any aren't found */ int varid; std::vector<std::string> varList = getVariableList(); for( unsigned int i = 0;i < varList.size();i++ ) { status = nc_inq_varid( ncid, varList[i].c_str(), &varid ); if( status != NC_NOERR ) identified = false; } /* * Check the global attributes for the following tag: * :Generating_Model = "RAP Model from FSL (isentropic; scale: 20km at 40N)" */ size_t len; nc_type type; char* model; status = nc_inq_att( ncid, NC_GLOBAL, "Analysis_or_forecast_generating_process_identifier_defined_by_originating_centre", &type, &len ); if( status != NC_NOERR ) identified = false; else { model = new char[len + 1]; status = nc_get_att_text( ncid, NC_GLOBAL, "Analysis_or_forecast_generating_process_identifier_defined_by_originating_centre", model ); model[len] = '\0'; std::string s( model ); if( s.find("Downscaled GFS from NAM eXtension" ) == s.npos ) { identified = false; } delete[] model; } status = nc_close( ncid ); return identified; }
static int verify_product(int ncid) { int result; char *convention_str; result = nc_inq_att(ncid, NC_GLOBAL, "Conventions", NULL, NULL); if (result == NC_NOERR) { if (read_string_attribute(ncid, NC_GLOBAL, "Conventions", &convention_str) == 0) { int major, minor; if (harp_parse_file_convention(convention_str, &major, &minor) == 0) { free(convention_str); if (major > HARP_FORMAT_VERSION_MAJOR || (major == HARP_FORMAT_VERSION_MAJOR && minor > HARP_FORMAT_VERSION_MINOR)) { harp_set_error(HARP_ERROR_UNSUPPORTED_PRODUCT, "unsupported HARP format version %d.%d", major, minor); return -1; } return 0; } free(convention_str); } } harp_set_error(HARP_ERROR_UNSUPPORTED_PRODUCT, "not a HARP product"); return -1; }
static int read_numeric_attribute(int ncid, int varid, const char *name, harp_data_type *data_type, harp_scalar *data) { nc_type netcdf_data_type; size_t netcdf_num_elements; int result; result = nc_inq_att(ncid, varid, name, &netcdf_data_type, &netcdf_num_elements); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } if (netcdf_num_elements != 1) { harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid format", name); return -1; } if (get_harp_type(netcdf_data_type, data_type) != 0) { harp_add_error_message(" (attribute '%s')", name); return -1; } switch (netcdf_data_type) { case NC_BYTE: result = nc_get_att_schar(ncid, varid, name, &data->int8_data); break; case NC_SHORT: result = nc_get_att_short(ncid, varid, name, &data->int16_data); break; case NC_INT: result = nc_get_att_int(ncid, varid, name, &data->int32_data); break; case NC_FLOAT: result = nc_get_att_float(ncid, varid, name, &data->float_data); break; case NC_DOUBLE: result = nc_get_att_double(ncid, varid, name, &data->double_data); break; default: harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid type", name); return -1; } if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } return 0; }
/* Both CF and CDM use an attribute to hold a space-separated list of * names of coordinate variables. This function reads that attribute * and looks up the ID of each coordinate var. */ int nccf_parse_coords(int ncid, int varid, char *att_name, int *naxes, int *axis_varids) { size_t len; char *coords_str; char axis_name[NC_MAX_NAME + 1], *p, *a; int num_axes = 0; int *axes; int a1, ret; /* Check reasonableness of name. */ if (!att_name || strlen(att_name) > NC_MAX_NAME) return CF_EINVAL; /* Find length of the attribute. */ if ((ret = nc_inq_att(ncid, varid, att_name, NULL, &len))) return ret; /* Allocate space to read in the string. */ if (!(coords_str = malloc(len))) return CF_ENOMEM; /* Read in the system string. */ ret = nc_get_att_text(ncid, varid, att_name, coords_str); /* If we got the coord axes string, parse it to find the names of * the coordinate vars which make up this system. */ axes = (int*)malloc(sizeof(int)*NC_MAX_DIMS); if(axes == null) return NC_ENOMEM; for (p = coords_str; !ret && (p - coords_str) < strlen(coords_str);) { for (a = axis_name; *p && *p != ' '; ) *a++ = *p++; p++; *a = '\0'; ret = nc_inq_varid(ncid, axis_name, &axes[num_axes++]); } /* Thanks for the memories! */ free(coords_str); /* Give the user what they asked for. */ if (naxes) *naxes = num_axes; if (axis_varids) for (a1 = 0; a1 < num_axes; a1++) axis_varids[a1] = axes[a1]; free(axes) return CF_NOERR; }
int main(int argc, char **argv) { printf("\n*** Testing netcdf-4 string type.\n"); printf("*** testing very simple string attribute..."); { #define ATT_LEN 1 size_t att_len; int ndims, nvars, natts, unlimdimid; nc_type att_type; int ncid, i; char *data_in[ATT_LEN]; char *data[ATT_LEN] = {"An appeaser is one who feeds a crocodile — " "hoping it will eat him last. " "Here are some non-ASCII characters: " "\x00\xAA\xBB\xFF"}; if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, NC_STRING, ATT_LEN, data)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_STRING || att_len != ATT_LEN) ERR; if (nc_close(ncid)) ERR; /* Check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_STRING || att_len != ATT_LEN) ERR; if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR; for (i = 0; i < att_len; i++) if (strcmp(data_in[i], data[i])) ERR; if (nc_free_string(att_len, (char **)data_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
/*! This function queries the type and the size of an attribute given its name and the id of the variable to which it is attached. \param [in] ncid Groupd id (or File Id) \param [in] varid the id of the variable to which the attribute is attached \param [in] name the name of the attribute \param [out] type the type of the attribute \param [out] len the size of the attribute \return Status code */ int CNetCdfInterface::inqAtt(int ncid, int varid, const StdString& name, nc_type& type, size_t& len) { int status = nc_inq_att(ncid, varid, name.c_str(), &type, &len); if (NC_NOERR != status) { StdString errormsg(nc_strerror(status)); StdStringStream sstr; sstr << "Error when calling function nc_inq_att(ncid, varid, name.c_str(), &type, &len)" << std::endl; sstr << errormsg << std::endl; sstr << "Unable to query the attribute information given its name: " << name << " and its variable id:" << varid << std::endl; StdString e = sstr.str(); throw CNetCdfException(e); } return status; }
static void pr_att( int ncid, int varid, const char *varname, int ia ) { struct ncatt att; /* attribute */ NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) ); Printf ("\t\t%s:%s = ", varname, att.name); NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) ); if (att.len == 0) { /* show 0-length attributes as empty strings */ att.type = NC_CHAR; att.len = 1; } switch (att.type) { case NC_CHAR: att.string = (char *) malloc(att.len); if (!att.string) { error("Out of memory!"); NC_CHECK( nc_close(ncid) ); return; } NC_CHECK( nc_get_att_text(ncid, varid, att.name, att.string ) ); pr_att_string(att.len, att.string); free(att.string); break; default: att.vals = (double *) malloc(att.len * sizeof(double)); if (!att.vals) { error("Out of memory!"); NC_CHECK( nc_close(ncid) ); return; } NC_CHECK( nc_get_att_double(ncid, varid, att.name, att.vals ) ); pr_att_vals(att.type, att.len, att.vals); free(att.vals); break; } Printf (" ;\n"); }
/*************************************************************************** int mpp_var_att_exist(int fid, int vid, const char *att) check the field var has the attribute "att" or not. ***************************************************************************/ int mpp_var_att_exist(int fid, int vid, const char *att) { int status; size_t attlen; nc_type atttype; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_var_att_exist): invalid fid number, fid should be " "a nonnegative integer that less than nfiles"); if(vid<0 || vid >=files[fid].nvar) mpp_error("mpp_io(mpp_var_att_exist): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); status = nc_inq_att(files[fid].ncid, files[fid].var[vid].fldid, att, &atttype, &attlen); if(status == NC_NOERR) return 1; else return 0; }; /* mpp_att_exist */
/* Given the varid of a system, write an attribute to a varid, whcih * indicates that it (the var) partakes of the system. Recall that the * system is just a collection of var names which are axes of the * coordinate system. */ int nccf_assign_coord_system(int ncid, int varid, int system_varid) { char system_name[NC_MAX_NAME + 1]; char *systems_str; size_t len, new_len = 0; int ret; /* Find the name of this system. */ if ((ret = nc_inq_varname(ncid, system_varid, system_name))) return ret; /* Is the att already here? If so, get it's length, then it's * contents, then append a space and the new system name. */ ret = nc_inq_att(ncid, varid, COORDINATE_SYSTEMS, NULL, &len); if (ret != NC_ENOTATT && ret != NC_NOERR) return ret; if (!ret) new_len += len; new_len += strlen(system_name) + 1; if (!(systems_str = malloc(new_len))) return NC_NOERR; systems_str[0] = 0; if (!ret) { if ((ret = nc_get_att_text(ncid, varid, COORDINATE_SYSTEMS, systems_str))) return ret; strcat(systems_str, " "); } strcat(systems_str, system_name); /* Write an att, called _CoordinateSystems, which * contains a list of the system names related to this variable. */ ret = nc_put_att_text(ncid, varid, COORDINATE_SYSTEMS, strlen(systems_str) + 1, systems_str); /* Free the memory we allocated. */ free(systems_str); return ret; }
/* Given an ncid, check the file to make sure it has all the objects I * expect. */ int check_classic_file(int ncid) { int varid, dimid, attnum; size_t att_len; nc_type att_type; char name_in[sizeof(name_utf8) + 1], strings_in[sizeof(name_utf8) + 1]; /* Check the variable. */ if (nc_inq_varid(ncid, name_utf8, &varid)) ERR; if (nc_inq_varname(ncid, varid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; if (nc_inq_varid(ncid, norm_utf8, &varid)) ERR; name_in[0] = 0; if (nc_inq_varname(ncid, varid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; if (nc_get_var_text(ncid, varid, strings_in)) ERR; if (strncmp(name_utf8, strings_in, sizeof(name_utf8))) ERR; strings_in[0] = '\0'; /* Reset my string buffer. */ /* Check the dimension. */ if (nc_inq_dimid(ncid, name_utf8, &dimid)) ERR; if (nc_inq_dimname(ncid, dimid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; if (nc_inq_dimid(ncid, norm_utf8, &dimid)) ERR; if (nc_inq_dimname(ncid, dimid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; /* Check the attribute. We don't normalize data or attribute * values, so get exactly what was put for the value, but * normalized values for names. */ if (nc_inq_attid(ncid, varid, norm_utf8, &attnum)) ERR; if (attnum) ERR; attnum = 99; /* Reset. */ if (nc_inq_attid(ncid, varid, name_utf8, &attnum)) ERR; if (attnum) ERR; if (nc_inq_att(ncid, varid, norm_utf8, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != sizeof(name_utf8)) ERR; if (nc_get_att_text(ncid, varid, norm_utf8, strings_in)) ERR; if (strncmp(name_utf8, strings_in, sizeof(name_utf8))) ERR; return NC_NOERR; }
bool Ensemble::getAttText(int ncid, int varid, const char* aName, std::vector<std::string>& vs ) { // true for failure vs.clear(); nc_type xtypep; size_t len; if( nc_inq_att(ncid, varid, aName, &xtypep, &len) ) return true; if( xtypep == 12 ) { char** arr = new char*[len]; for(size_t i=0 ; i < len ; ++i ) arr[i] = new char[250]; if( nc_get_att_string(ncid, varid, aName, arr) ) return true; for( size_t i=0 ; i < len ; ++i ) vs.push_back(arr[i]); for(size_t i=0 ; i < len ; ++i ) delete [] arr[i]; delete [] arr; } else if( xtypep == 2 ) { char uc[len+1] ; if( nc_get_att_text(ncid, varid, aName, uc) ) return true; uc[len]='\0'; vs.push_back(uc); } return false; }
static int read_string_attribute(int ncid, int varid, const char *name, char **data) { char *str; nc_type data_type; size_t netcdf_num_elements; int result; result = nc_inq_att(ncid, varid, name, &data_type, &netcdf_num_elements); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } if (data_type != NC_CHAR) { harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid type", name); return -1; } str = malloc((netcdf_num_elements + 1) * sizeof(char)); if (str == NULL) { harp_set_error(HARP_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)", (netcdf_num_elements + 1) * sizeof(char), __FILE__, __LINE__); return -1; } result = nc_get_att_text(ncid, varid, name, str); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); free(str); return -1; } str[netcdf_num_elements] = '\0'; *data = str; return 0; }
float * avtNETCDFReaderBase::ReadTimeAttribute() { float *times_array = 0; // // See if the global attribute time exists. If it does and is // either a float or double, then return the first value of it // as the time array. // int status; nc_type atttype; size_t attsize; if((status = nc_inq_att(fileObject->GetFileHandle(), NC_GLOBAL, "Time", &atttype, &attsize)) == NC_NOERR) { if (atttype == NC_FLOAT) { times_array = new float[1]; float *value = new float[attsize]; nc_get_att_float(fileObject->GetFileHandle(), NC_GLOBAL, "Time", value); times_array[0] = value[0]; delete [] value; } else if (atttype == NC_DOUBLE) { times_array = new float[1]; double *value = new double[attsize]; nc_get_att_double(fileObject->GetFileHandle(), NC_GLOBAL, "Time", value); times_array[0] = value[0]; delete [] value; } } return times_array; }
int test_pio_attr(int flag) { /* MPI stuff. */ int mpi_size, mpi_rank; MPI_Comm comm = MPI_COMM_WORLD; MPI_Info info = MPI_INFO_NULL; /* Netcdf-4 stuff. */ int ncid; int nvid; int j, i; double rh_range[2]; static char title[] = "parallel attr to netCDF"; nc_type st_type,vr_type; size_t vr_len,st_len; size_t orivr_len; double *vr_val; char *st_val; /* two dimensional integer data*/ int dimids[NDIMS1]; size_t start[NDIMS1]; size_t count[NDIMS1]; int *data; int *tempdata; /* Initialize MPI. */ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); /* Create a parallel netcdf-4 file. */ /* nc_set_log_level(NC_TURN_OFF_LOGGING); */ /* nc_set_log_level(3);*/ if (nc_create_par(file_name, facc_type, comm, info, &ncid)) ERR; /* Create a 2-D variable so that an attribute can be added. */ if (nc_def_dim(ncid, "d1", DIMSIZE2, dimids)) ERR; if (nc_def_dim(ncid, "d2", DIMSIZE, &dimids[1])) ERR; /* Create one var. */ if (nc_def_var(ncid, "v1", NC_INT, NDIMS1, dimids, &nvid)) ERR; orivr_len = 2; rh_range[0] = 1.0; rh_range[1] = 1000.0; /* Write attributes of a variable */ if (nc_put_att_double (ncid, nvid, "valid_range", NC_DOUBLE, orivr_len, rh_range)) ERR; if (nc_put_att_text (ncid, nvid, "title", strlen(title), title)) ERR; /* Write global attributes */ if (nc_put_att_double (ncid, NC_GLOBAL, "g_valid_range", NC_DOUBLE, orivr_len, rh_range)) ERR; if (nc_put_att_text (ncid, NC_GLOBAL, "g_title", strlen(title), title)) ERR; if (nc_enddef(ncid)) ERR; /* Set up slab for this process. */ start[0] = 0; start[1] = mpi_rank * DIMSIZE/mpi_size; count[0] = DIMSIZE2; count[1] = DIMSIZE/mpi_size; /* Access parallel */ if (nc_var_par_access(ncid, nvid, flag)) ERR; /* Allocating data */ data = malloc(sizeof(int)*count[1]*count[0]); tempdata = data; for(j = 0; j < count[0]; j++) for (i = 0; i < count[1]; i++) { *tempdata = mpi_rank * (j + 1); tempdata++; } if (nc_put_vara_int(ncid, nvid, start, count, data)) ERR; free(data); /* Close the netcdf file. */ if (nc_close(ncid)) ERR; /* Read attributes */ if (nc_open_par(file_name, facc_type_open, comm, info, &ncid)) ERR; /* Set up slab for this process. */ start[0] = 0; start[1] = mpi_rank * DIMSIZE/mpi_size; count[0] = DIMSIZE2; count[1] = DIMSIZE/mpi_size; /* Inquiry variable */ if (nc_inq_varid(ncid, "v1", &nvid)) ERR; /* Access parallel */ if (nc_var_par_access(ncid, nvid, flag)) ERR; /* Inquiry attribute */ if (nc_inq_att (ncid, nvid, "valid_range", &vr_type, &vr_len)) ERR; /* check stuff */ if(vr_type != NC_DOUBLE || vr_len != orivr_len) ERR; vr_val = (double *) malloc(vr_len * sizeof(double)); /* Get variable attribute values */ if (nc_get_att_double(ncid, nvid, "valid_range", vr_val)) ERR; /* Check variable attribute value */ for(i = 0; i < vr_len; i++) if (vr_val[i] != rh_range[i]) ERR_RET; free(vr_val); /* Inquiry global attribute */ if (nc_inq_att (ncid, NC_GLOBAL, "g_valid_range", &vr_type, &vr_len)) ERR; /* Check stuff. */ if(vr_type != NC_DOUBLE || vr_len != orivr_len) ERR; /* Obtain global attribute value */ vr_val = (double *) malloc(vr_len * sizeof(double)); if (nc_get_att_double(ncid, NC_GLOBAL, "g_valid_range", vr_val)) ERR; /* Check global attribute value */ for(i = 0; i < vr_len; i++) if (vr_val[i] != rh_range[i]) ERR_RET; free(vr_val); /* Inquiry string attribute of a variable */ if (nc_inq_att (ncid, nvid, "title", &st_type, &st_len)) ERR; /* check string attribute length */ if(st_len != strlen(title)) ERR_RET; /* Check string attribute type */ if(st_type != NC_CHAR) ERR_RET; /* Allocate meory for string attribute */ st_val = (char *) malloc(st_len * (sizeof(char))); /* Obtain variable string attribute value */ if (nc_get_att_text(ncid, nvid,"title", st_val)) ERR; /*check string value */ if(strncmp(st_val,title,st_len)) { free(st_val); ERR_RET; } free(st_val); /*Inquiry global attribute */ if (nc_inq_att (ncid, NC_GLOBAL, "g_title", &st_type, &st_len)) ERR; /* check attribute length*/ if(st_len != strlen(title)) ERR_RET; /*check attribute type*/ if(st_type != NC_CHAR) ERR_RET; /* obtain global string attribute value */ st_val = (char*)malloc(st_len*sizeof(char)); if (nc_get_att_text(ncid, NC_GLOBAL,"g_title", st_val)) ERR; /* check attribute value */ if(strncmp(st_val,title,st_len)){ free(st_val); ERR_RET; } free(st_val); /* Close the netcdf file. */ if (nc_close(ncid)) ERR; return 0; }
int main(int argc, char **argv) {/* create file that caused seg fault in ncdump */ int ncid; /* netCDF id */ /* dimension ids */ int Time_dim; int X_dim; int Y_dim; /* dimension lengths */ size_t Time_len = NC_UNLIMITED; size_t X_len = 4; size_t Y_len = 3; /* variable ids */ int Time_id; int P_id; /* rank (number of dimensions) for each variable */ # define RANK_Time 1 # define RANK_P 3 /* variable shapes */ int Time_dims[RANK_Time]; int P_dims[RANK_P]; printf("\n*** Testing preparation of fillbug test.\n"); printf("*** creating fillbug test file %s...", FILENAME); /* enter define mode */ if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "Time", Time_len, &Time_dim)) ERR; if (nc_def_dim(ncid, "X", X_len, &X_dim)) ERR; if (nc_def_dim(ncid, "Y", Y_len, &Y_dim)) ERR; /* define variables */ Time_dims[0] = Time_dim; if (nc_def_var(ncid, "Time", NC_DOUBLE, RANK_Time, Time_dims, &Time_id)) ERR; P_dims[0] = Time_dim; P_dims[1] = Y_dim; P_dims[2] = X_dim; if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, P_dims, &P_id)) ERR; /* leave define mode */ if (nc_enddef (ncid)) ERR; {/* assign variable data */ static double Time_data[1]={3.14159}; static size_t Time_startset[1] = {0}; static size_t Time_countset[1] = {1}; if (nc_put_vara(ncid, Time_id, Time_startset, Time_countset, Time_data)) ERR; } if (nc_close(ncid)) ERR; /* Try to duplicate segfault ncdump gets by making the same calls * to the netCDF-4 library, in the same order. This doesn't * result in the same segfault, so either we have missed a call * made by ncdump, or an earlier ncdump bug masks the real problem * until a call is made into the netCDF-4 library ... */ if (nc_open(FILENAME, NC_NOWRITE, &ncid)) ERR; { /* We declare local arrays with small constant sizes to avoid * all the mallocs and frees used in ncdump. For the example * above, the fixed-size arrays are ample. */ int format, ndims, nvars, ngatts, xdimid, ndims_grp, dimids_grp[3], unlimids[1], d_grp, nunlim, nvars_grp, varids_grp[3], v_grp, varid, varndims, vardims[3], varnatts, vartype, dimids[3], is_recvar, vdims[3], id, ntypes, numgrps, atttype, nc_status; size_t dimsize, len, attlen; char dimname[20], varname[20]; if ( nc_inq_format(ncid, &format)) ERR; ntypes = count_udtypes(ncid); if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR; if ( nc_inq_format(ncid, &format)) ERR; if ( nc_inq_grps(ncid, &numgrps, NULL) ) ERR; if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR; if ( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) ) ERR; if ( nc_inq_ndims(ncid, &ndims_grp) ) ERR; if ( nc_inq_dimids(ncid, 0, dimids_grp, 0) ) ERR; if ( nc_inq_unlimdims(ncid, &nunlim, NULL) ) ERR; if ( nc_inq_unlimdims(ncid, &nunlim, unlimids) ) ERR; for (d_grp = 0; d_grp < ndims_grp; d_grp++) { int dimid = dimids_grp[d_grp]; if ( nc_inq_dim(ncid, dimid, dimname, &dimsize) ) ERR; } if ( nc_inq_format(ncid, &format) ) ERR; if ( nc_inq_varids(ncid, &nvars_grp, varids_grp) ) ERR; for (v_grp = 0; v_grp < nvars_grp; v_grp++) { varid = varids_grp[v_grp]; if ( nc_inq_varndims(ncid, varid, &varndims) ) ERR; if ( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims, &varnatts) ) ERR; for (id = 0; id < varndims; id++) { if ( nc_inq_dimname(ncid, vardims[id], dimname) ) ERR; } } for (v_grp = 0; v_grp < nvars_grp; v_grp++) { varid = varids_grp[v_grp]; if( nc_inq_varndims(ncid, varid, &varndims) ) ERR; if( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims, &varnatts) ) ERR; { is_recvar = 0; if ( nc_inq_varndims(ncid, varid, &ndims) ) ERR; if (ndims > 0) { int nunlimdims; int recdimids[3]; int dim, recdim; if ( nc_inq_vardimid(ncid, varid, dimids) ) ERR; if ( nc_inq_unlimdims(ncid, &nunlimdims, NULL) ) ERR; if ( nc_inq_unlimdims(ncid, NULL, recdimids) ) ERR; for (dim = 0; dim < ndims && is_recvar == 0; dim++) { for(recdim = 0; recdim < nunlimdims; recdim++) { if(dimids[dim] == recdimids[recdim]) { is_recvar = 1; break; } } } } } for (id = 0; id < varndims; id++) { if( nc_inq_dimlen(ncid, vardims[id], &len) ) ERR; vdims[id] = len; } nc_status = nc_inq_att(ncid,varid,_FillValue,&atttype,&attlen); nc_status = nc_inq_att(ncid, varid, "units", &atttype, &attlen); nc_status = nc_inq_att(ncid, varid, "C_format", &atttype, &attlen); if (varid == 0) { /* read Time variable */ static double Time_data; static size_t cor[RANK_Time] = {0}; static size_t edg[RANK_Time] = {1}; if (nc_get_vara(ncid, varid, cor, edg, &Time_data)) ERR; } else { /* read data slices from P variable, should get fill values */ static float P_data[4]; static size_t cor[RANK_P] = {0, 0, 0}; static size_t edg[RANK_P] = {1, 1, 4}; /* first slice retrieved OK */ if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR; /* In ncdump, reading second slice gets seg fault in * nc4_open_var_grp(), but this attempt to do all the * same netCDF calls as ncdump can't duplicate the * error, which would seem to implicate ncdump rather * than HDF5 or netCDF-4 library ... */ cor[1] = 1; if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR; } } } if (nc_close(ncid)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; }
int ex_open_int(const char *path, int mode, int *comp_ws, int *io_ws, float *version, int run_version) { int exoid; int status, stat_att, stat_dim; nc_type att_type = NC_NAT; size_t att_len = 0; int old_fill; int file_wordsize; int dim_str_name; int int64_status = 0; int nc_mode = 0; char errmsg[MAX_ERR_LENGTH]; EX_FUNC_ENTER(); /* set error handling mode to no messages, non-fatal errors */ ex_opts(exoptval); /* call required to set ncopts first time through */ if (run_version != EX_API_VERS_NODOT && warning_output == 0) { int run_version_major = run_version / 100; int run_version_minor = run_version % 100; int lib_version_major = EX_API_VERS_NODOT / 100; int lib_version_minor = EX_API_VERS_NODOT % 100; fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus " "version %d.%02d,\n but was linked with exodus " "library version %d.%02d\n This is probably an " "error in the build process of this code.\n", run_version_major, run_version_minor, lib_version_major, lib_version_minor); warning_output = 1; } if ((mode & EX_READ) && (mode & EX_WRITE)) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Cannot specify both EX_READ and EX_WRITE"); ex_err(__func__, errmsg, EX_BADFILEMODE); EX_FUNC_LEAVE(EX_FATAL); } /* The EX_READ mode is the default if EX_WRITE is not specified... */ if (!(mode & EX_WRITE)) { /* READ ONLY */ nc_mode = NC_NOWRITE | NC_SHARE; #if NC_HAS_DISKLESS if (mode & EX_DISKLESS) { nc_mode |= NC_DISKLESS; } #endif if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ /* It is possible that the user is trying to open a netcdf4 file, but the netcdf4 capabilities aren't available in the netcdf linked to this library. Note that we can't just use a compile-time define since we could be using a shareable netcdf library, so the netcdf4 capabilities aren't known until runtime... Later versions of netcdf-4.X have a function that can be queried to determine whether the library being used was compiled with --enable-netcdf4, but not everyone is using that version yet, so we may have to do some guessing... At this time, query the beginning of the file and see if it is an HDF-5 file and if it is assume that the open failure is due to the netcdf library not enabling netcdf4 features unless we have the define that shows it is enabled, then assume other error... */ int type = 0; ex_check_file_type(path, &type); if (type == 5) { #if NC_HAS_HDF5 fprintf(stderr, "EXODUS: ERROR: Attempting to open the netcdf-4 " "file:\n\t'%s'\n\t failed. The netcdf library supports " "netcdf-4 so there must be a filesystem or some other " "issue \n", path); #else /* This is an hdf5 (netcdf4) file. If NC_HAS_HDF5 is not defined, then we either don't have hdf5 support in this netcdf version, OR this is an older netcdf version that doesn't provide that define. In either case, we don't have enough information, so we assume that the netcdf doesn't have netcdf4 capabilities enabled. Tell the user... */ fprintf(stderr, "EXODUS: ERROR: Attempting to open the netcdf-4 " "file:\n\t'%s'\n\t. Either the netcdf library does not " "support netcdf-4 or there is a filesystem or some " "other issue \n", path); #endif } else if (type == 4) { #if defined(NC_64BIT_DATA) fprintf(stderr, "EXODUS: ERROR: Attempting to open the CDF5 " "file:\n\t'%s'\n\t failed. The netcdf library supports " "CDF5-type files so there must be a filesystem or some other " "issue \n", path); #else /* This is an cdf5 (64BIT_DATA) file. If NC_64BIT_DATA is not defined, then we either don't have cdf5 support in this netcdf version, OR this is an older netcdf version that doesn't provide that define. In either case, we don't have enough information, so we assume that the netcdf doesn't have cdf5 capabilities enabled. Tell the user... */ fprintf(stderr, "EXODUS: ERROR: Attempting to open the CDF5 " "file:\n\t'%s'\n\t. Either the netcdf library does not " "support CDF5 or there is a filesystem or some " "other issue \n", path); #endif } snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s read only", path); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } else { /* (mode & EX_WRITE) READ/WRITE */ nc_mode = NC_WRITE | NC_SHARE; #if NC_HAS_DISKLESS if (mode & EX_DISKLESS) { nc_mode |= NC_DISKLESS; } #endif if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s write only", path); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* turn off automatic filling of netCDF variables */ if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len); stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name); if (stat_att != NC_NOERR || stat_dim != NC_NOERR) { if ((status = nc_redef(exoid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } if (stat_att != NC_NOERR) { int max_so_far = 32; nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far); } /* If the DIM_STR_NAME variable does not exist on the database, we need to * add it now. */ if (stat_dim != NC_NOERR) { /* Not found; set to default value of 32+1. */ int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length; if ((status = nc_def_dim(exoid, DIM_STR_NAME, max_name + 1, &dim_str_name)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define string name dimension in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } if ((status = nc_enddef(exoid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } } /* determine version of EXODUS file, and the word size of * floating point and integer values stored in the file */ if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get database version for file id: %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* check ExodusII file version - old version 1.x files are not supported */ if (*version < 2.0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Unsupported file version %.2f in file id: %d", *version, exoid); ex_err(__func__, errmsg, EX_BADPARAM); EX_FUNC_LEAVE(EX_FATAL); } if (nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR) { /* try old (prior to db version 2.02) attribute name */ if ((status = nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE_BLANK, &file_wordsize)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get file wordsize from file id: %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } /* See if int64 status attribute exists and if so, what data is stored as * int64 * Older files don't have the attribute, so it is not an error if it is * missing */ if (nc_get_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) { int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */ } /* Merge in API int64 status flags as specified by caller of function... */ int64_status |= (mode & EX_ALL_INT64_API); /* Verify that there is not an existing file_item struct for this exoid This could happen (and has) when application calls ex_open(), but then closes file using nc_close() and then reopens file. NetCDF will possibly reuse the exoid which results in internal corruption in exodus data structures since exodus does not know that file was closed and possibly new file opened for this exoid */ if (ex_find_file_item(exoid) != NULL) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: There is an existing file already using the file " "id %d which was also assigned to file %s.\n\tWas " "nc_close() called instead of ex_close() on an open Exodus " "file?\n", exoid, path); ex_err(__func__, errmsg, EX_BADFILEID); nc_close(exoid); EX_FUNC_LEAVE(EX_FATAL); } /* initialize floating point and integer size conversion. */ if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 0, 0, 0) != EX_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to initialize conversion routines in file id %d", exoid); ex_err(__func__, errmsg, EX_LASTERR); EX_FUNC_LEAVE(EX_FATAL); } EX_FUNC_LEAVE(exoid); }
/* Test the creation of a system, and it's assignment to a data * variable. THis matches example 2 from John's document (with some of * the other attributes left out.) */ static void test_system_assign(const char *testfile) { int ncid, axis_varids[NDIMS], system_varid, dimids[NDIMS]; int nvars, ndims, natts, unlimdimid; int dimids_in[NDIMS], ndims_in; size_t len_in; char name_in[NC_MAX_NAME + 1]; char systems_in[NC_MAX_NAME + 1]; int naxes_in, axis_varids_in[NDIMS], natts_in; char *dim_name[] = {TIME, LEVEL, LAT, LON}; size_t dim_len[NDIMS] = {NC_UNLIMITED, LEVEL_LEN, LAT_LEN, LON_LEN}; int earth_varid, air_varid; int varid_in; nc_type type_in; int d; /* Create a file. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; /* Create 4 dimensions, and a coordinate var to go with each. */ for (d = 0; d < NDIMS; d++) { if (nc_def_dim(ncid, dim_name[d], dim_len[d], &dimids[d])) ERR; if (nc_def_var(ncid, dim_name[d], NC_FLOAT, 1, &dimids[d], &axis_varids[d])) ERR; } /* Create two data vars, earth and air. (Don't know what happened * to fire and water Aristotle!) */ if (nc_def_var(ncid, EARTH, NC_FLOAT, NDIMS, dimids, &earth_varid)) ERR; if (nc_def_var(ncid, AIR, NC_FLOAT, NDIMS, dimids, &air_varid)) ERR; /* Unite our 4 dims in a coordinate system. */ if (nccf_def_coord_system(ncid, LAT_LON_COORDINATE_SYSTEM, NDIMS, axis_varids, &system_varid)) ERR; /* Check things out. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 4 && nvars != 7 && natts != 0 && unlimdimid != dimids[3]) ERR; if (nc_inq_varid(ncid, LAT_LON_COORDINATE_SYSTEM, &varid_in)) ERR; if (varid_in != system_varid) ERR; if (nc_inq_var(ncid, system_varid, name_in, &type_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LAT_LON_COORDINATE_SYSTEM) || type_in != NC_CHAR || ndims_in != 0 || natts_in != 1); if (nc_inq_att(ncid, system_varid, COORDINATE_AXES, &type_in, &len_in)) ERR; if (type_in != NC_CHAR) ERR; if (nccf_inq_coord_system(ncid, system_varid, name_in, &naxes_in, axis_varids_in)) ERR; if (strcmp(name_in, LAT_LON_COORDINATE_SYSTEM) || naxes_in != NDIMS) ERR; for (d = 0; d < NDIMS; d++) if (axis_varids_in[d] != axis_varids[d]) ERR; /* Assign the system to the earth and air data variables. */ if (nccf_assign_coord_system(ncid, earth_varid, system_varid)) ERR; if (nccf_assign_coord_system(ncid, air_varid, system_varid)) ERR; /* Check to ensure that the assignments happened. */ if (nc_inq_varnatts(ncid, earth_varid, &natts_in)) ERR; if (natts_in != 1) ERR; if (nc_inq_att(ncid, earth_varid, COORDINATE_SYSTEMS, &type_in, &len_in)) ERR; if (type_in != NC_CHAR) ERR; if (nc_inq_varnatts(ncid, air_varid, &natts_in)) ERR; if (natts_in != 1) ERR; if (nc_get_att_text(ncid, earth_varid, COORDINATE_SYSTEMS, systems_in)) ERR; if (strcmp(systems_in, LAT_LON_COORDINATE_SYSTEM)) ERR; if (nc_inq_att(ncid, air_varid, COORDINATE_SYSTEMS, &type_in, &len_in)) ERR; if (type_in != NC_CHAR) ERR; if (nc_get_att_text(ncid, air_varid, COORDINATE_SYSTEMS, systems_in)) ERR; if (strcmp(systems_in, LAT_LON_COORDINATE_SYSTEM)) ERR; /* Write the file. */ if (nc_close(ncid)) ERR; /* Reopen the file and check it. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 4 && nvars != 7 && natts != 0 && unlimdimid != dimids[3]) ERR; if (nc_inq_var(ncid, system_varid, name_in, &type_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LAT_LON_COORDINATE_SYSTEM) || type_in != NC_CHAR || ndims_in != 0 || natts_in != 1); if (nc_inq_att(ncid, system_varid, COORDINATE_AXES, &type_in, &len_in)) ERR; if (type_in != NC_CHAR) ERR; if (nccf_inq_coord_system(ncid, system_varid, name_in, &naxes_in, axis_varids_in)) ERR; if (strcmp(name_in, LAT_LON_COORDINATE_SYSTEM) || naxes_in != NDIMS) ERR; for (d = 0; d < NDIMS; d++) if (axis_varids_in[d] != axis_varids[d]) ERR; /* Check to ensure that the assignments happened. */ if (nc_inq_varnatts(ncid, earth_varid, &natts_in)) ERR; if (natts_in != 1) ERR; if (nc_inq_att(ncid, earth_varid, COORDINATE_SYSTEMS, &type_in, &len_in)) ERR; if (type_in != NC_CHAR) ERR; if (nc_inq_varnatts(ncid, air_varid, &natts_in)) ERR; if (natts_in != 1) ERR; if (nc_get_att_text(ncid, earth_varid, COORDINATE_SYSTEMS, systems_in)) ERR; if (strcmp(systems_in, LAT_LON_COORDINATE_SYSTEM)) ERR; if (nc_inq_att(ncid, air_varid, COORDINATE_SYSTEMS, &type_in, &len_in)) ERR; if (type_in != NC_CHAR) ERR; if (nc_get_att_text(ncid, air_varid, COORDINATE_SYSTEMS, systems_in)) ERR; if (strcmp(systems_in, LAT_LON_COORDINATE_SYSTEM)) ERR; if (nc_close(ncid)) ERR; }
static int ex_inquire_internal (int exoid, int req_info, int64_t *ret_int, float *ret_float, char *ret_char) { int dimid, varid, tmp_num; void_int *ids = NULL; size_t i; size_t ldum = 0; size_t num_sets, idum; int *stat_vals; char errmsg[MAX_ERR_LENGTH]; int status; char tmp_title[2048]; exerrval = 0; /* clear error code */ if (ret_char) *ret_char = '\0'; /* Only needs to be non-null for TITLE */ if (!ret_int) { exerrval = EX_BADPARAM; sprintf(errmsg, "Warning: integer argument is NULL which is not allowed."); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } switch (req_info) { case EX_INQ_FILE_TYPE: /* obsolete call */ /*returns "r" for regular EXODUS II file or "h" for history EXODUS file*/ exerrval = EX_BADPARAM; sprintf(errmsg, "Warning: file type inquire is obsolete"); ex_err("ex_inquire",errmsg,exerrval); return (EX_WARN); case EX_INQ_API_VERS: /* returns the EXODUS II API version number */ if (!ret_float) { exerrval = EX_BADPARAM; sprintf(errmsg, "Warning: float argument is NULL for EX_INQ_API_VERS which is not allowed."); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } if (nc_get_att_float(exoid, NC_GLOBAL, ATT_API_VERSION, ret_float) != NC_NOERR) { /* try old (prior to db version 2.02) attribute name */ if ((status = nc_get_att_float (exoid, NC_GLOBAL, ATT_API_VERSION_BLANK,ret_float)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get EXODUS API version for file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } } break; case EX_INQ_DB_VERS: /* returns the EXODUS II database version number */ if (!ret_float) { exerrval = EX_BADPARAM; sprintf(errmsg, "Warning: float argument is NULL for EX_INQ_DB_VERS which is not allowed."); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } if ((status = nc_get_att_float (exoid, NC_GLOBAL, ATT_VERSION, ret_float)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get EXODUS database version for file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } break; case EX_INQ_LIB_VERS: /* returns the EXODUS II Library version number */ if (ret_float) flt_cvt(ret_float, EX_API_VERS); *ret_int = EX_API_VERS_NODOT; break; case EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH: /* Return the MAX_NAME_LENGTH size for this database It will not include the space for the trailing null, so if it is defined as 33 on the database, 32 will be returned. */ if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &dimid)) != NC_NOERR) { /* If not found, then an older database */ *ret_int = 32; } else { /* Get the name string length */ size_t name_length = 0; if ((status = nc_inq_dimlen(exoid,dimid,&name_length)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get name string length in file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } else { *ret_int = name_length-1; } } break; case EX_INQ_DB_MAX_USED_NAME_LENGTH: /* Return the value of the ATT_MAX_NAME_LENGTH attribute (if it exists) which is the maximum length of any entity, variable, attribute, property name written to this database. If the attribute does not exist, then '32' is returned. The length does not include the trailing null. */ { nc_type att_type = NC_NAT; size_t att_len = 0; *ret_int = 32; /* Default size consistent with older databases */ status = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len); if (status == NC_NOERR && att_type == NC_INT) { /* The attribute exists, return it... */ nc_get_att_longlong(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, (long long*)ret_int); } } break; case EX_INQ_MAX_READ_NAME_LENGTH: { /* Returns the user-specified maximum size of names that will be * returned to the user by any of the ex_get_ routines. If the * name is longer than this value, it will be truncated. The * default if not set by the client is 32 characters. The value * does not include the trailing null. */ struct file_item* file = ex_find_file_item(exoid); if (!file ) { exerrval = EX_BADFILEID; sprintf(errmsg,"Error: unknown file id %d for ex_inquire_int().",exoid); ex_err("ex_intquire",errmsg,exerrval); *ret_int = 0; } else { *ret_int = file->maximum_name_length; } } break; case EX_INQ_TITLE: if (!ret_char) { sprintf(errmsg, "Error: Requested title, but character pointer was null for file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } else { /* returns the title of the database */ if ((status = nc_get_att_text (exoid, NC_GLOBAL, ATT_TITLE, tmp_title)) != NC_NOERR) { *ret_char = '\0'; exerrval = status; sprintf(errmsg, "Error: failed to get database title for file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } else { strncpy(ret_char, tmp_title, MAX_LINE_LENGTH+1); ret_char[MAX_LINE_LENGTH] = '\0'; } } break; case EX_INQ_DIM: /* returns the dimensionality (2 or 3, for 2-d or 3-d) of the database */ if (ex_get_dimension(exoid, DIM_NUM_DIM, "database dimensionality", &ldum, &dimid, "ex_inquire") != NC_NOERR) return EX_FATAL; *ret_int = ldum; break; case EX_INQ_NODES: /* returns the number of nodes */ if (ex_get_dimension(exoid, DIM_NUM_NODES, "nodes", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_ELEM: /* returns the number of elements */ if (ex_get_dimension(exoid, DIM_NUM_ELEM, "elements", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_ELEM_BLK: /* returns the number of element blocks */ if (ex_get_dimension(exoid, DIM_NUM_EL_BLK, "element blocks", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_NODE_SETS: /* returns the number of node sets */ if (ex_get_dimension(exoid, DIM_NUM_NS, "node sets", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_NS_NODE_LEN: /* returns the length of the concatenated node sets node list */ ex_get_concat_set_len(exoid, ret_int,"node",EX_NODE_SET,DIM_NUM_NS,VAR_NS_STAT,"num_nod_ns",0); break; case EX_INQ_NS_DF_LEN: /* returns the length of the concatenated node sets dist factor list */ /* Determine the concatenated node sets distribution factor length: 2. Check see if the dist factor variable for a node set id exists. 3. If it exists, goto step 4, else the length is zero. 4. Get the dimension of the number of nodes in the node set -0 use this value as the length as by definition they are the same. 5. Sum the individual lengths for the total list length. */ *ret_int = 0; /* default value if no node sets defined */ if (nc_inq_dimid (exoid, DIM_NUM_NS, &dimid) == NC_NOERR) { if ((status = nc_inq_dimlen(exoid, dimid, &num_sets)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get number of node sets in file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } for (i=0; i<num_sets; i++) { if ((status = nc_inq_varid (exoid, VAR_FACT_NS(i+1), &varid)) != NC_NOERR) { if (status == NC_ENOTVAR) { idum = 0; /* this dist factor doesn't exist */ } else { *ret_int = 0; exerrval = status; sprintf(errmsg, "Error: failed to locate number of dist fact for %"ST_ZU"'th node set in file id %d", i, exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } } else { if ((status = nc_inq_dimid (exoid, DIM_NUM_NOD_NS(i+1), &dimid)) != NC_NOERR) { *ret_int = 0; exerrval = status; sprintf(errmsg, "Error: failed to locate number of nodes in %"ST_ZU"'th node set in file id %d", i, exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } if ((status = nc_inq_dimlen (exoid, dimid, &idum)) != NC_NOERR) { *ret_int = 0; exerrval = status; sprintf(errmsg, "Error: failed to get number of nodes in %"ST_ZU"'th node set in file id %d", i,exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } } *ret_int += idum; } } break; case EX_INQ_SIDE_SETS: /* returns the number of side sets */ if (ex_get_dimension(exoid, DIM_NUM_SS, "side sets", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_SS_NODE_LEN: /* returns the length of the concatenated side sets node list */ *ret_int = 0; /* default return value */ if (nc_inq_dimid (exoid, DIM_NUM_SS, &dimid) == NC_NOERR) { if ((status = nc_inq_dimlen(exoid, dimid, &num_sets)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get number of side sets in file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } if (!(ids = malloc(num_sets*sizeof(int64_t)))) { /* May be getting 2x what is needed, but should be OK */ exerrval = EX_MEMFAIL; sprintf(errmsg, "Error: failed to allocate memory for side set ids for file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } if (ex_get_side_set_ids (exoid, ids) == EX_FATAL) { sprintf(errmsg, "Error: failed to get side set ids in file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); free(ids); return (EX_FATAL); } /* allocate space for stat array */ if (!(stat_vals = malloc((int)num_sets*sizeof(int)))) { exerrval = EX_MEMFAIL; free (ids); sprintf(errmsg, "Error: failed to allocate memory for side set status array for file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } /* get variable id of status array */ if ((status = nc_inq_varid (exoid, VAR_SS_STAT, &varid)) == NC_NOERR) { /* if status array exists, use it, otherwise assume, object exists to be backward compatible */ if ((status = nc_get_var_int(exoid, varid, stat_vals)) != NC_NOERR) { exerrval = status; free (ids); free(stat_vals); sprintf(errmsg, "Error: failed to get element block status array from file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } } else /* default: status is true */ for(i=0;i<num_sets;i++) stat_vals[i]=1; /* walk id list, get each side set node length and sum for total */ for (i=0; i<num_sets; i++) { ex_entity_id id; if (stat_vals[i] == 0) /* is this object null? */ continue; if (ex_int64_status(exoid) & EX_IDS_INT64_API) id = ((int64_t*)ids)[i]; else id = ((int*)ids)[i]; if ((status = ex_get_side_set_node_list_len(exoid, id, &tmp_num)) != NC_NOERR) { *ret_int = 0; exerrval = status; sprintf(errmsg, "Error: failed to side set %"PRId64" node length in file id %d", id,exoid); ex_err("ex_inquire",errmsg,exerrval); free(stat_vals); free(ids); return (EX_FATAL); } *ret_int += tmp_num; } free(stat_vals); free (ids); } break; case EX_INQ_SS_ELEM_LEN: /* returns the length of the concatenated side sets element list */ ex_get_concat_set_len(exoid, ret_int,"side",EX_SIDE_SET,DIM_NUM_SS,VAR_SS_STAT,"num_side_ss",0); break; case EX_INQ_SS_DF_LEN: /* returns the length of the concatenated side sets dist factor list */ /* Determine the concatenated side sets distribution factor length: 1. Get the side set ids list. 2. Check see if the dist factor dimension for a side set id exists. 3. If it exists, goto step 4, else set the individual length to zero. 4. Sum the dimension value into the running total length. */ *ret_int = 0; /* first check see if any side sets exist */ if (nc_inq_dimid (exoid, DIM_NUM_SS, &dimid) == NC_NOERR) { if ((status = nc_inq_dimlen (exoid, dimid, &num_sets)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get number of side sets in file id %d", exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } for (i=0; i<num_sets; i++) { if ((status = nc_inq_dimid (exoid, DIM_NUM_DF_SS(i+1), &dimid)) != NC_NOERR) { if (status == NC_EBADDIM) { ldum = 0; /* this dist factor doesn't exist */ } else { *ret_int = 0; exerrval = status; sprintf(errmsg, "Error: failed to locate number of dist fact for %"ST_ZU"'th side set in file id %d", i, exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } } else { if ((status = nc_inq_dimlen (exoid, dimid, &ldum)) != NC_NOERR) { *ret_int = 0; exerrval = status; sprintf(errmsg, "Error: failed to get number of dist factors in %"ST_ZU"'th side set in file id %d", i, exoid); ex_err("ex_inquire",errmsg,exerrval); return (EX_FATAL); } } *ret_int += ldum; } } break; case EX_INQ_QA: /* returns the number of QA records */ if (ex_get_dimension(exoid, DIM_NUM_QA, "QA records", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_INFO: /* returns the number of information records */ if (ex_get_dimension(exoid, DIM_NUM_INFO, "info records", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_TIME: /* returns the number of time steps stored in the database */ if (ex_get_dimension(exoid, DIM_TIME, "time dimension", &ldum, &dimid, "ex_inquire") != NC_NOERR) return EX_FATAL; *ret_int = ldum; break; case EX_INQ_EB_PROP: /* returns the number of element block properties */ *ret_int = ex_get_num_props (exoid, EX_ELEM_BLOCK); break; case EX_INQ_NS_PROP: /* returns the number of node set properties */ *ret_int = ex_get_num_props (exoid, EX_NODE_SET); break; case EX_INQ_SS_PROP: /* returns the number of side set properties */ *ret_int = ex_get_num_props (exoid, EX_SIDE_SET); break; case EX_INQ_ELEM_MAP: /* returns the number of element maps */ if (ex_get_dimension(exoid, DIM_NUM_EM, "element maps", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_EM_PROP: /* returns the number of element map properties */ *ret_int = ex_get_num_props (exoid, EX_ELEM_MAP); break; case EX_INQ_NODE_MAP: /* returns the number of node maps */ if (ex_get_dimension(exoid, DIM_NUM_NM, "node maps", &ldum, &dimid, NULL) != NC_NOERR) *ret_int = 0; else *ret_int = ldum; break; case EX_INQ_NM_PROP: /* returns the number of node map properties */ *ret_int = ex_get_num_props (exoid, EX_NODE_MAP); break; case EX_INQ_EDGE: /* returns the number of edges (defined across all edge blocks). */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_EDGE, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_EDGE_BLK: /* returns the number of edge blocks. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_ED_BLK, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_EDGE_SETS: /* returns the number of edge sets. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_ES, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_ES_LEN: /* returns the length of the concatenated edge set edge list. */ ex_get_concat_set_len(exoid, ret_int,"edge",EX_EDGE_SET,DIM_NUM_ES,VAR_ES_STAT,"num_edge_es",0); break; case EX_INQ_ES_DF_LEN: /* returns the length of the concatenated edge set distribution factor list. */ ex_get_concat_set_len(exoid, ret_int,"edge",EX_EDGE_SET,DIM_NUM_ES,VAR_ES_STAT,"num_df_es",1); break; case EX_INQ_EDGE_PROP: /* returns the number of integer properties stored for each edge block. This includes the "ID" property. */ *ret_int = ex_get_num_props( exoid, EX_EDGE_BLOCK ); break; case EX_INQ_ES_PROP: /* returns the number of integer properties stored for each edge set.. This includes the "ID" property */ *ret_int = ex_get_num_props( exoid, EX_EDGE_SET ); break; case EX_INQ_FACE: /* returns the number of faces (defined across all face blocks). */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FACE, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_FACE_BLK: /* returns the number of face blocks. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FA_BLK, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_FACE_SETS: /* returns the number of face sets. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FS, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_FS_LEN: /* returns the length of the concatenated edge set edge list. */ ex_get_concat_set_len(exoid, ret_int,"face",EX_FACE_SET,DIM_NUM_FS,VAR_FS_STAT,"num_face_fs",0); break; case EX_INQ_FS_DF_LEN: /* returns the length of the concatenated edge set distribution factor list. */ ex_get_concat_set_len(exoid, ret_int,"face",EX_FACE_SET,DIM_NUM_FS,VAR_FS_STAT,"num_df_fs",1); break; case EX_INQ_FACE_PROP: /* returns the number of integer properties stored for each edge block. This includes the "ID" property. */ *ret_int = ex_get_num_props( exoid, EX_FACE_BLOCK ); break; case EX_INQ_FS_PROP: /* returns the number of integer properties stored for each edge set.. This includes the "ID" property */ *ret_int = ex_get_num_props( exoid, EX_FACE_SET ); break; case EX_INQ_ELEM_SETS: /* returns the number of element sets. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_ELS, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_ELS_LEN: /* returns the length of the concatenated element set element list. */ ex_get_concat_set_len(exoid, ret_int,"element",EX_ELEM_SET,DIM_NUM_ELS,VAR_ELS_STAT,"num_ele_els",0); break; case EX_INQ_ELS_DF_LEN: /* returns the length of the concatenated element set distribution factor list. */ ex_get_concat_set_len(exoid, ret_int,"element",EX_ELEM_SET,DIM_NUM_ELS,VAR_ELS_STAT,"num_df_els",1); break; case EX_INQ_ELS_PROP: /* returns the number of integer properties stored for each element set. */ *ret_int = ex_get_num_props( exoid, EX_ELEM_SET ); break; case EX_INQ_EDGE_MAP: /* returns the number of edge maps. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_EDM, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_FACE_MAP: /* returns the number of face maps. */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FAM, 1) != EX_NOERR) return EX_FATAL; break; case EX_INQ_COORD_FRAMES: /* return the number of coordinate frames */ if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_CFRAMES, 1) != EX_NOERR) return EX_FATAL; break; default: *ret_int = 0; exerrval = EX_FATAL; sprintf(errmsg, "Error: invalid inquiry %d", req_info); ex_err("ex_inquire",errmsg,exerrval); return(EX_FATAL); } return (EX_NOERR); }
int main(int argc, char **argv) { int ncid; size_t size_in; nc_type xtype; unsigned char data[DIM_LEN][BASE_SIZE], data_in[DIM_LEN][BASE_SIZE]; int i, j; printf("\n*** Testing netcdf-4 opaque type.\n"); for (i=0; i<DIM_LEN; i++) for (j=0; j<BASE_SIZE; j++) data[i][j] = 0; printf("*** testing scalar opaque variable..."); { int varid; char name_in[NC_MAX_NAME+1]; size_t nfields_in, base_size_in; nc_type base_nc_type_in, var_type; int class_in; char var_name[NC_MAX_NAME+1]; int nvars, natts, ndims, unlimdimid; /* Create a file that has an opaque variable. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR; if (nc_def_opaque(ncid, BASE_SIZE, TYPE_NAME, &xtype)) ERR; if (nc_inq_user_type(ncid, xtype, name_in, &base_size_in, &base_nc_type_in, &nfields_in, &class_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE || base_nc_type_in != 0 || nfields_in != 0 || class_in != NC_OPAQUE) ERR; if (nc_inq_opaque(ncid, xtype, name_in, &base_size_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE) ERR; if (nc_def_var(ncid, VAR_NAME, xtype, 0, NULL, &varid)) ERR; if (nc_put_var(ncid, varid, &data[0])) ERR; if (nc_close(ncid)) ERR; /* Check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, NULL, &natts)) ERR; if (ndims != 0 || strcmp(var_name, VAR_NAME) || natts != 0) ERR; if (nc_get_var(ncid, 0, &data_in[0])) ERR; for (j = 0; j < BASE_SIZE; j++) if (data_in[0][j] != data[0][j]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing opaque variable..."); { int dimid, varid, dimids[] = {0}; char name_in[NC_MAX_NAME+1]; nc_type base_nc_type_in, var_type; size_t nfields_in, base_size_in; int class_in; char var_name[NC_MAX_NAME+1]; int nvars, natts, ndims, unlimdimid, dimids_var[1]; /* Create a file that has an opaque variable. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR; if (nc_def_opaque(ncid, BASE_SIZE, TYPE_NAME, &xtype)) ERR; if (nc_inq_user_type(ncid, xtype, name_in, &base_size_in, &base_nc_type_in, &nfields_in, &class_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE || base_nc_type_in != 0 || nfields_in != 0 || class_in != NC_OPAQUE) ERR; if (nc_inq_opaque(ncid, xtype, name_in, &base_size_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE) ERR; if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR; if (nc_def_var(ncid, VAR_NAME, xtype, 1, dimids, &varid)) ERR; if (nc_put_var(ncid, varid, data)) ERR; if (nc_close(ncid)) ERR; /* Check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR; if (ndims != 1 || strcmp(var_name, VAR_NAME) || dimids_var[0] != dimids[0] || natts != 0) ERR; if (nc_get_var(ncid, 0, data_in)) ERR; for (i=0; i<DIM_LEN; i++) for (j=0; j<BASE_SIZE; j++) if (data_in[i][j] != data[i][j]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing *really* simple opaque attribute..."); { /* Create a file that has an opaque attribute. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_opaque(ncid, BASE_SIZE, TYPE_NAME, &xtype)) ERR; /* Write an att. */ if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, xtype, DIM_LEN, data)) ERR; if (nc_close(ncid)) ERR; /* Reopen. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing opaque attribute..."); { char name_in[NC_MAX_NAME+1]; nc_type base_nc_type_in; size_t base_size_in; size_t nfields_in; int class_in; /* Create a file that has an opaque attribute. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_opaque(ncid, BASE_SIZE, TYPE_NAME, &xtype)) ERR; /* Check it out. */ if (nc_inq_user_type(ncid, xtype, name_in, &base_size_in, &base_nc_type_in, &nfields_in, &class_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE || base_nc_type_in != 0 || nfields_in != 0 || class_in != NC_OPAQUE) ERR; if (nc_inq_opaque(ncid, xtype, name_in, &base_size_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE) ERR; /* Write an att. */ if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, xtype, DIM_LEN, data)) ERR; if (nc_close(ncid)) ERR; /* Reopen. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check it out. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &xtype, &size_in)) ERR; if (size_in != DIM_LEN) ERR; if (nc_inq_user_type(ncid, xtype, name_in, &base_size_in, &base_nc_type_in, &nfields_in, &class_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE || base_nc_type_in != 0 || nfields_in != 0 || class_in != NC_OPAQUE) ERR; if (nc_inq_opaque(ncid, xtype, name_in, &base_size_in)) ERR; if (strcmp(name_in, TYPE_NAME) || base_size_in != BASE_SIZE) ERR; if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR; for (i=0; i<DIM_LEN; i++) for (j=0; j<BASE_SIZE; j++) if (data_in[i][j] != data[i][j]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing 3 opaque types..."); { #define TYPE_SIZE1 20 #define NUM_TYPES 3 char name_in[NC_MAX_NAME+1]; nc_type base_nc_type_in; size_t nfields_in, base_size_in; nc_type otid[3]; int class_in; char type_name[NUM_TYPES][NC_MAX_NAME + 1] = {"o1", "o2", "o3"}; int nvars, natts, ndims, unlimdimid; int ntypes, typeids[NUM_TYPES]; int i; /* Create a file that has three opaque types. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR; for (i = 0; i < NUM_TYPES; i++) { if (nc_def_opaque(ncid, TYPE_SIZE1, type_name[i], &otid[i])) ERR; if (nc_inq_user_type(ncid, otid[i], name_in, &base_size_in, &base_nc_type_in, &nfields_in, &class_in)) ERR; if (strcmp(name_in, type_name[i]) || base_size_in != TYPE_SIZE1 || base_nc_type_in != 0 || nfields_in != 0 || class_in != NC_OPAQUE) ERR; if (nc_inq_opaque(ncid, otid[i], name_in, &base_size_in)) ERR; if (strcmp(name_in, type_name[i]) || base_size_in != TYPE_SIZE1) ERR; } if (nc_close(ncid)) ERR; /* Check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_typeids(ncid, &ntypes, typeids)) ERR; if (ntypes != NUM_TYPES) ERR; for (i = 0; i < NUM_TYPES; i++) { if (nc_inq_user_type(ncid, otid[i], name_in, &base_size_in, &base_nc_type_in, &nfields_in, &class_in)) ERR; if (strcmp(name_in, type_name[i]) || base_size_in != TYPE_SIZE1 || base_nc_type_in != 0 || nfields_in != 0 || class_in != NC_OPAQUE) ERR; if (nc_inq_opaque(ncid, otid[i], name_in, &base_size_in)) ERR; if (strcmp(name_in, type_name[i]) || base_size_in != TYPE_SIZE1) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
int main(int argc, char **argv) { printf("\n*** Testing 'Fileinfo attributes.\n"); { hid_t fileid; hid_t fcplid; hid_t scalar_spaceid; printf("*** creating test file using HDF5 directly %s...", HDFFILE); /* Create scalar dataspace */ if((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR; /* Set creation ordering for file, so we can revise its contents later */ if((fcplid = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR; if(H5Pset_link_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR; if(H5Pset_attr_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR; /* Create new file, using default properties */ if((fileid = H5Fcreate(HDFFILE, H5F_ACC_TRUNC, fcplid, H5P_DEFAULT)) < 0) ERR; /* Close file creation property list */ if(H5Pclose(fcplid) < 0) ERR; /* Add attributes to root group */ { hid_t scalar_spaceid = -1; hid_t attid = -1; /* Create scalar dataspace */ if((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR; /* Create attribute with native integer datatype on object */ if((attid = H5Acreate2(fileid, INT_ATT_NAME, H5T_NATIVE_INT, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR; if(H5Aclose(attid) < 0) ERR; /* Clean up objects created */ if(H5Sclose(scalar_spaceid) < 0) ERR; } /* Close rest */ if(H5Sclose(scalar_spaceid) < 0) ERR; if(H5Fclose(fileid) < 0) ERR; } { int root, grpid, varid, stat, natts, id; int data = 17; const char* sdata = "text"; char ncprops[8192]; size_t len; int dimid; nc_type xtype; char name[NC_MAX_NAME]; printf("\n*** creating netcdf-4 test file using netCDF %s...", NC4FILE); if(nc_create(NC4FILE,NC_WRITE|NC_CLOBBER|NC_NETCDF4,&root)!=0) ERR; /* Create global attribute */ if(nc_put_att_int(root,NC_GLOBAL,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR; /* Create global variable */ if(nc_def_var(root,INT_VAR_NAME,NC_INT,0,NULL,&varid)!=0) ERR; /* Create attribute on var */ if(nc_put_att_int(root,varid,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR; /* Create global subgroup */ if(nc_def_grp(root,GROUPNAME,&grpid)!=0) ERR; /* Create global attribute in the group */ if(nc_put_att_int(grpid,NC_GLOBAL,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR; /* Create _NCProperties as var attr and as subgroup attribute */ if(nc_put_att_text(grpid,NC_GLOBAL,NCPROPS,strlen(sdata),sdata)!=0) ERR; if(nc_put_att_text(root,varid,NCPROPS,strlen(sdata),sdata)!=0) ERR; /* Create var + dimension to cause e.g. dimscales to appear */ if(nc_def_dim(root,DIMNAME,(size_t)4,&dimid)!=0) ERR; if(nc_def_var(root,DIMNAME,NC_INT,1,&dimid,&varid)!=0) ERR; /* same name */ /* Close, then re-open */ if(nc_close(root)) ERR; if(nc_open(NC4FILE,NC_WRITE|NC_NETCDF4,&root)!=0) ERR; /* Is all invisible attributes actually invisible vis-a-vis nc_inq? */ if(nc_inq(root,NULL,NULL,&natts,NULL)!=0) ERR; if(natts != 1) ERR; /* Now, fiddle with the NCPROPS attribute */ /* Get its metadata */ if(nc_inq_att(root,NC_GLOBAL,NCPROPS,&xtype,&len)!=0) ERR; if(xtype != NC_CHAR) ERR; /* Read in two ways */ if(nc_get_att_text(root,NC_GLOBAL,NCPROPS,ncprops)!=0) ERR; if(strlen(ncprops) != len) ERR; /* Attempt to get attribute metadata piecemeal; some will fail */ id = -1; stat = nc_inq_attid(root,NC_GLOBAL,NCPROPS,&id); if(stat == NC_NOERR) ERR; stat = nc_inq_attname(root,NC_GLOBAL,id,name); if(stat == NC_NOERR) ERR; if(nc_inq_atttype(root,NC_GLOBAL,NCPROPS,&xtype)!=0) ERR; if(xtype != NC_CHAR) ERR; if(nc_inq_attlen(root,NC_GLOBAL,NCPROPS,&len)!=0) ERR; if(len != strlen(ncprops)) ERR; /*Overwrite _NCProperties root attribute; should fail */ stat = nc_put_att_text(root,NC_GLOBAL,NCPROPS,strlen(sdata),sdata); if(stat == NC_NOERR) ERR; /* Delete; should fail */ stat = nc_del_att(root,NC_GLOBAL,NCPROPS); if(stat != NC_ENOTATT) ERR; /* Ditto _SuperblockVersion */ /* Get its metadata */ if(nc_inq_att(root,NC_GLOBAL,SUPERBLOCKATT,&xtype,&len)!=0) ERR; if(xtype != NC_INT) ERR; if(len != 1) ERR; if(nc_get_att_int(root,NC_GLOBAL,SUPERBLOCKATT,&data)!=0) ERR; /* Attempt to get attribute metadata piecemeal */ stat = nc_inq_attid(root,NC_GLOBAL,SUPERBLOCKATT,&id); if(stat == NC_NOERR) ERR; stat = nc_inq_attname(root,NC_GLOBAL,id,name); if(stat == NC_NOERR) ERR; if(nc_inq_atttype(root,NC_GLOBAL,SUPERBLOCKATT,&xtype)!=0) ERR; if(xtype != NC_INT) ERR; if(nc_inq_attlen(root,NC_GLOBAL,SUPERBLOCKATT,&len)!=0) ERR; if(len != 1) ERR; /*Overwrite; should fail */ stat = nc_put_att_int(root,NC_GLOBAL,NCPROPS,NC_INT,1,&data); if(stat == NC_NOERR) ERR; /* Delete; should fail */ stat = nc_del_att(root,NC_GLOBAL,SUPERBLOCKATT); if(stat == NC_NOERR) ERR; /* Ditto _IsNetcdf4 */ /* Get its metadata */ if(nc_inq_att(root,NC_GLOBAL,ISNETCDF4ATT,&xtype,&len)!=0) ERR; if(xtype != NC_INT) ERR; if(len != 1) ERR; if(nc_get_att_int(root,NC_GLOBAL,ISNETCDF4ATT,&data)!=0) ERR; /* Attempt to get attribute metadata piecemeal */ stat = nc_inq_attid(root,NC_GLOBAL,ISNETCDF4ATT,&id); if(stat == NC_NOERR) ERR; stat = nc_inq_attname(root,NC_GLOBAL,id,name); if(stat == NC_NOERR) ERR; if(nc_inq_atttype(root,NC_GLOBAL,ISNETCDF4ATT,&xtype)!=0) ERR; if(xtype != NC_INT) ERR; if(nc_inq_attlen(root,NC_GLOBAL,ISNETCDF4ATT,&len)!=0) ERR; if(len != 1) ERR; /*Overwrite; should fail */ stat = nc_put_att_int(root,NC_GLOBAL,ISNETCDF4ATT,NC_INT,1,&data); if(stat == NC_NOERR) ERR; /* Delete; should fail */ stat = nc_del_att(root,NC_GLOBAL,ISNETCDF4ATT); if(stat == NC_NOERR) ERR; if(nc_close(root)!=0) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
int main(int argc, char **argv) { int ncid; int dimid, varid; char name_in[NC_MAX_NAME+1]; int class_in; size_t size_in; char *value_in; nc_type att_type; size_t att_len; int i; int var_dims[VAR4_RANK]; const char *desc_data[DIM4_LEN] = { "first string", "second string", "third string", "", "last string" }; const char *missing_val[ATT4_LEN] = {""}; char *strings_in[DIM4_LEN]; #ifdef USE_PARALLEL MPI_Init(&argc, &argv); #endif #ifdef EXTRA_TESTS printf("*** creating strings test file %s...", FILE4_NAME); if (nc_create(FILE4_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR; /* Declare a line dimension */ if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimid)) ERR; /* Declare a string variable */ var_dims[0] = dimid; if (nc_def_var(ncid, VAR4_NAME, NC_STRING, VAR4_RANK, var_dims, &varid)) ERR; /* Create and write a variable attribute of string type */ if (nc_put_att_string(ncid, varid, ATT4_NAME, ATT4_LEN, missing_val)) ERR; if (nc_enddef(ncid)) ERR; /* Store some data of string type */ if(nc_put_var(ncid, varid, desc_data)) ERR; /* Write the file. */ if (nc_close(ncid)) ERR; /* Check it out. */ if (nc_open(FILE4_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, VAR4_NAME, &varid)) ERR; if (nc_inq_att(ncid, varid, ATT4_NAME, &att_type, &att_len)) ERR; if (att_type != NC_STRING || att_len != ATT4_LEN) ERR; if (nc_get_att_string(ncid, varid, ATT4_NAME, strings_in)) ERR; if (strcmp(strings_in[0], *missing_val) != 0) ERR; /* string atts should be explicitly freed when done with them */ nc_free_string(ATT4_LEN, strings_in); if(nc_get_var_string(ncid, varid, strings_in)) ERR; for (i = 0; i < DIM4_LEN; i++) { if (strcmp(strings_in[i], desc_data[i]) != 0) ERR; } nc_free_string(DIM4_LEN, strings_in); /* Try reading strings in with typeless generic interface also */ if(nc_get_var(ncid, varid, strings_in)) ERR; for (i = 0; i < DIM4_LEN; i++) { if (strcmp(strings_in[i], desc_data[i]) != 0) ERR; } nc_free_string(DIM4_LEN, strings_in); /* Try reading strings in with typeless generic array interface also */ { size_t cor[VAR4_RANK], edg[VAR4_RANK]; cor[0] = 0; edg[0] = DIM4_LEN; if(nc_get_vara(ncid, varid, cor, edg, strings_in)) ERR; for (i = 0; i < DIM4_LEN; i++) { if (strcmp(strings_in[i], desc_data[i]) != 0) ERR; } nc_free_string(DIM4_LEN, strings_in); } if (nc_close(ncid)) ERR; SUMMARIZE_ERR; #endif /* EXTRA_TESTS */ FINAL_RESULTS; #ifdef USE_PARALLEL MPI_Finalize(); #endif }
int ex_open_int (const char *path, int mode, int *comp_ws, int *io_ws, float *version, int run_version) { int exoid; int status, stat_att, stat_dim; nc_type att_type = NC_NAT; size_t att_len = 0; int old_fill; int file_wordsize; int dim_str_name; int int64_status = 0; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* set error handling mode to no messages, non-fatal errors */ ex_opts(exoptval); /* call required to set ncopts first time through */ if (run_version != EX_API_VERS_NODOT && warning_output == 0) { int run_version_major = run_version / 100; int run_version_minor = run_version % 100; int lib_version_major = EX_API_VERS_NODOT / 100; int lib_version_minor = EX_API_VERS_NODOT % 100; fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus version %d.%02d,\n but was linked with exodus library version %d.%02d\n This is probably an error in the build process of this code.\n", run_version_major, run_version_minor, lib_version_major, lib_version_minor); warning_output = 1; } if ((mode & EX_READ) && (mode & EX_WRITE)) { exerrval = EX_BADFILEMODE; sprintf(errmsg,"Error: Cannot specify both EX_READ and EX_WRITE"); ex_err("ex_open",errmsg,exerrval); return (EX_FATAL); } /* The EX_READ mode is the default if EX_WRITE is not specified... */ if (!(mode & EX_WRITE)) { /* READ ONLY */ #if defined(__LIBCATAMOUNT__) if ((status = nc_open (path, NC_NOWRITE, &exoid)) != NC_NOERR) #else if ((status = nc_open (path, NC_NOWRITE|NC_SHARE, &exoid)) != NC_NOERR) #endif { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ if (status == 0) { exerrval = EX_FATAL; } else { /* It is possible that the user is trying to open a netcdf4 file, but the netcdf4 capabilities aren't available in the netcdf linked to this library. Note that we can't just use a compile-time define since we could be using a shareable netcdf library, so the netcdf4 capabilities aren't known until runtime... Netcdf-4.X does not (yet?) have a function that can be queried to determine whether the library being used was compiled with --enable-netcdf4, so that isn't very helpful.. At this time, query the beginning of the file and see if it is an HDF-5 file and if it is assume that the open failure is due to the netcdf library not enabling netcdf4 features... */ int type = 0; ex_check_file_type(path, &type); if (type == 5) { /* This is an hdf5 (netcdf4) file. Since the nc_open failed, the assumption is that the netcdf doesn't have netcdf4 capabilities enabled. Tell the user... */ fprintf(stderr, "EXODUS: Error: Attempting to open the netcdf-4 file:\n\t'%s'\n\twith a netcdf library that does not support netcdf-4\n", path); } exerrval = status; } sprintf(errmsg,"Error: failed to open %s read only",path); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } } else /* (mode & EX_WRITE) READ/WRITE */ { #if defined(__LIBCATAMOUNT__) if ((status = nc_open (path, NC_WRITE, &exoid)) != NC_NOERR) #else if ((status = nc_open (path, NC_WRITE|NC_SHARE, &exoid)) != NC_NOERR) #endif { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ if (status == 0) exerrval = EX_FATAL; else exerrval = status; sprintf(errmsg,"Error: failed to open %s write only",path); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } /* turn off automatic filling of netCDF variables */ if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to set nofill mode in file id %d", exoid); ex_err("ex_open", errmsg, exerrval); return (EX_FATAL); } stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len); stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name); if(stat_att != NC_NOERR || stat_dim != NC_NOERR) { nc_redef(exoid); if (stat_att != NC_NOERR) { int max_so_far = 32; nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far); } /* If the DIM_STR_NAME variable does not exist on the database, we need to add it now. */ if(stat_dim != NC_NOERR) { /* Not found; set to default value of 32+1. */ int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length; nc_def_dim(exoid, DIM_STR_NAME, max_name+1, &dim_str_name); } nc_enddef (exoid); } } /* determine version of EXODUS II file, and the word size of * floating point and integer values stored in the file */ if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) { exerrval = status; sprintf(errmsg,"Error: failed to get database version for file id: %d", exoid); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } /* check ExodusII file version - old version 1.x files are not supported */ if (*version < 2.0) { exerrval = EX_FATAL; sprintf(errmsg,"Error: Unsupported file version %.2f in file id: %d", *version, exoid); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } if (nc_get_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR) { /* try old (prior to db version 2.02) attribute name */ if (nc_get_att_int (exoid,NC_GLOBAL,ATT_FLT_WORDSIZE_BLANK,&file_wordsize) != NC_NOERR) { exerrval = EX_FATAL; sprintf(errmsg,"Error: failed to get file wordsize from file id: %d", exoid); ex_err("ex_open",errmsg,exerrval); return(exerrval); } } /* See if int64 status attribute exists and if so, what data is stored as int64 * Older files don't have the attribute, so it is not an error if it is missing */ if (nc_get_att_int (exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) { int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */ } /* Merge in API int64 status flags as specified by caller of function... */ int64_status |= (mode & EX_ALL_INT64_API); /* initialize floating point and integer size conversion. */ if (ex_conv_ini( exoid, comp_ws, io_ws, file_wordsize, int64_status ) != EX_NOERR ) { exerrval = EX_FATAL; sprintf(errmsg, "Error: failed to initialize conversion routines in file id %d", exoid); ex_err("ex_open", errmsg, exerrval); return (EX_FATAL); } return (exoid); }
int main(int argc, char **argv) { int ncid, dimid, fvarid, dvarid; float fvals[NVALS], fvals_in[NVALS]; double dvals[NVALS], dvals_in[NVALS]; float fnan = NC_FNAN;//(NC_INFINITE-NC_INFINITE);//0.f/0.f; double dnan = NC_DNAN;//(NC_INFINITE-NC_INFINITE);//0.0/0.0; float fpinf = NC_FPINF;//NC_INFINITE;//1.0f/0.0f; float fninf = -fpinf; double dpinf = NC_DPINF;//NC_INFINITE;//1.0/0.0; double dninf = -dpinf; nc_type att_type; size_t att_len; float att_fvals[NVALS]; double att_dvals[NVALS]; printf("\n*** Testing NaN\n"); printf("*** creating NaN test file %s...", FILE8_NAME); if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR; if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, &dimid, &fvarid)) ERR; if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, &dimid, &dvarid)) ERR; fvals[0] = fninf; fvals[1] = fnan; fvals[2] = fpinf; dvals[0] = dninf; dvals[1] = dnan; dvals[2] = dpinf; /* Create float and double attributes */ if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR; if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR; if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR; if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR; if (nc_enddef(ncid)) ERR; /* Write float and double data */ if (nc_put_var_float(ncid, fvarid, fvals)) ERR; if (nc_put_var_double(ncid, dvarid, dvals)) ERR; if (nc_close(ncid)) ERR; /* Check it out. */ /* Reopen the file. */ if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR; if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR; /* Check the values of the float attributes */ if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR; if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR; if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR; if (!isnan(att_fvals[0])) ERR; if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR; if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR; if (!isnan(att_fvals[1])) ERR; if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR; /* Check the values of double attributes */ if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR; if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR; if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR; if (!isnan(att_dvals[0])) ERR; if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR; if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR; if (!isnan(att_dvals[1])) ERR; if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR; /* Check values of float data */ if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR; if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR; if (!isnan(fvals_in[1])) ERR; if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR; /* Check values of double data */ if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR; if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR; if (!isnan(dvals_in[1])) ERR; if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR; if (nc_close(ncid)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; }
int harp_import_global_attributes_netcdf(const char *filename, double *datetime_start, double *datetime_stop, long dimension[], char **source_product) { char *attr_source_product = NULL; harp_scalar attr_datetime_start; harp_scalar attr_datetime_stop; harp_data_type attr_data_type; long attr_dimension[HARP_NUM_DIM_TYPES]; int result; int ncid; int i; if (datetime_start == NULL && datetime_stop == NULL) { return 0; } if (filename == NULL) { harp_set_error(HARP_ERROR_INVALID_ARGUMENT, "filename is NULL (%s:%u)", __FILE__, __LINE__); return -1; } result = nc_open(filename, 0, &ncid); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } if (verify_product(ncid) != 0) { nc_close(ncid); return -1; } if (datetime_start != NULL) { if (nc_inq_att(ncid, NC_GLOBAL, "datetime_start", NULL, NULL) == NC_NOERR) { if (read_numeric_attribute(ncid, NC_GLOBAL, "datetime_start", &attr_data_type, &attr_datetime_start) != 0) { nc_close(ncid); return -1; } if (attr_data_type != harp_type_double) { harp_set_error(HARP_ERROR_IMPORT, "attribute 'datetime_start' has invalid type"); nc_close(ncid); return -1; } } else { attr_datetime_start.double_data = harp_mininf(); } } if (datetime_stop != NULL) { if (nc_inq_att(ncid, NC_GLOBAL, "datetime_stop", NULL, NULL) == NC_NOERR) { if (read_numeric_attribute(ncid, NC_GLOBAL, "datetime_stop", &attr_data_type, &attr_datetime_stop) != 0) { nc_close(ncid); return -1; } if (attr_data_type != harp_type_double) { harp_set_error(HARP_ERROR_IMPORT, "attribute 'datetime_stop' has invalid type"); nc_close(ncid); return -1; } } else { attr_datetime_stop.double_data = harp_plusinf(); } } if (source_product != NULL) { if (read_string_attribute(ncid, NC_GLOBAL, "source_product", &attr_source_product) != 0) { nc_close(ncid); return -1; } } if (dimension != NULL) { int num_dimensions; int num_variables; int num_attributes; int unlim_dim; int result; for (i = 0; i < HARP_NUM_DIM_TYPES; i++) { attr_dimension[i] = -1; } result = nc_inq(ncid, &num_dimensions, &num_variables, &num_attributes, &unlim_dim); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } for (i = 0; i < num_dimensions; i++) { netcdf_dimension_type netcdf_dim_type; harp_dimension_type harp_dim_type; char name[NC_MAX_NAME + 1]; size_t length; result = nc_inq_dim(ncid, i, name, &length); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } if (parse_dimension_type(name, &netcdf_dim_type) != 0) { return -1; } if (netcdf_dim_type != netcdf_dimension_independent && netcdf_dim_type != netcdf_dimension_string) { if (get_harp_dimension_type(netcdf_dim_type, &harp_dim_type) != 0) { return -1; } attr_dimension[harp_dim_type] = length; } } } result = nc_close(ncid); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); free(attr_source_product); return -1; } if (datetime_start != NULL) { *datetime_start = attr_datetime_start.double_data; } if (datetime_stop != NULL) { *datetime_stop = attr_datetime_stop.double_data; } if (source_product != NULL) { *source_product = attr_source_product; } if (dimension != NULL) { for (i = 0; i < HARP_NUM_DIM_TYPES; i++) { dimension[i] = attr_dimension[i]; } } return 0; }
int dumpmetadata(int ncid, NChdr** hdrp) { int stat,i,j,k; NChdr* hdr = (NChdr*)calloc(1,sizeof(NChdr)); MEMCHECK(hdr,NC_ENOMEM); hdr->ncid = ncid; hdr->content = ncbytesnew(); if(hdrp) *hdrp = hdr; stat = nc_inq(hdr->ncid, &hdr->ndims, &hdr->nvars, &hdr->ngatts, &hdr->unlimid); CHECK(stat); if(ncdap3debug > 0) { fprintf(stdout,"ncid=%d ngatts=%d ndims=%d nvars=%d unlimid=%d\n", hdr->ncid,hdr->ngatts,hdr->ndims,hdr->nvars,hdr->unlimid); } hdr->gatts = (NCattribute*)calloc(1,hdr->ngatts*sizeof(NCattribute)); MEMCHECK(hdr->gatts,NC_ENOMEM); if(hdr->ngatts > 0) fprintf(stdout,"global attributes:\n"); for(i=0;i<hdr->ngatts;i++) { NCattribute* att = &hdr->gatts[i]; char attname[NC_MAX_NAME]; nc_type nctype; size_t typesize; size_t nvalues; stat = nc_inq_attname(hdr->ncid,NC_GLOBAL,i,attname); CHECK(stat); att->name = nulldup(attname); stat = nc_inq_att(hdr->ncid,NC_GLOBAL,att->name,&nctype,&nvalues); CHECK(stat); att->etype = nctypetodap(nctype); typesize = nctypesizeof(att->etype); fprintf(stdout,"\t[%d]: name=%s type=%s values(%lu)=", i,att->name,nctypetostring(octypetonc(att->etype)), (unsigned long)nvalues); if(nctype == NC_CHAR) { size_t len = typesize*nvalues; char* values = (char*)malloc(len+1);/* for null terminate*/ MEMCHECK(values,NC_ENOMEM); stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values); CHECK(stat); values[len] = '\0'; fprintf(stdout," '%s'",values); } else { size_t len = typesize*nvalues; char* values = (char*)malloc(len); MEMCHECK(values,NC_ENOMEM); stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values); CHECK(stat); for(k=0;k<nvalues;k++) { fprintf(stdout," "); dumpdata1(octypetonc(att->etype),k,values); } } fprintf(stdout,"\n"); } hdr->dims = (Dim*)malloc(hdr->ndims*sizeof(Dim)); MEMCHECK(hdr->dims,NC_ENOMEM); for(i=0;i<hdr->ndims;i++) { hdr->dims[i].dimid = i; stat = nc_inq_dim(hdr->ncid, hdr->dims[i].dimid, hdr->dims[i].name, &hdr->dims[i].size); CHECK(stat); fprintf(stdout,"dim[%d]: name=%s size=%lu\n", i,hdr->dims[i].name,(unsigned long)hdr->dims[i].size); } hdr->vars = (Var*)malloc(hdr->nvars*sizeof(Var)); MEMCHECK(hdr->vars,NC_ENOMEM); for(i=0;i<hdr->nvars;i++) { Var* var = &hdr->vars[i]; nc_type nctype; var->varid = i; stat = nc_inq_var(hdr->ncid, var->varid, var->name, &nctype, &var->ndims, var->dimids, &var->natts); CHECK(stat); var->nctype = (nctype); fprintf(stdout,"var[%d]: name=%s type=%s |dims|=%d", i, var->name, nctypetostring(var->nctype), var->ndims); fprintf(stdout," dims={"); for(j=0;j<var->ndims;j++) { fprintf(stdout," %d",var->dimids[j]); } fprintf(stdout,"}\n"); var->atts = (NCattribute*)malloc(var->natts*sizeof(NCattribute)); MEMCHECK(var->atts,NC_ENOMEM); for(j=0;j<var->natts;j++) { NCattribute* att = &var->atts[j]; char attname[NC_MAX_NAME]; size_t typesize; char* values; nc_type nctype; size_t nvalues; stat = nc_inq_attname(hdr->ncid,var->varid,j,attname); CHECK(stat); att->name = nulldup(attname); stat = nc_inq_att(hdr->ncid,var->varid,att->name,&nctype,&nvalues); CHECK(stat); att->etype = nctypetodap(nctype); typesize = nctypesizeof(att->etype); values = (char*)malloc(typesize*nvalues); MEMCHECK(values,NC_ENOMEM); stat = nc_get_att(hdr->ncid,var->varid,att->name,values); CHECK(stat); fprintf(stdout,"\tattr[%d]: name=%s type=%s values(%lu)=", j,att->name,nctypetostring(octypetonc(att->etype)),(unsigned long)nvalues); for(k=0;k<nvalues;k++) { fprintf(stdout," "); dumpdata1(octypetonc(att->etype),k,values); } fprintf(stdout,"\n"); } } fflush(stdout); return NC_NOERR; }
int ex_copy (int in_exoid, int out_exoid) { int status; int ndims; /* number of dimensions */ int nvars; /* number of variables */ int ngatts; /* number of global attributes */ int recdimid; /* id of unlimited dimension */ int dimid; /* dimension id */ int dim_out_id; /* dimension id */ int varid; /* variable id */ int var_out_id; /* variable id */ struct ncvar var; /* variable */ struct ncatt att; /* attribute */ nc_type att_type = NC_NAT; size_t att_len = 0; size_t i; size_t numrec; size_t dim_sz; char dim_nm[NC_MAX_NAME]; int in_large, out_large; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* * Get exodus_large_model setting on both input and output * databases so know how to handle coordinates. */ in_large = ex_large_model(in_exoid); out_large = ex_large_model(out_exoid); /* * get number of dimensions, number of variables, number of global * atts, and dimension id of unlimited dimension, if any */ (void)nc_inq(in_exoid, &ndims, &nvars, &ngatts, &recdimid); (void)nc_inq_dimlen(in_exoid, recdimid, &numrec); /* put output file into define mode */ (void)nc_redef(out_exoid); /* copy global attributes */ for (i = 0; i < (size_t)ngatts; i++) { (void)nc_inq_attname(in_exoid, NC_GLOBAL, i, att.name); /* if attribute exists in output file, don't overwrite it; compute * word size, I/O word size etc. are global attributes stored when * file is created with ex_create; we don't want to overwrite those */ if ((status = nc_inq_att(out_exoid, NC_GLOBAL, att.name, &att.type, &att.len)) != NC_NOERR) { /* The "last_written_time" attribute is a special attribute used by the Sierra IO system to determine whether a timestep has been fully written to the database in order to try to detect a database crash that happens in the middle of a database output step. Don't want to copy that attribute. */ if (strcmp(att.name,"last_written_time") != 0) { /* attribute doesn't exist in new file so OK to create it */ nc_copy_att(in_exoid,NC_GLOBAL,att.name,out_exoid,NC_GLOBAL); } } } /* copy dimensions */ /* Get the dimension sizes and names */ for(dimid = 0; dimid < ndims; dimid++){ (void)nc_inq_dim(in_exoid,dimid,dim_nm,&dim_sz); /* If the dimension isn't one we specifically don't want * to copy (ie, number of QA or INFO records) and it * hasn't been defined, copy it */ if ( ( strcmp(dim_nm,DIM_NUM_QA) != 0) && ( strcmp(dim_nm,DIM_NUM_INFO) != 0) && ( strcmp(dim_nm,DIM_NUM_NOD_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_EDG_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_FAC_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_ELE_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_NSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_ESET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_FSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_SSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_ELSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_GLO_VAR) != 0) ) { /* See if the dimension has already been defined */ status = nc_inq_dimid(out_exoid, dim_nm, &dim_out_id); if(status != NC_NOERR) { if(dimid != recdimid) { status = nc_def_dim(out_exoid, dim_nm, dim_sz, &dim_out_id); } else { status = nc_def_dim(out_exoid, dim_nm, NC_UNLIMITED, &dim_out_id); } /* end else */ if (status != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to define %s dimension in file id %d", dim_nm, out_exoid); ex_err("ex_copy",errmsg,exerrval); return (EX_FATAL); } } /* end if */ } /* end if */ } /* end loop over dim */ /* DIM_STR_NAME is a newly added dimension required by current API. * If it doesn't exist on the source database, we need to add it to * the target... */ status = nc_inq_dimid(in_exoid, DIM_STR_NAME, &dim_out_id); if (status != NC_NOERR) { /* Not found; set to default value of 32+1. */ if ((status = nc_def_dim(out_exoid, DIM_STR_NAME, 33, &dim_out_id)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to define string name dimension in file id %d", out_exoid); ex_err("ex_copy",errmsg,exerrval); return (EX_FATAL); } } status = nc_inq_att(in_exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len); if (status != NC_NOERR) { int max_so_far = 32; nc_put_att_int(out_exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far); } /* copy variable definitions and variable attributes */ for (varid = 0; varid < nvars; varid++) { (void)nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts); /* we don't want to copy some variables because there is not a * simple way to add to them; * QA records, info records and all results variables (nodal * element, and global results) are examples */ if ( ( strcmp(var.name,VAR_QA_TITLE) != 0) && ( strcmp(var.name,VAR_INFO) != 0) && ( strcmp(var.name,VAR_EBLK_TAB) != 0) && ( strcmp(var.name,VAR_FBLK_TAB) != 0) && ( strcmp(var.name,VAR_ELEM_TAB) != 0) && ( strcmp(var.name,VAR_ELSET_TAB) != 0) && ( strcmp(var.name,VAR_SSET_TAB) != 0) && ( strcmp(var.name,VAR_FSET_TAB) != 0) && ( strcmp(var.name,VAR_ESET_TAB) != 0) && ( strcmp(var.name,VAR_NSET_TAB) != 0) && ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0) && ( strcmp(var.name,VAR_GLO_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)&& ( strncmp(var.name,"vals_elset_var", 14) != 0) && ( strncmp(var.name,"vals_sset_var", 13) != 0) && ( strncmp(var.name,"vals_fset_var", 13) != 0) && ( strncmp(var.name,"vals_eset_var", 13) != 0) && ( strncmp(var.name,"vals_nset_var", 13) != 0) && ( strncmp(var.name,"vals_nod_var", 12) != 0) && ( strncmp(var.name,"vals_edge_var", 13) != 0) && ( strncmp(var.name,"vals_face_var", 13) != 0) && ( strncmp(var.name,"vals_elem_var", 13) != 0) ) { if (strncmp(var.name,VAR_COORD,5) == 0) { var_out_id = cpy_coord_def (in_exoid, out_exoid, recdimid, var.name, in_large, out_large); } else { var_out_id = cpy_var_def (in_exoid, out_exoid, recdimid, var.name); } /* copy the variable's attributes */ (void) cpy_att (in_exoid, out_exoid, varid, var_out_id); } } /* take the output file out of define mode */ if ((exerrval=nc_enddef (out_exoid)) != NC_NOERR) { sprintf(errmsg, "Error: failed to complete definition in file id %d", out_exoid); ex_err("ex_copy",errmsg,exerrval); return (EX_FATAL); } /* output variable data */ for (varid = 0; varid < nvars; varid++) { (void)nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts); /* we don't want to copy some variable values; * QA records and info records shouldn't be copied because there * isn't an easy way to add to them; * the time value array ("time_whole") and any results variables * (nodal, elemental, or global) shouldn't be copied */ if ( ( strcmp(var.name,VAR_QA_TITLE) != 0) && ( strcmp(var.name,VAR_INFO) != 0) && ( strcmp(var.name,VAR_EBLK_TAB) != 0) && ( strcmp(var.name,VAR_FBLK_TAB) != 0) && ( strcmp(var.name,VAR_ELEM_TAB) != 0) && ( strcmp(var.name,VAR_ELSET_TAB) != 0) && ( strcmp(var.name,VAR_SSET_TAB) != 0) && ( strcmp(var.name,VAR_FSET_TAB) != 0) && ( strcmp(var.name,VAR_ESET_TAB) != 0) && ( strcmp(var.name,VAR_NSET_TAB) != 0) && ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0) && ( strcmp(var.name,VAR_GLO_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0) && ( strncmp(var.name,"vals_elset_var", 14) != 0)&& ( strncmp(var.name,"vals_sset_var", 13) != 0)&& ( strncmp(var.name,"vals_fset_var", 13) != 0)&& ( strncmp(var.name,"vals_eset_var", 13) != 0)&& ( strncmp(var.name,"vals_nset_var", 13) != 0)&& ( strncmp(var.name,"vals_nod_var", 12) != 0) && ( strncmp(var.name,"vals_edge_var",13) != 0) && ( strncmp(var.name,"vals_face_var",13) != 0) && ( strncmp(var.name,"vals_elem_var",13) != 0) && ( strcmp(var.name,VAR_WHOLE_TIME) != 0) ) { if (strncmp(var.name,VAR_COORD,5) == 0) { (void) cpy_coord_val (in_exoid, out_exoid, var.name, in_large, out_large); } else { (void) cpy_var_val (in_exoid, out_exoid, var.name); } } } /* ensure internal data structures are updated */ /* if number of blocks > 0 */ update_internal_structs( out_exoid, EX_INQ_EDGE_BLK, ex_get_counter_list(EX_EDGE_BLOCK)); update_internal_structs( out_exoid, EX_INQ_FACE_BLK, ex_get_counter_list(EX_FACE_BLOCK)); update_internal_structs( out_exoid, EX_INQ_ELEM_BLK, ex_get_counter_list(EX_ELEM_BLOCK)); /* if number of sets > 0 */ update_internal_structs( out_exoid, EX_INQ_NODE_SETS, ex_get_counter_list(EX_NODE_SET)); update_internal_structs( out_exoid, EX_INQ_EDGE_SETS, ex_get_counter_list(EX_EDGE_SET)); update_internal_structs( out_exoid, EX_INQ_FACE_SETS, ex_get_counter_list(EX_FACE_SET)); update_internal_structs( out_exoid, EX_INQ_SIDE_SETS, ex_get_counter_list(EX_SIDE_SET)); update_internal_structs( out_exoid, EX_INQ_ELEM_SETS, ex_get_counter_list(EX_ELEM_SET)); /* if number of maps > 0 */ update_internal_structs( out_exoid, EX_INQ_NODE_MAP, ex_get_counter_list(EX_NODE_MAP)); update_internal_structs( out_exoid, EX_INQ_EDGE_MAP, ex_get_counter_list(EX_EDGE_MAP)); update_internal_structs( out_exoid, EX_INQ_FACE_MAP, ex_get_counter_list(EX_FACE_MAP)); update_internal_structs( out_exoid, EX_INQ_ELEM_MAP, ex_get_counter_list(EX_ELEM_MAP)); return(EX_NOERR); }