1/* This is part of the netCDF package.
2   Copyright 2005 University Corporation for Atmospheric Research/Unidata
3   See COPYRIGHT file for conditions of use.
4
5   Test netcdf-4 compound type feature.
6
7   $Id: tst_compounds2.c,v 1.15 2010/05/25 13:53:04 ed Exp $
8*/
9
10#include <config.h>
11#include <stdlib.h>
12#include <nc_tests.h>
13#include "err_macros.h"
14
15#define FILE_NAME "tst_compounds2.nc"
16
17int
18main(int argc, char **argv)
19{
20
21    printf("\n*** Testing netcdf-4 user defined type functions, even more.\n");
22    printf("*** testing compound var containing byte arrays of various size...");
23   {
24#define DIM1_LEN 1
25#define ARRAY_LEN (NC_MAX_NAME + 1)
26      int ncid;
27      size_t len;
28      nc_type xtypetype_id;
29      int dim_sizes[] = {ARRAY_LEN};
30      int ij;
31
32      struct s1
33      {
34     unsigned char x[ARRAY_LEN];
35     float y;
36      };
37      struct s1 data_out[DIM1_LEN], data_in[DIM1_LEN];
38      char *dummy;
39
40      printf("array len=%d... ", ARRAY_LEN);
41
42      /* REALLY initialize the data (even the gaps in the structs). This
43       * is only needed to pass valgrind. */
44      if (!(dummy = calloc(sizeof(struct s1), DIM1_LEN)))
45  return NC_ENOMEM;
46      memcpy((void *)data_out, (void *)dummy, sizeof(struct s1) * DIM1_LEN);
47      free(dummy);
48
49      /* Create some phony data. */
50      for (i = 0; i < DIM1_LENi++)
51      {
52  data_out[i].y = 99.99;
53  for (j = 0; j < ARRAY_LENj++)
54     data_out[i].x[j] = j;
55      }
56
57      /* Create a file with a nested compound type attribute and variable. */
58      if (nc_create(FILE_NAMENC_NETCDF4, &ncid)) ERR;
59
60      /* Now define the compound type. */
61      if (nc_def_compound(ncid, sizeof(struct s1), "c", &type_id)) ERR;
62      if (nc_insert_array_compound(ncidtype_id, "x",
63    NC_COMPOUND_OFFSET(struct s1x), NC_UBYTE, 1, dim_sizes)) ERR;
64      if (nc_insert_compound(ncidtype_id, "y",
65      NC_COMPOUND_OFFSET(struct s1y), NC_FLOAT)) ERR;
66
67      /* Write it as an attribute. */
68      if (nc_put_att(ncidNC_GLOBAL, "a1", type_idDIM1_LENdata_out)) ERR;
69      if (nc_close(ncid)) ERR;
70
71      /* Read the att and check values. */
72      if (nc_open(FILE_NAMENC_WRITE, &ncid)) ERR;
73      if (nc_get_att(ncidNC_GLOBAL, "a1", data_in)) ERR;
74      for (i=0; i<DIM1_LENi++)
75      {
76  if (data_in[i].y != data_out[i].yERR;
77  for (j = 0; j < ARRAY_LENj++)
78     if (data_in[i].x[j] != data_out[i].x[j]) ERR_RET;
79      }
80
81      /* Use the inq functions to learn about the compound type. */
82      if (nc_inq_att(ncidNC_GLOBAL, "a1", &xtype, &len)) ERR;
83      if (len != DIM1_LENERR;
84
85      /* Finish checking the containing compound type. */
86      if (nc_close(ncid)) ERR;
87   }
88
89   SUMMARIZE_ERR;
90   printf("*** testing compound var on different machines...");
91   {
92#define DIM1_LEN 1
93#define NAME1 "x"
94#define NAME2 "y"
95      int ncid;
96      size_t len;
97      nc_type xtypetype_id;
98      char field_name_in[NC_MAX_NAME + 1];
99      size_t offset_in;
100      int field_ndims;
101      nc_type field_typeid;
102      int i;
103
104      struct s1
105      {
106     float x;
107     double y;
108      };
109      struct s1 data_out[DIM1_LEN], data_in[DIM1_LEN];
110      char *dummy;
111
112      /* REALLY initialize the data (even the gaps in the structs). This
113       * is only needed to pass valgrind. */
114      if (!(dummy = calloc(sizeof(struct s1), DIM1_LEN)))
115  return NC_ENOMEM;
116      memcpy((void *)data_out, (void *)dummy, sizeof(struct s1) * DIM1_LEN);
117      free(dummy);
118
119      /* Create some phony data. */
120      for (i = 0; i < DIM1_LENi++)
121      {
122  data_out[i].x = 1;
123  data_out[i].y = -2;
124      }
125
126      /* Create a file with a nested compound type attribute and variable. */
127      if (nc_create(FILE_NAMENC_NETCDF4, &ncid)) ERR;
128
129      /* Now define the compound type. */
130      if (nc_def_compound(ncid, sizeof(struct s1), "c", &type_id)) ERR;
131      if (nc_insert_compound(ncidtype_idNAME1,
132      NC_COMPOUND_OFFSET(struct s1x), NC_FLOAT)) ERR;
133      if (nc_insert_compound(ncidtype_idNAME2,
134      NC_COMPOUND_OFFSET(struct s1y), NC_DOUBLE)) ERR;
135
136      /* Write it as an attribute. */
137      if (nc_put_att(ncidNC_GLOBAL, "a1", type_idDIM1_LENdata_out)) ERR;
138      if (nc_close(ncid)) ERR;
139
140      /* Read the att and check values. */
141      if (nc_open(FILE_NAMENC_WRITE, &ncid)) ERR;
142      if (nc_get_att(ncidNC_GLOBAL, "a1", data_in)) ERR;
143      for (i = 0; i < DIM1_LENi++)
144  if (data_in[i].x != data_out[i].x || data_in[i].y != data_out[i].yERR;
145
146      /* Use the inq functions to learn about the compound type. */
147      if (nc_inq_att(ncidNC_GLOBAL, "a1", &xtype, &len)) ERR;
148      if (len != DIM1_LENERR;
149      if (nc_inq_compound_field(ncidxtype, 0, field_name_in,
150          &offset_in, &field_typeid, &field_ndimsNULL)) ERR;
151      if (strcmp(field_name_inNAME1) || field_typeid != NC_FLOAT || field_ndimsERR;
152      printf("offset x: %d  ", (int)offset_in);
153      if (nc_inq_compound_field(ncidxtype, 1, field_name_in,
154          &offset_in, &field_typeid, &field_ndimsNULL)) ERR;
155      if (strcmp(field_name_inNAME2) || field_typeid != NC_DOUBLE || field_ndimsERR;
156      printf("offset y: %d NC_COMPOUND_OFFSET(struct s1, y): %d ", (int)offset_in,
157      (int)NC_COMPOUND_OFFSET(struct s1y));
158
159      /* Finish checking the containing compound type. */
160      if (nc_close(ncid)) ERR;
161   }
162
163   SUMMARIZE_ERR;
164   printf("*** testing compound var containing compound var, on different machines...");
165   {
166#define DIM1_LEN 1
167#define S1_NAME_X "x"
168#define S1_NAME_Y "y"
169#define S2_NAME_S1 "s1"
170#define NUM_TYPES 2
171#define INNER_TYPE_NAME "c"
172#define OUTER_TYPE_NAME "d"
173#define ATT_NAME "a1"
174
175      int ncid;
176      size_t len;
177      nc_type inner_typeid = 0, outer_typeids1_typeids2_typeid;
178      char field_name_in[NC_MAX_NAME + 1];
179      size_t offset_in;
180      int field_ndims;
181      nc_type field_typeid;
182      int i;
183
184      struct s1
185      {
186     float x;
187     double y;
188      };
189      struct s2
190      {
191     struct s1 s1;
192      };
193      struct s2 data_out[DIM1_LEN], data_in[DIM1_LEN];
194      int ntypestypeids[NUM_TYPES];
195      size_t size_innfields_in;
196      char name_in[NC_MAX_NAME + 1];
197      int t;
198      char *dummy;
199
200      /* REALLY initialize the data (even the gaps in the structs). This
201       * is only needed to pass valgrind. */
202      if (!(dummy = calloc(sizeof(struct s2), DIM1_LEN)))
203  return NC_ENOMEM;
204      memcpy((void *)data_out, (void *)dummy, sizeof(struct s2) * DIM1_LEN);
205      free(dummy);
206
207      /* Create some phony data. */
208      for (i = 0; i < DIM1_LENi++)
209      {
210  data_out[i].s1.x = 1;
211  data_out[i].s1.y = -2;
212      }
213
214      /* Create a file with a nested compound type attribute and variable. */
215      if (nc_create(FILE_NAMENC_NETCDF4, &ncid)) ERR;
216
217      /* Now define the inner compound type. */
218      if (nc_def_compound(ncid, sizeof(struct s1), INNER_TYPE_NAME, &s1_typeid)) ERR;
219      if (nc_insert_compound(ncids1_typeidS1_NAME_X,
220      NC_COMPOUND_OFFSET(struct s1x), NC_FLOAT)) ERR;
221      if (nc_insert_compound(ncids1_typeidS1_NAME_Y,
222      NC_COMPOUND_OFFSET(struct s1y), NC_DOUBLE)) ERR;
223
224      /* Define the outer compound type. */
225      if (nc_def_compound(ncid, sizeof(struct s2), OUTER_TYPE_NAME, &s2_typeid)) ERR;
226      if (nc_insert_compound(ncids2_typeidS2_NAME_S1,
227      NC_COMPOUND_OFFSET(struct s2s1), s1_typeid)) ERR;
228
229      /* Write it as an attribute. */
230      if (nc_put_att(ncidNC_GLOBALATT_NAMEs2_typeidDIM1_LENdata_out)) ERR;
231      if (nc_close(ncid)) ERR;
232
233      /* Read the att and check values. */
234      if (nc_open(FILE_NAMENC_WRITE, &ncid)) ERR;
235      if (nc_get_att(ncidNC_GLOBALATT_NAMEdata_in)) ERR;
236      for (i = 0; i < DIM1_LENi++)
237  if (data_in[i].s1.x != data_out[i].s1.x || data_in[i].s1.y != data_out[i].s1.yERR;
238
239      /* Use the inq functions to learn about the compound type. */
240      if (nc_inq_typeids(ncid, &ntypestypeids)) ERR;
241      if (ntypes != NUM_TYPESERR;
242      for (t = 0; t < NUM_TYPESt++)
243      {
244  if (nc_inq_compound(ncidtypeids[t], name_in, &size_in, &nfields_in)) ERR;
245  if (!strcmp(name_inINNER_TYPE_NAME))
246     inner_typeid = typeids[t];
247      }
248
249      /* What type is the attribute? */
250      if (nc_inq_att(ncidNC_GLOBALATT_NAME, &outer_typeid, &len)) ERR;
251      if (len != DIM1_LENERR;
252      if (nc_inq_compound_field(ncidouter_typeid, 0, field_name_in,
253          &offset_in, &field_typeid, &field_ndimsNULL)) ERR;
254      if (strcmp(field_name_inS2_NAME_S1) || field_typeid != inner_typeid || field_ndimsERR;
255      if (nc_inq_compound_field(ncidfield_typeid, 1, field_name_in,
256          &offset_in, &field_typeid, &field_ndimsNULL)) ERR;
257      if (strcmp(field_name_inS1_NAME_Y) || field_typeid != NC_DOUBLE || field_ndimsERR;
258
259      /* Finish checking the containing compound type. */
260      if (nc_close(ncid)) ERR;
261   }
262
263   SUMMARIZE_ERR;
264   FINAL_RESULTS;
265}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed