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