1 /* This is part of the netCDF package. Copyright 2005 University
2    Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
3    conditions of use. See www.unidata.ucar.edu for more info.
4 
5    Test netcdf-4 cross platform compound type.
6 
7    $Id: tst_xplatform.c,v 1.14 2009/06/04 14:19:24 ed Exp $
8 */
9 
10 #include <nc_tests.h>
11 #include "err_macros.h"
12 #include "netcdf.h"
13 
14 #define FILE_NAME "tst_xplatform.nc"
15 
16 /* This file comes from the ncdump directory, where it is also used
17  * for testing. */
18 #define IN_FILE_NAME_3 "ref_tst_compounds3.nc"
19 #define IN_FILE_NAME_4 "ref_tst_compounds4.nc"
20 
21 #define CMP_TYPE_NAME "cmp_t"
22 #define X_NAME "x"
23 #define Y_NAME "y"
24 
25 struct s1
26 {
27       float x;
28       double y;
29 };
30 
31 int
main(int argc,char ** argv)32 main(int argc, char **argv)
33 {
34    printf("\n*** Testing cross-platform compound data.\n");
35    printf("*** testing define of struct s1 compound type...");
36    {
37       int ncid, ntypes_in, ndims_in;
38       char name_in[NC_MAX_NAME + 1];
39       size_t size_in, nfields_in, offset_in;
40       nc_type field_type_in, cmp_typeid;
41 
42       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
43       if (nc_def_compound(ncid, sizeof(struct s1), CMP_TYPE_NAME, &cmp_typeid)) ERR;
44       if (nc_insert_compound(ncid, cmp_typeid, X_NAME,
45           NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
46       if (nc_insert_compound(ncid, cmp_typeid, Y_NAME,
47           NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
48       if (nc_close(ncid)) ERR;
49 
50       /* Check it out. */
51       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
52       if (nc_inq_typeids(ncid, &ntypes_in, &cmp_typeid)) ERR;
53       if (ntypes_in != 1) ERR;
54       if (nc_inq_compound(ncid, cmp_typeid, name_in, &size_in, &nfields_in)) ERR;
55       if (nfields_in != 2 || strcmp(name_in, CMP_TYPE_NAME) || size_in != sizeof(struct s1)) ERR;
56       if (nc_inq_compound_field(ncid, cmp_typeid, 0, name_in, &offset_in,
57           &field_type_in, &ndims_in, NULL)) ERR;
58       if (strcmp(name_in, X_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
59           ndims_in) ERR;
60       if (nc_inq_compound_field(ncid, cmp_typeid, 1, name_in, &offset_in,
61           &field_type_in, &ndims_in, NULL)) ERR;
62       if (strcmp(name_in, Y_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1, y) ||
63           field_type_in != NC_DOUBLE || ndims_in) ERR;
64       if (nc_close(ncid)) ERR;
65    }
66    SUMMARIZE_ERR;
67    printf("*** reading ref_tst_compound3.nc...");
68    {
69      /* Here is the file:
70      netcdf ref_tst_compounds3 {
71      types:
72        compound cmp_t {
73          float x ;
74          double y ;
75        }; // cmp_t
76      dimensions:
77      	n = 1 ;
78      variables:
79      	cmp_t var(n) ;
80      data:
81       var = {1, -2} ;
82      }
83       */
84 
85       int ncid, cmp_typeid, ntypes_in, ndims_in, dimids_in[1], natts_in;
86       int nvars_in, unlimdimid;
87       char name_in[NC_MAX_NAME + 1];
88       size_t size_in, nfields_in, offset_in;
89       nc_type field_type_in;
90       struct s1 data_in[1];
91       char file_in[NC_MAX_NAME + 1];
92 
93       strcpy(file_in, "");
94       if (getenv("srcdir"))
95       {
96 	 strcat(file_in, getenv("srcdir"));
97 	 strcat(file_in, "/");
98       }
99       strcat(file_in, "../ncdump/");
100       strcat(file_in, IN_FILE_NAME_3);
101 
102       /* Check it out. But this version of the type was created on a
103        * Sun, so has different size and offsets. */
104       if (nc_open(file_in, NC_NOWRITE, &ncid)) ERR;
105       if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid)) ERR;
106       if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid != -1) ERR;
107       if (nc_inq_var(ncid, 0, name_in, &cmp_typeid, &ndims_in, dimids_in, &natts_in)) ERR;
108       if (strcmp(name_in, "var") || ndims_in != 1 || natts_in) ERR;
109 
110       /* Learn about the compound type. */
111       if (nc_inq_typeids(ncid, &ntypes_in, &cmp_typeid)) ERR;
112       if (ntypes_in != 1) ERR;
113       if (nc_inq_compound(ncid, cmp_typeid, name_in, &size_in, &nfields_in)) ERR;
114       if (nfields_in != 2 || strcmp(name_in, CMP_TYPE_NAME) || size_in != sizeof(struct s1)) ERR;
115       if (nc_inq_compound_field(ncid, cmp_typeid, 0, name_in, &offset_in,
116           &field_type_in, &ndims_in, NULL)) ERR;
117       if (strcmp(name_in, X_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
118           ndims_in) ERR;
119       if (nc_inq_compound_field(ncid, cmp_typeid, 1, name_in, &offset_in,
120           &field_type_in, &ndims_in, NULL)) ERR;
121       if (strcmp(name_in, Y_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1, y) || field_type_in != NC_DOUBLE ||
122           ndims_in) ERR;
123 
124       /* Read the data. */
125       if (nc_get_var(ncid, 0, data_in)) ERR;
126       if (data_in[0].x != 1.0 || data_in[0].y != -2.0) ERR;
127       if (nc_close(ncid)) ERR;
128    }
129    SUMMARIZE_ERR;
130    printf("*** reading ref_tst_compound4.nc...");
131    {
132      /* Here is the file:
133         netcdf ref_tst_compounds4 {
134         types:
135           compound c {
136             float x ;
137             double y ;
138           }; // c
139           compound d {
140             c s1 ;
141           }; // d
142 
143         // global attributes:
144         		d :a1 = {{1, -2}} ;
145         }
146       */
147 #define NUM_TYPES 2
148 #define CMP_TYPE_NAME_C "c"
149 #define CMP_TYPE_NAME_D "d"
150 #define ATT_NAME "a1"
151 #define S1_NAME "s1"
152       int ncid, cmp_typeid[NUM_TYPES], ntypes_in, ndims_in, natts_in;
153       int nvars_in, unlimdimid;
154       char name_in[NC_MAX_NAME + 1];
155       size_t size_in, nfields_in, offset_in;
156       nc_type field_type_in;
157       struct s2
158       {
159 	    struct s1 s1;
160       };
161       struct s2 data_in[1];
162       char file_in[NC_MAX_NAME + 1];
163 
164       strcpy(file_in, "");
165       if (getenv("srcdir"))
166       {
167 	 strcat(file_in, getenv("srcdir"));
168 	 strcat(file_in, "/");
169       }
170       strcat(file_in, "../ncdump/");
171       strcat(file_in, IN_FILE_NAME_4);
172 
173       /* Check it out. But this version of the type was created on a
174        * Sun, so has different size and offsets. */
175       if (nc_open(file_in, NC_NOWRITE, &ncid)) ERR;
176       if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid)) ERR;
177       if (ndims_in != 0 || nvars_in != 0 || natts_in != 1 || unlimdimid != -1) ERR;
178 
179       /* Learn about the compound type. */
180       if (nc_inq_typeids(ncid, &ntypes_in, cmp_typeid)) ERR;
181       if (ntypes_in != 2) ERR;
182 
183       /* Check the inner type. */
184       if (nc_inq_compound(ncid, cmp_typeid[0], name_in, &size_in, &nfields_in)) ERR;
185       if (nfields_in != 2 || strcmp(name_in, CMP_TYPE_NAME_C) || size_in != sizeof(struct s1)) ERR;
186       if (nc_inq_compound_field(ncid, cmp_typeid[0], 0, name_in, &offset_in,
187           &field_type_in, &ndims_in, NULL)) ERR;
188       if (strcmp(name_in, X_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
189           ndims_in) ERR;
190       if (nc_inq_compound_field(ncid, cmp_typeid[0], 1, name_in, &offset_in,
191           &field_type_in, &ndims_in, NULL)) ERR;
192       if (strcmp(name_in, Y_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1, y) || field_type_in != NC_DOUBLE ||
193           ndims_in) ERR;
194 
195       /* Check the outer type. */
196       if (nc_inq_compound(ncid, cmp_typeid[1], name_in, &size_in, &nfields_in)) ERR;
197       if (nfields_in != 1 || strcmp(name_in, CMP_TYPE_NAME_D) || size_in != sizeof(struct s2)) ERR;
198       if (nc_inq_compound_field(ncid, cmp_typeid[1], 0, name_in, &offset_in,
199           &field_type_in, &ndims_in, NULL)) ERR;
200 /*      if (strcmp(name_in, S1_NAME) || offset_in != 0 || field_type_in != cmp_typeid[0] || ndims_in) ERR;*/
201 
202       /* Read the data. */
203       if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR;
204       if (data_in[0].s1.x != 1.0 || data_in[0].s1.y != -2.0) ERR;
205       if (nc_close(ncid)) ERR;
206    }
207    SUMMARIZE_ERR;
208    FINAL_RESULTS;
209 }
210