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