    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    /**
    029     * The status of initialization for this object
    030     *
    031     * @return true if the data has been initialized
    032     */
    033    boolean isInited();
    034
    035    /**
    036     * Set the initial state of all the variables
    037     */
    038    void init();
    039
    040    /**
    041     * Retrieves the object's data from the file.
    042     *
    043     * @return the object's data.
    044     *
    045     * @throws Exception
    046     *             if the data can not be retrieved
    047     */
    048    Object getData() throws Exception, OutOfMemoryError;
    049
    050    /**
    051     *
    052     *
    053     * @param data
    054     *            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    /****************************************************************
    192     * * The following four definitions are used for data subsetting. * *
    193     ****************************************************************/
    194
    195    /**
    196     * Returns the dimension sizes of the selected subset.
    197     *
    198     * The SelectedDims is the number of data points of the selected subset.
    199     * Applications can use this array to change the size of selected subset.
    200     *
    201     * The selected size must be less than or equal to the current dimension size.
    202     * Combined with the starting position, selected sizes and stride, the subset of
    203     * a rectangle selection is fully defined.
    204     *
    205     * For example, if a 4 X 5 dataset is as follows:
    206     *
    207     * <pre>
    208     *     0,  1,  2,  3,  4
    209     *    10, 11, 12, 13, 14
    210     *    20, 21, 22, 23, 24
    211     *    30, 31, 32, 33, 34
    212     * long[] dims = {4, 5};
    213     * long[] startDims = {1, 2};
    214     * long[] selectedDims = {3, 3};
    215     * long[] selectedStride = {1, 1};
    216     * then the following subset is selected by the startDims and selectedDims
    217     *     12, 13, 14
    218     *     22, 23, 24
    219     *     32, 33, 34
    220     * </pre>
    221     *
    222     * @return the dimension sizes of the selected subset.
    223     */
    224    long[] getSelectedDims();
    225
    226    /**
    227     * Returns the starting position of a selected subset.
    228     *
    229     * Applications can use this array to change the starting position of a
    230     * selection. Combined with the selected dimensions, selected sizes and stride,
    231     * the subset of a rectangle selection is fully defined.
    232     *
    233     * For example, if a 4 X 5 dataset is as follows:
    234     *
    235     * <pre>
    236     *     0,  1,  2,  3,  4
    237     *    10, 11, 12, 13, 14
    238     *    20, 21, 22, 23, 24
    239     *    30, 31, 32, 33, 34
    240     * long[] dims = {4, 5};
    241     * long[] startDims = {1, 2};
    242     * long[] selectedDims = {3, 3};
    243     * long[] selectedStride = {1, 1};
    244     * then the following subset is selected by the startDims and selectedDims
    245     *     12, 13, 14
    246     *     22, 23, 24
    247     *     32, 33, 34
    248     * </pre>
    249     *
    250     * @return the starting position of a selected subset.
    251     */
    252    long[] getStartDims();
    253
    254    /**
    255     * Returns the selectedStride of the selected dataset.
    256     *
    257     * Applications can use this array to change how many elements to move in each
    258     * dimension.
    259     *
    260     * Combined with the starting position and selected sizes, the subset of a
    261     * rectangle selection is defined.
    262     *
    263     * For example, if a 4 X 5 dataset is as follows:
    264     *
    265     * <pre>
    266     *     0,  1,  2,  3,  4
    267     *    10, 11, 12, 13, 14
    268     *    20, 21, 22, 23, 24
    269     *    30, 31, 32, 33, 34
    270     * long[] dims = {4, 5};
    271     * long[] startDims = {0, 0};
    272     * long[] selectedDims = {2, 2};
    273     * long[] selectedStride = {2, 3};
    274     * then the following subset is selected by the startDims and selectedDims
    275     *     0,   3
    276     *     20, 23
    277     * </pre>
    278     *
    279     * @return the selectedStride of the selected dataset.
    280     */
    281    long[] getStride();
    282
    283    /**
    284     * Returns the indices of display order.
    285     *
    286     * selectedIndex[] is provided for two purposes:
    287     * <OL>
    288     * <LI>selectedIndex[] is used to indicate the order of dimensions for display.
    289     * selectedIndex[0] is for the row, selectedIndex[1] is for the column and
    290     * selectedIndex[2] for the depth.
    291     *
    292     * For example, for a four dimension dataset, if selectedIndex[] = {1, 2, 3},
    293     * then dim[1] is selected as row index, dim[2] is selected as column index and
    294     * dim[3] is selected as depth index.
    295     * <LI>selectedIndex[] is also used to select dimensions for display for
    296     * datasets with three or more dimensions. We assume that applications such as
    297     * HDFView can only display data values up to three dimensions (2D
    298     * spreadsheet/image with a third dimension which the 2D spreadsheet/image is
    299     * selected from). For datasets with more than three dimensions, we need
    300     * selectedIndex[] to tell applications which three dimensions are chosen for
    301     * display. <br>
    302     * For example, for a four dimension dataset, if selectedIndex[] = {1, 2, 3},
    303     * then dim[1] is selected as row index, dim[2] is selected as column index and
    304     * dim[3] is selected as depth index. dim[0] is not selected. Its location is
    305     * fixed at 0 by default.
    306     * </OL>
    307     *
    308     * @return the array of the indices of display order.
    309     */
    310    int[] getSelectedIndex();
    311
    312    /**************************************************************************
    313     * * The following two definitions are used primarily for GUI applications. * *
    314     **************************************************************************/
    315
    316    /**
    317     * Returns the dimension size of the vertical axis.
    318     *
    319     *
    320     * This function is used by GUI applications such as HDFView. GUI applications
    321     * display a dataset in a 2D table or 2D image. The display order is specified
    322     * by the index array of selectedIndex as follow:
    323     * <dl>
    324     * <dt>selectedIndex[0] -- height</dt>
    325     * <dd>The vertical axis</dd>
    326     * <dt>selectedIndex[1] -- width</dt>
    327     * <dd>The horizontal axis</dd>
    328     * <dt>selectedIndex[2] -- depth</dt>
    329     * <dd>The depth axis is used for 3 or more dimensional datasets.</dd>
    330     * </dl>
    331     * Applications can use getSelectedIndex() to access and change the display
    332     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
    333     * following code will set the height=200 and width=50.
    334     *
    335     * <pre>
    336     * int[] selectedIndex = dataset.getSelectedIndex();
    337     * selectedIndex[0] = 0;
    338     * selectedIndex[1] = 1;
    339     * </pre>
    340     *
    341     * @see #getSelectedIndex()
    342     * @see #getWidth()
    343     *
    344     * @return the size of dimension of the vertical axis.
    345     */
    346    long getHeight();
    347
    348    /**
    349     * Returns the dimension size of the horizontal axis.
    350     *
    351     *
    352     * This function is used by GUI applications such as HDFView. GUI applications
    353     * display a dataset in 2D Table or 2D Image. The display order is specified by
    354     * the index array of selectedIndex as follow:
    355     * <dl>
    356     * <dt>selectedIndex[0] -- height</dt>
    357     * <dd>The vertical axis</dd>
    358     * <dt>selectedIndex[1] -- width</dt>
    359     * <dd>The horizontal axis</dd>
    360     * <dt>selectedIndex[2] -- depth</dt>
    361     * <dd>The depth axis, which is used for 3 or more dimension datasets.</dd>
    362     * </dl>
    363     * Applications can use getSelectedIndex() to access and change the display
    364     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
    365     * following code will set the height=200 and width=100.
    366     *
    367     * <pre>
    368     * int[] selectedIndex = dataset.getSelectedIndex();
    369     * selectedIndex[0] = 0;
    370     * selectedIndex[1] = 1;
    371     * </pre>
    372     *
    373     * @see #getSelectedIndex()
    374     * @see #getHeight()
    375     *
    376     * @return the size of dimension of the horizontal axis.
    377     */
    378    long getWidth();
    379
    380    /**
    381     * Returns the dimension size of the frame axis.
    382     *
    383     *
    384     * This function is used by GUI applications such as HDFView. GUI applications
    385     * display a dataset in 2D Table or 2D Image. The display order is specified by
    386     * the index array of selectedIndex as follow:
    387     * <dl>
    388     * <dt>selectedIndex[0] -- height</dt>
    389     * <dd>The vertical axis</dd>
    390     * <dt>selectedIndex[1] -- width</dt>
    391     * <dd>The horizontal axis</dd>
    392     * <dt>selectedIndex[2] -- depth</dt>
    393     * <dd>The depth axis, which is used for 3 or more dimension datasets.</dd>
    394     * </dl>
    395     * Applications can use getSelectedIndex() to access and change the display
    396     * order. For example, in a 2D dataset of 200x50 (dim0=200, dim1=50), the
    397     * following code will set the height=200 and width=100.
    398     *
    399     * <pre>
    400     * int[] selectedIndex = dataset.getSelectedIndex();
    401     * selectedIndex[0] = 0;
    402     * selectedIndex[1] = 1;
    403     * </pre>
    404     *
    405     * @see #getSelectedIndex()
    406     * @see #getHeight()
    407     *
    408     * @return the size of dimension of the frame axis.
    409     */
    410    long getDepth();
    411
    412    /**
    413     * Returns the string representation of compression information.
    414     *
    415     * For example, "SZIP: Pixels per block = 8: H5Z_FILTER_CONFIG_DECODE_ENABLED".
    416     *
    417     * @return the string representation of compression information.
    418     */
    419    String getCompression();
    420
    421    /**
    422     * Get runtime Class of the original data buffer if converted.
    423     *
    424     * @return the Class of the original data buffer
    425     */
    426    @SuppressWarnings("rawtypes")
    427    Class getOriginalClass();
    428}