1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /************************************************************
15   This example shows how to commit a named datatype to a
16   file, and read back that datatype.  The program first
17   defines a compound datatype, commits it to a file, then
18   closes the file.  Next, it reopens the file, opens the
19   datatype, and outputs the names of its fields to the
20   screen.
21  ************************************************************/
22 
23 package examples.datatypes;
24 
25 import hdf.hdf5lib.H5;
26 import hdf.hdf5lib.HDF5Constants;
27 
28 import java.util.EnumSet;
29 import java.util.HashMap;
30 import java.util.Map;
31 
32 public class H5Ex_T_Commit {
33     private static String FILENAME = "H5Ex_T_Commit.h5";
34     private static String DATATYPENAME = "Sensor_Type";
35     protected static final int INTEGERSIZE = 4;
36     protected static final int DOUBLESIZE = 8;
37     protected final static int MAXSTRINGSIZE = 80;
38 
39     // Values for the various classes of datatypes
40     enum H5T_class {
41         H5T_NO_CLASS(HDF5Constants.H5T_NO_CLASS), // error
42         H5T_INTEGER(HDF5Constants.H5T_INTEGER), // integer types
43         H5T_FLOAT(HDF5Constants.H5T_FLOAT), // floating-point types
44         H5T_TIME(HDF5Constants.H5T_TIME), // date and time types
45         H5T_STRING(HDF5Constants.H5T_STRING), // character string types
46         H5T_BITFIELD(HDF5Constants.H5T_BITFIELD), // bit field types
47         H5T_OPAQUE(HDF5Constants.H5T_OPAQUE), // opaque types
48         H5T_COMPOUND(HDF5Constants.H5T_COMPOUND), // compound types
49         H5T_REFERENCE(HDF5Constants.H5T_REFERENCE), // reference types
50         H5T_ENUM(HDF5Constants.H5T_ENUM), // enumeration types
51         H5T_VLEN(HDF5Constants.H5T_VLEN), // Variable-Length types
52         H5T_ARRAY(HDF5Constants.H5T_ARRAY), // Array types
53         H5T_NCLASSES(11); // this must be last
54 
55         private static final Map<Long, H5T_class> lookup = new HashMap<Long, H5T_class>();
56 
57         static {
58             for (H5T_class s : EnumSet.allOf(H5T_class.class))
s.getCode()59                 lookup.put(s.getCode(), s);
60         }
61 
62         private long code;
63 
H5T_class(long layout_type)64         H5T_class(long layout_type) {
65             this.code = layout_type;
66         }
67 
getCode()68         public long getCode() {
69             return this.code;
70         }
71 
get(long typeclass_id)72         public static H5T_class get(long typeclass_id) {
73             return lookup.get(typeclass_id);
74         }
75     }
76 
77     // The supporting Sensor_Datatype class.
78     private static class Sensor_Datatype {
79         static int numberMembers = 4;
80         static int[] memberDims = { 1, 1, 1, 1 };
81 
82         String[] memberNames = { "Serial number", "Location", "Temperature (F)", "Pressure (inHg)" };
83         long[] memberFileTypes = { HDF5Constants.H5T_STD_I32BE, HDF5Constants.H5T_C_S1, HDF5Constants.H5T_IEEE_F64BE,
84                 HDF5Constants.H5T_IEEE_F64BE };
85         static int[] memberStorage = { INTEGERSIZE, MAXSTRINGSIZE, DOUBLESIZE, DOUBLESIZE };
86 
87         // Data size is the storage size for the members not the object.
getDataSize()88         static long getDataSize() {
89             long data_size = 0;
90             for (int indx = 0; indx < numberMembers; indx++)
91                 data_size += memberStorage[indx] * memberDims[indx];
92             return data_size;
93         }
94 
getOffset(int memberItem)95         static int getOffset(int memberItem) {
96             int data_offset = 0;
97             for (int indx = 0; indx < memberItem; indx++)
98                 data_offset += memberStorage[indx];
99             return data_offset;
100         }
101     }
102 
CreateDataType()103     private static void CreateDataType() {
104         long file_id = -1;
105         long strtype_id = -1;
106         long filetype_id = -1;
107         Sensor_Datatype datatypes = new Sensor_Datatype();
108         // Create a new file using default properties.
109         try {
110             file_id = H5.H5Fcreate(FILENAME, HDF5Constants.H5F_ACC_TRUNC, HDF5Constants.H5P_DEFAULT,
111                     HDF5Constants.H5P_DEFAULT);
112         }
113         catch (Exception e) {
114             e.printStackTrace();
115         }
116 
117         // Create string datatype.
118         try {
119             strtype_id = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
120             if (strtype_id >= 0)
121                 H5.H5Tset_size(strtype_id, MAXSTRINGSIZE);
122         }
123         catch (Exception e) {
124             e.printStackTrace();
125         }
126 
127         // Create the compound datatype for the file. Because the standard
128         // types we are using for the file may have different sizes than
129         // the corresponding native types, we must manually calculate the
130         // offset of each member.
131         try {
132             filetype_id = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, Sensor_Datatype.getDataSize());
133             if (filetype_id >= 0) {
134                 for (int indx = 0; indx < Sensor_Datatype.numberMembers; indx++) {
135                     long type_id = datatypes.memberFileTypes[indx];
136                     if (type_id == HDF5Constants.H5T_C_S1)
137                         type_id = strtype_id;
138                     H5.H5Tinsert(filetype_id, datatypes.memberNames[indx], Sensor_Datatype.getOffset(indx), type_id);
139                 }
140             }
141         }
142         catch (Exception e) {
143             e.printStackTrace();
144         }
145 
146         // Commit the compound datatype to the file, creating a named datatype.
147         try {
148             if ((file_id >= 0) && (filetype_id >= 0))
149                 H5.H5Tcommit(file_id, DATATYPENAME, filetype_id, HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT,
150                         HDF5Constants.H5P_DEFAULT);
151         }
152         catch (Exception e) {
153             e.printStackTrace();
154         }
155 
156         // Terminate access to the file type.
157         try {
158             if (filetype_id >= 0)
159                 H5.H5Tclose(filetype_id);
160         }
161         catch (Exception e) {
162             e.printStackTrace();
163         }
164 
165         // Terminate access to the str type.
166         try {
167             if (strtype_id >= 0)
168                 H5.H5Tclose(strtype_id);
169         }
170         catch (Exception e) {
171             e.printStackTrace();
172         }
173 
174         // Close the file.
175         try {
176             if (file_id >= 0)
177                 H5.H5Fclose(file_id);
178         }
179         catch (Exception e) {
180             e.printStackTrace();
181         }
182 
183     }
184 
ReadDataType()185     private static void ReadDataType() {
186         long file_id = -1;
187         long typeclass_id = -1;
188         long filetype_id = -1;
189 
190         // Open an existing file.
191         try {
192             file_id = H5.H5Fopen(FILENAME, HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT);
193         }
194         catch (Exception e) {
195             e.printStackTrace();
196         }
197 
198         // Open named datatype.
199         try {
200             if (file_id >= 0)
201                 filetype_id = H5.H5Topen(file_id, DATATYPENAME, HDF5Constants.H5P_DEFAULT);
202         }
203         catch (Exception e) {
204             e.printStackTrace();
205         }
206 
207         // Output the data to the screen.
208         System.out.println("Named datatype:  " + DATATYPENAME + ":");
209 
210         // Get datatype class. If it isn't compound, we won't print anything.
211         try {
212             if (filetype_id >= 0)
213                 typeclass_id = H5.H5Tget_class(filetype_id);
214         }
215         catch (Exception e) {
216             e.printStackTrace();
217         }
218         // Read data.
219         try {
220             if (H5T_class.get(typeclass_id) == H5T_class.H5T_COMPOUND) {
221                 System.out.println("   Class: H5T_COMPOUND");
222                 int nmembs = H5.H5Tget_nmembers(filetype_id);
223                 // Iterate over compound datatype members.
224                 for (int indx = 0; indx < nmembs; indx++) {
225                     String member_name = H5.H5Tget_member_name(filetype_id, indx);
226                     System.out.println("    " + member_name);
227                 }
228             }
229         }
230         catch (Exception e) {
231             e.printStackTrace();
232         }
233 
234         // Terminate access to the mem type.
235         try {
236             if (filetype_id >= 0)
237                 H5.H5Tclose(filetype_id);
238         }
239         catch (Exception e) {
240             e.printStackTrace();
241         }
242 
243         // Close the file.
244         try {
245             if (file_id >= 0)
246                 H5.H5Fclose(file_id);
247         }
248         catch (Exception e) {
249             e.printStackTrace();
250         }
251 
252     }
253 
main(String[] args)254     public static void main(String[] args) {
255         H5Ex_T_Commit.CreateDataType();
256         // Now we begin the read section of this example. Here we assume
257         // the dataset and array have the same name and rank, but can have
258         // any size. Therefore we must allocate a new array to read in
259         // data using malloc().
260         H5Ex_T_Commit.ReadDataType();
261     }
262 
263 }
264