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}