    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}