001/*****************************************************************************
002 * Copyright by The HDF Group.                                               *
003 * Copyright by the Board of Trustees of the University of Illinois.         *
004 * All rights reserved.                                                      *
005 *                                                                           *
006 * This file is part of the HDF Java Products distribution.                  *
007 * The full copyright notice, including terms governing use, modification,   *
008 * and redistribution, is contained in the files COPYING and Copyright.html. *
009 * COPYING can be found at the root of the source code distribution tree.    *
010 * Or, see https://support.hdfgroup.org/products/licenses.html               *
011 * If you do not have access to either file, you may request a copy from     *
012 * help@hdfgroup.org.                                                        *
013 ****************************************************************************/
014
015package hdf.object;
016
017/**
018 * An interface that provides general I/O operations for object data. For
019 * example, reading data content from the file into memory or writing data
020 * content from memory into the file.
021 *
022 * @see hdf.object.HObject
023 *
024 * @version 1.0 4/2/2018
025 * @author Jordan T. Henderson
026 */
027public interface DataFormat
028{
029    /**
030     * The status of initialization for this object
031     *
032     * @return true if the data has been initialized
033     */
034    boolean isInited();
035
036    /**
037     * Set the initial state of all the variables
038     */
039    void init();
040
041    /**
042     * Retrieves the object's data from the file.
043     *
044     * @return the object's data.
045     *
046     * @throws Exception
047     *             if the data can not be retrieved
048     */
049    Object getData() throws Exception, OutOfMemoryError;
050
051    /**
052     *
053     *
054     * @param data
055     *            the data to write.
056     */
057    void setData(Object data);
058
059    /**
060     * Clears the current data buffer in memory and forces the next read() to load
061     * the data from file.
062     *
063     * The function read() loads data from file into memory only if the data is not
064     * read. If data is already in memory, read() just returns the memory buffer.
065     * Sometimes we want to force read() to re-read data from file. For example,
066     * when the selection is changed, we need to re-read the data.
067     *
068     * @see #getData()
069     * @see #read()
070     */
071    void clearData();
072
073    /**
074     * Reads the data from file.
075     *
076     * read() reads the data from file to a memory buffer and returns the memory
077     * buffer. The dataset object does not hold the memory buffer. To store the
078     * memory buffer in the dataset object, one must call getData().
079     *
080     * By default, the whole dataset is read into memory. Users can also select
081     * a subset to read. Subsetting is done in an implicit way.
082     *
083     * @return the data read from file.
084     *
085     * @see #getData()
086     *
087     * @throws Exception
088     *             if object can not be read
089     * @throws OutOfMemoryError
090     *             if memory is exhausted
091     */
092    Object read() throws Exception, OutOfMemoryError;
093
094    /**
095     * Writes a memory buffer to the object in the file.
096     *
097     * @param buf
098     *            the data to write
099     *
100     * @throws Exception
101     *             if data can not be written
102     */
103    void write(Object buf) throws Exception;
104
105    /**
106     * Writes the current memory buffer to the object in the file.
107     *
108     * @throws Exception
109     *             if data can not be written
110     */
111    void write() throws Exception;
112
113    /**
114     * Converts the data values of this data object to appropriate Java integers if
115     * they are unsigned integers.
116     *
117     * @see hdf.object.Dataset#convertToUnsignedC(Object)
118     * @see hdf.object.Dataset#convertFromUnsignedC(Object, Object)
119     *
120     * @return the converted data buffer.
121     */
122    Object convertFromUnsignedC();
123
124    /**
125     * Converts Java integer data values of this data object back to unsigned C-type
126     * integer data if they are unsigned integers.
127     *
128     * @see hdf.object.Dataset#convertToUnsignedC(Object)
129     * @see hdf.object.Dataset#convertToUnsignedC(Object, Object)
130     *
131     * @return the converted data buffer.
132     */
133    Object convertToUnsignedC();
134
135    /**
136     * Returns the fill values for the data object.
137     *
138     * @return the fill values for the data object.
139     */
140    Object getFillValue();
141
142    /**
143     * Returns the datatype of the data object.
144     *
145     * @return the datatype of the data object.
146     */
147    Datatype getDatatype();
148
149    /**
150     * Returns the space type for the data object. It returns a
151     * negative number if it failed to retrieve the type information from
152     * the file.
153     *
154     * @return the space type for the data object.
155     */
156    int getSpaceType();
157
158    /**
159     * Returns the rank (number of dimensions) of the data object. It returns a
160     * negative number if it failed to retrieve the dimension information from
161     * the file.
162     *
163     * @return the number of dimensions of the data object.
164     */
165    int getRank();
166
167    /**
168     * Returns the array that contains the dimension sizes of the data value of
169     * the data object. It returns null if it failed to retrieve the dimension
170     * information from the file.
171     *
172     * @return the dimension sizes of the data object.
173     */
174    long[] getDims();
175
176
177    /****************************************************************
178     * * The following four definitions are used for data subsetting. * *
179     ****************************************************************/
180
181    /**
182     * Returns the dimension sizes of the selected subset.
183     *
184     * The SelectedDims is the number of data points of the selected subset.
185     * Applications can use this array to change the size of selected subset.
186     *
187     * The selected size must be less than or equal to the current dimension size.
188     * Combined with the starting position, selected sizes and stride, the subset of
189     * a rectangle selection is fully defined.
190     *
191     * For example, if a 4 X 5 dataset is as follows:
192     *
193     * <pre>
194     *     0,  1,  2,  3,  4
195     *    10, 11, 12, 13, 14
196     *    20, 21, 22, 23, 24
197     *    30, 31, 32, 33, 34
198     * long[] dims = {4, 5};
199     * long[] startDims = {1, 2};
200     * long[] selectedDims = {3, 3};
201     * long[] selectedStride = {1, 1};
202     * then the following subset is selected by the startDims and selectedDims
203     *     12, 13, 14
204     *     22, 23, 24
205     *     32, 33, 34
206     * </pre>
207     *
208     * @return the dimension sizes of the selected subset.
209     */
210    long[] getSelectedDims();
211
212    /**
213     * Returns the starting position of a selected subset.
214     *
215     * Applications can use this array to change the starting position of a
216     * selection. Combined with the selected dimensions, selected sizes and stride,
217     * the subset of a rectangle selection is fully defined.
218     *
219     * For example, if a 4 X 5 dataset is as follows:
220     *
221     * <pre>
222     *     0,  1,  2,  3,  4
223     *    10, 11, 12, 13, 14
224     *    20, 21, 22, 23, 24
225     *    30, 31, 32, 33, 34
226     * long[] dims = {4, 5};
227     * long[] startDims = {1, 2};
228     * long[] selectedDims = {3, 3};
229     * long[] selectedStride = {1, 1};
230     * then the following subset is selected by the startDims and selectedDims
231     *     12, 13, 14
232     *     22, 23, 24
233     *     32, 33, 34
234     * </pre>
235     *
236     * @return the starting position of a selected subset.
237     */
238    long[] getStartDims();
239
240    /**
241     * Returns the selectedStride of the selected dataset.
242     *
243     * Applications can use this array to change how many elements to move in each
244     * dimension.
245     *
246     * Combined with the starting position and selected sizes, the subset of a
247     * rectangle selection is defined.
248     *
249     * For example, if a 4 X 5 dataset is as follows:
250     *
251     * <pre>
252     *     0,  1,  2,  3,  4
253     *    10, 11, 12, 13, 14
254     *    20, 21, 22, 23, 24
255     *    30, 31, 32, 33, 34
256     * long[] dims = {4, 5};
257     * long[] startDims = {0, 0};
258     * long[] selectedDims = {2, 2};
259     * long[] selectedStride = {2, 3};
260     * then the following subset is selected by the startDims and selectedDims
261     *     0,   3
262     *     20, 23
263     * </pre>
264     *
265     * @return the selectedStride of the selected dataset.
266     */
267    long[] getStride();
268
269    /**
270     * Returns the indices of display order.
271     *
272     * selectedIndex[] is provided for two purposes:
273     * <OL>
274     * <LI>selectedIndex[] is used to indicate the order of dimensions for display.
275     * selectedIndex[0] is for the row, selectedIndex[1] is for the column and
276     * selectedIndex[2] for the depth.
277     *
278     * For example, for a four dimension dataset, if selectedIndex[] = {1, 2, 3},
279     * then dim[1] is selected as row index, dim[2] is selected as column index and
280     * dim[3] is selected as depth index.
281     * <LI>selectedIndex[] is also used to select dimensions for display for
282     * datasets with three or more dimensions. We assume that applications such as
283     * HDFView can only display data values up to three dimensions (2D
284     * spreadsheet/image with a third dimension which the 2D spreadsheet/image is
285     * selected from). For datasets with more than three dimensions, we need
286     * selectedIndex[] to tell applications which three dimensions are chosen for
287     * display. <br>
288     * For example, for a four dimension dataset, if selectedIndex[] = {1, 2, 3},
289     * then dim[1] is selected as row index, dim[2] is selected as column index and
290     * dim[3] is selected as depth index. dim[0] is not selected. Its location is
291     * fixed at 0 by default.
292     * </OL>
293     *
294     * @return the array of the indices of display order.
295     */
296    int[] getSelectedIndex();
297
298    /**************************************************************************
299     * * The following two definitions are used primarily for GUI applications. * *
300     **************************************************************************/
301
302    /**
303     * Returns the dimension size of the vertical axis.
304     *
305     *
306     * This function is used by GUI applications such as HDFView. GUI applications
307     * display a dataset in a 2D table or 2D image. The display order is specified
308     * by the index array of selectedIndex as follow:
309     * <dl>
310     * <dt>selectedIndex[0] -- height</dt>
311     * <dd>The vertical axis</dd>
312     * <dt>selectedIndex[1] -- width</dt>
313     * <dd>The horizontal axis</dd>
314     * <dt>selectedIndex[2] -- depth</dt>
315     * <dd>The depth axis is used for 3 or more dimensional datasets.</dd>
316     * </dl>
317     * Applications can use getSelectedIndex() to access and change the display
318     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
319     * following code will set the height=200 and width=50.
320     *
321     * <pre>
322     * int[] selectedIndex = dataset.getSelectedIndex();
323     * selectedIndex[0] = 0;
324     * selectedIndex[1] = 1;
325     * </pre>
326     *
327     * @see #getSelectedIndex()
328     * @see #getWidth()
329     *
330     * @return the size of dimension of the vertical axis.
331     */
332    long getHeight();
333
334    /**
335     * Returns the dimension size of the horizontal axis.
336     *
337     *
338     * This function is used by GUI applications such as HDFView. GUI applications
339     * display a dataset in 2D Table or 2D Image. The display order is specified by
340     * the index array of selectedIndex as follow:
341     * <dl>
342     * <dt>selectedIndex[0] -- height</dt>
343     * <dd>The vertical axis</dd>
344     * <dt>selectedIndex[1] -- width</dt>
345     * <dd>The horizontal axis</dd>
346     * <dt>selectedIndex[2] -- depth</dt>
347     * <dd>The depth axis, which is used for 3 or more dimension datasets.</dd>
348     * </dl>
349     * Applications can use getSelectedIndex() to access and change the display
350     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
351     * following code will set the height=200 and width=100.
352     *
353     * <pre>
354     * int[] selectedIndex = dataset.getSelectedIndex();
355     * selectedIndex[0] = 0;
356     * selectedIndex[1] = 1;
357     * </pre>
358     *
359     * @see #getSelectedIndex()
360     * @see #getHeight()
361     *
362     * @return the size of dimension of the horizontal axis.
363     */
364    long getWidth();
365
366    /**
367     * Returns the dimension size of the frame axis.
368     *
369     *
370     * This function is used by GUI applications such as HDFView. GUI applications
371     * display a dataset in 2D Table or 2D Image. The display order is specified by
372     * the index array of selectedIndex as follow:
373     * <dl>
374     * <dt>selectedIndex[0] -- height</dt>
375     * <dd>The vertical axis</dd>
376     * <dt>selectedIndex[1] -- width</dt>
377     * <dd>The horizontal axis</dd>
378     * <dt>selectedIndex[2] -- depth</dt>
379     * <dd>The depth axis, which is used for 3 or more dimension datasets.</dd>
380     * </dl>
381     * Applications can use getSelectedIndex() to access and change the display
382     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
383     * following code will set the height=200 and width=100.
384     *
385     * <pre>
386     * int[] selectedIndex = dataset.getSelectedIndex();
387     * selectedIndex[0] = 0;
388     * selectedIndex[1] = 1;
389     * </pre>
390     *
391     * @see #getSelectedIndex()
392     * @see #getHeight()
393     *
394     * @return the size of dimension of the frame axis.
395     */
396    long getDepth();
397
398    /**
399     * Returns the string representation of compression information.
400     *
401     * For example, "SZIP: Pixels per block = 8: H5Z_FILTER_CONFIG_DECODE_ENABLED".
402     *
403     * @return the string representation of compression information.
404     */
405    String getCompression();
406
407    /**
408     * Get runtime Class of the original data buffer if converted.
409     *
410     * @return the Class of the original data buffer
411     */
412    @SuppressWarnings("rawtypes")
413    Class getOriginalClass();
414}