1 /*! This is part of the netCDF package. Copyright 2005-2018, University
2    Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
3    for conditions of use.
4 
5    Test NetCDF-4 files with lots of attributes on big vs. little
6    endian platforms.
7 */
8 #include <config.h>
9 #include <nc_tests.h>
10 #include "err_macros.h"
11 
12 #define FILE_NAME "tst_interops4.nc"
13 #define REF_FILE_NAME "ref_tst_interops4.nc"
14 #define DIM_NAME "dim_0"
15 #define NUM_DIMS 1
16 #define NUM_ATTS 20
17 #define NUM_VARS 20
18 #define ATT_LEN 30
19 #define VAR_LEN 4
20 
21 int att_data[ATT_LEN];
22 int var_data[VAR_LEN];
23 
24 int
write_atts(int ncid,int varid)25 write_atts(int ncid, int varid)
26 {
27    int a;
28    char att_name[NC_MAX_NAME + 1];
29 
30    for (a = 0; a < NUM_ATTS; a++)
31    {
32       sprintf(att_name, "att_%d", a);
33       if (nc_put_att_int(ncid, varid, att_name, NC_INT,
34 			 ATT_LEN, att_data)) ERR_RET;
35    }
36    return NC_NOERR;
37 }
38 
39 int
read_atts(int ncid,int varid)40 read_atts(int ncid, int varid)
41 {
42    int a, i;
43    char att_name[NC_MAX_NAME + 1];
44    int att_data_in[ATT_LEN];
45 
46    for (a = 0; a < NUM_ATTS; a++)
47    {
48       sprintf(att_name, "att_%d", a);
49       if (nc_get_att_int(ncid, varid, att_name,
50 			 att_data_in)) ERR_RET;
51       for (i = 0; i < ATT_LEN; i++)
52 	 if (att_data_in[i] != att_data[i]) ERR_RET;
53 
54    }
55    return NC_NOERR;
56 }
57 
58 int
write_vars(int ncid)59 write_vars(int ncid)
60 {
61    int v;
62    char var_name[NC_MAX_NAME + 1];
63    /* NOT GOOD to assume the dimid, but I want to test passing a NULL
64     * into last argument of nc_def_dim. */
65    int dimid[NUM_DIMS] = {0};
66 
67    if (nc_def_dim(ncid, DIM_NAME, VAR_LEN, NULL)) ERR;
68    for (v = 0; v < NUM_VARS; v++)
69    {
70       sprintf(var_name, "var_%d", v);
71       if (nc_def_var(ncid, var_name, NC_INT, NUM_DIMS,
72 		     dimid, NULL)) ERR_RET;
73       write_atts(ncid, v);
74       if (nc_put_var_int(ncid, v, var_data)) ERR;
75    }
76    return NC_NOERR;
77 }
78 
79 int
read_vars(int ncid)80 read_vars(int ncid)
81 {
82    int v, i;
83    char var_name[NC_MAX_NAME + 1], var_name_in[NC_MAX_NAME + 1];
84    int var_data_in[VAR_LEN];
85    nc_type xtype_in;
86    int natts_in, ndims_in;
87 
88    for (v = 0; v < NUM_VARS; v++)
89    {
90       if (nc_inq_var(ncid, v, var_name_in, &xtype_in, &ndims_in,
91 		     NULL, &natts_in)) ERR_RET;
92       sprintf(var_name, "var_%d", v);
93       if (strcmp(var_name, var_name_in) || xtype_in != NC_INT ||
94 		 ndims_in != NUM_DIMS || natts_in != NUM_ATTS) ERR_RET;
95       read_atts(ncid, v);
96       if (nc_get_var_int(ncid, v, var_data_in)) ERR;
97       for (i = 0; i < VAR_LEN; i++)
98 	 if (var_data_in[i] != var_data[i]) ERR_RET;
99 
100    }
101    return NC_NOERR;
102 }
103 
104 int
main(int argc,char ** argv)105 main(int argc, char **argv)
106 {
107    printf("\n*** Testing interoperability between big vs. little endian platforms.\n");
108    printf("*** testing with file with lots of atts...");
109    {
110       int ncid;
111       int nvars_in, ndims_in, natts_in, unlimdim_in;
112       int i;
113 
114       /* Initialize data. */
115       for (i = 0; i < ATT_LEN; i++)
116 	 att_data[i] = i;
117       for (i = 0; i < VAR_LEN; i++)
118 	 var_data[i] = i;
119 
120       /* Create a file that will activate the bug in HDF5 1.8.4. */
121       if (nc_create(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
122       if (write_atts(ncid, NC_GLOBAL)) ERR;
123       if (write_vars(ncid)) ERR;
124       if (nc_close(ncid)) ERR;
125 
126       /* Open the file and check it. */
127       if (nc_open(FILE_NAME, 0, &ncid)) ERR;
128       if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR;
129       if (ndims_in != NUM_DIMS || nvars_in != NUM_VARS ||
130 	  natts_in != NUM_ATTS || unlimdim_in != -1) ERR;
131       if (read_atts(ncid, NC_GLOBAL)) ERR;
132       if (read_vars(ncid)) ERR;
133       if (nc_close(ncid)) ERR;
134 
135    }
136    SUMMARIZE_ERR;
137    {
138       char file_in[NC_MAX_NAME + 1];
139       int ncid;
140       int nvars_in, ndims_in, natts_in, unlimdim_in;
141 
142       /* Open the reference version of this file, generated on a
143        * big-endian platform. */
144       if (getenv("srcdir"))
145       {
146 	 strcpy(file_in, getenv("srcdir"));
147 	 strcat(file_in, "/");
148 	 strcat(file_in, REF_FILE_NAME);
149       }
150       else
151 	 strcpy(file_in, REF_FILE_NAME);
152 
153       printf("*** testing with file %s...", file_in);
154       if (nc_open(file_in, 0, &ncid)) ERR;
155       if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR;
156       if (ndims_in != NUM_DIMS || nvars_in != NUM_VARS ||
157 	  natts_in != NUM_ATTS || unlimdim_in != -1) ERR;
158       if (read_atts(ncid, NC_GLOBAL)) ERR;
159       if (read_vars(ncid)) ERR;
160       if (nc_close(ncid)) ERR;
161    }
162    SUMMARIZE_ERR;
163    FINAL_RESULTS;
164 }
165