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     * Refreshes the current object in the file.
075     *
076     * The function read() loads data from file into memory only if the data is not
077     * read. If data is already in memory, read() just returns the memory buffer.
078     * Sometimes we want to force a clear and read to re-read the object from the file.
079     * For example, when the dimensions has changed, we need to refresh the object and data.
080     *
081     * @return the updated data
082     *
083     * @see #getData()
084     * @see #read()
085     */
086    Object refreshData();
087
088    /**
089     * Reads the data from file.
090     *
091     * read() reads the data from file to a memory buffer and returns the memory
092     * buffer. The dataset object does not hold the memory buffer. To store the
093     * memory buffer in the dataset object, one must call getData().
094     *
095     * By default, the whole dataset is read into memory. Users can also select
096     * a subset to read. Subsetting is done in an implicit way.
097     *
098     * @return the data read from file.
099     *
100     * @see #getData()
101     *
102     * @throws Exception
103     *             if object can not be read
104     * @throws OutOfMemoryError
105     *             if memory is exhausted
106     */
107    Object read() throws Exception, OutOfMemoryError;
108
109    /**
110     * Writes a memory buffer to the object in the file.
111     *
112     * @param buf
113     *            the data to write
114     *
115     * @throws Exception
116     *             if data can not be written
117     */
118    void write(Object buf) throws Exception;
119
120    /**
121     * Writes the current memory buffer to the object in the file.
122     *
123     * @throws Exception
124     *             if data can not be written
125     */
126    void write() throws Exception;
127
128    /**
129     * Converts the data values of this data object to appropriate Java integers if
130     * they are unsigned integers.
131     *
132     * @see hdf.object.Dataset#convertToUnsignedC(Object)
133     * @see hdf.object.Dataset#convertFromUnsignedC(Object, Object)
134     *
135     * @return the converted data buffer.
136     */
137    Object convertFromUnsignedC();
138
139    /**
140     * Converts Java integer data values of this data object back to unsigned C-type
141     * integer data if they are unsigned integers.
142     *
143     * @see hdf.object.Dataset#convertToUnsignedC(Object)
144     * @see hdf.object.Dataset#convertToUnsignedC(Object, Object)
145     *
146     * @return the converted data buffer.
147     */
148    Object convertToUnsignedC();
149
150    /**
151     * Returns the fill values for the data object.
152     *
153     * @return the fill values for the data object.
154     */
155    Object getFillValue();
156
157    /**
158     * Returns the datatype of the data object.
159     *
160     * @return the datatype of the data object.
161     */
162    Datatype getDatatype();
163
164    /**
165     * Returns the space type for the data object. It returns a
166     * negative number if it failed to retrieve the type information from
167     * the file.
168     *
169     * @return the space type for the data object.
170     */
171    int getSpaceType();
172
173    /**
174     * Returns the rank (number of dimensions) of the data object. It returns a
175     * negative number if it failed to retrieve the dimension information from
176     * the file.
177     *
178     * @return the number of dimensions of the data object.
179     */
180    int getRank();
181
182    /**
183     * Returns the array that contains the dimension sizes of the data value of
184     * the data object. It returns null if it failed to retrieve the dimension
185     * information from the file.
186     *
187     * @return the dimension sizes of the data object.
188     */
189    long[] getDims();
190
191
192    /****************************************************************
193     * * The following four definitions are used for data subsetting. * *
194     ****************************************************************/
195
196    /**
197     * Returns the dimension sizes of the selected subset.
198     *
199     * The SelectedDims is the number of data points of the selected subset.
200     * Applications can use this array to change the size of selected subset.
201     *
202     * The selected size must be less than or equal to the current dimension size.
203     * Combined with the starting position, selected sizes and stride, the subset of
204     * a rectangle selection is fully defined.
205     *
206     * For example, if a 4 X 5 dataset is as follows:
207     *
208     * <pre>
209     *     0,  1,  2,  3,  4
210     *    10, 11, 12, 13, 14
211     *    20, 21, 22, 23, 24
212     *    30, 31, 32, 33, 34
213     * long[] dims = {4, 5};
214     * long[] startDims = {1, 2};
215     * long[] selectedDims = {3, 3};
216     * long[] selectedStride = {1, 1};
217     * then the following subset is selected by the startDims and selectedDims
218     *     12, 13, 14
219     *     22, 23, 24
220     *     32, 33, 34
221     * </pre>
222     *
223     * @return the dimension sizes of the selected subset.
224     */
225    long[] getSelectedDims();
226
227    /**
228     * Returns the starting position of a selected subset.
229     *
230     * Applications can use this array to change the starting position of a
231     * selection. Combined with the selected dimensions, selected sizes and stride,
232     * the subset of a rectangle selection is fully defined.
233     *
234     * For example, if a 4 X 5 dataset is as follows:
235     *
236     * <pre>
237     *     0,  1,  2,  3,  4
238     *    10, 11, 12, 13, 14
239     *    20, 21, 22, 23, 24
240     *    30, 31, 32, 33, 34
241     * long[] dims = {4, 5};
242     * long[] startDims = {1, 2};
243     * long[] selectedDims = {3, 3};
244     * long[] selectedStride = {1, 1};
245     * then the following subset is selected by the startDims and selectedDims
246     *     12, 13, 14
247     *     22, 23, 24
248     *     32, 33, 34
249     * </pre>
250     *
251     * @return the starting position of a selected subset.
252     */
253    long[] getStartDims();
254
255    /**
256     * Returns the selectedStride of the selected dataset.
257     *
258     * Applications can use this array to change how many elements to move in each
259     * dimension.
260     *
261     * Combined with the starting position and selected sizes, the subset of a
262     * rectangle selection is defined.
263     *
264     * For example, if a 4 X 5 dataset is as follows:
265     *
266     * <pre>
267     *     0,  1,  2,  3,  4
268     *    10, 11, 12, 13, 14
269     *    20, 21, 22, 23, 24
270     *    30, 31, 32, 33, 34
271     * long[] dims = {4, 5};
272     * long[] startDims = {0, 0};
273     * long[] selectedDims = {2, 2};
274     * long[] selectedStride = {2, 3};
275     * then the following subset is selected by the startDims and selectedDims
276     *     0,   3
277     *     20, 23
278     * </pre>
279     *
280     * @return the selectedStride of the selected dataset.
281     */
282    long[] getStride();
283
284    /**
285     * Returns the indices of display order.
286     *
287     * selectedIndex[] is provided for two purposes:
288     * <OL>
289     * <LI>selectedIndex[] is used to indicate the order of dimensions for display.
290     * selectedIndex[0] is for the row, selectedIndex[1] is for the column and
291     * selectedIndex[2] for the depth.
292     *
293     * For example, for a four dimension dataset, if selectedIndex[] = {1, 2, 3},
294     * then dim[1] is selected as row index, dim[2] is selected as column index and
295     * dim[3] is selected as depth index.
296     * <LI>selectedIndex[] is also used to select dimensions for display for
297     * datasets with three or more dimensions. We assume that applications such as
298     * HDFView can only display data values up to three dimensions (2D
299     * spreadsheet/image with a third dimension which the 2D spreadsheet/image is
300     * selected from). For datasets with more than three dimensions, we need
301     * selectedIndex[] to tell applications which three dimensions are chosen for
302     * display. <br>
303     * For example, for a four dimension dataset, if selectedIndex[] = {1, 2, 3},
304     * then dim[1] is selected as row index, dim[2] is selected as column index and
305     * dim[3] is selected as depth index. dim[0] is not selected. Its location is
306     * fixed at 0 by default.
307     * </OL>
308     *
309     * @return the array of the indices of display order.
310     */
311    int[] getSelectedIndex();
312
313    /**************************************************************************
314     * * The following two definitions are used primarily for GUI applications. * *
315     **************************************************************************/
316
317    /**
318     * Returns the dimension size of the vertical axis.
319     *
320     *
321     * This function is used by GUI applications such as HDFView. GUI applications
322     * display a dataset in a 2D table or 2D image. The display order is specified
323     * by the index array of selectedIndex as follow:
324     * <dl>
325     * <dt>selectedIndex[0] -- height</dt>
326     * <dd>The vertical axis</dd>
327     * <dt>selectedIndex[1] -- width</dt>
328     * <dd>The horizontal axis</dd>
329     * <dt>selectedIndex[2] -- depth</dt>
330     * <dd>The depth axis is used for 3 or more dimensional datasets.</dd>
331     * </dl>
332     * Applications can use getSelectedIndex() to access and change the display
333     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
334     * following code will set the height=200 and width=50.
335     *
336     * <pre>
337     * int[] selectedIndex = dataset.getSelectedIndex();
338     * selectedIndex[0] = 0;
339     * selectedIndex[1] = 1;
340     * </pre>
341     *
342     * @see #getSelectedIndex()
343     * @see #getWidth()
344     *
345     * @return the size of dimension of the vertical axis.
346     */
347    long getHeight();
348
349    /**
350     * Returns the dimension size of the horizontal axis.
351     *
352     *
353     * This function is used by GUI applications such as HDFView. GUI applications
354     * display a dataset in 2D Table or 2D Image. The display order is specified by
355     * the index array of selectedIndex as follow:
356     * <dl>
357     * <dt>selectedIndex[0] -- height</dt>
358     * <dd>The vertical axis</dd>
359     * <dt>selectedIndex[1] -- width</dt>
360     * <dd>The horizontal axis</dd>
361     * <dt>selectedIndex[2] -- depth</dt>
362     * <dd>The depth axis, which is used for 3 or more dimension datasets.</dd>
363     * </dl>
364     * Applications can use getSelectedIndex() to access and change the display
365     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
366     * following code will set the height=200 and width=100.
367     *
368     * <pre>
369     * int[] selectedIndex = dataset.getSelectedIndex();
370     * selectedIndex[0] = 0;
371     * selectedIndex[1] = 1;
372     * </pre>
373     *
374     * @see #getSelectedIndex()
375     * @see #getHeight()
376     *
377     * @return the size of dimension of the horizontal axis.
378     */
379    long getWidth();
380
381    /**
382     * Returns the dimension size of the frame axis.
383     *
384     *
385     * This function is used by GUI applications such as HDFView. GUI applications
386     * display a dataset in 2D Table or 2D Image. The display order is specified by
387     * the index array of selectedIndex as follow:
388     * <dl>
389     * <dt>selectedIndex[0] -- height</dt>
390     * <dd>The vertical axis</dd>
391     * <dt>selectedIndex[1] -- width</dt>
392     * <dd>The horizontal axis</dd>
393     * <dt>selectedIndex[2] -- depth</dt>
394     * <dd>The depth axis, which is used for 3 or more dimension datasets.</dd>
395     * </dl>
396     * Applications can use getSelectedIndex() to access and change the display
397     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
398     * following code will set the height=200 and width=100.
399     *
400     * <pre>
401     * int[] selectedIndex = dataset.getSelectedIndex();
402     * selectedIndex[0] = 0;
403     * selectedIndex[1] = 1;
404     * </pre>
405     *
406     * @see #getSelectedIndex()
407     * @see #getHeight()
408     *
409     * @return the size of dimension of the frame axis.
410     */
411    long getDepth();
412
413    /**
414     * Returns the string representation of compression information.
415     *
416     * For example, "SZIP: Pixels per block = 8: H5Z_FILTER_CONFIG_DECODE_ENABLED".
417     *
418     * @return the string representation of compression information.
419     */
420    String getCompression();
421
422    /**
423     * Get runtime Class of the original data buffer if converted.
424     *
425     * @return the Class of the original data buffer
426     */
427    @SuppressWarnings("rawtypes")
428    Class getOriginalClass();
429}