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