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 * <p> 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 * <p> 074 * @see #fromNative(int nativeID) 075 * @param nativeID the native datatype identifier. 076 */ 077 public H4Datatype(int nativeID) 078 { 079 super(nativeID); 080 081 fromNative(nativeID); 082 } 083 084 /* 085 * (non-Javadoc) 086 * @see hdf.object.DataFormat#hasAttribute() 087 */ 088 public boolean hasAttribute () { return false; } 089 090 /* 091 * (non-Javadoc) 092 * @see hdf.object.Datatype#fromNative(int) 093 */ 094 @Override 095 public void fromNative(int tid) 096 { 097 datatypeOrder = NATIVE; 098 datatypeSign = NATIVE; 099 100 switch(tid) 101 { 102 case HDFConstants.DFNT_CHAR: 103 datatypeClass = CLASS_CHAR; 104 datatypeSize = 1; 105 break; 106 case HDFConstants.DFNT_UCHAR8: 107 datatypeClass = CLASS_CHAR; 108 datatypeSize = 1; 109 datatypeSign = SIGN_NONE; 110 break; 111 case HDFConstants.DFNT_INT8: 112 datatypeClass = CLASS_INTEGER; 113 datatypeSize = 1; 114 break; 115 case HDFConstants.DFNT_UINT8: 116 datatypeClass = CLASS_INTEGER; 117 datatypeSize = 1; 118 datatypeSign = SIGN_NONE; 119 break; 120 case HDFConstants.DFNT_INT16: 121 datatypeClass = CLASS_INTEGER; 122 datatypeSize = 2; 123 break; 124 case HDFConstants.DFNT_UINT16: 125 datatypeClass = CLASS_INTEGER; 126 datatypeSize = 2; 127 datatypeSign = SIGN_NONE; 128 break; 129 case HDFConstants.DFNT_INT32: 130 datatypeClass = CLASS_INTEGER; 131 datatypeSize = 4; 132 break; 133 case HDFConstants.DFNT_UINT32: 134 datatypeClass = CLASS_INTEGER; 135 datatypeSize = 4; 136 datatypeSign = SIGN_NONE; 137 break; 138 case HDFConstants.DFNT_INT64: 139 datatypeClass = CLASS_INTEGER; 140 datatypeSize = 8; 141 break; 142 case HDFConstants.DFNT_UINT64: 143 datatypeClass = CLASS_INTEGER; 144 datatypeSize = 8; 145 datatypeSign = SIGN_NONE; 146 break; 147 case HDFConstants.DFNT_FLOAT32: 148 datatypeClass = CLASS_FLOAT; 149 datatypeSize = 4; 150 break; 151 case HDFConstants.DFNT_FLOAT64: 152 datatypeClass = CLASS_FLOAT; 153 datatypeSize = 8; 154 break; 155 default: 156 datatypeClass = CLASS_NO_CLASS; 157 break; 158 } 159 } 160 161 /** 162 * Allocate a 1D array large enough to hold a multidimensional 163 * array of 'datasize' elements of 'datatype' numbers. 164 * 165 * @param datatype the data type 166 * @param datasize the size of the data array 167 * @return an array of 'datasize' numbers of datatype. 168 */ 169 public static final Object allocateArray(int datatype, int datasize) 170 throws OutOfMemoryError 171 { 172 if (datasize <= 0) { 173 return null; 174 } 175 176 Object data = null; 177 178 switch(datatype) 179 { 180 case HDFConstants.DFNT_CHAR: 181 case HDFConstants.DFNT_UCHAR8: 182 case HDFConstants.DFNT_UINT8: 183 case HDFConstants.DFNT_INT8: 184 data = new byte[datasize]; 185 break; 186 case HDFConstants.DFNT_INT16: 187 case HDFConstants.DFNT_UINT16: 188 data = new short[datasize]; 189 break; 190 case HDFConstants.DFNT_INT32: 191 case HDFConstants.DFNT_UINT32: 192 data = new int[datasize]; 193 break; 194 case HDFConstants.DFNT_INT64: 195 case HDFConstants.DFNT_UINT64: 196 data = new long[datasize]; 197 break; 198 case HDFConstants.DFNT_FLOAT32: 199 data = new float[datasize]; 200 break; 201 case HDFConstants.DFNT_FLOAT64: 202 data = new double[datasize]; 203 break; 204 default: 205 data = null; 206 break; 207 } 208 209 return data; 210 } 211 212 /* 213 * (non-Javadoc) 214 * @see hdf.object.Datatype#getDatatypeDescription() 215 */ 216 @Override 217 public String getDatatypeDescription() 218 { 219 return getDatatypeDescription(toNative()); 220 } 221 222 /** 223 * Returns the short description of a given datatype. 224 */ 225 public static final String getDatatypeDescription(int datatype) 226 { 227 String description = "Unknown"; 228 229 switch(datatype) 230 { 231 case HDFConstants.DFNT_CHAR: 232 description = "8-bit character"; 233 break; 234 case HDFConstants.DFNT_UCHAR8: 235 description = "8-bit unsigned character"; 236 break; 237 case HDFConstants.DFNT_UINT8: 238 description = "8-bit unsigned integer"; 239 break; 240 case HDFConstants.DFNT_INT8: 241 description = "8-bit integer"; 242 break; 243 case HDFConstants.DFNT_INT16: 244 description = "16-bit integer"; 245 break; 246 case HDFConstants.DFNT_UINT16: 247 description = "16-bit unsigned integer"; 248 break; 249 case HDFConstants.DFNT_INT32: 250 description = "32-bit integer"; 251 break; 252 case HDFConstants.DFNT_UINT32: 253 description = "32-bit unsigned integer"; 254 break; 255 case HDFConstants.DFNT_INT64: 256 description = "64-bit integer"; 257 break; 258 case HDFConstants.DFNT_UINT64: 259 description = "64-bit unsigned integer"; 260 break; 261 case HDFConstants.DFNT_FLOAT32: 262 description = "32-bit floating-point"; 263 break; 264 case HDFConstants.DFNT_FLOAT64: 265 description = "64-bit floating-point"; 266 break; 267 default: 268 description = "Unknown"; 269 break; 270 } 271 272 return description; 273 } 274 275 /* 276 * (non-Javadoc) 277 * @see hdf.object.Datatype#isUnsigned() 278 */ 279 @Override 280 public boolean isUnsigned() 281 { 282 return isUnsigned(toNative()); 283 } 284 285 /** 286 * Checks if the datatype is an unsigned integer. 287 * <p> 288 * @param datatype the data type. 289 * @return True is the datatype is an unsigned integer; otherwise returns false. 290 */ 291 public static final boolean isUnsigned(int datatype) 292 { 293 boolean unsigned = false;; 294 295 switch(datatype) 296 { 297 case HDFConstants.DFNT_UCHAR8: 298 case HDFConstants.DFNT_UINT8: 299 case HDFConstants.DFNT_UINT16: 300 case HDFConstants.DFNT_UINT32: 301 case HDFConstants.DFNT_UINT64: 302 unsigned = true; 303 break; 304 default: 305 unsigned = false; 306 break; 307 } 308 309 return unsigned; 310 } 311 312 /* 313 * (non-Javadoc) 314 * @see hdf.object.Datatype#toNative() 315 */ 316 @Override 317 public int toNative() 318 { 319 int tid = -1; 320 int tclass = getDatatypeClass(); 321 int tsize = getDatatypeSize(); 322 323 // figure the datatype 324 switch (tclass) 325 { 326 case Datatype.CLASS_INTEGER: 327 int tsign = getDatatypeSign(); 328 if (tsize == 1) 329 { 330 if (tsign == Datatype.SIGN_NONE) { 331 tid = HDFConstants.DFNT_UINT8; 332 } else { 333 tid = HDFConstants.DFNT_INT8; 334 } 335 } 336 else if (tsize == 2) 337 { 338 if (tsign == Datatype.SIGN_NONE) { 339 tid = HDFConstants.DFNT_UINT16; 340 } else { 341 tid = HDFConstants.DFNT_INT16; 342 } 343 } 344 else if ((tsize == 4) || (tsize == NATIVE)) 345 { 346 if (tsign == Datatype.SIGN_NONE) { 347 tid = HDFConstants.DFNT_UINT32; 348 } else { 349 tid = HDFConstants.DFNT_INT32; 350 } 351 } 352 else if (tsize == 8) 353 { 354 if (tsign == Datatype.SIGN_NONE) { 355 tid = HDFConstants.DFNT_UINT64; 356 } else { 357 tid = HDFConstants.DFNT_INT64; 358 } 359 } 360 break; 361 case Datatype.CLASS_FLOAT: 362 if (tsize == Datatype.NATIVE) { 363 tid = HDFConstants.DFNT_FLOAT; 364 } else if (tsize == 4) { 365 tid = HDFConstants.DFNT_FLOAT32; 366 } else if (tsize == 8) { 367 tid = HDFConstants.DFNT_FLOAT64; 368 } 369 break; 370 case Datatype.CLASS_CHAR: 371 int tsign2 = getDatatypeSign(); 372 if (tsign2 == Datatype.SIGN_NONE) { 373 tid = HDFConstants.DFNT_UCHAR; 374 } else { 375 tid = HDFConstants.DFNT_CHAR; 376 } 377 break; 378 case Datatype.CLASS_STRING: 379 tid = HDFConstants.DFNT_CHAR; 380 break; 381 } 382 383 return tid; 384 } 385 386 /* 387 * (non-Javadoc) 388 * @see hdf.object.Datatype#close(int) 389 */ 390 @Override 391 public void close(int id) {;} 392 393 //Implementing DataFormat 394 public List getMetadata(int... attrPropList) throws Exception { 395 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 396 } 397 398 399}