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.fits;
016
017import java.util.List;
018
019import hdf.object.Datatype;
020
021import nom.tam.fits.BasicHDU;
022
023/**
024 * Datatype encapsulates information of a datatype.
025 * Information includes the class, size, endian of a datatype.
026 *
027 * @version 1.1 9/4/2007
028 * @author Peter X. Cao
029 */
030public class FitsDatatype extends Datatype {
031    private static final long serialVersionUID = 6545936196104493765L;
032
033    /** the native type */
034    private long nativeType;
035
036    /**
037     * Create an Datatype with specified class, size, byte order and sign.
038     * The following list a few example of how to create a Datatype.
039     * <OL>
040     * <LI>to create unsigned native integer<br>
041     * FitsDatatype type = new H5Dataype(Datatype.CLASS_INTEGER, Datatype.NATIVE, Datatype.NATIVE,
042     * Datatype.SIGN_NONE); <LI>to create 16-bit signed integer with big endian<br> FitsDatatype type = new
043     * H5Dataype(Datatype.CLASS_INTEGER, 2, Datatype.ORDER_BE, Datatype.NATIVE); <LI>to create native
044     * float<br> FitsDatatype type = new H5Dataype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE,
045     * Datatype.NATIVE); <LI>to create 64-bit double<br> FitsDatatype type = new
046     * H5Dataype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE);
047     * </OL>
048     *
049     * @param tclass the class of the datatype.
050     * @param tsize the size of the datatype in bytes.
051     * @param torder the order of the datatype.
052     * @param tsign the sign of the datatype.
053     *
054     * @throws Exception
055     *            if there is an error
056     */
057    public FitsDatatype(int tclass, int tsize, int torder, int tsign) throws Exception
058    {
059        super(tclass, tsize, torder, tsign);
060        datatypeDescription = getDescription();
061    }
062
063    /**
064     * Create a Datatype with a given fits native datatype.
065     *
066     * @param theType the fits native datatype.
067     *
068     * @throws Exception
069     *            if there is an error
070     */
071    public FitsDatatype(long theType) throws Exception
072    {
073        super(null, -1);
074        nativeType = theType;
075        fromNative(0);
076        datatypeDescription = getDescription();
077    }
078
079    /**
080     * Allocate an one-dimensional array of byte, short, int, long, float, double,
081     * or String to store data retrieved from an fits file based on the given
082     * fits datatype and dimension sizes.
083     *
084     * @param dtype the fits datatype.
085     * @param size the total size of the array.
086     * @return the array object if successful and null otherwise.
087     */
088    public static Object allocateArray(long dtype, int size) throws OutOfMemoryError
089    {
090        Object data = null;
091
092        if (size <= 0)
093            return null;
094
095        switch ((int)dtype) {
096        case BasicHDU.BITPIX_BYTE:
097            data = new byte[size];
098            break;
099        case BasicHDU.BITPIX_SHORT:
100            data = new short[size];
101            break;
102        case BasicHDU.BITPIX_INT:
103            data = new int[size];
104            break;
105        case BasicHDU.BITPIX_LONG:
106            data = new long[size];
107            break;
108        case BasicHDU.BITPIX_FLOAT:
109            data = new float[size];
110            break;
111        case BasicHDU.BITPIX_DOUBLE:
112            data = new double[size];
113            break;
114        default:
115            break;
116        }
117
118        return data;
119    }
120
121    /**
122     * Translate fits datatype identifier into FitsDatatype.
123     */
124    public void fromNative() { fromNative(nativeType); }
125
126    /**
127     * Translate fits datatype identifier into FitsDatatype.
128     *
129     * @param dtype the fits native datatype.
130     */
131    @Override
132    public void fromNative(long dtype)
133    {
134        switch ((int)dtype) {
135        case BasicHDU.BITPIX_BYTE:
136            datatypeClass = CLASS_INTEGER;
137            datatypeSize  = 1;
138            break;
139        case BasicHDU.BITPIX_SHORT:
140            datatypeClass = CLASS_INTEGER;
141            datatypeSize  = 2;
142            break;
143        case BasicHDU.BITPIX_INT:
144            datatypeClass = CLASS_INTEGER;
145            datatypeSize  = 4;
146            break;
147        case BasicHDU.BITPIX_LONG:
148            datatypeClass = CLASS_INTEGER;
149            datatypeSize  = 8;
150            break;
151        case BasicHDU.BITPIX_FLOAT:
152            datatypeClass = CLASS_FLOAT;
153            datatypeSize  = 4;
154            break;
155        case BasicHDU.BITPIX_DOUBLE:
156            datatypeClass = CLASS_FLOAT;
157            datatypeSize  = 8;
158            break;
159        default:
160            break;
161        }
162    }
163
164    // implementing Datatype
165    @Override
166    public String getDescription()
167    {
168        if (datatypeDescription != null)
169            return datatypeDescription;
170
171        String description = null;
172
173        switch ((int)nativeType) {
174        case BasicHDU.BITPIX_BYTE:
175            description = "8-bit integer";
176            break;
177        case BasicHDU.BITPIX_SHORT:
178            description = "16-bit integer";
179            break;
180        case BasicHDU.BITPIX_INT:
181            description = "32-bit integer";
182            break;
183        case BasicHDU.BITPIX_LONG:
184            description = "64-bit integer";
185            break;
186        case BasicHDU.BITPIX_FLOAT:
187            description = "32-bit float";
188            break;
189        case BasicHDU.BITPIX_DOUBLE:
190            description = "64-bit float";
191            break;
192        default:
193            if (this.isString())
194                description = "String";
195            else if (this.isChar())
196                description = "Char";
197            else if (this.isInteger())
198                description = "Integer";
199            else if (this.isFloat())
200                description = "Float";
201            else
202                description = "Unknown data type.";
203            break;
204        }
205
206        return description;
207    }
208
209    // implementing Datatype
210    @Override
211    public boolean isText()
212    {
213        return false;
214    }
215
216    // implementing Datatype
217    @Override
218    public boolean isUnsigned()
219    {
220        return false;
221    }
222
223    // implementing Datatype
224    @Override
225    public long createNative()
226    {
227        if (datatypeClass == CLASS_INTEGER) {
228            if (datatypeSize == 1)
229                nativeType = BasicHDU.BITPIX_BYTE;
230            else if (datatypeSize == 2)
231                nativeType = BasicHDU.BITPIX_SHORT;
232            else if (datatypeSize == 4)
233                nativeType = BasicHDU.BITPIX_INT;
234            else if (datatypeSize == 8)
235                nativeType = BasicHDU.BITPIX_LONG;
236        }
237        else if (datatypeClass == CLASS_FLOAT) {
238            if (datatypeSize == 4)
239                nativeType = BasicHDU.BITPIX_FLOAT;
240            else if (datatypeSize == 8)
241                nativeType = BasicHDU.BITPIX_DOUBLE;
242        }
243
244        return nativeType;
245    }
246
247    /*
248     * (non-Javadoc)
249     * @see hdf.object.Datatype#close(int)
250     */
251    @Override
252    public void close(long id)
253    {
254        // Nothing to implement
255    }
256
257    // Implementing MetaDataContainer
258    /**
259     * Retrieves the object's metadata, such as attributes, from the file.
260     *
261     * Metadata, such as attributes, is stored in a List.
262     *
263     * @param attrPropList
264     *             the list of properties to get
265     *
266     * @return the list of metadata objects.
267     *
268     * @throws Exception
269     *             if the metadata can not be retrieved
270     */
271    @SuppressWarnings("rawtypes")
272    public List getMetadata(int... attrPropList) throws Exception
273    {
274        throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported");
275    }
276
277    /*
278     * (non-Javadoc)
279     * @see hdf.object.MetaDataContainer#hasAttribute()
280     */
281    @Override
282    public boolean hasAttribute()
283    {
284        return false;
285    }
286}