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 http://hdfgroup.org/products/hdf-java/doc/Copyright.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.h4;
016
017import java.util.List;
018
019import hdf.hdflib.HDFConstants;
020import hdf.object.Datatype;
021
022/**
023 * This class defines HDF4 data type characteristics and APIs for a data type.
024 * <p>
025 * This class provides several methods to convert an HDF4 datatype identifier to
026 * a datatype object, and vice versa. A datatype object is described by four basic
027 * fields: datatype class, size, byte order, and sign, while an HDF5 datatype is
028 * presented by a datatype identifier.
029 *
030 * @version 1.1 9/4/2007
031 * @author Peter X. Cao
032 */
033public class H4Datatype extends Datatype
034{
035    /**
036     *
037     */
038    private static final long serialVersionUID = -1342029403385521874L;
039
040    /**
041     * Constructs a H4Datatype with specified class, size, byte order and sign.
042     * <p>
043     * The following is a list of a few example of H5Datatype.
044     * <ol>
045     * <li>to create unsigned native integer<br>
046     * H4Datatype type = new H4Dataype(CLASS_INTEGER, NATIVE, NATIVE, SIGN_NONE);
047     * <li>to create 16-bit signed integer with big endian<br>
048     * H4Datatype type = new H4Dataype(CLASS_INTEGER, 2, ORDER_BE, NATIVE);
049     * <li>to create native float<br>
050     * H4Datatype type = new H4Dataype(CLASS_FLOAT, NATIVE, NATIVE, -1);
051     * <li>to create 64-bit double<br>
052     * H4Datatype type = new H4Dataype(CLASS_FLOAT, 8, NATIVE, -1);
053     * </ol>
054     * @param tclass the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and etc.
055     * @param tsize the size of the datatype in bytes, e.g. for a 32-bit integer, the size is 4.
056     * @param torder the byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, ORDER_VAX and ORDER_NONE
057     * @param tsign the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 and MSGN
058     */
059    public H4Datatype(int tclass, int tsize, int torder, int tsign)
060    {
061        super(tclass, tsize, torder, tsign);
062    }
063
064    /**
065     * Constructs a H4Datatype with a given native datatype identifier.
066     * <p>
067     * For example,
068     * <pre>
069     * Datatype dtype = new H4Datatype(HDFConstants.DFNT_INT32);
070     * </pre>
071     * will construct a datatype equivalent to
072     * new H4Datatype(CLASS_INTEGER, 4, NATIVE, SIGN_NONE);
073     *
074     * @see #fromNative(int nativeID)
075     *
076     * @param nativeID the native datatype identifier.
077     */
078    public H4Datatype(int nativeID)
079    {
080        super(nativeID);
081
082        fromNative(nativeID);
083    }
084
085    /*
086     * (non-Javadoc)
087     * @see hdf.object.DataFormat#hasAttribute()
088     */
089    public boolean hasAttribute () { return false; }
090
091    /*
092     * (non-Javadoc)
093     * @see hdf.object.Datatype#fromNative(int)
094     */
095    @Override
096    public void fromNative(int tid)
097    {
098        datatypeOrder = NATIVE;
099        datatypeSign = NATIVE;
100
101        switch(tid)
102        {
103            case HDFConstants.DFNT_CHAR:
104                datatypeClass = CLASS_CHAR;
105                datatypeSize = 1;
106                break;
107            case HDFConstants.DFNT_UCHAR8:
108                datatypeClass = CLASS_CHAR;
109                datatypeSize = 1;
110                datatypeSign = SIGN_NONE;
111                break;
112            case HDFConstants.DFNT_INT8:
113                datatypeClass = CLASS_INTEGER;
114                datatypeSize = 1;
115                break;
116            case HDFConstants.DFNT_UINT8:
117                datatypeClass = CLASS_INTEGER;
118                datatypeSize = 1;
119                datatypeSign = SIGN_NONE;
120                 break;
121            case HDFConstants.DFNT_INT16:
122                datatypeClass = CLASS_INTEGER;
123                datatypeSize = 2;
124                break;
125            case HDFConstants.DFNT_UINT16:
126                datatypeClass = CLASS_INTEGER;
127                datatypeSize = 2;
128                datatypeSign = SIGN_NONE;
129                break;
130            case HDFConstants.DFNT_INT32:
131                datatypeClass = CLASS_INTEGER;
132                datatypeSize = 4;
133                break;
134            case HDFConstants.DFNT_UINT32:
135                datatypeClass = CLASS_INTEGER;
136                datatypeSize = 4;
137                datatypeSign = SIGN_NONE;
138                break;
139            case HDFConstants.DFNT_INT64:
140                datatypeClass = CLASS_INTEGER;
141                datatypeSize = 8;
142                break;
143            case HDFConstants.DFNT_UINT64:
144                datatypeClass = CLASS_INTEGER;
145                datatypeSize = 8;
146                datatypeSign = SIGN_NONE;
147                break;
148            case HDFConstants.DFNT_FLOAT32:
149                datatypeClass = CLASS_FLOAT;
150                datatypeSize = 4;
151                break;
152            case HDFConstants.DFNT_FLOAT64:
153                datatypeClass = CLASS_FLOAT;
154                datatypeSize = 8;
155                break;
156            default:
157                datatypeClass = CLASS_NO_CLASS;
158                break;
159        }
160    }
161
162    /**
163     *  Allocate a 1D array large enough to hold a multidimensional
164     *  array of 'datasize' elements of 'datatype' numbers.
165     *
166     *  @param datatype  the data type
167     *  @param datasize  the size of the data array
168     *
169     *  @return an array of 'datasize' numbers of datatype.
170     *
171     * @throws OutOfMemoryError
172     *             if the array cannot be allocated
173    */
174    public static final Object allocateArray(int datatype, int datasize)
175    throws OutOfMemoryError
176    {
177        if (datasize <= 0) {
178            return null;
179        }
180
181        Object data = null;
182
183        switch(datatype)
184        {
185            case HDFConstants.DFNT_CHAR:
186            case HDFConstants.DFNT_UCHAR8:
187            case HDFConstants.DFNT_UINT8:
188            case HDFConstants.DFNT_INT8:
189                data = new byte[datasize];
190                break;
191            case HDFConstants.DFNT_INT16:
192            case HDFConstants.DFNT_UINT16:
193                data = new short[datasize];
194                break;
195            case HDFConstants.DFNT_INT32:
196            case HDFConstants.DFNT_UINT32:
197                data = new int[datasize];
198                break;
199            case HDFConstants.DFNT_INT64:
200            case HDFConstants.DFNT_UINT64:
201                data = new long[datasize];
202                break;
203            case HDFConstants.DFNT_FLOAT32:
204                data = new float[datasize];
205                break;
206            case HDFConstants.DFNT_FLOAT64:
207                data = new double[datasize];
208                break;
209            default:
210                data = null;
211                break;
212        }
213
214        return data;
215    }
216
217    /*
218     * (non-Javadoc)
219     * @see hdf.object.Datatype#getDatatypeDescription()
220     */
221    @Override
222    public String getDatatypeDescription()
223    {
224        return getDatatypeDescription(toNative());
225    }
226
227    /**
228     *  Returns the short description of a given datatype.
229     *
230     *  @param datatype  the data type
231     *
232     *  @return  a description String
233     */
234    public static final String getDatatypeDescription(int datatype)
235    {
236        String description = "Unknown";
237
238        switch(datatype)
239        {
240            case HDFConstants.DFNT_CHAR:
241                description = "8-bit character";
242                break;
243            case HDFConstants.DFNT_UCHAR8:
244                description = "8-bit unsigned character";
245                break;
246            case HDFConstants.DFNT_UINT8:
247                description = "8-bit unsigned integer";
248                break;
249            case HDFConstants.DFNT_INT8:
250                description = "8-bit integer";
251                break;
252            case HDFConstants.DFNT_INT16:
253                description = "16-bit integer";
254                break;
255            case HDFConstants.DFNT_UINT16:
256                description = "16-bit unsigned integer";
257                break;
258            case HDFConstants.DFNT_INT32:
259                description = "32-bit integer";
260                break;
261            case HDFConstants.DFNT_UINT32:
262                description = "32-bit unsigned integer";
263                break;
264            case HDFConstants.DFNT_INT64:
265                description = "64-bit integer";
266                break;
267            case HDFConstants.DFNT_UINT64:
268                description = "64-bit unsigned integer";
269                break;
270            case HDFConstants.DFNT_FLOAT32:
271                description = "32-bit floating-point";
272                break;
273            case HDFConstants.DFNT_FLOAT64:
274                description = "64-bit floating-point";
275                break;
276            default:
277                description = "Unknown";
278                break;
279        }
280
281        return description;
282    }
283
284    /*
285     * (non-Javadoc)
286     * @see hdf.object.Datatype#isUnsigned()
287     */
288    @Override
289    public boolean isUnsigned()
290    {
291        return isUnsigned(toNative());
292    }
293
294    /**
295     *  Checks if the datatype is an unsigned integer.
296     *
297     *  @param datatype  the data type.
298     *
299     *  @return True is the datatype is an unsigned integer; otherwise returns false.
300     */
301    public static final boolean isUnsigned(int datatype)
302    {
303        boolean unsigned = false;;
304
305        switch(datatype)
306        {
307            case HDFConstants.DFNT_UCHAR8:
308            case HDFConstants.DFNT_UINT8:
309            case HDFConstants.DFNT_UINT16:
310            case HDFConstants.DFNT_UINT32:
311            case HDFConstants.DFNT_UINT64:
312                unsigned = true;
313                break;
314            default:
315                unsigned = false;
316                break;
317        }
318
319        return unsigned;
320    }
321
322    /*
323     * (non-Javadoc)
324     * @see hdf.object.Datatype#toNative()
325     */
326    @Override
327    public int toNative()
328    {
329        int tid = -1;
330        int tclass = getDatatypeClass();
331        int tsize = getDatatypeSize();
332
333        // figure the datatype
334        switch (tclass)
335        {
336            case Datatype.CLASS_INTEGER:
337                int tsign = getDatatypeSign();
338                if (tsize == 1)
339                {
340                    if (tsign == Datatype.SIGN_NONE) {
341                        tid = HDFConstants.DFNT_UINT8;
342                    } else {
343                        tid = HDFConstants.DFNT_INT8;
344                    }
345                }
346                else if (tsize == 2)
347                {
348                    if (tsign == Datatype.SIGN_NONE) {
349                        tid = HDFConstants.DFNT_UINT16;
350                    } else {
351                        tid = HDFConstants.DFNT_INT16;
352                    }
353                }
354                else if ((tsize == 4) || (tsize == NATIVE))
355                {
356                    if (tsign == Datatype.SIGN_NONE) {
357                        tid = HDFConstants.DFNT_UINT32;
358                    } else {
359                        tid = HDFConstants.DFNT_INT32;
360                    }
361                }
362                else if (tsize == 8)
363                {
364                    if (tsign == Datatype.SIGN_NONE) {
365                        tid = HDFConstants.DFNT_UINT64;
366                    } else {
367                        tid = HDFConstants.DFNT_INT64;
368                    }
369                }
370                break;
371            case Datatype.CLASS_FLOAT:
372                if (tsize == Datatype.NATIVE) {
373                    tid = HDFConstants.DFNT_FLOAT;
374                } else if (tsize == 4) {
375                    tid = HDFConstants.DFNT_FLOAT32;
376                } else if (tsize == 8) {
377                    tid = HDFConstants.DFNT_FLOAT64;
378                }
379                break;
380            case Datatype.CLASS_CHAR:
381                int tsign2 = getDatatypeSign();
382                if (tsign2 == Datatype.SIGN_NONE) {
383                    tid = HDFConstants.DFNT_UCHAR;
384                } else {
385                    tid = HDFConstants.DFNT_CHAR;
386                }
387                break;
388            case Datatype.CLASS_STRING:
389                    tid = HDFConstants.DFNT_CHAR;
390                break;
391        }
392
393        return tid;
394    }
395
396    /*
397     * (non-Javadoc)
398     * @see hdf.object.Datatype#close(int)
399     */
400    @Override
401    public void close(int id) {;}
402
403    //Implementing DataFormat
404    public List getMetadata(int... attrPropList) throws Exception {
405        throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported");
406    }
407
408
409}