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