    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 COPYING file, which can be found  *
    009 * at the root of the source code distribution tree,                         *
    010 * or in https://www.hdfgroup.org/licenses.                                  *
    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.nc2;
    016
    017import java.util.List;
    018
    019import org.slf4j.Logger;
    020import org.slf4j.LoggerFactory;
    021
    022import hdf.object.Datatype;
    023
    024import ucar.ma2.DataType;
    025
    026/**
    027 * Datatype encapsulates information of a datatype. Information includes the
    028 * class, size, endian of a datatype.
    029 *
    030 * @version 1.1 9/4/2007
    031 * @author Peter X. Cao
    032 */
    033public class NC2Datatype extends Datatype
    034{
    035    private static final long serialVersionUID = 5399364372073889764L;
    036
    037    private static final Logger log = LoggerFactory.getLogger(NC2Datatype.class);
    038
    039    /** the native datatype */
    040    private DataType nativeType = null;
    041
    042    /**
    043     * Create an Datatype with specified class, size, byte order and sign. The
    044     * following list a few example of how to create a Datatype.
    045     * <ol>
    046     * <li>to create unsigned native integer<br>
    047     * NC2Datatype type = new NC2Datatype(Datatype.CLASS_INTEGER, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);</li>
    048     * <li>to create 16-bit signed integer with big endian<br>
    049     * NC2Datatype type = new NC2Datatype(Datatype.CLASS_INTEGER, 2, Datatype.ORDER_BE, Datatype.NATIVE);</li>
    050     * <li>to create native float<br>
    051     * NC2Datatype type = new NC2Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, Datatype.NATIVE);</li>
    052     * <li>to create 64-bit double<br>
    053     * NC2Datatype type = new NC2Datatype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE);</li>
    054     * </ol>
    055     *
    056     * @param tclass
    057     *            the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and etc.
    058     * @param tsize
    059     *            the size of the datatype in bytes, e.g. for a 32-bit integer, the size is 4.
    060     *            Valid values are NATIVE or a positive value.
    061     * @param torder
    062     *            the byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, ORDER_VAX,
    063     *            ORDER_NONE and NATIVE.
    064     * @param tsign
    065     *            the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 and NATIVE.
    066     *
    067     * @throws Exception
    068     *            if there is an error
    069     */
    070    public NC2Datatype(int tclass, int tsize, int torder, int tsign) throws Exception {
    071        super(tclass, tsize, torder, tsign);
    072        datatypeDescription = getDescription();
    073    }
    074
    075    /**
    076     * Constructs a NC2Datatype with a given NetCDF3 native datatype object.
    077     *
    078     * @param theType
    079     *            the netcdf native datatype.
    080     *
    081     * @throws Exception
    082     *            if there is an error
    083     */
    084    public NC2Datatype(DataType theType) throws Exception {
    085        super(null, -1);
    086        log.trace("NC2Datatype: start nc2 type = {}", theType);
    087        nativeType = theType;
    088        fromNative(0);
    089        datatypeDescription = getDescription();
    090    }
    091
    092    /*
    093     * (non-Javadoc)
    094     *
    095     * @see hdf.object.Datatype#fromNative(long)
    096     */
    097    /**
    098     * Translate NetCDF3 datatype object into NC2Datatype.
    099     *
    100     * @param tid the native ID
    101     *            UNUSED.
    102     */
    103    @Override
    104    public void fromNative(long tid) {
    105        if (nativeType == null)
    106            return;
    107
    108        datatypeOrder = NATIVE;
    109        if (nativeType.equals(DataType.CHAR)) {
    110            datatypeClass = CLASS_CHAR;
    111            datatypeSize = 1;
    112        }
    113        else if (nativeType.equals(DataType.BYTE)) {
    114            datatypeClass = CLASS_INTEGER;
    115            datatypeSize = 1;
    116        }
    117        else if (nativeType.equals(DataType.SHORT)) {
    118            datatypeClass = CLASS_INTEGER;
    119            datatypeSize = 2;
    120        }
    121        else if (nativeType.equals(DataType.INT)) {
    122            datatypeClass = CLASS_INTEGER;
    123            datatypeSize = 4;
    124        }
    125        else if (nativeType.equals(DataType.LONG)) {
    126            datatypeClass = CLASS_INTEGER;
    127            datatypeSize = 8;
    128        }
    129        else if (nativeType.equals(DataType.FLOAT)) {
    130            datatypeClass = CLASS_FLOAT;
    131            datatypeSize = 4;
    132        }
    133        else if (nativeType.equals(DataType.DOUBLE)) {
    134            datatypeClass = CLASS_FLOAT;
    135            datatypeSize = 8;
    136        }
    137        else if (nativeType.equals(DataType.STRING)) {
    138            datatypeClass = CLASS_STRING;
    139            datatypeSize = 80; // default length. need to figure out the actual length
    140        }
    141        else if (nativeType.equals(DataType.OPAQUE)) {
    142            datatypeClass = CLASS_OPAQUE;
    143            datatypeSize = 1;
    144        }
    145
    146        log.trace("Datatype class={} size={}", datatypeClass, datatypeSize);
    147    }
    148
    149    /**
    150     * Allocate an one-dimensional array of byte, short, int, long, float,
    151     * double, or String to store data retrieved from an NetCDF3 file based on
    152     * the given NetCDF3 datatype and dimension sizes.
    153     *
    154     * @param dtype
    155     *            the NetCDF3 datatype object.
    156     * @param datasize
    157     *            the size of the data array
    158     *
    159     * @return an array of 'datasize' numbers of datatype.
    160     *
    161     * @throws OutOfMemoryError
    162     *             if the array cannot be allocated
    163     */
    164    public static final Object allocateArray(DataType dtype, int datasize) throws OutOfMemoryError {
    165        if ((datasize <= 0) || (dtype == null)) {
    166            log.debug("datasize <= 0");
    167            return null;
    168        }
    169
    170        Object data = null;
    171
    172        if (dtype.equals(DataType.BYTE))
    173            data = new byte[datasize];
    174        else if (dtype.equals(DataType.SHORT))
    175            data = new short[datasize];
    176        else if (dtype.equals(DataType.INT))
    177            data = new int[datasize];
    178        else if (dtype.equals(DataType.LONG))
    179            data = new long[datasize];
    180        else if (dtype.equals(DataType.FLOAT))
    181            data = new float[datasize];
    182        else if (dtype.equals(DataType.DOUBLE))
    183            data = new double[datasize];
    184        else if (dtype.equals(DataType.STRING))
    185            data = new String[datasize];
    186
    187        return data;
    188    }
    189
    190    /*
    191     * (non-Javadoc)
    192     *
    193     * @see hdf.object.Datatype#getDatatypeDescription()
    194     */
    195    @Override
    196    public String getDescription() {
    197        if (datatypeDescription != null)
    198            return datatypeDescription;
    199
    200        String description = null;
    201
    202        if (nativeType == null)
    203            description = "Unknown data type.";
    204
    205        description = nativeType.toString();
    206
    207        return description;
    208    }
    209
    210    /*
    211     * (non-Javadoc)
    212     *
    213     * @see hdf.object.Datatype#isUnsigned()
    214     */
    215    @Override
    216    public boolean isUnsigned() {
    217        if (nativeType.isNumeric())
    218            return false;
    219        else
    220            return false;
    221    }
    222
    223    @Override
    224    public boolean isText() {
    225        return (nativeType == DataType.CHAR);
    226    }
    227
    228    /*
    229     * (non-Javadoc)
    230     * @see hdf.object.Datatype#createNative()
    231     */
    232    @Override
    233    public long createNative() {
    234        if (datatypeClass == CLASS_INTEGER) {
    235            if (datatypeSize == 1)
    236                nativeType = DataType.BYTE;
    237            else if (datatypeSize == 2)
    238                nativeType = DataType.SHORT;
    239            else if (datatypeSize == 4)
    240                nativeType = DataType.INT;
    241            else if (datatypeSize == 8)
    242                nativeType = DataType.LONG;
    243        }
    244        else if (datatypeClass == CLASS_FLOAT) {
    245            if (datatypeSize == 4)
    246                nativeType = DataType.FLOAT;
    247            else if (datatypeSize == 8)
    248                nativeType = DataType.DOUBLE;
    249        }
    250        else if (datatypeClass == CLASS_STRING) {
    251            nativeType = DataType.STRING;
    252        }
    253        else {
    254            log.debug("createNative(): unknown datatype class {}", datatypeClass);
    255        }
    256
    257        return -1;
    258    }
    259
    260    /*
    261     * (non-Javadoc)
    262     *
    263     * @see hdf.object.Datatype#close(int)
    264     */
    265    @Override
    266    public void close(long id) {
    267        // No implementation
    268    }
    269
    270    // Implementing MetaDataContainer
    271    /**
    272     * Retrieves the object's metadata, such as attributes, from the file.
    273     *
    274     * Metadata, such as attributes, is stored in a List.
    275     *
    276     * @param attrPropList
    277     *             the list of properties to get
    278     *
    279     * @return the list of metadata objects.
    280     *
    281     * @throws Exception
    282     *             if the metadata can not be retrieved
    283     */
    284    @SuppressWarnings("rawtypes")
    285    public List getMetadata(int... attrPropList) throws Exception {
    286        throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported");
    287    }
    288
    289    /**
    290     * Check if the object has any attributes attached.
    291     *
    292     * @return true if it has any attributes, false otherwise.
    293     */
    294    @Override
    295    public boolean hasAttribute() {
    296        return false;
    297    }
    298}