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; 016 017import java.util.List; 018 019/** 020 * Datatype is an abstract class that defines datatype characteristics and APIs 021 * for a data type. 022 * <p> 023 * A datatype has four basic characteristics: class, size, byte order and sign. 024 * These charactertics are defeined in the 025 * <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a>. 026 * <p> 027 * These charactertics apply to all the sub-classes. The sub-classes may have 028 * different ways to describe a datatype. We here define the <strong> native 029 * datatype</strong> to the datatype used by the sub-class. For example, 030 * H5Datatype uses a datatype identifier (hid_t) to specify a datatype. 031 * NC2Datatype uses ucar.nc2.DataType object to describe its datatype. "Native" 032 * here is different from the "native" definition in the HDF5 library. 033 * <p> 034 * Two functions, toNative() and fromNative(), are defined to convert the 035 * general charactertics to/form the native datatype. Sub-classes must implement 036 * these functions so that the conversion will be done correctly. 037 * The values of the CLASS member are not identical to HDF5 values for a datatype class 038 * <p> 039 * 040 * @version 1.1 9/4/2007 041 * @author Peter X. Cao 042 */ 043public abstract class Datatype extends HObject { 044 /** 045 * 046 */ 047 private static final long serialVersionUID = -581324710549963177L; 048 049 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Datatype.class); 050 051 /** 052 * The default definition for datatype size, order, and sign. 053 */ 054 public static final int NATIVE = -1; 055 056 /** 057 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 058 */ 059 public static final int CLASS_NO_CLASS = -1; 060 061 /** 062 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 063 */ 064 public static final int CLASS_INTEGER = 0; 065 066 /** 067 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 068 */ 069 public static final int CLASS_FLOAT = 1; 070 071 /** 072 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 073 */ 074 public static final int CLASS_CHAR = 2; 075 076 /** 077 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 078 */ 079 public static final int CLASS_STRING = 3; 080 081 /** 082 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 083 */ 084 public static final int CLASS_BITFIELD = 4; 085 086 /** 087 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 088 */ 089 public static final int CLASS_OPAQUE = 5; 090 091 /** 092 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 093 */ 094 public static final int CLASS_COMPOUND = 6; 095 096 /** 097 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 098 */ 099 public static final int CLASS_REFERENCE = 7; 100 101 /** 102 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 103 */ 104 public static final int CLASS_ENUM = 8; 105 106 /** 107 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 108 */ 109 public static final int CLASS_VLEN = 9; 110 111 /** 112 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 113 */ 114 public static final int CLASS_ARRAY = 10; 115 116 /** 117 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 118 */ 119 public static final int CLASS_TIME = 11; 120 121 /** 122 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 123 */ 124 public static final int ORDER_LE = 0; 125 126 /** 127 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 128 */ 129 public static final int ORDER_BE = 1; 130 131 /** 132 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 133 */ 134 public static final int ORDER_VAX = 2; 135 136 /** 137 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 138 */ 139 public static final int ORDER_NONE = 3; 140 141 // sign 142 /** 143 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 144 */ 145 public static final int SIGN_NONE = 0; 146 147 /** 148 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 149 */ 150 public static final int SIGN_2 = 1; 151 152 /** 153 * See <a href="http://hdfgroup.org/HDF5/doc/UG/index.html">HDF5 User's Guide</a> 154 */ 155 public static final int NSGN = 2; 156 157 /** 158 * The class of the datatype. 159 */ 160 protected int datatypeClass; 161 162 /** 163 * The size (in bytes) of the datatype. 164 */ 165 protected int datatypeSize; 166 167 /** 168 * The byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, and 169 * ORDER_VAX. 170 */ 171 protected int datatypeOrder; 172 173 /** 174 * The sign of the datatype. 175 */ 176 protected int datatypeSign; 177 178 /** 179 * The (name, value) pairs of enum members 180 */ 181 protected String enumMembers; 182 183 /** 184 * The list of names of members of a compound Datatype 185 */ 186 protected List<String> compoundMemberNames; 187 188 /** 189 * The list of offsets of members of a compound Datatype 190 */ 191 protected List<Long> compoundMemberOffsets; 192 193 /** 194 * The list of field IDs of members of a compound Datatype 195 */ 196 protected List<Integer> compoundMemberFieldIDs; 197 198 /** 199 * The base datatype of every element of the array (for CLASS_ARRAY 200 * datatype). 201 */ 202 protected Datatype baseType; 203 204 /* 205 * The dimension of the ARRAY element. For ARRAY datatype only 206 */ 207 protected long[] dims; 208 209 210 /** 211 * Constructs a named datatype with a given file, name and path. 212 * 213 * @param theFile 214 * the HDF file. 215 * @param name 216 * the name of the datatype, e.g "12-bit Integer". 217 * @param path 218 * the full group path of the datatype, e.g. "/datatypes/". 219 */ 220 public Datatype(FileFormat theFile, String name, String path) { 221 this(theFile, name, path, null); 222 } 223 224 /** 225 * @deprecated Not for public use in the future.<br> 226 * Using {@link #Datatype(FileFormat, String, String)} 227 * 228 * @param theFile 229 * the HDF file. 230 * @param name 231 * the name of the datatype, e.g "12-bit Integer". 232 * @param path 233 * the full group path of the datatype, e.g. "/datatypes/". 234 * @param oid 235 * the oidof the datatype. 236 */ 237 @Deprecated 238 public Datatype(FileFormat theFile, String name, String path, long[] oid) { 239 super(theFile, name, path, oid); 240 } 241 242 /** 243 * Constructs a Datatype with specified class, size, byte order and sign. 244 * <p> 245 * The following is a list of a few example of H5Datatype. 246 * <ol> 247 * <li>to create unsigned native integer<br> 248 * H5Datatype type = new H5Dataype(CLASS_INTEGER, NATIVE, NATIVE, 249 * SIGN_NONE); 250 * <li>to create 16-bit signed integer with big endian<br> 251 * H5Datatype type = new H5Dataype(CLASS_INTEGER, 2, ORDER_BE, NATIVE); 252 * <li>to create native float<br> 253 * H5Datatype type = new H5Dataype(CLASS_FLOAT, NATIVE, NATIVE, -1); 254 * <li>to create 64-bit double<br> 255 * H5Datatype type = new H5Dataype(CLASS_FLOAT, 8, NATIVE, -1); 256 * </ol> 257 * 258 * @param tclass 259 * the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and 260 * etc. 261 * @param tsize 262 * the size of the datatype in bytes, e.g. for a 32-bit integer, 263 * the size is 4. 264 * @param torder 265 * the byte order of the datatype. Valid values are ORDER_LE, 266 * ORDER_BE, ORDER_VAX and ORDER_NONE 267 * @param tsign 268 * the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 269 * and MSGN 270 */ 271 public Datatype(int tclass, int tsize, int torder, int tsign) { 272 this(tclass, tsize, torder, tsign, null); 273 } 274 275 /** 276 * Constructs a Datatype with specified class, size, byte order and sign. 277 * <p> 278 * The following is a list of a few example of H5Datatype. 279 * <ol> 280 * <li>to create unsigned native integer<br> 281 * H5Datatype type = new H5Dataype(CLASS_INTEGER, NATIVE, NATIVE, 282 * SIGN_NONE); 283 * <li>to create 16-bit signed integer with big endian<br> 284 * H5Datatype type = new H5Dataype(CLASS_INTEGER, 2, ORDER_BE, NATIVE); 285 * <li>to create native float<br> 286 * H5Datatype type = new H5Dataype(CLASS_FLOAT, NATIVE, NATIVE, -1); 287 * <li>to create 64-bit double<br> 288 * H5Datatype type = new H5Dataype(CLASS_FLOAT, 8, NATIVE, -1); 289 * </ol> 290 * 291 * @param tclass 292 * the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and 293 * etc. 294 * @param tsize 295 * the size of the datatype in bytes, e.g. for a 32-bit integer, 296 * the size is 4. 297 * @param torder 298 * the byte order of the datatype. Valid values are ORDER_LE, 299 * ORDER_BE, ORDER_VAX and ORDER_NONE 300 * @param tsign 301 * the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 302 * and MSGN 303 * @param tbase 304 * the base datatype of the new datatype 305 */ 306 public Datatype(int tclass, int tsize, int torder, int tsign, Datatype tbase) { 307 datatypeClass = tclass; 308 datatypeSize = tsize; 309 datatypeOrder = torder; 310 datatypeSign = tsign; 311 enumMembers = null; 312 baseType = tbase; 313 dims = null; 314 log.trace("datatypeClass={} datatypeSize={} datatypeOrder={} datatypeSign={} baseType={}", datatypeClass, datatypeSize, datatypeOrder, datatypeSign, baseType); 315 } 316 317 /** 318 * Constructs a Datatype with a given native datatype identifier. 319 * <p> 320 * For example, if the datatype identifier is a 32-bit unsigned integer 321 * created from HDF5, 322 * 323 * <pre> 324 * int tid = H5.H5Tcopy(HDF5Constants.H5T_NATIVE_UNINT32); 325 * Datatype dtype = new Datatype(tid); 326 * </pre> 327 * 328 * will construct a datatype equivalent to new Datatype(CLASS_INTEGER, 4, 329 * NATIVE, SIGN_NONE); 330 * 331 * @see #fromNative(int tid) 332 * @param tid 333 * the native datatype identifier. 334 */ 335 public Datatype(int tid) { 336 this(CLASS_NO_CLASS, NATIVE, NATIVE, NATIVE); 337 } 338 339 /** 340 * Returns the class of the datatype. Valid values are: 341 * <ul> 342 * <li>CLASS_NO_CLASS 343 * <li>CLASS_INTEGER 344 * <li>CLASS_FLOAT 345 * <li>CLASS_CHAR 346 * <li>CLASS_STRING 347 * <li>CLASS_BITFIELD 348 * <li>CLASS_OPAQUE 349 * <li>CLASS_COMPOUND 350 * <li>CLASS_REFERENCE 351 * <li>CLASS_ENUM 352 * <li>CLASS_VLEN 353 * <li>CLASS_ARRAY 354 * </ul> 355 * 356 * @return the class of the datatype. 357 */ 358 public int getDatatypeClass() { 359 return datatypeClass; 360 } 361 362 /** 363 * Returns the size of the datatype in bytes. For example, for a 32-bit 364 * integer, the size is 4 (bytes). 365 * 366 * @return the size of the datatype. 367 */ 368 public int getDatatypeSize() { 369 return datatypeSize; 370 } 371 372 /** 373 * Returns the byte order of the datatype. Valid values are 374 * <ul> 375 * <li>ORDER_LE 376 * <li>ORDER_BE 377 * <li>ORDER_VAX 378 * <li>ORDER_NONE 379 * </ul> 380 * 381 * @return the byte order of the datatype. 382 */ 383 public int getDatatypeOrder() { 384 return datatypeOrder; 385 } 386 387 /** 388 * Returns the sign (SIGN_NONE, SIGN_2 or NSGN) of an integer datatype. 389 * 390 * @return the sign of the datatype. 391 */ 392 public int getDatatypeSign() { 393 return datatypeSign; 394 } 395 396 /** 397 * Returns the datatype of array element for ARRAY datatype. 398 * <p> 399 * For example, a dataset set of ARRAY of integer, The datatype of the 400 * dataset is ARRAY. The datatype of the base type is integer. 401 * 402 * @return the the datatype of array element for ARRAY datatype. 403 */ 404 public Datatype getBasetype() { 405 return baseType; 406 } 407 408 /** 409 * Sets the (name, value) pairs of enum members for enum datatype. 410 * <p> 411 * For Example, 412 * <dl> 413 * <dt>setEnumMembers("lowTemp=-40, highTemp=90")</dt> 414 * <dd>sets the value of enum member lowTemp to -40 and highTemp to 90.</dd> 415 * <dt>setEnumMembers("lowTemp, highTemp")</dt> 416 * <dd>sets enum members to defaults, i.e. lowTemp=0 and highTemp=1</dd> 417 * <dt>setEnumMembers("lowTemp=10, highTemp")</dt> 418 * <dd>sets enum member lowTemp to 10 and highTemp to 11.</dd> 419 * </dl> 420 * 421 * @param enumStr 422 * the (name, value) pairs of enum members 423 */ 424 public final void setEnumMembers(String enumStr) { 425 enumMembers = enumStr; 426 } 427 428 /** 429 * Returns the "name=value" pairs of enum members for enum datatype. 430 * <p> 431 * For Example, 432 * <dl> 433 * <dt>setEnumMembers("lowTemp=-40, highTemp=90")</dt> 434 * <dd>sets the value of enum member lowTemp to -40 and highTemp to 90.</dd> 435 * <dt>setEnumMembers("lowTemp, highTemp")</dt> 436 * <dd>sets enum members to defaults, i.e. lowTemp=0 and highTemp=1</dd> 437 * <dt>setEnumMembers("lowTemp=10, highTemp")</dt> 438 * <dd>sets enum member lowTemp to 10 and highTemp to 11.</dd> 439 * </dl> 440 * 441 * @return enumStr the (name, value) pairs of enum members 442 */ 443 public final String getEnumMembers() { 444 return enumMembers; 445 } 446 447 /** 448 * Returns the dimensions of an Array Datatype. 449 * 450 * @return dims the dimensions of the Array Datatype 451 */ 452 public final long[] getArrayDims() { 453 return dims; 454 } 455 456 /** 457 * Converts the datatype object to a native datatype. 458 * 459 * Subclasses must implement it so that this datatype will be converted 460 * accordingly. Use close() to close the native identifier; otherwise, the 461 * datatype will be left open. 462 * <p> 463 * For example, a HDF5 datatype created from<br> 464 * 465 * <pre> 466 * H5Dataype dtype = new H5Datatype(CLASS_INTEGER, 4, NATIVE, SIGN_NONE); 467 * int tid = dtype.toNative(); 468 * </pre> 469 * 470 * There "tid" will be the HDF5 datatype id of a 32-bit unsigned integer, 471 * which is equivalent to 472 * 473 * <pre> 474 * int tid = H5.H5Tcopy(HDF5Constants.H5T_NATIVE_UNINT32); 475 * </pre> 476 * 477 * @return the identifier of the native datatype. 478 */ 479 public abstract int toNative(); 480 481 /** 482 * Set datatype characteristics (class, size, byte order and sign) from a 483 * given datatye identifier. 484 * <p> 485 * Sub-classes must implement it so that this datatype will be converted 486 * accordingly. 487 * <p> 488 * For example, if the type identifier is a 32-bit unsigned integer created 489 * from HDF5, 490 * 491 * <pre> 492 * H5Datatype dtype = new H5Datatype(); 493 * dtype.fromNative(HDF5Constants.H5T_NATIVE_UNINT32); 494 * </pre> 495 * 496 * Where dtype is equivalent to <br> 497 * new H5Datatype(CLASS_INTEGER, 4, NATIVE, SIGN_NONE); 498 * 499 * @param nativeID 500 * the datatype identifier. 501 */ 502 public abstract void fromNative(int nativeID); 503 504 /** 505 * Returns a short text description of this datatype. 506 * 507 * @return a short text description of this datatype 508 */ 509 public String getDatatypeDescription() { 510 String description = "Unknown"; 511 512 switch (datatypeClass) { 513 case CLASS_INTEGER: 514 if (datatypeSign == SIGN_NONE) { 515 description = String.valueOf(datatypeSize * 8) 516 + "-bit unsigned integer"; 517 } 518 else { 519 description = String.valueOf(datatypeSize * 8) + "-bit integer"; 520 } 521 break; 522 case CLASS_FLOAT: 523 description = String.valueOf(datatypeSize * 8) 524 + "-bit floating-point"; 525 break; 526 case CLASS_STRING: 527 description = "String"; 528 break; 529 case CLASS_REFERENCE: 530 description = "Object reference"; 531 break; 532 case CLASS_BITFIELD: 533 description = "Bitfield"; 534 break; 535 case CLASS_ENUM: 536 description = String.valueOf(datatypeSize * 8) + "-bit enum"; 537 break; 538 case CLASS_ARRAY: 539 description = "Array"; 540 break; 541 case CLASS_COMPOUND: 542 description = "Compound "; 543 break; 544 case CLASS_VLEN: 545 description = "Variable-length"; 546 break; 547 default: 548 description = "Unknown"; 549 break; 550 } 551 552 log.trace("description={}", description); 553 return description; 554 } 555 556 /** 557 * Checks if this datatype is an unsigned integer. 558 * 559 * @return true if the datatype is an unsigned integer; otherwise, returns 560 * false. 561 */ 562 public abstract boolean isUnsigned(); 563 564 /** 565 * Opens access to this named datatype. Sub-clases must replace this default 566 * implementation. For example, in H5Datatype, open() function 567 * H5.H5Topen(loc_id, name) to get the datatype identifier. 568 * 569 * @return the datatype identifier if successful; otherwise returns negative 570 * value. 571 */ 572 @Override 573 public int open() { 574 return -1; 575 } 576 577 /** 578 * Closes a datatype identifier. 579 * <p> 580 * Sub-clases must replace this default implementation. 581 * 582 * @param id 583 * the datatype identifier to close. 584 */ 585 @Override 586 public abstract void close(int id); 587 588 /* 589 * (non-Javadoc) 590 * 591 * @see hdf.object.DataFormat#getMetadata() 592 */ 593 public List getMetadata() throws Exception { 594 return null; 595 } 596 597 /* 598 * (non-Javadoc) 599 * 600 * @see hdf.object.DataFormat#writeMetadata(java.lang.Object) 601 */ 602 public void writeMetadata(Object info) throws Exception { 603 ; 604 } 605 606 /* 607 * (non-Javadoc) 608 * 609 * @see hdf.object.DataFormat#removeMetadata(java.lang.Object) 610 */ 611 public void removeMetadata(Object info) throws Exception { 612 ; 613 } 614 615 /* 616 * (non-Javadoc) 617 * 618 * @see hdf.object.DataFormat#updateMetadata(java.lang.Object) 619 */ 620 public void updateMetadata(Object info) throws Exception { 621 ; 622 } 623}