1 /* This is part of the netCDF package.  Copyright 2018 University
2    Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
3    conditions of use.
4 
5    This program sets up HDF5 files that contain scalar attributes and
6    variables, of both string and numeric datatypes.  ncdump should handle
7    all of these.
8 
9    Russ Rew
10 */
11 
12 #include <nc_tests.h>
13 #include "err_macros.h"
14 #include <hdf5.h>
15 
16 #define FILE_NAME "tst_h_scalar.nc"
17 #define VSTR_ATT1_NAME  "vstratt1"
18 #define VSTR_ATT2_NAME  "vstratt2"
19 #define VSTR_ATT3_NAME  "vstratt3"
20 #define VSTR_ATT4_NAME  "vstratt4"
21 #define VSTR_VAR1_NAME  "vstrvar1"
22 #define VSTR_VAR2_NAME  "vstrvar2"
23 #define VSTR_VAR3_NAME  "vstrvar3"
24 #define VSTR_VAR4_NAME  "vstrvar4"
25 #define FSTR_ATT_NAME   "fstratt"
26 #define FSTR_VAR_NAME   "fstrvar"
27 #define INT_ATT_NAME    "intatt"
28 #define INT_VAR_NAME    "intvar"
29 
30 int
add_attrs(hid_t objid)31 add_attrs(hid_t objid)
32 {
33     hid_t scalar_spaceid = -1;
34     hid_t vlstr_typeid = -1, fixstr_typeid = -1;
35     char *vlstr;
36     hid_t attid = -1;
37 
38     /* Create scalar dataspace */
39     if ((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR_GOTO;
40 
41     /* Create string datatypes */
42     if ((vlstr_typeid = H5Tcreate(H5T_STRING, (size_t)H5T_VARIABLE)) < 0) ERR_GOTO;
43     if ((fixstr_typeid = H5Tcreate(H5T_STRING, (size_t)10)) < 0) ERR_GOTO;
44 
45 
46     /* Create attribute with VL string datatype on object */
47     if ((attid = H5Acreate2(objid, VSTR_ATT1_NAME, vlstr_typeid, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR_GOTO;
48     /* No write, use fill value */
49     if (H5Aclose(attid) < 0) ERR_GOTO;
50 
51     /* Create attribute with VL string datatype on object */
52     if ((attid = H5Acreate2(objid, VSTR_ATT2_NAME, vlstr_typeid, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR_GOTO;
53     vlstr = NULL;
54     if (H5Awrite(attid, vlstr_typeid, &vlstr) < 0) ERR_GOTO;
55     if (H5Aclose(attid) < 0) ERR_GOTO;
56 
57     /* Create attribute with VL string datatype on object */
58     if ((attid = H5Acreate2(objid, VSTR_ATT3_NAME, vlstr_typeid, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR_GOTO;
59     vlstr = malloc(10);
60     *vlstr = '\0';
61     if (H5Awrite(attid, vlstr_typeid, &vlstr) < 0) ERR_GOTO;
62     if (H5Aclose(attid) < 0) ERR_GOTO;
63 
64     /* Create attribute with VL string datatype on object */
65     if ((attid = H5Acreate2(objid, VSTR_ATT4_NAME, vlstr_typeid, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR_GOTO;
66     strcpy(vlstr, "foo");
67     if (H5Awrite(attid, vlstr_typeid, &vlstr) < 0) ERR_GOTO;
68     free(vlstr);
69     if (H5Aclose(attid) < 0) ERR_GOTO;
70 
71     /* Create attribute with fixed-length string datatype on object */
72     if ((attid = H5Acreate2(objid, FSTR_ATT_NAME, fixstr_typeid, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR_GOTO;
73     if (H5Aclose(attid) < 0) ERR_GOTO;
74 
75     /* Create attribute with native integer datatype on object */
76     if ((attid = H5Acreate2(objid, INT_ATT_NAME, H5T_NATIVE_INT, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR_GOTO;
77     if (H5Aclose(attid) < 0) ERR_GOTO;
78 
79 
80     /* Clean up objects created */
81     if (H5Sclose(scalar_spaceid) < 0) ERR_GOTO;
82     if (H5Tclose(vlstr_typeid) < 0) ERR_GOTO;
83     if (H5Tclose(fixstr_typeid) < 0) ERR_GOTO;
84 
85     return(0);
86 
87 error:
88     H5E_BEGIN_TRY {
89         H5Aclose(attid);
90         H5Sclose(scalar_spaceid);
91         H5Tclose(vlstr_typeid);
92         H5Tclose(fixstr_typeid);
93     } H5E_END_TRY;
94     return(-1);
95 }
96 
97 int
main()98 main()
99 {
100     printf("\n*** Create file with datasets & attributes that have scalar dataspaces...");
101     {
102 	hid_t fileid;
103         hid_t fcplid;
104 	hid_t dsetid;
105         hid_t dcplid;
106 	hid_t scalar_spaceid;
107         hid_t vlstr_typeid, fixstr_typeid;
108 
109         /* Create scalar dataspace */
110 	if ((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;
111 
112         /* Set creation ordering for file, so we can revise its contents later */
113         if ((fcplid = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
114         if (H5Pset_link_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
115         if (H5Pset_attr_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
116 
117 	/* Create new file, using default properties */
118 	if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcplid, H5P_DEFAULT)) < 0) ERR;
119 
120         /* Close file creation property list */
121         if (H5Pclose(fcplid) < 0) ERR;
122 
123 
124         /* Create variable-length string datatype */
125         if ((vlstr_typeid = H5Tcreate(H5T_STRING, (size_t)H5T_VARIABLE)) < 0) ERR;
126 
127         /* Create fixed-length string datatype */
128         if ((fixstr_typeid = H5Tcreate(H5T_STRING, (size_t)10)) < 0) ERR;
129 
130 
131         /* Set creation ordering for dataset, so we can revise its contents later */
132         if ((dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
133         if (H5Pset_attr_creation_order(dcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
134 
135 
136         /* Create scalar dataset with VL string datatype */
137         if ((dsetid = H5Dcreate2(fileid, VSTR_VAR1_NAME, vlstr_typeid, scalar_spaceid, H5P_DEFAULT, dcplid, H5P_DEFAULT)) < 0) ERR;
138 
139         /* Add attributes to dataset */
140         if (add_attrs(dsetid) < 0) ERR;
141 
142         /* Close VL string dataset */
143         if (H5Dclose(dsetid) < 0) ERR;
144 
145 
146         /* Create scalar dataset with fixed-length string datatype */
147         if ((dsetid = H5Dcreate2(fileid, FSTR_VAR_NAME, fixstr_typeid, scalar_spaceid, H5P_DEFAULT, dcplid, H5P_DEFAULT)) < 0) ERR;
148 
149         /* Add attributes to dataset */
150         if (add_attrs(dsetid) < 0) ERR;
151 
152         /* Close fixed-length string dataset */
153         if (H5Dclose(dsetid) < 0) ERR;
154 
155 
156         /* Create scalar dataset with native integer datatype */
157         if ((dsetid = H5Dcreate2(fileid, INT_VAR_NAME, H5T_NATIVE_INT, scalar_spaceid, H5P_DEFAULT, dcplid, H5P_DEFAULT)) < 0) ERR;
158 
159         /* Add attributes to dataset */
160         if (add_attrs(dsetid) < 0) ERR;
161 
162         /* Close native integer dataset */
163         if (H5Dclose(dsetid) < 0) ERR;
164 
165 
166         /* Add attributes to root group */
167         if (add_attrs(fileid) < 0) ERR;
168 
169 
170         /* Close dataset creation property list */
171         if (H5Pclose(dcplid) < 0) ERR;
172 
173         /* Close string datatypes */
174         if (H5Tclose(vlstr_typeid) < 0) ERR;
175         if (H5Tclose(fixstr_typeid) < 0) ERR;
176 
177 
178         /* Close rest */
179 	if (H5Sclose(scalar_spaceid) < 0) ERR;
180 	if (H5Fclose(fileid) < 0) ERR;
181     }
182     SUMMARIZE_ERR;
183 
184     printf("*** Revise file through netCDF-4 API...");
185     {
186 	int ncid, varid;
187         char *vlstr;
188 
189 	if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
190 
191 
192         /* Define new VL string variable */
193         if (nc_def_var(ncid, VSTR_VAR2_NAME , NC_STRING, 0, NULL, &varid)) ERR;
194 
195         /* Write to the variable */
196         vlstr = NULL;
197         if (nc_put_var(ncid, varid, &vlstr)) ERR;
198 
199 
200         /* Define new VL string variable */
201         if (nc_def_var(ncid, VSTR_VAR3_NAME , NC_STRING, 0, NULL, &varid)) ERR;
202 
203         /* Write to the variable */
204         vlstr = malloc(10);
205         *vlstr = '\0';
206         if (nc_put_var(ncid, varid, &vlstr)) ERR;
207 
208 
209         /* Define new VL string variable */
210         if (nc_def_var(ncid, VSTR_VAR4_NAME , NC_STRING, 0, NULL, &varid)) ERR;
211 
212         /* Write to the variable */
213         strcpy(vlstr, "foo");
214         if (nc_put_var(ncid, varid, &vlstr)) ERR;
215         free(vlstr);
216 
217 
218 	if (nc_close(ncid)) ERR;
219     }
220     SUMMARIZE_ERR;
221 
222     FINAL_RESULTS;
223 }
224