/*+++++++++++++++++++++++++ .IDENTifer SCIA_RD_NC_H2O_META .PURPOSE read header from IMLM-H2O product in netCDF-4 (ADAGUC standard) .INPUT/OUTPUT call as SCIA_RD_NC_H2O_META( ncid, &hdr ); input: int ncid : netCDF file ID output: struct imlm_hdr *hdr : IMLM header .RETURNS Nothing .COMMENTS static function -------------------------*/ void SCIA_RD_NC_H2O_META( int ncid, struct imlm_hdr *hdr ) { char cbuff[SHORT_STRING_LENGTH]; int retval; int var_id; /* * Product meta-data */ if ( (retval = nc_inq_varid( ncid, "product", &var_id )) != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "input_products", hdr->l1b_product ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "creation_date", hdr->creation_date ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "validity_start", hdr->validity_start ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "validity_stop", hdr->validity_stop ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "software_version", hdr->software_version ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); /* * Custom meta-data */ if ( (retval = nc_inq_varid( ncid, "custom", &var_id )) != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_ushort( ncid, var_id, "number_input_products", &hdr->numProd ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_uint( ncid, var_id, "abs_orbit", hdr->orbit ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "pixelmask_version", hdr->pixelmask_version ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "cloudmask_version", hdr->cloudmask_version ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_uchar( ncid, var_id, "Sciamachy_channel", &hdr->scia_channel ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "window_pixels", cbuff ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); (void) sscanf( cbuff, "%hu %*c %hu", hdr->window_pixel, hdr->window_pixel+1 ); retval = nc_get_att_text( ncid, var_id, "window_wave", cbuff ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); (void) sscanf( cbuff, "%f %*c %f", hdr->window_wave, hdr->window_wave+1 ); }
int main(int argc, char **argv) { (void) signal(SIGFPE, SIG_IGN); printf("\n*** Testing netcdf-4 attribute functions.\n"); printf("*** testing really simple global atts..."); #define NUM_SIMPLE_ATTS 9 { int ncid; char name[NUM_SIMPLE_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf", "Gd", "G7", "G8", "G9"}; char name_in[NC_MAX_NAME]; int j; /* Create a file with some global atts. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR; for (j = 0; j < NUM_SIMPLE_ATTS; j++) if (nc_put_att_int(ncid, NC_GLOBAL, name[j], NC_INT, 0, NULL)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check the order. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; for (j = 0; j < NUM_SIMPLE_ATTS; j++) { if (nc_inq_attname(ncid, NC_GLOBAL, j, name_in)) ERR; if (strcmp(name_in, name[j])) ERR; } /* Close up shop. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple global atts..."); { int ncid; nc_type att_type; size_t att_len; int i; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT}; unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT}; unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL}; long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64}; /* This won't work, because classic files can't create these types. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out) != NC_ESTRICTNC3) ERR; if (nc_close(ncid)) ERR; /* Create a file with a global attribute of each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* Check text. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); /* Check numeric values. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != uchar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (ushort_in[i] != ushort_out[i]) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint_in[i] != uint_out[i]) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int64_in[i] != int64_out[i]) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint64_in[i] != uint64_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute data type conversions..."); { int ncid; int i; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN]; unsigned int uint_in[ATT_LEN]; unsigned long long uint64_in[ATT_LEN]; long long int64_in[ATT_LEN]; /* Reopen the file and try different type conversions. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* No text conversions are allowed, and people who try them shold * be locked up, away from decent folk! */ if (nc_get_att_short(ncid, NC_GLOBAL, ATT_TEXT_NAME, short_in) != NC_ECHAR) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_TEXT_NAME, int_in) != NC_ECHAR) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_TEXT_NAME, float_in) != NC_ECHAR) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_TEXT_NAME, double_in) != NC_ECHAR) ERR; /* if (nc_get_att_ubyte(ncid, NC_GLOBAL, ATT_TEXT_NAME, uchar_in) != NC_ECHAR) ERR;*/ if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_TEXT_NAME, ushort_in) != NC_ECHAR) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint_in) != NC_ECHAR) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_TEXT_NAME, int64_in) != NC_ECHAR) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint64_in) != NC_ECHAR) ERR; /* Read all atts (except text) as double. */ if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SCHAR_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != schar_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SHORT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != short_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_INT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != int_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_FLOAT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != float_out[i]) ERR; /* Read all atts (except text) as float. */ if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SCHAR_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != schar_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SHORT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != short_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_INT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != (float)int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != (float)double_out[i]) ERR; /* Read all atts (except text) as int. */ if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SCHAR_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != schar_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SHORT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_FLOAT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != (int)float_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != (int)double_out[i]) ERR; /* Read all atts (except text) as short. */ if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SCHAR_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != schar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)int_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)float_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)double_out[i]) ERR; /* Read all atts (except text) as schar. Some range errors will * result converting to schar. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)short_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)int_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)float_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)double_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple variable atts..."); { int ncid, varid, dimids[2]; nc_type att_type; size_t att_len; int i, v; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; /* Create a file with two vars, attaching to each an attribute of * each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR; if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR; if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR; if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; for (v=0; v<2; v++) { if (nc_inq_att(ncid, v, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, v, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); if (nc_get_att_schar(ncid, v, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_short(ncid, v, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, v, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, v, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, v, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing zero-length attributes..."); { int ncid; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ /* Create a file with a global attribute of each type of zero length. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR; /* if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/ if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR; if (nc_close(ncid)) ERR; } /* Make sure we can read all these zero-length atts. */ { int ncid; signed char schar_in[ATT_LEN]; short short_in[ATT_LEN]; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN]; float float_in[ATT_LEN]; double double_in[ATT_LEN]; size_t len; nc_type xtype; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_CHAR) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, &xtype, &len)) ERR; if (len || xtype != NC_BYTE) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_SHORT) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_INT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_INT) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_FLOAT) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, &xtype, &len)) ERR; if (len || xtype != NC_DOUBLE) ERR; /* Conversions no longer result in range errors, since there's no data. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing zero-length attributes and redef...(this test skipped for HDF5-1.8.0 beta1"); { int ncid; signed char schar_in[ATT_LEN]; short short_in[ATT_LEN]; int int_in[ATT_LEN]; float float_in[ATT_LEN]; double double_in[ATT_LEN]; /* Create a file with a global attribute of each type of zero length. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR; /* if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/ if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR; if (nc_close(ncid)) ERR; /* Make sure we can read all these zero-length atts added during a * redef. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; /* Conversions no longer result in range errors, since there's no data. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute deletes and renames..."); { int ncid, varid, dimids[2]; nc_type att_type; size_t att_len; char *speech_in; char name_in[NC_MAX_NAME + 1]; int attid_in, natts_in; int int_out[ATT_LEN] = {-100000, 128, 100000}; /* Create a file with a global attribute. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_close(ncid)) ERR; /* Rename it. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT_TEXT_NAME, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR; if (strcmp(name_in, ATT_TEXT_NAME)) ERR; if (nc_rename_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ATT_TEXT_NAME2)) ERR; if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR; if (strcmp(name_in, ATT_TEXT_NAME2)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME2, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in) != NC_ENOTATT) ERR; if (nc_close(ncid)) ERR; /* Now delete the att. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_del_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2)) ERR; if (nc_close(ncid)) ERR; /* Now create a file with a variable, which has an att. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and delete it. Make sure it's gone. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and readd the attribute. Enddef and redef, * and delete it, then check to make sure it's gone. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR; if (nc_inq_varnatts(ncid, 0, &natts_in)) ERR; if (natts_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute create order..."); #define ATT0 "Maturin" #define ATT1 "Aubery" { int ncid, varid, dimids[2]; int attid_in; const int number = 42; /* Create a file with several global attributes. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT0, NC_INT, 1, &number)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT1, NC_INT, 1, &number)) ERR; if (nc_close(ncid)) ERR; /* Open it and check the order. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT0, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT1, &attid_in)) ERR; if (attid_in != 1) ERR; if (nc_close(ncid)) ERR; /* Now create a file with a variable, which has two atts. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, ATT0, NC_INT, 1, &number)) ERR; if (nc_put_att_int(ncid, varid, ATT1, NC_INT, 1, &number)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check the order of the attributes on the var. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, 0, ATT0, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attid(ncid, 0, ATT1, &attid_in)) ERR; if (attid_in != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute ordering some more..."); #define VAR_NAME "i" #define A1_NAME "i" #define A2_NAME "f" #define A3_NAME "d" #define A1_LEN 3 #define A2_LEN 4 #define A3_LEN 5 { int ncid; int varid, natts, nvars; double dvalue[] = {999.99, 999.99, 999.99, 999.99, 999.99}; int varids[1]; char name_in[NC_MAX_NAME + 1]; /* Create a file with one var, and attach three atts to it. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid)) ERR; if (nc_put_att_double(ncid, varid, A1_NAME, NC_INT, A1_LEN, dvalue)) ERR; if (nc_put_att_double(ncid, varid, A2_NAME, NC_INT, A2_LEN, dvalue)) ERR; if (nc_put_att_double(ncid, varid, A3_NAME, NC_INT, A3_LEN, dvalue)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars, varids)) ERR; if (nvars != 1 || varids[0] != 0) ERR; if (nc_inq_varnatts(ncid, 0, &natts)) ERR; if (natts != 3) ERR; if (nc_inq_attname(ncid, 0, 0, name_in)) ERR; if (strcmp(name_in, A1_NAME)) ERR; if (nc_inq_attname(ncid, 0, 1, name_in)) ERR; if (strcmp(name_in, A2_NAME)) ERR; if (nc_inq_attname(ncid, 0, 2, name_in)) ERR; if (strcmp(name_in, A3_NAME)) ERR; /* Close up shop. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute ordering even more..."); /* Test the ordering of atts for each cmode. */ if (tst_att_ordering(NC_CLOBBER)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_64BIT_OFFSET)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR; SUMMARIZE_ERR; printf("*** testing attributes and enddef/redef..."); #define ATT_1 "a" #define ATT_2 "b" #define ATT_3 "c" { int ncid, att = 1; if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL|NC_CLOBBER, &ncid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_1, NC_INT, 1, &att)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_2, NC_INT, 1, &att)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_3, NC_INT, 1, &att)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing copy of simple global atts..."); { int ncid, ncid2; nc_type att_type; size_t att_len; int i; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT}; unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT}; unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL}; long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64}; /* Create a file with a global attribute of each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR; /* Create another file and copy all the attributes. */ if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UCHAR_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_USHORT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT64_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT64_NAME, ncid2, NC_GLOBAL)) ERR; /* Close both files. */ if (nc_close(ncid)) ERR; if (nc_close(ncid2)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME2, 0, &ncid)) ERR; /* Check text. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); /* Check numeric values. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != uchar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (ushort_in[i] != ushort_out[i]) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint_in[i] != uint_out[i]) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int64_in[i] != int64_out[i]) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint64_in[i] != uint64_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
int test_redef(int format) { int ncid, varid, dimids[REDEF_NDIMS], dimids_in[REDEF_NDIMS]; int ndims, nvars, natts, unlimdimid; int dimids_var[REDEF_NDIMS], var_type; int cflags = 0; size_t dim_len; char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1]; float float_in; double double_out = 99E99; int int_in; unsigned char uchar_in, uchar_out = 255; short short_out = -999; nc_type xtype_in; size_t cache_size_in, cache_nelems_in; float cache_preemption_in; int ret; if (format == NC_FORMAT_64BIT) cflags |= NC_64BIT_OFFSET; else if (format == NC_FORMAT_NETCDF4_CLASSIC) cflags |= (NC_NETCDF4|NC_CLASSIC_MODEL); else if (format == NC_FORMAT_NETCDF4) cflags |= NC_NETCDF4; /* Change chunk cache. */ if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS, NEW_CACHE_PREEMPTION)) ERR; /* Create a file with two dims, two vars, and two atts. */ if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR; /* Retrieve the chunk cache settings, just for fun. */ if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in, &cache_preemption_in)) ERR; if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS || cache_preemption_in != NEW_CACHE_PREEMPTION) ERR; /* This will fail, except for netcdf-4/hdf5, which permits any * name. */ if (format != NC_FORMAT_NETCDF4) if ((ret = nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN, &dimids[1])) != NC_EBADNAME) ERR; if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, REDEF_VAR1_NAME, NC_INT, REDEF_NDIMS, dimids, &varid)) ERR; if (nc_def_var(ncid, REDEF_VAR2_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, REDEF_ATT1_NAME, NC_DOUBLE, 1, &double_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, REDEF_ATT2_NAME, NC_SHORT, 1, &short_out)) ERR; /* Check it out. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; /* Close it up. */ if (format != NC_FORMAT_NETCDF4) if (nc_enddef(ncid)) ERR; if (nc_close(ncid)) ERR; /* Reopen as read only - make sure it doesn't let us change file. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; /* This will fail. */ ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS, dimids, &varid); if(format == NC_FORMAT_NETCDF4) { if(ret != NC_EPERM) { ERR; } } else { if(ret != NC_ENOTINDEFINE) { ERR; } } /* This will fail. */ if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR; if (nc_close(ncid)) ERR; /* Make sure we can't redef a file opened for NOWRITE. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_redef(ncid) != NC_EPERM) ERR; /* Check it out again. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check it, add a variable and attribute. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; /* Check it out. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR; /* Add var. */ if ((format != NC_FORMAT_NETCDF4) && nc_redef(ncid)) ERR; if (nc_def_var(ncid, REDEF_VAR3_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR; /* Add att. */ ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out); if (format != NC_FORMAT_NETCDF4 && ret) ERR; else if (format == NC_FORMAT_NETCDF4 && ret != NC_ERANGE) ERR; /* Check it out. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != REDEF_NDIMS || nvars != 3 || natts != 3 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR; if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE || natts != 0) ERR; if (nc_close(ncid)) ERR; /* Reopen it and check each dim, var, and att. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR; if (dim_len != REDEF_DIM1_LEN || strcmp(dim_name, REDEF_DIM1_NAME)) ERR; if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR; if (dim_len != REDEF_DIM2_LEN || strcmp(dim_name, REDEF_DIM2_NAME)) ERR; if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR; if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR1_NAME) || var_type != NC_INT || natts != 0) ERR; if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR; if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR2_NAME) || var_type != NC_BYTE || natts != 0) ERR; if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR; if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE || natts != 0) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, REDEF_ATT1_NAME, &float_in) != NC_ERANGE) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR; if (int_in != short_out) ERR; ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in); if (format == NC_FORMAT_NETCDF4) { if (ret != NC_ERANGE) ERR; } else if (ret) ERR; if (uchar_in != uchar_out) ERR; if (nc_close(ncid)) ERR; return NC_NOERR; }
bool NETCDFFileObject::ReadAttribute(const char *varname, const char *attname, TypeEnum *type, int *ndims, int **dims, void **value) { const char *mName = "NETCDFFileObject::ReadAttribute: "; int varid, status; int natts = 0; bool varvalid = false; if(varname == 0) { varid = NC_GLOBAL; if((status = nc_inq_natts(GetFileHandle(), &natts)) == NC_NOERR) varvalid = natts > 0; else { debug4 << mName << "0: "; HandleError(status); } } else { // Look up the variable name and gets its variable id. varvalid = GetVarId(varname, &varid); } if(varvalid) { nc_type atttype; size_t attsize; if((status = nc_inq_att(GetFileHandle(), varid, attname, &atttype, &attsize)) == NC_NOERR) { void *val = 0; TypeEnum t = NO_TYPE; // Try and read the attribute. if(atttype == NC_CHAR) { char *arr = new char[attsize+1]; status = nc_get_att_text(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else { // Trim trailing spaces. arr[attsize] = '\0'; char *c2 = arr + attsize - 1; while(c2 >= arr && *c2 == ' ') *c2-- = '\0'; val = (void*)arr; } t = CHARARRAY_TYPE; } else if(atttype == NC_BYTE) { unsigned char *arr = new unsigned char[attsize+1]; status = nc_get_att_uchar(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = UCHARARRAY_TYPE; } else if(atttype == NC_SHORT) { short *arr = new short[attsize]; status = nc_get_att_short(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = SHORTARRAY_TYPE; } else if(atttype == NC_INT) { int *arr = new int[attsize]; status = nc_get_att_int(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = INTEGERARRAY_TYPE; } else if(atttype == NC_LONG) { long *arr = new long[attsize]; status = nc_get_att_long(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = LONGARRAY_TYPE; } else if(atttype == NC_FLOAT) { float *arr = new float[attsize]; status = nc_get_att_float(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = FLOATARRAY_TYPE; } else if(atttype == NC_DOUBLE) { double *arr = new double[attsize]; status = nc_get_att_double(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = DOUBLEARRAY_TYPE; } if(status == NC_NOERR) { *type = t; *ndims = 1; int *d = new int[1]; d[0] = (int)attsize; *dims = d; *value = val; } else { *type = NO_TYPE; *ndims = 0; *dims = 0; *value = 0; debug4 << mName << "3: "; HandleError(status); varvalid = false; } } else { varvalid = false; debug4 << mName << "4: "; HandleError(status); } } return varvalid; }