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_xplatform2.c,v 1.18 2009/10/26 18:44:59 russ Exp $
8*/
9
10#include <nc_tests.h>
11#include "err_macros.h"
12#include "netcdf.h"
13
14#define FILE_NAME_1 "tst_xplatform2_1.nc"
15#define REF_FILE_NAME_1 "ref_tst_xplatform2_1.nc"
16#define FILE_NAME_2 "tst_xplatform2_2.nc"
17#define REF_FILE_NAME_2 "ref_tst_xplatform2_2.nc"
18#define FILE_NAME_3 "tst_xplatform2_3.nc"
19#define REF_FILE_NAME_3 "ref_tst_xplatform2_3.nc"
20#define FILE_NAME_4 "tst_xplatform2_4.nc"
21#define REF_FILE_NAME_4 "ref_tst_xplatform2_4.nc"
22
23#define S1_TYPE_NAME "cmp_t"
24#define X_NAME "x"
25#define Y_NAME "y"
26#define S1_NAME "s1"
27#define S2_ATT_NAME "Runnymede"
28#define S2_TYPE_NAME "date_1215"
29
30#define DIM1_LEN 5
31#define DIM2_LEN 3
32#define VLEN_NAME "Magna_Carta_VLEN"
33#define VLEN_ATT_NAME "We_will_sell_to_no_man_we_will_not_deny_or_defer_to_any_man_either_Justice_or_Right"
34#define TWO_TYPES 2
35#define NUM_S1 4
36
37#define DIM3_LEN 1
38#define DIM3_NAME "DIMENSION->The city of London shall enjoy all its ancient liberties and free customs, both by land and by water."
39#define VAR3_NAME "VARIABLE->In future we will allow no one to levy an `aid' from his free men, except to ransom his person, to make his eldest son a knight, and (once) to marry his eldest daughter."
40
41#define NUM_VL 1
42#define S3_ATT_NAME "King_John"
43#define S3_TYPE_NAME "barons"
44#define VL_NAME "No scutage or aid may be levied in our kingdom without its general consent"
45#define THREE_TYPES 3
46
47struct s1
48{
49   float x;
50   double y;
51};
52struct s2
53{
54   struct s1 data[NUM_S1];
55};
56struct s3
57{
58   nc_vlen_t data[NUM_VL];
59};
60
61int
62check_file_1(int ncidnc_vlen_t *data_out)
63{
64   int ntypes_inndims_in;
65   char name_in[NC_MAX_NAME + 1];
66   size_t size_innfields_inoffset_in;
67   nc_type field_type_in;
68   nc_type typeids_in[TWO_TYPES], base_nc_type_in;
69   nc_vlen_t data_in[DIM1_LEN];
70   int ij;
71
72   /* There should be two types. */
73   if (nc_inq_typeids(ncid, &ntypes_intypeids_in)) ERR;
74   if (ntypes_in != 2) ERR;
75
76   /* The compound type is first: check it out. */
77   if (nc_inq_compound(ncidtypeids_in[0], name_in, &size_in, &nfields_in)) ERR;
78   if (nfields_in != 2 || strcmp(name_inS1_TYPE_NAME) || size_in != sizeof(struct s1)) ERR;
79   if (nc_inq_compound_field(ncidtypeids_in[0], 0, name_in, &offset_in,
80      &field_type_in, &ndims_inNULL)) ERR;
81   if (strcmp(name_inX_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
82       ndims_inERR;
83   if (nc_inq_compound_field(ncidtypeids_in[0], 1, name_in, &offset_in,
84      &field_type_in, &ndims_inNULL)) ERR;
85   if (strcmp(name_inY_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1y) || field_type_in != NC_DOUBLE ||
86       ndims_inERR;
87
88   /* How does the vlen type look? */
89   if (nc_inq_vlen(ncidtypeids_in[1], name_in, &size_in, &base_nc_type_in)) ERR;
90   if (strcmp(name_inVLEN_NAME) || size_in != sizeof(nc_vlen_t) ||
91       base_nc_type_in != typeids_in[0]) ERR;
92
93   /* Now read the attribute. */
94   if (nc_get_att(ncidNC_GLOBALVLEN_ATT_NAMEdata_in)) ERR;
95
96   /* Did we get the correct data? */
97   for (i = 0; i < DIM1_LENi++)
98   {
99      if (data_in[i].len != data_out[i].lenERR;
100      for (j = 0; j < data_in[i].lenj++)
101  if (((struct s1 *)data_in[i].p)->x != ((struct s1 *)data_out[i].p)->x ||
102      ((struct s1 *)data_in[i].p)->y != ((struct s1 *)data_out[i].p)->yERR_RET;
103   }
104
105   /* Free the memory that was malloced when the VLEN was read. */
106   for (i = 0; i < DIM1_LENi++)
107      free(data_in[i].p);
108
109   /* We're done! */
110   return NC_NOERR;
111}
112
113int
114check_file_2(int ncid, struct s2 *data_out)
115{
116   int ntypes_inndims_in;
117   char name_in[NC_MAX_NAME + 1];
118   size_t size_innfields_inoffset_in;
119   nc_type field_type_in;
120   nc_type typeids_in[TWO_TYPES];
121   struct s2 data_in[DIM2_LEN];
122   int field_dims_in[1];
123   int ij;
124
125   /* There should be two types. */
126   if (nc_inq_typeids(ncid, &ntypes_intypeids_in)) ERR;
127   if (ntypes_in != TWO_TYPESERR;
128
129   /* The compound type is first: check it out. */
130   if (nc_inq_compound(ncidtypeids_in[0], name_in, &size_in, &nfields_in)) ERR;
131   if (nfields_in != 2 || strcmp(name_inS1_TYPE_NAME) || size_in != sizeof(struct s1)) ERR;
132   if (nc_inq_compound_field(ncidtypeids_in[0], 0, name_in, &offset_in,
133      &field_type_in, &ndims_inNULL)) ERR;
134   if (strcmp(name_inX_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
135       ndims_inERR;
136   if (nc_inq_compound_field(ncidtypeids_in[0], 1, name_in, &offset_in,
137      &field_type_in, &ndims_inNULL)) ERR;
138   if (strcmp(name_inY_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1y) || field_type_in != NC_DOUBLE ||
139       ndims_inERR;
140
141   /* How does the containing compound type look? */
142   if (nc_inq_compound(ncidtypeids_in[1], name_in, &size_in, &nfields_in)) ERR;
143   if (strcmp(name_inS2_TYPE_NAME) || size_in != sizeof(struct s2) ||
144       nfields_in != 1) ERR;
145   if (nc_inq_compound_field(ncidtypeids_in[1], 0, name_in, &offset_in, &field_type_in,
146      &ndims_infield_dims_in)) ERR;
147   if (strcmp(name_inS1_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s2data) ||
148       field_type_in != typeids_in[0] || ndims_in != 1 || field_dims_in[0] != NUM_S1ERR;
149
150   /* Now read the attribute. */
151   if (nc_get_att(ncidNC_GLOBALS2_ATT_NAMEdata_in)) ERR;
152
153   /* Did we get the correct data? */
154   for (i = 0; i < DIM2_LENi++)
155      for (j = 0; j < NUM_S1j++)
156  if (data_out[i].data[j].x != data_in[i].data[j].x ||
157      data_out[i].data[j].y != data_in[i].data[j].yERR;
158
159   /* We're done! */
160   return NC_NOERR;
161}
162
163int
164check_file_3(int ncid, struct s3 *data_out)
165{
166   int ntypes_inndims_in;
167   char name_in[NC_MAX_NAME + 1];
168   size_t size_innfields_inoffset_in;
169   nc_type field_type_inbase_nc_type_in;
170   nc_type typeids_in[THREE_TYPES];
171   struct s3 data_in[DIM3_LEN];
172   int field_dims_in[1];
173   int ijk;
174
175   /* There should be three types. */
176   if (nc_inq_typeids(ncid, &ntypes_intypeids_in)) ERR;
177   if (ntypes_in != THREE_TYPESERR;
178
179   /* The s1 compound type is first: check it out. */
180   if (nc_inq_compound(ncidtypeids_in[0], name_in, &size_in, &nfields_in)) ERR;
181   if (nfields_in != 2 || strcmp(name_inS1_TYPE_NAME) || size_in != sizeof(struct s1)) ERR;
182   if (nc_inq_compound_field(ncidtypeids_in[0], 0, name_in, &offset_in,
183      &field_type_in, &ndims_inNULL)) ERR;
184   if (strcmp(name_inX_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
185       ndims_inERR;
186   if (nc_inq_compound_field(ncidtypeids_in[0], 1, name_in, &offset_in,
187      &field_type_in, &ndims_inNULL)) ERR;
188   if (strcmp(name_inY_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1y) || field_type_in != NC_DOUBLE ||
189       ndims_inERR;
190
191   /* How does the vlen type look? */
192   if (nc_inq_vlen(ncidtypeids_in[1], name_in, &size_in, &base_nc_type_in)) ERR;
193   if (strcmp(name_inVLEN_NAME) || size_in != sizeof(nc_vlen_t) ||
194       base_nc_type_in != typeids_in[0]) ERR;
195
196   /* How does the containing compound type look? */
197   if (nc_inq_compound(ncidtypeids_in[2], name_in, &size_in, &nfields_in)) ERR;
198   if (strcmp(name_inS3_TYPE_NAME) || size_in != sizeof(struct s3) ||
199       nfields_in != 1) ERR;
200   if (nc_inq_compound_field(ncidtypeids_in[2], 0, name_in, &offset_in, &field_type_in,
201      &ndims_infield_dims_in)) ERR;
202   if (strcmp(name_inVL_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s3data) ||
203       field_type_in != typeids_in[1] || ndims_in != 1 || field_dims_in[0] != NUM_VLERR;
204
205   /* Now read the attribute. */
206   if (nc_get_att(ncidNC_GLOBALS3_ATT_NAMEdata_in)) ERR;
207
208   /* Did we get the correct data? */
209   for (i = 0; i < DIM3_LENi++)
210      for (j = 0; j < NUM_VLj++)
211      {
212  if (data_in[i].data[j].len != data_in[i].data[j].lenERR;
213  for (k = 0; k < data_out[i].data[j].lenk++)
214     if (((struct s1 *)data_in[i].data[j].p)[k].x != ((struct s1 *)data_out[i].data[j].p)[k].x ||
215 ((struct s1 *)data_in[i].data[j].p)[k].y != ((struct s1 *)data_out[i].data[j].p)[k].yERR;
216      }
217
218   /* Free our vlens. */
219/*    for (i = 0; i < DIM3_LEN; i++) */
220/*       for (j = 0; j < NUM_VL; j++) */
221/*   nc_free_vlen(&(data_in[i].data[j])); */
222
223   /* We're done! */
224   return NC_NOERR;
225}
226
227int
228check_file_4(int ncid, struct s3 *data_out)
229{
230   int ntypes_inndims_in;
231   char name_in[NC_MAX_NAME + 1];
232   size_t size_innfields_inoffset_in;
233   nc_type field_type_inbase_nc_type_in;
234   nc_type typeids_in[THREE_TYPES];
235   struct s3 data_in[DIM3_LEN];
236   int field_dims_in[1];
237   int ijk;
238
239   /* There should be three types. */
240   if (nc_inq_typeids(ncid, &ntypes_intypeids_in)) ERR;
241   if (ntypes_in != THREE_TYPESERR;
242
243   /* The s1 compound type is first: check it out. */
244   if (nc_inq_compound(ncidtypeids_in[0], name_in, &size_in, &nfields_in)) ERR;
245   if (nfields_in != 2 || strcmp(name_inS1_TYPE_NAME) || size_in != sizeof(struct s1)) ERR;
246   if (nc_inq_compound_field(ncidtypeids_in[0], 0, name_in, &offset_in,
247      &field_type_in, &ndims_inNULL)) ERR;
248   if (strcmp(name_inX_NAME) || offset_in != 0 || field_type_in != NC_FLOAT ||
249       ndims_inERR;
250   if (nc_inq_compound_field(ncidtypeids_in[0], 1, name_in, &offset_in,
251      &field_type_in, &ndims_inNULL)) ERR;
252   if (strcmp(name_inY_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s1y) || field_type_in != NC_DOUBLE ||
253       ndims_inERR;
254
255   /* How does the vlen type look? */
256   if (nc_inq_vlen(ncidtypeids_in[1], name_in, &size_in, &base_nc_type_in)) ERR;
257   if (strcmp(name_inVLEN_NAME) || size_in != sizeof(nc_vlen_t) ||
258       base_nc_type_in != typeids_in[0]) ERR;
259
260   /* How does the containing compound type look? */
261   if (nc_inq_compound(ncidtypeids_in[2], name_in, &size_in, &nfields_in)) ERR;
262   if (strcmp(name_inS3_TYPE_NAME) || size_in != sizeof(struct s3) ||
263       nfields_in != 1) ERR;
264   if (nc_inq_compound_field(ncidtypeids_in[2], 0, name_in, &offset_in, &field_type_in,
265      &ndims_infield_dims_in)) ERR;
266   if (strcmp(name_inVL_NAME) || offset_in != NC_COMPOUND_OFFSET(struct s3data) ||
267       field_type_in != typeids_in[1] || ndims_in != 1 || field_dims_in[0] != NUM_VLERR;
268
269   /* Now read the variable. */
270   if (nc_get_var(ncid, 0, data_in)) ERR;
271
272   /* Did we get the correct data? */
273   for (i = 0; i < DIM3_LENi++)
274      for (j = 0; j < NUM_VLj++)
275      {
276  if (data_in[i].data[j].len != data_in[i].data[j].lenERR;
277  for (k = 0; k < data_out[i].data[j].lenk++)
278     if (((struct s1 *)data_in[i].data[j].p)[k].x != ((struct s1 *)data_out[i].data[j].p)[k].x ||
279 ((struct s1 *)data_in[i].data[j].p)[k].y != ((struct s1 *)data_out[i].data[j].p)[k].yERR;
280      }
281
282   /* Free our vlens. */
283/*    for (i = 0; i < DIM3_LEN; i++) */
284/*       for (j = 0; j < NUM_VL; j++) */
285/*   nc_free_vlen(&(data_in[i].data[j])); */
286
287   /* We're done! */
288   return NC_NOERR;
289}
290
291int
292main(int argc, char **argv)
293{
294   int ncid;
295   int ijk;
296   nc_vlen_t *vlen_of_comp_out;
297   struct s2 *comp_array_of_comp_out;
298   struct s3 *comp_array_of_vlen_of_comp_out;
299
300   printf("\nTesting nested types across platforms.\n");
301
302   if (!(vlen_of_comp_out = calloc(sizeof(nc_vlen_t), DIM1_LEN))) ERR;
303   if (!(comp_array_of_comp_out = calloc(sizeof(struct s2), DIM2_LEN))) ERR;
304   if (!(comp_array_of_vlen_of_comp_out = calloc(sizeof(struct s3), DIM3_LEN))) ERR;
305
306   /* Create some output data: a vlen of struct s1. */
307   for (i = 0; i < DIM1_LENi++)
308   {
309      vlen_of_comp_out[i].len = i + 1;
310      if (!(vlen_of_comp_out[i].p = malloc(sizeof(struct s1) * vlen_of_comp_out[i].len)))
311  return NC_ENOMEM;
312      for (j = 0; j < vlen_of_comp_out[i].lenj++)
313      {
314  ((struct s1 *)vlen_of_comp_out[i].p)[j].x = 42.42;
315  ((struct s1 *)vlen_of_comp_out[i].p)[j].y = 2.0;
316      }
317   }
318
319   /* Create some output data: a struct which holds an array of
320    * struct s1. */
321   for (i = 0; i < DIM2_LENi++)
322      for (j = 0; j < NUM_S1j++)
323      {
324  comp_array_of_comp_out[i].data[j].x = 42.42;
325  comp_array_of_comp_out[i].data[j].y = 2.0;
326      }
327
328   /* Create some output data: a struct which holds an array of
329    * vlen of struct s1. */
330   for (i = 0; i < DIM3_LENi++)
331      for (j = 0; j < NUM_VLj++)
332      {
333  comp_array_of_vlen_of_comp_out[i].data[j].len = i + 1;
334  if (!(comp_array_of_vlen_of_comp_out[i].data[j].p = malloc(sizeof(struct s1) * comp_array_of_vlen_of_comp_out[i].data[j].len)))
335     return NC_ENOMEM;
336  for (k = 0; k < comp_array_of_vlen_of_comp_out[i].data[j].lenk++)
337  {
338     ((struct s1 *)comp_array_of_vlen_of_comp_out[i].data[j].p)[k].x = 42.42;
339     ((struct s1 *)comp_array_of_vlen_of_comp_out[i].data[j].p)[k].y = 2.0;
340  }
341      }
342
343
344   printf("*** testing of vlen of compound type...");
345   {
346      nc_type s1_typeidvlen_typeid;
347
348      /* Create a netCDF-4 file. */
349      if (nc_create(FILE_NAME_1NC_NETCDF4, &ncid)) ERR;
350
351      /* Create a simple compound type which has different sizes on
352       * different platforms - our old friend struct s1. */
353      if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
354      if (nc_insert_compound(ncids1_typeidX_NAME,
355      NC_COMPOUND_OFFSET(struct s1x), NC_FLOAT)) ERR;
356      if (nc_insert_compound(ncids1_typeidY_NAME,
357      NC_COMPOUND_OFFSET(struct s1y), NC_DOUBLE)) ERR;
358
359      /* Now make a new type: a vlen of our compound type. */
360      if (nc_def_vlen(ncidVLEN_NAMEs1_typeid, &vlen_typeid)) ERR;
361
362      /* Write the output data as an attribute. */
363      if (nc_put_att(ncidNC_GLOBALVLEN_ATT_NAMEvlen_typeid,
364            DIM1_LENvlen_of_comp_out)) ERR;
365
366      /* How does it look? */
367      if (check_file_1(ncidvlen_of_comp_out)) ERR;
368
369      /* We're done - wasn't that easy? */
370      if (nc_close(ncid)) ERR;
371
372      /* Check it out. */
373      if (nc_open(FILE_NAME_1NC_NOWRITE, &ncid)) ERR;
374      if (check_file_1(ncidvlen_of_comp_out)) ERR;
375      if (nc_close(ncid)) ERR;
376   }
377   SUMMARIZE_ERR;
378   printf("*** testing Solaris-written vlen of compound type...");
379   {
380      char file_in[NC_MAX_NAME + 1];
381
382      strcpy(file_in, "");
383      if (getenv("srcdir"))
384      {
385  strcat(file_in, getenv("srcdir"));
386  strcat(file_in, "/");
387      }
388      strcat(file_inREF_FILE_NAME_1);
389
390      /* Check out the same file, generated on buddy and included with
391       * the distribution. */
392      if (nc_open(file_inNC_NOWRITE, &ncid)) ERR;
393      if (check_file_1(ncidvlen_of_comp_out)) ERR;
394      if (nc_close(ncid)) ERR;
395   }
396   SUMMARIZE_ERR;
397   printf("*** testing compound type containing array of compound type...");
398   {
399      nc_type s1_typeids2_typeid;
400      int dimsizes[1] = {NUM_S1};
401
402      /* Create a netCDF-4 file. */
403      if (nc_create(FILE_NAME_2NC_NETCDF4, &ncid)) ERR;
404
405      /* Create a simple compound type which has different sizes on
406       * different platforms - our old friend struct s1. */
407      if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
408      if (nc_insert_compound(ncids1_typeidX_NAME,
409      NC_COMPOUND_OFFSET(struct s1x), NC_FLOAT)) ERR;
410      if (nc_insert_compound(ncids1_typeidY_NAME,
411      NC_COMPOUND_OFFSET(struct s1y), NC_DOUBLE)) ERR;
412
413      /* Now make a compound type that holds an array of the struct s1
414       * type. */
415      if (nc_def_compound(ncid, sizeof(struct s2), S2_TYPE_NAME, &s2_typeid)) ERR;
416      if (nc_insert_array_compound(ncids2_typeidS1_NAME,
417    NC_COMPOUND_OFFSET(struct s2data),
418    s1_typeid, 1, dimsizes)) ERR;
419
420
421      /* Write the output data as an attribute. */
422      if (nc_put_att(ncidNC_GLOBALS2_ATT_NAMEs2_typeid,
423      DIM2_LENcomp_array_of_comp_out)) ERR;
424
425      /* How does it look? */
426      if (check_file_2(ncidcomp_array_of_comp_out)) ERR;
427
428      /* We're done - wasn't that easy? */
429      if (nc_close(ncid)) ERR;
430
431      /* Check it out. */
432      if (nc_open(FILE_NAME_2NC_NOWRITE, &ncid)) ERR;
433      if (check_file_2(ncidcomp_array_of_comp_out)) ERR;
434      if (nc_close(ncid)) ERR;
435   }
436   SUMMARIZE_ERR;
437   printf("*** testing Solaris-written compound type containing array of compound type...");
438   {
439      char file_in[NC_MAX_NAME + 1];
440
441      strcpy(file_in, "");
442      if (getenv("srcdir"))
443      {
444  strcat(file_in, getenv("srcdir"));
445  strcat(file_in, "/");
446      }
447      strcat(file_inREF_FILE_NAME_2);
448
449      /* Check out the same file, generated on buddy and included with
450       * the distribution. */
451      if (nc_open(file_inNC_NOWRITE, &ncid)) ERR;
452      if (check_file_2(ncidcomp_array_of_comp_out)) ERR;
453      if (nc_close(ncid)) ERR;
454   }
455   SUMMARIZE_ERR;
456   printf("*** testing compound attribute containing array of vlen of compound type...");
457   {
458      nc_type vlen_typeids3_typeids1_typeid;
459      int dimsizes[1] = {NUM_VL};
460
461      /* Create a netCDF-4 file. */
462      if (nc_create(FILE_NAME_3NC_NETCDF4, &ncid)) ERR;
463
464      /* Create a simple compound type which has different sizes on
465       * different platforms - our old friend struct s1. */
466      if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
467      if (nc_insert_compound(ncids1_typeidX_NAME,
468      NC_COMPOUND_OFFSET(struct s1x), NC_FLOAT)) ERR;
469      if (nc_insert_compound(ncids1_typeidY_NAME,
470      NC_COMPOUND_OFFSET(struct s1y), NC_DOUBLE)) ERR;
471
472      /* Now make a new type: a vlen of our s1 compound type. */
473      if (nc_def_vlen(ncidVLEN_NAMEs1_typeid, &vlen_typeid)) ERR;
474
475      /* Now make a compound type that holds an array of the VLEN
476       * type. */
477      if (nc_def_compound(ncid, sizeof(struct s3), S3_TYPE_NAME, &s3_typeid)) ERR;
478      if (nc_insert_array_compound(ncids3_typeidVL_NAME,
479    NC_COMPOUND_OFFSET(struct s3data),
480    vlen_typeid, 1, dimsizes)) ERR;
481
482
483      /* Write the output data as an attribute. */
484      if (nc_put_att(ncidNC_GLOBALS3_ATT_NAMEs3_typeid,
485      DIM3_LENcomp_array_of_vlen_of_comp_out)) ERR;
486
487      /* How does it look? */
488      if (check_file_3(ncidcomp_array_of_vlen_of_comp_out)) ERR;
489
490      /* We're done - wasn't that easy? */
491      if (nc_close(ncid)) ERR;
492
493      /* Check it out. */
494      if (nc_open(FILE_NAME_3NC_NOWRITE, &ncid)) ERR;
495      if (check_file_3(ncidcomp_array_of_vlen_of_comp_out)) ERR;
496      if (nc_close(ncid)) ERR;
497   }
498   SUMMARIZE_ERR;
499/*    printf("*** testing Solaris-written compound containing array of vlen of compound type..."); */
500/*    { */
501/*       /\* Check out the same file, generated on buddy and included with */
502/*        * the distribution. *\/ */
503/*       if (nc_open(REF_FILE_NAME_3, NC_NOWRITE, &ncid)) ERR; */
504/*       if (check_file_3(ncid, comp_array_of_vlen_of_comp_out)) ERR; */
505/*       if (nc_close(ncid)) ERR; */
506/*    } */
507/*    SUMMARIZE_ERR; */
508   printf("*** testing compound variable containing array of vlen of compound type...");
509   {
510      nc_type vlen_typeids3_typeids1_typeid;
511      int variddimid;
512      int dimsizes[1] = {NUM_VL};
513
514      /* Create a netCDF-4 file. */
515      if (nc_create(FILE_NAME_4NC_NETCDF4, &ncid)) ERR;
516
517      /* Create a simple compound type which has different sizes on
518       * different platforms - our old friend struct s1. */
519      if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
520      if (nc_insert_compound(ncids1_typeidX_NAME,
521      NC_COMPOUND_OFFSET(struct s1x), NC_FLOAT)) ERR;
522      if (nc_insert_compound(ncids1_typeidY_NAME,
523      NC_COMPOUND_OFFSET(struct s1y), NC_DOUBLE)) ERR;
524
525      /* Now make a new type: a vlen of our s1 compound type. */
526      if (nc_def_vlen(ncidVLEN_NAMEs1_typeid, &vlen_typeid)) ERR;
527
528      /* Now make a compound type that holds an array of the VLEN
529       * type. */
530      if (nc_def_compound(ncid, sizeof(struct s3), S3_TYPE_NAME, &s3_typeid)) ERR;
531      if (nc_insert_array_compound(ncids3_typeidVL_NAME,
532    NC_COMPOUND_OFFSET(struct s3data),
533    vlen_typeid, 1, dimsizes)) ERR;
534
535      /* Create a dimension and a var of s3 type, then write the
536       * data. */
537      if (nc_def_dim(ncidDIM3_NAMEDIM3_LEN, &dimid)) ERR;
538      if (nc_def_var(ncidVAR3_NAMEs3_typeid, 1, &dimid, &varid)) ERR;
539      if (nc_put_var(ncidvaridcomp_array_of_vlen_of_comp_out)) ERR;
540
541      /* How does it look? */
542      if (check_file_4(ncidcomp_array_of_vlen_of_comp_out)) ERR;
543
544      /* We're done - wasn't that easy? */
545      if (nc_close(ncid)) ERR;
546
547      /* Check it out. */
548      if (nc_open(FILE_NAME_4NC_NOWRITE, &ncid)) ERR;
549      if (check_file_4(ncidcomp_array_of_vlen_of_comp_out)) ERR;
550      if (nc_close(ncid)) ERR;
551   }
552   SUMMARIZE_ERR;
553
554   /* Free our mallocs. */
555   for (i = 0; i < DIM1_LENi++)
556      free(vlen_of_comp_out[i].p);
557   for (i = 0; i < DIM3_LENi++)
558      for (j = 0; j < NUM_VLj++)
559  free(comp_array_of_vlen_of_comp_out[i].data[j].p);
560
561   free(comp_array_of_comp_out);
562   free(comp_array_of_vlen_of_comp_out);
563   free(vlen_of_comp_out);
564
565   FINAL_RESULTS;
566}


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