1 /* This is part of the netCDF package.  Copyright 2005-2018,
2    University Corporation for Atmospheric Research/Unidata. See
3    COPYRIGHT file for conditions of use.
4 
5    Test that NetCDF-4 can read HDF4 files.
6    Ed Hartnett, Ward Fisher
7 */
8 #include <config.h>
9 #include <nc_tests.h>
10 #include "err_macros.h"
11 #include <mfhdf.h>
12 #include <netcdf_f.h>
13 
14 #define FILE_NAME "tst_hdf4_extra.h4"
15 
16 #define PRES_NAME "pres"
17 #define LAT_LEN 3
18 #define LON_LEN 2
19 #define NDIMS2 2
20 #define ATT_NAME "Caesar"
21 #define NAME_DUMB "Bozo"
22 
23 int
create_hdf4_file()24 create_hdf4_file()
25 {
26    int32 sd_id, sds_id;
27    int32 dim_size[NDIMS2] = {LAT_LEN, LON_LEN};
28    int32 start[NDIMS2] = {0, 0}, edge[NDIMS2] = {LAT_LEN, LON_LEN};
29    int data_out[LAT_LEN][LON_LEN];
30    int test_val = 42;
31    int i, j;
32    int count = 0;
33 
34    /* Create some data. */
35    for (i = 0; i < LAT_LEN; i++)
36       for (j = 0; j < LON_LEN; j++)
37          data_out[i][j] = count++;
38 
39    /* Create a file with one SDS, containing our phony data. */
40    sd_id = SDstart(FILE_NAME, DFACC_CREATE);
41    sds_id = SDcreate(sd_id, PRES_NAME, DFNT_INT32, NDIMS2, dim_size);
42    if (SDwritedata(sds_id, start, NULL, edge, (void *)data_out)) ERR;
43 
44    /* Add a global attribute. */
45    if (SDsetattr(sd_id, ATT_NAME, DFNT_INT32, 1, &test_val)) ERR;
46 
47    /* Shut down. */
48    if (SDendaccess(sds_id)) ERR;
49    if (SDend(sd_id)) ERR;
50 
51    return 0;
52 }
53 
54 int
main(int argc,char ** argv)55 main(int argc, char **argv)
56 {
57    printf("\n*** Testing HDF4/NetCDF-4 interoperability extra stuff...\n");
58 
59    /* Create our test file. */
60    if (create_hdf4_file()) ERR;
61 
62    printf("*** testing data conversion...");
63    {
64       int ncid;
65       size_t start[NDIMS2] = {0, 0}, count[NDIMS2] = {LAT_LEN, LON_LEN};
66       int data_int[LAT_LEN * LON_LEN];
67       short data_short[LAT_LEN * LON_LEN];
68       int data_int2[LAT_LEN * LON_LEN];
69       float data_float[LAT_LEN * LON_LEN];
70       double data_double[LAT_LEN * LON_LEN];
71       int i = 0;
72 
73       /* Open HDF4 file with netCDF. */
74       if (nc_open(FILE_NAME, 0, &ncid)) ERR;
75 
76       /* These won't work. */
77       if (nc_get_vara_int(ncid, 0, NULL, count, data_int) != NC_EINVALCOORDS) ERR;
78       if (nc_get_vara_int(ncid + TEST_VAL_42, 0, start, count, data_int) != NC_EBADID) ERR;
79 
80       /* Read data as short. */
81       if (nc_get_vara_short(ncid, 0, start, count, data_short)) ERR;
82       for (i = 0; i < LAT_LEN * LON_LEN; i++)
83          if (data_short[i] != (short)i) ERR;
84 
85       /* Read data as int. */
86       if (nc_get_vara_int(ncid, 0, start, count, data_int)) ERR;
87       for (i = 0; i < LAT_LEN * LON_LEN; i++)
88          if (data_int[i] != i) ERR;
89 
90       /* NULL count is treated as meaing entire variable. */
91       if (nc_get_vara_int(ncid, 0, start, NULL, data_int2)) ERR;
92       for (i = 0; i < LAT_LEN * LON_LEN; i++)
93          if (data_int2[i] != i) ERR;
94 
95       /* Read data as float. */
96       if (nc_get_vara_float(ncid, 0, start, count, data_float)) ERR;
97       for (i = 0; i < LAT_LEN * LON_LEN; i++)
98          if (data_float[i] != (float)i) ERR;
99 
100       /* Read data as double. */
101       if (nc_get_vara_double(ncid, 0, start, count, data_double)) ERR;
102       for (i = 0; i < LAT_LEN * LON_LEN; i++)
103          if (data_double[i] != (double)i) ERR;
104 
105       /* Close the file. */
106       if (nc_close(ncid)) ERR;
107    }
108    SUMMARIZE_ERR;
109    printf("*** testing bad parameters, read-only writes, and abort...");
110    {
111       int ncid;
112       int ndims, nvars, ngatts, unlimdimid;
113       size_t start[NDIMS2] = {0, 0}, count[NDIMS2] = {1, 1};
114       int test_val;
115 
116       /* These will not work. */
117       if (nc_open(FILE_NAME, NC_MMAP, &ncid) != NC_EINVAL) ERR;
118       if (nc_open(FILE_NAME, NC_64BIT_OFFSET, &ncid) != NC_EINVAL) ERR;
119       if (nc_open(FILE_NAME, NC_DISKLESS, &ncid) != NC_EINVAL) ERR;
120 
121       /* Now open with netCDF. */
122       if (nc_open(FILE_NAME, 0, &ncid)) ERR;
123 
124       /* Check it out. */
125       if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
126       if (ndims != 2 || nvars != 1 || ngatts != 1 || unlimdimid != -1) ERR;
127       if (nc_inq(ncid, NULL, NULL, NULL, NULL)) ERR;
128       if (nc_inq(ncid + TEST_VAL_42, NULL, NULL, NULL, NULL) != NC_EBADID) ERR;
129 
130       /* These only work for netCDF-3 files. */
131       if (nc_set_base_pe(ncid, 0) != NC_ENOTNC3) ERR;
132       if (nc_inq_base_pe(ncid, NULL) != NC_ENOTNC3) ERR;
133 
134       /* Attempt to write. */
135       if (nc_rename_att(ncid, NC_GLOBAL, ATT_NAME, NAME_DUMB) != NC_EPERM) ERR;
136       if (nc_del_att(ncid, NC_GLOBAL, ATT_NAME) != NC_EPERM) ERR;
137       if (nc_put_att_int(ncid, NC_GLOBAL, NAME_DUMB, NC_INT, 0, NULL) != NC_EPERM) ERR;
138       if (nc_def_dim(ncid, NAME_DUMB, 1, NULL) != NC_EPERM) ERR;
139       if (nc_def_var(ncid, "hh", NC_INT, 0, NULL, NULL) != NC_EPERM) ERR;
140       if (nc_def_var_fill(ncid, 0, 0, &test_val) != NC_EPERM) ERR;
141       if (nc_rename_var(ncid, 0, NAME_DUMB) != NC_EPERM) ERR;
142       if (nc_put_vara_int(ncid, 0, start, count, &test_val) != NC_EPERM) ERR;
143       if (nc_set_fill(ncid, 0, NULL) != NC_EPERM) ERR;
144       if (nc_rename_dim(ncid, 0, NULL) != NC_EPERM) ERR;
145 
146       /* These succeed but do nothing. */
147       if (nc_enddef(ncid)) ERR;
148       if (nc_sync(ncid)) ERR;
149 
150       /* These netcdf-4 operations are not supported. */
151       if (nc_def_var_filter(ncid, 0, 0, 0, NULL) != NC_ENOTNC4) ERR;
152       if (nc_def_var_fletcher32(ncid, 0, 0) != NC_ENOTNC4) ERR;
153       if (nc_def_var_endian(ncid, 0, 0) != NC_ENOTNC4) ERR;
154       if (nc_def_grp(ncid, NAME_DUMB, NULL) != NC_ENOTNC4) ERR;
155       if (nc_rename_grp(ncid, NAME_DUMB) != NC_ENOTNC4) ERR;
156       if (nc_def_compound(ncid, 1, NAME_DUMB, NULL) != NC_ENOTNC4) ERR;
157       if (nc_insert_compound(ncid, 1, NAME_DUMB, 1, 1) != NC_ENOTNC4) ERR;
158       if (nc_insert_array_compound(ncid, 1, NAME_DUMB, 1, 1, 1, NULL) != NC_ENOTNC4) ERR;
159       if (nc_inq_compound_field(ncid, 1, 1, NULL, NULL, NULL, NULL, NULL) != NC_ENOTNC4) ERR;
160       if (nc_inq_compound_fieldindex(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR;
161       if (nc_def_opaque(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR;
162       if (nc_def_vlen(ncid, NULL, 1, NULL) != NC_ENOTNC4) ERR;
163       if (nc_def_enum(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR;
164       if (nc_inq_enum_ident(ncid, 1, 1, NULL) != NC_ENOTNC4) ERR;
165       if (nc_inq_enum_member(ncid, 1, 1, NULL, NULL) != NC_ENOTNC4) ERR;
166       if (nc_insert_enum(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR;
167       if (nc_put_vlen_element(ncid, 1, NULL, 1, NULL) != NC_ENOTNC4) ERR;
168       if (nc_get_vlen_element(ncid, 1, NULL, NULL, NULL) != NC_ENOTNC4) ERR;
169       if (nc_set_var_chunk_cache(ncid, 1, 1, 1, 1.0) != NC_ENOTNC4) ERR;
170       if (nc_get_var_chunk_cache(ncid, 1, NULL, NULL, NULL) != NC_ENOTNC4) ERR;
171 
172       /* Abort is the same as nc_close, since HDF4 is read-only.) */
173       if (nc_abort(ncid)) ERR;
174    }
175    SUMMARIZE_ERR;
176    FINAL_RESULTS;
177 }
178