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